@ai-ecoverse/slicc-spectrum 1.98.0 → 1.99.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 +15 -4
- package/dist/slicc-dummy.js +36 -2
- package/dist/slicc-dummy.js.map +2 -2
- package/dist/slicc-ui.js +2977 -2654
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/composer.d.ts +1 -0
- package/dist/types/app/memory.d.ts +15 -3
- package/dist/types/dummy/updates.d.ts +1 -1
- package/dist/types/model/types.d.ts +7 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -349,7 +349,11 @@ On a follower while the link reconnects, the field is disabled and says so; the
|
|
|
349
349
|
While the agent port's `starting()` returns a line (no agent yet, but one is on its way), the composer stays usable: its placeholder is that line, there are no `/` or `@` popups, and sending, attachments included, adds a row above the field that reads "Sent when the agent starts" (`li.queued[data-mode="starting"]`), which can be dropped (`data-action="unqueue"`); a row with text and files says how many files go with it (`[data-files]`).
|
|
350
350
|
Whenever the model changes or its agent port fires `starting` or `agents`, and the current model's port has no line (`null`, or no `starting` at all) and `agent.list()` has an agent, the composer sends the rows in order to that model's active agent (else the first one) through `agent.send`, the first like a normal send and the rest with `mode: 'queue'`, and the rows go; if the line clears with no agent, the rows stay until one comes.
|
|
351
351
|
A line that comes back closes an open `/` or `@` popup.
|
|
352
|
-
The rows are kept for the page (for the `<slicc-app>` the composer is in, else for the document), not for the model, so a model swap (an embedder that puts a new `SliccModel` on `<slicc-app>` once the agent is there), a layout switch and a dock rebuild keep them
|
|
352
|
+
The rows are kept for the page (for the `<slicc-app>` the composer is in, else for the document), not for the model, so a model swap (an embedder that puts a new `SliccModel` on `<slicc-app>` once the agent is there), a layout switch and a dock rebuild keep them.
|
|
353
|
+
They're also kept in `sessionStorage` (`slicc-spectrum.starting`, so per origin and per tab) until they're sent or dropped: each row's text and `mode`, and only the name, type and size of its attachments, never their contents; each page (each `<slicc-app>`, or the document) rewrites only its own rows there.
|
|
354
|
+
Only a reload of the same tab brings them back (the navigation's type is `reload`); any other load, such as a duplicated tab that got a copy of the storage, clears them, so nothing is sent twice.
|
|
355
|
+
After a reload the rows come back in order with their text, and a second, muted line says "Not kept after reload: tides.csv" (`[data-lost]`), since attachments can't be restored; on arrival the text is sent without them.
|
|
356
|
+
A row that had only attachments shows an alert icon instead of the clock and reads "Not sent. Attach the files again." (`[data-unsent]`, with a **Dismiss** close button) instead of "Sent when the agent starts", isn't sent, and stays until it's dismissed; the "Not kept after reload" line starts with an alert icon too.
|
|
353
357
|
Text typed but not sent while it starts is kept for the page the same way, and stays in the field once the agent arrives.
|
|
354
358
|
While the agent holds tool results for the vault (`agent.hold()`), a status line above it says "Waiting for the vault" or "Unlock the vault to continue", with how many results are held, and offers the vault's **Unlock** button when locked and the model has a `vault`; if the browser blocks the vault window, the line says to allow pop-ups.
|
|
355
359
|
With the model's `seat` set it's a guest's composer: <kbd>Enter</kbd> and the send button send through `agent.send(cone, text)`, <kbd>Shift</kbd>+<kbd>Enter</kbd> adds a line and <kbd>↑</kbd>/<kbd>↓</kbd> walk the guest's own messages; there's no steer, queue, Stop, attachments (the field is `collapsed`, so its + is hidden and inert, and pasted files are ignored), `/` commands, `@` mentions, + menu or push to talk, and it never reads files; its description is "Enter sends, Shift+Enter adds a new line."
|
|
@@ -478,8 +482,10 @@ What agents remember, grouped by section: search, filter by scope and tag, expan
|
|
|
478
482
|
The scope picker starts on **Everyone** (`*`), which lists every memory with its scope on it (`.scope[data-scope]`); `global` reads **Shared** whatever the port calls it, and the cones and roles follow.
|
|
479
483
|
The count (“N of M memories”) counts the memories in the picked scope.
|
|
480
484
|
With a search or tag filter that hides everything it says “No memories match.”, otherwise “No memories yet.”, “No shared memories yet.” or “No memories for {scope} yet.”
|
|
481
|
-
Each memory is a row (`li.row[data-id]`)
|
|
482
|
-
|
|
485
|
+
Each memory is a row (`li.row[data-id]`, divided from the next by a rule) with one structure open or closed: the title line (`.head`, the disclosure button) keeps its chevron, title and marks where they are, and the text below it (`.content`) shows two lines closed and grows into the full text in place when the row opens, so opening only adds height below. It stays open across a layout switch. Open rows (`data-open`) take no fill, so nothing reads as selected; the chevron turns down. Height and chevron move like Spectrum's accordion (`--swc-animation-duration-100`, ease in and out), and not at all under `prefers-reduced-motion`. A click on a closed row's text opens it too.
|
|
486
|
+
An open row ends in an action row at the trailing end: **Edit** and **Forget** (`data-action="edit"`, `data-action="forget"`), Forget in the negative content colour and asking first with the destructive confirm.
|
|
487
|
+
At the end of the title line, small icons (`.mark`, `role="img"` with an `aria-label` and a tooltip) carry the metadata: the tag (`.tag[data-tag]`: User a file with a person, Feedback a comment, Project a briefcase), “From MEMORY.md” for free text outside an entry (`.from`), and under Everyone the scope (`.scope[data-scope]`: Shared a group of people, a cone a person, a role a person with a gear, labelled “Shared” or “{name} only”).
|
|
488
|
+
The tag is left out where the list already says it: under a section heading that names it (Projects, User, Feedback) and while the tag filter picks it.
|
|
483
489
|
Below 560 px of panel width, the search takes its own line over the two pickers.
|
|
484
490
|
The search field is the shared one from `search.ts` (`sp-search[data-action=search]`), as in Files.
|
|
485
491
|
|
|
@@ -804,6 +810,11 @@ A row with `origin: 'user'` (ids such as `user:user:<name>`) goes into Your pack
|
|
|
804
810
|
An installed pin reads "Pinned" with `0.24.0 · seven ships 0.25.0 · in /opt/agent` ("the version seven ships" when they match), and an addition reads "Added" with `^1.2.0 → 1.2.4 · in /opt/user`; `.meta[data-pin]` is `pinned` or `added`.
|
|
805
811
|
A pin that is `removing` reads "Unpinning"; other states keep their usual lights.
|
|
806
812
|
Offer `unpin` for pins and `remove` for additions.
|
|
813
|
+
Optional `installs` lists where a package is installed, each with its `version`, `where` (a folder such as `/home/cone/.local/share/pnpm`), an optional `user` and an optional `manager` (`pnpm` or `panel`).
|
|
814
|
+
A row with any install never offers `install`, nor `remove` unless one install's `manager` is `panel`, and one the port still reports as `available` reads Installed, or Update available when `offered` differs, with its first install's `version`.
|
|
815
|
+
Each install the panel doesn't own shows in the meta line as `[data-install]`, such as "for cone, via pnpm" or "in /opt/tools", with its version in front when it differs from the row's; when the panel's copy sits next to others it reads "the panel’s copy" (`[data-install="panel"]`) and Remove's accessible name is "Remove the panel’s copy of <label>", since it removes only that copy.
|
|
816
|
+
When no install is the panel's, `[data-managed]` under it reads "Managed by pnpm. Remove it with `pnpm remove -g <package>`." (the command in a `code` element; or "Installed outside this panel. Remove it where it was installed." for another manager).
|
|
817
|
+
Offer `update` for such a row to update it in place, for that user and with that manager, never as a second copy; never offer `remove` for it.
|
|
807
818
|
Emit `packages` whenever they change.
|
|
808
819
|
`actPackage(id, action)` keeps the row's button pending until it settles; it shows any confirm itself, resolves without a change when that confirm is cancelled, and rejects with a displayed error on a real failure.
|
|
809
820
|
Hooks: `section[data-section="packages"]`, `li[data-id][data-state]`, buttons with `data-action`, `[data-requires]`, `[data-notes]` and `[data-error]`.
|
|
@@ -946,7 +957,7 @@ Pass only the surfaces a follower has to `<slicc-app>` (agents, chat, terminal a
|
|
|
946
957
|
The dummy supports `createDummyModel({ updates: 'boot' | 'starting' | 'current' | 'available' | 'restart' | 'failure' })`, also selectable with `?updates=` on `/ui/`.
|
|
947
958
|
Fixtures stay stable for inspection; `model.updates.setScenario('current')` completes boot.
|
|
948
959
|
Dummy Update now and Retry simulate download and link progress, and a dummy package install reports half its `size` in bytes on the way; Restart agent and Reload only change fixture state, never restart a real process or reload the browser.
|
|
949
|
-
`createDummyModel({ packages: 'mixed' | 'empty' | 'fail' | 'user' | 'off' })` (or `?packages=` on `/ui/`, off by default) adds invented optional packages in every state: Install and Retry finish after a short wait and install missing requirements too, `fail` makes them fail, `user` adds a pinned agent-kit and two additions (one with a warning) that Unpin and Remove take out of the list, and removing Python while uv is installed asks through the `confirm` option (the `/ui/` page passes spectrum's `confirm`).
|
|
960
|
+
`createDummyModel({ packages: 'mixed' | 'empty' | 'fail' | 'user' | 'elsewhere' | 'off' })` (or `?packages=` on `/ui/`, off by default) adds invented optional packages in every state: Install and Retry finish after a short wait and install missing requirements too, `fail` makes them fail, `user` adds a pinned agent-kit and two additions (one with a warning) that Unpin and Remove take out of the list, `elsewhere` has git installed for cone with pnpm and TypeScript there at an older version, whose Update keeps it in place, and Biome both from the panel and for cone, whose Remove leaves cone's copy, and removing Python while uv is installed asks through the `confirm` option (the `/ui/` page passes spectrum's `confirm`).
|
|
950
961
|
`updateFixtures`, `packageFixtures` and `DummyUpdates` are exported from `/dummy`.
|
|
951
962
|
`createDummyModel({ mounts: 'mount' | 'cancel' | 'fail' | 'needs' })` (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; `needs` also lists `/mnt/photos` in `needsFolder()` until a folder is inserted there.
|
|
952
963
|
`createDummyModel({ network: 'ok' | 'limited' | 'failing' | 'off' })` (or `?network=` on `/ui/`, default `limited`) sets the dummy network: slicc on this computer as a linked device (`route: 'link'`, with browser automation through it), the page fetch with CORS failures, or no route, all invented; `off` leaves out the port.
|
package/dist/slicc-dummy.js
CHANGED
|
@@ -3291,7 +3291,7 @@ var memories = [
|
|
|
3291
3291
|
scope: "cone-harbor",
|
|
3292
3292
|
section: "Conventions",
|
|
3293
3293
|
title: "Cache keys",
|
|
3294
|
-
body: "Cache keys are `city:UTC-date`. Never key on local time.",
|
|
3294
|
+
body: "Cache keys are `city:UTC-date`. Never key on local time.\n\nThe warmer fills the next day\u2019s keys at 23:00 UTC, so a key built from local time misses it and every request goes upstream until midnight. `npm run cache:check` lists the keys that don\u2019t match.",
|
|
3295
3295
|
tag: "project",
|
|
3296
3296
|
updatedAt: now - 2 * day4
|
|
3297
3297
|
},
|
|
@@ -5131,6 +5131,24 @@ function packageFixtures(scenario) {
|
|
|
5131
5131
|
actions: ["retry"],
|
|
5132
5132
|
log: "Packages: +1\nERR_PNPM_FETCH_TIMEOUT Request timed out after 30000ms"
|
|
5133
5133
|
});
|
|
5134
|
+
if (scenario === "elsewhere") {
|
|
5135
|
+
const cone = (version) => [
|
|
5136
|
+
{ version, where: "/home/cone/.local/share/pnpm", user: "cone", manager: "pnpm" }
|
|
5137
|
+
];
|
|
5138
|
+
patch("git", { state: "installed", version: "2.47.1", actions: [], installs: cone("2.47.1") });
|
|
5139
|
+
patch("tsc", {
|
|
5140
|
+
state: "outdated",
|
|
5141
|
+
version: "5.8.2",
|
|
5142
|
+
actions: ["update"],
|
|
5143
|
+
installs: cone("5.8.2")
|
|
5144
|
+
});
|
|
5145
|
+
patch("biome", {
|
|
5146
|
+
installs: [
|
|
5147
|
+
{ version: "2.2.4", where: "/usr/local/share/pnpm", manager: "panel" },
|
|
5148
|
+
...cone("2.2.4")
|
|
5149
|
+
]
|
|
5150
|
+
});
|
|
5151
|
+
}
|
|
5134
5152
|
return scenario === "user" ? [...items, ...userPackages()] : items;
|
|
5135
5153
|
}
|
|
5136
5154
|
var DummyUpdates = class extends Emitter {
|
|
@@ -5191,6 +5209,16 @@ var DummyUpdates = class extends Emitter {
|
|
|
5191
5209
|
}
|
|
5192
5210
|
this.#patchPackage(id, { state: "removing", error: null, actions: [] });
|
|
5193
5211
|
await this.#clock.sleep(2);
|
|
5212
|
+
const kept = item.installs?.filter((install) => install.manager !== "panel") ?? [];
|
|
5213
|
+
if (kept.length) {
|
|
5214
|
+
this.#patchPackage(id, {
|
|
5215
|
+
state: "installed",
|
|
5216
|
+
version: kept[0].version,
|
|
5217
|
+
installs: kept,
|
|
5218
|
+
log: void 0
|
|
5219
|
+
});
|
|
5220
|
+
return;
|
|
5221
|
+
}
|
|
5194
5222
|
this.#patchPackage(id, {
|
|
5195
5223
|
state: "available",
|
|
5196
5224
|
version: null,
|
|
@@ -5244,7 +5272,13 @@ ERR_PNPM_FETCH_TIMEOUT Request timed out after 30000ms`
|
|
|
5244
5272
|
state: "installed",
|
|
5245
5273
|
version: item.offered,
|
|
5246
5274
|
progress: null,
|
|
5247
|
-
actions: ["remove"],
|
|
5275
|
+
actions: item.installs ? [] : ["remove"],
|
|
5276
|
+
...item.installs ? {
|
|
5277
|
+
installs: item.installs.map((install) => ({
|
|
5278
|
+
...install,
|
|
5279
|
+
version: item.offered
|
|
5280
|
+
}))
|
|
5281
|
+
} : {},
|
|
5248
5282
|
log: `${log}
|
|
5249
5283
|
Progress: resolved 1, downloaded 1, added 1
|
|
5250
5284
|
Done in 3.8s`
|