@astrosheep/keiyaku 2.9.8 → 2.9.10
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 +50 -182
- package/build/.tsbuildinfo +1 -1
- package/build/agents/harness/control-types.js +18 -1
- package/build/agents/harness/index.js +2 -0
- package/build/agents/harness/outcome-error.js +81 -0
- package/build/agents/harness/projection.js +10 -7
- package/build/agents/harness/router.js +5 -1
- package/build/agents/providers/claude-agent-sdk/adapter.js +18 -4
- package/build/agents/providers/claude-agent-sdk/registration.js +11 -1
- package/build/agents/providers/claude-agent-sdk/session.js +19 -5
- package/build/agents/providers/codex-app-server/adapter.js +11 -6
- package/build/agents/providers/codex-app-server/events.js +67 -6
- package/build/agents/providers/codex-app-server/registration.js +11 -1
- package/build/agents/providers/opencode-sdk/adapter.js +8 -1
- package/build/agents/providers/opencode-sdk/events.js +24 -2
- package/build/agents/providers/opencode-sdk/registration.js +11 -1
- package/build/agents/providers/pi/checkpoint.js +9 -1
- package/build/agents/providers/pi/events.js +2 -0
- package/build/agents/providers/pi/registration.js +14 -1
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/akuma/meta.js +3 -3
- package/build/cli/commands/akuma/catalog.js +2 -2
- package/build/cli/commands/akuma/{view → show}/handler.js +5 -5
- package/build/cli/commands/akuma/{view → show}/meta.js +3 -3
- package/build/cli/commands/akuma.js +1 -1
- package/build/cli/commands/contract/amend/handler.js +5 -4
- package/build/cli/commands/contract/arc/handler.js +5 -4
- package/build/cli/commands/contract/audit/handler.js +2 -2
- package/build/cli/commands/contract/bind/handler.js +12 -3
- package/build/cli/commands/contract/bind/meta.js +45 -15
- package/build/cli/commands/contract/forfeit/handler.js +9 -5
- package/build/cli/commands/contract/log/handler.js +2 -2
- package/build/cli/commands/contract/petition/handler.js +34 -7
- package/build/cli/commands/contract/renew/handler.js +7 -7
- package/build/cli/commands/contract/renew/meta.js +3 -3
- package/build/cli/commands/metadata.js +10 -6
- package/build/cli/commands/projection/call/meta.js +1 -1
- package/build/cli/commands/projection/catalog.js +2 -0
- package/build/cli/commands/projection/history/handler.js +21 -0
- package/build/cli/commands/projection/history/meta.js +9 -0
- package/build/cli/commands/projection/shared.js +3 -4
- package/build/cli/commands/projection/status/handler.js +3 -3
- package/build/cli/commands/projection/wait/handler.js +20 -11
- package/build/cli/commands/task/add/handler.js +14 -5
- package/build/cli/commands/task/add/meta.js +2 -2
- package/build/cli/commands/task/catalog.js +4 -0
- package/build/cli/commands/task/done/handler.js +1 -4
- package/build/cli/commands/task/done/meta.js +1 -1
- package/build/cli/commands/task/drop/meta.js +1 -1
- package/build/cli/commands/task/hold/handler.js +3 -0
- package/build/cli/commands/task/hold/meta.js +8 -0
- package/build/cli/commands/task/log/handler.js +1 -1
- package/build/cli/commands/task/log/meta.js +2 -2
- package/build/cli/commands/task/resume/handler.js +3 -0
- package/build/cli/commands/task/resume/meta.js +8 -0
- package/build/cli/commands/task/shared.js +39 -14
- package/build/cli/commands/task/show/handler.js +1 -1
- package/build/cli/commands/task/show/meta.js +1 -1
- package/build/cli/commands/task/start/meta.js +1 -1
- package/build/cli/commands/task/stop/handler.js +1 -4
- package/build/cli/commands/task/stop/meta.js +1 -1
- package/build/cli/commands/task/update/handler.js +11 -3
- package/build/cli/commands/task/update/meta.js +3 -3
- package/build/cli/completion.js +3 -2
- package/build/cli/flags.js +51 -14
- package/build/cli/help.js +4 -1
- package/build/cli/index.js +40 -25
- package/build/cli/parse-flags.js +40 -7
- package/build/cli/parse-metadata.js +5 -2
- package/build/cli/parse-selectors.js +2 -3
- package/build/cli/parse.js +40 -6
- package/build/cli/projection-address.js +12 -10
- package/build/cli/render/amendment-warning.js +8 -0
- package/build/cli/render/arc.js +6 -2
- package/build/cli/render/audit.js +400 -81
- package/build/cli/render/kanshi.js +242 -79
- package/build/cli/render/lifecycle.js +56 -0
- package/build/cli/render/misc.js +24 -28
- package/build/cli/render/petition.js +5 -0
- package/build/cli/render/projection-activity.js +65 -29
- package/build/cli/render/projection-history.js +64 -0
- package/build/cli/render/shared.js +23 -9
- package/build/cli/render/status.js +13 -35
- package/build/cli/render/task.js +51 -26
- package/build/cli/render/terminal-failure.js +3 -1
- package/build/cli/render/wait.js +45 -69
- package/build/cli/subagent-guard.js +1 -1
- package/build/cli/types.js +1 -1
- package/build/config/env-keys.js +3 -1
- package/build/config/env.js +24 -1
- package/build/config/settings/schema.js +3 -1
- package/build/core/address-carrier.js +89 -0
- package/build/core/addressing.js +255 -196
- package/build/core/amend.js +115 -38
- package/build/core/amendment-criteria.js +17 -0
- package/build/core/amendment-warning.js +10 -0
- package/build/core/arc.js +184 -83
- package/build/core/audit/candidate.js +110 -9
- package/build/core/audit/coordinates.js +120 -65
- package/build/core/audit/evidence.js +19 -23
- package/build/core/audit/facade.js +34 -11
- package/build/core/audit/report.js +5 -5
- package/build/core/bind-reconciliation.js +390 -0
- package/build/core/bind-workspace.js +12 -20
- package/build/core/bind.js +242 -273
- package/build/core/call/call.js +1 -0
- package/build/core/call/context.js +46 -71
- package/build/core/call/prompt.js +6 -3
- package/build/core/context.js +49 -35
- package/build/core/contract-carrier-runtime.js +408 -0
- package/build/core/contract-carrier.js +270 -0
- package/build/core/contract-view.js +33 -27
- package/build/core/contract.js +5 -1
- package/build/core/derived-replay.js +207 -0
- package/build/core/draft.js +125 -57
- package/build/core/forfeit.js +113 -56
- package/build/core/identifier-slug.js +63 -13
- package/build/core/ids.js +4 -4
- package/build/core/lifecycle-history.js +35 -0
- package/build/core/lifecycle-recovery.js +117 -0
- package/build/core/lifecycle-runner.js +377 -0
- package/build/core/log.js +37 -11
- package/build/core/outcome-base.js +181 -0
- package/build/core/process-group.js +139 -0
- package/build/core/projection/generation/database.js +82 -7
- package/build/core/projection/generation/model.js +9 -36
- package/build/core/projection/generation/projection-generation-continuation.js +10 -22
- package/build/core/projection/generation/projection-generation-execution.js +13 -6
- package/build/core/projection/index.js +5 -4
- package/build/core/projection/projection-activity.js +29 -8
- package/build/core/projection/projection-alias.js +23 -10
- package/build/core/projection/projection-core.js +21 -7
- package/build/core/projection/projection-execution-observer.js +91 -39
- package/build/core/projection/projection-history.js +474 -0
- package/build/core/projection/projection-runner-lock.js +12 -0
- package/build/core/projection/projection-status-observation.js +365 -0
- package/build/core/projection/projection-status.js +35 -337
- package/build/core/projection/projection-terminal-failure.js +13 -8
- package/build/core/projection/projection-wait.js +7 -2
- package/build/core/projection/tell/launch-store.js +244 -0
- package/build/core/projection/tell/model.js +3 -3
- package/build/core/projection/tell/store.js +70 -118
- package/build/core/registry.js +22 -87
- package/build/core/renew-build.js +424 -0
- package/build/core/renew-plan.js +239 -0
- package/build/core/renew-rewrite.js +77 -0
- package/build/core/renew.js +295 -520
- package/build/core/repository-ledger/accepted-fold-read.js +19 -0
- package/build/core/repository-ledger/accepted-tail.js +116 -0
- package/build/core/repository-ledger/admission.js +38 -0
- package/build/core/repository-ledger/authoritative-transaction.js +1 -0
- package/build/core/repository-ledger/claim-evidence.js +147 -0
- package/build/core/repository-ledger/codec.js +297 -0
- package/build/core/repository-ledger/current-state-store.js +853 -0
- package/build/core/repository-ledger/fold-repository.js +375 -0
- package/build/core/repository-ledger/fold.js +248 -0
- package/build/core/repository-ledger/git-object-store.js +243 -0
- package/build/core/repository-ledger/history-read.js +15 -0
- package/build/core/repository-ledger/incremental-read.js +153 -0
- package/build/core/repository-ledger/index.js +15 -0
- package/build/core/repository-ledger/inventory-plan.js +75 -0
- package/build/core/repository-ledger/inventory.js +310 -0
- package/build/core/repository-ledger/publication-admission.js +125 -0
- package/build/core/repository-ledger/publication.js +353 -0
- package/build/core/repository-ledger/read-model.js +469 -0
- package/build/core/repository-ledger/transaction-membership.js +78 -0
- package/build/core/repository-ledger/traversal.js +404 -0
- package/build/core/repository-ledger/write-transaction.js +339 -0
- package/build/core/seal.js +168 -161
- package/build/core/settlement/claim-delivery.js +42 -215
- package/build/core/settlement/claim.js +235 -153
- package/build/core/settlement/index.js +4 -4
- package/build/core/settlement/petition-claim-gates.js +52 -33
- package/build/core/settlement/petition-forfeit.js +12 -5
- package/build/core/settlement/petition-head-guard.js +8 -5
- package/build/core/settlement/petition-preview.js +68 -56
- package/build/core/settlement/petition-window.js +50 -0
- package/build/core/settlement/petition.js +252 -131
- package/build/core/settlement/queue-read-model.js +72 -95
- package/build/core/settlement/queue-seat-allocation.js +35 -126
- package/build/core/settlement/queue.js +1 -1
- package/build/core/settlement/settlement.js +172 -80
- package/build/core/settlement/verdict.js +112 -66
- package/build/core/settlement/verification-coordination.js +305 -0
- package/build/core/settlement/verification-supervisor.js +275 -0
- package/build/core/settlement/verification.js +398 -31
- package/build/core/status/board.js +125 -127
- package/build/core/status/lifecycle.js +7 -80
- package/build/core/structured-query.js +23 -0
- package/build/core/target-ref.js +1 -1
- package/build/core/task/board.js +59 -24
- package/build/core/task/commands.js +181 -33
- package/build/core/task/coordinate.js +56 -0
- package/build/core/task/document.js +25 -9
- package/build/core/task/index.js +7 -4
- package/build/core/task/query.js +17 -27
- package/build/core/task/settlement-git.js +164 -179
- package/build/core/task/settlement-policy.js +15 -11
- package/build/core/task/source-board.js +31 -13
- package/build/core/task/task-bind-preparation.js +193 -0
- package/build/core/task/task-contract.js +102 -193
- package/build/core/task/task-file-transaction.js +171 -0
- package/build/core/task/task-git-runtime.js +76 -14
- package/build/core/task/task-git-store.js +68 -169
- package/build/core/task/task-store-repository.js +13 -6
- package/build/core/task/task-worktree.js +6 -33
- package/build/core/task/task.js +1 -1
- package/build/core/task/tree.js +3 -3
- package/build/core/task/validation.js +4 -3
- package/build/core/transcripts.js +93 -1
- package/build/core/worktree-bootstrap.js +44 -36
- package/build/core/worktree-path.js +210 -77
- package/build/flow-error.js +7 -7
- package/build/generated/version.js +2 -2
- package/build/git/core.js +76 -13
- package/build/git/refs.js +168 -46
- package/build/git/streaming-batch.js +73 -13
- package/package.json +1 -1
- package/skills/keiyaku/SKILL.md +1 -1
- package/skills/keiyaku-akuma/SKILL.md +3 -3
- package/skills/keiyaku-task/SKILL.md +4 -2
- package/skills/keiyaku-workflow/SKILL.md +88 -203
- package/build/core/entry.js +0 -305
- package/build/core/ledger-batch.js +0 -194
- package/build/core/ledger.js +0 -84
- package/build/core/projection/leash.js +0 -87
- package/build/core/ref-log.js +0 -119
- package/build/core/renew-session.js +0 -128
- package/build/core/status/ledger-batch.js +0 -1
- package/build/core/status/reconciliation.js +0 -137
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import { compactText } from "./compact-text.js";
|
|
2
|
-
import { displayColumns, fitVariableLine, resolveLineColumns, truncateMiddleColumns } from "./line-width.js";
|
|
2
|
+
import { displayColumns, fitVariableLine, resolveLineColumns, truncateMiddleColumns, truncateColumns } from "./line-width.js";
|
|
3
3
|
import { presentFoldedToolActivity, } from "./tool-presentation.js";
|
|
4
4
|
import { presentLedgerPath, summarizeToolLedger } from "./tool-ledger-rollup.js";
|
|
5
5
|
const TIME_GUTTER_WIDTH = 5;
|
|
6
6
|
const VERB_WIDTH = 7;
|
|
7
7
|
const SILENCE_THRESHOLD_MS = 60_000;
|
|
8
8
|
const TIMELINE_GAP_MARKER = "⋮";
|
|
9
|
+
/** Keep the renderer and its gap grammar while giving Kanshi its smaller live window. */
|
|
10
|
+
export function selectProjectionActivityWindow(activity, ordinaryRows) {
|
|
11
|
+
// A Kanshi flow narrows only the settled history window. Unfinished activity
|
|
12
|
+
// remains pinned in its timeline position; it is not another history row.
|
|
13
|
+
const selected = activity.window.slice(-ordinaryRows);
|
|
14
|
+
const selectedOrders = new Set([
|
|
15
|
+
...selected.map((row) => row.order),
|
|
16
|
+
...activity.pinned.map((row) => row.order),
|
|
17
|
+
]);
|
|
18
|
+
return {
|
|
19
|
+
activity: {
|
|
20
|
+
...activity,
|
|
21
|
+
window: selected,
|
|
22
|
+
// Turn seals are a wait concern. Kanshi's narrow operational flow contains
|
|
23
|
+
// only ordinary activity plus durable tells.
|
|
24
|
+
timeline: activity.timeline.filter((row) => selectedOrders.has(row.order)),
|
|
25
|
+
},
|
|
26
|
+
leadingOmittedCount: activity.omittedSettledCount + activity.window.length - selected.length,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
9
29
|
export function formatTimelineDuration(ms) {
|
|
10
30
|
const totalSeconds = Math.max(0, Math.floor(ms / 1_000));
|
|
11
31
|
if (totalSeconds < 60)
|
|
@@ -40,6 +60,14 @@ export function formatWallClock(at) {
|
|
|
40
60
|
return " : │";
|
|
41
61
|
return `${String(value.getHours()).padStart(2, "0")}:${String(value.getMinutes()).padStart(2, "0")}│`;
|
|
42
62
|
}
|
|
63
|
+
/** One durable-tell line dialect shared by wait and the embedded Kanshi flow. */
|
|
64
|
+
export function renderPendingProjectionTell(tell, input) {
|
|
65
|
+
const createdAtMs = Date.parse(tell.createdAt);
|
|
66
|
+
const age = Math.max(0, input.anchorMs - (Number.isFinite(createdAtMs) ? createdAtMs : input.anchorMs));
|
|
67
|
+
const fixed = `${formatWallClock(tell.createdAt)} ${"told".padEnd(VERB_WIDTH)} `;
|
|
68
|
+
const tail = ` — ${formatTimelineDuration(age)}…`;
|
|
69
|
+
return `${fixed}${truncateColumns(`“${tell.text}”`, Math.max(0, input.maxColumns - displayColumns(fixed) - displayColumns(tail)))}${input.renderUnconsumedTail?.(tail) ?? tail}`;
|
|
70
|
+
}
|
|
43
71
|
function commonPrefix(left, right) {
|
|
44
72
|
const a = [...left];
|
|
45
73
|
const b = [...right];
|
|
@@ -73,8 +101,8 @@ function compressedPrefix(prefix) {
|
|
|
73
101
|
function timelineGutter(label, spine) {
|
|
74
102
|
return label || `${"".padStart(TIME_GUTTER_WIDTH)}${spine}`;
|
|
75
103
|
}
|
|
76
|
-
function renderTimelineGap(
|
|
77
|
-
return fitVariableLine(`${timelineGutter("", TIMELINE_GAP_MARKER)} `, `${
|
|
104
|
+
function renderTimelineGap(omittedRowCount, maxColumns) {
|
|
105
|
+
return fitVariableLine(`${timelineGutter("", TIMELINE_GAP_MARKER)} `, `${omittedRowCount} more`, maxColumns);
|
|
78
106
|
}
|
|
79
107
|
function compactTokens(value) {
|
|
80
108
|
if (value < 1_000)
|
|
@@ -148,13 +176,15 @@ function renderTerminalRollup(activity, input) {
|
|
|
148
176
|
? fitVariableLine(`${endPrefix} `, segments.join(" · "), input.maxColumns)
|
|
149
177
|
: endPrefix,
|
|
150
178
|
});
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
179
|
+
if (input.includeFiles !== false) {
|
|
180
|
+
for (const file of summary.files) {
|
|
181
|
+
const repeat = file.count > 1 ? ` ×${file.count}` : "";
|
|
182
|
+
const diffstat = file.diffstat ? ` +${file.diffstat.additions} −${file.diffstat.deletions}` : "";
|
|
183
|
+
rows.push({ kind: "file", line: fitVariableLine("", `${file.path}${repeat}${diffstat}`, input.maxColumns) });
|
|
184
|
+
}
|
|
185
|
+
if (summary.hiddenFileCount > 0) {
|
|
186
|
+
rows.push({ kind: "file", line: fitVariableLine("", `… ${summary.hiddenFileCount} more files`, input.maxColumns) });
|
|
187
|
+
}
|
|
158
188
|
}
|
|
159
189
|
return { rows, hasMutationFiles: summary.files.length > 0 };
|
|
160
190
|
}
|
|
@@ -174,33 +204,37 @@ function timelineEntries(activity) {
|
|
|
174
204
|
export function renderProjectionActivity(activity, input) {
|
|
175
205
|
const lines = [];
|
|
176
206
|
const rowKinds = [];
|
|
207
|
+
const rowAts = [];
|
|
177
208
|
let priorAtMs;
|
|
178
|
-
let priorOrder;
|
|
179
209
|
let priorMinute;
|
|
180
210
|
let priorCompletedRan;
|
|
181
211
|
let hasEndAnchor = false;
|
|
182
212
|
let lastRunningTool;
|
|
213
|
+
const interrupted = input.state === "dead" || input.state === "lost" || input.state === "dismissed";
|
|
183
214
|
const maxColumns = input.maxColumns ?? resolveLineColumns();
|
|
184
215
|
const entries = timelineEntries(activity);
|
|
185
|
-
const
|
|
216
|
+
const gapBeforeOrder = input.leadingOmittedCount ? activity.window[0]?.order : undefined;
|
|
217
|
+
let gapEmitted = false;
|
|
218
|
+
const pushRow = (line, kind, at) => {
|
|
186
219
|
lines.push(line);
|
|
187
220
|
rowKinds.push(kind);
|
|
221
|
+
rowAts.push(at);
|
|
188
222
|
return true;
|
|
189
223
|
};
|
|
190
224
|
for (let index = 0; index < entries.length; index += 1) {
|
|
191
225
|
const entry = entries[index];
|
|
192
226
|
const atMs = Date.parse(entry.at);
|
|
193
|
-
if (priorOrder !== undefined && entry.order > priorOrder + 1) {
|
|
194
|
-
pushRow(renderTimelineGap(entry.order - priorOrder - 1, maxColumns), "activity");
|
|
195
|
-
}
|
|
196
|
-
priorOrder = entry.order;
|
|
197
227
|
if (entry.kind === "clock") {
|
|
198
228
|
if (Number.isFinite(atMs))
|
|
199
229
|
priorAtMs = atMs;
|
|
200
230
|
continue;
|
|
201
231
|
}
|
|
202
|
-
if (
|
|
203
|
-
pushRow(
|
|
232
|
+
if (!gapEmitted && input.leadingOmittedCount && gapBeforeOrder !== undefined && entry.row.order >= gapBeforeOrder) {
|
|
233
|
+
pushRow(renderTimelineGap(input.leadingOmittedCount, maxColumns), "activity", entry.at);
|
|
234
|
+
gapEmitted = true;
|
|
235
|
+
}
|
|
236
|
+
if (input.showSilence !== false && priorAtMs !== undefined && Number.isFinite(atMs) && atMs - priorAtMs >= SILENCE_THRESHOLD_MS) {
|
|
237
|
+
pushRow(fitVariableLine(`${"".padStart(TIME_GUTTER_WIDTH)}┆ `, `${formatTimelineDuration(atMs - priorAtMs)} pass in silence`, maxColumns), "silence", entry.at);
|
|
204
238
|
}
|
|
205
239
|
if (Number.isFinite(atMs))
|
|
206
240
|
priorAtMs = atMs;
|
|
@@ -211,14 +245,14 @@ export function renderProjectionActivity(activity, input) {
|
|
|
211
245
|
priorMinute = minute;
|
|
212
246
|
const spine = row.kind === "turn"
|
|
213
247
|
? "├"
|
|
214
|
-
:
|
|
248
|
+
: interrupted
|
|
215
249
|
? "┆"
|
|
216
250
|
: "│";
|
|
217
251
|
if (row.kind === "ran") {
|
|
218
252
|
const duration = formatActionDuration(row.durationMs);
|
|
219
253
|
const activityState = row.state === "completed"
|
|
220
254
|
? "completed"
|
|
221
|
-
:
|
|
255
|
+
: interrupted
|
|
222
256
|
? "interrupted"
|
|
223
257
|
: input.state === "stalled" || input.state === "unknown"
|
|
224
258
|
? "unresolved"
|
|
@@ -235,22 +269,22 @@ export function renderProjectionActivity(activity, input) {
|
|
|
235
269
|
}
|
|
236
270
|
priorCompletedRan = row.state === "completed" ? presentation.variableText : undefined;
|
|
237
271
|
const budget = Math.max(0, maxColumns - displayColumns(fixed) - displayColumns(presentation.fixedSuffix));
|
|
238
|
-
pushRow(`${fixed}${truncateMiddleColumns(variable, budget)}${presentation.fixedSuffix}`, "activity");
|
|
272
|
+
pushRow(`${fixed}${truncateMiddleColumns(variable, budget)}${presentation.fixedSuffix}`, "activity", entry.at);
|
|
239
273
|
continue;
|
|
240
274
|
}
|
|
241
275
|
if (row.kind === "said") {
|
|
242
276
|
priorCompletedRan = undefined;
|
|
243
|
-
pushRow(fitVariableLine(`${timelineGutter(label, spine)} ${"said".padEnd(VERB_WIDTH)} `, `“${compactText(row.text)}”`, maxColumns), "activity");
|
|
277
|
+
pushRow(fitVariableLine(`${timelineGutter(label, spine)} ${"said".padEnd(VERB_WIDTH)} `, `“${compactText(row.text)}”`, maxColumns), "activity", entry.at);
|
|
244
278
|
}
|
|
245
279
|
else if (row.kind === "thought") {
|
|
246
280
|
priorCompletedRan = undefined;
|
|
247
281
|
const text = `${compactText(row.text)}${row.truncated && !row.text.endsWith("…") ? "…" : ""}`;
|
|
248
282
|
const duration = formatActionDuration(row.durationMs);
|
|
249
|
-
pushRow(fitVariableLine(`${timelineGutter(label, spine)} ${"thought".padEnd(VERB_WIDTH)} `, `${duration ? `${duration} — ` : ""}“${text}”`, maxColumns), "activity");
|
|
283
|
+
pushRow(fitVariableLine(`${timelineGutter(label, spine)} ${"thought".padEnd(VERB_WIDTH)} `, `${duration ? `${duration} — ` : ""}“${text}”`, maxColumns), "activity", entry.at);
|
|
250
284
|
}
|
|
251
285
|
else if (row.kind === "warning") {
|
|
252
286
|
priorCompletedRan = undefined;
|
|
253
|
-
pushRow(fitVariableLine(`${timelineGutter(label, spine)} ${"warning".padEnd(VERB_WIDTH)} `, warningText(row), maxColumns), "activity");
|
|
287
|
+
pushRow(fitVariableLine(`${timelineGutter(label, spine)} ${"warning".padEnd(VERB_WIDTH)} `, warningText(row), maxColumns), "activity", entry.at);
|
|
254
288
|
}
|
|
255
289
|
else {
|
|
256
290
|
priorCompletedRan = undefined;
|
|
@@ -258,7 +292,7 @@ export function renderProjectionActivity(activity, input) {
|
|
|
258
292
|
? ` · ${compactTokens(row.inputTokens)}▸${compactTokens(row.outputTokens)} tok`
|
|
259
293
|
: "";
|
|
260
294
|
const cost = row.costUsd !== undefined ? ` · $${row.costUsd.toFixed(2)}` : "";
|
|
261
|
-
pushRow(fitVariableLine(`${"".padStart(TIME_GUTTER_WIDTH)}├ `, `turn ${row.turn}${usage}${cost}`, maxColumns), "activity");
|
|
295
|
+
pushRow(fitVariableLine(`${"".padStart(TIME_GUTTER_WIDTH)}├ `, `turn ${row.turn}${usage}${cost}`, maxColumns), "activity", entry.at);
|
|
262
296
|
}
|
|
263
297
|
}
|
|
264
298
|
for (const row of activity.pinned) {
|
|
@@ -267,10 +301,10 @@ export function renderProjectionActivity(activity, input) {
|
|
|
267
301
|
}
|
|
268
302
|
if (input.showPlan && activity.plan) {
|
|
269
303
|
const planAtMs = Date.parse(activity.plan.at);
|
|
270
|
-
if (priorAtMs !== undefined && Number.isFinite(planAtMs) && planAtMs - priorAtMs >= SILENCE_THRESHOLD_MS) {
|
|
271
|
-
pushRow(fitVariableLine(`${"".padStart(TIME_GUTTER_WIDTH)}┆ `, `${formatTimelineDuration(planAtMs - priorAtMs)} pass in silence`, maxColumns), "silence");
|
|
304
|
+
if (input.showSilence !== false && priorAtMs !== undefined && Number.isFinite(planAtMs) && planAtMs - priorAtMs >= SILENCE_THRESHOLD_MS) {
|
|
305
|
+
pushRow(fitVariableLine(`${"".padStart(TIME_GUTTER_WIDTH)}┆ `, `${formatTimelineDuration(planAtMs - priorAtMs)} pass in silence`, maxColumns), "silence", activity.plan.at);
|
|
272
306
|
}
|
|
273
|
-
pushRow(renderPlan(activity.plan, maxColumns), "plan");
|
|
307
|
+
pushRow(renderPlan(activity.plan, maxColumns), "plan", activity.plan.at);
|
|
274
308
|
}
|
|
275
309
|
let hasMutationFiles = false;
|
|
276
310
|
if (["returned", "dead", "lost", "dismissed"].includes(input.state)) {
|
|
@@ -278,10 +312,11 @@ export function renderProjectionActivity(activity, input) {
|
|
|
278
312
|
anchorMs: input.anchorMs,
|
|
279
313
|
...(input.workspaceRoot ? { workspaceRoot: input.workspaceRoot } : {}),
|
|
280
314
|
...(input.terminalDiagnostic ? { diagnostic: input.terminalDiagnostic } : {}),
|
|
315
|
+
includeFiles: input.showTerminalFiles !== false,
|
|
281
316
|
maxColumns,
|
|
282
317
|
});
|
|
283
318
|
for (const row of rollup.rows) {
|
|
284
|
-
pushRow(row.line, row.kind);
|
|
319
|
+
pushRow(row.line, row.kind, new Date(input.anchorMs).toISOString());
|
|
285
320
|
}
|
|
286
321
|
hasEndAnchor = true;
|
|
287
322
|
hasMutationFiles = rollup.hasMutationFiles;
|
|
@@ -289,6 +324,7 @@ export function renderProjectionActivity(activity, input) {
|
|
|
289
324
|
return {
|
|
290
325
|
lines,
|
|
291
326
|
rowKinds,
|
|
327
|
+
rowAts,
|
|
292
328
|
...(lastRunningTool ? { lastRunningTool } : {}),
|
|
293
329
|
hasEndAnchor,
|
|
294
330
|
hasMutationFiles,
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { renderProjectionActivity } from "./projection-activity.js";
|
|
2
|
+
function fact(value) {
|
|
3
|
+
return value ?? "unavailable";
|
|
4
|
+
}
|
|
5
|
+
function consequenceLines(run) {
|
|
6
|
+
const consequences = run.consequences;
|
|
7
|
+
if (consequences === null)
|
|
8
|
+
return [];
|
|
9
|
+
if (consequences.retention === "unavailable") {
|
|
10
|
+
return [`consequences: unavailable · ${consequences.reason}`];
|
|
11
|
+
}
|
|
12
|
+
const retained = (name, value, detail) => value.retention === "retained" ? `${name}: retained · ${detail}` : `${name}: unavailable · ${value.reason}`;
|
|
13
|
+
return [
|
|
14
|
+
`review: unavailable · ${consequences.review.reason}`,
|
|
15
|
+
retained("petition", consequences.petition, consequences.petition.retention === "retained" ? `${consequences.petition.intent} · ${consequences.petition.objectId}` : ""),
|
|
16
|
+
retained("verdict", consequences.verdict, consequences.verdict.retention === "retained" ? `${consequences.verdict.result} · ${consequences.verdict.objectId}` : ""),
|
|
17
|
+
retained("claim", consequences.claim, consequences.claim.retention === "retained" ? `${consequences.claim.objectId} · ${consequences.claim.mergeCommit}` : ""),
|
|
18
|
+
retained("landed commit", consequences.landedCommit, consequences.landedCommit.retention === "retained" ? consequences.landedCommit.commit : ""),
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
function runLines(run) {
|
|
22
|
+
return [
|
|
23
|
+
`${run.id}${run.alias ? ` (${run.alias})` : ""} · ${run.outcome}`,
|
|
24
|
+
`akuma: ${fact(run.akuma)} · provider: ${fact(run.provider)}${run.pid === null ? "" : ` · pid: ${run.pid}`} · role: ${run.role}`,
|
|
25
|
+
`contract: ${fact(run.contractId)}`,
|
|
26
|
+
`created: ${fact(run.mintedAt)}${run.terminalAt ? ` · terminal: ${run.terminalAt}` : ""}`,
|
|
27
|
+
...(run.generation ? [`generation: ${run.generation.executionId} · created: ${run.generation.createdAt}${run.generation.adoptedAt ? ` · adopted: ${run.generation.adoptedAt}` : ""}`] : []),
|
|
28
|
+
`activity: ${run.activityRetention} · ${run.activityCount} retained${run.activityRange ? ` · ${run.activityRange.first}-${run.activityRange.last}` : ""}`,
|
|
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
|
+
...(run.artifact ? [`artifact: ${fact(run.artifact.id)} · ${run.artifact.retention}${run.artifact.path ? ` · path: ${run.artifact.path}` : ""}`] : []),
|
|
31
|
+
...consequenceLines(run),
|
|
32
|
+
...run.diagnostics.map((diagnostic) => `diagnostic: ${diagnostic}`),
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
export function renderProjectionHistoryList(runs) {
|
|
36
|
+
return runs.flatMap((run, index) => index === 0 ? runLines(run) : ["", ...runLines(run)]).join("\n");
|
|
37
|
+
}
|
|
38
|
+
export function renderProjectionHistoryDetail(detail) {
|
|
39
|
+
const lines = runLines(detail);
|
|
40
|
+
if (!detail.activity || detail.activity.retainedTimeline.length === 0)
|
|
41
|
+
return lines.join("\n");
|
|
42
|
+
const state = detail.outcome === "done" ? "returned"
|
|
43
|
+
: detail.outcome === "out" ? "running"
|
|
44
|
+
: detail.outcome === "failed" || detail.outcome === "dead" ? "dead"
|
|
45
|
+
: detail.outcome === "lost" ? "lost"
|
|
46
|
+
: detail.outcome === "killed" || detail.outcome === "dismissed" ? "dismissed"
|
|
47
|
+
: detail.outcome === "startup-timeout" ? "stalled"
|
|
48
|
+
: "unknown";
|
|
49
|
+
const activity = renderProjectionActivity({
|
|
50
|
+
...detail.activity,
|
|
51
|
+
timeline: detail.activity.retainedTimeline,
|
|
52
|
+
omittedSettledCount: 0,
|
|
53
|
+
}, {
|
|
54
|
+
anchorMs: Date.now(),
|
|
55
|
+
state,
|
|
56
|
+
showPlan: false,
|
|
57
|
+
showSilence: false,
|
|
58
|
+
showTerminalFiles: false,
|
|
59
|
+
});
|
|
60
|
+
return [...lines, "", ...activity.lines].join("\n");
|
|
61
|
+
}
|
|
62
|
+
export function projectionHistoryJson(value) {
|
|
63
|
+
return `${JSON.stringify(value)}\n`;
|
|
64
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { KEIYAKU_FILE } from "../../keiyaku.js";
|
|
2
|
+
import { isCompleteLifecycleOutcome } from "../../core/outcome-base.js";
|
|
2
3
|
import { commissionSlug, formatCommissionCoordinate } from "../../core/ids.js";
|
|
3
4
|
import { assembleResponse, buildSection, DISPLAY_TEXT_MAX_CHARS, FORMAT_LIST_MAX_ITEM_CHARS, FORMAT_LIST_MAX_ITEMS, formatMaybe, formatWarnings, shellQuote, truncateForDisplay, } from "./format.js";
|
|
4
5
|
import { WARNING_SECTION_TITLE } from "./response-style.js";
|
|
@@ -63,6 +64,26 @@ export function buildBindResponse(result, cwd) {
|
|
|
63
64
|
...(overlapWarnings.length > 0 ? ["Warnings:", ...overlapWarnings] : []),
|
|
64
65
|
].join("\n"), payload);
|
|
65
66
|
}
|
|
67
|
+
export function buildContainedBindResponse(result) {
|
|
68
|
+
const payload = {
|
|
69
|
+
family: result.family,
|
|
70
|
+
completion: result.completion,
|
|
71
|
+
committed: result.committed,
|
|
72
|
+
heads: result.heads,
|
|
73
|
+
reconciliationKey: result.reconciliationKey,
|
|
74
|
+
prerequisites: result.prerequisites,
|
|
75
|
+
downstream: result.downstream,
|
|
76
|
+
replay: result.replay,
|
|
77
|
+
carrier: result.carrier,
|
|
78
|
+
cancellationObserved: result.cancellationObserved,
|
|
79
|
+
};
|
|
80
|
+
return coreTextResponse(`Bind committed with incomplete replay · head ${result.committed.head} · reconcile ${result.reconciliationKey}`, payload);
|
|
81
|
+
}
|
|
82
|
+
export function buildBindOutcomeResponse(result, cwd) {
|
|
83
|
+
return isCompleteLifecycleOutcome(result)
|
|
84
|
+
? buildBindResponse(result, cwd)
|
|
85
|
+
: buildContainedBindResponse(result);
|
|
86
|
+
}
|
|
66
87
|
function renderScopeOverlapWarnings(overlaps) {
|
|
67
88
|
const overlapsByCounterparty = new Map();
|
|
68
89
|
for (const overlap of overlaps) {
|
|
@@ -105,10 +126,8 @@ export function buildForfeitResponse(result) {
|
|
|
105
126
|
`Could not remove contract worktree ${result.cleanup.worktreeRemoveFailure.path}: ${result.cleanup.worktreeRemoveFailure.reason}`,
|
|
106
127
|
]
|
|
107
128
|
: []),
|
|
108
|
-
...(result.cleanup.
|
|
109
|
-
? [
|
|
110
|
-
`Could not delete contract branch: ${redactBranchReference(result.cleanup.branchDeleteFailure.reason, result.cleanup.branchDeleteFailure.name)}`,
|
|
111
|
-
]
|
|
129
|
+
...(result.cleanup.deliveryRef.status === "mismatch"
|
|
130
|
+
? [`Delivery ref ${result.cleanup.deliveryRef.mismatch.ref} remains present at ${result.cleanup.deliveryRef.mismatch.observed.head}; terminal replay preserved it as a projected-surface mismatch.`]
|
|
112
131
|
: []),
|
|
113
132
|
];
|
|
114
133
|
if (warnings.length === 0) {
|
|
@@ -117,11 +136,6 @@ export function buildForfeitResponse(result) {
|
|
|
117
136
|
const warningSection = buildSection(WARNING_SECTION_TITLE, formatWarnings(warnings));
|
|
118
137
|
return prependAddressReceipt(coreTextResponse(assembleResponse(base, "", [warningSection].filter((section) => section !== null)), payload), result.address);
|
|
119
138
|
}
|
|
120
|
-
function redactBranchReference(message, branch) {
|
|
121
|
-
return message
|
|
122
|
-
.replaceAll(`refs/heads/${branch}`, "contract branch")
|
|
123
|
-
.replaceAll(branch, "contract branch");
|
|
124
|
-
}
|
|
125
139
|
export const RULES_SECTION_MAX_CHARS = 5000;
|
|
126
140
|
export const INFO_SECTION_TITLE = "Info";
|
|
127
141
|
export const HINTS_SECTION_TITLE = "Hints";
|
|
@@ -7,7 +7,6 @@ import { renderTerminalFailureFace, terminalFailureCodeSuffix } from "./terminal
|
|
|
7
7
|
import { formatTellCommand } from "./shared.js";
|
|
8
8
|
export const STATUS_DISEASES_SECTION_TITLE = "Diseases";
|
|
9
9
|
export const STATUS_PROJECTION_SECTION_TITLE = "akuma";
|
|
10
|
-
export const STATUS_CLAIM_RECEIPTS_SECTION_TITLE = "claim receipts";
|
|
11
10
|
function projectionGlyph(state) {
|
|
12
11
|
switch (state) {
|
|
13
12
|
case "out":
|
|
@@ -37,15 +36,19 @@ export function renderSettingsDiseasesSection(diseases, taskDiseases = []) {
|
|
|
37
36
|
return `${STATUS_DISEASES_SECTION_TITLE}\n${lines.join("\n")}\n`;
|
|
38
37
|
}
|
|
39
38
|
function renderTaskStatusSection(tasks) {
|
|
40
|
-
if (!tasks || tasks.inProgress + tasks.ready + tasks.blocked === 0)
|
|
39
|
+
if (!tasks || tasks.inProgress + tasks.onHold + tasks.ready + tasks.blocked === 0)
|
|
41
40
|
return "";
|
|
42
41
|
const segments = [
|
|
43
42
|
tasks.inProgress > 0 ? `${tasks.inProgress} in_progress` : undefined,
|
|
43
|
+
tasks.onHold > 0 ? `${tasks.onHold} on hold` : undefined,
|
|
44
44
|
tasks.ready > 0 ? `${tasks.ready} ready` : undefined,
|
|
45
45
|
tasks.blocked > 0 ? `${tasks.blocked} blocked` : undefined,
|
|
46
46
|
].filter((segment) => segment !== undefined);
|
|
47
47
|
const lines = [`tasks · ${segments.join(" / ")}`];
|
|
48
|
-
lines.push(...tasks.topTasks.map((task) =>
|
|
48
|
+
lines.push(...tasks.topTasks.map((task) => {
|
|
49
|
+
const onHold = task.state === "on_hold";
|
|
50
|
+
return ` ${task.id} · P${task.pri} · ${onHold ? "on hold" : "in_progress"} · age ${formatAgeMs(task.ageMs)} · ${onHold ? "updated" : "active"} ${formatAgeMs(task.activityAgeMs)} · ${task.title}`;
|
|
51
|
+
}));
|
|
49
52
|
if (tasks.omitted > 0) {
|
|
50
53
|
lines.push(` · +${tasks.omitted} more — keiyaku task ls`);
|
|
51
54
|
}
|
|
@@ -69,12 +72,12 @@ function terminalFailureSuffix(row) {
|
|
|
69
72
|
function renderProjectionOmission(board) {
|
|
70
73
|
if (!board.omitted)
|
|
71
74
|
return undefined;
|
|
72
|
-
const counts = ["failed", "dead", "done", "killed", "dismissed"
|
|
75
|
+
const counts = ["failed", "dead", "done", "killed", "dismissed"]
|
|
73
76
|
.flatMap((state) => {
|
|
74
77
|
const count = board.omitted?.byState[state] ?? 0;
|
|
75
78
|
return count > 0 ? [`${count} ${state}`] : [];
|
|
76
79
|
});
|
|
77
|
-
return
|
|
80
|
+
return counts.length > 0 ? `+ ${counts.join(" · ")}` : undefined;
|
|
78
81
|
}
|
|
79
82
|
function renderProjectionAge(row) {
|
|
80
83
|
const duration = formatAgeMs(row.durationMs) ?? "?";
|
|
@@ -99,10 +102,9 @@ function renderProjectionAge(row) {
|
|
|
99
102
|
return facts;
|
|
100
103
|
}
|
|
101
104
|
function renderProjectionTellCounts(row) {
|
|
102
|
-
const { inbox, inflight, submitted, consumed } = row.tellCounts;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return ` tell ${inbox}▸${inflight}▸${submitted}▸${consumed}`;
|
|
105
|
+
const { inbox, inflight, submitted, seen, consumed } = row.tellCounts;
|
|
106
|
+
const total = inbox + inflight + submitted + seen + consumed;
|
|
107
|
+
return total === 0 ? "" : ` tell ${total} told`;
|
|
106
108
|
}
|
|
107
109
|
function projectionActivityState(row) {
|
|
108
110
|
switch (row.state) {
|
|
@@ -194,42 +196,18 @@ export function renderProjectionStatusSection(board) {
|
|
|
194
196
|
lines.push(omission);
|
|
195
197
|
return `${STATUS_PROJECTION_SECTION_TITLE}\n${lines.join("\n")}\n`;
|
|
196
198
|
}
|
|
197
|
-
function renderClaimReconciliationSection(recon) {
|
|
198
|
-
if (!recon)
|
|
199
|
-
return "";
|
|
200
|
-
const lines = recon.unclaimedSegments.map((seg) => `${recon.defaultBranch} ${shortCommitHash(seg.oldHead)}▸${shortCommitHash(seg.newHead)} · ${seg.commitCount} commits · 无 claim 收据`);
|
|
201
|
-
lines.push(...recon.receiptIssues.map((issue) => `receipt line ${issue.line} · ${issue.reason}`));
|
|
202
|
-
if (lines.length === 0)
|
|
203
|
-
return "";
|
|
204
|
-
return `${STATUS_CLAIM_RECEIPTS_SECTION_TITLE}\n${lines.join("\n")}\n`;
|
|
205
|
-
}
|
|
206
199
|
/**
|
|
207
200
|
* Status mouth: kanshi board plus optional diseases section.
|
|
208
201
|
* Healthy boards (no diseases) are byte-identical to renderKanshiBoard alone.
|
|
209
202
|
*/
|
|
210
203
|
export function renderStatusBoard(board) {
|
|
211
204
|
const boardText = renderKanshiBoard(board);
|
|
212
|
-
const projectionText = renderProjectionStatusSection(board.projections);
|
|
213
|
-
const receiptsText = renderClaimReconciliationSection(board.claimReconciliation);
|
|
214
|
-
const taskText = renderTaskStatusSection(board.tasks);
|
|
215
205
|
const taskDiseaseText = [
|
|
216
206
|
...(board.tasks?.diseases ?? []).map((disease) => disease.message),
|
|
217
207
|
...(board.tasks?.diagnostic ? [board.tasks.diagnostic] : []),
|
|
218
208
|
];
|
|
219
209
|
const diseasesText = renderSettingsDiseasesSection(board.diseases, taskDiseaseText);
|
|
220
|
-
if (
|
|
210
|
+
if (diseasesText === "")
|
|
221
211
|
return boardText;
|
|
222
|
-
|
|
223
|
-
if (board.targetFilter !== null && (projectionText || receiptsText || diseasesText)) {
|
|
224
|
-
sections.push("repository-wide — not filtered by target");
|
|
225
|
-
}
|
|
226
|
-
if (projectionText)
|
|
227
|
-
sections.push(projectionText.trimEnd());
|
|
228
|
-
if (receiptsText)
|
|
229
|
-
sections.push(receiptsText.trimEnd());
|
|
230
|
-
if (taskText)
|
|
231
|
-
sections.push(taskText.trimEnd());
|
|
232
|
-
if (diseasesText)
|
|
233
|
-
sections.push(diseasesText.trimEnd());
|
|
234
|
-
return `${sections.join("\n\n")}\n`;
|
|
212
|
+
return `${[boardText.trimEnd(), diseasesText.trimEnd()].join("\n\n")}\n`;
|
|
235
213
|
}
|
package/build/cli/render/task.js
CHANGED
|
@@ -8,13 +8,29 @@ export function deriveTaskDisplay(task) {
|
|
|
8
8
|
return display === "bound" ? `bound(${shortContractId(task.contractId)})` : display;
|
|
9
9
|
}
|
|
10
10
|
function renderTaskRowWithId(task, id) {
|
|
11
|
-
return `${id} · P${task.pri} · ${deriveTaskDisplay(task)} · ${task.title}`;
|
|
11
|
+
return `${id} · ${task.namespace ?? "hub"} · P${task.pri} · ${deriveTaskDisplay(task)} · ${task.title}`;
|
|
12
12
|
}
|
|
13
13
|
export function renderTaskListRow(task) {
|
|
14
|
-
return renderTaskRowWithId(task, task.
|
|
14
|
+
return renderTaskRowWithId(task, task.coordinate);
|
|
15
15
|
}
|
|
16
16
|
export function renderTaskMutationRow(task) {
|
|
17
|
-
return renderTaskRowWithId(task, task.
|
|
17
|
+
return renderTaskRowWithId(task, task.coordinate);
|
|
18
|
+
}
|
|
19
|
+
export function renderTaskUpdate(result) {
|
|
20
|
+
const lines = [renderTaskMutationRow(result.task)];
|
|
21
|
+
if (result.bodyChange) {
|
|
22
|
+
lines.push(`body · +${result.bodyChange.diffstat.additions} −${result.bodyChange.diffstat.deletions} lines`);
|
|
23
|
+
for (const section of result.bodyChange.removedSections) {
|
|
24
|
+
lines.push(`▲ section removed: ${section}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return lines.join("\n");
|
|
28
|
+
}
|
|
29
|
+
export function renderTaskUpdateJson(result) {
|
|
30
|
+
return JSON.stringify({
|
|
31
|
+
...taskJson(result.task),
|
|
32
|
+
...(result.bodyChange === undefined ? {} : { bodyChange: result.bodyChange }),
|
|
33
|
+
});
|
|
18
34
|
}
|
|
19
35
|
export function renderTaskRow(task, completeId = false) {
|
|
20
36
|
return completeId ? renderTaskMutationRow(task) : renderTaskListRow(task);
|
|
@@ -28,24 +44,20 @@ export function renderTaskList(tasks, options = {}) {
|
|
|
28
44
|
export function renderSelectedTaskList(tasks) {
|
|
29
45
|
return tasks.map(renderTaskListRow).join("\n");
|
|
30
46
|
}
|
|
31
|
-
function renderIds(ids) {
|
|
32
|
-
return ids.length === 0 ? "(none)" : ids.join(", ");
|
|
33
|
-
}
|
|
34
47
|
function renderTaskDetails(task) {
|
|
35
48
|
const released = new Set(task.releasedNeeds);
|
|
36
|
-
const needs = task.needs.length === 0
|
|
37
|
-
? "(none)"
|
|
38
|
-
: task.needs
|
|
39
|
-
.map((id) => `${id}${released.has(id) ? " (dropped)" : ""}`)
|
|
40
|
-
.join(", ");
|
|
41
49
|
return [
|
|
42
|
-
`${task.
|
|
50
|
+
`${task.coordinate} · ${task.title}`,
|
|
51
|
+
`namespace: ${task.namespace ?? "(hub)"}`,
|
|
43
52
|
`state: ${deriveTaskDisplay(task)}`,
|
|
44
53
|
`priority: ${task.pri}`,
|
|
45
|
-
`needs: ${needs}
|
|
46
|
-
`blocks: ${
|
|
47
|
-
|
|
48
|
-
`from: ${
|
|
54
|
+
...(task.needs.length === 0 ? [] : [`needs: ${task.needs.map((id) => `${id}${released.has(id) ? " (dropped)" : ""}`).join(", ")}`]),
|
|
55
|
+
...(task.blocks.length === 0 ? [] : [`blocks: ${task.blocks.join(", ")}`]),
|
|
56
|
+
...(task.parent === null ? [] : [`parent: ${task.parent}`]),
|
|
57
|
+
...(task.from.length === 0 ? [] : [`from: ${task.from.join(", ")}`]),
|
|
58
|
+
...(task.supersedes.length === 0 ? [] : [`supersedes: ${task.supersedes.join(", ")}`]),
|
|
59
|
+
...(task.supersededBy.length === 0 ? [] : [`superseded by: ${task.supersededBy.join(", ")}`]),
|
|
60
|
+
...(task.relatedTasks.length === 0 ? [] : [`relates to: ${task.relatedTasks.join(", ")}`]),
|
|
49
61
|
`created: ${task.createdAt} by ${task.creator}`,
|
|
50
62
|
"",
|
|
51
63
|
task.body,
|
|
@@ -55,16 +67,24 @@ function renderTreeNode(node, prefix, last) {
|
|
|
55
67
|
const branch = last ? "`- " : "|- ";
|
|
56
68
|
const nestedPrefix = `${prefix}${last ? " " : "| "}`;
|
|
57
69
|
const task = node.task;
|
|
58
|
-
const released = new Set(task.releasedNeeds);
|
|
59
|
-
const needs = task.needs.length === 0
|
|
60
|
-
? "(none)"
|
|
61
|
-
: task.needs.map((id) => `${id}${released.has(id) ? " (dropped)" : ""}`).join(", ");
|
|
62
70
|
const lines = [
|
|
63
|
-
`${prefix}${branch}${task.
|
|
64
|
-
`${nestedPrefix}needs: ${needs}`,
|
|
65
|
-
`${nestedPrefix}blocks: ${renderIds(task.blocks)}`,
|
|
66
|
-
`${nestedPrefix}from: ${renderIds(task.from)}`,
|
|
71
|
+
`${prefix}${branch}${task.coordinate} · ${deriveTaskDisplay(task)} · P${task.pri} · ${task.title}`,
|
|
67
72
|
];
|
|
73
|
+
const released = new Set(task.releasedNeeds);
|
|
74
|
+
if (task.needs.length > 0)
|
|
75
|
+
lines.push(`${nestedPrefix}needs: ${task.needs.map((id) => `${id}${released.has(id) ? " (dropped)" : ""}`).join(", ")}`);
|
|
76
|
+
if (task.blocks.length > 0)
|
|
77
|
+
lines.push(`${nestedPrefix}blocks: ${task.blocks.join(", ")}`);
|
|
78
|
+
if (task.parent !== null)
|
|
79
|
+
lines.push(`${nestedPrefix}parent: ${task.parent}`);
|
|
80
|
+
if (task.from.length > 0)
|
|
81
|
+
lines.push(`${nestedPrefix}from: ${task.from.join(", ")}`);
|
|
82
|
+
if (task.supersedes.length > 0)
|
|
83
|
+
lines.push(`${nestedPrefix}supersedes: ${task.supersedes.join(", ")}`);
|
|
84
|
+
if (task.supersededBy.length > 0)
|
|
85
|
+
lines.push(`${nestedPrefix}superseded by: ${task.supersededBy.join(", ")}`);
|
|
86
|
+
if (task.relatedTasks.length > 0)
|
|
87
|
+
lines.push(`${nestedPrefix}relates to: ${task.relatedTasks.join(", ")}`);
|
|
68
88
|
node.children.forEach((child, index) => lines.push(...renderTreeNode(child, nestedPrefix, index === node.children.length - 1)));
|
|
69
89
|
return lines;
|
|
70
90
|
}
|
|
@@ -74,15 +94,17 @@ function treeDiagnostic(diagnostic) {
|
|
|
74
94
|
}
|
|
75
95
|
export function renderTaskShow(task, tree) {
|
|
76
96
|
const treeLines = tree.descendants.length === 0
|
|
77
|
-
? [
|
|
97
|
+
? []
|
|
78
98
|
: ["children tree:", ...tree.descendants.flatMap((node, index) => renderTreeNode(node, "", index === tree.descendants.length - 1))];
|
|
79
99
|
if (tree.diagnostics.length > 0)
|
|
80
100
|
treeLines.push("tree diagnostics:", ...tree.diagnostics.map(treeDiagnostic));
|
|
81
|
-
return [...renderTaskDetails(task), "", ...treeLines].join("\n");
|
|
101
|
+
return [...renderTaskDetails(task), ...(treeLines.length === 0 ? [] : ["", ...treeLines])].join("\n");
|
|
82
102
|
}
|
|
83
103
|
export function taskJson(task) {
|
|
84
104
|
return {
|
|
85
105
|
id: task.id,
|
|
106
|
+
namespace: task.namespace,
|
|
107
|
+
coordinate: task.coordinate,
|
|
86
108
|
title: task.title,
|
|
87
109
|
state: task.state,
|
|
88
110
|
display: deriveTaskDisplay(task),
|
|
@@ -91,6 +113,9 @@ export function taskJson(task) {
|
|
|
91
113
|
blocks: [...task.blocks],
|
|
92
114
|
parent: task.parent,
|
|
93
115
|
from: [...task.from],
|
|
116
|
+
supersedes: [...task.supersedes],
|
|
117
|
+
supersededBy: [...task.supersededBy],
|
|
118
|
+
relatesTo: [...task.relatedTasks],
|
|
94
119
|
contractId: task.contractId ?? null,
|
|
95
120
|
createdAt: task.createdAt,
|
|
96
121
|
updatedAt: task.updatedAt ?? task.createdAt,
|
|
@@ -3,7 +3,7 @@ export function terminalFailureCodeSuffix(code) {
|
|
|
3
3
|
return code.startsWith("SUBAGENT_") ? code.slice("SUBAGENT_".length) : code;
|
|
4
4
|
}
|
|
5
5
|
export function terminalFailureColdStatement(failure) {
|
|
6
|
-
if (failure.publicCause?.
|
|
6
|
+
if (failure.publicCause?.code === "rate_limit_exhausted") {
|
|
7
7
|
return "the provider rate limit is exhausted";
|
|
8
8
|
}
|
|
9
9
|
if (failure.class === "runner") {
|
|
@@ -33,6 +33,8 @@ function terminalFailureEvidence(failure, statement) {
|
|
|
33
33
|
&& failure.code === "SUBAGENT_NON_ZERO_EXIT"
|
|
34
34
|
&& failure.exitCode !== undefined;
|
|
35
35
|
const parts = [];
|
|
36
|
+
if (failure.message)
|
|
37
|
+
parts.push(failure.message);
|
|
36
38
|
if (failure.timeoutMs !== undefined) {
|
|
37
39
|
parts.push(failure.code === "SUBAGENT_POLICY_BUDGET" ? `budget ${failure.timeoutMs}ms` : `idle ${failure.timeoutMs}ms`);
|
|
38
40
|
}
|