@ai-ecoverse/slicc-agent 3.48.0 → 3.48.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 +1 -0
- package/dist/changes/git.js +2 -0
- package/dist/changes/git.js.map +2 -2
- package/dist/spectrum/changes-port.js +4 -0
- package/dist/spectrum/changes-port.js.map +2 -2
- package/dist/types/changes/git.d.ts +1 -0
- package/dist/types/spectrum/changes-port.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -425,6 +425,7 @@ pi has no git integration and no changes list; pi coding-agent leaves that to th
|
|
|
425
425
|
- Untracked files show as added, and a rename shows as a deleted plus an added file.
|
|
426
426
|
- `before` is the index version (`git show :<path>`) and `after` is the working file. Binary files and files over 1 MB get null for both, which spectrum shows as "no diff".
|
|
427
427
|
- At most 200 files per repo are listed. There's no store of our own, and `agentId` is null, because git doesn't know which agent wrote a file.
|
|
428
|
+
- **The spectrum adapter's `commands()`** returns `curl -fsSL https://get.sliccy.ai/slicc | sh`, which spectrum ≥ 1.67.0 shows as a Copy block under either empty state, after the text's own commands.
|
|
428
429
|
- **Without git,** `unavailable()` says git isn't installed and how to get it (`pnpm add -g @ai-ecoverse/wasm-git`). **With git but no repo,** it says to `git init` a folder under /home, and that cloning from the internet needs slicc or the SLICC extension linked; cloning over HTTPS through the page alone fails. Seven doesn't preinstall git; the user or the agent installs it with that command.
|
|
429
430
|
- **The `system` section** has a Git line. With `git` on PATH, it says local repositories work and that clone, fetch and push need slicc linked or the extension connected. Without it, it gives the agent `pnpm add -g @ai-ecoverse/wasm-git` to install it when needed. Seven doesn't preinstall git (Lars, 2026-10-09). The install line also names the other tested packages that aren't preinstalled: `@ai-ecoverse/wasi-esbuild` (esbuild), `@ai-ecoverse/wasi-typescript` (tsc), `@ai-ecoverse/wasi-biome` (biome), for PDFs `@ai-ecoverse/wasm-poppler` (pdftotext and friends) and `@ai-ecoverse/wasm-qpdf` (qpdf), and for Python `@ai-ecoverse/wasix-python` (python3, pip) with `@ai-ecoverse/wasix-uv-shim@0.1.0-1` (a uv-compatible shim, pinned while the package is new; only `uv run` uses the venv until kernel#168).
|
|
430
431
|
- **Which repos:**
|
package/dist/changes/git.js
CHANGED
|
@@ -2,6 +2,7 @@ const MAX_TEXT = 1024 * 1024;
|
|
|
2
2
|
const MAX_FILES = 200;
|
|
3
3
|
const SCAN_DEPTH = 3;
|
|
4
4
|
const SCAN_ENTRIES = 200;
|
|
5
|
+
const CLONE_COMMAND = "curl -fsSL https://get.sliccy.ai/slicc | sh";
|
|
5
6
|
const NO_GIT = "Changes needs git, and git isn't installed. Install it with `pnpm add -g @ai-ecoverse/wasm-git`, then run `git init` in a folder under /home. To clone from the internet, link slicc or the SLICC extension.";
|
|
6
7
|
const NO_REPO = "Changes lists the changes in git repositories, and there are none here yet. Run `git init` in a folder under /home. To clone from the internet, link slicc or the SLICC extension.";
|
|
7
8
|
const UNMERGED = ["DD", "AU", "UD", "UA", "DU", "AA", "UU"];
|
|
@@ -69,6 +70,7 @@ function failure(ran, what) {
|
|
|
69
70
|
return new Error(ran.err.trim() || ran.out.trim() || `${what} failed`);
|
|
70
71
|
}
|
|
71
72
|
export {
|
|
73
|
+
CLONE_COMMAND,
|
|
72
74
|
MAX_FILES,
|
|
73
75
|
MAX_TEXT,
|
|
74
76
|
NO_GIT,
|
package/dist/changes/git.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/changes/git.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\n\nexport const MAX_TEXT = 1024 * 1024;\nexport const MAX_FILES = 200;\nexport const SCAN_DEPTH = 3;\nexport const SCAN_ENTRIES = 200;\nexport const NO_GIT =\n \"Changes needs git, and git isn't installed. Install it with `pnpm add -g @ai-ecoverse/wasm-git`, then run `git init` in a folder under /home. To clone from the internet, link slicc or the SLICC extension.\";\nexport const NO_REPO =\n 'Changes lists the changes in git repositories, and there are none here yet. Run `git init` in a folder under /home. To clone from the internet, link slicc or the SLICC extension.';\n\nexport type ChangeStatus = 'added' | 'modified' | 'deleted';\nexport type ChangeKind = 'tracked' | 'untracked' | 'conflict';\n\nconst UNMERGED = ['DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU'];\n\nexport interface FileChange {\n path: string;\n repo: string;\n status: ChangeStatus;\n kind: ChangeKind;\n before: string | null;\n after: string | null;\n}\n\nexport interface ChangesView {\n unavailable: string | null;\n changes: FileChange[];\n}\n\nexport interface Pending {\n path: string;\n status: ChangeStatus;\n kind: ChangeKind;\n}\n\nexport function parseStatus(out: string): Pending[] {\n const parts = out.split('\\0');\n const found: Pending[] = [];\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i] as string;\n if (part.length < 4) continue;\n const index = part[0] as string;\n const tree = part[1] as string;\n const path = part.slice(3);\n if (index === 'R' || index === 'C') i++;\n if (UNMERGED.includes(index + tree)) found.push({ path, status: 'modified', kind: 'conflict' });\n else if (index === '?' && tree === '?')\n found.push({ path, status: 'added', kind: 'untracked' });\n else if (tree === 'D') found.push({ path, status: 'deleted', kind: 'tracked' });\n else if (tree === 'A') found.push({ path, status: 'added', kind: 'tracked' });\n else if (tree !== ' ' && tree !== '!')\n found.push({ path, status: 'modified', kind: 'tracked' });\n }\n return found;\n}\n\nexport function textOf(bytes: Uint8Array): string | null {\n if (bytes.length > MAX_TEXT || bytes.includes(0)) return null;\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(bytes);\n } catch {\n return null;\n }\n}\n\nexport function shown(text: string): string | null {\n return text.length > MAX_TEXT || text.includes('\\0') || text.includes('\uFFFD') ? null : text;\n}\n\nexport function scanned(name: string): boolean {\n return name !== 'node_modules' && !name.startsWith('.');\n}\n\nexport function within(path: string, root: string): boolean {\n return root === '/' || path === root || path.startsWith(`${root}/`);\n}\n\nexport function relative(path: string, root: string): string {\n return root === '/' ? path.slice(1) : path.slice(root.length + 1);\n}\n\nexport function joined(root: string, rel: string): string {\n return root === '/' ? `/${rel}` : `${root}/${rel}`;\n}\n\nexport type Ran = { code: number; out: string; err: string };\n\nexport const quote = (word: string): string => `'${word.replaceAll(\"'\", \"'\\\\''\")}'`;\n\nexport async function run(\n env: Pick<ExecutionEnv, 'exec'>,\n command: string | readonly string[],\n cwd: string,\n context: Context\n): Promise<Ran> {\n let out = '';\n let err = '';\n const ran = await env.exec(\n typeof command === 'string' ? command : command.map(quote).join(' '),\n {\n cwd,\n onOutput: (text, _context, info) => {\n if (info.stream === 'stdout') out += text;\n else err += text;\n },\n },\n context\n );\n return ran.ok\n ? { code: ran.value.exitCode, out, err }\n : { code: -1, out, err: ran.error.message };\n}\n\nexport function failure(ran: Ran, what: string): Error {\n return new Error(ran.err.trim() || ran.out.trim() || `${what} failed`);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\n\nexport const MAX_TEXT = 1024 * 1024;\nexport const MAX_FILES = 200;\nexport const SCAN_DEPTH = 3;\nexport const SCAN_ENTRIES = 200;\nexport const CLONE_COMMAND = 'curl -fsSL https://get.sliccy.ai/slicc | sh';\nexport const NO_GIT =\n \"Changes needs git, and git isn't installed. Install it with `pnpm add -g @ai-ecoverse/wasm-git`, then run `git init` in a folder under /home. To clone from the internet, link slicc or the SLICC extension.\";\nexport const NO_REPO =\n 'Changes lists the changes in git repositories, and there are none here yet. Run `git init` in a folder under /home. To clone from the internet, link slicc or the SLICC extension.';\n\nexport type ChangeStatus = 'added' | 'modified' | 'deleted';\nexport type ChangeKind = 'tracked' | 'untracked' | 'conflict';\n\nconst UNMERGED = ['DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU'];\n\nexport interface FileChange {\n path: string;\n repo: string;\n status: ChangeStatus;\n kind: ChangeKind;\n before: string | null;\n after: string | null;\n}\n\nexport interface ChangesView {\n unavailable: string | null;\n changes: FileChange[];\n}\n\nexport interface Pending {\n path: string;\n status: ChangeStatus;\n kind: ChangeKind;\n}\n\nexport function parseStatus(out: string): Pending[] {\n const parts = out.split('\\0');\n const found: Pending[] = [];\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i] as string;\n if (part.length < 4) continue;\n const index = part[0] as string;\n const tree = part[1] as string;\n const path = part.slice(3);\n if (index === 'R' || index === 'C') i++;\n if (UNMERGED.includes(index + tree)) found.push({ path, status: 'modified', kind: 'conflict' });\n else if (index === '?' && tree === '?')\n found.push({ path, status: 'added', kind: 'untracked' });\n else if (tree === 'D') found.push({ path, status: 'deleted', kind: 'tracked' });\n else if (tree === 'A') found.push({ path, status: 'added', kind: 'tracked' });\n else if (tree !== ' ' && tree !== '!')\n found.push({ path, status: 'modified', kind: 'tracked' });\n }\n return found;\n}\n\nexport function textOf(bytes: Uint8Array): string | null {\n if (bytes.length > MAX_TEXT || bytes.includes(0)) return null;\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(bytes);\n } catch {\n return null;\n }\n}\n\nexport function shown(text: string): string | null {\n return text.length > MAX_TEXT || text.includes('\\0') || text.includes('\uFFFD') ? null : text;\n}\n\nexport function scanned(name: string): boolean {\n return name !== 'node_modules' && !name.startsWith('.');\n}\n\nexport function within(path: string, root: string): boolean {\n return root === '/' || path === root || path.startsWith(`${root}/`);\n}\n\nexport function relative(path: string, root: string): string {\n return root === '/' ? path.slice(1) : path.slice(root.length + 1);\n}\n\nexport function joined(root: string, rel: string): string {\n return root === '/' ? `/${rel}` : `${root}/${rel}`;\n}\n\nexport type Ran = { code: number; out: string; err: string };\n\nexport const quote = (word: string): string => `'${word.replaceAll(\"'\", \"'\\\\''\")}'`;\n\nexport async function run(\n env: Pick<ExecutionEnv, 'exec'>,\n command: string | readonly string[],\n cwd: string,\n context: Context\n): Promise<Ran> {\n let out = '';\n let err = '';\n const ran = await env.exec(\n typeof command === 'string' ? command : command.map(quote).join(' '),\n {\n cwd,\n onOutput: (text, _context, info) => {\n if (info.stream === 'stdout') out += text;\n else err += text;\n },\n },\n context\n );\n return ran.ok\n ? { code: ran.value.exitCode, out, err }\n : { code: -1, out, err: ran.error.message };\n}\n\nexport function failure(ran: Ran, what: string): Error {\n return new Error(ran.err.trim() || ran.out.trim() || `${what} failed`);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
|
2
|
+
import { CLONE_COMMAND } from "../changes/git.js";
|
|
2
3
|
import { attempt, warn } from "./attempt.js";
|
|
3
4
|
import { Emitter } from "./emitter.js";
|
|
4
5
|
class ChangesAdapter extends Emitter {
|
|
@@ -34,6 +35,9 @@ class ChangesAdapter extends Emitter {
|
|
|
34
35
|
this.#open();
|
|
35
36
|
return this.#connection.changes?.value?.unavailable ?? null;
|
|
36
37
|
}
|
|
38
|
+
commands() {
|
|
39
|
+
return [CLONE_COMMAND];
|
|
40
|
+
}
|
|
37
41
|
accept(path) {
|
|
38
42
|
attempt(
|
|
39
43
|
this.#connection.control.changeAccept(path, BACKGROUND_CONTEXT),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/spectrum/changes-port.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Change, ChangesPort } from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentConnection } from '../client.ts';\nimport { attempt, type Report, warn } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\n\nexport interface ChangesEvents {\n changes: readonly Change[];\n}\n\nexport class ChangesAdapter extends Emitter<ChangesEvents> implements ChangesPort {\n readonly #connection: AgentConnection;\n readonly #report: Report;\n #opened = false;\n\n constructor(connection: AgentConnection, report: Report = warn) {\n super();\n this.#connection = connection;\n this.#report = report;\n connection.changes?.subscribe(() => this.emit('changes', this.#list()));\n }\n\n #open(): void {\n if (this.#opened) return;\n this.#opened = true;\n void this.#connection.control.changesOpen(BACKGROUND_CONTEXT).catch(() => undefined);\n }\n\n changes(): readonly Change[] {\n this.#open();\n return this.#list();\n }\n\n #list(): readonly Change[] {\n return (this.#connection.changes?.value?.changes ?? []).map((change) => ({\n path: change.path,\n repo: change.repo,\n status: change.status,\n before: change.before,\n after: change.after,\n agentId: null,\n }));\n }\n\n unavailable(): string | null {\n this.#open();\n return this.#connection.changes?.value?.unavailable ?? null;\n }\n\n accept(path: string): void {\n attempt(\n this.#connection.control.changeAccept(path, BACKGROUND_CONTEXT),\n 'accept changes',\n this.#report\n );\n }\n\n async revert(path: string): Promise<void> {\n const result = await this.#connection.control.changeRevert(path, BACKGROUND_CONTEXT);\n if (result.error !== null) throw new Error(result.error);\n }\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,0BAA0B;
|
|
4
|
+
"sourcesContent": ["import type { Change, ChangesPort } from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport { CLONE_COMMAND } from '../changes/git.ts';\nimport type { AgentConnection } from '../client.ts';\nimport { attempt, type Report, warn } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\n\nexport interface ChangesEvents {\n changes: readonly Change[];\n}\n\nexport class ChangesAdapter extends Emitter<ChangesEvents> implements ChangesPort {\n readonly #connection: AgentConnection;\n readonly #report: Report;\n #opened = false;\n\n constructor(connection: AgentConnection, report: Report = warn) {\n super();\n this.#connection = connection;\n this.#report = report;\n connection.changes?.subscribe(() => this.emit('changes', this.#list()));\n }\n\n #open(): void {\n if (this.#opened) return;\n this.#opened = true;\n void this.#connection.control.changesOpen(BACKGROUND_CONTEXT).catch(() => undefined);\n }\n\n changes(): readonly Change[] {\n this.#open();\n return this.#list();\n }\n\n #list(): readonly Change[] {\n return (this.#connection.changes?.value?.changes ?? []).map((change) => ({\n path: change.path,\n repo: change.repo,\n status: change.status,\n before: change.before,\n after: change.after,\n agentId: null,\n }));\n }\n\n unavailable(): string | null {\n this.#open();\n return this.#connection.changes?.value?.unavailable ?? null;\n }\n\n commands(): readonly string[] {\n return [CLONE_COMMAND];\n }\n\n accept(path: string): void {\n attempt(\n this.#connection.control.changeAccept(path, BACKGROUND_CONTEXT),\n 'accept changes',\n this.#report\n );\n }\n\n async revert(path: string): Promise<void> {\n const result = await this.#connection.control.changeRevert(path, BACKGROUND_CONTEXT);\n if (result.error !== null) throw new Error(result.error);\n }\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAE9B,SAAS,SAAsB,YAAY;AAC3C,SAAS,eAAe;AAMjB,MAAM,uBAAuB,QAA8C;AAAA,EACvE;AAAA,EACA;AAAA,EACT,UAAU;AAAA,EAEV,YAAY,YAA6B,SAAiB,MAAM;AAC9D,UAAM;AACN,SAAK,cAAc;AACnB,SAAK,UAAU;AACf,eAAW,SAAS,UAAU,MAAM,KAAK,KAAK,WAAW,KAAK,MAAM,CAAC,CAAC;AAAA,EACxE;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,QAAS;AAClB,SAAK,UAAU;AACf,SAAK,KAAK,YAAY,QAAQ,YAAY,kBAAkB,EAAE,MAAM,MAAM,MAAS;AAAA,EACrF;AAAA,EAEA,UAA6B;AAC3B,SAAK,MAAM;AACX,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,QAA2B;AACzB,YAAQ,KAAK,YAAY,SAAS,OAAO,WAAW,CAAC,GAAG,IAAI,CAAC,YAAY;AAAA,MACvE,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO;AAAA,MACd,SAAS;AAAA,IACX,EAAE;AAAA,EACJ;AAAA,EAEA,cAA6B;AAC3B,SAAK,MAAM;AACX,WAAO,KAAK,YAAY,SAAS,OAAO,eAAe;AAAA,EACzD;AAAA,EAEA,WAA8B;AAC5B,WAAO,CAAC,aAAa;AAAA,EACvB;AAAA,EAEA,OAAO,MAAoB;AACzB;AAAA,MACE,KAAK,YAAY,QAAQ,aAAa,MAAM,kBAAkB;AAAA,MAC9D;AAAA,MACA,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,MAA6B;AACxC,UAAM,SAAS,MAAM,KAAK,YAAY,QAAQ,aAAa,MAAM,kBAAkB;AACnF,QAAI,OAAO,UAAU,KAAM,OAAM,IAAI,MAAM,OAAO,KAAK;AAAA,EACzD;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,6 +4,7 @@ export declare const MAX_TEXT: number;
|
|
|
4
4
|
export declare const MAX_FILES = 200;
|
|
5
5
|
export declare const SCAN_DEPTH = 3;
|
|
6
6
|
export declare const SCAN_ENTRIES = 200;
|
|
7
|
+
export declare const CLONE_COMMAND = "curl -fsSL https://get.sliccy.ai/slicc | sh";
|
|
7
8
|
export declare const NO_GIT = "Changes needs git, and git isn't installed. Install it with `pnpm add -g @ai-ecoverse/wasm-git`, then run `git init` in a folder under /home. To clone from the internet, link slicc or the SLICC extension.";
|
|
8
9
|
export declare const NO_REPO = "Changes lists the changes in git repositories, and there are none here yet. Run `git init` in a folder under /home. To clone from the internet, link slicc or the SLICC extension.";
|
|
9
10
|
export type ChangeStatus = 'added' | 'modified' | 'deleted';
|
|
@@ -10,6 +10,7 @@ export declare class ChangesAdapter extends Emitter<ChangesEvents> implements Ch
|
|
|
10
10
|
constructor(connection: AgentConnection, report?: Report);
|
|
11
11
|
changes(): readonly Change[];
|
|
12
12
|
unavailable(): string | null;
|
|
13
|
+
commands(): readonly string[];
|
|
13
14
|
accept(path: string): void;
|
|
14
15
|
revert(path: string): Promise<void>;
|
|
15
16
|
}
|
package/package.json
CHANGED