@astrosheep/keiyaku 4.6.11 → 4.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/plugins/claude/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/plugins/codex/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/skills/keiyaku/SKILL.md +3 -1
- package/build/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/src/akuma/akuma-errors.d.ts +5 -0
- package/build/src/akuma/akuma-errors.js +9 -0
- package/build/src/akuma/akuma-owner.d.ts +14 -19
- package/build/src/akuma/akuma-owner.js +56 -54
- package/build/src/akuma/akuma-selection-execution.d.ts +5 -4
- package/build/src/akuma/akuma-selection-execution.js +59 -17
- package/build/src/akuma/akuma.d.ts +1 -2
- package/build/src/akuma/allowed.d.ts +2 -3
- package/build/src/akuma/allowed.js +1 -3
- package/build/src/akuma/body.js +17 -7
- package/build/src/akuma/call-initial-tell.d.ts +18 -0
- package/build/src/akuma/call-initial-tell.js +18 -0
- package/build/src/akuma/call-request.d.ts +20 -4
- package/build/src/akuma/heart/facts.d.ts +13 -0
- package/build/src/akuma/heart/facts.js +6 -0
- package/build/src/akuma/heart/index.d.ts +29 -14
- package/build/src/akuma/heart/index.js +75 -29
- package/build/src/akuma/heart/rows.d.ts +9 -2
- package/build/src/akuma/heart/rows.js +72 -11
- package/build/src/akuma/heart/storage.d.ts +2 -8
- package/build/src/akuma/heart/storage.js +13 -13
- package/build/src/akuma/heart/tells.d.ts +3 -1
- package/build/src/akuma/heart/tells.js +18 -2
- package/build/src/akuma/provider.d.ts +2 -4
- package/build/src/akuma/provider.js +29 -6
- package/build/src/akuma/providers/acp/core.js +23 -21
- package/build/src/akuma/providers/claude/index.js +0 -8
- package/build/src/akuma/providers/codex-app-server/index.js +9 -8
- package/build/src/akuma/providers/execution-environment.d.ts +1 -1
- package/build/src/akuma/providers/execution-environment.js +1 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +111 -81
- package/build/src/akuma/providers/opencode-sdk/index.js +179 -150
- package/build/src/akuma/providers/opencode-sdk/native-http.js +7 -3
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +5 -3
- package/build/src/akuma/providers/opencode-sdk/session.js +32 -27
- package/build/src/akuma/providers/paseo/index.js +0 -2
- package/build/src/akuma/providers/pi/index.js +23 -20
- package/build/src/akuma/selection-observation.d.ts +78 -9
- package/build/src/akuma/selection-owner-port.d.ts +2 -1
- package/build/src/akuma/selection-owner-port.js +6 -1
- package/build/src/akuma/selection-request.d.ts +1 -1
- package/build/src/akuma/selection-request.js +8 -3
- package/build/src/akuma/turn-drive.js +79 -48
- package/build/src/akuma-body.js +5 -3
- package/build/src/cli/commands/akuma-grammar.js +2 -2
- package/build/src/cli/commands/akuma.js +24 -16
- package/build/src/cli/commands/contract-grammar.d.ts +3 -7
- package/build/src/cli/commands/contract-grammar.js +12 -10
- package/build/src/cli/commands/contract-help.d.ts +3 -13
- package/build/src/cli/commands/contract-help.js +7 -16
- package/build/src/cli/commands/contract.js +19 -35
- package/build/src/cli/commands/debt.js +30 -29
- package/build/src/cli/parse.js +0 -1
- package/build/src/cli/render/akuma-activity.d.ts +36 -9
- package/build/src/cli/render/akuma-activity.js +142 -65
- package/build/src/cli/render/akuma.d.ts +6 -0
- package/build/src/cli/render/akuma.js +67 -24
- package/build/src/cli/render/catalog.js +0 -1
- package/build/src/cli/render/contract-observation.d.ts +16 -3
- package/build/src/cli/render/contract-observation.js +3 -0
- package/build/src/cli/render/contract.d.ts +2 -2
- package/build/src/cli/render/contract.js +4 -4
- package/build/src/cli/render/delivery-preview.d.ts +7 -0
- package/build/src/cli/render/{audit.js → delivery-preview.js} +29 -27
- package/build/src/cli/render/kanshi-akuma.d.ts +3 -1
- package/build/src/cli/render/kanshi-akuma.js +23 -8
- package/build/src/cli/render/kanshi.js +4 -1
- package/build/src/cli/render/receipt.js +3 -3
- package/build/src/cli/render/refusal.js +2 -2
- package/build/src/cli/render/terminal.d.ts +0 -1
- package/build/src/cli/render/terminal.js +1 -1
- package/build/src/cli/square-identity.d.ts +15 -0
- package/build/src/cli/square-identity.js +180 -0
- package/build/src/contract-worktree.js +1 -1
- package/build/src/core/verbs/placement.d.ts +2 -1
- package/build/src/core/verbs/placement.js +1 -1
- package/build/src/debt/context.d.ts +0 -5
- package/build/src/debt/context.js +32 -44
- package/build/src/git/process.d.ts +1 -0
- package/build/src/git/process.js +18 -1
- package/build/src/git/read-observation.js +2 -1
- package/build/src/git/scratch.d.ts +5 -1
- package/build/src/git/scratch.js +41 -12
- package/build/src/git/target-placement.d.ts +22 -4
- package/build/src/git/target-placement.js +44 -20
- package/build/src/index.d.ts +2 -2
- package/build/src/kanshi/read.js +187 -105
- package/build/src/kanshi/report.d.ts +5 -0
- package/build/src/library/address.d.ts +18 -4
- package/build/src/library/address.js +27 -6
- package/build/src/library/contract-address.d.ts +6 -0
- package/build/src/library/contract-address.js +12 -1
- package/build/src/library/contract-execution.d.ts +2 -2
- package/build/src/library/contract-execution.js +13 -17
- package/build/src/library/contract-operations.d.ts +59 -94
- package/build/src/library/contract-operations.js +23 -19
- package/build/src/library/contract-outcomes.d.ts +3 -3
- package/build/src/library/contract-settings.d.ts +1 -0
- package/build/src/library/contract-settings.js +1 -1
- package/build/src/library/invocation.d.ts +2 -2
- package/build/src/library/invocation.js +1 -1
- package/build/src/library/keiyaku.d.ts +2 -2
- package/build/src/library/keiyaku.js +2 -2
- package/build/src/library/outcome.d.ts +148 -268
- package/build/src/library/outcome.js +4 -8
- package/build/src/library/refusal.d.ts +2 -2
- package/build/src/library/refusal.js +2 -2
- package/build/src/plugin/runtime.js +15 -19
- package/build/src/protocol/{audit.d.ts → delivery-preview.d.ts} +62 -97
- package/build/src/protocol/delivery-preview.js +167 -0
- package/build/src/protocol/progress.d.ts +1 -1
- package/build/src/runtime/proc/run.js +22 -4
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/verification/execution.js +5 -3
- package/package.json +5 -2
- package/skills/keiyaku/SKILL.md +3 -1
- package/skills/keiyaku-babysit/SKILL.md +1 -1
- package/skills/keiyaku-bind/SKILL.md +3 -2
- package/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/src/cli/render/audit.d.ts +0 -7
- package/build/src/protocol/audit.js +0 -203
|
@@ -6,11 +6,13 @@ export const DEFAULT_CONTEXT = { columns: DEFAULT_CLI_COLUMNS, color: false };
|
|
|
6
6
|
const TIME_WIDTH = 5;
|
|
7
7
|
const VERB_WIDTH = 6;
|
|
8
8
|
/**
|
|
9
|
-
* The one blessed ruler: a run of U+2500
|
|
10
|
-
*
|
|
9
|
+
* The one blessed ruler: a run of U+2500 as wide as the frame head's widest line,
|
|
10
|
+
* never wider than the terminal, marking the boundary between an observation
|
|
11
|
+
* frame and its content.
|
|
11
12
|
*/
|
|
12
|
-
export function frameRule(headLines) {
|
|
13
|
-
const
|
|
13
|
+
export function frameRule(headLines, columns) {
|
|
14
|
+
const widest = headLines.reduce((widest, line) => Math.max(widest, displayColumns(line)), 0);
|
|
15
|
+
const width = columns === undefined ? widest : Math.min(widest, Math.max(0, columns));
|
|
14
16
|
return "─".repeat(width);
|
|
15
17
|
}
|
|
16
18
|
/** Tool rows an activity view prints after each say or Tell checkpoint; the surplus folds in place. */
|
|
@@ -21,14 +23,35 @@ function identity(id, alias) {
|
|
|
21
23
|
function associatedContractId(contract) {
|
|
22
24
|
return contract.kind === "associated" ? contract.contractId : undefined;
|
|
23
25
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
/** The one human-fact separator of this family. */
|
|
27
|
+
const FACT_SEPARATOR = " · ";
|
|
28
|
+
/** A supporting fact of an action receipt or an observation panel is one indent deep. */
|
|
29
|
+
const SUBORDINATE_INDENT = " ";
|
|
30
|
+
/** Indent already-decided supporting lines one level, for every caller of this family. */
|
|
31
|
+
export function subordinateLines(lines) {
|
|
32
|
+
return lines.map((line) => `${SUBORDINATE_INDENT}${line}`);
|
|
27
33
|
}
|
|
28
|
-
|
|
34
|
+
/**
|
|
35
|
+
* The one observation identity line: complete Akuma identity, optional alias as a parenthetical
|
|
36
|
+
* supplement, and a known associated Contract inline behind the shared separator.
|
|
37
|
+
*/
|
|
38
|
+
function panelIdentity(id, alias, contract) {
|
|
29
39
|
const contractId = contract === undefined ? undefined : associatedContractId(contract);
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
return `${identity(id, alias)}${contractId === undefined ? "" : `${FACT_SEPARATOR}${contractId}`}`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Identity and its static coordinates. The execution directory and any already-exposed effective
|
|
44
|
+
* actions belong above the content boundary; an absent coordinate is an absent line.
|
|
45
|
+
*/
|
|
46
|
+
export function panelHead(id, alias, contract, context = []) {
|
|
47
|
+
return [panelIdentity(id, alias, contract), ...subordinateLines(context)];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* One action receipt: the verdict and the complete subject on the first line, every supporting fact
|
|
51
|
+
* indented beneath it. Identity and evidence are never merged into one punctuation run.
|
|
52
|
+
*/
|
|
53
|
+
export function actionReceipt(input) {
|
|
54
|
+
return [`${input.mark} ${input.verb} ${identity(input.id, input.alias)}`, ...subordinateLines(input.evidence ?? [])];
|
|
32
55
|
}
|
|
33
56
|
function contractFacts(contract) {
|
|
34
57
|
return contract.kind === "failed" ? [`! contract failed ${safeText(contract.diagnostic)}`] : [];
|
|
@@ -44,7 +67,7 @@ function clock(at) {
|
|
|
44
67
|
}
|
|
45
68
|
function label(row, tool) {
|
|
46
69
|
if (row.kind === "said")
|
|
47
|
-
return "
|
|
70
|
+
return "";
|
|
48
71
|
if (row.kind === "thought")
|
|
49
72
|
return "think";
|
|
50
73
|
if (row.kind === "note")
|
|
@@ -118,12 +141,14 @@ function verbColumn(verb) {
|
|
|
118
141
|
*/
|
|
119
142
|
function actionCell(head, verb, columns) {
|
|
120
143
|
const prefix = `${head} `;
|
|
144
|
+
if (verb === "")
|
|
145
|
+
return prefix;
|
|
121
146
|
const available = Math.max(0, columns - displayColumns(prefix) - 1);
|
|
122
147
|
const width = Math.min(verbColumn(verb), available);
|
|
123
148
|
return `${prefix}${padToDisplay(truncateDisplayText(verb, width), width)} `;
|
|
124
149
|
}
|
|
125
|
-
function continuationPrefix() {
|
|
126
|
-
return " ".repeat(TIME_WIDTH) + " │ " + " ".repeat(VERB_WIDTH
|
|
150
|
+
function continuationPrefix(verb) {
|
|
151
|
+
return " ".repeat(TIME_WIDTH) + " │ " + (verb === "" ? "" : " ".repeat(VERB_WIDTH + 1));
|
|
127
152
|
}
|
|
128
153
|
function timelineMarker(text) {
|
|
129
154
|
return `${" ".repeat(TIME_WIDTH)} ⋮ ${text}`;
|
|
@@ -142,10 +167,7 @@ function historyLayout() {
|
|
|
142
167
|
return { ...compactLayout(), history: true };
|
|
143
168
|
}
|
|
144
169
|
function quotedBody(row) {
|
|
145
|
-
return (row.kind === "
|
|
146
|
-
row.kind === "thought" ||
|
|
147
|
-
row.kind === "tell" ||
|
|
148
|
-
(row.kind === "outcome" && row.outcome.kind === "answered"));
|
|
170
|
+
return row.kind === "thought" || row.kind === "tell" || (row.kind === "outcome" && row.outcome.kind === "answered");
|
|
149
171
|
}
|
|
150
172
|
function pathTail(path, maximum) {
|
|
151
173
|
if (displayColumns(path) <= maximum)
|
|
@@ -235,7 +257,7 @@ function toolOverflowPreview(options, value, columns) {
|
|
|
235
257
|
];
|
|
236
258
|
}
|
|
237
259
|
function renderRow(row, context, options) {
|
|
238
|
-
const { layout, first, continuation, tool
|
|
260
|
+
const { layout, first, continuation, tool } = options;
|
|
239
261
|
const value = rowText(row, tool);
|
|
240
262
|
const overflow = toolOverflowPreview(options, value, context.columns);
|
|
241
263
|
if (overflow !== undefined)
|
|
@@ -255,8 +277,7 @@ function renderRow(row, context, options) {
|
|
|
255
277
|
: layout.history === true
|
|
256
278
|
? Number.MAX_SAFE_INTEGER
|
|
257
279
|
: value.lines,
|
|
258
|
-
quote: quotedBody(row) ? (layout.singleLine === true
|
|
259
|
-
openQuote: row.kind === "said" && inFlightSay,
|
|
280
|
+
quote: quotedBody(row) ? (layout.singleLine === true ? '"' : "“") : "",
|
|
260
281
|
truncated: "truncated" in row && row.truncated === true,
|
|
261
282
|
});
|
|
262
283
|
}
|
|
@@ -264,12 +285,12 @@ function renderTimelineRow(row, context, layout, time, options = {}) {
|
|
|
264
285
|
const { inFlightSay = false, live = false, unsettled = false } = options;
|
|
265
286
|
const tool = row.kind === "tool" ? toolRepr(row) : undefined;
|
|
266
287
|
const glyph = inFlightSay ? (live ? "●" : "?") : unsettled ? "?" : mark(row, live);
|
|
288
|
+
const verb = label(row, tool);
|
|
267
289
|
return renderRow(row, context, {
|
|
268
290
|
layout,
|
|
269
|
-
first: layout.head(time, glyph,
|
|
270
|
-
continuation: layout.continuation(),
|
|
291
|
+
first: layout.head(time, glyph, verb, context.columns),
|
|
292
|
+
continuation: layout.continuation(verb),
|
|
271
293
|
tool,
|
|
272
|
-
inFlightSay,
|
|
273
294
|
});
|
|
274
295
|
}
|
|
275
296
|
function groupedEntries(entries, context, layout = plainLayout(), options = {}) {
|
|
@@ -695,7 +716,9 @@ export function inputWaitStream(context, head, options) {
|
|
|
695
716
|
throw new Error("input wait observed before admission");
|
|
696
717
|
opened = true;
|
|
697
718
|
const identity = head();
|
|
698
|
-
|
|
719
|
+
const headLines = panelHead(identity.id, identity.alias, identity.contract, identity.cwd === undefined ? [] : [safeText(identity.cwd)]);
|
|
720
|
+
// A streamed panel always states an observed conclusion before it closes, so its rule opens here.
|
|
721
|
+
lines.push(...headLines, frameRule(headLines, context.columns));
|
|
699
722
|
};
|
|
700
723
|
const observe = (observation) => {
|
|
701
724
|
const lines = [];
|
|
@@ -714,6 +737,8 @@ export function inputWaitStream(context, head, options) {
|
|
|
714
737
|
const conclude = (result) => {
|
|
715
738
|
const lines = [];
|
|
716
739
|
open(lines, result.kind === "failed");
|
|
740
|
+
if (result.kind === "failed" && result.evidence !== undefined)
|
|
741
|
+
lines.push(...result.evidence);
|
|
717
742
|
lines.push(...activity.flush());
|
|
718
743
|
if (result.kind === "failed")
|
|
719
744
|
lines.push(`! error ${safeText(result.diagnostic)}`);
|
|
@@ -724,7 +749,7 @@ export function inputWaitStream(context, head, options) {
|
|
|
724
749
|
now: now(),
|
|
725
750
|
...(lastStatus === undefined ? {} : { status: lastStatus }),
|
|
726
751
|
}));
|
|
727
|
-
lines.push(...head().facts);
|
|
752
|
+
lines.push(...subordinateLines(head().facts));
|
|
728
753
|
return `${lines.join("\n")}${options.answerSeparator === true ? "\n\n" : ""}`;
|
|
729
754
|
};
|
|
730
755
|
return { admitted: admit, observe, frame, flush, conclude, opened: () => opened };
|
|
@@ -736,11 +761,26 @@ export function callObservationStream(context, head, options = {}) {
|
|
|
736
761
|
...(options.now === undefined ? {} : { now: options.now }),
|
|
737
762
|
});
|
|
738
763
|
stream.admitted({ ...(options.admittedAt === undefined ? {} : { at: options.admittedAt }), rows: [] });
|
|
764
|
+
/** Tell rows already settled on the timeline, so a failed close never replays one. */
|
|
765
|
+
const settledTells = new Set();
|
|
739
766
|
return {
|
|
740
767
|
...stream,
|
|
768
|
+
observe: (observation) => {
|
|
769
|
+
for (const row of observation.rows)
|
|
770
|
+
if (row.kind === "tell" && row.state === "told")
|
|
771
|
+
settledTells.add(row.sequence);
|
|
772
|
+
return stream.observe(observation);
|
|
773
|
+
},
|
|
741
774
|
conclude: (observation) => {
|
|
742
|
-
if (observation.kind === "failed")
|
|
743
|
-
|
|
775
|
+
if (observation.kind === "failed") {
|
|
776
|
+
const tell = observation.tell;
|
|
777
|
+
const evidence = tell === undefined || settledTells.has(tell.row.sequence) ? [] : [tellAdmissionRow(tell, context)];
|
|
778
|
+
return stream.conclude({
|
|
779
|
+
kind: "failed",
|
|
780
|
+
diagnostic: observation.failure.diagnostic,
|
|
781
|
+
...(evidence.length === 0 ? {} : { evidence }),
|
|
782
|
+
});
|
|
783
|
+
}
|
|
744
784
|
if (observation.kind !== "observed")
|
|
745
785
|
return "";
|
|
746
786
|
return stream.conclude({
|
|
@@ -785,15 +825,15 @@ function renderDebtContextLines(created, columns) {
|
|
|
785
825
|
}
|
|
786
826
|
function snapshotCore(view, context, options) {
|
|
787
827
|
const activity = snapshotActivityLines(view.status.timeline, context);
|
|
788
|
-
|
|
828
|
+
// Static coordinates belong above the content boundary; a dynamic diagnostic stays below it.
|
|
829
|
+
const contextFacts = [
|
|
789
830
|
...(options.showAllowed === true ? [`allowed ${view.status.allowed.join(", ") || "none"}`] : []),
|
|
790
|
-
...
|
|
791
|
-
...(options.facts ?? []),
|
|
792
|
-
...(view.status.cwd === undefined ? [] : [`cwd ${safeText(view.status.cwd)}`]),
|
|
831
|
+
...(view.status.cwd === undefined ? [] : [safeText(view.status.cwd)]),
|
|
793
832
|
];
|
|
833
|
+
const facts = [...contractFacts(view.contract), ...(options.facts ?? [])];
|
|
794
834
|
return {
|
|
795
835
|
activity,
|
|
796
|
-
|
|
836
|
+
head: panelHead(view.status.id, options.alias, view.contract, contextFacts),
|
|
797
837
|
facts,
|
|
798
838
|
};
|
|
799
839
|
}
|
|
@@ -809,28 +849,36 @@ function snapshotConclusion(status) {
|
|
|
809
849
|
}
|
|
810
850
|
export function snapshotText(view, context, options = {}) {
|
|
811
851
|
const core = snapshotCore(view, context, options);
|
|
812
|
-
const debtContext = renderDebtContextLines(view.createdDebts, context.columns);
|
|
813
852
|
const conclusion = snapshotConclusion(view.status);
|
|
853
|
+
const content = [...core.activity, ...(conclusion.length === 0 ? [] : [conclusion])];
|
|
814
854
|
return [
|
|
815
|
-
...core.
|
|
816
|
-
...(
|
|
817
|
-
...(
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
855
|
+
...core.head,
|
|
856
|
+
...(content.length === 0 ? [] : [frameRule(core.head, context.columns), ...content]),
|
|
857
|
+
...subordinateLines([
|
|
858
|
+
...renderReportedChangeLines(view.status.timeline),
|
|
859
|
+
...renderDebtContextLines(view.createdDebts, context.columns - SUBORDINATE_INDENT.length),
|
|
860
|
+
...core.facts,
|
|
861
|
+
]),
|
|
821
862
|
].join("\n");
|
|
822
863
|
}
|
|
823
864
|
function killResultLabel(evidence) {
|
|
824
865
|
if (evidence === "killed")
|
|
825
|
-
return "✓ killed";
|
|
866
|
+
return { mark: "✓", verb: "killed", evidence: [] };
|
|
826
867
|
if (evidence === "already-killed")
|
|
827
|
-
return "✓ already killed";
|
|
868
|
+
return { mark: "✓", verb: "already killed", evidence: [] };
|
|
828
869
|
if (evidence === "already-stopped")
|
|
829
|
-
return "✓ already stopped";
|
|
830
|
-
return
|
|
870
|
+
return { mark: "✓", verb: "already stopped", evidence: [] };
|
|
871
|
+
return { mark: "!", verb: "not killed", evidence: [evidence] };
|
|
831
872
|
}
|
|
832
873
|
export function killResultText(id, evidence, alias) {
|
|
833
|
-
|
|
874
|
+
const label = killResultLabel(evidence);
|
|
875
|
+
return actionReceipt({
|
|
876
|
+
mark: label.mark,
|
|
877
|
+
verb: label.verb,
|
|
878
|
+
id,
|
|
879
|
+
...(alias === undefined ? {} : { alias }),
|
|
880
|
+
evidence: label.evidence,
|
|
881
|
+
}).join("\n");
|
|
834
882
|
}
|
|
835
883
|
function answerBytes(answer, structured) {
|
|
836
884
|
return !structured && typeof answer === "string" ? answer : JSON.stringify(answer);
|
|
@@ -884,32 +932,61 @@ export function historyText(result, presentation, context) {
|
|
|
884
932
|
: `${result.history.omitted} earlier events · showing last ${result.history.rows.length}`),
|
|
885
933
|
]
|
|
886
934
|
: [];
|
|
887
|
-
|
|
935
|
+
// History is an immutable timeline, so it takes the shared heading and content boundary and
|
|
936
|
+
// never gains a fabricated current-state conclusion or a live mark.
|
|
937
|
+
const content = [...paging, ...rows];
|
|
938
|
+
const head = panelHead(result.id, presentation.alias, result.contract);
|
|
939
|
+
return [...head, ...(content.length === 0 ? [] : [frameRule(head, context.columns), ...content])].join("\n");
|
|
940
|
+
}
|
|
941
|
+
/** One bounded preview of a submitted Tell, indented once beneath its verdict or evidence. */
|
|
942
|
+
export function tellPayloadLines(text, context) {
|
|
943
|
+
return renderBoundedPayload({
|
|
944
|
+
text,
|
|
945
|
+
first: SUBORDINATE_INDENT,
|
|
946
|
+
continuation: `${SUBORDINATE_INDENT}│ `,
|
|
947
|
+
columns: context.columns,
|
|
948
|
+
maxLines: 1,
|
|
949
|
+
quote: '"',
|
|
950
|
+
truncated: false,
|
|
951
|
+
});
|
|
888
952
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
const
|
|
953
|
+
/** One admitted Tell as a timeline row inside a shared input panel; the panel owns the identity. */
|
|
954
|
+
export function tellAdmissionRow(tell, context) {
|
|
955
|
+
const wake = tell.wake;
|
|
892
956
|
const glyph = wake.kind === "failed" ? "!" : wake.kind === "held" ? "⧗" : "✓";
|
|
893
957
|
const verb = wake.kind === "failed" || wake.kind === "held" ? "tell" : "told";
|
|
894
|
-
|
|
958
|
+
return groupedRows([tell.row], context, {
|
|
895
959
|
...plainLayout(),
|
|
896
960
|
head: (time, _glyph, _verb, columns) => eventPrefix(glyph, verb, time, columns),
|
|
897
961
|
singleLine: true,
|
|
898
962
|
}).join("\n");
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
914
|
-
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* One Tell action receipt: the delivery verdict and complete subject, then the submitted payload
|
|
966
|
+
* once. A held Tell keeps neutral vocabulary; a failed delivery keeps its own concrete diagnosis.
|
|
967
|
+
*/
|
|
968
|
+
export function tellText(result, alias, context) {
|
|
969
|
+
const wake = result.tell.wake;
|
|
970
|
+
const mark = wake.kind === "failed" ? "!" : wake.kind === "held" ? "⧗" : "✓";
|
|
971
|
+
const verb = wake.kind === "failed" || wake.kind === "held" ? "tell" : "told";
|
|
972
|
+
const verdict = actionReceipt({
|
|
973
|
+
mark,
|
|
974
|
+
verb,
|
|
975
|
+
id: result.akuma,
|
|
976
|
+
...(alias === undefined ? {} : { alias }),
|
|
977
|
+
});
|
|
978
|
+
if (wake.kind !== "failed")
|
|
979
|
+
return [...verdict, ...tellPayloadLines(result.tell.row.text, context)].join("\n");
|
|
980
|
+
const child = "child" in wake ? wake.child : undefined;
|
|
981
|
+
const failure = `! tell delivery failed · ${safeText(wake.diagnostic)}${child === undefined ? "" : ` · log ${child.log.path} ${child.log.from}..${child.log.to}`}`;
|
|
982
|
+
return [
|
|
983
|
+
...verdict,
|
|
984
|
+
...tellPayloadLines(result.tell.row.text, context),
|
|
985
|
+
...subordinateLines(renderBoundedTextBlock(failure, {
|
|
986
|
+
first: "",
|
|
987
|
+
continuation: "",
|
|
988
|
+
columns: context.columns - SUBORDINATE_INDENT.length,
|
|
989
|
+
lines: Number.MAX_SAFE_INTEGER,
|
|
990
|
+
})),
|
|
991
|
+
].join("\n");
|
|
915
992
|
}
|
|
@@ -19,8 +19,14 @@ export declare function waitedTellProgress(result: AkumaAskResult, alias: string
|
|
|
19
19
|
/** The shared identity frame for one admitted call input. */
|
|
20
20
|
export declare function callObservationHead(input: Readonly<{
|
|
21
21
|
akuma: string;
|
|
22
|
+
cwd?: string;
|
|
22
23
|
}> & CallWaitHead): ObservedCallHead;
|
|
23
24
|
export declare function renderCallText(result: CallResult, streamed: boolean, context: TextRenderContext): string;
|
|
25
|
+
/**
|
|
26
|
+
* The failure panel for an observing call whose stream never opened. It opens the same shared head
|
|
27
|
+
* over the failure's own evidence, including a Tell the invocation had already admitted.
|
|
28
|
+
*/
|
|
29
|
+
export declare function renderFailedCallObservation(result: CallResult, context: TextRenderContext): string;
|
|
24
30
|
export declare function renderForkText(receipt: ForkResult): string;
|
|
25
31
|
export declare function renderKillText(result: AkumaKillResult, alias: string | undefined, context: TextRenderContext): string;
|
|
26
32
|
export declare function callExitCode(result: CallResult): number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { actionReceipt, callObservationStream, inputWaitStream, killResultText, subordinateLines, tellAdmissionRow, tellPayloadLines, } from "./akuma-activity.js";
|
|
2
2
|
import { safeText } from "./terminal.js";
|
|
3
3
|
export function askProgressStream(akuma, alias, context) {
|
|
4
4
|
let target = akuma;
|
|
@@ -13,7 +13,7 @@ export function askProgressStream(akuma, alias, context) {
|
|
|
13
13
|
return stream.admitted({
|
|
14
14
|
at: tell.row.at,
|
|
15
15
|
sequence: tell.row.sequence,
|
|
16
|
-
rows: [
|
|
16
|
+
rows: [tellAdmissionRow(tell, context)],
|
|
17
17
|
});
|
|
18
18
|
},
|
|
19
19
|
observe: (observation) => stream.observe(observation),
|
|
@@ -39,8 +39,8 @@ function dispatchLines(stage) {
|
|
|
39
39
|
return (stage.seatClose ?? []).map((lag) => `dispatch lag ${lag.kind} ${safeText(lag.diagnostic)}`);
|
|
40
40
|
}
|
|
41
41
|
if (stage.failure.kind === "conflict")
|
|
42
|
-
return [
|
|
43
|
-
return [
|
|
42
|
+
return [`! dispatch failed conflict ${stage.failure.current.contractId}`];
|
|
43
|
+
return [`! dispatch failed ${stage.failure.kind} ${safeText(stage.failure.diagnostic)}`];
|
|
44
44
|
}
|
|
45
45
|
/** The shared identity frame for one admitted call input. */
|
|
46
46
|
export function callObservationHead(input) {
|
|
@@ -49,7 +49,7 @@ export function callObservationHead(input) {
|
|
|
49
49
|
const facts = [
|
|
50
50
|
...dispatchLines(input.dispatch),
|
|
51
51
|
...(input.alias.kind === "failed"
|
|
52
|
-
? [
|
|
52
|
+
? [`! alias failed ${input.alias.failure.kind} ${safeText(input.alias.failure.diagnostic)}`]
|
|
53
53
|
: []),
|
|
54
54
|
];
|
|
55
55
|
return {
|
|
@@ -57,8 +57,17 @@ export function callObservationHead(input) {
|
|
|
57
57
|
...(alias === undefined ? {} : { alias }),
|
|
58
58
|
contract: contractId === undefined ? { kind: "none" } : { kind: "associated", contractId },
|
|
59
59
|
facts,
|
|
60
|
+
...(input.cwd === undefined ? {} : { cwd: input.cwd }),
|
|
60
61
|
};
|
|
61
62
|
}
|
|
63
|
+
/** The admitted context a call action receipt can state without reading anything new. */
|
|
64
|
+
function callEvidence(result, head) {
|
|
65
|
+
return [
|
|
66
|
+
...(head.contract.kind === "associated" ? [safeText(head.contract.contractId)] : []),
|
|
67
|
+
safeText(result.execution.cwd),
|
|
68
|
+
...head.facts,
|
|
69
|
+
];
|
|
70
|
+
}
|
|
62
71
|
export function renderCallText(result, streamed, context) {
|
|
63
72
|
if (streamed)
|
|
64
73
|
return "";
|
|
@@ -66,23 +75,34 @@ export function renderCallText(result, streamed, context) {
|
|
|
66
75
|
akuma: result.akuma,
|
|
67
76
|
dispatch: result.dispatch,
|
|
68
77
|
alias: result.alias,
|
|
78
|
+
cwd: result.execution.cwd,
|
|
69
79
|
});
|
|
80
|
+
const receipt = (mark, extra = []) => actionReceipt({
|
|
81
|
+
mark,
|
|
82
|
+
verb: "called",
|
|
83
|
+
id: result.akuma,
|
|
84
|
+
...(head.alias === undefined ? {} : { alias: head.alias }),
|
|
85
|
+
evidence: [...callEvidence(result, head), ...extra],
|
|
86
|
+
}).join("\n");
|
|
70
87
|
if (result.observation.kind === "detached" || result.observation.kind === "born") {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
];
|
|
75
|
-
return [
|
|
76
|
-
associatedIdentity(result.akuma, head.alias),
|
|
77
|
-
...branches.map((fact, index) => `${index === branches.length - 1 ? "└─" : "├─"} ${fact}`),
|
|
78
|
-
...head.facts,
|
|
79
|
-
].join("\n");
|
|
88
|
+
// Birth and integration are admitted facts; a failed Dispatch/Alias stage marks the receipt
|
|
89
|
+
// honestly instead of letting a successful action line stand over it.
|
|
90
|
+
return receipt(result.dispatch.kind === "failed" || result.alias.kind === "failed" ? "!" : "✓");
|
|
80
91
|
}
|
|
81
92
|
if (result.observation.kind === "failed") {
|
|
93
|
+
// The child, its admitted Tell input, and its context survive a failed stage; a detached failure
|
|
94
|
+
// stays an action receipt rather than becoming an observation panel.
|
|
95
|
+
const admittedTell = result.observation.tell;
|
|
82
96
|
return [
|
|
83
|
-
...
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
...actionReceipt({
|
|
98
|
+
mark: "!",
|
|
99
|
+
verb: "called",
|
|
100
|
+
id: result.akuma,
|
|
101
|
+
...(head.alias === undefined ? {} : { alias: head.alias }),
|
|
102
|
+
evidence: callEvidence(result, head),
|
|
103
|
+
}),
|
|
104
|
+
...(admittedTell === undefined ? [] : tellPayloadLines(admittedTell.row.text, context)),
|
|
105
|
+
...subordinateLines([`! error ${safeText(result.observation.failure.diagnostic)}`]),
|
|
86
106
|
].join("\n");
|
|
87
107
|
}
|
|
88
108
|
const inputObservation = result.observation;
|
|
@@ -94,20 +114,43 @@ export function renderCallText(result, streamed, context) {
|
|
|
94
114
|
...(inputObservation.completedAt === undefined ? {} : { completedAt: inputObservation.completedAt }),
|
|
95
115
|
});
|
|
96
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The failure panel for an observing call whose stream never opened. It opens the same shared head
|
|
119
|
+
* over the failure's own evidence, including a Tell the invocation had already admitted.
|
|
120
|
+
*/
|
|
121
|
+
export function renderFailedCallObservation(result, context) {
|
|
122
|
+
const failure = callObservationStream(context, callObservationHead({
|
|
123
|
+
akuma: result.akuma,
|
|
124
|
+
dispatch: result.dispatch,
|
|
125
|
+
alias: result.alias,
|
|
126
|
+
cwd: result.execution.cwd,
|
|
127
|
+
}));
|
|
128
|
+
return failure.conclude(result.observation);
|
|
129
|
+
}
|
|
97
130
|
export function renderForkText(receipt) {
|
|
98
131
|
if (receipt.kind !== "forked") {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
132
|
+
const reason = receipt.kind === "unknown-history"
|
|
133
|
+
? `${receipt.at} has no matching retained answered turn`
|
|
134
|
+
: receipt.kind === "provider-cannot-fork"
|
|
135
|
+
? `${receipt.provider} cannot fork`
|
|
136
|
+
: receipt.diagnostic;
|
|
137
|
+
return actionReceipt({ mark: "!", verb: "fork", id: receipt.parent, evidence: [reason] }).join("\n");
|
|
104
138
|
}
|
|
105
139
|
const contractId = receipt.dispatch.kind === "dispatched" ? receipt.dispatch.dispatch.contractId : undefined;
|
|
106
|
-
return
|
|
140
|
+
return actionReceipt({
|
|
141
|
+
mark: receipt.dispatch.kind === "failed" ? "!" : "✓",
|
|
142
|
+
verb: "forked",
|
|
143
|
+
id: receipt.child,
|
|
144
|
+
evidence: [
|
|
145
|
+
`from ${receipt.parent}`,
|
|
146
|
+
...(contractId === undefined ? [] : [safeText(contractId)]),
|
|
147
|
+
...dispatchLines(receipt.dispatch),
|
|
148
|
+
],
|
|
149
|
+
}).join("\n");
|
|
107
150
|
}
|
|
108
151
|
export function renderKillText(result, alias, context) {
|
|
109
152
|
void context;
|
|
110
|
-
return result.results.map((member) => killResultText(member.id, member.evidence, alias)).join("\n
|
|
153
|
+
return result.results.map((member) => killResultText(member.id, member.evidence, alias)).join("\n");
|
|
111
154
|
}
|
|
112
155
|
export function callExitCode(result) {
|
|
113
156
|
if (result.dispatch.kind === "failed" || result.alias.kind === "failed" || result.observation.kind === "failed")
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
import type { ContractAfterEdge,
|
|
1
|
+
import type { ContractAfterEdge, ContractRow, ContractWorkspaceObservation } from "../../index.js";
|
|
2
|
+
type GateDisplayReport = Readonly<{
|
|
3
|
+
gate: string;
|
|
4
|
+
current: Readonly<{
|
|
5
|
+
kind: "missing";
|
|
6
|
+
} | {
|
|
7
|
+
kind: "stale";
|
|
8
|
+
} | {
|
|
9
|
+
kind: "attested";
|
|
10
|
+
verdict: "satisfied" | "unsatisfied";
|
|
11
|
+
}>;
|
|
12
|
+
}>;
|
|
2
13
|
export declare function shortGitId(value: string): string;
|
|
14
|
+
export declare function contractOperationName(operation: string): string;
|
|
3
15
|
export declare function gateDisplayName(gate: string): string;
|
|
4
16
|
/**
|
|
5
17
|
* The one display vocabulary for a Contract's lifecycle phase. The journal fact kind stays `claimed`; every
|
|
@@ -8,8 +20,8 @@ export declare function gateDisplayName(gate: string): string;
|
|
|
8
20
|
export declare function lifecycleWord(phase: ContractRow["phase"]): string;
|
|
9
21
|
/** The one readable projection of delivery and current-candidate gate progress. */
|
|
10
22
|
export declare function progressStrip(row: Pick<ContractRow, "delivery" | "gates">): string;
|
|
11
|
-
export declare function gateGlyph(report:
|
|
12
|
-
export declare function gateFact(report:
|
|
23
|
+
export declare function gateGlyph(report: GateDisplayReport): string;
|
|
24
|
+
export declare function gateFact(report: GateDisplayReport): string;
|
|
13
25
|
export declare function verificationFact(status: ContractRow["verification"]): string | undefined;
|
|
14
26
|
export declare function afterWording(edge: ContractAfterEdge): string;
|
|
15
27
|
export declare function mergeSummary(observation: ContractWorkspaceObservation): string | undefined;
|
|
@@ -18,3 +30,4 @@ export declare function gitIdsInRow(row: ContractRow): readonly string[];
|
|
|
18
30
|
export declare function displayGitId(value: string, abbreviations: ReadonlyMap<string, string>): string;
|
|
19
31
|
/** Render the pinned delivery target and the same-epoch observed target head. */
|
|
20
32
|
export declare function targetMovementFacts(row: ContractRow, abbreviations: ReadonlyMap<string, string>): readonly string[];
|
|
33
|
+
export {};
|
|
@@ -2,6 +2,9 @@ const GIT_OBJECT_ID = /^[0-9a-f]{40}$/iu;
|
|
|
2
2
|
export function shortGitId(value) {
|
|
3
3
|
return GIT_OBJECT_ID.test(value) ? value.slice(0, 7) : value;
|
|
4
4
|
}
|
|
5
|
+
export function contractOperationName(operation) {
|
|
6
|
+
return operation === "deliver-preview" ? "deliver --dry-run" : operation;
|
|
7
|
+
}
|
|
5
8
|
export function gateDisplayName(gate) {
|
|
6
9
|
if (gate === "reviewed")
|
|
7
10
|
return "review";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { AbandonOutcome, AmendOutcome, ArcOutcome,
|
|
1
|
+
import type { AbandonOutcome, AmendOutcome, ArcOutcome, DeliveryPreviewOutcome, BindOutcome, DeliverOutcome, ReviewOutcome } from "../../index.js";
|
|
2
2
|
import { type TextRenderContext } from "./terminal.js";
|
|
3
|
-
export type ContractOutcome = BindOutcome | AmendOutcome | DeliverOutcome | ReviewOutcome |
|
|
3
|
+
export type ContractOutcome = BindOutcome | AmendOutcome | DeliverOutcome | ReviewOutcome | DeliveryPreviewOutcome | ArcOutcome | AbandonOutcome;
|
|
4
4
|
export type AcceptedContractOutcome = Extract<ContractOutcome, {
|
|
5
5
|
kind: "accepted";
|
|
6
6
|
}>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { effectCleanup, effectExecutionStops, effectLags, effectRecoverySnapshot, effectRetainedCheckouts, effectRetainedWorktrees, effectRetiredWorktrees, effectSettlementLags, } from "./effects.js";
|
|
2
|
-
import {
|
|
2
|
+
import { renderDeliveryPreview } from "./delivery-preview.js";
|
|
3
3
|
import { appendHookPayload, executionCleanupLines, executionStopLines, gatesAwaitLines, hookFailureSummary, outcomeLines, receiptPayload, receiptRow, stopLines, titleLines, } from "./receipt.js";
|
|
4
4
|
import { abbreviateGitIds, displayGitId, lifecycleWord } from "./contract-observation.js";
|
|
5
5
|
import { renderDiffstat } from "./akuma-tool.js";
|
|
@@ -216,7 +216,7 @@ function landedChangesLines(scope, columns) {
|
|
|
216
216
|
* identically: one git-shaped target movement row, naming the reference it advanced, then the final lifecycle
|
|
217
217
|
* state. Satisfied Verification adds one fact row naming the integrated result; placement made that commit the
|
|
218
218
|
* reference's new head, so the movement and integrated-result rows share one sha. The verdict names reuse in the
|
|
219
|
-
*
|
|
219
|
+
* standing-evidence vocabulary and carries no qualifier when this command executed declarations. A completion
|
|
220
220
|
* without an advanced reference states no movement. Journal ULIDs stay in JSON and `history`, never in ordinary
|
|
221
221
|
* receipt text.
|
|
222
222
|
*/
|
|
@@ -403,8 +403,8 @@ function renderAcceptedAbandon(result, columns) {
|
|
|
403
403
|
export function renderAccepted(result, context) {
|
|
404
404
|
const columns = context?.columns ?? DEFAULT_CLI_COLUMNS;
|
|
405
405
|
switch (result.operation) {
|
|
406
|
-
case "
|
|
407
|
-
return
|
|
406
|
+
case "deliver-preview":
|
|
407
|
+
return renderDeliveryPreview(result, context);
|
|
408
408
|
case "bind":
|
|
409
409
|
return renderAcceptedBind(result, columns, context?.color === true);
|
|
410
410
|
case "amend":
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DeliveryPreviewOutcome } from "../../index.js";
|
|
2
|
+
import { type TextRenderContext } from "./terminal.js";
|
|
3
|
+
type AcceptedDeliveryPreview = Extract<DeliveryPreviewOutcome, {
|
|
4
|
+
kind: "accepted";
|
|
5
|
+
}>;
|
|
6
|
+
export declare function renderDeliveryPreview(result: AcceptedDeliveryPreview, context?: TextRenderContext): string;
|
|
7
|
+
export {};
|