@astrosheep/keiyaku 2.8.0 → 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/.tsbuildinfo +1 -1
- package/build/agents/call-terms_v2.js +6 -2
- package/build/agents/harness/index.js +5 -1
- package/build/agents/harness/pump.js +22 -5
- package/build/agents/launch-snapshot_v2.js +14 -9
- package/build/agents/selector_v2.js +15 -3
- package/build/cli/commands/akuma.js +21 -3
- package/build/cli/completion.js +4 -1
- package/build/cli/flags.js +10 -1
- package/build/cli/help.js +5 -3
- package/build/cli/index.js +67 -14
- package/build/cli/parse.js +65 -24
- package/build/cli/projection-address.js +97 -10
- package/build/cli/render/address.js +12 -3
- package/build/cli/render/call.js +10 -5
- package/build/cli/render/shared.js +2 -2
- package/build/cli/render/status.js +19 -4
- package/build/cli/render/wait.js +3 -3
- package/build/config/provider-policy-ownership.js +39 -0
- package/build/config/settings.js +1 -11
- package/build/core/addressing.js +82 -38
- package/build/core/call.js +33 -5
- package/build/core/projection/mint.js +23 -3
- package/build/core/projection-alias.js +123 -0
- package/build/core/projection-coordinate.js +23 -7
- package/build/core/projection-core.js +8 -47
- package/build/core/projection-kill.js +26 -0
- package/build/core/projection-mint.js +24 -3
- package/build/core/projection-runner-lock.js +1 -1
- package/build/core/projection-status.js +111 -12
- package/build/core/projection-wake.js +3 -0
- package/build/core/response-artifact-id.js +5 -0
- package/build/core/status.js +1 -1
- package/build/core/transcripts.js +42 -15
- package/build/generated/version.js +1 -1
- package/package.json +4 -4
|
@@ -19,11 +19,21 @@ function assertMintSlug(slug) {
|
|
|
19
19
|
if (!normalized) {
|
|
20
20
|
throw new ProjectionStateError("projection slug cannot be empty");
|
|
21
21
|
}
|
|
22
|
-
if (
|
|
22
|
+
if (!/^[a-zA-Z0-9]+(?:[.-][a-zA-Z0-9]+)*$/.test(normalized)) {
|
|
23
23
|
throw new ProjectionStateError(`invalid projection slug: ${slug}`);
|
|
24
24
|
}
|
|
25
25
|
return normalized;
|
|
26
26
|
}
|
|
27
|
+
function removeEmptyAkumaRoot(dir) {
|
|
28
|
+
try {
|
|
29
|
+
fs.rmdirSync(dir);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (isErrnoException(error) && ["ENOENT", "ENOTEMPTY", "EEXIST"].includes(error.code ?? ""))
|
|
33
|
+
return;
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
27
37
|
/**
|
|
28
38
|
* Validate mint inputs that can fail, then reserve one private staging directory.
|
|
29
39
|
* Dot-prefixed staging is never a published projection address.
|
|
@@ -42,14 +52,19 @@ function reserveProjectionDirectory(input) {
|
|
|
42
52
|
}
|
|
43
53
|
const root = projectionRoot(input.cwd);
|
|
44
54
|
fs.mkdirSync(root, { recursive: true });
|
|
55
|
+
const akumaRoot = path.join(root, slug);
|
|
56
|
+
const createdAkumaRoot = !fs.existsSync(akumaRoot);
|
|
57
|
+
fs.mkdirSync(akumaRoot, { recursive: true });
|
|
45
58
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
46
59
|
const hex = (input.randomHex?.(attempt) ?? randomHex8()).toLowerCase();
|
|
47
60
|
if (!/^[0-9a-f]{8}$/.test(hex)) {
|
|
61
|
+
if (createdAkumaRoot)
|
|
62
|
+
removeEmptyAkumaRoot(akumaRoot);
|
|
48
63
|
throw new ProjectionStateError(`projection id random segment must be 8 hex chars, got ${hex}`);
|
|
49
64
|
}
|
|
50
|
-
const id = `${slug}
|
|
65
|
+
const id = `${slug}/${hex}`;
|
|
51
66
|
const dir = projectionDir(input.cwd, id);
|
|
52
|
-
const stagingDir = path.join(
|
|
67
|
+
const stagingDir = path.join(akumaRoot, `.mint-${hex}`);
|
|
53
68
|
if (fs.existsSync(dir))
|
|
54
69
|
continue;
|
|
55
70
|
try {
|
|
@@ -59,6 +74,8 @@ function reserveProjectionDirectory(input) {
|
|
|
59
74
|
if (isErrnoException(error) && error.code === "EEXIST") {
|
|
60
75
|
continue;
|
|
61
76
|
}
|
|
77
|
+
if (createdAkumaRoot)
|
|
78
|
+
removeEmptyAkumaRoot(akumaRoot);
|
|
62
79
|
throw error;
|
|
63
80
|
}
|
|
64
81
|
if (fs.existsSync(dir)) {
|
|
@@ -67,6 +84,8 @@ function reserveProjectionDirectory(input) {
|
|
|
67
84
|
}
|
|
68
85
|
return { id, dir, stagingDir };
|
|
69
86
|
}
|
|
87
|
+
if (createdAkumaRoot)
|
|
88
|
+
removeEmptyAkumaRoot(akumaRoot);
|
|
70
89
|
throw new ProjectionMintCollisionError(`exhausted ${maxAttempts} projection id attempts under ${PROJECTION_ROOT_SEGMENTS.join("/")} (PROJECTION_MINT_COLLISION)`);
|
|
71
90
|
}
|
|
72
91
|
/** Build the pact fields shared by both authority variants. */
|
|
@@ -104,6 +123,8 @@ function publishReservedProjection(pact, reserved) {
|
|
|
104
123
|
finally {
|
|
105
124
|
if (!published) {
|
|
106
125
|
fs.rmSync(reserved.stagingDir, { recursive: true, force: true });
|
|
126
|
+
const parent = path.dirname(reserved.stagingDir);
|
|
127
|
+
removeEmptyAkumaRoot(parent);
|
|
107
128
|
}
|
|
108
129
|
}
|
|
109
130
|
}
|
|
@@ -3,7 +3,7 @@ import * as path from "node:path";
|
|
|
3
3
|
import { DatabaseSync } from "node:sqlite";
|
|
4
4
|
export const PROJECTION_RUNNER_LOCK_DATABASE = "leash";
|
|
5
5
|
const SQLITE_BUSY = 5;
|
|
6
|
-
const SUPPORTED_PLATFORMS = new Set(["darwin", "linux"]);
|
|
6
|
+
const SUPPORTED_PLATFORMS = new Set(["darwin", "linux", "win32"]);
|
|
7
7
|
export class ProjectionRunnerLockUnavailableError extends Error {
|
|
8
8
|
code = "PROJECTION_RUNNER_LOCK_UNAVAILABLE";
|
|
9
9
|
constructor(message, options) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { isErrnoException } from "../errno.js";
|
|
4
|
-
import { executionEventsPath, projectionRoot, } from "./projection-core.js";
|
|
4
|
+
import { executionEventsPath, isProjectionId, projectionRoot, } from "./projection-core.js";
|
|
5
|
+
import { readProjectionAlias } from "./projection-alias.js";
|
|
5
6
|
import { ProjectionStateError } from "./atomic-publish.js";
|
|
6
7
|
import { foldAgentActivity, } from "./projection-activity.js";
|
|
7
8
|
import { readProjectionIdentity } from "./projection-identity.js";
|
|
@@ -12,6 +13,73 @@ import { observeProjectionLifeSnapshot } from "./projection-life-observer.js";
|
|
|
12
13
|
import { selectCurrentGeneration } from "./projection-life-protocol.js";
|
|
13
14
|
import { invalidActivityEventDiagnostic, selectValidStoredAgentEvents } from "./stored-agent-event.js";
|
|
14
15
|
const MAX_STATUS_FILE_BYTES = 256 * 1024;
|
|
16
|
+
export const DEFAULT_PROJECTION_STATUS_ROW_BUDGET = 20;
|
|
17
|
+
const STATUS_GROUP = {
|
|
18
|
+
"startup-timeout": 0,
|
|
19
|
+
lost: 0,
|
|
20
|
+
unknown: 0,
|
|
21
|
+
minting: 1,
|
|
22
|
+
out: 1,
|
|
23
|
+
failed: 2,
|
|
24
|
+
dead: 2,
|
|
25
|
+
done: 3,
|
|
26
|
+
dismissed: 4,
|
|
27
|
+
};
|
|
28
|
+
function isOmissibleProjectionStatusState(state) {
|
|
29
|
+
return state === "failed" || state === "dead" || state === "done" || state === "dismissed";
|
|
30
|
+
}
|
|
31
|
+
function rowSortTime(row) {
|
|
32
|
+
if (row.activityAtMs !== undefined && Number.isFinite(row.activityAtMs)) {
|
|
33
|
+
return row.activityAtMs;
|
|
34
|
+
}
|
|
35
|
+
if (row.mintedAt !== undefined) {
|
|
36
|
+
const mintedAtMs = Date.parse(row.mintedAt);
|
|
37
|
+
if (Number.isFinite(mintedAtMs))
|
|
38
|
+
return mintedAtMs;
|
|
39
|
+
}
|
|
40
|
+
return Number.NEGATIVE_INFINITY;
|
|
41
|
+
}
|
|
42
|
+
function compareProjectionStatusRows(a, b) {
|
|
43
|
+
const groupDifference = STATUS_GROUP[a.state] - STATUS_GROUP[b.state];
|
|
44
|
+
if (groupDifference !== 0)
|
|
45
|
+
return groupDifference;
|
|
46
|
+
const aTime = rowSortTime(a);
|
|
47
|
+
const bTime = rowSortTime(b);
|
|
48
|
+
if (aTime !== bTime) {
|
|
49
|
+
if (aTime === Number.NEGATIVE_INFINITY)
|
|
50
|
+
return 1;
|
|
51
|
+
if (bTime === Number.NEGATIVE_INFINITY)
|
|
52
|
+
return -1;
|
|
53
|
+
return bTime - aTime;
|
|
54
|
+
}
|
|
55
|
+
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
56
|
+
}
|
|
57
|
+
export function prioritizeProjectionStatusRows(rows, showAll) {
|
|
58
|
+
const ordered = [...rows].sort(compareProjectionStatusRows);
|
|
59
|
+
if (showAll)
|
|
60
|
+
return { rows: ordered };
|
|
61
|
+
const protectedCount = ordered.filter((row) => STATUS_GROUP[row.state] < 2).length;
|
|
62
|
+
let terminalBudget = Math.max(0, DEFAULT_PROJECTION_STATUS_ROW_BUDGET - protectedCount);
|
|
63
|
+
const visible = [];
|
|
64
|
+
const byState = {
|
|
65
|
+
failed: 0,
|
|
66
|
+
dead: 0,
|
|
67
|
+
done: 0,
|
|
68
|
+
dismissed: 0,
|
|
69
|
+
};
|
|
70
|
+
for (const row of ordered) {
|
|
71
|
+
if (STATUS_GROUP[row.state] < 2 || terminalBudget > 0) {
|
|
72
|
+
visible.push(row);
|
|
73
|
+
if (STATUS_GROUP[row.state] >= 2)
|
|
74
|
+
terminalBudget -= 1;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (isOmissibleProjectionStatusState(row.state))
|
|
78
|
+
byState[row.state] += 1;
|
|
79
|
+
}
|
|
80
|
+
const total = Object.values(byState).reduce((sum, count) => sum + count, 0);
|
|
81
|
+
return total > 0 ? { rows: visible, omitted: { total, byState } } : { rows: visible };
|
|
82
|
+
}
|
|
15
83
|
class ProjectionStatusFileError extends Error {
|
|
16
84
|
diagnostic;
|
|
17
85
|
constructor(kind, filePath) {
|
|
@@ -198,7 +266,7 @@ function readActivityFacts(projectionDir, executionId, nowMs, diagnostics, fallb
|
|
|
198
266
|
: {}),
|
|
199
267
|
};
|
|
200
268
|
}
|
|
201
|
-
function readProjectionRow(projectionDir, id, nowMs) {
|
|
269
|
+
function readProjectionRow(projectionDir, id, alias, nowMs) {
|
|
202
270
|
const diagnostics = [];
|
|
203
271
|
const identityFacts = readIdentityFacts(projectionDir, diagnostics);
|
|
204
272
|
const tellCounts = identityFacts.identity
|
|
@@ -232,6 +300,7 @@ function readProjectionRow(projectionDir, id, nowMs) {
|
|
|
232
300
|
const state = phase === "active" || phase === "quiescent" ? "out" : phase;
|
|
233
301
|
return {
|
|
234
302
|
id,
|
|
303
|
+
...(alias ? { alias } : {}),
|
|
235
304
|
state,
|
|
236
305
|
akuma: identityFacts.akuma,
|
|
237
306
|
provider: identityFacts.provider,
|
|
@@ -243,7 +312,7 @@ function readProjectionRow(projectionDir, id, nowMs) {
|
|
|
243
312
|
diagnostics,
|
|
244
313
|
};
|
|
245
314
|
}
|
|
246
|
-
export function readProjectionStatusBoard(cwd, nowMs) {
|
|
315
|
+
export function readProjectionStatusBoard(cwd, nowMs, options = {}) {
|
|
247
316
|
const root = projectionRoot(cwd);
|
|
248
317
|
try {
|
|
249
318
|
if (!fs.lstatSync(root).isDirectory())
|
|
@@ -263,17 +332,47 @@ export function readProjectionStatusBoard(cwd, nowMs) {
|
|
|
263
332
|
return null;
|
|
264
333
|
throw error;
|
|
265
334
|
}
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
335
|
+
const aliases = new Map();
|
|
336
|
+
const aliasRoot = path.join(path.dirname(path.dirname(root)), ".keiyaku", "projection-alias");
|
|
337
|
+
try {
|
|
338
|
+
for (const alias of fs.readdirSync(aliasRoot).sort()) {
|
|
339
|
+
if (alias.startsWith("."))
|
|
340
|
+
continue;
|
|
341
|
+
const id = readProjectionAlias(cwd, alias);
|
|
342
|
+
if (id)
|
|
343
|
+
aliases.set(id, alias);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
if (!(isErrnoException(error) && error.code === "ENOENT"))
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
const rows = [];
|
|
351
|
+
for (const akuma of entries.sort()) {
|
|
352
|
+
if (akuma.startsWith("."))
|
|
353
|
+
continue;
|
|
354
|
+
const akumaDir = path.join(root, akuma);
|
|
269
355
|
try {
|
|
270
|
-
|
|
356
|
+
if (!fs.lstatSync(akumaDir).isDirectory())
|
|
357
|
+
continue;
|
|
271
358
|
}
|
|
272
359
|
catch {
|
|
273
|
-
|
|
360
|
+
continue;
|
|
274
361
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
362
|
+
for (const hex of fs.readdirSync(akumaDir).sort()) {
|
|
363
|
+
const id = `${akuma}/${hex}`;
|
|
364
|
+
const dir = path.join(akumaDir, hex);
|
|
365
|
+
if (!isProjectionId(id))
|
|
366
|
+
continue;
|
|
367
|
+
try {
|
|
368
|
+
if (!fs.lstatSync(dir).isDirectory())
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
rows.push(readProjectionRow(dir, id, aliases.get(id), nowMs));
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return rows.length > 0 ? prioritizeProjectionStatusRows(rows, options.showAll === true) : null;
|
|
279
378
|
}
|
|
@@ -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,
|
package/build/core/status.js
CHANGED
|
@@ -528,7 +528,7 @@ export async function readKanshiBoard(cwd, now, opts) {
|
|
|
528
528
|
const claimReconciliation = await computeClaimReconciliation(cwd, defaultBranch);
|
|
529
529
|
return {
|
|
530
530
|
contracts: filteredContracts,
|
|
531
|
-
projections: readProjectionStatusBoard(cwd, now),
|
|
531
|
+
projections: readProjectionStatusBoard(cwd, now, { showAll: opts?.showAllProjections }),
|
|
532
532
|
queueLength,
|
|
533
533
|
defaultBranch: defaultBranch?.branch,
|
|
534
534
|
defaultHead: defaultBranch?.head,
|
|
@@ -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(
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
222
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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",
|
|
@@ -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": "
|
|
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.
|
|
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
|
},
|