diff --git a/.claude/launch.json b/.claude/launch.json index 91e9a66..a94c249 100644 --- a/.claude/launch.json +++ b/.claude/launch.json @@ -3,8 +3,8 @@ "configurations": [ { "name": "web", - "runtimeExecutable": "npm", - "runtimeArgs": ["--prefix", "web", "run", "dev"], + "runtimeExecutable": "sh", + "runtimeArgs": ["-c", "export OIKOS_API_TOKEN=$(docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' oikos-api-1 | sed -n 's/^OIKOS_MCP_BEARER_TOKEN=//p'); exec npm --prefix web run dev"], "port": 5173 } ] diff --git a/web/index.html b/web/index.html index 4a9e955..6d405e6 100644 --- a/web/index.html +++ b/web/index.html @@ -6,7 +6,7 @@ Oikos - + diff --git a/web/src/App.svelte b/web/src/App.svelte index 72cd298..3836591 100644 --- a/web/src/App.svelte +++ b/web/src/App.svelte @@ -10,15 +10,14 @@ import Config from './pages/Config.svelte' import { newChat } from '$lib/stores/chat' import { summary, subscribeContext, openSignalCount } from '$lib/stores/context' - import { connectionState } from '$lib/stores/events' import { currentTask } from '$lib/stores/workspace' import { isConfigured } from '$lib/config' + import { truncateMiddle } from '$lib/utils' import { onMount } from 'svelte' import { processPendingCallback, initOIDC } from '$lib/oidc' import * as Sidebar from '$lib/components/ui/sidebar' import * as Sheet from '$lib/components/ui/sheet' import { Button } from '$lib/components/ui/button' - import { Badge } from '$lib/components/ui/badge' import { Separator } from '$lib/components/ui/separator' import { VERSION } from '$lib/version' import { Toaster } from '$lib/components/ui/sonner' @@ -206,37 +205,15 @@ {#if page === 'chat'} - - / - - {$currentTask?.goal ? $currentTask.goal.replace(/[*_`~#]|\[.*?\]\(.*?\)/g, '') : 'New Task'} + {@const goalText = $currentTask?.goal ? $currentTask.goal.replace(/[*_`~#]|\[.*?\]\(.*?\)/g, '') : 'New Task'} + + / + + {truncateMiddle(goalText, 100)} {:else} {page === 'entity' ? routeParam : page === 'kb' ? 'Knowledge Base' : page === 'overview' ? 'Tasks' : page} {/if} -
- {#if $summary} - - {#if approvalsPending} - - {/if} - {#if openSignals} - - {/if} - {/if} - -
{#if page === 'overview'} diff --git a/web/src/app.css b/web/src/app.css index 0e26fab..0c5eb9b 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -4,7 +4,7 @@ @theme inline { --font-sans: 'DM Sans', system-ui, sans-serif; - --font-mono: 'DM Sans', system-ui, sans-serif; + --font-mono: 'DM Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace; --font-heading: 'Inknut Antiqua', Georgia, serif; --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); diff --git a/web/src/lib/components/ActivityTimeline.svelte b/web/src/lib/components/ActivityTimeline.svelte index 5827712..5c30449 100644 --- a/web/src/lib/components/ActivityTimeline.svelte +++ b/web/src/lib/components/ActivityTimeline.svelte @@ -1,9 +1,9 @@
{#if $activityLog.length === 0} -
-
-
-
-
-
-

Waiting for activity…

+
+ + + + + + + + + + + + + + + + +

Waiting for activity…

{:else}
{#each $activityLog as entry, i (entry.id)} {@const isLast = i === $activityLog.length - 1} - {@const hasDetail = !!entry.detail} {@const icon = typeIcon(entry.type)} + {@const isOpen = expanded.has(entry.id)} + {@const time = formatTime(entry.timestamp)}
{#if !isLast} @@ -66,39 +92,56 @@ {/if} - - {#if hasDetail && expanded.has(entry.id)} -
-
{entry.detail}
+ + {#if isOpen} +
+
+ {entry.status} + {#if time}{time}{/if} + {#if entry.toolName}{entry.toolName}{/if} +
+ {#if entry.args} +
+

Called with

+
{prettyPrint(entry.args)}
+
+ {/if} + {#if entry.detail} +
+ {#if entry.args}

{entry.status === 'failed' ? 'Error' : 'Result'}

{/if} +
{prettyPrint(entry.detail)}
+
+ {/if} + {#if !entry.args && !entry.detail} +

No further detail for this step.

+ {/if}
{/if}
diff --git a/web/src/lib/components/AgentIndicator.svelte b/web/src/lib/components/AgentIndicator.svelte index 6c15b9c..64b78de 100644 --- a/web/src/lib/components/AgentIndicator.svelte +++ b/web/src/lib/components/AgentIndicator.svelte @@ -1,6 +1,6 @@ -