@ai-ecoverse/slicc-agent 3.43.0 → 3.43.1
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 +3 -3
- package/dist/browser/guard.js +19 -24
- package/dist/browser/guard.js.map +2 -2
- package/dist/browser/origins.js +7 -37
- package/dist/browser/origins.js.map +2 -2
- package/dist/types/browser/guard.d.ts +5 -3
- package/dist/types/browser/origins.d.ts +19 -4
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -363,9 +363,9 @@ pi core has no browser tooling, and Mario's pi-skills `browser-tools` launches i
|
|
|
363
363
|
- **`curlwright`** (slicc-cdp ≥ 1.2.1) runs curl-style requests as a page-context `fetch()` in an open tab, with that tab's cookies and origin. The skill prefers it to UI clicks for reading data the app already fetches, and plain `curl` when no login is needed. Writes need the user's yes like clicks do, and response bodies are data.
|
|
364
364
|
- **The `system` section** says the browser is connected when `SLICC_CDP_URL` is set and `playwright-cli` is on PATH (naming `curlwright` too when it's there), and lists it under "Not here yet" otherwise.
|
|
365
365
|
- **Images:** durable's `read` doesn't return images, so a wrapper (`slicc-images`) answers `read` of a PNG, JPEG, GIF or WebP with image content. In a worker that can draw, images wider than 1600 px are scaled down, and an image over 1 MB of base64 is re-encoded as JPEG or refused with a hint. The adapter puts image content from a tool result on the tool card (`ToolCall.image`), so screenshots show in the chat.
|
|
366
|
-
- **SLICC's own pages are off limits** (PRE-1). The `slicc-browser-guard` extension ([`src/browser/guard.ts`](src/browser/guard.ts)) refuses a `bash` call, direct or from codemode, that runs `playwright-cli` or `curlwright` and names a URL
|
|
367
|
-
- **How it reads a command:** a shell tokenizer ([`src/browser/shell.ts`](src/browser/shell.ts)) removes quotes and escapes (`'…'`, `"…"`, `$'…'`, `$"…"`, `\`), and reads into `$(…)`, backticks, `<(…)` and words that are themselves scripts, such as `bash -c` and `eval` arguments, four levels deep. If any word is `playwright-cli` or `curlwright` (by its last path segment), every word is checked: as a URL, as `https://` plus the word, after a `NAME=` or `--flag=` prefix, and for URLs and `//host` inside it.
|
|
368
|
-
- **The list**
|
|
366
|
+
- **SLICC's own pages are off limits** (PRE-1). The `slicc-browser-guard` extension ([`src/browser/guard.ts`](src/browser/guard.ts)) refuses a `bash` call, direct or from codemode, that runs `playwright-cli` or `curlwright` and names a protected URL: one that [`@ai-ecoverse/slicc-browsers`](https://github.com/ai-ecoverse/slicc-browsers#protected-origins)' `protectedOrigins` matcher protects, with the origin the worker runs on (`location.origin`) as its extra origin. That covers `sliccy.ai` and every name under it (including `www` and `vault`) over http or https on any port, the worker's origin, `devtools:`, and `blob:`, `filesystem:` and `view-source:` by their inner URL. It also refuses `*.kernel.localhost` names other than the agent's own kernel servers, `<port>.kernel.localhost` for a port 1–65535 other than the CDP facade's 9222. The answer is "SLICC's own pages can't be opened or driven from the browser tools.", and the `browser` skill says so too.
|
|
367
|
+
- **How it reads a command:** a shell tokenizer ([`src/browser/shell.ts`](src/browser/shell.ts)) removes quotes and escapes (`'…'`, `"…"`, `$'…'`, `$"…"`, `\`), and reads into `$(…)`, backticks, `<(…)` and words that are themselves scripts, such as `bash -c` and `eval` arguments, four levels deep. If any word is `playwright-cli` or `curlwright` (by its last path segment), every word is checked: as a URL, as `https://` plus the word, after a `NAME=` or `--flag=` prefix, and for URLs and `//host` inside it. Tabs and newlines are removed and surrounding spaces trimmed, as the URL parser does; the matcher parses with the WHATWG `URL`, so case, IDNA, full-width characters, percent escapes, backslashes and userinfo all count. `about:blank`, `about:srcdoc` and the empty URL are allowed: a tab `playwright-cli` opens has no SLICC opener, and a command that also names a protected URL is refused anyway.
|
|
368
|
+
- **The list** is slicc-browsers' `catalog.json` `protectedOrigins` with its reference matcher `protected.mjs`, wrapped by [`src/browser/origins.ts`](src/browser/origins.ts) (`protectedMatcher(extra)`); the unit tests run every URL and target vector in its `protected.json`. `*.kernel.localhost` isn't on the shared list; that rule is this guard's own. The build keeps the `with { type: 'json' }` import attribute, so the catalog loads unbundled.
|
|
369
369
|
- **What it can't catch:** it's defence in depth, and the browser tools themselves (slicc-cdp, the kernel's CDP facade and slicc-cli's `cdp` link) enforce the rule. It doesn't see a URL built at run time (from a variable set elsewhere, `printf`, brace expansion or a file), a browser command whose name is built at run time, a script or program file that drives the browser, a tab id (`--tab`, `tab-select`) that points at a SLICC tab, or a page that navigates there by itself. It may refuse a command that only names a SLICC URL alongside a browser command, such as `curl https://seven.sliccy.ai && playwright-cli open https://example.com`.
|
|
370
370
|
- There are no browser licks yet.
|
|
371
371
|
|
package/dist/browser/guard.js
CHANGED
|
@@ -4,20 +4,14 @@ import {
|
|
|
4
4
|
ToolTask,
|
|
5
5
|
wrapTool
|
|
6
6
|
} from "@earendil-works/pi-durable";
|
|
7
|
-
import {
|
|
7
|
+
import { PROTECTED_RULES, protectedMatcher } from "./origins.js";
|
|
8
8
|
import { words } from "./shell.js";
|
|
9
9
|
const BROWSER_GUARD = "slicc-browser-guard";
|
|
10
10
|
const REFUSAL = "SLICC's own pages can't be opened or driven from the browser tools.";
|
|
11
11
|
const FACADE_PORT = 9222;
|
|
12
12
|
const BROWSER = /* @__PURE__ */ new Set(["playwright-cli", "curlwright"]);
|
|
13
13
|
const WEB = /* @__PURE__ */ new Set(["http:", "https:", "ws:", "wss:"]);
|
|
14
|
-
const
|
|
15
|
-
const SECURE = {
|
|
16
|
-
"http:": "http:",
|
|
17
|
-
"https:": "https:",
|
|
18
|
-
"ws:": "http:",
|
|
19
|
-
"wss:": "https:"
|
|
20
|
-
};
|
|
14
|
+
const INNER = new Set(PROTECTED_RULES.innerSchemes.map((scheme) => `${scheme}:`));
|
|
21
15
|
const SCHEMED = /^[a-z][a-z0-9+.-]*:/i;
|
|
22
16
|
const EMBEDDED = /[a-z][a-z0-9+.-]*:\/\/[^\s'"`<>(){}\\]+/gi;
|
|
23
17
|
const RELATIVE = /(?<![:\w/])\/\/[^\s'"`<>(){}\\/]+/g;
|
|
@@ -35,20 +29,19 @@ function ownKernelServer(host) {
|
|
|
35
29
|
const port = OWN_KERNEL.exec(host)?.[1];
|
|
36
30
|
return port !== void 0 && Number(port) <= 65535 && Number(port) !== FACADE_PORT;
|
|
37
31
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return depth < 2 && [inner, `https://${inner}`].some((each) => forbidden(each, origins, depth + 1));
|
|
44
|
-
}
|
|
45
|
-
if (!WEB.has(parsed.protocol) || !parsed.hostname) return false;
|
|
32
|
+
function foreignKernel(url) {
|
|
33
|
+
let parsed = parse(url);
|
|
34
|
+
for (let depth = 0; parsed && INNER.has(parsed.protocol) && depth < 8; depth++)
|
|
35
|
+
parsed = parse(parsed.href.slice(parsed.protocol.length));
|
|
36
|
+
if (!parsed || !WEB.has(parsed.protocol)) return false;
|
|
46
37
|
const host = parsed.hostname.replace(/\.+$/, "");
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
38
|
+
return (host === KERNEL || host.endsWith(`.${KERNEL}`)) && !ownKernelServer(host);
|
|
39
|
+
}
|
|
40
|
+
function forbidden(url, matcher) {
|
|
41
|
+
return matcher.url(url) || foreignKernel(url);
|
|
50
42
|
}
|
|
51
|
-
function candidates(
|
|
43
|
+
function candidates(raw) {
|
|
44
|
+
const word = raw.replace(/[\t\n\r]/g, "").replace(/^[\0- ]+|[\0- ]+$/g, "");
|
|
52
45
|
const value = word.replace(PREFIX, "");
|
|
53
46
|
const found = [
|
|
54
47
|
word,
|
|
@@ -64,10 +57,10 @@ function candidates(word) {
|
|
|
64
57
|
function browserCommand(word) {
|
|
65
58
|
return BROWSER.has(word.slice(word.lastIndexOf("/") + 1));
|
|
66
59
|
}
|
|
67
|
-
function refused(command,
|
|
60
|
+
function refused(command, matcher) {
|
|
68
61
|
const all = words(command);
|
|
69
62
|
if (!all.some(browserCommand)) return false;
|
|
70
|
-
return all.some((word) => candidates(word).some((url) => forbidden(url,
|
|
63
|
+
return all.some((word) => candidates(word).some((url) => forbidden(url, matcher)));
|
|
71
64
|
}
|
|
72
65
|
function commandOf(args) {
|
|
73
66
|
const command = args?.command;
|
|
@@ -75,18 +68,19 @@ function commandOf(args) {
|
|
|
75
68
|
}
|
|
76
69
|
function browserGuard(origins, tools) {
|
|
77
70
|
const bash = tools.find((tool) => tool.name === "bash");
|
|
71
|
+
const matcher = protectedMatcher(origins);
|
|
78
72
|
return defineExtension({
|
|
79
73
|
name: BROWSER_GUARD,
|
|
80
74
|
hooks: [
|
|
81
75
|
hook(ToolTask, {
|
|
82
|
-
beforeTool: (call) => call.name === bash.name && refused(commandOf(call.arguments),
|
|
76
|
+
beforeTool: (call) => call.name === bash.name && refused(commandOf(call.arguments), matcher) ? { block: REFUSAL } : void 0
|
|
83
77
|
})
|
|
84
78
|
],
|
|
85
79
|
wraps: [
|
|
86
80
|
wrapTool(bash, (inner) => ({
|
|
87
81
|
...inner,
|
|
88
82
|
execute(args, api, context) {
|
|
89
|
-
if (!refused(commandOf(args),
|
|
83
|
+
if (!refused(commandOf(args), matcher)) return inner.execute(args, api, context);
|
|
90
84
|
return Promise.resolve({ content: [{ type: "text", text: REFUSAL }], isError: true });
|
|
91
85
|
}
|
|
92
86
|
}))
|
|
@@ -100,6 +94,7 @@ export {
|
|
|
100
94
|
browserGuard,
|
|
101
95
|
candidates,
|
|
102
96
|
forbidden,
|
|
97
|
+
foreignKernel,
|
|
103
98
|
ownKernelServer,
|
|
104
99
|
refused
|
|
105
100
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/browser/guard.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n defineExtension,\n type Extension,\n hook,\n type ToolRegistration,\n ToolTask,\n wrapTool,\n} from '@earendil-works/pi-durable';\nimport {
|
|
5
|
-
"mappings": "AAAA;AAAA,EACE;AAAA,EAEA;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AACP,SAAS,
|
|
4
|
+
"sourcesContent": ["import {\n defineExtension,\n type Extension,\n hook,\n type ToolRegistration,\n ToolTask,\n wrapTool,\n} from '@earendil-works/pi-durable';\nimport { PROTECTED_RULES, type ProtectedMatcher, protectedMatcher } from './origins.ts';\nimport { words } from './shell.ts';\n\nexport const BROWSER_GUARD = 'slicc-browser-guard';\nexport const REFUSAL = \"SLICC's own pages can't be opened or driven from the browser tools.\";\nexport const FACADE_PORT = 9222;\n\nconst BROWSER = new Set(['playwright-cli', 'curlwright']);\nconst WEB = new Set(['http:', 'https:', 'ws:', 'wss:']);\nconst INNER = new Set(PROTECTED_RULES.innerSchemes.map((scheme) => `${scheme}:`));\nconst SCHEMED = /^[a-z][a-z0-9+.-]*:/i;\nconst EMBEDDED = /[a-z][a-z0-9+.-]*:\\/\\/[^\\s'\"`<>(){}\\\\]+/gi;\nconst RELATIVE = /(?<![:\\w/])\\/\\/[^\\s'\"`<>(){}\\\\/]+/g;\nconst PREFIX = /^(?:[A-Za-z_][A-Za-z0-9_]*|-{1,2}[A-Za-z0-9-]+)=/;\nconst KERNEL = 'kernel.localhost';\nconst OWN_KERNEL = /^([1-9][0-9]{0,4})\\.kernel\\.localhost$/;\n\nfunction parse(url: string): URL | undefined {\n try {\n return new URL(url);\n } catch {\n return undefined;\n }\n}\n\nexport function ownKernelServer(host: string): boolean {\n const port = OWN_KERNEL.exec(host)?.[1];\n return port !== undefined && Number(port) <= 65535 && Number(port) !== FACADE_PORT;\n}\n\nexport function foreignKernel(url: string): boolean {\n let parsed = parse(url);\n for (let depth = 0; parsed && INNER.has(parsed.protocol) && depth < 8; depth++)\n parsed = parse(parsed.href.slice(parsed.protocol.length));\n if (!parsed || !WEB.has(parsed.protocol)) return false;\n const host = parsed.hostname.replace(/\\.+$/, '');\n return (host === KERNEL || host.endsWith(`.${KERNEL}`)) && !ownKernelServer(host);\n}\n\nexport function forbidden(url: string, matcher: ProtectedMatcher): boolean {\n return matcher.url(url) || foreignKernel(url);\n}\n\nexport function candidates(raw: string): string[] {\n const word = raw.replace(/[\\t\\n\\r]/g, '').replace(/^[\\0- ]+|[\\0- ]+$/g, '');\n const value = word.replace(PREFIX, '');\n const found = [\n word,\n value,\n ...(value.match(EMBEDDED) ?? []),\n ...(value.match(RELATIVE) ?? []).map((relative) => `https:${relative}`),\n ];\n if (!/^[/.~-]/.test(value) && !/^[a-z][a-z0-9+.-]*:\\/\\//i.test(value))\n found.push(`https://${value}`);\n if (value.startsWith('//')) found.push(`https:${value}`);\n return found.filter((each) => SCHEMED.test(each));\n}\n\nfunction browserCommand(word: string): boolean {\n return BROWSER.has(word.slice(word.lastIndexOf('/') + 1));\n}\n\nexport function refused(command: string, matcher: ProtectedMatcher): boolean {\n const all = words(command);\n if (!all.some(browserCommand)) return false;\n return all.some((word) => candidates(word).some((url) => forbidden(url, matcher)));\n}\n\nfunction commandOf(args: unknown): string {\n const command = (args as { command?: unknown } | undefined)?.command;\n return typeof command === 'string' ? command : '';\n}\n\nexport function browserGuard(\n origins: readonly string[],\n tools: readonly ToolRegistration[]\n): Extension {\n const bash = tools.find((tool) => tool.name === 'bash') as ToolRegistration;\n const matcher = protectedMatcher(origins);\n return defineExtension({\n name: BROWSER_GUARD,\n hooks: [\n hook(ToolTask, {\n beforeTool: (call) =>\n call.name === bash.name && refused(commandOf(call.arguments), matcher)\n ? { block: REFUSAL }\n : undefined,\n }),\n ],\n wraps: [\n wrapTool(bash, (inner) => ({\n ...inner,\n execute(args, api, context) {\n if (!refused(commandOf(args), matcher)) return inner.execute(args, api, context);\n return Promise.resolve({ content: [{ type: 'text', text: REFUSAL }], isError: true });\n },\n })),\n ],\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/browser/origins.js
CHANGED
|
@@ -1,41 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
try {
|
|
7
|
-
return new URL(url);
|
|
8
|
-
} catch {
|
|
9
|
-
return void 0;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
function hostOf(url) {
|
|
13
|
-
return url.hostname.replace(/\.+$/, "");
|
|
14
|
-
}
|
|
15
|
-
function originOf(url) {
|
|
16
|
-
const parsed = parse(url);
|
|
17
|
-
if (!parsed || !["http:", "https:"].includes(parsed.protocol) || !parsed.hostname)
|
|
18
|
-
return void 0;
|
|
19
|
-
return `${parsed.protocol}//${hostOf(parsed)}${parsed.port ? `:${parsed.port}` : ""}`;
|
|
20
|
-
}
|
|
21
|
-
function matches(pattern, url) {
|
|
22
|
-
const host = hostOf(url);
|
|
23
|
-
const wanted = pattern.slice("https://".length);
|
|
24
|
-
if (!wanted.startsWith("*.")) return host === wanted;
|
|
25
|
-
const suffix = wanted.slice(1);
|
|
26
|
-
return host.endsWith(suffix) && LABEL.test(host.slice(0, -suffix.length));
|
|
27
|
-
}
|
|
28
|
-
function isProtected(url, extra = []) {
|
|
29
|
-
const origin = originOf(url);
|
|
30
|
-
if (!origin) return false;
|
|
31
|
-
if (extra.some((other) => originOf(other) === origin)) return true;
|
|
32
|
-
const parsed = parse(url);
|
|
33
|
-
if (parsed.protocol !== "https:" || parsed.port) return false;
|
|
34
|
-
return protectedOrigins.patterns.some((pattern) => matches(pattern, parsed));
|
|
1
|
+
import catalog from "@ai-ecoverse/slicc-browsers/catalog.json" with { type: "json" };
|
|
2
|
+
import { protectedOrigins } from "@ai-ecoverse/slicc-browsers/protected.mjs";
|
|
3
|
+
const PROTECTED_RULES = catalog.protectedOrigins;
|
|
4
|
+
function protectedMatcher(extra = []) {
|
|
5
|
+
return protectedOrigins(PROTECTED_RULES, [...extra]);
|
|
35
6
|
}
|
|
36
7
|
export {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
protectedOrigins
|
|
8
|
+
PROTECTED_RULES,
|
|
9
|
+
protectedMatcher
|
|
40
10
|
};
|
|
41
11
|
//# sourceMappingURL=origins.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/browser/origins.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import catalog from '@ai-ecoverse/slicc-browsers/catalog.json' with { type: 'json' };\nimport { protectedOrigins } from '@ai-ecoverse/slicc-browsers/protected.mjs';\n\nexport const PROTECTED_RULES = catalog.protectedOrigins;\n\nexport interface ProtectedMatcher {\n url(text: string): boolean;\n target(target: { url: string; previous?: boolean; opener?: string }): boolean;\n cookieDomain(domain: string): boolean;\n storageKey(key: string): boolean;\n}\n\nexport function protectedMatcher(extra: readonly string[] = []): ProtectedMatcher {\n return protectedOrigins(PROTECTED_RULES, [...extra]);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa,2CAA2C,KAAK,EAAE,MAAM,OAAO;AACnF,SAAS,wBAAwB;AAE1B,MAAM,kBAAkB,QAAQ;AAShC,SAAS,iBAAiB,QAA2B,CAAC,GAAqB;AAChF,SAAO,iBAAiB,iBAAiB,CAAC,GAAG,KAAK,CAAC;AACrD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type Extension, type ToolRegistration } from '@earendil-works/pi-durable';
|
|
2
|
+
import { type ProtectedMatcher } from './origins.ts';
|
|
2
3
|
export declare const BROWSER_GUARD = "slicc-browser-guard";
|
|
3
4
|
export declare const REFUSAL = "SLICC's own pages can't be opened or driven from the browser tools.";
|
|
4
5
|
export declare const FACADE_PORT = 9222;
|
|
5
6
|
export declare function ownKernelServer(host: string): boolean;
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
7
|
+
export declare function foreignKernel(url: string): boolean;
|
|
8
|
+
export declare function forbidden(url: string, matcher: ProtectedMatcher): boolean;
|
|
9
|
+
export declare function candidates(raw: string): string[];
|
|
10
|
+
export declare function refused(command: string, matcher: ProtectedMatcher): boolean;
|
|
9
11
|
export declare function browserGuard(origins: readonly string[], tools: readonly ToolRegistration[]): Extension;
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
|
|
1
|
+
export declare const PROTECTED_RULES: {
|
|
2
|
+
domains: string[];
|
|
3
|
+
hosts: string[];
|
|
4
|
+
schemes: string[];
|
|
5
|
+
innerSchemes: string[];
|
|
6
|
+
anySchemes: string[];
|
|
7
|
+
inheriting: string[];
|
|
8
|
+
refusal: string;
|
|
3
9
|
};
|
|
4
|
-
export
|
|
5
|
-
|
|
10
|
+
export interface ProtectedMatcher {
|
|
11
|
+
url(text: string): boolean;
|
|
12
|
+
target(target: {
|
|
13
|
+
url: string;
|
|
14
|
+
previous?: boolean;
|
|
15
|
+
opener?: string;
|
|
16
|
+
}): boolean;
|
|
17
|
+
cookieDomain(domain: string): boolean;
|
|
18
|
+
storageKey(key: string): boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function protectedMatcher(extra?: readonly string[]): ProtectedMatcher;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc-agent",
|
|
3
|
-
"version": "3.43.
|
|
3
|
+
"version": "3.43.1",
|
|
4
4
|
"description": "SLICC's agent core on pi durable: an agent worker, session storage, remoting and pi extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@ai-ecoverse/slicc-kernel": "1.47.1",
|
|
65
65
|
"@ai-ecoverse/slicc-shared-web": "1.13.0",
|
|
66
|
-
"@ai-ecoverse/slicc-spectrum": "1.
|
|
66
|
+
"@ai-ecoverse/slicc-spectrum": "1.60.2",
|
|
67
67
|
"@ai-ecoverse/wasm-bash": "5.3.0-17",
|
|
68
68
|
"@ai-ecoverse/wasm-coreutils": "9.12.0-5",
|
|
69
69
|
"@ai-ecoverse/wasm-git": "2.55.0-15",
|
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
"typescript": "7.0.2"
|
|
79
79
|
},
|
|
80
80
|
"dependencies": {
|
|
81
|
+
"@ai-ecoverse/slicc-browsers": "1.4.0",
|
|
81
82
|
"@earendil-works/chord": "1.0.4",
|
|
82
83
|
"@earendil-works/pi-ai": "1.0.4",
|
|
83
84
|
"@earendil-works/pi-client": "1.0.4",
|