@ai-ecoverse/slicc-spectrum 1.25.0 → 1.27.0
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 +3 -3
- package/dist/{chunk-5I2AIF5I.js → chunk-22NCU4NL.js} +3 -2
- package/dist/{chunk-CHSUKIQC.js → chunk-4F4N6IHX.js} +2 -2
- package/dist/{chunk-Z2IOQT73.js → chunk-6DBT3DUR.js} +3 -3
- package/dist/{chunk-DYJTIU34.js → chunk-FAVZKAXS.js} +3 -3
- package/dist/{chunk-QROWP6N7.js → chunk-I57ZVWF7.js} +3 -3
- package/dist/{chunk-2TAFZNVG.js → chunk-LZPC6RUV.js} +3 -3
- package/dist/{chunk-LMDPCBR2.js → chunk-MQNH3NIC.js} +5 -5
- package/dist/slicc-dummy.js +111 -5
- package/dist/slicc-dummy.js.map +2 -2
- package/dist/slicc-ui.js +8720 -7527
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/chat.d.ts +3 -0
- package/dist/types/app/files.d.ts +20 -0
- package/dist/types/app/messages.d.ts +21 -1
- package/dist/types/dummy/files.d.ts +11 -1
- package/dist/types/dummy/fixtures.d.ts +2 -0
- package/dist/types/dummy/index.d.ts +3 -1
- package/dist/types/dummy.d.ts +1 -0
- package/dist/types/model/types.d.ts +5 -1
- package/package.json +2 -2
- /package/dist/{chunk-5I2AIF5I.js.map → chunk-22NCU4NL.js.map} +0 -0
- /package/dist/{chunk-CHSUKIQC.js.map → chunk-4F4N6IHX.js.map} +0 -0
- /package/dist/{chunk-Z2IOQT73.js.map → chunk-6DBT3DUR.js.map} +0 -0
- /package/dist/{chunk-DYJTIU34.js.map → chunk-FAVZKAXS.js.map} +0 -0
- /package/dist/{chunk-2TAFZNVG.js.map → chunk-I57ZVWF7.js.map} +0 -0
- /package/dist/{chunk-QROWP6N7.js.map → chunk-LZPC6RUV.js.map} +0 -0
- /package/dist/{chunk-LMDPCBR2.js.map → chunk-MQNH3NIC.js.map} +0 -0
package/README.md
CHANGED
|
@@ -136,7 +136,7 @@ Text is Adobe Clean Spectrum VF, falling back to Adobe Clean, and code is Spectr
|
|
|
136
136
|
| `<slicc-agents>` | Cones with their scoops, status, context fill and unread count. Selecting one makes it the active agent. |
|
|
137
137
|
| `<slicc-chat>` | One thread's conversation (its `agent`, or the active agent if unset), by day: user messages (with attachments, tagged as steered or follow-up by `delivered`, or delegated from another cone), assistant messages (Markdown with tables, task lists, quotes, code and images; thinking; tool calls, grouped into a collapsible cluster from three in a row, each with its input (a shell command after `$`), an optional `meta` such as a timeout, and an edit's `diff` shown as a diff view; media galleries with images, video and audio; action cards for tools, pull requests and status; plans and checklists; inline diffs; question prompts; delegations; link previews; errors with a fix-it action; a content-filter stop offers **Drop the last turn**, which rewinds that turn and puts its prompt back into the composer), standalone tool results, system messages (compaction markers, error cards, notices) and licks, SLICC's events into a cone, on every channel; a lick's `severity` (`warn` or `error`) turns its channel badge into a notice or negative one with an alert icon. Permission requests are allowed or denied in place. |
|
|
138
138
|
| `<slicc-composer>` | The message box. <kbd>Enter</kbd> sends, or steers a running reply: the message joins after the current tool round, without interrupting; <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>Enter</kbd> queues a follow-up that runs after the reply and can be withdrawn; <kbd>Shift</kbd>+<kbd>Enter</kbd> adds a line; <kbd>Tab</kbd> takes the suggested follow-up; <kbd>↑</kbd>/<kbd>↓</kbd> at the start or end walk this agent's history; <kbd>Esc</kbd> stops. `/` completes commands (`/clear`, `/compact`, `/model`, `/thinking`, `/scoop`, `/stop`, `/theme`) and their arguments, `@` mentions agents and files. Attach from the computer, from SLICC's files, a browser screenshot or a shared secret, or paste and drop files (25 MB each). Queued messages wait above it, to send now or drop. Model and thinking pickers, and dictation where the browser has speech recognition. Drafts are kept per agent. |
|
|
139
|
-
| `<slicc-files>` | The file system as a `<slicc-file-tree>`, with pending changes as git status. Opening a file opens it in a tab. |
|
|
139
|
+
| `<slicc-files>` | The file system as a `<slicc-file-tree>`, with pending changes as git status. Opening a file opens it in a tab. With `files.mountFolder`, **Mount a folder…** (`data-action="mount-folder"`) mounts a local folder, then selects and expands it in the tree; with `files.mounts`, a **Mounted** strip lists the mount points, each with **Eject** (`data-action="eject"`, `data-path` the mount point) when the port has `eject`. A failed mount or eject shows its message under the bar. |
|
|
140
140
|
| `<slicc-file-view>` | One file (`path`), highlighted, with its pending change and a link to the diff. |
|
|
141
141
|
| `<slicc-changes>` | Pending changes with their author. Opens the diff, accepts or reverts one change or all of them. |
|
|
142
142
|
| `<slicc-diff-panel>` | The diff of one pending change (`path`), unified or split, with accept and revert. |
|
|
@@ -195,7 +195,7 @@ Paths are the agent's: `/shared/…` and `/home/…`, nothing else. A refusal or
|
|
|
195
195
|
| Port | Later backed by | |
|
|
196
196
|
| :--- | :--- | :--- |
|
|
197
197
|
| `agent` | `@ai-ecoverse/slicc-agent` | Cones and scoops, the active agent, conversations, `send` (with attachments, as a send, a steer or a queued follow-up) and `stop`, the queue, suggestions, answers to questions, permission decisions, compaction, clearing, the model per agent and new scoops. The optional `rewind(agentId, messageId)` drops the user turn before that message and everything after it, and resolves with the turn's prompt (text and attachments) for the composer, or `null`. The optional `drop(agentId)` removes a scoop (its files stay), and `createCone(name)` resolves with a new cone; the dummy rejects a cone name that is taken. Assistant messages stream: the same message is re-emitted as its parts grow and its tool calls go from `running` to `done`. |
|
|
198
|
-
| `files` | slicc-kernel's OPFS | `list`, `read`, `write`, `remove`, and pending changes with their before and after text (`accept`, `revert`). |
|
|
198
|
+
| `files` | slicc-kernel's OPFS | `list`, `read`, `write`, `remove`, and pending changes with their before and after text (`accept`, `revert`). The optional `mountFolder()` asks for a local folder and resolves with its mount point (for example `/mnt/photos`), or `null` when the user cancels; the panel calls it synchronously in the click, so the port can call `showDirectoryPicker()`. The optional `mounts()` lists the mount points, and `eject(path)` unmounts one (the folder stays on disk). The port emits `mounts` and then `files` after every mount and eject, including those made from the shell. |
|
|
199
199
|
| `terminals` | slicc-kernel's terminal API | Terminal sessions; `backend(id)` returns a `TerminalBackend` for `<slicc-terminal>`. |
|
|
200
200
|
| `browser` | `@ai-ecoverse/slicc-cdp` | Tabs, the active tab, `open`, `navigate`, `close`, `screenshot`. |
|
|
201
201
|
| `settings` | local storage | Theme, model, thinking level, composer and diff preferences, the models on offer, and accounts. |
|
|
@@ -205,7 +205,7 @@ Paths are the agent's: `/shared/…` and `/home/…`, nothing else. A refusal or
|
|
|
205
205
|
| `tray` | the tray protocol | Connection, role, float kind, followers, spend and budget; `reconnect` and `disconnect`. |
|
|
206
206
|
| `updates` (optional) | BIOS installers | `list()` returns `UpdateItem` rows for BIOS, kernel, agent, grammars, global pnpm packages, skills and UI. `ready()` explicitly reports agent readiness, independently of agent activity. Emit `items` whenever rows or readiness change. `act(id, action)` resolves when dispatched or rejects with a displayed error; actions are `retry`, `update-now`, `restart-agent` and `reload`. Missing ports preserve existing adapters and report disconnected information in the panel. Real installer wiring belongs to ai-ecoverse/slicc-bios#70. |
|
|
207
207
|
|
|
208
|
-
The dummy supports `createDummyModel({ updates: 'boot' | 'current' | 'available' | 'restart' | 'failure' })`, also selectable with `?updates=` on `/ui/`. Fixtures stay stable for inspection; `model.updates.setScenario('current')` completes boot. Dummy Update now and Retry simulate download and link progress; Restart agent and Reload only change fixture state, never restart a real process or reload the browser. `updateFixtures` and `DummyUpdates` are exported from `/dummy`.
|
|
208
|
+
The dummy supports `createDummyModel({ updates: 'boot' | 'current' | 'available' | 'restart' | 'failure' })`, also selectable with `?updates=` on `/ui/`. Fixtures stay stable for inspection; `model.updates.setScenario('current')` completes boot. Dummy Update now and Retry simulate download and link progress; Restart agent and Reload only change fixture state, never restart a real process or reload the browser. `updateFixtures` and `DummyUpdates` are exported from `/dummy`. `createDummyModel({ mounts: 'mount' | 'cancel' | 'fail' })` (or `?mounts=` on `/ui/`) turns on the optional mount members, which are off by default: `mountFolder` mounts invented files at `/mnt/photos`, resolves with `null`, or rejects, as `model.files.mount.scenario` says.
|
|
209
209
|
|
|
210
210
|
On phones the tray uses a compact indicator (its full status remains available on activation), the agent picker shrinks to fit, and the bottom rail scrolls when needed. The update status comes first so progress and failures remain reachable on narrow screens.
|
|
211
211
|
|
|
@@ -376,7 +376,8 @@ export {
|
|
|
376
376
|
o2,
|
|
377
377
|
l,
|
|
378
378
|
n5 as n,
|
|
379
|
-
e3
|
|
379
|
+
e3,
|
|
380
|
+
n6 as n2
|
|
380
381
|
};
|
|
381
382
|
/*! Bundled license information:
|
|
382
383
|
|
|
@@ -418,4 +419,4 @@ lit-html/directives/join.js:
|
|
|
418
419
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
419
420
|
*)
|
|
420
421
|
*/
|
|
421
|
-
//# sourceMappingURL=chunk-
|
|
422
|
+
//# sourceMappingURL=chunk-22NCU4NL.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
o
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-22NCU4NL.js";
|
|
4
4
|
import {
|
|
5
5
|
defineElement
|
|
6
6
|
} from "./chunk-6A6NIESE.js";
|
|
@@ -231,4 +231,4 @@ export {
|
|
|
231
231
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
232
232
|
*)
|
|
233
233
|
*/
|
|
234
|
-
//# sourceMappingURL=chunk-
|
|
234
|
+
//# sourceMappingURL=chunk-4F4N6IHX.js.map
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-EN3XGF2M.js";
|
|
7
7
|
import {
|
|
8
8
|
o
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-22NCU4NL.js";
|
|
10
10
|
import {
|
|
11
11
|
defineElement
|
|
12
12
|
} from "./chunk-6A6NIESE.js";
|
|
@@ -146,7 +146,7 @@ var Tooltip = class extends SpectrumElement {
|
|
|
146
146
|
<span id="tip" aria-hidden="true"></span>
|
|
147
147
|
</sp-tooltip-openable>
|
|
148
148
|
`;
|
|
149
|
-
return this.selfManaged ? (this.dependencyManager.add("sp-overlay"), import("./chunk-
|
|
149
|
+
return this.selfManaged ? (this.dependencyManager.add("sp-overlay"), import("./chunk-FAVZKAXS.js"), b`
|
|
150
150
|
<sp-overlay
|
|
151
151
|
?open=${this.open && !this.disabled && this.dependencyManager.loaded}
|
|
152
152
|
?delayed=${this.delayed}
|
|
@@ -178,4 +178,4 @@ o3([n({ type: Boolean })], Tooltip.prototype, "delayed", 2), o3([n({ type: Boole
|
|
|
178
178
|
|
|
179
179
|
// node_modules/@spectrum-web-components/tooltip/sp-tooltip.js
|
|
180
180
|
defineElement("sp-tooltip", Tooltip);
|
|
181
|
-
//# sourceMappingURL=chunk-
|
|
181
|
+
//# sourceMappingURL=chunk-6DBT3DUR.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Overlay
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MQNH3NIC.js";
|
|
4
4
|
import "./chunk-IBQ4O4NO.js";
|
|
5
5
|
import "./chunk-ZMBN6APP.js";
|
|
6
6
|
import "./chunk-KD66QY2Y.js";
|
|
7
7
|
import "./chunk-OS3ZND7O.js";
|
|
8
8
|
import "./chunk-JPIG5BAD.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-22NCU4NL.js";
|
|
10
10
|
import {
|
|
11
11
|
defineElement
|
|
12
12
|
} from "./chunk-6A6NIESE.js";
|
|
@@ -15,4 +15,4 @@ import "./chunk-AXQFWXYZ.js";
|
|
|
15
15
|
|
|
16
16
|
// node_modules/@spectrum-web-components/overlay/sp-overlay.js
|
|
17
17
|
defineElement("sp-overlay", Overlay);
|
|
18
|
-
//# sourceMappingURL=chunk-
|
|
18
|
+
//# sourceMappingURL=chunk-FAVZKAXS.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LONGPRESS_INSTRUCTIONS,
|
|
3
3
|
Overlay
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MQNH3NIC.js";
|
|
5
5
|
import "./chunk-IBQ4O4NO.js";
|
|
6
6
|
import "./chunk-ZMBN6APP.js";
|
|
7
7
|
import "./chunk-KD66QY2Y.js";
|
|
8
8
|
import "./chunk-OS3ZND7O.js";
|
|
9
9
|
import "./chunk-JPIG5BAD.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-22NCU4NL.js";
|
|
11
11
|
import "./chunk-WXAII75O.js";
|
|
12
12
|
import "./chunk-AXQFWXYZ.js";
|
|
13
13
|
export {
|
|
14
14
|
LONGPRESS_INSTRUCTIONS,
|
|
15
15
|
Overlay
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=chunk-
|
|
17
|
+
//# sourceMappingURL=chunk-I57ZVWF7.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-4F4N6IHX.js";
|
|
2
2
|
import "./chunk-OS3ZND7O.js";
|
|
3
3
|
import "./chunk-JPIG5BAD.js";
|
|
4
|
-
import "./chunk-
|
|
4
|
+
import "./chunk-22NCU4NL.js";
|
|
5
5
|
import "./chunk-6A6NIESE.js";
|
|
6
6
|
import "./chunk-WXAII75O.js";
|
|
7
7
|
import "./chunk-AXQFWXYZ.js";
|
|
8
|
-
//# sourceMappingURL=chunk-
|
|
8
|
+
//# sourceMappingURL=chunk-LZPC6RUV.js.map
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
import {
|
|
33
33
|
o as o2,
|
|
34
34
|
o2 as o3
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-22NCU4NL.js";
|
|
36
36
|
import {
|
|
37
37
|
A,
|
|
38
38
|
SpectrumElement,
|
|
@@ -186,7 +186,7 @@ var AbstractOverlay = class _AbstractOverlay extends SpectrumElement {
|
|
|
186
186
|
document.dispatchEvent(e2);
|
|
187
187
|
}
|
|
188
188
|
static async open(e2, r3, n2, a) {
|
|
189
|
-
await import("./chunk-
|
|
189
|
+
await import("./chunk-FAVZKAXS.js");
|
|
190
190
|
const m = arguments.length === 2, l2 = n2 || e2, t = new this();
|
|
191
191
|
let p = false;
|
|
192
192
|
t.dispose = () => {
|
|
@@ -1413,9 +1413,9 @@ var InteractionController = class {
|
|
|
1413
1413
|
return;
|
|
1414
1414
|
}
|
|
1415
1415
|
e2 && (customElements.whenDefined("sp-overlay").then(async () => {
|
|
1416
|
-
const { Overlay: t } = await import("./chunk-
|
|
1416
|
+
const { Overlay: t } = await import("./chunk-I57ZVWF7.js");
|
|
1417
1417
|
this.overlay = new t(), this.overlay.open = true, this.target[lastInteractionType] = this.type;
|
|
1418
|
-
}), import("./chunk-
|
|
1418
|
+
}), import("./chunk-FAVZKAXS.js"));
|
|
1419
1419
|
}
|
|
1420
1420
|
}
|
|
1421
1421
|
get overlay() {
|
|
@@ -1884,4 +1884,4 @@ export {
|
|
|
1884
1884
|
LONGPRESS_INSTRUCTIONS,
|
|
1885
1885
|
Overlay
|
|
1886
1886
|
};
|
|
1887
|
-
//# sourceMappingURL=chunk-
|
|
1887
|
+
//# sourceMappingURL=chunk-MQNH3NIC.js.map
|
package/dist/slicc-dummy.js
CHANGED
|
@@ -637,7 +637,7 @@ var DummyAgent = class extends Emitter {
|
|
|
637
637
|
}
|
|
638
638
|
freeze(agentId) {
|
|
639
639
|
const agent = this.#agent(agentId);
|
|
640
|
-
if (agent?.kind !== "cone") return;
|
|
640
|
+
if (agent?.kind !== "cone" || agent.frozen) return;
|
|
641
641
|
this.stop(agentId);
|
|
642
642
|
const family = this.#agents.filter(
|
|
643
643
|
(candidate) => candidate.id === agentId || candidate.parentId === agentId
|
|
@@ -669,7 +669,13 @@ var DummyAgent = class extends Emitter {
|
|
|
669
669
|
}
|
|
670
670
|
thaw(id) {
|
|
671
671
|
const ice = this.#ice.get(id);
|
|
672
|
-
if (!ice)
|
|
672
|
+
if (!ice) {
|
|
673
|
+
const agent = this.#agent(id);
|
|
674
|
+
if (!agent?.frozen) return null;
|
|
675
|
+
delete agent.frozen;
|
|
676
|
+
this.#changed();
|
|
677
|
+
return { ...agent };
|
|
678
|
+
}
|
|
673
679
|
this.#ice.delete(id);
|
|
674
680
|
this.#frozen = this.#frozen.filter((cone) => cone.id !== id);
|
|
675
681
|
for (const { agent, messages } of ice) {
|
|
@@ -1906,14 +1912,25 @@ function parents(path) {
|
|
|
1906
1912
|
return parts.map((_, i) => `/${parts.slice(0, i + 1).join("/")}`);
|
|
1907
1913
|
}
|
|
1908
1914
|
var DummyFiles = class extends Emitter {
|
|
1915
|
+
mount;
|
|
1916
|
+
mountFolder;
|
|
1917
|
+
mounts;
|
|
1918
|
+
eject;
|
|
1919
|
+
#mounted = /* @__PURE__ */ new Set();
|
|
1909
1920
|
#contents = /* @__PURE__ */ new Map();
|
|
1910
1921
|
#directories = /* @__PURE__ */ new Set();
|
|
1911
1922
|
#modified = /* @__PURE__ */ new Map();
|
|
1912
1923
|
#changes = /* @__PURE__ */ new Map();
|
|
1913
1924
|
#clock;
|
|
1914
|
-
constructor(contents, directories2, changes, clock2) {
|
|
1925
|
+
constructor(contents, directories2, changes, clock2, mount = null) {
|
|
1915
1926
|
super();
|
|
1916
1927
|
this.#clock = clock2;
|
|
1928
|
+
this.mount = mount;
|
|
1929
|
+
if (mount) {
|
|
1930
|
+
this.mountFolder = () => this.#mountFolder(mount);
|
|
1931
|
+
this.mounts = () => [...this.#mounted];
|
|
1932
|
+
this.eject = (path) => this.#eject(path);
|
|
1933
|
+
}
|
|
1917
1934
|
for (const directory of directories2) this.#mkdirs(`${directory}/`);
|
|
1918
1935
|
for (const [path, text] of Object.entries(contents)) this.#put(path, text, 0);
|
|
1919
1936
|
for (const change of changes) this.#changes.set(change.path, { ...change });
|
|
@@ -1998,6 +2015,38 @@ var DummyFiles = class extends Emitter {
|
|
|
1998
2015
|
else this.#put(path, change.before, Date.now());
|
|
1999
2016
|
this.#announce(path);
|
|
2000
2017
|
}
|
|
2018
|
+
async #mountFolder(mount) {
|
|
2019
|
+
await this.#clock.sleep();
|
|
2020
|
+
if (mount.scenario === "cancel") return null;
|
|
2021
|
+
if (mount.scenario === "fail") throw new Error("The folder couldn\u2019t be mounted.");
|
|
2022
|
+
const files3 = [];
|
|
2023
|
+
for (const [path, text] of Object.entries(mount.files)) {
|
|
2024
|
+
const file = `${mount.point}/${path}`;
|
|
2025
|
+
this.#put(file, text, Date.now());
|
|
2026
|
+
files3.push(file);
|
|
2027
|
+
}
|
|
2028
|
+
this.#mounted.add(mount.point);
|
|
2029
|
+
this.#remount(files3);
|
|
2030
|
+
return mount.point;
|
|
2031
|
+
}
|
|
2032
|
+
async #eject(path) {
|
|
2033
|
+
await this.#clock.sleep();
|
|
2034
|
+
if (!this.#mounted.delete(path)) throw new Error(`Nothing is mounted at ${path}.`);
|
|
2035
|
+
const inside = (candidate) => candidate === path || candidate.startsWith(`${path}/`);
|
|
2036
|
+
const files3 = [...this.#contents.keys()].filter(inside);
|
|
2037
|
+
for (const file of files3) {
|
|
2038
|
+
this.#contents.delete(file);
|
|
2039
|
+
this.#modified.delete(file);
|
|
2040
|
+
}
|
|
2041
|
+
for (const directory of [...this.#directories].filter(inside))
|
|
2042
|
+
this.#directories.delete(directory);
|
|
2043
|
+
this.#remount(files3);
|
|
2044
|
+
}
|
|
2045
|
+
#remount(files3) {
|
|
2046
|
+
this.emit("mounts", [...this.#mounted]);
|
|
2047
|
+
this.emit("files", this.#entries());
|
|
2048
|
+
for (const file of files3) this.emit("file", file);
|
|
2049
|
+
}
|
|
2001
2050
|
};
|
|
2002
2051
|
|
|
2003
2052
|
// src/dummy/showcase.ts
|
|
@@ -2913,6 +2962,13 @@ var files2 = {
|
|
|
2913
2962
|
"/tmp/forecast-sample.json": sample
|
|
2914
2963
|
};
|
|
2915
2964
|
var directories = ["/sessions", "/home/user/downloads"];
|
|
2965
|
+
var mountPoint = "/mnt/photos";
|
|
2966
|
+
var mounted = {
|
|
2967
|
+
"README.md": "# Photos\n\nHarbor shots for the forecast pages, one album per season.\n",
|
|
2968
|
+
"albums/autumn.json": '{ "title": "Autumn", "shots": ["breakwater-fog", "pier-at-dusk"] }\n',
|
|
2969
|
+
"albums/winter.json": '{ "title": "Winter", "shots": ["ice-on-the-buoys"] }\n',
|
|
2970
|
+
"captions.txt": "breakwater-fog: low cloud over the outer wall\npier-at-dusk: lamps on, tide out\n"
|
|
2971
|
+
};
|
|
2916
2972
|
var pending = [
|
|
2917
2973
|
{
|
|
2918
2974
|
path: "/workspace/harbor/src/lib/cache.ts",
|
|
@@ -3034,6 +3090,17 @@ var agents = [
|
|
|
3034
3090
|
model: "claude-haiku-4-5",
|
|
3035
3091
|
contextFill: 0.02,
|
|
3036
3092
|
unread: 0
|
|
3093
|
+
},
|
|
3094
|
+
{
|
|
3095
|
+
id: "cone-tides",
|
|
3096
|
+
name: "tide-tables",
|
|
3097
|
+
kind: "cone",
|
|
3098
|
+
parentId: null,
|
|
3099
|
+
status: "idle",
|
|
3100
|
+
model: "claude-sonnet-5-5",
|
|
3101
|
+
contextFill: 0.31,
|
|
3102
|
+
unread: 0,
|
|
3103
|
+
frozen: true
|
|
3037
3104
|
}
|
|
3038
3105
|
];
|
|
3039
3106
|
var start2 = Date.UTC(2026, 9, 5, 8, 30);
|
|
@@ -3164,6 +3231,12 @@ var conversations = {
|
|
|
3164
3231
|
{
|
|
3165
3232
|
type: "text",
|
|
3166
3233
|
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."
|
|
3234
|
+
},
|
|
3235
|
+
{
|
|
3236
|
+
type: "delegation",
|
|
3237
|
+
kind: "scoop",
|
|
3238
|
+
scoop: "quiet-otter",
|
|
3239
|
+
text: "Started a scoop to add retries around the upstream fetch"
|
|
3167
3240
|
}
|
|
3168
3241
|
]
|
|
3169
3242
|
},
|
|
@@ -3180,6 +3253,8 @@ var conversations = {
|
|
|
3180
3253
|
{
|
|
3181
3254
|
id: "m-o1",
|
|
3182
3255
|
role: "user",
|
|
3256
|
+
origin: "agent",
|
|
3257
|
+
from: "harbor",
|
|
3183
3258
|
text: "Wrap the upstream fetch in src/routes/forecast.ts with three retries and exponential backoff.",
|
|
3184
3259
|
createdAt: at2(9)
|
|
3185
3260
|
},
|
|
@@ -3219,6 +3294,26 @@ var conversations = {
|
|
|
3219
3294
|
],
|
|
3220
3295
|
"scoop-heron": [],
|
|
3221
3296
|
"scoop-wren": [],
|
|
3297
|
+
"cone-tides": [
|
|
3298
|
+
{
|
|
3299
|
+
id: "m-f1",
|
|
3300
|
+
role: "user",
|
|
3301
|
+
text: "Add a tide table endpoint next to the forecast, with high and low water per day.",
|
|
3302
|
+
createdAt: at2(-2900)
|
|
3303
|
+
},
|
|
3304
|
+
{
|
|
3305
|
+
id: "m-f2",
|
|
3306
|
+
role: "assistant",
|
|
3307
|
+
status: "done",
|
|
3308
|
+
createdAt: at2(-2898),
|
|
3309
|
+
parts: [
|
|
3310
|
+
{
|
|
3311
|
+
type: "text",
|
|
3312
|
+
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."
|
|
3313
|
+
}
|
|
3314
|
+
]
|
|
3315
|
+
}
|
|
3316
|
+
],
|
|
3222
3317
|
"cone-release": [
|
|
3223
3318
|
{
|
|
3224
3319
|
id: "m-r1",
|
|
@@ -3270,6 +3365,15 @@ var conversations = {
|
|
|
3270
3365
|
title: "/workspace/notes",
|
|
3271
3366
|
text: "File watch on /workspace/notes stopped; retrying",
|
|
3272
3367
|
createdAt: at2(-1429)
|
|
3368
|
+
},
|
|
3369
|
+
{
|
|
3370
|
+
id: "m-r5",
|
|
3371
|
+
role: "lick",
|
|
3372
|
+
channel: "workflow",
|
|
3373
|
+
title: "Release report",
|
|
3374
|
+
text: "The weekly release report is ready",
|
|
3375
|
+
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.",
|
|
3376
|
+
createdAt: at2(-1428)
|
|
3273
3377
|
}
|
|
3274
3378
|
],
|
|
3275
3379
|
"cone-triage": [
|
|
@@ -3945,10 +4049,12 @@ var DummyUpdates = class extends Emitter {
|
|
|
3945
4049
|
function createDummyModel({
|
|
3946
4050
|
delay = 30,
|
|
3947
4051
|
storage = null,
|
|
3948
|
-
updates = "current"
|
|
4052
|
+
updates = "current",
|
|
4053
|
+
mounts = "off"
|
|
3949
4054
|
} = {}) {
|
|
3950
4055
|
const time = clock(delay);
|
|
3951
|
-
const
|
|
4056
|
+
const mount = mounts === "off" ? null : { scenario: mounts, point: mountPoint, files: mounted };
|
|
4057
|
+
const files3 = new DummyFiles(files2, directories, pending, time, mount);
|
|
3952
4058
|
const browser = new DummyBrowser(tabs, time);
|
|
3953
4059
|
const agent = new DummyAgent(
|
|
3954
4060
|
agents,
|