negotium 0.1.12 → 0.1.13
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/dist/canonical-mcp-bridge.js +2 -3
- package/dist/canonical-mcp-bridge.js.map +1 -1
- package/dist/chunk-a9y2rwxf.js.map +1 -1
- package/dist/{chunk-j0kjscb7.js → chunk-s2gez3wg.js} +20 -2
- package/dist/{chunk-j0kjscb7.js.map → chunk-s2gez3wg.js.map} +2 -2
- package/dist/cron.js +49 -25
- package/dist/cron.js.map +15 -14
- package/dist/hosted-agent.js +3012 -17
- package/dist/hosted-agent.js.map +30 -3
- package/dist/main.js +31323 -36
- package/dist/main.js.map +198 -3
- package/dist/prompts.js +11 -8
- package/dist/prompts.js.map +4 -4
- package/dist/runtime/src/application/submit-user-message.ts +3 -0
- package/dist/runtime/src/index.ts +7 -0
- package/dist/runtime/src/mcp/runtime-spec.ts +3 -0
- package/dist/runtime/src/mcp/session-comm/server.ts +1 -1
- package/dist/runtime/src/platform/mcp-config.ts +13 -0
- package/dist/runtime/src/prompts/builders.ts +20 -6
- package/dist/runtime/src/query/active-rooms.ts +2 -0
- package/dist/runtime/src/runtime/delivery-ack.ts +112 -0
- package/dist/runtime/src/runtime/errors.ts +12 -12
- package/dist/runtime/src/runtime/turn-runner.ts +12 -0
- package/dist/runtime/src/storage/runtime-turn-requests.ts +1 -0
- package/dist/runtime/src/types/api.ts +2 -0
- package/dist/runtime/src/types.ts +2 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js.map +1 -1
- package/dist/storage.js.map +1 -1
- package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +2 -0
- package/dist/types/packages/core/src/platform/mcp-config.d.ts +4 -0
- package/dist/types/packages/core/src/prompts/builders.d.ts +2 -0
- package/dist/types/packages/core/src/types/api.d.ts +2 -0
- package/dist/types/packages/core/src/types.d.ts +2 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-00q25k7p.js +0 -2387
- package/dist/chunk-00q25k7p.js.map +0 -26
- package/dist/chunk-03kv7mvj.js +0 -2152
- package/dist/chunk-03kv7mvj.js.map +0 -15
- package/dist/chunk-05pm51dh.js +0 -589
- package/dist/chunk-05pm51dh.js.map +0 -11
- package/dist/chunk-0eh16bk1.js +0 -2936
- package/dist/chunk-0eh16bk1.js.map +0 -20
- package/dist/chunk-0yfqyv88.js +0 -108
- package/dist/chunk-0yfqyv88.js.map +0 -10
- package/dist/chunk-1k7t7bnx.js +0 -97
- package/dist/chunk-1k7t7bnx.js.map +0 -10
- package/dist/chunk-3gkfr9vb.js +0 -431
- package/dist/chunk-3gkfr9vb.js.map +0 -11
- package/dist/chunk-5akd1gbj.js +0 -281
- package/dist/chunk-5akd1gbj.js.map +0 -10
- package/dist/chunk-7k19pcg8.js +0 -577
- package/dist/chunk-7k19pcg8.js.map +0 -14
- package/dist/chunk-81tbfbmt.js +0 -10
- package/dist/chunk-81tbfbmt.js.map +0 -10
- package/dist/chunk-82qhv1mq.js +0 -512
- package/dist/chunk-82qhv1mq.js.map +0 -13
- package/dist/chunk-8dy7e2a9.js +0 -103
- package/dist/chunk-8dy7e2a9.js.map +0 -10
- package/dist/chunk-8f2sqmrj.js +0 -1712
- package/dist/chunk-8f2sqmrj.js.map +0 -18
- package/dist/chunk-9hjeemfz.js +0 -372
- package/dist/chunk-9hjeemfz.js.map +0 -10
- package/dist/chunk-a4aa2ccv.js +0 -141
- package/dist/chunk-a4aa2ccv.js.map +0 -10
- package/dist/chunk-bsg215q3.js +0 -3536
- package/dist/chunk-bsg215q3.js.map +0 -20
- package/dist/chunk-bxnfsc7w.js +0 -58
- package/dist/chunk-bxnfsc7w.js.map +0 -10
- package/dist/chunk-c500xe9z.js +0 -33
- package/dist/chunk-c500xe9z.js.map +0 -10
- package/dist/chunk-cngrf7ab.js +0 -149
- package/dist/chunk-cngrf7ab.js.map +0 -10
- package/dist/chunk-d7tprf06.js +0 -53
- package/dist/chunk-d7tprf06.js.map +0 -10
- package/dist/chunk-ddnrmkrv.js +0 -61
- package/dist/chunk-ddnrmkrv.js.map +0 -10
- package/dist/chunk-edb07sjp.js +0 -567
- package/dist/chunk-edb07sjp.js.map +0 -14
- package/dist/chunk-ejcm6zx8.js +0 -591
- package/dist/chunk-ejcm6zx8.js.map +0 -11
- package/dist/chunk-ezs352qs.js +0 -237
- package/dist/chunk-ezs352qs.js.map +0 -11
- package/dist/chunk-f5xgprg1.js +0 -59
- package/dist/chunk-f5xgprg1.js.map +0 -10
- package/dist/chunk-fbtb3v0s.js +0 -1339
- package/dist/chunk-fbtb3v0s.js.map +0 -16
- package/dist/chunk-ffefbd3r.js +0 -17
- package/dist/chunk-ffefbd3r.js.map +0 -10
- package/dist/chunk-gaknyw04.js +0 -708
- package/dist/chunk-gaknyw04.js.map +0 -14
- package/dist/chunk-gxmny6tq.js +0 -1637
- package/dist/chunk-gxmny6tq.js.map +0 -15
- package/dist/chunk-h7bj5zwb.js +0 -3069
- package/dist/chunk-h7bj5zwb.js.map +0 -32
- package/dist/chunk-hp4g7wx7.js +0 -46
- package/dist/chunk-hp4g7wx7.js.map +0 -10
- package/dist/chunk-hwy3n31w.js +0 -21
- package/dist/chunk-hwy3n31w.js.map +0 -9
- package/dist/chunk-jzz91jwh.js +0 -70
- package/dist/chunk-jzz91jwh.js.map +0 -10
- package/dist/chunk-k778y16p.js +0 -153
- package/dist/chunk-k778y16p.js.map +0 -11
- package/dist/chunk-mh5mexsf.js +0 -147
- package/dist/chunk-mh5mexsf.js.map +0 -11
- package/dist/chunk-mnwaext5.js +0 -318
- package/dist/chunk-mnwaext5.js.map +0 -10
- package/dist/chunk-nkgs40ch.js +0 -23
- package/dist/chunk-nkgs40ch.js.map +0 -10
- package/dist/chunk-pz57vwsm.js +0 -250
- package/dist/chunk-pz57vwsm.js.map +0 -11
- package/dist/chunk-r6kdp7gn.js +0 -252
- package/dist/chunk-r6kdp7gn.js.map +0 -10
- package/dist/chunk-rkvrkcgx.js +0 -117
- package/dist/chunk-rkvrkcgx.js.map +0 -10
- package/dist/chunk-s74rdyqe.js +0 -117
- package/dist/chunk-s74rdyqe.js.map +0 -12
- package/dist/chunk-sa874j5c.js +0 -9
- package/dist/chunk-sa874j5c.js.map +0 -10
- package/dist/chunk-sffqdkvq.js +0 -122
- package/dist/chunk-sffqdkvq.js.map +0 -10
- package/dist/chunk-tcs9qjps.js +0 -64
- package/dist/chunk-tcs9qjps.js.map +0 -10
- package/dist/chunk-wx83ep8e.js +0 -131
- package/dist/chunk-wx83ep8e.js.map +0 -10
- package/dist/chunk-xag86ng3.js +0 -122
- package/dist/chunk-xag86ng3.js.map +0 -10
- package/dist/chunk-xfdkep71.js +0 -371
- package/dist/chunk-xfdkep71.js.map +0 -11
- package/dist/chunk-xhm1rfpt.js +0 -2907
- package/dist/chunk-xhm1rfpt.js.map +0 -24
- package/dist/chunk-xpcps28p.js +0 -2138
- package/dist/chunk-xpcps28p.js.map +0 -29
- package/dist/chunk-yb4rbev9.js +0 -214
- package/dist/chunk-yb4rbev9.js.map +0 -10
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../cli/src/commands/chat.ts", "../../cli/src/render.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * `negotium chat [topic]` — interactive terminal host.\n *\n * This command doubles as the reference implementation for anyone writing a\n * channel adapter: everything it does (ensure topic → persist user message →\n * startAiTurn → render bus events) is exactly what a Telegram/web/otium host\n * does with a different renderer.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { createInterface } from \"node:readline\";\nimport {\n type AgentKind,\n abortRoom,\n answerPendingAskUserQuestion,\n appendApiMessage,\n executeVaultCommand,\n getTopicByNameForUser,\n isAgentKind,\n isVaultCommandLine,\n type MessageDto,\n registerTopic,\n runtimeBus,\n startAiTurn,\n type TopicDto,\n} from \"@negotium/core\";\nimport { startDefaultNode } from \"@negotium/node\";\nimport { renderBusEvent } from \"@/render\";\n\nconst DEFAULT_USER = \"local\";\nconst DEFAULT_TOPIC = \"chat\";\nconst VAULT_SET_COMMAND_PATTERN = /^\\/vault(?:@\\w+)?\\s+set(?:\\s|$)/i;\n\n/**\n * Remove secret-bearing Vault writes from readline's in-memory history.\n *\n * Node records a line before emitting the `line` event, so this must run at\n * the beginning of the handler rather than after executing the command.\n */\nexport function scrubVaultSetCommandsFromHistory(history: string[]): void {\n for (let index = history.length - 1; index >= 0; index -= 1) {\n if (VAULT_SET_COMMAND_PATTERN.test(history[index]?.trim() ?? \"\")) {\n history.splice(index, 1);\n }\n }\n}\n\nfunction ensureTopic(title: string, agent?: string): TopicDto {\n const existing = getTopicByNameForUser(title, DEFAULT_USER);\n if (existing) return existing;\n return registerTopic({\n title,\n userId: DEFAULT_USER,\n kind: \"agent\",\n ...(agent && isAgentKind(agent) ? { agent: agent as AgentKind } : {}),\n });\n}\n\nexport async function chatCommand(args: string[]): Promise<void> {\n const topicArg = args.find((a) => !a.startsWith(\"--\"));\n const agentArg = args.find((a) => a.startsWith(\"--agent=\"))?.slice(\"--agent=\".length);\n\n const node = await startDefaultNode();\n let topic = ensureTopic(topicArg ?? DEFAULT_TOPIC, agentArg);\n\n console.log(`negotium node on :${node.port} — topic \"${topic.title}\" (agent: ${topic.agent})`);\n console.log(\"commands: /vault, /switch <topic>, /abort, /quit\\n\");\n\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: \"> \",\n }) as ReturnType<typeof createInterface> & { history: string[] };\n let pendingAsk: {\n messageId: string;\n choices: NonNullable<MessageDto[\"askUserQuestion\"]>[\"choices\"];\n } | null = null;\n const unsubscribe = runtimeBus().subscribe((event) => {\n renderBusEvent(event, { topicId: topic.id, selfUserId: DEFAULT_USER });\n if (event.topicId !== topic.id) return;\n if (event.type === \"message\") {\n const msg = event.payload as MessageDto;\n if (msg.kind === \"ask_user_question\" && msg.askUserQuestion) {\n pendingAsk = { messageId: msg.id, choices: msg.askUserQuestion.choices };\n rl.prompt();\n }\n return;\n }\n if (event.type === \"message-updated\" && pendingAsk) {\n const payload = event.payload as { messageId?: string; patch?: Partial<MessageDto> };\n if (\n payload.messageId === pendingAsk.messageId &&\n (payload.patch?.askUserQuestion?.expired || payload.patch?.askUserQuestion?.selectedLabel)\n ) {\n pendingAsk = null;\n }\n }\n });\n\n rl.prompt();\n\n rl.on(\"line\", (line) => {\n const text = line.trim();\n if (VAULT_SET_COMMAND_PATTERN.test(text)) {\n scrubVaultSetCommandsFromHistory(rl.history);\n }\n if (!text) {\n rl.prompt();\n return;\n }\n if (text === \"/quit\" || text === \"/exit\") {\n rl.close();\n return;\n }\n if (text === \"/abort\") {\n const aborted = abortRoom(topic.id);\n console.log(aborted ? \"aborted.\" : \"nothing running.\");\n rl.prompt();\n return;\n }\n if (text.startsWith(\"/switch \")) {\n topic = ensureTopic(text.slice(\"/switch \".length).trim(), agentArg);\n pendingAsk = null;\n console.log(`→ topic \"${topic.title}\" (agent: ${topic.agent})`);\n rl.prompt();\n return;\n }\n if (isVaultCommandLine(text)) {\n const result = executeVaultCommand(DEFAULT_USER, text);\n if (result) console.log(result);\n rl.prompt();\n return;\n }\n\n if (pendingAsk) {\n const choiceIndex = /^\\d+$/.test(text) ? Number(text) - 1 : -1;\n const choice =\n (choiceIndex >= 0 ? pendingAsk.choices[choiceIndex] : undefined) ??\n pendingAsk.choices.find((item) => item.label === text);\n if (!choice) {\n console.log(\"invalid choice — enter one of the displayed numbers or labels.\");\n rl.prompt();\n return;\n }\n const answered = answerPendingAskUserQuestion(\n topic.id,\n pendingAsk.messageId,\n choice.label,\n DEFAULT_USER,\n );\n if (!answered.ok) {\n console.log(`could not answer: ${answered.error}`);\n } else {\n pendingAsk = null;\n }\n rl.prompt();\n return;\n }\n\n appendApiMessage({\n id: randomUUID(),\n topicId: topic.id,\n authorId: DEFAULT_USER,\n text,\n createdAt: new Date().toISOString(),\n });\n startAiTurn({ topic, userId: DEFAULT_USER, prompt: text, allowAutoContinue: true });\n rl.prompt();\n });\n\n await new Promise<void>((resolve) => {\n rl.on(\"close\", async () => {\n unsubscribe();\n await node.stop();\n resolve();\n });\n });\n}\n",
|
|
6
|
-
"/**\n * Terminal rendering for RuntimeBus events — the CLI's half of the host\n * boundary. Deliberately dumb: everything the runtime wants a channel to show\n * arrives on the bus, so this file is the whole \"adapter\" a channel needs.\n */\n\nimport type { MessageDto, RuntimeBusEvent } from \"@negotium/core\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\nexport interface RenderOptions {\n /** Only render events for this topic id (chat mode). Undefined = all. */\n topicId?: string;\n /** Suppress echoing messages authored by this user (they typed them). */\n selfUserId?: string;\n}\n\nexport function renderBusEvent(event: RuntimeBusEvent, opts: RenderOptions = {}): void {\n if (opts.topicId && event.topicId !== opts.topicId) return;\n\n switch (event.type) {\n case \"message\": {\n const msg = event.payload as MessageDto;\n if (opts.selfUserId && msg.authorId === opts.selfUserId) return;\n if (msg.kind === \"tool\") {\n console.log(dim(` ${firstLine(msg.text)}`));\n return;\n }\n const author = msg.authorId === \"ai\" ? cyan(bold(\"ai\")) : bold(msg.authorId);\n console.log(`${author}${msg.agentType ? dim(` (${msg.agentType})`) : \"\"}: ${msg.text}`);\n if (msg.kind === \"ask_user_question\" && msg.askUserQuestion) {\n msg.askUserQuestion.choices.forEach((choice, index) => {\n const description = choice.description ? dim(` — ${choice.description}`) : \"\";\n console.log(` ${index + 1}) ${choice.label}${description}`);\n });\n console.log(dim(\" choose by number or exact label\"));\n }\n return;\n }\n case \"message-updated\":\n // Edit-in-place progress (tool status, subagent cards) — too chatty for\n // a line-oriented terminal; the final state arrives as ai-status/message.\n return;\n case \"ai-status\": {\n const status = event.payload as Record<string, unknown>;\n const kind = String(status.kind ?? \"\");\n if (kind === \"ai-active\" || kind === \"typing\") return;\n if (kind === \"tool-call\") {\n console.log(dim(` ⚙ ${firstLine(String(status.label ?? status.tool ?? \"tool\"))}`));\n return;\n }\n if (kind === \"error\") {\n console.log(red(` ✖ ${firstLine(String(status.message ?? \"error\"))}`));\n return;\n }\n if (kind === \"aborted\") {\n console.log(dim(\" ⏹ aborted\"));\n return;\n }\n return;\n }\n case \"topic-created\": {\n const topic = event.payload as { id: string; title?: string };\n console.log(dim(` + topic created: ${topic.title ?? topic.id}`));\n return;\n }\n case \"topic-deleted\":\n console.log(dim(` - topic deleted: ${event.topicId}`));\n return;\n default:\n return;\n }\n}\n\nfunction firstLine(s: string): string {\n const line = s.split(\"\\n\", 1)[0] ?? \"\";\n return line.length > 120 ? `${line.slice(0, 117)}...` : line;\n}\n"
|
|
7
|
-
],
|
|
8
|
-
"mappings": "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",
|
|
9
|
-
"debugId": "31CF6CADA058B1C964756E2164756E21",
|
|
10
|
-
"names": []
|
|
11
|
-
}
|
package/dist/chunk-r6kdp7gn.js
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
assertSecureCentralUrl,
|
|
3
|
-
assertSecureRelayUrl,
|
|
4
|
-
isJoinPersisted,
|
|
5
|
-
joinCredentialDigest,
|
|
6
|
-
saveJoinWhileLocked,
|
|
7
|
-
withJoinCredentialLock
|
|
8
|
-
} from "./chunk-xfdkep71.js";
|
|
9
|
-
import {
|
|
10
|
-
DATA_DIR
|
|
11
|
-
} from "./chunk-ezs352qs.js";
|
|
12
|
-
|
|
13
|
-
// ../../adapters/otium/src/enrollment.ts
|
|
14
|
-
import {
|
|
15
|
-
createDecipheriv,
|
|
16
|
-
createPrivateKey,
|
|
17
|
-
createPublicKey,
|
|
18
|
-
diffieHellman,
|
|
19
|
-
generateKeyPairSync,
|
|
20
|
-
hkdfSync,
|
|
21
|
-
randomUUID
|
|
22
|
-
} from "crypto";
|
|
23
|
-
import {
|
|
24
|
-
chmodSync,
|
|
25
|
-
closeSync,
|
|
26
|
-
existsSync,
|
|
27
|
-
fsyncSync,
|
|
28
|
-
linkSync,
|
|
29
|
-
mkdirSync,
|
|
30
|
-
openSync,
|
|
31
|
-
readFileSync,
|
|
32
|
-
renameSync,
|
|
33
|
-
unlinkSync,
|
|
34
|
-
writeFileSync
|
|
35
|
-
} from "fs";
|
|
36
|
-
import { dirname, resolve } from "path";
|
|
37
|
-
var INFO = Buffer.from("otium-node-enrollment-v1", "utf8");
|
|
38
|
-
function parseEnrollmentInvite(code) {
|
|
39
|
-
let parsed;
|
|
40
|
-
try {
|
|
41
|
-
parsed = JSON.parse(Buffer.from(code.trim(), "base64url").toString("utf8"));
|
|
42
|
-
} catch {
|
|
43
|
-
throw new Error("production invite must be base64url JSON");
|
|
44
|
-
}
|
|
45
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
46
|
-
throw new Error("production invite must decode to an object");
|
|
47
|
-
}
|
|
48
|
-
const raw = parsed;
|
|
49
|
-
const central = typeof raw.central === "string" ? raw.central.trim().replace(/\/+$/, "") : "";
|
|
50
|
-
const token = typeof raw.token === "string" ? raw.token.trim() : "";
|
|
51
|
-
if (raw.v !== 2 || !central || !token.startsWith("nei_")) {
|
|
52
|
-
throw new Error("production invite requires {v:2, central:http(s), token:nei_\u2026}");
|
|
53
|
-
}
|
|
54
|
-
assertSecureCentralUrl(central);
|
|
55
|
-
return { v: 2, central, token };
|
|
56
|
-
}
|
|
57
|
-
function pendingEnrollmentPath() {
|
|
58
|
-
return resolve(DATA_DIR, "otium-enrollment-pending.json");
|
|
59
|
-
}
|
|
60
|
-
function isEnrollmentPending(invite) {
|
|
61
|
-
const path = pendingEnrollmentPath();
|
|
62
|
-
if (!existsSync(path))
|
|
63
|
-
return false;
|
|
64
|
-
try {
|
|
65
|
-
const saved = JSON.parse(readFileSync(path, "utf8"));
|
|
66
|
-
return saved.central === invite.central && saved.token === invite.token;
|
|
67
|
-
} catch {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function loadOrCreatePending(invite, nodeName) {
|
|
72
|
-
const path = pendingEnrollmentPath();
|
|
73
|
-
if (existsSync(path)) {
|
|
74
|
-
const saved = JSON.parse(readFileSync(path, "utf8"));
|
|
75
|
-
if (saved.central === invite.central && saved.token === invite.token)
|
|
76
|
-
return saved;
|
|
77
|
-
throw new Error(`another Otium enrollment is pending at ${path}`);
|
|
78
|
-
}
|
|
79
|
-
const pair = generateKeyPairSync("x25519");
|
|
80
|
-
const pending = {
|
|
81
|
-
...invite,
|
|
82
|
-
idempotencyKey: randomUUID(),
|
|
83
|
-
privateKey: pair.privateKey.export({ format: "der", type: "pkcs8" }).toString("base64url"),
|
|
84
|
-
publicKey: pair.publicKey.export({ format: "der", type: "spki" }).toString("base64url"),
|
|
85
|
-
...nodeName ? { nodeName } : {}
|
|
86
|
-
};
|
|
87
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
88
|
-
const temporaryPath = resolve(dirname(path), `.otium-enrollment-pending.json.${process.pid}.${randomUUID()}.tmp`);
|
|
89
|
-
let fd;
|
|
90
|
-
try {
|
|
91
|
-
fd = openSync(temporaryPath, "wx", 384);
|
|
92
|
-
writeFileSync(fd, `${JSON.stringify(pending, null, 2)}
|
|
93
|
-
`, "utf8");
|
|
94
|
-
fsyncSync(fd);
|
|
95
|
-
closeSync(fd);
|
|
96
|
-
fd = undefined;
|
|
97
|
-
linkSync(temporaryPath, path);
|
|
98
|
-
unlinkSync(temporaryPath);
|
|
99
|
-
chmodSync(path, 384);
|
|
100
|
-
const directoryFd = openSync(dirname(path), "r");
|
|
101
|
-
try {
|
|
102
|
-
fsyncSync(directoryFd);
|
|
103
|
-
} finally {
|
|
104
|
-
closeSync(directoryFd);
|
|
105
|
-
}
|
|
106
|
-
} catch (error) {
|
|
107
|
-
if (fd !== undefined)
|
|
108
|
-
closeSync(fd);
|
|
109
|
-
if (existsSync(temporaryPath))
|
|
110
|
-
unlinkSync(temporaryPath);
|
|
111
|
-
if (error.code === "EEXIST" && existsSync(path)) {
|
|
112
|
-
const saved = JSON.parse(readFileSync(path, "utf8"));
|
|
113
|
-
if (saved.central === invite.central && saved.token === invite.token)
|
|
114
|
-
return saved;
|
|
115
|
-
}
|
|
116
|
-
throw error;
|
|
117
|
-
}
|
|
118
|
-
return pending;
|
|
119
|
-
}
|
|
120
|
-
function replacePendingEnrollment(pending) {
|
|
121
|
-
const path = pendingEnrollmentPath();
|
|
122
|
-
const directory = dirname(path);
|
|
123
|
-
const temporaryPath = resolve(directory, `.otium-enrollment-pending.json.${process.pid}.${randomUUID()}.tmp`);
|
|
124
|
-
let fd;
|
|
125
|
-
try {
|
|
126
|
-
fd = openSync(temporaryPath, "wx", 384);
|
|
127
|
-
writeFileSync(fd, `${JSON.stringify(pending, null, 2)}
|
|
128
|
-
`, "utf8");
|
|
129
|
-
fsyncSync(fd);
|
|
130
|
-
closeSync(fd);
|
|
131
|
-
fd = undefined;
|
|
132
|
-
renameSync(temporaryPath, path);
|
|
133
|
-
const directoryFd = openSync(directory, "r");
|
|
134
|
-
try {
|
|
135
|
-
fsyncSync(directoryFd);
|
|
136
|
-
} finally {
|
|
137
|
-
closeSync(directoryFd);
|
|
138
|
-
}
|
|
139
|
-
} catch (error) {
|
|
140
|
-
if (fd !== undefined)
|
|
141
|
-
closeSync(fd);
|
|
142
|
-
if (existsSync(temporaryPath))
|
|
143
|
-
unlinkSync(temporaryPath);
|
|
144
|
-
throw error;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
function recordClaimedCredential(pending, join) {
|
|
148
|
-
withJoinCredentialLock(() => {
|
|
149
|
-
const current = JSON.parse(readFileSync(pendingEnrollmentPath(), "utf8"));
|
|
150
|
-
if (current.central !== pending.central || current.token !== pending.token || current.idempotencyKey !== pending.idempotencyKey || current.publicKey !== pending.publicKey) {
|
|
151
|
-
throw new Error("pending Otium enrollment changed while its claim was in flight");
|
|
152
|
-
}
|
|
153
|
-
const claimed = { digest: joinCredentialDigest(join), cellId: join.cellId };
|
|
154
|
-
if (current.claimed && (current.claimed.digest !== claimed.digest || current.claimed.cellId !== claimed.cellId)) {
|
|
155
|
-
throw new Error("central returned different credentials for an idempotent enrollment claim");
|
|
156
|
-
}
|
|
157
|
-
replacePendingEnrollment({ ...current, claimed });
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
function openCredential(envelope, privateKeyDer) {
|
|
161
|
-
if (envelope.v !== 1 || envelope.algorithm !== "X25519-HKDF-SHA256-AES-256-GCM") {
|
|
162
|
-
throw new Error("unsupported enrollment credential envelope");
|
|
163
|
-
}
|
|
164
|
-
const privateKey = createPrivateKey({
|
|
165
|
-
key: Buffer.from(privateKeyDer, "base64url"),
|
|
166
|
-
format: "der",
|
|
167
|
-
type: "pkcs8"
|
|
168
|
-
});
|
|
169
|
-
const ephemeral = createPublicKey({
|
|
170
|
-
key: Buffer.from(envelope.ephemeralPublicKey, "base64url"),
|
|
171
|
-
format: "der",
|
|
172
|
-
type: "spki"
|
|
173
|
-
});
|
|
174
|
-
const shared = diffieHellman({ privateKey, publicKey: ephemeral });
|
|
175
|
-
const key = Buffer.from(hkdfSync("sha256", shared, Buffer.from(envelope.salt, "base64url"), INFO, 32));
|
|
176
|
-
const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(envelope.nonce, "base64url"));
|
|
177
|
-
decipher.setAAD(INFO);
|
|
178
|
-
decipher.setAuthTag(Buffer.from(envelope.tag, "base64url"));
|
|
179
|
-
return Buffer.concat([
|
|
180
|
-
decipher.update(Buffer.from(envelope.ciphertext, "base64url")),
|
|
181
|
-
decipher.final()
|
|
182
|
-
]).toString("utf8");
|
|
183
|
-
}
|
|
184
|
-
async function postJson(url, body, headers) {
|
|
185
|
-
const response = await fetch(url, {
|
|
186
|
-
method: "POST",
|
|
187
|
-
headers: { "content-type": "application/json", ...headers },
|
|
188
|
-
body: JSON.stringify(body)
|
|
189
|
-
});
|
|
190
|
-
const result = await response.json();
|
|
191
|
-
if (!response.ok)
|
|
192
|
-
throw new Error(String(result.error || `request failed (${response.status})`));
|
|
193
|
-
return result;
|
|
194
|
-
}
|
|
195
|
-
async function previewEnrollment(invite) {
|
|
196
|
-
return postJson(`${invite.central}/api/v1/node-enrollments/preview`, {
|
|
197
|
-
token: invite.token
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
async function claimEnrollment(invite, nodeName) {
|
|
201
|
-
const pending = loadOrCreatePending(invite, nodeName);
|
|
202
|
-
const response = await postJson(`${invite.central}/api/v1/node-enrollments/claim`, {
|
|
203
|
-
token: invite.token,
|
|
204
|
-
credentialPublicKey: pending.publicKey,
|
|
205
|
-
...pending.nodeName ? { nodeName: pending.nodeName } : {}
|
|
206
|
-
}, { "idempotency-key": pending.idempotencyKey });
|
|
207
|
-
const credential = response.credential;
|
|
208
|
-
const secret = openCredential(credential, pending.privateKey);
|
|
209
|
-
if (!secret.startsWith("rcs_"))
|
|
210
|
-
throw new Error("central returned an invalid runtime credential");
|
|
211
|
-
const join = {
|
|
212
|
-
v: 2,
|
|
213
|
-
central: invite.central,
|
|
214
|
-
relay: String(response.relayUrl),
|
|
215
|
-
cellId: String(response.cell?.id),
|
|
216
|
-
secret
|
|
217
|
-
};
|
|
218
|
-
if (!join.relay || !join.cellId || join.cellId === "undefined") {
|
|
219
|
-
throw new Error("central returned an incomplete enrollment response");
|
|
220
|
-
}
|
|
221
|
-
assertSecureRelayUrl(join.relay);
|
|
222
|
-
recordClaimedCredential(pending, join);
|
|
223
|
-
return join;
|
|
224
|
-
}
|
|
225
|
-
function commitEnrollment(join, options = {}) {
|
|
226
|
-
return withJoinCredentialLock(() => {
|
|
227
|
-
const pendingPath = pendingEnrollmentPath();
|
|
228
|
-
const pending = existsSync(pendingPath) ? JSON.parse(readFileSync(pendingPath, "utf8")) : null;
|
|
229
|
-
const digest = joinCredentialDigest(join);
|
|
230
|
-
if (pending && (!pending.claimed || pending.claimed.digest !== digest || pending.claimed.cellId !== join.cellId)) {
|
|
231
|
-
throw new Error(`pending Otium enrollment at ${pendingPath} does not match these credentials`);
|
|
232
|
-
}
|
|
233
|
-
const path = saveJoinWhileLocked(join, options);
|
|
234
|
-
if (!isJoinPersisted(join)) {
|
|
235
|
-
throw new Error("Otium join credentials were not durably persisted");
|
|
236
|
-
}
|
|
237
|
-
if (!pending)
|
|
238
|
-
return path;
|
|
239
|
-
unlinkSync(pendingPath);
|
|
240
|
-
const directoryFd = openSync(dirname(pendingPath), "r");
|
|
241
|
-
try {
|
|
242
|
-
fsyncSync(directoryFd);
|
|
243
|
-
} finally {
|
|
244
|
-
closeSync(directoryFd);
|
|
245
|
-
}
|
|
246
|
-
return path;
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
export { parseEnrollmentInvite, pendingEnrollmentPath, isEnrollmentPending, previewEnrollment, claimEnrollment, commitEnrollment };
|
|
251
|
-
|
|
252
|
-
//# debugId=3E67B5DF4109FD5964756E2164756E21
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../adapters/otium/src/enrollment.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import {\n createDecipheriv,\n createPrivateKey,\n createPublicKey,\n diffieHellman,\n generateKeyPairSync,\n hkdfSync,\n randomUUID,\n} from \"node:crypto\";\nimport {\n chmodSync,\n closeSync,\n existsSync,\n fsyncSync,\n linkSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { DATA_DIR } from \"@negotium/core\";\nimport {\n isJoinPersisted,\n joinCredentialDigest,\n type OtiumJoin,\n type SaveJoinOptions,\n saveJoinWhileLocked,\n withJoinCredentialLock,\n} from \"@/join\";\nimport { assertSecureCentralUrl, assertSecureRelayUrl } from \"@/secure-transport\";\n\nconst INFO = Buffer.from(\"otium-node-enrollment-v1\", \"utf8\");\n\nexport interface EnrollmentInvite {\n v: 2;\n central: string;\n token: string;\n}\n\ninterface PendingEnrollment extends EnrollmentInvite {\n idempotencyKey: string;\n privateKey: string;\n publicKey: string;\n /** Frozen with the idempotency key so retries replay the same claim body. */\n nodeName?: string;\n claimed?: {\n digest: string;\n cellId: string;\n };\n}\n\nexport interface EnrollmentCredentialEnvelope {\n v: 1;\n algorithm: \"X25519-HKDF-SHA256-AES-256-GCM\";\n ephemeralPublicKey: string;\n salt: string;\n nonce: string;\n ciphertext: string;\n tag: string;\n}\n\nexport interface EnrollmentPreviewResponse {\n ok: true;\n preview: {\n workspace: { id: string; slug: string; name: string };\n suggestedNodeName: string | null;\n transport: \"relay\";\n relayUrl: string;\n expiresAt: string;\n status: string;\n topics: string;\n };\n}\n\ninterface EnrollmentClaimResponse {\n ok: true;\n relayUrl: string;\n cell: { id: string; baseUrl: string };\n credential: EnrollmentCredentialEnvelope;\n}\n\nexport function parseEnrollmentInvite(code: string): EnrollmentInvite {\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.from(code.trim(), \"base64url\").toString(\"utf8\"));\n } catch {\n throw new Error(\"production invite must be base64url JSON\");\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"production invite must decode to an object\");\n }\n const raw = parsed as Record<string, unknown>;\n const central = typeof raw.central === \"string\" ? raw.central.trim().replace(/\\/+$/, \"\") : \"\";\n const token = typeof raw.token === \"string\" ? raw.token.trim() : \"\";\n if (raw.v !== 2 || !central || !token.startsWith(\"nei_\")) {\n throw new Error(\"production invite requires {v:2, central:http(s), token:nei_…}\");\n }\n assertSecureCentralUrl(central);\n return { v: 2, central, token };\n}\n\nexport function pendingEnrollmentPath(): string {\n return resolve(DATA_DIR, \"otium-enrollment-pending.json\");\n}\n\nexport function isEnrollmentPending(invite: EnrollmentInvite): boolean {\n const path = pendingEnrollmentPath();\n if (!existsSync(path)) return false;\n try {\n const saved = JSON.parse(readFileSync(path, \"utf8\")) as PendingEnrollment;\n return saved.central === invite.central && saved.token === invite.token;\n } catch {\n return false;\n }\n}\n\nfunction loadOrCreatePending(invite: EnrollmentInvite, nodeName?: string): PendingEnrollment {\n const path = pendingEnrollmentPath();\n if (existsSync(path)) {\n const saved = JSON.parse(readFileSync(path, \"utf8\")) as PendingEnrollment;\n if (saved.central === invite.central && saved.token === invite.token) return saved;\n throw new Error(`another Otium enrollment is pending at ${path}`);\n }\n const pair = generateKeyPairSync(\"x25519\");\n const pending: PendingEnrollment = {\n ...invite,\n idempotencyKey: randomUUID(),\n privateKey: pair.privateKey.export({ format: \"der\", type: \"pkcs8\" }).toString(\"base64url\"),\n publicKey: pair.publicKey.export({ format: \"der\", type: \"spki\" }).toString(\"base64url\"),\n ...(nodeName ? { nodeName } : {}),\n };\n mkdirSync(dirname(path), { recursive: true });\n const temporaryPath = resolve(\n dirname(path),\n `.otium-enrollment-pending.json.${process.pid}.${randomUUID()}.tmp`,\n );\n let fd: number | undefined;\n try {\n fd = openSync(temporaryPath, \"wx\", 0o600);\n writeFileSync(fd, `${JSON.stringify(pending, null, 2)}\\n`, \"utf8\");\n fsyncSync(fd);\n closeSync(fd);\n fd = undefined;\n // Publish only the completely written key material and never overwrite a\n // concurrent enrollment created by another process.\n linkSync(temporaryPath, path);\n unlinkSync(temporaryPath);\n chmodSync(path, 0o600);\n const directoryFd = openSync(dirname(path), \"r\");\n try {\n fsyncSync(directoryFd);\n } finally {\n closeSync(directoryFd);\n }\n } catch (error) {\n if (fd !== undefined) closeSync(fd);\n if (existsSync(temporaryPath)) unlinkSync(temporaryPath);\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\" && existsSync(path)) {\n const saved = JSON.parse(readFileSync(path, \"utf8\")) as PendingEnrollment;\n if (saved.central === invite.central && saved.token === invite.token) return saved;\n }\n throw error;\n }\n return pending;\n}\n\nfunction replacePendingEnrollment(pending: PendingEnrollment): void {\n const path = pendingEnrollmentPath();\n const directory = dirname(path);\n const temporaryPath = resolve(\n directory,\n `.otium-enrollment-pending.json.${process.pid}.${randomUUID()}.tmp`,\n );\n let fd: number | undefined;\n try {\n fd = openSync(temporaryPath, \"wx\", 0o600);\n writeFileSync(fd, `${JSON.stringify(pending, null, 2)}\\n`, \"utf8\");\n fsyncSync(fd);\n closeSync(fd);\n fd = undefined;\n renameSync(temporaryPath, path);\n const directoryFd = openSync(directory, \"r\");\n try {\n fsyncSync(directoryFd);\n } finally {\n closeSync(directoryFd);\n }\n } catch (error) {\n if (fd !== undefined) closeSync(fd);\n if (existsSync(temporaryPath)) unlinkSync(temporaryPath);\n throw error;\n }\n}\n\nfunction recordClaimedCredential(pending: PendingEnrollment, join: OtiumJoin): void {\n withJoinCredentialLock(() => {\n const current = JSON.parse(readFileSync(pendingEnrollmentPath(), \"utf8\")) as PendingEnrollment;\n if (\n current.central !== pending.central ||\n current.token !== pending.token ||\n current.idempotencyKey !== pending.idempotencyKey ||\n current.publicKey !== pending.publicKey\n ) {\n throw new Error(\"pending Otium enrollment changed while its claim was in flight\");\n }\n const claimed = { digest: joinCredentialDigest(join), cellId: join.cellId };\n if (\n current.claimed &&\n (current.claimed.digest !== claimed.digest || current.claimed.cellId !== claimed.cellId)\n ) {\n throw new Error(\"central returned different credentials for an idempotent enrollment claim\");\n }\n replacePendingEnrollment({ ...current, claimed });\n });\n}\n\nfunction openCredential(envelope: EnrollmentCredentialEnvelope, privateKeyDer: string): string {\n if (envelope.v !== 1 || envelope.algorithm !== \"X25519-HKDF-SHA256-AES-256-GCM\") {\n throw new Error(\"unsupported enrollment credential envelope\");\n }\n const privateKey = createPrivateKey({\n key: Buffer.from(privateKeyDer, \"base64url\"),\n format: \"der\",\n type: \"pkcs8\",\n });\n const ephemeral = createPublicKey({\n key: Buffer.from(envelope.ephemeralPublicKey, \"base64url\"),\n format: \"der\",\n type: \"spki\",\n });\n const shared = diffieHellman({ privateKey, publicKey: ephemeral });\n const key = Buffer.from(\n hkdfSync(\"sha256\", shared, Buffer.from(envelope.salt, \"base64url\"), INFO, 32),\n );\n const decipher = createDecipheriv(\"aes-256-gcm\", key, Buffer.from(envelope.nonce, \"base64url\"));\n decipher.setAAD(INFO);\n decipher.setAuthTag(Buffer.from(envelope.tag, \"base64url\"));\n return Buffer.concat([\n decipher.update(Buffer.from(envelope.ciphertext, \"base64url\")),\n decipher.final(),\n ]).toString(\"utf8\");\n}\n\nasync function postJson<T>(\n url: string,\n body: unknown,\n headers?: Record<string, string>,\n): Promise<T> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", ...headers },\n body: JSON.stringify(body),\n });\n const result = (await response.json()) as Record<string, unknown>;\n if (!response.ok) throw new Error(String(result.error || `request failed (${response.status})`));\n return result as T;\n}\n\nexport async function previewEnrollment(\n invite: EnrollmentInvite,\n): Promise<EnrollmentPreviewResponse> {\n return postJson<EnrollmentPreviewResponse>(`${invite.central}/api/v1/node-enrollments/preview`, {\n token: invite.token,\n });\n}\n\nexport async function claimEnrollment(\n invite: EnrollmentInvite,\n nodeName?: string,\n): Promise<OtiumJoin> {\n const pending = loadOrCreatePending(invite, nodeName);\n const response = await postJson<EnrollmentClaimResponse>(\n `${invite.central}/api/v1/node-enrollments/claim`,\n {\n token: invite.token,\n credentialPublicKey: pending.publicKey,\n ...(pending.nodeName ? { nodeName: pending.nodeName } : {}),\n },\n { \"idempotency-key\": pending.idempotencyKey },\n );\n const credential = response.credential as EnrollmentCredentialEnvelope;\n const secret = openCredential(credential, pending.privateKey);\n if (!secret.startsWith(\"rcs_\")) throw new Error(\"central returned an invalid runtime credential\");\n const join: OtiumJoin = {\n v: 2,\n central: invite.central,\n relay: String(response.relayUrl),\n cellId: String(response.cell?.id),\n secret,\n };\n if (!join.relay || !join.cellId || join.cellId === \"undefined\") {\n throw new Error(\"central returned an incomplete enrollment response\");\n }\n assertSecureRelayUrl(join.relay);\n recordClaimedCredential(pending, join);\n return join;\n}\n\n/**\n * Durably commit a claimed enrollment. The retry key is deliberately removed\n * only after the atomic join-file save is fsynced and verified. A crash before\n * that point leaves enough key material to replay the idempotent claim.\n */\nexport function commitEnrollment(join: OtiumJoin, options: SaveJoinOptions = {}): string {\n return withJoinCredentialLock(() => {\n const pendingPath = pendingEnrollmentPath();\n const pending = existsSync(pendingPath)\n ? (JSON.parse(readFileSync(pendingPath, \"utf8\")) as PendingEnrollment)\n : null;\n const digest = joinCredentialDigest(join);\n if (\n pending &&\n (!pending.claimed ||\n pending.claimed.digest !== digest ||\n pending.claimed.cellId !== join.cellId)\n ) {\n throw new Error(\n `pending Otium enrollment at ${pendingPath} does not match these credentials`,\n );\n }\n\n const path = saveJoinWhileLocked(join, options);\n if (!isJoinPersisted(join)) {\n throw new Error(\"Otium join credentials were not durably persisted\");\n }\n if (!pending) return path;\n\n // The same lock protects save→verification→pending deletion from a\n // concurrent explicit replacement through saveJoin().\n unlinkSync(pendingPath);\n const directoryFd = openSync(dirname(pendingPath), \"r\");\n try {\n fsyncSync(directoryFd);\n } finally {\n closeSync(directoryFd);\n }\n return path;\n });\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "3E67B5DF4109FD5964756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
package/dist/chunk-rkvrkcgx.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import"./chunk-h7bj5zwb.js";
|
|
3
|
-
import"./chunk-tcs9qjps.js";
|
|
4
|
-
import"./chunk-7k19pcg8.js";
|
|
5
|
-
import"./chunk-8dy7e2a9.js";
|
|
6
|
-
import"./chunk-9hjeemfz.js";
|
|
7
|
-
import"./chunk-1k7t7bnx.js";
|
|
8
|
-
import"./chunk-xhm1rfpt.js";
|
|
9
|
-
import"./chunk-mnwaext5.js";
|
|
10
|
-
import"./chunk-xpcps28p.js";
|
|
11
|
-
import"./chunk-fbtb3v0s.js";
|
|
12
|
-
import"./chunk-ejcm6zx8.js";
|
|
13
|
-
import"./chunk-hp4g7wx7.js";
|
|
14
|
-
import"./chunk-s74rdyqe.js";
|
|
15
|
-
import"./chunk-k778y16p.js";
|
|
16
|
-
import"./chunk-xag86ng3.js";
|
|
17
|
-
import"./chunk-wx83ep8e.js";
|
|
18
|
-
import {
|
|
19
|
-
VAULT_DESCRIPTION_MAX_LENGTH,
|
|
20
|
-
VAULT_VALUE_MAX_BYTES,
|
|
21
|
-
VAULT_VALUE_MIN_BYTES,
|
|
22
|
-
normalizeVaultKey,
|
|
23
|
-
validateVaultKey,
|
|
24
|
-
vaultDel,
|
|
25
|
-
vaultListWithValues,
|
|
26
|
-
vaultSet
|
|
27
|
-
} from "./chunk-00q25k7p.js";
|
|
28
|
-
import"./chunk-gaknyw04.js";
|
|
29
|
-
import"./chunk-mh5mexsf.js";
|
|
30
|
-
import"./chunk-ezs352qs.js";
|
|
31
|
-
import"./chunk-j0kjscb7.js";
|
|
32
|
-
import"./chunk-82qhv1mq.js";
|
|
33
|
-
import"./chunk-ffefbd3r.js";
|
|
34
|
-
import"./chunk-81tbfbmt.js";
|
|
35
|
-
import"./chunk-sffqdkvq.js";
|
|
36
|
-
import"./chunk-f5xgprg1.js";
|
|
37
|
-
import"./chunk-hwy3n31w.js";
|
|
38
|
-
|
|
39
|
-
// ../cli/src/commands/vault.ts
|
|
40
|
-
var DEFAULT_USER = "local";
|
|
41
|
-
function vaultCommand(args) {
|
|
42
|
-
const [sub, key, value, ...descParts] = args;
|
|
43
|
-
switch (sub) {
|
|
44
|
-
case undefined:
|
|
45
|
-
case "list": {
|
|
46
|
-
const entries = vaultListWithValues(DEFAULT_USER);
|
|
47
|
-
if (entries.length === 0) {
|
|
48
|
-
console.log("vault is empty \u2014 `negotium vault set MY_KEY <value> [description]`");
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
for (const entry of entries) {
|
|
52
|
-
console.log(`${entry.key} ${entry.description || ""}`.trimEnd());
|
|
53
|
-
}
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
case "set": {
|
|
57
|
-
if (!key || !value) {
|
|
58
|
-
console.error("usage: negotium vault set <KEY> <value> [description]");
|
|
59
|
-
process.exitCode = 1;
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const normalized = normalizeVaultKey(key);
|
|
63
|
-
if (!validateVaultKey(normalized)) {
|
|
64
|
-
console.error("invalid key \u2014 use A-Z, 0-9, _ (must start with a letter, max 128 chars)");
|
|
65
|
-
process.exitCode = 1;
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const valueBytes = Buffer.byteLength(value, "utf8");
|
|
69
|
-
if (valueBytes < VAULT_VALUE_MIN_BYTES || valueBytes > VAULT_VALUE_MAX_BYTES) {
|
|
70
|
-
console.error(`value must be between ${VAULT_VALUE_MIN_BYTES} and ${VAULT_VALUE_MAX_BYTES} bytes`);
|
|
71
|
-
process.exitCode = 1;
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const description = descParts.join(" ");
|
|
75
|
-
if (description.length > VAULT_DESCRIPTION_MAX_LENGTH) {
|
|
76
|
-
console.error(`description must be at most ${VAULT_DESCRIPTION_MAX_LENGTH} characters`);
|
|
77
|
-
process.exitCode = 1;
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
vaultSet(DEFAULT_USER, normalized, value, description);
|
|
81
|
-
console.log(`stored ${normalized}`);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
case "get": {
|
|
85
|
-
if (!key) {
|
|
86
|
-
console.error("usage: negotium vault get <KEY>");
|
|
87
|
-
process.exitCode = 1;
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const entry = vaultListWithValues(DEFAULT_USER).find((e) => e.key === normalizeVaultKey(key));
|
|
91
|
-
if (!entry) {
|
|
92
|
-
console.error(`no such key "${key}"`);
|
|
93
|
-
process.exitCode = 1;
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
console.log(entry.value);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
case "del": {
|
|
100
|
-
if (!key) {
|
|
101
|
-
console.error("usage: negotium vault del <KEY>");
|
|
102
|
-
process.exitCode = 1;
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
console.log(vaultDel(DEFAULT_USER, normalizeVaultKey(key)) ? `deleted ${key}` : `no such key "${key}"`);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
default:
|
|
109
|
-
console.error(`unknown subcommand "${sub}" \u2014 use list|set|get|del`);
|
|
110
|
-
process.exitCode = 1;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
export {
|
|
114
|
-
vaultCommand
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
//# debugId=EE1D095AA690E88864756E2164756E21
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../cli/src/commands/vault.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * `negotium vault <list|set|get|del>` — node secret store.\n *\n * Values are AES-encrypted at rest with the per-node master key\n * (~/.negotium/vault-master-key, or NEGOTIUM_VAULT_MASTER_KEY). The vault is a\n * core system: agents/MCPs read it through the runtime, humans through here.\n */\n\nimport {\n normalizeVaultKey,\n VAULT_DESCRIPTION_MAX_LENGTH,\n VAULT_VALUE_MAX_BYTES,\n VAULT_VALUE_MIN_BYTES,\n validateVaultKey,\n vaultDel,\n vaultListWithValues,\n vaultSet,\n} from \"@negotium/core\";\n\nconst DEFAULT_USER = \"local\";\n\nexport function vaultCommand(args: string[]): void {\n const [sub, key, value, ...descParts] = args;\n\n switch (sub) {\n case undefined:\n case \"list\": {\n const entries = vaultListWithValues(DEFAULT_USER);\n if (entries.length === 0) {\n console.log(\"vault is empty — `negotium vault set MY_KEY <value> [description]`\");\n return;\n }\n for (const entry of entries) {\n console.log(`${entry.key} ${entry.description || \"\"}`.trimEnd());\n }\n return;\n }\n case \"set\": {\n if (!key || !value) {\n console.error(\"usage: negotium vault set <KEY> <value> [description]\");\n process.exitCode = 1;\n return;\n }\n const normalized = normalizeVaultKey(key);\n if (!validateVaultKey(normalized)) {\n console.error(\"invalid key — use A-Z, 0-9, _ (must start with a letter, max 128 chars)\");\n process.exitCode = 1;\n return;\n }\n const valueBytes = Buffer.byteLength(value, \"utf8\");\n if (valueBytes < VAULT_VALUE_MIN_BYTES || valueBytes > VAULT_VALUE_MAX_BYTES) {\n console.error(\n `value must be between ${VAULT_VALUE_MIN_BYTES} and ${VAULT_VALUE_MAX_BYTES} bytes`,\n );\n process.exitCode = 1;\n return;\n }\n const description = descParts.join(\" \");\n if (description.length > VAULT_DESCRIPTION_MAX_LENGTH) {\n console.error(`description must be at most ${VAULT_DESCRIPTION_MAX_LENGTH} characters`);\n process.exitCode = 1;\n return;\n }\n vaultSet(DEFAULT_USER, normalized, value, description);\n console.log(`stored ${normalized}`);\n return;\n }\n case \"get\": {\n if (!key) {\n console.error(\"usage: negotium vault get <KEY>\");\n process.exitCode = 1;\n return;\n }\n const entry = vaultListWithValues(DEFAULT_USER).find((e) => e.key === normalizeVaultKey(key));\n if (!entry) {\n console.error(`no such key \"${key}\"`);\n process.exitCode = 1;\n return;\n }\n console.log(entry.value);\n return;\n }\n case \"del\": {\n if (!key) {\n console.error(\"usage: negotium vault del <KEY>\");\n process.exitCode = 1;\n return;\n }\n console.log(\n vaultDel(DEFAULT_USER, normalizeVaultKey(key)) ? `deleted ${key}` : `no such key \"${key}\"`,\n );\n return;\n }\n default:\n console.error(`unknown subcommand \"${sub}\" — use list|set|get|del`);\n process.exitCode = 1;\n }\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,IAAM,eAAe;AAEd,SAAS,YAAY,CAAC,MAAsB;AAAA,EACjD,OAAO,KAAK,KAAK,UAAU,aAAa;AAAA,EAExC,QAAQ;AAAA,SACD;AAAA,SACA,QAAQ;AAAA,MACX,MAAM,UAAU,oBAAoB,YAAY;AAAA,MAChD,IAAI,QAAQ,WAAW,GAAG;AAAA,QACxB,QAAQ,IAAI,yEAAmE;AAAA,QAC/E;AAAA,MACF;AAAA,MACA,WAAW,SAAS,SAAS;AAAA,QAC3B,QAAQ,IAAI,GAAG,MAAM,QAAQ,MAAM,eAAe,KAAK,QAAQ,CAAC;AAAA,MAClE;AAAA,MACA;AAAA,IACF;AAAA,SACK,OAAO;AAAA,MACV,KAAK,QAAQ,OAAO;AAAA,QAClB,QAAQ,MAAM,uDAAuD;AAAA,QACrE,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,MAAM,aAAa,kBAAkB,GAAG;AAAA,MACxC,KAAK,iBAAiB,UAAU,GAAG;AAAA,QACjC,QAAQ,MAAM,8EAAwE;AAAA,QACtF,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,MAAM,aAAa,OAAO,WAAW,OAAO,MAAM;AAAA,MAClD,IAAI,aAAa,yBAAyB,aAAa,uBAAuB;AAAA,QAC5E,QAAQ,MACN,yBAAyB,6BAA6B,6BACxD;AAAA,QACA,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,MAAM,cAAc,UAAU,KAAK,GAAG;AAAA,MACtC,IAAI,YAAY,SAAS,8BAA8B;AAAA,QACrD,QAAQ,MAAM,+BAA+B,yCAAyC;AAAA,QACtF,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,SAAS,cAAc,YAAY,OAAO,WAAW;AAAA,MACrD,QAAQ,IAAI,UAAU,YAAY;AAAA,MAClC;AAAA,IACF;AAAA,SACK,OAAO;AAAA,MACV,KAAK,KAAK;AAAA,QACR,QAAQ,MAAM,iCAAiC;AAAA,QAC/C,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,MAAM,QAAQ,oBAAoB,YAAY,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,kBAAkB,GAAG,CAAC;AAAA,MAC5F,KAAK,OAAO;AAAA,QACV,QAAQ,MAAM,gBAAgB,MAAM;AAAA,QACpC,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,QAAQ,IAAI,MAAM,KAAK;AAAA,MACvB;AAAA,IACF;AAAA,SACK,OAAO;AAAA,MACV,KAAK,KAAK;AAAA,QACR,QAAQ,MAAM,iCAAiC;AAAA,QAC/C,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,QAAQ,IACN,SAAS,cAAc,kBAAkB,GAAG,CAAC,IAAI,WAAW,QAAQ,gBAAgB,MACtF;AAAA,MACA;AAAA,IACF;AAAA;AAAA,MAEE,QAAQ,MAAM,uBAAuB,kCAA4B;AAAA,MACjE,QAAQ,WAAW;AAAA;AAAA;",
|
|
8
|
-
"debugId": "EE1D095AA690E88864756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
package/dist/chunk-s74rdyqe.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
readConversation
|
|
4
|
-
} from "./chunk-k778y16p.js";
|
|
5
|
-
import {
|
|
6
|
-
claudeRegistry,
|
|
7
|
-
writeCodexRollout
|
|
8
|
-
} from "./chunk-gaknyw04.js";
|
|
9
|
-
import"./chunk-mh5mexsf.js";
|
|
10
|
-
import {
|
|
11
|
-
CODEX_EFFORT_VALUES
|
|
12
|
-
} from "./chunk-ezs352qs.js";
|
|
13
|
-
import {
|
|
14
|
-
logger
|
|
15
|
-
} from "./chunk-ffefbd3r.js";
|
|
16
|
-
import"./chunk-sffqdkvq.js";
|
|
17
|
-
import"./chunk-f5xgprg1.js";
|
|
18
|
-
import"./chunk-hwy3n31w.js";
|
|
19
|
-
|
|
20
|
-
// ../../packages/core/src/agents/codex-registry.ts
|
|
21
|
-
import { unlinkSync } from "fs";
|
|
22
|
-
import { homedir } from "os";
|
|
23
|
-
import { join } from "path";
|
|
24
|
-
var VALID_EFFORTS = new Set(CODEX_EFFORT_VALUES);
|
|
25
|
-
var codexRegistry = {
|
|
26
|
-
kind: "codex",
|
|
27
|
-
defaultModel: "gpt-5.6-luna",
|
|
28
|
-
expandModelAlias(s) {
|
|
29
|
-
return s;
|
|
30
|
-
},
|
|
31
|
-
validateModel(s) {
|
|
32
|
-
return typeof s === "string" && s.length > 0;
|
|
33
|
-
},
|
|
34
|
-
validEfforts: CODEX_EFFORT_VALUES,
|
|
35
|
-
validateEffort(s) {
|
|
36
|
-
return VALID_EFFORTS.has(s);
|
|
37
|
-
},
|
|
38
|
-
footerLabel(model, effort) {
|
|
39
|
-
return `${model} \xB7 ${effort ?? "(off)"}`;
|
|
40
|
-
},
|
|
41
|
-
writeRollout(opts) {
|
|
42
|
-
const { threadId, rolloutPath } = writeCodexRollout({
|
|
43
|
-
cwd: opts.cwd,
|
|
44
|
-
entries: opts.entries,
|
|
45
|
-
model: opts.model ?? codexRegistry.defaultModel,
|
|
46
|
-
...opts.effort ? { effort: opts.effort } : {},
|
|
47
|
-
...opts.reuseSessionId ? { threadId: opts.reuseSessionId } : {}
|
|
48
|
-
});
|
|
49
|
-
return { sessionId: threadId, rolloutPath };
|
|
50
|
-
},
|
|
51
|
-
async forkSession({ cwd, userId, topicName, model, effort }) {
|
|
52
|
-
const entries = readConversation(userId, topicName);
|
|
53
|
-
const { threadId, rolloutPath } = writeCodexRollout({
|
|
54
|
-
cwd,
|
|
55
|
-
entries,
|
|
56
|
-
model: model ?? codexRegistry.defaultModel,
|
|
57
|
-
...effort ? { effort } : {}
|
|
58
|
-
});
|
|
59
|
-
return { forkId: threadId, rolloutPath };
|
|
60
|
-
},
|
|
61
|
-
async cleanupRollouts({ sessionIds }) {
|
|
62
|
-
if (sessionIds.length === 0)
|
|
63
|
-
return;
|
|
64
|
-
const sessionsDir = join(process.env.CODEX_HOME || join(homedir(), ".codex"), "sessions");
|
|
65
|
-
const failures = [];
|
|
66
|
-
for (const tid of sessionIds) {
|
|
67
|
-
try {
|
|
68
|
-
const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);
|
|
69
|
-
for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {
|
|
70
|
-
const path = join(sessionsDir, rel);
|
|
71
|
-
try {
|
|
72
|
-
unlinkSync(path);
|
|
73
|
-
} catch (e) {
|
|
74
|
-
if (e?.code !== "ENOENT") {
|
|
75
|
-
logger.warn({ err: e, path }, "codex cleanupRollouts: unlink failed");
|
|
76
|
-
failures.push(e);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
} catch (e) {
|
|
81
|
-
logger.warn({ err: e, threadId: tid }, "codex cleanupRollouts: scan failed");
|
|
82
|
-
failures.push(e);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (failures.length > 0) {
|
|
86
|
-
throw new AggregateError(failures, "codex cleanupRollouts failed");
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// ../../packages/core/src/agents/maestro-registry.ts
|
|
92
|
-
import {
|
|
93
|
-
setConversationReader,
|
|
94
|
-
maestroRegistry as upstreamMaestroRegistry
|
|
95
|
-
} from "maestro-agent-sdk";
|
|
96
|
-
setConversationReader(readConversation);
|
|
97
|
-
var maestroRegistry = {
|
|
98
|
-
...upstreamMaestroRegistry,
|
|
99
|
-
defaultModel: "deepseek-pro"
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// ../../packages/core/src/agents/registry.ts
|
|
103
|
-
var REGISTRIES = {
|
|
104
|
-
claude: claudeRegistry,
|
|
105
|
-
codex: codexRegistry,
|
|
106
|
-
maestro: maestroRegistry
|
|
107
|
-
};
|
|
108
|
-
function getRegistry(agent) {
|
|
109
|
-
return REGISTRIES[agent];
|
|
110
|
-
}
|
|
111
|
-
export {
|
|
112
|
-
getRegistry
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
export { getRegistry };
|
|
116
|
-
|
|
117
|
-
//# debugId=40E6B322C20232BB64756E2164756E21
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../packages/core/src/agents/codex-registry.ts", "../../../packages/core/src/agents/maestro-registry.ts", "../../../packages/core/src/agents/registry.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import { unlinkSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { AgentRegistry } from \"#agents/contracts\";\nimport { writeCodexRollout } from \"#agents/rollout/codex\";\nimport { logger } from \"#platform/logger\";\nimport { readConversation } from \"#storage/conversations\";\nimport { CODEX_EFFORT_VALUES, type EffortLevel } from \"#types\";\n\nconst VALID_EFFORTS = new Set<EffortLevel>(CODEX_EFFORT_VALUES);\n\n// Codex CLI's own empirical default is gpt-5.6-sol (`codex exec` 2026-07-10 →\n// \"model: gpt-5.6-sol\"), but we deliberately default to gpt-5.6-luna — the\n// cheapest/fastest GPT-5.6 tier — for a general always-on assistant where most\n// queries are light. Heavier work escalates to terra/sol via set_model. This\n// value is passed explicitly to the SDK (see event-processor resolveDefaultModel),\n// so the footer and the actual model stay in sync.\nexport const codexRegistry: AgentRegistry = {\n kind: \"codex\",\n defaultModel: \"gpt-5.6-luna\",\n // defaultEffort intentionally omitted — Codex SDK treats absence as\n // \"reasoning off\". Setting \"high\"/etc. would silently flip on reasoning.\n\n expandModelAlias(s) {\n return s;\n },\n\n validateModel(s) {\n // Codex doesn't publish a closed model list and OpenAI ships new IDs\n // (gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, o3, ...) frequently. Best-effort: accept any\n // non-empty string. Bad IDs surface at SDK call time with a clear error.\n return typeof s === \"string\" && s.length > 0;\n },\n\n validEfforts: CODEX_EFFORT_VALUES,\n validateEffort(s) {\n // GPT-5.6 accepts low/medium/high/xhigh/max; 'minimal'\n // was removed because the Codex API rejects it when default tools\n // (image_gen, web_search) are active.\n return VALID_EFFORTS.has(s);\n },\n\n footerLabel(model, effort) {\n // Codex omits effort to mean \"reasoning off\". Show `(off)` explicitly so\n // the user can distinguish from claude (which always has a default).\n return `${model} · ${effort ?? \"(off)\"}`;\n },\n\n writeRollout(opts) {\n // Codex SDK exposes the resume key as `threadId`; AgentRegistry unifies\n // the name to `sessionId` so callers don't branch on agent.\n // `reuseSessionId` (if any) is forwarded as `threadId` so claude→codex→claude\n // round-trips also keep one continuous codex thread instead of orphaning a\n // fresh uuidv7 on every switch.\n const { threadId, rolloutPath } = writeCodexRollout({\n cwd: opts.cwd,\n entries: opts.entries,\n model: opts.model ?? codexRegistry.defaultModel,\n ...(opts.effort ? { effort: opts.effort } : {}),\n ...(opts.reuseSessionId ? { threadId: opts.reuseSessionId } : {}),\n });\n return { sessionId: threadId, rolloutPath };\n },\n\n // Codex SDK has no fork API. We synthesize a rollout from the\n // provider-agnostic conversation log (same path as `set_agent` cross-agent\n // bridging). Caveats: extractChatPairs folds tool_use/tool_result into\n // assistant text as `[Tool: ...]` annotations, so structural tool history\n // is lost.\n async forkSession({ cwd, userId, topicName, model, effort }) {\n const entries = readConversation(userId, topicName);\n const { threadId, rolloutPath } = writeCodexRollout({\n cwd,\n entries,\n model: model ?? codexRegistry.defaultModel,\n ...(effort ? { effort } : {}),\n });\n return { forkId: threadId, rolloutPath };\n },\n\n // Codex stores rollouts at `~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-<ts>-<threadId>.jsonl`.\n // The date prefix is unknown at cleanup time (it's the *original* write\n // timestamp, not \"now\"), so we glob across the whole sessions tree by\n // threadId suffix. With at most a few thousand files in active use this\n // is well under a millisecond on a warm filesystem.\n async cleanupRollouts({ sessionIds }) {\n if (sessionIds.length === 0) return;\n const sessionsDir = join(process.env.CODEX_HOME || join(homedir(), \".codex\"), \"sessions\");\n const failures: unknown[] = [];\n // One Glob per threadId so a single corrupt entry can't poison the rest.\n // Bun.Glob's `scan` yields paths relative to its base dir.\n for (const tid of sessionIds) {\n try {\n const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);\n for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {\n const path = join(sessionsDir, rel);\n try {\n unlinkSync(path);\n } catch (e) {\n if ((e as NodeJS.ErrnoException)?.code !== \"ENOENT\") {\n logger.warn({ err: e, path }, \"codex cleanupRollouts: unlink failed\");\n failures.push(e);\n }\n }\n }\n } catch (e) {\n logger.warn({ err: e, threadId: tid }, \"codex cleanupRollouts: scan failed\");\n failures.push(e);\n }\n }\n if (failures.length > 0) {\n throw new AggregateError(failures, \"codex cleanupRollouts failed\");\n }\n },\n};\n",
|
|
6
|
-
"/**\n * Maestro agent registry — local re-export of `maestro-agent-sdk` with\n * a project-specific default-model override.\n *\n * Mirrors the pattern of claude-registry.ts / codex-registry.ts so that\n * agents/registry.ts can resolve all three AgentRegistry instances from\n * sibling `@/agents/*` paths, keeping the import topology consistent.\n *\n * maestro-agent-sdk v0.1.39 is DeepSeek-only — the Anthropic and Codex\n * providers were removed. The SDK's own default is `deepseek-pro`, which\n * matches this override. The override is kept explicit so the intent is\n * clear if the upstream default ever changes; users can still switch to\n * `deepseek-flash` per-topic via `/model deepseek-flash`.\n */\nimport \"#platform/maestro-bootstrap-env\";\nimport {\n setConversationReader,\n maestroRegistry as upstreamMaestroRegistry,\n} from \"maestro-agent-sdk\";\nimport type { AgentRegistry } from \"#agents/contracts\";\nimport { readConversation } from \"#storage/conversations\";\n\n// The SDK intentionally defaults its conversation reader to `() => []` so it\n// can stay storage-agnostic. Wire Negotium's unified log into it once at module\n// load; otherwise Maestro forkSession() creates a valid but empty rollout.\nsetConversationReader(readConversation as Parameters<typeof setConversationReader>[0]);\n\nexport const maestroRegistry: AgentRegistry = {\n ...(upstreamMaestroRegistry as AgentRegistry),\n defaultModel: \"deepseek-pro\",\n};\n",
|
|
7
|
-
"import { claudeRegistry } from \"#agents/claude-registry\";\nimport { codexRegistry } from \"#agents/codex-registry\";\nimport type { AgentRegistry } from \"#agents/contracts\";\nimport { maestroRegistry } from \"#agents/maestro-registry\";\nimport type { AgentKind } from \"#types\";\n\nexport type {\n AgentRegistry,\n CleanupRolloutsOptions,\n ForkRegistryOptions,\n ForkRegistryResult,\n WriteRolloutOptions,\n WriteRolloutResult,\n} from \"#agents/contracts\";\n\nconst REGISTRIES: Record<AgentKind, AgentRegistry> = {\n claude: claudeRegistry,\n codex: codexRegistry,\n maestro: maestroRegistry,\n};\n\nexport function getRegistry(agent: AgentKind): AgentRegistry {\n return REGISTRIES[agent];\n}\n"
|
|
8
|
-
],
|
|
9
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AAOA,IAAM,gBAAgB,IAAI,IAAiB,mBAAmB;AAQvD,IAAM,gBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,cAAc;AAAA,EAId,gBAAgB,CAAC,GAAG;AAAA,IAClB,OAAO;AAAA;AAAA,EAGT,aAAa,CAAC,GAAG;AAAA,IAIf,OAAO,OAAO,MAAM,YAAY,EAAE,SAAS;AAAA;AAAA,EAG7C,cAAc;AAAA,EACd,cAAc,CAAC,GAAG;AAAA,IAIhB,OAAO,cAAc,IAAI,CAAC;AAAA;AAAA,EAG5B,WAAW,CAAC,OAAO,QAAQ;AAAA,IAGzB,OAAO,GAAG,cAAU,UAAU;AAAA;AAAA,EAGhC,YAAY,CAAC,MAAM;AAAA,IAMjB,QAAQ,UAAU,gBAAgB,kBAAkB;AAAA,MAClD,KAAK,KAAK;AAAA,MACV,SAAS,KAAK;AAAA,MACd,OAAO,KAAK,SAAS,cAAc;AAAA,SAC/B,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,SACzC,KAAK,iBAAiB,EAAE,UAAU,KAAK,eAAe,IAAI,CAAC;AAAA,IACjE,CAAC;AAAA,IACD,OAAO,EAAE,WAAW,UAAU,YAAY;AAAA;AAAA,OAQtC,YAAW,GAAG,KAAK,QAAQ,WAAW,OAAO,UAAU;AAAA,IAC3D,MAAM,UAAU,iBAAiB,QAAQ,SAAS;AAAA,IAClD,QAAQ,UAAU,gBAAgB,kBAAkB;AAAA,MAClD;AAAA,MACA;AAAA,MACA,OAAO,SAAS,cAAc;AAAA,SAC1B,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC7B,CAAC;AAAA,IACD,OAAO,EAAE,QAAQ,UAAU,YAAY;AAAA;AAAA,OAQnC,gBAAe,GAAG,cAAc;AAAA,IACpC,IAAI,WAAW,WAAW;AAAA,MAAG;AAAA,IAC7B,MAAM,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,QAAQ,GAAG,QAAQ,GAAG,UAAU;AAAA,IACxF,MAAM,WAAsB,CAAC;AAAA,IAG7B,WAAW,OAAO,YAAY;AAAA,MAC5B,IAAI;AAAA,QACF,MAAM,OAAO,IAAI,IAAI,KAAK,gBAAgB,WAAW;AAAA,QACrD,iBAAiB,OAAO,KAAK,KAAK,EAAE,KAAK,aAAa,WAAW,KAAK,CAAC,GAAG;AAAA,UACxE,MAAM,OAAO,KAAK,aAAa,GAAG;AAAA,UAClC,IAAI;AAAA,YACF,WAAW,IAAI;AAAA,YACf,OAAO,GAAG;AAAA,YACV,IAAK,GAA6B,SAAS,UAAU;AAAA,cACnD,OAAO,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,sCAAsC;AAAA,cACpE,SAAS,KAAK,CAAC;AAAA,YACjB;AAAA;AAAA,QAEJ;AAAA,QACA,OAAO,GAAG;AAAA,QACV,OAAO,KAAK,EAAE,KAAK,GAAG,UAAU,IAAI,GAAG,oCAAoC;AAAA,QAC3E,SAAS,KAAK,CAAC;AAAA;AAAA,IAEnB;AAAA,IACA,IAAI,SAAS,SAAS,GAAG;AAAA,MACvB,MAAM,IAAI,eAAe,UAAU,8BAA8B;AAAA,IACnE;AAAA;AAEJ;;;ACnGA;AAAA;AAAA,qBAEE;AAAA;AAQF,sBAAsB,gBAA+D;AAE9E,IAAM,kBAAiC;AAAA,KACxC;AAAA,EACJ,cAAc;AAChB;;;ACfA,IAAM,aAA+C;AAAA,EACnD,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAEO,SAAS,WAAW,CAAC,OAAiC;AAAA,EAC3D,OAAO,WAAW;AAAA;",
|
|
10
|
-
"debugId": "40E6B322C20232BB64756E2164756E21",
|
|
11
|
-
"names": []
|
|
12
|
-
}
|
package/dist/chunk-sa874j5c.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// ../../packages/adapter-sdk/src/index.ts
|
|
2
|
-
var NEGOTIUM_ADAPTER_API_VERSION = 3;
|
|
3
|
-
function defineNegotiumAdapter(definition) {
|
|
4
|
-
return { apiVersion: NEGOTIUM_ADAPTER_API_VERSION, ...definition };
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export { defineNegotiumAdapter };
|
|
8
|
-
|
|
9
|
-
//# debugId=4B9EA4CD81D4F9FD64756E2164756E21
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../packages/adapter-sdk/src/index.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/** Stable lifecycle contract implemented by every first-party channel adapter. */\n\nexport const NEGOTIUM_ADAPTER_API_VERSION = 3 as const;\n\nexport type Awaitable<T> = T | Promise<T>;\n\nexport interface NegotiumAdapterHandle<Name extends string = string> {\n /** Stable adapter key used in logs, configuration, and contract tests. */\n readonly name: Name;\n /** Stop accepting channel input and release every owned resource. Idempotent. */\n stop(): Awaitable<void>;\n}\n\n/** User-facing transcript semantics; transport gaps stay explicit metadata. */\nexport interface NegotiumAdapterProjectionCapabilities {\n /** Whether the surface can render a room timeline or only newly delivered events. */\n readonly transcript: \"full\" | \"live-only\";\n /** Whether pre-existing topic messages can populate the surface on binding. */\n readonly historyBackfill: boolean;\n /** How authors originating in another adapter are represented. */\n readonly externalAuthors: \"native\" | \"relayed\";\n}\n\n/** Optional behavioral surfaces are declared independently from lifecycle. */\nexport interface NegotiumAdapterCapabilities {\n /** Accepts a human message originating on this adapter. */\n readonly localUserInput: boolean;\n /** Exposes create/delete/reset/compact topic commands. */\n readonly topicManagement: boolean;\n /** Executes a turn placed by an external peer runtime. */\n readonly externalPlacedTurn: boolean;\n}\n\nexport interface NegotiumAdapterDefinition<\n Name extends string,\n Options,\n Handle extends NegotiumAdapterHandle<Name>,\n> {\n readonly apiVersion: typeof NEGOTIUM_ADAPTER_API_VERSION;\n readonly name: Name;\n readonly capabilities: NegotiumAdapterCapabilities;\n readonly projection: NegotiumAdapterProjectionCapabilities;\n start(options: Options): Awaitable<Handle>;\n}\n\nexport function defineNegotiumAdapter<\n const Name extends string,\n Options,\n Handle extends NegotiumAdapterHandle<Name>,\n>(\n definition: Omit<NegotiumAdapterDefinition<Name, Options, Handle>, \"apiVersion\">,\n): NegotiumAdapterDefinition<Name, Options, Handle> {\n return { apiVersion: NEGOTIUM_ADAPTER_API_VERSION, ...definition };\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": ";AAEO,IAAM,+BAA+B;AA2CrC,SAAS,qBAIf,CACC,YACkD;AAAA,EAClD,OAAO,EAAE,YAAY,iCAAiC,WAAW;AAAA;",
|
|
8
|
-
"debugId": "4B9EA4CD81D4F9FD64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|