@anyi61/codex-claude-delegate-mcp 0.1.0
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/LICENSE +21 -0
- package/README.md +262 -0
- package/dist/claude-cli.d.ts +84 -0
- package/dist/claude-cli.js +3123 -0
- package/dist/claude-cli.js.map +1 -0
- package/dist/cli.d.ts +61 -0
- package/dist/cli.js +334 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-config.d.ts +104 -0
- package/dist/codex-config.js +446 -0
- package/dist/codex-config.js.map +1 -0
- package/dist/guard.d.ts +27 -0
- package/dist/guard.js +229 -0
- package/dist/guard.js.map +1 -0
- package/dist/job-runner.d.ts +13 -0
- package/dist/job-runner.js +75 -0
- package/dist/job-runner.js.map +1 -0
- package/dist/jobs.d.ts +46 -0
- package/dist/jobs.js +175 -0
- package/dist/jobs.js.map +1 -0
- package/dist/package-info.d.ts +4 -0
- package/dist/package-info.js +14 -0
- package/dist/package-info.js.map +1 -0
- package/dist/schema.d.ts +779 -0
- package/dist/schema.js +325 -0
- package/dist/schema.js.map +1 -0
- package/dist/server.d.ts +1142 -0
- package/dist/server.js +693 -0
- package/dist/server.js.map +1 -0
- package/dist/session.d.ts +35 -0
- package/dist/session.js +109 -0
- package/dist/session.js.map +1 -0
- package/package.json +49 -0
- package/plugins/codex-claude-delegate/.codex-plugin/plugin.json +36 -0
- package/plugins/codex-claude-delegate/.mcp.json +9 -0
- package/plugins/codex-claude-delegate/hooks/hooks.json +16 -0
- package/plugins/codex-claude-delegate/hooks/review-gate-stop.mjs +66 -0
- package/plugins/codex-claude-delegate/server/job-runner.js +16999 -0
- package/plugins/codex-claude-delegate/server/server.js +28048 -0
- package/plugins/codex-claude-delegate/skills/claude-delegate.md +30 -0
- package/plugins/codex-claude-delegate/skills/claude-rescue.md +52 -0
- package/plugins/codex-claude-delegate/skills/claude-review.md +25 -0
package/dist/guard.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { realpath, stat } from "node:fs/promises";
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
// Allowlist of directories that MCP tools may operate within.
|
|
6
|
+
// Override via CODEX_CLAUDE_ALLOW_ROOTS (colon-separated paths on macOS/Linux).
|
|
7
|
+
export function dangerousRoot(raw) {
|
|
8
|
+
const resolved = path.resolve(raw);
|
|
9
|
+
const home = process.env.HOME ? path.resolve(process.env.HOME) : "";
|
|
10
|
+
return resolved === "/" || resolved === "/etc" || resolved === "/tmp" || (!!home && resolved === home);
|
|
11
|
+
}
|
|
12
|
+
function splitAllowRootsEnv(raw) {
|
|
13
|
+
const delimiterPattern = path.delimiter === ";" ? /[;,]/g : /[:,]/g;
|
|
14
|
+
return raw.split(delimiterPattern).map((part) => part.trim()).filter(Boolean);
|
|
15
|
+
}
|
|
16
|
+
export function getAllowRoots() {
|
|
17
|
+
const normalizeRoot = (p) => {
|
|
18
|
+
const resolved = path.resolve(p);
|
|
19
|
+
try {
|
|
20
|
+
return realpathSync(resolved);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return resolved;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const env = process.env.CODEX_CLAUDE_ALLOW_ROOTS;
|
|
27
|
+
if (env) {
|
|
28
|
+
return splitAllowRootsEnv(env).map(normalizeRoot);
|
|
29
|
+
}
|
|
30
|
+
const home = process.env.HOME;
|
|
31
|
+
return [
|
|
32
|
+
home ? `${home}/projects` : null,
|
|
33
|
+
home ? `${home}/work` : null,
|
|
34
|
+
home ? `${home}/codex-claude` : null,
|
|
35
|
+
].filter(Boolean);
|
|
36
|
+
}
|
|
37
|
+
export async function validateCwd(raw) {
|
|
38
|
+
if (dangerousRoot(raw)) {
|
|
39
|
+
return { ok: false, resolved: path.resolve(raw), error: `Refusing dangerous root path: ${path.resolve(raw)}` };
|
|
40
|
+
}
|
|
41
|
+
// Resolve symlinks and relative paths
|
|
42
|
+
let resolved;
|
|
43
|
+
try {
|
|
44
|
+
resolved = await realpath(raw);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return { ok: false, resolved: raw, error: `Path does not exist: ${raw}` };
|
|
48
|
+
}
|
|
49
|
+
if (dangerousRoot(resolved)) {
|
|
50
|
+
return { ok: false, resolved, error: `Refusing dangerous root path: ${resolved}` };
|
|
51
|
+
}
|
|
52
|
+
// Must be within an allowed root
|
|
53
|
+
const allowRoots = getAllowRoots();
|
|
54
|
+
const allowed = allowRoots.some((root) => resolved === root || resolved.startsWith(root + path.sep));
|
|
55
|
+
if (!allowed) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
resolved,
|
|
59
|
+
error: `Path "${resolved}" is outside allowed roots: ${allowRoots.join(", ")}`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Must be a directory
|
|
63
|
+
const s = await stat(resolved);
|
|
64
|
+
if (!s.isDirectory()) {
|
|
65
|
+
return { ok: false, resolved, error: `Path is not a directory: ${resolved}` };
|
|
66
|
+
}
|
|
67
|
+
return { ok: true, resolved };
|
|
68
|
+
}
|
|
69
|
+
export async function validateFilesWithinCwd(cwd, files) {
|
|
70
|
+
const cwdReal = await realpath(cwd);
|
|
71
|
+
for (const file of files ?? []) {
|
|
72
|
+
const candidate = path.resolve(cwdReal, file);
|
|
73
|
+
let resolved = candidate;
|
|
74
|
+
try {
|
|
75
|
+
resolved = await realpath(candidate);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
resolved = candidate;
|
|
79
|
+
}
|
|
80
|
+
if (resolved !== cwdReal && !resolved.startsWith(cwdReal + path.sep)) {
|
|
81
|
+
return { ok: false, resolved, error: `File path escapes cwd: ${file}` };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { ok: true, resolved: cwdReal };
|
|
85
|
+
}
|
|
86
|
+
export function resolveRepoLocalPath(cwd, relativePath) {
|
|
87
|
+
const resolved = path.resolve(cwd, relativePath);
|
|
88
|
+
if (resolved !== cwd && !resolved.startsWith(cwd + path.sep)) {
|
|
89
|
+
return { ok: false, resolved, error: `Path escapes cwd: ${relativePath}` };
|
|
90
|
+
}
|
|
91
|
+
return { ok: true, resolved };
|
|
92
|
+
}
|
|
93
|
+
// ---- Git repo check ----
|
|
94
|
+
export async function isGitRepo(cwd) {
|
|
95
|
+
try {
|
|
96
|
+
await execCapture("git", ["rev-parse", "--git-dir"], { cwd });
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// ---- Worktree capability check ----
|
|
104
|
+
export async function supportsWorktree(cwd) {
|
|
105
|
+
try {
|
|
106
|
+
await execCapture("git", ["worktree", "list"], { cwd });
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// ---- Recursion guard ----
|
|
114
|
+
export const MAX_BRIDGE_DEPTH = 2;
|
|
115
|
+
export function checkRecursion() {
|
|
116
|
+
const raw = process.env.BRIDGE_DEPTH ?? "0";
|
|
117
|
+
const depth = Number.parseInt(raw, 10);
|
|
118
|
+
if (Number.isNaN(depth) || depth < 0)
|
|
119
|
+
return 0;
|
|
120
|
+
return depth;
|
|
121
|
+
}
|
|
122
|
+
export function assertCanDelegate() {
|
|
123
|
+
const depth = checkRecursion();
|
|
124
|
+
if (depth >= MAX_BRIDGE_DEPTH) {
|
|
125
|
+
throw new Error(`BRIDGE_DEPTH=${depth} >= ${MAX_BRIDGE_DEPTH}; refusing recursive delegation`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// ---- Environment sanitization ----
|
|
129
|
+
const DANGEROUS_ENV_KEYS = [
|
|
130
|
+
"OPENAI_API_KEY",
|
|
131
|
+
"ANTHROPIC_API_KEY",
|
|
132
|
+
"GITHUB_TOKEN",
|
|
133
|
+
"GH_TOKEN",
|
|
134
|
+
"AWS_ACCESS_KEY_ID",
|
|
135
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
136
|
+
"AWS_SESSION_TOKEN",
|
|
137
|
+
"CLOUDFLARE_API_TOKEN",
|
|
138
|
+
"DOCKER_PASSWORD",
|
|
139
|
+
"NPM_TOKEN",
|
|
140
|
+
"SSH_AUTH_SOCK",
|
|
141
|
+
"SSH_AGENT_PID",
|
|
142
|
+
];
|
|
143
|
+
const ALLOWED_ENV_KEYS = [
|
|
144
|
+
"PATH",
|
|
145
|
+
"HOME",
|
|
146
|
+
"SHELL",
|
|
147
|
+
"LANG",
|
|
148
|
+
"LC_ALL",
|
|
149
|
+
"TERM",
|
|
150
|
+
"USER",
|
|
151
|
+
"TMPDIR",
|
|
152
|
+
"TEMP",
|
|
153
|
+
"TMP",
|
|
154
|
+
"NODE_ENV",
|
|
155
|
+
];
|
|
156
|
+
export function sanitizeEnv() {
|
|
157
|
+
const safe = {};
|
|
158
|
+
// Keep known-safe vars
|
|
159
|
+
for (const key of ALLOWED_ENV_KEYS) {
|
|
160
|
+
if (process.env[key] !== undefined) {
|
|
161
|
+
safe[key] = process.env[key];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Strip dangerous secrets
|
|
165
|
+
for (const key of Object.keys(process.env)) {
|
|
166
|
+
const upper = key.toUpperCase();
|
|
167
|
+
if (DANGEROUS_ENV_KEYS.includes(upper) ||
|
|
168
|
+
upper.includes("SECRET") ||
|
|
169
|
+
upper.includes("TOKEN") ||
|
|
170
|
+
upper.includes("CREDENTIAL") ||
|
|
171
|
+
upper.includes("PASSWORD") ||
|
|
172
|
+
upper.includes("API_KEY")) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (!(key in safe)) {
|
|
176
|
+
safe[key] = process.env[key];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
safe.BRIDGE_DEPTH = String(Math.min(checkRecursion() + 1, MAX_BRIDGE_DEPTH));
|
|
180
|
+
return safe;
|
|
181
|
+
}
|
|
182
|
+
// ---- Cli execution helper ----
|
|
183
|
+
export function execCapture(command, args, opts) {
|
|
184
|
+
return new Promise((resolve, reject) => {
|
|
185
|
+
const child = spawn(command, args, {
|
|
186
|
+
cwd: opts.cwd,
|
|
187
|
+
timeout: opts.timeoutMs ?? 30_000,
|
|
188
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
189
|
+
});
|
|
190
|
+
let stdout = "";
|
|
191
|
+
let stderr = "";
|
|
192
|
+
child.stdout?.on("data", (chunk) => {
|
|
193
|
+
stdout += chunk.toString();
|
|
194
|
+
});
|
|
195
|
+
child.stderr?.on("data", (chunk) => {
|
|
196
|
+
stderr += chunk.toString();
|
|
197
|
+
});
|
|
198
|
+
child.on("error", (err) => reject(err));
|
|
199
|
+
child.on("close", (code) => {
|
|
200
|
+
if (code === 0) {
|
|
201
|
+
resolve(stdout.trim());
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
reject(new Error(`Command failed (exit ${code}): ${command} ${args.join(" ")}\n${stderr}`));
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
export function execStream(command, args, opts, onStdout) {
|
|
210
|
+
return new Promise((resolve, reject) => {
|
|
211
|
+
const child = spawn(command, args, {
|
|
212
|
+
cwd: opts.cwd,
|
|
213
|
+
timeout: opts.timeoutMs ?? 300_000,
|
|
214
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
215
|
+
});
|
|
216
|
+
let stderr = "";
|
|
217
|
+
child.stdout?.on("data", (chunk) => {
|
|
218
|
+
onStdout?.(chunk.toString());
|
|
219
|
+
});
|
|
220
|
+
child.stderr?.on("data", (chunk) => {
|
|
221
|
+
stderr += chunk.toString();
|
|
222
|
+
});
|
|
223
|
+
child.on("error", (err) => reject(err));
|
|
224
|
+
child.on("close", (code) => {
|
|
225
|
+
resolve({ code, stderr });
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,8DAA8D;AAC9D,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,OAAO,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,QAAQ,KAAK,IAAI,CAAC,CAAC;AACzG,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACpE,OAAO,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,aAAa,GAAG,CAAC,CAAS,EAAU,EAAE;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IACF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IACjD,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAC9B,OAAO;QACL,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI;QAChC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI;QAC5B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,eAAe,CAAC,CAAC,CAAC,IAAI;KACrC,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;AAChC,CAAC;AAUD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,iCAAiC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IACjH,CAAC;IAED,sCAAsC;IACtC,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,wBAAwB,GAAG,EAAE,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,iCAAiC,QAAQ,EAAE,EAAE,CAAC;IACrF,CAAC;IAED,iCAAiC;IACjC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAC7B,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CACpE,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ;YACR,KAAK,EAAE,SAAS,QAAQ,+BAA+B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAC/E,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,4BAA4B,QAAQ,EAAE,EAAE,CAAC;IAChF,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,GAAW,EAAE,KAAgB;IACxE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,QAAQ,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,SAAS,CAAC;QACvB,CAAC;QACD,IAAI,QAAQ,KAAK,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACrE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,IAAI,EAAE,EAAE,CAAC;QAC1E,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAE,YAAoB;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACjD,IAAI,QAAQ,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAqB,YAAY,EAAE,EAAE,CAAC;IAC7E,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,2BAA2B;AAE3B,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW;IACzC,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,sCAAsC;AAEtC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAW;IAChD,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,4BAA4B;AAE5B,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC;IAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,IAAI,KAAK,IAAI,gBAAgB,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,gBAAgB,KAAK,OAAO,gBAAgB,iCAAiC,CAAC,CAAC;IACjG,CAAC;AACH,CAAC;AAED,qCAAqC;AAErC,MAAM,kBAAkB,GAAG;IACzB,gBAAgB;IAChB,mBAAmB;IACnB,cAAc;IACd,UAAU;IACV,mBAAmB;IACnB,uBAAuB;IACvB,mBAAmB;IACnB,sBAAsB;IACtB,iBAAiB;IACjB,WAAW;IACX,eAAe;IACf,eAAe;CAChB,CAAC;AAEF,MAAM,gBAAgB,GAAG;IACvB,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,QAAQ;IACR,MAAM;IACN,MAAM;IACN,QAAQ;IACR,MAAM;IACN,KAAK;IACL,UAAU;CACX,CAAC;AAEF,MAAM,UAAU,WAAW;IACzB,MAAM,IAAI,GAA2B,EAAE,CAAC;IAExC,uBAAuB;IACvB,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAChC,IACE,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC;YAClC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxB,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;YACvB,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;YAC5B,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC1B,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EACzB,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE7E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iCAAiC;AAEjC,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,IAAc,EACd,IAAyC;IAEzC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,OAAO,EAAE,IAAI,CAAC,SAAS,IAAI,MAAM;YACjC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,IAAI,MAAM,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,IAAc,EACd,IAAyC,EACzC,QAAiC;IAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,OAAO,EAAE,IAAI,CAAC,SAAS,IAAI,OAAO;YAClC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { JobStore } from "./jobs.js";
|
|
2
|
+
export interface JobRunnerDependencies {
|
|
3
|
+
createStore?: () => JobStore;
|
|
4
|
+
executeBackgroundJob?: (jobId: string) => Promise<void>;
|
|
5
|
+
abortActiveClaudeRun?: (signal?: NodeJS.Signals) => boolean;
|
|
6
|
+
onSignal?: (signal: NodeJS.Signals, handler: () => void) => void;
|
|
7
|
+
exit?: (code: number) => never | void;
|
|
8
|
+
setExitCode?: (code: number) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function markCancelled(jobId: string, createStore?: () => JobStore): Promise<void>;
|
|
11
|
+
export declare function registerTerminationHandler(jobId: string, deps?: JobRunnerDependencies): () => void;
|
|
12
|
+
export declare function runJobRunner(jobId: string, deps?: JobRunnerDependencies): Promise<void>;
|
|
13
|
+
export declare function main(argv?: string[], deps?: JobRunnerDependencies): Promise<void>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { JobStore } from "./jobs.js";
|
|
5
|
+
import { abortActiveClaudeRun, executeBackgroundJob } from "./claude-cli.js";
|
|
6
|
+
const JOB_STATE_DIR_ENV = "CODEX_CLAUDE_BACKGROUND_STATE_DIR";
|
|
7
|
+
function getBackgroundStateDir() {
|
|
8
|
+
if (process.env[JOB_STATE_DIR_ENV]) {
|
|
9
|
+
return path.resolve(process.env[JOB_STATE_DIR_ENV]);
|
|
10
|
+
}
|
|
11
|
+
if (process.env.CODEX_CLAUDE_RUN_LOG_DIR) {
|
|
12
|
+
return path.dirname(path.resolve(process.env.CODEX_CLAUDE_RUN_LOG_DIR));
|
|
13
|
+
}
|
|
14
|
+
return path.join(process.cwd(), ".codex-claude-delegate");
|
|
15
|
+
}
|
|
16
|
+
export async function markCancelled(jobId, createStore) {
|
|
17
|
+
const store = createStore ? createStore() : new JobStore(getBackgroundStateDir());
|
|
18
|
+
await store.init();
|
|
19
|
+
await store.update(jobId, {
|
|
20
|
+
status: "cancelled",
|
|
21
|
+
updated_at: new Date().toISOString(),
|
|
22
|
+
summary: "Cancelled by user",
|
|
23
|
+
error: undefined,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function registerTerminationHandler(jobId, deps = {}) {
|
|
27
|
+
const onSignal = deps.onSignal ?? ((signal, handler) => {
|
|
28
|
+
process.on(signal, handler);
|
|
29
|
+
});
|
|
30
|
+
const abort = deps.abortActiveClaudeRun ?? abortActiveClaudeRun;
|
|
31
|
+
const exit = deps.exit ?? ((code) => process.exit(code));
|
|
32
|
+
let shuttingDown = false;
|
|
33
|
+
const handleSigterm = () => {
|
|
34
|
+
if (shuttingDown)
|
|
35
|
+
return;
|
|
36
|
+
shuttingDown = true;
|
|
37
|
+
void (async () => {
|
|
38
|
+
await markCancelled(jobId, deps.createStore).catch(() => { });
|
|
39
|
+
abort("SIGTERM");
|
|
40
|
+
exit(0);
|
|
41
|
+
})();
|
|
42
|
+
};
|
|
43
|
+
onSignal("SIGTERM", handleSigterm);
|
|
44
|
+
return handleSigterm;
|
|
45
|
+
}
|
|
46
|
+
export async function runJobRunner(jobId, deps = {}) {
|
|
47
|
+
if (!jobId.trim()) {
|
|
48
|
+
throw new Error("jobId is required");
|
|
49
|
+
}
|
|
50
|
+
registerTerminationHandler(jobId, deps);
|
|
51
|
+
try {
|
|
52
|
+
await (deps.executeBackgroundJob ?? executeBackgroundJob)(jobId);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
if (deps.setExitCode) {
|
|
56
|
+
deps.setExitCode(1);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export async function main(argv = process.argv, deps = {}) {
|
|
64
|
+
const jobId = argv[2]?.trim() ?? "";
|
|
65
|
+
await runJobRunner(jobId, deps);
|
|
66
|
+
}
|
|
67
|
+
function isMainModule() {
|
|
68
|
+
if (!process.argv[1])
|
|
69
|
+
return false;
|
|
70
|
+
return fileURLToPath(import.meta.url) === resolve(process.argv[1]);
|
|
71
|
+
}
|
|
72
|
+
if (isMainModule()) {
|
|
73
|
+
await main();
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=job-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-runner.js","sourceRoot":"","sources":["../src/job-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/jobs.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BackgroundJobCleanupEntry, BackgroundJobStatus, BackgroundJobSummary, BackgroundJobType } from "./schema.js";
|
|
2
|
+
export interface BackgroundJobRecord extends BackgroundJobSummary {
|
|
3
|
+
payload: Record<string, unknown>;
|
|
4
|
+
result?: Record<string, unknown>;
|
|
5
|
+
}
|
|
6
|
+
interface JobListInput {
|
|
7
|
+
cwd: string;
|
|
8
|
+
limit: number;
|
|
9
|
+
status?: BackgroundJobStatus;
|
|
10
|
+
type?: BackgroundJobType;
|
|
11
|
+
}
|
|
12
|
+
interface JobCleanupInput {
|
|
13
|
+
cwd: string;
|
|
14
|
+
older_than_hours?: number;
|
|
15
|
+
dry_run: boolean;
|
|
16
|
+
limit: number;
|
|
17
|
+
}
|
|
18
|
+
interface ActiveFingerprintInput {
|
|
19
|
+
cwd: string;
|
|
20
|
+
type?: BackgroundJobType;
|
|
21
|
+
fingerprint: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class JobStore {
|
|
24
|
+
private readonly baseDir;
|
|
25
|
+
private readonly jobsDir;
|
|
26
|
+
constructor(baseDir: string);
|
|
27
|
+
init(): Promise<void>;
|
|
28
|
+
create(record: BackgroundJobRecord): Promise<void>;
|
|
29
|
+
get(jobId: string): Promise<BackgroundJobRecord | null>;
|
|
30
|
+
update(jobId: string, patch: Partial<BackgroundJobRecord>): Promise<BackgroundJobRecord | null>;
|
|
31
|
+
list(input: JobListInput): Promise<BackgroundJobRecord[]>;
|
|
32
|
+
cleanup(input: JobCleanupInput): Promise<{
|
|
33
|
+
dry_run: boolean;
|
|
34
|
+
matched_count: number;
|
|
35
|
+
removed_count: number;
|
|
36
|
+
failed_count: number;
|
|
37
|
+
entries: BackgroundJobCleanupEntry[];
|
|
38
|
+
}>;
|
|
39
|
+
findActiveByFingerprint(input: ActiveFingerprintInput): Promise<BackgroundJobRecord | null>;
|
|
40
|
+
touchHeartbeat(jobId: string, heartbeatAt?: string): Promise<BackgroundJobRecord | null>;
|
|
41
|
+
touchWait(jobId: string, waitAt?: string, recommendedDelayMs?: number): Promise<BackgroundJobRecord | null>;
|
|
42
|
+
private getJobPath;
|
|
43
|
+
private readAllRecords;
|
|
44
|
+
private writeRecord;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
package/dist/jobs.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, readFile, readdir, rename, unlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const TERMINAL_JOB_STATUSES = new Set(["succeeded", "failed", "cancelled"]);
|
|
5
|
+
const ACTIVE_JOB_STATUSES = new Set(["queued", "running"]);
|
|
6
|
+
export class JobStore {
|
|
7
|
+
baseDir;
|
|
8
|
+
jobsDir;
|
|
9
|
+
constructor(baseDir) {
|
|
10
|
+
this.baseDir = baseDir;
|
|
11
|
+
this.jobsDir = path.join(baseDir, "jobs");
|
|
12
|
+
}
|
|
13
|
+
async init() {
|
|
14
|
+
await mkdir(this.jobsDir, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
async create(record) {
|
|
17
|
+
await this.init();
|
|
18
|
+
await this.writeRecord(record);
|
|
19
|
+
}
|
|
20
|
+
async get(jobId) {
|
|
21
|
+
const filePath = this.getJobPath(jobId);
|
|
22
|
+
if (!existsSync(filePath))
|
|
23
|
+
return null;
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(await readFile(filePath, "utf8"));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async update(jobId, patch) {
|
|
32
|
+
const current = await this.get(jobId);
|
|
33
|
+
if (!current)
|
|
34
|
+
return null;
|
|
35
|
+
const next = {
|
|
36
|
+
...current,
|
|
37
|
+
...patch,
|
|
38
|
+
job_id: current.job_id,
|
|
39
|
+
};
|
|
40
|
+
await this.writeRecord(next);
|
|
41
|
+
return next;
|
|
42
|
+
}
|
|
43
|
+
async list(input) {
|
|
44
|
+
const jobs = await this.readAllRecords();
|
|
45
|
+
return jobs
|
|
46
|
+
.filter((entry) => entry !== null)
|
|
47
|
+
.filter((entry) => entry.cwd === input.cwd)
|
|
48
|
+
.filter((entry) => !input.status || entry.status === input.status)
|
|
49
|
+
.filter((entry) => !input.type || entry.type === input.type)
|
|
50
|
+
.sort((a, b) => b.updated_at.localeCompare(a.updated_at))
|
|
51
|
+
.slice(0, input.limit);
|
|
52
|
+
}
|
|
53
|
+
async cleanup(input) {
|
|
54
|
+
const cutoff = typeof input.older_than_hours === "number"
|
|
55
|
+
? Date.now() - (input.older_than_hours * 60 * 60 * 1000)
|
|
56
|
+
: null;
|
|
57
|
+
const jobs = (await this.readAllRecords())
|
|
58
|
+
.filter((entry) => entry !== null)
|
|
59
|
+
.filter((entry) => entry.cwd === input.cwd)
|
|
60
|
+
.filter((entry) => TERMINAL_JOB_STATUSES.has(entry.status))
|
|
61
|
+
.filter((entry) => {
|
|
62
|
+
if (cutoff === null)
|
|
63
|
+
return true;
|
|
64
|
+
const updatedAt = Date.parse(entry.updated_at);
|
|
65
|
+
return Number.isFinite(updatedAt) && updatedAt <= cutoff;
|
|
66
|
+
})
|
|
67
|
+
.sort((a, b) => a.updated_at.localeCompare(b.updated_at))
|
|
68
|
+
.slice(0, input.limit);
|
|
69
|
+
const entries = [];
|
|
70
|
+
let removedCount = 0;
|
|
71
|
+
let failedCount = 0;
|
|
72
|
+
for (const job of jobs) {
|
|
73
|
+
if (input.dry_run) {
|
|
74
|
+
entries.push({
|
|
75
|
+
job_id: job.job_id,
|
|
76
|
+
type: job.type,
|
|
77
|
+
status: job.status,
|
|
78
|
+
updated_at: job.updated_at,
|
|
79
|
+
removed: false,
|
|
80
|
+
summary: job.summary,
|
|
81
|
+
});
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
await unlink(this.getJobPath(job.job_id));
|
|
86
|
+
removedCount += 1;
|
|
87
|
+
entries.push({
|
|
88
|
+
job_id: job.job_id,
|
|
89
|
+
type: job.type,
|
|
90
|
+
status: job.status,
|
|
91
|
+
updated_at: job.updated_at,
|
|
92
|
+
removed: true,
|
|
93
|
+
summary: job.summary,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
failedCount += 1;
|
|
98
|
+
entries.push({
|
|
99
|
+
job_id: job.job_id,
|
|
100
|
+
type: job.type,
|
|
101
|
+
status: job.status,
|
|
102
|
+
updated_at: job.updated_at,
|
|
103
|
+
removed: false,
|
|
104
|
+
summary: job.summary,
|
|
105
|
+
error: err instanceof Error ? err.message : String(err),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
dry_run: input.dry_run,
|
|
111
|
+
matched_count: jobs.length,
|
|
112
|
+
removed_count: removedCount,
|
|
113
|
+
failed_count: failedCount,
|
|
114
|
+
entries,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async findActiveByFingerprint(input) {
|
|
118
|
+
const jobs = await this.readAllRecords();
|
|
119
|
+
const match = jobs
|
|
120
|
+
.filter((entry) => entry !== null)
|
|
121
|
+
.filter((entry) => entry.cwd === input.cwd)
|
|
122
|
+
.filter((entry) => !input.type || entry.type === input.type)
|
|
123
|
+
.filter((entry) => entry.fingerprint === input.fingerprint)
|
|
124
|
+
.filter((entry) => ACTIVE_JOB_STATUSES.has(entry.status))
|
|
125
|
+
.sort((a, b) => b.updated_at.localeCompare(a.updated_at))[0];
|
|
126
|
+
return match ?? null;
|
|
127
|
+
}
|
|
128
|
+
async touchHeartbeat(jobId, heartbeatAt = new Date().toISOString()) {
|
|
129
|
+
const current = await this.get(jobId);
|
|
130
|
+
if (!current)
|
|
131
|
+
return null;
|
|
132
|
+
if (TERMINAL_JOB_STATUSES.has(current.status))
|
|
133
|
+
return current;
|
|
134
|
+
return this.update(jobId, {
|
|
135
|
+
heartbeat_at: heartbeatAt,
|
|
136
|
+
updated_at: heartbeatAt,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async touchWait(jobId, waitAt = new Date().toISOString(), recommendedDelayMs) {
|
|
140
|
+
const current = await this.get(jobId);
|
|
141
|
+
if (!current)
|
|
142
|
+
return null;
|
|
143
|
+
if (TERMINAL_JOB_STATUSES.has(current.status))
|
|
144
|
+
return current;
|
|
145
|
+
return this.update(jobId, {
|
|
146
|
+
last_wait_at: waitAt,
|
|
147
|
+
last_wait_recommended_delay_ms: recommendedDelayMs,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
getJobPath(jobId) {
|
|
151
|
+
return path.join(this.jobsDir, `${jobId}.json`);
|
|
152
|
+
}
|
|
153
|
+
async readAllRecords() {
|
|
154
|
+
await this.init();
|
|
155
|
+
const entries = await readdir(this.jobsDir).catch(() => []);
|
|
156
|
+
return Promise.all(entries
|
|
157
|
+
.filter((entry) => entry.endsWith(".json"))
|
|
158
|
+
.map(async (entry) => {
|
|
159
|
+
try {
|
|
160
|
+
const raw = await readFile(path.join(this.jobsDir, entry), "utf8");
|
|
161
|
+
return JSON.parse(raw);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
async writeRecord(record) {
|
|
169
|
+
const filePath = this.getJobPath(record.job_id);
|
|
170
|
+
const tmpPath = `${filePath}.tmp`;
|
|
171
|
+
await writeFile(tmpPath, JSON.stringify(record, null, 2), "utf8");
|
|
172
|
+
await rename(tmpPath, filePath);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=jobs.js.map
|
package/dist/jobs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../src/jobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
let cached;
|
|
5
|
+
export async function getPackageInfo() {
|
|
6
|
+
if (cached)
|
|
7
|
+
return cached;
|
|
8
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const packageJsonPath = resolve(here, "..", "package.json");
|
|
10
|
+
const raw = await readFile(packageJsonPath, "utf8");
|
|
11
|
+
cached = JSON.parse(raw);
|
|
12
|
+
return cached;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=package-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-info.js","sourceRoot":"","sources":["../src/package-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,IAAI,MAAqD,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,eAAe,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsC,CAAC;IAC9D,OAAO,MAAM,CAAC;AAChB,CAAC"}
|