@astrosheep/keiyaku 4.4.0 → 4.5.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.
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +4 -2
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +9 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +16 -5
- package/build/integrations/pi/keiyaku.ts +159 -0
- package/build/src/akuma/abort.js +9 -9
- package/build/src/akuma/akuma-handle.d.ts +4 -2
- package/build/src/akuma/akuma-handle.js +14 -2
- package/build/src/akuma/akuma-product.d.ts +32 -3
- package/build/src/akuma/akuma-product.js +44 -20
- package/build/src/akuma/akuma.d.ts +0 -1
- package/build/src/akuma/body.d.ts +1 -7
- package/build/src/akuma/body.js +35 -13
- package/build/src/akuma/heart/index.js +7 -3
- package/build/src/akuma/heart/rows.d.ts +1 -1
- package/build/src/akuma/heart/rows.js +3 -3
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +28 -6
- package/build/src/akuma/identity.d.ts +1 -0
- package/build/src/akuma/identity.js +7 -0
- package/build/src/akuma/index.d.ts +1 -2
- package/build/src/akuma/projection.d.ts +18 -2
- package/build/src/akuma/projection.js +11 -1
- package/build/src/akuma/providers/claude/index.js +68 -37
- package/build/src/akuma/publication.d.ts +9 -3
- package/build/src/akuma/publication.js +20 -3
- package/build/src/akuma/request-lifecycle.d.ts +45 -0
- package/build/src/akuma/request-lifecycle.js +171 -0
- package/build/src/akuma/request-serve.d.ts +9 -32
- package/build/src/akuma/request-serve.js +48 -178
- package/build/src/akuma/request-wire.js +1 -1
- package/build/src/akuma/requests.js +3 -2
- package/build/src/cli/commands/akuma-invoke.d.ts +11 -2
- package/build/src/cli/commands/akuma-invoke.js +29 -7
- package/build/src/cli/commands/akuma.d.ts +1 -0
- package/build/src/cli/commands/akuma.js +16 -6
- package/build/src/cli/commands/contract.d.ts +3 -2
- package/build/src/cli/commands/contract.js +5 -2
- package/build/src/cli/commands/status-set.d.ts +4 -0
- package/build/src/cli/commands/status-set.js +61 -0
- package/build/src/cli/invoke.js +6 -3
- package/build/src/cli/parse.js +1 -1
- package/build/src/cli/render/akuma-activity.js +11 -0
- package/build/src/cli/render/akuma.js +7 -0
- package/build/src/cli/render/status-set.d.ts +5 -0
- package/build/src/cli/render/status-set.js +14 -0
- package/build/src/cli/render/text.js +3 -0
- package/build/src/cli/result.d.ts +15 -1
- package/build/src/cli/runtime.js +2 -0
- package/build/src/cli/square-edge.d.ts +6 -0
- package/build/src/cli/square-edge.js +74 -0
- package/build/src/contract-worktree.js +18 -5
- package/build/src/library/akuma-creation.d.ts +14 -3
- package/build/src/library/akuma-creation.js +31 -18
- package/build/src/library/fleet.d.ts +12 -1
- package/build/src/library/fleet.js +21 -5
- package/build/src/library/repo.js +3 -1
- package/build/src/runtime/proc/process-exit.js +6 -1
- package/build/src/runtime/proc/run.js +6 -10
- package/build/src/runtime/proc/termination.d.ts +1 -0
- package/build/src/runtime/proc/termination.js +22 -2
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/runtime/proc/windows-run.js +10 -7
- package/build/src/world.d.ts +2 -0
- package/build/src/world.js +4 -0
- package/package.json +8 -3
- package/build/src/akuma/result-route.d.ts +0 -2
- package/build/src/akuma/result-route.js +0 -1
|
@@ -40,13 +40,6 @@ export async function spawnDetachedProcess(input) {
|
|
|
40
40
|
return spawnWindowsRetainedProcess(input);
|
|
41
41
|
const log = await open(input.log, "a");
|
|
42
42
|
let launched = false;
|
|
43
|
-
let logClosed = false;
|
|
44
|
-
const closeLog = async () => {
|
|
45
|
-
if (logClosed)
|
|
46
|
-
return;
|
|
47
|
-
logClosed = true;
|
|
48
|
-
await log.close();
|
|
49
|
-
};
|
|
50
43
|
try {
|
|
51
44
|
const from = (await log.stat()).size;
|
|
52
45
|
const child = spawn(input.argv[0], input.argv.slice(1), spawnOptionsFor(input, ["ignore", log.fd, log.fd]));
|
|
@@ -62,14 +55,16 @@ export async function spawnDetachedProcess(input) {
|
|
|
62
55
|
const status = detachedExitStatus(code, signal);
|
|
63
56
|
let failure;
|
|
64
57
|
let result;
|
|
58
|
+
let exitLog;
|
|
65
59
|
try {
|
|
66
|
-
|
|
60
|
+
exitLog = await open(input.log, "r+");
|
|
61
|
+
result = await retainDetachedExitEvidence(exitLog, input.log, from, code, signal);
|
|
67
62
|
}
|
|
68
63
|
catch (error) {
|
|
69
64
|
failure = error;
|
|
70
65
|
}
|
|
71
66
|
try {
|
|
72
|
-
await
|
|
67
|
+
await exitLog?.close();
|
|
73
68
|
}
|
|
74
69
|
catch (error) {
|
|
75
70
|
failure ??= error;
|
|
@@ -89,6 +84,7 @@ export async function spawnDetachedProcess(input) {
|
|
|
89
84
|
if (child.pid === undefined)
|
|
90
85
|
throw new Error("detached process spawned without a pid");
|
|
91
86
|
const pid = child.pid;
|
|
87
|
+
await log.close();
|
|
92
88
|
launched = true;
|
|
93
89
|
return {
|
|
94
90
|
pid,
|
|
@@ -99,7 +95,7 @@ export async function spawnDetachedProcess(input) {
|
|
|
99
95
|
}
|
|
100
96
|
finally {
|
|
101
97
|
if (!launched)
|
|
102
|
-
await
|
|
98
|
+
await log.close();
|
|
103
99
|
}
|
|
104
100
|
}
|
|
105
101
|
function terminalOutcome(code, stdout, stderr, consuming) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { type ChildProcess } from "node:child_process";
|
|
2
2
|
export declare function terminateWindowsTree(pid: number): Promise<void>;
|
|
3
|
+
export declare function settleWindowsTermination(exit: Promise<void>): Promise<void>;
|
|
3
4
|
export declare function terminateOwnedProcess(child: ChildProcess, force?: boolean): Promise<void>;
|
|
@@ -2,6 +2,7 @@ import { execFile } from "node:child_process";
|
|
|
2
2
|
import { setTimeout as delay } from "node:timers/promises";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
const TERMINATION_GRACE_MS = 250;
|
|
5
|
+
const WINDOWS_TERMINATION_SETTLE_MS = 250;
|
|
5
6
|
const WINDOWS_TERMINATION_TIMEOUT_MS = 1_000;
|
|
6
7
|
const execFileAsync = promisify(execFile);
|
|
7
8
|
function ignoreMissingProcess(error) {
|
|
@@ -23,6 +24,20 @@ export async function terminateWindowsTree(pid) {
|
|
|
23
24
|
throw error;
|
|
24
25
|
}
|
|
25
26
|
}
|
|
27
|
+
export async function settleWindowsTermination(exit) {
|
|
28
|
+
const settled = await Promise.race([
|
|
29
|
+
exit.then(() => true),
|
|
30
|
+
delay(WINDOWS_TERMINATION_TIMEOUT_MS, false, { ref: false }).then(() => false),
|
|
31
|
+
]);
|
|
32
|
+
if (!settled)
|
|
33
|
+
throw new Error("Windows process did not exit after taskkill");
|
|
34
|
+
await delay(WINDOWS_TERMINATION_SETTLE_MS);
|
|
35
|
+
}
|
|
36
|
+
function closeWindowsStreams(child) {
|
|
37
|
+
child.stdin?.destroy();
|
|
38
|
+
child.stdout?.destroy();
|
|
39
|
+
child.stderr?.destroy();
|
|
40
|
+
}
|
|
26
41
|
export async function terminateOwnedProcess(child, force = false) {
|
|
27
42
|
const pid = child.pid;
|
|
28
43
|
if (pid === undefined || child.exitCode !== null || child.signalCode !== null)
|
|
@@ -39,8 +54,13 @@ export async function terminateOwnedProcess(child, force = false) {
|
|
|
39
54
|
});
|
|
40
55
|
});
|
|
41
56
|
if (process.platform === "win32") {
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
try {
|
|
58
|
+
await terminateWindowsTree(pid);
|
|
59
|
+
await settleWindowsTermination(exit);
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
closeWindowsStreams(child);
|
|
63
|
+
}
|
|
44
64
|
return;
|
|
45
65
|
}
|
|
46
66
|
if (force) {
|
|
Binary file
|
|
@@ -3,8 +3,8 @@ import { createInterface } from "node:readline";
|
|
|
3
3
|
import { launchFailure, spawnWindowsLauncher } from "./launch.js";
|
|
4
4
|
import { detachedExitStatus, retainDetachedExitEvidence } from "./process-exit.js";
|
|
5
5
|
import { createProcessLifecycle } from "./lifecycle.js";
|
|
6
|
-
import { terminateWindowsTree } from "./termination.js";
|
|
7
|
-
function createWindowsContext(input,
|
|
6
|
+
import { settleWindowsTermination, terminateWindowsTree } from "./termination.js";
|
|
7
|
+
function createWindowsContext(input, from, closeLog) {
|
|
8
8
|
const child = spawnWindowsLauncher(input);
|
|
9
9
|
const reader = createInterface({ input: child.stdout });
|
|
10
10
|
let startedResolve;
|
|
@@ -23,7 +23,6 @@ function createWindowsContext(input, log, from, closeLog) {
|
|
|
23
23
|
child.stderr?.setEncoding("utf8");
|
|
24
24
|
const context = {
|
|
25
25
|
input,
|
|
26
|
-
log,
|
|
27
26
|
from,
|
|
28
27
|
closeLog,
|
|
29
28
|
child,
|
|
@@ -79,14 +78,16 @@ function recordWindowsExit(context, code) {
|
|
|
79
78
|
void (async () => {
|
|
80
79
|
let failure;
|
|
81
80
|
let result;
|
|
81
|
+
let exitLog;
|
|
82
82
|
try {
|
|
83
|
-
|
|
83
|
+
exitLog = await open(context.input.log, "r+");
|
|
84
|
+
result = await retainDetachedExitEvidence(exitLog, context.input.log, context.from, code, null);
|
|
84
85
|
}
|
|
85
86
|
catch (error) {
|
|
86
87
|
failure = error;
|
|
87
88
|
}
|
|
88
89
|
try {
|
|
89
|
-
await
|
|
90
|
+
await exitLog?.close();
|
|
90
91
|
}
|
|
91
92
|
catch (error) {
|
|
92
93
|
failure ??= error;
|
|
@@ -98,6 +99,7 @@ function recordWindowsExit(context, code) {
|
|
|
98
99
|
const status = detachedExitStatus(code, null);
|
|
99
100
|
throw new Error(`pre-admission ${status}: run-log evidence unavailable: ${failure instanceof Error ? failure.message : String(failure)}`);
|
|
100
101
|
}
|
|
102
|
+
await settleWindowsTermination(Promise.resolve());
|
|
101
103
|
context.exitResolve(result);
|
|
102
104
|
})().catch(context.exitReject);
|
|
103
105
|
}
|
|
@@ -143,7 +145,7 @@ function installWindowsProtocol(context) {
|
|
|
143
145
|
function ownedWindowsProcess(context, pid) {
|
|
144
146
|
const lifecycle = createProcessLifecycle(async () => {
|
|
145
147
|
await terminateWindowsTree(pid);
|
|
146
|
-
await context.exited;
|
|
148
|
+
await settleWindowsTermination(context.exited.then(() => undefined));
|
|
147
149
|
}, () => {
|
|
148
150
|
context.released = true;
|
|
149
151
|
context.reader.close();
|
|
@@ -170,10 +172,11 @@ export async function spawnWindowsRetainedProcess(input) {
|
|
|
170
172
|
logClosed = true;
|
|
171
173
|
await log.close();
|
|
172
174
|
};
|
|
173
|
-
const context = createWindowsContext(input,
|
|
175
|
+
const context = createWindowsContext(input, (await log.stat()).size, closeLog);
|
|
174
176
|
installWindowsProtocol(context);
|
|
175
177
|
try {
|
|
176
178
|
const pid = await context.startedPromise;
|
|
179
|
+
await closeLog();
|
|
177
180
|
return ownedWindowsProcess(context, pid);
|
|
178
181
|
}
|
|
179
182
|
catch (error) {
|
package/build/src/world.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export type WorldResolution = Readonly<{
|
|
|
11
11
|
candidate: WorldRoot | null;
|
|
12
12
|
establish: () => Promise<WorldRoot>;
|
|
13
13
|
}>;
|
|
14
|
+
export declare const KEIYAKU_SQUARE_FILE = "KEIYAKU.square";
|
|
15
|
+
export declare function keiyakuSquarePath(worldRoot: string): string;
|
|
14
16
|
export declare class WorldError extends Error {
|
|
15
17
|
readonly kind: "invalid-world" | "home-world" | "root-world";
|
|
16
18
|
constructor(kind: "invalid-world" | "home-world" | "root-world", message: string);
|
package/build/src/world.js
CHANGED
|
@@ -2,6 +2,10 @@ import { mkdir, realpath, stat } from "node:fs/promises";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { dirname, join, parse, resolve } from "node:path";
|
|
4
4
|
const WORLD_BRAND = Symbol("keiyaku.world");
|
|
5
|
+
export const KEIYAKU_SQUARE_FILE = "KEIYAKU.square";
|
|
6
|
+
export function keiyakuSquarePath(worldRoot) {
|
|
7
|
+
return join(worldRoot, ".square", KEIYAKU_SQUARE_FILE);
|
|
8
|
+
}
|
|
5
9
|
export class WorldError extends Error {
|
|
6
10
|
kind;
|
|
7
11
|
constructor(kind, message) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrosheep/keiyaku",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"files": [
|
|
5
5
|
"build"
|
|
6
6
|
],
|
|
@@ -35,14 +35,19 @@
|
|
|
35
35
|
"build": "node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('build', { recursive: true, force: true })\" && tsc -p tsconfig.json && node scripts/copy-integrations.js && node scripts/build-windows-launcher.js && node --input-type=module -e \"import { chmodSync } from 'node:fs'; chmodSync('build/src/cli/index.js', 0o755)\"",
|
|
36
36
|
"prepack": "node scripts/verify-package.js",
|
|
37
37
|
"postpack": "node scripts/verify-package.js",
|
|
38
|
+
"harness:version": "node scripts/update-harness-version.js",
|
|
38
39
|
"review:model-impact": "node --import tsx scripts/model-change-impact.ts",
|
|
39
40
|
"format": "prettier --write --print-width 120 \"src/**/*.ts\" \"scripts/**/*.ts\"",
|
|
40
41
|
"format:check": "prettier --check --print-width 120 \"src/**/*.ts\" \"scripts/**/*.ts\"",
|
|
41
|
-
"test": "npm run format:check && npm run build && npm run test:architecture && npm run test:maintainability && npm run test:reachability &&
|
|
42
|
+
"test": "npm run format:check && npm run build && npm run test:architecture && npm run test:maintainability && npm run test:reachability && npm run test:parallel",
|
|
42
43
|
"test:architecture": "node --import tsx scripts/check-architecture.ts",
|
|
43
44
|
"test:e2e": "npm run build && node scripts/run-tests.mjs tests/packaged-cli.e2e.ts",
|
|
45
|
+
"test:local": "node scripts/run-tests.mjs --suite local",
|
|
46
|
+
"test:integration": "node scripts/run-tests.mjs --suite integration",
|
|
47
|
+
"test:parallel": "node scripts/run-tests.mjs --suite local --test-concurrency=8 && node scripts/run-tests.mjs --suite integration --test-concurrency=8",
|
|
44
48
|
"test:maintainability": "node scripts/check-maintainability.js",
|
|
45
49
|
"test:focused": "node scripts/run-tests.mjs",
|
|
50
|
+
"test:focused:serial": "node scripts/run-tests.mjs --test-concurrency=1",
|
|
46
51
|
"test:reachability": "knip --include files,dependencies,unlisted,unresolved,duplicates",
|
|
47
52
|
"test:typecheck": "tsc -p tsconfig.json --noEmit"
|
|
48
53
|
},
|
|
@@ -59,7 +64,7 @@
|
|
|
59
64
|
"dependencies": {
|
|
60
65
|
"@agentclientprotocol/sdk": "^1.3.0",
|
|
61
66
|
"@anthropic-ai/claude-agent-sdk": "^0.3.226",
|
|
62
|
-
"@astrosheep/square": "0.3.
|
|
67
|
+
"@astrosheep/square": "0.3.23",
|
|
63
68
|
"@earendil-works/pi-coding-agent": "0.80.10",
|
|
64
69
|
"@opencode-ai/sdk": "1.18.3",
|
|
65
70
|
"cross-spawn": "^7.0.6",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|