@astrosheep/keiyaku 2.8.0 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,15 +8,17 @@ import { FlowError, requireText } from "../flow-error.js";
8
8
  import { getCurrentBranch } from "../git/branches.js";
9
9
  import { getLatestCommitHash } from "../git/staging.js";
10
10
  import { RESPONSE_ARTIFACT_NOTICE, RESPONSE_HISTORY_DIR } from "../keiyaku.js";
11
+ import { attachAddressCarrier } from "./addressing.js";
11
12
  import { parseExecutionCoordinates } from "./execution-coordinate.js";
12
13
  import { createUlid } from "./ids.js";
13
14
  import { parseToAST } from "./markdown/parser.js";
15
+ import { isResponseArtifactId, RESPONSE_ARTIFACT_ID_RE } from "./response-artifact-id.js";
16
+ export { isResponseArtifactId, RESPONSE_ARTIFACT_ID_RE } from "./response-artifact-id.js";
14
17
  const RESPONSE_HISTORY_SLUG_MAX_LENGTH = 24;
15
18
  const RESPONSE_HISTORY_SESSION_KEY = "session";
16
19
  const RESPONSE_HISTORY_LAUNCH_SNAPSHOT_KEY = "launch_snapshot";
17
20
  const RESPONSE_HISTORY_PROVENANCE_KEY = "provenance";
18
21
  const REVIEW_HISTORY_FILE_RE = /^\d{8}-\d{9}_REVIEW_(\d+)\.md$/;
19
- export const RESPONSE_ARTIFACT_ID_RE = /^rsp_[0-9A-HJKMNP-TV-Z]{26}$/;
20
22
  export const RESPONSE_ARTIFACT_HEADINGS = {
21
23
  call: "# Call",
22
24
  bind: "# Bind",
@@ -207,24 +209,41 @@ export async function readResponseArtifact(input) {
207
209
  const storageRoot = path.resolve(path.dirname(absolutePath), "..", "..");
208
210
  return { artifactId: provenance.artifactId, responsePath: path.relative(input.cwd, absolutePath), absolutePath, storageRoot, provenance, tool, ...(session ? { session } : {}), ...(launchSnapshot ? { launchSnapshot } : {}), ...(subagentName ? { subagentName } : {}) };
209
211
  }
210
- export async function locateResponseArtifact(cwd, artifactId) {
211
- const identity = requireText("artifactId", artifactId);
212
- if (!RESPONSE_ARTIFACT_ID_RE.test(identity))
213
- throw artifactError(identity, "provenance.artifactId", "must be rsp_ followed by a ULID");
214
- const historyDir = path.join(cwd, RESPONSE_HISTORY_DIR);
212
+ export async function locateResponseArtifact(input) {
213
+ const carry = (error) => {
214
+ throw attachAddressCarrier(error, input.attempt);
215
+ };
216
+ let identity;
217
+ try {
218
+ identity = requireText("artifactId", input.artifactId);
219
+ }
220
+ catch (error) {
221
+ return carry(error);
222
+ }
223
+ if (!isResponseArtifactId(identity)) {
224
+ return carry(new FlowError("INVALID_RESPONSE_PATH", `${identity} is not a response artifact handle; revive expects an artifact id`));
225
+ }
226
+ const historyDir = path.join(input.cwd, RESPONSE_HISTORY_DIR);
215
227
  let names;
216
228
  try {
217
229
  names = await fs.readdir(historyDir);
218
230
  }
219
231
  catch (error) {
220
- if (isErrnoException(error) && error.code === "ENOENT")
221
- throw new FlowError("INVALID_RESPONSE_PATH", `Response artifact '${identity}' was not found in ${historyDir}.`);
222
- throw error;
232
+ if (isErrnoException(error) && error.code === "ENOENT") {
233
+ return carry(new FlowError("INVALID_RESPONSE_PATH", `Response artifact '${identity}' was not found in ${historyDir}.`));
234
+ }
235
+ return carry(error);
223
236
  }
224
237
  let match;
225
238
  for (const name of names.filter((candidate) => candidate.endsWith(".md")).sort()) {
226
239
  const responsePath = path.join(RESPONSE_HISTORY_DIR, name);
227
- const document = await fs.readFile(path.join(cwd, responsePath), "utf8");
240
+ let document;
241
+ try {
242
+ document = await fs.readFile(path.join(input.cwd, responsePath), "utf8");
243
+ }
244
+ catch (error) {
245
+ return carry(error);
246
+ }
228
247
  const encoded = parseToAST(document).frontmatter?.entries?.[RESPONSE_HISTORY_PROVENANCE_KEY];
229
248
  if (encoded === undefined)
230
249
  continue;
@@ -237,15 +256,23 @@ export async function locateResponseArtifact(cwd, artifactId) {
237
256
  }
238
257
  if (!isRecord(indexed) || indexed.artifactId !== identity)
239
258
  continue;
240
- const parsed = await readResponseArtifact({ cwd, responsePath });
259
+ let parsed;
260
+ try {
261
+ parsed = await readResponseArtifact({ cwd: input.cwd, responsePath });
262
+ }
263
+ catch (error) {
264
+ return carry(error);
265
+ }
241
266
  if (!parsed)
242
267
  continue;
243
- if (match)
244
- throw new FlowError("INVALID_RESPONSE_PATH", `Response artifact identity '${identity}' is duplicated in ${historyDir}.`);
268
+ if (match) {
269
+ return carry(new FlowError("INVALID_RESPONSE_PATH", `Response artifact identity '${identity}' is duplicated in ${historyDir}.`));
270
+ }
245
271
  match = parsed;
246
272
  }
247
- if (!match)
248
- throw new FlowError("INVALID_RESPONSE_PATH", `Response artifact '${identity}' was not found in ${historyDir}.`);
273
+ if (!match) {
274
+ return carry(new FlowError("INVALID_RESPONSE_PATH", `Response artifact '${identity}' was not found in ${historyDir}.`));
275
+ }
249
276
  return match;
250
277
  }
251
278
  export function requireResumableArtifact(artifact) {
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by scripts/generate-version.mjs
2
- export const VERSION = "2.8.0";
2
+ export const VERSION = "2.8.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/keiyaku",
3
- "version": "2.8.0",
3
+ "version": "2.8.1",
4
4
  "description": "CLI for running iterative keiyaku workflows with Codex subagents.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,7 +33,7 @@
33
33
  "preversion": "npm test --silent",
34
34
  "version": "npm run sync:version --silent && git add src/generated/version.ts",
35
35
  "dev": "npx tsx src/index.ts",
36
- "build": "rm -rf build && npx tsc && chmod +x build/index.js",
36
+ "build": "node scripts/build.mjs",
37
37
  "test:typecheck": "npx tsc --project tsconfig.tests.json",
38
38
  "prepublishOnly": "npm run build",
39
39
  "start": "node build/index.js",
@@ -48,10 +48,10 @@
48
48
  "dependencies": {
49
49
  "@anthropic-ai/claude-agent-sdk": "^0.3.204",
50
50
  "@anthropic-ai/sdk": "^0.110.0",
51
- "@earendil-works/pi-coding-agent": "0.80.2",
51
+ "@earendil-works/pi-coding-agent": "^0.80.10",
52
52
  "@modelcontextprotocol/sdk": "^1.29.0",
53
- "@opencode-ai/sdk": "1.17.20",
54
53
  "@openai/codex-sdk": "^0.113.0",
54
+ "@opencode-ai/sdk": "1.17.20",
55
55
  "simple-git": "^3.21.0",
56
56
  "zod": "4.3.6"
57
57
  },