@astrosheep/keiyaku 4.0.5 → 4.0.6

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.
Files changed (153) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +1 -1
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +15 -7
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -3
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +10 -4
  8. package/build/src/akuma/akuma.d.ts +2 -0
  9. package/build/src/akuma/akuma.js +26 -3
  10. package/build/src/akuma/archetype.d.ts +3 -1
  11. package/build/src/akuma/archetype.js +11 -6
  12. package/build/src/akuma/body-turn.d.ts +64 -0
  13. package/build/src/akuma/body-turn.js +449 -0
  14. package/build/src/akuma/body.d.ts +3 -7
  15. package/build/src/akuma/body.js +9 -420
  16. package/build/src/akuma/heart/facts.d.ts +2 -0
  17. package/build/src/akuma/heart/facts.js +3 -1
  18. package/build/src/akuma/heart/index.js +12 -2
  19. package/build/src/akuma/heart/rows.js +4 -1
  20. package/build/src/akuma/heart/schema.d.ts +1 -1
  21. package/build/src/akuma/heart/schema.js +3 -2
  22. package/build/src/akuma/heart/timeline.d.ts +1 -0
  23. package/build/src/akuma/heart/timeline.js +19 -0
  24. package/build/src/akuma/nuke.d.ts +2 -0
  25. package/build/src/akuma/nuke.js +152 -0
  26. package/build/src/akuma/provider.d.ts +3 -1
  27. package/build/src/akuma/providers/acp/config.d.ts +8 -0
  28. package/build/src/akuma/providers/acp/config.js +37 -0
  29. package/build/src/akuma/providers/acp/core.js +6 -0
  30. package/build/src/akuma/providers/acp/index.d.ts +1 -8
  31. package/build/src/akuma/providers/acp/index.js +2 -37
  32. package/build/src/akuma/providers/claude/index.js +5 -0
  33. package/build/src/akuma/providers/codex-app-server/index.js +5 -0
  34. package/build/src/akuma/providers/grok-build/index.js +1 -1
  35. package/build/src/akuma/providers/index.d.ts +3 -2
  36. package/build/src/akuma/providers/index.js +36 -36
  37. package/build/src/akuma/providers/opencode-sdk/index.js +6 -0
  38. package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
  39. package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
  40. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  41. package/build/src/akuma/providers/pi/index.js +27 -11
  42. package/build/src/akuma/request-serve.d.ts +1 -0
  43. package/build/src/akuma/request-serve.js +31 -31
  44. package/build/src/akuma/request-wire.d.ts +3 -2
  45. package/build/src/akuma/request-wire.js +5 -2
  46. package/build/src/akuma-body.js +15 -1
  47. package/build/src/alias/index.d.ts +1 -0
  48. package/build/src/alias/index.js +34 -1
  49. package/build/src/cli/accepted.js +4 -0
  50. package/build/src/cli/commands/akuma-invoke.js +1 -0
  51. package/build/src/cli/commands/akuma.d.ts +1 -0
  52. package/build/src/cli/commands/akuma.js +11 -8
  53. package/build/src/cli/commands/contract.d.ts +25 -14
  54. package/build/src/cli/commands/contract.js +23 -17
  55. package/build/src/cli/commands/install.d.ts +2 -2
  56. package/build/src/cli/commands/install.js +6 -6
  57. package/build/src/cli/commands/nuke.d.ts +10 -0
  58. package/build/src/cli/commands/nuke.js +20 -0
  59. package/build/src/cli/commands/task-invoke.d.ts +15 -0
  60. package/build/src/cli/commands/task-invoke.js +57 -26
  61. package/build/src/cli/commands/task-query.d.ts +2 -2
  62. package/build/src/cli/commands/task-query.js +1 -2
  63. package/build/src/cli/commands/task.js +22 -22
  64. package/build/src/cli/coordinates.d.ts +5 -2
  65. package/build/src/cli/coordinates.js +5 -52
  66. package/build/src/cli/invoke.d.ts +5 -4
  67. package/build/src/cli/invoke.js +89 -59
  68. package/build/src/cli/main.d.ts +0 -2
  69. package/build/src/cli/main.js +4 -140
  70. package/build/src/cli/parse.d.ts +15 -2
  71. package/build/src/cli/parse.js +73 -8
  72. package/build/src/cli/render/akuma.js +55 -40
  73. package/build/src/cli/render/contract.js +49 -48
  74. package/build/src/cli/render/kanshi.js +15 -5
  75. package/build/src/cli/render/nuke.d.ts +3 -0
  76. package/build/src/cli/render/nuke.js +8 -0
  77. package/build/src/cli/render/refusal.d.ts +2 -1
  78. package/build/src/cli/render/refusal.js +31 -0
  79. package/build/src/cli/render/text.js +6 -1
  80. package/build/src/cli/result.d.ts +21 -2
  81. package/build/src/cli/runtime.d.ts +2 -0
  82. package/build/src/cli/runtime.js +140 -0
  83. package/build/src/cli/usage.d.ts +0 -2
  84. package/build/src/cli/usage.js +0 -4
  85. package/build/src/contract-worktree.d.ts +28 -12
  86. package/build/src/contract-worktree.js +129 -63
  87. package/build/src/git/hooks.d.ts +2 -0
  88. package/build/src/git/hooks.js +34 -1
  89. package/build/src/git/integration.d.ts +4 -0
  90. package/build/src/git/integration.js +38 -0
  91. package/build/src/git/nuke.d.ts +2 -0
  92. package/build/src/git/nuke.js +97 -0
  93. package/build/src/git/process.d.ts +2 -0
  94. package/build/src/git/reconcile.d.ts +2 -0
  95. package/build/src/git/reconcile.js +33 -2
  96. package/build/src/git/repository.js +4 -1
  97. package/build/src/git/target-placement.d.ts +2 -1
  98. package/build/src/git/target-placement.js +6 -7
  99. package/build/src/git/tender.d.ts +1 -0
  100. package/build/src/git/tender.js +2 -2
  101. package/build/src/git/workspace.d.ts +3 -0
  102. package/build/src/kanshi/read.js +5 -1
  103. package/build/src/library/akuma-creation.d.ts +1 -0
  104. package/build/src/library/akuma-creation.js +8 -1
  105. package/build/src/library/audit.d.ts +1 -0
  106. package/build/src/library/audit.js +1 -0
  107. package/build/src/library/contract.d.ts +6 -4
  108. package/build/src/library/contract.js +56 -34
  109. package/build/src/library/delivery.d.ts +3 -1
  110. package/build/src/library/keiyaku.d.ts +5 -1
  111. package/build/src/library/keiyaku.js +2 -0
  112. package/build/src/library/mutation.d.ts +1 -0
  113. package/build/src/library/mutation.js +3 -0
  114. package/build/src/library/nuke.d.ts +14 -0
  115. package/build/src/library/nuke.js +54 -0
  116. package/build/src/library/reconcile.js +5 -2
  117. package/build/src/library/refusal.d.ts +10 -1
  118. package/build/src/library/repo.d.ts +1 -0
  119. package/build/src/library/repo.js +2 -0
  120. package/build/src/protocol/audit.js +12 -5
  121. package/build/src/protocol/completion.d.ts +11 -1
  122. package/build/src/protocol/completion.js +68 -15
  123. package/build/src/protocol/deliver.d.ts +14 -2
  124. package/build/src/protocol/deliver.js +107 -6
  125. package/build/src/protocol/intent.d.ts +1 -0
  126. package/build/src/protocol/intent.js +7 -1
  127. package/build/src/protocol/operations.d.ts +30 -3
  128. package/build/src/protocol/operations.js +2 -2
  129. package/build/src/protocol/placement.d.ts +9 -1
  130. package/build/src/protocol/placement.js +5 -4
  131. package/build/src/protocol/read/status.d.ts +16 -4
  132. package/build/src/protocol/read/status.js +54 -12
  133. package/build/src/protocol/review.d.ts +1 -0
  134. package/build/src/protocol/review.js +8 -0
  135. package/build/src/runtime/proc/run.js +9 -5
  136. package/build/src/settlement/fence.d.ts +2 -0
  137. package/build/src/settlement/fence.js +24 -0
  138. package/build/src/settlement/settle.js +1 -2
  139. package/build/src/task/compose.d.ts +1 -1
  140. package/build/src/task/compose.js +2 -7
  141. package/build/src/task/context.d.ts +14 -2
  142. package/build/src/task/context.js +30 -7
  143. package/build/src/task/index.d.ts +6 -5
  144. package/build/src/task/index.js +15 -18
  145. package/build/src/task/mutation.d.ts +7 -2
  146. package/build/src/task/mutation.js +14 -6
  147. package/build/src/task/operations.d.ts +12 -6
  148. package/build/src/task/operations.js +22 -46
  149. package/build/src/task/store.d.ts +1 -0
  150. package/build/src/task/store.js +91 -1
  151. package/build/src/workspace-place.d.ts +2 -0
  152. package/build/src/workspace-place.js +27 -1
  153. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  import { type AkuId } from "./identity.js";
2
2
  import { decodeProviderOptions, type ReadonlyRestraint } from "./provider-recipe.js";
3
- import { resolveProviderExecution } from "./providers/index.js";
3
+ import { decodeProviderExecution } from "./providers/index.js";
4
4
  import { type TaskMutationAction, type TaskMutationRequest } from "../task/mutation.js";
5
5
  export type RequestRecipe = Readonly<{
6
6
  description?: string;
7
7
  allowed: readonly string[];
8
- provider: ReturnType<typeof resolveProviderExecution>["execution"];
8
+ provider: ReturnType<typeof decodeProviderExecution>;
9
9
  options: ReturnType<typeof decodeProviderOptions>;
10
10
  readonly?: ReadonlyRestraint;
11
11
  }>;
@@ -43,6 +43,7 @@ export type DeliverRequestClaim = Readonly<{
43
43
  contractId: string;
44
44
  message?: string;
45
45
  includeDirty: boolean;
46
+ materializeConflict: boolean;
46
47
  }>;
47
48
  export type ReviewRequestClaim = Readonly<{
48
49
  id: string;
@@ -4,7 +4,7 @@ import { isAbsolute, join, resolve } from "node:path";
4
4
  import { decodeAllowedActions } from "./allowed.js";
5
5
  import { archetypeName, parseAkuId } from "./identity.js";
6
6
  import { decodeProviderOptions, decodeReadonlyRestraint, } from "./provider-recipe.js";
7
- import { resolveProviderExecution } from "./providers/index.js";
7
+ import { decodeProviderExecution } from "./providers/index.js";
8
8
  import { decodeTaskMutationRequest, isTaskMutationAction, } from "../task/mutation.js";
9
9
  const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
10
10
  function object(value) {
@@ -69,7 +69,7 @@ export function decodeRecipe(value) {
69
69
  return Object.freeze({
70
70
  ...(recipe.description === undefined ? {} : { description: recipe.description }),
71
71
  allowed: decodeAllowedActions(recipe.allowed),
72
- provider: resolveProviderExecution(recipe.provider).execution,
72
+ provider: decodeProviderExecution(recipe.provider),
73
73
  options,
74
74
  ...(readonly === undefined ? {} : { readonly }),
75
75
  });
@@ -153,6 +153,7 @@ function decodeDeliver(id, payload) {
153
153
  const valid = exactKeys(payload, [
154
154
  "contractId",
155
155
  "includeDirty",
156
+ "materializeConflict",
156
157
  "repoRoot",
157
158
  ...(payload.message === undefined ? [] : ["message"]),
158
159
  ]);
@@ -161,6 +162,7 @@ function decodeDeliver(id, payload) {
161
162
  && selected !== null
162
163
  && absolute(payload.repoRoot)
163
164
  && typeof payload.includeDirty === "boolean"
165
+ && typeof payload.materializeConflict === "boolean"
164
166
  && (payload.message === undefined
165
167
  || (typeof payload.message === "string"
166
168
  && payload.message.trim().length > 0))
@@ -170,6 +172,7 @@ function decodeDeliver(id, payload) {
170
172
  repoRoot: payload.repoRoot,
171
173
  contractId: selected,
172
174
  includeDirty: payload.includeDirty,
175
+ materializeConflict: payload.materializeConflict,
173
176
  ...(payload.message === undefined
174
177
  ? {}
175
178
  : { message: payload.message }),
@@ -48,6 +48,7 @@ export function upstreamFor(launch, processConfiguration) {
48
48
  requester: input.requester,
49
49
  ...(input.message === undefined ? {} : { message: input.message }),
50
50
  includeDirty: input.includeDirty,
51
+ materializeConflict: input.materializeConflict,
51
52
  requireBranchesToBeUpToDate: requireBranchesToBeUpToDateFrom({ settings: configuration }),
52
53
  hooks: worktreeHooksFrom({ settings: configuration }),
53
54
  signal: input.signal,
@@ -81,4 +82,17 @@ export function upstreamFor(launch, processConfiguration) {
81
82
  }),
82
83
  };
83
84
  }
84
- await runAkumaBody(upstreamFor);
85
+ const encoded = process.argv[2];
86
+ if (encoded === undefined)
87
+ throw new TypeError("Akuma body launch payload is missing");
88
+ const launch = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
89
+ const mappedHome = process.env.KEIYAKU_HOME?.trim();
90
+ const mappedGitPath = process.env.KEIYAKU_GIT_PATH;
91
+ if (mappedGitPath !== undefined && mappedGitPath.trim().length === 0) {
92
+ throw new TypeError("KEIYAKU_GIT_PATH requires a nonblank value");
93
+ }
94
+ const configuration = {
95
+ ...(mappedHome === undefined || mappedHome.length === 0 ? {} : { home: mappedHome }),
96
+ ...(mappedGitPath === undefined ? {} : { gitPath: mappedGitPath }),
97
+ };
98
+ await runAkumaBody(launch, upstreamFor(launch, configuration));
@@ -9,6 +9,7 @@ export type AliasMove = Readonly<{
9
9
  alias: AliasBinding;
10
10
  previous: AkuId | null;
11
11
  }>;
12
+ export declare function nukeAliases(world: WorldRoot): Promise<void>;
12
13
  export declare function readAliases(world: WorldRoot): Promise<readonly AliasBinding[]>;
13
14
  export declare function resolveAlias(world: WorldRoot, value: AkumaAlias): Promise<AkuId | null>;
14
15
  export declare function moveAlias(input: Readonly<{
@@ -1,4 +1,4 @@
1
- import { mkdir, readFile } from "node:fs/promises";
1
+ import { lstat, mkdir, readFile, unlink } from "node:fs/promises";
2
2
  import { dirname, resolve } from "node:path";
3
3
  import { parseAkuId } from "../akuma/identity.js";
4
4
  import { replaceFileDurably } from "../coordination/durable-file.js";
@@ -77,6 +77,39 @@ async function read(path) {
77
77
  throw error;
78
78
  }
79
79
  }
80
+ async function regularFile(path) {
81
+ try {
82
+ const value = await lstat(path);
83
+ if (!value.isFile() || value.isSymbolicLink())
84
+ throw new Error(`Alias custody is not a regular file: ${path}`);
85
+ return true;
86
+ }
87
+ catch (error) {
88
+ if (error.code === "ENOENT")
89
+ return false;
90
+ throw error;
91
+ }
92
+ }
93
+ export async function nukeAliases(world) {
94
+ const location = paths(world);
95
+ const initialAuthority = await regularFile(location.authority);
96
+ const initialLock = await regularFile(location.lock);
97
+ if (!initialAuthority && !initialLock)
98
+ return;
99
+ const held = await acquireSqliteTransactionLock({ path: location.lock, mode: "immediate" });
100
+ try {
101
+ // Alias writers use this same custody lock. Observe after acquiring it so
102
+ // an authority committed by a prior holder is part of this reset sweep.
103
+ const authorityPresent = await regularFile(location.authority);
104
+ if (authorityPresent) {
105
+ await read(location.authority);
106
+ await unlink(location.authority);
107
+ }
108
+ }
109
+ finally {
110
+ held.close();
111
+ }
112
+ }
80
113
  export async function readAliases(world) {
81
114
  return await read(paths(world).authority);
82
115
  }
@@ -51,9 +51,11 @@ export function acceptedDeliver(result, coordinate) {
51
51
  return {
52
52
  ...acceptedEnvelope(result, coordinate),
53
53
  verb: "deliver",
54
+ ...(value.completion === undefined ? {} : { completion: value.completion }),
54
55
  ...(verificationVerdict === undefined ? {} : { verificationVerdict }),
55
56
  ...(value.verification === undefined ? {} : { verification: value.verification }),
56
57
  ...(value.verificationReuse === undefined ? {} : { verificationReuse: value.verificationReuse }),
58
+ ...(value.verificationSummary === undefined ? {} : { verificationSummary: value.verificationSummary }),
57
59
  ...(value.placement === undefined ? {} : { placement: value.placement }),
58
60
  ...(value.cleanup === undefined ? {} : { cleanup: value.cleanup }),
59
61
  ...(value.leak === undefined ? {} : { leak: value.leak }),
@@ -70,9 +72,11 @@ export function acceptedReview(result, coordinate) {
70
72
  ...acceptedEnvelope(result, coordinate),
71
73
  verb: "review",
72
74
  verdict: reviewAttestation.data.verdict,
75
+ ...(value.completion === undefined ? {} : { completion: value.completion }),
73
76
  ...(verificationVerdict === undefined ? {} : { verificationVerdict }),
74
77
  ...(value.verification === undefined ? {} : { verification: value.verification }),
75
78
  ...(value.verificationReuse === undefined ? {} : { verificationReuse: value.verificationReuse }),
79
+ ...(value.verificationSummary === undefined ? {} : { verificationSummary: value.verificationSummary }),
76
80
  ...(value.placement === undefined ? {} : { placement: value.placement }),
77
81
  ...(value.workspace === undefined ? {} : { workspace: value.workspace }),
78
82
  ...(value.cleanup === undefined ? {} : { cleanup: value.cleanup }),
@@ -102,6 +102,7 @@ export async function invokeAkuma(command, input) {
102
102
  ...(input.statedCwd === undefined ? {} : { cwd: input.statedCwd }),
103
103
  mode: command.mode,
104
104
  ...(command.timeoutMs === undefined ? {} : { timeoutMs: command.timeoutMs }),
105
+ ...(command.readonly === undefined ? {} : { readonly: command.readonly }),
105
106
  ...(input.contract === undefined ? {} : { contract: input.contract }),
106
107
  ...(command.alias === undefined ? {} : { alias: command.alias }),
107
108
  ...(command.allowed === undefined ? {} : { allowed: command.allowed }),
@@ -22,6 +22,7 @@ export type ParsedAkumaCommand = Output & ((Readonly<{
22
22
  alias?: AkumaAlias;
23
23
  mode: "wait" | "detach";
24
24
  timeoutMs?: number;
25
+ readonly?: true;
25
26
  allowed?: AllowedActions;
26
27
  }> & Prompted) | Readonly<{
27
28
  command: "kill";
@@ -1,4 +1,4 @@
1
- import { CliUsageError, isBlankInput, usageLine, withJsonAutomationHelp } from "../usage.js";
1
+ import { CliUsageError, isBlankInput, usageLine } from "../usage.js";
2
2
  import { archetypeName, parseAkuId } from "../../akuma/identity.js";
3
3
  import { parseDuration as decodeDuration } from "../../duration.js";
4
4
  import { parseAkumaAlias, parseAkumaGlob } from "../../identity/selector.js";
@@ -12,16 +12,18 @@ const AKUMA_COMMAND_SPECS = {
12
12
  alias: "value",
13
13
  wait: "value",
14
14
  detach: "boolean",
15
+ readonly: "boolean",
15
16
  allowed: "repeatable",
16
17
  json: "boolean",
17
18
  },
18
- usage: "call <akuma-name> [--contract <kei/...>] [--alias @name] [--allowed <product.action>]... [--wait <duration> | -d | --detach] [--json] (<prompt> | -)",
19
+ usage: "call <akuma-name> [--contract <kei/...>] [--alias @name] [--readonly] [--allowed <product.action>]... [--wait <duration> | -d | --detach] (<prompt> | -)",
19
20
  purpose: "Birth an Akuma from <akuma-name> with one prompt.",
20
21
  details: [
21
22
  "Give <prompt> as one argument, or use final - to read stdin.",
22
23
  "Default: --wait 5m. An explicit --wait replaces that duration; -d and --detach return after birth.",
23
24
  "--contract dispatches the born Akuma to that Contract.",
24
25
  "--alias assigns the world-local @name selector to the born Akuma.",
26
+ "--readonly adds the one-way read-only birth restriction.",
25
27
  "Repeated --allowed replaces the Archetype list; --allowed none selects an empty list.",
26
28
  "With --contract, Dispatch succeeds first. If @name exists, the alias then moves.",
27
29
  ].join("\n"),
@@ -30,14 +32,14 @@ const AKUMA_COMMAND_SPECS = {
30
32
  arity: "one-or-more",
31
33
  stdin: false,
32
34
  flags: { any: "boolean", all: "boolean", timeout: "value", json: "boolean" },
33
- usage: "wait <akuma-selector>... [--any | --all] [--timeout <duration>] [--json]",
35
+ usage: "wait <akuma-selector>... [--any | --all] [--timeout <duration>]",
34
36
  purpose: "Wait for one Akuma or an explicitly selected Akuma set.",
35
37
  },
36
38
  tell: {
37
39
  arity: 1,
38
40
  stdin: true,
39
41
  flags: { interrupt: "boolean", json: "boolean" },
40
- usage: "tell <aku/...|@alias> [--interrupt] [--json] (<prompt> | -)",
42
+ usage: "tell <aku/...|@alias> [--interrupt] (<prompt> | -)",
41
43
  purpose: "Send one prompt to an existing Akuma and wake it.",
42
44
  details: [
43
45
  "Give <prompt> as one argument, or use final - to read stdin.",
@@ -48,21 +50,21 @@ const AKUMA_COMMAND_SPECS = {
48
50
  arity: 1,
49
51
  stdin: false,
50
52
  flags: { before: "value", since: "value", limit: "value", last: "boolean", json: "boolean" },
51
- usage: "history <aku/...|@alias|kei/...> [--before <index> | --since <index>] [--limit <count>] [--last] [--json]",
53
+ usage: "history <aku/...|@alias|kei/...> [--before <index> | --since <index>] [--limit <count>] [--last]",
52
54
  purpose: "Read Akuma execution history or one complete Contract journal and Dispatch timeline.",
53
55
  },
54
56
  fork: {
55
57
  arity: 1,
56
58
  stdin: false,
57
59
  flags: { at: "value", json: "boolean" },
58
- usage: "fork <aku/...> --at <historyId> [--json]",
60
+ usage: "fork <aku/...> --at <historyId>",
59
61
  purpose: "Fork one Akuma at a retained answered history point.",
60
62
  },
61
63
  kill: {
62
64
  arity: "one-or-more",
63
65
  stdin: false,
64
66
  flags: { json: "boolean" },
65
- usage: "kill <akuma-selector>... [--json]",
67
+ usage: "kill <akuma-selector>...",
66
68
  purpose: "Put down the current Body of an Akuma selector snapshot.",
67
69
  },
68
70
  };
@@ -77,7 +79,7 @@ export function renderAkumaRootRows() {
77
79
  }
78
80
  export function renderAkumaHelp(action) {
79
81
  const spec = AKUMA_COMMAND_SPECS[action];
80
- return withJsonAutomationHelp(`${spec.purpose}\n\n${usageLine(spec.usage)}${spec.details === undefined ? "" : `\n\n${spec.details}`}`);
82
+ return `${spec.purpose}\n\n${usageLine(spec.usage)}${spec.details === undefined ? "" : `\n\n${spec.details}`}`;
81
83
  }
82
84
  export function renderAkumaUsage(action) {
83
85
  return usageLine(AKUMA_COMMAND_SPECS[action].usage);
@@ -305,6 +307,7 @@ function parseCall(flags, archetype, prompt, output, fail) {
305
307
  ...(alias === undefined ? {} : { alias }),
306
308
  mode,
307
309
  ...(timeoutMs === undefined ? {} : { timeoutMs }),
310
+ ...(flags.readonly === true ? { readonly: true } : {}),
308
311
  ...(allowed === undefined ? {} : { allowed }),
309
312
  prompt,
310
313
  output,
@@ -6,7 +6,7 @@ export type ContractCommandSpec = Readonly<{
6
6
  usage: string;
7
7
  purpose: string;
8
8
  }>;
9
- export declare const AMEND_MINIMAL_STDIN_HELP: string;
9
+ export declare const AMEND_OPERATIONS_HELP: string;
10
10
  export declare const CONTRACT_COMMAND_SPECS: {
11
11
  readonly bind: {
12
12
  readonly positional: "none";
@@ -20,7 +20,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
20
20
  readonly gates: "raw-value";
21
21
  readonly json: "boolean";
22
22
  };
23
- readonly usage: "bind [--task <task/...>] [--target <ref>] [--here] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] [--json] -";
23
+ readonly usage: "bind [--task <task/...>] [--target <ref>] [--here] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] -";
24
24
  readonly purpose: "Create one Contract from stdin Markdown.";
25
25
  };
26
26
  readonly amend: {
@@ -33,7 +33,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
33
33
  readonly gates: "raw-value";
34
34
  readonly json: "boolean";
35
35
  };
36
- readonly usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name,...>] [--actor <actor>] [--json] [-]";
36
+ readonly usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name,...>] [--actor <actor>] [-]";
37
37
  readonly purpose: "Amend one Contract's document operations or structured terms.";
38
38
  };
39
39
  readonly deliver: {
@@ -43,9 +43,10 @@ export declare const CONTRACT_COMMAND_SPECS: {
43
43
  readonly actor: "value";
44
44
  readonly message: "value";
45
45
  readonly "include-dirty": "boolean";
46
+ readonly "materialize-conflict": "boolean";
46
47
  readonly json: "boolean";
47
48
  };
48
- readonly usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--actor <actor>] [--json]";
49
+ readonly usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--materialize-conflict] [--actor <actor>]";
49
50
  readonly purpose: "Deliver one Contract candidate.";
50
51
  };
51
52
  readonly review: {
@@ -58,7 +59,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
58
59
  readonly summary: "value";
59
60
  readonly json: "boolean";
60
61
  };
61
- readonly usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>] [--json]";
62
+ readonly usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>]";
62
63
  readonly purpose: "Record one review verdict.";
63
64
  };
64
65
  readonly arc: {
@@ -68,7 +69,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
68
69
  readonly actor: "value";
69
70
  readonly json: "boolean";
70
71
  };
71
- readonly usage: "arc [<contract>|@<contract>] [--actor <actor>] [--json] -";
72
+ readonly usage: "arc [<contract>|@<contract>] [--actor <actor>] -";
72
73
  readonly purpose: "Record stdin arc Markdown for one Contract.";
73
74
  };
74
75
  readonly abandon: {
@@ -79,7 +80,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
79
80
  readonly note: "value";
80
81
  readonly json: "boolean";
81
82
  };
82
- readonly usage: "abandon [<contract>|@<contract>] [--note <text>] [--actor <actor>] [--json]";
83
+ readonly usage: "abandon [<contract>|@<contract>] [--note <text>] [--actor <actor>]";
83
84
  readonly purpose: "Abandon one Contract with an optional note.";
84
85
  };
85
86
  readonly status: {
@@ -88,7 +89,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
88
89
  readonly flags: {
89
90
  readonly json: "boolean";
90
91
  };
91
- readonly usage: "status [<contract>|@name|<aku/...>] [--json]";
92
+ readonly usage: "status [<contract>|@name|<aku/...>]";
92
93
  readonly purpose: "Read the world status board or one Contract projection.";
93
94
  };
94
95
  readonly show: {
@@ -97,7 +98,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
97
98
  readonly flags: {
98
99
  readonly json: "boolean";
99
100
  };
100
- readonly usage: "show [<contract>|@<contract>] [--json]";
101
+ readonly usage: "show [<contract>|@<contract>]";
101
102
  readonly purpose: "Read one Contract guidance projection.";
102
103
  };
103
104
  readonly ls: {
@@ -106,7 +107,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
106
107
  readonly flags: {
107
108
  readonly json: "boolean";
108
109
  };
109
- readonly usage: "ls task[/] [--json]\n keiyaku ls kei[/] [--json]\n keiyaku ls aku[/] [--json]\n keiyaku ls aku/<akuma>[/] [--json]\n keiyaku ls \"aku/*/*\" [--json]";
110
+ readonly usage: "ls task[/]\n keiyaku ls kei[/]\n keiyaku ls aku[/]\n keiyaku ls aku/<akuma>[/]\n keiyaku ls \"aku/*/*\"";
110
111
  readonly purpose: "List one identity directory.";
111
112
  };
112
113
  readonly audit: {
@@ -118,7 +119,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
118
119
  readonly actor: "value";
119
120
  readonly json: "boolean";
120
121
  };
121
- readonly usage: "audit [<contract>|@<contract>] [--include-dirty] [--diff] [--actor <actor>] [--json]";
122
+ readonly usage: "audit [<contract>|@<contract>] [--include-dirty] [--diff] [--actor <actor>]";
122
123
  readonly purpose: "Ask what candidate preparation, Verification, and target placement would do.";
123
124
  };
124
125
  readonly reconcile: {
@@ -128,16 +129,26 @@ export declare const CONTRACT_COMMAND_SPECS: {
128
129
  readonly "retry-hooks": "boolean";
129
130
  readonly json: "boolean";
130
131
  };
131
- readonly usage: "reconcile [<contract>|@<contract>] [--retry-hooks] [--json]";
132
+ readonly usage: "reconcile [<contract>|@<contract>] [--retry-hooks]";
132
133
  readonly purpose: "Reconcile one Contract or the invocation world.";
133
134
  };
135
+ readonly nuke: {
136
+ readonly positional: "none";
137
+ readonly stdin: "none";
138
+ readonly flags: {
139
+ readonly confirm: "value";
140
+ readonly json: "boolean";
141
+ };
142
+ readonly usage: "nuke [--confirm <WorldRoot>]";
143
+ readonly purpose: "Remove Keiyaku-owned data from one confirmed World.";
144
+ };
134
145
  readonly settings: {
135
146
  readonly positional: "none";
136
147
  readonly stdin: "none";
137
148
  readonly flags: {
138
149
  readonly json: "boolean";
139
150
  };
140
- readonly usage: "settings [--json]";
151
+ readonly usage: "settings";
141
152
  readonly purpose: "Read user and project Settings resources.";
142
153
  };
143
154
  readonly region: {
@@ -148,7 +159,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
148
159
  readonly path: "value";
149
160
  readonly json: "boolean";
150
161
  };
151
- readonly usage: "region [<contract>] [--overlap] [--json]\n region --path <repo-relative-path> [--json]";
162
+ readonly usage: "region [<contract>] [--overlap]\n region --path <repo-relative-path>";
152
163
  readonly purpose: "Read active declared Contract Regions.";
153
164
  };
154
165
  };
@@ -1,20 +1,26 @@
1
- export const AMEND_MINIMAL_STDIN_HELP = [
2
- "minimal stdin:",
3
- " ## Replace: Design",
4
- " <complete replacement>",
1
+ export const AMEND_OPERATIONS_HELP = [
2
+ "stdin operations (H2 sections only, no H1):",
3
+ " ## Replace: Context|Objective|Design|Region|Criteria|Verification|<extension>",
4
+ " ## Append: Context|Objective|Design|Criteria|<extension>",
5
+ " ## Add: Criteria|<new-extension-title>",
6
+ " ## Update: Criterion <existing-title>|<existing-extension-title>",
7
+ " ## Remove: Criterion <existing-title>|<existing-extension-title>",
8
+ "",
9
+ "full operation grammar: docs/document.md, Amend Operations",
5
10
  ].join("\n");
6
11
  export const CONTRACT_COMMAND_SPECS = {
7
- bind: { positional: "none", stdin: "required", flags: { actor: "value", task: "value", target: "value", here: "boolean", after: "repeat-value", gates: "raw-value", json: "boolean" }, usage: "bind [--task <task/...>] [--target <ref>] [--here] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] [--json] -", purpose: "Create one Contract from stdin Markdown." },
8
- amend: { positional: "optional", stdin: "optional", flags: { actor: "value", after: "repeat-value", "clear-after": "boolean", gates: "raw-value", json: "boolean" }, usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name,...>] [--actor <actor>] [--json] [-]", purpose: "Amend one Contract's document operations or structured terms." },
9
- deliver: { positional: "optional", stdin: "none", flags: { actor: "value", message: "value", "include-dirty": "boolean", json: "boolean" }, usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--actor <actor>] [--json]", purpose: "Deliver one Contract candidate." },
10
- review: { positional: "optional", stdin: "optional", flags: { actor: "value", satisfied: "boolean", unsatisfied: "boolean", summary: "value", json: "boolean" }, usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>] [--json]", purpose: "Record one review verdict." },
11
- arc: { positional: "optional", stdin: "required", flags: { actor: "value", json: "boolean" }, usage: "arc [<contract>|@<contract>] [--actor <actor>] [--json] -", purpose: "Record stdin arc Markdown for one Contract." },
12
- abandon: { positional: "optional", stdin: "none", flags: { actor: "value", note: "value", json: "boolean" }, usage: "abandon [<contract>|@<contract>] [--note <text>] [--actor <actor>] [--json]", purpose: "Abandon one Contract with an optional note." },
13
- status: { positional: "optional", stdin: "none", flags: { json: "boolean" }, usage: "status [<contract>|@name|<aku/...>] [--json]", purpose: "Read the world status board or one Contract projection." },
14
- show: { positional: "optional", stdin: "none", flags: { json: "boolean" }, usage: "show [<contract>|@<contract>] [--json]", purpose: "Read one Contract guidance projection." },
15
- ls: { positional: "optional", stdin: "none", flags: { json: "boolean" }, usage: "ls task[/] [--json]\n keiyaku ls kei[/] [--json]\n keiyaku ls aku[/] [--json]\n keiyaku ls aku/<akuma>[/] [--json]\n keiyaku ls \"aku/*/*\" [--json]", purpose: "List one identity directory." },
16
- audit: { positional: "optional", stdin: "none", flags: { "include-dirty": "boolean", diff: "boolean", actor: "value", json: "boolean" }, usage: "audit [<contract>|@<contract>] [--include-dirty] [--diff] [--actor <actor>] [--json]", purpose: "Ask what candidate preparation, Verification, and target placement would do." },
17
- reconcile: { positional: "optional", stdin: "none", flags: { "retry-hooks": "boolean", json: "boolean" }, usage: "reconcile [<contract>|@<contract>] [--retry-hooks] [--json]", purpose: "Reconcile one Contract or the invocation world." },
18
- settings: { positional: "none", stdin: "none", flags: { json: "boolean" }, usage: "settings [--json]", purpose: "Read user and project Settings resources." },
19
- region: { positional: "optional", stdin: "none", flags: { overlap: "boolean", path: "value", json: "boolean" }, usage: "region [<contract>] [--overlap] [--json]\n region --path <repo-relative-path> [--json]", purpose: "Read active declared Contract Regions." },
12
+ bind: { positional: "none", stdin: "required", flags: { actor: "value", task: "value", target: "value", here: "boolean", after: "repeat-value", gates: "raw-value", json: "boolean" }, usage: "bind [--task <task/...>] [--target <ref>] [--here] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] -", purpose: "Create one Contract from stdin Markdown." },
13
+ amend: { positional: "optional", stdin: "optional", flags: { actor: "value", after: "repeat-value", "clear-after": "boolean", gates: "raw-value", json: "boolean" }, usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name,...>] [--actor <actor>] [-]", purpose: "Amend one Contract's document operations or structured terms." },
14
+ deliver: { positional: "optional", stdin: "none", flags: { actor: "value", message: "value", "include-dirty": "boolean", "materialize-conflict": "boolean", json: "boolean" }, usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--materialize-conflict] [--actor <actor>]", purpose: "Deliver one Contract candidate." },
15
+ review: { positional: "optional", stdin: "optional", flags: { actor: "value", satisfied: "boolean", unsatisfied: "boolean", summary: "value", json: "boolean" }, usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>]", purpose: "Record one review verdict." },
16
+ arc: { positional: "optional", stdin: "required", flags: { actor: "value", json: "boolean" }, usage: "arc [<contract>|@<contract>] [--actor <actor>] -", purpose: "Record stdin arc Markdown for one Contract." },
17
+ abandon: { positional: "optional", stdin: "none", flags: { actor: "value", note: "value", json: "boolean" }, usage: "abandon [<contract>|@<contract>] [--note <text>] [--actor <actor>]", purpose: "Abandon one Contract with an optional note." },
18
+ status: { positional: "optional", stdin: "none", flags: { json: "boolean" }, usage: "status [<contract>|@name|<aku/...>]", purpose: "Read the world status board or one Contract projection." },
19
+ show: { positional: "optional", stdin: "none", flags: { json: "boolean" }, usage: "show [<contract>|@<contract>]", purpose: "Read one Contract guidance projection." },
20
+ ls: { positional: "optional", stdin: "none", flags: { json: "boolean" }, usage: "ls task[/]\n keiyaku ls kei[/]\n keiyaku ls aku[/]\n keiyaku ls aku/<akuma>[/]\n keiyaku ls \"aku/*/*\"", purpose: "List one identity directory." },
21
+ audit: { positional: "optional", stdin: "none", flags: { "include-dirty": "boolean", diff: "boolean", actor: "value", json: "boolean" }, usage: "audit [<contract>|@<contract>] [--include-dirty] [--diff] [--actor <actor>]", purpose: "Ask what candidate preparation, Verification, and target placement would do." },
22
+ reconcile: { positional: "optional", stdin: "none", flags: { "retry-hooks": "boolean", json: "boolean" }, usage: "reconcile [<contract>|@<contract>] [--retry-hooks]", purpose: "Reconcile one Contract or the invocation world." },
23
+ nuke: { positional: "none", stdin: "none", flags: { confirm: "value", json: "boolean" }, usage: "nuke [--confirm <WorldRoot>]", purpose: "Remove Keiyaku-owned data from one confirmed World." },
24
+ settings: { positional: "none", stdin: "none", flags: { json: "boolean" }, usage: "settings", purpose: "Read user and project Settings resources." },
25
+ region: { positional: "optional", stdin: "none", flags: { overlap: "boolean", path: "value", json: "boolean" }, usage: "region [<contract>] [--overlap]\n region --path <repo-relative-path>", purpose: "Read active declared Contract Regions." },
20
26
  };
@@ -1,4 +1,4 @@
1
- import { type ProcessInput, type ProcessOutcome } from "../../runtime/proc/run.js";
1
+ import type { ProcessInput, ProcessOutcome } from "../../runtime/proc/run.js";
2
2
  export declare const HARNESS_NAMES: readonly ["codex", "claude", "opencode", "pi"];
3
3
  export type HarnessName = typeof HARNESS_NAMES[number];
4
4
  export type ParsedInstallCommand = Readonly<{
@@ -16,7 +16,7 @@ export type InstallInvocationResult = Readonly<{
16
16
  results: readonly HarnessInstallResult[];
17
17
  }>;
18
18
  export type InstallRunner = (input: ProcessInput) => Promise<ProcessOutcome>;
19
- export declare const INSTALL_USAGE = "install <codex|claude|opencode|pi> [--json]\n install --all [--json]";
19
+ export declare const INSTALL_USAGE = "install <codex|claude|opencode|pi>\n install --all";
20
20
  export declare function parseInstallCommand(argv: readonly string[]): ParsedInstallCommand;
21
21
  export declare function renderInstallHelp(): string;
22
22
  export declare function installAssetsRoot(): string;
@@ -1,9 +1,8 @@
1
1
  import { dirname, resolve } from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
- import { runCrossPlatformProcess } from "../../runtime/proc/run.js";
4
- import { CliUsageError, usageLine, withJsonAutomationHelp } from "../usage.js";
3
+ import { CliUsageError, usageLine } from "../usage.js";
5
4
  export const HARNESS_NAMES = ["codex", "claude", "opencode", "pi"];
6
- export const INSTALL_USAGE = "install <codex|claude|opencode|pi> [--json]\n install --all [--json]";
5
+ export const INSTALL_USAGE = "install <codex|claude|opencode|pi>\n install --all";
7
6
  function isHarness(value) {
8
7
  return value !== undefined && HARNESS_NAMES.includes(value);
9
8
  }
@@ -43,7 +42,7 @@ export function parseInstallCommand(argv) {
43
42
  };
44
43
  }
45
44
  export function renderInstallHelp() {
46
- return withJsonAutomationHelp(`Install the Keiyaku skills into one or more agent harnesses.\n\n${usageLine(INSTALL_USAGE)}`);
45
+ return `Install the Keiyaku skills into one or more agent harnesses.\n\n${usageLine(INSTALL_USAGE)}`;
47
46
  }
48
47
  const INSTALL_TIMEOUT_MS = 5 * 60 * 1000;
49
48
  const ASSET_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../../../integrations/marketplace");
@@ -80,12 +79,13 @@ function diagnostic(argv, outcome) {
80
79
  export function installAssetsRoot() {
81
80
  return ASSET_ROOT;
82
81
  }
83
- export async function installHarnesses(harnesses, environment, runner = runCrossPlatformProcess) {
82
+ export async function installHarnesses(harnesses, environment, runner) {
83
+ const run = runner ?? (await import("../../runtime/proc/run.js")).runCrossPlatformProcess;
84
84
  const results = [];
85
85
  for (const harness of harnesses) {
86
86
  let failure;
87
87
  for (const argv of recipes(harness)) {
88
- const detail = diagnostic(argv, await runner({ argv, env: environment, timeoutMs: INSTALL_TIMEOUT_MS }));
88
+ const detail = diagnostic(argv, await run({ argv, env: environment, timeoutMs: INSTALL_TIMEOUT_MS }));
89
89
  if (detail.length > 0) {
90
90
  failure = detail;
91
91
  break;
@@ -0,0 +1,10 @@
1
+ import { type NukeResult } from "../../index.js";
2
+ import type { WorldRoot } from "../../world.js";
3
+ import { type ParsedCommand } from "../parse.js";
4
+ import type { InvocationResult } from "../result.js";
5
+ export declare function invokeNuke(command: Extract<ParsedCommand, {
6
+ command: "nuke";
7
+ }>, world: WorldRoot | null): Promise<Readonly<{
8
+ kind: "nuke";
9
+ result: NukeResult;
10
+ }> | InvocationResult>;
@@ -0,0 +1,20 @@
1
+ import { Keiyaku, KeiyakuRefused } from "../../index.js";
2
+ import { CliUsageError } from "../parse.js";
3
+ export async function invokeNuke(command, world) {
4
+ if (world === null)
5
+ throw new CliUsageError("no Keiyaku world contains the invocation cwd");
6
+ try {
7
+ return {
8
+ kind: "nuke",
9
+ result: await Keiyaku.nuke({
10
+ world,
11
+ ...(command.confirm === undefined ? {} : { confirm: command.confirm }),
12
+ }),
13
+ };
14
+ }
15
+ catch (error) {
16
+ if (error instanceof KeiyakuRefused)
17
+ return { kind: "refused", verb: "nuke", refusal: error.refusal };
18
+ throw error;
19
+ }
20
+ }
@@ -16,9 +16,24 @@ export type TaskWorldObservation = Readonly<{
16
16
  }>;
17
17
  type TaskInput = Readonly<{
18
18
  world: WorldRoot | null;
19
+ context: Readonly<{
20
+ directory: string;
21
+ boundary: string;
22
+ }>;
19
23
  establish(): Promise<WorldRoot>;
20
24
  readStdin(): Promise<string>;
21
25
  actor?: string;
22
26
  }>;
27
+ export declare function invokeTaskFromEdge(input: Readonly<{
28
+ parsed: ParsedTaskCommand;
29
+ world: WorldRoot | null;
30
+ context: Readonly<{
31
+ directory: string;
32
+ boundary: string;
33
+ }>;
34
+ establish: () => Promise<WorldRoot>;
35
+ readStdin: () => Promise<string>;
36
+ actor: string | undefined;
37
+ }>): Promise<TaskInvocationResult>;
23
38
  export declare function invokeTask(command: ParsedTaskCommand, input: TaskInput): Promise<TaskInvocationResult>;
24
39
  export {};