@ai-ecoverse/slicc-spectrum 1.96.0 → 1.96.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -280,7 +280,7 @@ Under 480 px of column width the label takes a row of its own under the icons, w
280
280
  A cluster's label comes from the agent port's optional `toolLabel(agentId, callIds)`, asked once for each agent port, agent and set of runs; while a growing run waits for its new label, it keeps its last one, and without `toolLabel` the label is empty.
281
281
  A command's icon is the favicon of the site it names when an open browser tab already has a `data:` favicon for it (nothing is fetched; otherwise the globe), else the file browser's icon for the file it names, else the code icon; other tools show their kind's icon.
282
282
  A running run pulses (still, with a dashed ring, under `prefers-reduced-motion`), a done or cancelled one is grey and a failed one red, each with a corner glyph.
283
- The card (`.tool[data-tool][data-status][data-kind]`, a `details.run` under a pill and a `div[role=region]` named by its `title` and status under a strip) has no header of its own, no chevron, title, tool name or status: its input (a shell command after `$`), an edit's `diff` shown as a diff view, its output wrapped rather than cut off, an `image`, such as a screenshot, an optional `meta` such as a timeout, a standalone tool message's time ("Ran at 16:12", `.ran`, by the two-minute rule), and its `notes` (`{ severity, text }`, such as "Exited with code 5" or "Full output in /tmp/…") as lines under the output, `li[data-note][data-severity]`: `error` with an alert icon in the negative colour, `warn` with an alert icon and `info` with an info icon, both subdued; media galleries with images, video and audio; action cards for tools, pull requests and status; plans and checklists; inline diffs; question prompts (as decision cards, below); delegations; link previews; errors with a fix-it action, as a grey card (`.error-card[role=alert]`, `data-id` on system errors) inset by a wide margin on each side, a narrower one under 480 px: a red alert icon, the title in bold, the detail subdued and the action on the right, or under the detail below 360 px, announced as "Error: " and the title; an error with `action: 'login'` and an `account` (an `Account.id`) signs that account in: **Log in** calls `settings.connect(account)` synchronously in the click when the account is OAuth or needs no secret or fields, so a sign-in pop-up opens within the user gesture, and otherwise, or when `accounts()` doesn't have it, opens Settings at its row; the card follows the account's status from `accounts` (`data-login` is `idle`, `signing-in` or `connected`): while it is `signing-in` or `connect` is pending, **Log in** is pending and reads “Signing in…”, for an OAuth account the detail reads “Continue in the sign-in window that opened.” and, after `SliccChat.closedAfter` (20 s, since a closed window can't be detected), “Closed the sign-in window? Cancel, then Log in again.”, with **Cancel** (`data-action="cancel-login"`) when the port has `cancel`; once `connected`, the card is no longer an alert: a neutral info icon in the detail colour replaces the red one, the "Error: " prefix goes, the title reads “Signed in to {provider} again.” (the account's `provider`), the detail reads “Signed in. Retry to send it again.” (a polite status) and the button becomes **Retry**, which sends the last prompt again only when clicked; a rejected `connect` shows its message as negative help text (`[data-error=login]`), keeps **Log in** and adds a quiet **Open settings** (`data-action="settings"`) to that account; without an `account`, **Log in** opens Settings at Accounts, and watch-only and guest seats keep their gating; a content-filter stop offers **Drop the last turn**, which rewinds that turn and puts its prompt back into the composer; when the turns right before it failed too, the button reads **Drop N failed turns** and rewinds to before the first of them, putting the latest prompt back), system messages (error cards; compactions and notices, rewinds and model changes included, as full-width dividers with a line on each side, like the day: a compaction shows only its title, its `text` kept for screen readers, one that lost messages (`state: 'fallback'`, by default "Compaction failed, transcript truncated", or `discarded`, "Context discarded") an alert icon in the negative colour, and a notice its title and text on one line, `role="note"`; a divider that wraps keeps a short line on each side) and licks, SLICC's events into a cone, on every channel, on the right (`.lick-turn`): a byline with the title and the time by the two-minute rule, then a dashed box (`.lick[data-id][data-channel]`) with the text and the count (×3); emoji pills on its bottom edge (`.reactions .reaction`, `aria-hidden`, each named by its `title`) give the channel (⏰ Schedule, 🪝 Webhook, ✨ Sprinkle, …) and the outcome (👍 Allowed, 👎 Denied, also said in the box's hidden text).
283
+ The card (`.tool[data-tool][data-status][data-kind]`, a `details.run` under a pill and a `div[role=region]` named by its `title` and status under a strip) has no header of its own, no chevron, title, tool name or status: its input (a shell command after `$`), an edit's `diff` shown as a diff view, its output wrapped rather than cut off, with its ANSI styles shown (bold, dim, italic, underline, inverse, and the 16, 256 and truecolor foregrounds and backgrounds; the 16 foregrounds come from `--slicc-terminal-color-0` to `-15` when an embedder sets them, else the terminal panel's light tokens, which adapt in dark (so a card in dark uses Spectrum's colors, not the panel's VS Code ones); the 16 backgrounds are Spectrum's subtle tints under the default text, black a solid grey under the lightest grey, so text keeps 4.5:1; a 256 or truecolor background gets black or white text by its luminance unless the program set a 256 or truecolor foreground too; 256 and truecolor foregrounds show as sent; dim subdues default text and turns a bright color into its normal one) and every other escape stripped, a partial escape at the end of streamed output waiting for the rest (the model still sees the raw bytes, and a copy gets the text without escapes), an `image`, such as a screenshot, an optional `meta` such as a timeout, a standalone tool message's time ("Ran at 16:12", `.ran`, by the two-minute rule), and its `notes` (`{ severity, text }`, such as "Exited with code 5" or "Full output in /tmp/…") as lines under the output, `li[data-note][data-severity]`: `error` with an alert icon in the negative colour, `warn` with an alert icon and `info` with an info icon, both subdued; media galleries with images, video and audio; action cards for tools, pull requests and status; plans and checklists; inline diffs; question prompts (as decision cards, below); delegations; link previews; errors with a fix-it action, as a grey card (`.error-card[role=alert]`, `data-id` on system errors) inset by a wide margin on each side, a narrower one under 480 px: a red alert icon, the title in bold, the detail subdued and the action on the right, or under the detail below 360 px, announced as "Error: " and the title; an error with `action: 'login'` and an `account` (an `Account.id`) signs that account in: **Log in** calls `settings.connect(account)` synchronously in the click when the account is OAuth or needs no secret or fields, so a sign-in pop-up opens within the user gesture, and otherwise, or when `accounts()` doesn't have it, opens Settings at its row; the card follows the account's status from `accounts` (`data-login` is `idle`, `signing-in` or `connected`): while it is `signing-in` or `connect` is pending, **Log in** is pending and reads “Signing in…”, for an OAuth account the detail reads “Continue in the sign-in window that opened.” and, after `SliccChat.closedAfter` (20 s, since a closed window can't be detected), “Closed the sign-in window? Cancel, then Log in again.”, with **Cancel** (`data-action="cancel-login"`) when the port has `cancel`; once `connected`, the card is no longer an alert: a neutral info icon in the detail colour replaces the red one, the "Error: " prefix goes, the title reads “Signed in to {provider} again.” (the account's `provider`), the detail reads “Signed in. Retry to send it again.” (a polite status) and the button becomes **Retry**, which sends the last prompt again only when clicked; a rejected `connect` shows its message as negative help text (`[data-error=login]`), keeps **Log in** and adds a quiet **Open settings** (`data-action="settings"`) to that account; without an `account`, **Log in** opens Settings at Accounts, and watch-only and guest seats keep their gating; a content-filter stop offers **Drop the last turn**, which rewinds that turn and puts its prompt back into the composer; when the turns right before it failed too, the button reads **Drop N failed turns** and rewinds to before the first of them, putting the latest prompt back), system messages (error cards; compactions and notices, rewinds and model changes included, as full-width dividers with a line on each side, like the day: a compaction shows only its title, its `text` kept for screen readers, one that lost messages (`state: 'fallback'`, by default "Compaction failed, transcript truncated", or `discarded`, "Context discarded") an alert icon in the negative colour, and a notice its title and text on one line, `role="note"`; a divider that wraps keeps a short line on each side) and licks, SLICC's events into a cone, on every channel, on the right (`.lick-turn`): a byline with the title and the time by the two-minute rule, then a dashed box (`.lick[data-id][data-channel]`) with the text and the count (×3); emoji pills on its bottom edge (`.reactions .reaction`, `aria-hidden`, each named by its `title`) give the channel (⏰ Schedule, 🪝 Webhook, ✨ Sprinkle, …) and the outcome (👍 Allowed, 👎 Denied, also said in the box's hidden text).
284
284
  A lick with a body is a `details.lick` whose head (`summary.lick-head`, with a quiet chevron that turns when open) toggles it with a click, <kbd>Enter</kbd> or <kbd>Space</kbd>; clicking the body doesn't close it.
285
285
  Open licks and open tool runs hold for every view of the chat on the same model, so a layout switch keeps them.
286
286
  A lick's `severity` (`warn` or `error`) adds an alert icon to its byline, a coloured edge to its box and a spoken prefix.
@@ -181,7 +181,7 @@ var toolShapes = [
181
181
  "bash",
182
182
  "Check the staging routes",
183
183
  "wrangler routes list --env staging",
184
- "ROUTE ZONE WORKER ENV\nforecast.harbor.example/v2/forecast/* harbor.example harbor-forecast-v2 staging\nerror: the route forecast.harbor.example/v2/units/* belongs to another account; ask its owner to release it first",
184
+ "\x1B[1mROUTE ZONE WORKER ENV\x1B[0m\nforecast.harbor.example/v2/forecast/* harbor.example \x1B[36mharbor-forecast-v2\x1B[0m \x1B[2mstaging\x1B[0m\n\x1B[33mwarning:\x1B[0m the zone \x1B[1mharbor.example\x1B[0m has \x1B[37m2\x1B[0m routes on an old plan\n\x1B[1;31merror:\x1B[0m the route forecast.harbor.example/v2/units/* belongs to another account; ask its owner to release it first",
185
185
  {
186
186
  status: "error",
187
187
  notes: [
@@ -1941,4 +1941,4 @@ export {
1941
1941
  dummySettingsKey,
1942
1942
  DummySettings
1943
1943
  };
1944
- //# sourceMappingURL=chunk-CVMI4FSY.js.map
1944
+ //# sourceMappingURL=chunk-YUDOYEMB.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/dummy/showcase.ts", "../src/dummy/fixtures.ts", "../src/dummy/providers.ts", "../src/dummy/clock.ts", "../src/dummy/settings.ts"],
4
+ "sourcesContent": ["import type { Agent, LickChannel, Message, ToolCall, UserMessage } from '../model/types.ts';\n\nconst start = Date.UTC(2026, 9, 4, 16, 0);\nconst at = (minutes: number) => start + minutes * 60_000;\n\nexport function picture(\n label: string,\n from: string,\n to: string,\n width = 640,\n height = 400\n): string {\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\"><defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"${from}\"/><stop offset=\"1\" stop-color=\"${to}\"/></linearGradient></defs><rect width=\"${width}\" height=\"${height}\" fill=\"url(#g)\"/><text x=\"50%\" y=\"50%\" font-family=\"sans-serif\" font-size=\"${Math.round(height / 9)}\" fill=\"#ffffff\" text-anchor=\"middle\" dominant-baseline=\"middle\">${label}</text></svg>`;\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n}\n\nexport function tone(seconds = 0.6, frequency = 440, rate = 8000): string {\n const samples = Math.round(seconds * rate);\n const bytes = new Uint8Array(44 + samples);\n const view = new DataView(bytes.buffer);\n const text = (offset: number, value: string) => {\n for (let i = 0; i < value.length; i++) bytes[offset + i] = value.charCodeAt(i);\n };\n text(0, 'RIFF');\n view.setUint32(4, 36 + samples, true);\n text(8, 'WAVEfmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n view.setUint16(22, 1, true);\n view.setUint32(24, rate, true);\n view.setUint32(28, rate, true);\n view.setUint16(32, 1, true);\n view.setUint16(34, 8, true);\n text(36, 'data');\n view.setUint32(40, samples, true);\n for (let i = 0; i < samples; i++) {\n const fade = Math.min(1, (samples - i) / (rate / 10));\n bytes[44 + i] = 128 + Math.round(60 * fade * Math.sin((2 * Math.PI * frequency * i) / rate));\n }\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return `data:audio/wav;base64,${btoa(binary)}`;\n}\n\nfunction tool(\n id: string,\n name: string,\n title: string,\n input: string,\n output: string,\n extra: Partial<ToolCall> = {}\n): ToolCall {\n return { id, name, title, input, output, status: 'done', paths: [], ...extra };\n}\n\nconst markdown = [\n '## The forecast API in one page',\n '',\n 'harbor answers `GET /forecast?city=\u2026` with the day\u2019s **high**, **low** and a *short summary*, and caches per city for an hour. ~~XML output~~ is gone.',\n '',\n '### How a request flows',\n '',\n '1. The worker parses the city.',\n '2. The cache answers if it has a fresh entry:',\n ' - same UTC day',\n ' - younger than one hour',\n '3. Otherwise the upstream call runs, with three retries.',\n '',\n '> Upstream is slow at the top of the hour. Retries back off at 250, 500 and 1000 ms.',\n '',\n '```ts',\n 'export async function forecast(city: string): Promise<Forecast> {',\n ' const cached = cache.get(city);',\n ' if (cached) return cached;',\n ' return cache.set(city, await retry(() => upstream(city)));',\n '}',\n '```',\n '',\n '| Route | Cache | Typical latency |',\n '| --- | --- | ---: |',\n '| `/forecast` | 1 hour, per city | 38 ms |',\n '| `/health` | none | 2 ms |',\n '| `/forecast` (miss) | \u2014 | 410 ms |',\n '',\n '- [x] TTL fix merged',\n '- [ ] Move the cache to KV',\n '',\n 'Details are in the [API reference](https://api.example.com/docs/v2/forecast). A long path that must wrap: `/workspace/harbor/node_modules/.cache/wrangler/state/v3/cache/miniflare-CacheObject/7c1f0e3b9a5d4e2f8b6a1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f.sqlite`.',\n].join('\\n');\n\nconst toolShapes: ToolCall[] = [\n tool('k-t1', 'bash', 'Count the routes', \"rg -c 'pathname ===' src\", 'src/index.ts:2'),\n tool(\n 'k-t2',\n 'read_file',\n 'Read the router',\n '/workspace/harbor/src/index.ts',\n \"import { forecast } from './routes/forecast.ts';\\n\u2026\",\n {\n paths: ['/workspace/harbor/src/index.ts'],\n }\n ),\n tool(\n 'k-t3',\n 'write_file',\n 'Create the KV binding notes',\n '/workspace/harbor/docs/kv.md',\n 'Wrote 18 lines',\n {\n paths: ['/workspace/harbor/docs/kv.md'],\n }\n ),\n tool(\n 'k-t4',\n 'edit_file',\n 'Rename the cache key',\n '/workspace/harbor/src/lib/cache.ts',\n 'No match for \"cityKey(\" in src/lib/cache.ts',\n {\n status: 'error',\n paths: ['/workspace/harbor/src/lib/cache.ts'],\n }\n ),\n tool(\n 'k-t5',\n 'grep',\n 'Find TODOs',\n 'TODO --glob \"src/**\"',\n 'src/routes/forecast.ts:14: TODO: cache negative results\\nsrc/lib/units.ts:3: TODO: round half to even'\n ),\n tool(\n 'k-t6',\n 'web_fetch',\n 'Fetch the API changelog',\n 'https://api.example.com/changelog.json',\n '{ \"latest\": \"2.4.1\", \"breaking\": false }'\n ),\n tool(\n 'k-t7',\n 'browser',\n 'Screenshot the preview',\n 'screenshot http://localhost:8787/',\n 'Captured 1280\u00D7800',\n {\n image: picture('localhost:8787', '#3b63fb', '#0a7a43', 640, 400),\n }\n ),\n tool(\n 'k-t8',\n 'scoop_scoop',\n 'Start a scoop for the docs',\n 'name: docs-pass\\ntask: Update the forecast page to Celsius',\n 'Scoop docs-pass is running'\n ),\n tool(\n 'k-t9',\n 'feed_scoop',\n 'Hand the screenshots to docs-pass',\n 'scoop_name: docs-pass\\nmessage: Use the new screenshots in /tmp/shots',\n 'Delivered'\n ),\n tool(\n 'k-t10',\n 'send_message',\n 'Tell quiet-otter the tests pass',\n 'to: quiet-otter\\nmessage: CI is green, merge when ready',\n 'Delivered'\n ),\n tool(\n 'k-t11',\n 'drop_scoop',\n 'Wrap up amber-heron',\n 'scoop_name: amber-heron',\n 'Dropped amber-heron; its notes are in /shared/notes'\n ),\n tool(\n 'k-t12',\n 'update_global_memory',\n 'Remember the cache rule',\n 'Cache keys are per city and per UTC day.',\n 'Memory updated (3 sections, 412 characters)'\n ),\n tool(\n 'k-mcp',\n 'mcp__docs__search',\n 'docs \u00B7 search',\n '{\\n \"query\": \"forecast units\"\\n}',\n '2 pages: /forecast, /units'\n ),\n tool('k-t13', 'bash', 'Deploy to staging', 'wrangler deploy --env staging', 'Stopped', {\n status: 'cancelled',\n }),\n tool('k-t14', 'bash', 'Watch the logs', 'wrangler tail --env staging', '', { status: 'running' }),\n tool(\n 'k-t16',\n 'bash',\n 'Check the staging routes',\n 'wrangler routes list --env staging',\n '\\x1b[1mROUTE ZONE WORKER ENV\\x1b[0m\\nforecast.harbor.example/v2/forecast/* harbor.example \\x1b[36mharbor-forecast-v2\\x1b[0m \\x1b[2mstaging\\x1b[0m\\n\\x1b[33mwarning:\\x1b[0m the zone \\x1b[1mharbor.example\\x1b[0m has \\x1b[37m2\\x1b[0m routes on an old plan\\n\\x1b[1;31merror:\\x1b[0m the route forecast.harbor.example/v2/units/* belongs to another account; ask its owner to release it first',\n {\n status: 'error',\n notes: [\n { severity: 'error', text: 'Exited with code 5' },\n {\n severity: 'warn',\n text: 'Output truncated: 12 lines and 1,840 bytes dropped from the start',\n },\n { severity: 'info', text: 'Full output in /tmp/pi-bash-7f3a.log' },\n ],\n }\n ),\n];\n\nconst licks: Array<[LickChannel, string, string, string | undefined, Partial<Message>]> = [\n [\n 'webhook',\n 'GitHub \u00B7 pull_request.opened',\n 'example/harbor#58 Add retries for upstream timeouts',\n '{\\n \"action\": \"opened\",\\n \"number\": 58,\\n \"repository\": { \"full_name\": \"example/harbor\" }\\n}',\n {},\n ],\n [\n 'cron',\n 'Every weekday 09:00',\n 'Morning summary for the harbor cone',\n undefined,\n { count: 3 } as Partial<Message>,\n ],\n [\n 'sprinkle',\n 'Release board',\n 'Button \u201CShip 1.9.0\u201D clicked',\n '{ \"button\": \"ship\", \"version\": \"1.9.0\" }',\n {},\n ],\n [\n 'fswatch',\n '/workspace/harbor/src',\n '2 files changed',\n 'modified /workspace/harbor/src/lib/cache.ts\\ncreated /workspace/harbor/src/lib/retry.ts',\n {},\n ],\n [\n 'session-reload',\n 'Session restored',\n 'The page reloaded; 4 cones resumed from storage',\n undefined,\n {},\n ],\n [\n 'navigate',\n 'api.example.com',\n 'A page offered a SLICC handoff: open the forecast docs',\n '{ \"verb\": \"open\", \"target\": \"https://api.example.com/docs/v2/forecast\" }',\n {},\n ],\n [\n 'discovery',\n 'api.example.com',\n 'Found an ai-catalog.json with 3 tools',\n 'https://api.example.com/.well-known/ai-catalog.json',\n {},\n ],\n ['upgrade', 'SLICC updated', '6.4.0 \u2192 6.5.0', undefined, {}],\n [\n 'workflow',\n 'release-notes',\n 'Step 2 of 4 finished: collect merged pull requests',\n undefined,\n {},\n ],\n ['bash', 'Job 3', 'npm run build exited with status 0 after 41 s', undefined, {}],\n ['jshd', 'collect.jsh', 'Script finished: 12 pull requests since v1.8.0', undefined, {}],\n ['preview', 'Preview bridge', 'Connected from localhost:8787', undefined, {}],\n [\n 'cherry',\n 'Host page',\n 'Event \u201Ccart-updated\u201D from shop.example.com',\n '{ \"items\": 3, \"total\": 42.5 }',\n {},\n ],\n ['scoop-notify', 'docs-pass', 'Finished: the forecast page now shows Celsius', undefined, {}],\n ['scoop-idle', 'amber-heron', 'Idle for 30 minutes', undefined, {}],\n ['scoop-wait', 'quiet-otter', 'The wait for CI resolved: all checks passed', undefined, {}],\n [\n 'sudo-request',\n 'docs-pass',\n 'Wants to push to example/harbor (branch docs/celsius)',\n 'git push origin docs/celsius',\n { state: 'pending', expiresAt: Date.now() + 10 * 60_000 } as Partial<Message>,\n ],\n [\n 'sudo-request',\n 'quiet-otter',\n 'Wants to read secrets: UPSTREAM_TOKEN',\n undefined,\n { state: 'confirmed' } as Partial<Message>,\n ],\n [\n 'sudo-request',\n 'amber-heron',\n 'Wants to run: rm -rf /workspace/harbor/node_modules',\n undefined,\n { state: 'dismissed' } as Partial<Message>,\n ],\n];\n\nconst attachmentsMessage: UserMessage = {\n id: 'k-u2',\n role: 'user',\n text: 'Here is the mockup, my notes and the old spec.',\n createdAt: at(4),\n attachments: [\n {\n id: 'k-a1',\n name: 'forecast-card.png',\n kind: 'image',\n mimeType: 'image/png',\n size: 48211,\n url: picture('Mockup', '#f5a623', '#d0021b', 480, 320),\n },\n {\n id: 'k-a2',\n name: 'notes.txt',\n kind: 'text',\n mimeType: 'text/plain',\n size: 214,\n text: 'Show \u00B0C first.\\nRound to whole degrees.\\nKeep the summary under 60 characters.',\n },\n {\n id: 'k-a3',\n name: 'spec-v1.pdf',\n kind: 'file',\n mimeType: 'application/pdf',\n size: 1_204_331,\n path: '/home/user/downloads/spec-v1.pdf',\n },\n {\n id: 'k-a4',\n name: 'UPSTREAM_TOKEN',\n kind: 'secret',\n mimeType: 'application/octet-stream',\n size: 0,\n },\n {\n id: 'k-a5',\n name: 'recording.mov',\n kind: 'file',\n mimeType: 'video/quicktime',\n size: 98_304_000,\n error: 'Too large: attachments are limited to 25 MB',\n },\n ],\n};\n\nexport const showcaseAgent: Agent = {\n id: 'cone-kitchen',\n name: 'kitchen-sink',\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: 'claude-opus-5-5',\n contextFill: 0.47,\n unread: 0,\n};\n\nfunction opening(): Message[] {\n return [\n {\n id: 'k-u1',\n role: 'user',\n text: 'Give me the full tour of harbor, everything you can show.',\n createdAt: at(0),\n },\n {\n id: 'k-m1',\n role: 'assistant',\n status: 'done',\n createdAt: at(1),\n model: 'claude-sonnet-5-5',\n usage: { input: 18_204, output: 912, cost: 0.31 },\n parts: [\n {\n type: 'thinking',\n text: 'Start with the shape of the API, then show the pieces one kind at a time.',\n },\n { type: 'text', text: markdown },\n ],\n },\n attachmentsMessage,\n {\n id: 'k-m2',\n role: 'assistant',\n status: 'done',\n createdAt: at(5),\n model: 'claude-sonnet-5-5',\n parts: [\n {\n type: 'text',\n text: 'Mockup, notes and spec received. The recording was too large to attach. Here are the current screens and the alert sound:',\n },\n {\n type: 'media',\n items: [\n {\n kind: 'image',\n src: picture('Forecast card', '#3b63fb', '#7a5af8'),\n alt: 'The forecast card in light mode',\n },\n {\n kind: 'image',\n src: picture('Dark card', '#1d1d1d', '#3b63fb'),\n alt: 'The forecast card in dark mode',\n },\n {\n kind: 'image',\n src: picture('Phone', '#0a7a43', '#12b886', 360, 640),\n alt: 'The forecast card on a phone',\n },\n {\n kind: 'video',\n src: '',\n poster: picture('\u25B6 Walkthrough', '#292929', '#717171'),\n alt: 'A walkthrough of the forecast page',\n },\n { kind: 'audio', src: tone(), alt: 'The storm alert sound' },\n ],\n },\n ],\n },\n { id: 'k-u3', role: 'user', text: 'Show me every tool you used.', createdAt: at(8) },\n {\n id: 'k-m3',\n role: 'assistant',\n status: 'done',\n createdAt: at(9),\n model: 'claude-sonnet-5-5',\n parts: [\n { type: 'text', text: 'Every tool from today\u2019s run, in order:' },\n ...toolShapes.map((call) => ({ type: 'tool' as const, tool: call })),\n ],\n },\n {\n id: 'k-tool1',\n role: 'tool',\n createdAt: at(12),\n tool: tool(\n 'k-t15',\n 'bash',\n 'You ran a command',\n 'git log --oneline -3',\n 'a1b2c3d fix: expire entries from the previous day\\ne4f5a6b feat: retry upstream timeouts\\n0c9d8e7 chore: update wrangler'\n ),\n },\n ];\n}\n\nfunction runs(): Message[] {\n return [\n {\n id: 'k-u6',\n role: 'user',\n text: 'Get the forecast docs ready for the Celsius release.',\n createdAt: at(13),\n },\n {\n id: 'k-m8',\n role: 'assistant',\n status: 'done',\n createdAt: at(13.1),\n model: 'claude-sonnet-5-5',\n parts: [\n { type: 'text', text: 'Checking what the docs and the API say today.' },\n ...[\n tool(\n 'k-r1',\n 'bash',\n 'Ask the API for Lisbon',\n 'curl -s https://api.example.com/v2/forecast?city=Lisbon',\n '{ \"city\": \"Lisbon\", \"high\": 71, \"low\": 58, \"unit\": \"F\" }'\n ),\n tool(\n 'k-r2',\n 'bash',\n 'Read the forecast page',\n 'cat /workspace/harbor/docs/forecast.md',\n '# Forecast\\n\\nTemperatures are in Fahrenheit.'\n ),\n tool('k-r3', 'bash', 'See what changed', 'git status --short', ' M src/lib/units.ts'),\n tool(\n 'k-r4',\n 'read_file',\n 'Read the units helper',\n '/workspace/harbor/src/lib/units.ts',\n 'export function toCelsius(f: number): number {\u2026}',\n { paths: ['/workspace/harbor/src/lib/units.ts'] }\n ),\n ].map((call) => ({ type: 'tool' as const, tool: call })),\n {\n type: 'text',\n text: 'The page still says Fahrenheit. Updating it, then building and testing.',\n },\n ...[\n tool(\n 'k-r5',\n 'edit_file',\n 'Switch the page to Celsius',\n '/workspace/harbor/docs/forecast.md',\n 'Edited 1 line',\n {\n paths: ['/workspace/harbor/docs/forecast.md'],\n diff: {\n before: '# Forecast\\n\\nTemperatures are in Fahrenheit.\\n',\n after: '# Forecast\\n\\nTemperatures are in Celsius.\\n',\n },\n }\n ),\n tool('k-r6', 'bash', 'Build the site', 'npm run build', 'Built 14 pages in 2.1s', {\n meta: 'timeout 120s',\n }),\n tool(\n 'k-r7',\n 'bash',\n 'Run the unit tests',\n 'npx vitest run src/lib/units.test.ts',\n 'FAIL src/lib/units.test.ts > rounds half to even\\nExpected 22, received 21',\n {\n status: 'error',\n notes: [{ severity: 'error', text: 'Exited with code 1' }],\n }\n ),\n tool(\n 'k-r8',\n 'bash',\n 'Open the release pull request',\n 'gh pr create --repo https://git.example.com/example/harbor --title \"Celsius docs\"',\n 'Stopped before the tests pass',\n { status: 'cancelled' }\n ),\n tool('k-r9', 'bash', 'Watch the preview logs', 'wrangler tail --env preview', '', {\n status: 'running',\n }),\n ].map((call) => ({ type: 'tool' as const, tool: call })),\n {\n type: 'text',\n text: 'One test fails on rounding, so the pull request waits for the fix.',\n },\n ],\n },\n {\n id: 'k-tool2',\n role: 'tool',\n createdAt: at(13.5),\n tool: tool(\n 'k-r10',\n 'bash',\n 'Check the preview port',\n 'lsof -i :8787',\n 'workerd 4120 harbor 12u IPv4 TCP localhost:8787 (LISTEN)'\n ),\n },\n ];\n}\n\nfunction work(): Message[] {\n return [\n {\n id: 'k-m4',\n role: 'assistant',\n status: 'done',\n createdAt: at(14),\n model: 'claude-sonnet-5-5',\n parts: [\n { type: 'text', text: 'Here is where things stand.' },\n { type: 'sprinkle', sprinkle: 'status' },\n {\n type: 'delegation',\n kind: 'scoop',\n scoop: 'docs-pass',\n text: 'Started a scoop to update the docs',\n },\n {\n type: 'delegation',\n kind: 'feed',\n scoop: 'docs-pass',\n text: 'Handed over the new screenshots',\n },\n {\n type: 'delegation',\n kind: 'sprinkle',\n scoop: 'suggestions',\n text: 'Opened the suggestions sprinkle',\n },\n { type: 'delegation', kind: 'drop', scoop: 'amber-heron', text: 'Wrapped up amber-heron' },\n ],\n },\n {\n id: 'k-m5',\n role: 'assistant',\n status: 'done',\n createdAt: at(18),\n model: 'claude-sonnet-5-5',\n parts: [\n { type: 'text', text: 'Three decisions from earlier:' },\n {\n type: 'question',\n question: {\n id: 'k-q1',\n kind: 'yes-no',\n question: 'Tag 1.9.0 after the merge?',\n options: [],\n state: 'answered',\n answer: 'Yes',\n },\n },\n {\n type: 'question',\n question: {\n id: 'k-q2',\n kind: 'text',\n question: 'What should the release be called?',\n options: [],\n state: 'inert',\n },\n },\n {\n type: 'question',\n question: {\n id: 'k-q3',\n kind: 'choice',\n question: 'Where should the cache live?',\n options: ['Keep it in memory', 'Move it to KV', 'Decide after the load test'],\n state: 'open',\n },\n },\n ],\n },\n ];\n}\n\nfunction events(): Message[] {\n return [\n {\n id: 'k-s1',\n role: 'system',\n kind: 'compaction',\n title: 'Context compacted',\n text: '58 earlier messages were summarized.',\n trigger: 'threshold',\n state: 'summarized',\n createdAt: at(1440),\n },\n {\n id: 'k-s2',\n role: 'system',\n kind: 'compaction',\n title: 'Compaction failed, transcript truncated',\n text: 'The summary failed, so the oldest 20 messages were dropped instead.',\n trigger: 'overflow',\n state: 'fallback',\n createdAt: at(1441),\n },\n ...licks.map(\n ([channel, title, text, body, extra], index): Message =>\n ({\n id: `k-l${index + 1}`,\n role: 'lick',\n channel,\n title,\n text,\n createdAt: at(1445 + index),\n ...(body ? { body } : {}),\n ...extra,\n }) as Message\n ),\n {\n id: 'k-u4',\n role: 'user',\n text: 'Actually, stop the deploy, staging is frozen today.',\n mode: 'steer',\n createdAt: at(1470),\n },\n {\n id: 'k-m6',\n role: 'assistant',\n status: 'stopped',\n createdAt: at(1470),\n model: 'claude-haiku-4-5',\n parts: [{ type: 'text', text: 'Stopping the staging deploy and leaving' }],\n },\n {\n id: 'k-u5',\n role: 'user',\n text: 'Update the forecast page to Celsius and use the new screenshots.',\n from: 'harbor',\n createdAt: at(1472),\n },\n {\n id: 'k-m7',\n role: 'assistant',\n status: 'error',\n createdAt: at(1475),\n model: 'claude-haiku-4-5',\n parts: [\n {\n type: 'thinking',\n text: 'The model rejected the request because the context is too large.',\n },\n {\n type: 'error',\n message: 'The request is too large for this model.',\n detail: 'The model returned 413: the request is larger than its context window.',\n action: 'change-model',\n },\n ],\n },\n {\n id: 'k-s3',\n role: 'system',\n kind: 'error',\n title: 'docs-pass failed',\n text: 'The Adobe session expired. Log in again to continue.',\n action: 'login',\n account: 'ai-adobe',\n createdAt: at(1476),\n },\n {\n id: 'k-s4',\n role: 'system',\n kind: 'error',\n title: 'Rate limited',\n text: 'Anthropic answered 429. Retrying in 30 seconds.',\n action: 'retry',\n createdAt: at(1477),\n },\n {\n id: 'k-s5',\n role: 'system',\n kind: 'notice',\n title: 'Model changed',\n text: 'to Claude Opus 5.5 (Anthropic)',\n createdAt: at(1478),\n },\n ];\n}\n\nexport function showcase(): Message[] {\n return [...opening(), ...runs(), ...work(), ...events()];\n}\n\nexport function showcaseQueue(): UserMessage[] {\n return [\n {\n id: 'k-q-1',\n role: 'user',\n text: 'Then open a pull request for the docs.',\n createdAt: at(1480),\n queued: true,\n mode: 'queue',\n },\n {\n id: 'k-q-2',\n role: 'user',\n text: 'And post the link in the release channel.',\n createdAt: at(1481),\n queued: true,\n mode: 'queue',\n },\n ];\n}\n", "import type {\n Account,\n Agent,\n BrowserTab,\n Change,\n Message,\n ModelOption,\n Settings,\n TerminalInfo,\n UserMessage,\n} from '../model/types.ts';\nimport { showcase, showcaseAgent, showcaseQueue } from './showcase.ts';\n\nconst cacheBefore = `export interface Entry<T> {\n value: T;\n storedAt: number;\n}\n\nconst TTL = 60 * 60 * 1000;\n\nexport class ForecastCache<T> {\n #entries = new Map<string, Entry<T>>();\n\n get(key: string, now = Date.now()): T | undefined {\n const entry = this.#entries.get(key);\n if (!entry) return undefined;\n const day = new Date(entry.storedAt).getDate();\n if (day !== new Date(now).getDate()) return entry.value;\n if (now - entry.storedAt > TTL) return undefined;\n return entry.value;\n }\n\n set(key: string, value: T, now = Date.now()): void {\n this.#entries.set(key, { value, storedAt: now });\n }\n}\n`;\n\nconst cacheAfter = `export interface Entry<T> {\n value: T;\n storedAt: number;\n}\n\nconst TTL = 60 * 60 * 1000;\n\nexport class ForecastCache<T> {\n #entries = new Map<string, Entry<T>>();\n\n get(key: string, now = Date.now()): T | undefined {\n const entry = this.#entries.get(key);\n if (!entry) return undefined;\n if (dayOf(entry.storedAt) !== dayOf(now)) {\n this.#entries.delete(key);\n return undefined;\n }\n if (now - entry.storedAt > TTL) return undefined;\n return entry.value;\n }\n\n set(key: string, value: T, now = Date.now()): void {\n this.#entries.set(key, { value, storedAt: now });\n }\n}\n\nfunction dayOf(time: number): string {\n return new Date(time).toISOString().slice(0, 10);\n}\n`;\n\nconst retry = `export async function retry<T>(task: () => Promise<T>, attempts = 3, wait = 250): Promise<T> {\n let last: unknown;\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n return await task();\n } catch (error) {\n last = error;\n await new Promise((resolve) => setTimeout(resolve, wait * 2 ** attempt));\n }\n }\n throw last;\n}\n`;\n\nconst legacyXml = `export function toXml(forecast: { city: string; high: number; low: number }): string {\n return \\`<forecast city=\"\\${forecast.city}\"><high>\\${forecast.high}</high><low>\\${forecast.low}</low></forecast>\\`;\n}\n`;\n\nconst forecastBefore = `import { ForecastCache } from '../lib/cache.ts';\nimport { toCelsius } from '../lib/units.ts';\n\nconst cache = new ForecastCache<Forecast>();\n\nexport interface Forecast {\n city: string;\n high: number;\n low: number;\n summary: string;\n}\n\nexport async function forecast(city: string, upstream: typeof fetch = fetch): Promise<Forecast> {\n const cached = cache.get(city);\n if (cached) return cached;\n const response = await upstream(\\`https://api.example.com/v2/forecast?city=\\${encodeURIComponent(city)}\\`);\n const body = await response.json();\n const result = {\n city,\n high: toCelsius(body.daily.max),\n low: toCelsius(body.daily.min),\n summary: body.daily.summary,\n };\n cache.set(city, result);\n return result;\n}\n`;\n\nconst forecastAfter = forecastBefore\n .replace(\n \"import { toCelsius } from '../lib/units.ts';\",\n \"import { retry } from '../lib/retry.ts';\\nimport { toCelsius } from '../lib/units.ts';\"\n )\n .replace('const response = await upstream(', 'const response = await retry(() =>\\n upstream(')\n .replace('(city)}`);', '(city)}`)\\n );');\n\nconst units = `export function toCelsius(fahrenheit: number): number {\n return Math.round(((fahrenheit - 32) * 5) / 9);\n}\n\nexport function toFahrenheit(celsius: number): number {\n return Math.round((celsius * 9) / 5 + 32);\n}\n`;\n\nconst unitsTest = `import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { toCelsius, toFahrenheit } from '../src/lib/units.ts';\n\ntest('converts both ways', () => {\n assert.equal(toCelsius(212), 100);\n assert.equal(toFahrenheit(0), 32);\n});\n`;\n\nconst index = `import { forecast } from './routes/forecast.ts';\n\nexport default {\n async fetch(request: Request): Promise<Response> {\n const url = new URL(request.url);\n if (url.pathname === '/health') return new Response('ok');\n const city = url.searchParams.get('city');\n if (!city) return Response.json({ error: 'city is required' }, { status: 400 });\n return Response.json(await forecast(city));\n },\n};\n`;\n\nconst readme = `# harbor\n\nA small forecast API that sits in front of the upstream weather service and caches per city.\n\n## Development\n\n\\`\\`\\`sh\nnpm install\nnpm test\nnpm run dev\n\\`\\`\\`\n\nThe worker listens on \\`http://localhost:8787\\`. Try \\`/forecast?city=Lisbon\\`.\n`;\n\nconst pkg = `{\n \"name\": \"harbor\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"wrangler dev\",\n \"test\": \"node --test test/\"\n },\n \"devDependencies\": {\n \"wrangler\": \"4.40.0\"\n }\n}\n`;\n\nconst skill = `---\nname: release-notes\ndescription: Draft release notes from merged pull requests since the last tag.\n---\n\n1. Run \\`collect.jsh\\` with the repository and the previous tag.\n2. Group the pull requests by label: features, fixes, chores.\n3. Write one sentence per change, in the past tense, without ticket numbers.\n`;\n\nconst collect = `const [repo, since] = process.argv.slice(2);\nconst pulls = await gh(\\`repos/\\${repo}/pulls?state=closed&per_page=100\\`);\nfor (const pull of pulls.filter((p) => p.merged_at > since)) {\n console.log(\\`\\${pull.number}\\\\t\\${pull.labels.map((l) => l.name).join(',')}\\\\t\\${pull.title}\\`);\n}\n`;\n\nconst memory = `# Shared memory\n\n## Preferences\n- Keep replies short. Lead with the result, then the evidence.\n- Run the tests before saying something is fixed.\n\n## Projects\n- harbor: forecast API, deployed as a worker. Cache bugs show up around midnight UTC.\n- release-notes: drafted every Friday from merged pull requests.\n`;\n\nconst standup = `# Standup, 4 October\n\n- harbor: retries for upstream timeouts are in review.\n- Docs: the forecast endpoint page still shows Fahrenheit examples.\n- Next: move the cache to KV once the TTL fix lands.\n`;\n\nconst sample = `{\n \"city\": \"Lisbon\",\n \"daily\": { \"max\": 77, \"min\": 61, \"summary\": \"Clear, light wind from the north\" }\n}\n`;\n\nconst bashrc = `export PS1='\\\\u@slicc:\\\\w\\\\$ '\nalias ll='ls -la'\n`;\n\nconst suggestions = `${JSON.stringify(\n [\n {\n id: 'sug-units',\n kind: 'skill',\n title: 'Unit conversions',\n body: 'You converted Fahrenheit to Celsius by hand in three chats this week. A skill can do it for you.',\n skill: 'unit-converter',\n install:\n 'unit-converter from raw.githubusercontent.com/example/skills/main/unit-converter/SKILL.md',\n },\n {\n id: 'sug-notes',\n kind: 'use-case',\n title: 'Release notes from the week',\n body: 'You write release notes for harbor every Friday. Let the cone draft them from the commits.',\n prompt: 'Draft release notes for harbor from the commits since last Friday.',\n },\n {\n id: 'sug-cache',\n kind: 'tip',\n title: 'Name your cache keys',\n body: 'Forecast cache keys mix the city and the units. Splitting them makes stale entries easier to find.',\n },\n ],\n null,\n 2\n)}\n`;\n\nconst upstreamReport =\n '# Upstream limits\\n\\n## Summary\\n\\nThe forecast upstream allows **60 requests a minute** per key and answers `429` with a `Retry-After` header past that. A one-minute cache keeps harbor well under it.\\n\\n## Findings\\n\\n- Bursts after midnight UTC reach about 40 requests a minute.\\n- `Retry-After` is in seconds, never a date.\\n- Timeouts come from the upstream, not the network: 3 in the last 1,000 calls.\\n';\n\nexport const files: Record<string, string> = {\n '/workspace/harbor/README.md': readme,\n '/workspace/harbor/package.json': pkg,\n '/workspace/harbor/wrangler.toml':\n 'name = \"harbor\"\\nmain = \"src/index.ts\"\\ncompatibility_date = \"2026-09-01\"\\n',\n '/workspace/harbor/.gitignore': 'node_modules/\\n.wrangler/\\n',\n '/workspace/harbor/src/index.ts': index,\n '/workspace/harbor/src/routes/forecast.ts': forecastBefore,\n '/workspace/harbor/src/lib/cache.ts': cacheBefore,\n '/workspace/harbor/src/lib/units.ts': units,\n '/workspace/harbor/src/legacy/xml.ts': legacyXml,\n '/workspace/harbor/static/radar.png': '\\u0089PNG\\r\\n\\u001a\\n',\n '/workspace/harbor/test/units.test.ts': unitsTest,\n '/workspace/skills/release-notes/SKILL.md': skill,\n '/workspace/skills/release-notes/scripts/collect.jsh': collect,\n '/shared/MEMORY.md': memory,\n '/shared/notes/2026-10-04-standup.md': standup,\n '/shared/scoop-notifications/amber-heron.md': upstreamReport,\n '/home/user/.bashrc': bashrc,\n '/home/.gelatiere/suggestions.json': suggestions,\n '/tmp/forecast-sample.json': sample,\n};\n\nexport const directories = ['/sessions', '/home/user/downloads'];\n\nexport const mountPoint = '/mnt/photos';\n\nexport const mounted: Record<string, string> = {\n 'README.md': '# Photos\\n\\nHarbor shots for the forecast pages, one album per season.\\n',\n 'albums/autumn.json': '{ \"title\": \"Autumn\", \"shots\": [\"breakwater-fog\", \"pier-at-dusk\"] }\\n',\n 'albums/winter.json': '{ \"title\": \"Winter\", \"shots\": [\"ice-on-the-buoys\"] }\\n',\n 'captions.txt':\n 'breakwater-fog: low cloud over the outer wall\\npier-at-dusk: lamps on, tide out\\n',\n};\n\nexport const pending: Change[] = [\n {\n path: '/workspace/harbor/src/lib/cache.ts',\n status: 'modified',\n before: cacheBefore,\n after: cacheAfter,\n agentId: 'cone-harbor',\n },\n {\n path: '/workspace/harbor/src/lib/retry.ts',\n status: 'added',\n before: null,\n after: retry,\n agentId: 'scoop-otter',\n },\n {\n path: '/workspace/harbor/src/routes/forecast.ts',\n status: 'modified',\n before: forecastBefore,\n after: forecastAfter,\n agentId: 'scoop-otter',\n },\n {\n path: '/workspace/harbor/src/legacy/xml.ts',\n status: 'deleted',\n before: legacyXml,\n after: null,\n agentId: 'cone-harbor',\n },\n {\n path: '/workspace/harbor/static/radar.png',\n status: 'modified',\n before: null,\n after: null,\n agentId: 'scoop-otter',\n },\n];\n\nexport const skillEdit: Change = {\n path: '/workspace/skills/release-notes/SKILL.md',\n status: 'modified',\n before: skill,\n after: `${skill}4. Link each change to its pull request.\\n`,\n agentId: null,\n};\n\nexport const models: ModelOption[] = [\n { id: 'claude-opus-5-5', label: 'Claude Opus 5.5', provider: 'Anthropic', images: true },\n { id: 'claude-sonnet-5-5', label: 'Claude Sonnet 5.5', provider: 'Anthropic', images: true },\n { id: 'claude-haiku-4-5', label: 'Claude Haiku 4.5', provider: 'Anthropic', images: true },\n { id: 'local-small', label: 'Local (ort-llama)', provider: 'This browser', images: false },\n { id: 'local-guard', label: 'Local guard', provider: 'This browser', kind: 'classifier' },\n { id: 'local-tiny', label: 'Local tiny (no tools)', provider: 'This browser', tools: false },\n];\n\nexport const laterModels: ModelOption[] = [\n { id: 'gpt-6', label: 'GPT-6', provider: 'OpenAI', images: true },\n { id: 'gpt-6-mini', label: 'GPT-6 mini', provider: 'OpenAI', images: true, default: true },\n];\n\nexport const defaults: Settings = {\n color: 'system',\n model: 'claude-sonnet-5-5',\n thinking: 'medium',\n sendOnEnter: true,\n pushToTalk: false,\n showThinking: true,\n diffStyle: 'unified',\n};\n\nexport const accounts: Account[] = [\n { id: 'anthropic', provider: 'Anthropic', identity: 'API key ending 3f2a', status: 'connected' },\n { id: 'github', provider: 'GitHub', identity: '@example-dev', status: 'connected' },\n { id: 'adobe', provider: 'Adobe', identity: 'dev@example.com', status: 'expired' },\n {\n id: 'ai-adobe',\n provider: 'Adobe AI',\n identity: 'harbor-ops@example.com',\n status: 'expired',\n auth: 'oauth',\n },\n { id: 'openai', provider: 'OpenAI', identity: '', status: 'disconnected', auth: 'api-key' },\n {\n id: 'amazon-bedrock',\n provider: 'Amazon Bedrock',\n identity: '',\n status: 'disconnected',\n auth: 'api-key',\n fields: [\n {\n name: 'region',\n label: 'Region',\n required: true,\n options: [\n { value: 'us-east-1', label: 'US East (N. Virginia)' },\n { value: 'us-west-2', label: 'US West (Oregon)' },\n { value: 'eu-central-1', label: 'Europe (Frankfurt)' },\n { value: 'ap-northeast-1', label: 'Asia Pacific (Tokyo)' },\n ],\n value: 'us-west-2',\n },\n ],\n },\n {\n id: 'mcp:docs',\n provider: 'docs',\n identity: 'docs.example',\n url: 'https://docs.example/mcp',\n status: 'connected',\n auth: 'api-key',\n group: 'mcp',\n secret: 'token',\n },\n {\n id: 'mcp:tickets',\n provider: 'tickets',\n identity: 'tickets.example',\n url: 'https://tickets.example/mcp',\n status: 'expired',\n auth: 'api-key',\n group: 'mcp',\n secret: 'token',\n },\n {\n id: 'mcp:design',\n provider: 'design',\n identity: 'design.example',\n status: 'disconnected',\n auth: 'oauth',\n group: 'mcp',\n },\n];\n\nexport const agents: Agent[] = [\n {\n id: 'cone-sliccy',\n name: 'sliccy',\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: 'claude-sonnet-5-5',\n contextFill: 0.21,\n unread: 0,\n },\n showcaseAgent,\n {\n id: 'cone-harbor',\n name: 'harbor',\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: 'claude-opus-5-5',\n contextFill: 0.38,\n unread: 0,\n },\n {\n id: 'scoop-otter',\n name: 'quiet-otter',\n kind: 'scoop',\n parentId: 'cone-harbor',\n status: 'working',\n model: 'claude-haiku-4-5',\n contextFill: 0.12,\n unread: 0,\n },\n {\n id: 'scoop-heron',\n name: 'amber-heron',\n kind: 'scoop',\n parentId: 'cone-harbor',\n status: 'idle',\n model: 'claude-haiku-4-5',\n contextFill: 0.04,\n unread: 0,\n },\n {\n id: 'cone-release',\n name: 'release-notes',\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: 'claude-sonnet-5-5',\n contextFill: 0.7,\n unread: 1,\n },\n {\n id: 'cone-triage',\n name: 'inbox-triage',\n kind: 'cone',\n parentId: null,\n status: 'waiting',\n model: 'claude-sonnet-5-5',\n contextFill: 0.95,\n unread: 2,\n },\n {\n id: 'scoop-wren',\n name: 'tidal-wren',\n kind: 'scoop',\n parentId: 'cone-sliccy',\n status: 'idle',\n model: 'claude-haiku-4-5',\n contextFill: 0.02,\n unread: 0,\n },\n {\n id: 'cone-tides',\n name: 'tide-tables',\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: 'claude-sonnet-5-5',\n contextFill: 0.31,\n unread: 0,\n frozen: true,\n },\n];\n\nconst start = Date.UTC(2026, 9, 5, 8, 30);\nconst at = (minutes: number) => start + minutes * 60_000;\n\nexport const queues: Record<string, UserMessage[]> = { 'cone-kitchen': showcaseQueue() };\n\nexport const conversations: Record<string, Message[]> = {\n 'cone-kitchen': showcase(),\n 'cone-sliccy': [\n {\n id: 'm-s0',\n role: 'assistant',\n status: 'done',\n createdAt: at(-24 * 60),\n parts: [\n {\n type: 'text',\n text: 'Hi, I am sliccy. Tell me a little about yourself, and I will set things up for you.',\n },\n { type: 'sprinkle', sprinkle: 'welcome' },\n ],\n },\n {\n id: 'm-s1',\n role: 'user',\n text: 'What is on my plate today?',\n createdAt: at(0),\n },\n {\n id: 'm-s2',\n role: 'assistant',\n status: 'done',\n createdAt: at(1),\n parts: [\n {\n type: 'tool',\n tool: {\n id: 't-s1',\n name: 'read_file',\n title: 'Read the standup notes',\n input: '/shared/notes/2026-10-04-standup.md',\n output: standup,\n status: 'done',\n paths: ['/shared/notes/2026-10-04-standup.md'],\n },\n },\n {\n type: 'text',\n text: 'Three things carry over from yesterday:\\n\\n1. **harbor**: the retry change is in review, and the midnight cache bug is still open.\\n2. **Docs**: the forecast page still shows Fahrenheit examples.\\n3. **release-notes** has a draft waiting for you.\\n\\nThe `harbor` cone is the one to start with.',\n },\n ],\n },\n ],\n 'cone-harbor': [\n {\n id: 'm-h1',\n role: 'lick',\n channel: 'webhook',\n title: 'GitHub \u00B7 issue opened',\n text: 'example/harbor#57: Forecast stays on yesterday after midnight UTC',\n createdAt: at(2),\n },\n {\n id: 'm-h2',\n role: 'user',\n text: 'The forecast endpoint serves stale data after midnight UTC. Find out why and fix it.',\n createdAt: at(3),\n },\n {\n id: 'm-h3',\n role: 'assistant',\n status: 'done',\n createdAt: at(4),\n parts: [\n {\n type: 'thinking',\n text: 'Stale after midnight points at the cache expiry. Check how the cache compares days.',\n },\n {\n type: 'tool',\n tool: {\n id: 't-h1',\n name: 'bash',\n title: 'Search for the cache expiry',\n input: 'rg -n \"getDate|TTL\" src',\n output:\n 'src/lib/cache.ts:6:const TTL = 60 * 60 * 1000;\\nsrc/lib/cache.ts:14: const day = new Date(entry.storedAt).getDate();\\nsrc/lib/cache.ts:16: if (now - entry.storedAt > TTL) return undefined;',\n status: 'done',\n paths: ['/workspace/harbor/src/lib/cache.ts'],\n },\n },\n {\n type: 'tool',\n tool: {\n id: 't-h2',\n name: 'read_file',\n title: 'Read the cache',\n input: '/workspace/harbor/src/lib/cache.ts',\n output: cacheBefore,\n status: 'done',\n paths: ['/workspace/harbor/src/lib/cache.ts'],\n },\n },\n {\n type: 'tool',\n tool: {\n id: 't-h3',\n name: 'edit_file',\n title: 'Expire entries from the previous day',\n input: '/workspace/harbor/src/lib/cache.ts',\n output: 'Replaced 1 block (4 lines \u2192 7 lines), added dayOf()',\n status: 'done',\n paths: ['/workspace/harbor/src/lib/cache.ts'],\n diff: { before: cacheBefore, after: cacheAfter },\n },\n },\n {\n type: 'tool',\n tool: {\n id: 't-h4',\n name: 'bash',\n title: 'Run the tests',\n input: 'npm test',\n meta: 'timeout 120s',\n output:\n '> harbor@0.0.0 test\\n> node --test test/\\n\\n\u2714 converts both ways (0.6ms)\\n\u2714 expires entries from the previous day (0.4ms)\\n\u2139 tests 2\\n\u2139 pass 2\\n\u2139 fail 0',\n status: 'done',\n paths: [],\n },\n },\n {\n type: 'text',\n text: 'Found it. `ForecastCache.get` compared **local** calendar days, and when the day changed it returned the old entry instead of dropping it:\\n\\n```ts\\nif (day !== new Date(now).getDate()) return entry.value;\\n```\\n\\nI changed it to compare UTC dates and delete the entry, so the first request after midnight goes upstream. The tests pass.\\n\\n| | Before | After |\\n| --- | --- | --- |\\n| Day compared | local `getDate()` | UTC `toISOString()` |\\n| On a new day | returns stale entry | deletes and refetches |\\n\\nquiet-otter is adding retries for upstream timeouts in a scoop.',\n },\n {\n type: 'delegation',\n kind: 'scoop',\n scoop: 'quiet-otter',\n text: 'Started a scoop to add retries around the upstream fetch',\n },\n ],\n },\n {\n id: 'm-h4',\n role: 'lick',\n channel: 'scoop-notify',\n title: 'quiet-otter',\n text: 'Started: add retries with backoff around the upstream fetch',\n createdAt: at(9),\n },\n {\n id: 'm-h5',\n role: 'lick',\n channel: 'scoop-notify',\n title: 'amber-heron (scout)',\n text: '[scoop amber-heron (scout) completed]',\n summary:\n 'The upstream allows 60 requests a minute, so a one-minute cache keeps harbor under it.',\n report: '/shared/scoop-notifications/amber-heron.md',\n body: `[scoop amber-heron (scout) completed]\\n${upstreamReport}`,\n createdAt: at(11),\n },\n {\n id: 'm-h6',\n role: 'lick',\n channel: 'scoop-notify',\n title: 'grey-tern (worker)',\n text: '[scoop grey-tern (worker) failed]',\n body: '[scoop grey-tern (worker) failed]\\nThe deploy preview timed out after **120 s**. Nothing was pushed.',\n createdAt: at(13),\n },\n {\n id: 'm-h7',\n role: 'lick',\n channel: 'scoop-notify',\n title: 'salt-gull (scout)',\n text: '[scoop salt-gull (scout) completed]',\n createdAt: at(15),\n },\n ],\n 'scoop-otter': [\n {\n id: 'm-o1',\n role: 'user',\n origin: 'agent',\n from: 'harbor',\n text: 'Wrap the upstream fetch in src/routes/forecast.ts with three retries and exponential backoff.',\n createdAt: at(9),\n },\n {\n id: 'm-o2',\n role: 'assistant',\n status: 'done',\n createdAt: at(10),\n parts: [\n {\n type: 'tool',\n tool: {\n id: 't-o1',\n name: 'write_file',\n title: 'Add retry()',\n input: '/workspace/harbor/src/lib/retry.ts',\n output: 'Wrote 12 lines',\n status: 'done',\n paths: ['/workspace/harbor/src/lib/retry.ts'],\n },\n },\n {\n type: 'tool',\n tool: {\n id: 't-o2',\n name: 'edit_file',\n title: 'Use retry() for the upstream call',\n input: '/workspace/harbor/src/routes/forecast.ts',\n output: 'Replaced 1 block',\n status: 'done',\n paths: ['/workspace/harbor/src/routes/forecast.ts'],\n },\n },\n { type: 'text', text: 'Both edits are in. Running the tests next.' },\n ],\n },\n ],\n 'scoop-heron': [],\n 'scoop-wren': [],\n 'cone-tides': [\n {\n id: 'm-f1',\n role: 'user',\n text: 'Add a tide table endpoint next to the forecast, with high and low water per day.',\n createdAt: at(-2900),\n },\n {\n id: 'm-f2',\n role: 'assistant',\n status: 'done',\n createdAt: at(-2898),\n parts: [\n {\n type: 'text',\n text: 'Added `/v1/tides?city=` with the next seven days of high and low water. It reads from the same upstream as the forecast and shares its cache.',\n },\n ],\n },\n ],\n 'cone-release': [\n {\n id: 'm-r1',\n role: 'lick',\n channel: 'cron',\n title: 'Every Friday 09:00',\n text: 'Draft the release notes for example/harbor',\n createdAt: at(-1440),\n },\n {\n id: 'm-r2',\n role: 'assistant',\n status: 'done',\n createdAt: at(-1438),\n parts: [\n {\n type: 'tool',\n tool: {\n id: 't-r1',\n name: 'bash',\n title: 'Collect merged pull requests',\n input: 'collect.jsh example/harbor v1.8.0',\n output:\n '41\\tfix\\tReturn 400 when the city is missing\\n43\\tfeature\\tAdd /health\\n44\\tchore\\tUpdate wrangler to 4.40.0',\n status: 'done',\n paths: ['/workspace/skills/release-notes/scripts/collect.jsh'],\n },\n },\n {\n type: 'text',\n text: '## harbor 1.9.0\\n\\n#### Features\\n- Added a `/health` endpoint.\\n\\n#### Fixes\\n- Requests without a city now get a 400 instead of a 500.\\n\\n#### Chores\\n- Updated wrangler to 4.40.0.',\n },\n ],\n },\n {\n id: 'm-r3',\n role: 'lick',\n channel: 'cron',\n severity: 'error',\n title: 'Crontab',\n text: 'Crontab line 3 is invalid',\n body: '30 25 * * * sweep-drafts\\nThe hour is 25. It must be 0 to 23.',\n createdAt: at(-1430),\n },\n {\n id: 'm-r4',\n role: 'lick',\n channel: 'fswatch',\n severity: 'warn',\n title: '/workspace/notes',\n text: 'File watch on /workspace/notes stopped; retrying',\n createdAt: at(-1429),\n },\n {\n id: 'm-r5',\n role: 'lick',\n channel: 'workflow',\n title: 'Release report',\n text: 'The weekly release report is ready',\n body: 'Summary: harbor 1.9.0 shipped three changes this week, the /health endpoint, a 400 for requests without a city and a wrangler update, with no failed deploys, no rollbacks and two flaky test runs in the forecast suite that passed on retry, so the next release can go out on Friday as planned once the docs pass lands.',\n createdAt: at(-1428),\n },\n ],\n 'cone-triage': [\n {\n id: 'm-t1',\n role: 'system',\n kind: 'compaction',\n trigger: 'threshold',\n state: 'summarized',\n title: 'Context compacted',\n text: '41 earlier messages were summarized to stay under the context limit.',\n createdAt: at(-30),\n },\n {\n id: 'm-t2',\n role: 'assistant',\n status: 'done',\n createdAt: at(-20),\n parts: [\n {\n type: 'text',\n text: 'Two messages need a decision from you:\\n\\n- A vendor asks to move Thursday\u2019s call to Friday.\\n- The staging certificate expires in 6 days. Should I open a ticket?',\n },\n ],\n },\n {\n id: 'm-t3',\n role: 'system',\n kind: 'error',\n action: 'login',\n title: 'Mail connector',\n text: 'The connector returned 401. Reconnect the account in Settings.',\n createdAt: at(-19),\n },\n {\n id: 'm-t4',\n role: 'system',\n kind: 'error',\n action: 'login',\n account: 'mcp:tickets',\n title: 'Tickets connector',\n text: 'The tickets server rejected its token.',\n createdAt: at(-18),\n },\n ],\n};\n\nexport const tabs: BrowserTab[] = [\n {\n id: 'tab-preview',\n title: 'harbor \u00B7 localhost',\n url: 'http://localhost:8787/forecast?city=Lisbon',\n status: 'complete',\n agentId: 'cone-harbor',\n },\n {\n id: 'tab-docs',\n title: 'Forecast API reference',\n url: 'https://api.example.com/docs/v2/forecast',\n status: 'complete',\n agentId: null,\n favicon: `data:image/svg+xml;charset=utf-8,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><rect width=\"16\" height=\"16\" rx=\"3\" fill=\"#7a5af8\"/><text x=\"8\" y=\"12\" font-family=\"sans-serif\" font-size=\"11\" font-weight=\"700\" fill=\"#ffffff\" text-anchor=\"middle\">A</text></svg>')}`,\n },\n {\n id: 'tab-pull',\n title: 'Add retries for upstream timeouts \u00B7 Pull request #58',\n url: 'https://git.example.com/example/harbor/pull/58',\n status: 'complete',\n agentId: 'scoop-otter',\n favicon: `data:image/svg+xml;charset=utf-8,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><rect width=\"16\" height=\"16\" rx=\"3\" fill=\"#0a7a43\"/><text x=\"8\" y=\"12\" font-family=\"sans-serif\" font-size=\"11\" font-weight=\"700\" fill=\"#ffffff\" text-anchor=\"middle\">G</text></svg>')}`,\n },\n];\n\nexport const terminals: TerminalInfo[] = [\n { id: 'term-1', title: 'bash', cwd: '/workspace/harbor', agentId: null },\n];\n", "import type { Account, ProviderOption } from '../model/types.ts';\nimport { accounts } from './fixtures.ts';\n\nconst options: ProviderOption[] = [\n {\n id: 'ai-adobe',\n name: 'Adobe AI',\n description: 'Models from your Adobe plan',\n auth: 'oauth',\n },\n {\n id: 'amazon-bedrock',\n name: 'Amazon Bedrock',\n description: 'Claude and more through AWS',\n auth: 'fields',\n keyUrl: 'https://console.aws.example/bedrock/api-keys',\n fields: accounts.find((account) => account.id === 'amazon-bedrock')?.fields,\n },\n {\n id: 'anthropic',\n name: 'Anthropic',\n description: 'Claude models with your own key',\n auth: 'api-key',\n keyUrl: 'https://console.anthropic.example/keys',\n },\n {\n id: 'openai',\n name: 'OpenAI',\n description: 'GPT models with your own key',\n auth: 'api-key',\n keyUrl: 'https://platform.openai.example/api-keys',\n },\n {\n id: 'mistral',\n name: 'Mistral',\n description: 'Mistral and Codestral models',\n auth: 'api-key',\n keyUrl: 'https://console.mistral.example/keys',\n },\n {\n id: 'groq',\n name: 'Groq',\n description: 'Fast open models',\n auth: 'api-key',\n keyUrl: 'https://console.groq.example/keys',\n },\n {\n id: 'openrouter',\n name: 'OpenRouter',\n description: 'Many providers behind one key',\n auth: 'api-key',\n keyUrl: 'https://openrouter.example/keys',\n },\n {\n id: 'cerebras',\n name: 'Cerebras',\n description: 'Open models on wafer-scale chips',\n auth: 'api-key',\n keyUrl: 'https://cloud.cerebras.example/keys',\n },\n {\n id: 'github-copilot',\n name: 'GitHub Copilot',\n description: 'Models from your Copilot plan',\n auth: 'oauth',\n },\n {\n id: 'openai-codex',\n name: 'OpenAI Codex',\n description: 'Models from your ChatGPT plan',\n auth: 'oauth',\n },\n {\n id: 'azure-openai',\n name: 'Azure OpenAI',\n description: 'Your own Azure deployment',\n auth: 'fields',\n keyUrl: 'https://portal.azure.example/openai',\n fields: [\n {\n name: 'endpoint',\n label: 'Endpoint',\n required: true,\n customBase: true,\n placeholder: 'https://harbor.openai.azure.example',\n help: 'The resource\u2019s endpoint, from Keys and endpoint.',\n },\n { name: 'deployment', label: 'Deployment', required: true, placeholder: 'harbor-gpt' },\n ],\n vaultName: 'AZURE_OPENAI_API_KEY',\n },\n {\n id: 'cloudflare',\n name: 'Cloudflare',\n description: 'Workers AI models',\n auth: 'fields',\n keyUrl: 'https://dash.cloudflare.example/api-tokens',\n needs: 'cors-free-transport',\n fields: [\n {\n name: 'account',\n label: 'Account ID',\n required: true,\n placeholder: '3f2a9c\u2026',\n help: 'On the right of the Workers AI page.',\n },\n ],\n vaultName: 'CLOUDFLARE_WORKERS_AI_API_KEY',\n },\n {\n id: 'ollama',\n name: 'Ollama',\n description: 'Models running on this device',\n auth: 'local',\n },\n {\n id: 'lm-studio',\n name: 'LM Studio',\n description: 'Models served by LM Studio on this device',\n auth: 'local',\n },\n];\n\nexport const providerFixtures: readonly ProviderOption[] = options.sort((a, b) =>\n a.name.localeCompare(b.name)\n);\n\nexport function providerAccount(option: ProviderOption): Account {\n const keyed = option.auth === 'api-key' || option.auth === 'fields';\n return {\n id: option.id,\n provider: option.name,\n identity: '',\n status: 'disconnected',\n group: 'providers',\n auth: keyed ? 'api-key' : (option.auth as 'oauth' | 'local'),\n ...(keyed ? { store: 'vault' as const } : {}),\n ...(option.fields ? { fields: option.fields } : {}),\n ...(option.keyUrl ? { keyUrl: option.keyUrl } : {}),\n ...(option.description ? { description: option.description } : {}),\n ...(option.needs ? { needs: option.needs } : {}),\n ...(option.blocked ? { blocked: option.blocked } : {}),\n ...(option.vaultName ? { vaultName: option.vaultName } : {}),\n };\n}\n\nexport function providerAccounts(rows: readonly Account[], transport?: 'none'): Account[] {\n const added = (id: string, patch: Partial<Account>): Account => ({\n ...providerAccount(providerFixtures.find((option) => option.id === id) as ProviderOption),\n ...patch,\n });\n const offered = (account: Account) => providerFixtures.find((option) => option.id === account.id);\n const providers = rows\n .filter((account) => account.group !== 'mcp')\n .map((account) => {\n const option = offered(account);\n return option ? { ...providerAccount(option), ...account } : account;\n });\n const servers = rows.filter((account) => account.group === 'mcp');\n return [\n ...providers,\n added('ollama', { status: 'connected', identity: 'On this device' }),\n ...(transport ? [added('cloudflare', { status: 'connected', identity: 'API key' })] : []),\n ...servers,\n ];\n}\n", "export interface Clock {\n delay: number;\n sleep(ticks?: number): Promise<void>;\n}\n\nexport function clock(delay: number): Clock {\n return {\n delay,\n sleep: (ticks = 1) => new Promise((resolve) => setTimeout(resolve, delay * ticks)),\n };\n}\n", "import { Emitter } from '../model/emitter.ts';\nimport type {\n Account,\n AccountField,\n AccountStatus,\n ModelOption,\n ProviderOption,\n Settings,\n SettingsEvents,\n SettingsPort,\n} from '../model/types.ts';\nimport type { Clock } from './clock.ts';\nimport { providerAccount } from './providers.ts';\n\nexport const dummySettingsKey = 'slicc-ui.settings';\nexport const signInClosed = 'The sign-in window was closed before it finished.';\n\nexport type DummyTransport = 'none' | 'extension' | 'link';\n\nfunction chosen(\n fields: readonly AccountField[] | undefined,\n values: Record<string, string> | undefined\n): string[] {\n return (fields ?? []).flatMap((field) => {\n const option = field.options?.find((candidate) => candidate.value === values?.[field.name]);\n return option ? [option.label] : [];\n });\n}\n\nfunction kept(\n fields: readonly AccountField[] | undefined,\n values: Record<string, string> | undefined\n): Pick<Account, 'fields'> {\n if (!(fields && values)) return {};\n return {\n fields: fields.map((field) => ({ ...field, value: values[field.name] ?? field.value })),\n };\n}\n\nexport class DummySettings extends Emitter<SettingsEvents> implements SettingsPort {\n #settings: Settings;\n #accounts: Account[];\n #models: readonly ModelOption[];\n #storage: Storage | null;\n #clock: Clock;\n #keys: readonly string[];\n #signIns = new Map<string, { before: AccountStatus; stop: () => void }>();\n #gated: boolean;\n #fails: boolean;\n #transport: DummyTransport | undefined;\n #options: readonly ProviderOption[] = [];\n readonly connects: Array<{\n id: string;\n gesture: boolean | null;\n fields?: Record<string, string>;\n }> = [];\n providers?: () => readonly ProviderOption[];\n remove?: (id: string) => Promise<void>;\n\n constructor(\n defaults: Settings,\n models: readonly ModelOption[],\n accounts: readonly Account[],\n storage: Storage | null,\n clock: Clock,\n keys: readonly string[] = [dummySettingsKey],\n gated = false,\n login?: 'ok' | 'fail',\n providers?: readonly ProviderOption[],\n transport?: DummyTransport\n ) {\n super();\n this.#transport = transport;\n if (providers) {\n this.#options = providers;\n this.providers = () =>\n this.#transport === 'none' ? providers.map((option) => this.#block(option)) : providers;\n this.remove = async (id) => this.#drop(id);\n }\n this.#fails = login === 'fail';\n this.#gated = gated;\n this.#keys = keys;\n this.#storage = storage;\n this.#clock = clock;\n this.#models = models;\n this.#accounts = accounts.map((account) => ({ ...account }));\n this.#settings = { ...defaults, ...this.#load() };\n }\n\n #load(): Partial<Settings> {\n try {\n const saved = this.#keys\n .map((key) => this.#storage?.getItem(key))\n .find((value) => value != null);\n return JSON.parse(saved ?? '{}');\n } catch {\n return {};\n }\n }\n\n get(): Settings {\n return { ...this.#settings };\n }\n\n update(patch: Partial<Settings>): void {\n this.#settings = { ...this.#settings, ...patch };\n this.#storage?.setItem(this.#keys[0], JSON.stringify(this.#settings));\n this.emit('settings', this.get());\n }\n\n models(): readonly ModelOption[] {\n if (!this.#gated) return this.#models;\n const live = new Set(\n this.#accounts\n .filter((account) => account.status === 'connected')\n .map((account) => account.provider)\n );\n return this.#models.filter((option) => live.has(option.provider));\n }\n\n accounts(): readonly Account[] {\n return this.#accounts.map((account) => this.#block({ ...account }));\n }\n\n #block<T extends Account | ProviderOption>(row: T): T {\n if (this.#transport !== 'none' || !row.needs) return row;\n return { ...row, blocked: row.needs };\n }\n\n setTransport(transport: DummyTransport): void {\n this.#transport = transport;\n if (this.providers) this.emit('providers', this.providers());\n this.emit('accounts', this.accounts());\n }\n\n #set(id: string, patch: Partial<Account>): void {\n this.#accounts = this.#accounts.map((account) =>\n account.id === id ? { ...account, ...patch } : account\n );\n this.emit('accounts', this.accounts());\n }\n\n #drop(id: string): void {\n this.#signIns.get(id)?.stop();\n this.#accounts = this.#accounts.filter((account) => account.id !== id);\n this.emit('accounts', this.accounts());\n }\n\n #add(id: string): boolean {\n const option = this.#options.find((candidate) => candidate.id === id);\n if (!option || this.#accounts.some((account) => account.id === id)) return false;\n this.#accounts = [...this.#accounts, providerAccount(option)];\n this.emit('accounts', this.accounts());\n return true;\n }\n\n async connect(id: string, secret?: string, fields?: Record<string, string>): Promise<void> {\n const activation = (globalThis.navigator as Navigator | undefined)?.userActivation;\n this.connects.push({\n id,\n gesture: activation ? activation.isActive : null,\n ...(fields ? { fields } : {}),\n });\n const fresh = this.#add(id);\n try {\n if (!(await this.#connect(id, secret, fields)) && fresh) this.#drop(id);\n } catch (error) {\n if (fresh) this.#drop(id);\n throw error;\n }\n }\n\n async #connect(id: string, secret?: string, fields?: Record<string, string>): Promise<boolean> {\n const account = this.#accounts.find((candidate) => candidate.id === id);\n const local = account?.auth === 'local';\n const window = !!account && account.auth !== 'api-key' && !local;\n if (window && !(await this.#signIn(account))) return false;\n if (window && this.#fails) {\n this.#set(id, { status: account.status });\n throw new Error(signInClosed);\n }\n if (!window) await this.#clock.sleep(10);\n if (account?.auth === 'api-key' && account.store !== 'vault' && !secret)\n throw new Error(\n `${account.provider} needs ${account.secret === 'token' ? 'a token' : 'an API key'}`\n );\n if ([secret, ...Object.values(fields ?? {})].some((value) => value?.startsWith('bad')))\n throw new Error(`${account?.provider} didn\u2019t accept that key.`);\n if (fields?.endpoint?.includes('://') && !fields.endpoint.startsWith('https://'))\n throw new Error('The endpoint must use https://.');\n const identity =\n account?.group === 'mcp'\n ? account.identity\n : local\n ? 'On this device'\n : account?.auth === 'api-key'\n ? ['API key', ...chosen(account.fields, fields)].join(' \u00B7 ')\n : account?.identity || `${id}-user@example.com`;\n this.#set(id, { status: 'connected', identity, ...kept(account?.fields, fields) });\n return true;\n }\n\n #signIn(account: Account): Promise<boolean> {\n const before = this.#signIns.get(account.id)?.before ?? account.status;\n this.#signIns.get(account.id)?.stop();\n this.#set(account.id, { status: 'signing-in' });\n return new Promise((resolve) => {\n const stop = () => {\n this.#signIns.delete(account.id);\n this.#set(account.id, { status: before });\n resolve(false);\n };\n this.#signIns.set(account.id, { before, stop });\n void this.#clock.sleep(100).then(() => {\n if (this.#signIns.get(account.id)?.stop !== stop) return;\n this.#signIns.delete(account.id);\n resolve(true);\n });\n });\n }\n\n cancel(id: string): void {\n this.#signIns.get(id)?.stop();\n }\n\n disconnect(id: string): void {\n this.#set(id, { status: 'disconnected' });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["index", "start", "at", "defaults", "models", "accounts", "clock"]
7
+ }
@@ -24,7 +24,7 @@ import {
24
24
  skillEdit,
25
25
  tabs,
26
26
  terminals
27
- } from "./chunk-CVMI4FSY.js";
27
+ } from "./chunk-YUDOYEMB.js";
28
28
  import {
29
29
  Emitter
30
30
  } from "./chunk-T5NHW4KC.js";
@@ -1226,6 +1226,26 @@ function test() {
1226
1226
  }
1227
1227
  ];
1228
1228
  }
1229
+ var colourChunks = [
1230
+ "\x1B[1mbold\x1B[0m \x1B[3",
1231
+ "6mcyan\x1B[0m \x1B[31mred\x1B[0m \x1B[1;32mbold green\x1B[0m\n",
1232
+ "\x1B[2A\x1B[2K\x1B]8;;https://example.com/harbor\x1B\\harbor\x1B]8;;\x1B\\ \x1B]0;done\x07\x1B[2;92mready\x1B[0m\n\x1B[1;41;97m FAIL \x1B[0m \x1B[42;30m PASS \x1B[0m \x1B[48;5;226m 256 \x1B[0m\n"
1233
+ ];
1234
+ function colours() {
1235
+ return [
1236
+ {
1237
+ type: "tool",
1238
+ name: "bash",
1239
+ title: "Print in color",
1240
+ input: "printf '\\033[1mbold\\033[0m \\033[36mcyan\\033[0m \\033[31mred\\033[0m \\033[1;32mbold green\\033[0m\\n' && ./status",
1241
+ output: colourChunks.join(""),
1242
+ chunks: colourChunks,
1243
+ paths: [],
1244
+ ticks: 60
1245
+ },
1246
+ { type: "text", text: "Printed it in **color**." }
1247
+ ];
1248
+ }
1229
1249
  function edit() {
1230
1250
  return [
1231
1251
  {
@@ -1454,6 +1474,7 @@ function script(prompt, attachments = []) {
1454
1474
  if (/\b(ask|choose|decide)\b/.test(text)) return { steps: ask(), suggestion };
1455
1475
  if (/\b(debug|investigate)\b/.test(text)) return { steps: investigate(), suggestion };
1456
1476
  if (/\b(search|grep)\b/.test(text)) return { steps: search(), suggestion };
1477
+ if (/\bcolou?rs?\b/.test(text)) return { steps: colours(), suggestion };
1457
1478
  if (/\btests?\b/.test(text)) return { steps: test(), suggestion };
1458
1479
  if (/\b(fix|edit|add|change)\b/.test(text)) return { steps: edit(), suggestion };
1459
1480
  if (/\b(open|browse|page|docs)\b/.test(text)) return { steps: browse(), suggestion };
@@ -1616,7 +1637,14 @@ var DummyAgent = class extends Emitter {
1616
1637
  };
1617
1638
  reply.parts.push({ type: "tool", tool });
1618
1639
  this.emit("message", { agentId, message: reply });
1619
- await this.#clock.sleep(step.ticks * run.pace);
1640
+ const chunks2 = step.chunks ?? [];
1641
+ for (const chunk of chunks2) {
1642
+ await this.#clock.sleep(step.ticks / (chunks2.length + 1) * run.pace);
1643
+ if (run.stopped) break;
1644
+ tool.output += chunk;
1645
+ this.emit("message", { agentId, message: reply });
1646
+ }
1647
+ await this.#clock.sleep(step.ticks / (chunks2.length + 1) * run.pace);
1620
1648
  const done = run.stopped ? { status: "cancelled", output: "Stopped" } : { status: "done", output: step.output };
1621
1649
  if (!run.stopped) await step.effect?.({ ...this.#effects, agentId });
1622
1650
  Object.assign(tool, done);