@astrosheep/keiyaku 2.8.5 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -15
- package/build/.tsbuildinfo +1 -1
- package/build/agents/{call-terms_v2.js → call-terms.js} +12 -8
- package/build/agents/harness/control-types.js +1 -0
- package/build/agents/harness/execution-handle.js +23 -3
- package/build/agents/harness/index.js +6 -607
- package/build/agents/harness/outcome.js +141 -0
- package/build/agents/harness/projection.js +310 -0
- package/build/agents/harness/router.js +201 -0
- package/build/agents/harness/runtime.js +2 -1
- package/build/agents/{launch-snapshot_v2.js → launch-snapshot/model.js} +69 -74
- package/build/agents/launch-snapshot/resolve.js +72 -0
- package/build/agents/opencode-sdk.js +24 -3
- package/build/agents/providers/{claude-agent-sdk.js → claude-agent-sdk/adapter.js} +46 -368
- package/build/agents/providers/claude-agent-sdk/events.js +218 -0
- package/build/agents/providers/claude-agent-sdk/session.js +158 -0
- package/build/agents/providers/codex-app-server/adapter.js +347 -0
- package/build/agents/providers/codex-app-server/events.js +352 -0
- package/build/agents/providers/codex-app-server/session.js +266 -0
- package/build/agents/providers/codex-sdk.js +23 -5
- package/build/agents/providers/opencode-sdk/adapter.js +344 -0
- package/build/agents/providers/opencode-sdk/events.js +354 -0
- package/build/agents/providers/opencode-sdk/session.js +180 -0
- package/build/agents/providers/pi/adapter.js +269 -0
- package/build/agents/providers/pi/checkpoint.js +41 -0
- package/build/agents/providers/pi/events.js +282 -0
- package/build/agents/{selector_v2.js → selector.js} +8 -6
- package/build/cli/commands/akuma/akuma/handler.js +4 -0
- package/build/cli/commands/akuma/akuma/meta.js +16 -0
- package/build/cli/commands/akuma/catalog.js +8 -0
- package/build/cli/commands/akuma/list/handler.js +15 -0
- package/build/cli/commands/akuma/list/meta-ls.js +9 -0
- package/build/cli/commands/akuma/view/handler.js +34 -0
- package/build/cli/commands/akuma/view/meta.js +8 -0
- package/build/cli/commands/akuma.js +1 -1
- package/build/cli/commands/contract/amend/handler.js +10 -0
- package/build/cli/commands/contract/amend/meta.js +12 -0
- package/build/cli/commands/contract/arc/handler.js +9 -0
- package/build/cli/commands/contract/arc/meta.js +26 -0
- package/build/cli/commands/contract/bind/handler.js +23 -0
- package/build/cli/commands/contract/bind/meta.js +30 -0
- package/build/cli/commands/contract/catalog.js +16 -0
- package/build/cli/commands/contract/forfeit/handler.js +13 -0
- package/build/cli/commands/contract/forfeit/meta.js +12 -0
- package/build/cli/commands/contract/log/handler.js +12 -0
- package/build/cli/commands/contract/log/meta.js +12 -0
- package/build/cli/commands/contract/petition/handler.js +26 -0
- package/build/cli/commands/contract/petition/meta.js +23 -0
- package/build/cli/commands/contract/renew/handler.js +10 -0
- package/build/cli/commands/contract/renew/meta.js +17 -0
- package/build/cli/commands/projection/call/handler.js +42 -0
- package/build/cli/commands/projection/call/meta.js +9 -0
- package/build/cli/commands/projection/catalog.js +14 -0
- package/build/cli/commands/projection/kill/handler.js +37 -0
- package/build/cli/commands/projection/kill/meta.js +11 -0
- package/build/cli/commands/projection/revive/handler.js +56 -0
- package/build/cli/commands/projection/revive/meta.js +9 -0
- package/build/cli/commands/projection/status/handler.js +25 -0
- package/build/cli/commands/projection/status/meta.js +9 -0
- package/build/cli/commands/projection/tell/handler.js +36 -0
- package/build/cli/commands/projection/tell/meta.js +9 -0
- package/build/cli/commands/projection/wait/handler.js +23 -0
- package/build/cli/commands/projection/wait/meta.js +11 -0
- package/build/cli/commands/registry.js +100 -0
- package/build/cli/commands/shared.js +71 -0
- package/build/cli/commands/skills/catalog.js +6 -0
- package/build/cli/commands/skills/install/handler.js +10 -0
- package/build/cli/commands/skills/install/meta.js +9 -0
- package/build/cli/commands/skills/skills/handler.js +4 -0
- package/build/cli/commands/skills/skills/meta.js +10 -0
- package/build/cli/commands/system/catalog.js +8 -0
- package/build/cli/commands/system/completion/handler.js +10 -0
- package/build/cli/commands/system/completion/meta.js +9 -0
- package/build/cli/commands/system/dump-env/handler.js +3 -0
- package/build/cli/commands/system/dump-env/meta.js +10 -0
- package/build/cli/commands/system/guide/handler.js +4 -0
- package/build/cli/commands/system/guide/meta.js +9 -0
- package/build/cli/commands/task/add/handler.js +21 -0
- package/build/cli/commands/task/add/meta.js +8 -0
- package/build/cli/commands/task/catalog.js +22 -0
- package/build/cli/commands/task/doctor/handler.js +4 -0
- package/build/cli/commands/task/doctor/meta.js +8 -0
- package/build/cli/commands/task/done/handler.js +17 -0
- package/build/cli/commands/task/done/meta.js +8 -0
- package/build/cli/commands/task/drop/handler.js +6 -0
- package/build/cli/commands/task/drop/meta.js +8 -0
- package/build/cli/commands/task/ls/handler.js +13 -0
- package/build/cli/commands/task/ls/meta.js +8 -0
- package/build/cli/commands/task/shared.js +131 -0
- package/build/cli/commands/task/start/handler.js +6 -0
- package/build/cli/commands/task/start/meta.js +8 -0
- package/build/cli/commands/task/stop/handler.js +17 -0
- package/build/cli/commands/task/stop/meta.js +8 -0
- package/build/cli/commands/task/task/handler.js +5 -0
- package/build/cli/commands/task/task/meta.js +11 -0
- package/build/cli/commands/task/update/handler.js +18 -0
- package/build/cli/commands/task/update/meta.js +8 -0
- package/build/cli/commands/task/view/handler.js +14 -0
- package/build/cli/commands/task/view/meta.js +8 -0
- package/build/cli/completion.js +26 -27
- package/build/cli/flags.js +79 -2
- package/build/cli/help.js +27 -49
- package/build/cli/index.js +121 -374
- package/build/cli/output-stream-error-policy.js +17 -0
- package/build/cli/parse-flags.js +197 -0
- package/build/cli/parse-metadata.js +129 -0
- package/build/cli/parse-selectors.js +65 -0
- package/build/cli/parse.js +46 -313
- package/build/cli/projection-address.js +5 -0
- package/build/cli/render/arc.js +1 -1
- package/build/cli/render/errors.js +4 -3
- package/build/cli/render/format.js +14 -0
- package/build/cli/render/kanshi.js +106 -0
- package/build/cli/render/petition.js +24 -1
- package/build/cli/render/projection-activity.js +5 -1
- package/build/cli/render/shared.js +2 -2
- package/build/cli/render/status.js +79 -13
- package/build/cli/render/task.js +113 -0
- package/build/cli/render/wait.js +23 -3
- package/build/cli/types.js +1 -1
- package/build/config/{akuma-loader_v2.js → akuma-loader.js} +7 -4
- package/build/config/env.js +9 -4
- package/build/config/settings/disease.js +26 -0
- package/build/config/settings/knobs.js +8 -0
- package/build/config/settings/loader.js +244 -0
- package/build/config/settings/schema.js +276 -0
- package/build/core/addressing.js +1 -1
- package/build/core/amend.js +5 -8
- package/build/core/arc.js +7 -8
- package/build/core/bind-workspace.js +123 -0
- package/build/core/bind.js +75 -155
- package/build/core/call/call.js +229 -0
- package/build/core/call/context.js +251 -0
- package/build/core/call/execution.js +217 -0
- package/build/core/call/prompt.js +42 -0
- package/build/core/call/reference.js +24 -0
- package/build/core/call-persist.js +10 -3
- package/build/core/claim-delivery.js +247 -0
- package/build/core/claim.js +39 -277
- package/build/core/context.js +2 -1
- package/build/core/{render.js → contract-view.js} +12 -140
- package/build/core/draft.js +107 -9
- package/build/core/entry.js +9 -1
- package/build/core/execution-coordinate.js +4 -20
- package/build/core/execution-pact.js +16 -31
- package/build/core/forfeit.js +35 -22
- package/build/core/hints.js +2 -2
- package/build/core/log.js +2 -2
- package/build/core/path-coordinate.js +27 -0
- package/build/core/petition-claim-gates.js +8 -6
- package/build/core/petition-preview.js +97 -0
- package/build/core/petition-run.js +5 -7
- package/build/core/petition.js +39 -26
- package/build/core/projection/generation/database.js +306 -0
- package/build/core/projection/generation/identity.js +84 -0
- package/build/core/projection/generation/model.js +201 -0
- package/build/core/projection/generation/store.js +73 -0
- package/build/core/projection/generation/transitions.js +258 -0
- package/build/core/projection/heart.js +0 -307
- package/build/core/projection/tell/database.js +109 -0
- package/build/core/projection/tell/model.js +97 -0
- package/build/core/{projection-tells.js → projection/tell/store.js} +3 -158
- package/build/core/projection-activity.js +23 -2
- package/build/core/projection-coordinate.js +14 -2
- package/build/core/projection-core.js +2 -1
- package/build/core/projection-execution-observer.js +259 -0
- package/build/core/projection-generation-continuation.js +1 -1
- package/build/core/projection-generation-execution.js +90 -20
- package/build/core/projection-generation-launcher.js +1 -1
- package/build/core/projection-generation-runner.js +198 -4
- package/build/core/projection-identity.js +1 -1
- package/build/core/projection-kill.js +50 -17
- package/build/core/projection-life-observer.js +1 -1
- package/build/core/projection-life-protocol.js +10 -0
- package/build/core/projection-mint.js +1 -1
- package/build/core/projection-status.js +45 -32
- package/build/core/projection-wait.js +12 -2
- package/build/core/projection-wake.js +5 -2
- package/build/core/{queue_v2.js → queue.js} +2 -1
- package/build/core/registry.js +1 -1
- package/build/core/renew.js +9 -11
- package/build/core/response-artifact-catalog-sqlite.js +112 -0
- package/build/core/response-artifact-catalog.js +7 -0
- package/build/core/seal.js +44 -16
- package/build/core/status/board.js +289 -0
- package/build/core/status/drift.js +99 -0
- package/build/core/status/lifecycle.js +84 -0
- package/build/core/status/reconciliation.js +131 -0
- package/build/core/stored-agent-event.js +28 -4
- package/build/core/target-ref.js +10 -0
- package/build/core/task/board.js +175 -0
- package/build/core/task/commands.js +211 -0
- package/build/core/task/document.js +189 -0
- package/build/core/task/model.js +1 -0
- package/build/core/task/settlement-git.js +207 -0
- package/build/core/task/settlement-policy.js +82 -0
- package/build/core/task/source-board.js +84 -0
- package/build/core/task/source-model.js +1 -0
- package/build/core/task/validation.js +44 -0
- package/build/core/task-contract.js +237 -0
- package/build/core/task-doctor.js +14 -0
- package/build/core/task-git-actor.js +38 -0
- package/build/core/task-git-runtime.js +37 -0
- package/build/core/task-git-store.js +385 -0
- package/build/core/task-repository.js +1 -0
- package/build/core/task-store-repository.js +86 -0
- package/build/core/task-store.js +1 -0
- package/build/core/task-worktree.js +51 -0
- package/build/core/task.js +4 -0
- package/build/core/transcripts.js +138 -56
- package/build/core/validation.js +17 -0
- package/build/core/verdict.js +2 -2
- package/build/core/worktree-path.js +33 -8
- package/build/flow-error.js +5 -2
- package/build/generated/version.js +1 -1
- package/build/git/branches.js +33 -9
- package/build/git/commits.js +3 -0
- package/build/git/core.js +9 -0
- package/build/git/diff/parsers.js +0 -94
- package/build/index.js +2 -0
- package/build/keiyaku-constants.js +2 -0
- package/build/keiyaku.js +4 -3
- package/package.json +3 -2
- package/skills/keiyaku/SKILL.md +30 -13
- package/skills/keiyaku-akuma/SKILL.md +30 -57
- package/skills/keiyaku-task/SKILL.md +51 -0
- package/skills/keiyaku-workflow/SKILL.md +71 -0
- package/build/agents/harness/pump.js +0 -158
- package/build/agents/providers/codex-app-server.js +0 -864
- package/build/agents/providers/opencode-sdk.js +0 -363
- package/build/agents/providers/pi.js +0 -557
- package/build/config/settings.js +0 -533
- package/build/core/call.js +0 -686
- package/build/core/projection/generation.js +0 -412
- package/build/core/projection/identity.js +0 -81
- package/build/core/projection/mint.js +0 -174
- package/build/core/projection-generation-store.js +0 -707
- package/build/core/status.js +0 -539
package/build/cli/parse.js
CHANGED
|
@@ -1,276 +1,11 @@
|
|
|
1
1
|
import { FlowError } from "../flow-error.js";
|
|
2
|
-
import { agentNameSchema } from "../config/settings.js";
|
|
2
|
+
import { agentNameSchema } from "../config/settings/schema.js";
|
|
3
3
|
import { isResponseArtifactId } from "../core/response-artifact-id.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"call",
|
|
10
|
-
"wait",
|
|
11
|
-
"tell",
|
|
12
|
-
"kill",
|
|
13
|
-
"log",
|
|
14
|
-
"renew",
|
|
15
|
-
"petition",
|
|
16
|
-
"forfeit",
|
|
17
|
-
]);
|
|
18
|
-
const CLI_COMMAND_ORDER = [
|
|
19
|
-
"bind",
|
|
20
|
-
"arc",
|
|
21
|
-
"call",
|
|
22
|
-
"revive",
|
|
23
|
-
"wait",
|
|
24
|
-
"tell",
|
|
25
|
-
"kill",
|
|
26
|
-
"log",
|
|
27
|
-
"akuma list",
|
|
28
|
-
"akuma ls",
|
|
29
|
-
"akuma show",
|
|
30
|
-
"skills install",
|
|
31
|
-
"skills",
|
|
32
|
-
"akuma",
|
|
33
|
-
"amend",
|
|
34
|
-
"renew",
|
|
35
|
-
"forfeit",
|
|
36
|
-
"petition",
|
|
37
|
-
"guide",
|
|
38
|
-
"completion",
|
|
39
|
-
"status",
|
|
40
|
-
"dump-env",
|
|
41
|
-
];
|
|
42
|
-
const COMMAND_FLAGS = {
|
|
43
|
-
// contract is parseable on bind only so the mouth can reject it with bind-specific copy.
|
|
44
|
-
bind: ["cwd", "repo", "contract", "after", "exclusive", "draft-only"],
|
|
45
|
-
arc: ["cwd", "repo", "contract", "waive"],
|
|
46
|
-
call: ["cwd", "repo", "contract", "akuma", "model", "effort", "incognito", "bare", "detach", "alias"],
|
|
47
|
-
revive: ["cwd", "repo", "model", "effort"],
|
|
48
|
-
wait: ["cwd", "repo", "contract", "timeout"],
|
|
49
|
-
tell: ["cwd", "repo", "contract", "effort"],
|
|
50
|
-
kill: ["cwd", "repo", "contract"],
|
|
51
|
-
log: ["cwd", "repo", "contract"],
|
|
52
|
-
akuma: [],
|
|
53
|
-
"akuma ls": ["cwd", "repo"],
|
|
54
|
-
"akuma list": ["cwd", "repo"],
|
|
55
|
-
"akuma show": ["cwd", "repo"],
|
|
56
|
-
skills: [],
|
|
57
|
-
"skills install": ["force"],
|
|
58
|
-
amend: ["cwd", "repo", "contract"],
|
|
59
|
-
renew: ["cwd", "repo", "contract", "waive"],
|
|
60
|
-
petition: ["cwd", "repo", "contract", "waive"],
|
|
61
|
-
forfeit: ["cwd", "repo", "contract", "reason"],
|
|
62
|
-
guide: [],
|
|
63
|
-
completion: ["cwd", "repo", "shell", "word", "previous", "complete"],
|
|
64
|
-
status: ["cwd", "repo", "target", "all"],
|
|
65
|
-
"dump-env": [],
|
|
66
|
-
};
|
|
67
|
-
const STDIN_COMMANDS = new Set(["bind", "arc", "amend"]);
|
|
68
|
-
export function normalizeContractAddress(raw) {
|
|
69
|
-
const value = raw.startsWith("@") ? raw.slice(1) : raw;
|
|
70
|
-
if (!value.trim()) {
|
|
71
|
-
throw new FlowError("EMPTY_PARAM", "contract address cannot be empty");
|
|
72
|
-
}
|
|
73
|
-
return value.trim();
|
|
74
|
-
}
|
|
75
|
-
export function isCallCommand(command) {
|
|
76
|
-
return command === "call";
|
|
77
|
-
}
|
|
78
|
-
export function commandUsesPromptInput(command) {
|
|
79
|
-
return isCallCommand(command) || command === "revive";
|
|
80
|
-
}
|
|
81
|
-
export function parseWaitTimeout(value) {
|
|
82
|
-
const matched = /^(?<amount>[1-9][0-9]*)(?<unit>[smh])$/.exec(value);
|
|
83
|
-
if (!matched?.groups) {
|
|
84
|
-
throw new FlowError("EMPTY_PARAM", "wait timeout must use <positive integer><s|m|h>, for example 45s, 5m, or 2h (maximum 24h)");
|
|
85
|
-
}
|
|
86
|
-
const amount = Number(matched.groups.amount);
|
|
87
|
-
const multiplier = matched.groups.unit === "s" ? 1_000 : matched.groups.unit === "m" ? 60_000 : 3_600_000;
|
|
88
|
-
const timeoutMs = amount * multiplier;
|
|
89
|
-
if (!Number.isSafeInteger(timeoutMs) || timeoutMs > 24 * 3_600_000) {
|
|
90
|
-
throw new FlowError("EMPTY_PARAM", "wait timeout must use <positive integer><s|m|h>, for example 45s, 5m, or 2h (maximum 24h)");
|
|
91
|
-
}
|
|
92
|
-
return timeoutMs;
|
|
93
|
-
}
|
|
94
|
-
export function commandPositionalRange(command) {
|
|
95
|
-
if (command === "akuma show")
|
|
96
|
-
return { min: 1, max: 1, label: "<name>" };
|
|
97
|
-
if (command === "log")
|
|
98
|
-
return { min: 0, max: 0, label: "" };
|
|
99
|
-
if (command === "revive")
|
|
100
|
-
return { min: 1, max: 1, label: "<artifact-id>" };
|
|
101
|
-
if (command === "wait")
|
|
102
|
-
return { min: 1, max: 1, label: "<projection-address>" };
|
|
103
|
-
if (command === "tell")
|
|
104
|
-
return { min: 2, max: 2, label: "<projection> <message>" };
|
|
105
|
-
if (command === "kill")
|
|
106
|
-
return { min: 1, max: 1, label: "<projection-address>" };
|
|
107
|
-
if (isCallCommand(command))
|
|
108
|
-
return { min: 0, max: 1 };
|
|
109
|
-
return { min: 0, max: 0 };
|
|
110
|
-
}
|
|
111
|
-
function commandRequiresStdin(command) {
|
|
112
|
-
return STDIN_COMMANDS.has(command);
|
|
113
|
-
}
|
|
114
|
-
function commandTokens(command) {
|
|
115
|
-
return command.split(" ");
|
|
116
|
-
}
|
|
117
|
-
function parseFlagName(raw) {
|
|
118
|
-
return raw.slice(2);
|
|
119
|
-
}
|
|
120
|
-
function assignFlag(flags, name, value) {
|
|
121
|
-
switch (name) {
|
|
122
|
-
case "cwd":
|
|
123
|
-
flags.cwd = String(value);
|
|
124
|
-
return;
|
|
125
|
-
case "repo":
|
|
126
|
-
flags.repo = String(value);
|
|
127
|
-
return;
|
|
128
|
-
case "contract":
|
|
129
|
-
flags.contractId = normalizeContractAddress(String(value));
|
|
130
|
-
flags.contractAddressSource = "explicit-flag";
|
|
131
|
-
return;
|
|
132
|
-
case "akuma":
|
|
133
|
-
flags.akuma = String(value);
|
|
134
|
-
return;
|
|
135
|
-
case "projection":
|
|
136
|
-
flags.projection = String(value);
|
|
137
|
-
return;
|
|
138
|
-
case "alias":
|
|
139
|
-
flags.alias = String(value);
|
|
140
|
-
return;
|
|
141
|
-
case "timeout":
|
|
142
|
-
flags.timeoutMs = parseWaitTimeout(String(value));
|
|
143
|
-
return;
|
|
144
|
-
case "model":
|
|
145
|
-
flags.model = String(value);
|
|
146
|
-
return;
|
|
147
|
-
case "effort": {
|
|
148
|
-
const effort = String(value);
|
|
149
|
-
flags.effort = effort;
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
case "incognito":
|
|
153
|
-
flags.incognito = Boolean(value);
|
|
154
|
-
return;
|
|
155
|
-
case "bare":
|
|
156
|
-
flags.bare = Boolean(value);
|
|
157
|
-
return;
|
|
158
|
-
case "detach":
|
|
159
|
-
flags.detach = Boolean(value);
|
|
160
|
-
return;
|
|
161
|
-
case "draft-only":
|
|
162
|
-
flags.draftOnly = Boolean(value);
|
|
163
|
-
return;
|
|
164
|
-
case "exclusive":
|
|
165
|
-
flags.exclusive = Boolean(value);
|
|
166
|
-
return;
|
|
167
|
-
case "after":
|
|
168
|
-
flags.after = [...(flags.after ?? []), String(value)];
|
|
169
|
-
return;
|
|
170
|
-
case "force":
|
|
171
|
-
flags.force = Boolean(value);
|
|
172
|
-
return;
|
|
173
|
-
case "reason":
|
|
174
|
-
flags.reason = String(value);
|
|
175
|
-
return;
|
|
176
|
-
case "dry-run":
|
|
177
|
-
flags.dryRun = Boolean(value);
|
|
178
|
-
return;
|
|
179
|
-
case "waive":
|
|
180
|
-
flags.waivePaths = [...(flags.waivePaths ?? []), String(value)];
|
|
181
|
-
return;
|
|
182
|
-
case "shell":
|
|
183
|
-
flags.shell = String(value);
|
|
184
|
-
return;
|
|
185
|
-
case "word":
|
|
186
|
-
flags.word = String(value);
|
|
187
|
-
return;
|
|
188
|
-
case "previous":
|
|
189
|
-
flags.previous = String(value);
|
|
190
|
-
return;
|
|
191
|
-
case "complete":
|
|
192
|
-
flags.complete = Boolean(value);
|
|
193
|
-
return;
|
|
194
|
-
case "all":
|
|
195
|
-
flags.all = Boolean(value);
|
|
196
|
-
return;
|
|
197
|
-
case "target":
|
|
198
|
-
if (flags.target !== undefined) {
|
|
199
|
-
throw new FlowError("EMPTY_PARAM", "option --target may only be specified once");
|
|
200
|
-
}
|
|
201
|
-
flags.target = String(value);
|
|
202
|
-
return;
|
|
203
|
-
default:
|
|
204
|
-
throw new FlowError("EMPTY_PARAM", `unknown option: --${name}`);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
function assertAllowedFlag(command, name) {
|
|
208
|
-
if (!COMMAND_FLAGS[command].includes(name)) {
|
|
209
|
-
throw new FlowError("EMPTY_PARAM", `option --${name} is not valid for ${command}`);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
function resolveCommand(tokens) {
|
|
213
|
-
if (tokens[0] === "petition" && (tokens[1] === "claim" || tokens[1] === "forfeit")) {
|
|
214
|
-
throw new FlowError("UNKNOWN_COMMAND", `unknown command: petition ${tokens[1]}`);
|
|
215
|
-
}
|
|
216
|
-
for (const command of CLI_COMMAND_ORDER) {
|
|
217
|
-
const parts = commandTokens(command);
|
|
218
|
-
if (parts.every((part, index) => tokens[index] === part)) {
|
|
219
|
-
return { command, rest: tokens.slice(parts.length) };
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
const [head] = tokens;
|
|
223
|
-
if (head === "skills") {
|
|
224
|
-
return { command: "skills", rest: tokens.slice(1) };
|
|
225
|
-
}
|
|
226
|
-
if (!head)
|
|
227
|
-
throw new FlowError("EMPTY_PARAM", "command cannot be empty");
|
|
228
|
-
throw new FlowError("UNKNOWN_COMMAND", `unknown command: ${head ?? ""}`.trim());
|
|
229
|
-
}
|
|
230
|
-
function splitAtLiteralBoundary(tokens) {
|
|
231
|
-
const boundary = tokens.indexOf("--");
|
|
232
|
-
if (boundary === -1)
|
|
233
|
-
return { head: tokens, payload: [] };
|
|
234
|
-
return { head: tokens.slice(0, boundary), payload: tokens.slice(boundary + 1) };
|
|
235
|
-
}
|
|
236
|
-
function readValueFlag(name, token, eq, tokens, index) {
|
|
237
|
-
// --target alone owns emptiness in core; empty remains a supplied value.
|
|
238
|
-
// Other value flags keep the historical requires-a-value rejection.
|
|
239
|
-
if (eq !== -1) {
|
|
240
|
-
const value = token.slice(eq + 1);
|
|
241
|
-
if (value === "" && name !== "target") {
|
|
242
|
-
throw new FlowError("EMPTY_PARAM", `option --${name} requires a value`);
|
|
243
|
-
}
|
|
244
|
-
return { value, nextIndex: index };
|
|
245
|
-
}
|
|
246
|
-
const value = tokens[index + 1];
|
|
247
|
-
if (value === undefined || value === "--" || value.startsWith("--")) {
|
|
248
|
-
throw new FlowError("EMPTY_PARAM", `option --${name} requires a value`);
|
|
249
|
-
}
|
|
250
|
-
if (value === "" && name !== "target") {
|
|
251
|
-
throw new FlowError("EMPTY_PARAM", `option --${name} requires a value`);
|
|
252
|
-
}
|
|
253
|
-
// Short-flag values may begin with @; they are flag values, not commission tokens.
|
|
254
|
-
return { value, nextIndex: index + 1 };
|
|
255
|
-
}
|
|
256
|
-
function commissionConflictMessage(atForm, contractForm) {
|
|
257
|
-
return `commission address supplied twice: ${atForm} and --contract ${contractForm}; use exactly one form`;
|
|
258
|
-
}
|
|
259
|
-
function formatSelectorList(items) {
|
|
260
|
-
if (items.length <= 1)
|
|
261
|
-
return items[0] ?? "";
|
|
262
|
-
if (items.length === 2)
|
|
263
|
-
return `${items[0]} and ${items[1]}`;
|
|
264
|
-
return `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
|
|
265
|
-
}
|
|
266
|
-
function multiCommissionSelectorMessage(command, spellings) {
|
|
267
|
-
return `${command} accepts one commission address; got ${formatSelectorList(spellings)}`;
|
|
268
|
-
}
|
|
269
|
-
function commissionSelectorSpelling(source, value, rawToken) {
|
|
270
|
-
if (source === "at-address")
|
|
271
|
-
return rawToken ?? `@${value}`;
|
|
272
|
-
return `--contract ${rawToken ?? value}`;
|
|
273
|
-
}
|
|
4
|
+
import { HELP_FLAGS } from "./flags.js";
|
|
5
|
+
import { assertAllowedFlag, assignFlag, BOOLEAN_FLAGS, CONTROL_FLAGS, parseFlagName, readValueFlag, SHORT_FLAG_ALIASES, VALUE_FLAGS, } from "./parse-flags.js";
|
|
6
|
+
import { commandPositionalRange, commandRequiresStdin, isCallCommand, resolveCommand, splitAtLiteralBoundary, TASK_SUBCOMMANDS, } from "./parse-metadata.js";
|
|
7
|
+
import { applyCommissionSelector, assertCommissionSelectorAllowed, assertProjectionSelectorPresent, } from "./parse-selectors.js";
|
|
8
|
+
export { commandPositionalRange, commandUsesPromptInput, isCallCommand, isPetitionDryRunInvocation, normalizeContractAddress, parseWaitTimeout, } from "./parse-metadata.js";
|
|
274
9
|
export function parseCliArgs(tokens) {
|
|
275
10
|
const { head, payload } = splitAtLiteralBoundary(tokens);
|
|
276
11
|
const flags = {};
|
|
@@ -322,9 +57,6 @@ export function parseCliArgs(tokens) {
|
|
|
322
57
|
}
|
|
323
58
|
const eq = token.indexOf("=");
|
|
324
59
|
const name = parseFlagName(eq === -1 ? token : token.slice(0, eq));
|
|
325
|
-
if (name === "place") {
|
|
326
|
-
throw new FlowError("EMPTY_PARAM", "unknown option --place; use @addr or --contract <addr>");
|
|
327
|
-
}
|
|
328
60
|
if (!CONTROL_FLAGS.has(name)) {
|
|
329
61
|
throw new FlowError("EMPTY_PARAM", `unknown option: --${name}`);
|
|
330
62
|
}
|
|
@@ -348,81 +80,82 @@ export function parseCliArgs(tokens) {
|
|
|
348
80
|
}
|
|
349
81
|
}
|
|
350
82
|
const { command, rest } = resolveCommand(free);
|
|
351
|
-
|
|
352
|
-
throw new FlowError("EMPTY_PARAM", commissionConflictMessage(atTokens[0], contractFlagRaws[0]));
|
|
353
|
-
}
|
|
354
|
-
if (atTokens.length > 1) {
|
|
355
|
-
throw new FlowError("EMPTY_PARAM", multiCommissionSelectorMessage(command, atTokens));
|
|
356
|
-
}
|
|
357
|
-
if (contractFlagRaws.length > 1) {
|
|
358
|
-
throw new FlowError("EMPTY_PARAM", multiCommissionSelectorMessage(command, contractFlagRaws.map((raw) => `--contract ${raw}`)));
|
|
359
|
-
}
|
|
360
|
-
if (atTokens.length === 1) {
|
|
361
|
-
flags.contractId = normalizeContractAddress(atTokens[0]);
|
|
362
|
-
flags.contractAddressSource = "at-address";
|
|
363
|
-
}
|
|
364
|
-
else if (contractFlagRaws.length === 1) {
|
|
365
|
-
assignFlag(flags, "contract", contractFlagRaws[0]);
|
|
366
|
-
}
|
|
83
|
+
applyCommissionSelector(command, flags, atTokens, contractFlagRaws);
|
|
367
84
|
if (helpRequested) {
|
|
368
85
|
return {
|
|
369
86
|
command,
|
|
370
|
-
flags: flags.contractId
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
87
|
+
flags: flags.contractId
|
|
88
|
+
? {
|
|
89
|
+
contractId: flags.contractId,
|
|
90
|
+
contractAddressSource: flags.contractAddressSource,
|
|
91
|
+
...(flags.cwd ? { cwd: flags.cwd } : {}),
|
|
92
|
+
...(flags.repo ? { repo: flags.repo } : {}),
|
|
93
|
+
}
|
|
94
|
+
: {
|
|
95
|
+
...(flags.cwd ? { cwd: flags.cwd } : {}),
|
|
96
|
+
...(flags.repo ? { repo: flags.repo } : {}),
|
|
97
|
+
},
|
|
374
98
|
positional: [],
|
|
375
99
|
helpRequested: true,
|
|
376
100
|
};
|
|
377
101
|
}
|
|
378
102
|
if (command === "akuma") {
|
|
379
|
-
throw new FlowError("EMPTY_PARAM", "akuma requires subcommand:
|
|
103
|
+
throw new FlowError("EMPTY_PARAM", "akuma requires subcommand: ls or view");
|
|
380
104
|
}
|
|
381
105
|
if (command === "skills") {
|
|
382
106
|
throw new FlowError("EMPTY_PARAM", "skills requires subcommand: install");
|
|
383
107
|
}
|
|
108
|
+
if (command === "task") {
|
|
109
|
+
throw new FlowError("EMPTY_PARAM", `task requires subcommand: ${TASK_SUBCOMMANDS.join(", ")}`);
|
|
110
|
+
}
|
|
111
|
+
if (command !== "bind" && seenFlagNames.has("place")) {
|
|
112
|
+
throw new FlowError("EMPTY_PARAM", "unknown option --place; use @addr or --contract <addr>");
|
|
113
|
+
}
|
|
384
114
|
for (const name of seenFlagNames) {
|
|
385
115
|
assertAllowedFlag(command, name);
|
|
386
116
|
}
|
|
387
|
-
if (flags.
|
|
388
|
-
throw new FlowError("EMPTY_PARAM",
|
|
389
|
-
? `bind creates a commission and does not accept @${flags.contractId}; use -C/--cwd to select the repository`
|
|
390
|
-
: `contract address @${flags.contractId} is not valid for ${command}`);
|
|
117
|
+
if (command === "call" && flags.detach && flags.timeoutMs !== undefined) {
|
|
118
|
+
throw new FlowError("EMPTY_PARAM", "call cannot combine --detach and --wait");
|
|
391
119
|
}
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
120
|
+
if (command === "task ls" && flags.all && flags.done) {
|
|
121
|
+
throw new FlowError("EMPTY_PARAM", "task ls cannot combine --all and --done");
|
|
122
|
+
}
|
|
123
|
+
if (command === "task update" && flags.taskParent !== undefined && flags.taskNoParent) {
|
|
124
|
+
throw new FlowError("EMPTY_PARAM", "task update cannot combine --parent and --no-parent");
|
|
125
|
+
}
|
|
126
|
+
if (command === "task update" && flags.taskTitle === undefined && flags.taskBody === undefined
|
|
127
|
+
&& flags.taskPri === undefined && flags.taskNeeds === undefined && flags.taskDropNeeds === undefined
|
|
128
|
+
&& flags.taskParent === undefined && !flags.taskNoParent && flags.taskFrom === undefined) {
|
|
129
|
+
throw new FlowError("EMPTY_PARAM", "task update requires at least one change");
|
|
130
|
+
}
|
|
131
|
+
if (command === "petition" && flags.json && !flags.dryRun) {
|
|
132
|
+
throw new FlowError("EMPTY_PARAM", "petition --json requires --dry-run");
|
|
402
133
|
}
|
|
134
|
+
assertCommissionSelectorAllowed(command, flags);
|
|
135
|
+
assertProjectionSelectorPresent(command, flags, atTokens, contractFlagRaws, rest.length, payload.length);
|
|
403
136
|
const positional = [...rest, ...payload];
|
|
404
137
|
if (isCallCommand(command)) {
|
|
405
138
|
if (flags.akuma) {
|
|
406
139
|
if (positional.length > 1) {
|
|
407
|
-
throw new FlowError("EMPTY_PARAM", `${command} accepts at most one
|
|
140
|
+
throw new FlowError("EMPTY_PARAM", `${command} accepts at most one <BODY|-> when --akuma is used`);
|
|
408
141
|
}
|
|
409
142
|
}
|
|
410
143
|
else {
|
|
411
144
|
const [name] = positional;
|
|
412
145
|
if (!name) {
|
|
413
|
-
throw new FlowError("EMPTY_PARAM", `${command} requires an agent name; use \`keiyaku ${command} NAME
|
|
146
|
+
throw new FlowError("EMPTY_PARAM", `${command} requires an agent name; use \`keiyaku ${command} NAME <BODY|->\``);
|
|
414
147
|
}
|
|
415
148
|
if (isResponseArtifactId(name)) {
|
|
416
149
|
throw new FlowError("EMPTY_PARAM", `artifact ${name} is a response artifact; call expects an Akuma profile name`);
|
|
417
150
|
}
|
|
418
151
|
const parsedName = agentNameSchema.safeParse(name);
|
|
419
152
|
if (!parsedName.success) {
|
|
420
|
-
throw new FlowError("EMPTY_PARAM", `${command} requires a valid agent name before
|
|
153
|
+
throw new FlowError("EMPTY_PARAM", `${command} requires a valid agent name before <BODY|->`);
|
|
421
154
|
}
|
|
422
155
|
flags.akuma = parsedName.data;
|
|
423
156
|
positional.shift();
|
|
424
157
|
if (positional.length > 1) {
|
|
425
|
-
throw new FlowError("EMPTY_PARAM", `${command} accepts at most one
|
|
158
|
+
throw new FlowError("EMPTY_PARAM", `${command} accepts at most one <BODY|-> after the agent name`);
|
|
426
159
|
}
|
|
427
160
|
}
|
|
428
161
|
}
|
|
@@ -5,6 +5,7 @@ import { resolveProjectionCoordinate } from "../core/projection-coordinate.js";
|
|
|
5
5
|
import { isProjectionId, projectionDir } from "../core/projection-core.js";
|
|
6
6
|
import { isProjectionAlias, readProjectionAlias } from "../core/projection-alias.js";
|
|
7
7
|
import { readProjectionIdentity } from "../core/projection-identity.js";
|
|
8
|
+
import { isProjectionGenerationSchemaV1Residue } from "../core/projection/generation/store.js";
|
|
8
9
|
import { isResponseArtifactId } from "../core/response-artifact-id.js";
|
|
9
10
|
import { isErrnoException } from "../errno.js";
|
|
10
11
|
function isRealDirectory(directory) {
|
|
@@ -80,6 +81,10 @@ export async function resolveProjectionAddress(input) {
|
|
|
80
81
|
const subject = alias ? `projection alias ${alias} points to missing projection ${id}` : `projection ${id}`;
|
|
81
82
|
throw new AddressResolutionError("EMPTY_PARAM", `${subject} has no match ${suffix}`, attempt);
|
|
82
83
|
}
|
|
84
|
+
if (isProjectionGenerationSchemaV1Residue(directory)) {
|
|
85
|
+
const subject = alias ? `projection alias ${alias} points to missing projection ${id}` : `projection ${id}`;
|
|
86
|
+
throw new AddressResolutionError("EMPTY_PARAM", `${subject} has no match ${suffix}`, attempt);
|
|
87
|
+
}
|
|
83
88
|
let identity;
|
|
84
89
|
try {
|
|
85
90
|
identity = readProjectionIdentity(directory);
|
package/build/cli/render/arc.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { shortCommitHash } from "../../
|
|
1
|
+
import { shortCommitHash } from "../../git/commits.js";
|
|
2
2
|
import { assembleResponse, buildPayload, buildSection, formatHints, formatList, formatMaybe, formatWarnings, } from "./format.js";
|
|
3
3
|
import { DIFF_OVERVIEW_SECTION_TITLE, RESPONSE_MARKERS, WARNING_SECTION_TITLE } from "./response-style.js";
|
|
4
4
|
import { appendPersistenceSummary, BRANCH_LABEL, CONTENT_SECTION_TITLE, HINTS_LIST_MAX_ITEMS, HINTS_SECTION_TITLE, INFO_BRANCH_MAX_CHARS, INFO_COMMIT_MAX_CHARS, INFO_PLEA_MAX_CHARS, INFO_SECTION_TITLE, } from "./shared.js";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { asMessage, isFlowError, pickHintsFromError } from "../../flow-error.js";
|
|
2
|
-
import { assertSettingsKnobUsable
|
|
3
|
-
import {
|
|
2
|
+
import { assertSettingsKnobUsable } from "../../config/settings/disease.js";
|
|
3
|
+
import { loadKeiyakuSettings } from "../../config/settings/loader.js";
|
|
4
|
+
import { loadAkumaCatalog } from "../../config/akuma-loader.js";
|
|
4
5
|
import { appendDebugLog } from "../../telemetry/debug-log.js";
|
|
5
6
|
import { ACTOR_IDENTITY, TOOL_NAMES, BUILTIN_AGENT_NAMES } from "../../keiyaku.js";
|
|
6
7
|
import { buildErrorResponse } from "./misc.js";
|
|
@@ -18,7 +19,7 @@ async function getAvailableActorNames(cwd, fallback) {
|
|
|
18
19
|
try {
|
|
19
20
|
const loaded = await loadKeiyakuSettings(cwd);
|
|
20
21
|
assertSettingsKnobUsable(loaded, "agents");
|
|
21
|
-
return Object.keys((await
|
|
22
|
+
return Object.keys((await loadAkumaCatalog(cwd)).selected);
|
|
22
23
|
}
|
|
23
24
|
catch {
|
|
24
25
|
return [...fallback];
|
|
@@ -6,6 +6,20 @@ export function shellQuote(value) {
|
|
|
6
6
|
return value;
|
|
7
7
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
8
8
|
}
|
|
9
|
+
export function formatAgeMs(ms) {
|
|
10
|
+
if (ms === undefined)
|
|
11
|
+
return undefined;
|
|
12
|
+
const seconds = Math.max(0, Math.floor(ms / 1_000));
|
|
13
|
+
if (seconds < 60)
|
|
14
|
+
return `${seconds}s`;
|
|
15
|
+
const minutes = Math.floor(seconds / 60);
|
|
16
|
+
if (minutes < 60)
|
|
17
|
+
return `${minutes}m`;
|
|
18
|
+
const hours = Math.floor(minutes / 60);
|
|
19
|
+
if (hours < 24)
|
|
20
|
+
return `${hours}h`;
|
|
21
|
+
return `${Math.floor(hours / 24)}d`;
|
|
22
|
+
}
|
|
9
23
|
export const DISPLAY_TEXT_MAX_CHARS = 5000;
|
|
10
24
|
export const FORMAT_MAYBE_MAX_CHARS = 1200;
|
|
11
25
|
export const FORMAT_LIST_MAX_ITEMS = 20;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { formatAgeMs } from "./format.js";
|
|
2
|
+
function shortHead(hash) {
|
|
3
|
+
if (!hash)
|
|
4
|
+
return "????????";
|
|
5
|
+
return hash.slice(0, 7);
|
|
6
|
+
}
|
|
7
|
+
function compactWhitespace(value) {
|
|
8
|
+
return value.replace(/\s+/g, " ").trim();
|
|
9
|
+
}
|
|
10
|
+
function arcSparkline(arcs) {
|
|
11
|
+
if (arcs <= 0)
|
|
12
|
+
return "";
|
|
13
|
+
return Array.from({ length: arcs }, () => "·").join("──");
|
|
14
|
+
}
|
|
15
|
+
function pendingAfterIds(contract) {
|
|
16
|
+
return contract.after.filter((item) => !item.terminal).map((item) => item.id);
|
|
17
|
+
}
|
|
18
|
+
function kanshiGlyph(contract) {
|
|
19
|
+
if (contract.state.state === "corrupt")
|
|
20
|
+
return "×";
|
|
21
|
+
if (pendingAfterIds(contract).length > 0)
|
|
22
|
+
return "○";
|
|
23
|
+
if (contract.state.state === "petitioned")
|
|
24
|
+
return "◎";
|
|
25
|
+
return "●";
|
|
26
|
+
}
|
|
27
|
+
function renderDriftMark(drift) {
|
|
28
|
+
if (drift.state === "drift")
|
|
29
|
+
return `▲${drift.behindBy}`;
|
|
30
|
+
if (drift.state === "orphaned")
|
|
31
|
+
return "▲orphaned";
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
export function renderKanshiBoard(status) {
|
|
35
|
+
const head = shortHead(status.defaultHead);
|
|
36
|
+
if (status.contracts.length === 0) {
|
|
37
|
+
if (status.targetFilter !== null) {
|
|
38
|
+
return `現世 ${head} · target ${status.targetFilter}\nno commissions on target ${status.targetFilter}\n`;
|
|
39
|
+
}
|
|
40
|
+
return `現世 ${head} 无在飞契约\n`;
|
|
41
|
+
}
|
|
42
|
+
const header = status.targetFilter !== null
|
|
43
|
+
? `現世 ${head} · target ${status.targetFilter}`
|
|
44
|
+
: `現世 ${head}`;
|
|
45
|
+
const lines = [header, ""];
|
|
46
|
+
for (const contract of status.contracts) {
|
|
47
|
+
const glyph = kanshiGlyph(contract);
|
|
48
|
+
const name = contract.slug;
|
|
49
|
+
const spark = arcSparkline(contract.arcs);
|
|
50
|
+
const facts = [];
|
|
51
|
+
const lifecycle = contract.state.state;
|
|
52
|
+
if (lifecycle === "bound" || lifecycle === "active" || lifecycle === "petitioned") {
|
|
53
|
+
facts.push(lifecycle);
|
|
54
|
+
}
|
|
55
|
+
if (contract.place) {
|
|
56
|
+
facts.push(`@${contract.place}`);
|
|
57
|
+
}
|
|
58
|
+
const arcObjective = compactWhitespace(contract.currentArc.objective || "(no arc objective)");
|
|
59
|
+
const arcMark = contract.currentArc.state === "open"
|
|
60
|
+
? `a${contract.currentArc.number}+`
|
|
61
|
+
: `a${contract.currentArc.number}`;
|
|
62
|
+
facts.push(`${arcMark} ${arcObjective}`);
|
|
63
|
+
facts.push(`next ${contract.nextStep.detail}`);
|
|
64
|
+
const age = formatAgeMs(contract.lastActiveMs);
|
|
65
|
+
if (age)
|
|
66
|
+
facts.push(age);
|
|
67
|
+
if (contract.queuePosition)
|
|
68
|
+
facts.push(`Q${contract.queuePosition}`);
|
|
69
|
+
const drift = renderDriftMark(contract.baseDrift);
|
|
70
|
+
if (drift)
|
|
71
|
+
facts.push(drift);
|
|
72
|
+
if (contract.nextStep.hint)
|
|
73
|
+
facts.push(contract.nextStep.hint);
|
|
74
|
+
const pending = pendingAfterIds(contract);
|
|
75
|
+
if (pending.length > 0) {
|
|
76
|
+
facts.push(`⧗ ${pending.map((id) => {
|
|
77
|
+
const dot = id.indexOf(".");
|
|
78
|
+
return dot > 0 ? id.slice(0, dot) : id;
|
|
79
|
+
}).join(",")}`);
|
|
80
|
+
}
|
|
81
|
+
if (contract.state.state === "corrupt") {
|
|
82
|
+
facts.push(`corrupt (${contract.state.reason ?? contract.corruptReason ?? "unknown"})`);
|
|
83
|
+
}
|
|
84
|
+
if (contract.queueHeadStalled) {
|
|
85
|
+
facts.push("朱 stall 去广场");
|
|
86
|
+
}
|
|
87
|
+
const sparkCol = spark.padEnd(14);
|
|
88
|
+
const factText = facts.join(" · ");
|
|
89
|
+
lines.push(`${glyph} ${name.padEnd(18)} ${sparkCol} ${factText}`.trimEnd());
|
|
90
|
+
if (contract.bootstrapDiagnostics.some((diagnostic) => diagnostic.kind === "plan-without-result")) {
|
|
91
|
+
lines.push(" ! bootstrap · no result recorded · forfeit and re-bind");
|
|
92
|
+
}
|
|
93
|
+
for (const diagnostic of contract.queueDiagnostics) {
|
|
94
|
+
if (diagnostic.kind === "legacy-petition") {
|
|
95
|
+
lines.push(" ! legacy petition · no seat · reject then re-petition");
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (diagnostic.kind === "duplicate-seat") {
|
|
99
|
+
lines.push(` ! seat ${diagnostic.seat} duplicated with ${diagnostic.with} · ordered by contract id`);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
lines.push(` ! target mismatch · petitioned ${diagnostic.petitioned} · derived ${diagnostic.derived}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return `${lines.join("\n")}\n`;
|
|
106
|
+
}
|
|
@@ -1,8 +1,31 @@
|
|
|
1
|
-
import { shortCommitHash } from "../../
|
|
1
|
+
import { shortCommitHash } from "../../git/commits.js";
|
|
2
2
|
import { assembleResponse, buildPayload, buildSection, formatMaybe, formatWarnings, } from "./format.js";
|
|
3
3
|
import { DIFF_OVERVIEW_SECTION_TITLE, RESPONSE_MARKERS, WARNING_SECTION_TITLE } from "./response-style.js";
|
|
4
4
|
import { BRANCH_LABEL, INFO_BRANCH_MAX_CHARS, INFO_COMMIT_MAX_CHARS, INFO_PLEA_MAX_CHARS, } from "./shared.js";
|
|
5
5
|
import { prependAddressReceipt } from "./address.js";
|
|
6
|
+
export function buildPetitionPreviewResponse(preview, json) {
|
|
7
|
+
const failed = preview.gates.filter((gate) => gate.result === "failed").length;
|
|
8
|
+
const text = json
|
|
9
|
+
? JSON.stringify(preview)
|
|
10
|
+
: [
|
|
11
|
+
`contract ${preview.contract}`,
|
|
12
|
+
`target ${preview.target}`,
|
|
13
|
+
`arc ${preview.arc.source}`,
|
|
14
|
+
...preview.gates.map((gate) => {
|
|
15
|
+
if (gate.result === "not_evaluated")
|
|
16
|
+
return `gate ${gate.name} · not evaluated`;
|
|
17
|
+
if (gate.result === "failed")
|
|
18
|
+
return `gate ${gate.name} · failed · ${gate.detail ?? "failed"}`;
|
|
19
|
+
return `gate ${gate.name} · pass${gate.detail ? ` · ${gate.detail}` : ""}`;
|
|
20
|
+
}),
|
|
21
|
+
failed === 0 ? "would succeed" : `would fail (${failed} gates failed)`,
|
|
22
|
+
].join("\n");
|
|
23
|
+
return {
|
|
24
|
+
text,
|
|
25
|
+
payload: preview,
|
|
26
|
+
...(failed > 0 ? { exitCode: 1 } : {}),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
6
29
|
export function buildPetitionClaimResponse(result, input) {
|
|
7
30
|
const { status: _status, address: _address, ...resultData } = result;
|
|
8
31
|
const renderedCommit = result.commit ? shortCommitHash(result.commit) : undefined;
|
|
@@ -41,6 +41,10 @@ function compactTokens(value) {
|
|
|
41
41
|
}
|
|
42
42
|
function warningText(row) {
|
|
43
43
|
const warning = row.warning;
|
|
44
|
+
if (warning.reason === "retry") {
|
|
45
|
+
const status = warning.errorStatus === null ? "no response" : String(warning.errorStatus);
|
|
46
|
+
return `provider retrying ${warning.attempt}/${warning.maxRetries} · retry in ${formatTimelineDuration(warning.retryDelayMs)} · status ${status}${row.count > 1 ? ` (${row.count})` : ""}`;
|
|
47
|
+
}
|
|
44
48
|
const modelRoute = warning.originalModel && warning.fallbackModel
|
|
45
49
|
? ` ${warning.originalModel}→${warning.fallbackModel}`
|
|
46
50
|
: warning.direction
|
|
@@ -166,7 +170,7 @@ export function renderProjectionActivity(activity, input) {
|
|
|
166
170
|
? ` · ${compactTokens(row.inputTokens)}▸${compactTokens(row.outputTokens)} tok`
|
|
167
171
|
: "";
|
|
168
172
|
const cost = row.costUsd !== undefined ? ` · $${row.costUsd.toFixed(2)}` : "";
|
|
169
|
-
lines.push(fitVariableLine(`${"".padStart(TIME_GUTTER_WIDTH)}├ `, `turn ${row.turn}
|
|
173
|
+
lines.push(fitVariableLine(`${"".padStart(TIME_GUTTER_WIDTH)}├ `, `turn ${row.turn}${usage}${cost}`, maxColumns));
|
|
170
174
|
}
|
|
171
175
|
}
|
|
172
176
|
for (const row of activity.pinned) {
|
|
@@ -128,7 +128,7 @@ export function formatDurableReviveCommand(input) {
|
|
|
128
128
|
export function projectionRejoinHintLines(projectionId) {
|
|
129
129
|
return [
|
|
130
130
|
"Come back for the result:",
|
|
131
|
-
` » keiyaku wait ${projectionId}`,
|
|
131
|
+
` » keiyaku wait ${projectionId} [--timeout DURATION]`,
|
|
132
132
|
"Steer it while it works:",
|
|
133
133
|
` » keiyaku tell ${projectionId} "your words"`,
|
|
134
134
|
];
|
|
@@ -145,7 +145,7 @@ export function formatCallNextAction(input) {
|
|
|
145
145
|
` » keiyaku tell ${input.projection.alias ?? input.projection.id} "your words"`,
|
|
146
146
|
].join("\n");
|
|
147
147
|
}
|
|
148
|
-
return "
|
|
148
|
+
return "» keiyaku status";
|
|
149
149
|
}
|
|
150
150
|
export function appendPersistenceSummary(base, responsePath) {
|
|
151
151
|
const persistence = formatPersistenceSummary(responsePath);
|