@astrosheep/keiyaku 4.6.15 → 4.6.17
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 +1 -1
- package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +13 -8
- package/build/plugins/codex/skills/keiyaku/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +13 -8
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +13 -8
- package/build/skills/keiyaku/SKILL.md +1 -1
- package/build/skills/keiyaku-akuma/SKILL.md +13 -8
- package/build/src/akuma/archetype.js +2 -2
- package/build/src/cli/commands/akuma-grammar.js +18 -14
- package/build/src/cli/commands/akuma.d.ts +2 -1
- package/build/src/cli/commands/akuma.js +24 -25
- package/build/src/cli/commands/contract-help.d.ts +11 -11
- package/build/src/cli/commands/contract-help.js +16 -16
- package/build/src/cli/commands/contract.d.ts +3 -2
- package/build/src/cli/commands/contract.js +45 -65
- package/build/src/cli/commands/debt-grammar.js +8 -15
- package/build/src/cli/commands/debt.d.ts +2 -1
- package/build/src/cli/commands/debt.js +22 -22
- package/build/src/cli/commands/install.d.ts +2 -1
- package/build/src/cli/commands/install.js +4 -3
- package/build/src/cli/commands/whoami.d.ts +46 -0
- package/build/src/cli/commands/whoami.js +127 -0
- package/build/src/cli/main.js +5 -4
- package/build/src/cli/parse.d.ts +7 -1
- package/build/src/cli/parse.js +23 -3
- package/build/src/cli/render/akuma-activity.d.ts +10 -23
- package/build/src/cli/render/akuma-activity.js +178 -212
- package/build/src/cli/render/akuma.d.ts +7 -6
- package/build/src/cli/render/akuma.js +22 -18
- package/build/src/cli/render/catalog.js +4 -3
- package/build/src/cli/render/contract-history.js +5 -16
- package/build/src/cli/render/debt.d.ts +2 -1
- package/build/src/cli/render/debt.js +6 -6
- package/build/src/cli/render/nuke.d.ts +2 -1
- package/build/src/cli/render/nuke.js +4 -2
- package/build/src/cli/render/receipt.js +8 -3
- package/build/src/cli/render/reconcile.js +8 -7
- package/build/src/cli/render/refusal.js +7 -3
- package/build/src/cli/render/terminal.d.ts +5 -2
- package/build/src/cli/render/terminal.js +74 -12
- package/build/src/cli/render/whoami.d.ts +2 -0
- package/build/src/cli/render/whoami.js +56 -0
- package/build/src/cli/runtime.d.ts +2 -1
- package/build/src/cli/runtime.js +59 -58
- package/build/src/cli/streams.d.ts +11 -1
- package/build/src/cli/streams.js +6 -2
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +7 -6
- package/build/src/contract-worktree.js +1 -1
- package/build/src/library/selection.d.ts +1 -0
- package/build/src/library/selection.js +1 -1
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/package.json +3 -3
- package/skills/keiyaku/SKILL.md +1 -1
- package/skills/keiyaku-akuma/SKILL.md +13 -8
|
@@ -13,7 +13,7 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
13
13
|
"fork-of": "value",
|
|
14
14
|
json: "boolean",
|
|
15
15
|
},
|
|
16
|
-
usage: "bind [--debt <debt/...>] [--target <ref> | --no-target] [--after <kei/...>
|
|
16
|
+
usage: "bind [--debt <debt/...>] [--target <ref> | --no-target] [--after <kei/...>]... [--gates <name,...>] [--actor <actor>] [--repo <path>] -\nbind --fork-of <kei/...> [--target <ref> | --no-target] [--actor <actor>] [--repo <path>]",
|
|
17
17
|
purpose: "Create a Contract from stdin Markdown or copy an existing Contract as a starting point.",
|
|
18
18
|
details: [
|
|
19
19
|
"--target names one existing local branch literally; it is never created and never",
|
|
@@ -64,7 +64,7 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
64
64
|
positional: "optional",
|
|
65
65
|
stdin: "optional",
|
|
66
66
|
flags: { actor: "value", after: "repeat", "clear-after": "boolean", gates: "raw-value", json: "boolean" },
|
|
67
|
-
usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name,...>] [--actor <actor>] [-]",
|
|
67
|
+
usage: "amend [<contract>|@<contract>] [--after <kei/...> [--after <kei/...>]... | --clear-after] [--gates <name,...>] [--actor <actor>] [--repo <path>] [-]",
|
|
68
68
|
purpose: "Change a Contract's document, prerequisites, or acceptance gates.",
|
|
69
69
|
details: [
|
|
70
70
|
"Gates are acceptance obligations checked at placement: reviewed awaits a",
|
|
@@ -97,7 +97,7 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
97
97
|
overwrite: "boolean",
|
|
98
98
|
json: "boolean",
|
|
99
99
|
},
|
|
100
|
-
usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--materialize-conflict] [--overwrite]
|
|
100
|
+
usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--materialize-conflict] [--overwrite] [--repo <path>]\ndeliver [<contract>|@<contract>] --dry-run [--include-dirty] [--show-diff] [--repo <path>]",
|
|
101
101
|
purpose: "Submit work for a Contract and integrate it when its requirements are met.",
|
|
102
102
|
details: [
|
|
103
103
|
"The Contract, not the current Arc, sets what delivery must satisfy. An Arc records progress; it does not narrow acceptance.",
|
|
@@ -122,7 +122,7 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
122
122
|
positional: "optional",
|
|
123
123
|
stdin: "optional",
|
|
124
124
|
flags: { actor: "value", satisfied: "boolean", unsatisfied: "boolean", summary: "value", json: "boolean" },
|
|
125
|
-
usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>]",
|
|
125
|
+
usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>] [--repo <path>]",
|
|
126
126
|
purpose: "Record whether a Contract meets its acceptance criteria.",
|
|
127
127
|
details: [
|
|
128
128
|
"A review checks the whole Contract, not just one Arc. After delivery it checks the candidate; before delivery it checks the current Contract and worktree, but cannot integrate.",
|
|
@@ -136,7 +136,7 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
136
136
|
positional: "optional",
|
|
137
137
|
stdin: "required",
|
|
138
138
|
flags: { actor: "value", json: "boolean" },
|
|
139
|
-
usage: "arc [<contract>|@<contract>] [--actor <actor>] -",
|
|
139
|
+
usage: "arc [<contract>|@<contract>] [--actor <actor>] [--repo <path>] -",
|
|
140
140
|
purpose: "Name the current chapter of a Contract's story (a story arc).",
|
|
141
141
|
details: [
|
|
142
142
|
"stdin is one nonblank H1 chapter name followed by any Markdown body, including none:",
|
|
@@ -149,14 +149,14 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
149
149
|
positional: "optional",
|
|
150
150
|
stdin: "none",
|
|
151
151
|
flags: { actor: "value", note: "value", json: "boolean" },
|
|
152
|
-
usage: "abandon [<contract>|@<contract>] [--note <text>] [--actor <actor>]",
|
|
153
|
-
purpose: "End work on a Contract without
|
|
152
|
+
usage: "abandon [<contract>|@<contract>] [--note <text>] [--actor <actor>] [--repo <path>]",
|
|
153
|
+
purpose: "End work on a Contract without accepting it; optionally record why.",
|
|
154
154
|
},
|
|
155
155
|
show: {
|
|
156
156
|
positional: "optional",
|
|
157
157
|
stdin: "none",
|
|
158
158
|
flags: { json: "boolean" },
|
|
159
|
-
usage: "show [<contract>|@<contract>]",
|
|
159
|
+
usage: "show [<contract>|@<contract>] [--repo <path>]",
|
|
160
160
|
purpose: "Read one Contract's guidance.",
|
|
161
161
|
details: [
|
|
162
162
|
"Accepts a complete Contract identity or exact @<contract> short selector.",
|
|
@@ -183,12 +183,12 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
183
183
|
positional: "optional",
|
|
184
184
|
stdin: "none",
|
|
185
185
|
flags: { limit: "value", json: "boolean", mine: "boolean", caller: "value" },
|
|
186
|
-
usage: 'ls debt[/] [--limit <count>]\nls kei[/] [--limit <count>]\nls aku[/] [--limit <count>]\nls aku/<name>[/] [--limit <count>]\nls "aku/<name>/*" [--limit <count>]\nls "aku/*/*" [--limit <count>]\nls ["aku
|
|
186
|
+
usage: 'ls debt[/] [--limit <count>]\nls debt/<namespace>/ [--limit <count>]\nls kei[/] [--limit <count>]\nls aku[/] [--limit <count>]\nls aku/<name>[/] [--limit <count>]\nls "aku/<name>/*" [--limit <count>]\nls "aku/*/*" [--limit <count>]\nls [aku/<name>[/] | "aku/<name>/*" | "aku/*/*"] (--mine | --caller (<integration>:<id> | aku/<name>/<suffix>)) [--limit <count>]',
|
|
187
187
|
purpose: "List debts (ls debt), contracts (ls kei), or akumas (ls aku).",
|
|
188
188
|
details: [
|
|
189
189
|
"ls kei lists active Contracts; accepted and abandoned ones leave the list, and their record stays in history and Git.",
|
|
190
|
-
"ls aku/ lists the callable Akuma-name catalog; ls aku/<name> lists
|
|
191
|
-
'ls "aku/<name>/*" is the same
|
|
190
|
+
"ls aku/ lists the callable Akuma-name catalog; ls aku/<name> lists recent retained Akuma instances under one name.",
|
|
191
|
+
'ls "aku/<name>/*" is the same roster in glob form; ls "aku/*/*" lists recent retained Akuma instances across names.',
|
|
192
192
|
"--mine selects the caller identity of this process and lists that caller's direct and transitive descendants in this World.",
|
|
193
193
|
"--caller selects an explicit caller instead; both selectors are World-local and refuse for Contract, Debt, or Akuma-name catalogues.",
|
|
194
194
|
"Descendant rows name their immediate calling Akuma beside the row.",
|
|
@@ -198,7 +198,7 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
198
198
|
positional: "optional",
|
|
199
199
|
stdin: "none",
|
|
200
200
|
flags: { "retry-hooks": "boolean", json: "boolean" },
|
|
201
|
-
usage: "reconcile [<contract>|@<contract>] [--retry-hooks]",
|
|
201
|
+
usage: "reconcile [<contract>|@<contract>] [--retry-hooks] [--repo <path>]",
|
|
202
202
|
purpose: "Restore a Contract's Git workspace from its recorded state, or all of this World's.",
|
|
203
203
|
details: "--retry-hooks reruns configured setup commands even when a Contract workspace already exists; otherwise they run when reconciliation creates it.",
|
|
204
204
|
},
|
|
@@ -221,7 +221,7 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
221
221
|
positional: "optional",
|
|
222
222
|
stdin: "none",
|
|
223
223
|
flags: { path: "repeat", json: "boolean" },
|
|
224
|
-
usage: "region [<contract>]\nregion --path <pattern> [--path <pattern>
|
|
224
|
+
usage: "region [<contract>] [--repo <path>]\nregion --path <pattern> [--path <pattern>]... [--repo <path>]",
|
|
225
225
|
purpose: "Show declared Contract write patterns — all, one Contract's, or those overlapping given paths.",
|
|
226
226
|
details: "Check overlap before starting parallel work.",
|
|
227
227
|
},
|
|
@@ -248,8 +248,8 @@ export function renderContractHelp(command) {
|
|
|
248
248
|
"value's diagnostic states the expected shape.",
|
|
249
249
|
"",
|
|
250
250
|
"Akuma definitions are Markdown files, one per name:",
|
|
251
|
-
" user ~/.keiyaku/
|
|
252
|
-
" project <WorldRoot>/.keiyaku/
|
|
251
|
+
" user ~/.keiyaku/akumas/<name>.md",
|
|
252
|
+
" project <WorldRoot>/.keiyaku/akumas/<name>.md",
|
|
253
253
|
"A project file wholly shadows the same-name user file. YAML",
|
|
254
254
|
"frontmatter selects the provider and may declare base, model,",
|
|
255
255
|
"effort, network, allowed, systemPromptMode, and description; the body is",
|
|
@@ -261,7 +261,7 @@ export function renderContractHelp(command) {
|
|
|
261
261
|
' "config": { "url": "ws://127.0.0.1:6767/ws", "provider": "claude" }',
|
|
262
262
|
" } } }",
|
|
263
263
|
"The native provider id is bare (claude, codex, pi), not provider/model.",
|
|
264
|
-
"Example .keiyaku/
|
|
264
|
+
"Example .keiyaku/akumas/paseo-worker.md frontmatter:",
|
|
265
265
|
" ---",
|
|
266
266
|
" provider: paseo",
|
|
267
267
|
" model: <native-model-id>",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CliCoordinates } from "../coordinates.js";
|
|
2
2
|
import type { CliRuntime } from "../runtime.js";
|
|
3
|
+
import { type CliOutcome } from "../streams.js";
|
|
3
4
|
import type { ParsedContractCommand } from "./contract-grammar.js";
|
|
4
5
|
/**
|
|
5
6
|
* The one bind-document admission that runs before coordinate resolution, so a malformed document
|
|
@@ -16,6 +17,6 @@ type ParsedContractHistory = Readonly<{
|
|
|
16
17
|
full: boolean;
|
|
17
18
|
output: "text" | "json";
|
|
18
19
|
}>;
|
|
19
|
-
export declare function runContractHistoryCommand(command: ParsedContractHistory, coordinates: CliCoordinates): Promise<
|
|
20
|
-
export declare function runContractCommand(command: ParsedContractCommand, coordinates: CliCoordinates, runtime: CliRuntime): Promise<
|
|
20
|
+
export declare function runContractHistoryCommand(command: ParsedContractHistory, coordinates: CliCoordinates): Promise<CliOutcome>;
|
|
21
|
+
export declare function runContractCommand(command: ParsedContractCommand, coordinates: CliCoordinates, runtime: CliRuntime): Promise<CliOutcome>;
|
|
21
22
|
export {};
|
|
@@ -15,7 +15,7 @@ import { snapshotText } from "../render/akuma-activity.js";
|
|
|
15
15
|
import { renderAkumaCatalogue, renderArchetypeCatalogue, renderContractCatalogue, renderDebtCatalogue, } from "../render/catalog.js";
|
|
16
16
|
import { renderAccepted, renderContractHistory, renderRetry } from "../render/contract.js";
|
|
17
17
|
import { renderKanshiCategoryText, renderKanshiText } from "../render/kanshi.js";
|
|
18
|
-
import {
|
|
18
|
+
import { nukeOutcome, renderNukeText } from "../render/nuke.js";
|
|
19
19
|
import { reconcileHasFailure, renderReconcile } from "../render/reconcile.js";
|
|
20
20
|
import { renderConflictMaterialized, renderRefusal } from "../render/refusal.js";
|
|
21
21
|
import { renderRegionText } from "../render/region.js";
|
|
@@ -92,9 +92,6 @@ function deliverRefusalProjection(refusal) {
|
|
|
92
92
|
const submodules = "submodules" in refusal && Array.isArray(refusal.submodules) ? refusal.submodules : [];
|
|
93
93
|
return { ...refusal, option: { flag: "--include-dirty", available: submodules.length === 0 } };
|
|
94
94
|
}
|
|
95
|
-
function contractExitCode(answer) {
|
|
96
|
-
return answer.kind === "refused" ? 1 : answer.kind === "retry" ? 2 : 0;
|
|
97
|
-
}
|
|
98
95
|
function renderContractAnswer(answer, project, context) {
|
|
99
96
|
switch (answer.kind) {
|
|
100
97
|
case "handoff":
|
|
@@ -108,8 +105,8 @@ function renderContractAnswer(answer, project, context) {
|
|
|
108
105
|
}
|
|
109
106
|
}
|
|
110
107
|
async function finishContractAnswer(answer, output, project) {
|
|
111
|
-
const
|
|
112
|
-
return emit(output, answer,
|
|
108
|
+
const outcome = answer.kind === "refused" ? "refused" : answer.kind === "retry" ? "retryable" : "accepted";
|
|
109
|
+
return emit(output, answer, () => renderContractAnswer(answer, project, displayContext()), outcome);
|
|
113
110
|
}
|
|
114
111
|
async function selectedContract(repo, selector, scope) {
|
|
115
112
|
const id = await resolveContractId(repo, selector, scope);
|
|
@@ -125,16 +122,6 @@ async function existingSeat(command, coordinates, runtime, library) {
|
|
|
125
122
|
...(actor === undefined ? {} : { actor }),
|
|
126
123
|
};
|
|
127
124
|
}
|
|
128
|
-
/** One composition for every mutation leaf; gates, hooks, and freshness derive lazily inside it. */
|
|
129
|
-
async function contractLibrary(command, execution, configuration, runtime) {
|
|
130
|
-
const actor = executionChannel(execution).kind === "local" && ["deliver", "review"].includes(command.command)
|
|
131
|
-
? actorFromEdge(undefined, runtime.environment)
|
|
132
|
-
: undefined;
|
|
133
|
-
return composeContractLibrary(execution, createKeiyakuHandle, {
|
|
134
|
-
...(configuration === undefined ? {} : { settings: configuration }),
|
|
135
|
-
...(actor === undefined ? {} : { actor }),
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
125
|
async function runBind(command, input, library) {
|
|
139
126
|
const { coordinates, runtime } = input;
|
|
140
127
|
const repo = requiredRepo(coordinates);
|
|
@@ -164,7 +151,7 @@ async function runBind(command, input, library) {
|
|
|
164
151
|
return await finishContractAnswer(answer, command.output);
|
|
165
152
|
const draft = await bindDraftReceipt(coordinates.establishWorld, markdown);
|
|
166
153
|
const text = () => renderRefusal(refusedInvocation(answer), draft, displayContext());
|
|
167
|
-
return emit(command.output, answer, text,
|
|
154
|
+
return emit(command.output, answer, text, "refused");
|
|
168
155
|
}
|
|
169
156
|
catch (error) {
|
|
170
157
|
if (error instanceof Error && "executionReceipt" in error)
|
|
@@ -193,18 +180,20 @@ async function runAmend(command, input, seat) {
|
|
|
193
180
|
return await finishContractAnswer(answer, command.output);
|
|
194
181
|
}
|
|
195
182
|
async function runDeliver(command, runtime, seat) {
|
|
196
|
-
if (command.dryRun)
|
|
197
|
-
return await runDeliveryPreview(command, runtime, seat);
|
|
198
183
|
const driver = command.output === "text" ? await runtime.progress() : undefined;
|
|
199
184
|
let answer;
|
|
200
185
|
try {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
186
|
+
const progress = { ...(driver === undefined ? {} : { observe: driver.observe }) };
|
|
187
|
+
const signal = { ...(runtime.signal === undefined ? {} : { signal: runtime.signal }) };
|
|
188
|
+
answer = command.dryRun
|
|
189
|
+
? await seat.contract.previewDelivery({ includeDirty: command.includeDirty, showDiff: command.showDiff, ...signal }, progress)
|
|
190
|
+
: await seat.contract.deliver({
|
|
191
|
+
...(command.message === undefined ? {} : { message: command.message }),
|
|
192
|
+
includeDirty: command.includeDirty,
|
|
193
|
+
materializeConflict: command.materializeConflict,
|
|
194
|
+
overwrite: command.overwrite,
|
|
195
|
+
...signal,
|
|
196
|
+
}, progress);
|
|
208
197
|
}
|
|
209
198
|
finally {
|
|
210
199
|
if (driver !== undefined)
|
|
@@ -242,7 +231,7 @@ async function runArc(command, runtime, seat) {
|
|
|
242
231
|
throw error;
|
|
243
232
|
const refusal = { kind: "invalid-document", diagnostic: error.message };
|
|
244
233
|
const refused = { kind: "refused", operation: "arc", contract: seat.id, refusal };
|
|
245
|
-
return emit(command.output, refused, () => renderRefusal(refused, undefined, displayContext()),
|
|
234
|
+
return emit(command.output, refused, () => renderRefusal(refused, undefined, displayContext()), "refused");
|
|
246
235
|
}
|
|
247
236
|
const answer = await seat.contract.arc({
|
|
248
237
|
markdown,
|
|
@@ -257,24 +246,15 @@ async function runAbandon(command, seat) {
|
|
|
257
246
|
});
|
|
258
247
|
return await finishContractAnswer(answer, command.output);
|
|
259
248
|
}
|
|
260
|
-
async function runDeliveryPreview(command, runtime, seat) {
|
|
261
|
-
const driver = command.output === "text" ? await runtime.progress() : undefined;
|
|
262
|
-
let answer;
|
|
263
|
-
try {
|
|
264
|
-
answer = await seat.contract.previewDelivery({
|
|
265
|
-
includeDirty: command.includeDirty,
|
|
266
|
-
showDiff: command.showDiff,
|
|
267
|
-
...(runtime.signal === undefined ? {} : { signal: runtime.signal }),
|
|
268
|
-
}, { ...(driver === undefined ? {} : { observe: driver.observe }) });
|
|
269
|
-
}
|
|
270
|
-
finally {
|
|
271
|
-
if (driver !== undefined)
|
|
272
|
-
await driver.finish().catch(() => undefined);
|
|
273
|
-
}
|
|
274
|
-
return await finishContractAnswer(answer, command.output, deliverRefusalProjection);
|
|
275
|
-
}
|
|
276
249
|
async function runContractMutation(command, input) {
|
|
277
|
-
const
|
|
250
|
+
const { execution, configuration, runtime } = input;
|
|
251
|
+
const actor = executionChannel(execution).kind === "local" && ["deliver", "review"].includes(command.command)
|
|
252
|
+
? actorFromEdge(undefined, runtime.environment)
|
|
253
|
+
: undefined;
|
|
254
|
+
const library = composeContractLibrary(execution, createKeiyakuHandle, {
|
|
255
|
+
...(configuration === undefined ? {} : { settings: configuration }),
|
|
256
|
+
...(actor === undefined ? {} : { actor }),
|
|
257
|
+
});
|
|
278
258
|
if (command.command === "bind")
|
|
279
259
|
return await runBind(command, input, library);
|
|
280
260
|
const seat = await existingSeat(command, input.coordinates, input.runtime, library);
|
|
@@ -296,7 +276,7 @@ function statusRefusal(operation, contract) {
|
|
|
296
276
|
}
|
|
297
277
|
async function runSettings(coordinates, home, output) {
|
|
298
278
|
const value = await settingsAt(coordinates.world ?? undefined, home);
|
|
299
|
-
return emit(output, settingsJsonValue(value), () => renderSettingsText(value, displayContext().columns),
|
|
279
|
+
return emit(output, settingsJsonValue(value), () => renderSettingsText(value, displayContext().columns), "accepted");
|
|
300
280
|
}
|
|
301
281
|
async function runNuke(command, coordinates) {
|
|
302
282
|
if (coordinates.world === null)
|
|
@@ -305,7 +285,7 @@ async function runNuke(command, coordinates) {
|
|
|
305
285
|
world: coordinates.world,
|
|
306
286
|
...(command.confirm === undefined ? {} : { confirm: command.confirm }),
|
|
307
287
|
});
|
|
308
|
-
return emit(command.output, result, () => renderNukeText(result),
|
|
288
|
+
return emit(command.output, result, () => renderNukeText(result), nukeOutcome(result));
|
|
309
289
|
}
|
|
310
290
|
async function runLs(command, coordinates, home, runtime) {
|
|
311
291
|
const query = command.query;
|
|
@@ -314,7 +294,7 @@ async function runLs(command, coordinates, home, runtime) {
|
|
|
314
294
|
repo: requiredRepo(coordinates),
|
|
315
295
|
...(query.limit === undefined ? {} : { limit: query.limit }),
|
|
316
296
|
});
|
|
317
|
-
return emit(command.output, list, () => renderContractCatalogue(list),
|
|
297
|
+
return emit(command.output, list, () => renderContractCatalogue(list), "accepted");
|
|
318
298
|
}
|
|
319
299
|
if (query.kind === "archetypes") {
|
|
320
300
|
const list = await listArchetypeDefinitions({
|
|
@@ -322,7 +302,7 @@ async function runLs(command, coordinates, home, runtime) {
|
|
|
322
302
|
...(query.limit === undefined ? {} : { limit: query.limit }),
|
|
323
303
|
...(home === undefined ? {} : { home }),
|
|
324
304
|
});
|
|
325
|
-
return emit(command.output, list, () => renderArchetypeCatalogue(list),
|
|
305
|
+
return emit(command.output, list, () => renderArchetypeCatalogue(list), "accepted");
|
|
326
306
|
}
|
|
327
307
|
if (coordinates.world === null)
|
|
328
308
|
throw new CliUsageError("no Keiyaku world contains the invocation cwd");
|
|
@@ -334,7 +314,7 @@ async function runLs(command, coordinates, home, runtime) {
|
|
|
334
314
|
});
|
|
335
315
|
if (listed.kind !== "accepted")
|
|
336
316
|
throw new Error("Debt list did not return an accepted observation");
|
|
337
|
-
return emit(command.output, listed, () => renderDebtCatalogue(listed.value, query.namespace ?? []),
|
|
317
|
+
return emit(command.output, listed, () => renderDebtCatalogue(listed.value, query.namespace ?? []), "accepted");
|
|
338
318
|
}
|
|
339
319
|
const caller = await lsCaller(query.caller, coordinates, runtime);
|
|
340
320
|
const listed = await Akumas.of(coordinates.world).list({
|
|
@@ -342,7 +322,7 @@ async function runLs(command, coordinates, home, runtime) {
|
|
|
342
322
|
...(query.limit === undefined ? {} : { limit: query.limit }),
|
|
343
323
|
...(caller === undefined ? {} : { caller }),
|
|
344
324
|
});
|
|
345
|
-
return emit(command.output, listed, () => renderAkumaCatalogue(listed, query.archetype ?? null, caller),
|
|
325
|
+
return emit(command.output, listed, () => renderAkumaCatalogue(listed, query.archetype ?? null, caller), "accepted");
|
|
346
326
|
}
|
|
347
327
|
/** `--mine` is the process caller identity; `--caller` names the same coordinate explicitly. */
|
|
348
328
|
async function lsCaller(selection, coordinates, runtime) {
|
|
@@ -400,9 +380,9 @@ async function runShow(command, coordinates) {
|
|
|
400
380
|
const guidance = await selected.contract.guidance();
|
|
401
381
|
if (guidance === null) {
|
|
402
382
|
const refusal = statusRefusal(command.command, selected.id);
|
|
403
|
-
return emit(command.output, null, () => renderRefusal(refusal, undefined, displayContext()),
|
|
383
|
+
return emit(command.output, null, () => renderRefusal(refusal, undefined, displayContext()), "refused");
|
|
404
384
|
}
|
|
405
|
-
return emit(command.output, guidance, () => guidance,
|
|
385
|
+
return emit(command.output, guidance, () => guidance, "accepted");
|
|
406
386
|
}
|
|
407
387
|
async function runStatusSelection(command, coordinates) {
|
|
408
388
|
const selectors = command.selectors;
|
|
@@ -426,7 +406,7 @@ async function runStatusSelection(command, coordinates) {
|
|
|
426
406
|
if (command.output === "text")
|
|
427
407
|
blocks.push(resolved.project());
|
|
428
408
|
}
|
|
429
|
-
return emit(command.output, values, () => blocks.join("\n\n"),
|
|
409
|
+
return emit(command.output, values, () => blocks.join("\n\n"), "accepted");
|
|
430
410
|
}
|
|
431
411
|
async function runStatusCategory(command, coordinates) {
|
|
432
412
|
if (command.category === "contract")
|
|
@@ -437,7 +417,7 @@ async function runStatusCategory(command, coordinates) {
|
|
|
437
417
|
category: command.category,
|
|
438
418
|
...(command.limit === undefined ? {} : { limit: command.limit }),
|
|
439
419
|
});
|
|
440
|
-
return emit(command.output, report, () => renderKanshiCategoryText(report, displayContext()),
|
|
420
|
+
return emit(command.output, report, () => renderKanshiCategoryText(report, displayContext()), "accepted");
|
|
441
421
|
}
|
|
442
422
|
async function runStatusIdentity(command, coordinates) {
|
|
443
423
|
if (command.contract === undefined) {
|
|
@@ -445,11 +425,11 @@ async function runStatusIdentity(command, coordinates) {
|
|
|
445
425
|
world: coordinates.world,
|
|
446
426
|
...(coordinates.repo === undefined ? {} : { repo: coordinates.repo }),
|
|
447
427
|
});
|
|
448
|
-
return emit(command.output, report, () => renderKanshiText(report, displayContext(), "world"),
|
|
428
|
+
return emit(command.output, report, () => renderKanshiText(report, displayContext(), "world"), "accepted");
|
|
449
429
|
}
|
|
450
430
|
if (command.contract.startsWith("@")) {
|
|
451
431
|
const resolved = await namedStatus(command.contract, coordinates, await observeNamedAddress({ world: coordinates.world, repo: coordinates.repo ?? null }));
|
|
452
|
-
return emit(command.output, resolved.value, () => resolved.project(),
|
|
432
|
+
return emit(command.output, resolved.value, () => resolved.project(), "accepted");
|
|
453
433
|
}
|
|
454
434
|
if (command.contract.startsWith("kei/")) {
|
|
455
435
|
const repo = requiredRepo(coordinates);
|
|
@@ -457,9 +437,9 @@ async function runStatusIdentity(command, coordinates) {
|
|
|
457
437
|
const report = await kanshi({ world: coordinates.world, repo, contract });
|
|
458
438
|
if (report.contracts.kind === "present" && report.contracts.value.rows.length === 0) {
|
|
459
439
|
const refusal = statusRefusal("status", contract);
|
|
460
|
-
return emit(command.output, refusal.refusal, () => renderRefusal(refusal, undefined, displayContext()),
|
|
440
|
+
return emit(command.output, refusal.refusal, () => renderRefusal(refusal, undefined, displayContext()), "refused");
|
|
461
441
|
}
|
|
462
|
-
return emit(command.output, report, () => renderKanshiText(report, displayContext(), "contract"),
|
|
442
|
+
return emit(command.output, report, () => renderKanshiText(report, displayContext(), "contract"), "accepted");
|
|
463
443
|
}
|
|
464
444
|
throw new CliUsageError(`contract selector must use kei/: ${command.contract}`);
|
|
465
445
|
}
|
|
@@ -470,13 +450,13 @@ async function runStatus(command, coordinates) {
|
|
|
470
450
|
return await runStatusSelection({ ...command, selectors: command.selectors }, coordinates);
|
|
471
451
|
if (command.akuma === true && command.contract !== undefined) {
|
|
472
452
|
const resolved = await readAkumaStatus(command.contract, undefined, coordinates);
|
|
473
|
-
return emit(command.output, resolved.value, () => resolved.project(),
|
|
453
|
+
return emit(command.output, resolved.value, () => resolved.project(), "accepted");
|
|
474
454
|
}
|
|
475
455
|
return await runStatusIdentity(command, coordinates);
|
|
476
456
|
}
|
|
477
457
|
async function runRegion(command, coordinates) {
|
|
478
458
|
const repo = requiredRepo(coordinates);
|
|
479
|
-
const emitSection = (section) => emit(command.output, section, () => renderRegionText(section),
|
|
459
|
+
const emitSection = (section) => emit(command.output, section, () => renderRegionText(section), "accepted");
|
|
480
460
|
if (command.paths !== undefined) {
|
|
481
461
|
const report = await kanshi({ world: coordinates.world, repo, region: { kind: "path", patterns: command.paths } });
|
|
482
462
|
return emitSection(report.region ?? { kind: "absent" });
|
|
@@ -495,7 +475,7 @@ async function runRegion(command, coordinates) {
|
|
|
495
475
|
writeJson(refusal);
|
|
496
476
|
else
|
|
497
477
|
writeStdout(renderRefusal({ operation: "region", contract, refusal }, undefined, displayContext()));
|
|
498
|
-
return
|
|
478
|
+
return "refused";
|
|
499
479
|
}
|
|
500
480
|
if (report.region?.kind !== "present" || report.region.value.kind !== "declarations")
|
|
501
481
|
return emitSection(report.region ?? { kind: "absent" });
|
|
@@ -517,9 +497,9 @@ export async function runContractHistoryCommand(command, coordinates) {
|
|
|
517
497
|
writeJson(refusal);
|
|
518
498
|
else
|
|
519
499
|
writeStdout(renderRefusal({ operation: "history", contract: selected.id, refusal }, undefined, displayContext()));
|
|
520
|
-
return
|
|
500
|
+
return "refused";
|
|
521
501
|
}
|
|
522
|
-
return emit(command.output, history, () => renderContractHistory(history, { full: command.full }),
|
|
502
|
+
return emit(command.output, history, () => renderContractHistory(history, { full: command.full }), "accepted");
|
|
523
503
|
}
|
|
524
504
|
async function runReconcile(command, coordinates, execution, home) {
|
|
525
505
|
const repo = requiredRepo(coordinates);
|
|
@@ -539,7 +519,7 @@ async function runReconcile(command, coordinates, execution, home) {
|
|
|
539
519
|
writeJson(statusRefusal("reconcile", selected.id).refusal);
|
|
540
520
|
else
|
|
541
521
|
writeStdout(renderRefusal(statusRefusal("reconcile", selected.id), undefined, displayContext()));
|
|
542
|
-
return
|
|
522
|
+
return "refused";
|
|
543
523
|
}
|
|
544
524
|
report = await library.reconcile({ repo, contract: selected.id, retryHooks: command.retryHooks });
|
|
545
525
|
}
|
|
@@ -547,7 +527,7 @@ async function runReconcile(command, coordinates, execution, home) {
|
|
|
547
527
|
writeJson(report);
|
|
548
528
|
else
|
|
549
529
|
writeStdout(renderReconcile(report, displayContext()));
|
|
550
|
-
return reconcileHasFailure(report) ?
|
|
530
|
+
return reconcileHasFailure(report) ? "failed" : "accepted";
|
|
551
531
|
}
|
|
552
532
|
export async function runContractCommand(command, coordinates, runtime) {
|
|
553
533
|
const execution = runtime.execution;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CliUsageError, DEBT_FAMILY_USAGE_GUIDE, unknownCommandGuide } from "../usage.js";
|
|
1
|
+
import { CliUsageError, commonInvocationOptions, DEBT_FAMILY_USAGE_GUIDE, unknownCommandGuide, } from "../usage.js";
|
|
2
2
|
import { scanArgs } from "../scan.js";
|
|
3
3
|
import { parseDebtNamespaceSelector } from "../../debt/catalog.js";
|
|
4
4
|
import { parseDebtId } from "../../debt/identity.js";
|
|
@@ -165,26 +165,19 @@ export function renderDebtHelp(action) {
|
|
|
165
165
|
].join("\n");
|
|
166
166
|
}
|
|
167
167
|
function renderDebtUsage(action) {
|
|
168
|
-
return
|
|
168
|
+
return debtUsage(action)
|
|
169
169
|
.split("\n")
|
|
170
|
-
.map((line, index) => {
|
|
171
|
-
if (index === 0 || line.trimStart().startsWith("debt ")) {
|
|
172
|
-
const command = line.trimStart().startsWith("debt ") ? `keiyaku ${line.trim()}` : `keiyaku ${line}`;
|
|
173
|
-
return `${index === 0 ? "usage " : " "}${command}`;
|
|
174
|
-
}
|
|
175
|
-
return ` ${line.trim()}`;
|
|
176
|
-
})
|
|
170
|
+
.map((line, index) => `${index === 0 ? "usage " : " "}${line.trimStart()}`)
|
|
177
171
|
.join("\n");
|
|
178
172
|
}
|
|
179
173
|
function debtUsage(action) {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
.map((line, index) => {
|
|
174
|
+
const usage = DEBT_COMMAND_SPECS[action].usage;
|
|
175
|
+
const lines = usage.split("\n").map((line, index) => {
|
|
183
176
|
if (index === 0 || line.trimStart().startsWith("debt "))
|
|
184
177
|
return `keiyaku ${line.trim()}`;
|
|
185
|
-
return
|
|
186
|
-
})
|
|
187
|
-
|
|
178
|
+
return line.trim();
|
|
179
|
+
});
|
|
180
|
+
return [...lines, commonInvocationOptions(usage)].join("\n");
|
|
188
181
|
}
|
|
189
182
|
export function debtUsageGuide(action) {
|
|
190
183
|
return {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ParsedDebtCommand } from "./debt-grammar.js";
|
|
2
|
+
import { type CliOutcome } from "../streams.js";
|
|
2
3
|
import type { CliRuntime } from "../runtime.js";
|
|
3
4
|
import type { CliCoordinates } from "../coordinates.js";
|
|
4
|
-
export declare function runDebtCommand(command: ParsedDebtCommand, coordinates: CliCoordinates, runtime: CliRuntime): Promise<
|
|
5
|
+
export declare function runDebtCommand(command: ParsedDebtCommand, coordinates: CliCoordinates, runtime: CliRuntime): Promise<CliOutcome>;
|
|
@@ -3,7 +3,7 @@ import { parseDebtNamespaceSelector } from "../../debt/catalog.js";
|
|
|
3
3
|
import { debtsWithExecution, debtRowViewLimit, } from "../../debt/index.js";
|
|
4
4
|
import { installNamespaceContext, resolveDebtNamespaceContext } from "../../debt/context.js";
|
|
5
5
|
import { displayContext, emit, writeJson } from "../streams.js";
|
|
6
|
-
import { renderDoctor, renderDebtContext, renderDebtLifecycle, renderDebtList, renderDebtMutation, renderDebtShow, renderDebtTree, renderDebtUpdate,
|
|
6
|
+
import { renderDoctor, renderDebtContext, renderDebtLifecycle, renderDebtList, renderDebtMutation, renderDebtShow, renderDebtTree, renderDebtUpdate, debtOutcome, } from "../render/debt.js";
|
|
7
7
|
import { actorFromEdge } from "../actor.js";
|
|
8
8
|
import { debtQuerySelection } from "../../debt/query.js";
|
|
9
9
|
function value(command, name) {
|
|
@@ -121,15 +121,15 @@ async function runShow(command, debts) {
|
|
|
121
121
|
for (const id of handles)
|
|
122
122
|
details.push(await debts.debt({ id }).read());
|
|
123
123
|
const missing = details.findIndex((detail) => detail === null);
|
|
124
|
-
const
|
|
124
|
+
const outcome = missing >= 0 ? "refused" : "accepted";
|
|
125
125
|
const projected = handles.length === 1 ? details[0] : details;
|
|
126
126
|
if (missing >= 0) {
|
|
127
127
|
const refusal = { kind: "refused", refusal: { kind: "debt-missing", debtId: handles[missing] } };
|
|
128
|
-
return emit(command.output, projected, () => renderDebtShow(refusal, displayContext()),
|
|
128
|
+
return emit(command.output, projected, () => renderDebtShow(refusal, displayContext()), outcome);
|
|
129
129
|
}
|
|
130
130
|
const found = details.filter((detail) => detail !== null);
|
|
131
131
|
const result = found.length === 1 ? found[0] : found;
|
|
132
|
-
return emit(command.output, projected, () => renderDebtShow(result, displayContext()),
|
|
132
|
+
return emit(command.output, projected, () => renderDebtShow(result, displayContext()), outcome);
|
|
133
133
|
}
|
|
134
134
|
/** Presentation-only list scope the leaf acquired, never part of the native answer. */
|
|
135
135
|
function listPresentation(command) {
|
|
@@ -151,7 +151,7 @@ async function runRead(input) {
|
|
|
151
151
|
: { namespace: explicitListNamespace(command) }),
|
|
152
152
|
...(limit(command) === undefined ? {} : { limit: limit(command) }),
|
|
153
153
|
});
|
|
154
|
-
return emit(command.output, result, () => renderDebtList("ls", scope, result, displayContext()),
|
|
154
|
+
return emit(command.output, result, () => renderDebtList("ls", scope, result, displayContext()), debtOutcome(result));
|
|
155
155
|
}
|
|
156
156
|
case "ready":
|
|
157
157
|
case "blocked": {
|
|
@@ -161,7 +161,7 @@ async function runRead(input) {
|
|
|
161
161
|
...(value(command, "parent") === undefined ? {} : { parent: value(command, "parent") }),
|
|
162
162
|
...(limit(command) === undefined ? {} : { limit: limit(command) }),
|
|
163
163
|
});
|
|
164
|
-
return emit(command.output, result, () => renderDebtList(action, scope, result, displayContext()),
|
|
164
|
+
return emit(command.output, result, () => renderDebtList(action, scope, result, displayContext()), debtOutcome(result));
|
|
165
165
|
}
|
|
166
166
|
case "query": {
|
|
167
167
|
const result = await debts.query({
|
|
@@ -170,15 +170,15 @@ async function runRead(input) {
|
|
|
170
170
|
...(value(command, "sort") === undefined ? {} : { sort: value(command, "sort") }),
|
|
171
171
|
...(limit(command) === undefined ? {} : { limit: limit(command) }),
|
|
172
172
|
});
|
|
173
|
-
return emit(command.output, result, () => renderDebtList("query", scope, result, displayContext()),
|
|
173
|
+
return emit(command.output, result, () => renderDebtList("query", scope, result, displayContext()), debtOutcome(result));
|
|
174
174
|
}
|
|
175
175
|
case "tree": {
|
|
176
176
|
const result = await debts.debt({ id }).tree();
|
|
177
|
-
return emit(command.output, result, () => renderDebtTree(result, displayContext()),
|
|
177
|
+
return emit(command.output, result, () => renderDebtTree(result, displayContext()), debtOutcome(result));
|
|
178
178
|
}
|
|
179
179
|
case "doctor": {
|
|
180
180
|
const result = await debts.doctor();
|
|
181
|
-
return emit(command.output, result, () => renderDoctor(result),
|
|
181
|
+
return emit(command.output, result, () => renderDoctor(result), debtOutcome(result));
|
|
182
182
|
}
|
|
183
183
|
default:
|
|
184
184
|
throw new Error(`debt action is not a read: ${command.action}`);
|
|
@@ -204,32 +204,32 @@ function missingWorld(command) {
|
|
|
204
204
|
// An addressed missing read keeps its native null in JSON; text refuses without partial output.
|
|
205
205
|
if (output === "json") {
|
|
206
206
|
writeJson(command.positionals.length === 1 ? null : command.positionals.map(() => null));
|
|
207
|
-
return
|
|
207
|
+
return "refused";
|
|
208
208
|
}
|
|
209
209
|
const refusal = missingDebt(command.positionals[0]);
|
|
210
|
-
return emit(output, refusal, () => renderDebtShow(refusal, displayContext()),
|
|
210
|
+
return emit(output, refusal, () => renderDebtShow(refusal, displayContext()), "refused");
|
|
211
211
|
}
|
|
212
212
|
if (isWorldObservationAction(command)) {
|
|
213
|
-
return emit(output, { kind: "absent" }, () => "debt world absent",
|
|
213
|
+
return emit(output, { kind: "absent" }, () => "debt world absent", "refused");
|
|
214
214
|
}
|
|
215
215
|
if (command.action === "context") {
|
|
216
216
|
const result = { kind: "accepted", value: { namespace: [], source: "default-root" } };
|
|
217
|
-
return emit(output, result, () => renderDebtContext(result, displayContext()),
|
|
217
|
+
return emit(output, result, () => renderDebtContext(result, displayContext()), debtOutcome(result));
|
|
218
218
|
}
|
|
219
219
|
if (command.action === "tree") {
|
|
220
220
|
const result = missingDebt(command.positionals[0]);
|
|
221
|
-
return emit(output, result, () => renderDebtTree(result, displayContext()),
|
|
221
|
+
return emit(output, result, () => renderDebtTree(result, displayContext()), debtOutcome(result));
|
|
222
222
|
}
|
|
223
223
|
if (command.action === "update") {
|
|
224
224
|
const result = missingDebt(command.positionals[0]);
|
|
225
|
-
return emit(output, result, () => renderDebtUpdate(result, displayContext()),
|
|
225
|
+
return emit(output, result, () => renderDebtUpdate(result, displayContext()), debtOutcome(result));
|
|
226
226
|
}
|
|
227
227
|
if (command.action !== "done" && command.action !== "drop")
|
|
228
228
|
throw new Error(`debt action has no missing-world answer: ${command.action}`);
|
|
229
229
|
const result = {
|
|
230
230
|
items: command.positionals.map((id) => ({ id: id, outcome: missingDebt(id) })),
|
|
231
231
|
};
|
|
232
|
-
return emit(output, result, () => renderDebtLifecycle(command.action, result, displayContext()),
|
|
232
|
+
return emit(output, result, () => renderDebtLifecycle(command.action, result, displayContext()), debtOutcome(result));
|
|
233
233
|
}
|
|
234
234
|
/** One plural Debt lifecycle answer: every verb shares the same batch shape and renderer. */
|
|
235
235
|
async function runBatchLifecycle(debts, command, verb) {
|
|
@@ -239,7 +239,7 @@ async function runBatchLifecycle(debts, command, verb) {
|
|
|
239
239
|
ids: command.positionals,
|
|
240
240
|
...(note === undefined ? {} : { note }),
|
|
241
241
|
});
|
|
242
|
-
return emit(command.output, result, () => renderDebtLifecycle(verb, result, displayContext()),
|
|
242
|
+
return emit(command.output, result, () => renderDebtLifecycle(verb, result, displayContext()), debtOutcome(result));
|
|
243
243
|
}
|
|
244
244
|
async function runMutation(input) {
|
|
245
245
|
const { debts, command } = input;
|
|
@@ -248,11 +248,11 @@ async function runMutation(input) {
|
|
|
248
248
|
switch (command.action) {
|
|
249
249
|
case "add": {
|
|
250
250
|
const result = await invokeAdd(input);
|
|
251
|
-
return emit(command.output, result, () => renderDebtMutation("add", result, displayContext()),
|
|
251
|
+
return emit(command.output, result, () => renderDebtMutation("add", result, displayContext()), debtOutcome(result));
|
|
252
252
|
}
|
|
253
253
|
case "update": {
|
|
254
254
|
const result = await invokeUpdate(input);
|
|
255
|
-
return emit(command.output, result, () => renderDebtUpdate(result, displayContext()),
|
|
255
|
+
return emit(command.output, result, () => renderDebtUpdate(result, displayContext()), debtOutcome(result));
|
|
256
256
|
}
|
|
257
257
|
case "done":
|
|
258
258
|
case "drop":
|
|
@@ -276,10 +276,10 @@ function refuseNamespace(command, refusal) {
|
|
|
276
276
|
case "blocked":
|
|
277
277
|
case "query": {
|
|
278
278
|
const action = command.action;
|
|
279
|
-
return emit(command.output, result, () => renderDebtList(action, listPresentation(command), result, displayContext()),
|
|
279
|
+
return emit(command.output, result, () => renderDebtList(action, listPresentation(command), result, displayContext()), debtOutcome(result));
|
|
280
280
|
}
|
|
281
281
|
case "add":
|
|
282
|
-
return emit(command.output, result, () => renderDebtMutation("add", result, displayContext()),
|
|
282
|
+
return emit(command.output, result, () => renderDebtMutation("add", result, displayContext()), debtOutcome(result));
|
|
283
283
|
default:
|
|
284
284
|
throw new Error(`debt action has no namespace refusal: ${command.action}`);
|
|
285
285
|
}
|
|
@@ -307,7 +307,7 @@ async function runContext(command, context) {
|
|
|
307
307
|
const result = typeof resolved === "object" && "kind" in resolved
|
|
308
308
|
? { kind: "refused", refusal: resolved }
|
|
309
309
|
: { kind: "accepted", value: resolved };
|
|
310
|
-
return emit(command.output, result, () => renderDebtContext(result, displayContext()),
|
|
310
|
+
return emit(command.output, result, () => renderDebtContext(result, displayContext()), debtOutcome(result));
|
|
311
311
|
}
|
|
312
312
|
// eslint-disable-next-line complexity -- this is the single CLI edge ordering world, context, forwarding, and local execution.
|
|
313
313
|
export async function runDebtCommand(command, coordinates, runtime) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CliOutcome } from "../streams.js";
|
|
1
2
|
import type { ProcessInput, ProcessOutcome } from "../../runtime/proc/run.js";
|
|
2
3
|
declare const HARNESS_NAMES: readonly ["codex", "claude", "opencode", "pi"];
|
|
3
4
|
type HarnessName = (typeof HARNESS_NAMES)[number];
|
|
@@ -22,5 +23,5 @@ export declare function parseInstallCommand(argv: readonly string[]): ParsedInst
|
|
|
22
23
|
export declare function renderInstallHelp(): string;
|
|
23
24
|
export declare function installHarnesses(harnesses: readonly HarnessName[], environment: NodeJS.ProcessEnv, runner?: InstallRunner): Promise<InstallInvocationResult>;
|
|
24
25
|
export declare function renderInstallText(result: InstallInvocationResult): string;
|
|
25
|
-
export declare function
|
|
26
|
+
export declare function installOutcome(result: InstallInvocationResult): CliOutcome;
|
|
26
27
|
export {};
|