@astrosheep/keiyaku 4.0.1 → 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 +137 -5
- 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/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
- package/build/src/akuma/abort.d.ts +2 -0
- package/build/src/akuma/abort.js +50 -0
- package/build/src/akuma/akuma.d.ts +23 -14
- package/build/src/akuma/akuma.js +120 -104
- package/build/src/akuma/archetype.d.ts +7 -6
- package/build/src/akuma/archetype.js +68 -41
- package/build/src/akuma/body.d.ts +3 -5
- package/build/src/akuma/body.js +408 -213
- package/build/src/akuma/heart/facts.d.ts +25 -34
- package/build/src/akuma/heart/facts.js +18 -7
- package/build/src/akuma/heart/index.d.ts +39 -42
- package/build/src/akuma/heart/index.js +134 -93
- package/build/src/akuma/heart/rows.d.ts +9 -31
- package/build/src/akuma/heart/rows.js +26 -44
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +7 -15
- 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 +28 -14
- package/build/src/akuma/heart/storage.js +86 -26
- package/build/src/akuma/identity.d.ts +2 -2
- package/build/src/akuma/identity.js +9 -9
- package/build/src/akuma/index.d.ts +6 -1
- package/build/src/akuma/index.js +6 -0
- package/build/src/akuma/projection.d.ts +117 -38
- package/build/src/akuma/projection.js +208 -97
- 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 +12 -4
- package/build/src/akuma/provider.js +117 -70
- 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/events.js +66 -13
- package/build/src/akuma/providers/claude/index.d.ts +2 -1
- package/build/src/akuma/providers/claude/index.js +35 -21
- package/build/src/akuma/providers/codex-app-server/events.js +4 -1
- package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
- package/build/src/akuma/providers/codex-app-server/index.js +24 -31
- 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 +24 -59
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
- package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
- package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
- package/build/src/akuma/providers/pi/events.js +49 -11
- package/build/src/akuma/providers/pi/index.d.ts +1 -1
- package/build/src/akuma/providers/pi/index.js +50 -21
- 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 -7
- package/build/src/akuma/requests.js +92 -65
- package/build/src/alias/index.d.ts +2 -2
- package/build/src/alias/index.js +10 -10
- 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/cli/accepted.d.ts +17 -13
- package/build/src/cli/accepted.js +72 -34
- package/build/src/cli/actor.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
- package/build/src/cli/commands/akuma-invoke.js +14 -9
- package/build/src/cli/commands/akuma.d.ts +13 -3
- package/build/src/cli/commands/akuma.js +67 -34
- package/build/src/cli/commands/contract.d.ts +18 -5
- package/build/src/cli/commands/contract.js +9 -3
- package/build/src/cli/commands/task-invoke.d.ts +17 -4
- package/build/src/cli/commands/task-invoke.js +43 -20
- 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 +51 -13
- 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 +4 -3
- package/build/src/cli/invoke.js +160 -179
- package/build/src/cli/main.js +34 -6
- package/build/src/cli/parse.d.ts +9 -2
- package/build/src/cli/parse.js +29 -7
- 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 +2 -2
- package/build/src/cli/render/akuma-tool.js +30 -4
- package/build/src/cli/render/akuma.d.ts +1 -0
- package/build/src/cli/render/akuma.js +211 -116
- package/build/src/cli/render/audit.d.ts +3 -0
- package/build/src/cli/render/audit.js +104 -0
- package/build/src/cli/render/contract.d.ts +3 -3
- package/build/src/cli/render/contract.js +192 -79
- package/build/src/cli/render/kanshi.js +263 -168
- 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 -20
- 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 +7 -0
- package/build/src/cli/render/terminal.js +46 -0
- package/build/src/cli/render/text.js +6 -3
- package/build/src/cli/result.d.ts +115 -20
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +3 -0
- package/build/src/contract-worktree.d.ts +6 -5
- package/build/src/contract-worktree.js +95 -57
- package/build/src/coordination/durable-file.d.ts +4 -3
- package/build/src/coordination/durable-file.js +29 -25
- 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/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/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +0 -11
- package/build/src/core/verbs/deliver.d.ts +1 -1
- package/build/src/core/verbs/deliver.js +1 -7
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +4 -1
- package/build/src/dispatch/index.d.ts +2 -2
- package/build/src/dispatch/index.js +17 -17
- package/build/src/git/admission.d.ts +1 -1
- package/build/src/git/admission.js +11 -11
- package/build/src/git/hooks.js +13 -13
- package/build/src/git/integration.d.ts +14 -15
- package/build/src/git/integration.js +80 -44
- package/build/src/git/observe.d.ts +5 -3
- package/build/src/git/observe.js +18 -12
- package/build/src/git/read-observation.js +9 -9
- package/build/src/git/reconcile.d.ts +2 -0
- package/build/src/git/reconcile.js +138 -95
- package/build/src/git/repository.d.ts +27 -19
- package/build/src/git/repository.js +155 -83
- package/build/src/git/scratch.d.ts +7 -3
- package/build/src/git/scratch.js +44 -37
- package/build/src/git/target-placement.d.ts +40 -4
- package/build/src/git/target-placement.js +221 -101
- package/build/src/git/tender.d.ts +6 -5
- package/build/src/git/tender.js +24 -43
- package/build/src/git/terminal-seal.d.ts +1 -1
- package/build/src/git/terminal-seal.js +7 -5
- package/build/src/git/workspace.d.ts +36 -4
- package/build/src/git/workspace.js +53 -18
- package/build/src/identity/selector.js +1 -1
- package/build/src/index.d.ts +3 -3
- package/build/src/index.js +1 -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 +2 -1
- package/build/src/kanshi/read.js +118 -27
- package/build/src/kanshi/report.d.ts +50 -0
- package/build/src/kanshi/select.d.ts +5 -0
- package/build/src/kanshi/select.js +32 -0
- package/build/src/library/address.d.ts +12 -3
- package/build/src/library/address.js +77 -46
- package/build/src/library/akuma-creation.d.ts +6 -1
- package/build/src/library/akuma-creation.js +86 -13
- package/build/src/library/audit.d.ts +18 -0
- package/build/src/library/audit.js +44 -0
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -1
- package/build/src/library/catalog.js +5 -8
- package/build/src/library/contract.d.ts +5 -6
- package/build/src/library/contract.js +11 -35
- package/build/src/library/delivery.d.ts +2 -1
- package/build/src/library/fleet.d.ts +2 -2
- package/build/src/library/fleet.js +35 -71
- package/build/src/library/keiyaku.d.ts +3 -2
- package/build/src/library/keiyaku.js +1 -0
- package/build/src/library/mutation.d.ts +7 -6
- package/build/src/library/mutation.js +23 -25
- package/build/src/library/reconcile.d.ts +29 -0
- package/build/src/library/reconcile.js +179 -0
- package/build/src/library/region.d.ts +12 -0
- package/build/src/library/region.js +15 -1
- package/build/src/library/repo.d.ts +4 -16
- package/build/src/library/repo.js +13 -38
- package/build/src/protocol/attempt.js +6 -6
- package/build/src/protocol/bind.js +4 -4
- package/build/src/protocol/intent.d.ts +15 -2
- package/build/src/protocol/intent.js +21 -6
- package/build/src/protocol/operations.d.ts +73 -22
- package/build/src/protocol/operations.js +292 -88
- package/build/src/protocol/outcome.d.ts +9 -3
- package/build/src/protocol/outcome.js +3 -1
- package/build/src/protocol/placement.d.ts +15 -4
- package/build/src/protocol/placement.js +58 -25
- package/build/src/protocol/read/status.d.ts +8 -1
- package/build/src/protocol/read/status.js +61 -14
- package/build/src/runtime/proc/line-rpc.d.ts +3 -8
- package/build/src/runtime/proc/line-rpc.js +16 -43
- package/build/src/runtime/proc/run.d.ts +15 -29
- package/build/src/runtime/proc/run.js +113 -105
- 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 +2 -2
- package/build/src/settings.js +8 -8
- package/build/src/settlement/fence.d.ts +0 -4
- package/build/src/settlement/fence.js +0 -9
- package/build/src/settlement/holder.d.ts +11 -1
- package/build/src/settlement/holder.js +25 -0
- package/build/src/settlement/settle.d.ts +1 -1
- package/build/src/settlement/settle.js +52 -89
- package/build/src/task/board.d.ts +3 -3
- package/build/src/task/board.js +6 -9
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +18 -10
- package/build/src/task/context.d.ts +3 -3
- package/build/src/task/context.js +14 -14
- package/build/src/task/document.d.ts +2 -1
- package/build/src/task/document.js +15 -5
- package/build/src/task/index.d.ts +19 -7
- package/build/src/task/index.js +42 -23
- package/build/src/task/operations.d.ts +15 -9
- package/build/src/task/operations.js +78 -48
- package/build/src/task/query.d.ts +67 -0
- package/build/src/task/query.js +279 -0
- package/build/src/task/store.d.ts +2 -2
- package/build/src/task/store.js +40 -25
- package/build/src/verification/execution.d.ts +4 -2
- package/build/src/verification/execution.js +9 -5
- package/build/src/workspace-place.d.ts +41 -0
- package/build/src/workspace-place.js +386 -0
- package/build/src/world.d.ts +13 -2
- package/build/src/world.js +81 -48
- package/package.json +3 -2
- package/build/src/protocol/read/audit.d.ts +0 -31
- package/build/src/protocol/read/audit.js +0 -55
|
@@ -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,10 +25,10 @@ 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")
|
|
@@ -35,39 +46,111 @@ function gateMark(report) {
|
|
|
35
46
|
return "?";
|
|
36
47
|
return report.current.verdict === "satisfied" ? "✓" : "!";
|
|
37
48
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
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`;
|
|
40
64
|
}
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
return priorities.flatMap((value) => rows.filter((row) => priority(row) === value));
|
|
65
|
+
function isLost(life) {
|
|
66
|
+
return life === "stranded" || life === "hung" || life === "untidy";
|
|
44
67
|
}
|
|
45
|
-
function
|
|
46
|
-
if (
|
|
47
|
-
return
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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;
|
|
58
126
|
}
|
|
59
|
-
|
|
60
|
-
|
|
127
|
+
return row.gates.reports.some((report) => report.current.kind === "stale"
|
|
128
|
+
|| (report.current.kind === "attested" && report.current.verdict === "unsatisfied"));
|
|
61
129
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
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";
|
|
137
|
+
}
|
|
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 [];
|
|
64
147
|
const lines = [];
|
|
65
|
-
let current =
|
|
66
|
-
for (const fact of
|
|
67
|
-
const candidate = `${current} · ${fact}`;
|
|
68
|
-
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) {
|
|
69
152
|
lines.push(current);
|
|
70
|
-
current =
|
|
153
|
+
current = `${PLUMB}${fact}`;
|
|
71
154
|
}
|
|
72
155
|
else
|
|
73
156
|
current = candidate;
|
|
@@ -75,178 +158,190 @@ function wrapHeading(primary, facts, columns) {
|
|
|
75
158
|
lines.push(current);
|
|
76
159
|
return lines;
|
|
77
160
|
}
|
|
78
|
-
function
|
|
79
|
-
|
|
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)];
|
|
80
174
|
if (!includeSummaries)
|
|
81
175
|
return lines;
|
|
82
176
|
for (const report of reports) {
|
|
83
177
|
if (report.current.kind !== "attested" || report.current.summary === undefined)
|
|
84
178
|
continue;
|
|
85
|
-
lines.push(...
|
|
86
|
-
.map((line) => tone(line, "dim", context.color)));
|
|
179
|
+
lines.push(...plumbBlock(`${report.gate}: ${report.current.summary}`, columns));
|
|
87
180
|
}
|
|
88
181
|
return lines;
|
|
89
182
|
}
|
|
90
183
|
function failure(name, section, context) {
|
|
91
|
-
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}`;
|
|
92
195
|
}
|
|
93
196
|
function renderContracts(report, context, selection) {
|
|
94
197
|
const section = report.contracts;
|
|
95
198
|
if (section.kind === "absent")
|
|
96
|
-
return "
|
|
199
|
+
return sectionAbsent("KEIYAKU", context.columns);
|
|
97
200
|
if (section.kind === "failed")
|
|
98
|
-
return failure("
|
|
99
|
-
const rows =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return 2;
|
|
105
|
-
});
|
|
106
|
-
const lines = [`keiyaku ${rows.length}`];
|
|
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)];
|
|
107
207
|
for (const row of rows) {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
row.workspace,
|
|
126
|
-
...deliveryFacts,
|
|
127
|
-
...(row.target === null ? [] : [`-> ${row.target}`]),
|
|
128
|
-
...targetFacts,
|
|
129
|
-
];
|
|
130
|
-
lines.push(`${contractMark(row.phase)} ${safeText(row.id)} ${row.phase}`);
|
|
131
|
-
lines.push(...wrapChain(facts, context.columns));
|
|
132
|
-
lines.push(...renderGates(row.gates.reports, context, selection === "contract"));
|
|
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"));
|
|
133
225
|
if (row.holder.kind === "held")
|
|
134
|
-
lines.push(...
|
|
226
|
+
lines.push(...plumbFacts([`task ${row.holder.taskId}`], context.columns));
|
|
135
227
|
if (row.holder.kind === "unavailable")
|
|
136
|
-
lines.push(...
|
|
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
|
+
}
|
|
137
233
|
}
|
|
138
|
-
|
|
234
|
+
const attention = rows.filter(contractHot).length;
|
|
235
|
+
lines.push(aperture(`${rows.length} keiyaku · ${attention} attention`, context.columns));
|
|
236
|
+
return lines;
|
|
139
237
|
}
|
|
140
238
|
function renderTasks(report, context) {
|
|
141
239
|
const section = report.tasks;
|
|
142
240
|
if (section.kind === "absent")
|
|
143
|
-
return "
|
|
241
|
+
return sectionAbsent("TASK", context.columns);
|
|
144
242
|
if (section.kind === "failed")
|
|
145
|
-
return failure("
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const lines = [
|
|
151
|
-
for (const row of
|
|
152
|
-
const
|
|
153
|
-
lines.push(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
243
|
+
return failure("TASK", section, context);
|
|
244
|
+
const rows = [
|
|
245
|
+
...section.value.rows.filter(taskHot),
|
|
246
|
+
...section.value.rows.filter((row) => !taskHot(row)),
|
|
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));
|
|
158
265
|
}
|
|
159
266
|
}
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return life === "stranded" || life === "headless";
|
|
164
|
-
}
|
|
165
|
-
function akumaPriority(row) {
|
|
166
|
-
if (isLost(row.life) || row.life === "stillborn")
|
|
167
|
-
return 0;
|
|
168
|
-
return row.life === "running" ? 1 : 2;
|
|
169
|
-
}
|
|
170
|
-
function firstLine(value) {
|
|
171
|
-
return value.split(/[\r\n\u2028\u2029]/u, 1)[0] ?? "";
|
|
172
|
-
}
|
|
173
|
-
function truncateDisplay(value, columns) {
|
|
174
|
-
if (displayColumns(value) <= columns)
|
|
175
|
-
return value;
|
|
176
|
-
if (columns <= 0)
|
|
177
|
-
return "";
|
|
178
|
-
const ellipsis = "…";
|
|
179
|
-
if (columns <= displayColumns(ellipsis))
|
|
180
|
-
return ellipsis;
|
|
181
|
-
let result = "";
|
|
182
|
-
let used = 0;
|
|
183
|
-
for (const character of value) {
|
|
184
|
-
const width = displayColumns(character);
|
|
185
|
-
if (used + width + displayColumns(ellipsis) > columns)
|
|
186
|
-
break;
|
|
187
|
-
result += character;
|
|
188
|
-
used += width;
|
|
189
|
-
}
|
|
190
|
-
return `${result}${ellipsis}`;
|
|
191
|
-
}
|
|
192
|
-
function bornFacts(row) {
|
|
193
|
-
const association = [
|
|
194
|
-
...(row.aliases ?? []).map((alias) => `alias ${alias}`),
|
|
195
|
-
...(row.contract === undefined ? [] : [`keiyaku ${row.contract.id} (${row.contract.observed})`]),
|
|
196
|
-
];
|
|
197
|
-
if (!("pending" in row) || (row.life !== "running" && !isLost(row.life)))
|
|
198
|
-
return association;
|
|
199
|
-
const confinement = row.confinement.kind === "unconfined"
|
|
200
|
-
? ["unconfined"]
|
|
201
|
-
: row.confinement.writableRoots.map((root, index) => index === 0 ? `writes ${root}` : root);
|
|
202
|
-
return [
|
|
203
|
-
...association,
|
|
204
|
-
...(row.pending.length === 0 ? [] : [`pending ${row.pending.length}`]),
|
|
205
|
-
...confinement,
|
|
206
|
-
];
|
|
267
|
+
const attention = rows.filter(taskHot).length;
|
|
268
|
+
lines.push(aperture(`${rows.length} task · ${attention} attention`, context.columns));
|
|
269
|
+
return lines;
|
|
207
270
|
}
|
|
208
|
-
function
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const prefix = " seal ";
|
|
212
|
-
const evidence = safeText(firstLine(row.seal.evidence)).trim();
|
|
213
|
-
if (evidence.length === 0)
|
|
214
|
-
return null;
|
|
215
|
-
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(" ")})`;
|
|
216
274
|
}
|
|
217
275
|
function renderAkuma(report, context) {
|
|
218
276
|
const section = report.akuma;
|
|
219
277
|
if (section.kind === "absent")
|
|
220
|
-
return "
|
|
278
|
+
return sectionAbsent("FLEET", context.columns);
|
|
221
279
|
if (section.kind === "failed")
|
|
222
|
-
return failure("
|
|
280
|
+
return failure("FLEET", section, context);
|
|
223
281
|
const rows = [
|
|
224
|
-
...section.value.rows.filter(
|
|
225
|
-
...section.value.rows.filter((row) =>
|
|
226
|
-
...section.value.rows.filter((row) => akumaPriority(row) === 2),
|
|
282
|
+
...section.value.rows.filter(akumaHot),
|
|
283
|
+
...section.value.rows.filter((row) => !akumaHot(row)),
|
|
227
284
|
];
|
|
228
|
-
const lines = [
|
|
285
|
+
const lines = [aperture("FLEET", context.columns)];
|
|
229
286
|
for (const row of rows) {
|
|
230
|
-
lines.push(
|
|
231
|
-
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
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
|
+
}
|
|
235
302
|
}
|
|
236
|
-
|
|
303
|
+
const attention = rows.filter(akumaHot).length;
|
|
304
|
+
lines.push(aperture(`${rows.length} akuma · ${attention} attention`, context.columns));
|
|
305
|
+
return lines;
|
|
237
306
|
}
|
|
238
|
-
|
|
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;
|
|
239
314
|
const branch = report.branch?.startsWith("refs/heads/") === true
|
|
240
315
|
? report.branch.slice("refs/heads/".length)
|
|
241
316
|
: report.branch;
|
|
242
|
-
const state = report.contracts.kind === "present" ? report.contracts.value.state : null;
|
|
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}`];
|
|
336
|
+
}
|
|
337
|
+
export function renderKanshiText(report, context = { columns: 80, color: false }, selection = "world") {
|
|
243
338
|
return [
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
renderAkuma(report, context),
|
|
251
|
-
].join("\n
|
|
339
|
+
...splitHorizon(report, context.columns),
|
|
340
|
+
"",
|
|
341
|
+
...renderContracts(report, context, selection),
|
|
342
|
+
"",
|
|
343
|
+
...renderTasks(report, context),
|
|
344
|
+
"",
|
|
345
|
+
...renderAkuma(report, context),
|
|
346
|
+
].join("\n");
|
|
252
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 {};
|