@astrosheep/keiyaku 2.8.1 → 2.8.2

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/cli/help.js CHANGED
@@ -14,6 +14,7 @@ export const CLI_COMMAND_METADATA = {
14
14
  revive: command("revive", "Revive an Akuma helper session", ["keiyaku revive ARTIFACT_ID"], "none", ["cwd", "repo", "model", "effort"], "Continue a persisted helper session."),
15
15
  wait: command("wait", "Wait for an akuma projection", ["keiyaku wait <projection-address> [--timeout DURATION]", "keiyaku @addr wait <projection-address> [--timeout DURATION]"], "none", ["cwd", "repo", "contract", "timeout"], "Read an akuma projection until its outcome is available, or show a timeout snapshot."),
16
16
  tell: command("tell", "Send intent to a projection mailbox", ["keiyaku tell [--effort LEVEL] PROJECTION MESSAGE", "keiyaku @addr tell [--effort LEVEL] PROJECTION MESSAGE"], "none", ["cwd", "repo", "contract", "effort"], "Write intent to the mailbox and wake only when eligible."),
17
+ kill: command("kill", "Stop the current projection generation", ["keiyaku kill <projection-address>", "keiyaku @addr kill <projection-address>"], "none", ["cwd", "repo", "contract"], "Terminate the current generation while keeping the projection identity and tell ledger."),
17
18
  log: command("log", "Render a contract ledger", ["keiyaku log [-C|--cwd DIR] [--repo DIR] [--contract ADDR]", "keiyaku @addr log [-C|--cwd DIR] [--repo DIR]"], "none", ["cwd", "repo", "contract"], "Read a contract ledger."),
18
19
  akuma: command("akuma", "Inspect Akuma profiles", ["keiyaku akuma list|show"], "none", [], "Inspect configured helper profiles.", {
19
20
  subcommands: ["list", "ls", "show"],
@@ -84,6 +85,7 @@ export function renderCliHelp(version) {
84
85
  " wait Wait for an akuma projection.",
85
86
  " revive Revive an Akuma helper session.",
86
87
  " tell Send intent to an Akuma projection.",
88
+ " kill Stop the current Akuma generation.",
87
89
  " log Render a contract ledger.",
88
90
  " akuma Inspect helper profiles.",
89
91
  " skills Install bundled official skills.",
@@ -35,6 +35,7 @@ import { buildBindDraftResponse, buildBindResponse, buildForfeitResponse, format
35
35
  import { buildCallResponse, renderAdoptedLaunchReceipt } from "./render/call.js";
36
36
  import { projectionDir, writeInboxTell } from "../core/projection-core.js";
37
37
  import { assertTellEffortSupported, tellProjection } from "../core/projection-wake.js";
38
+ import { killProjectionGeneration } from "../core/projection-kill.js";
38
39
  import { resolveProjectionAddress } from "./projection-address.js";
39
40
  import { waitForProjection } from "../core/projection-wait.js";
40
41
  import { buildWaitResponse } from "./render/wait.js";
@@ -233,6 +234,27 @@ const CLI_COMMAND_SPECS = {
233
234
  };
234
235
  return address ? await withResolvedAddress(address, operation) : await operation();
235
236
  }),
237
+ kill: commandSpec("kill", async (_stdin, flags, _signal, positional) => {
238
+ const cwd = flags.contractId ? await repositoryDirectory(flags) : await projectDirectory(flags);
239
+ const [projectionAddress] = positional;
240
+ if (!projectionAddress)
241
+ throw new FlowError("EMPTY_PARAM", "kill requires a projection address");
242
+ const address = flags.contractId ? await resolveContractAddress(cwd, flags.contractId, flags.contractAddressSource) : undefined;
243
+ const operation = async () => {
244
+ const projection = await resolveProjectionAddress({
245
+ cwd,
246
+ address: projectionAddress,
247
+ scope: address,
248
+ verb: "kill",
249
+ });
250
+ const result = killProjectionGeneration(projectionDir(cwd, projection.id));
251
+ const line = result.status === "killed"
252
+ ? `× killed ${projection.id}`
253
+ : `· already resting ${projection.id}`;
254
+ return textResponse(line);
255
+ };
256
+ return address ? await withResolvedAddress(address, operation) : await operation();
257
+ }),
236
258
  log: commandSpec("log", async (_stdin, flags) => {
237
259
  const cwd = await repositoryDirectory(flags);
238
260
  const address = await resolveContractAddress(cwd, flags.contractId, flags.contractAddressSource);
@@ -9,6 +9,7 @@ const COMMISSION_SELECTOR_COMMANDS = new Set([
9
9
  "call",
10
10
  "wait",
11
11
  "tell",
12
+ "kill",
12
13
  "log",
13
14
  "renew",
14
15
  "petition",
@@ -21,6 +22,7 @@ const CLI_COMMAND_ORDER = [
21
22
  "revive",
22
23
  "wait",
23
24
  "tell",
25
+ "kill",
24
26
  "log",
25
27
  "akuma list",
26
28
  "akuma ls",
@@ -45,6 +47,7 @@ const COMMAND_FLAGS = {
45
47
  revive: ["cwd", "repo", "model", "effort"],
46
48
  wait: ["cwd", "repo", "contract", "timeout"],
47
49
  tell: ["cwd", "repo", "contract", "effort"],
50
+ kill: ["cwd", "repo", "contract"],
48
51
  log: ["cwd", "repo", "contract"],
49
52
  akuma: [],
50
53
  "akuma ls": ["cwd", "repo"],
@@ -99,6 +102,8 @@ export function commandPositionalRange(command) {
99
102
  return { min: 1, max: 1, label: "<projection-address>" };
100
103
  if (command === "tell")
101
104
  return { min: 2, max: 2, label: "<projection> <message>" };
105
+ if (command === "kill")
106
+ return { min: 1, max: 1, label: "<projection-address>" };
102
107
  if (isCallCommand(command))
103
108
  return { min: 0, max: 1 };
104
109
  return { min: 0, max: 0 };
@@ -0,0 +1,26 @@
1
+ import { openProjectionGenerationStore } from "./projection-generation-store.js";
2
+ export function killProjectionGeneration(projectionDirectory, nowMs = Date.now()) {
3
+ const store = openProjectionGenerationStore(projectionDirectory);
4
+ try {
5
+ const current = store.readCurrentGeneration();
6
+ if (!current)
7
+ return { status: "already-resting" };
8
+ if (current.verdict) {
9
+ return { status: "already-resting", executionId: current.launch.executionId };
10
+ }
11
+ const transition = store.verdictIfOpen({
12
+ executionId: current.launch.executionId,
13
+ verdict: "completed",
14
+ facts: {
15
+ operatorAction: "kill",
16
+ killedAt: new Date(nowMs).toISOString(),
17
+ },
18
+ });
19
+ return transition.status === "committed"
20
+ ? { status: "killed", executionId: current.launch.executionId }
21
+ : { status: "already-resting", executionId: current.launch.executionId };
22
+ }
23
+ finally {
24
+ store.close();
25
+ }
26
+ }
@@ -116,6 +116,9 @@ export async function tellProjection(projectionDirectory, effort) {
116
116
  ? await startCommittedSuccessor(projectionDirectory, successorExecutionId)
117
117
  : "pending";
118
118
  }
119
+ if (life.phase !== "done") {
120
+ return "pending";
121
+ }
119
122
  const transition = store.launchIfSettled({
120
123
  executionId: successorExecutionId,
121
124
  facts,
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by scripts/generate-version.mjs
2
- export const VERSION = "2.8.1";
2
+ export const VERSION = "2.8.2";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/keiyaku",
3
- "version": "2.8.1",
3
+ "version": "2.8.2",
4
4
  "description": "CLI for running iterative keiyaku workflows with Codex subagents.",
5
5
  "license": "MIT",
6
6
  "type": "module",