@astrosheep/keiyaku 2.9.12 → 2.9.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/README.md +22 -18
- package/build/.tsbuildinfo +1 -1
- package/build/agents/call-terms.js +1 -0
- package/build/agents/providers/claude-agent-sdk/adapter.js +2 -2
- package/build/cli/commands/akuma/akuma/handler.js +2 -1
- package/build/cli/commands/akuma/akuma/meta.js +4 -3
- package/build/cli/commands/akuma/catalog.js +2 -0
- package/build/cli/commands/akuma/list/handler.js +1 -1
- package/build/cli/commands/akuma/list/meta-list.js +12 -0
- package/build/cli/commands/akuma/list/meta-ls.js +2 -2
- package/build/cli/commands/akuma.js +5 -0
- package/build/cli/commands/contract/amend/meta.js +4 -3
- package/build/cli/commands/contract/arc/meta.js +2 -0
- package/build/cli/commands/contract/audit/handler.js +28 -2
- package/build/cli/commands/contract/audit/meta.js +4 -3
- package/build/cli/commands/contract/petition/handler.js +2 -1
- package/build/cli/commands/contract/petition/meta.js +2 -2
- package/build/cli/commands/contract/renew/handler.js +44 -3
- package/build/cli/commands/contract/renew/meta.js +5 -4
- package/build/cli/commands/metadata.js +12 -9
- package/build/cli/commands/projection/call/handler.js +1 -1
- package/build/cli/commands/projection/call/meta.js +1 -1
- package/build/cli/commands/projection/catalog.js +2 -2
- package/build/cli/commands/projection/{revive → fork}/handler.js +10 -5
- package/build/cli/commands/projection/fork/meta.js +12 -0
- package/build/cli/commands/projection/history/handler.js +46 -2
- package/build/cli/commands/projection/history/meta.js +3 -3
- package/build/cli/commands/projection/kill/meta.js +2 -2
- package/build/cli/commands/projection/status/handler.js +29 -13
- package/build/cli/commands/projection/status/meta.js +14 -3
- package/build/cli/commands/projection/tell/handler.js +8 -4
- package/build/cli/commands/projection/tell/meta.js +1 -1
- package/build/cli/commands/projection/wait/handler.js +45 -20
- package/build/cli/commands/projection/wait/meta.js +1 -1
- package/build/cli/commands/shared.js +1 -1
- package/build/cli/commands/system/catalog.js +2 -0
- package/build/cli/commands/task/add/handler.js +28 -12
- package/build/cli/commands/task/add/meta.js +18 -6
- package/build/cli/commands/task/catalog.js +2 -0
- package/build/cli/commands/task/compose/handler.js +2 -2
- package/build/cli/commands/task/compose/meta.js +2 -2
- package/build/cli/commands/task/doctor/handler.js +2 -3
- package/build/cli/commands/task/doctor/meta.js +2 -2
- package/build/cli/commands/task/done/meta.js +2 -2
- package/build/cli/commands/task/drop/handler.js +7 -2
- package/build/cli/commands/task/drop/meta.js +6 -3
- package/build/cli/commands/task/hold/meta.js +2 -2
- package/build/cli/commands/task/log/meta.js +2 -2
- package/build/cli/commands/task/ls/meta.js +2 -2
- package/build/cli/commands/task/note/handler.js +6 -0
- package/build/cli/commands/task/note/meta.js +11 -0
- package/build/cli/commands/task/resume/meta.js +2 -2
- package/build/cli/commands/task/shared.js +29 -15
- package/build/cli/commands/task/show/meta.js +2 -2
- package/build/cli/commands/task/start/meta.js +2 -2
- package/build/cli/commands/task/stop/meta.js +2 -2
- package/build/cli/commands/task/update/meta.js +3 -2
- package/build/cli/commands/verification/handler.js +43 -0
- package/build/cli/commands/verification/meta.js +13 -0
- package/build/cli/completion.js +16 -13
- package/build/cli/flags.js +43 -11
- package/build/cli/help.js +29 -30
- package/build/cli/index.js +6 -5
- package/build/cli/parse-flags.js +39 -0
- package/build/cli/parse-metadata.js +5 -2
- package/build/cli/parse-selectors.js +18 -0
- package/build/cli/parse.js +21 -8
- package/build/cli/render/arc.js +12 -3
- package/build/cli/render/audit.js +2 -2
- package/build/cli/render/call.js +4 -4
- package/build/cli/render/kanshi.js +122 -85
- package/build/cli/render/misc.js +2 -2
- package/build/cli/render/petition.js +16 -1
- package/build/cli/render/projection-history.js +17 -4
- package/build/cli/render/shared.js +5 -5
- package/build/cli/render/status-indicator.js +47 -0
- package/build/cli/render/status.js +106 -76
- package/build/cli/render/success-response.js +20 -5
- package/build/cli/render/task.js +6 -5
- package/build/cli/render/tell.js +10 -4
- package/build/cli/render/tool-command-normalization.js +137 -0
- package/build/cli/render/tool-presentation.js +2 -1
- package/build/cli/render/verification.js +23 -0
- package/build/cli/render/wait.js +101 -33
- package/build/cli/types.js +2 -1
- package/build/config/akuma-loader.js +21 -1
- package/build/config/settings/knobs.js +7 -1
- package/build/config/settings/schema.js +10 -5
- package/build/core/amend.js +102 -17
- package/build/core/arc.js +4 -4
- package/build/core/audit/candidate.js +10 -18
- package/build/core/audit/coordinates.js +12 -17
- package/build/core/audit/evidence.js +6 -4
- package/build/core/audit/facade.js +3 -3
- package/build/core/audit/report.js +1 -1
- package/build/core/bind-reconciliation.js +42 -23
- package/build/core/bind.js +182 -81
- package/build/core/call/call.js +6 -7
- package/build/core/call/context.js +43 -30
- package/build/core/call/execution.js +21 -6
- package/build/core/call/prompt.js +11 -42
- package/build/core/contract-carrier-runtime.js +209 -105
- package/build/core/contract-carrier.js +156 -73
- package/build/core/contract-view.js +42 -5
- package/build/core/contract.js +2 -1
- package/build/core/derived-replay.js +168 -35
- package/build/core/draft.js +9 -5
- package/build/core/forfeit.js +1 -1
- package/build/core/lifecycle-history.js +13 -0
- package/build/core/lifecycle-recovery.js +32 -27
- package/build/core/lifecycle-runner.js +14 -14
- package/build/core/log.js +1 -1
- package/build/core/outcome-base.js +2 -2
- package/build/core/projection/akuma-name.js +43 -0
- package/build/core/projection/generation/database.js +141 -79
- package/build/core/projection/generation/ledger.js +91 -0
- package/build/core/projection/generation/model.js +18 -13
- package/build/core/projection/generation/projection-generation-continuation.js +1 -1
- package/build/core/projection/generation/projection-generation-doorbell.js +88 -0
- package/build/core/projection/generation/projection-generation-execution.js +24 -0
- package/build/core/projection/generation/projection-generation-identity.js +4 -0
- package/build/core/projection/generation/projection-generation-launcher.js +72 -138
- package/build/core/projection/generation/projection-generation-process.js +16 -15
- package/build/core/projection/generation/projection-generation-runner.js +125 -79
- package/build/core/projection/generation/projection-generation-runtime.js +10 -61
- package/build/core/projection/generation/protocol.js +68 -0
- package/build/core/projection/generation/store.js +17 -7
- package/build/core/projection/generation/transitions.js +14 -14
- package/build/core/projection/index.js +5 -5
- package/build/core/projection/projection-core.js +6 -2
- package/build/core/projection/projection-execution-observer.js +1 -1
- package/build/core/projection/projection-history.js +7 -7
- package/build/core/projection/projection-kill.js +15 -6
- package/build/core/projection/projection-life-observer.js +8 -8
- package/build/core/projection/projection-mint.js +6 -8
- package/build/core/projection/projection-status-observation.js +77 -8
- package/build/core/projection/projection-status.js +151 -4
- package/build/core/projection/projection-wait.js +46 -27
- package/build/core/projection/projection-wake.js +27 -89
- package/build/core/projection/tell/launch-store.js +1 -1
- package/build/core/projection/tell/store.js +1 -1
- package/build/core/renew-build.js +204 -74
- package/build/core/renew-plan.js +34 -9
- package/build/core/renew-rewrite.js +56 -15
- package/build/core/renew.js +39 -35
- package/build/core/repository-ledger/accepted-fold-read.js +6 -3
- package/build/core/repository-ledger/codec.js +11 -5
- package/build/core/repository-ledger/current-state-store.js +13 -16
- package/build/core/repository-ledger/fold-repository.js +5 -6
- package/build/core/repository-ledger/identity.js +60 -0
- package/build/core/repository-ledger/inventory.js +3 -3
- package/build/core/repository-ledger/read-model.js +54 -6
- package/build/core/repository-ledger/write-transaction.js +9 -4
- package/build/core/run-control/connection-bound-close.js +41 -0
- package/build/core/run-control/detached-lease-bootstrap.js +208 -0
- package/build/core/run-control/detached-process.js +14 -0
- package/build/core/run-control/index.js +6 -0
- package/build/core/{process-group.js → run-control/process-tree.js} +1 -1
- package/build/core/run-control/runner-lease.js +172 -0
- package/build/core/{sqlite-process-lifetime-lock.js → run-control/sqlite-process-lifetime-lock.js} +4 -24
- package/build/core/seal.js +44 -32
- package/build/core/settlement/claim-delivery.js +22 -9
- package/build/core/settlement/claim.js +8 -6
- package/build/core/settlement/petition-claim-gates.js +9 -8
- package/build/core/settlement/petition-head-guard.js +5 -6
- package/build/core/settlement/petition-preview.js +21 -5
- package/build/core/settlement/petition.js +51 -17
- package/build/core/settlement/settlement.js +20 -15
- package/build/core/settlement/verdict.js +2 -2
- package/build/core/settlement/verification.js +492 -364
- package/build/core/status/board.js +184 -75
- package/build/core/status/drift.js +8 -10
- package/build/core/task/board.js +1 -0
- package/build/core/task/commands.js +25 -0
- package/build/core/task/compose.js +3 -2
- package/build/core/task/document.js +102 -39
- package/build/core/task/index.js +3 -3
- package/build/core/task/settlement-git.js +1 -4
- package/build/core/task/settlement-policy.js +27 -14
- package/build/core/task/source-board.js +1 -0
- package/build/core/task/task-bind-preparation.js +59 -9
- package/build/core/task/task-contract.js +2 -2
- package/build/core/task/task-store-repository.js +1 -0
- package/build/core/task/task.js +2 -2
- package/build/core/transcripts.js +4 -4
- package/build/core/verification-declaration.js +95 -0
- package/build/core/worktree-bootstrap.js +1 -1
- package/build/core/worktree-path.js +7 -11
- package/build/flow-error.js +9 -1
- package/build/generated/version.js +2 -2
- package/build/git/branches.js +41 -70
- package/build/git/commits.js +92 -21
- package/build/git/core.js +9 -161
- package/build/git/diff/preview.js +4 -4
- package/build/git/diff/read.js +4 -4
- package/build/git/diff/structured.js +5 -5
- package/build/git/process.js +229 -0
- package/build/git/refs.js +30 -5
- package/build/git/staging.js +39 -115
- package/build/git/streaming-batch.js +9 -16
- package/build/git/worktree.js +104 -91
- package/build/index.js +7 -0
- package/package.json +1 -1
- package/skills/keiyaku-akuma/SKILL.md +21 -20
- package/skills/keiyaku-task/SKILL.md +38 -4
- package/skills/keiyaku-workflow/SKILL.md +51 -11
- package/build/cli/commands/projection/revive/meta.js +0 -12
- package/build/core/projection/projection-life-protocol.js +0 -115
- package/build/core/projection/projection-runner-lock.js +0 -211
- package/build/core/projection/tell/database.js +0 -127
- package/build/core/settlement/verification-coordination.js +0 -305
- package/build/core/settlement/verification-supervisor.js +0 -275
|
@@ -1,33 +1,13 @@
|
|
|
1
1
|
import { formatSettingsDiseases } from "../../config/settings/disease.js";
|
|
2
2
|
import { shortCommitHash } from "../../git/commits.js";
|
|
3
3
|
import { formatAgeMs } from "./format.js";
|
|
4
|
-
import { renderKanshiBoard } from "./kanshi.js";
|
|
4
|
+
import { renderAkumaRosterBoard, renderKanshiBoard } from "./kanshi.js";
|
|
5
5
|
import { renderProjectionActivitySummary, } from "./projection-activity.js";
|
|
6
|
-
import {
|
|
6
|
+
import { terminalFailureCodeSuffix } from "./terminal-failure.js";
|
|
7
7
|
import { formatTellCommand } from "./shared.js";
|
|
8
|
+
import { projectionStatusIndicator } from "./status-indicator.js";
|
|
8
9
|
export const STATUS_DISEASES_SECTION_TITLE = "Diseases";
|
|
9
10
|
export const STATUS_PROJECTION_SECTION_TITLE = "akuma";
|
|
10
|
-
function projectionGlyph(state) {
|
|
11
|
-
switch (state) {
|
|
12
|
-
case "out":
|
|
13
|
-
return "●";
|
|
14
|
-
case "lost":
|
|
15
|
-
return "○";
|
|
16
|
-
case "done":
|
|
17
|
-
return "◎";
|
|
18
|
-
case "dismissed":
|
|
19
|
-
return "×";
|
|
20
|
-
case "dead":
|
|
21
|
-
return "✕";
|
|
22
|
-
case "minting":
|
|
23
|
-
return "…";
|
|
24
|
-
case "startup-timeout":
|
|
25
|
-
return "!";
|
|
26
|
-
case "unknown":
|
|
27
|
-
case "incompatible":
|
|
28
|
-
return "?";
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
11
|
export function renderSettingsDiseasesSection(diseases, taskDiseases = []) {
|
|
32
12
|
if (diseases.length === 0 && taskDiseases.length === 0)
|
|
33
13
|
return "";
|
|
@@ -72,7 +52,7 @@ function terminalFailureSuffix(row) {
|
|
|
72
52
|
function renderProjectionOmission(board) {
|
|
73
53
|
if (!board.omitted)
|
|
74
54
|
return undefined;
|
|
75
|
-
const counts = ["failed", "dead", "done", "killed", "dismissed"]
|
|
55
|
+
const counts = ["failed", "dead", "done", "killed", "dismissed", "incompatible"]
|
|
76
56
|
.flatMap((state) => {
|
|
77
57
|
const count = board.omitted?.byState[state] ?? 0;
|
|
78
58
|
return count > 0 ? [`${count} ${state}`] : [];
|
|
@@ -80,26 +60,15 @@ function renderProjectionOmission(board) {
|
|
|
80
60
|
return counts.length > 0 ? `+ ${counts.join(" · ")}` : undefined;
|
|
81
61
|
}
|
|
82
62
|
function renderProjectionAge(row) {
|
|
83
|
-
const duration = formatAgeMs(row.durationMs)
|
|
84
|
-
const activity = formatAgeMs(row.activityAgeMs)
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (row.state === "failed")
|
|
93
|
-
return `failed · ${facts}`;
|
|
94
|
-
if (row.state === "dead")
|
|
95
|
-
return `dead · ${facts}`;
|
|
96
|
-
if (row.state === "startup-timeout")
|
|
97
|
-
return `startup timed out · ${facts}`;
|
|
98
|
-
if (row.state === "unknown")
|
|
99
|
-
return `unknown · ${facts}`;
|
|
100
|
-
if (row.state === "incompatible")
|
|
101
|
-
return "incompatible history";
|
|
102
|
-
return facts;
|
|
63
|
+
const duration = formatAgeMs(row.durationMs);
|
|
64
|
+
const activity = formatAgeMs(row.activityAgeMs);
|
|
65
|
+
const terminalAge = formatAgeMs(row.terminalAgeMs);
|
|
66
|
+
const facts = [
|
|
67
|
+
...(terminalAge ? [`terminal ${terminalAge} ago`] : []),
|
|
68
|
+
...(duration ? [`${isTerminalProjectionStatus(row) ? "ran" : "observed for"} ${duration}`] : []),
|
|
69
|
+
...(activity ? [`last activity ${activity} ago`] : []),
|
|
70
|
+
];
|
|
71
|
+
return [row.state, ...facts].join(" · ");
|
|
103
72
|
}
|
|
104
73
|
function renderProjectionTellCounts(row) {
|
|
105
74
|
const { inbox, inflight, submitted, seen, consumed } = row.tellCounts;
|
|
@@ -131,30 +100,24 @@ function renderProjectionActivityLine(row) {
|
|
|
131
100
|
...(row.workspaceRoot ? { workspaceRoot: row.workspaceRoot } : {}),
|
|
132
101
|
});
|
|
133
102
|
}
|
|
134
|
-
function renderProjectionRow(row) {
|
|
135
|
-
const glyph = row.state === "killed"
|
|
136
|
-
? "×"
|
|
137
|
-
: projectionGlyph(row.state === "failed"
|
|
138
|
-
? "lost"
|
|
139
|
-
: row.state === "startup-timeout"
|
|
140
|
-
? "minting"
|
|
141
|
-
: row.state);
|
|
103
|
+
function renderProjectionRow(row, includeDrillDown = true, includeIdentity = true) {
|
|
142
104
|
const identity = row.alias ? `${row.id} (${row.alias})` : row.id;
|
|
105
|
+
const prefix = includeIdentity
|
|
106
|
+
? `${projectionStatusIndicator(row.state)} ${identity} · `
|
|
107
|
+
: `${projectionStatusIndicator(row.state)} `;
|
|
143
108
|
let heading;
|
|
144
109
|
if (row.state === "startup-timeout" || row.state === "unknown" || row.state === "incompatible") {
|
|
145
|
-
|
|
146
|
-
heading = ` ${glyph} ${identity} ${akuma} ${renderProjectionAge(row)}${terminalFailureSuffix(row)}${renderProjectionDiagnostics(row)}`.trimEnd();
|
|
110
|
+
heading = ` ${prefix}${renderProjectionAge(row)}${terminalFailureSuffix(row)}${renderProjectionDiagnostics(row)}`.trimEnd();
|
|
147
111
|
}
|
|
148
112
|
else if (row.state === "minting") {
|
|
149
|
-
heading = ` ${
|
|
113
|
+
heading = ` ${prefix}${renderProjectionAge(row)}${terminalFailureSuffix(row)}${renderProjectionDiagnostics(row)}`.trimEnd();
|
|
150
114
|
}
|
|
151
115
|
else {
|
|
152
116
|
const age = renderProjectionAge(row);
|
|
153
|
-
|
|
154
|
-
heading = ` ${glyph} ${identity} ${akuma} ${age}${renderProjectionTellCounts(row)}${terminalFailureSuffix(row)}${renderProjectionDiagnostics(row)}`.trimEnd();
|
|
117
|
+
heading = ` ${prefix}${age}${renderProjectionTellCounts(row)}${terminalFailureSuffix(row)}${renderProjectionDiagnostics(row)}`.trimEnd();
|
|
155
118
|
}
|
|
156
119
|
const activity = renderProjectionActivityLine(row);
|
|
157
|
-
const drillDown = row.terminalFailure ? [` » keiyaku wait ${row.
|
|
120
|
+
const drillDown = includeDrillDown && row.terminalFailure ? [` » keiyaku wait ${row.id}`] : [];
|
|
158
121
|
return activity ? [heading, activity, ...drillDown] : [heading, ...drillDown];
|
|
159
122
|
}
|
|
160
123
|
function isTerminalProjectionStatus(row) {
|
|
@@ -167,47 +130,114 @@ function isTerminalProjectionStatus(row) {
|
|
|
167
130
|
}
|
|
168
131
|
export function renderProjectionFilteredStatus(board, projectionId) {
|
|
169
132
|
const head = board.defaultHead ? shortCommitHash(board.defaultHead) : "(no HEAD)";
|
|
170
|
-
const
|
|
171
|
-
const row = board.projections?.rows.find((candidate) => candidate.id === projectionId);
|
|
133
|
+
const row = board.projections?.rows[0];
|
|
172
134
|
if (!row)
|
|
173
|
-
return
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
135
|
+
return `現世 ${head} · projection ${projectionId}\nunknown projection ${projectionId}\n`;
|
|
136
|
+
const identity = row.alias ? `${row.identity.canonicalId} (${row.alias})` : row.identity.canonicalId;
|
|
137
|
+
const heading = `現世 ${head} · projection ${identity}`;
|
|
138
|
+
const moved = row.addressedBy?.aliasMovedTo
|
|
139
|
+
? [`${row.addressedBy.token} has since moved to ${row.addressedBy.aliasMovedTo}`]
|
|
140
|
+
: [];
|
|
141
|
+
const lines = [heading, "", ...renderProjectionRow(row, false, false), ""];
|
|
142
|
+
lines.push(...moved);
|
|
179
143
|
if (row.observation.compatibility === "incompatible") {
|
|
180
144
|
return `${lines.join("\n")}\n`;
|
|
181
145
|
}
|
|
182
146
|
if (isTerminalProjectionStatus(row)) {
|
|
183
|
-
|
|
184
|
-
|
|
147
|
+
if (row.terminalAnswer?.text) {
|
|
148
|
+
if (row.responseArtifact?.state === "none") {
|
|
149
|
+
lines.push("nothing written to disk", row.terminalAnswer.text);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
const answer = row.terminalAnswer.text.split("\n");
|
|
153
|
+
lines.push(...answer.slice(0, 4));
|
|
154
|
+
if (answer.length > 4) {
|
|
155
|
+
lines.push(row.responseArtifact?.state === "retained"
|
|
156
|
+
? `… answer continues in ${row.responseArtifact.path}`
|
|
157
|
+
: `… +${answer.length - 4} more lines`);
|
|
158
|
+
}
|
|
159
|
+
else if (row.responseArtifact?.state === "retained") {
|
|
160
|
+
lines.push(`response: ${row.responseArtifact.path}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (row.responseArtifact?.state === "retained") {
|
|
165
|
+
lines.push(`response: ${row.responseArtifact.path}`);
|
|
166
|
+
}
|
|
167
|
+
return `${lines.join("\n")}\n`;
|
|
185
168
|
}
|
|
186
|
-
|
|
187
|
-
|
|
169
|
+
const commandAddress = row.addressedBy?.kind === "alias" && !row.addressedBy.aliasMovedTo
|
|
170
|
+
? row.addressedBy.token
|
|
171
|
+
: row.identity.canonicalId;
|
|
172
|
+
lines.push(`» ${formatTellCommand(commandAddress, '"..."')}`);
|
|
173
|
+
lines.push(`» keiyaku wait ${commandAddress}`);
|
|
188
174
|
return `${lines.join("\n")}\n`;
|
|
189
175
|
}
|
|
190
176
|
export function renderProjectionStatusSection(board) {
|
|
191
177
|
if (!board || (board.rows.length === 0 && !board.omitted))
|
|
192
178
|
return "";
|
|
193
|
-
const lines = board.rows.flatMap(renderProjectionRow);
|
|
179
|
+
const lines = board.rows.flatMap((row) => renderProjectionRow(row));
|
|
194
180
|
const omission = renderProjectionOmission(board);
|
|
195
181
|
if (omission)
|
|
196
182
|
lines.push(omission);
|
|
197
|
-
|
|
183
|
+
const total = board.rows.length + (board.omitted?.total ?? 0);
|
|
184
|
+
return `${STATUS_PROJECTION_SECTION_TITLE} ${board.rows.length}/${total}\n${lines.join("\n")}\n`;
|
|
198
185
|
}
|
|
199
186
|
/**
|
|
200
187
|
* Status mouth: kanshi board plus optional diseases section.
|
|
201
188
|
* Healthy boards (no diseases) are byte-identical to renderKanshiBoard alone.
|
|
202
189
|
*/
|
|
203
190
|
export function renderStatusBoard(board) {
|
|
204
|
-
const boardText = renderKanshiBoard(board);
|
|
205
191
|
const taskDiseaseText = [
|
|
206
192
|
...(board.tasks?.diseases ?? []).map((disease) => disease.message),
|
|
207
193
|
...(board.tasks?.diagnostic ? [board.tasks.diagnostic] : []),
|
|
208
194
|
];
|
|
209
195
|
const diseasesText = renderSettingsDiseasesSection(board.diseases, taskDiseaseText);
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
196
|
+
return renderKanshiBoard(board, diseasesText === "" ? [] : [diseasesText.trimEnd()]);
|
|
197
|
+
}
|
|
198
|
+
export function renderAkumaRosterStatus(board) {
|
|
199
|
+
return renderAkumaRosterBoard(board);
|
|
200
|
+
}
|
|
201
|
+
function statusJsonValue(value) {
|
|
202
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
203
|
+
return value;
|
|
204
|
+
}
|
|
205
|
+
if (typeof value === "number") {
|
|
206
|
+
if (!Number.isFinite(value))
|
|
207
|
+
throw new TypeError("Status payload numbers must be finite");
|
|
208
|
+
return value;
|
|
209
|
+
}
|
|
210
|
+
if (Array.isArray(value))
|
|
211
|
+
return value.map(statusJsonValue);
|
|
212
|
+
if (value instanceof Map || value instanceof Set) {
|
|
213
|
+
throw new TypeError("Status payload collections must be converted explicitly");
|
|
214
|
+
}
|
|
215
|
+
if (typeof value === "object") {
|
|
216
|
+
const entries = [];
|
|
217
|
+
for (const [key, item] of Object.entries(value)) {
|
|
218
|
+
if (item !== undefined)
|
|
219
|
+
entries.push([key, statusJsonValue(item)]);
|
|
220
|
+
}
|
|
221
|
+
return Object.fromEntries(entries);
|
|
222
|
+
}
|
|
223
|
+
throw new TypeError(`Status payload contains unsupported ${typeof value}`);
|
|
224
|
+
}
|
|
225
|
+
/** One JSON-safe status DTO shared by human and JSON command responses. */
|
|
226
|
+
export function buildStatusPayload(board) {
|
|
227
|
+
return {
|
|
228
|
+
contracts: statusJsonValue(board.contracts),
|
|
229
|
+
contractsObservable: board.contractsObservable,
|
|
230
|
+
commissionPlaces: statusJsonValue(Object.fromEntries(board.commissionPlaces)),
|
|
231
|
+
projections: statusJsonValue(board.projections),
|
|
232
|
+
queueLength: board.queueLength,
|
|
233
|
+
...(board.defaultBranch === undefined ? {} : { defaultBranch: board.defaultBranch }),
|
|
234
|
+
...(board.defaultHead === undefined ? {} : { defaultHead: board.defaultHead }),
|
|
235
|
+
diseases: statusJsonValue(board.diseases),
|
|
236
|
+
targetFilter: board.targetFilter,
|
|
237
|
+
...(board.commissionFilter === undefined ? {} : { commissionFilter: board.commissionFilter }),
|
|
238
|
+
...(board.tasks === undefined ? {} : { tasks: statusJsonValue(board.tasks) }),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
export function renderStatusJson(payload) {
|
|
242
|
+
return `${JSON.stringify(payload)}\n`;
|
|
213
243
|
}
|
|
@@ -11,6 +11,12 @@ function responseData(response) {
|
|
|
11
11
|
return {};
|
|
12
12
|
return payload;
|
|
13
13
|
}
|
|
14
|
+
const AKUMA_JSON_COMMANDS = new Set(["call", "tell", "wait", "fork"]);
|
|
15
|
+
export function serializeAkumaSuccessResponse(command, flags, response) {
|
|
16
|
+
return flags.json && AKUMA_JSON_COMMANDS.has(command)
|
|
17
|
+
? `${JSON.stringify(responseData(response))}\n`
|
|
18
|
+
: undefined;
|
|
19
|
+
}
|
|
14
20
|
function isCallProjectionFacts(value) {
|
|
15
21
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
16
22
|
return false;
|
|
@@ -25,10 +31,17 @@ function conversationalFooter(response) {
|
|
|
25
31
|
if (response.address) {
|
|
26
32
|
const projection = data.projection;
|
|
27
33
|
const projectionFacts = isCallProjectionFacts(projection) ? projection : undefined;
|
|
28
|
-
const receiptArtifactId = typeof data.
|
|
29
|
-
? data.
|
|
34
|
+
const receiptArtifactId = typeof data.sourceArtifactId === "string"
|
|
35
|
+
? data.sourceArtifactId
|
|
30
36
|
: typeof data.artifactId === "string" ? data.artifactId : undefined;
|
|
31
37
|
lines.push(renderResolvedAddressReceipt(response.address, { artifactId: receiptArtifactId, projectionId: projectionFacts?.id }));
|
|
38
|
+
if (typeof data.sourceArtifactId === "string" && typeof data.artifactId === "string") {
|
|
39
|
+
lines.push([
|
|
40
|
+
typeof data.sourceProjectionId === "string" ? `source projection ${data.sourceProjectionId}` : undefined,
|
|
41
|
+
"conversation continued",
|
|
42
|
+
`response artifact ${data.artifactId}`,
|
|
43
|
+
].filter((part) => part !== undefined).join(" · "));
|
|
44
|
+
}
|
|
32
45
|
}
|
|
33
46
|
const responsePath = typeof data.responsePath === "string" ? data.responsePath : undefined;
|
|
34
47
|
const agent = typeof data.agent === "string" ? data.agent : undefined;
|
|
@@ -56,9 +69,11 @@ function conversationalFooter(response) {
|
|
|
56
69
|
return lines.join("\n");
|
|
57
70
|
}
|
|
58
71
|
export async function writeSuccessResponse(command, flags, response) {
|
|
59
|
-
|
|
60
|
-
if (
|
|
72
|
+
const json = serializeAkumaSuccessResponse(command, flags, response);
|
|
73
|
+
if (json !== undefined) {
|
|
74
|
+
await writeCliOutput(process.stdout, json);
|
|
61
75
|
return;
|
|
76
|
+
}
|
|
62
77
|
if (command === "bind" && flags.dryRun) {
|
|
63
78
|
// Canonical Markdown already ends with exactly one newline.
|
|
64
79
|
await writeCliOutput(process.stdout, responseText(response));
|
|
@@ -66,7 +81,7 @@ export async function writeSuccessResponse(command, flags, response) {
|
|
|
66
81
|
await writeCliOutput(process.stderr, `${response.stderr}\n`);
|
|
67
82
|
return;
|
|
68
83
|
}
|
|
69
|
-
if (command !== "
|
|
84
|
+
if (command !== "fork") {
|
|
70
85
|
await writeCliOutput(process.stdout, `${responseText(response)}\n`);
|
|
71
86
|
return;
|
|
72
87
|
}
|
package/build/cli/render/task.js
CHANGED
|
@@ -7,14 +7,14 @@ export function deriveTaskDisplay(task) {
|
|
|
7
7
|
const display = deriveStructuredTaskDisplay(task);
|
|
8
8
|
return display === "bound" ? `bound(${shortContractId(task.contractId)})` : display;
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
return `${
|
|
10
|
+
function renderTaskRowWithCoordinate(task, coordinate) {
|
|
11
|
+
return `${coordinate} · P${task.pri} · ${deriveTaskDisplay(task)} · ${task.title}`;
|
|
12
12
|
}
|
|
13
13
|
export function renderTaskListRow(task) {
|
|
14
|
-
return
|
|
14
|
+
return renderTaskRowWithCoordinate(task, task.coordinate);
|
|
15
15
|
}
|
|
16
16
|
export function renderTaskMutationRow(task) {
|
|
17
|
-
return
|
|
17
|
+
return renderTaskRowWithCoordinate(task, task.coordinate);
|
|
18
18
|
}
|
|
19
19
|
export function renderTaskUpdate(result) {
|
|
20
20
|
const lines = [renderTaskMutationRow(result.task)];
|
|
@@ -75,7 +75,6 @@ function renderTaskDetails(task) {
|
|
|
75
75
|
const released = new Set(task.releasedNeeds);
|
|
76
76
|
return [
|
|
77
77
|
`${task.coordinate} · ${task.title}`,
|
|
78
|
-
`namespace: ${task.namespace ?? "(hub)"}`,
|
|
79
78
|
`state: ${deriveTaskDisplay(task)}`,
|
|
80
79
|
`priority: ${task.pri}`,
|
|
81
80
|
...(task.needs.length === 0 ? [] : [`needs: ${task.needs.map((id) => `${id}${released.has(id) ? " (dropped)" : ""}`).join(", ")}`]),
|
|
@@ -88,6 +87,7 @@ function renderTaskDetails(task) {
|
|
|
88
87
|
`created: ${task.createdAt} by ${task.creator}`,
|
|
89
88
|
"",
|
|
90
89
|
task.body,
|
|
90
|
+
...task.notes.flatMap((note) => ["", `${note.timestamp} · ${note.actor}`, note.text]),
|
|
91
91
|
];
|
|
92
92
|
}
|
|
93
93
|
function renderTreeNode(node, prefix, last) {
|
|
@@ -147,6 +147,7 @@ export function taskJson(task) {
|
|
|
147
147
|
createdAt: task.createdAt,
|
|
148
148
|
updatedAt: task.updatedAt ?? task.createdAt,
|
|
149
149
|
creator: task.creator,
|
|
150
|
+
notes: task.notes.map((note) => ({ ...note })),
|
|
150
151
|
};
|
|
151
152
|
}
|
|
152
153
|
function taskTreeNodeJson(node) {
|
package/build/cli/render/tell.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
3
|
-
export function
|
|
4
|
-
|
|
1
|
+
import { coreTextResponse } from "./shared.js";
|
|
2
|
+
/** Tell returns after mailbox acceptance; it never claims consumption. */
|
|
3
|
+
export function buildTellAcceptedResponse(projectionId, inputToken, alias) {
|
|
4
|
+
const payload = {
|
|
5
|
+
state: "accepted",
|
|
6
|
+
canonicalId: projectionId,
|
|
7
|
+
inputToken,
|
|
8
|
+
...(alias ? { alias } : {}),
|
|
9
|
+
};
|
|
10
|
+
return coreTextResponse(`${projectionId}${alias ? ` (${alias})` : ""} heard.`, payload);
|
|
5
11
|
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unwrap only complete provider transport launchers. This is deliberately not
|
|
3
|
+
* a shell parser: uncertainty preserves the persisted command's presentation.
|
|
4
|
+
*/
|
|
5
|
+
const HORIZONTAL_WHITESPACE = new Set([" ", "\t"]);
|
|
6
|
+
const UNSUPPORTED_UNQUOTED = new Set(["$", "`", "|", "&", ";", "<", ">", "(", ")"]);
|
|
7
|
+
const POWERSHELL_OPTION_FLAGS = new Set(["-nologo", "-noprofile"]);
|
|
8
|
+
const POWERSHELL_COMMAND_FLAGS = new Set(["-command", "-c"]);
|
|
9
|
+
function isAbsoluteExecutable(value) {
|
|
10
|
+
return value.startsWith("/") || /^[A-Za-z]:[\\/]/.test(value);
|
|
11
|
+
}
|
|
12
|
+
function executableName(value) {
|
|
13
|
+
const segments = value.split(/[\\/]/);
|
|
14
|
+
return segments[segments.length - 1].toLowerCase();
|
|
15
|
+
}
|
|
16
|
+
function isBashOrZsh(value) {
|
|
17
|
+
const name = executableName(value);
|
|
18
|
+
return (value === "bash" || value === "zsh" || isAbsoluteExecutable(value))
|
|
19
|
+
&& (name === "bash" || name === "zsh");
|
|
20
|
+
}
|
|
21
|
+
function isPowerShell(value) {
|
|
22
|
+
const name = executableName(value);
|
|
23
|
+
return (value.toLowerCase() === "powershell" || value.toLowerCase() === "pwsh" || isAbsoluteExecutable(value))
|
|
24
|
+
&& (name === "powershell" || name === "powershell.exe" || name === "pwsh" || name === "pwsh.exe");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Read only a conservative argv-shaped command line. Newlines are supported
|
|
28
|
+
* inside a quoted argument but not as outer command syntax.
|
|
29
|
+
*/
|
|
30
|
+
function parseTransportArgv(command) {
|
|
31
|
+
const argv = [];
|
|
32
|
+
let index = 0;
|
|
33
|
+
while (index < command.length) {
|
|
34
|
+
while (HORIZONTAL_WHITESPACE.has(command[index]))
|
|
35
|
+
index += 1;
|
|
36
|
+
if (index === command.length)
|
|
37
|
+
break;
|
|
38
|
+
if (command[index] === "\n" || command[index] === "\r")
|
|
39
|
+
return undefined;
|
|
40
|
+
let value = "";
|
|
41
|
+
let consumed = false;
|
|
42
|
+
while (index < command.length && !HORIZONTAL_WHITESPACE.has(command[index])) {
|
|
43
|
+
const character = command[index];
|
|
44
|
+
if (character === "\n" || character === "\r" || UNSUPPORTED_UNQUOTED.has(character))
|
|
45
|
+
return undefined;
|
|
46
|
+
if (character === "'") {
|
|
47
|
+
const end = command.indexOf("'", index + 1);
|
|
48
|
+
if (end < 0)
|
|
49
|
+
return undefined;
|
|
50
|
+
value += command.slice(index + 1, end);
|
|
51
|
+
index = end + 1;
|
|
52
|
+
consumed = true;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (character === '"') {
|
|
56
|
+
index += 1;
|
|
57
|
+
consumed = true;
|
|
58
|
+
let closed = false;
|
|
59
|
+
while (index < command.length) {
|
|
60
|
+
const quoted = command[index];
|
|
61
|
+
if (quoted === '"') {
|
|
62
|
+
index += 1;
|
|
63
|
+
closed = true;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
if (quoted === "$")
|
|
67
|
+
return undefined;
|
|
68
|
+
if (quoted === "`")
|
|
69
|
+
return undefined;
|
|
70
|
+
if (quoted === "\\") {
|
|
71
|
+
const next = command[index + 1];
|
|
72
|
+
if (next === undefined || next === "\n" || next === "\r")
|
|
73
|
+
return undefined;
|
|
74
|
+
if (next === '"' || next === "\\" || next === "$" || next === "`") {
|
|
75
|
+
value += next;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
value += `\\${next}`;
|
|
79
|
+
}
|
|
80
|
+
index += 2;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
value += quoted;
|
|
84
|
+
index += 1;
|
|
85
|
+
}
|
|
86
|
+
if (!closed)
|
|
87
|
+
return undefined;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (character === "\\") {
|
|
91
|
+
const next = command[index + 1];
|
|
92
|
+
if (next === undefined || next === "\n" || next === "\r")
|
|
93
|
+
return undefined;
|
|
94
|
+
value += next;
|
|
95
|
+
index += 2;
|
|
96
|
+
consumed = true;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
value += character;
|
|
100
|
+
index += 1;
|
|
101
|
+
consumed = true;
|
|
102
|
+
}
|
|
103
|
+
if (!consumed)
|
|
104
|
+
return undefined;
|
|
105
|
+
argv.push(value);
|
|
106
|
+
}
|
|
107
|
+
return argv;
|
|
108
|
+
}
|
|
109
|
+
function unwrapBashOrZsh(argv) {
|
|
110
|
+
const [shell, flag, script] = argv;
|
|
111
|
+
if (argv.length !== 3 || !shell || !script || !isBashOrZsh(shell))
|
|
112
|
+
return undefined;
|
|
113
|
+
return flag === "-c" || flag === "-lc" ? script : undefined;
|
|
114
|
+
}
|
|
115
|
+
function unwrapPowerShell(argv) {
|
|
116
|
+
const [shell, ...arguments_] = argv;
|
|
117
|
+
if (!shell || !isPowerShell(shell) || arguments_.length < 2)
|
|
118
|
+
return undefined;
|
|
119
|
+
const options = new Set();
|
|
120
|
+
for (let index = 0; index < arguments_.length - 1; index += 1) {
|
|
121
|
+
const flag = arguments_[index].toLowerCase();
|
|
122
|
+
if (POWERSHELL_COMMAND_FLAGS.has(flag)) {
|
|
123
|
+
return index === arguments_.length - 2 && arguments_[index + 1] ? arguments_[index + 1] : undefined;
|
|
124
|
+
}
|
|
125
|
+
if (!POWERSHELL_OPTION_FLAGS.has(flag) || options.has(flag))
|
|
126
|
+
return undefined;
|
|
127
|
+
options.add(flag);
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
/** Return a display subject only when the full transport shape is unambiguous. */
|
|
132
|
+
export function normalizeToolCommand(command) {
|
|
133
|
+
const argv = parseTransportArgv(command);
|
|
134
|
+
if (!argv)
|
|
135
|
+
return command;
|
|
136
|
+
return unwrapBashOrZsh(argv) ?? unwrapPowerShell(argv) ?? command;
|
|
137
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { compactText } from "./compact-text.js";
|
|
2
|
+
import { normalizeToolCommand } from "./tool-command-normalization.js";
|
|
2
3
|
export function activitySemanticClass(call) {
|
|
3
4
|
switch (call.kind) {
|
|
4
5
|
case "run": return "run";
|
|
@@ -24,7 +25,7 @@ function rangeText(call) {
|
|
|
24
25
|
}
|
|
25
26
|
function subject(call, presentPath) {
|
|
26
27
|
switch (call.kind) {
|
|
27
|
-
case "run": return compactText(call.description ?? `$ ${call.command}`);
|
|
28
|
+
case "run": return compactText(call.description ?? `$ ${normalizeToolCommand(call.command)}`);
|
|
28
29
|
case "read": return presentPath(call.path);
|
|
29
30
|
case "search": return `“${compactText(call.query)}”`;
|
|
30
31
|
case "other": return compactText(call.display);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { buildPayload } from "./format.js";
|
|
2
|
+
import { coreTextResponse } from "./shared.js";
|
|
3
|
+
function humanLines(model) {
|
|
4
|
+
return `${model.runId}\n${model.phase}`;
|
|
5
|
+
}
|
|
6
|
+
/** Canonical Verification CLI renderer: one model drives human text and JSON. */
|
|
7
|
+
export function renderVerificationCli(model, json) {
|
|
8
|
+
const payload = buildPayload(model);
|
|
9
|
+
const output = coreTextResponse(json ? JSON.stringify(payload) : humanLines(model), payload);
|
|
10
|
+
return model.operation === "wait" && model.phase === "timeout" ? { ...output, exitCode: 124 } : output;
|
|
11
|
+
}
|
|
12
|
+
export function verificationStatusModel(run) {
|
|
13
|
+
return { operation: "status", runId: run.id, phase: run.terminal?.status ?? "running", run };
|
|
14
|
+
}
|
|
15
|
+
export function verificationWaitModel(runId, terminal) {
|
|
16
|
+
return { operation: "wait", runId, phase: terminal.status, terminal };
|
|
17
|
+
}
|
|
18
|
+
export function verificationWaitTimeoutModel(runId) {
|
|
19
|
+
return { operation: "wait", runId, phase: "timeout" };
|
|
20
|
+
}
|
|
21
|
+
export function verificationCancelModel(runId, accepted) {
|
|
22
|
+
return { operation: "cancel", runId, phase: accepted ? "accepted" : "already-terminal-or-missing", accepted };
|
|
23
|
+
}
|