@astrosheep/keiyaku 2.8.5 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -15
- package/build/.tsbuildinfo +1 -1
- package/build/agents/{call-terms_v2.js → call-terms.js} +12 -8
- package/build/agents/harness/control-types.js +1 -0
- package/build/agents/harness/execution-handle.js +23 -3
- package/build/agents/harness/index.js +6 -607
- package/build/agents/harness/outcome.js +141 -0
- package/build/agents/harness/projection.js +310 -0
- package/build/agents/harness/router.js +201 -0
- package/build/agents/harness/runtime.js +2 -1
- package/build/agents/{launch-snapshot_v2.js → launch-snapshot/model.js} +69 -74
- package/build/agents/launch-snapshot/resolve.js +72 -0
- package/build/agents/opencode-sdk.js +24 -3
- package/build/agents/providers/{claude-agent-sdk.js → claude-agent-sdk/adapter.js} +46 -368
- package/build/agents/providers/claude-agent-sdk/events.js +218 -0
- package/build/agents/providers/claude-agent-sdk/session.js +158 -0
- package/build/agents/providers/codex-app-server/adapter.js +347 -0
- package/build/agents/providers/codex-app-server/events.js +352 -0
- package/build/agents/providers/codex-app-server/session.js +266 -0
- package/build/agents/providers/codex-sdk.js +23 -5
- package/build/agents/providers/opencode-sdk/adapter.js +344 -0
- package/build/agents/providers/opencode-sdk/events.js +354 -0
- package/build/agents/providers/opencode-sdk/session.js +180 -0
- package/build/agents/providers/pi/adapter.js +269 -0
- package/build/agents/providers/pi/checkpoint.js +41 -0
- package/build/agents/providers/pi/events.js +282 -0
- package/build/agents/{selector_v2.js → selector.js} +8 -6
- package/build/cli/commands/akuma/akuma/handler.js +4 -0
- package/build/cli/commands/akuma/akuma/meta.js +16 -0
- package/build/cli/commands/akuma/catalog.js +8 -0
- package/build/cli/commands/akuma/list/handler.js +15 -0
- package/build/cli/commands/akuma/list/meta-ls.js +9 -0
- package/build/cli/commands/akuma/view/handler.js +34 -0
- package/build/cli/commands/akuma/view/meta.js +8 -0
- package/build/cli/commands/akuma.js +1 -1
- package/build/cli/commands/contract/amend/handler.js +10 -0
- package/build/cli/commands/contract/amend/meta.js +12 -0
- package/build/cli/commands/contract/arc/handler.js +9 -0
- package/build/cli/commands/contract/arc/meta.js +26 -0
- package/build/cli/commands/contract/bind/handler.js +23 -0
- package/build/cli/commands/contract/bind/meta.js +30 -0
- package/build/cli/commands/contract/catalog.js +16 -0
- package/build/cli/commands/contract/forfeit/handler.js +13 -0
- package/build/cli/commands/contract/forfeit/meta.js +12 -0
- package/build/cli/commands/contract/log/handler.js +12 -0
- package/build/cli/commands/contract/log/meta.js +12 -0
- package/build/cli/commands/contract/petition/handler.js +26 -0
- package/build/cli/commands/contract/petition/meta.js +23 -0
- package/build/cli/commands/contract/renew/handler.js +10 -0
- package/build/cli/commands/contract/renew/meta.js +17 -0
- package/build/cli/commands/projection/call/handler.js +42 -0
- package/build/cli/commands/projection/call/meta.js +9 -0
- package/build/cli/commands/projection/catalog.js +14 -0
- package/build/cli/commands/projection/kill/handler.js +37 -0
- package/build/cli/commands/projection/kill/meta.js +11 -0
- package/build/cli/commands/projection/revive/handler.js +56 -0
- package/build/cli/commands/projection/revive/meta.js +9 -0
- package/build/cli/commands/projection/status/handler.js +25 -0
- package/build/cli/commands/projection/status/meta.js +9 -0
- package/build/cli/commands/projection/tell/handler.js +36 -0
- package/build/cli/commands/projection/tell/meta.js +9 -0
- package/build/cli/commands/projection/wait/handler.js +23 -0
- package/build/cli/commands/projection/wait/meta.js +11 -0
- package/build/cli/commands/registry.js +100 -0
- package/build/cli/commands/shared.js +71 -0
- package/build/cli/commands/skills/catalog.js +6 -0
- package/build/cli/commands/skills/install/handler.js +10 -0
- package/build/cli/commands/skills/install/meta.js +9 -0
- package/build/cli/commands/skills/skills/handler.js +4 -0
- package/build/cli/commands/skills/skills/meta.js +10 -0
- package/build/cli/commands/system/catalog.js +8 -0
- package/build/cli/commands/system/completion/handler.js +10 -0
- package/build/cli/commands/system/completion/meta.js +9 -0
- package/build/cli/commands/system/dump-env/handler.js +3 -0
- package/build/cli/commands/system/dump-env/meta.js +10 -0
- package/build/cli/commands/system/guide/handler.js +4 -0
- package/build/cli/commands/system/guide/meta.js +9 -0
- package/build/cli/commands/task/add/handler.js +21 -0
- package/build/cli/commands/task/add/meta.js +8 -0
- package/build/cli/commands/task/catalog.js +22 -0
- package/build/cli/commands/task/doctor/handler.js +4 -0
- package/build/cli/commands/task/doctor/meta.js +8 -0
- package/build/cli/commands/task/done/handler.js +17 -0
- package/build/cli/commands/task/done/meta.js +8 -0
- package/build/cli/commands/task/drop/handler.js +6 -0
- package/build/cli/commands/task/drop/meta.js +8 -0
- package/build/cli/commands/task/ls/handler.js +13 -0
- package/build/cli/commands/task/ls/meta.js +8 -0
- package/build/cli/commands/task/shared.js +131 -0
- package/build/cli/commands/task/start/handler.js +6 -0
- package/build/cli/commands/task/start/meta.js +8 -0
- package/build/cli/commands/task/stop/handler.js +17 -0
- package/build/cli/commands/task/stop/meta.js +8 -0
- package/build/cli/commands/task/task/handler.js +5 -0
- package/build/cli/commands/task/task/meta.js +11 -0
- package/build/cli/commands/task/update/handler.js +18 -0
- package/build/cli/commands/task/update/meta.js +8 -0
- package/build/cli/commands/task/view/handler.js +14 -0
- package/build/cli/commands/task/view/meta.js +8 -0
- package/build/cli/completion.js +26 -27
- package/build/cli/flags.js +79 -2
- package/build/cli/help.js +27 -49
- package/build/cli/index.js +121 -374
- package/build/cli/output-stream-error-policy.js +17 -0
- package/build/cli/parse-flags.js +197 -0
- package/build/cli/parse-metadata.js +129 -0
- package/build/cli/parse-selectors.js +65 -0
- package/build/cli/parse.js +46 -313
- package/build/cli/projection-address.js +5 -0
- package/build/cli/render/arc.js +1 -1
- package/build/cli/render/errors.js +4 -3
- package/build/cli/render/format.js +14 -0
- package/build/cli/render/kanshi.js +106 -0
- package/build/cli/render/petition.js +24 -1
- package/build/cli/render/projection-activity.js +5 -1
- package/build/cli/render/shared.js +2 -2
- package/build/cli/render/status.js +79 -13
- package/build/cli/render/task.js +113 -0
- package/build/cli/render/wait.js +23 -3
- package/build/cli/types.js +1 -1
- package/build/config/{akuma-loader_v2.js → akuma-loader.js} +7 -4
- package/build/config/env.js +9 -4
- package/build/config/settings/disease.js +26 -0
- package/build/config/settings/knobs.js +8 -0
- package/build/config/settings/loader.js +244 -0
- package/build/config/settings/schema.js +276 -0
- package/build/core/addressing.js +1 -1
- package/build/core/amend.js +5 -8
- package/build/core/arc.js +7 -8
- package/build/core/bind-workspace.js +123 -0
- package/build/core/bind.js +75 -155
- package/build/core/call/call.js +229 -0
- package/build/core/call/context.js +251 -0
- package/build/core/call/execution.js +217 -0
- package/build/core/call/prompt.js +42 -0
- package/build/core/call/reference.js +24 -0
- package/build/core/call-persist.js +10 -3
- package/build/core/claim-delivery.js +247 -0
- package/build/core/claim.js +39 -277
- package/build/core/context.js +2 -1
- package/build/core/{render.js → contract-view.js} +12 -140
- package/build/core/draft.js +107 -9
- package/build/core/entry.js +9 -1
- package/build/core/execution-coordinate.js +4 -20
- package/build/core/execution-pact.js +16 -31
- package/build/core/forfeit.js +35 -22
- package/build/core/hints.js +2 -2
- package/build/core/log.js +2 -2
- package/build/core/path-coordinate.js +27 -0
- package/build/core/petition-claim-gates.js +8 -6
- package/build/core/petition-preview.js +97 -0
- package/build/core/petition-run.js +5 -7
- package/build/core/petition.js +39 -26
- package/build/core/projection/generation/database.js +306 -0
- package/build/core/projection/generation/identity.js +84 -0
- package/build/core/projection/generation/model.js +201 -0
- package/build/core/projection/generation/store.js +73 -0
- package/build/core/projection/generation/transitions.js +258 -0
- package/build/core/projection/heart.js +0 -307
- package/build/core/projection/tell/database.js +109 -0
- package/build/core/projection/tell/model.js +97 -0
- package/build/core/{projection-tells.js → projection/tell/store.js} +3 -158
- package/build/core/projection-activity.js +23 -2
- package/build/core/projection-coordinate.js +14 -2
- package/build/core/projection-core.js +2 -1
- package/build/core/projection-execution-observer.js +259 -0
- package/build/core/projection-generation-continuation.js +1 -1
- package/build/core/projection-generation-execution.js +90 -20
- package/build/core/projection-generation-launcher.js +1 -1
- package/build/core/projection-generation-runner.js +198 -4
- package/build/core/projection-identity.js +1 -1
- package/build/core/projection-kill.js +50 -17
- package/build/core/projection-life-observer.js +1 -1
- package/build/core/projection-life-protocol.js +10 -0
- package/build/core/projection-mint.js +1 -1
- package/build/core/projection-status.js +45 -32
- package/build/core/projection-wait.js +12 -2
- package/build/core/projection-wake.js +5 -2
- package/build/core/{queue_v2.js → queue.js} +2 -1
- package/build/core/registry.js +1 -1
- package/build/core/renew.js +9 -11
- package/build/core/response-artifact-catalog-sqlite.js +112 -0
- package/build/core/response-artifact-catalog.js +7 -0
- package/build/core/seal.js +44 -16
- package/build/core/status/board.js +289 -0
- package/build/core/status/drift.js +99 -0
- package/build/core/status/lifecycle.js +84 -0
- package/build/core/status/reconciliation.js +131 -0
- package/build/core/stored-agent-event.js +28 -4
- package/build/core/target-ref.js +10 -0
- package/build/core/task/board.js +175 -0
- package/build/core/task/commands.js +211 -0
- package/build/core/task/document.js +189 -0
- package/build/core/task/model.js +1 -0
- package/build/core/task/settlement-git.js +207 -0
- package/build/core/task/settlement-policy.js +82 -0
- package/build/core/task/source-board.js +84 -0
- package/build/core/task/source-model.js +1 -0
- package/build/core/task/validation.js +44 -0
- package/build/core/task-contract.js +237 -0
- package/build/core/task-doctor.js +14 -0
- package/build/core/task-git-actor.js +38 -0
- package/build/core/task-git-runtime.js +37 -0
- package/build/core/task-git-store.js +385 -0
- package/build/core/task-repository.js +1 -0
- package/build/core/task-store-repository.js +86 -0
- package/build/core/task-store.js +1 -0
- package/build/core/task-worktree.js +51 -0
- package/build/core/task.js +4 -0
- package/build/core/transcripts.js +138 -56
- package/build/core/validation.js +17 -0
- package/build/core/verdict.js +2 -2
- package/build/core/worktree-path.js +33 -8
- package/build/flow-error.js +5 -2
- package/build/generated/version.js +1 -1
- package/build/git/branches.js +33 -9
- package/build/git/commits.js +3 -0
- package/build/git/core.js +9 -0
- package/build/git/diff/parsers.js +0 -94
- package/build/index.js +2 -0
- package/build/keiyaku-constants.js +2 -0
- package/build/keiyaku.js +4 -3
- package/package.json +3 -2
- package/skills/keiyaku/SKILL.md +30 -13
- package/skills/keiyaku-akuma/SKILL.md +30 -57
- package/skills/keiyaku-task/SKILL.md +51 -0
- package/skills/keiyaku-workflow/SKILL.md +71 -0
- package/build/agents/harness/pump.js +0 -158
- package/build/agents/providers/codex-app-server.js +0 -864
- package/build/agents/providers/opencode-sdk.js +0 -363
- package/build/agents/providers/pi.js +0 -557
- package/build/config/settings.js +0 -533
- package/build/core/call.js +0 -686
- package/build/core/projection/generation.js +0 -412
- package/build/core/projection/identity.js +0 -81
- package/build/core/projection/mint.js +0 -174
- package/build/core/projection-generation-store.js +0 -707
- package/build/core/status.js +0 -539
|
@@ -1,15 +1,50 @@
|
|
|
1
|
-
import { formatSettingsDiseases } from "../../config/settings.js";
|
|
2
|
-
import {
|
|
1
|
+
import { formatSettingsDiseases } from "../../config/settings/disease.js";
|
|
2
|
+
import { shortCommitHash } from "../../git/commits.js";
|
|
3
|
+
import { formatAgeMs } from "./format.js";
|
|
4
|
+
import { renderKanshiBoard } from "./kanshi.js";
|
|
3
5
|
import { renderProjectionActivitySummary, } from "./projection-activity.js";
|
|
4
6
|
export const STATUS_DISEASES_SECTION_TITLE = "Diseases";
|
|
5
7
|
export const STATUS_PROJECTION_SECTION_TITLE = "akuma";
|
|
6
8
|
export const STATUS_CLAIM_RECEIPTS_SECTION_TITLE = "claim receipts";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
function projectionGlyph(state) {
|
|
10
|
+
switch (state) {
|
|
11
|
+
case "out":
|
|
12
|
+
return "●";
|
|
13
|
+
case "lost":
|
|
14
|
+
return "○";
|
|
15
|
+
case "done":
|
|
16
|
+
return "◎";
|
|
17
|
+
case "dismissed":
|
|
18
|
+
return "×";
|
|
19
|
+
case "dead":
|
|
20
|
+
return "✕";
|
|
21
|
+
case "minting":
|
|
22
|
+
return "…";
|
|
23
|
+
case "startup-timeout":
|
|
24
|
+
return "!";
|
|
25
|
+
case "unknown":
|
|
26
|
+
return "?";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function renderSettingsDiseasesSection(diseases, taskDiseases = []) {
|
|
30
|
+
if (diseases.length === 0 && taskDiseases.length === 0)
|
|
9
31
|
return "";
|
|
10
32
|
const lines = formatSettingsDiseases(diseases).map((line) => `- ${line}`);
|
|
33
|
+
lines.push(...taskDiseases.map((line) => `- ${line}`));
|
|
11
34
|
return `${STATUS_DISEASES_SECTION_TITLE}\n${lines.join("\n")}\n`;
|
|
12
35
|
}
|
|
36
|
+
function renderTaskStatusSection(tasks) {
|
|
37
|
+
if (!tasks || tasks.inProgress + tasks.ready + tasks.blocked === 0)
|
|
38
|
+
return "";
|
|
39
|
+
const segments = [
|
|
40
|
+
tasks.inProgress > 0 ? `${tasks.inProgress} in_progress` : undefined,
|
|
41
|
+
tasks.ready > 0 ? `${tasks.ready} ready` : undefined,
|
|
42
|
+
tasks.blocked > 0 ? `${tasks.blocked} blocked` : undefined,
|
|
43
|
+
].filter((segment) => segment !== undefined);
|
|
44
|
+
const lines = [`tasks · ${segments.join(" / ")}`];
|
|
45
|
+
lines.push(...tasks.topTasks.map((task) => ` ${task.id.slice(0, 9)} · P${task.pri} · ${task.state === "in_progress" ? "in_progress" : "ready"} · ${task.title}`));
|
|
46
|
+
return `${lines.join("\n")}\n`;
|
|
47
|
+
}
|
|
13
48
|
function renderProjectionDiagnostics(row) {
|
|
14
49
|
if (row.diagnostics.length === 0)
|
|
15
50
|
return "";
|
|
@@ -18,7 +53,7 @@ function renderProjectionDiagnostics(row) {
|
|
|
18
53
|
function renderProjectionOmission(board) {
|
|
19
54
|
if (!board.omitted)
|
|
20
55
|
return undefined;
|
|
21
|
-
const counts = ["failed", "dead", "done", "dismissed"]
|
|
56
|
+
const counts = ["failed", "dead", "done", "killed", "dismissed"]
|
|
22
57
|
.flatMap((state) => {
|
|
23
58
|
const count = board.omitted?.byState[state] ?? 0;
|
|
24
59
|
return count > 0 ? [`${count} ${state}`] : [];
|
|
@@ -28,6 +63,8 @@ function renderProjectionOmission(board) {
|
|
|
28
63
|
function renderProjectionAge(row) {
|
|
29
64
|
if (row.state === "done")
|
|
30
65
|
return "done";
|
|
66
|
+
if (row.state === "killed")
|
|
67
|
+
return "killed";
|
|
31
68
|
if (row.state === "dismissed")
|
|
32
69
|
return "dismissed";
|
|
33
70
|
if (row.state === "failed")
|
|
@@ -50,6 +87,7 @@ function projectionActivityState(row) {
|
|
|
50
87
|
case "failed":
|
|
51
88
|
case "dead": return "dead";
|
|
52
89
|
case "lost": return "lost";
|
|
90
|
+
case "killed":
|
|
53
91
|
case "dismissed": return "dismissed";
|
|
54
92
|
case "minting":
|
|
55
93
|
case "out": return "running";
|
|
@@ -68,11 +106,13 @@ function renderProjectionActivityLine(row) {
|
|
|
68
106
|
});
|
|
69
107
|
}
|
|
70
108
|
function renderProjectionRow(row) {
|
|
71
|
-
const glyph =
|
|
72
|
-
? "
|
|
73
|
-
: row.state === "
|
|
74
|
-
? "
|
|
75
|
-
: row.state
|
|
109
|
+
const glyph = row.state === "killed"
|
|
110
|
+
? "×"
|
|
111
|
+
: projectionGlyph(row.state === "failed"
|
|
112
|
+
? "lost"
|
|
113
|
+
: row.state === "startup-timeout"
|
|
114
|
+
? "minting"
|
|
115
|
+
: row.state);
|
|
76
116
|
const identity = row.alias ? `${row.id} (${row.alias})` : row.id;
|
|
77
117
|
let heading;
|
|
78
118
|
if (row.state === "startup-timeout" || row.state === "unknown") {
|
|
@@ -90,6 +130,25 @@ function renderProjectionRow(row) {
|
|
|
90
130
|
const activity = renderProjectionActivityLine(row);
|
|
91
131
|
return activity ? [heading, activity] : [heading];
|
|
92
132
|
}
|
|
133
|
+
function isTerminalProjectionStatus(row) {
|
|
134
|
+
return row.state === "done"
|
|
135
|
+
|| row.state === "killed"
|
|
136
|
+
|| row.state === "dismissed"
|
|
137
|
+
|| row.state === "failed"
|
|
138
|
+
|| row.state === "dead";
|
|
139
|
+
}
|
|
140
|
+
export function renderProjectionFilteredStatus(board, projectionId) {
|
|
141
|
+
const head = board.defaultHead ? shortCommitHash(board.defaultHead) : "(no HEAD)";
|
|
142
|
+
const heading = `現世 ${head} · projection ${projectionId}`;
|
|
143
|
+
const row = board.projections?.rows.find((candidate) => candidate.id === projectionId);
|
|
144
|
+
if (!row)
|
|
145
|
+
return `${heading}\nno projections on projection ${projectionId}\n`;
|
|
146
|
+
const lines = [heading, "", ...renderProjectionRow(row), ""];
|
|
147
|
+
if (!isTerminalProjectionStatus(row))
|
|
148
|
+
lines.push(`» keiyaku tell ${projectionId} "..."`);
|
|
149
|
+
lines.push(`» keiyaku wait ${projectionId}`);
|
|
150
|
+
return `${lines.join("\n")}\n`;
|
|
151
|
+
}
|
|
93
152
|
export function renderProjectionStatusSection(board) {
|
|
94
153
|
if (!board || board.rows.length === 0)
|
|
95
154
|
return "";
|
|
@@ -116,17 +175,24 @@ export function renderStatusBoard(board) {
|
|
|
116
175
|
const boardText = renderKanshiBoard(board);
|
|
117
176
|
const projectionText = renderProjectionStatusSection(board.projections);
|
|
118
177
|
const receiptsText = renderClaimReconciliationSection(board.claimReconciliation);
|
|
119
|
-
const
|
|
120
|
-
|
|
178
|
+
const taskText = renderTaskStatusSection(board.tasks);
|
|
179
|
+
const taskDiseaseText = [
|
|
180
|
+
...(board.tasks?.diseases ?? []).map((disease) => disease.message),
|
|
181
|
+
...(board.tasks?.diagnostic ? [board.tasks.diagnostic] : []),
|
|
182
|
+
];
|
|
183
|
+
const diseasesText = renderSettingsDiseasesSection(board.diseases, taskDiseaseText);
|
|
184
|
+
if (!projectionText && !receiptsText && !taskText && diseasesText === "")
|
|
121
185
|
return boardText;
|
|
122
186
|
const sections = [boardText.trimEnd()];
|
|
123
|
-
if (board.targetFilter !== null) {
|
|
187
|
+
if (board.targetFilter !== null && (projectionText || receiptsText || diseasesText)) {
|
|
124
188
|
sections.push("repository-wide — not filtered by target");
|
|
125
189
|
}
|
|
126
190
|
if (projectionText)
|
|
127
191
|
sections.push(projectionText.trimEnd());
|
|
128
192
|
if (receiptsText)
|
|
129
193
|
sections.push(receiptsText.trimEnd());
|
|
194
|
+
if (taskText)
|
|
195
|
+
sections.push(taskText.trimEnd());
|
|
130
196
|
if (diseasesText)
|
|
131
197
|
sections.push(diseasesText.trimEnd());
|
|
132
198
|
return `${sections.join("\n\n")}\n`;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export function shortTaskId(id) {
|
|
2
|
+
return id.slice(0, 9);
|
|
3
|
+
}
|
|
4
|
+
export function shortContractId(contractId) {
|
|
5
|
+
const separator = contractId.indexOf(".");
|
|
6
|
+
return separator > 0 ? contractId.slice(0, separator) : contractId;
|
|
7
|
+
}
|
|
8
|
+
export function deriveTaskDisplay(task) {
|
|
9
|
+
if (task.state === "done")
|
|
10
|
+
return "done";
|
|
11
|
+
if (task.state === "drop")
|
|
12
|
+
return "dropped";
|
|
13
|
+
if (task.contractId !== undefined)
|
|
14
|
+
return `bound(${shortContractId(task.contractId)})`;
|
|
15
|
+
if (task.state === "in_progress")
|
|
16
|
+
return "in_progress";
|
|
17
|
+
return task.blocked ? "blocked" : "ready";
|
|
18
|
+
}
|
|
19
|
+
function renderTaskRowWithId(task, id) {
|
|
20
|
+
return `${id} · P${task.pri} · ${deriveTaskDisplay(task)} · ${task.title}`;
|
|
21
|
+
}
|
|
22
|
+
export function renderTaskListRow(task) {
|
|
23
|
+
return renderTaskRowWithId(task, shortTaskId(task.id));
|
|
24
|
+
}
|
|
25
|
+
export function renderTaskMutationRow(task) {
|
|
26
|
+
return renderTaskRowWithId(task, task.id);
|
|
27
|
+
}
|
|
28
|
+
export function renderTaskRow(task, completeId = false) {
|
|
29
|
+
return completeId ? renderTaskMutationRow(task) : renderTaskListRow(task);
|
|
30
|
+
}
|
|
31
|
+
function displayOrder(display) {
|
|
32
|
+
if (display === "in_progress")
|
|
33
|
+
return 0;
|
|
34
|
+
if (display === "ready")
|
|
35
|
+
return 1;
|
|
36
|
+
if (display === "blocked")
|
|
37
|
+
return 2;
|
|
38
|
+
if (display.startsWith("bound("))
|
|
39
|
+
return 3;
|
|
40
|
+
return display === "done" ? 4 : 5;
|
|
41
|
+
}
|
|
42
|
+
function compareText(left, right) {
|
|
43
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
44
|
+
}
|
|
45
|
+
function compareTasks(left, right) {
|
|
46
|
+
const displayDifference = displayOrder(deriveTaskDisplay(left)) - displayOrder(deriveTaskDisplay(right));
|
|
47
|
+
if (displayDifference !== 0)
|
|
48
|
+
return displayDifference;
|
|
49
|
+
if (left.pri !== right.pri)
|
|
50
|
+
return left.pri - right.pri;
|
|
51
|
+
const createdDifference = compareText(left.createdAt, right.createdAt);
|
|
52
|
+
return createdDifference || compareText(left.id, right.id);
|
|
53
|
+
}
|
|
54
|
+
function selected(task, selection) {
|
|
55
|
+
const display = deriveTaskDisplay(task);
|
|
56
|
+
const terminal = display === "done" || display === "dropped";
|
|
57
|
+
if (selection === "done")
|
|
58
|
+
return terminal;
|
|
59
|
+
if (selection === "default")
|
|
60
|
+
return !terminal;
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
export function groupAndSortTasks(tasks, selection = "default") {
|
|
64
|
+
return tasks.filter((task) => selected(task, selection)).sort(compareTasks);
|
|
65
|
+
}
|
|
66
|
+
export function renderTaskList(tasks, options = {}) {
|
|
67
|
+
return groupAndSortTasks(tasks, options.selection).map(renderTaskListRow).join("\n");
|
|
68
|
+
}
|
|
69
|
+
function renderIds(ids) {
|
|
70
|
+
return ids.length === 0 ? "(none)" : ids.map(shortTaskId).join(", ");
|
|
71
|
+
}
|
|
72
|
+
export function renderTaskShow(task) {
|
|
73
|
+
const released = new Set(task.releasedNeeds);
|
|
74
|
+
const needs = task.needs.length === 0
|
|
75
|
+
? "(none)"
|
|
76
|
+
: task.needs
|
|
77
|
+
.map((id) => `${shortTaskId(id)}${released.has(id) ? " (dropped)" : ""}`)
|
|
78
|
+
.join(", ");
|
|
79
|
+
return [
|
|
80
|
+
`${shortTaskId(task.id)} · ${task.title}`,
|
|
81
|
+
`state: ${deriveTaskDisplay(task)}`,
|
|
82
|
+
`priority: ${task.pri}`,
|
|
83
|
+
`needs: ${needs}`,
|
|
84
|
+
`blocks: ${renderIds(task.blocks)}`,
|
|
85
|
+
`parent: ${task.parent === null ? "(none)" : shortTaskId(task.parent)}`,
|
|
86
|
+
`from: ${renderIds(task.from)}`,
|
|
87
|
+
`created: ${task.createdAt} by ${task.creator}`,
|
|
88
|
+
"",
|
|
89
|
+
task.body,
|
|
90
|
+
].join("\n");
|
|
91
|
+
}
|
|
92
|
+
export function taskJson(task) {
|
|
93
|
+
return {
|
|
94
|
+
id: task.id,
|
|
95
|
+
title: task.title,
|
|
96
|
+
state: task.state,
|
|
97
|
+
display: deriveTaskDisplay(task),
|
|
98
|
+
priority: task.pri,
|
|
99
|
+
needs: [...task.needs],
|
|
100
|
+
blocks: [...task.blocks],
|
|
101
|
+
parent: task.parent,
|
|
102
|
+
from: [...task.from],
|
|
103
|
+
contractId: task.contractId ?? null,
|
|
104
|
+
createdAt: task.createdAt,
|
|
105
|
+
creator: task.creator,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
export function renderTaskShowJson(task) {
|
|
109
|
+
return `${JSON.stringify({ ...taskJson(task), body: task.body })}\n`;
|
|
110
|
+
}
|
|
111
|
+
export function renderTaskListJson(tasks, selection = "default") {
|
|
112
|
+
return `${JSON.stringify(groupAndSortTasks(tasks, selection).map(taskJson))}\n`;
|
|
113
|
+
}
|
package/build/cli/render/wait.js
CHANGED
|
@@ -10,6 +10,7 @@ function phaseState(phase) {
|
|
|
10
10
|
case "done": return "returned";
|
|
11
11
|
case "failed": return "dead";
|
|
12
12
|
case "lost": return "lost";
|
|
13
|
+
case "killed":
|
|
13
14
|
case "dismissed": return "dismissed";
|
|
14
15
|
case "startup-timeout": return "stalled";
|
|
15
16
|
case "unknown": return "unknown";
|
|
@@ -35,6 +36,8 @@ function waitStateText(snapshot) {
|
|
|
35
36
|
return `returned · lived ${formatTimelineDuration(snapshot.durationMs)}`;
|
|
36
37
|
case "failed":
|
|
37
38
|
return `dead · lived ${formatTimelineDuration(snapshot.durationMs)}`;
|
|
39
|
+
case "killed":
|
|
40
|
+
return "killed";
|
|
38
41
|
case "dismissed":
|
|
39
42
|
return "dismissed";
|
|
40
43
|
case "lost":
|
|
@@ -68,7 +71,7 @@ function terminalDiagnostic(result) {
|
|
|
68
71
|
}
|
|
69
72
|
function ledgerHint(projectionId, snapshot) {
|
|
70
73
|
const file = snapshot.eventLedgerFile ?? "events.jsonl";
|
|
71
|
-
return
|
|
74
|
+
return `· ledger: .keiyaku/projection/${projectionId}/${file}`;
|
|
72
75
|
}
|
|
73
76
|
function recordReviveLines(artifactId) {
|
|
74
77
|
return [
|
|
@@ -98,6 +101,17 @@ function nextActionLines(projectionId, result, state) {
|
|
|
98
101
|
: ["The akuma dropped dead mid-turn.", "no record survived — there is nothing to revive."];
|
|
99
102
|
}
|
|
100
103
|
if (result.state === "terminal" && result.verdict.state === "failed") {
|
|
104
|
+
if (snapshot.failureCode === "SUBAGENT_PROVIDER_UNAVAILABLE") {
|
|
105
|
+
return snapshot.sourceArtifactId
|
|
106
|
+
? [
|
|
107
|
+
"× provider unavailable — no turn accepted",
|
|
108
|
+
`» nothing was consumed · retry from the same artifact: keiyaku revive ${snapshot.sourceArtifactId}`,
|
|
109
|
+
]
|
|
110
|
+
: [
|
|
111
|
+
"× provider unavailable — no turn accepted",
|
|
112
|
+
"» nothing was consumed · safe to call again",
|
|
113
|
+
];
|
|
114
|
+
}
|
|
101
115
|
return [
|
|
102
116
|
"The akuma failed and stopped.",
|
|
103
117
|
...(snapshot.artifactId ? [`record: ${snapshot.artifactId}`] : []),
|
|
@@ -117,7 +131,7 @@ function nextActionLines(projectionId, result, state) {
|
|
|
117
131
|
];
|
|
118
132
|
}
|
|
119
133
|
if (state === "stalled" || state === "unknown") {
|
|
120
|
-
return [ledgerHint(projectionId, snapshot), "
|
|
134
|
+
return [ledgerHint(projectionId, snapshot), "» keiyaku status"];
|
|
121
135
|
}
|
|
122
136
|
return [];
|
|
123
137
|
}
|
|
@@ -186,6 +200,12 @@ export function buildWaitResponse(projectionId, result, options = {}) {
|
|
|
186
200
|
}
|
|
187
201
|
const snapshot = result.snapshot;
|
|
188
202
|
const maxColumns = options.maxColumns ?? resolveLineColumns();
|
|
203
|
+
if (result.state === "terminal" && result.verdict.state === "killed") {
|
|
204
|
+
return {
|
|
205
|
+
...textResponse(`× killed ${projectionId}`),
|
|
206
|
+
exitCode: 1,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
189
209
|
if (snapshot.phase === "startup-timeout") {
|
|
190
210
|
return startupTimeoutResponse(projectionId, result.pact.akuma);
|
|
191
211
|
}
|
|
@@ -216,7 +236,7 @@ export function buildWaitResponse(projectionId, result, options = {}) {
|
|
|
216
236
|
lines.push(" not a word out of it yet — pulse is steady");
|
|
217
237
|
}
|
|
218
238
|
const nextActions = nextActionLines(options.alias ?? projectionId, result, state);
|
|
219
|
-
if (
|
|
239
|
+
if (nextActions.length > 0)
|
|
220
240
|
lines.push("");
|
|
221
241
|
lines.push(...nextActions);
|
|
222
242
|
const response = textResponse(lines.join("\n"));
|
package/build/cli/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const TASK_SUBCOMMANDS = ["add", "view", "ls", "start", "stop", "done", "drop", "update", "doctor"];
|
|
@@ -2,10 +2,10 @@ import * as fs from "node:fs/promises";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { parseToAST } from "../core/markdown/parser.js";
|
|
5
|
-
import {
|
|
5
|
+
import { observeGitRepository } from "../git/branches.js";
|
|
6
6
|
import { BUILTIN_AGENT_PROFILES } from "../keiyaku.js";
|
|
7
7
|
import { getKeiyakuHome } from "./env.js";
|
|
8
|
-
import { agentNameSchema, providerInstanceNameSchema } from "./settings.js";
|
|
8
|
+
import { agentNameSchema, providerInstanceNameSchema } from "./settings/schema.js";
|
|
9
9
|
const nonblankString = z.string().refine((value) => value.trim().length > 0, { message: "must not be blank" });
|
|
10
10
|
const effortOptionsSchema = z.array(nonblankString).superRefine((values, ctx) => {
|
|
11
11
|
if (new Set(values).size !== values.length) {
|
|
@@ -187,7 +187,7 @@ function foldLayer(selected, shadows, allCandidates, source, layer) {
|
|
|
187
187
|
selected[candidate.name] = candidate;
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
|
-
export async function
|
|
190
|
+
export async function loadAkumaCatalog(cwd) {
|
|
191
191
|
const candidates = [];
|
|
192
192
|
const selected = {};
|
|
193
193
|
const shadows = [];
|
|
@@ -211,7 +211,10 @@ export async function loadAkumaCatalogV2(cwd) {
|
|
|
211
211
|
selected[name] = candidate;
|
|
212
212
|
}
|
|
213
213
|
foldLayer(selected, shadows, candidates, "user", await readLayer(path.join(getKeiyakuHome(), "akuma"), "user"));
|
|
214
|
-
|
|
214
|
+
const repository = await observeGitRepository(cwd);
|
|
215
|
+
if (repository.capability === "unknown")
|
|
216
|
+
throw repository.error;
|
|
217
|
+
if (repository.capability === "available" && repository.coordinate === "repository") {
|
|
215
218
|
foldLayer(selected, shadows, candidates, "project", await readLayer(path.join(cwd, ".keiyaku", "akuma"), "project"));
|
|
216
219
|
}
|
|
217
220
|
return Object.freeze({
|
package/build/config/env.js
CHANGED
|
@@ -4,12 +4,14 @@ import * as path from "node:path";
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { isErrnoException } from "../errno.js";
|
|
6
6
|
import { ENV_KEYS, getEnvDefaultValue } from "./env-keys.js";
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import { configureResponseArtifactCatalog } from "../core/response-artifact-catalog.js";
|
|
8
|
+
import { createSqliteResponseArtifactCatalog } from "../core/response-artifact-catalog-sqlite.js";
|
|
9
|
+
function readEnvHome(env = process.env) {
|
|
10
|
+
const value = env.KEIYAKU_HOME?.trim();
|
|
9
11
|
return value && value.length > 0 ? value : undefined;
|
|
10
12
|
}
|
|
11
|
-
export function getKeiyakuHome() {
|
|
12
|
-
return readEnvHome() ?? path.join(os.homedir(), ".keiyaku");
|
|
13
|
+
export function getKeiyakuHome(env = process.env) {
|
|
14
|
+
return readEnvHome(env) ?? path.join(os.homedir(), ".keiyaku");
|
|
13
15
|
}
|
|
14
16
|
const DOTENV_FILE = ".env";
|
|
15
17
|
function decodeQuotedValue(raw) {
|
|
@@ -260,6 +262,8 @@ export function initializeConfig(env = process.env, cwd = process.cwd()) {
|
|
|
260
262
|
runtimeEnv: snapshotEnv({ ...dotenvEnv, ...env }),
|
|
261
263
|
});
|
|
262
264
|
activeConfig = runtimeConfig;
|
|
265
|
+
const homeEnv = { ...process.env, ...env };
|
|
266
|
+
configureResponseArtifactCatalog(createSqliteResponseArtifactCatalog({ keiyakuHome: getKeiyakuHome(homeEnv) }));
|
|
263
267
|
return runtimeConfig;
|
|
264
268
|
}
|
|
265
269
|
export function getConfig() {
|
|
@@ -270,4 +274,5 @@ export function getConfig() {
|
|
|
270
274
|
}
|
|
271
275
|
export function resetConfigForTests() {
|
|
272
276
|
activeConfig = undefined;
|
|
277
|
+
configureResponseArtifactCatalog(undefined);
|
|
273
278
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FlowError } from "../../flow-error.js";
|
|
2
|
+
import { SETTINGS_FILE } from "../../keiyaku.js";
|
|
3
|
+
export function findSettingsDiseasesForKnob(diseases, knob) {
|
|
4
|
+
return diseases.filter((disease) => disease.knob === knob);
|
|
5
|
+
}
|
|
6
|
+
export function formatSettingsDiseases(diseases) {
|
|
7
|
+
return diseases.map((disease) => {
|
|
8
|
+
const where = disease.knob ? `${disease.source}:${disease.knob}` : `${disease.source}:(root)`;
|
|
9
|
+
return `${where}: ${disease.reason}`;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Reject when a named knob is diseased and was not admitted into knobs.
|
|
14
|
+
* A healthy value from another source still wins; only failed-and-unset knobs reject.
|
|
15
|
+
*/
|
|
16
|
+
export function assertSettingsKnobUsable(loaded, knob) {
|
|
17
|
+
const knobs = loaded.knobs;
|
|
18
|
+
if (knobs !== null && knobs[knob] !== undefined)
|
|
19
|
+
return;
|
|
20
|
+
const hits = findSettingsDiseasesForKnob(loaded.diseases, knob);
|
|
21
|
+
if (hits.length === 0)
|
|
22
|
+
return;
|
|
23
|
+
throw new FlowError("INVALID_SETTINGS", `Invalid settings in ${SETTINGS_FILE} (diseased knob '${knob}').`, {
|
|
24
|
+
hints: formatSettingsDiseases(hits),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const KNOWN_SETTINGS_KNOBS = ["default", "reviewer", "gate", "defaultBranch", "worktreeBootstrap"];
|
|
2
|
+
export const KNOWN_SETTINGS_ROOT_KEYS = [...KNOWN_SETTINGS_KNOBS, "providers"];
|
|
3
|
+
export function resolveDefaultAgentName(settings) {
|
|
4
|
+
return settings?.default ?? "akuma-codex";
|
|
5
|
+
}
|
|
6
|
+
export function resolveReviewerAgentName(settings) {
|
|
7
|
+
return settings?.reviewer ?? resolveDefaultAgentName(settings);
|
|
8
|
+
}
|