@astrosheep/keiyaku 4.6.10 → 4.6.12
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 +13 -17
- 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 +35 -8
- package/build/src/cli/render/akuma-activity.js +132 -52
- package/build/src/cli/render/akuma.d.ts +6 -0
- package/build/src/cli/render/akuma.js +67 -24
- 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 -0
- package/build/src/cli/render/receipt.js +3 -3
- package/build/src/cli/render/refusal.js +2 -2
- 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 +16 -21
- 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 +4 -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)}`] : [];
|
|
@@ -695,7 +718,9 @@ export function inputWaitStream(context, head, options) {
|
|
|
695
718
|
throw new Error("input wait observed before admission");
|
|
696
719
|
opened = true;
|
|
697
720
|
const identity = head();
|
|
698
|
-
|
|
721
|
+
const headLines = panelHead(identity.id, identity.alias, identity.contract, identity.cwd === undefined ? [] : [safeText(identity.cwd)]);
|
|
722
|
+
// A streamed panel always states an observed conclusion before it closes, so its rule opens here.
|
|
723
|
+
lines.push(...headLines, frameRule(headLines, context.columns));
|
|
699
724
|
};
|
|
700
725
|
const observe = (observation) => {
|
|
701
726
|
const lines = [];
|
|
@@ -714,6 +739,8 @@ export function inputWaitStream(context, head, options) {
|
|
|
714
739
|
const conclude = (result) => {
|
|
715
740
|
const lines = [];
|
|
716
741
|
open(lines, result.kind === "failed");
|
|
742
|
+
if (result.kind === "failed" && result.evidence !== undefined)
|
|
743
|
+
lines.push(...result.evidence);
|
|
717
744
|
lines.push(...activity.flush());
|
|
718
745
|
if (result.kind === "failed")
|
|
719
746
|
lines.push(`! error ${safeText(result.diagnostic)}`);
|
|
@@ -724,7 +751,7 @@ export function inputWaitStream(context, head, options) {
|
|
|
724
751
|
now: now(),
|
|
725
752
|
...(lastStatus === undefined ? {} : { status: lastStatus }),
|
|
726
753
|
}));
|
|
727
|
-
lines.push(...head().facts);
|
|
754
|
+
lines.push(...subordinateLines(head().facts));
|
|
728
755
|
return `${lines.join("\n")}${options.answerSeparator === true ? "\n\n" : ""}`;
|
|
729
756
|
};
|
|
730
757
|
return { admitted: admit, observe, frame, flush, conclude, opened: () => opened };
|
|
@@ -736,11 +763,26 @@ export function callObservationStream(context, head, options = {}) {
|
|
|
736
763
|
...(options.now === undefined ? {} : { now: options.now }),
|
|
737
764
|
});
|
|
738
765
|
stream.admitted({ ...(options.admittedAt === undefined ? {} : { at: options.admittedAt }), rows: [] });
|
|
766
|
+
/** Tell rows already settled on the timeline, so a failed close never replays one. */
|
|
767
|
+
const settledTells = new Set();
|
|
739
768
|
return {
|
|
740
769
|
...stream,
|
|
770
|
+
observe: (observation) => {
|
|
771
|
+
for (const row of observation.rows)
|
|
772
|
+
if (row.kind === "tell" && row.state === "told")
|
|
773
|
+
settledTells.add(row.sequence);
|
|
774
|
+
return stream.observe(observation);
|
|
775
|
+
},
|
|
741
776
|
conclude: (observation) => {
|
|
742
|
-
if (observation.kind === "failed")
|
|
743
|
-
|
|
777
|
+
if (observation.kind === "failed") {
|
|
778
|
+
const tell = observation.tell;
|
|
779
|
+
const evidence = tell === undefined || settledTells.has(tell.row.sequence) ? [] : [tellAdmissionRow(tell, context)];
|
|
780
|
+
return stream.conclude({
|
|
781
|
+
kind: "failed",
|
|
782
|
+
diagnostic: observation.failure.diagnostic,
|
|
783
|
+
...(evidence.length === 0 ? {} : { evidence }),
|
|
784
|
+
});
|
|
785
|
+
}
|
|
744
786
|
if (observation.kind !== "observed")
|
|
745
787
|
return "";
|
|
746
788
|
return stream.conclude({
|
|
@@ -785,15 +827,15 @@ function renderDebtContextLines(created, columns) {
|
|
|
785
827
|
}
|
|
786
828
|
function snapshotCore(view, context, options) {
|
|
787
829
|
const activity = snapshotActivityLines(view.status.timeline, context);
|
|
788
|
-
|
|
830
|
+
// Static coordinates belong above the content boundary; a dynamic diagnostic stays below it.
|
|
831
|
+
const contextFacts = [
|
|
789
832
|
...(options.showAllowed === true ? [`allowed ${view.status.allowed.join(", ") || "none"}`] : []),
|
|
790
|
-
...
|
|
791
|
-
...(options.facts ?? []),
|
|
792
|
-
...(view.status.cwd === undefined ? [] : [`cwd ${safeText(view.status.cwd)}`]),
|
|
833
|
+
...(view.status.cwd === undefined ? [] : [safeText(view.status.cwd)]),
|
|
793
834
|
];
|
|
835
|
+
const facts = [...contractFacts(view.contract), ...(options.facts ?? [])];
|
|
794
836
|
return {
|
|
795
837
|
activity,
|
|
796
|
-
|
|
838
|
+
head: panelHead(view.status.id, options.alias, view.contract, contextFacts),
|
|
797
839
|
facts,
|
|
798
840
|
};
|
|
799
841
|
}
|
|
@@ -809,28 +851,36 @@ function snapshotConclusion(status) {
|
|
|
809
851
|
}
|
|
810
852
|
export function snapshotText(view, context, options = {}) {
|
|
811
853
|
const core = snapshotCore(view, context, options);
|
|
812
|
-
const debtContext = renderDebtContextLines(view.createdDebts, context.columns);
|
|
813
854
|
const conclusion = snapshotConclusion(view.status);
|
|
855
|
+
const content = [...core.activity, ...(conclusion.length === 0 ? [] : [conclusion])];
|
|
814
856
|
return [
|
|
815
|
-
...core.
|
|
816
|
-
...(
|
|
817
|
-
...(
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
857
|
+
...core.head,
|
|
858
|
+
...(content.length === 0 ? [] : [frameRule(core.head, context.columns), ...content]),
|
|
859
|
+
...subordinateLines([
|
|
860
|
+
...renderReportedChangeLines(view.status.timeline),
|
|
861
|
+
...renderDebtContextLines(view.createdDebts, context.columns - SUBORDINATE_INDENT.length),
|
|
862
|
+
...core.facts,
|
|
863
|
+
]),
|
|
821
864
|
].join("\n");
|
|
822
865
|
}
|
|
823
866
|
function killResultLabel(evidence) {
|
|
824
867
|
if (evidence === "killed")
|
|
825
|
-
return "✓ killed";
|
|
868
|
+
return { mark: "✓", verb: "killed", evidence: [] };
|
|
826
869
|
if (evidence === "already-killed")
|
|
827
|
-
return "✓ already killed";
|
|
870
|
+
return { mark: "✓", verb: "already killed", evidence: [] };
|
|
828
871
|
if (evidence === "already-stopped")
|
|
829
|
-
return "✓ already stopped";
|
|
830
|
-
return
|
|
872
|
+
return { mark: "✓", verb: "already stopped", evidence: [] };
|
|
873
|
+
return { mark: "!", verb: "not killed", evidence: [evidence] };
|
|
831
874
|
}
|
|
832
875
|
export function killResultText(id, evidence, alias) {
|
|
833
|
-
|
|
876
|
+
const label = killResultLabel(evidence);
|
|
877
|
+
return actionReceipt({
|
|
878
|
+
mark: label.mark,
|
|
879
|
+
verb: label.verb,
|
|
880
|
+
id,
|
|
881
|
+
...(alias === undefined ? {} : { alias }),
|
|
882
|
+
evidence: label.evidence,
|
|
883
|
+
}).join("\n");
|
|
834
884
|
}
|
|
835
885
|
function answerBytes(answer, structured) {
|
|
836
886
|
return !structured && typeof answer === "string" ? answer : JSON.stringify(answer);
|
|
@@ -884,32 +934,62 @@ export function historyText(result, presentation, context) {
|
|
|
884
934
|
: `${result.history.omitted} earlier events · showing last ${result.history.rows.length}`),
|
|
885
935
|
]
|
|
886
936
|
: [];
|
|
887
|
-
|
|
937
|
+
// History is an immutable timeline, so it takes the shared heading and content boundary and
|
|
938
|
+
// never gains a fabricated current-state conclusion or a live mark.
|
|
939
|
+
const content = [...paging, ...rows];
|
|
940
|
+
const head = panelHead(result.id, presentation.alias, result.contract);
|
|
941
|
+
return [...head, ...(content.length === 0 ? [] : [frameRule(head, context.columns), ...content])].join("\n");
|
|
942
|
+
}
|
|
943
|
+
/** One bounded preview of a submitted Tell, indented once beneath its verdict or evidence. */
|
|
944
|
+
export function tellPayloadLines(text, context) {
|
|
945
|
+
return renderBoundedPayload({
|
|
946
|
+
text,
|
|
947
|
+
first: SUBORDINATE_INDENT,
|
|
948
|
+
continuation: `${SUBORDINATE_INDENT}│ `,
|
|
949
|
+
columns: context.columns,
|
|
950
|
+
maxLines: 1,
|
|
951
|
+
quote: '"',
|
|
952
|
+
openQuote: false,
|
|
953
|
+
truncated: false,
|
|
954
|
+
});
|
|
888
955
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
const
|
|
956
|
+
/** One admitted Tell as a timeline row inside a shared input panel; the panel owns the identity. */
|
|
957
|
+
export function tellAdmissionRow(tell, context) {
|
|
958
|
+
const wake = tell.wake;
|
|
892
959
|
const glyph = wake.kind === "failed" ? "!" : wake.kind === "held" ? "⧗" : "✓";
|
|
893
960
|
const verb = wake.kind === "failed" || wake.kind === "held" ? "tell" : "told";
|
|
894
|
-
|
|
961
|
+
return groupedRows([tell.row], context, {
|
|
895
962
|
...plainLayout(),
|
|
896
963
|
head: (time, _glyph, _verb, columns) => eventPrefix(glyph, verb, time, columns),
|
|
897
964
|
singleLine: true,
|
|
898
965
|
}).join("\n");
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
914
|
-
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* One Tell action receipt: the delivery verdict and complete subject, then the submitted payload
|
|
969
|
+
* once. A held Tell keeps neutral vocabulary; a failed delivery keeps its own concrete diagnosis.
|
|
970
|
+
*/
|
|
971
|
+
export function tellText(result, alias, context) {
|
|
972
|
+
const wake = result.tell.wake;
|
|
973
|
+
const mark = wake.kind === "failed" ? "!" : wake.kind === "held" ? "⧗" : "✓";
|
|
974
|
+
const verb = wake.kind === "failed" || wake.kind === "held" ? "tell" : "told";
|
|
975
|
+
const verdict = actionReceipt({
|
|
976
|
+
mark,
|
|
977
|
+
verb,
|
|
978
|
+
id: result.akuma,
|
|
979
|
+
...(alias === undefined ? {} : { alias }),
|
|
980
|
+
});
|
|
981
|
+
if (wake.kind !== "failed")
|
|
982
|
+
return [...verdict, ...tellPayloadLines(result.tell.row.text, context)].join("\n");
|
|
983
|
+
const child = "child" in wake ? wake.child : undefined;
|
|
984
|
+
const failure = `! tell delivery failed · ${safeText(wake.diagnostic)}${child === undefined ? "" : ` · log ${child.log.path} ${child.log.from}..${child.log.to}`}`;
|
|
985
|
+
return [
|
|
986
|
+
...verdict,
|
|
987
|
+
...tellPayloadLines(result.tell.row.text, context),
|
|
988
|
+
...subordinateLines(renderBoundedTextBlock(failure, {
|
|
989
|
+
first: "",
|
|
990
|
+
continuation: "",
|
|
991
|
+
columns: context.columns - SUBORDINATE_INDENT.length,
|
|
992
|
+
lines: Number.MAX_SAFE_INTEGER,
|
|
993
|
+
})),
|
|
994
|
+
].join("\n");
|
|
915
995
|
}
|
|
@@ -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 {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { effectCleanup, effectExecutionStops } from "./effects.js";
|
|
2
|
-
import { executionCleanupLines, executionStopLines, receiptPayload, receiptRow,
|
|
2
|
+
import { executionCleanupLines, executionStopLines, receiptPayload, receiptRow, titleLines } from "./receipt.js";
|
|
3
3
|
import { renderRefusalFacts } from "./refusal.js";
|
|
4
|
-
import { abbreviateGitIds, displayGitId } from "./contract-observation.js";
|
|
4
|
+
import { abbreviateGitIds, displayGitId, gateFact } from "./contract-observation.js";
|
|
5
5
|
import { DEFAULT_CLI_COLUMNS, gitShortStat, renderTextBlock, safeText } from "./terminal.js";
|
|
6
6
|
const CHILD = " ";
|
|
7
7
|
function workspaceEvidence(workspace) {
|
|
@@ -16,11 +16,16 @@ function candidateLines(report, columns, addressed, abbreviations) {
|
|
|
16
16
|
return lines;
|
|
17
17
|
}
|
|
18
18
|
const identity = candidate.identity;
|
|
19
|
-
receiptRow(lines, " ", "candidate", [{ text: "
|
|
19
|
+
receiptRow(lines, " ", "candidate", [{ text: "prepared" }, { text: displayGitId(identity.tenderSnapshot, abbreviations), opaque: true }], columns);
|
|
20
20
|
lines.push(`${CHILD}integration result ${displayGitId(identity.integration.snapshot, abbreviations)}`);
|
|
21
21
|
if (!/^0{40}$/u.test(identity.integration.changeId))
|
|
22
22
|
lines.push(`${CHILD}content identity ${displayGitId(identity.integration.changeId, abbreviations)}`);
|
|
23
23
|
lines.push(...workspaceEvidence(candidate.workspace));
|
|
24
|
+
for (const report of candidate.requirements.gates)
|
|
25
|
+
lines.push(`${CHILD}${gateFact(report)}`);
|
|
26
|
+
for (const prerequisite of candidate.requirements.unmetPrerequisites) {
|
|
27
|
+
receiptRow(lines, "!", "prerequisite", [{ text: prerequisite.contractId }, { text: prerequisite.state }], columns);
|
|
28
|
+
}
|
|
24
29
|
lines.push(...renderTextBlock(gitShortStat(candidate.scope), CHILD, columns));
|
|
25
30
|
if (candidate.scope.paths !== undefined) {
|
|
26
31
|
for (const path of candidate.scope.paths) {
|
|
@@ -31,32 +36,23 @@ function candidateLines(report, columns, addressed, abbreviations) {
|
|
|
31
36
|
receiptPayload(lines, "diff", candidate.diff);
|
|
32
37
|
return lines;
|
|
33
38
|
}
|
|
34
|
-
function verificationLines(verification, columns
|
|
39
|
+
function verificationLines(verification, columns) {
|
|
35
40
|
const lines = [];
|
|
36
|
-
if (verification.kind
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
if (verification.kind === "stopped") {
|
|
45
|
-
return stopLines(verification.stop, columns, addressed);
|
|
46
|
-
}
|
|
47
|
-
if (verification.kind === "reused") {
|
|
48
|
-
receiptRow(lines, " ", "verification", [{ text: "reused" }, { text: verification.verdict }], columns);
|
|
49
|
-
if (verification.summary !== undefined)
|
|
50
|
-
receiptPayload(lines, "summary", auditSummary(verification.summary));
|
|
41
|
+
if (verification.kind !== "recorded") {
|
|
42
|
+
const text = verification.kind === "undeclared"
|
|
43
|
+
? "none declared"
|
|
44
|
+
: verification.kind === "required"
|
|
45
|
+
? "required · not run"
|
|
46
|
+
: "not run";
|
|
47
|
+
receiptRow(lines, " ", "verification", [{ text }], columns);
|
|
51
48
|
return lines;
|
|
52
49
|
}
|
|
53
|
-
receiptRow(lines, verification.
|
|
54
|
-
if (verification.summary !== undefined)
|
|
55
|
-
receiptPayload(lines, "summary",
|
|
56
|
-
}
|
|
50
|
+
receiptRow(lines, verification.verdict === "unsatisfied" ? "!" : " ", "verification", [{ text: "recorded" }, { text: verification.verdict }], columns);
|
|
51
|
+
if (verification.summary !== undefined)
|
|
52
|
+
receiptPayload(lines, "summary", previewSummary(verification.summary));
|
|
57
53
|
return lines;
|
|
58
54
|
}
|
|
59
|
-
function
|
|
55
|
+
function previewSummary(summary) {
|
|
60
56
|
return summary.replace(/\[(\d+) (bash|zsh|pwsh) exit (-?\d+)( output-truncated)?\]/gu, (_, number, executor, exit, truncated) => `declaration ${number} · ${executor} exit ${exit}${truncated ?? ""}`);
|
|
61
57
|
}
|
|
62
58
|
function admittedCandidateLines(report, columns) {
|
|
@@ -86,6 +82,12 @@ function targetLines(report, columns, addressed, abbreviations) {
|
|
|
86
82
|
opaque: true,
|
|
87
83
|
},
|
|
88
84
|
], columns);
|
|
85
|
+
for (const checkout of target.checkouts) {
|
|
86
|
+
if (checkout.kind === "followable")
|
|
87
|
+
continue;
|
|
88
|
+
receiptRow(lines, "!", "checkout cannot follow", [{ text: checkout.path, opaque: true }], columns);
|
|
89
|
+
receiptPayload(lines, "reason", checkout.diagnostic);
|
|
90
|
+
}
|
|
89
91
|
return lines;
|
|
90
92
|
}
|
|
91
93
|
if (target.kind === "moved") {
|
|
@@ -114,7 +116,7 @@ function obligationLines(result, columns) {
|
|
|
114
116
|
...executionStopLines(effectExecutionStops(result.effects), columns),
|
|
115
117
|
];
|
|
116
118
|
}
|
|
117
|
-
export function
|
|
119
|
+
export function renderDeliveryPreview(result, context) {
|
|
118
120
|
const report = result.value;
|
|
119
121
|
const columns = context?.columns ?? DEFAULT_CLI_COLUMNS;
|
|
120
122
|
const ids = report.candidate.kind === "ready"
|
|
@@ -130,10 +132,10 @@ export function renderAcceptedAudit(result, context) {
|
|
|
130
132
|
ids.push(report.target.expected, report.target.observed ?? "");
|
|
131
133
|
const abbreviations = abbreviateGitIds(ids);
|
|
132
134
|
return [
|
|
133
|
-
...titleLines("✓", "
|
|
135
|
+
...titleLines("✓", "deliver --dry-run", result.contract, columns),
|
|
134
136
|
...candidateLines(report, columns, result.contract, abbreviations),
|
|
135
137
|
...admittedCandidateLines(report, columns),
|
|
136
|
-
...verificationLines(report.verification, columns
|
|
138
|
+
...verificationLines(report.verification, columns),
|
|
137
139
|
...targetLines(report, columns, result.contract, abbreviations),
|
|
138
140
|
...obligationLines(result, columns),
|
|
139
141
|
].join("\n");
|