@ai-ecoverse/slicc-agent 6.11.1 → 6.11.2
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 +11 -3
- package/dist/control.js.map +1 -1
- package/dist/host.js.map +1 -1
- package/dist/secrets/extension.js +35 -15
- package/dist/secrets/extension.js.map +2 -2
- package/dist/secrets/names.js +175 -26
- package/dist/secrets/names.js.map +3 -3
- package/dist/secrets/view.js +12 -2
- package/dist/secrets/view.js.map +2 -2
- package/dist/spectrum/messages.js +6 -2
- package/dist/spectrum/messages.js.map +2 -2
- package/dist/types/control.d.ts +2 -2
- package/dist/types/host.d.ts +2 -2
- package/dist/types/secrets/extension.d.ts +10 -6
- package/dist/types/secrets/names.d.ts +34 -6
- package/dist/types/secrets/view.d.ts +7 -2
- package/package.json +2 -1
package/dist/secrets/names.js
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { replicatedState } from "@earendil-works/chord";
|
|
2
|
-
const
|
|
2
|
+
const DESCRIBE = "fnox env --json --describe";
|
|
3
|
+
const RULES = "fnox proxy rules --json";
|
|
4
|
+
const SEALED_LIST = `exec 3<>/dev/sealed && printf '%s' '{"v":1,"op":"list"}' >&3 && cat <&3`;
|
|
5
|
+
const NO_PROXY = "No [proxy] configuration found";
|
|
6
|
+
const MISSING = "fnox isn't installed";
|
|
7
|
+
const EXPOSED = "shell grants are off: fnox exec would also give every command the unsealed fnox secrets";
|
|
8
|
+
const FNOX_ENV = /(^|[\s;&|(])fnox\s+env(\s|$)/;
|
|
9
|
+
const DESCRIBING = /(^|\s)--describe(\s|$)/;
|
|
10
|
+
function guarded(command) {
|
|
11
|
+
if (FNOX_ENV.test(command) && !DESCRIBING.test(command))
|
|
12
|
+
throw new Error(
|
|
13
|
+
`refused to run ${JSON.stringify(command)}: without --describe it prints values`
|
|
14
|
+
);
|
|
15
|
+
return command;
|
|
16
|
+
}
|
|
3
17
|
function strings(value) {
|
|
4
18
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : void 0;
|
|
5
19
|
}
|
|
@@ -11,50 +25,175 @@ function ruleOf(value) {
|
|
|
11
25
|
return [
|
|
12
26
|
{
|
|
13
27
|
domain: rule.domain,
|
|
14
|
-
...typeof rule.header === "string" ? { header: rule.header } : {},
|
|
15
|
-
...methods ? { methods } : {},
|
|
16
|
-
...paths ? { paths } : {}
|
|
28
|
+
...typeof rule.header === "string" && rule.header ? { header: rule.header } : {},
|
|
29
|
+
...methods?.length ? { methods } : {},
|
|
30
|
+
...paths?.length ? { paths } : {}
|
|
17
31
|
}
|
|
18
32
|
];
|
|
19
33
|
}
|
|
20
34
|
const EXEC = /* @__PURE__ */ new Set(["any", "argv", "shell"]);
|
|
21
|
-
function
|
|
22
|
-
let parsed;
|
|
35
|
+
function json(text) {
|
|
23
36
|
try {
|
|
24
|
-
|
|
37
|
+
return JSON.parse(text);
|
|
25
38
|
} catch {
|
|
26
|
-
return
|
|
39
|
+
return void 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const line = (text) => text.replace(/\s+/g, " ").trim();
|
|
43
|
+
class Unavailable extends Error {
|
|
44
|
+
detail;
|
|
45
|
+
constructor(shown, detail) {
|
|
46
|
+
super(shown);
|
|
47
|
+
this.detail = detail;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const word = (value, shape) => typeof value === "string" && shape.test(value) ? value : void 0;
|
|
51
|
+
function parseDescribe(text) {
|
|
52
|
+
const keys = json(text)?.keys;
|
|
53
|
+
if (!Array.isArray(keys)) throw new Unavailable("fnox env --describe printed unparseable output");
|
|
54
|
+
return keys.flatMap(
|
|
55
|
+
(item) => item?.kind === "secret" && typeof item.key === "string" ? [
|
|
56
|
+
{
|
|
57
|
+
name: item.key,
|
|
58
|
+
injected: item.injectable?.exec !== false
|
|
59
|
+
}
|
|
60
|
+
] : []
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function parseRules(text) {
|
|
64
|
+
const rules2 = json(text)?.rules;
|
|
65
|
+
if (!Array.isArray(rules2)) throw new Unavailable("fnox proxy rules printed unparseable output");
|
|
66
|
+
const out = /* @__PURE__ */ new Map();
|
|
67
|
+
for (const rule of rules2) {
|
|
68
|
+
if (typeof rule?.secret !== "string") continue;
|
|
69
|
+
const found = ruleOf(rule).map((item) => ({ ...item, proposed: true }));
|
|
70
|
+
out.set(rule.secret, [...out.get(rule.secret) ?? [], ...found]);
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
function parseSealed(text) {
|
|
75
|
+
const reply = json(text);
|
|
76
|
+
if (reply?.error) {
|
|
77
|
+
const code = word(reply.error.code, /^[A-Z][A-Z0-9_]{0,31}$/);
|
|
78
|
+
throw new Unavailable(
|
|
79
|
+
code ? `the vault refused to list secrets (${code})` : "the vault refused to list secrets",
|
|
80
|
+
`${String(reply.error.code ?? "")} ${String(reply.error.message ?? "")}`
|
|
81
|
+
);
|
|
27
82
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return
|
|
83
|
+
if (!Array.isArray(reply?.secrets))
|
|
84
|
+
throw new Unavailable("the vault's list reply is unparseable");
|
|
85
|
+
return reply.secrets.flatMap((item) => {
|
|
31
86
|
if (typeof item?.name !== "string" || typeof item.placeholder !== "string") return [];
|
|
32
87
|
const exec = EXEC.has(item.exec) ? item.exec : false;
|
|
33
|
-
const
|
|
34
|
-
return [{ name: item.name, placeholder: item.placeholder, exec, rules }];
|
|
88
|
+
const rules2 = Array.isArray(item.rules) ? item.rules.flatMap(ruleOf) : [];
|
|
89
|
+
return [{ name: item.name, placeholder: item.placeholder, exec, rules: rules2 }];
|
|
35
90
|
});
|
|
36
91
|
}
|
|
37
|
-
|
|
38
|
-
|
|
92
|
+
function joinNames(keys, proposed, sealed2) {
|
|
93
|
+
const vault = new Map(sealed2.map((item) => [item.name, item]));
|
|
94
|
+
const rules2 = (name, own) => own.length ? own : proposed.get(name) ?? [];
|
|
95
|
+
const named = keys.map(({ name }) => {
|
|
96
|
+
const held = vault.get(name);
|
|
97
|
+
return held ? { ...held, rules: rules2(name, held.rules), fnox: true } : { name, placeholder: null, exec: false, rules: rules2(name, []), fnox: true };
|
|
98
|
+
});
|
|
99
|
+
const known = new Set(keys.map((key) => key.name));
|
|
100
|
+
const extra = sealed2.filter((item) => !known.has(item.name)).map((item) => ({ ...item, rules: rules2(item.name, item.rules), fnox: false }));
|
|
101
|
+
const exposed = keys.filter((key) => key.injected && !vault.has(key.name)).map((key) => key.name);
|
|
102
|
+
return { names: [...named, ...extra], error: null, exposed };
|
|
103
|
+
}
|
|
104
|
+
async function run(env, label, command, context) {
|
|
105
|
+
const out = { stdout: "", stderr: "" };
|
|
39
106
|
const ran = await env.exec(
|
|
40
|
-
|
|
107
|
+
guarded(command),
|
|
41
108
|
{
|
|
42
109
|
onOutput: (text, _using, info) => {
|
|
43
|
-
|
|
110
|
+
out[info?.stream === "stderr" ? "stderr" : "stdout"] += text;
|
|
44
111
|
}
|
|
45
112
|
},
|
|
46
113
|
context
|
|
47
|
-
)
|
|
48
|
-
|
|
114
|
+
);
|
|
115
|
+
if (!ran.ok)
|
|
116
|
+
throw new Unavailable(`${label} couldn't run (${ran.error.code})`, ran.error.message);
|
|
117
|
+
return { code: ran.value.exitCode ?? 1, ...out };
|
|
49
118
|
}
|
|
50
|
-
|
|
51
|
-
|
|
119
|
+
const KINDS = {
|
|
120
|
+
config: "the fnox config has an error; check /etc/fnox/config.toml"
|
|
121
|
+
};
|
|
122
|
+
function failed(label, ran) {
|
|
123
|
+
if (ran.code === 127) return new Unavailable(MISSING);
|
|
124
|
+
const error = json(ran.stdout)?.error;
|
|
125
|
+
const kind = word(error?.kind, /^[a-z][a-z_]{0,31}$/);
|
|
126
|
+
const detail = typeof error?.message === "string" ? error.message : void 0;
|
|
127
|
+
if (kind) return new Unavailable(KINDS[kind] ?? `${label} failed (${kind})`, detail);
|
|
128
|
+
return new Unavailable(`${label} exited ${ran.code}`, detail);
|
|
129
|
+
}
|
|
130
|
+
async function describe(env, context) {
|
|
131
|
+
const label = "fnox env --describe";
|
|
132
|
+
const ran = await run(env, label, DESCRIBE, context);
|
|
133
|
+
if (ran.code !== 0) throw failed(label, ran);
|
|
134
|
+
return parseDescribe(ran.stdout);
|
|
135
|
+
}
|
|
136
|
+
async function rules(env, context) {
|
|
137
|
+
const ran = await run(env, "fnox proxy rules", RULES, context);
|
|
138
|
+
if (ran.code === 1 && ran.stderr.includes(NO_PROXY)) return /* @__PURE__ */ new Map();
|
|
139
|
+
if (ran.code !== 0) throw failed("fnox proxy rules", ran);
|
|
140
|
+
return parseRules(ran.stdout);
|
|
141
|
+
}
|
|
142
|
+
async function sealed(env, context) {
|
|
143
|
+
const ran = await run(env, "/dev/sealed", SEALED_LIST, context);
|
|
144
|
+
if (ran.code !== 0) throw new Unavailable(`/dev/sealed couldn't be read (exit ${ran.code})`);
|
|
145
|
+
return parseSealed(ran.stdout);
|
|
146
|
+
}
|
|
147
|
+
async function listNames(env, context) {
|
|
148
|
+
const [keys, proposed, held] = await Promise.allSettled([
|
|
149
|
+
describe(env, context),
|
|
150
|
+
rules(env, context),
|
|
151
|
+
sealed(env, context)
|
|
152
|
+
]);
|
|
153
|
+
if (keys.status === "fulfilled" && proposed.status === "fulfilled" && held.status === "fulfilled")
|
|
154
|
+
return { listing: joinNames(keys.value, proposed.value, held.value), details: [] };
|
|
155
|
+
const failures = [keys, proposed, held].flatMap(
|
|
156
|
+
(item) => item.status === "rejected" ? [
|
|
157
|
+
item.reason instanceof Unavailable ? item.reason : new Unavailable("listing failed", String(item.reason))
|
|
158
|
+
] : []
|
|
159
|
+
);
|
|
160
|
+
return {
|
|
161
|
+
listing: {
|
|
162
|
+
names: [],
|
|
163
|
+
error: [...new Set(failures.map((item) => item.message))].join("; "),
|
|
164
|
+
exposed: []
|
|
165
|
+
},
|
|
166
|
+
details: failures.flatMap((item) => item.detail ? [line(item.detail)] : [])
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function secretNames(env, vault, warn = (message) => console.warn(message)) {
|
|
170
|
+
const state = replicatedState({ names: [], error: null, exposed: [] });
|
|
52
171
|
let version = vault.state.value.version;
|
|
172
|
+
let warned = null;
|
|
53
173
|
let lock = Promise.resolve();
|
|
174
|
+
const report = async (listing, details) => {
|
|
175
|
+
const said = listing.error ?? (listing.exposed.length ? EXPOSED : null);
|
|
176
|
+
const fresh = said !== warned;
|
|
177
|
+
warned = said;
|
|
178
|
+
if (said && fresh) {
|
|
179
|
+
const shown = details.length ? await vault.texts(details).then(
|
|
180
|
+
(texts) => texts.join("; ").slice(0, 200),
|
|
181
|
+
() => ""
|
|
182
|
+
) : "";
|
|
183
|
+
const named = listing.error ? "" : listing.exposed.join(", ");
|
|
184
|
+
warn(
|
|
185
|
+
`slicc-secrets: ${listing.error ? `secrets are unavailable: ${said}` : `${said}: ${named}`}${shown ? ` (${shown})` : ""}`
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
54
189
|
const refresh = (context) => {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
190
|
+
const run2 = lock.then(async () => {
|
|
191
|
+
const { listing, details } = await listNames(env, context);
|
|
192
|
+
state.replace(context, listing);
|
|
193
|
+
void report(listing, details);
|
|
194
|
+
});
|
|
195
|
+
lock = run2.catch(() => void 0);
|
|
196
|
+
return run2;
|
|
58
197
|
};
|
|
59
198
|
const off = vault.state.subscribe((value, context) => {
|
|
60
199
|
if (value.version === version) return;
|
|
@@ -64,9 +203,19 @@ function secretNames(env, vault) {
|
|
|
64
203
|
return { state, refresh, close: off };
|
|
65
204
|
}
|
|
66
205
|
export {
|
|
67
|
-
|
|
206
|
+
DESCRIBE,
|
|
207
|
+
EXPOSED,
|
|
208
|
+
MISSING,
|
|
209
|
+
NO_PROXY,
|
|
210
|
+
RULES,
|
|
211
|
+
SEALED_LIST,
|
|
212
|
+
Unavailable,
|
|
213
|
+
guarded,
|
|
214
|
+
joinNames,
|
|
68
215
|
listNames,
|
|
69
|
-
|
|
216
|
+
parseDescribe,
|
|
217
|
+
parseRules,
|
|
218
|
+
parseSealed,
|
|
70
219
|
secretNames
|
|
71
220
|
};
|
|
72
221
|
//# sourceMappingURL=names.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/secrets/names.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Context, type MutableReplicatedState, replicatedState } from '@earendil-works/chord';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport type { Vault } from './vault.ts';\n\nexport interface SecretRule {\n domain: string;\n header?: string;\n methods?: string[];\n paths?: string[];\n}\n\nexport interface SecretName {\n name: string;\n placeholder: string;\n exec: false | 'any' | 'argv' | 'shell';\n rules: SecretRule[];\n}\n\nexport const LIST = 'secret list --json';\n\nfunction strings(value: unknown): string[] | undefined {\n return Array.isArray(value) ? value.filter((item) => typeof item === 'string') : undefined;\n}\n\nfunction ruleOf(value: unknown): SecretRule[] {\n const rule = value as Record<string, unknown> | null;\n if (typeof rule?.domain !== 'string') return [];\n const methods = strings(rule.methods);\n const paths = strings(rule.paths);\n return [\n {\n domain: rule.domain,\n ...(typeof rule.header === 'string' ? { header: rule.header } : {}),\n ...(methods ? { methods } : {}),\n ...(paths ? { paths } : {}),\n },\n ];\n}\n\nconst EXEC = new Set(['any', 'argv', 'shell']);\n\nexport function parseNames(text: string): SecretName[] {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return [];\n }\n const list = (parsed as { secrets?: unknown } | null)?.secrets;\n if (!Array.isArray(list)) return [];\n return list.flatMap((item: Record<string, unknown> | null) => {\n if (typeof item?.name !== 'string' || typeof item.placeholder !== 'string') return [];\n const exec = EXEC.has(item.exec as string) ? (item.exec as SecretName['exec']) : false;\n const rules = Array.isArray(item.rules) ? item.rules.flatMap(ruleOf) : [];\n return [{ name: item.name, placeholder: item.placeholder, exec, rules }];\n });\n}\n\nexport async function listNames(env: ExecutionEnv, context: Context): Promise<SecretName[]> {\n let out = '';\n const ran = await env\n .exec(\n LIST,\n {\n onOutput: (text, _using, info) => {\n if (info?.stream !== 'stderr') out += text;\n },\n },\n context\n )\n .catch(() => undefined);\n return ran?.ok && ran.value.exitCode === 0 ? parseNames(out) : [];\n}\n\nexport interface Names {\n readonly state: MutableReplicatedState<SecretName[]>;\n refresh(context: Context): Promise<void>;\n close(): void;\n}\n\nexport function secretNames(env: ExecutionEnv, vault: Pick<Vault, 'state'>): Names {\n const state = replicatedState<SecretName[]>([]);\n let version = vault.state.value.version;\n let lock: Promise<unknown> = Promise.resolve();\n const refresh = (context: Context) => {\n const run = lock.then(async () => state.replace(context, await listNames(env, context)));\n lock = run.catch(() => undefined);\n return run;\n };\n const off = vault.state.subscribe((value, context) => {\n if (value.version === version) return;\n version = value.version;\n void refresh(context).catch(() => undefined);\n });\n return { state, refresh, close: off };\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAoD,uBAAuB;
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["import { type Context, type MutableReplicatedState, replicatedState } from '@earendil-works/chord';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport type { Vault } from './vault.ts';\n\nexport interface SecretRule {\n domain: string;\n header?: string;\n methods?: string[];\n paths?: string[];\n proposed?: true;\n}\n\nexport interface SecretName {\n name: string;\n placeholder: string | null;\n exec: false | 'any' | 'argv' | 'shell';\n rules: SecretRule[];\n fnox: boolean;\n}\n\nexport interface SecretListing {\n names: SecretName[];\n error: string | null;\n exposed: string[];\n}\n\nexport const DESCRIBE = 'fnox env --json --describe';\nexport const RULES = 'fnox proxy rules --json';\nexport const SEALED_LIST = `exec 3<>/dev/sealed && printf '%s' '{\"v\":1,\"op\":\"list\"}' >&3 && cat <&3`;\nexport const NO_PROXY = 'No [proxy] configuration found';\nexport const MISSING = \"fnox isn't installed\";\nexport const EXPOSED =\n 'shell grants are off: fnox exec would also give every command the unsealed fnox secrets';\n\nconst FNOX_ENV = /(^|[\\s;&|(])fnox\\s+env(\\s|$)/;\nconst DESCRIBING = /(^|\\s)--describe(\\s|$)/;\n\nexport function guarded(command: string): string {\n if (FNOX_ENV.test(command) && !DESCRIBING.test(command))\n throw new Error(\n `refused to run ${JSON.stringify(command)}: without --describe it prints values`\n );\n return command;\n}\n\nfunction strings(value: unknown): string[] | undefined {\n return Array.isArray(value) ? value.filter((item) => typeof item === 'string') : undefined;\n}\n\nfunction ruleOf(value: unknown): SecretRule[] {\n const rule = value as Record<string, unknown> | null;\n if (typeof rule?.domain !== 'string') return [];\n const methods = strings(rule.methods);\n const paths = strings(rule.paths);\n return [\n {\n domain: rule.domain,\n ...(typeof rule.header === 'string' && rule.header ? { header: rule.header } : {}),\n ...(methods?.length ? { methods } : {}),\n ...(paths?.length ? { paths } : {}),\n },\n ];\n}\n\nconst EXEC = new Set(['any', 'argv', 'shell']);\n\nfunction json(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nconst line = (text: string) => text.replace(/\\s+/g, ' ').trim();\n\nexport class Unavailable extends Error {\n readonly detail: string | undefined;\n constructor(shown: string, detail?: string) {\n super(shown);\n this.detail = detail;\n }\n}\n\nconst word = (value: unknown, shape: RegExp) =>\n typeof value === 'string' && shape.test(value) ? value : undefined;\n\nexport interface FnoxKey {\n name: string;\n injected: boolean;\n}\n\nexport function parseDescribe(text: string): FnoxKey[] {\n const keys = (json(text) as { keys?: unknown } | null | undefined)?.keys;\n if (!Array.isArray(keys)) throw new Unavailable('fnox env --describe printed unparseable output');\n return keys.flatMap((item: Record<string, unknown> | null) =>\n item?.kind === 'secret' && typeof item.key === 'string'\n ? [\n {\n name: item.key,\n injected: (item.injectable as { exec?: unknown } | undefined)?.exec !== false,\n },\n ]\n : []\n );\n}\n\nexport function parseRules(text: string): Map<string, SecretRule[]> {\n const rules = (json(text) as { rules?: unknown } | null | undefined)?.rules;\n if (!Array.isArray(rules)) throw new Unavailable('fnox proxy rules printed unparseable output');\n const out = new Map<string, SecretRule[]>();\n for (const rule of rules as (Record<string, unknown> | null)[]) {\n if (typeof rule?.secret !== 'string') continue;\n const found = ruleOf(rule).map((item) => ({ ...item, proposed: true as const }));\n out.set(rule.secret, [...(out.get(rule.secret) ?? []), ...found]);\n }\n return out;\n}\n\nexport function parseSealed(text: string): Omit<SecretName, 'fnox'>[] {\n const reply = json(text) as { secrets?: unknown; error?: { code?: unknown; message?: unknown } };\n if (reply?.error) {\n const code = word(reply.error.code, /^[A-Z][A-Z0-9_]{0,31}$/);\n throw new Unavailable(\n code ? `the vault refused to list secrets (${code})` : 'the vault refused to list secrets',\n `${String(reply.error.code ?? '')} ${String(reply.error.message ?? '')}`\n );\n }\n if (!Array.isArray(reply?.secrets))\n throw new Unavailable(\"the vault's list reply is unparseable\");\n return reply.secrets.flatMap((item: Record<string, unknown> | null) => {\n if (typeof item?.name !== 'string' || typeof item.placeholder !== 'string') return [];\n const exec = EXEC.has(item.exec as string) ? (item.exec as SecretName['exec']) : false;\n const rules = Array.isArray(item.rules) ? item.rules.flatMap(ruleOf) : [];\n return [{ name: item.name, placeholder: item.placeholder, exec, rules }];\n });\n}\n\nexport function joinNames(\n keys: readonly FnoxKey[],\n proposed: ReadonlyMap<string, SecretRule[]>,\n sealed: readonly Omit<SecretName, 'fnox'>[]\n): SecretListing {\n const vault = new Map(sealed.map((item) => [item.name, item]));\n const rules = (name: string, own: SecretRule[]) =>\n own.length ? own : (proposed.get(name) ?? []);\n const named = keys.map(({ name }): SecretName => {\n const held = vault.get(name);\n return held\n ? { ...held, rules: rules(name, held.rules), fnox: true }\n : { name, placeholder: null, exec: false, rules: rules(name, []), fnox: true };\n });\n const known = new Set(keys.map((key) => key.name));\n const extra = sealed\n .filter((item) => !known.has(item.name))\n .map((item) => ({ ...item, rules: rules(item.name, item.rules), fnox: false }));\n const exposed = keys.filter((key) => key.injected && !vault.has(key.name)).map((key) => key.name);\n return { names: [...named, ...extra], error: null, exposed };\n}\n\ninterface Ran {\n code: number;\n stdout: string;\n stderr: string;\n}\n\nasync function run(\n env: ExecutionEnv,\n label: string,\n command: string,\n context: Context\n): Promise<Ran> {\n const out = { stdout: '', stderr: '' };\n const ran = await env.exec(\n guarded(command),\n {\n onOutput: (text, _using, info) => {\n out[info?.stream === 'stderr' ? 'stderr' : 'stdout'] += text;\n },\n },\n context\n );\n if (!ran.ok)\n throw new Unavailable(`${label} couldn't run (${ran.error.code})`, ran.error.message);\n return { code: ran.value.exitCode ?? 1, ...out };\n}\n\nconst KINDS: Record<string, string> = {\n config: 'the fnox config has an error; check /etc/fnox/config.toml',\n};\n\nfunction failed(label: string, ran: Ran): Unavailable {\n if (ran.code === 127) return new Unavailable(MISSING);\n const error = (json(ran.stdout) as { error?: { kind?: unknown; message?: unknown } } | undefined)\n ?.error;\n const kind = word(error?.kind, /^[a-z][a-z_]{0,31}$/);\n const detail = typeof error?.message === 'string' ? error.message : undefined;\n if (kind) return new Unavailable(KINDS[kind] ?? `${label} failed (${kind})`, detail);\n return new Unavailable(`${label} exited ${ran.code}`, detail);\n}\n\nasync function describe(env: ExecutionEnv, context: Context) {\n const label = 'fnox env --describe';\n const ran = await run(env, label, DESCRIBE, context);\n if (ran.code !== 0) throw failed(label, ran);\n return parseDescribe(ran.stdout);\n}\n\nasync function rules(env: ExecutionEnv, context: Context) {\n const ran = await run(env, 'fnox proxy rules', RULES, context);\n if (ran.code === 1 && ran.stderr.includes(NO_PROXY)) return new Map<string, SecretRule[]>();\n if (ran.code !== 0) throw failed('fnox proxy rules', ran);\n return parseRules(ran.stdout);\n}\n\nasync function sealed(env: ExecutionEnv, context: Context) {\n const ran = await run(env, '/dev/sealed', SEALED_LIST, context);\n if (ran.code !== 0) throw new Unavailable(`/dev/sealed couldn't be read (exit ${ran.code})`);\n return parseSealed(ran.stdout);\n}\n\nexport interface Listed {\n listing: SecretListing;\n details: string[];\n}\n\nexport async function listNames(env: ExecutionEnv, context: Context): Promise<Listed> {\n const [keys, proposed, held] = await Promise.allSettled([\n describe(env, context),\n rules(env, context),\n sealed(env, context),\n ]);\n if (keys.status === 'fulfilled' && proposed.status === 'fulfilled' && held.status === 'fulfilled')\n return { listing: joinNames(keys.value, proposed.value, held.value), details: [] };\n const failures = [keys, proposed, held].flatMap((item) =>\n item.status === 'rejected'\n ? [\n item.reason instanceof Unavailable\n ? item.reason\n : new Unavailable('listing failed', String(item.reason)),\n ]\n : []\n );\n return {\n listing: {\n names: [],\n error: [...new Set(failures.map((item) => item.message))].join('; '),\n exposed: [],\n },\n details: failures.flatMap((item) => (item.detail ? [line(item.detail)] : [])),\n };\n}\n\nexport interface Names {\n readonly state: MutableReplicatedState<SecretListing>;\n refresh(context: Context): Promise<void>;\n close(): void;\n}\n\nexport function secretNames(\n env: ExecutionEnv,\n vault: Pick<Vault, 'state' | 'texts'>,\n warn: (message: string) => void = (message) => console.warn(message)\n): Names {\n const state = replicatedState<SecretListing>({ names: [], error: null, exposed: [] });\n let version = vault.state.value.version;\n let warned: string | null = null;\n let lock: Promise<unknown> = Promise.resolve();\n const report = async (listing: SecretListing, details: string[]) => {\n const said = listing.error ?? (listing.exposed.length ? EXPOSED : null);\n const fresh = said !== warned;\n warned = said;\n if (said && fresh) {\n const shown = details.length\n ? await vault.texts(details).then(\n (texts) => texts.join('; ').slice(0, 200),\n () => ''\n )\n : '';\n const named = listing.error ? '' : listing.exposed.join(', ');\n warn(\n `slicc-secrets: ${listing.error ? `secrets are unavailable: ${said}` : `${said}: ${named}`}${shown ? ` (${shown})` : ''}`\n );\n }\n };\n const refresh = (context: Context) => {\n const run = lock.then(async () => {\n const { listing, details } = await listNames(env, context);\n state.replace(context, listing);\n void report(listing, details);\n });\n lock = run.catch(() => undefined);\n return run;\n };\n const off = vault.state.subscribe((value, context) => {\n if (value.version === version) return;\n version = value.version;\n void refresh(context).catch(() => undefined);\n });\n return { state, refresh, close: off };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["rules", "sealed", "run"]
|
|
7
7
|
}
|
package/dist/secrets/view.js
CHANGED
|
@@ -4,12 +4,22 @@ function vaultHold(state) {
|
|
|
4
4
|
if (state.locked === "passkey") return { reason: "locked", held: state.held };
|
|
5
5
|
return state.port === "ready" ? null : { reason: "waiting", held: state.held };
|
|
6
6
|
}
|
|
7
|
-
function
|
|
8
|
-
return `
|
|
7
|
+
function unavailableLine(reason) {
|
|
8
|
+
return `Secrets are unavailable: ${reason.replace(/\.+$/, "")}.`;
|
|
9
|
+
}
|
|
10
|
+
function exposedLine(exposed) {
|
|
11
|
+
return `Shell grants are off: fnox exec would also give every command the unsealed fnox secrets ${exposed.join(", ")}; seal them or set env = false for them.`;
|
|
12
|
+
}
|
|
13
|
+
function listedLine(listing) {
|
|
14
|
+
if (listing.error) return unavailableLine(listing.error);
|
|
15
|
+
const listed = `The user listed secrets: ${listing.names.length ? listing.names.map((name) => name.name).join(", ") : "none"}.`;
|
|
16
|
+
return listing.exposed?.length ? `${listed} ${exposedLine(listing.exposed)}` : listed;
|
|
9
17
|
}
|
|
10
18
|
export {
|
|
11
19
|
SECRETS_KIND,
|
|
20
|
+
exposedLine,
|
|
12
21
|
listedLine,
|
|
22
|
+
unavailableLine,
|
|
13
23
|
vaultHold
|
|
14
24
|
};
|
|
15
25
|
//# sourceMappingURL=view.js.map
|
package/dist/secrets/view.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/secrets/view.ts"],
|
|
4
|
-
"sourcesContent": ["import type {
|
|
5
|
-
"mappings": "AAGO,MAAM,eAAe;AAOrB,SAAS,UAAU,OAAiD;AACzE,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,MAAI,MAAM,WAAW,UAAW,QAAO,EAAE,QAAQ,UAAU,MAAM,MAAM,KAAK;AAC5E,SAAO,MAAM,SAAS,UAAU,OAAO,EAAE,QAAQ,WAAW,MAAM,MAAM,KAAK;AAC/E;AAEO,SAAS,
|
|
4
|
+
"sourcesContent": ["import type { SecretListing } from './names.ts';\nimport type { VaultState } from './vault.ts';\n\nexport const SECRETS_KIND = 'slicc.secrets';\n\nexport interface VaultHold {\n reason: 'waiting' | 'locked';\n held: number;\n}\n\nexport function vaultHold(state: VaultState | undefined): VaultHold | null {\n if (!state?.needed) return null;\n if (state.locked === 'passkey') return { reason: 'locked', held: state.held };\n return state.port === 'ready' ? null : { reason: 'waiting', held: state.held };\n}\n\nexport function unavailableLine(reason: string): string {\n return `Secrets are unavailable: ${reason.replace(/\\.+$/, '')}.`;\n}\n\nexport function exposedLine(exposed: readonly string[]): string {\n return `Shell grants are off: fnox exec would also give every command the unsealed fnox secrets ${exposed.join(', ')}; seal them or set env = false for them.`;\n}\n\nexport function listedLine(\n listing: Pick<SecretListing, 'names'> & { error?: string | null; exposed?: string[] }\n): string {\n if (listing.error) return unavailableLine(listing.error);\n const listed = `The user listed secrets: ${listing.names.length ? listing.names.map((name) => name.name).join(', ') : 'none'}.`;\n return listing.exposed?.length ? `${listed} ${exposedLine(listing.exposed)}` : listed;\n}\n"],
|
|
5
|
+
"mappings": "AAGO,MAAM,eAAe;AAOrB,SAAS,UAAU,OAAiD;AACzE,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,MAAI,MAAM,WAAW,UAAW,QAAO,EAAE,QAAQ,UAAU,MAAM,MAAM,KAAK;AAC5E,SAAO,MAAM,SAAS,UAAU,OAAO,EAAE,QAAQ,WAAW,MAAM,MAAM,KAAK;AAC/E;AAEO,SAAS,gBAAgB,QAAwB;AACtD,SAAO,4BAA4B,OAAO,QAAQ,QAAQ,EAAE,CAAC;AAC/D;AAEO,SAAS,YAAY,SAAoC;AAC9D,SAAO,2FAA2F,QAAQ,KAAK,IAAI,CAAC;AACtH;AAEO,SAAS,WACd,SACQ;AACR,MAAI,QAAQ,MAAO,QAAO,gBAAgB,QAAQ,KAAK;AACvD,QAAM,SAAS,4BAA4B,QAAQ,MAAM,SAAS,QAAQ,MAAM,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,KAAK,IAAI,IAAI,MAAM;AAC5H,SAAO,QAAQ,SAAS,SAAS,GAAG,MAAM,IAAI,YAAY,QAAQ,OAAO,CAAC,KAAK;AACjF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -413,8 +413,12 @@ function secrets(id, entry) {
|
|
|
413
413
|
id,
|
|
414
414
|
role: "system",
|
|
415
415
|
kind: "notice",
|
|
416
|
-
title: "Secrets listed",
|
|
417
|
-
text: listedLine(
|
|
416
|
+
title: data.error ? "Secrets unavailable" : "Secrets listed",
|
|
417
|
+
text: listedLine({
|
|
418
|
+
names: data.names ?? [],
|
|
419
|
+
error: data.error ?? null,
|
|
420
|
+
exposed: data.exposed ?? []
|
|
421
|
+
}),
|
|
418
422
|
createdAt: entry.model?.[0]?.timestamp ?? 0
|
|
419
423
|
};
|
|
420
424
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/spectrum/messages.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n AssistantMessage,\n AssistantStatus,\n ErrorAction,\n LickMessage,\n Message,\n MessagePart,\n SystemMessage,\n ToolCall,\n ToolStatus,\n Usage,\n UserMessage,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport type { ConversationView, EntryRecord } from '@earendil-works/pi-durable';\nimport { splitUser } from '../attachments.ts';\nimport {\n ASKED_KIND,\n askedLine,\n GUEST_INPUT_KIND,\n type GuestAsked,\n type GuestInput,\n type GuestOutcome,\n type GuestReviewed,\n guestText,\n REVIEWED_KIND,\n} from '../guests/attribution.ts';\nimport { parseLick } from '../licks/lick.ts';\nimport { entryLick, LICK_TOOLS, type LickDecision, lickDecisions } from '../licks/state.ts';\nimport { mcpLabel } from '../mcp/label.ts';\nimport { FROM_KIND, type From } from '../scoops/from.ts';\nimport type { SecretName } from '../secrets/names.ts';\nimport { listedLine, SECRETS_KIND } from '../secrets/view.ts';\nimport type { Delivered } from '../services.ts';\nimport { SPRINKLE_KIND } from '../sprinkles/kind.ts';\nimport { warn } from './attempt.ts';\n\ntype Json = Record<string, unknown>;\n\ninterface Block {\n type: string;\n text?: string;\n thinking?: string;\n id?: string;\n name?: string;\n arguments?: Json;\n}\n\ninterface ModelMessage {\n role: string;\n content?: string | Block[];\n timestamp?: number;\n stopReason?: string;\n errorMessage?: string;\n provider?: string;\n model?: string;\n usage?: {\n input?: number;\n output?: number;\n cacheRead?: number;\n cacheWrite?: number;\n cost?: { total?: number };\n };\n toolCallId?: string;\n isError?: boolean;\n details?: { patch?: unknown };\n}\n\ninterface Slot {\n callId: string;\n status: string;\n output?: string;\n}\n\ninterface Live {\n run?: unknown;\n generation?: { message?: ModelMessage; retry?: { at: number; error: string } };\n tools?: Slot[];\n compactions?: { taskId: number; reason: string }[];\n}\n\nexport function textOf(content: ModelMessage['content']): string {\n if (typeof content === 'string') return content;\n return (content ?? []).map((block) => (block.type === 'text' ? (block.text ?? '') : '')).join('');\n}\n\nconst paths = (args: Json | undefined): string[] =>\n typeof args?.path === 'string' ? [args.path] : [];\n\nfunction title(args: Json | undefined): string {\n const subject = args?.command ?? args?.path;\n return typeof subject === 'string' ? subject : '';\n}\n\ninterface Replacement {\n oldText?: string;\n newText?: string;\n}\n\nconst GAP = '\u2026';\n\nfunction seconds(value: unknown): string | undefined {\n return typeof value === 'number' ? `timeout ${value}s` : undefined;\n}\n\nfunction lines(args: Json): string | undefined {\n const { offset, limit } = args as { offset?: number; limit?: number };\n if (typeof offset === 'number' && typeof limit === 'number')\n return `lines ${offset}\u2013${offset + limit - 1}`;\n if (typeof offset === 'number') return `from line ${offset}`;\n return typeof limit === 'number' ? `first ${limit} lines` : undefined;\n}\n\nfunction edits(args: Json): ToolCall['diff'] {\n const list = Array.isArray(args.edits) ? (args.edits as Replacement[]) : [];\n if (list.length === 0) return undefined;\n return {\n before: list.map((edit) => edit.oldText ?? '').join(`\\n${GAP}\\n`),\n after: list.map((edit) => edit.newText ?? '').join(`\\n${GAP}\\n`),\n };\n}\n\nexport function fromPatch(patch: string): ToolCall['diff'] {\n const before: string[] = [];\n const after: string[] = [];\n let hunks = 0;\n for (const line of patch.split('\\n')) {\n if (line.startsWith('@@')) {\n if (hunks++ > 0) {\n before.push(GAP);\n after.push(GAP);\n }\n continue;\n }\n if (hunks === 0 || line === '' || line.startsWith('\\\\')) continue;\n const text = line.slice(1);\n if (line.startsWith('-')) before.push(text);\n else if (line.startsWith('+')) after.push(text);\n else {\n before.push(text);\n after.push(text);\n }\n }\n return hunks ? { before: before.join('\\n'), after: after.join('\\n') } : undefined;\n}\n\nfunction shape(name: string, args: Json): Pick<ToolCall, 'input' | 'meta' | 'diff'> {\n const path = typeof args.path === 'string' ? args.path : '';\n const meta = name === 'bash' ? seconds(args.timeout) : name === 'read' ? lines(args) : undefined;\n const base = meta ? { meta } : {};\n if (name === 'bash' && typeof args.command === 'string') return { input: args.command, ...base };\n if (name === 'read' || name === 'write') return { input: path, ...base };\n if (name === 'edit') {\n const diff = edits(args);\n return { input: path, ...(diff ? { diff } : {}) };\n }\n return { input: JSON.stringify(args, null, 2) };\n}\n\nfunction toolCall(block: Block): ToolCall {\n const args = block.arguments ?? {};\n return {\n id: block.id ?? '',\n name: block.name ?? 'tool',\n title: mcpLabel(block.name ?? '') ?? title(block.arguments),\n ...shape(block.name ?? 'tool', args),\n output: '',\n status: 'running',\n paths: paths(block.arguments),\n };\n}\n\nfunction part(block: Block): MessagePart | undefined {\n if (block.type === 'text') return { type: 'text', text: block.text ?? '' };\n if (block.type === 'thinking') return { type: 'thinking', text: block.thinking ?? '' };\n if (block.type === 'toolCall') return { type: 'tool', tool: toolCall(block) };\n return undefined;\n}\n\nfunction usage(message: ModelMessage): Usage | undefined {\n const used = message.usage;\n if (!used) return undefined;\n return {\n input: used.input ?? 0,\n output: used.output ?? 0,\n cost: used.cost?.total ?? 0,\n cacheRead: used.cacheRead ?? 0,\n cacheWrite: used.cacheWrite ?? 0,\n };\n}\n\nconst statuses: Record<string, AssistantStatus> = { error: 'error', aborted: 'stopped' };\n\nconst credentials =\n /security token|unrecognizedclient|not authori[sz]ed|unauthori[sz]ed|forbidden|\\b40[13]\\b|api key|credential|bearer/i;\nconst models = /model/i;\nconst unavailable =\n /access|invalid|not found|identifier|unsupported|not supported|isn['\u2019]t supported|not available|isn['\u2019]t available/i;\n\nconst providerNames: Record<string, string> = { 'amazon-bedrock': 'Bedrock', adobe: 'Adobe' };\nconst filtered =\n /Provider (?:stopped with|finish_reason): (?:content_filter(?:ed)?|guardrail_intervened|sensitive)|content[_ ]filter(?:ed|ing)?\\b|guardrail[_ ]intervened/i;\nconst refused =\n /refused to complete the request|Provider (?:stopped with|finish_reason): refusal|\\bstop_?reason\\W+refusal\\b/i;\nconst unconnected = /no api key|not configured|no credentials/i;\nconst missing = /missing/i;\nconst adobeAuth =\n /\\b401\\b|authenticat|unauthori[sz]ed|expired|invalid[_ ]?(?:token|credentials?|api[_ ]key)|token verification/i;\n\nfunction proxyRefusal(error: string): { message: string; detail: string } {\n try {\n const body = JSON.parse(error.match(/\\{.*\\}/s)?.[0] ?? '') as {\n error?: { type?: unknown; message?: unknown };\n };\n const { type, message } = body.error ?? {};\n const status = error.match(/^\\s*(\\d{3})\\b/)?.[1];\n return {\n message: typeof message === 'string' ? message : error,\n detail: typeof type === 'string' ? [status, type].filter(Boolean).join(' ') : error,\n };\n } catch {\n return { message: error, detail: error };\n }\n}\n\nexport const CONNECT_IT = 'Connect it in Settings \u203A Accounts.';\nexport const LOG_IN_AGAIN = 'Log in again to continue.';\n\nconst logged = new Set<string>();\n\nfunction logOnce(error: string): void {\n if (logged.has(error)) return;\n logged.add(error);\n warn(`slicc-agent: the Adobe session expired: ${error}`);\n}\n\nexport function providerName(provider: string | undefined, fallback = 'The provider'): string {\n return providerNames[provider ?? ''] ?? fallback;\n}\n\nexport function errorPart(error: string, provider?: string): MessagePart {\n const action = errorAction(error);\n if (action === 'drop-turn') {\n return {\n type: 'error',\n message: filtered.test(error)\n ? \"The model's content filter stopped this reply.\"\n : 'The model refused to answer this turn.',\n detail: error,\n action,\n };\n }\n const name = providerName(provider);\n const account = provider ? { account: provider } : {};\n if (unconnected.test(error))\n return {\n type: 'error',\n message: `${name} isn't connected.`,\n detail: CONNECT_IT,\n action: 'settings',\n ...account,\n };\n if (action === 'settings' && provider === 'adobe') {\n if (!adobeAuth.test(error)) return { type: 'error', ...proxyRefusal(error), action: 'retry' };\n logOnce(error);\n return {\n type: 'error',\n message: 'Your Adobe session has expired.',\n detail: LOG_IN_AGAIN,\n action: 'login',\n ...account,\n };\n }\n if (action === 'settings') {\n const lead = missing.test(error)\n ? `${name} needs an API key.`\n : `${name} rejected the API key.`;\n return { type: 'error', message: lead, detail: error, action, ...account };\n }\n return action === 'change-model'\n ? {\n type: 'error',\n message: \"This model isn't available with the current account.\",\n detail: error,\n action,\n }\n : { type: 'error', message: error, action };\n}\n\nexport function errorAction(message: string): ErrorAction {\n if (filtered.test(message) || refused.test(message)) return 'drop-turn';\n if (credentials.test(message)) return 'settings';\n if (models.test(message) && unavailable.test(message)) return 'change-model';\n return 'retry';\n}\n\nfunction sprinkleMessage(id: string, entry: EntryRecord): AssistantMessage {\n const data = (entry.data ?? {}) as { sprinkle?: unknown; at?: unknown };\n return {\n id,\n role: 'assistant',\n parts: [{ type: 'sprinkle', sprinkle: String(data.sprinkle ?? '') }],\n status: 'done',\n createdAt: typeof data.at === 'number' ? data.at : 0,\n };\n}\n\nexport function assistant(\n id: string,\n message: ModelMessage,\n status?: AssistantStatus\n): AssistantMessage {\n const blocks = Array.isArray(message.content) ? message.content : [];\n const parts = blocks.map(part).filter((item): item is MessagePart => item !== undefined);\n if (message.errorMessage) parts.push(errorPart(message.errorMessage, message.provider));\n const used = usage(message);\n return {\n id,\n role: 'assistant',\n parts,\n status: status ?? statuses[message.stopReason ?? ''] ?? 'done',\n createdAt: message.timestamp ?? 0,\n ...(message.provider && message.model ? { model: `${message.provider}/${message.model}` } : {}),\n ...(used ? { usage: used } : {}),\n };\n}\n\nfunction user(\n id: string,\n message: ModelMessage,\n delivered: Delivered | undefined,\n from: From | undefined\n): UserMessage {\n return {\n id,\n role: 'user',\n ...shownUser(message.content, `ref:${id.slice(1)}:0`),\n createdAt: message.timestamp ?? 0,\n ...(delivered ? { delivered } : {}),\n ...(from ? { from: from.from } : {}),\n ...(from?.agent ? { origin: 'agent' as const } : {}),\n };\n}\n\nfunction guestUser(\n id: string,\n message: ModelMessage,\n delivered: Delivered | undefined,\n data: unknown\n): UserMessage {\n const input = data as Partial<GuestInput> | undefined;\n const name = String(input?.name ?? '');\n const shown = shownUser(message.content, `ref:${id.slice(1)}:0`);\n return {\n id,\n role: 'user',\n ...shown,\n text: guestText(shown.text, name),\n createdAt: message.timestamp ?? 0,\n ...(delivered ? { delivered } : {}),\n from: name,\n origin: 'guest',\n ...(typeof input?.seat === 'string' ? { seat: input.seat } : {}),\n };\n}\n\nexport function origins(entries: readonly EntryRecord[]): Map<number, From> {\n const out = new Map<number, From>();\n for (const entry of entries)\n if (entry.kind === FROM_KIND) {\n const note = entry.data as From;\n out.set(note.entry, note);\n }\n return out;\n}\n\nfunction lickMessage(\n id: string,\n entry: EntryRecord,\n decisions: ReadonlyMap<string, LickDecision>\n): LickMessage | undefined {\n const lick = entryLick(entry);\n if (!lick) return undefined;\n const state = lick.actions?.length ? (decisions.get(lick.id) ?? 'pending') : undefined;\n return {\n id,\n role: 'lick',\n channel: lick.channel,\n title: lick.title,\n text: lick.text,\n createdAt: lick.at,\n ...(lick.body ? { body: lick.body } : {}),\n ...(lick.count > 1 ? { count: lick.count } : {}),\n ...(state ? { state } : {}),\n ...(lick.severity ? { severity: lick.severity } : {}),\n };\n}\n\nfunction withoutLickTools(message: AssistantMessage): AssistantMessage {\n const parts = message.parts.filter((item) => item.type !== 'tool' || !LICK_TOOLS[item.tool.name]);\n return parts.length === message.parts.length ? message : { ...message, parts };\n}\n\nfunction system(id: string, entry: EntryRecord, text: string): SystemMessage {\n const reason = (entry.data as Json | undefined)?.reason as SystemMessage['trigger'] | undefined;\n return {\n id,\n role: 'system',\n kind: 'compaction',\n text,\n createdAt: 0,\n state: 'summarized',\n ...(reason ? { trigger: reason } : {}),\n };\n}\n\nfunction tools(messages: Message[]): Map<string, ToolCall> {\n const found = new Map<string, ToolCall>();\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const item of message.parts) if (item.type === 'tool') found.set(item.tool.id, item.tool);\n }\n return found;\n}\n\ninterface Diagnostic {\n severity: string;\n message: string;\n}\n\ninterface Note {\n severity: 'error' | 'warn' | 'info';\n text: string;\n}\n\ntype Card = ToolCall & { notes?: Note[] };\n\nconst RANK: Note['severity'][] = ['error', 'warn', 'info'];\n\nconst LINE = /^\\[(error|warn|info)\\] (.*)$/;\n\nfunction rendered(diagnostics: readonly Diagnostic[]): string {\n return `<harness>\\n${diagnostics.map((item) => `[${item.severity}] ${item.message}`).join('\\n')}\\n</harness>`;\n}\n\nfunction parsed(text: string): Diagnostic[] | undefined {\n const body = /^<harness>\\n([\\s\\S]*)\\n<\\/harness>$/.exec(text)?.[1];\n if (body === undefined) return undefined;\n const found = body.split('\\n').map((line) => LINE.exec(line));\n if (!found.every((match): match is RegExpExecArray => match !== null)) return undefined;\n return found.map(([, severity, message]) => ({ severity, message }) as Diagnostic);\n}\n\nfunction harness(\n content: ModelMessage['content'],\n data: unknown\n): { content: ModelMessage['content']; diagnostics: Diagnostic[] } {\n const last = Array.isArray(content) ? content.at(-1) : undefined;\n const stored = (data as { diagnostics?: unknown } | undefined)?.diagnostics;\n const listed = Array.isArray(stored) ? (stored as Diagnostic[]) : parsed(last?.text ?? '');\n if (!listed?.length || last?.type !== 'text' || last.text !== rendered(listed))\n return { content, diagnostics: [] };\n return { content: (content as Block[]).slice(0, -1), diagnostics: listed };\n}\n\nconst count = (value: string | undefined): string => Number(value).toLocaleString('en');\n\nconst ends: Record<string, string> = { end: ' from the start', beginning: ' from the end' };\n\nconst phrasings: [RegExp, (match: RegExpExecArray) => string][] = [\n [/^Command exited with code (-?\\d+)$/, (match) => `Exited with code ${match[1]}`],\n [/^Command timed out after (.+)$/, (match) => `Timed out after ${match[1]}`],\n [/^Command aborted$/, () => 'Aborted'],\n [/^Full output: (.+)$/, (match) => `Full output in ${match[1]}`],\n [\n /^Output truncated(?: to its (beginning|end))?: (\\d+) lines, (\\d+) bytes dropped$/,\n (match) =>\n `Output truncated: ${count(match[2])} lines and ${count(match[3])} bytes dropped${ends[match[1] ?? ''] ?? ''}`,\n ],\n];\n\nfunction phrased(message: string): string {\n const line = message\n .replace(/\\n[\\s\\S]*$/, '')\n .trim()\n .replace(/\\.$/, '');\n for (const [pattern, phrase] of phrasings) {\n const match = pattern.exec(line);\n if (match) return phrase(match);\n }\n return line;\n}\n\nfunction note(diagnostic: Diagnostic): Note {\n return { severity: diagnostic.severity as Note['severity'], text: phrased(diagnostic.message) };\n}\n\nfunction settle(calls: Map<string, ToolCall>, result: ModelMessage, data?: unknown): void {\n const call = calls.get(result.toolCallId ?? '') as Card | undefined;\n if (!call) return;\n const split = harness(result.content, data);\n call.output = textOf(split.content);\n if (split.diagnostics.length)\n call.notes = split.diagnostics\n .map(note)\n .sort((a, b) => RANK.indexOf(a.severity) - RANK.indexOf(b.severity));\n call.status = result.isError ? 'error' : 'done';\n const image = Array.isArray(result.content)\n ? (result.content as { type: string; data?: string; mimeType?: string }[]).find(\n (part) => part.type === 'image' && part.data && part.mimeType\n )\n : undefined;\n if (image) call.image = `data:${image.mimeType};base64,${image.data}`;\n const patch = result.details?.patch;\n const diff = typeof patch === 'string' ? fromPatch(patch) : undefined;\n if (diff) call.diff = diff;\n else if (result.isError) delete call.diff;\n}\n\nfunction rewound(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { stopped?: string[]; restored?: string[]; files?: boolean };\n const notes = [\n 'Its prompt is back in the composer.',\n ...(data.stopped?.length\n ? [`Stopped ${data.stopped.map((name) => `scoop ${name}`).join(', ')}.`]\n : []),\n ...(data.restored?.length\n ? [`Restored ${data.restored.map((name) => `scoop ${name}`).join(', ')}.`]\n : []),\n ...(data.files ? ['Changed files stay; use Changes or git to revert them.'] : []),\n ];\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: 'Rewound 1 turn',\n text: notes.join(' '),\n createdAt: 0,\n };\n}\n\nfunction thawed(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { name?: string; kind?: string; v6?: boolean };\n const what = data.v6 ? 'SLICC 6' : data.kind === 'agent' ? 'agent run' : 'scoop';\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: `Thawed from ${what} ${data.name ?? ''}`.trim(),\n text: textOf(entry.model?.[0]?.content ?? ''),\n createdAt: entry.model?.[0]?.timestamp ?? 0,\n };\n}\n\nexport function reviewed(entries: readonly EntryRecord[]): Map<string, GuestOutcome> {\n const out = new Map<string, GuestOutcome>();\n for (const entry of entries) {\n if (entry.kind !== REVIEWED_KIND) continue;\n const data = (entry.data ?? {}) as Partial<GuestReviewed>;\n if (typeof data.review === 'string' && data.outcome) out.set(data.review, data.outcome);\n }\n return out;\n}\n\nfunction asked(\n id: string,\n entry: EntryRecord,\n outcomes: ReadonlyMap<string, GuestOutcome>\n): SystemMessage {\n const data = (entry.data ?? {}) as Partial<GuestAsked>;\n return {\n id,\n role: 'system',\n kind: 'notice',\n text: askedLine(\n String(data.name ?? ''),\n String(data.text ?? ''),\n outcomes.get(String(data.review))\n ),\n createdAt: typeof data.at === 'number' ? data.at : 0,\n };\n}\n\nfunction secrets(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { names?: SecretName[] };\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: 'Secrets listed',\n text: listedLine(data.names ?? []),\n createdAt: entry.model?.[0]?.timestamp ?? 0,\n };\n}\n\nconst V6_KINDS: Record<string, string> = {\n user: 'pi.user',\n assistant: 'pi.assistant',\n toolResult: 'pi.tool-result',\n};\n\nfunction entryMessage(\n entry: EntryRecord,\n out: Message[],\n calls: Map<string, ToolCall>,\n delivered: Delivered | undefined,\n notes: {\n decisions: ReadonlyMap<string, LickDecision>;\n origins: ReadonlyMap<number, From>;\n outcomes: ReadonlyMap<string, GuestOutcome>;\n }\n): void {\n const id = `e${entry.id}`;\n const model = entry.model?.[0] as ModelMessage | undefined;\n if (entry.kind === 'slicc.v6' && model) {\n const kind = V6_KINDS[model.role as string];\n if (kind) entryMessage({ ...entry, kind }, out, calls, delivered, notes);\n return;\n }\n if (entry.kind === 'slicc.rewound') out.push(rewound(id, entry));\n if (entry.kind === 'slicc.thawed') out.push(thawed(id, entry));\n else if (entry.kind === SECRETS_KIND) out.push(secrets(id, entry));\n else if (entry.kind === ASKED_KIND) out.push(asked(id, entry, notes.outcomes));\n else if (entry.kind === SPRINKLE_KIND) out.push(sprinkleMessage(id, entry));\n else if (entry.kind === 'pi.user' && model)\n out.push(\n lickMessage(id, entry, notes.decisions) ??\n user(id, model, delivered, notes.origins.get(entry.id))\n );\n else if (entry.kind === GUEST_INPUT_KIND && model)\n out.push(guestUser(id, model, delivered, entry.data));\n else if (entry.kind === 'pi.assistant' && model) {\n const message = assistant(id, model);\n out.push(withoutLickTools(message));\n for (const [key, value] of tools([message])) calls.set(key, value);\n } else if (entry.kind === 'pi.tool-result' && model) settle(calls, model, entry.data);\n else if (entry.kind === 'pi.compaction') out.push(system(id, entry, textOf(model?.content)));\n}\n\nconst slotStatus: Record<string, ToolStatus> = {\n pending: 'running',\n running: 'running',\n done: 'done',\n};\n\nfunction live(view: ConversationView, out: Message[], calls: Map<string, ToolCall>): void {\n const state = view.docs['pi.live'] as Live | undefined;\n for (const slot of state?.tools ?? []) {\n const call = calls.get(slot.callId);\n if (call && call.status === 'running') {\n call.status = slotStatus[slot.status] ?? 'running';\n call.output = slot.output ?? call.output;\n }\n }\n const partial = state?.generation?.message;\n if (partial) out.push(assistant('live', partial, 'streaming'));\n for (const compaction of state?.compactions ?? []) {\n out.push({\n id: `compaction-${compaction.taskId}`,\n role: 'system',\n kind: 'compaction',\n text: '',\n createdAt: 0,\n state: 'summarizing',\n trigger: compaction.reason as SystemMessage['trigger'],\n });\n }\n const retry = state?.generation?.retry;\n if (retry)\n out.push({\n id: 'retry',\n role: 'system',\n kind: 'notice',\n text: retry.error,\n createdAt: retry.at,\n });\n}\n\nexport function toMessages(\n view: ConversationView | undefined,\n deliveries: Readonly<Record<string, Delivered>> = {}\n): Message[] {\n const out: Message[] = [];\n if (!view) return out;\n const calls = new Map<string, ToolCall>();\n const notes = {\n decisions: lickDecisions(view.entries),\n origins: origins(view.entries),\n outcomes: reviewed(view.entries),\n };\n let previous: EntryRecord | undefined;\n for (const entry of view.entries) {\n const steered = previous?.kind === 'pi.tool-result' ? 'steer' : undefined;\n entryMessage(entry, out, calls, deliveries[String(entry.id)] ?? steered, notes);\n previous = entry;\n }\n live(view, out, calls);\n return out;\n}\n\nfunction shownUser(\n content: ModelMessage['content'],\n prefix?: string\n): Pick<UserMessage, 'text' | 'attachments'> {\n const { text, attachments } = splitUser(content, prefix);\n return attachments.length ? { text, attachments } : { text };\n}\n\nexport function isBusy(view: ConversationView | undefined): boolean {\n return Boolean((view?.docs['pi.live'] as Live | undefined)?.run);\n}\n\nexport function queued(\n view: ConversationView | undefined,\n at: (id: string) => number = () => 0\n): UserMessage[] {\n const items = ((view?.docs['pi.inbox'] as { items?: Json[] } | undefined)?.items ?? []) as {\n id: number;\n mode: string;\n content?: ModelMessage['content'];\n entry?: { kind?: string; data?: Partial<GuestInput> };\n }[];\n return items\n .filter((item) => item.mode !== 'write' && !parseLick(textOf(item.content)))\n .map((item) => {\n const shown = shownUser(item.content);\n const data = item.entry?.data;\n const guest = item.entry?.kind === GUEST_INPUT_KIND ? String(data?.name ?? '') : null;\n const seat = typeof data?.seat === 'string' ? { seat: data.seat } : {};\n return {\n id: `q${item.id}`,\n role: 'user' as const,\n ...shown,\n ...(guest === null\n ? {}\n : {\n text: guestText(shown.text, guest),\n from: guest,\n origin: 'guest' as const,\n ...seat,\n }),\n createdAt: at(`q${item.id}`),\n queued: true,\n mode: item.mode === 'steer' ? 'steer' : 'queue',\n };\n });\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type {\n AssistantMessage,\n AssistantStatus,\n ErrorAction,\n LickMessage,\n Message,\n MessagePart,\n SystemMessage,\n ToolCall,\n ToolStatus,\n Usage,\n UserMessage,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport type { ConversationView, EntryRecord } from '@earendil-works/pi-durable';\nimport { splitUser } from '../attachments.ts';\nimport {\n ASKED_KIND,\n askedLine,\n GUEST_INPUT_KIND,\n type GuestAsked,\n type GuestInput,\n type GuestOutcome,\n type GuestReviewed,\n guestText,\n REVIEWED_KIND,\n} from '../guests/attribution.ts';\nimport { parseLick } from '../licks/lick.ts';\nimport { entryLick, LICK_TOOLS, type LickDecision, lickDecisions } from '../licks/state.ts';\nimport { mcpLabel } from '../mcp/label.ts';\nimport { FROM_KIND, type From } from '../scoops/from.ts';\nimport type { SecretName } from '../secrets/names.ts';\nimport { listedLine, SECRETS_KIND } from '../secrets/view.ts';\nimport type { Delivered } from '../services.ts';\nimport { SPRINKLE_KIND } from '../sprinkles/kind.ts';\nimport { warn } from './attempt.ts';\n\ntype Json = Record<string, unknown>;\n\ninterface Block {\n type: string;\n text?: string;\n thinking?: string;\n id?: string;\n name?: string;\n arguments?: Json;\n}\n\ninterface ModelMessage {\n role: string;\n content?: string | Block[];\n timestamp?: number;\n stopReason?: string;\n errorMessage?: string;\n provider?: string;\n model?: string;\n usage?: {\n input?: number;\n output?: number;\n cacheRead?: number;\n cacheWrite?: number;\n cost?: { total?: number };\n };\n toolCallId?: string;\n isError?: boolean;\n details?: { patch?: unknown };\n}\n\ninterface Slot {\n callId: string;\n status: string;\n output?: string;\n}\n\ninterface Live {\n run?: unknown;\n generation?: { message?: ModelMessage; retry?: { at: number; error: string } };\n tools?: Slot[];\n compactions?: { taskId: number; reason: string }[];\n}\n\nexport function textOf(content: ModelMessage['content']): string {\n if (typeof content === 'string') return content;\n return (content ?? []).map((block) => (block.type === 'text' ? (block.text ?? '') : '')).join('');\n}\n\nconst paths = (args: Json | undefined): string[] =>\n typeof args?.path === 'string' ? [args.path] : [];\n\nfunction title(args: Json | undefined): string {\n const subject = args?.command ?? args?.path;\n return typeof subject === 'string' ? subject : '';\n}\n\ninterface Replacement {\n oldText?: string;\n newText?: string;\n}\n\nconst GAP = '\u2026';\n\nfunction seconds(value: unknown): string | undefined {\n return typeof value === 'number' ? `timeout ${value}s` : undefined;\n}\n\nfunction lines(args: Json): string | undefined {\n const { offset, limit } = args as { offset?: number; limit?: number };\n if (typeof offset === 'number' && typeof limit === 'number')\n return `lines ${offset}\u2013${offset + limit - 1}`;\n if (typeof offset === 'number') return `from line ${offset}`;\n return typeof limit === 'number' ? `first ${limit} lines` : undefined;\n}\n\nfunction edits(args: Json): ToolCall['diff'] {\n const list = Array.isArray(args.edits) ? (args.edits as Replacement[]) : [];\n if (list.length === 0) return undefined;\n return {\n before: list.map((edit) => edit.oldText ?? '').join(`\\n${GAP}\\n`),\n after: list.map((edit) => edit.newText ?? '').join(`\\n${GAP}\\n`),\n };\n}\n\nexport function fromPatch(patch: string): ToolCall['diff'] {\n const before: string[] = [];\n const after: string[] = [];\n let hunks = 0;\n for (const line of patch.split('\\n')) {\n if (line.startsWith('@@')) {\n if (hunks++ > 0) {\n before.push(GAP);\n after.push(GAP);\n }\n continue;\n }\n if (hunks === 0 || line === '' || line.startsWith('\\\\')) continue;\n const text = line.slice(1);\n if (line.startsWith('-')) before.push(text);\n else if (line.startsWith('+')) after.push(text);\n else {\n before.push(text);\n after.push(text);\n }\n }\n return hunks ? { before: before.join('\\n'), after: after.join('\\n') } : undefined;\n}\n\nfunction shape(name: string, args: Json): Pick<ToolCall, 'input' | 'meta' | 'diff'> {\n const path = typeof args.path === 'string' ? args.path : '';\n const meta = name === 'bash' ? seconds(args.timeout) : name === 'read' ? lines(args) : undefined;\n const base = meta ? { meta } : {};\n if (name === 'bash' && typeof args.command === 'string') return { input: args.command, ...base };\n if (name === 'read' || name === 'write') return { input: path, ...base };\n if (name === 'edit') {\n const diff = edits(args);\n return { input: path, ...(diff ? { diff } : {}) };\n }\n return { input: JSON.stringify(args, null, 2) };\n}\n\nfunction toolCall(block: Block): ToolCall {\n const args = block.arguments ?? {};\n return {\n id: block.id ?? '',\n name: block.name ?? 'tool',\n title: mcpLabel(block.name ?? '') ?? title(block.arguments),\n ...shape(block.name ?? 'tool', args),\n output: '',\n status: 'running',\n paths: paths(block.arguments),\n };\n}\n\nfunction part(block: Block): MessagePart | undefined {\n if (block.type === 'text') return { type: 'text', text: block.text ?? '' };\n if (block.type === 'thinking') return { type: 'thinking', text: block.thinking ?? '' };\n if (block.type === 'toolCall') return { type: 'tool', tool: toolCall(block) };\n return undefined;\n}\n\nfunction usage(message: ModelMessage): Usage | undefined {\n const used = message.usage;\n if (!used) return undefined;\n return {\n input: used.input ?? 0,\n output: used.output ?? 0,\n cost: used.cost?.total ?? 0,\n cacheRead: used.cacheRead ?? 0,\n cacheWrite: used.cacheWrite ?? 0,\n };\n}\n\nconst statuses: Record<string, AssistantStatus> = { error: 'error', aborted: 'stopped' };\n\nconst credentials =\n /security token|unrecognizedclient|not authori[sz]ed|unauthori[sz]ed|forbidden|\\b40[13]\\b|api key|credential|bearer/i;\nconst models = /model/i;\nconst unavailable =\n /access|invalid|not found|identifier|unsupported|not supported|isn['\u2019]t supported|not available|isn['\u2019]t available/i;\n\nconst providerNames: Record<string, string> = { 'amazon-bedrock': 'Bedrock', adobe: 'Adobe' };\nconst filtered =\n /Provider (?:stopped with|finish_reason): (?:content_filter(?:ed)?|guardrail_intervened|sensitive)|content[_ ]filter(?:ed|ing)?\\b|guardrail[_ ]intervened/i;\nconst refused =\n /refused to complete the request|Provider (?:stopped with|finish_reason): refusal|\\bstop_?reason\\W+refusal\\b/i;\nconst unconnected = /no api key|not configured|no credentials/i;\nconst missing = /missing/i;\nconst adobeAuth =\n /\\b401\\b|authenticat|unauthori[sz]ed|expired|invalid[_ ]?(?:token|credentials?|api[_ ]key)|token verification/i;\n\nfunction proxyRefusal(error: string): { message: string; detail: string } {\n try {\n const body = JSON.parse(error.match(/\\{.*\\}/s)?.[0] ?? '') as {\n error?: { type?: unknown; message?: unknown };\n };\n const { type, message } = body.error ?? {};\n const status = error.match(/^\\s*(\\d{3})\\b/)?.[1];\n return {\n message: typeof message === 'string' ? message : error,\n detail: typeof type === 'string' ? [status, type].filter(Boolean).join(' ') : error,\n };\n } catch {\n return { message: error, detail: error };\n }\n}\n\nexport const CONNECT_IT = 'Connect it in Settings \u203A Accounts.';\nexport const LOG_IN_AGAIN = 'Log in again to continue.';\n\nconst logged = new Set<string>();\n\nfunction logOnce(error: string): void {\n if (logged.has(error)) return;\n logged.add(error);\n warn(`slicc-agent: the Adobe session expired: ${error}`);\n}\n\nexport function providerName(provider: string | undefined, fallback = 'The provider'): string {\n return providerNames[provider ?? ''] ?? fallback;\n}\n\nexport function errorPart(error: string, provider?: string): MessagePart {\n const action = errorAction(error);\n if (action === 'drop-turn') {\n return {\n type: 'error',\n message: filtered.test(error)\n ? \"The model's content filter stopped this reply.\"\n : 'The model refused to answer this turn.',\n detail: error,\n action,\n };\n }\n const name = providerName(provider);\n const account = provider ? { account: provider } : {};\n if (unconnected.test(error))\n return {\n type: 'error',\n message: `${name} isn't connected.`,\n detail: CONNECT_IT,\n action: 'settings',\n ...account,\n };\n if (action === 'settings' && provider === 'adobe') {\n if (!adobeAuth.test(error)) return { type: 'error', ...proxyRefusal(error), action: 'retry' };\n logOnce(error);\n return {\n type: 'error',\n message: 'Your Adobe session has expired.',\n detail: LOG_IN_AGAIN,\n action: 'login',\n ...account,\n };\n }\n if (action === 'settings') {\n const lead = missing.test(error)\n ? `${name} needs an API key.`\n : `${name} rejected the API key.`;\n return { type: 'error', message: lead, detail: error, action, ...account };\n }\n return action === 'change-model'\n ? {\n type: 'error',\n message: \"This model isn't available with the current account.\",\n detail: error,\n action,\n }\n : { type: 'error', message: error, action };\n}\n\nexport function errorAction(message: string): ErrorAction {\n if (filtered.test(message) || refused.test(message)) return 'drop-turn';\n if (credentials.test(message)) return 'settings';\n if (models.test(message) && unavailable.test(message)) return 'change-model';\n return 'retry';\n}\n\nfunction sprinkleMessage(id: string, entry: EntryRecord): AssistantMessage {\n const data = (entry.data ?? {}) as { sprinkle?: unknown; at?: unknown };\n return {\n id,\n role: 'assistant',\n parts: [{ type: 'sprinkle', sprinkle: String(data.sprinkle ?? '') }],\n status: 'done',\n createdAt: typeof data.at === 'number' ? data.at : 0,\n };\n}\n\nexport function assistant(\n id: string,\n message: ModelMessage,\n status?: AssistantStatus\n): AssistantMessage {\n const blocks = Array.isArray(message.content) ? message.content : [];\n const parts = blocks.map(part).filter((item): item is MessagePart => item !== undefined);\n if (message.errorMessage) parts.push(errorPart(message.errorMessage, message.provider));\n const used = usage(message);\n return {\n id,\n role: 'assistant',\n parts,\n status: status ?? statuses[message.stopReason ?? ''] ?? 'done',\n createdAt: message.timestamp ?? 0,\n ...(message.provider && message.model ? { model: `${message.provider}/${message.model}` } : {}),\n ...(used ? { usage: used } : {}),\n };\n}\n\nfunction user(\n id: string,\n message: ModelMessage,\n delivered: Delivered | undefined,\n from: From | undefined\n): UserMessage {\n return {\n id,\n role: 'user',\n ...shownUser(message.content, `ref:${id.slice(1)}:0`),\n createdAt: message.timestamp ?? 0,\n ...(delivered ? { delivered } : {}),\n ...(from ? { from: from.from } : {}),\n ...(from?.agent ? { origin: 'agent' as const } : {}),\n };\n}\n\nfunction guestUser(\n id: string,\n message: ModelMessage,\n delivered: Delivered | undefined,\n data: unknown\n): UserMessage {\n const input = data as Partial<GuestInput> | undefined;\n const name = String(input?.name ?? '');\n const shown = shownUser(message.content, `ref:${id.slice(1)}:0`);\n return {\n id,\n role: 'user',\n ...shown,\n text: guestText(shown.text, name),\n createdAt: message.timestamp ?? 0,\n ...(delivered ? { delivered } : {}),\n from: name,\n origin: 'guest',\n ...(typeof input?.seat === 'string' ? { seat: input.seat } : {}),\n };\n}\n\nexport function origins(entries: readonly EntryRecord[]): Map<number, From> {\n const out = new Map<number, From>();\n for (const entry of entries)\n if (entry.kind === FROM_KIND) {\n const note = entry.data as From;\n out.set(note.entry, note);\n }\n return out;\n}\n\nfunction lickMessage(\n id: string,\n entry: EntryRecord,\n decisions: ReadonlyMap<string, LickDecision>\n): LickMessage | undefined {\n const lick = entryLick(entry);\n if (!lick) return undefined;\n const state = lick.actions?.length ? (decisions.get(lick.id) ?? 'pending') : undefined;\n return {\n id,\n role: 'lick',\n channel: lick.channel,\n title: lick.title,\n text: lick.text,\n createdAt: lick.at,\n ...(lick.body ? { body: lick.body } : {}),\n ...(lick.count > 1 ? { count: lick.count } : {}),\n ...(state ? { state } : {}),\n ...(lick.severity ? { severity: lick.severity } : {}),\n };\n}\n\nfunction withoutLickTools(message: AssistantMessage): AssistantMessage {\n const parts = message.parts.filter((item) => item.type !== 'tool' || !LICK_TOOLS[item.tool.name]);\n return parts.length === message.parts.length ? message : { ...message, parts };\n}\n\nfunction system(id: string, entry: EntryRecord, text: string): SystemMessage {\n const reason = (entry.data as Json | undefined)?.reason as SystemMessage['trigger'] | undefined;\n return {\n id,\n role: 'system',\n kind: 'compaction',\n text,\n createdAt: 0,\n state: 'summarized',\n ...(reason ? { trigger: reason } : {}),\n };\n}\n\nfunction tools(messages: Message[]): Map<string, ToolCall> {\n const found = new Map<string, ToolCall>();\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const item of message.parts) if (item.type === 'tool') found.set(item.tool.id, item.tool);\n }\n return found;\n}\n\ninterface Diagnostic {\n severity: string;\n message: string;\n}\n\ninterface Note {\n severity: 'error' | 'warn' | 'info';\n text: string;\n}\n\ntype Card = ToolCall & { notes?: Note[] };\n\nconst RANK: Note['severity'][] = ['error', 'warn', 'info'];\n\nconst LINE = /^\\[(error|warn|info)\\] (.*)$/;\n\nfunction rendered(diagnostics: readonly Diagnostic[]): string {\n return `<harness>\\n${diagnostics.map((item) => `[${item.severity}] ${item.message}`).join('\\n')}\\n</harness>`;\n}\n\nfunction parsed(text: string): Diagnostic[] | undefined {\n const body = /^<harness>\\n([\\s\\S]*)\\n<\\/harness>$/.exec(text)?.[1];\n if (body === undefined) return undefined;\n const found = body.split('\\n').map((line) => LINE.exec(line));\n if (!found.every((match): match is RegExpExecArray => match !== null)) return undefined;\n return found.map(([, severity, message]) => ({ severity, message }) as Diagnostic);\n}\n\nfunction harness(\n content: ModelMessage['content'],\n data: unknown\n): { content: ModelMessage['content']; diagnostics: Diagnostic[] } {\n const last = Array.isArray(content) ? content.at(-1) : undefined;\n const stored = (data as { diagnostics?: unknown } | undefined)?.diagnostics;\n const listed = Array.isArray(stored) ? (stored as Diagnostic[]) : parsed(last?.text ?? '');\n if (!listed?.length || last?.type !== 'text' || last.text !== rendered(listed))\n return { content, diagnostics: [] };\n return { content: (content as Block[]).slice(0, -1), diagnostics: listed };\n}\n\nconst count = (value: string | undefined): string => Number(value).toLocaleString('en');\n\nconst ends: Record<string, string> = { end: ' from the start', beginning: ' from the end' };\n\nconst phrasings: [RegExp, (match: RegExpExecArray) => string][] = [\n [/^Command exited with code (-?\\d+)$/, (match) => `Exited with code ${match[1]}`],\n [/^Command timed out after (.+)$/, (match) => `Timed out after ${match[1]}`],\n [/^Command aborted$/, () => 'Aborted'],\n [/^Full output: (.+)$/, (match) => `Full output in ${match[1]}`],\n [\n /^Output truncated(?: to its (beginning|end))?: (\\d+) lines, (\\d+) bytes dropped$/,\n (match) =>\n `Output truncated: ${count(match[2])} lines and ${count(match[3])} bytes dropped${ends[match[1] ?? ''] ?? ''}`,\n ],\n];\n\nfunction phrased(message: string): string {\n const line = message\n .replace(/\\n[\\s\\S]*$/, '')\n .trim()\n .replace(/\\.$/, '');\n for (const [pattern, phrase] of phrasings) {\n const match = pattern.exec(line);\n if (match) return phrase(match);\n }\n return line;\n}\n\nfunction note(diagnostic: Diagnostic): Note {\n return { severity: diagnostic.severity as Note['severity'], text: phrased(diagnostic.message) };\n}\n\nfunction settle(calls: Map<string, ToolCall>, result: ModelMessage, data?: unknown): void {\n const call = calls.get(result.toolCallId ?? '') as Card | undefined;\n if (!call) return;\n const split = harness(result.content, data);\n call.output = textOf(split.content);\n if (split.diagnostics.length)\n call.notes = split.diagnostics\n .map(note)\n .sort((a, b) => RANK.indexOf(a.severity) - RANK.indexOf(b.severity));\n call.status = result.isError ? 'error' : 'done';\n const image = Array.isArray(result.content)\n ? (result.content as { type: string; data?: string; mimeType?: string }[]).find(\n (part) => part.type === 'image' && part.data && part.mimeType\n )\n : undefined;\n if (image) call.image = `data:${image.mimeType};base64,${image.data}`;\n const patch = result.details?.patch;\n const diff = typeof patch === 'string' ? fromPatch(patch) : undefined;\n if (diff) call.diff = diff;\n else if (result.isError) delete call.diff;\n}\n\nfunction rewound(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { stopped?: string[]; restored?: string[]; files?: boolean };\n const notes = [\n 'Its prompt is back in the composer.',\n ...(data.stopped?.length\n ? [`Stopped ${data.stopped.map((name) => `scoop ${name}`).join(', ')}.`]\n : []),\n ...(data.restored?.length\n ? [`Restored ${data.restored.map((name) => `scoop ${name}`).join(', ')}.`]\n : []),\n ...(data.files ? ['Changed files stay; use Changes or git to revert them.'] : []),\n ];\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: 'Rewound 1 turn',\n text: notes.join(' '),\n createdAt: 0,\n };\n}\n\nfunction thawed(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { name?: string; kind?: string; v6?: boolean };\n const what = data.v6 ? 'SLICC 6' : data.kind === 'agent' ? 'agent run' : 'scoop';\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: `Thawed from ${what} ${data.name ?? ''}`.trim(),\n text: textOf(entry.model?.[0]?.content ?? ''),\n createdAt: entry.model?.[0]?.timestamp ?? 0,\n };\n}\n\nexport function reviewed(entries: readonly EntryRecord[]): Map<string, GuestOutcome> {\n const out = new Map<string, GuestOutcome>();\n for (const entry of entries) {\n if (entry.kind !== REVIEWED_KIND) continue;\n const data = (entry.data ?? {}) as Partial<GuestReviewed>;\n if (typeof data.review === 'string' && data.outcome) out.set(data.review, data.outcome);\n }\n return out;\n}\n\nfunction asked(\n id: string,\n entry: EntryRecord,\n outcomes: ReadonlyMap<string, GuestOutcome>\n): SystemMessage {\n const data = (entry.data ?? {}) as Partial<GuestAsked>;\n return {\n id,\n role: 'system',\n kind: 'notice',\n text: askedLine(\n String(data.name ?? ''),\n String(data.text ?? ''),\n outcomes.get(String(data.review))\n ),\n createdAt: typeof data.at === 'number' ? data.at : 0,\n };\n}\n\nfunction secrets(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as {\n names?: SecretName[];\n error?: string | null;\n exposed?: string[];\n };\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: data.error ? 'Secrets unavailable' : 'Secrets listed',\n text: listedLine({\n names: data.names ?? [],\n error: data.error ?? null,\n exposed: data.exposed ?? [],\n }),\n createdAt: entry.model?.[0]?.timestamp ?? 0,\n };\n}\n\nconst V6_KINDS: Record<string, string> = {\n user: 'pi.user',\n assistant: 'pi.assistant',\n toolResult: 'pi.tool-result',\n};\n\nfunction entryMessage(\n entry: EntryRecord,\n out: Message[],\n calls: Map<string, ToolCall>,\n delivered: Delivered | undefined,\n notes: {\n decisions: ReadonlyMap<string, LickDecision>;\n origins: ReadonlyMap<number, From>;\n outcomes: ReadonlyMap<string, GuestOutcome>;\n }\n): void {\n const id = `e${entry.id}`;\n const model = entry.model?.[0] as ModelMessage | undefined;\n if (entry.kind === 'slicc.v6' && model) {\n const kind = V6_KINDS[model.role as string];\n if (kind) entryMessage({ ...entry, kind }, out, calls, delivered, notes);\n return;\n }\n if (entry.kind === 'slicc.rewound') out.push(rewound(id, entry));\n if (entry.kind === 'slicc.thawed') out.push(thawed(id, entry));\n else if (entry.kind === SECRETS_KIND) out.push(secrets(id, entry));\n else if (entry.kind === ASKED_KIND) out.push(asked(id, entry, notes.outcomes));\n else if (entry.kind === SPRINKLE_KIND) out.push(sprinkleMessage(id, entry));\n else if (entry.kind === 'pi.user' && model)\n out.push(\n lickMessage(id, entry, notes.decisions) ??\n user(id, model, delivered, notes.origins.get(entry.id))\n );\n else if (entry.kind === GUEST_INPUT_KIND && model)\n out.push(guestUser(id, model, delivered, entry.data));\n else if (entry.kind === 'pi.assistant' && model) {\n const message = assistant(id, model);\n out.push(withoutLickTools(message));\n for (const [key, value] of tools([message])) calls.set(key, value);\n } else if (entry.kind === 'pi.tool-result' && model) settle(calls, model, entry.data);\n else if (entry.kind === 'pi.compaction') out.push(system(id, entry, textOf(model?.content)));\n}\n\nconst slotStatus: Record<string, ToolStatus> = {\n pending: 'running',\n running: 'running',\n done: 'done',\n};\n\nfunction live(view: ConversationView, out: Message[], calls: Map<string, ToolCall>): void {\n const state = view.docs['pi.live'] as Live | undefined;\n for (const slot of state?.tools ?? []) {\n const call = calls.get(slot.callId);\n if (call && call.status === 'running') {\n call.status = slotStatus[slot.status] ?? 'running';\n call.output = slot.output ?? call.output;\n }\n }\n const partial = state?.generation?.message;\n if (partial) out.push(assistant('live', partial, 'streaming'));\n for (const compaction of state?.compactions ?? []) {\n out.push({\n id: `compaction-${compaction.taskId}`,\n role: 'system',\n kind: 'compaction',\n text: '',\n createdAt: 0,\n state: 'summarizing',\n trigger: compaction.reason as SystemMessage['trigger'],\n });\n }\n const retry = state?.generation?.retry;\n if (retry)\n out.push({\n id: 'retry',\n role: 'system',\n kind: 'notice',\n text: retry.error,\n createdAt: retry.at,\n });\n}\n\nexport function toMessages(\n view: ConversationView | undefined,\n deliveries: Readonly<Record<string, Delivered>> = {}\n): Message[] {\n const out: Message[] = [];\n if (!view) return out;\n const calls = new Map<string, ToolCall>();\n const notes = {\n decisions: lickDecisions(view.entries),\n origins: origins(view.entries),\n outcomes: reviewed(view.entries),\n };\n let previous: EntryRecord | undefined;\n for (const entry of view.entries) {\n const steered = previous?.kind === 'pi.tool-result' ? 'steer' : undefined;\n entryMessage(entry, out, calls, deliveries[String(entry.id)] ?? steered, notes);\n previous = entry;\n }\n live(view, out, calls);\n return out;\n}\n\nfunction shownUser(\n content: ModelMessage['content'],\n prefix?: string\n): Pick<UserMessage, 'text' | 'attachments'> {\n const { text, attachments } = splitUser(content, prefix);\n return attachments.length ? { text, attachments } : { text };\n}\n\nexport function isBusy(view: ConversationView | undefined): boolean {\n return Boolean((view?.docs['pi.live'] as Live | undefined)?.run);\n}\n\nexport function queued(\n view: ConversationView | undefined,\n at: (id: string) => number = () => 0\n): UserMessage[] {\n const items = ((view?.docs['pi.inbox'] as { items?: Json[] } | undefined)?.items ?? []) as {\n id: number;\n mode: string;\n content?: ModelMessage['content'];\n entry?: { kind?: string; data?: Partial<GuestInput> };\n }[];\n return items\n .filter((item) => item.mode !== 'write' && !parseLick(textOf(item.content)))\n .map((item) => {\n const shown = shownUser(item.content);\n const data = item.entry?.data;\n const guest = item.entry?.kind === GUEST_INPUT_KIND ? String(data?.name ?? '') : null;\n const seat = typeof data?.seat === 'string' ? { seat: data.seat } : {};\n return {\n id: `q${item.id}`,\n role: 'user' as const,\n ...shown,\n ...(guest === null\n ? {}\n : {\n text: guestText(shown.text, guest),\n from: guest,\n origin: 'guest' as const,\n ...seat,\n }),\n createdAt: at(`q${item.id}`),\n queued: true,\n mode: item.mode === 'steer' ? 'steer' : 'queue',\n };\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["note", "part"]
|
|
7
7
|
}
|
package/dist/types/control.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { LickSources, Licks } from './licks/index.ts';
|
|
|
8
8
|
import type { MemoryRuntime } from './memory/index.ts';
|
|
9
9
|
import type { Monitor } from './monitor/index.ts';
|
|
10
10
|
import type { Scoops, ScoopsRuntime } from './scoops/index.ts';
|
|
11
|
-
import type {
|
|
11
|
+
import type { SecretListing } from './secrets/names.ts';
|
|
12
12
|
import type { AgentControl } from './services.ts';
|
|
13
13
|
import type { SkillsRuntime } from './skills/index.ts';
|
|
14
14
|
import type { SprinklesRuntime } from './sprinkles/index.ts';
|
|
@@ -25,5 +25,5 @@ export interface HostScoops {
|
|
|
25
25
|
export declare function readable(out: string): string;
|
|
26
26
|
type FreezerControl = Pick<FreezerRuntime, 'freeze' | 'newChat' | 'thaw' | 'discard' | 'importProfile' | 'cancelImport'>;
|
|
27
27
|
export declare function submissionId(value: string): SubmissionId | undefined;
|
|
28
|
-
export declare function createAgentControl(harness: Harness, target: Conversation | Cones, deliveries?: Deliveries, licks?: HostLicks, scoops?: HostScoops, skills?: Pick<SkillsRuntime, 'expand' | 'commandsFor'>, sprinkles?: Pick<SprinklesRuntime, 'send' | 'call'>, memory?: Pick<MemoryRuntime, 'save' | 'remove'>, freezer?: FreezerControl, changes?: Pick<ChangesRuntime, 'open' | 'accept' | 'revert'>, monitor?: Pick<Monitor, 'open' | 'close'>, secrets?: () =>
|
|
28
|
+
export declare function createAgentControl(harness: Harness, target: Conversation | Cones, deliveries?: Deliveries, licks?: HostLicks, scoops?: HostScoops, skills?: Pick<SkillsRuntime, 'expand' | 'commandsFor'>, sprinkles?: Pick<SprinklesRuntime, 'send' | 'call'>, memory?: Pick<MemoryRuntime, 'save' | 'remove'>, freezer?: FreezerControl, changes?: Pick<ChangesRuntime, 'open' | 'accept' | 'revert'>, monitor?: Pick<Monitor, 'open' | 'close'>, secrets?: () => SecretListing, uploads?: Uploads, labels?: Pick<LabelsRuntime, 'label'>, guests?: Pick<Guests, 'open' | 'revoke' | 'forgetAlways'>): Omit<AgentControl, 'approvalPolicySet'>;
|
|
29
29
|
export {};
|
package/dist/types/host.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type { MemoryRuntime } from './memory/index.ts';
|
|
|
13
13
|
import { type MonitorOptions } from './monitor/index.ts';
|
|
14
14
|
import { type AgentRemote } from './remote/host.ts';
|
|
15
15
|
import { type Pages } from './remote/pages.ts';
|
|
16
|
-
import type {
|
|
16
|
+
import type { SecretListing } from './secrets/names.ts';
|
|
17
17
|
import type { VaultState } from './secrets/vault.ts';
|
|
18
18
|
import { AgentControl, type AgentGuest, AgentSettings, AgentTranscript } from './services.ts';
|
|
19
19
|
import { type AgentPrincipal, type GuestPrincipal } from './serving.ts';
|
|
@@ -44,7 +44,7 @@ export interface AgentHost {
|
|
|
44
44
|
}
|
|
45
45
|
export interface HostSecrets {
|
|
46
46
|
vault: ReplicatedState<VaultState>;
|
|
47
|
-
list():
|
|
47
|
+
list(): SecretListing;
|
|
48
48
|
close?(): void;
|
|
49
49
|
}
|
|
50
50
|
export declare function hostAgent(agent: Agent, options?: {
|