mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-20 17:24:22 +01:00
wip: desktop work
This commit is contained in:
1
bun.lock
1
bun.lock
@@ -141,6 +141,7 @@
|
||||
"@types/luxon": "3.7.1",
|
||||
"@types/node": "catalog:",
|
||||
"@typescript/native-preview": "catalog:",
|
||||
"opencode": "workspace:*",
|
||||
"typescript": "catalog:",
|
||||
"vite": "catalog:",
|
||||
"vite-plugin-icons-spritesheet": "3.0.1",
|
||||
|
||||
@@ -12,12 +12,13 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"opencode": "workspace:*",
|
||||
"@tailwindcss/vite": "catalog:",
|
||||
"@tsconfig/bun": "1.0.9",
|
||||
"@types/luxon": "3.7.1",
|
||||
"@types/node": "catalog:",
|
||||
"typescript": "catalog:",
|
||||
"@typescript/native-preview": "catalog:",
|
||||
"typescript": "catalog:",
|
||||
"vite": "catalog:",
|
||||
"vite-plugin-icons-spritesheet": "3.0.1",
|
||||
"vite-plugin-solid": "catalog:"
|
||||
|
||||
362
packages/desktop/src/components/assistant-message.tsx
Normal file
362
packages/desktop/src/components/assistant-message.tsx
Normal file
@@ -0,0 +1,362 @@
|
||||
import type { Part, AssistantMessage, ReasoningPart, TextPart, ToolPart } from "@opencode-ai/sdk"
|
||||
import type { Tool } from "opencode/tool/tool"
|
||||
import type { ReadTool } from "opencode/tool/read"
|
||||
import { children, Component, createMemo, For, Match, Show, Switch, type JSX } from "solid-js"
|
||||
import { Dynamic } from "solid-js/web"
|
||||
import { Markdown } from "./markdown"
|
||||
import { Collapsible, Icon, IconProps } from "@opencode-ai/ui"
|
||||
import { getDirectory, getFilename } from "@/utils"
|
||||
import { ListTool } from "opencode/tool/ls"
|
||||
import { GlobTool } from "opencode/tool/glob"
|
||||
import { GrepTool } from "opencode/tool/grep"
|
||||
import { WebFetchTool } from "opencode/tool/webfetch"
|
||||
import { TaskTool } from "opencode/tool/task"
|
||||
import { BashTool } from "opencode/tool/bash"
|
||||
import { EditTool } from "opencode/tool/edit"
|
||||
import { DiffChanges } from "./diff-changes"
|
||||
import { WriteTool } from "opencode/tool/write"
|
||||
|
||||
export function AssistantMessage(props: { message: AssistantMessage; parts: Part[] }) {
|
||||
return (
|
||||
<div class="w-full flex flex-col items-start gap-4">
|
||||
<For each={props.parts}>
|
||||
{(part) => {
|
||||
const component = createMemo(() => PART_MAPPING[part.type as keyof typeof PART_MAPPING])
|
||||
return (
|
||||
<Show when={component()}>
|
||||
<Dynamic component={component()} part={part as any} message={props.message} />
|
||||
</Show>
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const PART_MAPPING = {
|
||||
text: TextPart,
|
||||
tool: ToolPart,
|
||||
reasoning: ReasoningPart,
|
||||
}
|
||||
|
||||
function ReasoningPart(props: { part: ReasoningPart; message: AssistantMessage }) {
|
||||
return null
|
||||
// return (
|
||||
// <Show when={props.part.text.trim()}>
|
||||
// <div>{props.part.text}</div>
|
||||
// </Show>
|
||||
// )
|
||||
}
|
||||
|
||||
function TextPart(props: { part: TextPart; message: AssistantMessage }) {
|
||||
return (
|
||||
<Show when={props.part.text.trim()}>
|
||||
<Markdown text={props.part.text.trim()} />
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
|
||||
function ToolPart(props: { part: ToolPart; message: AssistantMessage }) {
|
||||
// const sync = useSync()
|
||||
|
||||
const component = createMemo(() => {
|
||||
const render = ToolRegistry.render(props.part.tool) ?? GenericTool
|
||||
|
||||
const metadata = props.part.state.status === "pending" ? {} : (props.part.state.metadata ?? {})
|
||||
const input = props.part.state.status === "completed" ? props.part.state.input : {}
|
||||
// const permissions = sync.data.permission[props.message.sessionID] ?? []
|
||||
// const permissionIndex = permissions.findIndex((x) => x.callID === props.part.callID)
|
||||
// const permission = permissions[permissionIndex]
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dynamic
|
||||
component={render}
|
||||
input={input}
|
||||
tool={props.part.tool}
|
||||
metadata={metadata}
|
||||
// permission={permission?.metadata ?? {}}
|
||||
output={props.part.state.status === "completed" ? props.part.state.output : undefined}
|
||||
/>
|
||||
{/* <Show when={props.part.state.status === "error"}>{props.part.state.error.replace("Error: ", "")}</Show> */}
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
return <Show when={component()}>{component()}</Show>
|
||||
}
|
||||
|
||||
type TriggerTitle = {
|
||||
title: string
|
||||
subtitle?: string
|
||||
args?: string[]
|
||||
action?: JSX.Element
|
||||
}
|
||||
|
||||
const isTriggerTitle = (val: any): val is TriggerTitle => {
|
||||
return typeof val === "object" && val !== null && "title" in val && !(val instanceof Node)
|
||||
}
|
||||
|
||||
function BasicTool(props: { icon: IconProps["name"]; trigger: TriggerTitle | JSX.Element; children?: JSX.Element }) {
|
||||
const resolved = children(() => props.children)
|
||||
|
||||
return (
|
||||
<Collapsible>
|
||||
<Collapsible.Trigger>
|
||||
<div class="w-full flex items-center self-stretch gap-5 justify-between">
|
||||
<div class="w-full flex items-center self-stretch gap-5">
|
||||
<Icon name={props.icon} size="small" />
|
||||
<Switch>
|
||||
<Match when={isTriggerTitle(props.trigger)}>
|
||||
<div class="w-full flex items-center gap-2 justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-12-medium text-text-base capitalize">
|
||||
{(props.trigger as TriggerTitle).title}
|
||||
</span>
|
||||
<Show when={(props.trigger as TriggerTitle).subtitle}>
|
||||
<span class="text-12-medium text-text-weak">{(props.trigger as TriggerTitle).subtitle}</span>
|
||||
</Show>
|
||||
<Show when={(props.trigger as TriggerTitle).args?.length}>
|
||||
<For each={(props.trigger as TriggerTitle).args}>
|
||||
{(arg) => <span class="text-12-regular text-text-weaker">{arg}</span>}
|
||||
</For>
|
||||
</Show>
|
||||
</div>
|
||||
<Show when={(props.trigger as TriggerTitle).action}>{(props.trigger as TriggerTitle).action}</Show>
|
||||
</div>
|
||||
</Match>
|
||||
<Match when={true}>{props.trigger as JSX.Element}</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
<Show when={resolved()}>
|
||||
<Collapsible.Arrow />
|
||||
</Show>
|
||||
</div>
|
||||
</Collapsible.Trigger>
|
||||
<Show when={props.children}>
|
||||
<Collapsible.Content>{props.children}</Collapsible.Content>
|
||||
</Show>
|
||||
</Collapsible>
|
||||
)
|
||||
}
|
||||
|
||||
function GenericTool(props: ToolProps<any>) {
|
||||
return <BasicTool icon="mcp" trigger={{ title: props.tool }} />
|
||||
}
|
||||
|
||||
type ToolProps<T extends Tool.Info> = {
|
||||
input: Partial<Tool.InferParameters<T>>
|
||||
metadata: Partial<Tool.InferMetadata<T>>
|
||||
// permission: Record<string, any>
|
||||
tool: string
|
||||
output?: string
|
||||
}
|
||||
|
||||
const ToolRegistry = (() => {
|
||||
const state: Record<
|
||||
string,
|
||||
{
|
||||
name: string
|
||||
render?: Component<ToolProps<any>>
|
||||
}
|
||||
> = {}
|
||||
function register<T extends Tool.Info>(input: { name: string; render?: Component<ToolProps<T>> }) {
|
||||
state[input.name] = input
|
||||
return input
|
||||
}
|
||||
return {
|
||||
register,
|
||||
render(name: string) {
|
||||
return state[name]?.render
|
||||
},
|
||||
}
|
||||
})()
|
||||
|
||||
ToolRegistry.register<typeof ReadTool>({
|
||||
name: "read",
|
||||
render(props) {
|
||||
return (
|
||||
<BasicTool
|
||||
icon="glasses"
|
||||
trigger={{ title: props.tool, subtitle: props.input.filePath ? getFilename(props.input.filePath) : "" }}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
ToolRegistry.register<typeof ListTool>({
|
||||
name: "list",
|
||||
render(props) {
|
||||
return (
|
||||
<BasicTool icon="bullet-list" trigger={{ title: props.tool, subtitle: props.input.path || "/" }}>
|
||||
<Show when={false && props.output}>
|
||||
<div class="whitespace-pre">{props.output}</div>
|
||||
</Show>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
ToolRegistry.register<typeof GlobTool>({
|
||||
name: "glob",
|
||||
render(props) {
|
||||
return (
|
||||
<BasicTool
|
||||
icon="magnifying-glass-menu"
|
||||
trigger={{
|
||||
title: props.tool,
|
||||
subtitle: props.input.path || "/",
|
||||
args: props.input.pattern ? ["pattern=" + props.input.pattern] : [],
|
||||
}}
|
||||
>
|
||||
<Show when={false && props.output}>
|
||||
<div class="whitespace-pre">{props.output}</div>
|
||||
</Show>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
ToolRegistry.register<typeof GrepTool>({
|
||||
name: "grep",
|
||||
render(props) {
|
||||
const args = []
|
||||
if (props.input.pattern) args.push("pattern=" + props.input.pattern)
|
||||
if (props.input.include) args.push("include=" + props.input.include)
|
||||
return (
|
||||
<BasicTool
|
||||
icon="magnifying-glass-menu"
|
||||
trigger={{
|
||||
title: props.tool,
|
||||
subtitle: props.input.path || "/",
|
||||
args,
|
||||
}}
|
||||
>
|
||||
<Show when={false && props.output}>
|
||||
<div class="whitespace-pre">{props.output}</div>
|
||||
</Show>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
ToolRegistry.register<typeof WebFetchTool>({
|
||||
name: "webfetch",
|
||||
render(props) {
|
||||
return (
|
||||
<BasicTool
|
||||
icon="window-cursor"
|
||||
trigger={{
|
||||
title: props.tool,
|
||||
subtitle: props.input.url || "",
|
||||
args: props.input.format ? ["format=" + props.input.format] : [],
|
||||
action: (
|
||||
<div class="size-6 flex items-center justify-center">
|
||||
<Icon name="square-arrow-top-right" size="small" />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Show when={false && props.output}>
|
||||
<div class="whitespace-pre">{props.output}</div>
|
||||
</Show>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
ToolRegistry.register<typeof TaskTool>({
|
||||
name: "task",
|
||||
render(props) {
|
||||
return (
|
||||
<BasicTool
|
||||
icon="task"
|
||||
trigger={{
|
||||
title: `${props.input.subagent_type || props.tool} Agent`,
|
||||
subtitle: props.input.description,
|
||||
}}
|
||||
>
|
||||
<Show when={false && props.output}>
|
||||
<div class="whitespace-pre">{props.output}</div>
|
||||
</Show>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
ToolRegistry.register<typeof BashTool>({
|
||||
name: "bash",
|
||||
render(props) {
|
||||
return (
|
||||
<BasicTool
|
||||
icon="console"
|
||||
trigger={{
|
||||
title: "Shell",
|
||||
subtitle: "Ran " + props.input.command,
|
||||
}}
|
||||
>
|
||||
<Show when={false && props.output}>
|
||||
<div class="whitespace-pre">{props.output}</div>
|
||||
</Show>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
ToolRegistry.register<typeof EditTool>({
|
||||
name: "edit",
|
||||
render(props) {
|
||||
return (
|
||||
<BasicTool
|
||||
icon="code-lines"
|
||||
trigger={
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<div class="flex items-center gap-5">
|
||||
<div class="text-12-medium text-text-base capitalize">Edit</div>
|
||||
<div class="flex">
|
||||
<Show when={props.input.filePath?.includes("/")}>
|
||||
<span class="text-text-weak">{getDirectory(props.input.filePath!)}/</span>
|
||||
</Show>
|
||||
<span class="text-text-strong">{getFilename(props.input.filePath ?? "")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4 items-center justify-end">{/* <DiffChanges diff={diff} /> */}</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Show when={false && props.output}>
|
||||
<div class="whitespace-pre">{props.output}</div>
|
||||
</Show>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
ToolRegistry.register<typeof WriteTool>({
|
||||
name: "write",
|
||||
render(props) {
|
||||
return (
|
||||
<BasicTool
|
||||
icon="code-lines"
|
||||
trigger={
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<div class="flex items-center gap-5">
|
||||
<div class="text-12-medium text-text-base capitalize">Write</div>
|
||||
<div class="flex">
|
||||
<Show when={props.input.filePath?.includes("/")}>
|
||||
<span class="text-text-weak">{getDirectory(props.input.filePath!)}/</span>
|
||||
</Show>
|
||||
<span class="text-text-strong">{getFilename(props.input.filePath ?? "")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4 items-center justify-end">{/* <DiffChanges diff={diff} /> */}</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Show when={false && props.output}>
|
||||
<div class="whitespace-pre">{props.output}</div>
|
||||
</Show>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
})
|
||||
20
packages/desktop/src/components/diff-changes.tsx
Normal file
20
packages/desktop/src/components/diff-changes.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { FileDiff } from "@opencode-ai/sdk"
|
||||
import { createMemo, Show } from "solid-js"
|
||||
|
||||
export function DiffChanges(props: { diff: FileDiff | FileDiff[] }) {
|
||||
const additions = createMemo(() =>
|
||||
Array.isArray(props.diff) ? props.diff.reduce((acc, diff) => acc + (diff.additions ?? 0), 0) : props.diff.additions,
|
||||
)
|
||||
const deletions = createMemo(() =>
|
||||
Array.isArray(props.diff) ? props.diff.reduce((acc, diff) => acc + (diff.deletions ?? 0), 0) : props.diff.deletions,
|
||||
)
|
||||
const total = createMemo(() => additions() + deletions())
|
||||
return (
|
||||
<Show when={total() > 0}>
|
||||
<div class="flex gap-2 justify-end items-center">
|
||||
<span class="text-12-mono text-right text-text-diff-add-base">{`+${additions()}`}</span>
|
||||
<span class="text-12-mono text-right text-text-diff-delete-base">{`-${deletions()}`}</span>
|
||||
</div>
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
@@ -460,13 +460,6 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
|
||||
return sync.data.message[store.active]?.find((m) => m.id === store.activeMessage)
|
||||
})
|
||||
|
||||
const activeAssistantMessages = createMemo(() => {
|
||||
if (!store.active || !activeMessage()) return []
|
||||
return sync.data.message[store.active]?.filter(
|
||||
(m) => m.role === "assistant" && m.parentID == activeMessage()?.id,
|
||||
)
|
||||
})
|
||||
|
||||
const model = createMemo(() => {
|
||||
if (!last()) return
|
||||
const model = sync.data.provider.find((x) => x.id === last().providerID)?.models[last().modelID]
|
||||
@@ -504,7 +497,6 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
|
||||
return {
|
||||
active,
|
||||
activeMessage,
|
||||
activeAssistantMessages,
|
||||
lastUserMessage,
|
||||
cost,
|
||||
last,
|
||||
|
||||
@@ -22,6 +22,10 @@ import { Code } from "@/components/code"
|
||||
import { useSync } from "@/context/sync"
|
||||
import { useSDK } from "@/context/sdk"
|
||||
import { Diff } from "@/components/diff"
|
||||
import { ProgressCircle } from "@/components/progress-circle"
|
||||
import { AssistantMessage } from "@/components/assistant-message"
|
||||
import { type AssistantMessage as AssistantMessageType } from "@opencode-ai/sdk"
|
||||
import { DiffChanges } from "@/components/diff-changes"
|
||||
|
||||
export default function Page() {
|
||||
const local = useLocal()
|
||||
@@ -92,7 +96,7 @@ export default function Page() {
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key.length === 1 && event.key !== "Unidentified") {
|
||||
if (event.key.length === 1 && event.key !== "Unidentified" && !(event.ctrlKey || event.metaKey)) {
|
||||
inputRef?.focus()
|
||||
}
|
||||
}
|
||||
@@ -392,9 +396,6 @@ export default function Page() {
|
||||
{(session) => {
|
||||
const diffs = createMemo(() => session.summary?.diffs ?? [])
|
||||
const filesChanged = createMemo(() => diffs().length)
|
||||
const additions = createMemo(() => diffs().reduce((acc, diff) => (acc ?? 0) + (diff.additions ?? 0), 0))
|
||||
const deletions = createMemo(() => diffs().reduce((acc, diff) => (acc ?? 0) + (diff.deletions ?? 0), 0))
|
||||
|
||||
return (
|
||||
<Tooltip placement="right" value={session.title}>
|
||||
<div>
|
||||
@@ -408,12 +409,7 @@ export default function Page() {
|
||||
</div>
|
||||
<div class="flex justify-between items-center self-stretch">
|
||||
<span class="text-12-regular text-text-weak">{`${filesChanged() || "No"} file${filesChanged() !== 1 ? "s" : ""} changed`}</span>
|
||||
<Show when={additions() || deletions()}>
|
||||
<div class="flex gap-2 justify-end items-center">
|
||||
<span class="text-12-mono text-right text-text-diff-add-base">{`+${additions()}`}</span>
|
||||
<span class="text-12-mono text-right text-text-diff-delete-base">{`-${deletions()}`}</span>
|
||||
</div>
|
||||
</Show>
|
||||
<DiffChanges diff={diffs()} />
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
@@ -434,13 +430,12 @@ export default function Page() {
|
||||
<Tabs onChange={handleTabChange}>
|
||||
<div class="sticky top-0 shrink-0 flex">
|
||||
<Tabs.List>
|
||||
<Tabs.Trigger value="chat" class="flex gap-x-1.5 items-center">
|
||||
<Tabs.Trigger value="chat" class="flex gap-x-4 items-center">
|
||||
<div>Chat</div>
|
||||
<Show when={local.session.active()}>
|
||||
<div class="flex flex-col h-4 px-2 -mr-2 justify-center items-center rounded-full bg-surface-base text-12-medium text-text-strong">
|
||||
{local.session.context()}%
|
||||
</div>
|
||||
</Show>
|
||||
<Tooltip value={`${local.session.tokens() ?? 0} Tokens`} class="flex items-center gap-1.5">
|
||||
<ProgressCircle percentage={local.session.context() ?? 0} />
|
||||
<div class="text-14-regular text-text-weak text-right">{local.session.context() ?? 0}%</div>
|
||||
</Tooltip>
|
||||
</Tabs.Trigger>
|
||||
{/* <Tabs.Trigger value="review">Review</Tabs.Trigger> */}
|
||||
<SortableProvider ids={local.file.opened().map((file) => file.path)}>
|
||||
@@ -548,7 +543,87 @@ export default function Page() {
|
||||
<Show when={local.session.userMessages().length > 1}>
|
||||
<ul role="list" class="w-60 shrink-0 flex flex-col items-start gap-1">
|
||||
<For each={local.session.userMessages()}>
|
||||
{(message) => (
|
||||
{(message) => {
|
||||
const countLines = (text: string) => {
|
||||
if (!text) return 0
|
||||
return text.split("\n").length
|
||||
}
|
||||
|
||||
const additions = createMemo(
|
||||
() =>
|
||||
message.summary?.diffs.reduce((acc, diff) => acc + (diff.additions ?? 0), 0) ?? 0,
|
||||
)
|
||||
|
||||
const deletions = createMemo(
|
||||
() =>
|
||||
message.summary?.diffs.reduce((acc, diff) => acc + (diff.deletions ?? 0), 0) ?? 0,
|
||||
)
|
||||
|
||||
const totalBeforeLines = createMemo(
|
||||
() =>
|
||||
message.summary?.diffs.reduce((acc, diff) => acc + countLines(diff.before), 0) ??
|
||||
0,
|
||||
)
|
||||
|
||||
const blockCounts = createMemo(() => {
|
||||
const TOTAL_BLOCKS = 5
|
||||
|
||||
const adds = additions()
|
||||
const dels = deletions()
|
||||
const unchanged = Math.max(0, totalBeforeLines() - dels)
|
||||
|
||||
const totalActivity = unchanged + adds + dels
|
||||
|
||||
if (totalActivity === 0) {
|
||||
return { added: 0, deleted: 0, neutral: TOTAL_BLOCKS }
|
||||
}
|
||||
|
||||
const percentAdded = adds / totalActivity
|
||||
const percentDeleted = dels / totalActivity
|
||||
const added_raw = percentAdded * TOTAL_BLOCKS
|
||||
const deleted_raw = percentDeleted * TOTAL_BLOCKS
|
||||
|
||||
let added = adds > 0 ? Math.ceil(added_raw) : 0
|
||||
let deleted = dels > 0 ? Math.ceil(deleted_raw) : 0
|
||||
|
||||
let total_allocated = added + deleted
|
||||
if (total_allocated > TOTAL_BLOCKS) {
|
||||
if (added_raw < deleted_raw) {
|
||||
added = Math.floor(added_raw)
|
||||
} else {
|
||||
deleted = Math.floor(deleted_raw)
|
||||
}
|
||||
|
||||
total_allocated = added + deleted
|
||||
if (total_allocated > TOTAL_BLOCKS) {
|
||||
if (added_raw < deleted_raw) {
|
||||
deleted = Math.floor(deleted_raw)
|
||||
} else {
|
||||
added = Math.floor(added_raw)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const neutral = Math.max(0, TOTAL_BLOCKS - added - deleted)
|
||||
|
||||
return { added, deleted, neutral }
|
||||
})
|
||||
|
||||
const ADD_COLOR = "var(--icon-diff-add-base)"
|
||||
const DELETE_COLOR = "var(--icon-diff-delete-base)"
|
||||
const NEUTRAL_COLOR = "var(--icon-weak-base)"
|
||||
|
||||
const visibleBlocks = createMemo(() => {
|
||||
const counts = blockCounts()
|
||||
const blocks = [
|
||||
...Array(counts.added).fill(ADD_COLOR),
|
||||
...Array(counts.deleted).fill(DELETE_COLOR),
|
||||
...Array(counts.neutral).fill(NEUTRAL_COLOR),
|
||||
]
|
||||
return blocks.slice(0, 5)
|
||||
})
|
||||
|
||||
return (
|
||||
<li
|
||||
class="group/li flex items-center gap-x-2 py-1 self-stretch cursor-default"
|
||||
onClick={() => local.session.setActiveMessage(message.id)}
|
||||
@@ -556,11 +631,11 @@ export default function Page() {
|
||||
<div class="w-[18px] shrink-0">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 12" fill="none">
|
||||
<g>
|
||||
<rect x="0" width="2" height="12" rx="1" fill="#CFCECD" />
|
||||
<rect x="4" width="2" height="12" rx="1" fill="#CFCECD" />
|
||||
<rect x="8" width="2" height="12" rx="1" fill="#CFCECD" />
|
||||
<rect x="12" width="2" height="12" rx="1" fill="#CFCECD" />
|
||||
<rect x="16" width="2" height="12" rx="1" fill="#CFCECD" />
|
||||
<For each={visibleBlocks()}>
|
||||
{(color, i) => (
|
||||
<rect x={i() * 4} width="2" height="12" rx="1" fill={color} />
|
||||
)}
|
||||
</For>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
@@ -574,7 +649,8 @@ export default function Page() {
|
||||
{message.summary?.title ?? local.session.getMessageText(message)}
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
</ul>
|
||||
</Show>
|
||||
@@ -585,6 +661,11 @@ export default function Page() {
|
||||
const title = createMemo(() => message.summary?.title)
|
||||
const prompt = createMemo(() => local.session.getMessageText(message))
|
||||
const summary = createMemo(() => message.summary?.body)
|
||||
const assistantMessages = createMemo(() => {
|
||||
return sync.data.message[activeSession().id]?.filter(
|
||||
(m) => m.role === "assistant" && m.parentID == message.id,
|
||||
) as AssistantMessageType[]
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -633,10 +714,7 @@ export default function Page() {
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4 items-center justify-end">
|
||||
<div class="flex gap-2 justify-end items-center">
|
||||
<span class="text-12-mono text-right text-text-diff-add-base">{`+${diff.additions}`}</span>
|
||||
<span class="text-12-mono text-right text-text-diff-delete-base">{`-${diff.deletions}`}</span>
|
||||
</div>
|
||||
<DiffChanges diff={diff} />
|
||||
<Icon name="chevron-grabber-vertical" size="small" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -661,10 +739,18 @@ export default function Page() {
|
||||
</Show>
|
||||
</div>
|
||||
{/* Response */}
|
||||
<div data-todo="Response (Timeline)">
|
||||
<div data-todo="Response" class="w-full">
|
||||
<div class="flex flex-col items-start gap-1 self-stretch">
|
||||
<h2 class="text-12-medium text-text-weak">Response</h2>
|
||||
</div>
|
||||
<div class="w-full flex flex-col items-start self-stretch gap-8">
|
||||
<For each={assistantMessages()}>
|
||||
{(assistantMessage) => {
|
||||
const parts = createMemo(() => sync.data.part[assistantMessage.id])
|
||||
return <AssistantMessage message={assistantMessage} parts={parts()} />
|
||||
}}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -32,6 +32,9 @@ export namespace Tool {
|
||||
}>
|
||||
}
|
||||
|
||||
export type InferParameters<T extends Info> = T extends Info<infer P> ? z.infer<P> : never
|
||||
export type InferMetadata<T extends Info> = T extends Info<any, infer M> ? M : never
|
||||
|
||||
export function define<Parameters extends z.ZodType, Result extends Metadata>(
|
||||
id: string,
|
||||
init: Info<Parameters, Result>["init"] | Awaited<ReturnType<Info<Parameters, Result>["init"]>>,
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
--background-base: #f8f7f7;
|
||||
--background-base: #F8F7F7;
|
||||
--background-weak: var(--smoke-light-3);
|
||||
--background-strong: var(--smoke-light-1);
|
||||
--background-stronger: #fcfcfc;
|
||||
--background-stronger: #FCFCFC;
|
||||
--base: var(--smoke-light-alpha-2);
|
||||
--surface-base: var(--smoke-light-alpha-2);
|
||||
--surface-base-hover: #0500000F;
|
||||
--surface-base-active: var(--smoke-light-alpha-3);
|
||||
--surface-base-interactive-active: var(--cobalt-light-alpha-3);
|
||||
--base2: var(--smoke-light-alpha-2);
|
||||
--base3: var(--smoke-light-alpha-2);
|
||||
--surface-inset-base: var(--smoke-light-alpha-3);
|
||||
--surface-inset-base: var(--smoke-light-alpha-2);
|
||||
--surface-inset-base-hover: var(--smoke-light-alpha-3);
|
||||
--surface-inset-strong: #1f000017;
|
||||
--surface-inset-strong-hover: #1f000017;
|
||||
--surface-inset-strong: #1F000017;
|
||||
--surface-inset-strong-hover: #1F000017;
|
||||
--surface-raised-base: var(--smoke-light-alpha-1);
|
||||
--surface-float-base: var(--smoke-dark-1);
|
||||
--surface-float-base-hover: var(--smoke-dark-2);
|
||||
@@ -20,7 +23,7 @@
|
||||
--surface-raised-stronger-hover: var(--white);
|
||||
--surface-weak: var(--smoke-light-alpha-3);
|
||||
--surface-weaker: var(--smoke-light-alpha-4);
|
||||
--surface-strong: #ffffff;
|
||||
--surface-strong: #FFFFFF;
|
||||
--surface-raised-stronger-non-alpha: var(--white);
|
||||
--surface-brand-base: var(--yuzu-light-9);
|
||||
--surface-brand-hover: var(--yuzu-light-10);
|
||||
@@ -40,9 +43,9 @@
|
||||
--surface-info-base: var(--lilac-light-3);
|
||||
--surface-info-weak: var(--lilac-light-2);
|
||||
--surface-info-strong: var(--lilac-light-9);
|
||||
--surface-diff-skip-base: var(--smoke-light-3);
|
||||
--surface-diff-unchanged-base: #ffffff00;
|
||||
--surface-diff-hidden-base: var(--blue-light-3);
|
||||
--surface-diff-skip-base: var(--smoke-light-2);
|
||||
--surface-diff-unchanged-base: #FFFFFF00;
|
||||
--surface-diff-hidden-weak: var(--blue-light-2);
|
||||
--surface-diff-hidden-weaker: var(--blue-light-1);
|
||||
--surface-diff-hidden-strong: var(--blue-light-5);
|
||||
@@ -67,8 +70,10 @@
|
||||
--text-weak: var(--smoke-light-9);
|
||||
--text-weaker: var(--smoke-light-8);
|
||||
--text-strong: var(--smoke-light-12);
|
||||
--text-interactive-base: var(--cobalt-light-9);
|
||||
--text-on-brand-base: var(--smoke-light-alpha-11);
|
||||
--text-on-interactive-base: var(--smoke-light-1);
|
||||
--text-on-interactive-weak: var(--smoke-dark-alpha-11);
|
||||
--text-on-success-base: var(--smoke-dark-alpha-11);
|
||||
--text-on-warning-base: var(--smoke-dark-alpha-11);
|
||||
--text-on-info-base: var(--smoke-dark-alpha-11);
|
||||
@@ -85,7 +90,8 @@
|
||||
--text-on-brand-weak: var(--smoke-light-alpha-9);
|
||||
--text-on-brand-weaker: var(--smoke-light-alpha-8);
|
||||
--text-on-brand-strong: var(--smoke-light-alpha-12);
|
||||
--button-secondary-base: #fdfcfc;
|
||||
--button-secondary-base: #FDFCFC;
|
||||
--button-secondary-base-hover: #FAF9F9;
|
||||
--border-base: var(--smoke-light-alpha-7);
|
||||
--border-hover: var(--smoke-light-alpha-8);
|
||||
--border-active: var(--smoke-light-alpha-9);
|
||||
@@ -101,7 +107,7 @@
|
||||
--border-strong-focus: var(--smoke-light-alpha-7);
|
||||
--border-weak-hover: var(--smoke-light-alpha-6);
|
||||
--border-weak-active: var(--smoke-light-alpha-7);
|
||||
--border-weak-selected: var(--cobalt-light-alpha-6);
|
||||
--border-weak-selected: var(--cobalt-light-alpha-5);
|
||||
--border-weak-disabled: var(--smoke-light-alpha-6);
|
||||
--border-weak-focus: var(--smoke-light-alpha-7);
|
||||
--border-interactive-base: var(--cobalt-light-7);
|
||||
@@ -129,7 +135,7 @@
|
||||
--icon-disabled: var(--smoke-light-8);
|
||||
--icon-focus: var(--smoke-light-12);
|
||||
--icon-weak-base: var(--smoke-light-7);
|
||||
--icon-invert-base: #ffffff;
|
||||
--icon-invert-base: #FFFFFF;
|
||||
--icon-weak-hover: var(--smoke-light-8);
|
||||
--icon-weak-active: var(--smoke-light-9);
|
||||
--icon-weak-selected: var(--smoke-light-10);
|
||||
@@ -158,13 +164,11 @@
|
||||
--icon-on-brand-base: var(--smoke-light-alpha-11);
|
||||
--icon-on-brand-hover: var(--smoke-light-alpha-12);
|
||||
--icon-on-brand-selected: var(--smoke-light-alpha-12);
|
||||
--icon-on-interactive-base: var(--smoke-light-alpha-9);
|
||||
--icon-on-interactive-hover: var(--smoke-light-alpha-10);
|
||||
--icon-on-interactive-selected: var(--smoke-light-alpha-11);
|
||||
--icon-on-interactive-base: var(--smoke-light-1);
|
||||
--icon-agent-plan-base: var(--purple-light-9);
|
||||
--icon-agent-docs-base: var(--amber-light-9);
|
||||
--icon-agent-ask-base: var(--cyan-light-9);
|
||||
--icon-agent-build-base: var(--blue-light-9);
|
||||
--icon-agent-build-base: var(--cobalt-light-9);
|
||||
--icon-on-success-base: var(--apple-light-alpha-9);
|
||||
--icon-on-success-hover: var(--apple-light-alpha-10);
|
||||
--icon-on-success-selected: var(--apple-light-alpha-11);
|
||||
@@ -183,32 +187,38 @@
|
||||
--icon-diff-delete-base: var(--ember-light-9);
|
||||
--icon-diff-delete-hover: var(--ember-light-10);
|
||||
--icon-diff-delete-active: var(--ember-light-11);
|
||||
--syntax-comment: #ffffff;
|
||||
--syntax-string: #ffffff;
|
||||
--syntax-keyword: #ffffff;
|
||||
--syntax-function: #ffffff;
|
||||
--syntax-number: #ffffff;
|
||||
--syntax-operator: #ffffff;
|
||||
--syntax-variable: #ffffff;
|
||||
--syntax-type: #ffffff;
|
||||
--syntax-constant: #ffffff;
|
||||
--syntax-punctuation: #ffffff;
|
||||
--syntax-success: #ffffff;
|
||||
--syntax-warning: #ffffff;
|
||||
--syntax-critical: #ffffff;
|
||||
--syntax-info: #ffffff;
|
||||
--markdown-heading: #ffffff;
|
||||
--markdown-text: #ffffff;
|
||||
--markdown-link: #ffffff;
|
||||
--markdown-link-text: #ffffff;
|
||||
--markdown-code: #ffffff;
|
||||
--markdown-block-quote: #ffffff;
|
||||
--markdown-emph: #ffffff;
|
||||
--markdown-strong: #ffffff;
|
||||
--markdown-horizontal-rule: #ffffff;
|
||||
--markdown-list-item: #ffffff;
|
||||
--markdown-list-enumeration: #ffffff;
|
||||
--markdown-image: #ffffff;
|
||||
--markdown-image-text: #ffffff;
|
||||
--markdown-code-block: #ffffff;
|
||||
--border-color: #ffffff;
|
||||
--syntax-comment: #8A8A8A;
|
||||
--syntax-string: #D68C27;
|
||||
--syntax-keyword: #3B7DD8;
|
||||
--syntax-function: #D1383D;
|
||||
--syntax-number: #3D9A57;
|
||||
--syntax-operator: #D68C27;
|
||||
--syntax-variable: #B0851F;
|
||||
--syntax-type: #318795;
|
||||
--syntax-constant: #953170;
|
||||
--syntax-punctuation: #1A1A1A;
|
||||
--syntax-success: var(--apple-dark-10);
|
||||
--syntax-warning: var(--amber-light-10);
|
||||
--syntax-critical: var(--ember-dark-9);
|
||||
--syntax-info: var(--lilac-dark-11);
|
||||
--markdown-heading: #D68C27;
|
||||
--markdown-text: #1A1A1A;
|
||||
--markdown-link: #3B7DD8;
|
||||
--markdown-link-text: #318795;
|
||||
--markdown-code: #3D9A57;
|
||||
--markdown-block-quote: #B0851F;
|
||||
--markdown-emph: #B0851F;
|
||||
--markdown-strong: #D68C27;
|
||||
--markdown-horizontal-rule: #8A8A8A;
|
||||
--markdown-list-item: #3B7DD8;
|
||||
--markdown-list-enumeration: #318795;
|
||||
--markdown-image: #3B7DD8;
|
||||
--markdown-image-text: #318795;
|
||||
--markdown-code-block: #1A1A1A;
|
||||
--border-color: #FFFFFF;
|
||||
--border-weaker-base: var(--smoke-light-alpha-3);
|
||||
--border-weaker-hover: var(--smoke-light-alpha-4);
|
||||
--border-weaker-active: var(--smoke-light-alpha-6);
|
||||
--border-weaker-selected: var(--cobalt-light-alpha-4);
|
||||
--border-weaker-disabled: var(--smoke-light-alpha-2);
|
||||
--border-weaker-focus: var(--smoke-light-alpha-6);
|
||||
|
||||
@@ -1,23 +1,55 @@
|
||||
[data-component="collapsible"] {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--surface-inset-base);
|
||||
border: 1px solid var(--border-weaker-base);
|
||||
transition: background-color 0.15s ease;
|
||||
border-radius: 8px;
|
||||
overflow: clip;
|
||||
|
||||
[data-slot="trigger"] {
|
||||
cursor: pointer;
|
||||
[data-slot="collapsible-trigger"] {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
padding: 6px 8px 6px 12px;
|
||||
align-items: center;
|
||||
align-self: stretch;
|
||||
cursor: default;
|
||||
user-select: none;
|
||||
color: var(--text-base);
|
||||
|
||||
/* text-12-medium */
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: var(--font-size-small);
|
||||
font-style: normal;
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: var(--line-height-large); /* 166.667% */
|
||||
letter-spacing: var(--letter-spacing-normal);
|
||||
|
||||
/* &:hover { */
|
||||
/* background-color: var(--surface-base); */
|
||||
/* } */
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--border-focus);
|
||||
outline-offset: 2px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
[data-slot="collapsible-arrow"] {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
/* [data-slot="collapsible-arrow-icon"] { */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="content"] {
|
||||
[data-slot="collapsible-content"] {
|
||||
overflow: hidden;
|
||||
/* animation: slideUp 250ms ease-out; */
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Collapsible as Kobalte, CollapsibleRootProps } from "@kobalte/core/collapsible"
|
||||
import { ComponentProps, ParentProps, splitProps } from "solid-js"
|
||||
import { Icon } from "./icon"
|
||||
|
||||
export interface CollapsibleProps extends ParentProps<CollapsibleRootProps> {
|
||||
class?: string
|
||||
@@ -21,14 +22,23 @@ function CollapsibleRoot(props: CollapsibleProps) {
|
||||
}
|
||||
|
||||
function CollapsibleTrigger(props: ComponentProps<typeof Kobalte.Trigger>) {
|
||||
return <Kobalte.Trigger data-slot="trigger" {...props} />
|
||||
return <Kobalte.Trigger data-slot="collapsible-trigger" {...props} />
|
||||
}
|
||||
|
||||
function CollapsibleContent(props: ComponentProps<typeof Kobalte.Content>) {
|
||||
return <Kobalte.Content data-slot="content" {...props} />
|
||||
return <Kobalte.Content data-slot="collapsible-content" {...props} />
|
||||
}
|
||||
|
||||
function CollapsibleArrow(props?: ComponentProps<"div">) {
|
||||
return (
|
||||
<div data-slot="collapsible-arrow" {...(props || {})}>
|
||||
<Icon data-slot="collapsible-arrow-icon" name="chevron-grabber-vertical" size="small" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const Collapsible = Object.assign(CollapsibleRoot, {
|
||||
Arrow: CollapsibleArrow,
|
||||
Trigger: CollapsibleTrigger,
|
||||
Content: CollapsibleContent,
|
||||
})
|
||||
|
||||
@@ -139,6 +139,16 @@ const newIcons = {
|
||||
folder: `<path d="M2.08301 2.91675V16.2501H17.9163V5.41675H9.99967L8.33301 2.91675H2.08301Z" stroke="currentColor" stroke-linecap="round"/>`,
|
||||
"pencil-line": `<path d="M9.58301 17.9166H17.9163M17.9163 5.83325L14.1663 2.08325L2.08301 14.1666V17.9166H5.83301L17.9163 5.83325Z" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
"chevron-grabber-vertical": `<path d="M6.66675 12.4998L10.0001 15.8332L13.3334 12.4998M6.66675 7.49984L10.0001 4.1665L13.3334 7.49984" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
mcp: `<g><path d="M0.972656 9.37176L9.5214 1.60019C10.7018 0.527151 12.6155 0.527151 13.7957 1.60019C14.9761 2.67321 14.9761 4.41295 13.7957 5.48599L7.3397 11.3552" stroke="currentColor" stroke-linecap="round"/><path d="M7.42871 11.2747L13.7957 5.48643C14.9761 4.41338 16.8898 4.41338 18.0702 5.48643L18.1147 5.52688C19.2951 6.59993 19.2951 8.33966 18.1147 9.4127L10.3831 16.4414C9.98966 16.7991 9.98966 17.379 10.3831 17.7366L11.9707 19.1799" stroke="currentColor" stroke-linecap="round"/><path d="M11.6587 3.54346L5.33619 9.29119C4.15584 10.3642 4.15584 12.1039 5.33619 13.177C6.51649 14.25 8.43019 14.25 9.61054 13.177L15.9331 7.42923" stroke="currentColor" stroke-linecap="round"/></g>`,
|
||||
glasses: `<path d="M0.416626 7.91667H1.66663M19.5833 7.91667H18.3333M11.866 7.57987C11.3165 7.26398 10.6793 7.08333 9.99996 7.08333C9.32061 7.08333 8.68344 7.26398 8.13389 7.57987M8.74996 10C8.74996 12.0711 7.07103 13.75 4.99996 13.75C2.92889 13.75 1.24996 12.0711 1.24996 10C1.24996 7.92893 2.92889 6.25 4.99996 6.25C7.07103 6.25 8.74996 7.92893 8.74996 10ZM18.75 10C18.75 12.0711 17.071 13.75 15 13.75C12.9289 13.75 11.25 12.0711 11.25 10C11.25 7.92893 12.9289 6.25 15 6.25C17.071 6.25 18.75 7.92893 18.75 10Z" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
"bullet-list": `<path d="M9.58329 13.7497H17.0833M9.58329 6.24967H17.0833M6.24996 6.24967C6.24996 7.17015 5.50377 7.91634 4.58329 7.91634C3.66282 7.91634 2.91663 7.17015 2.91663 6.24967C2.91663 5.3292 3.66282 4.58301 4.58329 4.58301C5.50377 4.58301 6.24996 5.3292 6.24996 6.24967ZM6.24996 13.7497C6.24996 14.6701 5.50377 15.4163 4.58329 15.4163C3.66282 15.4163 2.91663 14.6701 2.91663 13.7497C2.91663 12.8292 3.66282 12.083 4.58329 12.083C5.50377 12.083 6.24996 12.8292 6.24996 13.7497Z" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
"magnifying-glass-menu": `<path d="M2.08325 10.0002H4.58325M2.08325 5.41683H5.41659M2.08325 14.5835H5.41659M16.4583 13.9585L18.7499 16.2502M17.9166 10.0002C17.9166 12.9917 15.4915 15.4168 12.4999 15.4168C9.50838 15.4168 7.08325 12.9917 7.08325 10.0002C7.08325 7.00862 9.50838 4.5835 12.4999 4.5835C15.4915 4.5835 17.9166 7.00862 17.9166 10.0002Z" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
"window-cursor": `<path d="M17.9166 10.4167V3.75H2.08325V17.0833H10.4166M17.9166 13.5897L11.6666 11.6667L13.5897 17.9167L15.032 15.0321L17.9166 13.5897Z" stroke="currentColor" stroke-width="1.07143" stroke-linecap="square"/><path d="M5.00024 6.125C5.29925 6.12518 5.54126 6.36795 5.54126 6.66699C5.54108 6.96589 5.29914 7.20783 5.00024 7.20801C4.7012 7.20801 4.45843 6.966 4.45825 6.66699C4.45825 6.36784 4.70109 6.125 5.00024 6.125ZM7.91626 6.125C8.21541 6.125 8.45825 6.36784 8.45825 6.66699C8.45808 6.966 8.21531 7.20801 7.91626 7.20801C7.61736 7.20783 7.37542 6.96589 7.37524 6.66699C7.37524 6.36795 7.61726 6.12518 7.91626 6.125ZM10.8333 6.125C11.1324 6.125 11.3752 6.36784 11.3752 6.66699C11.3751 6.966 11.1323 7.20801 10.8333 7.20801C10.5342 7.20801 10.2914 6.966 10.2913 6.66699C10.2913 6.36784 10.5341 6.125 10.8333 6.125Z" fill="currentColor" stroke="currentColor" stroke-width="0.25" stroke-linecap="square"/>`,
|
||||
task: `<path d="M9.99992 2.0835V17.9168M7.08325 3.75016H2.08325V16.2502H7.08325M12.9166 16.2502H17.9166V3.75016H12.9166" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
checklist: `<path d="M9.58342 13.7498H17.0834M9.58342 6.24984H17.0834M2.91675 6.6665L4.58341 7.9165L7.08341 4.1665M2.91675 14.1665L4.58341 15.4165L7.08341 11.6665" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
console: `<path d="M3.75 5.4165L8.33333 9.99984L3.75 14.5832M10.4167 14.5832H16.25" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
"code-lines": `<path d="M2.08325 3.75H11.2499M14.5833 3.75H17.9166M2.08325 10L7.08325 10M10.4166 10L17.9166 10M2.08325 16.25L8.74992 16.25M12.0833 16.25L17.9166 16.25" stroke="currentColor" stroke-linecap="square" stroke-linejoin="round"/>`,
|
||||
"square-arrow-top-right": `<path d="M7.91675 2.9165H2.91675V17.0832H17.0834V12.0832M12.0834 2.9165H17.0834V7.9165M9.58342 10.4165L16.6667 3.33317" stroke="currentColor" stroke-linecap="square"/>`,
|
||||
}
|
||||
|
||||
export interface IconProps extends ComponentProps<"svg"> {
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
--color-background-stronger: var(--background-stronger);
|
||||
--color-base: var(--base);
|
||||
--color-surface-base: var(--surface-base);
|
||||
--color-surface-base-hover: var(--surface-base-hover);
|
||||
--color-surface-base-active: var(--surface-base-active);
|
||||
--color-surface-base-interactive-active: var(--surface-base-interactive-active);
|
||||
--color-base2: var(--base2);
|
||||
--color-base3: var(--base3);
|
||||
--color-surface-inset-base: var(--surface-inset-base);
|
||||
@@ -45,9 +48,9 @@
|
||||
--color-surface-info-base: var(--surface-info-base);
|
||||
--color-surface-info-weak: var(--surface-info-weak);
|
||||
--color-surface-info-strong: var(--surface-info-strong);
|
||||
--color-surface-diff-hidden-base: var(--surface-diff-hidden-base);
|
||||
--color-surface-diff-skip-base: var(--surface-diff-skip-base);
|
||||
--color-surface-diff-unchanged-base: var(--surface-diff-unchanged-base);
|
||||
--color-surface-diff-hidden-base: var(--surface-diff-hidden-base);
|
||||
--color-surface-diff-hidden-weak: var(--surface-diff-hidden-weak);
|
||||
--color-surface-diff-hidden-weaker: var(--surface-diff-hidden-weaker);
|
||||
--color-surface-diff-hidden-strong: var(--surface-diff-hidden-strong);
|
||||
@@ -72,8 +75,10 @@
|
||||
--color-text-weak: var(--text-weak);
|
||||
--color-text-weaker: var(--text-weaker);
|
||||
--color-text-strong: var(--text-strong);
|
||||
--color-text-interactive-base: var(--text-interactive-base);
|
||||
--color-text-on-brand-base: var(--text-on-brand-base);
|
||||
--color-text-on-interactive-base: var(--text-on-interactive-base);
|
||||
--color-text-on-interactive-weak: var(--text-on-interactive-weak);
|
||||
--color-text-on-success-base: var(--text-on-success-base);
|
||||
--color-text-on-warning-base: var(--text-on-warning-base);
|
||||
--color-text-on-info-base: var(--text-on-info-base);
|
||||
@@ -91,6 +96,7 @@
|
||||
--color-text-on-brand-weaker: var(--text-on-brand-weaker);
|
||||
--color-text-on-brand-strong: var(--text-on-brand-strong);
|
||||
--color-button-secondary-base: var(--button-secondary-base);
|
||||
--color-button-secondary-base-hover: var(--button-secondary-base-hover);
|
||||
--color-border-base: var(--border-base);
|
||||
--color-border-hover: var(--border-hover);
|
||||
--color-border-active: var(--border-active);
|
||||
@@ -164,8 +170,6 @@
|
||||
--color-icon-on-brand-hover: var(--icon-on-brand-hover);
|
||||
--color-icon-on-brand-selected: var(--icon-on-brand-selected);
|
||||
--color-icon-on-interactive-base: var(--icon-on-interactive-base);
|
||||
--color-icon-on-interactive-hover: var(--icon-on-interactive-hover);
|
||||
--color-icon-on-interactive-selected: var(--icon-on-interactive-selected);
|
||||
--color-icon-agent-plan-base: var(--icon-agent-plan-base);
|
||||
--color-icon-agent-docs-base: var(--icon-agent-docs-base);
|
||||
--color-icon-agent-ask-base: var(--icon-agent-ask-base);
|
||||
@@ -217,4 +221,10 @@
|
||||
--color-markdown-image-text: var(--markdown-image-text);
|
||||
--color-markdown-code-block: var(--markdown-code-block);
|
||||
--color-border-color: var(--border-color);
|
||||
--color-border-weaker-base: var(--border-weaker-base);
|
||||
--color-border-weaker-hover: var(--border-weaker-hover);
|
||||
--color-border-weaker-active: var(--border-weaker-active);
|
||||
--color-border-weaker-selected: var(--border-weaker-selected);
|
||||
--color-border-weaker-disabled: var(--border-weaker-disabled);
|
||||
--color-border-weaker-focus: var(--border-weaker-focus);
|
||||
}
|
||||
@@ -66,11 +66,14 @@
|
||||
--background-weak: var(--smoke-light-3);
|
||||
--background-strong: var(--smoke-light-1);
|
||||
--background-stronger: #fcfcfc;
|
||||
--surface-base: var(--smoke-light-alpha-2);
|
||||
--base: var(--smoke-light-alpha-2);
|
||||
--surface-base: var(--smoke-light-alpha-2);
|
||||
--surface-base-hover: #0500000f;
|
||||
--surface-base-active: var(--smoke-light-alpha-3);
|
||||
--surface-base-interactive-active: var(--cobalt-light-alpha-3);
|
||||
--base2: var(--smoke-light-alpha-2);
|
||||
--base3: var(--smoke-light-alpha-2);
|
||||
--surface-inset-base: var(--smoke-light-alpha-3);
|
||||
--surface-inset-base: var(--smoke-light-alpha-2);
|
||||
--surface-inset-base-hover: var(--smoke-light-alpha-3);
|
||||
--surface-inset-strong: #1f000017;
|
||||
--surface-inset-strong-hover: #1f000017;
|
||||
@@ -105,7 +108,7 @@
|
||||
--surface-info-weak: var(--lilac-light-2);
|
||||
--surface-info-strong: var(--lilac-light-9);
|
||||
--surface-diff-hidden-base: var(--blue-light-3);
|
||||
--surface-diff-skip-base: var(--smoke-light-3);
|
||||
--surface-diff-skip-base: var(--smoke-light-2);
|
||||
--surface-diff-unchanged-base: #ffffff00;
|
||||
--surface-diff-hidden-weak: var(--blue-light-2);
|
||||
--surface-diff-hidden-weaker: var(--blue-light-1);
|
||||
@@ -131,6 +134,7 @@
|
||||
--text-weak: var(--smoke-light-9);
|
||||
--text-weaker: var(--smoke-light-8);
|
||||
--text-strong: var(--smoke-light-12);
|
||||
--text-interactive-base: var(--cobalt-light-9);
|
||||
--text-on-brand-base: var(--smoke-light-alpha-11);
|
||||
--text-on-interactive-base: var(--smoke-light-1);
|
||||
--text-on-interactive-weak: var(--smoke-dark-alpha-11);
|
||||
@@ -151,7 +155,7 @@
|
||||
--text-on-brand-weaker: var(--smoke-light-alpha-8);
|
||||
--text-on-brand-strong: var(--smoke-light-alpha-12);
|
||||
--button-secondary-base: #fdfcfc;
|
||||
--button-secondary-base-hover: var(--smoke-light-2);
|
||||
--button-secondary-base-hover: #faf9f9;
|
||||
--border-base: var(--smoke-light-alpha-7);
|
||||
--border-hover: var(--smoke-light-alpha-8);
|
||||
--border-active: var(--smoke-light-alpha-9);
|
||||
@@ -167,7 +171,7 @@
|
||||
--border-strong-focus: var(--smoke-light-alpha-7);
|
||||
--border-weak-hover: var(--smoke-light-alpha-6);
|
||||
--border-weak-active: var(--smoke-light-alpha-7);
|
||||
--border-weak-selected: var(--cobalt-light-alpha-4);
|
||||
--border-weak-selected: var(--cobalt-light-alpha-5);
|
||||
--border-weak-disabled: var(--smoke-light-alpha-6);
|
||||
--border-weak-focus: var(--smoke-light-alpha-7);
|
||||
--border-interactive-base: var(--cobalt-light-7);
|
||||
@@ -228,7 +232,7 @@
|
||||
--icon-agent-plan-base: var(--purple-light-9);
|
||||
--icon-agent-docs-base: var(--amber-light-9);
|
||||
--icon-agent-ask-base: var(--cyan-light-9);
|
||||
--icon-agent-build-base: var(--blue-light-9);
|
||||
--icon-agent-build-base: var(--cobalt-light-9);
|
||||
--icon-on-success-base: var(--apple-light-alpha-9);
|
||||
--icon-on-success-hover: var(--apple-light-alpha-10);
|
||||
--icon-on-success-selected: var(--apple-light-alpha-11);
|
||||
@@ -276,6 +280,12 @@
|
||||
--markdown-image-text: #318795;
|
||||
--markdown-code-block: #1a1a1a;
|
||||
--border-color: #ffffff;
|
||||
--border-weaker-base: var(--smoke-light-alpha-3);
|
||||
--border-weaker-hover: var(--smoke-light-alpha-4);
|
||||
--border-weaker-active: var(--smoke-light-alpha-6);
|
||||
--border-weaker-selected: var(--cobalt-light-alpha-4);
|
||||
--border-weaker-disabled: var(--smoke-light-alpha-2);
|
||||
--border-weaker-focus: var(--smoke-light-alpha-6);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
/* OC-1-Dark */
|
||||
@@ -284,8 +294,11 @@
|
||||
--background-weak: #201d1d;
|
||||
--background-strong: #151313;
|
||||
--background-stronger: #201c1c;
|
||||
--surface-base: var(--smoke-dark-alpha-3);
|
||||
--base: var(--smoke-dark-alpha-2);
|
||||
--surface-base: var(--smoke-dark-alpha-2);
|
||||
--surface-base-hover: #e0b7b716;
|
||||
--surface-base-active: var(--smoke-dark-alpha-3);
|
||||
--surface-base-interactive-active: var(--cobalt-dark-alpha-2);
|
||||
--base2: var(--smoke-dark-alpha-2);
|
||||
--base3: var(--smoke-dark-alpha-2);
|
||||
--surface-inset-base: #0e0b0b7f;
|
||||
@@ -300,8 +313,8 @@
|
||||
--surface-raised-strong-hover: var(--smoke-dark-alpha-6);
|
||||
--surface-raised-stronger: var(--smoke-dark-alpha-6);
|
||||
--surface-raised-stronger-hover: var(--smoke-dark-alpha-7);
|
||||
--surface-weak: var(--smoke-dark-alpha-5);
|
||||
--surface-weaker: var(--smoke-dark-alpha-6);
|
||||
--surface-weak: var(--smoke-dark-alpha-4);
|
||||
--surface-weaker: var(--smoke-dark-alpha-5);
|
||||
--surface-strong: var(--smoke-dark-alpha-7);
|
||||
--surface-raised-stronger-non-alpha: var(--smoke-dark-4);
|
||||
--surface-brand-base: var(--yuzu-light-9);
|
||||
@@ -323,7 +336,7 @@
|
||||
--surface-info-weak: var(--lilac-light-2);
|
||||
--surface-info-strong: var(--lilac-light-9);
|
||||
--surface-diff-hidden-base: var(--blue-dark-2);
|
||||
--surface-diff-skip-base: var(--smoke-dark-alpha-2);
|
||||
--surface-diff-skip-base: var(--smoke-dark-alpha-1);
|
||||
--surface-diff-unchanged-base: var(--smoke-dark-1);
|
||||
--surface-diff-hidden-weak: var(--blue-dark-1);
|
||||
--surface-diff-hidden-weaker: var(--blue-dark-3);
|
||||
@@ -349,6 +362,7 @@
|
||||
--text-weak: var(--smoke-dark-alpha-9);
|
||||
--text-weaker: var(--smoke-dark-alpha-8);
|
||||
--text-strong: var(--smoke-dark-alpha-12);
|
||||
--text-interactive-base: var(--cobalt-dark-11);
|
||||
--text-on-brand-base: var(--smoke-dark-alpha-11);
|
||||
--text-on-interactive-base: var(--smoke-dark-12);
|
||||
--text-on-interactive-weak: var(--smoke-dark-alpha-11);
|
||||
@@ -368,12 +382,12 @@
|
||||
--text-on-brand-weak: var(--smoke-dark-alpha-9);
|
||||
--text-on-brand-weaker: var(--smoke-dark-alpha-8);
|
||||
--text-on-brand-strong: var(--smoke-dark-alpha-12);
|
||||
--button-secondary-base: var(--smoke-dark-6);
|
||||
--button-secondary-base-hover: var(--smoke-dark-5);
|
||||
--button-secondary-base: var(--smoke-dark-4);
|
||||
--button-secondary-base-hover: #2a2727;
|
||||
--border-base: var(--smoke-dark-alpha-7);
|
||||
--border-hover: var(--smoke-dark-alpha-8);
|
||||
--border-active: var(--smoke-dark-alpha-9);
|
||||
--border-selected: var(--cobalt-dark-alpha-9);
|
||||
--border-selected: var(--cobalt-dark-alpha-11);
|
||||
--border-disabled: var(--smoke-dark-alpha-8);
|
||||
--border-focus: var(--smoke-dark-alpha-9);
|
||||
--border-weak-base: var(--smoke-dark-alpha-6);
|
||||
@@ -385,7 +399,7 @@
|
||||
--border-strong-focus: var(--smoke-dark-alpha-8);
|
||||
--border-weak-hover: var(--smoke-dark-alpha-7);
|
||||
--border-weak-active: var(--smoke-dark-alpha-8);
|
||||
--border-weak-selected: var(--cobalt-dark-alpha-3);
|
||||
--border-weak-selected: var(--cobalt-dark-alpha-6);
|
||||
--border-weak-disabled: var(--smoke-dark-alpha-6);
|
||||
--border-weak-focus: var(--smoke-dark-alpha-8);
|
||||
--border-interactive-base: var(--cobalt-light-7);
|
||||
@@ -446,7 +460,7 @@
|
||||
--icon-agent-plan-base: var(--purple-dark-9);
|
||||
--icon-agent-docs-base: var(--amber-dark-9);
|
||||
--icon-agent-ask-base: var(--cyan-dark-9);
|
||||
--icon-agent-build-base: var(--blue-dark-9);
|
||||
--icon-agent-build-base: var(--cobalt-dark-11);
|
||||
--icon-on-success-base: var(--apple-dark-alpha-9);
|
||||
--icon-on-success-hover: var(--apple-dark-alpha-10);
|
||||
--icon-on-success-selected: var(--apple-dark-alpha-11);
|
||||
@@ -494,5 +508,11 @@
|
||||
--markdown-image-text: #56b6c2;
|
||||
--markdown-code-block: #eeeeee;
|
||||
--border-color: #ffffff;
|
||||
--border-weaker-base: var(--smoke-dark-alpha-3);
|
||||
--border-weaker-hover: var(--smoke-dark-alpha-4);
|
||||
--border-weaker-active: var(--smoke-dark-alpha-6);
|
||||
--border-weaker-selected: var(--cobalt-dark-alpha-3);
|
||||
--border-weaker-disabled: var(--smoke-dark-alpha-2);
|
||||
--border-weaker-focus: var(--smoke-dark-alpha-6);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user