@kody-ade/kody-engine 0.4.28 → 0.4.29
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/dist/bin/kody.js +73 -17
- package/package.json +1 -1
package/dist/bin/kody.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@kody-ade/kody-engine",
|
|
6
|
-
version: "0.4.
|
|
6
|
+
version: "0.4.29",
|
|
7
7
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
8
8
|
license: "MIT",
|
|
9
9
|
type: "module",
|
|
@@ -4521,14 +4521,15 @@ var dispatchJobFileTicks = async (ctx, _profile, args) => {
|
|
|
4521
4521
|
const results = [];
|
|
4522
4522
|
const now = Date.now();
|
|
4523
4523
|
for (const slug of slugs) {
|
|
4524
|
-
const
|
|
4524
|
+
const frontmatter = readJobFrontmatter(ctx.cwd, jobsDir, slug);
|
|
4525
|
+
const decision = await decideShouldFire(frontmatter.every, slug, backend, now);
|
|
4525
4526
|
if (decision.skip) {
|
|
4526
4527
|
process.stdout.write(`[jobs] \u23ED skip ${slug}: ${decision.reason}
|
|
4527
4528
|
`);
|
|
4528
4529
|
results.push({ slug, exitCode: 0, skipped: true, reason: decision.reason });
|
|
4529
4530
|
continue;
|
|
4530
4531
|
}
|
|
4531
|
-
const slugTarget =
|
|
4532
|
+
const slugTarget = frontmatter.tickScript ? "job-tick-scripted" : targetExecutable;
|
|
4532
4533
|
process.stdout.write(`[jobs] \u2192 tick ${slug} (${slugTarget})
|
|
4533
4534
|
`);
|
|
4534
4535
|
try {
|
|
@@ -4565,14 +4566,7 @@ var dispatchJobFileTicks = async (ctx, _profile, args) => {
|
|
|
4565
4566
|
}
|
|
4566
4567
|
}
|
|
4567
4568
|
};
|
|
4568
|
-
async function decideShouldFire(
|
|
4569
|
-
let every;
|
|
4570
|
-
try {
|
|
4571
|
-
const raw = fs19.readFileSync(path18.join(cwd, jobsDir, `${slug}.md`), "utf-8");
|
|
4572
|
-
every = splitFrontmatter(raw).frontmatter.every;
|
|
4573
|
-
} catch {
|
|
4574
|
-
return { skip: false, reason: "frontmatter unreadable" };
|
|
4575
|
-
}
|
|
4569
|
+
async function decideShouldFire(every, slug, backend, now) {
|
|
4576
4570
|
if (!every) return { skip: false, reason: "no schedule (every cron tick)" };
|
|
4577
4571
|
if (every === "manual") {
|
|
4578
4572
|
return { skip: true, reason: "manual-only (no auto-fire; trigger via dashboard Run now)" };
|
|
@@ -4612,12 +4606,12 @@ function formatAgo(ms) {
|
|
|
4612
4606
|
const day = Math.round(hr / 24);
|
|
4613
4607
|
return `${day}d`;
|
|
4614
4608
|
}
|
|
4615
|
-
function
|
|
4609
|
+
function readJobFrontmatter(cwd, jobsDir, slug) {
|
|
4616
4610
|
try {
|
|
4617
4611
|
const raw = fs19.readFileSync(path18.join(cwd, jobsDir, `${slug}.md`), "utf-8");
|
|
4618
|
-
return splitFrontmatter(raw).frontmatter
|
|
4612
|
+
return splitFrontmatter(raw).frontmatter;
|
|
4619
4613
|
} catch {
|
|
4620
|
-
return
|
|
4614
|
+
return {};
|
|
4621
4615
|
}
|
|
4622
4616
|
}
|
|
4623
4617
|
function listJobSlugs(absDir) {
|
|
@@ -7267,15 +7261,29 @@ var runTickScript = async (ctx, _profile, args) => {
|
|
|
7267
7261
|
return;
|
|
7268
7262
|
}
|
|
7269
7263
|
const backend = resolveBackend({ config: ctx.config, cwd: ctx.cwd, jobsDir });
|
|
7270
|
-
|
|
7264
|
+
let loaded;
|
|
7265
|
+
try {
|
|
7266
|
+
loaded = await backend.load(slug);
|
|
7267
|
+
} catch (err) {
|
|
7268
|
+
ctx.output.exitCode = 99;
|
|
7269
|
+
ctx.output.reason = `runTickScript: state load failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
7270
|
+
return;
|
|
7271
|
+
}
|
|
7271
7272
|
ctx.data.jobSlug = slug;
|
|
7272
7273
|
ctx.data.jobState = loaded;
|
|
7274
|
+
const childEnv = buildChildEnv(process.env, Boolean(ctx.args.force));
|
|
7273
7275
|
const result = spawnSync("bash", [scriptPath], {
|
|
7274
7276
|
cwd: ctx.cwd,
|
|
7275
|
-
env:
|
|
7277
|
+
env: childEnv,
|
|
7276
7278
|
stdio: ["ignore", "pipe", "pipe"],
|
|
7277
7279
|
encoding: "utf-8",
|
|
7278
|
-
timeout: 5 * 60 * 1e3
|
|
7280
|
+
timeout: 5 * 60 * 1e3,
|
|
7281
|
+
// Default maxBuffer is 1MB — a chatty `gh pr list --json …` over a
|
|
7282
|
+
// busy repo (or an accidental `set -x`) can blow that and silently
|
|
7283
|
+
// truncate stdout, which is the exact "silent state drop" failure
|
|
7284
|
+
// mode this whole executable was written to prevent. 16MB is well
|
|
7285
|
+
// above any realistic tick output.
|
|
7286
|
+
maxBuffer: 16 * 1024 * 1024
|
|
7279
7287
|
});
|
|
7280
7288
|
if (result.stdout) process.stdout.write(result.stdout);
|
|
7281
7289
|
if (result.stderr) process.stderr.write(result.stderr);
|
|
@@ -7284,6 +7292,11 @@ var runTickScript = async (ctx, _profile, args) => {
|
|
|
7284
7292
|
ctx.output.reason = `runTickScript: spawn error: ${result.error.message}`;
|
|
7285
7293
|
return;
|
|
7286
7294
|
}
|
|
7295
|
+
if (result.signal) {
|
|
7296
|
+
ctx.output.exitCode = 124;
|
|
7297
|
+
ctx.output.reason = `runTickScript: ${tickScript} killed by ${result.signal} (likely 5min timeout)`;
|
|
7298
|
+
return;
|
|
7299
|
+
}
|
|
7287
7300
|
if (result.status !== 0) {
|
|
7288
7301
|
ctx.output.exitCode = result.status ?? 99;
|
|
7289
7302
|
ctx.output.reason = `runTickScript: ${tickScript} exited ${result.status}`;
|
|
@@ -7299,6 +7312,49 @@ var runTickScript = async (ctx, _profile, args) => {
|
|
|
7299
7312
|
}
|
|
7300
7313
|
ctx.data.nextJobState = parsed.envelope;
|
|
7301
7314
|
};
|
|
7315
|
+
function buildChildEnv(parent, force) {
|
|
7316
|
+
const allow = /* @__PURE__ */ new Set([
|
|
7317
|
+
"PATH",
|
|
7318
|
+
"HOME",
|
|
7319
|
+
"USER",
|
|
7320
|
+
"LOGNAME",
|
|
7321
|
+
"SHELL",
|
|
7322
|
+
"TMPDIR",
|
|
7323
|
+
"LANG",
|
|
7324
|
+
"LC_ALL",
|
|
7325
|
+
"TERM",
|
|
7326
|
+
// GitHub auth — `gh` reads these.
|
|
7327
|
+
"GH_TOKEN",
|
|
7328
|
+
"GH_PAT",
|
|
7329
|
+
"GITHUB_TOKEN",
|
|
7330
|
+
// CI metadata commonly read by tick scripts (`gh repo view`,
|
|
7331
|
+
// workflow run links, etc.). All public values from GitHub Actions.
|
|
7332
|
+
"GITHUB_ACTIONS",
|
|
7333
|
+
"GITHUB_ACTOR",
|
|
7334
|
+
"GITHUB_REPOSITORY",
|
|
7335
|
+
"GITHUB_REPOSITORY_OWNER",
|
|
7336
|
+
"GITHUB_REF",
|
|
7337
|
+
"GITHUB_SHA",
|
|
7338
|
+
"GITHUB_RUN_ID",
|
|
7339
|
+
"GITHUB_RUN_NUMBER",
|
|
7340
|
+
"GITHUB_WORKFLOW",
|
|
7341
|
+
"GITHUB_JOB",
|
|
7342
|
+
"GITHUB_SERVER_URL",
|
|
7343
|
+
"GITHUB_API_URL",
|
|
7344
|
+
"GITHUB_EVENT_NAME",
|
|
7345
|
+
"RUNNER_OS",
|
|
7346
|
+
"RUNNER_ARCH"
|
|
7347
|
+
]);
|
|
7348
|
+
const out = {};
|
|
7349
|
+
for (const [key, value] of Object.entries(parent)) {
|
|
7350
|
+
if (value === void 0) continue;
|
|
7351
|
+
if (allow.has(key) || key.startsWith("KODY_PUBLIC_")) {
|
|
7352
|
+
out[key] = value;
|
|
7353
|
+
}
|
|
7354
|
+
}
|
|
7355
|
+
if (force) out.KODY_FORCE = "1";
|
|
7356
|
+
return out;
|
|
7357
|
+
}
|
|
7302
7358
|
|
|
7303
7359
|
// src/scripts/saveTaskState.ts
|
|
7304
7360
|
var saveTaskState = async (ctx, profile) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.29",
|
|
4
4
|
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|