@astrosheep/keiyaku 4.0.5 → 4.1.0
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/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 +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +15 -7
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +10 -4
- package/build/src/akuma/akuma.d.ts +2 -0
- package/build/src/akuma/akuma.js +26 -3
- package/build/src/akuma/archetype.d.ts +3 -1
- package/build/src/akuma/archetype.js +19 -7
- package/build/src/akuma/body-turn.d.ts +64 -0
- package/build/src/akuma/body-turn.js +449 -0
- package/build/src/akuma/body.d.ts +3 -7
- package/build/src/akuma/body.js +9 -420
- package/build/src/akuma/heart/facts.d.ts +2 -0
- package/build/src/akuma/heart/facts.js +3 -1
- package/build/src/akuma/heart/index.js +12 -2
- package/build/src/akuma/heart/rows.js +4 -1
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +3 -2
- package/build/src/akuma/heart/timeline.d.ts +1 -0
- package/build/src/akuma/heart/timeline.js +19 -0
- package/build/src/akuma/nuke.d.ts +2 -0
- package/build/src/akuma/nuke.js +152 -0
- package/build/src/akuma/provider-recipe.d.ts +2 -0
- package/build/src/akuma/provider-recipe.js +10 -0
- package/build/src/akuma/provider.d.ts +3 -1
- package/build/src/akuma/providers/acp/config.d.ts +10 -0
- package/build/src/akuma/providers/acp/config.js +45 -0
- package/build/src/akuma/providers/acp/core.d.ts +5 -2
- package/build/src/akuma/providers/acp/core.js +35 -16
- package/build/src/akuma/providers/acp/index.d.ts +1 -8
- package/build/src/akuma/providers/acp/index.js +10 -39
- package/build/src/akuma/providers/claude/index.d.ts +1 -1
- package/build/src/akuma/providers/claude/index.js +14 -5
- package/build/src/akuma/providers/codex-app-server/index.js +9 -1
- package/build/src/akuma/providers/grok-build/index.js +16 -2
- package/build/src/akuma/providers/index.d.ts +3 -2
- package/build/src/akuma/providers/index.js +37 -37
- package/build/src/akuma/providers/opencode-sdk/index.js +9 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
- package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
- package/build/src/akuma/providers/pi/index.d.ts +1 -1
- package/build/src/akuma/providers/pi/index.js +30 -12
- package/build/src/akuma/request-serve.d.ts +1 -0
- package/build/src/akuma/request-serve.js +31 -31
- package/build/src/akuma/request-wire.d.ts +3 -2
- package/build/src/akuma/request-wire.js +5 -2
- package/build/src/akuma-body.js +15 -1
- package/build/src/alias/index.d.ts +1 -0
- package/build/src/alias/index.js +34 -1
- package/build/src/body/amend.js +0 -9
- package/build/src/body/region.js +2 -2
- package/build/src/cli/accepted.js +6 -0
- package/build/src/cli/commands/akuma-invoke.js +1 -0
- package/build/src/cli/commands/akuma.d.ts +1 -0
- package/build/src/cli/commands/akuma.js +11 -8
- package/build/src/cli/commands/contract.d.ts +28 -15
- package/build/src/cli/commands/contract.js +34 -18
- package/build/src/cli/commands/install.d.ts +2 -2
- package/build/src/cli/commands/install.js +6 -6
- package/build/src/cli/commands/nuke.d.ts +10 -0
- package/build/src/cli/commands/nuke.js +20 -0
- package/build/src/cli/commands/task-invoke.d.ts +19 -1
- package/build/src/cli/commands/task-invoke.js +63 -29
- package/build/src/cli/commands/task-query.d.ts +2 -2
- package/build/src/cli/commands/task-query.js +1 -2
- package/build/src/cli/commands/task.js +30 -22
- package/build/src/cli/coordinates.d.ts +5 -2
- package/build/src/cli/coordinates.js +5 -52
- package/build/src/cli/invoke.d.ts +5 -4
- package/build/src/cli/invoke.js +89 -59
- package/build/src/cli/main.d.ts +0 -2
- package/build/src/cli/main.js +4 -140
- package/build/src/cli/parse.d.ts +15 -2
- package/build/src/cli/parse.js +73 -8
- package/build/src/cli/render/akuma.js +95 -49
- package/build/src/cli/render/catalog.js +5 -1
- package/build/src/cli/render/contract.js +72 -49
- package/build/src/cli/render/kanshi.js +157 -99
- package/build/src/cli/render/nuke.d.ts +3 -0
- package/build/src/cli/render/nuke.js +8 -0
- package/build/src/cli/render/receipt.d.ts +1 -0
- package/build/src/cli/render/receipt.js +18 -14
- package/build/src/cli/render/refusal.d.ts +2 -1
- package/build/src/cli/render/refusal.js +37 -0
- package/build/src/cli/render/task.js +63 -11
- package/build/src/cli/render/text.js +6 -1
- package/build/src/cli/result.d.ts +28 -2
- package/build/src/cli/runtime.d.ts +2 -0
- package/build/src/cli/runtime.js +140 -0
- package/build/src/cli/usage.d.ts +0 -2
- package/build/src/cli/usage.js +0 -4
- package/build/src/contract-worktree.d.ts +26 -12
- package/build/src/contract-worktree.js +119 -64
- package/build/src/git/hooks.d.ts +2 -0
- package/build/src/git/hooks.js +34 -1
- package/build/src/git/integration.d.ts +4 -0
- package/build/src/git/integration.js +38 -0
- package/build/src/git/nuke.d.ts +2 -0
- package/build/src/git/nuke.js +92 -0
- package/build/src/git/process.d.ts +2 -0
- package/build/src/git/repository.js +4 -1
- package/build/src/git/target-placement.d.ts +2 -1
- package/build/src/git/target-placement.js +6 -7
- package/build/src/git/tender.d.ts +14 -2
- package/build/src/git/tender.js +45 -6
- package/build/src/git/workspace.d.ts +3 -0
- package/build/src/kanshi/read.js +37 -13
- package/build/src/kanshi/report.d.ts +2 -1
- package/build/src/library/akuma-creation.d.ts +1 -0
- package/build/src/library/akuma-creation.js +8 -1
- package/build/src/library/audit.d.ts +1 -0
- package/build/src/library/audit.js +1 -0
- package/build/src/library/continuation.d.ts +26 -0
- package/build/src/library/continuation.js +78 -0
- package/build/src/library/contract.d.ts +14 -8
- package/build/src/library/contract.js +82 -35
- package/build/src/library/delivery.d.ts +18 -11
- package/build/src/library/keiyaku.d.ts +5 -1
- package/build/src/library/keiyaku.js +2 -0
- package/build/src/library/mutation.d.ts +1 -0
- package/build/src/library/mutation.js +14 -4
- package/build/src/library/nuke.d.ts +14 -0
- package/build/src/library/nuke.js +54 -0
- package/build/src/library/reconcile.js +5 -2
- package/build/src/library/refusal.d.ts +10 -1
- package/build/src/library/repo.d.ts +1 -0
- package/build/src/library/repo.js +2 -0
- package/build/src/protocol/audit.js +12 -5
- package/build/src/protocol/completion.d.ts +11 -1
- package/build/src/protocol/completion.js +68 -15
- package/build/src/protocol/deliver.d.ts +25 -3
- package/build/src/protocol/deliver.js +148 -14
- package/build/src/protocol/intent.d.ts +1 -0
- package/build/src/protocol/intent.js +7 -1
- package/build/src/protocol/operations.d.ts +36 -4
- package/build/src/protocol/operations.js +2 -2
- package/build/src/protocol/placement.d.ts +9 -1
- package/build/src/protocol/placement.js +5 -4
- package/build/src/protocol/read/status.d.ts +16 -4
- package/build/src/protocol/read/status.js +54 -12
- package/build/src/protocol/review.d.ts +1 -0
- package/build/src/protocol/review.js +8 -0
- package/build/src/runtime/proc/run.js +9 -5
- package/build/src/settlement/settle.js +1 -2
- package/build/src/task/board.d.ts +21 -2
- package/build/src/task/board.js +25 -12
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +2 -7
- package/build/src/task/context.d.ts +14 -2
- package/build/src/task/context.js +30 -7
- package/build/src/task/identity.js +14 -4
- package/build/src/task/index.d.ts +7 -5
- package/build/src/task/index.js +21 -18
- package/build/src/task/mutation.d.ts +7 -2
- package/build/src/task/mutation.js +14 -6
- package/build/src/task/operations.d.ts +14 -7
- package/build/src/task/operations.js +37 -50
- package/build/src/task/query.js +2 -2
- package/build/src/task/store.d.ts +3 -0
- package/build/src/task/store.js +21 -2
- package/build/src/workspace-place.d.ts +2 -0
- package/build/src/workspace-place.js +27 -1
- package/package.json +1 -1
package/build/src/cli/parse.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ParsedTaskCommand, type TaskAction } from "./commands/task.js";
|
|
2
2
|
import { type AkumaAction, type ParsedAkumaCommand } from "./commands/akuma.js";
|
|
3
|
-
import type { CatalogQuery } from "../
|
|
3
|
+
import type { CatalogQuery } from "../library/catalog.js";
|
|
4
4
|
import { type ParsedInstallCommand } from "./commands/install.js";
|
|
5
5
|
import { type ContractCommand as Command } from "./commands/contract.js";
|
|
6
6
|
export { CliUsageError } from "./usage.js";
|
|
@@ -8,6 +8,7 @@ export type { Command };
|
|
|
8
8
|
export declare function renderRootHelp(): string;
|
|
9
9
|
export declare function renderContractHelp(command: Command): string;
|
|
10
10
|
export declare function renderCommandUsage(command: ParsedCommand): string;
|
|
11
|
+
export declare function renderHelp(coordinate: CliHelpCoordinate): string;
|
|
11
12
|
type Output = Readonly<{
|
|
12
13
|
output: "text" | "json";
|
|
13
14
|
}>;
|
|
@@ -35,6 +36,7 @@ export type ParsedDeliver = Output & Actor & Readonly<{
|
|
|
35
36
|
contract?: string;
|
|
36
37
|
message?: string;
|
|
37
38
|
includeDirty: boolean;
|
|
39
|
+
materializeConflict: boolean;
|
|
38
40
|
}>;
|
|
39
41
|
export type ParsedReview = Output & Actor & Readonly<{
|
|
40
42
|
command: "review";
|
|
@@ -77,6 +79,10 @@ type ParsedReconcile = Output & Readonly<{
|
|
|
77
79
|
contract?: string;
|
|
78
80
|
retryHooks: boolean;
|
|
79
81
|
}>;
|
|
82
|
+
export type ParsedNuke = Output & Readonly<{
|
|
83
|
+
command: "nuke";
|
|
84
|
+
confirm?: string;
|
|
85
|
+
}>;
|
|
80
86
|
export type ParsedSettings = Output & Readonly<{
|
|
81
87
|
command: "settings";
|
|
82
88
|
}>;
|
|
@@ -89,7 +95,7 @@ export type ParsedRegion = Output & Readonly<{
|
|
|
89
95
|
export type ParsedCommand = ParsedBind | ParsedAmend | ParsedDeliver | ParsedReview | ParsedArc | ParsedAbandon | ParsedStatus | (Output & Readonly<{
|
|
90
96
|
command: "show";
|
|
91
97
|
contract?: string;
|
|
92
|
-
}>) | ParsedLs | ParsedAudit | ParsedReconcile | ParsedSettings | ParsedRegion | ParsedInstallCommand | ParsedAkumaCommand | ParsedTaskCommand;
|
|
98
|
+
}>) | ParsedLs | ParsedAudit | ParsedReconcile | ParsedNuke | ParsedSettings | ParsedRegion | ParsedInstallCommand | ParsedAkumaCommand | ParsedTaskCommand;
|
|
93
99
|
export type CliHelpCoordinate = Readonly<{
|
|
94
100
|
kind: "root";
|
|
95
101
|
}> | Readonly<{
|
|
@@ -112,4 +118,11 @@ export type ParsedExecution = Readonly<{
|
|
|
112
118
|
export type ParsedInvocation = ParsedExecution | Readonly<{
|
|
113
119
|
help: CliHelpCoordinate;
|
|
114
120
|
}>;
|
|
121
|
+
type RepoUse = "none" | "optional" | "required";
|
|
122
|
+
export type CommandRepoPolicy = Readonly<{
|
|
123
|
+
use: RepoUse;
|
|
124
|
+
acceptsExplicit: boolean;
|
|
125
|
+
}>;
|
|
126
|
+
export declare function commandRepoPolicy(command: ParsedCommand): CommandRepoPolicy;
|
|
127
|
+
export declare function assertExplicitRepoUse(command: ParsedCommand, repo: string | undefined): void;
|
|
115
128
|
export declare function parseArgv(argv: readonly string[]): ParsedInvocation;
|
package/build/src/cli/parse.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { isTaskAction, parseTaskCommand, renderTaskUsage, } from "./commands/task.js";
|
|
2
|
-
import { isAkumaAction, parseAkumaCatalogPath, parseAkumaCommand, renderAkumaRootRows, renderAkumaUsage, } from "./commands/akuma.js";
|
|
1
|
+
import { isTaskAction, parseTaskCommand, renderTaskHelp, renderTaskUsage, } from "./commands/task.js";
|
|
2
|
+
import { isAkumaAction, parseAkumaCatalogPath, parseAkumaCommand, renderAkumaHelp, renderAkumaRootRows, renderAkumaUsage, } from "./commands/akuma.js";
|
|
3
3
|
import { INSTALL_USAGE, parseInstallCommand, renderInstallHelp } from "./commands/install.js";
|
|
4
|
-
import {
|
|
5
|
-
import { CliUsageError, isBlankInput, usageLine
|
|
4
|
+
import { CONTRACT_COMMAND_SPECS, } from "./commands/contract.js";
|
|
5
|
+
import { CliUsageError, isBlankInput, usageLine } from "./usage.js";
|
|
6
6
|
export { CliUsageError } from "./usage.js";
|
|
7
7
|
const ROOT_USAGE = "usage: keiyaku [-C <path>] [--repo <path>] <command> [<contract>|@<contract>] [--flag ...] [-]";
|
|
8
8
|
export function renderRootHelp() {
|
|
9
|
-
return
|
|
9
|
+
return [
|
|
10
10
|
ROOT_USAGE,
|
|
11
11
|
"",
|
|
12
12
|
"global options:",
|
|
@@ -20,12 +20,12 @@ export function renderRootHelp() {
|
|
|
20
20
|
" task ...",
|
|
21
21
|
" Task coordination; see `keiyaku task --help`.",
|
|
22
22
|
...renderAkumaRootRows(),
|
|
23
|
-
].join("\n")
|
|
23
|
+
].join("\n");
|
|
24
24
|
}
|
|
25
25
|
export function renderContractHelp(command) {
|
|
26
26
|
const spec = CONTRACT_COMMAND_SPECS[command];
|
|
27
27
|
const help = `${spec.purpose}\n\n${usageLine(spec.usage)}`;
|
|
28
|
-
return
|
|
28
|
+
return spec.help === undefined ? help : `${help}\n\n${spec.help}`;
|
|
29
29
|
}
|
|
30
30
|
function contractUsage(command) {
|
|
31
31
|
return usageLine(CONTRACT_COMMAND_SPECS[command].usage);
|
|
@@ -39,6 +39,65 @@ export function renderCommandUsage(command) {
|
|
|
39
39
|
return renderAkumaUsage(command.command);
|
|
40
40
|
return contractUsage(command.command);
|
|
41
41
|
}
|
|
42
|
+
export function renderHelp(coordinate) {
|
|
43
|
+
switch (coordinate.kind) {
|
|
44
|
+
case "root": return renderRootHelp();
|
|
45
|
+
case "contract": return renderContractHelp(coordinate.command);
|
|
46
|
+
case "task": return renderTaskHelp(coordinate.action);
|
|
47
|
+
case "install": return renderInstallHelp();
|
|
48
|
+
case "akuma": return renderAkumaHelp(coordinate.action);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function commandRepoPolicy(command) {
|
|
52
|
+
switch (command.command) {
|
|
53
|
+
case "bind":
|
|
54
|
+
case "amend":
|
|
55
|
+
case "deliver":
|
|
56
|
+
case "review":
|
|
57
|
+
case "arc":
|
|
58
|
+
case "abandon":
|
|
59
|
+
case "audit":
|
|
60
|
+
case "reconcile":
|
|
61
|
+
case "show":
|
|
62
|
+
case "region":
|
|
63
|
+
return { use: "required", acceptsExplicit: true };
|
|
64
|
+
case "ls":
|
|
65
|
+
return { use: command.query.kind === "contracts" ? "required" : "none", acceptsExplicit: false };
|
|
66
|
+
case "status":
|
|
67
|
+
case "tell":
|
|
68
|
+
return { use: "optional", acceptsExplicit: false };
|
|
69
|
+
case "history":
|
|
70
|
+
return "contract" in command
|
|
71
|
+
? { use: "required", acceptsExplicit: true }
|
|
72
|
+
: { use: "optional", acceptsExplicit: false };
|
|
73
|
+
case "fork":
|
|
74
|
+
return { use: "optional", acceptsExplicit: true };
|
|
75
|
+
case "wait":
|
|
76
|
+
case "kill": {
|
|
77
|
+
const contractSelector = command.akuma.some((selector) => selector.startsWith("kei/"));
|
|
78
|
+
return { use: contractSelector ? "required" : "optional", acceptsExplicit: contractSelector };
|
|
79
|
+
}
|
|
80
|
+
case "call":
|
|
81
|
+
return {
|
|
82
|
+
use: command.contract === undefined ? "none" : "required",
|
|
83
|
+
acceptsExplicit: command.contract !== undefined,
|
|
84
|
+
};
|
|
85
|
+
case "settings":
|
|
86
|
+
case "nuke":
|
|
87
|
+
case "task":
|
|
88
|
+
case "install":
|
|
89
|
+
return { use: "none", acceptsExplicit: false };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function refuseUnusedRepo(command) {
|
|
93
|
+
if (command.command === "call")
|
|
94
|
+
throw new CliUsageError("--repo has no consumer without --contract");
|
|
95
|
+
throw new CliUsageError(`--repo has no consumer for ${command.command}`);
|
|
96
|
+
}
|
|
97
|
+
export function assertExplicitRepoUse(command, repo) {
|
|
98
|
+
if (repo !== undefined && !commandRepoPolicy(command).acceptsExplicit)
|
|
99
|
+
refuseUnusedRepo(command);
|
|
100
|
+
}
|
|
42
101
|
function optionalFlag(flags, name) {
|
|
43
102
|
const value = flags[name];
|
|
44
103
|
return typeof value === "string" ? value : undefined;
|
|
@@ -175,6 +234,7 @@ function parseDeliver(parts) {
|
|
|
175
234
|
...(parts.actor === undefined ? {} : { actor: parts.actor }),
|
|
176
235
|
...(message === undefined ? {} : { message }),
|
|
177
236
|
includeDirty: parts.flags["include-dirty"] === true,
|
|
237
|
+
materializeConflict: parts.flags["materialize-conflict"] === true,
|
|
178
238
|
output: parts.output,
|
|
179
239
|
};
|
|
180
240
|
}
|
|
@@ -356,6 +416,10 @@ function parseCommand(parts) {
|
|
|
356
416
|
output: parts.output,
|
|
357
417
|
};
|
|
358
418
|
}
|
|
419
|
+
case "nuke": {
|
|
420
|
+
const confirm = optionalFlag(parts.flags, "confirm");
|
|
421
|
+
return { command: "nuke", ...(confirm === undefined ? {} : { confirm }), output: parts.output };
|
|
422
|
+
}
|
|
359
423
|
case "settings": return { command: "settings", output: parts.output };
|
|
360
424
|
case "region": return parseRegion(parts);
|
|
361
425
|
}
|
|
@@ -379,9 +443,10 @@ export function parseArgv(argv) {
|
|
|
379
443
|
const akuma = isAkumaAction(invocation.commandArgv[0])
|
|
380
444
|
? parseAkumaCommand(invocation.commandArgv)
|
|
381
445
|
: undefined;
|
|
382
|
-
|
|
446
|
+
const parsed = {
|
|
383
447
|
...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
|
|
384
448
|
...(invocation.repo === undefined ? {} : { repo: invocation.repo }),
|
|
385
449
|
command: task ?? akuma ?? install ?? parseCommand(scanArgv(invocation.commandArgv)),
|
|
386
450
|
};
|
|
451
|
+
return parsed;
|
|
387
452
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toolRepr } from "./akuma-tool.js";
|
|
2
|
-
import { displayColumns, renderBoundedTextBlock,
|
|
2
|
+
import { displayColumns, renderBoundedTextBlock, safeText, truncateMiddleDisplayText, } from "./terminal.js";
|
|
3
3
|
const DEFAULT_CONTEXT = { columns: 80, color: false };
|
|
4
4
|
const OPENING_STROKE = "─────";
|
|
5
5
|
const TIME_WIDTH = 5;
|
|
@@ -14,14 +14,20 @@ function associatedIdentity(id, alias, contract) {
|
|
|
14
14
|
const contractId = contract === undefined ? undefined : associatedContractId(contract);
|
|
15
15
|
return `${identity(id, alias)}${contractId === undefined ? "" : ` [${contractId}]`}`;
|
|
16
16
|
}
|
|
17
|
-
function
|
|
17
|
+
function ruler(columns) {
|
|
18
|
+
return "─".repeat(Math.max(OPENING_STROKE.length, columns));
|
|
19
|
+
}
|
|
20
|
+
function snapshotHeading(id, alias, contract, columns) {
|
|
18
21
|
const contractId = contract === undefined ? undefined : associatedContractId(contract);
|
|
19
22
|
return [
|
|
20
|
-
OPENING_STROKE,
|
|
21
23
|
identity(id, alias),
|
|
24
|
+
ruler(columns),
|
|
22
25
|
...(contractId === undefined ? [] : [`└─ ${contractId}`]),
|
|
23
26
|
];
|
|
24
27
|
}
|
|
28
|
+
function answeredHeading(id, alias, columns) {
|
|
29
|
+
return [`✓ came back ${identity(id, alias)}`, ruler(columns)].join("\n");
|
|
30
|
+
}
|
|
25
31
|
function contractFacts(contract) {
|
|
26
32
|
return contract.kind === "failed" ? [`! contract failed ${safeText(contract.diagnostic)}`] : [];
|
|
27
33
|
}
|
|
@@ -30,9 +36,9 @@ function unobservedText(id, diagnostic) {
|
|
|
30
36
|
}
|
|
31
37
|
function lifeLabel(life) {
|
|
32
38
|
if (life === "running")
|
|
33
|
-
return "●
|
|
39
|
+
return "● STILL RUNNING";
|
|
34
40
|
if (life === "asleep")
|
|
35
|
-
return "
|
|
41
|
+
return "✓ came back";
|
|
36
42
|
if (life === "killed")
|
|
37
43
|
return "× killed";
|
|
38
44
|
return `? ${life}`;
|
|
@@ -70,7 +76,7 @@ function mark(row) {
|
|
|
70
76
|
return "?";
|
|
71
77
|
return row.state.status === "ok" ? "✓" : "!";
|
|
72
78
|
}
|
|
73
|
-
return "
|
|
79
|
+
return "│";
|
|
74
80
|
}
|
|
75
81
|
function rowText(row) {
|
|
76
82
|
if (row.kind === "said" || row.kind === "thought" || row.kind === "note" || row.kind === "call" || row.kind === "tell") {
|
|
@@ -160,47 +166,72 @@ function taskDispositionMark(disposition) {
|
|
|
160
166
|
return "●";
|
|
161
167
|
return disposition === "blocked" ? "‖" : "○";
|
|
162
168
|
}
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
for (const change of snapshot.reportedChanges) {
|
|
172
|
-
const scan = ` ${changeOp(change.op)}`;
|
|
173
|
-
const path = safeText(change.path);
|
|
174
|
-
const stat = change.diffstat === undefined
|
|
175
|
-
? ""
|
|
176
|
-
: ` — +${change.diffstat.added} -${change.diffstat.removed}`;
|
|
177
|
-
const inline = `${scan} ${path}${stat}`;
|
|
178
|
-
if (displayColumns(inline) <= columns)
|
|
179
|
-
lines.push(inline);
|
|
180
|
-
else
|
|
181
|
-
lines.push(`${scan}`, ...renderTextBlock(`${path}${stat}`, " ", columns));
|
|
169
|
+
function changeStat(group) {
|
|
170
|
+
let added = 0;
|
|
171
|
+
let removed = 0;
|
|
172
|
+
for (const change of group) {
|
|
173
|
+
if (change.diffstat === undefined)
|
|
174
|
+
return "+? -?";
|
|
175
|
+
added += change.diffstat.added;
|
|
176
|
+
removed += change.diffstat.removed;
|
|
182
177
|
}
|
|
183
|
-
|
|
184
|
-
|
|
178
|
+
return `+${added} -${removed}`;
|
|
179
|
+
}
|
|
180
|
+
function groupedChangeRows(changes) {
|
|
181
|
+
const groups = [];
|
|
182
|
+
const seen = new Map();
|
|
183
|
+
for (const change of changes) {
|
|
184
|
+
const index = seen.get(change.path);
|
|
185
|
+
if (index === undefined) {
|
|
186
|
+
seen.set(change.path, groups.length);
|
|
187
|
+
groups.push([change]);
|
|
188
|
+
}
|
|
189
|
+
else
|
|
190
|
+
groups[index].push(change);
|
|
185
191
|
}
|
|
186
|
-
return
|
|
192
|
+
return groups.map((group) => ({ path: group[0].path, stat: changeStat(group) }));
|
|
193
|
+
}
|
|
194
|
+
function renderReportedChangeLines(snapshot) {
|
|
195
|
+
const rows = groupedChangeRows(snapshot.reportedChanges);
|
|
196
|
+
const width = rows.reduce((max, row) => Math.max(max, row.stat.length), 0);
|
|
197
|
+
return [
|
|
198
|
+
`changes ${snapshot.reportedChanges.length + snapshot.reportedChangesOmitted}`,
|
|
199
|
+
...rows.map((row) => ` ${row.stat.padEnd(width)} ${safeText(row.path)}`),
|
|
200
|
+
...(snapshot.reportedChangesOmitted > 0 ? [` ⋮ ${snapshot.reportedChangesOmitted} earlier changes`] : []),
|
|
201
|
+
];
|
|
202
|
+
}
|
|
203
|
+
function renderTaskRow(row, columns) {
|
|
204
|
+
const prefix = ` ${taskDispositionMark(row.disposition)} ${row.id} · `;
|
|
205
|
+
const body = `${safeText(row.title)} · ${row.disposition} · P${row.priority}`;
|
|
206
|
+
const inline = `${prefix}${body}`;
|
|
207
|
+
if (displayColumns(inline) <= columns)
|
|
208
|
+
return [inline];
|
|
209
|
+
return renderBoundedTextBlock(body, {
|
|
210
|
+
first: prefix,
|
|
211
|
+
continuation: " ",
|
|
212
|
+
columns,
|
|
213
|
+
lines: Number.MAX_SAFE_INTEGER,
|
|
214
|
+
});
|
|
187
215
|
}
|
|
188
216
|
function renderTaskContextLines(created, columns) {
|
|
189
217
|
if (created === undefined)
|
|
190
218
|
return [];
|
|
191
219
|
if (created.kind === "failed")
|
|
192
220
|
return [`! tasks failed ${safeText(created.diagnostic)}`];
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
221
|
+
return [`tasks ${created.rows.length}`, ...created.rows.flatMap((row) => renderTaskRow(row, columns))];
|
|
222
|
+
}
|
|
223
|
+
function answerContextLines(observation, columns) {
|
|
224
|
+
return [
|
|
225
|
+
...renderTaskContextLines(observation.createdTasks, columns),
|
|
226
|
+
...renderReportedChangeLines(observation.status.timeline),
|
|
227
|
+
];
|
|
228
|
+
}
|
|
229
|
+
function answeredBlock(observation, answer, alias, columns) {
|
|
230
|
+
const context = answerContextLines(observation, columns).join("\n");
|
|
231
|
+
if (context.length === 0)
|
|
232
|
+
return `${answeredHeading(observation.status.id, alias, columns)}\n${answer}`;
|
|
233
|
+
const separator = answer.endsWith("\n") ? "\n" : "\n\n";
|
|
234
|
+
return `${answeredHeading(observation.status.id, alias, columns)}\n${answer}${separator}${context}`;
|
|
204
235
|
}
|
|
205
236
|
function snapshotText(view, context, options = {}) {
|
|
206
237
|
const snapshot = view.status.timeline;
|
|
@@ -215,14 +246,17 @@ function snapshotText(view, context, options = {}) {
|
|
|
215
246
|
...contractFacts(view.contract),
|
|
216
247
|
...(options.facts ?? []),
|
|
217
248
|
];
|
|
218
|
-
const
|
|
249
|
+
const taskContext = renderTaskContextLines(view.createdTasks, context.columns);
|
|
250
|
+
const changes = renderReportedChangeLines(snapshot);
|
|
251
|
+
const footer = options.showLife === false ? [] : ["", lifeLabel(view.status.life)];
|
|
219
252
|
return [
|
|
220
|
-
...snapshotHeading(view.status.id, options.alias, view.contract),
|
|
253
|
+
...snapshotHeading(view.status.id, options.alias, view.contract, context.columns),
|
|
221
254
|
...facts,
|
|
222
255
|
...activity,
|
|
256
|
+
...(activity.length > 0 && taskContext.length > 0 ? [""] : []),
|
|
257
|
+
...taskContext,
|
|
258
|
+
...changes,
|
|
223
259
|
...footer,
|
|
224
|
-
...renderReportedChangeLines(snapshot, context.columns),
|
|
225
|
-
...renderTaskContextLines(view.createdTasks, context.columns),
|
|
226
260
|
].join("\n");
|
|
227
261
|
}
|
|
228
262
|
function observationStageText(id, observation, context, options = {}) {
|
|
@@ -232,18 +266,27 @@ function observationStageText(id, observation, context, options = {}) {
|
|
|
232
266
|
}
|
|
233
267
|
function waitText(result, context) {
|
|
234
268
|
const alias = result.alias;
|
|
269
|
+
const total = result.result.observations.length + result.result.unobserved.length;
|
|
270
|
+
const done = result.result.observations.filter((observation) => observation.status.life !== "running").length;
|
|
235
271
|
const blocks = [
|
|
236
|
-
...result.result.observations.map((observation) =>
|
|
272
|
+
...result.result.observations.map((observation) => {
|
|
273
|
+
const answer = statusAnswer(observation);
|
|
274
|
+
if (answer !== undefined)
|
|
275
|
+
return answeredBlock(observation, answer, alias, context.columns);
|
|
276
|
+
return snapshotText(observation, context, { ...(alias === undefined ? {} : { alias }) });
|
|
277
|
+
}),
|
|
237
278
|
...result.result.unobserved.map((member) => unobservedText(member.id, member.diagnostic)),
|
|
238
279
|
];
|
|
239
|
-
|
|
280
|
+
if (total <= 1)
|
|
281
|
+
return blocks.join("\n\n");
|
|
282
|
+
return [...blocks, `${done} of ${total} done`].join("\n\n");
|
|
240
283
|
}
|
|
241
284
|
function historyText(command, result, context) {
|
|
242
285
|
if (command.last)
|
|
243
286
|
return result.mode === "last" ? result.answer : "no answer retained";
|
|
244
287
|
if (result.mode !== "page")
|
|
245
288
|
throw new Error("history result lacks page");
|
|
246
|
-
return [...snapshotHeading(result.akuma, result.alias, result.historyResult.contract), ...groupedRows(result.history.rows, context, true)].join("\n");
|
|
289
|
+
return [...snapshotHeading(result.akuma, result.alias, result.historyResult.contract, context.columns), ...groupedRows(result.history.rows, context, true)].join("\n");
|
|
247
290
|
}
|
|
248
291
|
function tellText(result, context) {
|
|
249
292
|
const facts = typeof result.result.tell.wake === "string" ? [] : [`! error ${safeText(result.result.tell.wake.diagnostic)}`];
|
|
@@ -291,6 +334,9 @@ export function akumaRawAnswer(result) {
|
|
|
291
334
|
function executionCwdLine(result) {
|
|
292
335
|
return result.execution.source === "contract-worktree" ? [`cwd ${result.execution.cwd}`] : [];
|
|
293
336
|
}
|
|
337
|
+
function posixShellArgument(value) {
|
|
338
|
+
return `'${value.replace(/'/g, `'\"'\"'`)}'`;
|
|
339
|
+
}
|
|
294
340
|
function callText(result, context) {
|
|
295
341
|
const alias = result.result.alias.kind === "aliased" ? result.result.alias.alias.alias : undefined;
|
|
296
342
|
const contractId = result.result.dispatch.kind === "dispatched" ? result.result.dispatch.dispatch.contractId : undefined;
|
|
@@ -302,17 +348,17 @@ function callText(result, context) {
|
|
|
302
348
|
if (result.result.observation.kind === "detached") {
|
|
303
349
|
const lines = [...snapshotHeading(result.result.akuma, alias, contractId === undefined
|
|
304
350
|
? { kind: "none" }
|
|
305
|
-
: { kind: "associated", contractId }), ...cwd, ...restraint, ...facts];
|
|
351
|
+
: { kind: "associated", contractId }, context.columns), ...cwd, ...restraint, ...facts];
|
|
306
352
|
if (!callFailed(result.result)) {
|
|
307
353
|
const selector = result.result.alias.kind === "aliased" ? result.result.alias.alias.alias : result.result.akuma;
|
|
308
|
-
lines.push(`$ keiyaku -C ${result.world} wait ${selector} --timeout 5m`);
|
|
354
|
+
lines.push(`$ keiyaku -C ${posixShellArgument(result.world)} wait ${selector} --timeout 5m`);
|
|
309
355
|
}
|
|
310
356
|
return lines.join("\n");
|
|
311
357
|
}
|
|
312
358
|
if (result.result.observation.kind === "failed") {
|
|
313
359
|
return [...snapshotHeading(result.result.akuma, alias, contractId === undefined
|
|
314
360
|
? { kind: "none" }
|
|
315
|
-
: { kind: "associated", contractId }), ...cwd, ...restraint, ...facts, `! error ${safeText(result.result.observation.failure.diagnostic)}`].join("\n");
|
|
361
|
+
: { kind: "associated", contractId }, context.columns), ...cwd, ...restraint, ...facts, `! error ${safeText(result.result.observation.failure.diagnostic)}`].join("\n");
|
|
316
362
|
}
|
|
317
363
|
return snapshotText({
|
|
318
364
|
status: result.result.observation.status,
|
|
@@ -12,5 +12,9 @@ export function renderCatalogText(catalog) {
|
|
|
12
12
|
...(row.description === undefined ? [] : [` ${safeText(row.description)}`]),
|
|
13
13
|
]).join("\n");
|
|
14
14
|
}
|
|
15
|
-
return catalog.rows.map((row) =>
|
|
15
|
+
return catalog.rows.map((row) => {
|
|
16
|
+
if (!("lifeAt" in row))
|
|
17
|
+
return `${safeText(row.id)} - ${row.life}`;
|
|
18
|
+
return `${safeText(row.id)} - ${row.life} - runtime ${row.lifeAt ?? "-"} - last activity ${row.lastActivityAt ?? "-"}`;
|
|
19
|
+
}).join("\n");
|
|
16
20
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { renderAcceptedAudit } from "./audit.js";
|
|
2
|
-
import { appendHookPayload, cleanupLines, hookFailureSummary, leakLines, outcomeLines, receiptPayload, receiptRow, reuseLines, stopLines, titleLines, } from "./receipt.js";
|
|
2
|
+
import { appendHookPayload, cleanupLines, hookFailureSummary, leakLines, outcomeLines, receiptPayload, receiptRow, reuseLines, stopLines, stopSummary, titleLines, } from "./receipt.js";
|
|
3
3
|
import { gitShortStat, renderOpaqueBlock } from "./terminal.js";
|
|
4
4
|
const HANG = " ";
|
|
5
5
|
function isRecord(value) {
|
|
@@ -113,11 +113,20 @@ function acceptedRecord(result, columns) {
|
|
|
113
113
|
const record = [];
|
|
114
114
|
for (const fact of result.facts) {
|
|
115
115
|
const contract = fact.contract === result.contract ? [] : [{ text: fact.contract, opaque: true }];
|
|
116
|
-
receiptRow(record, " ", "journal",
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
receiptRow(record, " ", "journal", fact.kind === "reintegrated"
|
|
117
|
+
? [
|
|
118
|
+
...contract,
|
|
119
|
+
{ text: fact.entry, opaque: true },
|
|
120
|
+
{ text: "· reintegrated" },
|
|
121
|
+
{ text: fact.data.predecessor, opaque: true },
|
|
122
|
+
{ text: "->" },
|
|
123
|
+
{ text: fact.data.snapshot, opaque: true },
|
|
124
|
+
]
|
|
125
|
+
: [
|
|
126
|
+
...contract,
|
|
127
|
+
{ text: fact.entry, opaque: true },
|
|
128
|
+
{ text: `· ${fact.kind}` },
|
|
129
|
+
], columns);
|
|
121
130
|
}
|
|
122
131
|
receiptRow(record, " ", "head", [{ text: result.head, opaque: true }], columns);
|
|
123
132
|
if (result.verb === "deliver") {
|
|
@@ -176,11 +185,58 @@ function recordBlock(result, columns) {
|
|
|
176
185
|
const rows = [...acceptedRecord(result, columns), ...acceptedLagRows(result, columns)];
|
|
177
186
|
return [" record", ...indentRecord(rows)];
|
|
178
187
|
}
|
|
179
|
-
function
|
|
188
|
+
function completionLines(result, columns) {
|
|
180
189
|
const lines = [];
|
|
181
|
-
|
|
182
|
-
|
|
190
|
+
const completion = result.completion;
|
|
191
|
+
if (completion === undefined)
|
|
192
|
+
return lines;
|
|
193
|
+
const verification = completion.verification;
|
|
194
|
+
receiptRow(lines, " ", "target", [
|
|
195
|
+
{ text: "->" },
|
|
196
|
+
{ text: completion.integration, opaque: true },
|
|
197
|
+
...(verification?.verdict === "satisfied"
|
|
198
|
+
? [{ text: `· verified (${verification.mode})` }]
|
|
199
|
+
: []),
|
|
183
200
|
], columns);
|
|
201
|
+
if (verification?.verdict === "unsatisfied") {
|
|
202
|
+
receiptRow(lines, "!", "verification", [
|
|
203
|
+
{ text: "unsatisfied" },
|
|
204
|
+
{ text: `(${verification.mode})` },
|
|
205
|
+
], columns);
|
|
206
|
+
if (result.verificationSummary !== undefined) {
|
|
207
|
+
receiptPayload(lines, " summary", result.verificationSummary);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return lines;
|
|
211
|
+
}
|
|
212
|
+
function movementLines(result, columns) {
|
|
213
|
+
const count = result.facts.filter((fact) => fact.kind === "reintegrated").length;
|
|
214
|
+
if (count === 0)
|
|
215
|
+
return [];
|
|
216
|
+
const lines = [];
|
|
217
|
+
receiptRow(lines, "~", "target", [{ text: `moved · re-integrated x${count}` }], columns);
|
|
218
|
+
return lines;
|
|
219
|
+
}
|
|
220
|
+
function continuationLines(result, columns) {
|
|
221
|
+
const report = result.continuation;
|
|
222
|
+
if (report === undefined)
|
|
223
|
+
return [];
|
|
224
|
+
const lines = [];
|
|
225
|
+
for (const contractId of report.claimed) {
|
|
226
|
+
receiptRow(lines, "✓", "continuation", [
|
|
227
|
+
{ text: "complete" },
|
|
228
|
+
{ text: contractId, opaque: true },
|
|
229
|
+
], columns);
|
|
230
|
+
}
|
|
231
|
+
for (const { contractId, stop } of report.stopped) {
|
|
232
|
+
const detail = "kind" in stop ? [{ text: stop.kind }] : stopSummary(stop, contractId);
|
|
233
|
+
receiptRow(lines, "!", "continuation", [
|
|
234
|
+
{ text: "blocked" },
|
|
235
|
+
{ text: contractId, opaque: true },
|
|
236
|
+
{ text: "·" },
|
|
237
|
+
...detail,
|
|
238
|
+
], columns);
|
|
239
|
+
}
|
|
184
240
|
return lines;
|
|
185
241
|
}
|
|
186
242
|
function renderAcceptedBind(result, columns) {
|
|
@@ -201,51 +257,19 @@ function renderAcceptedAmend(result, columns) {
|
|
|
201
257
|
lines.push(...acceptedDeviations(result, columns), ...recordBlock(result, columns));
|
|
202
258
|
return lines.join("\n");
|
|
203
259
|
}
|
|
204
|
-
function reintegrationLines(result, complete, columns) {
|
|
205
|
-
const reintegrated = result.facts.filter((fact) => fact.kind === "reintegrated");
|
|
206
|
-
if (reintegrated.length === 0)
|
|
207
|
-
return [];
|
|
208
|
-
const lines = [];
|
|
209
|
-
for (const fact of reintegrated) {
|
|
210
|
-
receiptRow(lines, " ", "re-integrated", [
|
|
211
|
-
{ text: fact.data.predecessor, opaque: true },
|
|
212
|
-
{ text: "->" },
|
|
213
|
-
{ text: fact.data.snapshot, opaque: true },
|
|
214
|
-
], columns);
|
|
215
|
-
}
|
|
216
|
-
if (result.verificationVerdict !== undefined) {
|
|
217
|
-
receiptRow(lines, " ", "verification re-run", [
|
|
218
|
-
{ text: "·" },
|
|
219
|
-
{ text: result.verificationVerdict },
|
|
220
|
-
], columns);
|
|
221
|
-
}
|
|
222
|
-
if (complete) {
|
|
223
|
-
receiptRow(lines, " ", "target", [
|
|
224
|
-
{ text: "->" },
|
|
225
|
-
{ text: reintegrated.at(-1).data.snapshot, opaque: true },
|
|
226
|
-
], columns);
|
|
227
|
-
}
|
|
228
|
-
return lines;
|
|
229
|
-
}
|
|
230
260
|
function renderAcceptedDeliver(result, columns) {
|
|
231
|
-
const complete = result.
|
|
261
|
+
const complete = result.completion !== undefined;
|
|
232
262
|
const title = complete ? "delivered" : "deliver — not complete";
|
|
233
263
|
const lines = titleLines("✓", title, result.contract, columns);
|
|
234
|
-
lines.push(...
|
|
264
|
+
lines.push(...movementLines(result, columns), ...completionLines(result, columns), ...continuationLines(result, columns));
|
|
235
265
|
if (!complete)
|
|
236
266
|
receiptRow(lines, " ", "candidate", [{ text: "kept" }], columns);
|
|
237
267
|
if (result.verification !== undefined) {
|
|
238
268
|
lines.push(...stopLines("verification", result.verification, columns, result.contract));
|
|
239
269
|
}
|
|
240
|
-
else if (result.verificationVerdict !== undefined) {
|
|
241
|
-
lines.push(...verificationVerdictLine(result.verificationVerdict, columns));
|
|
242
|
-
}
|
|
243
270
|
if (!complete && result.placement !== undefined) {
|
|
244
271
|
lines.push(...stopLines("completion", result.placement, columns, result.contract));
|
|
245
272
|
}
|
|
246
|
-
else if (!complete && (result.verification !== undefined || result.verificationVerdict === "unsatisfied")) {
|
|
247
|
-
receiptRow(lines, "·", "completion", [{ text: "not attempted" }], columns);
|
|
248
|
-
}
|
|
249
273
|
if (result.cleanup !== undefined)
|
|
250
274
|
pushBlock(lines, cleanupLines(result.cleanup, columns));
|
|
251
275
|
if (result.leak !== undefined)
|
|
@@ -254,12 +278,11 @@ function renderAcceptedDeliver(result, columns) {
|
|
|
254
278
|
return lines.join("\n");
|
|
255
279
|
}
|
|
256
280
|
function renderAcceptedReview(result, columns) {
|
|
257
|
-
const complete = result.
|
|
258
|
-
const lines = titleLines("✓", `review ${result.verdict}`, result.contract, columns);
|
|
259
|
-
lines.push(...
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
], columns);
|
|
281
|
+
const complete = result.completion !== undefined;
|
|
282
|
+
const lines = titleLines("✓", `review ${result.verdict} — ${complete ? "complete" : "not complete"}`, result.contract, columns);
|
|
283
|
+
lines.push(...movementLines(result, columns), ...completionLines(result, columns), ...continuationLines(result, columns));
|
|
284
|
+
if (!complete)
|
|
285
|
+
receiptRow(lines, " ", "candidate", [{ text: "kept" }], columns);
|
|
263
286
|
if (result.placement !== undefined) {
|
|
264
287
|
lines.push(...stopLines("completion", result.placement, columns, result.contract));
|
|
265
288
|
}
|