@astrosheep/keiyaku 4.0.0 → 4.0.2
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 +133 -8
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +13 -5
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -32
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +134 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +262 -46
- package/build/src/akuma/abort.d.ts +2 -0
- package/build/src/akuma/abort.js +50 -0
- package/build/src/akuma/akuma.d.ts +50 -33
- package/build/src/akuma/akuma.js +175 -127
- package/build/src/akuma/archetype.d.ts +14 -5
- package/build/src/akuma/archetype.js +85 -39
- package/build/src/akuma/body.d.ts +3 -5
- package/build/src/akuma/body.js +490 -183
- package/build/src/akuma/coordinate.d.ts +9 -0
- package/build/src/akuma/coordinate.js +22 -0
- package/build/src/akuma/heart/facts.d.ts +88 -45
- package/build/src/akuma/heart/facts.js +19 -8
- package/build/src/akuma/heart/index.d.ts +64 -55
- package/build/src/akuma/heart/index.js +172 -252
- package/build/src/akuma/heart/rows.d.ts +38 -83
- package/build/src/akuma/heart/rows.js +117 -155
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +61 -22
- package/build/src/akuma/heart/soul.d.ts +8 -0
- package/build/src/akuma/heart/soul.js +136 -0
- package/build/src/akuma/heart/storage.d.ts +47 -0
- package/build/src/akuma/heart/storage.js +224 -0
- package/build/src/akuma/heart/tells.d.ts +12 -0
- package/build/src/akuma/heart/tells.js +79 -0
- package/build/src/akuma/heart/timeline.d.ts +15 -0
- package/build/src/akuma/heart/timeline.js +86 -0
- package/build/src/akuma/identity.d.ts +2 -2
- package/build/src/akuma/identity.js +9 -9
- package/build/src/akuma/index.d.ts +10 -3
- package/build/src/akuma/index.js +7 -1
- package/build/src/akuma/projection.d.ts +176 -0
- package/build/src/akuma/projection.js +256 -0
- package/build/src/akuma/provider-recipe.d.ts +24 -0
- package/build/src/akuma/provider-recipe.js +100 -0
- package/build/src/akuma/provider.d.ts +67 -13
- package/build/src/akuma/provider.js +172 -105
- package/build/src/akuma/providers/acp/core.d.ts +19 -0
- package/build/src/akuma/providers/acp/core.js +159 -0
- package/build/src/akuma/providers/acp/events.d.ts +20 -0
- package/build/src/akuma/providers/acp/events.js +73 -0
- package/build/src/akuma/providers/acp/index.d.ts +12 -0
- package/build/src/akuma/providers/acp/index.js +94 -0
- package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
- package/build/src/akuma/providers/claude/events.js +238 -0
- package/build/src/akuma/providers/claude/index.d.ts +47 -0
- package/build/src/akuma/providers/claude/index.js +279 -0
- package/build/src/akuma/providers/claude/input.d.ts +13 -0
- package/build/src/akuma/providers/claude/input.js +109 -0
- package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
- package/build/src/akuma/providers/codex-app-server/events.js +15 -12
- package/build/src/akuma/providers/codex-app-server/index.d.ts +15 -13
- package/build/src/akuma/providers/codex-app-server/index.js +77 -33
- package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
- package/build/src/akuma/providers/grok-build/index.js +70 -0
- package/build/src/akuma/providers/index.d.ts +5 -3
- package/build/src/akuma/providers/index.js +35 -56
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +54 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +235 -0
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +33 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +308 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +26 -0
- package/build/src/akuma/providers/opencode-sdk/session.js +63 -0
- package/build/src/akuma/providers/pi/events.d.ts +33 -0
- package/build/src/akuma/providers/pi/events.js +166 -0
- package/build/src/akuma/providers/pi/index.d.ts +11 -0
- package/build/src/akuma/providers/pi/index.js +191 -0
- package/build/src/akuma/publication.d.ts +3 -3
- package/build/src/akuma/publication.js +28 -40
- package/build/src/akuma/requests.d.ts +9 -6
- package/build/src/akuma/requests.js +95 -65
- package/build/src/alias/index.d.ts +4 -3
- package/build/src/alias/index.js +12 -13
- package/build/src/body/decode.js +7 -1
- package/build/src/body/region.d.ts +2 -0
- package/build/src/body/region.js +77 -7
- package/build/src/body/render.js +2 -1
- package/build/src/body/shape.js +7 -1
- package/build/src/body/verification.js +19 -4
- package/build/src/cli/accepted.d.ts +18 -12
- package/build/src/cli/accepted.js +73 -34
- package/build/src/cli/actor.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +44 -19
- package/build/src/cli/commands/akuma-invoke.js +101 -52
- package/build/src/cli/commands/akuma.d.ts +27 -9
- package/build/src/cli/commands/akuma.js +151 -80
- package/build/src/cli/commands/contract.d.ts +155 -0
- package/build/src/cli/commands/contract.js +20 -0
- package/build/src/cli/commands/install.js +2 -0
- package/build/src/cli/commands/task-invoke.d.ts +19 -4
- package/build/src/cli/commands/task-invoke.js +65 -17
- package/build/src/cli/commands/task-query.d.ts +5 -0
- package/build/src/cli/commands/task-query.js +247 -0
- package/build/src/cli/commands/task.d.ts +3 -1
- package/build/src/cli/commands/task.js +52 -14
- package/build/src/cli/coordinates.d.ts +18 -0
- package/build/src/cli/coordinates.js +120 -0
- package/build/src/cli/draft.d.ts +8 -0
- package/build/src/cli/draft.js +96 -0
- package/build/src/cli/invoke.d.ts +9 -3
- package/build/src/cli/invoke.js +287 -108
- package/build/src/cli/main.js +54 -7
- package/build/src/cli/parse.d.ts +21 -117
- package/build/src/cli/parse.js +79 -84
- package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
- package/build/src/cli/render/akuma-tool-command.js +144 -0
- package/build/src/cli/render/akuma-tool.d.ts +4 -2
- package/build/src/cli/render/akuma-tool.js +35 -5
- package/build/src/cli/render/akuma.d.ts +3 -1
- package/build/src/cli/render/akuma.js +247 -212
- package/build/src/cli/render/audit.d.ts +3 -0
- package/build/src/cli/render/audit.js +104 -0
- package/build/src/cli/render/catalog.d.ts +2 -0
- package/build/src/cli/render/catalog.js +16 -0
- package/build/src/cli/render/contract.d.ts +3 -3
- package/build/src/cli/render/contract.js +200 -54
- package/build/src/cli/render/kanshi.js +272 -129
- package/build/src/cli/render/receipt.d.ts +19 -0
- package/build/src/cli/render/receipt.js +106 -0
- package/build/src/cli/render/refusal.d.ts +16 -2
- package/build/src/cli/render/refusal.js +88 -3
- package/build/src/cli/render/region.d.ts +2 -0
- package/build/src/cli/render/region.js +17 -0
- package/build/src/cli/render/task.d.ts +2 -1
- package/build/src/cli/render/task.js +223 -60
- package/build/src/cli/render/terminal.d.ts +20 -0
- package/build/src/cli/render/terminal.js +121 -0
- package/build/src/cli/render/text.js +11 -3
- package/build/src/cli/result.d.ts +126 -19
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +3 -0
- package/build/src/contract-worktree.d.ts +44 -0
- package/build/src/contract-worktree.js +251 -0
- package/build/src/coordination/durable-file.d.ts +5 -1
- package/build/src/coordination/durable-file.js +57 -10
- package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
- package/build/src/coordination/sqlite-transaction-lock.js +22 -5
- package/build/src/core/facts/codec.js +23 -4
- package/build/src/core/facts/eligibility.d.ts +1 -10
- package/build/src/core/facts/eligibility.js +0 -49
- package/build/src/core/facts/fold.js +1 -6
- package/build/src/core/facts/gate.d.ts +1 -0
- package/build/src/core/facts/gate.js +1 -0
- package/build/src/core/facts/observation.d.ts +3 -0
- package/build/src/core/facts/observation.js +12 -0
- package/build/src/core/facts/types.d.ts +10 -3
- package/build/src/core/subject.js +2 -2
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +3 -18
- package/build/src/core/verbs/bind.js +2 -16
- package/build/src/core/verbs/deliver.d.ts +1 -1
- package/build/src/core/verbs/deliver.js +14 -4
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +7 -9
- package/build/src/dispatch/index.d.ts +5 -3
- package/build/src/dispatch/index.js +30 -21
- package/build/src/duration.d.ts +10 -0
- package/build/src/duration.js +22 -0
- package/build/src/git/admission.d.ts +2 -2
- package/build/src/git/admission.js +33 -23
- package/build/src/git/hooks.d.ts +15 -0
- package/build/src/git/hooks.js +70 -18
- package/build/src/git/identity.d.ts +5 -1
- package/build/src/git/identity.js +23 -4
- package/build/src/git/integration.d.ts +48 -0
- package/build/src/git/integration.js +250 -0
- package/build/src/git/observe.d.ts +29 -15
- package/build/src/git/observe.js +185 -76
- package/build/src/git/read-observation.d.ts +41 -0
- package/build/src/git/read-observation.js +361 -0
- package/build/src/git/reconcile.d.ts +17 -5
- package/build/src/git/reconcile.js +305 -109
- package/build/src/git/repository.d.ts +41 -18
- package/build/src/git/repository.js +220 -114
- package/build/src/git/scratch.d.ts +17 -0
- package/build/src/git/scratch.js +73 -0
- package/build/src/git/target-placement.d.ts +92 -0
- package/build/src/git/target-placement.js +375 -0
- package/build/src/git/tender.d.ts +49 -0
- package/build/src/git/tender.js +63 -0
- package/build/src/git/terminal-seal.d.ts +24 -0
- package/build/src/git/terminal-seal.js +89 -0
- package/build/src/git/tree.d.ts +2 -2
- package/build/src/git/tree.js +4 -0
- package/build/src/git/workspace.d.ts +53 -0
- package/build/src/git/workspace.js +139 -0
- package/build/src/identity/selector.d.ts +6 -0
- package/build/src/identity/selector.js +19 -0
- package/build/src/index.d.ts +4 -2
- package/build/src/index.js +2 -1
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +7 -3
- package/build/src/kanshi/read.js +245 -45
- package/build/src/kanshi/report.d.ts +81 -6
- package/build/src/kanshi/select.d.ts +5 -0
- package/build/src/kanshi/select.js +33 -1
- package/build/src/library/address.d.ts +57 -0
- package/build/src/library/address.js +165 -0
- package/build/src/library/akuma-creation.d.ts +16 -7
- package/build/src/library/akuma-creation.js +96 -22
- package/build/src/library/audit.d.ts +18 -0
- package/build/src/library/audit.js +44 -0
- package/build/src/library/bind.d.ts +21 -0
- package/build/src/library/bind.js +56 -0
- package/build/src/library/catalog.d.ts +58 -0
- package/build/src/library/catalog.js +69 -0
- package/build/src/library/configuration.d.ts +6 -15
- package/build/src/library/configuration.js +14 -17
- package/build/src/library/contract.d.ts +23 -49
- package/build/src/library/contract.js +171 -185
- package/build/src/library/delivery.d.ts +24 -0
- package/build/src/library/delivery.js +21 -0
- package/build/src/library/fleet.d.ts +65 -0
- package/build/src/library/fleet.js +153 -0
- package/build/src/library/input.d.ts +3 -0
- package/build/src/library/input.js +19 -0
- package/build/src/library/keiyaku.d.ts +18 -3
- package/build/src/library/keiyaku.js +12 -1
- package/build/src/library/mutation.d.ts +39 -0
- package/build/src/library/mutation.js +37 -0
- package/build/src/library/reconcile.d.ts +29 -0
- package/build/src/library/reconcile.js +179 -0
- package/build/src/library/refusal.d.ts +21 -0
- package/build/src/library/refusal.js +29 -0
- package/build/src/library/region.d.ts +14 -1
- package/build/src/library/region.js +18 -4
- package/build/src/library/repo.d.ts +4 -13
- package/build/src/library/repo.js +14 -24
- package/build/src/protocol/attempt.d.ts +16 -3
- package/build/src/protocol/attempt.js +41 -10
- package/build/src/protocol/bind.d.ts +9 -2
- package/build/src/protocol/bind.js +48 -40
- package/build/src/protocol/intent.d.ts +57 -20
- package/build/src/protocol/intent.js +55 -79
- package/build/src/protocol/operations.d.ts +152 -43
- package/build/src/protocol/operations.js +482 -166
- package/build/src/protocol/outcome.d.ts +14 -3
- package/build/src/protocol/outcome.js +11 -3
- package/build/src/protocol/placement.d.ts +41 -0
- package/build/src/protocol/placement.js +147 -0
- package/build/src/protocol/read/documents.d.ts +2 -2
- package/build/src/protocol/read/documents.js +4 -4
- package/build/src/protocol/read/status.d.ts +18 -5
- package/build/src/protocol/read/status.js +73 -13
- package/build/src/protocol/run.d.ts +49 -7
- package/build/src/protocol/run.js +53 -25
- package/build/src/runtime/proc/line-rpc.d.ts +4 -8
- package/build/src/runtime/proc/line-rpc.js +22 -28
- package/build/src/runtime/proc/run.d.ts +23 -21
- package/build/src/runtime/proc/run.js +123 -89
- package/build/src/runtime/proc/stdio.d.ts +18 -0
- package/build/src/runtime/proc/stdio.js +58 -0
- package/build/src/settings.d.ts +7 -1
- package/build/src/settings.js +32 -17
- package/build/src/settlement/fence.d.ts +5 -0
- package/build/src/settlement/fence.js +14 -0
- package/build/src/settlement/holder.d.ts +35 -4
- package/build/src/settlement/holder.js +127 -28
- package/build/src/settlement/settle.d.ts +9 -1
- package/build/src/settlement/settle.js +74 -37
- package/build/src/task/board.d.ts +23 -5
- package/build/src/task/board.js +17 -10
- package/build/src/task/compose.d.ts +2 -2
- package/build/src/task/compose.js +18 -10
- package/build/src/task/context.d.ts +3 -3
- package/build/src/task/context.js +15 -20
- package/build/src/task/document.d.ts +2 -1
- package/build/src/task/document.js +15 -5
- package/build/src/task/index.d.ts +27 -15
- package/build/src/task/index.js +57 -35
- package/build/src/task/operations.d.ts +38 -13
- package/build/src/task/operations.js +80 -46
- package/build/src/task/query.d.ts +67 -0
- package/build/src/task/query.js +279 -0
- package/build/src/task/store.d.ts +5 -7
- package/build/src/task/store.js +43 -28
- package/build/src/verification/declaration.d.ts +1 -0
- package/build/src/verification/execution.d.ts +51 -0
- package/build/src/verification/execution.js +108 -0
- package/build/src/workspace-place.d.ts +41 -0
- package/build/src/workspace-place.js +386 -0
- package/build/src/world.d.ts +24 -0
- package/build/src/world.js +136 -0
- package/package.json +8 -4
- package/build/src/akuma/activity.d.ts +0 -66
- package/build/src/akuma/activity.js +0 -139
- package/build/src/akuma/providers/claude.js +0 -305
- package/build/src/context-root.d.ts +0 -4
- package/build/src/context-root.js +0 -15
- package/build/src/git/delivery.d.ts +0 -20
- package/build/src/git/delivery.js +0 -109
- package/build/src/git/verification.d.ts +0 -14
- package/build/src/git/verification.js +0 -56
- package/build/src/protocol/read/audit.d.ts +0 -25
- package/build/src/protocol/read/audit.js +0 -39
- package/build/src/verification/producer.d.ts +0 -23
- package/build/src/verification/producer.js +0 -54
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { displayColumns, renderTextBlock, safeText, tone } from "./terminal.js";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
const RULE = "─";
|
|
3
|
+
const HORIZON = "───";
|
|
4
|
+
const PLUMB = " │ ";
|
|
5
|
+
const PATH_PREFIX = `${PLUMB}↳ `;
|
|
6
|
+
function contractMark(row) {
|
|
7
|
+
if (row.phase === "claimed")
|
|
4
8
|
return "✓";
|
|
5
|
-
if (phase === "abandoned")
|
|
9
|
+
if (row.phase === "abandoned")
|
|
6
10
|
return "×";
|
|
7
|
-
if (
|
|
8
|
-
return "
|
|
11
|
+
if (row.title === null)
|
|
12
|
+
return "?";
|
|
13
|
+
if (row.gates.reports.some((report) => report.current.kind === "attested" && report.current.verdict === "unsatisfied")) {
|
|
14
|
+
return "!";
|
|
15
|
+
}
|
|
16
|
+
if (row.targetLag.kind === "unknown")
|
|
17
|
+
return "?";
|
|
18
|
+
if (row.phase === "waiting")
|
|
19
|
+
return "○";
|
|
9
20
|
return "●";
|
|
10
21
|
}
|
|
11
22
|
function taskMark(row) {
|
|
@@ -14,18 +25,20 @@ function taskMark(row) {
|
|
|
14
25
|
if (row.disposition === "drop")
|
|
15
26
|
return "×";
|
|
16
27
|
if (row.disposition === "on_hold")
|
|
17
|
-
return "
|
|
28
|
+
return "⧗";
|
|
18
29
|
if (row.disposition === "in_progress")
|
|
19
30
|
return "●";
|
|
20
|
-
return row.disposition === "blocked" ? "
|
|
31
|
+
return row.disposition === "blocked" ? "‖" : "○";
|
|
21
32
|
}
|
|
22
33
|
function akumaMark(life) {
|
|
23
34
|
if (life === "running")
|
|
24
35
|
return "●";
|
|
25
36
|
if (life === "stillborn")
|
|
26
37
|
return "!";
|
|
27
|
-
if (life === "asleep"
|
|
38
|
+
if (life === "asleep")
|
|
28
39
|
return "○";
|
|
40
|
+
if (life === "killed")
|
|
41
|
+
return "×";
|
|
29
42
|
return "?";
|
|
30
43
|
}
|
|
31
44
|
function gateMark(report) {
|
|
@@ -33,35 +46,111 @@ function gateMark(report) {
|
|
|
33
46
|
return "?";
|
|
34
47
|
return report.current.verdict === "satisfied" ? "✓" : "!";
|
|
35
48
|
}
|
|
36
|
-
function
|
|
37
|
-
|
|
49
|
+
function formatAge(source, observedAt) {
|
|
50
|
+
if (source === null || source === undefined)
|
|
51
|
+
return "—";
|
|
52
|
+
const sourceMs = Date.parse(source);
|
|
53
|
+
const observedMs = Date.parse(observedAt);
|
|
54
|
+
if (sourceMs > observedMs)
|
|
55
|
+
return "future";
|
|
56
|
+
const seconds = Math.floor((observedMs - sourceMs) / 1_000);
|
|
57
|
+
if (seconds < 60)
|
|
58
|
+
return `${seconds}s`;
|
|
59
|
+
const minutes = Math.floor(seconds / 60);
|
|
60
|
+
if (minutes < 60)
|
|
61
|
+
return `${minutes}m`;
|
|
62
|
+
const hours = Math.floor(minutes / 60);
|
|
63
|
+
return hours < 24 ? `${hours}h` : `${Math.floor(hours / 24)}d`;
|
|
38
64
|
}
|
|
39
|
-
function
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
65
|
+
function isLost(life) {
|
|
66
|
+
return life === "stranded" || life === "hung" || life === "untidy";
|
|
67
|
+
}
|
|
68
|
+
function branchName(target) {
|
|
69
|
+
if (target === null)
|
|
70
|
+
return null;
|
|
71
|
+
return target.startsWith("refs/heads/") ? target.slice("refs/heads/".length) : target;
|
|
72
|
+
}
|
|
73
|
+
function targetFacts(row) {
|
|
74
|
+
const name = branchName(row.target);
|
|
75
|
+
if (name === null)
|
|
76
|
+
return ["no target"];
|
|
77
|
+
const facts = [`target ${name}`];
|
|
78
|
+
if (row.targetLag.kind === "unknown")
|
|
79
|
+
facts.push("behind unknown");
|
|
80
|
+
if (row.targetLag.kind === "counted")
|
|
81
|
+
facts.push(`behind ${row.targetLag.behind}`);
|
|
82
|
+
if (row.targetObservation?.drift === true)
|
|
83
|
+
facts.push("drift");
|
|
84
|
+
return facts;
|
|
85
|
+
}
|
|
86
|
+
function workspaceState(row) {
|
|
87
|
+
const observation = row.workspaceObservation;
|
|
88
|
+
if (row.workspace === "here")
|
|
89
|
+
return `workspace here · ${observation.kind}`;
|
|
90
|
+
if (observation.kind === "unappointed")
|
|
91
|
+
return "worktree unappointed";
|
|
92
|
+
if (observation.kind === "unavailable")
|
|
93
|
+
return "worktree unavailable";
|
|
94
|
+
if (observation.kind === "clean")
|
|
95
|
+
return "worktree clean";
|
|
96
|
+
const counts = [
|
|
97
|
+
...(observation.counts.staged > 0 ? [`staged ${observation.counts.staged}`] : []),
|
|
98
|
+
...(observation.counts.unstaged > 0 ? [`unstaged ${observation.counts.unstaged}`] : []),
|
|
99
|
+
...(observation.counts.untracked > 0 ? [`untracked ${observation.counts.untracked}`] : []),
|
|
100
|
+
...(observation.counts.submodules > 0 ? [`submodules ${observation.counts.submodules}`] : []),
|
|
101
|
+
];
|
|
102
|
+
return counts.length === 0 ? "worktree dirty" : `worktree dirty · ${counts.join(" · ")}`;
|
|
103
|
+
}
|
|
104
|
+
function showWorkspacePath(row, hot) {
|
|
105
|
+
if (row.workspace !== "worktree")
|
|
106
|
+
return false;
|
|
107
|
+
if (row.workspaceObservation.kind === "unappointed")
|
|
108
|
+
return false;
|
|
109
|
+
if (row.workspaceObservation.kind !== "clean")
|
|
110
|
+
return true;
|
|
111
|
+
return hot;
|
|
112
|
+
}
|
|
113
|
+
function contractHot(row) {
|
|
114
|
+
if (row.title === null)
|
|
115
|
+
return true;
|
|
116
|
+
if (row.phase === "pending-delivery")
|
|
117
|
+
return true;
|
|
118
|
+
if (row.holder.kind === "unavailable" || row.holder.kind === "held")
|
|
119
|
+
return true;
|
|
120
|
+
if (row.fleet.length > 0)
|
|
121
|
+
return true;
|
|
122
|
+
if (row.targetLag.kind === "counted" && row.targetLag.behind > 0)
|
|
123
|
+
return true;
|
|
124
|
+
if (row.workspaceObservation.kind !== "clean" && row.workspaceObservation.kind !== "unappointed") {
|
|
125
|
+
return true;
|
|
52
126
|
}
|
|
53
|
-
|
|
54
|
-
|
|
127
|
+
return row.gates.reports.some((report) => report.current.kind === "stale"
|
|
128
|
+
|| (report.current.kind === "attested" && report.current.verdict === "unsatisfied"));
|
|
129
|
+
}
|
|
130
|
+
function taskHot(row) {
|
|
131
|
+
return row.disposition === "blocked" || row.disposition === "in_progress";
|
|
132
|
+
}
|
|
133
|
+
function akumaHot(row) {
|
|
134
|
+
if (row.life === "running" || row.life === "stillborn" || isLost(row.life))
|
|
135
|
+
return true;
|
|
136
|
+
return row.contract?.observed === "missing" || row.contract?.observed === "unavailable";
|
|
55
137
|
}
|
|
56
|
-
function
|
|
57
|
-
const
|
|
138
|
+
function aperture(label, columns) {
|
|
139
|
+
const prefix = `──[ ${label} ]`;
|
|
140
|
+
const fill = Math.max(1, columns - displayColumns(prefix));
|
|
141
|
+
return `${prefix}${RULE.repeat(fill)}`;
|
|
142
|
+
}
|
|
143
|
+
function plumbFacts(facts, columns) {
|
|
144
|
+
const clean = facts.map(safeText).filter((fact) => fact.length > 0);
|
|
145
|
+
if (clean.length === 0)
|
|
146
|
+
return [];
|
|
58
147
|
const lines = [];
|
|
59
|
-
let current =
|
|
60
|
-
for (const fact of
|
|
61
|
-
const candidate = `${current} · ${fact}`;
|
|
62
|
-
if (displayColumns(candidate) > columns) {
|
|
148
|
+
let current = PLUMB;
|
|
149
|
+
for (const fact of clean) {
|
|
150
|
+
const candidate = current === PLUMB ? `${PLUMB}${fact}` : `${current} · ${fact}`;
|
|
151
|
+
if (current !== PLUMB && displayColumns(candidate) > columns) {
|
|
63
152
|
lines.push(current);
|
|
64
|
-
current =
|
|
153
|
+
current = `${PLUMB}${fact}`;
|
|
65
154
|
}
|
|
66
155
|
else
|
|
67
156
|
current = candidate;
|
|
@@ -69,136 +158,190 @@ function wrapHeading(primary, facts, columns) {
|
|
|
69
158
|
lines.push(current);
|
|
70
159
|
return lines;
|
|
71
160
|
}
|
|
72
|
-
function
|
|
73
|
-
|
|
161
|
+
function plumbBlock(value, columns) {
|
|
162
|
+
return renderTextBlock(value, PLUMB, columns);
|
|
163
|
+
}
|
|
164
|
+
function plumbPath(path) {
|
|
165
|
+
return `${PATH_PREFIX}${safeText(path)}`;
|
|
166
|
+
}
|
|
167
|
+
function identityLine(mark, identity, extra = "") {
|
|
168
|
+
return extra.length === 0 ? `${mark} ${safeText(identity)}` : `${mark} ${safeText(identity)} ${safeText(extra)}`;
|
|
169
|
+
}
|
|
170
|
+
function renderGates(reports, observedAt, columns, includeSummaries) {
|
|
171
|
+
if (reports.length === 0)
|
|
172
|
+
return [];
|
|
173
|
+
const lines = [...plumbFacts([`gates: ${reports.map((report) => `${gateMark(report)} ${report.gate} ${formatAge(report.current.kind === "attested" ? report.current.at : null, observedAt)}`).join(" · ")}`], columns)];
|
|
74
174
|
if (!includeSummaries)
|
|
75
175
|
return lines;
|
|
76
176
|
for (const report of reports) {
|
|
77
177
|
if (report.current.kind !== "attested" || report.current.summary === undefined)
|
|
78
178
|
continue;
|
|
79
|
-
lines.push(...
|
|
80
|
-
.map((line) => tone(line, "dim", context.color)));
|
|
179
|
+
lines.push(...plumbBlock(`${report.gate}: ${report.current.summary}`, columns));
|
|
81
180
|
}
|
|
82
181
|
return lines;
|
|
83
182
|
}
|
|
84
183
|
function failure(name, section, context) {
|
|
85
|
-
return
|
|
184
|
+
return [aperture(name, context.columns), `${tone(`! ${safeText(section.failure.message)}`, "alert", context.color)}`];
|
|
185
|
+
}
|
|
186
|
+
function sectionAbsent(name, columns) {
|
|
187
|
+
return [aperture(name, columns), `${PLUMB}${name.toLowerCase()} absent`];
|
|
188
|
+
}
|
|
189
|
+
function endpointFact(id, observed) {
|
|
190
|
+
if (observed === "missing")
|
|
191
|
+
return `-> ${id} (missing)`;
|
|
192
|
+
if (observed === "unavailable")
|
|
193
|
+
return `-> ${id} (unavailable)`;
|
|
194
|
+
return `-> ${id}`;
|
|
86
195
|
}
|
|
87
196
|
function renderContracts(report, context, selection) {
|
|
88
197
|
const section = report.contracts;
|
|
89
198
|
if (section.kind === "absent")
|
|
90
|
-
return "
|
|
199
|
+
return sectionAbsent("KEIYAKU", context.columns);
|
|
91
200
|
if (section.kind === "failed")
|
|
92
|
-
return failure("
|
|
93
|
-
const rows =
|
|
94
|
-
|
|
201
|
+
return failure("KEIYAKU", section, context);
|
|
202
|
+
const rows = [
|
|
203
|
+
...section.value.rows.filter(contractHot),
|
|
204
|
+
...section.value.rows.filter((row) => !contractHot(row)),
|
|
205
|
+
];
|
|
206
|
+
const lines = [aperture("KEIYAKU", context.columns)];
|
|
95
207
|
for (const row of rows) {
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
lines.push(
|
|
102
|
-
|
|
103
|
-
|
|
208
|
+
const hot = contractHot(row);
|
|
209
|
+
const compact = !hot && selection !== "contract";
|
|
210
|
+
const title = row.title ?? "title unavailable";
|
|
211
|
+
const phase = `${row.phase} · ${formatAge(row.phaseAt, report.observedAt)}`;
|
|
212
|
+
lines.push(identityLine(contractMark(row), row.id));
|
|
213
|
+
lines.push(...plumbFacts(compact
|
|
214
|
+
? [title, phase, ...targetFacts(row)]
|
|
215
|
+
: [title], context.columns));
|
|
216
|
+
if (!compact)
|
|
217
|
+
lines.push(...plumbFacts([phase, ...targetFacts(row)], context.columns));
|
|
218
|
+
lines.push(...plumbFacts([workspaceState(row)], context.columns));
|
|
219
|
+
if (showWorkspacePath(row, hot || selection === "contract")
|
|
220
|
+
&& row.workspaceObservation.kind !== "unappointed"
|
|
221
|
+
&& row.workspaceObservation.location.kind === "worktree") {
|
|
222
|
+
lines.push(plumbPath(row.workspaceObservation.location.path));
|
|
223
|
+
}
|
|
224
|
+
lines.push(...renderGates(row.gates.reports, report.observedAt, context.columns, selection === "contract"));
|
|
225
|
+
if (row.holder.kind === "held")
|
|
226
|
+
lines.push(...plumbFacts([`task ${row.holder.taskId}`], context.columns));
|
|
227
|
+
if (row.holder.kind === "unavailable")
|
|
228
|
+
lines.push(...plumbFacts(["holder unavailable"], context.columns));
|
|
229
|
+
for (const attached of row.fleet) {
|
|
230
|
+
const aliases = attached.aliases.length === 0 ? "" : ` (${attached.aliases.join(" ")})`;
|
|
231
|
+
lines.push(...plumbFacts([`akuma ${attached.id}${aliases}`], context.columns));
|
|
232
|
+
}
|
|
104
233
|
}
|
|
105
|
-
|
|
234
|
+
const attention = rows.filter(contractHot).length;
|
|
235
|
+
lines.push(aperture(`${rows.length} keiyaku · ${attention} attention`, context.columns));
|
|
236
|
+
return lines;
|
|
106
237
|
}
|
|
107
238
|
function renderTasks(report, context) {
|
|
108
239
|
const section = report.tasks;
|
|
109
240
|
if (section.kind === "absent")
|
|
110
|
-
return "
|
|
241
|
+
return sectionAbsent("TASK", context.columns);
|
|
111
242
|
if (section.kind === "failed")
|
|
112
|
-
return failure("
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const visible = hotFirst(active.filter((row) => row.disposition === "in_progress" || row.disposition === "blocked"), (row) => row.disposition === "blocked");
|
|
117
|
-
const lines = [...wrapHeading(`task ${active.length}`, [`${ready} ready`, `${onHold} held`], context.columns)];
|
|
118
|
-
for (const row of visible) {
|
|
119
|
-
const contract = row.contract === undefined ? [] : [`keiyaku ${row.contract.id} (${row.contract.observed})`];
|
|
120
|
-
lines.push(`${taskMark(row)} ${safeText(row.id)} ${row.disposition}`);
|
|
121
|
-
lines.push(...renderTextBlock(row.title, " ", context.columns));
|
|
122
|
-
lines.push(...wrapChain([`P${row.priority}`, ...contract], context.columns));
|
|
123
|
-
}
|
|
124
|
-
return lines.join("\n");
|
|
125
|
-
}
|
|
126
|
-
function isLost(life) {
|
|
127
|
-
return life === "stranded" || life === "headless";
|
|
128
|
-
}
|
|
129
|
-
function akumaPriority(row) {
|
|
130
|
-
if (isLost(row.life) || row.life === "stillborn")
|
|
131
|
-
return 0;
|
|
132
|
-
return row.life === "running" ? 1 : 2;
|
|
133
|
-
}
|
|
134
|
-
function firstLine(value) {
|
|
135
|
-
return value.split(/[\r\n\u2028\u2029]/u, 1)[0] ?? "";
|
|
136
|
-
}
|
|
137
|
-
function truncateDisplay(value, columns) {
|
|
138
|
-
if (displayColumns(value) <= columns)
|
|
139
|
-
return value;
|
|
140
|
-
if (columns <= 0)
|
|
141
|
-
return "";
|
|
142
|
-
const ellipsis = "…";
|
|
143
|
-
if (columns <= displayColumns(ellipsis))
|
|
144
|
-
return ellipsis;
|
|
145
|
-
let result = "";
|
|
146
|
-
let used = 0;
|
|
147
|
-
for (const character of value) {
|
|
148
|
-
const width = displayColumns(character);
|
|
149
|
-
if (used + width + displayColumns(ellipsis) > columns)
|
|
150
|
-
break;
|
|
151
|
-
result += character;
|
|
152
|
-
used += width;
|
|
153
|
-
}
|
|
154
|
-
return `${result}${ellipsis}`;
|
|
155
|
-
}
|
|
156
|
-
function bornFacts(row) {
|
|
157
|
-
if (!("pending" in row) || (row.life !== "running" && !isLost(row.life)))
|
|
158
|
-
return [];
|
|
159
|
-
const confinement = row.confinement.kind === "unconfined"
|
|
160
|
-
? ["unconfined"]
|
|
161
|
-
: row.confinement.writableRoots.map((root, index) => index === 0 ? `writes ${root}` : root);
|
|
162
|
-
return [
|
|
163
|
-
...(row.pending.length === 0 ? [] : [`pending ${row.pending.length}`]),
|
|
164
|
-
...confinement,
|
|
243
|
+
return failure("TASK", section, context);
|
|
244
|
+
const rows = [
|
|
245
|
+
...section.value.rows.filter(taskHot),
|
|
246
|
+
...section.value.rows.filter((row) => !taskHot(row)),
|
|
165
247
|
];
|
|
248
|
+
const lines = [aperture("TASK", context.columns)];
|
|
249
|
+
for (const row of rows) {
|
|
250
|
+
const compact = !taskHot(row);
|
|
251
|
+
lines.push(identityLine(taskMark(row), row.id));
|
|
252
|
+
const relation = row.contract === undefined
|
|
253
|
+
? ["unbound"]
|
|
254
|
+
: [endpointFact(row.contract.id, row.contract.observed)];
|
|
255
|
+
const facts = [row.title, row.disposition, `P${row.priority}`, ...relation];
|
|
256
|
+
if (compact)
|
|
257
|
+
lines.push(...plumbFacts(facts, context.columns));
|
|
258
|
+
else {
|
|
259
|
+
lines.push(...plumbBlock(row.title, context.columns));
|
|
260
|
+
lines.push(...plumbFacts([row.disposition, `P${row.priority}`], context.columns));
|
|
261
|
+
for (const blocker of row.blockers ?? []) {
|
|
262
|
+
lines.push(...plumbFacts([`blocked by ${blocker.id}`], context.columns));
|
|
263
|
+
}
|
|
264
|
+
lines.push(...plumbFacts(relation, context.columns));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const attention = rows.filter(taskHot).length;
|
|
268
|
+
lines.push(aperture(`${rows.length} task · ${attention} attention`, context.columns));
|
|
269
|
+
return lines;
|
|
166
270
|
}
|
|
167
|
-
function
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const prefix = " seal ";
|
|
171
|
-
const evidence = safeText(firstLine(row.seal.evidence)).trim();
|
|
172
|
-
if (evidence.length === 0)
|
|
173
|
-
return null;
|
|
174
|
-
return `${prefix}${truncateDisplay(evidence, Math.max(0, columns - displayColumns(prefix)))}`;
|
|
271
|
+
function akumaLabel(row) {
|
|
272
|
+
const aliases = row.aliases ?? [];
|
|
273
|
+
return aliases.length === 0 ? "" : `(${aliases.join(" ")})`;
|
|
175
274
|
}
|
|
176
275
|
function renderAkuma(report, context) {
|
|
177
276
|
const section = report.akuma;
|
|
178
277
|
if (section.kind === "absent")
|
|
179
|
-
return "
|
|
278
|
+
return sectionAbsent("FLEET", context.columns);
|
|
180
279
|
if (section.kind === "failed")
|
|
181
|
-
return failure("
|
|
280
|
+
return failure("FLEET", section, context);
|
|
182
281
|
const rows = [
|
|
183
|
-
...section.value.rows.filter(
|
|
184
|
-
...section.value.rows.filter((row) =>
|
|
185
|
-
...section.value.rows.filter((row) => akumaPriority(row) === 2),
|
|
282
|
+
...section.value.rows.filter(akumaHot),
|
|
283
|
+
...section.value.rows.filter((row) => !akumaHot(row)),
|
|
186
284
|
];
|
|
187
|
-
const lines = [
|
|
285
|
+
const lines = [aperture("FLEET", context.columns)];
|
|
188
286
|
for (const row of rows) {
|
|
189
|
-
lines.push(
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
287
|
+
lines.push(identityLine(akumaMark(row.life), row.id, akumaLabel(row)));
|
|
288
|
+
const lifeAt = "lifeAt" in row ? row.lifeAt : null;
|
|
289
|
+
const life = `${row.life} · ${formatAge(lifeAt, report.observedAt)}`;
|
|
290
|
+
const key = row.life === "stranded" && "strandedReason" in row && row.strandedReason === "resume-unsupported"
|
|
291
|
+
? [life, "resume unsupported"]
|
|
292
|
+
: [life];
|
|
293
|
+
const relation = row.contract === undefined
|
|
294
|
+
? ["unbound"]
|
|
295
|
+
: [endpointFact(row.contract.id, row.contract.observed)];
|
|
296
|
+
if (!akumaHot(row))
|
|
297
|
+
lines.push(...plumbFacts([...key, ...relation], context.columns));
|
|
298
|
+
else {
|
|
299
|
+
lines.push(...plumbFacts(key, context.columns));
|
|
300
|
+
lines.push(...plumbFacts(relation, context.columns));
|
|
301
|
+
}
|
|
194
302
|
}
|
|
195
|
-
|
|
303
|
+
const attention = rows.filter(akumaHot).length;
|
|
304
|
+
lines.push(aperture(`${rows.length} akuma · ${attention} attention`, context.columns));
|
|
305
|
+
return lines;
|
|
306
|
+
}
|
|
307
|
+
function sectionCount(name, section) {
|
|
308
|
+
if (section.kind === "present")
|
|
309
|
+
return `${section.value.rows.length} ${name}`;
|
|
310
|
+
return `${section.kind} ${name}`;
|
|
311
|
+
}
|
|
312
|
+
function worldCoordinate(report) {
|
|
313
|
+
const project = report.root;
|
|
314
|
+
const branch = report.branch?.startsWith("refs/heads/") === true
|
|
315
|
+
? report.branch.slice("refs/heads/".length)
|
|
316
|
+
: report.branch;
|
|
317
|
+
const state = report.contracts.kind === "present" ? report.contracts.value.state ?? null : null;
|
|
318
|
+
return [project, branch, state].filter((part) => part !== null && part.length > 0).map(safeText).join(" ");
|
|
319
|
+
}
|
|
320
|
+
function splitHorizon(report, columns) {
|
|
321
|
+
if (report.root === null)
|
|
322
|
+
return ["✗ keiyaku world absent"];
|
|
323
|
+
const aggregate = [
|
|
324
|
+
sectionCount("keiyaku", report.contracts),
|
|
325
|
+
sectionCount("akuma", report.akuma),
|
|
326
|
+
sectionCount("task", report.tasks),
|
|
327
|
+
].join(" · ");
|
|
328
|
+
const world = worldCoordinate(report);
|
|
329
|
+
const minimum = `kanshi ${HORIZON} ${aggregate} ${HORIZON} ${world}`;
|
|
330
|
+
if (displayColumns(minimum) > columns)
|
|
331
|
+
return [minimum];
|
|
332
|
+
const fill = columns - displayColumns(minimum);
|
|
333
|
+
const left = Math.floor(fill / 2);
|
|
334
|
+
const right = Math.ceil(fill / 2);
|
|
335
|
+
return [`kanshi ${HORIZON}${RULE.repeat(left)} ${aggregate} ${HORIZON}${RULE.repeat(right)} ${world}`];
|
|
196
336
|
}
|
|
197
337
|
export function renderKanshiText(report, context = { columns: 80, color: false }, selection = "world") {
|
|
198
338
|
return [
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
339
|
+
...splitHorizon(report, context.columns),
|
|
340
|
+
"",
|
|
341
|
+
...renderContracts(report, context, selection),
|
|
342
|
+
"",
|
|
343
|
+
...renderTasks(report, context),
|
|
344
|
+
"",
|
|
345
|
+
...renderAkuma(report, context),
|
|
346
|
+
].join("\n");
|
|
204
347
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PlacementStop, VerificationReuse, VerificationStop } from "../../index.js";
|
|
2
|
+
import type { AcceptedDeliverResult, Lag } from "../result.js";
|
|
3
|
+
export type ReceiptSegment = Readonly<{
|
|
4
|
+
text: string;
|
|
5
|
+
opaque?: boolean;
|
|
6
|
+
}>;
|
|
7
|
+
type HookFailure = Extract<Lag, {
|
|
8
|
+
kind: "worktree-hook-failed";
|
|
9
|
+
}>["failure"];
|
|
10
|
+
export declare function receiptRow(lines: string[], mark: string, label: string, segments: readonly ReceiptSegment[], columns: number): void;
|
|
11
|
+
export declare function receiptPayload(lines: string[], label: string, payload: string): void;
|
|
12
|
+
export declare function outcomeLines(mark: "✓" | "!" | "?", verb: string, word: "accepted" | "refused" | "retry", contract: string | undefined, columns?: number): string[];
|
|
13
|
+
export declare function hookFailureSummary(failure: HookFailure): string;
|
|
14
|
+
export declare function appendHookPayload(lines: string[], failure: HookFailure): void;
|
|
15
|
+
export declare function reuseLines(reuse: VerificationReuse | undefined, columns: number): readonly string[];
|
|
16
|
+
export declare function stopLines(label: "verification" | "claim", stop: VerificationStop | PlacementStop, columns: number, addressed: string): readonly string[];
|
|
17
|
+
export declare function cleanupLines(cleanup: NonNullable<AcceptedDeliverResult["cleanup"]>, columns: number): readonly string[];
|
|
18
|
+
export declare function leakLines(leak: NonNullable<AcceptedDeliverResult["leak"]>, columns: number): readonly string[];
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { displayColumns, renderOpaqueBlock, safeText } from "./terminal.js";
|
|
2
|
+
export function receiptRow(lines, mark, label, segments, columns) {
|
|
3
|
+
let current = `${mark} ${label}`;
|
|
4
|
+
for (const segment of segments) {
|
|
5
|
+
const text = segment.opaque === true ? safeText(segment.text) : segment.text;
|
|
6
|
+
const candidate = `${current} ${text}`;
|
|
7
|
+
if (displayColumns(candidate) <= columns) {
|
|
8
|
+
current = candidate;
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
if (current === `${mark} ${label}` && segment.opaque === true) {
|
|
12
|
+
lines.push(current);
|
|
13
|
+
current = ` ${text}`;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
lines.push(current);
|
|
17
|
+
current = ` ${text}`;
|
|
18
|
+
}
|
|
19
|
+
lines.push(current);
|
|
20
|
+
}
|
|
21
|
+
export function receiptPayload(lines, label, payload) {
|
|
22
|
+
lines.push(label, "", payload, "");
|
|
23
|
+
}
|
|
24
|
+
export function outcomeLines(mark, verb, word, contract, columns = 80) {
|
|
25
|
+
const base = `${mark} ${verb} ${word}`;
|
|
26
|
+
if (contract === undefined)
|
|
27
|
+
return [base];
|
|
28
|
+
const inline = `${base} — ${contract}`;
|
|
29
|
+
if (displayColumns(inline) <= columns)
|
|
30
|
+
return [inline];
|
|
31
|
+
return [`${base} —`, ` ${safeText(contract)}`];
|
|
32
|
+
}
|
|
33
|
+
export function hookFailureSummary(failure) {
|
|
34
|
+
if (failure.kind === "timeout" || failure.kind === "unknown-exit")
|
|
35
|
+
return failure.kind;
|
|
36
|
+
if (failure.kind === "spawn-error")
|
|
37
|
+
return failure.kind;
|
|
38
|
+
return `exit=${failure.code} · truncated=${failure.truncated}`;
|
|
39
|
+
}
|
|
40
|
+
export function appendHookPayload(lines, failure) {
|
|
41
|
+
if (failure.kind === "spawn-error")
|
|
42
|
+
receiptPayload(lines, "diagnostic", failure.diagnostic);
|
|
43
|
+
if (!("stdout" in failure))
|
|
44
|
+
return;
|
|
45
|
+
if (failure.stdout.length > 0)
|
|
46
|
+
receiptPayload(lines, "stdout", failure.stdout);
|
|
47
|
+
if (failure.stderr.length > 0)
|
|
48
|
+
receiptPayload(lines, "stderr", failure.stderr);
|
|
49
|
+
}
|
|
50
|
+
export function reuseLines(reuse, columns) {
|
|
51
|
+
if (reuse === undefined)
|
|
52
|
+
return [];
|
|
53
|
+
return renderOpaqueBlock(`reuse verification ${reuse.entry} ${reuse.verdict}`, " ", columns);
|
|
54
|
+
}
|
|
55
|
+
export function stopLines(label, stop, columns, addressed) {
|
|
56
|
+
const detail = [];
|
|
57
|
+
if ("refusal" in stop && stop.refusal !== undefined) {
|
|
58
|
+
detail.push({ text: stop.refusal.kind });
|
|
59
|
+
if ("contractId" in stop.refusal && stop.refusal.contractId !== addressed) {
|
|
60
|
+
detail.push({ text: `contract=${stop.refusal.contractId}`, opaque: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if ("retry" in stop && stop.retry !== undefined) {
|
|
64
|
+
detail.push({ text: stop.retry.kind });
|
|
65
|
+
}
|
|
66
|
+
else if ("failure" in stop) {
|
|
67
|
+
detail.push({ text: stop.failure });
|
|
68
|
+
if (stop.failure === "environment-failure" && "command" in stop) {
|
|
69
|
+
detail.push({ text: `command=${stop.command}` }, { text: hookFailureSummary(stop.detail), opaque: true });
|
|
70
|
+
}
|
|
71
|
+
else if (stop.failure === "target-moved") {
|
|
72
|
+
detail.push({ text: stop.target, opaque: true }, { text: `${stop.expected} -> ${stop.observed}`, opaque: true });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const lines = [];
|
|
76
|
+
receiptRow(lines, "!", label, detail, columns);
|
|
77
|
+
if ("failure" in stop && stop.failure === "environment-failure" && "command" in stop) {
|
|
78
|
+
appendHookPayload(lines, stop.detail);
|
|
79
|
+
}
|
|
80
|
+
if ("retry" in stop && stop.retry?.kind === "publication-failed") {
|
|
81
|
+
receiptPayload(lines, "diagnostic", stop.retry.diagnostic);
|
|
82
|
+
}
|
|
83
|
+
else if ("failure" in stop && "diagnostic" in stop) {
|
|
84
|
+
receiptPayload(lines, "diagnostic", stop.diagnostic);
|
|
85
|
+
}
|
|
86
|
+
return lines;
|
|
87
|
+
}
|
|
88
|
+
export function cleanupLines(cleanup, columns) {
|
|
89
|
+
const lines = [];
|
|
90
|
+
receiptRow(lines, "!", "cleanup", [
|
|
91
|
+
{ text: cleanup.phase },
|
|
92
|
+
{ text: `command=${cleanup.command}` },
|
|
93
|
+
{ text: hookFailureSummary(cleanup.detail), opaque: true },
|
|
94
|
+
], columns);
|
|
95
|
+
appendHookPayload(lines, cleanup.detail);
|
|
96
|
+
return lines;
|
|
97
|
+
}
|
|
98
|
+
export function leakLines(leak, columns) {
|
|
99
|
+
const lines = [];
|
|
100
|
+
receiptRow(lines, "!", "leak", [
|
|
101
|
+
{ text: "worktree" },
|
|
102
|
+
{ text: leak.path, opaque: true },
|
|
103
|
+
], columns);
|
|
104
|
+
receiptPayload(lines, "diagnostic", leak.diagnostic);
|
|
105
|
+
return lines;
|
|
106
|
+
}
|
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
import type { RefusedResult } from "../result.js";
|
|
2
|
-
|
|
1
|
+
import type { BindDraftReceipt, RefusedResult } from "../result.js";
|
|
2
|
+
import type { KeiyakuRefusal } from "../../index.js";
|
|
3
|
+
import { type TextRenderContext } from "./terminal.js";
|
|
4
|
+
type DirtyWithOption = Extract<KeiyakuRefusal, {
|
|
5
|
+
kind: "dirty-workspace";
|
|
6
|
+
}> & {
|
|
7
|
+
option?: Readonly<{
|
|
8
|
+
flag: string;
|
|
9
|
+
available: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
};
|
|
12
|
+
export type RenderableRefusal = KeiyakuRefusal | DirtyWithOption;
|
|
13
|
+
export declare function renderRefusalFacts(refusal: RenderableRefusal, indent: string, columns: number, addressed?: string): readonly string[];
|
|
14
|
+
export declare function renderRefusal(result: RefusedResult, context?: TextRenderContext): string;
|
|
15
|
+
export declare function renderBindDraftReceipt(receipt: BindDraftReceipt): string;
|
|
16
|
+
export {};
|