@astrosheep/keiyaku 2.9.11 → 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 +79 -85
- package/build/.tsbuildinfo +1 -1
- package/build/agents/call-terms.js +1 -0
- package/build/agents/providers/claude-agent-sdk/adapter.js +17 -4
- 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/bind/meta.js +4 -4
- 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 +14 -10
- 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/handler.js +4 -5
- 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 +2 -2
- 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 +4 -0
- package/build/cli/commands/task/compose/handler.js +18 -0
- package/build/cli/commands/task/compose/meta.js +10 -0
- 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 +48 -12
- package/build/cli/help.js +29 -30
- package/build/cli/index.js +14 -8
- package/build/cli/parse-flags.js +60 -21
- package/build/cli/parse-metadata.js +10 -4
- package/build/cli/parse-selectors.js +22 -4
- package/build/cli/parse.js +43 -30
- package/build/cli/projection-address.js +7 -7
- 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 +33 -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/addressing.js +3 -3
- 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 +46 -33
- 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 +43 -6
- package/build/core/contract.js +2 -1
- package/build/core/derived-replay.js +168 -35
- package/build/core/draft.js +60 -27
- 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 +19 -14
- 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 +132 -76
- 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 +24 -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 +8 -8
- package/build/core/projection/projection-kill.js +20 -10
- 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 +48 -29
- package/build/core/projection/projection-wake.js +28 -88
- 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/claim-evidence.js +1 -1
- package/build/core/repository-ledger/codec.js +11 -5
- package/build/core/repository-ledger/current-state-store.js +464 -349
- 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 +57 -9
- package/build/core/repository-ledger/write-transaction.js +24 -17
- 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/run-control/sqlite-process-lifetime-lock.js +174 -0
- 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 +328 -0
- package/build/core/task/document.js +102 -39
- package/build/core/task/index.js +4 -3
- package/build/core/task/settlement-git.js +70 -30
- 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-git-store.js +1 -0
- package/build/core/task/task-store-repository.js +2 -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 +15 -2
- 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 +2 -2
- package/skills/keiyaku-akuma/SKILL.md +27 -21
- package/skills/keiyaku-task/SKILL.md +61 -5
- package/skills/keiyaku-workflow/SKILL.md +81 -26
- 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 -382
- 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,9 +1,10 @@
|
|
|
1
1
|
import { getConfig } from "../../config/env.js";
|
|
2
2
|
import { formatAgeMs } from "./format.js";
|
|
3
3
|
import { displayColumns, resolveLineColumns, truncateColumns } from "./line-width.js";
|
|
4
|
-
import {
|
|
4
|
+
import { renderProjectionActivitySummary, } from "./projection-activity.js";
|
|
5
|
+
import { contractStatusIndicator, projectionStatusIndicator, STATUS_INDICATOR_LEGEND, taskStatusIndicator, } from "./status-indicator.js";
|
|
5
6
|
const KANSHI_MAX_COLUMNS = 120;
|
|
6
|
-
const
|
|
7
|
+
const KANSHI_MAX_LINES = 40;
|
|
7
8
|
function shortHead(hash) {
|
|
8
9
|
return hash?.slice(0, 7);
|
|
9
10
|
}
|
|
@@ -80,27 +81,31 @@ export function orderKanshiContracts(contracts) {
|
|
|
80
81
|
}
|
|
81
82
|
function renderDriftMark(drift) {
|
|
82
83
|
if (drift.state === "drift")
|
|
83
|
-
return
|
|
84
|
+
return `behind ${drift.defaultBranch} by ${drift.behindBy}`;
|
|
84
85
|
if (drift.state === "orphaned")
|
|
85
|
-
return
|
|
86
|
+
return `base not on ${drift.defaultBranch}`;
|
|
86
87
|
return undefined;
|
|
87
88
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
function contractIndicator(contract) {
|
|
90
|
+
return contractStatusIndicator({
|
|
91
|
+
state: contract.state.state,
|
|
92
|
+
waiting: pendingAfterIds(contract).length > 0,
|
|
93
|
+
broken: contract.queueHeadStalled || contract.replayBlockers.length > 0,
|
|
94
|
+
});
|
|
92
95
|
}
|
|
93
96
|
function contractFacts(contract) {
|
|
94
97
|
const facts = [];
|
|
95
98
|
const spark = arcSparkline(contract.arcs);
|
|
96
99
|
if (spark)
|
|
97
100
|
facts.push({ text: spark });
|
|
101
|
+
const waitingOn = pendingAfterIds(contract);
|
|
102
|
+
if (waitingOn.length > 0)
|
|
103
|
+
facts.push({ text: `waiting on ${waitingOn.join(", ")}` });
|
|
98
104
|
const drift = renderDriftMark(contract.baseDrift);
|
|
99
105
|
if (drift)
|
|
100
106
|
facts.push({ text: drift });
|
|
101
|
-
const lifecycle = contract.state.state === "active" ? "open" : contract.state.state;
|
|
102
107
|
const age = formatAgeMs(contract.lastActiveMs);
|
|
103
|
-
facts.push({ text: age ? `${
|
|
108
|
+
facts.push({ text: age ? `${contract.state.state} ${age}` : contract.state.state });
|
|
104
109
|
if (contract.queueHeadStalled) {
|
|
105
110
|
facts.push({ text: age ? `stalled ${age}` : "stalled", tone: "alert" });
|
|
106
111
|
}
|
|
@@ -112,11 +117,26 @@ function renderKeiyakuSection(board, width) {
|
|
|
112
117
|
const lines = [`keiyaku ${board.contracts.length}`];
|
|
113
118
|
for (const contract of orderKanshiContracts(board.contracts)) {
|
|
114
119
|
lines.push(alignedBoardRow({
|
|
115
|
-
prefix: `${
|
|
120
|
+
prefix: `${contractIndicator(contract)} ${contract.place ?? contract.slug}`,
|
|
116
121
|
title: contract.title,
|
|
117
122
|
facts: contractFacts(contract),
|
|
118
123
|
width,
|
|
119
124
|
}));
|
|
125
|
+
if (contract.tasks) {
|
|
126
|
+
const progress = contract.tasks;
|
|
127
|
+
const summary = `${progress.done}/${progress.total} done`;
|
|
128
|
+
if (board.commissionFilter === contract.id) {
|
|
129
|
+
for (const task of progress.tasks) {
|
|
130
|
+
lines.push(` ${taskStatusIndicator(task)} task ${task.coordinate} · ${task.state} · ${task.title}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else if (progress.current) {
|
|
134
|
+
lines.push(` ${taskStatusIndicator(progress.current)} task ${summary} · ${progress.current.state} · ${progress.current.coordinate} · ${progress.current.title}`);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
lines.push(` task ${summary}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
120
140
|
if (contract.replayBlockers.length > 0) {
|
|
121
141
|
lines.push(` ! incomplete replay · ${contract.replayBlockers.map((blocker) => blocker.surface).join(", ")}`);
|
|
122
142
|
lines.push(` • ${contract.replayBlockers[0].recoveryCommand}`);
|
|
@@ -147,81 +167,71 @@ function projectionBinding(board, row) {
|
|
|
147
167
|
}
|
|
148
168
|
function projectionFacts(row) {
|
|
149
169
|
const facts = [];
|
|
150
|
-
|
|
151
|
-
|
|
170
|
+
const terminal = row.state === "done" || row.state === "failed" || row.state === "dead"
|
|
171
|
+
|| row.state === "killed" || row.state === "dismissed" || row.state === "incompatible";
|
|
172
|
+
const terminalAge = row.terminalAgeMs === undefined ? undefined : formatAgeMs(row.terminalAgeMs);
|
|
173
|
+
facts.push({ text: terminalAge ? `${row.state} ${terminalAge} ago` : row.state, tone: row.state === "startup-timeout" ? "alert" : "normal" });
|
|
174
|
+
if (row.durationMs !== undefined) {
|
|
175
|
+
facts.push({ text: `${terminal ? "ran" : "running for"} ${formatAgeMs(row.durationMs) ?? "0s"}` });
|
|
176
|
+
}
|
|
152
177
|
if (row.activityAgeMs !== undefined)
|
|
153
|
-
facts.push({ text: `
|
|
154
|
-
if (row.state !== "out" && row.state !== "minting")
|
|
155
|
-
facts.push({ text: row.state, tone: row.state === "startup-timeout" ? "alert" : "normal" });
|
|
178
|
+
facts.push({ text: `last activity ${formatAgeMs(row.activityAgeMs) ?? "0s"} ago` });
|
|
156
179
|
return facts;
|
|
157
180
|
}
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
anchorMs: observedAtMs,
|
|
166
|
-
state: activityState(row),
|
|
167
|
-
showPlan: false,
|
|
168
|
-
showSilence: false,
|
|
169
|
-
...(row.workspaceRoot ? { workspaceRoot: row.workspaceRoot } : {}),
|
|
170
|
-
maxColumns: width,
|
|
171
|
-
leadingOmittedCount: selection.leadingOmittedCount,
|
|
172
|
-
})
|
|
173
|
-
: undefined;
|
|
174
|
-
const rendered = ordinary?.lines.map((line, index) => ({
|
|
175
|
-
line,
|
|
176
|
-
at: ordinary.rowAts[index],
|
|
177
|
-
order: index,
|
|
178
|
-
})) ?? [];
|
|
179
|
-
const tells = (row.pendingTells ?? []).map((tell, index) => ({
|
|
180
|
-
line: renderPendingProjectionTell(tell, {
|
|
181
|
-
anchorMs: observedAtMs,
|
|
182
|
-
maxColumns: width,
|
|
183
|
-
renderUnconsumedTail: (tail) => tone(tail, "alert"),
|
|
184
|
-
}),
|
|
185
|
-
at: tell.createdAt,
|
|
186
|
-
order: rendered.length + index,
|
|
187
|
-
}));
|
|
188
|
-
return [...rendered, ...tells]
|
|
189
|
-
.sort((left, right) => {
|
|
190
|
-
const leftAt = Date.parse(left.at ?? "");
|
|
191
|
-
const rightAt = Date.parse(right.at ?? "");
|
|
192
|
-
const safeLeft = Number.isFinite(leftAt) ? leftAt : Number.POSITIVE_INFINITY;
|
|
193
|
-
const safeRight = Number.isFinite(rightAt) ? rightAt : Number.POSITIVE_INFINITY;
|
|
194
|
-
return safeLeft - safeRight || left.order - right.order;
|
|
195
|
-
})
|
|
196
|
-
.map((entry) => entry.line);
|
|
197
|
-
}
|
|
198
|
-
function terminalSummary(board) {
|
|
199
|
-
const omitted = board.projections?.omitted;
|
|
200
|
-
if (!omitted)
|
|
201
|
-
return undefined;
|
|
202
|
-
const compatibleStates = ["failed", "dead", "done", "killed", "dismissed"];
|
|
203
|
-
const details = compatibleStates
|
|
204
|
-
.flatMap((state) => omitted.byState[state] > 0 ? [`${omitted.byState[state]} ${state}`] : []);
|
|
205
|
-
return details.length > 0 ? `+ ${details.join(" · ")}` : undefined;
|
|
181
|
+
function renderSnapshot(row) {
|
|
182
|
+
if (!row.activity)
|
|
183
|
+
return "";
|
|
184
|
+
return renderProjectionActivitySummary(row.activity, {
|
|
185
|
+
state: activityState(row),
|
|
186
|
+
...(row.workspaceRoot ? { workspaceRoot: row.workspaceRoot } : {}),
|
|
187
|
+
}) ?? "";
|
|
206
188
|
}
|
|
207
|
-
function renderAkumaSection(board, width) {
|
|
189
|
+
function renderAkumaSection(board, width, includeRosterFooter = true) {
|
|
208
190
|
if (!board.projections)
|
|
209
|
-
return
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
191
|
+
return "akuma 0\nno akuma out there · full roster: keiyaku status --akuma";
|
|
192
|
+
const triage = board.projections.triage;
|
|
193
|
+
const sections = triage
|
|
194
|
+
? [
|
|
195
|
+
["startup failed", triage.startupFailed],
|
|
196
|
+
["unknown", triage.unknown],
|
|
197
|
+
["running", triage.active],
|
|
198
|
+
["recent terminal", triage.recentTerminal],
|
|
199
|
+
]
|
|
200
|
+
: [[null, board.projections.rows]];
|
|
201
|
+
const total = board.projections.rows.length + (triage?.overflow ?? board.projections.omitted?.total ?? 0);
|
|
202
|
+
const lines = [`akuma ${board.projections.rows.length}/${total}`];
|
|
203
|
+
for (const [label, rows] of sections) {
|
|
204
|
+
if (triage && rows.length === 0)
|
|
205
|
+
continue;
|
|
206
|
+
if (label !== null) {
|
|
207
|
+
const sectionTotal = label === "startup failed"
|
|
208
|
+
? triage.totals.startupFailed
|
|
209
|
+
: label === "unknown"
|
|
210
|
+
? triage.totals.unknown
|
|
211
|
+
: label === "running"
|
|
212
|
+
? triage.totals.active
|
|
213
|
+
: triage.totals.terminal;
|
|
214
|
+
lines.push(`${label} ${rows.length}/${sectionTotal}`);
|
|
215
|
+
}
|
|
216
|
+
for (const row of rows) {
|
|
217
|
+
const identity = row.alias ? `${row.identity.canonicalId} (${row.alias})` : row.identity.canonicalId;
|
|
218
|
+
const pending = (row.pendingTells?.length ?? 0) > 0 ? [{ text: `pending tell ${row.pendingTells.length}` }] : [];
|
|
219
|
+
const snapshot = renderSnapshot(row) || projectionBinding(board, row);
|
|
220
|
+
lines.push(alignedBoardRow({
|
|
221
|
+
prefix: `${projectionStatusIndicator(row.state)} ${identity}`,
|
|
222
|
+
title: snapshot,
|
|
223
|
+
titleTone: "normal",
|
|
224
|
+
facts: [...projectionFacts(row), ...pending],
|
|
225
|
+
width,
|
|
226
|
+
}));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (board.projections.rows.length === 0) {
|
|
230
|
+
lines.push(includeRosterFooter ? "no akuma out there · full roster: keiyaku status --akuma" : "no akuma out there");
|
|
231
|
+
}
|
|
232
|
+
else if (includeRosterFooter) {
|
|
233
|
+
lines.push(tone("full roster: keiyaku status --akuma", "description"));
|
|
221
234
|
}
|
|
222
|
-
const folded = terminalSummary(board);
|
|
223
|
-
if (folded)
|
|
224
|
-
lines.push(tone(folded, "description"));
|
|
225
235
|
return lines.join("\n");
|
|
226
236
|
}
|
|
227
237
|
function taskLabel(task) {
|
|
@@ -233,9 +243,9 @@ function renderTaskSection(tasks, width) {
|
|
|
233
243
|
const lines = [`task ${tasks.total}`];
|
|
234
244
|
for (const task of tasks.topTasks) {
|
|
235
245
|
lines.push(alignedBoardRow({
|
|
236
|
-
prefix:
|
|
246
|
+
prefix: `${taskStatusIndicator(task)} ${task.state}`,
|
|
237
247
|
title: taskLabel(task),
|
|
238
|
-
facts: [{ text:
|
|
248
|
+
facts: [{ text: `last update ${formatAgeMs(task.activityAgeMs) ?? "0s"} ago` }],
|
|
239
249
|
width,
|
|
240
250
|
}));
|
|
241
251
|
}
|
|
@@ -248,16 +258,43 @@ function renderTaskSection(tasks, width) {
|
|
|
248
258
|
lines.push(tone(`+ ${folded.join(" · ")}`, "description"));
|
|
249
259
|
return lines.join("\n");
|
|
250
260
|
}
|
|
251
|
-
export function renderKanshiBoard(board) {
|
|
261
|
+
export function renderKanshiBoard(board, beforeAkuma = []) {
|
|
252
262
|
const width = Math.min(KANSHI_MAX_COLUMNS, resolveLineColumns());
|
|
253
263
|
const left = "kanshi ";
|
|
254
264
|
const head = shortHead(board.defaultHead);
|
|
255
265
|
const right = head ? ` 現世 ${head}` : " 現世";
|
|
256
266
|
const dashes = "─".repeat(Math.max(1, width - displayColumns(left) - displayColumns(right)));
|
|
257
267
|
const sections = [
|
|
268
|
+
STATUS_INDICATOR_LEGEND,
|
|
258
269
|
renderKeiyakuSection(board, width),
|
|
270
|
+
board.commissionFilter === undefined ? renderTaskSection(board.tasks, width) : undefined,
|
|
271
|
+
...beforeAkuma,
|
|
259
272
|
renderAkumaSection(board, width),
|
|
260
|
-
renderTaskSection(board.tasks, width),
|
|
261
273
|
].filter((section) => section !== undefined);
|
|
262
|
-
|
|
274
|
+
const header = `${left}${dashes}${right}`;
|
|
275
|
+
const rendered = [header, ...sections].join("\n\n");
|
|
276
|
+
if (board.commissionFilter !== undefined || rendered.split("\n").length <= KANSHI_MAX_LINES) {
|
|
277
|
+
return `${rendered}\n`;
|
|
278
|
+
}
|
|
279
|
+
const akuma = sections.at(-1);
|
|
280
|
+
const leading = sections.slice(0, -1).join("\n\n").split("\n");
|
|
281
|
+
const akumaLines = akuma.split("\n");
|
|
282
|
+
const leadingBudget = Math.max(0, KANSHI_MAX_LINES - 3 - akumaLines.length);
|
|
283
|
+
const visible = leading.slice(0, Math.max(0, leadingBudget - 1));
|
|
284
|
+
while (visible.at(-1) === "")
|
|
285
|
+
visible.pop();
|
|
286
|
+
const omitted = leading.length - visible.length;
|
|
287
|
+
if (omitted > 0 && leadingBudget > 0)
|
|
288
|
+
visible.push(tone(`+ ${omitted} board lines omitted`, "description"));
|
|
289
|
+
return `${[header, visible.join("\n"), akuma].filter(Boolean).join("\n\n")}\n`;
|
|
290
|
+
}
|
|
291
|
+
/** Akuma roster mouth: reuse the shared frame and row grammar without unrelated board sections. */
|
|
292
|
+
export function renderAkumaRosterBoard(board) {
|
|
293
|
+
const width = Math.min(KANSHI_MAX_COLUMNS, resolveLineColumns());
|
|
294
|
+
const left = "kanshi ";
|
|
295
|
+
const head = shortHead(board.defaultHead);
|
|
296
|
+
const right = head ? ` 現世 ${head}` : " 現世";
|
|
297
|
+
const dashes = "─".repeat(Math.max(1, width - displayColumns(left) - displayColumns(right)));
|
|
298
|
+
const akuma = renderAkumaSection(board, width, false) ?? "akuma 0\nno akuma out there";
|
|
299
|
+
return `${[`${left}${dashes}${right}`, STATUS_INDICATOR_LEGEND, akuma].join("\n\n")}\n`;
|
|
263
300
|
}
|
package/build/cli/render/misc.js
CHANGED
|
@@ -31,7 +31,7 @@ function buildErrorText(input) {
|
|
|
31
31
|
const errorSection = buildSection("Error", input.message);
|
|
32
32
|
const conflictSection = input.facts?.kind === "renew_conflict_scratch"
|
|
33
33
|
? buildSection("Conflict scratch", [
|
|
34
|
-
input.facts.scratchPath
|
|
34
|
+
`${input.facts.scratchPath}/files`,
|
|
35
35
|
"",
|
|
36
36
|
"Conflicting paths:",
|
|
37
37
|
...input.facts.conflictPaths.map((filePath) => ` ${filePath}`),
|
|
@@ -52,7 +52,7 @@ function buildErrorText(input) {
|
|
|
52
52
|
: undefined;
|
|
53
53
|
const nextActionSection = input.facts?.kind === "renew_conflict_scratch" && renewAddress
|
|
54
54
|
? buildSection("Next action", [
|
|
55
|
-
"Resolve files in the conflict
|
|
55
|
+
"Resolve files in the linked conflict worktree, then:",
|
|
56
56
|
`» keiyaku ${renewAddress} renew --continue`,
|
|
57
57
|
"Or discard the conflict scratch:",
|
|
58
58
|
`» keiyaku ${renewAddress} renew --abort`,
|
|
@@ -30,6 +30,15 @@ export function buildPetitionPreviewResponse(preview, json) {
|
|
|
30
30
|
: [
|
|
31
31
|
`contract ${commissionSlug(preview.contract)}`,
|
|
32
32
|
`arc ${source}`,
|
|
33
|
+
...(preview.scopeWarning
|
|
34
|
+
? [
|
|
35
|
+
`Scope warning: ${preview.scopeWarning.violations.join(", ")}`,
|
|
36
|
+
...preview.scopeWarning.evidence.map((evidence) => {
|
|
37
|
+
const patterns = evidence.patterns.length ? ` · ${evidence.patterns.map((pattern) => pattern.pattern).join(", ")}` : "";
|
|
38
|
+
return ` ${evidence.path} · ${evidence.outcome}${patterns}`;
|
|
39
|
+
}),
|
|
40
|
+
]
|
|
41
|
+
: []),
|
|
33
42
|
...preview.gates.map((gate) => {
|
|
34
43
|
if (gate.result === "not_evaluated")
|
|
35
44
|
return `gate ${gate.name} · not evaluated`;
|
|
@@ -53,7 +62,13 @@ export function buildPetitionClaimResponse(result, input) {
|
|
|
53
62
|
const summary = `Claimed contract${commitSuffix}.`;
|
|
54
63
|
const diffSection = result.diff ? buildSection(DIFF_OVERVIEW_SECTION_TITLE, result.diff) : null;
|
|
55
64
|
const ledgerSection = result.ledgerView ? buildSection("Ledger", result.ledgerView) : null;
|
|
56
|
-
const
|
|
65
|
+
const scopeWarning = result.sealed?.scopeAudit.violations.length
|
|
66
|
+
? [`Scope warning: ${result.sealed.scopeAudit.violations.join(", ")}`]
|
|
67
|
+
: [];
|
|
68
|
+
const warningSection = buildSection(WARNING_SECTION_TITLE, [
|
|
69
|
+
...scopeWarning,
|
|
70
|
+
...formatWarnings(result.meta?.warnings ?? []),
|
|
71
|
+
]);
|
|
57
72
|
const infoLines = [
|
|
58
73
|
...formatMaybe("Result", result.result, INFO_COMMIT_MAX_CHARS),
|
|
59
74
|
...formatMaybe("Title", input.title),
|
|
@@ -28,17 +28,30 @@ function runLines(run) {
|
|
|
28
28
|
`activity: ${run.activityRetention} · ${run.activityCount} retained${run.activityRange ? ` · ${run.activityRange.first}-${run.activityRange.last}` : ""}`,
|
|
29
29
|
...(run.telemetry ? [`telemetry: ${run.telemetry.inputTokens} in · ${run.telemetry.outputTokens} out${run.telemetry.cachedInputTokens !== undefined ? ` · ${run.telemetry.cachedInputTokens} cached` : ""}${run.telemetry.costUsd !== undefined ? ` · $${run.telemetry.costUsd.toFixed(2)}` : ""}`] : []),
|
|
30
30
|
...(run.artifact ? [`artifact: ${fact(run.artifact.id)} · ${run.artifact.retention}${run.artifact.path ? ` · path: ${run.artifact.path}` : ""}`] : []),
|
|
31
|
+
...(run.terminalAnswer ? [`answer: ${run.terminalAnswer.text}`] : []),
|
|
31
32
|
...consequenceLines(run),
|
|
32
33
|
...run.diagnostics.map((diagnostic) => `diagnostic: ${diagnostic}`),
|
|
33
34
|
];
|
|
34
35
|
}
|
|
35
|
-
export function renderProjectionHistoryList(runs) {
|
|
36
|
-
|
|
36
|
+
export function renderProjectionHistoryList(runs, pagination) {
|
|
37
|
+
const lines = runs.flatMap((run, index) => index === 0 ? runLines(run) : ["", ...runLines(run)]);
|
|
38
|
+
if (!pagination)
|
|
39
|
+
return lines.join("\n");
|
|
40
|
+
const range = runs.length === 0
|
|
41
|
+
? "none"
|
|
42
|
+
: `${pagination.offset}-${pagination.offset + runs.length - 1}`;
|
|
43
|
+
return [...lines, ...(lines.length > 0 ? [""] : []), `entries: ${range} of ${pagination.total}${pagination.nextOffset === null ? "" : ` · next offset: ${pagination.nextOffset}`}`].join("\n");
|
|
37
44
|
}
|
|
38
|
-
export function renderProjectionHistoryDetail(detail) {
|
|
45
|
+
export function renderProjectionHistoryDetail(detail, entry) {
|
|
39
46
|
const lines = runLines(detail);
|
|
40
|
-
if (
|
|
47
|
+
if (entry) {
|
|
48
|
+
return [...lines, "", `entry: ${entry.index}`, `event: ${JSON.stringify(entry.event)}`,
|
|
49
|
+
...(entry.raw ? [`raw: ${entry.raw.retention} · ${entry.raw.reason}`] : []),
|
|
50
|
+
].join("\n");
|
|
51
|
+
}
|
|
52
|
+
if (!detail.activity || detail.activity.retainedTimeline.length === 0) {
|
|
41
53
|
return lines.join("\n");
|
|
54
|
+
}
|
|
42
55
|
const state = detail.outcome === "done" ? "returned"
|
|
43
56
|
: detail.outcome === "out" ? "running"
|
|
44
57
|
: detail.outcome === "failed" || detail.outcome === "dead" ? "dead"
|
|
@@ -192,11 +192,11 @@ export function formatCallCompletionHeading(projection) {
|
|
|
192
192
|
default: return "no record of this akuma";
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
-
/** Machine-generated durable
|
|
195
|
+
/** Machine-generated durable fork command: artifactId + explicit repository coordinate. */
|
|
196
196
|
export function formatDurableReviveCommand(input) {
|
|
197
197
|
return input.repositoryCoordinate
|
|
198
|
-
? `keiyaku
|
|
199
|
-
: `keiyaku
|
|
198
|
+
? `keiyaku fork ${input.artifactId} --repo ${shellQuote(input.repositoryCoordinate)}`
|
|
199
|
+
: `keiyaku fork ${input.artifactId}`;
|
|
200
200
|
}
|
|
201
201
|
export function formatTellCommand(projectionId, body) {
|
|
202
202
|
return `keiyaku tell ${projectionId} [--wait DURATION] ${body}`;
|
|
@@ -211,14 +211,14 @@ export function projectionRejoinHintLines(projectionId) {
|
|
|
211
211
|
}
|
|
212
212
|
export function formatCallNextAction(input) {
|
|
213
213
|
if (input.projection?.phase === "active") {
|
|
214
|
-
return projectionRejoinHintLines(input.projection.
|
|
214
|
+
return projectionRejoinHintLines(input.projection.id).join("\n");
|
|
215
215
|
}
|
|
216
216
|
if (input.projection?.phase === "done") {
|
|
217
217
|
return [
|
|
218
218
|
"The akuma is back.",
|
|
219
219
|
...(input.artifactId ? [`record: ${input.artifactId}`] : []),
|
|
220
220
|
"talk to it:",
|
|
221
|
-
` » ${formatTellCommand(input.projection.
|
|
221
|
+
` » ${formatTellCommand(input.projection.id, '"your words"')}`,
|
|
222
222
|
].join("\n");
|
|
223
223
|
}
|
|
224
224
|
return "» keiyaku status";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const STATUS_INDICATOR = {
|
|
2
|
+
active: "●",
|
|
3
|
+
starting: "…",
|
|
4
|
+
waiting: "⧗",
|
|
5
|
+
ready: "○",
|
|
6
|
+
paused: "‖",
|
|
7
|
+
success: "✓",
|
|
8
|
+
stopped: "×",
|
|
9
|
+
failed: "!",
|
|
10
|
+
unknown: "?",
|
|
11
|
+
};
|
|
12
|
+
export const STATUS_INDICATOR_LEGEND = "marks ● active · … starting · ⧗ waiting · ○ ready · ‖ paused · ✓ success · × stopped · ! failed/broken · ? unknown";
|
|
13
|
+
export function projectionStatusIndicator(state) {
|
|
14
|
+
switch (state) {
|
|
15
|
+
case "out": return STATUS_INDICATOR.active;
|
|
16
|
+
case "minting": return STATUS_INDICATOR.starting;
|
|
17
|
+
case "done": return STATUS_INDICATOR.success;
|
|
18
|
+
case "killed":
|
|
19
|
+
case "dismissed": return STATUS_INDICATOR.stopped;
|
|
20
|
+
case "failed":
|
|
21
|
+
case "dead":
|
|
22
|
+
case "startup-timeout": return STATUS_INDICATOR.failed;
|
|
23
|
+
case "lost":
|
|
24
|
+
case "unknown":
|
|
25
|
+
case "incompatible": return STATUS_INDICATOR.unknown;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function contractStatusIndicator(input) {
|
|
29
|
+
if (input.state === "corrupt" || input.broken)
|
|
30
|
+
return STATUS_INDICATOR.failed;
|
|
31
|
+
if (input.state === "claimed")
|
|
32
|
+
return STATUS_INDICATOR.success;
|
|
33
|
+
if (input.state === "forfeited")
|
|
34
|
+
return STATUS_INDICATOR.stopped;
|
|
35
|
+
if (input.state === "petitioned" || input.waiting)
|
|
36
|
+
return STATUS_INDICATOR.waiting;
|
|
37
|
+
return STATUS_INDICATOR.active;
|
|
38
|
+
}
|
|
39
|
+
export function taskStatusIndicator(input) {
|
|
40
|
+
if (input.state === "done")
|
|
41
|
+
return STATUS_INDICATOR.success;
|
|
42
|
+
if (input.state === "on_hold")
|
|
43
|
+
return STATUS_INDICATOR.paused;
|
|
44
|
+
if (input.state === "in_progress")
|
|
45
|
+
return STATUS_INDICATOR.active;
|
|
46
|
+
return input.blocked ? STATUS_INDICATOR.waiting : STATUS_INDICATOR.ready;
|
|
47
|
+
}
|