@ai-ecoverse/slicc-spectrum 1.37.0 → 1.38.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 +5 -5
- package/dist/slicc-dummy.js +75 -5
- package/dist/slicc-dummy.js.map +3 -3
- package/dist/slicc-ui.js +246 -14
- package/dist/slicc-ui.js.map +3 -3
- package/dist/types/app/network.d.ts +16 -1
- package/dist/types/dummy/index.d.ts +3 -2
- package/dist/types/dummy/network.d.ts +8 -2
- package/dist/types/dummy.d.ts +2 -2
- package/dist/types/model/types.d.ts +25 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -138,17 +138,17 @@ Text is Adobe Clean Spectrum VF, falling back to Adobe Clean, and code is Spectr
|
|
|
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
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
|
-
| `<slicc-changes>` | Pending changes with their author. Opens the diff, accepts or reverts one change or all of them. Changes with a `repo` show their folder relative to it, and no author when `agentId` is `null`;
|
|
141
|
+
| `<slicc-changes>` | Pending changes with their author. Opens the diff, accepts or reverts one change or all of them. Changes with a `repo` show their folder relative to it, and no author when `agentId` is `null`; they group under a header per repository (its path and count), even when there is only one, in the order the port returns them. In a diff panel narrower than 480 px, Accept and Revert (`data-action="accept"`, `data-action="revert"`) show only their icons. Revert and Revert all ask with a destructive confirm that says the uncommitted (or, without a repo, pending) changes can't be undone; a failed revert shows its message under the bar. When the port's `unavailable()` returns a string, the panel shows it instead of the list, with each `backtick` span as inline code in the text's color and, below, each command once with a **Copy** button (`data-command`, `data-action="copy-command"`). |
|
|
142
142
|
| `<slicc-diff-panel>` | The diff of one pending change (`path`), unified or split, with accept and revert. A change with `before` and `after` both `null` (a binary file, or text over 1 MB) shows “No diff for this file” and Open the file instead, and keeps 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. An account whose status is `signing-in` (or a non-API-key account while its `connect` is pending) reads “Signing in…”; when the port has `cancel(id)`, its row offers Cancel (`data-action="cancel-sign-in"`), and the rejected `connect` that follows shows no error. |
|
|
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. |
|
|
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, and after a reload into a boot that isn't ready yet such a panel closes once the agent is ready. Every automatic close is saved to the layout. 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, and the chats New chat put away: 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`, a line on browser automation (`data-browser`: through the SLICC extension, through slicc-node, not available with how to get it, or `declined`, muted: off for this session, reload to be asked again) when the status has `browser`, **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
|
+
| `<slicc-network>` | Network: the route and its health in plain words with the bios `detail`, a line on browser automation (`data-browser`: through the SLICC extension, through slicc-node, not available with how to get it, or `declined`, muted: off for this session, reload to be asked again) when the status has `browser`, **Check again** (`data-action="check"`) when the port has `check`, a **Tailscale** section (`data-tailnet` with the state) when the status has `tailnet`, **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, which adds "Tailscale is connected." while the tailnet runs; on a phone, a cloud icon for the state. Offered only when the model has a `network` port. |
|
|
152
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. |
|
|
153
153
|
| `<slicc-confirm>` | The confirmation dialog `confirm()` opens. Not for direct use. |
|
|
154
154
|
| `<slicc-prompt>` | The name dialog `prompt()` opens. Not for direct use. |
|
|
@@ -206,9 +206,9 @@ Paths are the agent's: `/shared/…` and `/home/…`, nothing else. A refusal or
|
|
|
206
206
|
| `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`. |
|
|
207
207
|
| `tray` | the tray protocol | Connection, role, float kind, followers, spend and budget; `reconnect` and `disconnect`. |
|
|
208
208
|
| `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. Use `starting` for an installed row that is only starting up: it reads "Starting" without a checked line, and the header shows a neutral "Starting" only when nothing is failed, updating or ready. 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. |
|
|
209
|
-
| `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), an optional `extensionUrl` and an optional `browser` (`{ via, detail?, declined? }`, `via` being `extension`, `proxy` or `null` when browser automation isn't available, and `declined: true` once the user declined browser control for the session). Emit `network` when it changes. The optional `check()` tests the route again. Without the port, the indicator and the Network panel don't show. |
|
|
209
|
+
| `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), an optional `extensionUrl` and an optional `browser` (`{ via, detail?, declined? }`, `via` being `extension`, `proxy` or `null` when browser automation isn't available, and `declined: true` once the user declined browser control for the session). Emit `network` when it changes. The optional `check()` tests the route again. An optional `tailnet` (`TailnetStatus`) shows the Tailscale section: `state` (`off`, `loading`, `needs-login`, `starting`, `running` or `failed`, a status light), a plain-language `detail` (progress, or the failure reason in an error box with **Retry** through `check()`), a `loginUrl` (**Sign in to Tailscale**, a new tab), the `node` (`{ name, addresses }`; the name and the first 100.x address, each with a Copy button), `exitNode` (the name in use or `null`), `exitNodes` (`{ id, name, online }`), `autoExitNode`, `shieldsUp` (a muted line when `true`, a warning when `false`) and `peers` (a count). The optional `setTailnet(on)` adds the **Use Tailscale** switch (`data-action="tailnet"`); `submitAuthKey(key)` adds an auth-key field to `needs-login` (a password field without a `name`, cleared on submit, never kept in component state); `setExitNode(id | 'auto' | null)` adds the **Exit node** picker (None, Automatic, and each node, offline ones disabled) to `running`, with a line saying where traffic goes; `logoutTailnet()` adds **Sign out**, behind a confirm. A rejected call shows its message in the section. Peers are never named beyond the exit-node list. Without the port, the indicator and the Network panel don't show. |
|
|
210
210
|
|
|
211
|
-
The dummy supports `createDummyModel({ updates: 'boot' | 'starting' | '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 (with browser automation through it), 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`. `createDummyModel({ changes: 'files' | 'git' | 'nogit' })` (or `?changes=` on `/ui/`, default `files`) adds a git `changes` port: `git` lists the pending changes under `/workspace/harbor` and `/workspace/skills` with their `repo` and no author, and `nogit` reports git as unavailable. `DummyChanges` is exported from `/dummy`.
|
|
211
|
+
The dummy supports `createDummyModel({ updates: 'boot' | 'starting' | '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 (with browser automation through it), 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. `createDummyModel({ tailnet: 'off' | 'needs-login' | 'running' | 'failed' })` (or `?tailnet=` on `/ui/`, off by default) adds an invented tailnet: an auth key starting with `tskey-` signs in, `mast-pi` and `keel-router` are online exit nodes and `buoy-laptop` is offline, and Retry on `failed` connects. `networkFixtures`, `tailnetFixtures` and `DummyNetwork` are exported from `/dummy`. `createDummyModel({ changes: 'files' | 'git' | 'nogit' })` (or `?changes=` on `/ui/`, default `files`) adds a git `changes` port: `git` lists the pending changes under `/workspace/harbor` and `/workspace/skills` with their `repo` and no author, and `nogit` reports git as unavailable. `DummyChanges` is exported from `/dummy`.
|
|
212
212
|
|
|
213
213
|
On phones the update status and the tray show only their status light and the network indicator a cloud icon, with the text in their labels and tooltips; the agent picker keeps room for the cone's name, cut with an ellipsis when long, and the bottom rail scrolls when needed. The update status comes first so progress and failures remain reachable on narrow screens.
|
|
214
214
|
|
package/dist/slicc-dummy.js
CHANGED
|
@@ -3785,29 +3785,97 @@ function networkFixtures(scenario, now2 = Date.now()) {
|
|
|
3785
3785
|
browser: { via: null }
|
|
3786
3786
|
};
|
|
3787
3787
|
}
|
|
3788
|
+
var exitNodes = [
|
|
3789
|
+
{ id: "nKeel1CNTRL", name: "keel-router", online: true },
|
|
3790
|
+
{ id: "nMast2CNTRL", name: "mast-pi", online: true },
|
|
3791
|
+
{ id: "nBuoy3CNTRL", name: "buoy-laptop", online: false }
|
|
3792
|
+
];
|
|
3793
|
+
function tailnetFixtures(scenario) {
|
|
3794
|
+
const base = { exitNode: null, exitNodes: [], autoExitNode: false, shieldsUp: true };
|
|
3795
|
+
if (scenario === "needs-login") {
|
|
3796
|
+
return { ...base, state: "needs-login", loginUrl: "https://login.tailnet.example/a/7f3c2e" };
|
|
3797
|
+
}
|
|
3798
|
+
if (scenario === "running") {
|
|
3799
|
+
return {
|
|
3800
|
+
...base,
|
|
3801
|
+
state: "running",
|
|
3802
|
+
node: { name: "slicc-harbor", addresses: ["fd7a:115c:a1e0::7", "100.64.12.7"] },
|
|
3803
|
+
exitNodes,
|
|
3804
|
+
peers: 4
|
|
3805
|
+
};
|
|
3806
|
+
}
|
|
3807
|
+
if (scenario === "failed") {
|
|
3808
|
+
return {
|
|
3809
|
+
...base,
|
|
3810
|
+
state: "failed",
|
|
3811
|
+
detail: "The coordination server didn\u2019t answer. Check the connection and try again."
|
|
3812
|
+
};
|
|
3813
|
+
}
|
|
3814
|
+
return { ...base, state: "off" };
|
|
3815
|
+
}
|
|
3788
3816
|
var DummyNetwork = class extends Emitter {
|
|
3789
3817
|
scenario;
|
|
3790
3818
|
#status;
|
|
3791
3819
|
#clock;
|
|
3792
|
-
|
|
3820
|
+
#tailnet;
|
|
3821
|
+
constructor(scenario, clock2, tailnet) {
|
|
3793
3822
|
super();
|
|
3794
3823
|
this.scenario = scenario;
|
|
3795
|
-
this.#status = networkFixtures(scenario);
|
|
3796
3824
|
this.#clock = clock2;
|
|
3825
|
+
this.#tailnet = tailnet ? tailnetFixtures(tailnet) : void 0;
|
|
3826
|
+
this.#status = this.#with(networkFixtures(scenario));
|
|
3827
|
+
}
|
|
3828
|
+
#with(status) {
|
|
3829
|
+
return this.#tailnet ? { ...status, tailnet: this.#tailnet } : status;
|
|
3830
|
+
}
|
|
3831
|
+
#set(tailnet) {
|
|
3832
|
+
this.#tailnet = tailnet;
|
|
3833
|
+
this.#status = this.#with(this.#status);
|
|
3834
|
+
this.emit("network", this.#status);
|
|
3797
3835
|
}
|
|
3798
3836
|
status() {
|
|
3799
3837
|
return this.#status;
|
|
3800
3838
|
}
|
|
3801
3839
|
setScenario(scenario) {
|
|
3802
3840
|
this.scenario = scenario;
|
|
3803
|
-
this.#status = networkFixtures(scenario);
|
|
3841
|
+
this.#status = this.#with(networkFixtures(scenario));
|
|
3804
3842
|
this.emit("network", this.#status);
|
|
3805
3843
|
}
|
|
3806
3844
|
async check() {
|
|
3807
3845
|
await this.#clock.sleep(4);
|
|
3808
|
-
this.#
|
|
3846
|
+
if (this.#tailnet?.state === "failed") this.#tailnet = tailnetFixtures("running");
|
|
3847
|
+
this.#status = this.#with(networkFixtures(this.scenario));
|
|
3809
3848
|
this.emit("network", this.#status);
|
|
3810
3849
|
}
|
|
3850
|
+
async setTailnet(on) {
|
|
3851
|
+
await this.#clock.sleep(4);
|
|
3852
|
+
this.#set(tailnetFixtures(on ? "needs-login" : "off"));
|
|
3853
|
+
}
|
|
3854
|
+
async submitAuthKey(key) {
|
|
3855
|
+
if (!key.startsWith("tskey-")) {
|
|
3856
|
+
throw new Error("That isn\u2019t a Tailscale auth key. Auth keys start with tskey-.");
|
|
3857
|
+
}
|
|
3858
|
+
this.#set({ ...tailnetFixtures("off"), state: "starting", detail: "Joining your tailnet\u2026" });
|
|
3859
|
+
await this.#clock.sleep(8);
|
|
3860
|
+
this.#set(tailnetFixtures("running"));
|
|
3861
|
+
}
|
|
3862
|
+
async setExitNode(id) {
|
|
3863
|
+
await this.#clock.sleep(4);
|
|
3864
|
+
const tailnet = this.#tailnet ?? tailnetFixtures("running");
|
|
3865
|
+
const nodes = tailnet.exitNodes ?? [];
|
|
3866
|
+
if (id === "auto") {
|
|
3867
|
+
const node2 = nodes.find((item) => item.online);
|
|
3868
|
+
this.#set({ ...tailnet, autoExitNode: true, exitNode: node2?.name ?? null });
|
|
3869
|
+
return;
|
|
3870
|
+
}
|
|
3871
|
+
const node = nodes.find((item) => item.id === id);
|
|
3872
|
+
if (id && !node?.online) throw new Error("That exit node is offline.");
|
|
3873
|
+
this.#set({ ...tailnet, autoExitNode: false, exitNode: node?.name ?? null });
|
|
3874
|
+
}
|
|
3875
|
+
async logoutTailnet() {
|
|
3876
|
+
await this.#clock.sleep(4);
|
|
3877
|
+
this.#set(tailnetFixtures("needs-login"));
|
|
3878
|
+
}
|
|
3811
3879
|
};
|
|
3812
3880
|
|
|
3813
3881
|
// src/dummy/sprinkles.ts
|
|
@@ -4257,6 +4325,7 @@ function createDummyModel({
|
|
|
4257
4325
|
updates = "current",
|
|
4258
4326
|
mounts = "off",
|
|
4259
4327
|
network = "limited",
|
|
4328
|
+
tailnet,
|
|
4260
4329
|
changes = "files"
|
|
4261
4330
|
} = {}) {
|
|
4262
4331
|
const time = clock(delay);
|
|
@@ -4292,7 +4361,7 @@ function createDummyModel({
|
|
|
4292
4361
|
sprinkles: new DummySprinkles(sprinkles, agent, files3),
|
|
4293
4362
|
tray: new DummyTray(tray, time),
|
|
4294
4363
|
updates: new DummyUpdates(updates, time),
|
|
4295
|
-
...network === "off" ? {} : { network: new DummyNetwork(network, time) },
|
|
4364
|
+
...network === "off" ? {} : { network: new DummyNetwork(network, time, tailnet) },
|
|
4296
4365
|
...changes === "files" ? {} : { changes: new DummyChanges(files3, changes === "git") }
|
|
4297
4366
|
};
|
|
4298
4367
|
return { ...base, monitor: new DummyMonitor(base) };
|
|
@@ -4303,6 +4372,7 @@ export {
|
|
|
4303
4372
|
DummyUpdates,
|
|
4304
4373
|
createDummyModel,
|
|
4305
4374
|
networkFixtures,
|
|
4375
|
+
tailnetFixtures,
|
|
4306
4376
|
updateFixtures
|
|
4307
4377
|
};
|
|
4308
4378
|
//# sourceMappingURL=slicc-dummy.js.map
|