@ai-ecoverse/slicc-spectrum 2.9.0 → 2.9.2
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 +6 -5
- package/dist/slicc-dummy.js +10 -2
- package/dist/slicc-dummy.js.map +2 -2
- package/dist/slicc-kernel-model.js.map +2 -2
- package/dist/slicc-ui.js +162 -58
- package/dist/slicc-ui.js.map +3 -3
- package/dist/types/app/browser.d.ts +28 -1
- package/dist/types/dummy/browser.d.ts +11 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -431,10 +431,11 @@ Sessions stay alive while hidden; `exit` closes the tab.
|
|
|
431
431
|
|
|
432
432
|
What the agents' browser control is doing.
|
|
433
433
|
It opens on the most recently driven tab (`.focused`), or on the tab overview: cards (`li[data-id]`, `data-controlled` while an agent drives the tab, `data-pulse` when another tab starts being driven, without switching to it) with a thumbnail, the agent and a small **Stop <agent>** (`data-action="stop-agent"`), and an address bar to open a URL.
|
|
434
|
-
The focused tab
|
|
434
|
+
The focused tab is preview-first: **All tabs** (`data-action="all-tabs"`) with a tab picker (a list of tabs at 720 px and wider) on one row, the URL with **Copy** (`data-action="copy-url"`) and **Open** (`data-action="open-tab"`, activates the tab) on the next, who's using it (`.driving[data-driving=agent|user|none]`; **Watching <agent>** while an agent drives, **In use** when a controlled tab has no agent and no Stop) with a small **Stop <agent>** (`data-action="stop-agent"`) in the same row, which keeps its height with or without an agent, a watching-only preview (`figure[data-view]`: `live` while watching with a frame under 3 s old, `shot` with "Updated N s ago", `none`; the caption says **Watching only**) that keeps a 16:10 frame, and a **Recent actions** feed (`.feed`) that fills the leftover height.
|
|
435
|
+
Recent actions (`li[data-action-id][data-kind][data-status]`, failures with their error inline) are newest first: the tab's own filtered first, then the latest 50, with **Show more** (`data-action="more-actions"`) adding 50 earlier ones each time up to all the port has ("Showing the latest N of M"); the list scrolls and takes focus.
|
|
436
|
+
Consecutive identical done actions fold into one row (`li[data-group]`) with a count (`×n`).
|
|
435
437
|
Actions with a URL (`open`, `goto`, `request`) expand (`data-action="action-url"`, `aria-expanded`) to show the full URL, or the request line, under the shortened one.
|
|
436
|
-
|
|
437
|
-
The tab the user opened (or **All tabs**), expanded URLs and an open **Recent actions** hold for every view of the panel on the same model, so a layout switch keeps them; a closed tab lets go, and the panel opens on the most recently driven tab again.
|
|
438
|
+
The tab the user opened (or **All tabs**) and expanded URLs hold for every view of the panel on the same model, so a layout switch keeps them; a closed tab lets go, and the panel opens on the most recently driven tab again.
|
|
438
439
|
Labels, URLs and errors are text only.
|
|
439
440
|
With no tabs and `browser.via` `null` in the network status, it says browser control isn't connected (`data-browser="none"`) with the extension link and the commands to install and run slicc (`curl -fsSL https://get.sliccy.ai/slicc | sh`, then `slicc`, or `npx sliccy@next` with Node).
|
|
440
441
|
The Browser rail button carries a dot (`data-driven`) while a tab is in use.
|
|
@@ -483,10 +484,10 @@ Values go only to `vault.put` and are never kept on the element or put in an eve
|
|
|
483
484
|
The head shows **Locked** or **Unlocked**, then, when `status.policy` marks a file `paused`, a second light (`[data-paused]`) "Paused: {file} is missing" ("Paused: {file} and 1 more are missing" for both), and the lock mode ("Unlocks automatically in this browser", "Unlocks with a passkey" or "Unlocks with a passphrase"); locked, the vault's **Unlock** button (`slicc-vault-button[data-action=unlock]`); unlocked, **Lock** (`data-action="lock"`, with `lock`) and the vault's **Protect with a passkey** (lock `auto`) or **Change protection** button (`data-action="protect"`).
|
|
484
485
|
A status line (`[data-availability]`) says "Waiting for the vault" while `availability()` is `connecting` or `waiting` (or `status()` is `null` without it), and "Unlock the vault to continue" while `scrub.needed` and not `scrub.ready`.
|
|
485
486
|
Waiting requests show under **Waiting for you** (`[data-request]`, the agent's `prompt` as plain text under "From the agent, not checked by SLICC:", capped at 200 characters, and "Expires in N min"), with **Enter value** (`data-action="answer"`, which fires `value-request` with `{ id, vault }` for the `<slicc-value-request>` on the same vault) for `value` requests and **Cancel request** (`data-action="cancel-request"`); `oauth`, `jerk-seal`, `jerk` and `unseal` requests say what they ask for and offer Cancel request only.
|
|
486
|
-
With `backupReminder: 'due'`, an alert (`[data-backup]`) offers **Export backup** (`data-action="export"`) and **Not now** (`data-action="dismiss-backup"`, with `dismissBackupReminder`).
|
|
487
487
|
**Add secret** (`data-action="add-secret"`, `[data-form=add]`, a name and a value; a name that exists asks before it replaces the value; with `vault.enter` and `valueFrame`, a name and **Next** (`data-action="enter-value"`), which opens `vault.enter` (with `replace: true` after that question) and shows the vault's own field (`[data-form][data-entry] slicc-vault-value`); **Replace value** opens `vault.enter({ name, kind, provider | server, replace: true })` and that field at once; the frame's `done` closes the form and says it was saved (with the name the form asked for when `done` carries none), and Cancel, Escape, the frame's `escape`, another form and a change of vault cancel the request), **Import…** (`data-action="import"`, `[data-form=import]`: Bundle, KeePass or six, a file, an optional password, then a pick of candidates, all checked but the `refused` ones (disabled, with their reason), marked "Replaces a secret" when they exist, with their suggested rules as untrusted text and a note that the file's rules aren't applied, and **Import N**, which sends `{ name, kind }` for a candidate of another `kind`; then "Imported N" and "Skipped NAME: reason" for each skipped name, from `reasons`) and **Export…** (`data-action="export"`, `[data-form=export]`: a passphrase twice, at least 8 bytes, behind a confirmation, downloaded as `slicc-secrets-<yyyy-mm-dd>.slicc-vault`, with "Last exported" or "Never exported" from `exportedAt`).
|
|
488
488
|
Saved shows "Saved NAME in the vault" (`[data-said]`).
|
|
489
|
-
The secrets, sorted by name (`li[data-secret][data-state]`, with `[data-rules]`, `[data-exits]` only when restricted, `[data-exec]` (any command, the listed commands, every bash) and how often programs were given it today, `[data-source]`, `[data-used]`, `[data-expires]`; a model record or an MCP token no rule names reads “Used for” (`[data-used-for]`, model requests to its provider or requests to its MCP server, by the agent) instead of where it's sent, with its account's state as its light, and shows its Provider (`[data-provider]`, the account's name) or Server (`[data-server]`)) offer **Replace value** (`data-action="replace"`, for `settings`, `process` and `import:*` secrets that aren't sign-ins) and **Remove** (`data-action="remove"`, behind a confirmation, passing the secret's `kind`), and removed ones, under **Removed**, **Restore** (`data-action="restore"`; ENOENT reads "Removed too long ago to restore").
|
|
489
|
+
The secrets, sorted by name (`li[data-secret][data-state]`, with `[data-rules]`, `[data-exits]` only when restricted, `[data-exec]` (any command, the listed commands, every bash) and how often programs were given it today — the last argv in that "Revealed to programs…" line is capped at 120 characters with an ellipsis, while Activity keeps the full command; the allow-list and reveal lines are not CSS-clamped, `[data-source]`, `[data-used]`, `[data-expires]`; a model record or an MCP token no rule names reads “Used for” (`[data-used-for]`, model requests to its provider or requests to its MCP server, by the agent) instead of where it's sent, with its account's state as its light in `.aside` beside the row actions, and shows its Provider (`[data-provider]`, the account's name) or Server (`[data-server]`)) offer **Replace value** (`data-action="replace"`, for `settings`, `process` and `import:*` secrets that aren't sign-ins) and **Remove** (`data-action="remove"`, behind a confirmation, passing the secret's `kind`), and removed ones, under **Removed**, **Restore** (`data-action="restore"`; ENOENT reads "Removed too long ago to restore").
|
|
490
|
+
With `backupReminder: 'due'`, an alert below the list (`[data-backup]`) offers **Export backup** (`data-action="export"`) and **Not now** (`data-action="dismiss-backup"`, with `dismissBackupReminder`).
|
|
490
491
|
Locked, every form (Add secret and Replace value without `vault.enter`, Import, Export; with it, the vault's field unlocks itself) says "Unlock the vault first" (`p[data-locked]`) next to the vault's own small **Unlock** button (`slicc-vault-button[data-action=unlock]`) and disables its submit; once unlocked, the form stays open with what was typed and its submit enables.
|
|
491
492
|
Vault errors show their message, EACCES as "Unlock the vault first", an EACCES with `cause: 'policy-paused'` as "Secrets are paused until the missing policy file is back", and ENOTSUP as "This arrives with a later vault version".
|
|
492
493
|
Each action shows only when the port has its method.
|
package/dist/slicc-dummy.js
CHANGED
|
@@ -721,10 +721,15 @@ var DummyBrowser = class extends Emitter {
|
|
|
721
721
|
this.finish(action.id, "Stopped");
|
|
722
722
|
if (changed) this.emit("tabs", this.list());
|
|
723
723
|
}
|
|
724
|
-
watch
|
|
724
|
+
#watch = null;
|
|
725
|
+
lastWatch() {
|
|
726
|
+
return this.#watch;
|
|
727
|
+
}
|
|
728
|
+
watch(tabId, size) {
|
|
725
729
|
const tab = () => this.#tabs.find((candidate) => candidate.id === tabId);
|
|
726
730
|
if (!tab()?.controlled) return () => {
|
|
727
731
|
};
|
|
732
|
+
this.#watch = { tabId, size: size ? { ...size } : void 0 };
|
|
728
733
|
const send = () => {
|
|
729
734
|
const now2 = tab();
|
|
730
735
|
if (!now2?.controlled) return;
|
|
@@ -732,7 +737,10 @@ var DummyBrowser = class extends Emitter {
|
|
|
732
737
|
};
|
|
733
738
|
const timer = setInterval(send, 500);
|
|
734
739
|
void this.#clock.sleep(0).then(send);
|
|
735
|
-
return () =>
|
|
740
|
+
return () => {
|
|
741
|
+
clearInterval(timer);
|
|
742
|
+
if (this.#watch?.tabId === tabId) this.#watch = null;
|
|
743
|
+
};
|
|
736
744
|
}
|
|
737
745
|
#changed() {
|
|
738
746
|
this.emit("tabs", this.list());
|