@kody-ade/kody-engine 0.4.99 → 0.4.101
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 +358 -272
- package/dist/executables/goal-scheduler/scheduler.sh +0 -0
- package/dist/executables/release-deploy/deploy.sh +0 -0
- package/dist/executables/release-prepare/prepare.sh +0 -0
- package/dist/executables/release-publish/publish.sh +0 -0
- package/dist/executables/resolve/apply-prefer.sh +0 -0
- package/dist/executables/revert/revert.sh +0 -0
- package/package.json +21 -20
package/dist/bin/kody.js
CHANGED
|
@@ -470,11 +470,11 @@ var init_issue = __esm({
|
|
|
470
470
|
|
|
471
471
|
// src/prompt.ts
|
|
472
472
|
import * as fs18 from "fs";
|
|
473
|
-
import * as
|
|
473
|
+
import * as path17 from "path";
|
|
474
474
|
function loadProjectConventions(projectDir) {
|
|
475
475
|
const out = [];
|
|
476
476
|
for (const rel of CONVENTION_FILES) {
|
|
477
|
-
const abs =
|
|
477
|
+
const abs = path17.join(projectDir, rel);
|
|
478
478
|
if (!fs18.existsSync(abs)) continue;
|
|
479
479
|
let content;
|
|
480
480
|
try {
|
|
@@ -627,7 +627,7 @@ __export(loadMemoryContext_exports, {
|
|
|
627
627
|
loadMemoryContext: () => loadMemoryContext
|
|
628
628
|
});
|
|
629
629
|
import * as fs33 from "fs";
|
|
630
|
-
import * as
|
|
630
|
+
import * as path32 from "path";
|
|
631
631
|
function collectPages(memoryAbs) {
|
|
632
632
|
const out = [];
|
|
633
633
|
walkMd(memoryAbs, (file) => {
|
|
@@ -644,10 +644,10 @@ function collectPages(memoryAbs) {
|
|
|
644
644
|
return;
|
|
645
645
|
}
|
|
646
646
|
const fm = raw.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
647
|
-
const title = fm?.[1]?.match(/^title:\s*(.+)$/m)?.[1]?.trim() ??
|
|
647
|
+
const title = fm?.[1]?.match(/^title:\s*(.+)$/m)?.[1]?.trim() ?? path32.basename(file, ".md");
|
|
648
648
|
const updated = fm?.[1]?.match(/^updated:\s*([0-9T:.+\-Z]+)/m)?.[1]?.trim() ?? "";
|
|
649
649
|
out.push({
|
|
650
|
-
relPath:
|
|
650
|
+
relPath: path32.relative(memoryAbs, file),
|
|
651
651
|
title,
|
|
652
652
|
updated,
|
|
653
653
|
content: raw.length > PER_PAGE_MAX_BYTES ? raw.slice(0, PER_PAGE_MAX_BYTES) + TRUNCATED_SUFFIX : raw,
|
|
@@ -721,7 +721,7 @@ function walkMd(root, visit) {
|
|
|
721
721
|
}
|
|
722
722
|
for (const name of names) {
|
|
723
723
|
if (name.startsWith(".")) continue;
|
|
724
|
-
const full =
|
|
724
|
+
const full = path32.join(dir, name);
|
|
725
725
|
let stat;
|
|
726
726
|
try {
|
|
727
727
|
stat = fs33.statSync(full);
|
|
@@ -747,7 +747,7 @@ var init_loadMemoryContext = __esm({
|
|
|
747
747
|
TRUNCATED_SUFFIX = "\n\n\u2026 (truncated)";
|
|
748
748
|
loadMemoryContext = async (ctx) => {
|
|
749
749
|
if (typeof ctx.data.memoryContext === "string") return;
|
|
750
|
-
const memoryAbs =
|
|
750
|
+
const memoryAbs = path32.join(ctx.cwd, MEMORY_DIR_RELATIVE);
|
|
751
751
|
if (!fs33.existsSync(memoryAbs)) {
|
|
752
752
|
ctx.data.memoryContext = "";
|
|
753
753
|
return;
|
|
@@ -765,7 +765,10 @@ var init_loadMemoryContext = __esm({
|
|
|
765
765
|
}
|
|
766
766
|
const queryTerms = extractQueryTerms(ctx);
|
|
767
767
|
const ranked = queryTerms.length > 0 ? scorePages(pages, queryTerms) : sortByRecency(pages);
|
|
768
|
-
const
|
|
768
|
+
const indexPage = pages.find((p) => p.relPath === "INDEX.md");
|
|
769
|
+
const withoutIndex = ranked.filter((p) => p.relPath !== "INDEX.md");
|
|
770
|
+
const ordered = indexPage ? [indexPage, ...withoutIndex] : withoutIndex;
|
|
771
|
+
const top = ordered.slice(0, MAX_PAGES);
|
|
769
772
|
ctx.data.memoryContext = formatBlock(top);
|
|
770
773
|
};
|
|
771
774
|
}
|
|
@@ -877,7 +880,7 @@ var init_loadPriorArt = __esm({
|
|
|
877
880
|
// package.json
|
|
878
881
|
var package_default = {
|
|
879
882
|
name: "@kody-ade/kody-engine",
|
|
880
|
-
version: "0.4.
|
|
883
|
+
version: "0.4.101",
|
|
881
884
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
882
885
|
license: "MIT",
|
|
883
886
|
type: "module",
|
|
@@ -931,9 +934,9 @@ var package_default = {
|
|
|
931
934
|
};
|
|
932
935
|
|
|
933
936
|
// src/chat-cli.ts
|
|
934
|
-
import { execFileSync as
|
|
937
|
+
import { execFileSync as execFileSync32 } from "child_process";
|
|
935
938
|
import * as fs39 from "fs";
|
|
936
|
-
import * as
|
|
939
|
+
import * as path37 from "path";
|
|
937
940
|
|
|
938
941
|
// src/chat/events.ts
|
|
939
942
|
import * as fs from "fs";
|
|
@@ -1000,6 +1003,7 @@ function makeRunId(sessionId, suffix) {
|
|
|
1000
1003
|
|
|
1001
1004
|
// src/chat/loop.ts
|
|
1002
1005
|
import * as fs9 from "fs";
|
|
1006
|
+
import * as path9 from "path";
|
|
1003
1007
|
|
|
1004
1008
|
// src/task-artifacts.ts
|
|
1005
1009
|
import fs2 from "fs";
|
|
@@ -1996,7 +2000,8 @@ async function runChatTurn(opts) {
|
|
|
1996
2000
|
taskType: "chat",
|
|
1997
2001
|
relDir: taskArtifactsPaths.relDir
|
|
1998
2002
|
});
|
|
1999
|
-
const
|
|
2003
|
+
const memoryBlock = readMemoryIndexBlock(opts.cwd);
|
|
2004
|
+
const systemPrompt = [basePrompt, memoryBlock, catalog, artifactAddendum].filter((s) => typeof s === "string" && s.length > 0).join("\n\n");
|
|
2000
2005
|
const prompt = buildPrompt(turns);
|
|
2001
2006
|
let progressSeq = 0;
|
|
2002
2007
|
const invoke = opts.invokeAgent ?? ((p) => runAgent({
|
|
@@ -2088,12 +2093,33 @@ async function emit(sink, type, sessionId, suffix, payload) {
|
|
|
2088
2093
|
emittedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2089
2094
|
});
|
|
2090
2095
|
}
|
|
2096
|
+
var MEMORY_INDEX_REL = ".kody/memory/INDEX.md";
|
|
2097
|
+
var MAX_INDEX_BYTES = 8e3;
|
|
2098
|
+
function readMemoryIndexBlock(cwd) {
|
|
2099
|
+
const indexPath = path9.join(cwd, MEMORY_INDEX_REL);
|
|
2100
|
+
let raw;
|
|
2101
|
+
try {
|
|
2102
|
+
raw = fs9.readFileSync(indexPath, "utf-8");
|
|
2103
|
+
} catch {
|
|
2104
|
+
return "";
|
|
2105
|
+
}
|
|
2106
|
+
const trimmed = raw.trim();
|
|
2107
|
+
if (!trimmed) return "";
|
|
2108
|
+
const body = trimmed.length > MAX_INDEX_BYTES ? trimmed.slice(0, MAX_INDEX_BYTES) + "\n\n_\u2026 (memory index truncated; open individual files under `.kody/memory/` to read more)_" : trimmed;
|
|
2109
|
+
return [
|
|
2110
|
+
"# Project memory index (`.kody/memory/INDEX.md`)",
|
|
2111
|
+
"",
|
|
2112
|
+
"These are the lessons, decisions, and preferences already captured for this repo. Skim before acting; read individual files only if a line looks relevant to the current task.",
|
|
2113
|
+
"",
|
|
2114
|
+
body
|
|
2115
|
+
].join("\n");
|
|
2116
|
+
}
|
|
2091
2117
|
|
|
2092
2118
|
// src/chat/modes/interactive.ts
|
|
2093
2119
|
init_issue();
|
|
2094
2120
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
2095
2121
|
import * as fs10 from "fs";
|
|
2096
|
-
import * as
|
|
2122
|
+
import * as path10 from "path";
|
|
2097
2123
|
|
|
2098
2124
|
// src/chat/inbox.ts
|
|
2099
2125
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
@@ -2252,9 +2278,9 @@ function findNextUserTurn(turns, fromIdx) {
|
|
|
2252
2278
|
return -1;
|
|
2253
2279
|
}
|
|
2254
2280
|
function commitTurn(cwd, sessionId, _verbose) {
|
|
2255
|
-
const sessionRel =
|
|
2256
|
-
const eventsRel =
|
|
2257
|
-
const rels = [sessionRel, eventsRel].filter((p) => fs10.existsSync(
|
|
2281
|
+
const sessionRel = path10.relative(cwd, sessionFilePath(cwd, sessionId));
|
|
2282
|
+
const eventsRel = path10.relative(cwd, eventsFilePath(cwd, sessionId));
|
|
2283
|
+
const rels = [sessionRel, eventsRel].filter((p) => fs10.existsSync(path10.join(cwd, p)));
|
|
2258
2284
|
if (rels.length === 0) return;
|
|
2259
2285
|
const repository = process.env.GITHUB_REPOSITORY;
|
|
2260
2286
|
if (!repository) {
|
|
@@ -2266,8 +2292,8 @@ function commitTurn(cwd, sessionId, _verbose) {
|
|
|
2266
2292
|
}
|
|
2267
2293
|
const branch = defaultBranch(cwd) ?? "main";
|
|
2268
2294
|
for (const rel of rels) {
|
|
2269
|
-
const repoPath = rel.split(
|
|
2270
|
-
const localText = fs10.readFileSync(
|
|
2295
|
+
const repoPath = rel.split(path10.sep).join("/");
|
|
2296
|
+
const localText = fs10.readFileSync(path10.join(cwd, rel), "utf-8");
|
|
2271
2297
|
putJsonlViaContents(repository, branch, repoPath, localText, sessionId, cwd);
|
|
2272
2298
|
}
|
|
2273
2299
|
}
|
|
@@ -2356,9 +2382,9 @@ async function emit2(sink, type, sessionId, suffix, payload) {
|
|
|
2356
2382
|
}
|
|
2357
2383
|
|
|
2358
2384
|
// src/kody-cli.ts
|
|
2359
|
-
import { execFileSync as
|
|
2385
|
+
import { execFileSync as execFileSync31 } from "child_process";
|
|
2360
2386
|
import * as fs38 from "fs";
|
|
2361
|
-
import * as
|
|
2387
|
+
import * as path36 from "path";
|
|
2362
2388
|
|
|
2363
2389
|
// src/dispatch.ts
|
|
2364
2390
|
import * as fs11 from "fs";
|
|
@@ -2679,9 +2705,9 @@ function coerceBare(spec, value) {
|
|
|
2679
2705
|
init_issue();
|
|
2680
2706
|
|
|
2681
2707
|
// src/executor.ts
|
|
2682
|
-
import { execFileSync as
|
|
2708
|
+
import { execFileSync as execFileSync30, spawn as spawn6 } from "child_process";
|
|
2683
2709
|
import * as fs37 from "fs";
|
|
2684
|
-
import * as
|
|
2710
|
+
import * as path35 from "path";
|
|
2685
2711
|
init_events();
|
|
2686
2712
|
|
|
2687
2713
|
// src/lifecycleLabels.ts
|
|
@@ -2689,7 +2715,7 @@ init_issue();
|
|
|
2689
2715
|
|
|
2690
2716
|
// src/profile.ts
|
|
2691
2717
|
import * as fs12 from "fs";
|
|
2692
|
-
import * as
|
|
2718
|
+
import * as path11 from "path";
|
|
2693
2719
|
|
|
2694
2720
|
// src/profile-error.ts
|
|
2695
2721
|
var ProfileError = class extends Error {
|
|
@@ -2873,7 +2899,7 @@ function loadProfile(profilePath) {
|
|
|
2873
2899
|
const unknownKeys = Object.keys(r).filter((k) => !KNOWN_PROFILE_KEYS.has(k));
|
|
2874
2900
|
if (unknownKeys.length > 0) {
|
|
2875
2901
|
process.stderr.write(
|
|
2876
|
-
`[kody profile] ${
|
|
2902
|
+
`[kody profile] ${path11.basename(path11.dirname(profilePath))}: unknown top-level keys ignored: ${unknownKeys.join(", ")}
|
|
2877
2903
|
`
|
|
2878
2904
|
);
|
|
2879
2905
|
}
|
|
@@ -2934,7 +2960,7 @@ function loadProfile(profilePath) {
|
|
|
2934
2960
|
// Phase 5 in-process handoff opt-in. Default false; containers
|
|
2935
2961
|
// flip to true after end-to-end verification.
|
|
2936
2962
|
preloadContext: r.preloadContext === true,
|
|
2937
|
-
dir:
|
|
2963
|
+
dir: path11.dirname(profilePath)
|
|
2938
2964
|
};
|
|
2939
2965
|
if (lifecycle) {
|
|
2940
2966
|
applyLifecycle(profile, profilePath);
|
|
@@ -3306,7 +3332,7 @@ function errMsg(err) {
|
|
|
3306
3332
|
import { execFileSync as execFileSync4, spawn as spawn2 } from "child_process";
|
|
3307
3333
|
import * as fs13 from "fs";
|
|
3308
3334
|
import * as os2 from "os";
|
|
3309
|
-
import * as
|
|
3335
|
+
import * as path12 from "path";
|
|
3310
3336
|
async function checkLitellmHealth(url) {
|
|
3311
3337
|
try {
|
|
3312
3338
|
const response = await fetch(`${url}/health`, { signal: AbortSignal.timeout(3e3) });
|
|
@@ -3353,13 +3379,13 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
|
|
|
3353
3379
|
throw new Error("litellm not installed \u2014 run: pip install 'litellm[proxy]'");
|
|
3354
3380
|
}
|
|
3355
3381
|
}
|
|
3356
|
-
const configPath =
|
|
3382
|
+
const configPath = path12.join(os2.tmpdir(), `kody-litellm-${Date.now()}.yaml`);
|
|
3357
3383
|
fs13.writeFileSync(configPath, generateLitellmConfigYaml(model));
|
|
3358
3384
|
const portMatch = url.match(/:(\d+)/);
|
|
3359
3385
|
const port = portMatch ? portMatch[1] : "4000";
|
|
3360
3386
|
const args = cmd === "litellm" ? ["--config", configPath, "--port", port] : ["-m", "litellm", "--config", configPath, "--port", port];
|
|
3361
3387
|
const dotenvVars = readDotenvApiKeys(projectDir);
|
|
3362
|
-
const logPath =
|
|
3388
|
+
const logPath = path12.join(os2.tmpdir(), `kody-litellm-${Date.now()}.log`);
|
|
3363
3389
|
const outFd = fs13.openSync(logPath, "w");
|
|
3364
3390
|
const child = spawn2(cmd, args, {
|
|
3365
3391
|
stdio: ["ignore", outFd, outFd],
|
|
@@ -3397,7 +3423,7 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
|
|
|
3397
3423
|
${logTail}`);
|
|
3398
3424
|
}
|
|
3399
3425
|
function readDotenvApiKeys(projectDir) {
|
|
3400
|
-
const dotenvPath =
|
|
3426
|
+
const dotenvPath = path12.join(projectDir, ".env");
|
|
3401
3427
|
if (!fs13.existsSync(dotenvPath)) return {};
|
|
3402
3428
|
const result = {};
|
|
3403
3429
|
for (const rawLine of fs13.readFileSync(dotenvPath, "utf-8").split("\n")) {
|
|
@@ -3423,9 +3449,87 @@ function stripBlockingEnv(env) {
|
|
|
3423
3449
|
}
|
|
3424
3450
|
|
|
3425
3451
|
// src/commit.ts
|
|
3452
|
+
import { execFileSync as execFileSync6 } from "child_process";
|
|
3453
|
+
|
|
3454
|
+
// src/pushWithRetry.ts
|
|
3426
3455
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
3456
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
3457
|
+
var DEFAULT_BACKOFF_MS = 1e3;
|
|
3458
|
+
var MAX_BACKOFF_MS = 6e4;
|
|
3459
|
+
var NON_FAST_FORWARD_RE = /non-fast-forward|fetch first|\(rejected\)|! \[rejected\]/i;
|
|
3460
|
+
function sleepSync(ms) {
|
|
3461
|
+
if (ms <= 0) return;
|
|
3462
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
3463
|
+
}
|
|
3464
|
+
function runGit(args, cwd) {
|
|
3465
|
+
try {
|
|
3466
|
+
const stdout = execFileSync5("git", args, {
|
|
3467
|
+
cwd,
|
|
3468
|
+
encoding: "utf-8",
|
|
3469
|
+
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
3470
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3471
|
+
});
|
|
3472
|
+
return { ok: true, stdout: stdout?.toString() ?? "", stderr: "" };
|
|
3473
|
+
} catch (err) {
|
|
3474
|
+
const e = err;
|
|
3475
|
+
const stderr = e.stderr?.toString() ?? e.message ?? "";
|
|
3476
|
+
const stdout = e.stdout?.toString() ?? "";
|
|
3477
|
+
return { ok: false, stdout, stderr };
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
function resolveBranch(cwd, explicit) {
|
|
3481
|
+
if (explicit && explicit.trim()) return explicit.trim();
|
|
3482
|
+
const r = runGit(["symbolic-ref", "--short", "HEAD"], cwd);
|
|
3483
|
+
return r.ok ? r.stdout.trim() : "";
|
|
3484
|
+
}
|
|
3485
|
+
function pushWithRetry(opts = {}) {
|
|
3486
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
3487
|
+
const maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
3488
|
+
const baseBackoff = opts.backoffMs ?? DEFAULT_BACKOFF_MS;
|
|
3489
|
+
const branch = resolveBranch(cwd, opts.branch);
|
|
3490
|
+
if (!branch) {
|
|
3491
|
+
return { ok: false, reason: "could not determine current branch (detached HEAD?)", attempts: 0 };
|
|
3492
|
+
}
|
|
3493
|
+
const pushArgs = opts.setUpstream ? ["push", "-u", "origin", `HEAD:${branch}`] : ["push", "origin", "HEAD"];
|
|
3494
|
+
let lastError = "";
|
|
3495
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
3496
|
+
const push = runGit(pushArgs, cwd);
|
|
3497
|
+
if (push.ok) return { ok: true, attempts: attempt };
|
|
3498
|
+
lastError = push.stderr || push.stdout || "(no error detail)";
|
|
3499
|
+
if (!NON_FAST_FORWARD_RE.test(lastError)) {
|
|
3500
|
+
return { ok: false, reason: `push failed (not retryable): ${lastError.trim().slice(-400)}`, attempts: attempt };
|
|
3501
|
+
}
|
|
3502
|
+
if (attempt === maxRetries) break;
|
|
3503
|
+
const fetch2 = runGit(["fetch", "origin", branch], cwd);
|
|
3504
|
+
if (!fetch2.ok) {
|
|
3505
|
+
return {
|
|
3506
|
+
ok: false,
|
|
3507
|
+
reason: `fetch failed during retry: ${(fetch2.stderr || fetch2.stdout).trim().slice(-400)}`,
|
|
3508
|
+
attempts: attempt
|
|
3509
|
+
};
|
|
3510
|
+
}
|
|
3511
|
+
const rebase = runGit(["rebase", `origin/${branch}`], cwd);
|
|
3512
|
+
if (!rebase.ok) {
|
|
3513
|
+
runGit(["rebase", "--abort"], cwd);
|
|
3514
|
+
return {
|
|
3515
|
+
ok: false,
|
|
3516
|
+
reason: `rebase onto origin/${branch} failed (conflict?): ${(rebase.stderr || rebase.stdout).trim().slice(-400)}`,
|
|
3517
|
+
attempts: attempt
|
|
3518
|
+
};
|
|
3519
|
+
}
|
|
3520
|
+
const delay = Math.min(baseBackoff * 2 ** (attempt - 1), MAX_BACKOFF_MS);
|
|
3521
|
+
sleepSync(delay);
|
|
3522
|
+
}
|
|
3523
|
+
return {
|
|
3524
|
+
ok: false,
|
|
3525
|
+
reason: `push rejected after ${maxRetries} attempts: ${lastError.trim().slice(-400)}`,
|
|
3526
|
+
attempts: maxRetries
|
|
3527
|
+
};
|
|
3528
|
+
}
|
|
3529
|
+
|
|
3530
|
+
// src/commit.ts
|
|
3427
3531
|
import * as fs14 from "fs";
|
|
3428
|
-
import * as
|
|
3532
|
+
import * as path13 from "path";
|
|
3429
3533
|
var FORBIDDEN_PATH_PREFIXES = [
|
|
3430
3534
|
".kody/",
|
|
3431
3535
|
".kody-engine/",
|
|
@@ -3436,7 +3540,7 @@ var FORBIDDEN_PATH_PREFIXES = [
|
|
|
3436
3540
|
"dist/",
|
|
3437
3541
|
"build/"
|
|
3438
3542
|
];
|
|
3439
|
-
var ALLOWED_PATH_PREFIXES = [".kody/memory/"];
|
|
3543
|
+
var ALLOWED_PATH_PREFIXES = [".kody/memory/", ".kody/tasks/"];
|
|
3440
3544
|
var FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".kody-pip-requirements.txt"]);
|
|
3441
3545
|
var FORBIDDEN_PATH_SUFFIXES = [".log"];
|
|
3442
3546
|
var CONVENTIONAL_PREFIXES = [
|
|
@@ -3452,13 +3556,9 @@ var CONVENTIONAL_PREFIXES = [
|
|
|
3452
3556
|
"build:",
|
|
3453
3557
|
"revert:"
|
|
3454
3558
|
];
|
|
3455
|
-
var PUSH_RETRY_DELAYS_MS = [2e3, 4e3, 8e3];
|
|
3456
|
-
function sleepSync(ms) {
|
|
3457
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
3458
|
-
}
|
|
3459
3559
|
function git(args, cwd) {
|
|
3460
3560
|
try {
|
|
3461
|
-
return
|
|
3561
|
+
return execFileSync6("git", args, {
|
|
3462
3562
|
encoding: "utf-8",
|
|
3463
3563
|
timeout: 12e4,
|
|
3464
3564
|
cwd,
|
|
@@ -3485,18 +3585,18 @@ function tryGit(args, cwd) {
|
|
|
3485
3585
|
}
|
|
3486
3586
|
function abortUnfinishedGitOps(cwd) {
|
|
3487
3587
|
const aborted = [];
|
|
3488
|
-
const gitDir =
|
|
3588
|
+
const gitDir = path13.join(cwd ?? process.cwd(), ".git");
|
|
3489
3589
|
if (!fs14.existsSync(gitDir)) return aborted;
|
|
3490
|
-
if (fs14.existsSync(
|
|
3590
|
+
if (fs14.existsSync(path13.join(gitDir, "MERGE_HEAD"))) {
|
|
3491
3591
|
if (tryGit(["merge", "--abort"], cwd)) aborted.push("merge");
|
|
3492
3592
|
}
|
|
3493
|
-
if (fs14.existsSync(
|
|
3593
|
+
if (fs14.existsSync(path13.join(gitDir, "CHERRY_PICK_HEAD"))) {
|
|
3494
3594
|
if (tryGit(["cherry-pick", "--abort"], cwd)) aborted.push("cherry-pick");
|
|
3495
3595
|
}
|
|
3496
|
-
if (fs14.existsSync(
|
|
3596
|
+
if (fs14.existsSync(path13.join(gitDir, "REVERT_HEAD"))) {
|
|
3497
3597
|
if (tryGit(["revert", "--abort"], cwd)) aborted.push("revert");
|
|
3498
3598
|
}
|
|
3499
|
-
if (fs14.existsSync(
|
|
3599
|
+
if (fs14.existsSync(path13.join(gitDir, "rebase-merge")) || fs14.existsSync(path13.join(gitDir, "rebase-apply"))) {
|
|
3500
3600
|
if (tryGit(["rebase", "--abort"], cwd)) aborted.push("rebase");
|
|
3501
3601
|
}
|
|
3502
3602
|
try {
|
|
@@ -3517,7 +3617,7 @@ function isForbiddenPath(p) {
|
|
|
3517
3617
|
return false;
|
|
3518
3618
|
}
|
|
3519
3619
|
function listChangedFiles(cwd) {
|
|
3520
|
-
const raw =
|
|
3620
|
+
const raw = execFileSync6("git", ["status", "--porcelain=v1", "-z"], {
|
|
3521
3621
|
encoding: "utf-8",
|
|
3522
3622
|
cwd,
|
|
3523
3623
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
@@ -3529,7 +3629,7 @@ function listChangedFiles(cwd) {
|
|
|
3529
3629
|
}
|
|
3530
3630
|
function listFilesInCommit(ref = "HEAD", cwd) {
|
|
3531
3631
|
try {
|
|
3532
|
-
const raw =
|
|
3632
|
+
const raw = execFileSync6("git", ["show", "--name-only", "--pretty=format:", "-z", ref], {
|
|
3533
3633
|
encoding: "utf-8",
|
|
3534
3634
|
cwd,
|
|
3535
3635
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
@@ -3552,7 +3652,7 @@ function normalizeCommitMessage(raw) {
|
|
|
3552
3652
|
function commitAndPush(branch, agentMessage, cwd) {
|
|
3553
3653
|
const allChanged = listChangedFiles(cwd);
|
|
3554
3654
|
const allowedFiles = allChanged.filter((f) => !isForbiddenPath(f));
|
|
3555
|
-
const mergeHeadExists = fs14.existsSync(
|
|
3655
|
+
const mergeHeadExists = fs14.existsSync(path13.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
|
|
3556
3656
|
if (allowedFiles.length === 0 && !mergeHeadExists) {
|
|
3557
3657
|
return { committed: false, pushed: false, sha: "", message: "" };
|
|
3558
3658
|
}
|
|
@@ -3573,28 +3673,11 @@ function commitAndPush(branch, agentMessage, cwd) {
|
|
|
3573
3673
|
throw err;
|
|
3574
3674
|
}
|
|
3575
3675
|
const sha = git(["rev-parse", "HEAD"], cwd).slice(0, 7);
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
git(["push", "-u", "origin", branch], cwd);
|
|
3580
|
-
return { committed: true, pushed: true, sha, message };
|
|
3581
|
-
} catch (firstErr) {
|
|
3582
|
-
try {
|
|
3583
|
-
git(["push", "--force-with-lease", "-u", "origin", branch], cwd);
|
|
3584
|
-
return { committed: true, pushed: true, sha, message };
|
|
3585
|
-
} catch (secondErr) {
|
|
3586
|
-
const tail = (secondErr instanceof Error ? secondErr.message : String(secondErr)).slice(-400);
|
|
3587
|
-
const initial = firstErr instanceof Error ? firstErr.message : String(firstErr);
|
|
3588
|
-
pushError = `push failed: ${initial.slice(-200)} | force-with-lease failed: ${tail}`;
|
|
3589
|
-
const delay = PUSH_RETRY_DELAYS_MS[attempt];
|
|
3590
|
-
if (delay === void 0) break;
|
|
3591
|
-
process.stderr.write(`[kody:commit] push failed (attempt ${attempt + 1}); retrying in ${delay}ms
|
|
3592
|
-
`);
|
|
3593
|
-
sleepSync(delay);
|
|
3594
|
-
}
|
|
3595
|
-
}
|
|
3676
|
+
const pushResult = pushWithRetry({ cwd, branch, setUpstream: true });
|
|
3677
|
+
if (pushResult.ok) {
|
|
3678
|
+
return { committed: true, pushed: true, sha, message };
|
|
3596
3679
|
}
|
|
3597
|
-
return { committed: true, pushed: false, sha, message, pushError };
|
|
3680
|
+
return { committed: true, pushed: false, sha, message, pushError: pushResult.reason };
|
|
3598
3681
|
}
|
|
3599
3682
|
function hasCommitsAhead(branch, defaultBranch2, cwd) {
|
|
3600
3683
|
try {
|
|
@@ -3621,10 +3704,10 @@ var abortUnfinishedGitOps2 = async (ctx) => {
|
|
|
3621
3704
|
};
|
|
3622
3705
|
|
|
3623
3706
|
// src/scripts/advanceFlow.ts
|
|
3624
|
-
import { execFileSync as
|
|
3707
|
+
import { execFileSync as execFileSync8 } from "child_process";
|
|
3625
3708
|
|
|
3626
3709
|
// src/state.ts
|
|
3627
|
-
import { execFileSync as
|
|
3710
|
+
import { execFileSync as execFileSync7 } from "child_process";
|
|
3628
3711
|
var STATE_BEGIN = "<!-- kody:state:v1:begin -->";
|
|
3629
3712
|
var STATE_END = "<!-- kody:state:v1:end -->";
|
|
3630
3713
|
var HISTORY_MAX_ENTRIES = 20;
|
|
@@ -3650,7 +3733,7 @@ function ghToken2() {
|
|
|
3650
3733
|
function gh2(args, input, cwd) {
|
|
3651
3734
|
const token = ghToken2();
|
|
3652
3735
|
const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
|
|
3653
|
-
return
|
|
3736
|
+
return execFileSync7("gh", args, {
|
|
3654
3737
|
encoding: "utf-8",
|
|
3655
3738
|
timeout: API_TIMEOUT_MS2,
|
|
3656
3739
|
cwd,
|
|
@@ -3853,7 +3936,7 @@ var advanceFlow = async (ctx, profile) => {
|
|
|
3853
3936
|
}
|
|
3854
3937
|
const body = `@kody ${flow.name}`;
|
|
3855
3938
|
try {
|
|
3856
|
-
|
|
3939
|
+
execFileSync8("gh", ["issue", "comment", String(flow.issueNumber), "--body", body], {
|
|
3857
3940
|
timeout: API_TIMEOUT_MS3,
|
|
3858
3941
|
cwd: ctx.cwd,
|
|
3859
3942
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -3869,14 +3952,14 @@ var advanceFlow = async (ctx, profile) => {
|
|
|
3869
3952
|
// src/scripts/brainServe.ts
|
|
3870
3953
|
import { createServer } from "http";
|
|
3871
3954
|
import * as fs16 from "fs";
|
|
3872
|
-
import * as
|
|
3955
|
+
import * as path15 from "path";
|
|
3873
3956
|
|
|
3874
3957
|
// src/scripts/brainTurnLog.ts
|
|
3875
3958
|
import * as fs15 from "fs";
|
|
3876
|
-
import * as
|
|
3959
|
+
import * as path14 from "path";
|
|
3877
3960
|
var live = /* @__PURE__ */ new Map();
|
|
3878
3961
|
function eventsPath(dir, chatId) {
|
|
3879
|
-
return
|
|
3962
|
+
return path14.join(dir, ".kody", "brain-events", `${chatId}.jsonl`);
|
|
3880
3963
|
}
|
|
3881
3964
|
function lastPersistedSeq(dir, chatId) {
|
|
3882
3965
|
const p = eventsPath(dir, chatId);
|
|
@@ -3919,7 +4002,7 @@ function beginTurn(dir, chatId) {
|
|
|
3919
4002
|
};
|
|
3920
4003
|
live.set(chatId, state);
|
|
3921
4004
|
const p = eventsPath(dir, chatId);
|
|
3922
|
-
fs15.mkdirSync(
|
|
4005
|
+
fs15.mkdirSync(path14.dirname(p), { recursive: true });
|
|
3923
4006
|
return (event) => {
|
|
3924
4007
|
state.seq += 1;
|
|
3925
4008
|
const rec = { seq: state.seq, turn, ts: Date.now(), event };
|
|
@@ -4179,7 +4262,7 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
4179
4262
|
return;
|
|
4180
4263
|
}
|
|
4181
4264
|
const sessionFile = sessionFilePath(opts.cwd, chatId);
|
|
4182
|
-
fs16.mkdirSync(
|
|
4265
|
+
fs16.mkdirSync(path15.dirname(sessionFile), { recursive: true });
|
|
4183
4266
|
appendTurn(sessionFile, {
|
|
4184
4267
|
role: "user",
|
|
4185
4268
|
content: message,
|
|
@@ -4321,15 +4404,15 @@ var brainServe = async (ctx) => {
|
|
|
4321
4404
|
// src/scripts/buildSyntheticPlugin.ts
|
|
4322
4405
|
import * as fs17 from "fs";
|
|
4323
4406
|
import * as os3 from "os";
|
|
4324
|
-
import * as
|
|
4407
|
+
import * as path16 from "path";
|
|
4325
4408
|
function getPluginsCatalogRoot() {
|
|
4326
|
-
const here =
|
|
4409
|
+
const here = path16.dirname(new URL(import.meta.url).pathname);
|
|
4327
4410
|
const candidates = [
|
|
4328
|
-
|
|
4411
|
+
path16.join(here, "..", "plugins"),
|
|
4329
4412
|
// dev: src/scripts → src/plugins
|
|
4330
|
-
|
|
4413
|
+
path16.join(here, "..", "..", "plugins"),
|
|
4331
4414
|
// built: dist/scripts → dist/plugins
|
|
4332
|
-
|
|
4415
|
+
path16.join(here, "..", "..", "src", "plugins")
|
|
4333
4416
|
// fallback
|
|
4334
4417
|
];
|
|
4335
4418
|
for (const c of candidates) {
|
|
@@ -4343,40 +4426,40 @@ var buildSyntheticPlugin = async (ctx, profile) => {
|
|
|
4343
4426
|
if (!needsSynthetic) return;
|
|
4344
4427
|
const catalog = getPluginsCatalogRoot();
|
|
4345
4428
|
const runId = `${profile.name}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
4346
|
-
const root =
|
|
4347
|
-
fs17.mkdirSync(
|
|
4429
|
+
const root = path16.join(os3.tmpdir(), `kody-synth-${runId}`);
|
|
4430
|
+
fs17.mkdirSync(path16.join(root, ".claude-plugin"), { recursive: true });
|
|
4348
4431
|
const resolvePart = (bucket, entry) => {
|
|
4349
|
-
const local =
|
|
4432
|
+
const local = path16.join(profile.dir, bucket, entry);
|
|
4350
4433
|
if (fs17.existsSync(local)) return local;
|
|
4351
|
-
const central =
|
|
4434
|
+
const central = path16.join(catalog, bucket, entry);
|
|
4352
4435
|
if (fs17.existsSync(central)) return central;
|
|
4353
4436
|
throw new Error(
|
|
4354
4437
|
`buildSyntheticPlugin: ${bucket} entry '${entry}' not found in executable dir (${profile.dir}/${bucket}/) or catalog (${catalog}/${bucket}/)`
|
|
4355
4438
|
);
|
|
4356
4439
|
};
|
|
4357
4440
|
if (cc.skills.length > 0) {
|
|
4358
|
-
const dst =
|
|
4441
|
+
const dst = path16.join(root, "skills");
|
|
4359
4442
|
fs17.mkdirSync(dst, { recursive: true });
|
|
4360
4443
|
for (const name of cc.skills) {
|
|
4361
|
-
copyDir(resolvePart("skills", name),
|
|
4444
|
+
copyDir(resolvePart("skills", name), path16.join(dst, name));
|
|
4362
4445
|
}
|
|
4363
4446
|
}
|
|
4364
4447
|
if (cc.commands.length > 0) {
|
|
4365
|
-
const dst =
|
|
4448
|
+
const dst = path16.join(root, "commands");
|
|
4366
4449
|
fs17.mkdirSync(dst, { recursive: true });
|
|
4367
4450
|
for (const name of cc.commands) {
|
|
4368
|
-
fs17.copyFileSync(resolvePart("commands", `${name}.md`),
|
|
4451
|
+
fs17.copyFileSync(resolvePart("commands", `${name}.md`), path16.join(dst, `${name}.md`));
|
|
4369
4452
|
}
|
|
4370
4453
|
}
|
|
4371
4454
|
if (cc.subagents.length > 0) {
|
|
4372
|
-
const dst =
|
|
4455
|
+
const dst = path16.join(root, "agents");
|
|
4373
4456
|
fs17.mkdirSync(dst, { recursive: true });
|
|
4374
4457
|
for (const name of cc.subagents) {
|
|
4375
|
-
fs17.copyFileSync(resolvePart("agents", `${name}.md`),
|
|
4458
|
+
fs17.copyFileSync(resolvePart("agents", `${name}.md`), path16.join(dst, `${name}.md`));
|
|
4376
4459
|
}
|
|
4377
4460
|
}
|
|
4378
4461
|
if (cc.hooks.length > 0) {
|
|
4379
|
-
const dst =
|
|
4462
|
+
const dst = path16.join(root, "hooks");
|
|
4380
4463
|
fs17.mkdirSync(dst, { recursive: true });
|
|
4381
4464
|
const merged = { hooks: {} };
|
|
4382
4465
|
for (const name of cc.hooks) {
|
|
@@ -4388,7 +4471,7 @@ var buildSyntheticPlugin = async (ctx, profile) => {
|
|
|
4388
4471
|
merged.hooks[event].push(...entries);
|
|
4389
4472
|
}
|
|
4390
4473
|
}
|
|
4391
|
-
fs17.writeFileSync(
|
|
4474
|
+
fs17.writeFileSync(path16.join(dst, "hooks.json"), `${JSON.stringify(merged, null, 2)}
|
|
4392
4475
|
`);
|
|
4393
4476
|
}
|
|
4394
4477
|
const manifest = {
|
|
@@ -4399,22 +4482,22 @@ var buildSyntheticPlugin = async (ctx, profile) => {
|
|
|
4399
4482
|
if (cc.skills.length > 0) manifest.skills = ["./skills/"];
|
|
4400
4483
|
if (cc.commands.length > 0) manifest.commands = ["./commands/"];
|
|
4401
4484
|
if (cc.subagents.length > 0) manifest.agents = cc.subagents.map((n) => `./agents/${n}.md`);
|
|
4402
|
-
fs17.writeFileSync(
|
|
4485
|
+
fs17.writeFileSync(path16.join(root, ".claude-plugin", "plugin.json"), `${JSON.stringify(manifest, null, 2)}
|
|
4403
4486
|
`);
|
|
4404
4487
|
ctx.data.syntheticPluginPath = root;
|
|
4405
4488
|
};
|
|
4406
4489
|
function copyDir(src, dst) {
|
|
4407
4490
|
fs17.mkdirSync(dst, { recursive: true });
|
|
4408
4491
|
for (const ent of fs17.readdirSync(src, { withFileTypes: true })) {
|
|
4409
|
-
const s =
|
|
4410
|
-
const d =
|
|
4492
|
+
const s = path16.join(src, ent.name);
|
|
4493
|
+
const d = path16.join(dst, ent.name);
|
|
4411
4494
|
if (ent.isDirectory()) copyDir(s, d);
|
|
4412
4495
|
else if (ent.isFile()) fs17.copyFileSync(s, d);
|
|
4413
4496
|
}
|
|
4414
4497
|
}
|
|
4415
4498
|
|
|
4416
4499
|
// src/coverage.ts
|
|
4417
|
-
import { execFileSync as
|
|
4500
|
+
import { execFileSync as execFileSync9 } from "child_process";
|
|
4418
4501
|
function patternToRegex(pattern) {
|
|
4419
4502
|
let s = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
4420
4503
|
s = s.replace(/\*\*\//g, "\xA7S").replace(/\*\*/g, "\xA7A").replace(/\*/g, "[^/]*");
|
|
@@ -4432,7 +4515,7 @@ function renderSiblingPath(file, requireSibling) {
|
|
|
4432
4515
|
}
|
|
4433
4516
|
function safeGit(args, cwd) {
|
|
4434
4517
|
try {
|
|
4435
|
-
return
|
|
4518
|
+
return execFileSync9("git", args, { encoding: "utf-8", cwd, env: { ...process.env, HUSKY: "0" } }).trim();
|
|
4436
4519
|
} catch {
|
|
4437
4520
|
return "";
|
|
4438
4521
|
}
|
|
@@ -4551,12 +4634,12 @@ function defaultLabelMap() {
|
|
|
4551
4634
|
|
|
4552
4635
|
// src/scripts/commitAndPush.ts
|
|
4553
4636
|
import * as fs19 from "fs";
|
|
4554
|
-
import * as
|
|
4637
|
+
import * as path18 from "path";
|
|
4555
4638
|
init_events();
|
|
4556
4639
|
var DEFAULT_COMMIT_MESSAGE = "chore: kody changes";
|
|
4557
4640
|
function sentinelPathForStage(cwd, profileName) {
|
|
4558
4641
|
const runId = resolveRunId();
|
|
4559
|
-
return
|
|
4642
|
+
return path18.join(cwd, ".kody", "runs", runId, `commit-${profileName}.lock`);
|
|
4560
4643
|
}
|
|
4561
4644
|
var commitAndPush2 = async (ctx, profile) => {
|
|
4562
4645
|
const branch = ctx.data.branch;
|
|
@@ -4621,7 +4704,7 @@ var commitAndPush2 = async (ctx, profile) => {
|
|
|
4621
4704
|
const result = ctx.data.commitResult;
|
|
4622
4705
|
if (sentinel && result?.committed) {
|
|
4623
4706
|
try {
|
|
4624
|
-
fs19.mkdirSync(
|
|
4707
|
+
fs19.mkdirSync(path18.dirname(sentinel), { recursive: true });
|
|
4625
4708
|
fs19.writeFileSync(
|
|
4626
4709
|
sentinel,
|
|
4627
4710
|
JSON.stringify(
|
|
@@ -4642,14 +4725,14 @@ var commitAndPush2 = async (ctx, profile) => {
|
|
|
4642
4725
|
};
|
|
4643
4726
|
|
|
4644
4727
|
// src/scripts/commitGoalState.ts
|
|
4645
|
-
import { execFileSync as
|
|
4646
|
-
import * as
|
|
4728
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
4729
|
+
import * as path19 from "path";
|
|
4647
4730
|
var commitGoalState = async (ctx) => {
|
|
4648
4731
|
const goal = ctx.data.goal;
|
|
4649
4732
|
if (!goal) return;
|
|
4650
|
-
const stateRel =
|
|
4733
|
+
const stateRel = path19.posix.join(".kody", "goals", goal.id, "state.json");
|
|
4651
4734
|
try {
|
|
4652
|
-
|
|
4735
|
+
execFileSync10("git", ["add", stateRel], { cwd: ctx.cwd, stdio: "pipe" });
|
|
4653
4736
|
} catch (err) {
|
|
4654
4737
|
process.stderr.write(
|
|
4655
4738
|
`[goal-tick] commitGoalState: git add failed: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -4658,13 +4741,13 @@ var commitGoalState = async (ctx) => {
|
|
|
4658
4741
|
return;
|
|
4659
4742
|
}
|
|
4660
4743
|
try {
|
|
4661
|
-
|
|
4744
|
+
execFileSync10("git", ["diff", "--cached", "--quiet"], { cwd: ctx.cwd, stdio: "pipe" });
|
|
4662
4745
|
return;
|
|
4663
4746
|
} catch {
|
|
4664
4747
|
}
|
|
4665
4748
|
const msg = describeCommitMessage(goal);
|
|
4666
4749
|
try {
|
|
4667
|
-
|
|
4750
|
+
execFileSync10("git", ["commit", "-m", msg, "--quiet"], { cwd: ctx.cwd, stdio: "pipe" });
|
|
4668
4751
|
} catch (err) {
|
|
4669
4752
|
process.stderr.write(
|
|
4670
4753
|
`[goal-tick] commitGoalState: git commit failed: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -4672,10 +4755,10 @@ var commitGoalState = async (ctx) => {
|
|
|
4672
4755
|
);
|
|
4673
4756
|
return;
|
|
4674
4757
|
}
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4758
|
+
const result = pushWithRetry({ cwd: ctx.cwd });
|
|
4759
|
+
if (!result.ok) {
|
|
4760
|
+
process.stderr.write(`[goal-tick] commitGoalState: push failed (${result.reason}); will retry next tick
|
|
4761
|
+
`);
|
|
4679
4762
|
}
|
|
4680
4763
|
};
|
|
4681
4764
|
function describeCommitMessage(goal) {
|
|
@@ -4693,15 +4776,15 @@ function describeCommitMessage(goal) {
|
|
|
4693
4776
|
|
|
4694
4777
|
// src/scripts/composePrompt.ts
|
|
4695
4778
|
import * as fs20 from "fs";
|
|
4696
|
-
import * as
|
|
4779
|
+
import * as path20 from "path";
|
|
4697
4780
|
var MUSTACHE = /\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g;
|
|
4698
4781
|
var composePrompt = async (ctx, profile) => {
|
|
4699
4782
|
const explicit = ctx.data.promptTemplate;
|
|
4700
4783
|
const mode = ctx.args.mode;
|
|
4701
4784
|
const candidates = [
|
|
4702
|
-
explicit ?
|
|
4703
|
-
mode ?
|
|
4704
|
-
|
|
4785
|
+
explicit ? path20.join(profile.dir, explicit) : null,
|
|
4786
|
+
mode ? path20.join(profile.dir, "prompts", `${mode}.md`) : null,
|
|
4787
|
+
path20.join(profile.dir, "prompt.md")
|
|
4705
4788
|
].filter(Boolean);
|
|
4706
4789
|
let templatePath = "";
|
|
4707
4790
|
for (const c of candidates) {
|
|
@@ -4791,9 +4874,9 @@ function formatToolsUsage(profile) {
|
|
|
4791
4874
|
|
|
4792
4875
|
// src/scripts/createQaGoal.ts
|
|
4793
4876
|
init_issue();
|
|
4794
|
-
import { execFileSync as
|
|
4877
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
4795
4878
|
import * as fs21 from "fs";
|
|
4796
|
-
import * as
|
|
4879
|
+
import * as path21 from "path";
|
|
4797
4880
|
|
|
4798
4881
|
// src/scripts/postReviewResult.ts
|
|
4799
4882
|
init_issue();
|
|
@@ -5046,7 +5129,7 @@ function createOrUpdateManifestIssue(number, manifest, cwd) {
|
|
|
5046
5129
|
return { number: Number(m[1]), created: true };
|
|
5047
5130
|
}
|
|
5048
5131
|
function writeStateFile(cwd, goalId, lastDispatchedIssue) {
|
|
5049
|
-
const dir =
|
|
5132
|
+
const dir = path21.join(cwd, ".kody", "goals", goalId);
|
|
5050
5133
|
fs21.mkdirSync(dir, { recursive: true });
|
|
5051
5134
|
const state = {
|
|
5052
5135
|
version: 1,
|
|
@@ -5055,7 +5138,7 @@ function writeStateFile(cwd, goalId, lastDispatchedIssue) {
|
|
|
5055
5138
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5056
5139
|
...typeof lastDispatchedIssue === "number" ? { lastDispatchedIssue } : {}
|
|
5057
5140
|
};
|
|
5058
|
-
const filePath =
|
|
5141
|
+
const filePath = path21.join(dir, "state.json");
|
|
5059
5142
|
fs21.writeFileSync(filePath, `${JSON.stringify(state, null, 2)}
|
|
5060
5143
|
`);
|
|
5061
5144
|
return filePath;
|
|
@@ -5063,7 +5146,7 @@ function writeStateFile(cwd, goalId, lastDispatchedIssue) {
|
|
|
5063
5146
|
function gitTry(args, cwd) {
|
|
5064
5147
|
const env = { ...process.env, SKIP_HOOKS: "1", HUSKY: "0" };
|
|
5065
5148
|
try {
|
|
5066
|
-
|
|
5149
|
+
execFileSync11("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"], env });
|
|
5067
5150
|
return { ok: true, stderr: "" };
|
|
5068
5151
|
} catch (err) {
|
|
5069
5152
|
const e = err;
|
|
@@ -5564,13 +5647,13 @@ function filterGoalTaskPrs(prs, taskIssueNumbers) {
|
|
|
5564
5647
|
}
|
|
5565
5648
|
|
|
5566
5649
|
// src/scripts/diagMcp.ts
|
|
5567
|
-
import { execFileSync as
|
|
5650
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
5568
5651
|
import * as fs22 from "fs";
|
|
5569
5652
|
import * as os4 from "os";
|
|
5570
|
-
import * as
|
|
5653
|
+
import * as path22 from "path";
|
|
5571
5654
|
var diagMcp = async (_ctx) => {
|
|
5572
5655
|
const home = os4.homedir();
|
|
5573
|
-
const cacheDir =
|
|
5656
|
+
const cacheDir = path22.join(home, ".cache", "ms-playwright");
|
|
5574
5657
|
let entries = [];
|
|
5575
5658
|
try {
|
|
5576
5659
|
entries = fs22.readdirSync(cacheDir);
|
|
@@ -5584,7 +5667,7 @@ var diagMcp = async (_ctx) => {
|
|
|
5584
5667
|
process.stderr.write(`[kody diag] chromium present: ${hasChromium ? "yes" : "no"}
|
|
5585
5668
|
`);
|
|
5586
5669
|
try {
|
|
5587
|
-
const v =
|
|
5670
|
+
const v = execFileSync12("npx", ["-y", "--package=@playwright/mcp@latest", "--", "playwright-mcp", "--version"], {
|
|
5588
5671
|
stdio: "pipe",
|
|
5589
5672
|
timeout: 6e4,
|
|
5590
5673
|
encoding: "utf8"
|
|
@@ -5600,16 +5683,16 @@ var diagMcp = async (_ctx) => {
|
|
|
5600
5683
|
|
|
5601
5684
|
// src/scripts/discoverQaContext.ts
|
|
5602
5685
|
import * as fs24 from "fs";
|
|
5603
|
-
import * as
|
|
5686
|
+
import * as path24 from "path";
|
|
5604
5687
|
|
|
5605
5688
|
// src/scripts/frameworkDetectors.ts
|
|
5606
5689
|
import * as fs23 from "fs";
|
|
5607
|
-
import * as
|
|
5690
|
+
import * as path23 from "path";
|
|
5608
5691
|
function detectFrameworks(cwd) {
|
|
5609
5692
|
const out = [];
|
|
5610
5693
|
let deps = {};
|
|
5611
5694
|
try {
|
|
5612
|
-
const pkg = JSON.parse(fs23.readFileSync(
|
|
5695
|
+
const pkg = JSON.parse(fs23.readFileSync(path23.join(cwd, "package.json"), "utf-8"));
|
|
5613
5696
|
deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
5614
5697
|
} catch {
|
|
5615
5698
|
return out;
|
|
@@ -5646,7 +5729,7 @@ function detectFrameworks(cwd) {
|
|
|
5646
5729
|
}
|
|
5647
5730
|
function findFile(cwd, candidates) {
|
|
5648
5731
|
for (const c of candidates) {
|
|
5649
|
-
if (fs23.existsSync(
|
|
5732
|
+
if (fs23.existsSync(path23.join(cwd, c))) return c;
|
|
5650
5733
|
}
|
|
5651
5734
|
return null;
|
|
5652
5735
|
}
|
|
@@ -5659,7 +5742,7 @@ var COLLECTION_DIRS = [
|
|
|
5659
5742
|
function discoverPayloadCollections(cwd) {
|
|
5660
5743
|
const out = [];
|
|
5661
5744
|
for (const dir of COLLECTION_DIRS) {
|
|
5662
|
-
const full =
|
|
5745
|
+
const full = path23.join(cwd, dir);
|
|
5663
5746
|
if (!fs23.existsSync(full)) continue;
|
|
5664
5747
|
let files;
|
|
5665
5748
|
try {
|
|
@@ -5669,7 +5752,7 @@ function discoverPayloadCollections(cwd) {
|
|
|
5669
5752
|
}
|
|
5670
5753
|
for (const file of files) {
|
|
5671
5754
|
try {
|
|
5672
|
-
const filePath =
|
|
5755
|
+
const filePath = path23.join(full, file);
|
|
5673
5756
|
const content = fs23.readFileSync(filePath, "utf-8").slice(0, 1e4);
|
|
5674
5757
|
const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
|
|
5675
5758
|
if (!slugMatch) continue;
|
|
@@ -5684,7 +5767,7 @@ function discoverPayloadCollections(cwd) {
|
|
|
5684
5767
|
out.push({
|
|
5685
5768
|
name,
|
|
5686
5769
|
slug,
|
|
5687
|
-
filePath:
|
|
5770
|
+
filePath: path23.relative(cwd, filePath),
|
|
5688
5771
|
fields: fields.slice(0, 20),
|
|
5689
5772
|
hasAdmin
|
|
5690
5773
|
});
|
|
@@ -5698,7 +5781,7 @@ var ADMIN_COMPONENT_DIRS = ["src/ui/admin", "src/admin/components", "src/compone
|
|
|
5698
5781
|
function discoverAdminComponents(cwd, collections) {
|
|
5699
5782
|
const out = [];
|
|
5700
5783
|
for (const dir of ADMIN_COMPONENT_DIRS) {
|
|
5701
|
-
const full =
|
|
5784
|
+
const full = path23.join(cwd, dir);
|
|
5702
5785
|
if (!fs23.existsSync(full)) continue;
|
|
5703
5786
|
let entries;
|
|
5704
5787
|
try {
|
|
@@ -5707,19 +5790,19 @@ function discoverAdminComponents(cwd, collections) {
|
|
|
5707
5790
|
continue;
|
|
5708
5791
|
}
|
|
5709
5792
|
for (const entry of entries) {
|
|
5710
|
-
const entryPath =
|
|
5793
|
+
const entryPath = path23.join(full, entry.name);
|
|
5711
5794
|
let name;
|
|
5712
5795
|
let filePath;
|
|
5713
5796
|
if (entry.isDirectory()) {
|
|
5714
5797
|
const indexFile = ["index.tsx", "index.ts", "index.jsx", "index.js"].find(
|
|
5715
|
-
(f) => fs23.existsSync(
|
|
5798
|
+
(f) => fs23.existsSync(path23.join(entryPath, f))
|
|
5716
5799
|
);
|
|
5717
5800
|
if (!indexFile) continue;
|
|
5718
5801
|
name = entry.name;
|
|
5719
|
-
filePath =
|
|
5802
|
+
filePath = path23.relative(cwd, path23.join(entryPath, indexFile));
|
|
5720
5803
|
} else if (/\.(tsx?|jsx?)$/.test(entry.name)) {
|
|
5721
5804
|
name = entry.name.replace(/\.(tsx?|jsx?)$/, "");
|
|
5722
|
-
filePath =
|
|
5805
|
+
filePath = path23.relative(cwd, entryPath);
|
|
5723
5806
|
} else {
|
|
5724
5807
|
continue;
|
|
5725
5808
|
}
|
|
@@ -5727,7 +5810,7 @@ function discoverAdminComponents(cwd, collections) {
|
|
|
5727
5810
|
if (collections) {
|
|
5728
5811
|
for (const col of collections) {
|
|
5729
5812
|
try {
|
|
5730
|
-
const colContent = fs23.readFileSync(
|
|
5813
|
+
const colContent = fs23.readFileSync(path23.join(cwd, col.filePath), "utf-8");
|
|
5731
5814
|
if (colContent.includes(name)) {
|
|
5732
5815
|
usedInCollection = col.slug;
|
|
5733
5816
|
break;
|
|
@@ -5746,7 +5829,7 @@ function scanApiRoutes(cwd) {
|
|
|
5746
5829
|
const out = [];
|
|
5747
5830
|
const appDirs = ["src/app", "app"];
|
|
5748
5831
|
for (const appDir of appDirs) {
|
|
5749
|
-
const apiDir =
|
|
5832
|
+
const apiDir = path23.join(cwd, appDir, "api");
|
|
5750
5833
|
if (!fs23.existsSync(apiDir)) continue;
|
|
5751
5834
|
walkApiRoutes(apiDir, "/api", cwd, out);
|
|
5752
5835
|
break;
|
|
@@ -5763,7 +5846,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
|
|
|
5763
5846
|
const routeFile = entries.find((e) => e.isFile() && /^route\.(ts|js|tsx|jsx)$/.test(e.name));
|
|
5764
5847
|
if (routeFile) {
|
|
5765
5848
|
try {
|
|
5766
|
-
const content = fs23.readFileSync(
|
|
5849
|
+
const content = fs23.readFileSync(path23.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
|
|
5767
5850
|
const methods = HTTP_METHODS.filter(
|
|
5768
5851
|
(m) => new RegExp(`export\\s+(?:async\\s+)?function\\s+${m}\\b`).test(content)
|
|
5769
5852
|
);
|
|
@@ -5771,7 +5854,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
|
|
|
5771
5854
|
out.push({
|
|
5772
5855
|
path: prefix,
|
|
5773
5856
|
methods,
|
|
5774
|
-
filePath:
|
|
5857
|
+
filePath: path23.relative(cwd, path23.join(dir, routeFile.name))
|
|
5775
5858
|
});
|
|
5776
5859
|
}
|
|
5777
5860
|
} catch {
|
|
@@ -5782,7 +5865,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
|
|
|
5782
5865
|
if (entry.name === "node_modules" || entry.name === ".next") continue;
|
|
5783
5866
|
let segment = entry.name;
|
|
5784
5867
|
if (segment.startsWith("(") && segment.endsWith(")")) {
|
|
5785
|
-
walkApiRoutes(
|
|
5868
|
+
walkApiRoutes(path23.join(dir, entry.name), prefix, cwd, out);
|
|
5786
5869
|
continue;
|
|
5787
5870
|
}
|
|
5788
5871
|
if (segment.startsWith("[[") && segment.endsWith("]]")) {
|
|
@@ -5790,7 +5873,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
|
|
|
5790
5873
|
} else if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
5791
5874
|
segment = `:${segment.slice(1, -1)}`;
|
|
5792
5875
|
}
|
|
5793
|
-
walkApiRoutes(
|
|
5876
|
+
walkApiRoutes(path23.join(dir, entry.name), `${prefix}/${segment}`, cwd, out);
|
|
5794
5877
|
}
|
|
5795
5878
|
}
|
|
5796
5879
|
var BUILTIN_ENV_VARS = /* @__PURE__ */ new Set([
|
|
@@ -5810,7 +5893,7 @@ var BUILTIN_ENV_VARS = /* @__PURE__ */ new Set([
|
|
|
5810
5893
|
function scanEnvVars(cwd) {
|
|
5811
5894
|
const candidates = [".env.example", ".env.local.example", ".env.template"];
|
|
5812
5895
|
for (const envFile of candidates) {
|
|
5813
|
-
const envPath =
|
|
5896
|
+
const envPath = path23.join(cwd, envFile);
|
|
5814
5897
|
if (!fs23.existsSync(envPath)) continue;
|
|
5815
5898
|
try {
|
|
5816
5899
|
const content = fs23.readFileSync(envPath, "utf-8");
|
|
@@ -5861,9 +5944,9 @@ function runQaDiscovery(cwd) {
|
|
|
5861
5944
|
}
|
|
5862
5945
|
function detectDevServer(cwd, out) {
|
|
5863
5946
|
try {
|
|
5864
|
-
const pkg = JSON.parse(fs24.readFileSync(
|
|
5947
|
+
const pkg = JSON.parse(fs24.readFileSync(path24.join(cwd, "package.json"), "utf-8"));
|
|
5865
5948
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
5866
|
-
const pm = fs24.existsSync(
|
|
5949
|
+
const pm = fs24.existsSync(path24.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs24.existsSync(path24.join(cwd, "yarn.lock")) ? "yarn" : fs24.existsSync(path24.join(cwd, "bun.lockb")) ? "bun" : "npm";
|
|
5867
5950
|
if (pkg.scripts?.dev) out.devCommand = `${pm} dev`;
|
|
5868
5951
|
if (allDeps.next || allDeps.nuxt) out.devPort = 3e3;
|
|
5869
5952
|
else if (allDeps.vite) out.devPort = 5173;
|
|
@@ -5873,7 +5956,7 @@ function detectDevServer(cwd, out) {
|
|
|
5873
5956
|
function scanFrontendRoutes(cwd, out) {
|
|
5874
5957
|
const appDirs = ["src/app", "app"];
|
|
5875
5958
|
for (const appDir of appDirs) {
|
|
5876
|
-
const full =
|
|
5959
|
+
const full = path24.join(cwd, appDir);
|
|
5877
5960
|
if (!fs24.existsSync(full)) continue;
|
|
5878
5961
|
walkFrontendRoutes(full, "", out);
|
|
5879
5962
|
break;
|
|
@@ -5899,7 +5982,7 @@ function walkFrontendRoutes(dir, prefix, out) {
|
|
|
5899
5982
|
if (entry.name === "node_modules" || entry.name === ".next") continue;
|
|
5900
5983
|
let segment = entry.name;
|
|
5901
5984
|
if (segment.startsWith("(") && segment.endsWith(")")) {
|
|
5902
|
-
walkFrontendRoutes(
|
|
5985
|
+
walkFrontendRoutes(path24.join(dir, entry.name), prefix, out);
|
|
5903
5986
|
continue;
|
|
5904
5987
|
}
|
|
5905
5988
|
if (segment.startsWith("[[") && segment.endsWith("]]")) {
|
|
@@ -5907,7 +5990,7 @@ function walkFrontendRoutes(dir, prefix, out) {
|
|
|
5907
5990
|
} else if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
5908
5991
|
segment = `:${segment.slice(1, -1)}`;
|
|
5909
5992
|
}
|
|
5910
|
-
walkFrontendRoutes(
|
|
5993
|
+
walkFrontendRoutes(path24.join(dir, entry.name), `${prefix}/${segment}`, out);
|
|
5911
5994
|
}
|
|
5912
5995
|
}
|
|
5913
5996
|
function detectAuthFiles(cwd, out) {
|
|
@@ -5924,13 +6007,13 @@ function detectAuthFiles(cwd, out) {
|
|
|
5924
6007
|
"src/app/api/oauth"
|
|
5925
6008
|
];
|
|
5926
6009
|
for (const c of candidates) {
|
|
5927
|
-
if (fs24.existsSync(
|
|
6010
|
+
if (fs24.existsSync(path24.join(cwd, c))) out.authFiles.push(c);
|
|
5928
6011
|
}
|
|
5929
6012
|
}
|
|
5930
6013
|
function detectRoles(cwd, out) {
|
|
5931
6014
|
const rolePaths = ["src/types", "src/lib", "src/utils", "src/constants", "src/access", "src/collections"];
|
|
5932
6015
|
for (const rp of rolePaths) {
|
|
5933
|
-
const dir =
|
|
6016
|
+
const dir = path24.join(cwd, rp);
|
|
5934
6017
|
if (!fs24.existsSync(dir)) continue;
|
|
5935
6018
|
let files;
|
|
5936
6019
|
try {
|
|
@@ -5940,7 +6023,7 @@ function detectRoles(cwd, out) {
|
|
|
5940
6023
|
}
|
|
5941
6024
|
for (const f of files) {
|
|
5942
6025
|
try {
|
|
5943
|
-
const content = fs24.readFileSync(
|
|
6026
|
+
const content = fs24.readFileSync(path24.join(dir, f), "utf-8").slice(0, 5e3);
|
|
5944
6027
|
const roleMatches = content.match(/(?:role|Role|ROLE)\s*[=:]\s*['"](\w+)['"]/g);
|
|
5945
6028
|
if (roleMatches) {
|
|
5946
6029
|
for (const m of roleMatches) {
|
|
@@ -6086,7 +6169,7 @@ var discoverQaContext = async (ctx) => {
|
|
|
6086
6169
|
};
|
|
6087
6170
|
|
|
6088
6171
|
// src/scripts/dispatch.ts
|
|
6089
|
-
import { execFileSync as
|
|
6172
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
6090
6173
|
var API_TIMEOUT_MS4 = 3e4;
|
|
6091
6174
|
var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
6092
6175
|
const next = args?.next;
|
|
@@ -6122,7 +6205,7 @@ var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
|
6122
6205
|
const sub = usePr ? "pr" : "issue";
|
|
6123
6206
|
const body = `@kody ${next}`;
|
|
6124
6207
|
try {
|
|
6125
|
-
|
|
6208
|
+
execFileSync13("gh", [sub, "comment", String(targetNumber), "--body", body], {
|
|
6126
6209
|
timeout: API_TIMEOUT_MS4,
|
|
6127
6210
|
cwd: ctx.cwd,
|
|
6128
6211
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -6142,7 +6225,7 @@ function parsePr(url) {
|
|
|
6142
6225
|
}
|
|
6143
6226
|
|
|
6144
6227
|
// src/scripts/dispatchClassified.ts
|
|
6145
|
-
import { execFileSync as
|
|
6228
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
6146
6229
|
var API_TIMEOUT_MS5 = 3e4;
|
|
6147
6230
|
var VALID_CLASSES2 = /* @__PURE__ */ new Set(["feature", "bug", "spec", "chore"]);
|
|
6148
6231
|
var dispatchClassified = async (ctx) => {
|
|
@@ -6166,7 +6249,7 @@ ${auditLine}
|
|
|
6166
6249
|
|
|
6167
6250
|
${stateBody}`;
|
|
6168
6251
|
try {
|
|
6169
|
-
|
|
6252
|
+
execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
6170
6253
|
cwd: ctx.cwd,
|
|
6171
6254
|
timeout: API_TIMEOUT_MS5,
|
|
6172
6255
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -6187,7 +6270,7 @@ function failedAction3(reason) {
|
|
|
6187
6270
|
|
|
6188
6271
|
// src/scripts/dispatchJobFileTicks.ts
|
|
6189
6272
|
import * as fs26 from "fs";
|
|
6190
|
-
import * as
|
|
6273
|
+
import * as path26 from "path";
|
|
6191
6274
|
|
|
6192
6275
|
// src/scripts/jobFrontmatter.ts
|
|
6193
6276
|
var SCHEDULE_EVERY_VALUES = [
|
|
@@ -6449,7 +6532,7 @@ var ContentsApiBackend = class {
|
|
|
6449
6532
|
|
|
6450
6533
|
// src/scripts/jobState/localFileBackend.ts
|
|
6451
6534
|
import * as fs25 from "fs";
|
|
6452
|
-
import * as
|
|
6535
|
+
import * as path25 from "path";
|
|
6453
6536
|
var LocalFileBackend = class {
|
|
6454
6537
|
name = "local-file";
|
|
6455
6538
|
cwd;
|
|
@@ -6464,7 +6547,7 @@ var LocalFileBackend = class {
|
|
|
6464
6547
|
if (!opts.owner || !opts.repo) throw new Error("LocalFileBackend: owner and repo are required");
|
|
6465
6548
|
this.cwd = opts.cwd;
|
|
6466
6549
|
this.jobsDir = opts.jobsDir;
|
|
6467
|
-
this.absDir =
|
|
6550
|
+
this.absDir = path25.join(opts.cwd, opts.jobsDir);
|
|
6468
6551
|
this.owner = opts.owner;
|
|
6469
6552
|
this.repo = opts.repo;
|
|
6470
6553
|
this.cache = opts.cache ?? defaultCacheAdapter();
|
|
@@ -6524,7 +6607,7 @@ var LocalFileBackend = class {
|
|
|
6524
6607
|
}
|
|
6525
6608
|
load(slug) {
|
|
6526
6609
|
const relPath = stateFilePath(this.jobsDir, slug);
|
|
6527
|
-
const absPath =
|
|
6610
|
+
const absPath = path25.join(this.cwd, relPath);
|
|
6528
6611
|
if (!fs25.existsSync(absPath)) {
|
|
6529
6612
|
return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
|
|
6530
6613
|
}
|
|
@@ -6545,8 +6628,8 @@ var LocalFileBackend = class {
|
|
|
6545
6628
|
if (!loaded.created && isStateUnchanged(loaded.state, next)) {
|
|
6546
6629
|
return false;
|
|
6547
6630
|
}
|
|
6548
|
-
const absPath =
|
|
6549
|
-
fs25.mkdirSync(
|
|
6631
|
+
const absPath = path25.join(this.cwd, loaded.path);
|
|
6632
|
+
fs25.mkdirSync(path25.dirname(absPath), { recursive: true });
|
|
6550
6633
|
const body = JSON.stringify(next, null, 2) + "\n";
|
|
6551
6634
|
fs25.writeFileSync(absPath, body, "utf-8");
|
|
6552
6635
|
return true;
|
|
@@ -6626,7 +6709,7 @@ var dispatchJobFileTicks = async (ctx, _profile, args) => {
|
|
|
6626
6709
|
await backend.hydrate();
|
|
6627
6710
|
}
|
|
6628
6711
|
try {
|
|
6629
|
-
const slugs = listJobSlugs(
|
|
6712
|
+
const slugs = listJobSlugs(path26.join(ctx.cwd, jobsDir));
|
|
6630
6713
|
ctx.data.jobSlugCount = slugs.length;
|
|
6631
6714
|
if (slugs.length === 0) {
|
|
6632
6715
|
process.stdout.write(`[jobs] no job files in ${jobsDir}
|
|
@@ -6739,7 +6822,7 @@ function formatAgo(ms) {
|
|
|
6739
6822
|
}
|
|
6740
6823
|
function readJobFrontmatter(cwd, jobsDir, slug) {
|
|
6741
6824
|
try {
|
|
6742
|
-
const raw = fs26.readFileSync(
|
|
6825
|
+
const raw = fs26.readFileSync(path26.join(cwd, jobsDir, `${slug}.md`), "utf-8");
|
|
6743
6826
|
return splitFrontmatter(raw).frontmatter;
|
|
6744
6827
|
} catch {
|
|
6745
6828
|
return {};
|
|
@@ -7263,7 +7346,7 @@ var finalizeTerminal = async (ctx) => {
|
|
|
7263
7346
|
|
|
7264
7347
|
// src/scripts/finishFlow.ts
|
|
7265
7348
|
init_issue();
|
|
7266
|
-
import { execFileSync as
|
|
7349
|
+
import { execFileSync as execFileSync15 } from "child_process";
|
|
7267
7350
|
var TERMINAL_PHASE = {
|
|
7268
7351
|
"review-passed": { phase: "shipped", status: "succeeded" },
|
|
7269
7352
|
"fix-applied": { phase: "shipped", status: "succeeded" },
|
|
@@ -7303,7 +7386,7 @@ var finishFlow = async (ctx, profile, _agentResult, args) => {
|
|
|
7303
7386
|
**PR:** ${state.core.prUrl}` : "";
|
|
7304
7387
|
const body = `${icon} kody flow \`${flowName}\` finished \u2014 \`${reason}\`${prSuffix}`;
|
|
7305
7388
|
try {
|
|
7306
|
-
|
|
7389
|
+
execFileSync15("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
7307
7390
|
timeout: API_TIMEOUT_MS6,
|
|
7308
7391
|
cwd: ctx.cwd,
|
|
7309
7392
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -7333,9 +7416,9 @@ var finishFlow = async (ctx, profile, _agentResult, args) => {
|
|
|
7333
7416
|
};
|
|
7334
7417
|
|
|
7335
7418
|
// src/branch.ts
|
|
7336
|
-
import { execFileSync as
|
|
7419
|
+
import { execFileSync as execFileSync16 } from "child_process";
|
|
7337
7420
|
function git2(args, cwd) {
|
|
7338
|
-
return
|
|
7421
|
+
return execFileSync16("git", args, {
|
|
7339
7422
|
encoding: "utf-8",
|
|
7340
7423
|
timeout: 3e4,
|
|
7341
7424
|
cwd,
|
|
@@ -7352,11 +7435,11 @@ function getCurrentBranch(cwd) {
|
|
|
7352
7435
|
}
|
|
7353
7436
|
function resetWorkingTree(cwd) {
|
|
7354
7437
|
try {
|
|
7355
|
-
|
|
7438
|
+
execFileSync16("git", ["reset", "--hard", "HEAD"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
7356
7439
|
} catch {
|
|
7357
7440
|
}
|
|
7358
7441
|
try {
|
|
7359
|
-
|
|
7442
|
+
execFileSync16("git", ["clean", "-fd"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
7360
7443
|
} catch {
|
|
7361
7444
|
}
|
|
7362
7445
|
}
|
|
@@ -7368,14 +7451,14 @@ function checkoutPrBranch(prNumber, cwd) {
|
|
|
7368
7451
|
GH_TOKEN: process.env.GH_PAT?.trim() || process.env.GH_TOKEN || ""
|
|
7369
7452
|
};
|
|
7370
7453
|
try {
|
|
7371
|
-
|
|
7454
|
+
execFileSync16("git", ["reset", "--hard", "HEAD"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
7372
7455
|
} catch {
|
|
7373
7456
|
}
|
|
7374
7457
|
try {
|
|
7375
|
-
|
|
7458
|
+
execFileSync16("git", ["clean", "-fd"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
7376
7459
|
} catch {
|
|
7377
7460
|
}
|
|
7378
|
-
|
|
7461
|
+
execFileSync16("gh", ["pr", "checkout", String(prNumber)], {
|
|
7379
7462
|
cwd,
|
|
7380
7463
|
env,
|
|
7381
7464
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -7501,7 +7584,7 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
|
|
|
7501
7584
|
}
|
|
7502
7585
|
|
|
7503
7586
|
// src/gha.ts
|
|
7504
|
-
import { execFileSync as
|
|
7587
|
+
import { execFileSync as execFileSync17 } from "child_process";
|
|
7505
7588
|
import * as fs27 from "fs";
|
|
7506
7589
|
function getRunUrl() {
|
|
7507
7590
|
const server = process.env.GITHUB_SERVER_URL;
|
|
@@ -7544,7 +7627,7 @@ function reactToTriggerComment(cwd) {
|
|
|
7544
7627
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
7545
7628
|
if (attempt > 0) sleepMs(attempt === 1 ? 500 : 1500);
|
|
7546
7629
|
try {
|
|
7547
|
-
|
|
7630
|
+
execFileSync17("gh", args, opts);
|
|
7548
7631
|
return;
|
|
7549
7632
|
} catch (err) {
|
|
7550
7633
|
lastErr = err;
|
|
@@ -7557,7 +7640,7 @@ function reactToTriggerComment(cwd) {
|
|
|
7557
7640
|
}
|
|
7558
7641
|
function sleepMs(ms) {
|
|
7559
7642
|
try {
|
|
7560
|
-
|
|
7643
|
+
execFileSync17("sleep", [(ms / 1e3).toString()], { stdio: "ignore", timeout: ms + 1e3 });
|
|
7561
7644
|
} catch {
|
|
7562
7645
|
}
|
|
7563
7646
|
}
|
|
@@ -7566,7 +7649,7 @@ function sleepMs(ms) {
|
|
|
7566
7649
|
init_issue();
|
|
7567
7650
|
|
|
7568
7651
|
// src/workflow.ts
|
|
7569
|
-
import { execFileSync as
|
|
7652
|
+
import { execFileSync as execFileSync18 } from "child_process";
|
|
7570
7653
|
var GH_TIMEOUT_MS = 3e4;
|
|
7571
7654
|
function ghToken3() {
|
|
7572
7655
|
return process.env.GH_PAT?.trim() || process.env.GH_TOKEN;
|
|
@@ -7574,7 +7657,7 @@ function ghToken3() {
|
|
|
7574
7657
|
function gh3(args, cwd) {
|
|
7575
7658
|
const token = ghToken3();
|
|
7576
7659
|
const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
|
|
7577
|
-
return
|
|
7660
|
+
return execFileSync18("gh", args, {
|
|
7578
7661
|
encoding: "utf-8",
|
|
7579
7662
|
timeout: GH_TIMEOUT_MS,
|
|
7580
7663
|
cwd,
|
|
@@ -7808,16 +7891,16 @@ var handleAbandonedGoal = async (ctx) => {
|
|
|
7808
7891
|
};
|
|
7809
7892
|
|
|
7810
7893
|
// src/scripts/initFlow.ts
|
|
7811
|
-
import { execFileSync as
|
|
7894
|
+
import { execFileSync as execFileSync19 } from "child_process";
|
|
7812
7895
|
import * as fs29 from "fs";
|
|
7813
|
-
import * as
|
|
7896
|
+
import * as path28 from "path";
|
|
7814
7897
|
|
|
7815
7898
|
// src/scripts/loadQaGuide.ts
|
|
7816
7899
|
import * as fs28 from "fs";
|
|
7817
|
-
import * as
|
|
7900
|
+
import * as path27 from "path";
|
|
7818
7901
|
var QA_GUIDE_REL_PATH = ".kody/qa-guide.md";
|
|
7819
7902
|
var loadQaGuide = async (ctx) => {
|
|
7820
|
-
const full =
|
|
7903
|
+
const full = path27.join(ctx.cwd, QA_GUIDE_REL_PATH);
|
|
7821
7904
|
if (!fs28.existsSync(full)) {
|
|
7822
7905
|
ctx.data.qaGuide = "";
|
|
7823
7906
|
ctx.data.qaGuidePath = "";
|
|
@@ -7834,9 +7917,9 @@ var loadQaGuide = async (ctx) => {
|
|
|
7834
7917
|
|
|
7835
7918
|
// src/scripts/initFlow.ts
|
|
7836
7919
|
function detectPackageManager(cwd) {
|
|
7837
|
-
if (fs29.existsSync(
|
|
7838
|
-
if (fs29.existsSync(
|
|
7839
|
-
if (fs29.existsSync(
|
|
7920
|
+
if (fs29.existsSync(path28.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
7921
|
+
if (fs29.existsSync(path28.join(cwd, "yarn.lock"))) return "yarn";
|
|
7922
|
+
if (fs29.existsSync(path28.join(cwd, "bun.lockb"))) return "bun";
|
|
7840
7923
|
return "npm";
|
|
7841
7924
|
}
|
|
7842
7925
|
function qualityCommandsFor(pm) {
|
|
@@ -7849,7 +7932,7 @@ function qualityCommandsFor(pm) {
|
|
|
7849
7932
|
function detectOwnerRepo(cwd) {
|
|
7850
7933
|
let url;
|
|
7851
7934
|
try {
|
|
7852
|
-
url =
|
|
7935
|
+
url = execFileSync19("git", ["remote", "get-url", "origin"], {
|
|
7853
7936
|
cwd,
|
|
7854
7937
|
encoding: "utf-8",
|
|
7855
7938
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -7934,7 +8017,7 @@ jobs:
|
|
|
7934
8017
|
`;
|
|
7935
8018
|
function defaultBranchFromGit(cwd) {
|
|
7936
8019
|
try {
|
|
7937
|
-
const ref =
|
|
8020
|
+
const ref = execFileSync19("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
|
|
7938
8021
|
cwd,
|
|
7939
8022
|
encoding: "utf-8",
|
|
7940
8023
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -7942,7 +8025,7 @@ function defaultBranchFromGit(cwd) {
|
|
|
7942
8025
|
return ref.replace("refs/remotes/origin/", "");
|
|
7943
8026
|
} catch {
|
|
7944
8027
|
try {
|
|
7945
|
-
return
|
|
8028
|
+
return execFileSync19("git", ["branch", "--show-current"], {
|
|
7946
8029
|
cwd,
|
|
7947
8030
|
encoding: "utf-8",
|
|
7948
8031
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -7958,7 +8041,7 @@ function performInit(cwd, force) {
|
|
|
7958
8041
|
const pm = detectPackageManager(cwd);
|
|
7959
8042
|
const ownerRepo = detectOwnerRepo(cwd);
|
|
7960
8043
|
const defaultBranch2 = defaultBranchFromGit(cwd);
|
|
7961
|
-
const configPath =
|
|
8044
|
+
const configPath = path28.join(cwd, "kody.config.json");
|
|
7962
8045
|
if (fs29.existsSync(configPath) && !force) {
|
|
7963
8046
|
skipped.push("kody.config.json");
|
|
7964
8047
|
} else {
|
|
@@ -7967,8 +8050,8 @@ function performInit(cwd, force) {
|
|
|
7967
8050
|
`);
|
|
7968
8051
|
wrote.push("kody.config.json");
|
|
7969
8052
|
}
|
|
7970
|
-
const workflowDir =
|
|
7971
|
-
const workflowPath =
|
|
8053
|
+
const workflowDir = path28.join(cwd, ".github", "workflows");
|
|
8054
|
+
const workflowPath = path28.join(workflowDir, "kody.yml");
|
|
7972
8055
|
if (fs29.existsSync(workflowPath) && !force) {
|
|
7973
8056
|
skipped.push(".github/workflows/kody.yml");
|
|
7974
8057
|
} else {
|
|
@@ -7976,13 +8059,13 @@ function performInit(cwd, force) {
|
|
|
7976
8059
|
fs29.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
|
|
7977
8060
|
wrote.push(".github/workflows/kody.yml");
|
|
7978
8061
|
}
|
|
7979
|
-
const hasUi = fs29.existsSync(
|
|
8062
|
+
const hasUi = fs29.existsSync(path28.join(cwd, "src/app")) || fs29.existsSync(path28.join(cwd, "app")) || fs29.existsSync(path28.join(cwd, "pages"));
|
|
7980
8063
|
if (hasUi) {
|
|
7981
|
-
const qaGuidePath =
|
|
8064
|
+
const qaGuidePath = path28.join(cwd, QA_GUIDE_REL_PATH);
|
|
7982
8065
|
if (fs29.existsSync(qaGuidePath) && !force) {
|
|
7983
8066
|
skipped.push(QA_GUIDE_REL_PATH);
|
|
7984
8067
|
} else {
|
|
7985
|
-
fs29.mkdirSync(
|
|
8068
|
+
fs29.mkdirSync(path28.dirname(qaGuidePath), { recursive: true });
|
|
7986
8069
|
const discovery = runQaDiscovery(cwd);
|
|
7987
8070
|
fs29.writeFileSync(qaGuidePath, generateQaGuideTemplate(discovery));
|
|
7988
8071
|
wrote.push(QA_GUIDE_REL_PATH);
|
|
@@ -7990,11 +8073,11 @@ function performInit(cwd, force) {
|
|
|
7990
8073
|
}
|
|
7991
8074
|
const builtinJobs = listBuiltinJobs();
|
|
7992
8075
|
if (builtinJobs.length > 0) {
|
|
7993
|
-
const jobsDir =
|
|
8076
|
+
const jobsDir = path28.join(cwd, ".kody", "jobs");
|
|
7994
8077
|
fs29.mkdirSync(jobsDir, { recursive: true });
|
|
7995
8078
|
for (const job of builtinJobs) {
|
|
7996
|
-
const rel =
|
|
7997
|
-
const target =
|
|
8079
|
+
const rel = path28.join(".kody", "jobs", `${job.slug}.md`);
|
|
8080
|
+
const target = path28.join(cwd, rel);
|
|
7998
8081
|
if (fs29.existsSync(target) && !force) {
|
|
7999
8082
|
skipped.push(rel);
|
|
8000
8083
|
continue;
|
|
@@ -8011,7 +8094,7 @@ function performInit(cwd, force) {
|
|
|
8011
8094
|
continue;
|
|
8012
8095
|
}
|
|
8013
8096
|
if (profile.kind !== "scheduled" || !profile.schedule) continue;
|
|
8014
|
-
const target =
|
|
8097
|
+
const target = path28.join(workflowDir, `kody-${exe.name}.yml`);
|
|
8015
8098
|
if (fs29.existsSync(target) && !force) {
|
|
8016
8099
|
skipped.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
8017
8100
|
continue;
|
|
@@ -8095,13 +8178,13 @@ init_loadCoverageRules();
|
|
|
8095
8178
|
|
|
8096
8179
|
// src/goal/state.ts
|
|
8097
8180
|
import * as fs30 from "fs";
|
|
8098
|
-
import * as
|
|
8181
|
+
import * as path29 from "path";
|
|
8099
8182
|
var VALID_STATES = /* @__PURE__ */ new Set(["active", "abandoned", "closed", "awaiting-merge", "done"]);
|
|
8100
8183
|
var GoalStateError = class extends Error {
|
|
8101
|
-
constructor(
|
|
8102
|
-
super(`Invalid goal state at ${
|
|
8184
|
+
constructor(path38, message) {
|
|
8185
|
+
super(`Invalid goal state at ${path38}:
|
|
8103
8186
|
${message}`);
|
|
8104
|
-
this.path =
|
|
8187
|
+
this.path = path38;
|
|
8105
8188
|
this.name = "GoalStateError";
|
|
8106
8189
|
}
|
|
8107
8190
|
path;
|
|
@@ -8149,7 +8232,7 @@ function serializeGoalState(s) {
|
|
|
8149
8232
|
`;
|
|
8150
8233
|
}
|
|
8151
8234
|
function goalStatePath(cwd, goalId) {
|
|
8152
|
-
return
|
|
8235
|
+
return path29.join(cwd, ".kody", "goals", goalId, "state.json");
|
|
8153
8236
|
}
|
|
8154
8237
|
function readGoalState(cwd, goalId) {
|
|
8155
8238
|
const file = goalStatePath(cwd, goalId);
|
|
@@ -8166,7 +8249,7 @@ function readGoalState(cwd, goalId) {
|
|
|
8166
8249
|
}
|
|
8167
8250
|
function writeGoalState(cwd, goalId, state) {
|
|
8168
8251
|
const file = goalStatePath(cwd, goalId);
|
|
8169
|
-
fs30.mkdirSync(
|
|
8252
|
+
fs30.mkdirSync(path29.dirname(file), { recursive: true });
|
|
8170
8253
|
fs30.writeFileSync(file, serializeGoalState(state), "utf-8");
|
|
8171
8254
|
}
|
|
8172
8255
|
function nowIso() {
|
|
@@ -8265,7 +8348,7 @@ var loadIssueStateComment = async (ctx, _profile, args) => {
|
|
|
8265
8348
|
|
|
8266
8349
|
// src/scripts/loadJobFromFile.ts
|
|
8267
8350
|
import * as fs31 from "fs";
|
|
8268
|
-
import * as
|
|
8351
|
+
import * as path30 from "path";
|
|
8269
8352
|
var loadJobFromFile = async (ctx, _profile, args) => {
|
|
8270
8353
|
const jobsDir = String(args?.jobsDir ?? ".kody/jobs");
|
|
8271
8354
|
const workersDir = String(args?.workersDir ?? ".kody/workers");
|
|
@@ -8274,7 +8357,7 @@ var loadJobFromFile = async (ctx, _profile, args) => {
|
|
|
8274
8357
|
if (!slug) {
|
|
8275
8358
|
throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
|
|
8276
8359
|
}
|
|
8277
|
-
const absPath =
|
|
8360
|
+
const absPath = path30.join(ctx.cwd, jobsDir, `${slug}.md`);
|
|
8278
8361
|
if (!fs31.existsSync(absPath)) {
|
|
8279
8362
|
throw new Error(`loadJobFromFile: job file not found: ${absPath}`);
|
|
8280
8363
|
}
|
|
@@ -8284,7 +8367,7 @@ var loadJobFromFile = async (ctx, _profile, args) => {
|
|
|
8284
8367
|
let workerTitle = "";
|
|
8285
8368
|
let workerPersona = "";
|
|
8286
8369
|
if (workerSlug) {
|
|
8287
|
-
const workerPath =
|
|
8370
|
+
const workerPath = path30.join(ctx.cwd, workersDir, `${workerSlug}.md`);
|
|
8288
8371
|
if (!fs31.existsSync(workerPath)) {
|
|
8289
8372
|
throw new Error(
|
|
8290
8373
|
`loadJobFromFile: job '${slug}' declares worker '${workerSlug}' but ${workerPath} does not exist`
|
|
@@ -8329,14 +8412,14 @@ function humanizeSlug(slug) {
|
|
|
8329
8412
|
|
|
8330
8413
|
// src/scripts/loadWorkerAdhoc.ts
|
|
8331
8414
|
import * as fs32 from "fs";
|
|
8332
|
-
import * as
|
|
8415
|
+
import * as path31 from "path";
|
|
8333
8416
|
var loadWorkerAdhoc = async (ctx, _profile, args) => {
|
|
8334
8417
|
const workersDir = String(args?.workersDir ?? ".kody/workers");
|
|
8335
8418
|
const workerSlug = String(ctx.args.worker ?? "").trim();
|
|
8336
8419
|
if (!workerSlug) {
|
|
8337
8420
|
throw new Error("loadWorkerAdhoc: ctx.args.worker must be a non-empty slug");
|
|
8338
8421
|
}
|
|
8339
|
-
const workerPath =
|
|
8422
|
+
const workerPath = path31.join(ctx.cwd, workersDir, `${workerSlug}.md`);
|
|
8340
8423
|
if (!fs32.existsSync(workerPath)) {
|
|
8341
8424
|
throw new Error(`loadWorkerAdhoc: worker persona not found: ${workerPath}`);
|
|
8342
8425
|
}
|
|
@@ -8409,7 +8492,7 @@ init_events();
|
|
|
8409
8492
|
|
|
8410
8493
|
// src/taskContext.ts
|
|
8411
8494
|
import * as fs34 from "fs";
|
|
8412
|
-
import * as
|
|
8495
|
+
import * as path33 from "path";
|
|
8413
8496
|
var TASK_CONTEXT_SCHEMA_VERSION = 1;
|
|
8414
8497
|
function buildTaskContext(args) {
|
|
8415
8498
|
return {
|
|
@@ -8425,9 +8508,9 @@ function buildTaskContext(args) {
|
|
|
8425
8508
|
}
|
|
8426
8509
|
function persistTaskContext(cwd, ctx) {
|
|
8427
8510
|
try {
|
|
8428
|
-
const dir =
|
|
8511
|
+
const dir = path33.join(cwd, ".kody", "runs", ctx.runId);
|
|
8429
8512
|
fs34.mkdirSync(dir, { recursive: true });
|
|
8430
|
-
const file =
|
|
8513
|
+
const file = path33.join(dir, "task-context.json");
|
|
8431
8514
|
fs34.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
|
|
8432
8515
|
`);
|
|
8433
8516
|
return file;
|
|
@@ -8484,7 +8567,7 @@ var markFlowSuccess = async (ctx) => {
|
|
|
8484
8567
|
};
|
|
8485
8568
|
|
|
8486
8569
|
// src/scripts/mergeReleasePr.ts
|
|
8487
|
-
import { execFileSync as
|
|
8570
|
+
import { execFileSync as execFileSync20 } from "child_process";
|
|
8488
8571
|
var API_TIMEOUT_MS7 = 6e4;
|
|
8489
8572
|
var mergeReleasePr = async (ctx) => {
|
|
8490
8573
|
const state = ctx.data.taskState;
|
|
@@ -8503,7 +8586,7 @@ var mergeReleasePr = async (ctx) => {
|
|
|
8503
8586
|
process.stderr.write(`[kody mergeReleasePr] merging PR #${prNumber} (${prUrl})
|
|
8504
8587
|
`);
|
|
8505
8588
|
try {
|
|
8506
|
-
const out =
|
|
8589
|
+
const out = execFileSync20("gh", ["pr", "merge", String(prNumber), "--merge"], {
|
|
8507
8590
|
timeout: API_TIMEOUT_MS7,
|
|
8508
8591
|
cwd: ctx.cwd,
|
|
8509
8592
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -9138,7 +9221,7 @@ ${body}`;
|
|
|
9138
9221
|
}
|
|
9139
9222
|
|
|
9140
9223
|
// src/scripts/recordClassification.ts
|
|
9141
|
-
import { execFileSync as
|
|
9224
|
+
import { execFileSync as execFileSync21 } from "child_process";
|
|
9142
9225
|
var API_TIMEOUT_MS8 = 3e4;
|
|
9143
9226
|
var VALID_CLASSES3 = /* @__PURE__ */ new Set(["feature", "bug", "spec", "chore"]);
|
|
9144
9227
|
var recordClassification = async (ctx) => {
|
|
@@ -9186,7 +9269,7 @@ function parseClassification(prSummary) {
|
|
|
9186
9269
|
}
|
|
9187
9270
|
function tryAuditComment(issueNumber, body, cwd) {
|
|
9188
9271
|
try {
|
|
9189
|
-
|
|
9272
|
+
execFileSync21("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
9190
9273
|
cwd,
|
|
9191
9274
|
timeout: API_TIMEOUT_MS8,
|
|
9192
9275
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -9300,7 +9383,7 @@ var resolveArtifacts = async (ctx, profile) => {
|
|
|
9300
9383
|
};
|
|
9301
9384
|
|
|
9302
9385
|
// src/scripts/resolveFlow.ts
|
|
9303
|
-
import { execFileSync as
|
|
9386
|
+
import { execFileSync as execFileSync22 } from "child_process";
|
|
9304
9387
|
init_issue();
|
|
9305
9388
|
var CONFLICT_DIFF_MAX_BYTES = 4e4;
|
|
9306
9389
|
var resolveFlow = async (ctx) => {
|
|
@@ -9394,7 +9477,7 @@ function buildPreferBlock(prefer, baseBranch) {
|
|
|
9394
9477
|
}
|
|
9395
9478
|
function getConflictedFiles(cwd) {
|
|
9396
9479
|
try {
|
|
9397
|
-
const out =
|
|
9480
|
+
const out = execFileSync22("git", ["diff", "--name-only", "--diff-filter=U"], {
|
|
9398
9481
|
encoding: "utf-8",
|
|
9399
9482
|
cwd,
|
|
9400
9483
|
env: { ...process.env, HUSKY: "0" }
|
|
@@ -9409,7 +9492,7 @@ function getConflictMarkersPreview(files, cwd, maxBytes = CONFLICT_DIFF_MAX_BYTE
|
|
|
9409
9492
|
let total = 0;
|
|
9410
9493
|
for (const f of files) {
|
|
9411
9494
|
try {
|
|
9412
|
-
const content =
|
|
9495
|
+
const content = execFileSync22("cat", [f], { encoding: "utf-8", cwd }).toString();
|
|
9413
9496
|
const snippet = `### ${f}
|
|
9414
9497
|
|
|
9415
9498
|
\`\`\`
|
|
@@ -9433,12 +9516,12 @@ function tryPostPr3(prNumber, body, cwd) {
|
|
|
9433
9516
|
function pushEmptyCommit(branch, cwd) {
|
|
9434
9517
|
const env = { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" };
|
|
9435
9518
|
try {
|
|
9436
|
-
|
|
9519
|
+
execFileSync22(
|
|
9437
9520
|
"git",
|
|
9438
9521
|
["commit", "--allow-empty", "-m", "chore: kody resolve refresh \u2014 empty commit to recompute mergeable status"],
|
|
9439
9522
|
{ cwd, env, stdio: ["ignore", "pipe", "pipe"] }
|
|
9440
9523
|
);
|
|
9441
|
-
|
|
9524
|
+
execFileSync22("git", ["push", "-u", "origin", branch], {
|
|
9442
9525
|
cwd,
|
|
9443
9526
|
env,
|
|
9444
9527
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -9529,10 +9612,10 @@ var resolvePreviewUrl = async (ctx) => {
|
|
|
9529
9612
|
};
|
|
9530
9613
|
|
|
9531
9614
|
// src/scripts/resolveQaUrl.ts
|
|
9532
|
-
import { execFileSync as
|
|
9615
|
+
import { execFileSync as execFileSync23 } from "child_process";
|
|
9533
9616
|
function ghQuery(args, cwd) {
|
|
9534
9617
|
try {
|
|
9535
|
-
const out =
|
|
9618
|
+
const out = execFileSync23("gh", args, {
|
|
9536
9619
|
cwd,
|
|
9537
9620
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9538
9621
|
encoding: "utf-8",
|
|
@@ -9602,7 +9685,7 @@ var resolveQaUrl = async (ctx) => {
|
|
|
9602
9685
|
};
|
|
9603
9686
|
|
|
9604
9687
|
// src/scripts/revertFlow.ts
|
|
9605
|
-
import { execFileSync as
|
|
9688
|
+
import { execFileSync as execFileSync24 } from "child_process";
|
|
9606
9689
|
init_issue();
|
|
9607
9690
|
var SHA_RE = /^[0-9a-f]{4,40}$/i;
|
|
9608
9691
|
var revertFlow = async (ctx) => {
|
|
@@ -9685,7 +9768,7 @@ function buildPrSummary(resolved) {
|
|
|
9685
9768
|
return resolved.map((r) => `- Reverted \`${r.full.slice(0, 7)}\`${r.subject ? ` \u2014 ${r.subject}` : ""}`).join("\n");
|
|
9686
9769
|
}
|
|
9687
9770
|
function git3(args, cwd) {
|
|
9688
|
-
return
|
|
9771
|
+
return execFileSync24("git", args, {
|
|
9689
9772
|
encoding: "utf-8",
|
|
9690
9773
|
timeout: 3e4,
|
|
9691
9774
|
cwd,
|
|
@@ -9695,7 +9778,7 @@ function git3(args, cwd) {
|
|
|
9695
9778
|
}
|
|
9696
9779
|
function isAncestorOfHead(sha, cwd) {
|
|
9697
9780
|
try {
|
|
9698
|
-
|
|
9781
|
+
execFileSync24("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
|
|
9699
9782
|
cwd,
|
|
9700
9783
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
9701
9784
|
stdio: ["ignore", "ignore", "ignore"]
|
|
@@ -9792,7 +9875,7 @@ function resolveBaseOverride(value) {
|
|
|
9792
9875
|
// src/scripts/runTickScript.ts
|
|
9793
9876
|
import { spawnSync } from "child_process";
|
|
9794
9877
|
import * as fs35 from "fs";
|
|
9795
|
-
import * as
|
|
9878
|
+
import * as path34 from "path";
|
|
9796
9879
|
var runTickScript = async (ctx, _profile, args) => {
|
|
9797
9880
|
ctx.skipAgent = true;
|
|
9798
9881
|
const jobsDir = String(args?.jobsDir ?? ".kody/jobs");
|
|
@@ -9804,7 +9887,7 @@ var runTickScript = async (ctx, _profile, args) => {
|
|
|
9804
9887
|
ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
|
|
9805
9888
|
return;
|
|
9806
9889
|
}
|
|
9807
|
-
const jobPath =
|
|
9890
|
+
const jobPath = path34.join(ctx.cwd, jobsDir, `${slug}.md`);
|
|
9808
9891
|
if (!fs35.existsSync(jobPath)) {
|
|
9809
9892
|
ctx.output.exitCode = 99;
|
|
9810
9893
|
ctx.output.reason = `runTickScript: job file not found: ${jobPath}`;
|
|
@@ -9818,7 +9901,7 @@ var runTickScript = async (ctx, _profile, args) => {
|
|
|
9818
9901
|
ctx.output.reason = `runTickScript: job ${slug} has no \`tickScript:\` frontmatter \u2014 route via job-tick instead`;
|
|
9819
9902
|
return;
|
|
9820
9903
|
}
|
|
9821
|
-
const scriptPath =
|
|
9904
|
+
const scriptPath = path34.isAbsolute(tickScript) ? tickScript : path34.join(ctx.cwd, tickScript);
|
|
9822
9905
|
if (!fs35.existsSync(scriptPath)) {
|
|
9823
9906
|
ctx.output.exitCode = 99;
|
|
9824
9907
|
ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
|
|
@@ -10114,11 +10197,11 @@ var skipAgent = async (ctx) => {
|
|
|
10114
10197
|
};
|
|
10115
10198
|
|
|
10116
10199
|
// src/scripts/stageMergeConflicts.ts
|
|
10117
|
-
import { execFileSync as
|
|
10200
|
+
import { execFileSync as execFileSync25 } from "child_process";
|
|
10118
10201
|
var stageMergeConflicts = async (ctx) => {
|
|
10119
10202
|
if (ctx.data.agentDone === false) return;
|
|
10120
10203
|
try {
|
|
10121
|
-
|
|
10204
|
+
execFileSync25("git", ["add", "-A"], {
|
|
10122
10205
|
cwd: ctx.cwd,
|
|
10123
10206
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
10124
10207
|
stdio: "pipe"
|
|
@@ -10129,7 +10212,7 @@ var stageMergeConflicts = async (ctx) => {
|
|
|
10129
10212
|
|
|
10130
10213
|
// src/scripts/startFlow.ts
|
|
10131
10214
|
init_issue();
|
|
10132
|
-
import { execFileSync as
|
|
10215
|
+
import { execFileSync as execFileSync26 } from "child_process";
|
|
10133
10216
|
var API_TIMEOUT_MS9 = 3e4;
|
|
10134
10217
|
var startFlow = async (ctx, profile, _agentResult, args) => {
|
|
10135
10218
|
const entry = args?.entry;
|
|
@@ -10163,7 +10246,7 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
|
10163
10246
|
const sub = target === "pr" && state?.core.prUrl ? "pr" : "issue";
|
|
10164
10247
|
const body = `@kody ${next}`;
|
|
10165
10248
|
try {
|
|
10166
|
-
|
|
10249
|
+
execFileSync26("gh", [sub, "comment", String(targetNumber), "--body", body], {
|
|
10167
10250
|
timeout: API_TIMEOUT_MS9,
|
|
10168
10251
|
cwd,
|
|
10169
10252
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -10177,7 +10260,7 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
|
10177
10260
|
}
|
|
10178
10261
|
|
|
10179
10262
|
// src/scripts/syncFlow.ts
|
|
10180
|
-
import { execFileSync as
|
|
10263
|
+
import { execFileSync as execFileSync27 } from "child_process";
|
|
10181
10264
|
init_issue();
|
|
10182
10265
|
var syncFlow = async (ctx, _profile, args) => {
|
|
10183
10266
|
const announceOnSuccess = Boolean(args?.announceOnSuccess);
|
|
@@ -10242,21 +10325,15 @@ function bail2(ctx, prNumber, reason) {
|
|
|
10242
10325
|
}
|
|
10243
10326
|
function revParseHead(cwd) {
|
|
10244
10327
|
try {
|
|
10245
|
-
return
|
|
10328
|
+
return execFileSync27("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
|
|
10246
10329
|
} catch {
|
|
10247
10330
|
return "";
|
|
10248
10331
|
}
|
|
10249
10332
|
}
|
|
10250
10333
|
function pushBranch(branch, cwd) {
|
|
10251
|
-
const
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
} catch {
|
|
10255
|
-
execFileSync26("git", ["push", "--force-with-lease", "-u", "origin", branch], {
|
|
10256
|
-
cwd,
|
|
10257
|
-
env,
|
|
10258
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
10259
|
-
});
|
|
10334
|
+
const result = pushWithRetry({ cwd: cwd ?? process.cwd(), branch, setUpstream: true });
|
|
10335
|
+
if (!result.ok) {
|
|
10336
|
+
throw new Error(result.reason);
|
|
10260
10337
|
}
|
|
10261
10338
|
}
|
|
10262
10339
|
function tryPostPr6(prNumber, body, cwd) {
|
|
@@ -10505,7 +10582,7 @@ var verifyWithRetry = async (ctx) => {
|
|
|
10505
10582
|
|
|
10506
10583
|
// src/scripts/waitForCi.ts
|
|
10507
10584
|
init_issue();
|
|
10508
|
-
import { execFileSync as
|
|
10585
|
+
import { execFileSync as execFileSync28 } from "child_process";
|
|
10509
10586
|
var API_TIMEOUT_MS10 = 3e4;
|
|
10510
10587
|
var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
10511
10588
|
const timeoutMinutes = numArg(args, "timeoutMinutes", 30);
|
|
@@ -10583,7 +10660,7 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
10583
10660
|
};
|
|
10584
10661
|
function fetchChecks(prNumber, cwd) {
|
|
10585
10662
|
try {
|
|
10586
|
-
const raw =
|
|
10663
|
+
const raw = execFileSync28("gh", ["pr", "checks", String(prNumber), "--json", "bucket,state,name,workflow,link"], {
|
|
10587
10664
|
encoding: "utf-8",
|
|
10588
10665
|
timeout: API_TIMEOUT_MS10,
|
|
10589
10666
|
cwd,
|
|
@@ -10962,7 +11039,7 @@ var allScriptNames = /* @__PURE__ */ new Set([
|
|
|
10962
11039
|
]);
|
|
10963
11040
|
|
|
10964
11041
|
// src/tools.ts
|
|
10965
|
-
import { execFileSync as
|
|
11042
|
+
import { execFileSync as execFileSync29 } from "child_process";
|
|
10966
11043
|
function verifyCliTools(tools, cwd) {
|
|
10967
11044
|
const out = [];
|
|
10968
11045
|
for (const t of tools) out.push(verifyOne(t, cwd));
|
|
@@ -10995,7 +11072,7 @@ function verifyOne(tool2, cwd) {
|
|
|
10995
11072
|
}
|
|
10996
11073
|
function runShell(cmd, cwd, timeoutMs = 3e4) {
|
|
10997
11074
|
try {
|
|
10998
|
-
|
|
11075
|
+
execFileSync29("sh", ["-c", cmd], { cwd, stdio: "pipe", timeout: timeoutMs });
|
|
10999
11076
|
return true;
|
|
11000
11077
|
} catch {
|
|
11001
11078
|
return false;
|
|
@@ -11103,9 +11180,9 @@ async function runExecutable(profileName, input) {
|
|
|
11103
11180
|
})
|
|
11104
11181
|
};
|
|
11105
11182
|
})() : null;
|
|
11106
|
-
const ndjsonDir =
|
|
11183
|
+
const ndjsonDir = path35.join(input.cwd, ".kody");
|
|
11107
11184
|
const invokeAgent = async (prompt) => {
|
|
11108
|
-
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) =>
|
|
11185
|
+
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path35.isAbsolute(p) ? p : path35.resolve(profile.dir, p)).filter((p) => p.length > 0);
|
|
11109
11186
|
const syntheticPath = ctx.data.syntheticPluginPath;
|
|
11110
11187
|
const pluginPaths = [...externalPlugins, ...syntheticPath ? [syntheticPath] : []];
|
|
11111
11188
|
return runAgent({
|
|
@@ -11321,13 +11398,13 @@ function getProfileInputsForChild(profileName, _cwd) {
|
|
|
11321
11398
|
function resolveProfilePath(profileName) {
|
|
11322
11399
|
const found = resolveExecutable(profileName);
|
|
11323
11400
|
if (found) return found;
|
|
11324
|
-
const here =
|
|
11401
|
+
const here = path35.dirname(new URL(import.meta.url).pathname);
|
|
11325
11402
|
const candidates = [
|
|
11326
|
-
|
|
11403
|
+
path35.join(here, "executables", profileName, "profile.json"),
|
|
11327
11404
|
// same-dir sibling (dev)
|
|
11328
|
-
|
|
11405
|
+
path35.join(here, "..", "executables", profileName, "profile.json"),
|
|
11329
11406
|
// up one (prod: dist/bin → dist/executables)
|
|
11330
|
-
|
|
11407
|
+
path35.join(here, "..", "src", "executables", profileName, "profile.json")
|
|
11331
11408
|
// fallback
|
|
11332
11409
|
];
|
|
11333
11410
|
for (const c of candidates) {
|
|
@@ -11431,7 +11508,7 @@ function resolveShellTimeoutMs(entry) {
|
|
|
11431
11508
|
var SIGKILL_GRACE_MS = 5e3;
|
|
11432
11509
|
async function runShellEntry(entry, ctx, profile) {
|
|
11433
11510
|
const shellName = entry.shell;
|
|
11434
|
-
const shellPath =
|
|
11511
|
+
const shellPath = path35.join(profile.dir, shellName);
|
|
11435
11512
|
if (!fs37.existsSync(shellPath)) {
|
|
11436
11513
|
ctx.skipAgent = true;
|
|
11437
11514
|
ctx.output.exitCode = 99;
|
|
@@ -11759,7 +11836,7 @@ async function runContainerLoop(profile, ctx, input) {
|
|
|
11759
11836
|
}
|
|
11760
11837
|
function resetWorkingTree2(cwd) {
|
|
11761
11838
|
try {
|
|
11762
|
-
|
|
11839
|
+
execFileSync30("git", ["reset", "--hard", "HEAD"], {
|
|
11763
11840
|
cwd,
|
|
11764
11841
|
stdio: ["ignore", "pipe", "pipe"],
|
|
11765
11842
|
timeout: 3e4
|
|
@@ -11911,14 +11988,14 @@ function resolveAuthToken(env = process.env) {
|
|
|
11911
11988
|
return token;
|
|
11912
11989
|
}
|
|
11913
11990
|
function detectPackageManager2(cwd) {
|
|
11914
|
-
if (fs38.existsSync(
|
|
11915
|
-
if (fs38.existsSync(
|
|
11916
|
-
if (fs38.existsSync(
|
|
11991
|
+
if (fs38.existsSync(path36.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
11992
|
+
if (fs38.existsSync(path36.join(cwd, "yarn.lock"))) return "yarn";
|
|
11993
|
+
if (fs38.existsSync(path36.join(cwd, "bun.lockb"))) return "bun";
|
|
11917
11994
|
return "npm";
|
|
11918
11995
|
}
|
|
11919
11996
|
function shellOut(cmd, args, cwd, stream = true) {
|
|
11920
11997
|
try {
|
|
11921
|
-
|
|
11998
|
+
execFileSync31(cmd, args, {
|
|
11922
11999
|
cwd,
|
|
11923
12000
|
stdio: stream ? "inherit" : "pipe",
|
|
11924
12001
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" }
|
|
@@ -11931,7 +12008,7 @@ function shellOut(cmd, args, cwd, stream = true) {
|
|
|
11931
12008
|
}
|
|
11932
12009
|
function isOnPath(bin) {
|
|
11933
12010
|
try {
|
|
11934
|
-
|
|
12011
|
+
execFileSync31("which", [bin], { stdio: "pipe" });
|
|
11935
12012
|
return true;
|
|
11936
12013
|
} catch {
|
|
11937
12014
|
return false;
|
|
@@ -11972,7 +12049,7 @@ function installLitellmIfNeeded(cwd) {
|
|
|
11972
12049
|
} catch {
|
|
11973
12050
|
}
|
|
11974
12051
|
try {
|
|
11975
|
-
|
|
12052
|
+
execFileSync31("python3", ["-c", "import litellm"], { stdio: "pipe" });
|
|
11976
12053
|
process.stdout.write("\u2192 kody: litellm already installed\n");
|
|
11977
12054
|
return 0;
|
|
11978
12055
|
} catch {
|
|
@@ -11982,16 +12059,16 @@ function installLitellmIfNeeded(cwd) {
|
|
|
11982
12059
|
}
|
|
11983
12060
|
function configureGitIdentity(cwd) {
|
|
11984
12061
|
try {
|
|
11985
|
-
const name =
|
|
12062
|
+
const name = execFileSync31("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
|
|
11986
12063
|
if (name) return;
|
|
11987
12064
|
} catch {
|
|
11988
12065
|
}
|
|
11989
12066
|
try {
|
|
11990
|
-
|
|
12067
|
+
execFileSync31("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
|
|
11991
12068
|
} catch {
|
|
11992
12069
|
}
|
|
11993
12070
|
try {
|
|
11994
|
-
|
|
12071
|
+
execFileSync31("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
|
|
11995
12072
|
cwd,
|
|
11996
12073
|
stdio: "pipe"
|
|
11997
12074
|
});
|
|
@@ -12000,7 +12077,7 @@ function configureGitIdentity(cwd) {
|
|
|
12000
12077
|
}
|
|
12001
12078
|
function postFailureTail(issueNumber, cwd, reason) {
|
|
12002
12079
|
if (!issueNumber) return;
|
|
12003
|
-
const logPath =
|
|
12080
|
+
const logPath = path36.join(cwd, ".kody", "last-run.jsonl");
|
|
12004
12081
|
let tail = "";
|
|
12005
12082
|
try {
|
|
12006
12083
|
if (fs38.existsSync(logPath)) {
|
|
@@ -12029,7 +12106,7 @@ async function runCi(argv) {
|
|
|
12029
12106
|
return 0;
|
|
12030
12107
|
}
|
|
12031
12108
|
const args = parseCiArgs(argv);
|
|
12032
|
-
const cwd = args.cwd ?
|
|
12109
|
+
const cwd = args.cwd ? path36.resolve(args.cwd) : process.cwd();
|
|
12033
12110
|
let earlyConfig;
|
|
12034
12111
|
try {
|
|
12035
12112
|
earlyConfig = loadConfig(cwd);
|
|
@@ -12300,19 +12377,28 @@ function parseChatArgs(argv, env = process.env) {
|
|
|
12300
12377
|
return result;
|
|
12301
12378
|
}
|
|
12302
12379
|
function commitChatFiles(cwd, sessionId, verbose) {
|
|
12303
|
-
const sessionFile =
|
|
12304
|
-
const eventsFile =
|
|
12305
|
-
const
|
|
12380
|
+
const sessionFile = path37.relative(cwd, sessionFilePath(cwd, sessionId));
|
|
12381
|
+
const eventsFile = path37.relative(cwd, eventsFilePath(cwd, sessionId));
|
|
12382
|
+
const safeSession = sessionId.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
12383
|
+
const tasksDir = path37.join(".kody", "tasks", safeSession);
|
|
12384
|
+
const candidatePaths = [sessionFile, eventsFile, tasksDir];
|
|
12385
|
+
const paths = candidatePaths.filter((p) => fs39.existsSync(path37.join(cwd, p)));
|
|
12306
12386
|
if (paths.length === 0) return;
|
|
12307
12387
|
const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
|
|
12308
12388
|
try {
|
|
12309
|
-
|
|
12310
|
-
|
|
12311
|
-
execFileSync31("git", ["push", "--quiet", "origin", "HEAD"], opts);
|
|
12389
|
+
execFileSync32("git", ["add", "-f", ...paths], opts);
|
|
12390
|
+
execFileSync32("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
|
|
12312
12391
|
} catch (err) {
|
|
12313
12392
|
const msg = err instanceof Error ? err.message : String(err);
|
|
12314
|
-
process.stderr.write(`[kody:chat] commit
|
|
12393
|
+
process.stderr.write(`[kody:chat] commit skipped: ${msg}
|
|
12315
12394
|
`);
|
|
12395
|
+
return;
|
|
12396
|
+
}
|
|
12397
|
+
const result = pushWithRetry({ cwd });
|
|
12398
|
+
if (!result.ok) {
|
|
12399
|
+
process.stderr.write(`[kody:chat] push FAILED after ${result.attempts} attempt(s): ${result.reason}
|
|
12400
|
+
`);
|
|
12401
|
+
throw new Error(`chat push failed: ${result.reason}`);
|
|
12316
12402
|
}
|
|
12317
12403
|
}
|
|
12318
12404
|
function tryLoadConfig(cwd) {
|
|
@@ -12340,7 +12426,7 @@ async function runChat(argv) {
|
|
|
12340
12426
|
${CHAT_HELP}`);
|
|
12341
12427
|
return 64;
|
|
12342
12428
|
}
|
|
12343
|
-
const cwd = args.cwd ?
|
|
12429
|
+
const cwd = args.cwd ? path37.resolve(args.cwd) : process.cwd();
|
|
12344
12430
|
const sessionId = args.sessionId;
|
|
12345
12431
|
const unpackedSecrets = unpackAllSecrets();
|
|
12346
12432
|
if (unpackedSecrets > 0) {
|