@astrosheep/keiyaku 4.5.7 → 4.5.8
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 +10 -0
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/opencode.js +3 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +10 -9
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +22 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +35 -96
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +28 -49
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +21 -15
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +148 -89
- package/build/src/akuma/abort.d.ts +2 -1
- package/build/src/akuma/abort.js +6 -23
- package/build/src/akuma/akuma-handle.js +4 -2
- package/build/src/akuma/akuma-observe.d.ts +2 -0
- package/build/src/akuma/akuma-observe.js +1 -0
- package/build/src/akuma/akuma-product.js +9 -7
- package/build/src/akuma/akuma.d.ts +372 -9
- package/build/src/akuma/akuma.js +31 -1
- package/build/src/akuma/allowed.d.ts +1 -1
- package/build/src/akuma/allowed.js +1 -0
- package/build/src/akuma/body.d.ts +6 -4
- package/build/src/akuma/body.js +5 -3
- package/build/src/akuma/call-request.d.ts +80 -0
- package/build/src/akuma/call-request.js +211 -0
- package/build/src/akuma/heart/facts.d.ts +6 -78
- package/build/src/akuma/heart/index.d.ts +1 -1
- package/build/src/akuma/heart/request-authority.d.ts +5 -4
- package/build/src/akuma/heart/request-authority.js +20 -34
- package/build/src/akuma/heart/request-rows.js +12 -23
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +5 -13
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/projection-read.d.ts +1 -0
- package/build/src/akuma/projection-read.js +8 -1
- package/build/src/akuma/projection.d.ts +856 -137
- package/build/src/akuma/projection.js +190 -0
- package/build/src/akuma/provider.d.ts +30 -3
- package/build/src/akuma/provider.js +104 -0
- package/build/src/akuma/providers/acp/core.d.ts +2 -2
- package/build/src/akuma/providers/acp/core.js +13 -6
- package/build/src/akuma/providers/acp/index.js +5 -4
- package/build/src/akuma/providers/claude/index.d.ts +3 -3
- package/build/src/akuma/providers/claude/index.js +16 -5
- package/build/src/akuma/providers/codex-app-server/events.js +1 -1
- package/build/src/akuma/providers/codex-app-server/index.js +18 -6
- package/build/src/akuma/providers/grok-build/index.js +5 -4
- package/build/src/akuma/providers/opencode-sdk/index.js +66 -25
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/session.js +28 -11
- package/build/src/akuma/providers/pi/index.js +42 -14
- package/build/src/akuma/request-lifecycle.d.ts +3 -9
- package/build/src/akuma/request-lifecycle.js +4 -4
- package/build/src/akuma/request-rendezvous.d.ts +26 -0
- package/build/src/akuma/request-rendezvous.js +100 -0
- package/build/src/akuma/request-serve.d.ts +5 -65
- package/build/src/akuma/request-serve.js +81 -208
- package/build/src/akuma/request-wire.d.ts +109 -115
- package/build/src/akuma/request-wire.js +63 -318
- package/build/src/akuma/requests.d.ts +19 -47
- package/build/src/akuma/requests.js +51 -107
- package/build/src/akuma/turn-drive.d.ts +5 -3
- package/build/src/akuma/turn-drive.js +32 -10
- package/build/src/akuma-body.d.ts +7 -2
- package/build/src/akuma-body.js +68 -46
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +2 -2
- package/build/src/cli/commands/akuma-invoke.d.ts +2 -0
- package/build/src/cli/commands/akuma-invoke.js +17 -9
- package/build/src/cli/commands/akuma.js +7 -7
- package/build/src/cli/commands/contract-invoke.d.ts +3 -2
- package/build/src/cli/commands/contract-invoke.js +26 -19
- package/build/src/cli/commands/contract.d.ts +13 -13
- package/build/src/cli/commands/contract.js +32 -17
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +1 -1
- package/build/src/cli/commands/task-invoke.d.ts +3 -0
- package/build/src/cli/commands/task-invoke.js +23 -140
- package/build/src/cli/commands/task.js +54 -20
- package/build/src/cli/invoke.js +39 -25
- package/build/src/cli/main.js +2 -1
- package/build/src/cli/parse.d.ts +2 -2
- package/build/src/cli/parse.js +37 -22
- package/build/src/cli/render/akuma-activity.d.ts +4 -1
- package/build/src/cli/render/akuma-activity.js +45 -30
- package/build/src/cli/render/akuma-tool.d.ts +5 -1
- package/build/src/cli/render/akuma.js +5 -9
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/catalog.js +80 -21
- package/build/src/cli/render/contract-observation.d.ts +2 -0
- package/build/src/cli/render/contract-observation.js +11 -0
- package/build/src/cli/render/contract.js +25 -65
- package/build/src/cli/render/kanshi-akuma.d.ts +8 -0
- package/build/src/cli/render/kanshi-akuma.js +111 -0
- package/build/src/cli/render/kanshi.js +108 -213
- package/build/src/cli/render/receipt.d.ts +1 -2
- package/build/src/cli/render/receipt.js +76 -26
- package/build/src/cli/render/refusal.js +2 -10
- package/build/src/cli/render/region.js +5 -2
- package/build/src/cli/render/settings.d.ts +1 -1
- package/build/src/cli/render/settings.js +27 -8
- package/build/src/cli/render/task.js +22 -5
- package/build/src/cli/render/terminal.d.ts +28 -0
- package/build/src/cli/render/terminal.js +65 -0
- package/build/src/cli/result.d.ts +3 -3
- package/build/src/cli/runtime.js +3 -1
- package/build/src/cli/selectors.d.ts +2 -1
- package/build/src/cli/selectors.js +4 -3
- package/build/src/cli/square-edge.js +120 -36
- package/build/src/cli/usage.js +2 -1
- package/build/src/contract-guidance.d.ts +5 -0
- package/build/src/contract-guidance.js +121 -0
- package/build/src/contract-worktree.d.ts +0 -1
- package/build/src/contract-worktree.js +32 -83
- package/build/src/coordination/sqlite-transaction-lock.d.ts +1 -0
- package/build/src/coordination/sqlite-transaction-lock.js +5 -0
- package/build/src/core/facts/codec.d.ts +2 -0
- package/build/src/core/facts/codec.js +4 -0
- package/build/src/core/verbs/placement.d.ts +6 -1
- package/build/src/core/verbs/placement.js +5 -3
- package/build/src/dispatch/index.d.ts +0 -2
- package/build/src/dispatch/index.js +54 -55
- package/build/src/git/admission.js +2 -2
- package/build/src/git/hooks.d.ts +9 -15
- package/build/src/git/hooks.js +23 -317
- package/build/src/git/nuke.d.ts +2 -1
- package/build/src/git/nuke.js +36 -18
- package/build/src/git/private-state-seat.d.ts +12 -0
- package/build/src/git/private-state-seat.js +39 -0
- package/build/src/git/process.d.ts +6 -0
- package/build/src/git/process.js +19 -7
- package/build/src/git/read-observation.js +29 -20
- package/build/src/git/reconcile.d.ts +11 -0
- package/build/src/git/reconcile.js +64 -11
- package/build/src/git/repository.d.ts +6 -2
- package/build/src/git/repository.js +8 -0
- package/build/src/git/target-placement.d.ts +1 -0
- package/build/src/git/target-placement.js +5 -0
- package/build/src/git/tender.d.ts +1 -0
- package/build/src/git/terminal-reconcile.d.ts +1 -1
- package/build/src/git/terminal-reconcile.js +22 -20
- package/build/src/git/workspace.d.ts +14 -0
- package/build/src/git/workspace.js +44 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +16 -16
- package/build/src/kanshi/report.d.ts +2 -2
- package/build/src/library/address.d.ts +9 -3
- package/build/src/library/address.js +3 -2
- package/build/src/library/akuma-creation.d.ts +4 -3
- package/build/src/library/akuma-creation.js +19 -13
- package/build/src/library/audit.d.ts +1 -1
- package/build/src/library/audit.js +5 -3
- package/build/src/library/catalog.d.ts +3 -1
- package/build/src/library/catalog.js +20 -6
- package/build/src/library/composition.d.ts +371 -0
- package/build/src/library/composition.js +28 -0
- package/build/src/library/configuration.js +8 -2
- package/build/src/library/continuation.js +66 -30
- package/build/src/library/contract-bind.js +10 -2
- package/build/src/library/contract-forwarding-reconciliation-result.d.ts +96 -0
- package/build/src/library/contract-forwarding-reconciliation-result.js +83 -0
- package/build/src/library/contract-forwarding-result.d.ts +6723 -0
- package/build/src/library/contract-forwarding-result.js +521 -0
- package/build/src/library/contract-forwarding.d.ts +72 -0
- package/build/src/library/contract-forwarding.js +125 -0
- package/build/src/library/contract-handle.d.ts +36 -0
- package/build/src/library/contract-handle.js +313 -0
- package/build/src/library/contract-operations.d.ts +1044 -67
- package/build/src/library/contract-operations.js +190 -118
- package/build/src/library/contract.d.ts +11 -32
- package/build/src/library/contract.js +16 -289
- package/build/src/library/fleet-result.d.ts +1454 -0
- package/build/src/library/fleet-result.js +96 -0
- package/build/src/library/fleet.d.ts +112 -54
- package/build/src/library/fleet.js +211 -71
- package/build/src/library/input.d.ts +2 -0
- package/build/src/library/input.js +4 -0
- package/build/src/library/keiyaku.d.ts +371 -20
- package/build/src/library/keiyaku.js +8 -21
- package/build/src/library/mutation.d.ts +3 -3
- package/build/src/library/mutation.js +5 -9
- package/build/src/library/nuke.d.ts +1 -1
- package/build/src/library/nuke.js +4 -3
- package/build/src/library/reconcile.d.ts +4 -0
- package/build/src/library/reconcile.js +2 -0
- package/build/src/library/refusal.d.ts +0 -9
- package/build/src/library/refusal.js +0 -7
- package/build/src/protocol/amend.js +56 -50
- package/build/src/protocol/attempt.d.ts +2 -0
- package/build/src/protocol/attempt.js +8 -1
- package/build/src/protocol/completion.js +7 -0
- package/build/src/protocol/deliver.js +6 -2
- package/build/src/protocol/operations.d.ts +4 -1
- package/build/src/protocol/operations.js +5 -2
- package/build/src/protocol/placement.d.ts +1 -0
- package/build/src/protocol/placement.js +52 -38
- package/build/src/protocol/read/observation.d.ts +1 -4
- package/build/src/protocol/read/observation.js +2 -15
- package/build/src/protocol/reintegrate.js +62 -58
- package/build/src/protocol/review.js +5 -0
- package/build/src/protocol/run.js +17 -13
- package/build/src/runtime/proc/run.d.ts +8 -0
- package/build/src/runtime/proc/run.js +27 -0
- package/build/src/runtime/proc/termination.js +26 -22
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/holder.d.ts +2 -1
- package/build/src/settlement/holder.js +15 -4
- package/build/src/settlement/settle.js +99 -33
- package/build/src/task/board.d.ts +68 -27
- package/build/src/task/board.js +31 -1
- package/build/src/task/catalog.d.ts +4 -0
- package/build/src/task/catalog.js +23 -0
- package/build/src/task/compose-language.js +33 -7
- package/build/src/task/compose-parser.d.ts +1 -1
- package/build/src/task/compose-parser.js +1 -1
- package/build/src/task/compose.js +2 -0
- package/build/src/task/index.d.ts +12 -4
- package/build/src/task/index.js +97 -16
- package/build/src/task/mutation-result.d.ts +923 -0
- package/build/src/task/mutation-result.js +140 -0
- package/build/src/task/mutation.d.ts +552 -28
- package/build/src/task/mutation.js +304 -97
- package/build/src/task/operations.d.ts +1 -4
- package/build/src/task/operations.js +0 -6
- package/build/src/task/public.d.ts +2 -0
- package/build/src/task/public.js +1 -0
- package/build/src/workspace-place.d.ts +7 -2
- package/build/src/workspace-place.js +34 -24
- package/build/src/world.d.ts +1 -0
- package/build/src/world.js +11 -0
- package/package.json +8 -6
- package/build/src/akuma/request-execution.d.ts +0 -8
- package/build/src/akuma/request-execution.js +0 -98
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseAkumaStatus } from "../../akuma/akuma.js";
|
|
2
|
+
import { DEFAULT_CONTEXT, akumaRawAnswer, associatedIdentity, historyText, killResultText, mutationObservationStageText, snapshotHeading, snapshotText, tellText, waitText, } from "./akuma-activity.js";
|
|
2
3
|
import { safeText } from "./terminal.js";
|
|
3
4
|
export { akumaRawAnswer } from "./akuma-activity.js";
|
|
4
5
|
function dispatchLines(stage) {
|
|
@@ -6,8 +7,6 @@ function dispatchLines(stage) {
|
|
|
6
7
|
return [];
|
|
7
8
|
if (stage.failure.kind === "conflict")
|
|
8
9
|
return [`dispatch failed conflict ${stage.failure.current.contractId}`];
|
|
9
|
-
if (stage.failure.kind === "contention")
|
|
10
|
-
return ["dispatch failed contention"];
|
|
11
10
|
return [`dispatch failed ${stage.failure.kind} ${safeText(stage.failure.diagnostic)}`];
|
|
12
11
|
}
|
|
13
12
|
function executionCwdLine(result) {
|
|
@@ -49,7 +48,7 @@ function callText(result, context) {
|
|
|
49
48
|
].join("\n");
|
|
50
49
|
}
|
|
51
50
|
return snapshotText({
|
|
52
|
-
status: result.result.observation.status,
|
|
51
|
+
status: parseAkumaStatus(result.result.observation.status),
|
|
53
52
|
contract: contractId === undefined ? { kind: "none" } : { kind: "associated", contractId },
|
|
54
53
|
}, context, { ...(alias === undefined ? {} : { alias }), facts: [...cwd, ...facts] });
|
|
55
54
|
}
|
|
@@ -70,7 +69,7 @@ export function renderAkumaText(command, result, context = DEFAULT_CONTEXT) {
|
|
|
70
69
|
return waitText(result, context);
|
|
71
70
|
case "tell":
|
|
72
71
|
return result.mode === "ordinary"
|
|
73
|
-
? tellText(result
|
|
72
|
+
? tellText(result)
|
|
74
73
|
: mutationObservationStageText(result.result.id, result.result.observation, context, {
|
|
75
74
|
...(result.alias === undefined ? {} : { alias: result.alias }),
|
|
76
75
|
showLife: false,
|
|
@@ -89,10 +88,7 @@ export function renderAkumaText(command, result, context = DEFAULT_CONTEXT) {
|
|
|
89
88
|
}
|
|
90
89
|
case "kill":
|
|
91
90
|
return result.result.results
|
|
92
|
-
.map((member) =>
|
|
93
|
-
facts: [`kill ${member.evidence}`],
|
|
94
|
-
...(result.alias === undefined ? {} : { alias: result.alias }),
|
|
95
|
-
}))
|
|
91
|
+
.map((member) => killResultText(member.id, member.evidence, result.alias))
|
|
96
92
|
.join("\n\n");
|
|
97
93
|
}
|
|
98
94
|
}
|
|
@@ -39,7 +39,7 @@ function verificationLines(verification, columns, addressed) {
|
|
|
39
39
|
return lines;
|
|
40
40
|
}
|
|
41
41
|
if (verification.kind === "stopped") {
|
|
42
|
-
return stopLines(
|
|
42
|
+
return stopLines(verification.stop, columns, addressed);
|
|
43
43
|
}
|
|
44
44
|
receiptRow(lines, verification.kind === "satisfied" ? "✓" : "!", "verification", [{ text: verification.kind }, { text: `${verification.passed} of ${verification.total}` }], columns);
|
|
45
45
|
if (verification.summary !== undefined) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { abbreviateGitIds, afterWording, candidateFact, dependentWording, displayGitId, gateFact, gitIdsInRow, } from "./contract-observation.js";
|
|
1
|
+
import { abbreviateGitIds, afterWording, candidateFact, dependentWording, displayGitId, gateFact, gitIdsInRow, targetMovementFacts, } from "./contract-observation.js";
|
|
2
2
|
import { safeText } from "./terminal.js";
|
|
3
|
-
function targetLine(row) {
|
|
3
|
+
function targetLine(row, abbreviations) {
|
|
4
4
|
if (row.target === null)
|
|
5
5
|
return "no target";
|
|
6
6
|
const target = row.target.startsWith("refs/heads/") ? row.target.slice("refs/heads/".length) : row.target;
|
|
@@ -9,11 +9,74 @@ function targetLine(row) {
|
|
|
9
9
|
: row.targetLag.kind === "unknown"
|
|
10
10
|
? `commits behind ${target} unknown`
|
|
11
11
|
: undefined;
|
|
12
|
-
return [
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
return [`target ${target}`, ...(lag === undefined ? [] : [lag]), ...targetMovementFacts(row, abbreviations)].join(" · ");
|
|
13
|
+
}
|
|
14
|
+
const CATALOG_VISIBLE_AKUMA = 10;
|
|
15
|
+
function akumaMark(life) {
|
|
16
|
+
if (life === "running")
|
|
17
|
+
return "●";
|
|
18
|
+
if (life === "asleep" || life === "unborn")
|
|
19
|
+
return "○";
|
|
20
|
+
if (life === "killed")
|
|
21
|
+
return "×";
|
|
22
|
+
if (life === "stillborn")
|
|
23
|
+
return "!";
|
|
24
|
+
return "?";
|
|
25
|
+
}
|
|
26
|
+
function akumaUpdatedAt(row) {
|
|
27
|
+
const lifeAt = "lifeAt" in row ? row.lifeAt : null;
|
|
28
|
+
const activityAt = "lastActivityAt" in row ? row.lastActivityAt : null;
|
|
29
|
+
if (lifeAt === null)
|
|
30
|
+
return activityAt;
|
|
31
|
+
if (activityAt === null)
|
|
32
|
+
return lifeAt;
|
|
33
|
+
return lifeAt > activityAt ? lifeAt : activityAt;
|
|
34
|
+
}
|
|
35
|
+
function relativeAge(source, observedAt) {
|
|
36
|
+
if (source === null)
|
|
37
|
+
return null;
|
|
38
|
+
const seconds = Math.floor((Date.parse(observedAt) - Date.parse(source)) / 1_000);
|
|
39
|
+
if (seconds < 0)
|
|
40
|
+
return "now";
|
|
41
|
+
if (seconds < 60)
|
|
42
|
+
return `${seconds}s`;
|
|
43
|
+
const minutes = Math.floor(seconds / 60);
|
|
44
|
+
if (minutes < 60)
|
|
45
|
+
return `${minutes}m`;
|
|
46
|
+
const hours = Math.floor(minutes / 60);
|
|
47
|
+
if (hours < 24)
|
|
48
|
+
return `${hours}h`;
|
|
49
|
+
return `${Math.floor(hours / 24)}d`;
|
|
50
|
+
}
|
|
51
|
+
function renderAkumaCatalog(catalog) {
|
|
52
|
+
const ordered = [...catalog.rows].sort((left, right) => {
|
|
53
|
+
const leftAt = akumaUpdatedAt(left);
|
|
54
|
+
const rightAt = akumaUpdatedAt(right);
|
|
55
|
+
if (leftAt === rightAt)
|
|
56
|
+
return 0;
|
|
57
|
+
if (leftAt === null)
|
|
58
|
+
return 1;
|
|
59
|
+
if (rightAt === null)
|
|
60
|
+
return -1;
|
|
61
|
+
return leftAt > rightAt ? -1 : 1;
|
|
62
|
+
});
|
|
63
|
+
const rows = ordered.slice(0, CATALOG_VISIBLE_AKUMA);
|
|
64
|
+
const lines = [
|
|
65
|
+
`akuma instances ${rows.length} of ${ordered.length} known`,
|
|
66
|
+
...(catalog.archetype === null ? [] : [` scope ${safeText(catalog.archetype)}`]),
|
|
67
|
+
"",
|
|
68
|
+
];
|
|
69
|
+
for (const row of rows) {
|
|
70
|
+
const lifeAt = "lifeAt" in row ? row.lifeAt : null;
|
|
71
|
+
const activityAt = "lastActivityAt" in row ? row.lastActivityAt : null;
|
|
72
|
+
const ages = [relativeAge(lifeAt, catalog.observedAt), relativeAge(activityAt, catalog.observedAt)].filter((age) => age !== null);
|
|
73
|
+
lines.push(`${akumaMark(row.life)} ${safeText(row.id)} · ${row.life}${ages.length === 0 ? "" : ` · ${ages.join(" · ")}`}`);
|
|
74
|
+
}
|
|
75
|
+
if (rows.length < ordered.length) {
|
|
76
|
+
const selector = catalog.archetype === null ? '"aku/*/*"' : `aku/${catalog.archetype}/`;
|
|
77
|
+
lines.push("", ` + ${ordered.length - rows.length} more akuma not shown`, ` keiyaku ls ${selector}`);
|
|
78
|
+
}
|
|
79
|
+
return lines.join("\n");
|
|
17
80
|
}
|
|
18
81
|
function catalogMark(row) {
|
|
19
82
|
if (row.phase === "claimed")
|
|
@@ -58,7 +121,7 @@ function renderContractCatalog(catalog) {
|
|
|
58
121
|
const blocks = rows.map((row) => {
|
|
59
122
|
const lines = [
|
|
60
123
|
`${catalogMark(row)} ${safeText(row.id)} · ${row.phase} · ${formatAge(row.phaseAt, catalog.observedAt)} · ${safeText(row.title ?? "title unavailable")}`,
|
|
61
|
-
` ${candidateFact(row.delivery)} · ${targetLine(row)}`,
|
|
124
|
+
` ${candidateFact(row.delivery)} · ${targetLine(row, abbreviations)}`,
|
|
62
125
|
...row.after.map((edge) => ` ${afterWording(edge)}`),
|
|
63
126
|
...(row.dependents.length === 0 ? [] : [` dependents ${row.dependents.map(dependentWording).join(" · ")}`]),
|
|
64
127
|
...(row.gates.reports.length === 0 ? [] : [` ${row.gates.reports.map(gateFact).join(" ")}`]),
|
|
@@ -76,18 +139,14 @@ export function renderCatalogText(catalog) {
|
|
|
76
139
|
if (catalog.kind === "contracts")
|
|
77
140
|
return renderContractCatalog(catalog);
|
|
78
141
|
if (catalog.kind === "archetypes") {
|
|
79
|
-
return
|
|
80
|
-
.
|
|
81
|
-
|
|
82
|
-
...(row
|
|
83
|
-
|
|
84
|
-
|
|
142
|
+
return [
|
|
143
|
+
`archetypes ${catalog.rows.length}`,
|
|
144
|
+
"",
|
|
145
|
+
...catalog.rows.flatMap((row) => [
|
|
146
|
+
`${safeText(row.name)}${row.model === undefined ? "" : ` - ${safeText(row.model)}`}`,
|
|
147
|
+
...(row.description === undefined ? [] : [` ${safeText(row.description)}`]),
|
|
148
|
+
]),
|
|
149
|
+
].join("\n");
|
|
85
150
|
}
|
|
86
|
-
return catalog
|
|
87
|
-
.map((row) => {
|
|
88
|
-
if (!("lifeAt" in row))
|
|
89
|
-
return `${safeText(row.id)} - ${row.life}`;
|
|
90
|
-
return `${safeText(row.id)} - ${row.life} - runtime ${row.lifeAt ?? "-"} - last activity ${row.lastActivityAt ?? "-"}`;
|
|
91
|
-
})
|
|
92
|
-
.join("\n");
|
|
151
|
+
return renderAkumaCatalog(catalog);
|
|
93
152
|
}
|
|
@@ -8,3 +8,5 @@ export declare function mergeSummary(observation: ContractWorkspaceObservation):
|
|
|
8
8
|
export declare function abbreviateGitIds(ids: readonly string[]): ReadonlyMap<string, string>;
|
|
9
9
|
export declare function gitIdsInRow(row: ContractRow): readonly string[];
|
|
10
10
|
export declare function displayGitId(value: string, abbreviations: ReadonlyMap<string, string>): string;
|
|
11
|
+
/** Render the pinned delivery target and the same-epoch observed target head. */
|
|
12
|
+
export declare function targetMovementFacts(row: ContractRow, abbreviations: ReadonlyMap<string, string>): readonly string[];
|
|
@@ -56,3 +56,14 @@ export function gitIdsInRow(row) {
|
|
|
56
56
|
export function displayGitId(value, abbreviations) {
|
|
57
57
|
return abbreviations.get(value) ?? value;
|
|
58
58
|
}
|
|
59
|
+
/** Render the pinned delivery target and the same-epoch observed target head. */
|
|
60
|
+
export function targetMovementFacts(row, abbreviations) {
|
|
61
|
+
if (row.target === null || row.targetObservation?.drift !== true)
|
|
62
|
+
return [];
|
|
63
|
+
if (row.delivery === null)
|
|
64
|
+
return ["target moved"];
|
|
65
|
+
return [
|
|
66
|
+
"target moved",
|
|
67
|
+
`${displayGitId(row.delivery.integration.snapshot, abbreviations)} -> ${row.targetObservation.head === null ? "null" : displayGitId(row.targetObservation.head, abbreviations)}`,
|
|
68
|
+
];
|
|
69
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { renderAcceptedAudit } from "./audit.js";
|
|
2
|
-
import { appendHookPayload, cleanupLines, hookFailureSummary, leakLines, outcomeLines, receiptPayload, receiptRow, reuseLines, stopLines,
|
|
2
|
+
import { appendHookPayload, cleanupLines, hookFailureSummary, leakLines, outcomeLines, receiptPayload, receiptRow, reuseLines, stopLines, titleLines, } from "./receipt.js";
|
|
3
3
|
import { gitShortStat, renderOpaqueBlock } from "./terminal.js";
|
|
4
4
|
const HANG = " ";
|
|
5
5
|
function isRecord(value) {
|
|
@@ -11,33 +11,6 @@ function retryLines(detail, indent, columns) {
|
|
|
11
11
|
}
|
|
12
12
|
return renderOpaqueBlock(detail.kind, indent, columns);
|
|
13
13
|
}
|
|
14
|
-
function changedEffect(effect) {
|
|
15
|
-
return effect.action !== "unchanged";
|
|
16
|
-
}
|
|
17
|
-
function effectRows(effect, columns) {
|
|
18
|
-
const mark = changedEffect(effect) ? "✓" : "·";
|
|
19
|
-
const lines = [];
|
|
20
|
-
if (effect.kind === "worktree") {
|
|
21
|
-
receiptRow(lines, mark, "worktree", [{ text: effect.action }, { text: effect.path, opaque: true }], columns);
|
|
22
|
-
}
|
|
23
|
-
else if (effect.kind === "contract-file") {
|
|
24
|
-
receiptRow(lines, mark, "contract-file", [{ text: effect.action }, { text: effect.path, opaque: true }], columns);
|
|
25
|
-
}
|
|
26
|
-
else if (effect.kind === "target-checkout") {
|
|
27
|
-
receiptRow(lines, mark, "target-checkout", [{ text: effect.action }, { text: effect.target, opaque: true }, { text: effect.path, opaque: true }], columns);
|
|
28
|
-
}
|
|
29
|
-
else if (effect.kind === "recovery-snapshot") {
|
|
30
|
-
receiptRow(lines, mark, "recovery-snapshot", [{ text: effect.action }, { text: effect.snapshot, opaque: true }, { text: effect.retention }], columns);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
receiptRow(lines, mark, "ref", [
|
|
34
|
-
{ text: effect.action },
|
|
35
|
-
{ text: effect.name, opaque: true },
|
|
36
|
-
{ text: `${effect.before ?? "null"} -> ${effect.after ?? "null"}`, opaque: true },
|
|
37
|
-
], columns);
|
|
38
|
-
}
|
|
39
|
-
return lines;
|
|
40
|
-
}
|
|
41
14
|
function lagRows(lag, columns) {
|
|
42
15
|
const lines = [];
|
|
43
16
|
if (lag.kind === "worktree-retained") {
|
|
@@ -46,7 +19,7 @@ function lagRows(lag, columns) {
|
|
|
46
19
|
else if (lag.kind === "worktree-follow-retained") {
|
|
47
20
|
receiptRow(lines, "!", "lag", [
|
|
48
21
|
{
|
|
49
|
-
text: `${lag.kind} reason=${lag.reason} tender=${lag.tender} head=${lag.head} path=${lag.path}`,
|
|
22
|
+
text: `${lag.kind} reason=${lag.reason} tender=${lag.tender} head=${lag.head}${lag.paths === undefined || lag.paths.length === 0 ? "" : ` paths=${lag.paths.join(",")}`} path=${lag.path}`,
|
|
50
23
|
opaque: true,
|
|
51
24
|
},
|
|
52
25
|
], columns);
|
|
@@ -66,7 +39,7 @@ function lagRows(lag, columns) {
|
|
|
66
39
|
else if (lag.kind === "worktree-hook-failed") {
|
|
67
40
|
receiptRow(lines, "!", "lag", [
|
|
68
41
|
{
|
|
69
|
-
text: `worktree-hook-failed ${lag.phase} ${lag.path} command=${lag.command} ${hookFailureSummary(lag.failure)}`,
|
|
42
|
+
text: `worktree-hook-failed ${lag.phase} ${lag.path} command=${lag.command} name=${lag.name} ${hookFailureSummary(lag.failure)}`,
|
|
70
43
|
opaque: true,
|
|
71
44
|
},
|
|
72
45
|
], columns);
|
|
@@ -142,20 +115,11 @@ function acceptedRecord(result, columns) {
|
|
|
142
115
|
: [...contract, { text: fact.entry, opaque: true }, { text: `· ${fact.kind}` }], columns);
|
|
143
116
|
}
|
|
144
117
|
receiptRow(record, " ", "head", [{ text: result.head, opaque: true }], columns);
|
|
118
|
+
if (result.recoverySnapshot !== undefined)
|
|
119
|
+
receiptRow(record, " ", "recovery snapshot", [{ text: result.recoverySnapshot, opaque: true }], columns);
|
|
145
120
|
if (result.verb === "deliver") {
|
|
146
121
|
pushBlock(record, reuseLines(result.verificationReuse, columns));
|
|
147
122
|
}
|
|
148
|
-
const changed = result.effects.filter(changedEffect);
|
|
149
|
-
const unchanged = result.effects.filter((effect) => !changedEffect(effect));
|
|
150
|
-
for (const effect of [...changed, ...unchanged])
|
|
151
|
-
pushBlock(record, effectRows(effect, columns));
|
|
152
|
-
for (const action of result.settlement.actions) {
|
|
153
|
-
receiptRow(record, "·", "settle", [
|
|
154
|
-
{ text: action.kind },
|
|
155
|
-
{ text: action.action },
|
|
156
|
-
{ text: action.kind === "task" ? action.taskId : action.path, opaque: true },
|
|
157
|
-
], columns);
|
|
158
|
-
}
|
|
159
123
|
return record;
|
|
160
124
|
}
|
|
161
125
|
function acceptedLagRows(result, columns) {
|
|
@@ -164,7 +128,7 @@ function acceptedLagRows(result, columns) {
|
|
|
164
128
|
for (const lag of result.lag)
|
|
165
129
|
pushBlock(obligations, lagRows(lag, columns));
|
|
166
130
|
}
|
|
167
|
-
for (const lag of result.
|
|
131
|
+
for (const lag of result.settlementLags) {
|
|
168
132
|
pushBlock(obligations, settlementLagRows(lag, columns));
|
|
169
133
|
}
|
|
170
134
|
return obligations;
|
|
@@ -210,7 +174,7 @@ function completionLines(result, columns) {
|
|
|
210
174
|
...(verification?.verdict === "satisfied" ? [{ text: `· verified (${verification.mode})` }] : []),
|
|
211
175
|
], columns);
|
|
212
176
|
if (verification?.verdict === "unsatisfied") {
|
|
213
|
-
receiptRow(lines, "!", "verification", [{ text: "unsatisfied" }, { text: `(${verification.mode})` }], columns);
|
|
177
|
+
receiptRow(lines, "!", "verification", [{ text: "unsatisfied" }, { text: `(${verification.mode})` }, { text: "· not required by Contract gates" }], columns);
|
|
214
178
|
if (result.verificationSummary !== undefined) {
|
|
215
179
|
receiptPayload(lines, " summary", result.verificationSummary);
|
|
216
180
|
}
|
|
@@ -234,8 +198,10 @@ function continuationLines(result, columns) {
|
|
|
234
198
|
receiptRow(lines, "✓", "continuation", [{ text: "complete" }, { text: contractId, opaque: true }], columns);
|
|
235
199
|
}
|
|
236
200
|
for (const { contractId, stop } of report.stopped) {
|
|
237
|
-
|
|
238
|
-
|
|
201
|
+
if ("kind" in stop)
|
|
202
|
+
receiptRow(lines, "!", contractId, [{ text: "· already terminal" }], columns);
|
|
203
|
+
else
|
|
204
|
+
lines.push(...stopLines(stop, columns, contractId, contractId));
|
|
239
205
|
}
|
|
240
206
|
return lines;
|
|
241
207
|
}
|
|
@@ -259,15 +225,16 @@ function renderAcceptedDeliver(result, columns) {
|
|
|
259
225
|
const complete = result.completion !== undefined;
|
|
260
226
|
const title = complete ? "delivered" : "deliver — not complete";
|
|
261
227
|
const lines = titleLines("✓", title, result.contract, columns);
|
|
262
|
-
lines.push(...movementLines(result, columns), ...completionLines(result, columns)
|
|
263
|
-
if (!complete)
|
|
264
|
-
receiptRow(lines, " ", "candidate", [{ text: "kept" }], columns);
|
|
228
|
+
lines.push(...movementLines(result, columns), ...completionLines(result, columns));
|
|
265
229
|
if (result.verification !== undefined) {
|
|
266
|
-
lines.push(...stopLines(
|
|
230
|
+
lines.push(...stopLines(result.verification, columns, result.contract));
|
|
267
231
|
}
|
|
268
232
|
if (!complete && result.placement !== undefined) {
|
|
269
|
-
lines.push(...stopLines(
|
|
233
|
+
lines.push(...stopLines(result.placement, columns, result.contract));
|
|
270
234
|
}
|
|
235
|
+
if (!complete)
|
|
236
|
+
receiptRow(lines, " ", "candidate", [{ text: "kept" }], columns);
|
|
237
|
+
lines.push(...continuationLines(result, columns));
|
|
271
238
|
if (result.cleanup !== undefined)
|
|
272
239
|
pushBlock(lines, cleanupLines(result.cleanup, columns));
|
|
273
240
|
if (result.leak !== undefined)
|
|
@@ -278,15 +245,16 @@ function renderAcceptedDeliver(result, columns) {
|
|
|
278
245
|
function renderAcceptedReview(result, columns) {
|
|
279
246
|
const complete = result.completion !== undefined;
|
|
280
247
|
const lines = titleLines("✓", `review ${result.verdict} — ${complete ? "complete" : "not complete"}`, result.contract, columns);
|
|
281
|
-
lines.push(...movementLines(result, columns), ...completionLines(result, columns)
|
|
282
|
-
if (!complete)
|
|
283
|
-
receiptRow(lines, " ", "candidate", [{ text: "kept" }], columns);
|
|
284
|
-
if (result.placement !== undefined) {
|
|
285
|
-
lines.push(...stopLines("completion", result.placement, columns, result.contract));
|
|
286
|
-
}
|
|
248
|
+
lines.push(...movementLines(result, columns), ...completionLines(result, columns));
|
|
287
249
|
if (result.verification !== undefined) {
|
|
288
|
-
lines.push(...stopLines(
|
|
250
|
+
lines.push(...stopLines(result.verification, columns, result.contract));
|
|
289
251
|
}
|
|
252
|
+
if (result.placement !== undefined) {
|
|
253
|
+
lines.push(...stopLines(result.placement, columns, result.contract));
|
|
254
|
+
}
|
|
255
|
+
if (!complete)
|
|
256
|
+
receiptRow(lines, " ", "candidate", [{ text: "kept" }], columns);
|
|
257
|
+
lines.push(...continuationLines(result, columns));
|
|
290
258
|
if (result.cleanup !== undefined)
|
|
291
259
|
pushBlock(lines, cleanupLines(result.cleanup, columns));
|
|
292
260
|
if (result.leak !== undefined)
|
|
@@ -304,14 +272,6 @@ function renderAcceptedAbandon(result, columns) {
|
|
|
304
272
|
const lines = titleLines("✓", "abandoned", result.contract, columns);
|
|
305
273
|
if (result.note !== undefined)
|
|
306
274
|
receiptRow(lines, " ", "note", [{ text: result.note }], columns);
|
|
307
|
-
for (const effect of result.effects) {
|
|
308
|
-
if (effect.kind === "worktree") {
|
|
309
|
-
receiptRow(lines, " ", "workspace", [{ text: effect.action }, { text: effect.path, opaque: true }], columns);
|
|
310
|
-
}
|
|
311
|
-
else if (effect.kind === "recovery-snapshot") {
|
|
312
|
-
receiptRow(lines, " ", "recovery snapshot", [{ text: effect.snapshot, opaque: true }, { text: `· ${effect.retention}` }], columns);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
275
|
lines.push(...recordBlock(result, columns));
|
|
316
276
|
return lines.join("\n");
|
|
317
277
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { KanshiReport } from "../../kanshi/index.js";
|
|
2
|
+
import { type TextRenderContext } from "./terminal.js";
|
|
3
|
+
declare const NARROW_COLUMNS = 72;
|
|
4
|
+
declare function akumaMark(life: string): string;
|
|
5
|
+
declare function endpointFact(id: string, observed: string | undefined): string;
|
|
6
|
+
declare function renderAkuma(report: KanshiReport, context: TextRenderContext): readonly string[];
|
|
7
|
+
declare function formatAge(source: string | null | undefined, observedAt: string): string;
|
|
8
|
+
export { akumaMark, endpointFact, formatAge, NARROW_COLUMNS, renderAkuma };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { visibleFleetRows } from "../../kanshi/fleet.js";
|
|
2
|
+
import { boundedActivity, entityLines, identityLine, plumbFacts, renderSectionBlock, safeText, tone, } from "./terminal.js";
|
|
3
|
+
const PLUMB = " │ ";
|
|
4
|
+
const NARROW_COLUMNS = 72;
|
|
5
|
+
function akumaMark(life) {
|
|
6
|
+
return life === "running"
|
|
7
|
+
? "●"
|
|
8
|
+
: life === "stillborn"
|
|
9
|
+
? "!"
|
|
10
|
+
: life === "asleep"
|
|
11
|
+
? "○"
|
|
12
|
+
: life === "killed"
|
|
13
|
+
? "×"
|
|
14
|
+
: "?";
|
|
15
|
+
}
|
|
16
|
+
function activitySnapshotLine(row) {
|
|
17
|
+
const snapshot = row.snapshot;
|
|
18
|
+
if (snapshot === undefined)
|
|
19
|
+
return undefined;
|
|
20
|
+
const latest = snapshot.entries.flatMap((entry) => (entry.kind === "row" ? [entry.row] : [])).at(-1);
|
|
21
|
+
if (latest === undefined) {
|
|
22
|
+
if (snapshot.kind !== "idle" || snapshot.outcome === undefined)
|
|
23
|
+
return undefined;
|
|
24
|
+
return snapshot.outcome.outcome.kind === "answered"
|
|
25
|
+
? snapshot.outcome.outcome.answer
|
|
26
|
+
: snapshot.outcome.outcome.diagnostic;
|
|
27
|
+
}
|
|
28
|
+
if (latest.kind === "tool")
|
|
29
|
+
return latest.name;
|
|
30
|
+
return "text" in latest ? latest.text : "activity";
|
|
31
|
+
}
|
|
32
|
+
function akumaLabel(row) {
|
|
33
|
+
const aliases = row.aliases ?? [];
|
|
34
|
+
return aliases.length === 0 ? "" : `(${aliases.join(" ")})`;
|
|
35
|
+
}
|
|
36
|
+
function endpointFact(id, observed) {
|
|
37
|
+
return observed === "missing"
|
|
38
|
+
? `-> ${id} (missing)`
|
|
39
|
+
: observed === "unavailable"
|
|
40
|
+
? `-> ${id} (unavailable)`
|
|
41
|
+
: `-> ${id}`;
|
|
42
|
+
}
|
|
43
|
+
function renderAkuma(report, context) {
|
|
44
|
+
const section = report.akuma;
|
|
45
|
+
if (section.kind === "absent")
|
|
46
|
+
return ["AKUMA // absent", "", `${PLUMB}akuma absent`];
|
|
47
|
+
if (section.kind === "failed")
|
|
48
|
+
return ["AKUMA // unavailable", "", tone(`! ${safeText(section.failure.message)}`, "alert", context.color)];
|
|
49
|
+
const rows = visibleFleetRows(section.value.rows);
|
|
50
|
+
const rowLines = rows.map((row) => {
|
|
51
|
+
const lifeAt = "lifeAt" in row ? row.lifeAt : null;
|
|
52
|
+
const life = `${row.life} · ${formatAge(lifeAt, report.observedAt)}`;
|
|
53
|
+
const activity = "lastActivityAt" in row && row.lastActivityAt !== null
|
|
54
|
+
? [`activity ${formatAge(row.lastActivityAt, report.observedAt)}`]
|
|
55
|
+
: [];
|
|
56
|
+
const key = row.life === "stranded" && "strandedReason" in row && row.strandedReason === "resume-unsupported"
|
|
57
|
+
? [life, ...activity, "resume unsupported"]
|
|
58
|
+
: [life, ...activity];
|
|
59
|
+
const relation = row.contract === undefined ? ["unbound"] : [endpointFact(row.contract.id, row.contract.observed)];
|
|
60
|
+
const snapshot = activitySnapshotLine(row);
|
|
61
|
+
const aliases = akumaLabel(row);
|
|
62
|
+
if (context.columns > NARROW_COLUMNS) {
|
|
63
|
+
const lines = [
|
|
64
|
+
identityLine(akumaMark(row.life), row.id, `${aliases} · ${[...key, ...relation].join(" · ")}`.trim()),
|
|
65
|
+
];
|
|
66
|
+
return snapshot === undefined
|
|
67
|
+
? lines
|
|
68
|
+
: [...lines, ...plumbFacts([boundedActivity(snapshot, context.columns, PLUMB)], context.columns)];
|
|
69
|
+
}
|
|
70
|
+
const identity = aliases.length === 0 ? row.id : `${row.id} ${aliases}`;
|
|
71
|
+
const lines = entityLines({
|
|
72
|
+
mark: akumaMark(row.life),
|
|
73
|
+
identity,
|
|
74
|
+
state: key[0],
|
|
75
|
+
title: "",
|
|
76
|
+
facts: [...key.slice(1), ...relation],
|
|
77
|
+
context,
|
|
78
|
+
});
|
|
79
|
+
return snapshot === undefined
|
|
80
|
+
? lines
|
|
81
|
+
: [...lines, ...plumbFacts([boundedActivity(snapshot, context.columns, PLUMB)], context.columns)];
|
|
82
|
+
});
|
|
83
|
+
const header = `AKUMA // ${rows.length} recent · ${section.value.rows.length} known`;
|
|
84
|
+
const rendered = renderSectionBlock({
|
|
85
|
+
name: "AKUMA",
|
|
86
|
+
unit: "akuma",
|
|
87
|
+
selector: "aku",
|
|
88
|
+
continuation: 'keiyaku ls "aku/*/*"',
|
|
89
|
+
rows: rowLines,
|
|
90
|
+
total: section.value.rows.length,
|
|
91
|
+
neutral: true,
|
|
92
|
+
});
|
|
93
|
+
return [header, ...rendered.slice(1)];
|
|
94
|
+
}
|
|
95
|
+
function formatAge(source, observedAt) {
|
|
96
|
+
if (source === null || source === undefined)
|
|
97
|
+
return "—";
|
|
98
|
+
const sourceMs = Date.parse(source);
|
|
99
|
+
const observedMs = Date.parse(observedAt);
|
|
100
|
+
if (sourceMs > observedMs)
|
|
101
|
+
return "now";
|
|
102
|
+
const seconds = Math.floor((observedMs - sourceMs) / 1_000);
|
|
103
|
+
if (seconds < 60)
|
|
104
|
+
return `${seconds}s`;
|
|
105
|
+
const minutes = Math.floor(seconds / 60);
|
|
106
|
+
if (minutes < 60)
|
|
107
|
+
return `${minutes}m`;
|
|
108
|
+
const hours = Math.floor(minutes / 60);
|
|
109
|
+
return hours < 24 ? `${hours}h` : `${Math.floor(hours / 24)}d`;
|
|
110
|
+
}
|
|
111
|
+
export { akumaMark, endpointFact, formatAge, NARROW_COLUMNS, renderAkuma };
|