@ai-ecoverse/slicc-spectrum 1.89.2 → 1.91.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 CHANGED
@@ -429,7 +429,7 @@ The secrets, sorted by name (`li[data-secret][data-state]`, with `[data-rules]`,
429
429
  Locked, every form (Add secret, Replace value, Import, Export) 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.
430
430
  Vault errors show their message, EACCES as "Unlock the vault first" and ENOTSUP as "This arrives with a later vault version".
431
431
  Each action shows only when the port has its method.
432
- Then **Rules SLICC refused** (`[data-refused]`), where the rules live (`[data-policy]`) and **Activity** (`ol.audit li[data-seq][data-type]`; an entry with `uid` and `tag` both `null` reads "by you", a `refresh` entry "Refreshed automatically" (with the sign-in it used), an `mcp` entry "Sent to the MCP server SERVER at DOMAIN" with its request and exit, and a policy entry lists its changes, its warning and, when accepted, how to change the file back; **Only reveals to programs**, `data-action="reveals"`, and **Show older**, `data-action="older"`).
432
+ Then **Rules SLICC refused** (`[data-refused]`), where the rules live (`[data-policy]`) and **Activity** (`ol.audit li[data-seq][data-type]`; an entry with `uid` and `tag` both `null` reads "by you", a `refresh` entry "Refreshed automatically" (with the sign-in it used), an `endpoints` entry (the vault removing model URLs an older agent registered) "Removed custom model URLs an agent set, automatically:" with each provider and URL and no "by …", an `mcp` entry "Sent to the MCP server SERVER at DOMAIN" with its request and exit, and a policy entry lists its changes, its warning and, when accepted, how to change the file back; **Only reveals to programs**, `data-action="reveals"`, and **Show older**, `data-action="older"`).
433
433
  The section's `data-vault` is `locked`, `unlocked` or `loading`.
434
434
  A popup the browser blocked shows how to allow it (`[data-popup=blocked]`).
435
435
  Widened-rule notices aren't shown.
@@ -449,7 +449,7 @@ It closes, clearing the field, when the request leaves `waiting` or while the va
449
449
  #### `<slicc-updates>`
450
450
 
451
451
  Install / Update: component states, version changes, last checks, download and link counts, action buttons, failures with Retry, and collapsible install logs behind a quiet chevron, which stay open across a layout switch.
452
- An install shows one bar for update rows and package rows alike: it fills 0–50% while downloading and 50–100% while linking (`value` against `max-value="100"`). While the row runs it never goes back, not when pnpm's total grows and not when progress drops out between passes. Its value label stays the phase's "n of m" count, and it starts at 0 again once the row settles.
452
+ An install shows one bar for update rows and package rows alike: it fills 0–50% while downloading and 50–100% while linking (`value` against `max-value="100"`). While the row runs it never goes back, not when pnpm's total grows and not when progress drops out between passes. While a download reports `bytes` with a total above 0, the first half fills by bytes and the value label reads "10.0 MB of 40.0 MB". Otherwise, and always while linking, the label falls back to the phase's "n of m" count. The bar starts at 0 again once the row settles.
453
453
  Opens at boot until the agent is ready without failures.
454
454
  Background updates stay in the header's update status; new failures reopen the panel, and after a reload into a boot that isn't ready yet such a panel closes once the agent is ready.
455
455
  Every automatic close is saved to the layout.
@@ -773,6 +773,7 @@ Connection, role, float kind, followers, spend and budget; `reconnect` and `disc
773
773
 
774
774
  Later backed by: BIOS installers.
775
775
  `list()` returns `UpdateItem` rows for BIOS, kernel, agent, grammars, global pnpm packages, skills and UI.
776
+ A row's and a package's `progress` (`InstallProgress`) is the `phase` (`download` or `link`) with `done` of `total` packages, and an optional `bytes` (`{ done, total }`), which counts only while `phase` is `download` (it's ignored while linking and when its total is 0), summed from pnpm's `Downloading <package>: <done>/<total>` lines; send it even when pnpm counts a single package, since a few large tarballs are most of an install's time.
776
777
  `ready()` explicitly reports agent readiness, independently of agent activity.
777
778
  Emit `items` whenever rows or readiness change.
778
779
  Use `queued` for a row that waits for another component before it starts; it reads "Waiting" and doesn't count as updating.
@@ -781,7 +782,7 @@ A `failed` row with an installed `from` version reads "Update failed".
781
782
  `act(id, action)` resolves when dispatched or rejects with a displayed error; actions are `retry`, `update-now`, `restart-agent` and `reload`.
782
783
  Missing ports preserve existing adapters and report disconnected information in the panel.
783
784
  Optional `packages()` returns `PackageItem` rows for optional tools, each with a short catalog `id`, its npm `package` (shown in the name's tooltip and at the top of its Install log), `label`, a one-sentence `description`, the `commands` it provides, `requires` (other package ids, read as "Uses Python" while it's installed, or "Installs Python too" on a row that isn't installed yet; an installed row leaves out a requirement that isn't installed, since its warning says so), optional `notes` (short plain-text lines shown muted under the row, such as "1 untested dependency: …"; leave it out when there's nothing to say), optional `warnings` (lines with an alert icon, `data-warnings`, such as "Needs Python, which isn't installed.
784
- Install Python again to use it."; the dummy adds that one when a required package is removed), `state` (`available`, `queued`, `installing`, `installed`, `outdated`, `updating`, `removing` or `failed`), the installed `version`, the `offered` version and its `size` in bytes, `progress` counted in packages (or `null` for an indeterminate bar), `error`, `actions` (`install`, `update`, `remove`, `retry`, `unpin`) and an optional `log`.
785
+ Install Python again to use it."; the dummy adds that one when a required package is removed), `state` (`available`, `queued`, `installing`, `installed`, `outdated`, `updating`, `removing` or `failed`), the installed `version`, the `offered` version and its `size` in bytes, `progress` (`InstallProgress`, or `null` for an indeterminate bar), `error`, `actions` (`install`, `update`, `remove`, `retry`, `unpin`) and an optional `log`.
785
786
  A row with `origin: 'user'` (ids such as `user:user:<name>`) goes into Your packages, `section[data-section="user-packages"]`, which only shows when there is one; its `pin` holds `base` (the version seven ships, or `null` for a package seven doesn't ship), the user's `range` and the `project` folder, such as `/opt/user`.
786
787
  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`.
787
788
  A pin that is `removing` reads "Unpinning"; other states keep their usual lights.
@@ -927,7 +928,7 @@ Pass only the surfaces a follower has to `<slicc-app>` (agents, chat, terminal a
927
928
 
928
929
  The dummy supports `createDummyModel({ updates: 'boot' | 'starting' | 'current' | 'available' | 'restart' | 'failure' })`, also selectable with `?updates=` on `/ui/`.
929
930
  Fixtures stay stable for inspection; `model.updates.setScenario('current')` completes boot.
930
- 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.
931
+ 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.
931
932
  `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`).
932
933
  `updateFixtures`, `packageFixtures` and `DummyUpdates` are exported from `/dummy`.
933
934
  `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.
@@ -981,7 +982,8 @@ Like slicc-agent's snapshot, the dummy's vitals are the budget, Spend, Active ag
981
982
  (`guest-follower`: the same without `decide`), or (`guest-always`) one guest tool call from Seat 2 (Mara) to `read_file` with `always: true`.
982
983
  Decisions are recorded in `model.approvals.decisions`, and `model.approvals.end(id, reason)` ends a request.
983
984
 
984
- `createDummyModel({ vault: 'empty' | 'secrets' | 'policy' | 'locked' | 'request' | 'backup' | 'waiting' | 'off' })` (`?vault=` on `/ui/`, off by default; `notice` is kept as another name for `policy`) adds an invented vault: no secrets yet; five secrets (an API key, a jerk lease from pier-nuc revealed to `pier publish`, a Tide Mail sign-in, one without a rule and a removed one) with an activity log that pages back once; the same with a refused rule and a policy change in the log; locked before the first unlock, with a waiting request from docs-pass; unlocked with a `fnox set` request for `TIDE_STATION_TOKEN`; the secrets with a due backup reminder; or a vault that hasn't answered yet (`model.vault.arrive()` brings it).
985
+ `createDummyModel({ vault: 'empty' | 'secrets' | 'policy' | 'locked' | 'request' | 'backup' | 'waiting' | 'purged' | 'off' })` (`?vault=` on `/ui/`, off by default; `notice` is kept as another name for `policy`) adds an invented vault: no secrets yet; five secrets (an API key, a jerk lease from pier-nuc revealed to `pier publish`, a Tide Mail sign-in, one without a rule and a removed one) with an activity log that pages back once; the same with a refused rule and a policy change in the log; locked before the first unlock, with a waiting request from docs-pass; unlocked with a `fnox set` request for `TIDE_STATION_TOKEN`; the secrets with a due backup reminder; or a vault that hasn't answered yet (`model.vault.arrive()` brings it).
986
+ `purged` is `secrets` plus an `endpoints` audit entry for two invented model URLs.
985
987
  It implements every op with the vault's checks, and keeps only names: `model.vault.puts` records `{ name, request? }`, `cancelled` the cancelled requests, `imports` each import's kind, size and pick, and `exported` the exports.
986
988
  Import offers five invented candidates (one replaces a secret, one is a model key, one is refused with a reason that the done stage repeats; KeePass adds a `_2` duplicate), six answers ENOTSUP, page ops are recorded with `uid: null, tag: null`, and value ops while locked answer EACCES.
987
989
  `model.vault.fail(code, message)` makes the next op fail.
@@ -6646,10 +6646,21 @@ var DummyUpdates = class extends Emitter {
6646
6646
  log: `${log}
6647
6647
  Progress: resolved 1, downloaded 0, added 0`
6648
6648
  });
6649
- await this.#clock.sleep(4);
6649
+ await this.#clock.sleep(2);
6650
+ if (item.size !== void 0) {
6651
+ const half = Math.round(item.size / 2);
6652
+ this.#patchPackage(id, {
6653
+ progress: { phase: "download", done: 0, total: 1, bytes: { done: half, total: item.size } },
6654
+ log: `${log}
6655
+ Progress: resolved 1, downloaded 0, added 0
6656
+ Downloading ${item.package}@${item.offered}: ${half} B/${item.size} B`
6657
+ });
6658
+ }
6659
+ await this.#clock.sleep(2);
6650
6660
  if (this.#fail) {
6651
6661
  this.#patchPackage(id, {
6652
6662
  state: "failed",
6663
+ progress: null,
6653
6664
  error: fetchFailed,
6654
6665
  actions: ["retry"],
6655
6666
  log: `${log}
@@ -7009,6 +7020,20 @@ function vaultRefused() {
7009
7020
  }
7010
7021
  ];
7011
7022
  }
7023
+ function vaultPurged(now2 = Date.now()) {
7024
+ return {
7025
+ type: "endpoints",
7026
+ seq: 13,
7027
+ id: "audit-13",
7028
+ at: now2 - 30 * minute3,
7029
+ uid: null,
7030
+ tag: null,
7031
+ purged: [
7032
+ { provider: "openai", url: "https://models.harbor.example/v1" },
7033
+ { provider: "anthropic", url: "https://relay.harbor.example" }
7034
+ ]
7035
+ };
7036
+ }
7012
7037
  function vaultPolicy(now2 = Date.now()) {
7013
7038
  return {
7014
7039
  type: "policy",
@@ -7098,7 +7123,11 @@ function vaultFixtures(scenario, now2 = Date.now()) {
7098
7123
  const list = {
7099
7124
  secrets,
7100
7125
  refused: policy ? vaultRefused() : [],
7101
- audit: empty ? [] : [...policy ? [vaultPolicy(now2)] : [], ...vaultAudit(now2)],
7126
+ audit: empty ? [] : [
7127
+ ...policy ? [vaultPolicy(now2)] : [],
7128
+ ...scenario === "purged" ? [vaultPurged(now2)] : [],
7129
+ ...vaultAudit(now2)
7130
+ ],
7102
7131
  auditMore: !empty,
7103
7132
  exits: {
7104
7133
  file: "/etc/slicc/secrets-policy.toml",
@@ -7604,6 +7633,7 @@ export {
7604
7633
  vaultNotice,
7605
7634
  vaultOlder,
7606
7635
  vaultPolicy,
7636
+ vaultPurged,
7607
7637
  vaultRefused,
7608
7638
  vaultSecrets
7609
7639
  };