@astrosheep/keiyaku 2.9.2 → 2.9.4
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/build/.tsbuildinfo +1 -1
- package/build/agents/call-terms.js +13 -94
- package/build/agents/harness/activity-values.js +16 -0
- package/build/agents/harness/event-persistence.js +218 -0
- package/build/agents/harness/execution-handle.js +25 -222
- package/build/agents/harness/index.js +3 -1
- package/build/agents/harness/outcome.js +47 -4
- package/build/agents/harness/projection.js +42 -59
- package/build/agents/harness/provider-adapter.js +58 -0
- package/build/agents/harness/router.js +11 -187
- package/build/agents/harness/runtime.js +17 -4
- package/build/agents/harness/session.js +15 -0
- package/build/agents/launch-snapshot/model.js +15 -236
- package/build/agents/launch-snapshot/parse-helpers.js +114 -0
- package/build/agents/launch-snapshot/resolve.js +17 -43
- package/build/agents/opencode-sdk.js +45 -12
- package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
- package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
- package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
- package/build/agents/providers/codex-app-server/adapter.js +50 -53
- package/build/agents/providers/codex-app-server/events.js +67 -11
- package/build/agents/providers/codex-app-server/identity.js +1 -0
- package/build/agents/providers/codex-app-server/policy.js +29 -0
- package/build/agents/providers/codex-app-server/registration.js +248 -0
- package/build/agents/providers/codex-app-server/session-schema.js +6 -0
- package/build/agents/providers/codex-app-server/session.js +23 -17
- package/build/agents/providers/codex-app-server/terms.js +1 -0
- package/build/agents/providers/opencode-sdk/adapter.js +94 -50
- package/build/agents/providers/opencode-sdk/events.js +8 -4
- package/build/agents/providers/opencode-sdk/registration.js +135 -0
- package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
- package/build/agents/providers/opencode-sdk/session.js +21 -14
- package/build/agents/providers/opencode-sdk/terms.js +1 -0
- package/build/agents/providers/pi/adapter.js +36 -30
- package/build/agents/providers/pi/registration.js +145 -0
- package/build/agents/providers/pi/session-schema.js +6 -0
- package/build/agents/providers/pi/terms.js +1 -0
- package/build/agents/providers/registration.js +7 -0
- package/build/agents/providers/registry.js +76 -0
- package/build/agents/selector.js +2 -29
- package/build/agents/types.js +8 -0
- package/build/artifact-directories.js +22 -0
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/view/handler.js +5 -4
- package/build/cli/commands/akuma.js +6 -0
- package/build/cli/commands/contract/amend/handler.js +8 -2
- package/build/cli/commands/contract/arc/handler.js +7 -1
- package/build/cli/commands/contract/bind/handler.js +4 -3
- package/build/cli/commands/contract/bind/meta.js +34 -7
- package/build/cli/commands/contract/forfeit/handler.js +4 -4
- package/build/cli/commands/contract/log/handler.js +3 -3
- package/build/cli/commands/contract/petition/handler.js +4 -6
- package/build/cli/commands/contract/renew/handler.js +20 -6
- package/build/cli/commands/contract/renew/meta.js +5 -4
- package/build/cli/commands/metadata.js +58 -0
- package/build/cli/commands/projection/call/handler.js +6 -5
- package/build/cli/commands/projection/kill/handler.js +16 -32
- package/build/cli/commands/projection/shared.js +28 -0
- package/build/cli/commands/projection/status/handler.js +1 -1
- package/build/cli/commands/projection/tell/handler.js +14 -30
- package/build/cli/commands/projection/wait/handler.js +45 -22
- package/build/cli/commands/projection/wait/meta.js +7 -2
- package/build/cli/commands/registry.js +2 -54
- package/build/cli/commands/shared.js +10 -7
- package/build/cli/commands/skills/install/handler.js +2 -5
- package/build/cli/commands/skills/skills/handler.js +1 -1
- package/build/cli/commands/task/add/handler.js +5 -13
- package/build/cli/commands/task/catalog.js +2 -2
- package/build/cli/commands/task/done/handler.js +4 -8
- package/build/cli/commands/task/drop/handler.js +3 -6
- package/build/cli/commands/task/ls/handler.js +3 -5
- package/build/cli/commands/task/shared.js +14 -4
- package/build/cli/commands/task/{view → show}/handler.js +7 -8
- package/build/cli/commands/task/show/meta.js +8 -0
- package/build/cli/commands/task/start/handler.js +3 -6
- package/build/cli/commands/task/stop/handler.js +4 -8
- package/build/cli/commands/task/task/handler.js +1 -1
- package/build/cli/commands/task/update/handler.js +4 -8
- package/build/cli/completion.js +1 -1
- package/build/cli/flags.js +19 -3
- package/build/cli/help.js +4 -11
- package/build/cli/index.js +57 -83
- package/build/cli/missing-subcommand.js +7 -0
- package/build/cli/parse-flags.js +14 -5
- package/build/cli/parse-metadata.js +3 -3
- package/build/cli/parse-selectors.js +1 -1
- package/build/cli/parse.js +21 -0
- package/build/cli/projection-address.js +7 -12
- package/build/cli/render/address.js +41 -37
- package/build/cli/render/arc.js +24 -12
- package/build/cli/render/call.js +11 -5
- package/build/cli/render/errors.js +36 -1
- package/build/cli/render/format.js +4 -0
- package/build/cli/render/kanshi.js +6 -12
- package/build/cli/render/kill.js +9 -0
- package/build/cli/render/misc.js +55 -12
- package/build/cli/render/petition.js +20 -15
- package/build/cli/render/projection-activity.js +3 -0
- package/build/cli/render/shared.js +60 -21
- package/build/cli/render/skills.js +10 -0
- package/build/cli/render/status.js +37 -14
- package/build/cli/render/success-response.js +77 -0
- package/build/cli/render/task.js +54 -14
- package/build/cli/render/tell.js +5 -0
- package/build/cli/render/terminal-failure.js +58 -0
- package/build/cli/render/types.js +1 -0
- package/build/cli/render/wait.js +38 -36
- package/build/cli/types.js +1 -1
- package/build/config/akuma-loader.js +0 -5
- package/build/config/env-keys.js +1 -1
- package/build/config/provider-policy-ownership.js +3 -32
- package/build/config/settings/disease.js +8 -1
- package/build/config/settings/loader.js +11 -3
- package/build/config/settings/provider-instance-fields.js +51 -0
- package/build/config/settings/schema.js +6 -176
- package/build/core/addressing.js +66 -16
- package/build/core/amend.js +135 -18
- package/build/core/arc.js +19 -67
- package/build/core/bind.js +82 -35
- package/build/core/call/call.js +15 -9
- package/build/core/call/context.js +6 -51
- package/build/core/call/execution.js +21 -22
- package/build/core/call/prompt.js +14 -1
- package/build/core/command-markdown.js +45 -0
- package/build/core/context.js +13 -7
- package/build/core/contract-view.js +20 -3
- package/build/core/draft.js +123 -16
- package/build/core/forfeit.js +5 -2
- package/build/core/hints.js +1 -75
- package/build/core/identifier-slug.js +66 -0
- package/build/core/ids.js +25 -11
- package/build/core/ledger.js +20 -68
- package/build/core/markdown/parser.js +0 -68
- package/build/core/markdown/render.js +68 -0
- package/build/core/markdown/sections.js +2 -1
- package/build/core/outcome-base.js +4 -0
- package/build/core/projection/generation/database.js +2 -38
- package/build/core/projection/generation/model.js +42 -1
- package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
- package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +19 -49
- package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
- package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +5 -3
- package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
- package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +18 -3
- package/build/core/projection/generation/store.js +2 -2
- package/build/core/projection/generation/transitions.js +1 -1
- package/build/core/projection/index.js +27 -0
- package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
- package/build/core/{projection-alias.js → projection/projection-alias.js} +14 -19
- package/build/core/projection/projection-coordinate.js +61 -0
- package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
- package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +2 -57
- package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
- package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
- package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +1 -1
- package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
- package/build/core/{projection-status.js → projection/projection-status.js} +98 -25
- package/build/core/projection/projection-terminal-failure.js +104 -0
- package/build/core/projection/projection-wait.js +278 -0
- package/build/core/projection/projection-wake.js +203 -0
- package/build/core/provider-loader-ports.js +4 -0
- package/build/core/ref-log.js +65 -40
- package/build/core/registry.js +63 -10
- package/build/core/renew-session.js +128 -0
- package/build/core/renew.js +426 -99
- package/build/core/scope.js +143 -66
- package/build/core/seal.js +139 -35
- package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +9 -14
- package/build/core/{claim.js → settlement/claim.js} +32 -8
- package/build/core/settlement/index.js +19 -0
- package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +22 -18
- package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
- package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
- package/build/core/settlement/petition-io.js +1 -0
- package/build/core/{petition-preview.js → settlement/petition-preview.js} +1 -1
- package/build/core/{petition.js → settlement/petition.js} +12 -10
- package/build/core/settlement/queue-read-model.js +143 -0
- package/build/core/settlement/queue-seat-allocation.js +156 -0
- package/build/core/settlement/queue.js +6 -0
- package/build/core/settlement/settlement.js +295 -0
- package/build/core/{verdict.js → settlement/verdict.js} +9 -37
- package/build/core/status/board.js +24 -23
- package/build/core/status/ledger-batch.js +158 -0
- package/build/core/status/reconciliation.js +10 -4
- package/build/core/stored-agent-event.js +3 -0
- package/build/core/task/board.js +40 -4
- package/build/core/task/commands.js +30 -21
- package/build/core/task/index.js +12 -0
- package/build/core/task/settlement-git.js +157 -65
- package/build/core/task/settlement-policy.js +54 -24
- package/build/core/task/task-contract.js +370 -0
- package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
- package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
- package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
- package/build/core/{task-git-store.js → task/task-git-store.js} +92 -29
- package/build/core/task/task-repository.js +1 -0
- package/build/core/{task-store-repository.js → task/task-store-repository.js} +5 -4
- package/build/core/task/task-store.js +1 -0
- package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
- package/build/core/task/task.js +5 -0
- package/build/core/task/tree.js +37 -0
- package/build/core/task/validation.js +5 -2
- package/build/core/transcripts.js +15 -3
- package/build/core/worktree-path.js +43 -28
- package/build/flow-error.js +85 -39
- package/build/fs/durability.js +27 -0
- package/build/fs/path-coordinate.js +16 -0
- package/build/generated/version.js +3 -2
- package/build/git/branches.js +2 -1
- package/build/git/core.js +106 -2
- package/build/git/path-coordinate.js +17 -0
- package/build/git/refs.js +57 -0
- package/build/git/streaming-batch.js +301 -0
- package/build/git/worktree.js +65 -0
- package/build/index.js +3 -3
- package/build/keiyaku.js +2 -36
- package/package.json +4 -10
- package/skills/keiyaku/SKILL.md +3 -2
- package/skills/keiyaku-akuma/SKILL.md +10 -6
- package/skills/keiyaku-task/SKILL.md +1 -1
- package/skills/keiyaku-workflow/SKILL.md +25 -4
- package/build/agents/providers/codex-sdk.js +0 -329
- package/build/cli/commands/task/view/meta.js +0 -8
- package/build/core/command-io.js +0 -174
- package/build/core/path-coordinate.js +0 -27
- package/build/core/petition-claim.js +0 -117
- package/build/core/petition-run.js +0 -83
- package/build/core/projection-coordinate.js +0 -63
- package/build/core/projection-wait.js +0 -165
- package/build/core/projection-wake.js +0 -136
- package/build/core/queue.js +0 -343
- package/build/core/task-contract.js +0 -237
- package/build/core/task.js +0 -4
- /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
- /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
- /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
- /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
- /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
|
@@ -258,71 +258,3 @@ export function parseToAST(content, options = {}) {
|
|
|
258
258
|
});
|
|
259
259
|
return parser.parseDocument();
|
|
260
260
|
}
|
|
261
|
-
function renderListItemFirstLine(item) {
|
|
262
|
-
const content = renderNodeContent(item);
|
|
263
|
-
if (!content) {
|
|
264
|
-
return `${" ".repeat(item.indent)}${item.marker}`;
|
|
265
|
-
}
|
|
266
|
-
const [firstLine, ...rest] = content.split("\n");
|
|
267
|
-
const prefix = `${" ".repeat(item.indent)}${item.marker}${firstLine.length > 0 ? " " : ""}${firstLine}`;
|
|
268
|
-
if (rest.length === 0) {
|
|
269
|
-
return prefix;
|
|
270
|
-
}
|
|
271
|
-
return [prefix, ...rest].join("\n");
|
|
272
|
-
}
|
|
273
|
-
export function renderBlock(node) {
|
|
274
|
-
switch (node.type) {
|
|
275
|
-
case "section": {
|
|
276
|
-
const header = `${"#".repeat(node.level)} ${node.title}`;
|
|
277
|
-
const body = renderNodeContent(node);
|
|
278
|
-
return body ? `${header}\n${body}` : header;
|
|
279
|
-
}
|
|
280
|
-
case "list":
|
|
281
|
-
return node.items.map((item) => renderListItemFirstLine(item)).join("\n");
|
|
282
|
-
case "code_block":
|
|
283
|
-
return node.lines.join("\n");
|
|
284
|
-
case "blockquote":
|
|
285
|
-
return node.lines.map((line) => `${node.marker}${line}`).join("\n");
|
|
286
|
-
case "text":
|
|
287
|
-
return node.value;
|
|
288
|
-
case "heading":
|
|
289
|
-
return `${"#".repeat(node.level)} ${node.text}`;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
export function renderNodeContent(node) {
|
|
293
|
-
switch (node.type) {
|
|
294
|
-
case "document":
|
|
295
|
-
return node.children.map((child) => renderBlock(child)).join("\n");
|
|
296
|
-
case "section":
|
|
297
|
-
return node.children.map((child) => renderBlock(child)).join("\n");
|
|
298
|
-
case "list":
|
|
299
|
-
return renderBlock(node);
|
|
300
|
-
case "list_item":
|
|
301
|
-
return node.children.map((child) => renderBlock(child)).join("\n");
|
|
302
|
-
case "code_block":
|
|
303
|
-
return node.lines.join("\n");
|
|
304
|
-
case "blockquote":
|
|
305
|
-
return node.lines.map((line) => `${node.marker}${line}`).join("\n");
|
|
306
|
-
case "text":
|
|
307
|
-
return node.value;
|
|
308
|
-
case "heading":
|
|
309
|
-
return `${"#".repeat(node.level)} ${node.text}`;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
export function renderSectionContent(sectionNode) {
|
|
313
|
-
return sectionNode.children.map((child) => renderBlock(child)).join("\n");
|
|
314
|
-
}
|
|
315
|
-
export function extractListItems(sectionNode) {
|
|
316
|
-
const items = [];
|
|
317
|
-
for (const child of sectionNode.children) {
|
|
318
|
-
if (child.type !== "list")
|
|
319
|
-
continue;
|
|
320
|
-
for (const item of child.items) {
|
|
321
|
-
const rendered = renderNodeContent(item).trimEnd();
|
|
322
|
-
if (rendered.trim().length > 0) {
|
|
323
|
-
items.push(rendered);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
return items;
|
|
328
|
-
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
function renderListItemFirstLine(item) {
|
|
2
|
+
const content = renderNodeContent(item);
|
|
3
|
+
if (!content) {
|
|
4
|
+
return `${" ".repeat(item.indent)}${item.marker}`;
|
|
5
|
+
}
|
|
6
|
+
const [firstLine, ...rest] = content.split("\n");
|
|
7
|
+
const prefix = `${" ".repeat(item.indent)}${item.marker}${firstLine.length > 0 ? " " : ""}${firstLine}`;
|
|
8
|
+
if (rest.length === 0) {
|
|
9
|
+
return prefix;
|
|
10
|
+
}
|
|
11
|
+
return [prefix, ...rest].join("\n");
|
|
12
|
+
}
|
|
13
|
+
export function renderBlock(node) {
|
|
14
|
+
switch (node.type) {
|
|
15
|
+
case "section": {
|
|
16
|
+
const header = `${"#".repeat(node.level)} ${node.title}`;
|
|
17
|
+
const body = renderNodeContent(node);
|
|
18
|
+
return body ? `${header}\n${body}` : header;
|
|
19
|
+
}
|
|
20
|
+
case "list":
|
|
21
|
+
return node.items.map((item) => renderListItemFirstLine(item)).join("\n");
|
|
22
|
+
case "code_block":
|
|
23
|
+
return node.lines.join("\n");
|
|
24
|
+
case "blockquote":
|
|
25
|
+
return node.lines.map((line) => `${node.marker}${line}`).join("\n");
|
|
26
|
+
case "text":
|
|
27
|
+
return node.value;
|
|
28
|
+
case "heading":
|
|
29
|
+
return `${"#".repeat(node.level)} ${node.text}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function renderNodeContent(node) {
|
|
33
|
+
switch (node.type) {
|
|
34
|
+
case "document":
|
|
35
|
+
return node.children.map((child) => renderBlock(child)).join("\n");
|
|
36
|
+
case "section":
|
|
37
|
+
return node.children.map((child) => renderBlock(child)).join("\n");
|
|
38
|
+
case "list":
|
|
39
|
+
return renderBlock(node);
|
|
40
|
+
case "list_item":
|
|
41
|
+
return node.children.map((child) => renderBlock(child)).join("\n");
|
|
42
|
+
case "code_block":
|
|
43
|
+
return node.lines.join("\n");
|
|
44
|
+
case "blockquote":
|
|
45
|
+
return node.lines.map((line) => `${node.marker}${line}`).join("\n");
|
|
46
|
+
case "text":
|
|
47
|
+
return node.value;
|
|
48
|
+
case "heading":
|
|
49
|
+
return `${"#".repeat(node.level)} ${node.text}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function renderSectionContent(sectionNode) {
|
|
53
|
+
return sectionNode.children.map((child) => renderBlock(child)).join("\n");
|
|
54
|
+
}
|
|
55
|
+
export function extractListItems(sectionNode) {
|
|
56
|
+
const items = [];
|
|
57
|
+
for (const child of sectionNode.children) {
|
|
58
|
+
if (child.type !== "list")
|
|
59
|
+
continue;
|
|
60
|
+
for (const item of child.items) {
|
|
61
|
+
const rendered = renderNodeContent(item).trimEnd();
|
|
62
|
+
if (rendered.trim().length > 0) {
|
|
63
|
+
items.push(rendered);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return items;
|
|
68
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseToAST } from "./parser.js";
|
|
2
|
+
import { extractListItems, renderBlock, renderSectionContent } from "./render.js";
|
|
2
3
|
import { KeiyakuParseError } from "./types.js";
|
|
3
4
|
import { normalizeSectionTitle } from "./titles.js";
|
|
4
5
|
function splitByHeadingBlocks(sectionNode) {
|
|
@@ -76,7 +76,7 @@ export function rollbackQuietly(database) {
|
|
|
76
76
|
function validateSchemaShape(database) {
|
|
77
77
|
const version = pragmaNumber(database, "user_version");
|
|
78
78
|
if (version !== PROJECTION_GENERATION_SCHEMA_VERSION) {
|
|
79
|
-
throw new ProjectionGenerationStoreError(`projection generation schema version ${version}
|
|
79
|
+
throw new ProjectionGenerationStoreError(`incompatible projection generation schema version ${version}; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
|
|
80
80
|
}
|
|
81
81
|
const objects = database.prepare(`
|
|
82
82
|
SELECT name, type
|
|
@@ -138,7 +138,7 @@ function initializeOrValidateSchema(database) {
|
|
|
138
138
|
database.exec(`PRAGMA user_version = ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
|
|
139
139
|
}
|
|
140
140
|
else if (version !== PROJECTION_GENERATION_SCHEMA_VERSION) {
|
|
141
|
-
throw new ProjectionGenerationStoreError(`projection generation schema version ${version}
|
|
141
|
+
throw new ProjectionGenerationStoreError(`incompatible projection generation schema version ${version}; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
|
|
142
142
|
}
|
|
143
143
|
validateSchemaShape(database);
|
|
144
144
|
database.exec("COMMIT");
|
|
@@ -268,39 +268,3 @@ export function closeDatabase(database) {
|
|
|
268
268
|
closedDatabases.add(database);
|
|
269
269
|
database.close();
|
|
270
270
|
}
|
|
271
|
-
/**
|
|
272
|
-
* Discovery-only predicate: a readable regular heart whose PRAGMA user_version
|
|
273
|
-
* is exactly 1 is recognized historical residue. Never opens through the store
|
|
274
|
-
* class, never mutates, and any observation failure returns false so callers
|
|
275
|
-
* proceed into the strict current-schema reader.
|
|
276
|
-
*/
|
|
277
|
-
export function isProjectionGenerationSchemaV1Residue(projectionDirectory) {
|
|
278
|
-
const databasePath = path.join(projectionDirectory, PROJECTION_GENERATION_STORE_FILE);
|
|
279
|
-
let database;
|
|
280
|
-
let residue = false;
|
|
281
|
-
try {
|
|
282
|
-
if (!fs.lstatSync(databasePath).isFile())
|
|
283
|
-
return false;
|
|
284
|
-
database = new DatabaseSync(databasePath, {
|
|
285
|
-
readOnly: true,
|
|
286
|
-
enableDoubleQuotedStringLiterals: false,
|
|
287
|
-
allowExtension: false,
|
|
288
|
-
});
|
|
289
|
-
configureHeartBusyTimeout(database);
|
|
290
|
-
residue = pragmaNumber(database, "user_version") === 1;
|
|
291
|
-
}
|
|
292
|
-
catch {
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
finally {
|
|
296
|
-
if (database) {
|
|
297
|
-
try {
|
|
298
|
-
database.close();
|
|
299
|
-
}
|
|
300
|
-
catch {
|
|
301
|
-
residue = false;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
return residue;
|
|
306
|
-
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import { GENERATION_VERDICT_STATES, } from "
|
|
1
|
+
import { GENERATION_VERDICT_STATES, } from "../projection-life-protocol.js";
|
|
2
|
+
import { OUTCOME_ERROR_VERSION, SUBAGENT_FAILURE_CODES } from "../../../agents/types.js";
|
|
2
3
|
export { GENERATION_VERDICT_STATES };
|
|
3
4
|
export const VERDICTS = new Set(GENERATION_VERDICT_STATES);
|
|
5
|
+
const OUTCOME_ERROR_CODES = new Set(SUBAGENT_FAILURE_CODES);
|
|
6
|
+
const OUTCOME_ERROR_KEYS = new Set([
|
|
7
|
+
"version",
|
|
8
|
+
"code",
|
|
9
|
+
"message",
|
|
10
|
+
"timeoutMs",
|
|
11
|
+
"exitCode",
|
|
12
|
+
"publicCause",
|
|
13
|
+
]);
|
|
4
14
|
export class ProjectionGenerationStoreError extends Error {
|
|
5
15
|
code = "PROJECTION_GENERATION_STORE_ERROR";
|
|
6
16
|
constructor(message, options) {
|
|
@@ -121,6 +131,37 @@ export function validateVerdictFacts(value, location) {
|
|
|
121
131
|
if (typeof facts.state !== "string" || !VERDICTS.has(facts.state)) {
|
|
122
132
|
throw new ProjectionGenerationStoreError(`${location}.state is not in the closed verdict vocabulary`);
|
|
123
133
|
}
|
|
134
|
+
if (facts.state === "failed") {
|
|
135
|
+
const error = isPlainObject(facts.error) ? facts.error : undefined;
|
|
136
|
+
const version = error?.version;
|
|
137
|
+
if (!error || version !== OUTCOME_ERROR_VERSION) {
|
|
138
|
+
throw new ProjectionGenerationStoreError(`${location}.error has incompatible version ${version === undefined ? "missing" : String(version)}; expected ${OUTCOME_ERROR_VERSION}`);
|
|
139
|
+
}
|
|
140
|
+
if (Object.keys(error).some((key) => !OUTCOME_ERROR_KEYS.has(key))) {
|
|
141
|
+
throw new ProjectionGenerationStoreError(`${location}.error is not the current closed OutcomeError shape`);
|
|
142
|
+
}
|
|
143
|
+
if (typeof error.code !== "string" || !OUTCOME_ERROR_CODES.has(error.code)) {
|
|
144
|
+
throw new ProjectionGenerationStoreError(`${location}.error.code is not a recognized subagent failure code`);
|
|
145
|
+
}
|
|
146
|
+
if (typeof error.message !== "string") {
|
|
147
|
+
throw new ProjectionGenerationStoreError(`${location}.error.message must be a string`);
|
|
148
|
+
}
|
|
149
|
+
if (error.timeoutMs !== null && (typeof error.timeoutMs !== "number"
|
|
150
|
+
|| !Number.isSafeInteger(error.timeoutMs)
|
|
151
|
+
|| error.timeoutMs < 0)) {
|
|
152
|
+
throw new ProjectionGenerationStoreError(`${location}.error.timeoutMs must be null or a non-negative safe integer`);
|
|
153
|
+
}
|
|
154
|
+
if (error.exitCode !== null && (typeof error.exitCode !== "number"
|
|
155
|
+
|| !Number.isSafeInteger(error.exitCode))) {
|
|
156
|
+
throw new ProjectionGenerationStoreError(`${location}.error.exitCode must be null or a safe integer`);
|
|
157
|
+
}
|
|
158
|
+
if (error.publicCause !== undefined) {
|
|
159
|
+
const cause = isPlainObject(error.publicCause) ? error.publicCause : undefined;
|
|
160
|
+
if (!cause || cause.kind !== "rate_limit_exhausted" || Object.keys(cause).length !== 1) {
|
|
161
|
+
throw new ProjectionGenerationStoreError(`${location}.error.publicCause is not a current closed cause`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
124
165
|
return facts;
|
|
125
166
|
}
|
|
126
167
|
export function parseStoredRow(row) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ProjectionStateError } from "
|
|
2
|
-
import { applySnapshotEffort, parseResolvedAkumaLaunchSnapshot, } from "
|
|
3
|
-
import { listTellIds, readTellOriginal, readTellSubmitted, } from "
|
|
1
|
+
import { ProjectionStateError } from "../../atomic-publish.js";
|
|
2
|
+
import { applySnapshotEffort, parseResolvedAkumaLaunchSnapshot, } from "../../../agents/launch-snapshot/model.js";
|
|
3
|
+
import { listTellIds, readTellOriginal, readTellSubmitted, } from "../projection-core.js";
|
|
4
4
|
export function snapshotPendingTells(projectionDirectory) {
|
|
5
5
|
const pending = ["inbox", "inflight", "submitted"]
|
|
6
6
|
.flatMap((layer) => listTellIds(projectionDirectory, layer)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { initializeConfig } from "
|
|
2
|
-
import { buildCallTerms } from "
|
|
3
|
-
import { parseResolvedAkumaLaunchSnapshot
|
|
4
|
-
import { revive, call, } from "
|
|
5
|
-
import { demoteSubmittedTellsForReplay, readProjectionEvents, } from "
|
|
6
|
-
import { createProjectionExecutionObserver,
|
|
7
|
-
import { readProjectionIdentity } from "
|
|
8
|
-
import { selectValidStoredAgentEvents } from "
|
|
9
|
-
import { persistResponseHistory } from "
|
|
1
|
+
import { initializeConfig } from "../../../config/env.js";
|
|
2
|
+
import { buildCallTerms } from "../../../agents/call-terms.js";
|
|
3
|
+
import { parseResolvedAkumaLaunchSnapshot } from "../../../agents/launch-snapshot/model.js";
|
|
4
|
+
import { revive, call, } from "../../../agents/harness/index.js";
|
|
5
|
+
import { demoteSubmittedTellsForReplay, readProjectionEvents, } from "../projection-core.js";
|
|
6
|
+
import { createProjectionExecutionObserver, } from "../projection-execution-observer.js";
|
|
7
|
+
import { readProjectionIdentity } from "../projection-identity.js";
|
|
8
|
+
import { selectValidStoredAgentEvents } from "../../stored-agent-event.js";
|
|
9
|
+
import { persistResponseHistory } from "../../transcripts.js";
|
|
10
|
+
import { attachProviderLoaderPorts, } from "../../provider-loader-ports.js";
|
|
10
11
|
function isObject(value) {
|
|
11
12
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
12
13
|
}
|
|
@@ -134,50 +135,27 @@ async function completionFacts(projectionDirectory, executionId, inputs, outcome
|
|
|
134
135
|
* Construct the public Projection once and expose a provider-neutral execution
|
|
135
136
|
* handle. Provider adapters and harness public types are unchanged.
|
|
136
137
|
*/
|
|
137
|
-
export function executeProjectionGeneration(projectionDirectory, launch) {
|
|
138
|
+
export function executeProjectionGeneration(projectionDirectory, launch, providerLoaderPorts = {}) {
|
|
138
139
|
const inputs = parseLaunchInputs(launch);
|
|
139
140
|
initializeConfig(process.env, inputs.cwd);
|
|
140
141
|
const executionId = launch.executionId;
|
|
141
|
-
const tellFence = launch.facts.tellFence ?? [];
|
|
142
142
|
demoteSubmittedTellsForReplay(projectionDirectory, executionId);
|
|
143
|
-
const
|
|
143
|
+
const terms = attachProviderLoaderPorts(buildCallTerms(inputs.launchSnapshot, inputs.prompt, inputs.cwd, {
|
|
144
144
|
idleTimeoutMs: inputs.idleTimeoutMs,
|
|
145
145
|
initialTurn: maximumValidEnvelopeTurn(projectionDirectory),
|
|
146
|
-
});
|
|
147
|
-
const launchSnapshot = baseTerms.provider === "codex-sdk"
|
|
148
|
-
? snapshotReplayPrompt(projectionDirectory, baseTerms.prompt, tellFence, executionId, {
|
|
149
|
-
sessionContinuationPromptPrefix: inputs.session && inputs.resumePath
|
|
150
|
-
? baseTerms.sessionContinuationPromptPrefix
|
|
151
|
-
: undefined,
|
|
152
|
-
})
|
|
153
|
-
: undefined;
|
|
154
|
-
const terms = launchSnapshot
|
|
155
|
-
? baseTerms.provider === "codex-sdk" && launchSnapshot.effort
|
|
156
|
-
? {
|
|
157
|
-
...baseTerms,
|
|
158
|
-
prompt: launchSnapshot.prompt,
|
|
159
|
-
threadOptions: {
|
|
160
|
-
...baseTerms.threadOptions,
|
|
161
|
-
modelReasoningEffort: launchSnapshot.effort,
|
|
162
|
-
},
|
|
163
|
-
}
|
|
164
|
-
: { ...baseTerms, prompt: launchSnapshot.prompt }
|
|
165
|
-
: baseTerms;
|
|
166
|
-
// A constructed driver is not an SDK run acknowledgement. Tier-2 has no
|
|
167
|
-
// live steer surface, so the first provider event is the earliest harness
|
|
168
|
-
// observable start; a successful no-event completion is the only fallback.
|
|
169
|
-
const replayStartGate = launchSnapshot
|
|
170
|
-
? createReplayRunStartGate(projectionDirectory, executionId, launchSnapshot.tellIds)
|
|
171
|
-
: undefined;
|
|
146
|
+
}), providerLoaderPorts);
|
|
172
147
|
const observerController = createProjectionExecutionObserver({
|
|
173
148
|
projectionDirectory,
|
|
174
149
|
executionId,
|
|
175
|
-
...(replayStartGate ? { replayStartGate } : {}),
|
|
176
150
|
});
|
|
177
151
|
let projection;
|
|
178
152
|
try {
|
|
179
|
-
projection = inputs.session
|
|
180
|
-
? revive({
|
|
153
|
+
projection = inputs.session
|
|
154
|
+
? revive({
|
|
155
|
+
...terms,
|
|
156
|
+
session: inputs.session,
|
|
157
|
+
resumePath: inputs.resumePath ?? projectionDirectory,
|
|
158
|
+
}, { observer: observerController.observer })
|
|
181
159
|
: call(terms, { observer: observerController.observer });
|
|
182
160
|
}
|
|
183
161
|
catch (error) {
|
|
@@ -186,14 +164,6 @@ export function executeProjectionGeneration(projectionDirectory, launch) {
|
|
|
186
164
|
}
|
|
187
165
|
const outcome = projection.outcome.then(async (result) => {
|
|
188
166
|
try {
|
|
189
|
-
if (result.status === "completed") {
|
|
190
|
-
// A provider may complete successfully without emitting any observable
|
|
191
|
-
// events. Its successful completion is still a real run start.
|
|
192
|
-
replayStartGate?.observeSuccessfulCompletion();
|
|
193
|
-
if (launchSnapshot) {
|
|
194
|
-
markReplayCompleted(projectionDirectory, executionId);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
167
|
return {
|
|
198
168
|
verdict: result.status === "completed"
|
|
199
169
|
? "completed"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { ProjectionStateError } from "
|
|
4
|
-
import { createUlid } from "
|
|
3
|
+
import { ProjectionStateError } from "../../atomic-publish.js";
|
|
4
|
+
import { createUlid } from "../../ids.js";
|
|
5
5
|
const EXECUTION_ID_PATTERN = /^[0-9A-HJKMNP-TV-Z]{26}$/;
|
|
6
6
|
export function createProjectionExecutionId(nowMs = Date.now()) {
|
|
7
7
|
return createUlid(nowMs, [...randomBytes(10)]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { setTimeout as delay } from "node:timers/promises";
|
|
2
|
-
import { openProjectionGenerationStore } from "./
|
|
2
|
+
import { openProjectionGenerationStore } from "./store.js";
|
|
3
3
|
import { spawnProjectionGenerationRunner, } from "./projection-generation-process.js";
|
|
4
4
|
export const PROJECTION_ADOPTION_TIMEOUT_MS = 4_000;
|
|
5
5
|
export const PROJECTION_ADOPTION_POLL_MS = 20;
|
|
@@ -30,7 +30,7 @@ export async function startProjectionGeneration(projectionDirectory, executionId
|
|
|
30
30
|
catch (error) {
|
|
31
31
|
const detail = `runner spawn failed: ${errorDetail(error)}`;
|
|
32
32
|
recordLaunchFailure(projectionDirectory, executionId, detail, "spawn");
|
|
33
|
-
return { status: "failed", detail };
|
|
33
|
+
return { status: "failed", cause: "spawn", detail };
|
|
34
34
|
}
|
|
35
35
|
const deadline = now() + PROJECTION_ADOPTION_TIMEOUT_MS;
|
|
36
36
|
for (;;) {
|
|
@@ -41,6 +41,7 @@ export async function startProjectionGeneration(projectionDirectory, executionId
|
|
|
41
41
|
if (current?.launch.executionId !== executionId) {
|
|
42
42
|
return {
|
|
43
43
|
status: "failed",
|
|
44
|
+
cause: "adoption",
|
|
44
45
|
detail: "launch stopped being current before adoption",
|
|
45
46
|
};
|
|
46
47
|
}
|
|
@@ -49,6 +50,7 @@ export async function startProjectionGeneration(projectionDirectory, executionId
|
|
|
49
50
|
if (current.verdict) {
|
|
50
51
|
return {
|
|
51
52
|
status: "failed",
|
|
53
|
+
cause: "adoption",
|
|
52
54
|
detail: typeof current.verdict.facts.detail === "string"
|
|
53
55
|
? current.verdict.facts.detail
|
|
54
56
|
: `launch ended as ${String(current.verdict.facts.state)}`,
|
|
@@ -86,5 +88,5 @@ export async function startProjectionGeneration(projectionDirectory, executionId
|
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
child.kill("SIGTERM");
|
|
89
|
-
return { status: "failed", detail };
|
|
91
|
+
return { status: "failed", cause: "adoption", detail };
|
|
90
92
|
}
|
|
@@ -4,7 +4,8 @@ import { spawn as nodeSpawn } from "node:child_process";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { executionStdioLogPath } from "./projection-generation-identity.js";
|
|
6
6
|
const MODULE_FILE = fileURLToPath(import.meta.url);
|
|
7
|
-
|
|
7
|
+
// Lives at src/core/projection/generation/ — four levels up is the package root.
|
|
8
|
+
const PACKAGE_ROOT = path.resolve(path.dirname(MODULE_FILE), "..", "..", "..", "..");
|
|
8
9
|
const RUNNER_ENTRY = MODULE_FILE.endsWith(".ts")
|
|
9
10
|
? [process.execPath, "--import", "tsx", path.join(PACKAGE_ROOT, "src", "index.ts")]
|
|
10
11
|
: [process.execPath, path.join(PACKAGE_ROOT, "build", "index.js")];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { openProjectionGenerationStore, } from "./
|
|
2
|
-
import { acquireProjectionRunnerLock, observeProjectionRunnerLock, } from "
|
|
1
|
+
import { openProjectionGenerationStore, } from "./store.js";
|
|
2
|
+
import { acquireProjectionRunnerLock, observeProjectionRunnerLock, } from "../projection-runner-lock.js";
|
|
3
3
|
import { createProjectionExecutionId } from "./projection-generation-identity.js";
|
|
4
4
|
import { applyContinuationEffort, } from "./projection-generation-continuation.js";
|
|
5
|
-
import { openProjectionTellObserver } from "
|
|
5
|
+
import { openProjectionTellObserver } from "../tell/database.js";
|
|
6
|
+
import { OUTCOME_ERROR_VERSION } from "../../../agents/types.js";
|
|
6
7
|
/** Private runner-side kill grace. Not a setting, env, parameter, or export. */
|
|
7
8
|
const KILL_GRACE_MS = 5000;
|
|
8
9
|
function successorLaunchFacts(launch, completionFacts, effort, now) {
|
|
@@ -228,6 +229,13 @@ export async function runProjectionGeneration(input) {
|
|
|
228
229
|
diagnostic: "escalation-failed",
|
|
229
230
|
detail: errorDetail(error),
|
|
230
231
|
failedAt: new Date(now()).toISOString(),
|
|
232
|
+
error: {
|
|
233
|
+
version: OUTCOME_ERROR_VERSION,
|
|
234
|
+
code: "SUBAGENT_EXEC_ERROR",
|
|
235
|
+
message: errorDetail(error),
|
|
236
|
+
timeoutMs: null,
|
|
237
|
+
exitCode: null,
|
|
238
|
+
},
|
|
231
239
|
},
|
|
232
240
|
});
|
|
233
241
|
// Durably completed after the failed verdict; outer catch must not overwrite.
|
|
@@ -315,6 +323,13 @@ export async function runProjectionGeneration(input) {
|
|
|
315
323
|
facts: {
|
|
316
324
|
failedAt: new Date(now()).toISOString(),
|
|
317
325
|
detail: error instanceof Error ? error.message : String(error),
|
|
326
|
+
error: {
|
|
327
|
+
version: OUTCOME_ERROR_VERSION,
|
|
328
|
+
code: "SUBAGENT_EXEC_ERROR",
|
|
329
|
+
message: error instanceof Error ? error.message : String(error),
|
|
330
|
+
timeoutMs: null,
|
|
331
|
+
exitCode: null,
|
|
332
|
+
},
|
|
318
333
|
},
|
|
319
334
|
});
|
|
320
335
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE, assertDatabaseOpen, closeDatabase,
|
|
1
|
+
import { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE, assertDatabaseOpen, closeDatabase, openMutableDatabase, openReadOnlyDatabase, readValidatedHistory, } from "./database.js";
|
|
2
2
|
import { initializeIdentity as initializeProjectionIdentity, readIdentity as readProjectionIdentity, } from "./identity.js";
|
|
3
3
|
import * as transitions from "./transitions.js";
|
|
4
|
-
export { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE,
|
|
4
|
+
export { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE, };
|
|
5
5
|
export { GENERATION_VERDICT_STATES, ProjectionGenerationStoreError, } from "./model.js";
|
|
6
6
|
export class ProjectionGenerationStore {
|
|
7
7
|
databasePath;
|
|
@@ -131,7 +131,6 @@ export function verdictIfOpen(database, readOnly, input) {
|
|
|
131
131
|
if (input.verdict === "killed") {
|
|
132
132
|
throw new ProjectionGenerationStoreError("verdict 'killed' is reserved to runnerKilledIfRequested and settleKillIfRunnerDead");
|
|
133
133
|
}
|
|
134
|
-
const facts = validateVerdictFacts({ ...(input.facts ?? {}), state: input.verdict }, "verdict facts");
|
|
135
134
|
return writeTransition(database, readOnly, () => {
|
|
136
135
|
const history = readValidatedHistory(database);
|
|
137
136
|
const current = history.current;
|
|
@@ -150,6 +149,7 @@ export function verdictIfOpen(database, readOnly, input) {
|
|
|
150
149
|
if (input.verdict === "launch-failed" && current.adoption) {
|
|
151
150
|
return rejected("already-adopted", current);
|
|
152
151
|
}
|
|
152
|
+
const facts = validateVerdictFacts({ ...(input.facts ?? {}), state: input.verdict }, "verdict facts");
|
|
153
153
|
return committed([appendRecord(database, "verdict", executionId, facts, history.records.length + 1)]);
|
|
154
154
|
});
|
|
155
155
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for the projection package.
|
|
3
|
+
* Only symbols required by current external consumers are re-exported.
|
|
4
|
+
* Package-internal modules must import each other directly, not through this file.
|
|
5
|
+
*/
|
|
6
|
+
export { heartPath } from "./heart.js";
|
|
7
|
+
export { AGENT_ACTIVITY_WINDOW_SIZE, foldAgentActivity, } from "./projection-activity.js";
|
|
8
|
+
export { assertProjectionAlias, isProjectionAlias, moveProjectionAlias, projectionAliasRoot, readProjectionAlias, } from "./projection-alias.js";
|
|
9
|
+
export { resolveProjectionCoordinate } from "./projection-coordinate.js";
|
|
10
|
+
export { appendGenerationEvent, executionEventsPath, isProjectionId, isPublishedProjection, isoFromNowMs, projectionDir, projectionRoot, readProjectionEvents, } from "./projection-core.js";
|
|
11
|
+
export { readProjectionIdentity } from "./projection-identity.js";
|
|
12
|
+
export { killProjectionGeneration } from "./projection-kill.js";
|
|
13
|
+
export { observeProjectionLife } from "./projection-life-observer.js";
|
|
14
|
+
export { mintProjection, mintRepositoryProjection, ProjectionMintCollisionError, } from "./projection-mint.js";
|
|
15
|
+
export { acquireProjectionRunnerLock, initializeProjectionRunnerLockDatabase, isProjectionRunnerLockPlatformSupported, observeProjectionRunnerLock, projectionRunnerLockPath, } from "./projection-runner-lock.js";
|
|
16
|
+
export { hasStrandableProjectionGeneration, prioritizeProjectionStatusRows, readProjectionStatusBoard, } from "./projection-status.js";
|
|
17
|
+
export { projectTerminalFailure, } from "./projection-terminal-failure.js";
|
|
18
|
+
export { snapshotCommissionProjectionIds, waitForProjection, waitForProjectionSet, } from "./projection-wait.js";
|
|
19
|
+
export { assertTellEffortSupported, tellProjection, } from "./projection-wake.js";
|
|
20
|
+
export { openProjectionGenerationStore, openProjectionGenerationStoreReadOnly, ProjectionGenerationStore, } from "./generation/store.js";
|
|
21
|
+
export { createProjectionExecutionId } from "./generation/projection-generation-identity.js";
|
|
22
|
+
export { PROJECTION_ADOPTION_TIMEOUT_MS, startProjectionGeneration, } from "./generation/projection-generation-launcher.js";
|
|
23
|
+
export { projectionGenerationRunnerArgv, spawnProjectionGenerationRunner, } from "./generation/projection-generation-process.js";
|
|
24
|
+
export { runProjectionGeneration, } from "./generation/projection-generation-runner.js";
|
|
25
|
+
export { executeProjectionGeneration } from "./generation/projection-generation-execution.js";
|
|
26
|
+
export { runProjectionGenerationRuntime } from "./generation/projection-generation-runtime.js";
|
|
27
|
+
export { claimFencedTells, claimTellToInflight, demoteSubmittedTellsForReplay, listTellIds, markTellConsumed, markTellSubmitted, readProjectionTellCounts, readTellOriginal, readTellSubmitted, writeInboxTell, } from "./tell/store.js";
|
|
@@ -9,6 +9,9 @@ function duration(first, last) {
|
|
|
9
9
|
return Math.max(0, last - first);
|
|
10
10
|
}
|
|
11
11
|
function warningIdentity(warning) {
|
|
12
|
+
if (warning.reason === "rate-limit") {
|
|
13
|
+
return JSON.stringify(warning);
|
|
14
|
+
}
|
|
12
15
|
if (warning.reason === "retry") {
|
|
13
16
|
return JSON.stringify({
|
|
14
17
|
reason: warning.reason,
|
|
@@ -238,3 +241,12 @@ export function foldAgentActivity(events) {
|
|
|
238
241
|
...(failure ? { failure } : {}),
|
|
239
242
|
};
|
|
240
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Public wait/status activity deliberately excludes provider-origin terminal
|
|
246
|
+
* prose. Diagnostic and fail-event text remains available to artifact/internal
|
|
247
|
+
* consumers through the full fold, but has no JSON or human projection path.
|
|
248
|
+
*/
|
|
249
|
+
export function foldPublicProjectionActivity(events) {
|
|
250
|
+
const { diagnostic: _diagnostic, failure: _failure, ...activity } = foldAgentActivity(events);
|
|
251
|
+
return activity;
|
|
252
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { isErrnoException } from "
|
|
4
|
-
import {
|
|
3
|
+
import { isErrnoException } from "../../errno.js";
|
|
4
|
+
import { syncDirectorySync } from "../../fs/durability.js";
|
|
5
|
+
import { ProjectionStateError, randomHex8 } from "../atomic-publish.js";
|
|
5
6
|
import { projectionCoordinateRoot } from "./projection-coordinate.js";
|
|
6
7
|
import { isProjectionId } from "./projection-core.js";
|
|
7
8
|
export const PROJECTION_ALIAS_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
@@ -15,12 +16,12 @@ export function assertProjectionAlias(value) {
|
|
|
15
16
|
}
|
|
16
17
|
return value;
|
|
17
18
|
}
|
|
18
|
-
export function projectionAliasRoot(cwd) {
|
|
19
|
-
return path.join(projectionCoordinateRoot(cwd), ".keiyaku", "projection-alias");
|
|
19
|
+
export async function projectionAliasRoot(cwd) {
|
|
20
|
+
return path.join(await projectionCoordinateRoot(cwd), ".keiyaku", "projection-alias");
|
|
20
21
|
}
|
|
21
|
-
export function projectionAliasPath(cwd, alias) {
|
|
22
|
+
export async function projectionAliasPath(cwd, alias) {
|
|
22
23
|
assertProjectionAlias(alias);
|
|
23
|
-
return path.join(projectionAliasRoot(cwd), alias);
|
|
24
|
+
return path.join(await projectionAliasRoot(cwd), alias);
|
|
24
25
|
}
|
|
25
26
|
function invalidAliasRef(filePath) {
|
|
26
27
|
return new ProjectionStateError(`invalid projection alias ref: ${filePath}`);
|
|
@@ -61,8 +62,8 @@ function readBoundedRegularAliasRef(filePath) {
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
/** Undefined means no ref; malformed refs fail closed with their exact sidecar path. */
|
|
64
|
-
export function readProjectionAlias(cwd, alias) {
|
|
65
|
-
const filePath = projectionAliasPath(cwd, alias);
|
|
65
|
+
export async function readProjectionAlias(cwd, alias) {
|
|
66
|
+
const filePath = await projectionAliasPath(cwd, alias);
|
|
66
67
|
const content = readBoundedRegularAliasRef(filePath);
|
|
67
68
|
if (content === undefined)
|
|
68
69
|
return undefined;
|
|
@@ -74,14 +75,14 @@ export function readProjectionAlias(cwd, alias) {
|
|
|
74
75
|
return id;
|
|
75
76
|
}
|
|
76
77
|
/** Atomically replace one alias ref. Aliases intentionally have no multi-ref transaction. */
|
|
77
|
-
export function moveProjectionAlias(cwd, alias, id) {
|
|
78
|
+
export async function moveProjectionAlias(cwd, alias, id) {
|
|
78
79
|
assertProjectionAlias(alias);
|
|
79
80
|
if (!isProjectionId(id))
|
|
80
81
|
throw new ProjectionStateError(`invalid projection id: ${id}`);
|
|
81
|
-
const previous = readProjectionAlias(cwd, alias);
|
|
82
|
-
const root = projectionAliasRoot(cwd);
|
|
82
|
+
const previous = await readProjectionAlias(cwd, alias);
|
|
83
|
+
const root = await projectionAliasRoot(cwd);
|
|
83
84
|
fs.mkdirSync(root, { recursive: true });
|
|
84
|
-
const target = projectionAliasPath(cwd, alias);
|
|
85
|
+
const target = await projectionAliasPath(cwd, alias);
|
|
85
86
|
let temp;
|
|
86
87
|
try {
|
|
87
88
|
for (let attempt = 0; attempt < 16; attempt += 1) {
|
|
@@ -107,13 +108,7 @@ export function moveProjectionAlias(cwd, alias, id) {
|
|
|
107
108
|
if (!temp)
|
|
108
109
|
throw new ProjectionStateError(`failed to create projection alias temp: ${target}`);
|
|
109
110
|
fs.renameSync(temp, target);
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
fs.fsyncSync(directoryFd);
|
|
113
|
-
}
|
|
114
|
-
finally {
|
|
115
|
-
fs.closeSync(directoryFd);
|
|
116
|
-
}
|
|
111
|
+
syncDirectorySync(root);
|
|
117
112
|
}
|
|
118
113
|
finally {
|
|
119
114
|
if (temp)
|