@ai-ecoverse/slicc-spectrum 2.6.0 → 2.7.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
@@ -358,7 +358,8 @@ Renders nothing without the port.
358
358
  The message box uses Spectrum Web Components 2.0.0-beta.6. Its explicit accessible names stay "Message" for the textarea, "Send" ("Steer" while busy) for send, "Add" for upload and "Stop" for stop, using `accessible-label`, `send-accessible-label`, `upload-accessible-label` and `stop-accessible-label`. Attachment navigation stays "Show previous attachments" / "Show more attachments", and the strip stays "Uploaded assets strip", through their `*-accessible-label` attributes.
359
359
  <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.
360
360
  `/` completes commands (`/clear`, `/compact`, `/model`, `/thinking`, `/scoop`, `/stop`, `/freeze` when the port can freeze, `/theme`) and their arguments, `@` mentions agents and files.
361
- Attach from the computer, from SLICC's files, a browser screenshot or a shared secret (with `vault.enter` and `valueFrame`, the popup (`form.popup.secret`) takes only the name (`input[name=name]`): **Share** (`data-action="share-secret"`) attaches a name the vault already has at once, and for a new name opens `vault.enter({ name })` and shows the vault's own field (`slicc-vault-value`, `form.popup.secret[data-entry]`) in place of a value field, attaching the name on the frame's `done`; for a name the vault has, **Replace value** (`data-action="replace-secret"`) asks before it replaces the value and then opens `vault.enter({ name, replace: true })`; **Back** (`data-action="back-secret"`) cancels the request and goes back to the name, and **Cancel** (`data-action="cancel-secret"`), a press outside the form, Escape and the frame's `escape` cancel it and close the popup (Cancel is disabled and a press outside is ignored while a share is pending), and `enter`'s refusals, the frame's `error` and a `gone` frame ("The vault’s field timed out. Try again.") show inline; a locked vault unlocks in that field; while the vault is away it attaches the name only and opens no request, and a field already open stays through it; with `enter` it never shows a value input. Without `enter`, with a `vault.put`, the popup takes the value too, checks it like Settings › Secrets, puts it in the vault and attaches the name, showing errors inline and clearing the field; an empty value shares a name the vault already has, and a new value for one asks before it replaces it; while the vault is away (`availability()` `connecting` or `waiting`) or locked, it takes no value and says so; without one, it attaches the name and says to add the value in Settings › Secrets; the popup closes on Cancel (`data-action="cancel-secret"`, disabled while a share is pending), on a press outside the form (ignored while a share is pending) and on Escape, each clearing the typed value), or paste and drop files (25 MB each; a dropped folder, told apart by its drag entry, becomes a “Folders can’t be attached” chip, and a file that can't be read a “Could not read the file” chip, instead of an attachment).
361
+ Attach from the computer, from SLICC's files, a screenshot, optional **Record audio** / **Record video** when the model has a `capture` port (video only when `capture.kinds` includes `'video'`; `data-action="record-audio"` / `data-action="record-video"`), or a shared secret (with `vault.enter` and `valueFrame`, the popup (`form.popup.secret`) takes only the name (`input[name=name]`): **Share** (`data-action="share-secret"`) attaches a name the vault already has at once, and for a new name opens `vault.enter({ name })` and shows the vault's own field (`slicc-vault-value`, `form.popup.secret[data-entry]`) in place of a value field, attaching the name on the frame's `done`; for a name the vault has, **Replace value** (`data-action="replace-secret"`) asks before it replaces the value and then opens `vault.enter({ name, replace: true })`; **Back** (`data-action="back-secret"`) cancels the request and goes back to the name, and **Cancel** (`data-action="cancel-secret"`), a press outside the form, Escape and the frame's `escape` cancel it and close the popup (Cancel is disabled and a press outside is ignored while a share is pending), and `enter`'s refusals, the frame's `error` and a `gone` frame ("The vault’s field timed out. Try again.") show inline; a locked vault unlocks in that field; while the vault is away it attaches the name only and opens no request, and a field already open stays through it; with `enter` it never shows a value input. Without `enter`, with a `vault.put`, the popup takes the value too, checks it like Settings › Secrets, puts it in the vault and attaches the name, showing errors inline and clearing the field; an empty value shares a name the vault already has, and a new value for one asks before it replaces it; while the vault is away (`availability()` `connecting` or `waiting`) or locked, it takes no value and says so; without one, it attaches the name and says to add the value in Settings › Secrets; the popup closes on Cancel (`data-action="cancel-secret"`, disabled while a share is pending), on a press outside the form (ignored while a share is pending) and on Escape, each clearing the typed value), or paste and drop files (25 MB each; a dropped folder, told apart by its drag entry, becomes a “Folders can’t be attached” chip, and a file that can't be read a “Could not read the file” chip, instead of an attachment).
362
+ **Take a screenshot** (`value="screenshot"`) prefers `capture.still()` when present (a screen still through the capture port), else the active browser tab through `browser.screenshot`, and never fails silently: with neither a still method nor a usable tab it attaches an error chip ("No screen or browser tab to screenshot"); Chrome denial and other capture failures become error chips too. When `NotAllowedError` meets a matching Capture and devices switch that is off (`switches` keys `screen`, `camera`, `microphone`), the chip keeps the full reason (including Capture and devices) on its `title` tooltip and shows a short subtitle that still names Settings (for example "Microphone is off. Turn it on in Settings."); otherwise it shows the port's own `error.message`, then a generic fallback. Record items call `capture.record('audio'|'video')` inside the click; the live chip's Stop is the recording's `stop()`, `cancel()` discards, and a finished blob attaches like an upload (`kind` `file` / `image` as `addFiles` decides); `NotAllowedError` / `NotSupportedError` attach an error chip, and a user cancel (`AbortError`) attaches nothing. Error chips never go to the agent: `send` keeps only attachments without `error`, and a message that is only an error chip does not send.
362
363
  <kbd>Esc</kbd> in the `+` menu closes it, from any item, and puts focus back on `+`; it goes no further, so it doesn't also stop a reply.
363
364
  Queued messages wait above it in a dashed box (`--swc-neutral-visual-color`, 3:1 or more against the composer in both themes), to send now or drop; a steer the agent still holds (`mode: 'steer'`, `li.queued[data-mode=steer]`) reads "Sends at the next step" and can only be dropped.
364
365
  Model and thinking pickers.
@@ -1001,11 +1002,17 @@ Later backed by: BIOS.
1001
1002
  `items()` returns the `LiveItem`s, what is live in seven now (a recording, later an open serial port): `id`, `kind` (free text: `screen`, `camera`, `microphone`, later `serial`), `label` (such as "Recording screen"), `what` (may be empty), `asker`, `since` (ms) and `action` (`{ label }`, such as "Stop"); emit `items` when the list changes. `act(id)` runs the item's action.
1002
1003
  `<slicc-app>` shows `<slicc-live>` under the header when the port is there: nothing while `items()` is empty, else one chip per item, stacked (`[data-surface=live]`, each chip `[data-id]`): a red dot, then "{label} · {what} · {asker} · m:ss" (`what` left out when empty), ticking once a second from `since`, and a quiet button with `action.label` (`data-action="live-act"`) that calls `act(id)`. On phones (`compact`) a chip keeps only the dot, the label and the button.
1003
1004
 
1005
+ #### `capture` (optional)
1006
+
1007
+ Later backed by: BIOS (page modules behind the same Camera / Microphone / Screen switches and live chips as programmatic capture).
1008
+ A person's click in the composer is the intent: no agent consent and no click item; Chrome's own prompt still applies.
1009
+ `record(kind)` starts inside that click (`kind` `'audio'` or `'video'`) and resolves with a `Recording` (`stop()`, `cancel()`, `finished` resolving to `{ blob, mimeType, name, durationMs }`); it rejects `NotAllowedError` (denied or a switch off) or `NotSupportedError`. The live chip's Stop is the same as `stop()`; `cancel()` discards. Optional `kinds` lists what the port can record (`'audio'` | `'video'`); the composer shows **Record video** only when `'video'` is listed, and **Record audio** whenever the port is present. Optional `still()` takes a screen still (`{ blob, mimeType, name }`) for **Take a screenshot**, under the Screen switch and a short "Taking a photo" live chip. Attachments are made from the blob the same way as an upload. The dummy port (`createDummyModel({ capture: 'on' | 'audio' | 'deny' })`) returns fake media and drives `live` when that port is also on.
1010
+
1004
1011
  #### `switches` (optional)
1005
1012
 
1006
1013
  Later backed by: BIOS.
1007
1014
  `list()` returns the `Switch`es (`key`, `label`, `on`), in order; emit `switches` when they change. `set(key, on)` turns one on or off.
1008
- Settings shows them under "Capture and devices", one switch each (`[data-surface=switches]`, each `sp-switch[data-id={key}]`), with "Programs can capture only what’s on here. Turning one off stops what’s live under it."; without the port, or with an empty list, the section isn't there.
1015
+ Settings shows them under "Capture and devices", one switch each (`[data-surface=switches]`, each `sp-switch[data-id={key}]`), with "Programs and linked devices can use only what’s on here. Turning one off stops what’s live under it."; without the port, or with an empty list, the section isn't there.
1009
1016
 
1010
1017
  #### `vault` (optional)
1011
1018