@ai-ecoverse/slicc-spectrum 1.31.0 → 1.32.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 +9 -7
- package/dist/slicc-dummy.js +101 -7
- package/dist/slicc-dummy.js.map +4 -4
- package/dist/slicc-ui.js +3335 -2866
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/files.d.ts +8 -0
- package/dist/types/app/network.d.ts +49 -0
- package/dist/types/dummy/files.d.ts +3 -2
- package/dist/types/dummy/index.d.ts +4 -1
- package/dist/types/dummy/network.d.ts +15 -0
- package/dist/types/dummy.d.ts +2 -0
- package/dist/types/model/types.d.ts +22 -1
- package/dist/types/ui.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -121,7 +121,7 @@ Things found while building this against wterm 0.5.4, recorded here, not pushed
|
|
|
121
121
|
|
|
122
122
|
The layout follows the width of `<slicc-app>`, which it reflects as its `screen` attribute: `phone` (under 640 px) has one column, `tablet` (under 1200 px) two, `desktop` three, like SLICC v6. Each screen class starts with few panels open and saves its own layout (`slicc-ui.layout.v2.<screen>`). Every surface has a home side, left, center or right. Closed panels wait as icons in the left and right rails (on a phone, in one bar at the bottom); one click puts a panel back on its side, next to its neighbours. Each thread, a cone's or a scoop's conversation, opens in its own chat panel (`chat:<agent id>`), as a tab in the same group as the other chats. Selecting a thread opens or reveals its tab, activating a chat tab selects its thread, and a thread's chat closes when the thread goes away (frozen or deleted).
|
|
123
123
|
|
|
124
|
-
`surfaces` on `<slicc-app>` (default: every surface, exported as `surfaces`) is what the app offers: the panels it can open, the View menu, the rails and `Alt+1…9`. A saved layout with a panel it doesn't offer is dropped for the default. An embedder can pass a subset with its own `open` per screen class. The agent picker
|
|
124
|
+
`surfaces` on `<slicc-app>` (default: every surface, exported as `surfaces`) is what the app offers: the panels it can open, the View menu, the rails and `Alt+1…9`. A saved layout with a panel it doesn't offer is dropped for the default. An embedder can pass a subset with its own `open` per screen class. The agent picker and the tray show only when `chat` is offered, the update status only with `updates`, the network indicator only with `network` and a `network` port, and the settings button only with `settings`. Elements with `slot="status"` show in the header as compact single-line items, before the update status, and are cut with an ellipsis when long; a `hidden` one takes no space. There are no strips under the header. On a phone the status items are hidden.
|
|
125
125
|
|
|
126
126
|
### Fonts
|
|
127
127
|
|
|
@@ -131,23 +131,24 @@ Text is Adobe Clean Spectrum VF, falling back to Adobe Clean, and code is Spectr
|
|
|
131
131
|
|
|
132
132
|
| Element | |
|
|
133
133
|
| :--- | :--- |
|
|
134
|
-
| `<slicc-app>` | The shell: header with the agent picker, the View menu and the theme switch, rails, a `<slicc-dock
|
|
134
|
+
| `<slicc-app>` | The shell: header with the agent picker, status items, the update status, the network indicator, the tray, the View menu and the theme switch, rails, and a `<slicc-dock>`. Saves the dock layout per screen class to `storage` (default `localStorage`) under `layoutKey`. While connected it sets `overscroll-behavior` to `none !important` on the page's `html` and `body`, so only scroll areas inside panels rubber-band. When the last app on the page is removed, the page's own inline values come back. |
|
|
135
135
|
| `<slicc-dock>` | Generic. [dockview-core](https://dockview.dev/) 8 with a theme mapped to Spectrum tokens, in its own shadow root. Panels come from `factories` (`name → (params) => HTMLElement`). `open`, `close`, `has`, `content`, `focusPanel`, `cycleGroup`, `cycleTab`, `toJSON`, `restore`, `clear`, and the full `api`. Tabs have a context menu (close, close others, float, maximize). Events: `layout-change`, `active-panel-change`, `panel-close`. |
|
|
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; when the turns right before it failed too, the button reads **Drop N failed turns** and rewinds to before the first of them, putting the latest prompt back), 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`, `/freeze` when the port can freeze, `/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. 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. |
|
|
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`. With `files.needsFolder`, a **Needs a folder** section lists the mount points waiting for a folder, each with **Insert folder…** (`data-action="insert-folder"`, `data-id` the mount point), which calls `mountFolder(path)`. A failed mount, insert 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. |
|
|
143
143
|
| `<slicc-terminals>` | Terminal sessions in tabs, each a `<slicc-terminal>` on the session's `TerminalBackend`. Sessions stay alive while hidden; `exit` closes the tab. |
|
|
144
144
|
| `<slicc-browser>` | Browser tabs with the agent driving each, an address bar, reload, and the active tab's screenshot. |
|
|
145
145
|
| `<slicc-settings>` | Theme, the model and thinking level for new cones, composer and diff preferences, and accounts to connect, reconnect or disconnect. |
|
|
146
|
-
| `<slicc-updates>` | Install / Update: component states, version changes, last checks, download and link counts, action buttons, failures with Retry, and collapsible install logs. Opens at boot until the agent is ready without failures. Background updates stay in the status
|
|
146
|
+
| `<slicc-updates>` | Install / Update: component states, version changes, last checks, download and link counts, action buttons, failures with Retry, and collapsible install logs. Opens at boot until the agent is ready without failures. Background updates stay in the header's update status; new failures reopen the panel. Also available through View and the rails. |
|
|
147
147
|
| `<slicc-memory>` | What agents remember, per scope (everyone, a cone or a role), grouped by section: search, filter by tag, expand, edit, add and forget. Free text outside an entry shows “From MEMORY.md”. |
|
|
148
148
|
| `<slicc-monitor>` | The live monitor: vitals with sparklines (active agents, spend, budget, fullest context), alerts, and the topology (cones and scoops, terminals, tabs, pending changes, sprinkles, tray followers). |
|
|
149
149
|
| `<slicc-freezer>` | Frozen cones, archived with their scoops: thaw to bring one back, delete, or freeze the active cone (also `/freeze`). |
|
|
150
150
|
| `<slicc-sprinkle>` | A SLICC sprinkle (`.shtml`), as a panel or, with `inline`, as a dip in the chat that grows to fit. A dip has a tab-like handle: drag it into the dock (or onto a rail, or use its open-as-panel button) and it lives on as a sprinkle panel, with a note in the chat where it was; which dips are out is saved in `slicc-ui.dips`. It runs in a sandboxed frame (`allow-scripts` only) with SLICC's sprinkle theme (the `--s2-*` tokens and `.sprinkle-*` classes), the app's fonts, and Lucide icons (`<i data-lucide>`, `LucideIcons.render()`). It talks back through `slicc.lick({ action, data })`, which reaches the owning cone as a `sprinkle` lick, and, when the port has `call`, reads files and keeps state (see [Sprinkle bridge](#sprinkle-bridge)). Panel sprinkles sit at the top of the right rail with their Lucide icon. |
|
|
151
|
+
| `<slicc-network>` | Network: the route and its health in plain words with the bios `detail`, **Check again** (`data-action="check"`) when the port has `check`, **Get the whole web** with the Chrome extension link (`data-action="install-extension"`, when `extensionUrl` is set) and `npx @ai-ecoverse/slicc-node` with a copy button (`data-action="copy-command"`), folded away when the route already reaches the whole web, and recent failures with host, error and time. The header's **Network** indicator (`data-network`, `data-health`) opens it: a status light, green for `ok`, yellow for `limited` and red for `failing`, with the state in its text and label and `detail` as its tooltip; on a phone, a cloud icon for the state. Offered only when the model has a `network` port. |
|
|
151
152
|
| `<slicc-tray>` | The tray indicator in the header: connection, the float's name, followers and budget; its panel adds role, runtime, spend, the follower list, the join link, and disconnect or reconnect. |
|
|
152
153
|
| `<slicc-confirm>` | The confirmation dialog `confirm()` opens. Not for direct use. |
|
|
153
154
|
| `<slicc-prompt>` | The name dialog `prompt()` opens. Not for direct use. |
|
|
@@ -195,7 +196,7 @@ Paths are the agent's: `/shared/…` and `/home/…`, nothing else. A refusal or
|
|
|
195
196
|
| Port | Later backed by | |
|
|
196
197
|
| :--- | :--- | :--- |
|
|
197
198
|
| `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: it stops and its working folder is deleted, while its conversation and reports are kept, and `createCone(name)` resolves with a new cone; the dummy rejects a cone name that is taken. `freeze(agentId)` is optional too: without it, `/freeze` and the Freezer's freeze button don't show. 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`). 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
|
+
| `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). `mountFolder(path)` inserts the picked folder at a mount point that waits for one; the optional `needsFolder()` lists those mount points. The port emits `mounts` and then `files` after every mount and eject, including those made from the shell, and `mounts` whenever `needsFolder()` changes. |
|
|
199
200
|
| `terminals` | slicc-kernel's terminal API | Terminal sessions; `backend(id)` returns a `TerminalBackend` for `<slicc-terminal>`. |
|
|
200
201
|
| `browser` | `@ai-ecoverse/slicc-cdp` | Tabs, the active tab, `open`, `navigate`, `close`, `screenshot`. |
|
|
201
202
|
| `settings` | local storage | Theme, model, thinking level, composer and diff preferences, the models on offer, and accounts. |
|
|
@@ -204,10 +205,11 @@ Paths are the agent's: `/shared/…` and `/home/…`, nothing else. A refusal or
|
|
|
204
205
|
| `sprinkles` | `@ai-ecoverse/slicc-agent` | Sprinkles (`inline` ones show as dips in the chat, not in the rail) and `send`, which turns a sprinkle's lick into a lick on its cone. The optional `call(id, method, args)` serves the [sprinkle bridge](#sprinkle-bridge) for sprinkle `id`: `readFile` and `exists` (`[path]`) resolve with a string and a boolean, `getState` (`[]`) with the saved value or `null`, and `setState` (`[value]`) once it is saved. The adapter owns path policy and keeps state per sprinkle; `<slicc-sprinkle>` awaits `getState` before it builds a frame, mirrors what the frame saves, and forwards only these four methods from its own frame. The dummy keeps state in memory and maps `/shared/x` to `/home/x` in its files, refusing anything outside `/home`. |
|
|
205
206
|
| `tray` | the tray protocol | Connection, role, float kind, followers, spend and budget; `reconnect` and `disconnect`. |
|
|
206
207
|
| `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. Use `queued` for a row that waits for another component before it starts; it reads "Waiting" and doesn't count as updating. A `failed` row with an installed `from` version reads "Update failed". `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. |
|
|
208
|
+
| `network` (optional) | BIOS | `status()` returns the `NetworkStatus`: `route` (`proxy` for slicc-node, `extension` for the Chrome extension relay, `page` for the page's own fetch, limited by CORS, or `null`), `health` (`ok`, `limited` or `failing`, decided by the port), a one-line `detail`, recent `failures` (`{ url, error, at }`, newest first) and an optional `extensionUrl`. Emit `network` when it changes. The optional `check()` tests the route again. Without the port, the indicator and the Network panel don't show. |
|
|
207
209
|
|
|
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.
|
|
210
|
+
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' | '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. `createDummyModel({ network: 'ok' | 'limited' | 'failing' | 'off' })` (or `?network=` on `/ui/`, default `limited`) sets the dummy network: slicc-node, the page fetch with CORS failures, or no route, all invented; `off` leaves out the port. `model.network.setScenario()` switches it and Check again re-emits after a short wait. `networkFixtures` and `DummyNetwork` are exported from `/dummy`.
|
|
209
211
|
|
|
210
|
-
On phones the tray
|
|
212
|
+
On phones the tray and the network indicator use compact indicators (their 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
213
|
|
|
212
214
|
### Kernel model
|
|
213
215
|
|
package/dist/slicc-dummy.js
CHANGED
|
@@ -1936,7 +1936,9 @@ var DummyFiles = class extends Emitter {
|
|
|
1936
1936
|
mountFolder;
|
|
1937
1937
|
mounts;
|
|
1938
1938
|
eject;
|
|
1939
|
+
needsFolder;
|
|
1939
1940
|
#mounted = /* @__PURE__ */ new Set();
|
|
1941
|
+
#needs = /* @__PURE__ */ new Set();
|
|
1940
1942
|
#contents = /* @__PURE__ */ new Map();
|
|
1941
1943
|
#directories = /* @__PURE__ */ new Set();
|
|
1942
1944
|
#modified = /* @__PURE__ */ new Map();
|
|
@@ -1947,9 +1949,11 @@ var DummyFiles = class extends Emitter {
|
|
|
1947
1949
|
this.#clock = clock2;
|
|
1948
1950
|
this.mount = mount;
|
|
1949
1951
|
if (mount) {
|
|
1950
|
-
this.mountFolder = () => this.#mountFolder(mount);
|
|
1952
|
+
this.mountFolder = (path) => this.#mountFolder(mount, path);
|
|
1951
1953
|
this.mounts = () => [...this.#mounted];
|
|
1952
1954
|
this.eject = (path) => this.#eject(path);
|
|
1955
|
+
this.needsFolder = () => [...this.#needs];
|
|
1956
|
+
if (mount.scenario === "needs") this.#needs.add(mount.point);
|
|
1953
1957
|
}
|
|
1954
1958
|
for (const directory of directories2) this.#mkdirs(`${directory}/`);
|
|
1955
1959
|
for (const [path, text] of Object.entries(contents)) this.#put(path, text, 0);
|
|
@@ -2035,19 +2039,23 @@ var DummyFiles = class extends Emitter {
|
|
|
2035
2039
|
else this.#put(path, change.before, Date.now());
|
|
2036
2040
|
this.#announce(path);
|
|
2037
2041
|
}
|
|
2038
|
-
async #mountFolder(mount) {
|
|
2042
|
+
async #mountFolder(mount, point) {
|
|
2039
2043
|
await this.#clock.sleep();
|
|
2040
2044
|
if (mount.scenario === "cancel") return null;
|
|
2041
2045
|
if (mount.scenario === "fail") throw new Error("The folder couldn\u2019t be mounted.");
|
|
2046
|
+
if (point !== void 0 && !this.#needs.has(point))
|
|
2047
|
+
throw new Error(`Nothing is waiting for a folder at ${point}.`);
|
|
2048
|
+
const at3 = point ?? mount.point;
|
|
2042
2049
|
const files3 = [];
|
|
2043
2050
|
for (const [path, text] of Object.entries(mount.files)) {
|
|
2044
|
-
const file = `${
|
|
2051
|
+
const file = `${at3}/${path}`;
|
|
2045
2052
|
this.#put(file, text, Date.now());
|
|
2046
2053
|
files3.push(file);
|
|
2047
2054
|
}
|
|
2048
|
-
this.#mounted.add(
|
|
2055
|
+
this.#mounted.add(at3);
|
|
2056
|
+
this.#needs.delete(at3);
|
|
2049
2057
|
this.#remount(files3);
|
|
2050
|
-
return
|
|
2058
|
+
return at3;
|
|
2051
2059
|
}
|
|
2052
2060
|
async #eject(path) {
|
|
2053
2061
|
await this.#clock.sleep();
|
|
@@ -3633,6 +3641,88 @@ var DummyMonitor = class extends Emitter {
|
|
|
3633
3641
|
}
|
|
3634
3642
|
};
|
|
3635
3643
|
|
|
3644
|
+
// src/dummy/network.ts
|
|
3645
|
+
var minute = 6e4;
|
|
3646
|
+
function networkFixtures(scenario, now2 = Date.now()) {
|
|
3647
|
+
const extensionUrl = "https://extensions.example/slicc";
|
|
3648
|
+
if (scenario === "ok") {
|
|
3649
|
+
return {
|
|
3650
|
+
route: "proxy",
|
|
3651
|
+
health: "ok",
|
|
3652
|
+
detail: "slicc-node on localhost:5710 reaches every site.",
|
|
3653
|
+
failures: [],
|
|
3654
|
+
extensionUrl
|
|
3655
|
+
};
|
|
3656
|
+
}
|
|
3657
|
+
if (scenario === "limited") {
|
|
3658
|
+
return {
|
|
3659
|
+
route: "page",
|
|
3660
|
+
health: "limited",
|
|
3661
|
+
detail: "The page fetch, limited by CORS.",
|
|
3662
|
+
failures: [
|
|
3663
|
+
{
|
|
3664
|
+
url: "https://api.tidewatch.example/v2/forecast?port=harbor",
|
|
3665
|
+
error: "Blocked by CORS",
|
|
3666
|
+
at: now2 - 2 * minute
|
|
3667
|
+
},
|
|
3668
|
+
{
|
|
3669
|
+
url: "https://feeds.lighthouse.example/notices.xml",
|
|
3670
|
+
error: "Blocked by CORS",
|
|
3671
|
+
at: now2 - 14 * minute
|
|
3672
|
+
}
|
|
3673
|
+
],
|
|
3674
|
+
extensionUrl
|
|
3675
|
+
};
|
|
3676
|
+
}
|
|
3677
|
+
return {
|
|
3678
|
+
route: null,
|
|
3679
|
+
health: "failing",
|
|
3680
|
+
detail: "No route answered. The last request timed out.",
|
|
3681
|
+
failures: [
|
|
3682
|
+
{
|
|
3683
|
+
url: "https://registry.harbor.example/agent",
|
|
3684
|
+
error: "Timed out after 30 s",
|
|
3685
|
+
at: now2 - 4e4
|
|
3686
|
+
},
|
|
3687
|
+
{
|
|
3688
|
+
url: "https://docs.tidewatch.example/",
|
|
3689
|
+
error: "Network unreachable",
|
|
3690
|
+
at: now2 - 3 * minute
|
|
3691
|
+
},
|
|
3692
|
+
{
|
|
3693
|
+
url: "https://api.tidewatch.example/v2/tides",
|
|
3694
|
+
error: "Network unreachable",
|
|
3695
|
+
at: now2 - 75 * minute
|
|
3696
|
+
}
|
|
3697
|
+
],
|
|
3698
|
+
extensionUrl
|
|
3699
|
+
};
|
|
3700
|
+
}
|
|
3701
|
+
var DummyNetwork = class extends Emitter {
|
|
3702
|
+
scenario;
|
|
3703
|
+
#status;
|
|
3704
|
+
#clock;
|
|
3705
|
+
constructor(scenario, clock2) {
|
|
3706
|
+
super();
|
|
3707
|
+
this.scenario = scenario;
|
|
3708
|
+
this.#status = networkFixtures(scenario);
|
|
3709
|
+
this.#clock = clock2;
|
|
3710
|
+
}
|
|
3711
|
+
status() {
|
|
3712
|
+
return this.#status;
|
|
3713
|
+
}
|
|
3714
|
+
setScenario(scenario) {
|
|
3715
|
+
this.scenario = scenario;
|
|
3716
|
+
this.#status = networkFixtures(scenario);
|
|
3717
|
+
this.emit("network", this.#status);
|
|
3718
|
+
}
|
|
3719
|
+
async check() {
|
|
3720
|
+
await this.#clock.sleep(4);
|
|
3721
|
+
this.#status = networkFixtures(this.scenario);
|
|
3722
|
+
this.emit("network", this.#status);
|
|
3723
|
+
}
|
|
3724
|
+
};
|
|
3725
|
+
|
|
3636
3726
|
// src/dummy/sprinkles.ts
|
|
3637
3727
|
function homePath(path) {
|
|
3638
3728
|
const text = String(path);
|
|
@@ -4076,7 +4166,8 @@ function createDummyModel({
|
|
|
4076
4166
|
delay = 30,
|
|
4077
4167
|
storage = null,
|
|
4078
4168
|
updates = "current",
|
|
4079
|
-
mounts = "off"
|
|
4169
|
+
mounts = "off",
|
|
4170
|
+
network = "limited"
|
|
4080
4171
|
} = {}) {
|
|
4081
4172
|
const time = clock(delay);
|
|
4082
4173
|
const mount = mounts === "off" ? null : { scenario: mounts, point: mountPoint, files: mounted };
|
|
@@ -4109,13 +4200,16 @@ function createDummyModel({
|
|
|
4109
4200
|
]),
|
|
4110
4201
|
sprinkles: new DummySprinkles(sprinkles, agent, files3),
|
|
4111
4202
|
tray: new DummyTray(tray, time),
|
|
4112
|
-
updates: new DummyUpdates(updates, time)
|
|
4203
|
+
updates: new DummyUpdates(updates, time),
|
|
4204
|
+
...network === "off" ? {} : { network: new DummyNetwork(network, time) }
|
|
4113
4205
|
};
|
|
4114
4206
|
return { ...base, monitor: new DummyMonitor(base) };
|
|
4115
4207
|
}
|
|
4116
4208
|
export {
|
|
4209
|
+
DummyNetwork,
|
|
4117
4210
|
DummyUpdates,
|
|
4118
4211
|
createDummyModel,
|
|
4212
|
+
networkFixtures,
|
|
4119
4213
|
updateFixtures
|
|
4120
4214
|
};
|
|
4121
4215
|
//# sourceMappingURL=slicc-dummy.js.map
|