@kody-ade/kody-engine 0.4.286 → 0.4.287
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 +39 -21
- package/package.json +1 -1
package/dist/bin/kody.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@kody-ade/kody-engine",
|
|
18
|
-
version: "0.4.
|
|
18
|
+
version: "0.4.287",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -443,7 +443,7 @@ var STATE_BRANCH;
|
|
|
443
443
|
var init_stateBranch = __esm({
|
|
444
444
|
"src/stateBranch.ts"() {
|
|
445
445
|
"use strict";
|
|
446
|
-
STATE_BRANCH = "
|
|
446
|
+
STATE_BRANCH = "main";
|
|
447
447
|
}
|
|
448
448
|
});
|
|
449
449
|
|
|
@@ -497,18 +497,33 @@ function normalizeStatePath(raw, field = "statePath") {
|
|
|
497
497
|
}
|
|
498
498
|
return parts.join("/");
|
|
499
499
|
}
|
|
500
|
+
function normalizeStateBranch(raw, field = "state.branch") {
|
|
501
|
+
const value = raw?.trim() || STATE_BRANCH;
|
|
502
|
+
if (!value) throw new Error(`kody.config.json: ${field} must not be empty`);
|
|
503
|
+
if (value.startsWith("/") || value.endsWith("/") || value.includes("\\") || value.includes("..") || value.includes("@{") || /[\x00-\x20\x7f~^:?*\[]/.test(value)) {
|
|
504
|
+
throw new Error(`kody.config.json: ${field} contains an invalid branch`);
|
|
505
|
+
}
|
|
506
|
+
for (const part of value.split("/")) {
|
|
507
|
+
if (!part || part === "." || part === ".." || part.startsWith(".") || part.endsWith(".lock")) {
|
|
508
|
+
throw new Error(`kody.config.json: ${field} contains an invalid branch`);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return value;
|
|
512
|
+
}
|
|
500
513
|
function resolveStateRepoConfig(config) {
|
|
501
514
|
if (config.state?.repo && config.state?.path) {
|
|
502
515
|
parseStateRepoSlug(config.state.repo);
|
|
503
516
|
return {
|
|
504
517
|
repo: config.state.repo,
|
|
505
|
-
path: normalizeStatePath(config.state.path)
|
|
518
|
+
path: normalizeStatePath(config.state.path),
|
|
519
|
+
branch: normalizeStateBranch(config.state.branch)
|
|
506
520
|
};
|
|
507
521
|
}
|
|
508
522
|
if (config.github?.owner && config.github?.repo) {
|
|
509
523
|
return {
|
|
510
524
|
repo: `${config.github.owner}/kody-state`,
|
|
511
|
-
path: normalizeStatePath(config.github.repo)
|
|
525
|
+
path: normalizeStatePath(config.github.repo),
|
|
526
|
+
branch: normalizeStateBranch(void 0)
|
|
512
527
|
};
|
|
513
528
|
}
|
|
514
529
|
throw new Error("stateRepo: config.state or config.github owner/repo is required");
|
|
@@ -516,7 +531,7 @@ function resolveStateRepoConfig(config) {
|
|
|
516
531
|
function parseStateRepo(config) {
|
|
517
532
|
const state = resolveStateRepoConfig(config);
|
|
518
533
|
const parsed = parseStateRepoSlug(state.repo);
|
|
519
|
-
return { ...parsed, basePath: state.path };
|
|
534
|
+
return { ...parsed, basePath: state.path, branch: state.branch };
|
|
520
535
|
}
|
|
521
536
|
function stateRepoPath(config, filePath) {
|
|
522
537
|
const state = resolveStateRepoConfig(config);
|
|
@@ -528,14 +543,15 @@ function apiPath(config, targetPath) {
|
|
|
528
543
|
return `/repos/${parsed.owner}/${parsed.repo}/contents/${targetPath}`;
|
|
529
544
|
}
|
|
530
545
|
function branchApiPath(config, targetPath) {
|
|
531
|
-
|
|
546
|
+
const state = resolveStateRepoConfig(config);
|
|
547
|
+
return `${apiPath(config, targetPath)}?ref=${encodeURIComponent(state.branch)}`;
|
|
532
548
|
}
|
|
533
549
|
function ensureStateBranch(config, cwd) {
|
|
534
550
|
const parsed = parseStateRepo(config);
|
|
535
|
-
const cacheKey3 = `${parsed.owner}/${parsed.repo}:${
|
|
551
|
+
const cacheKey3 = `${parsed.owner}/${parsed.repo}:${parsed.branch}`;
|
|
536
552
|
if (ensuredStateBranches.has(cacheKey3)) return;
|
|
537
553
|
try {
|
|
538
|
-
gh(["api", `/repos/${parsed.owner}/${parsed.repo}/git/ref/heads/${
|
|
554
|
+
gh(["api", `/repos/${parsed.owner}/${parsed.repo}/git/ref/heads/${parsed.branch}`], { cwd });
|
|
539
555
|
ensuredStateBranches.add(cacheKey3);
|
|
540
556
|
return;
|
|
541
557
|
} catch (err) {
|
|
@@ -550,7 +566,7 @@ function ensureStateBranch(config, cwd) {
|
|
|
550
566
|
try {
|
|
551
567
|
gh(["api", "--method", "POST", `/repos/${parsed.owner}/${parsed.repo}/git/refs`, "--input", "-"], {
|
|
552
568
|
cwd,
|
|
553
|
-
input: JSON.stringify({ ref: `refs/heads/${
|
|
569
|
+
input: JSON.stringify({ ref: `refs/heads/${parsed.branch}`, sha })
|
|
554
570
|
});
|
|
555
571
|
} catch (err) {
|
|
556
572
|
if (!isAlreadyExists(err)) throw err;
|
|
@@ -590,7 +606,7 @@ function writeStateText(config, cwd, filePath, content, message, sha) {
|
|
|
590
606
|
const payload = {
|
|
591
607
|
message,
|
|
592
608
|
content: Buffer.from(content, "utf-8").toString("base64"),
|
|
593
|
-
branch:
|
|
609
|
+
branch: resolveStateRepoConfig(config).branch
|
|
594
610
|
};
|
|
595
611
|
if (sha) payload.sha = sha;
|
|
596
612
|
gh(["api", "--method", "PUT", apiPath(config, targetPath), "--input", "-"], {
|
|
@@ -722,12 +738,14 @@ function parseStateConfig(raw, github) {
|
|
|
722
738
|
const nested = recordValue(raw.state) ?? {};
|
|
723
739
|
const repoRaw = typeof raw.stateRepo === "string" ? raw.stateRepo : nested.repo;
|
|
724
740
|
const pathRaw = typeof raw.statePath === "string" ? raw.statePath : nested.path;
|
|
741
|
+
const branchRaw = typeof raw.stateBranch === "string" ? raw.stateBranch : nested.branch;
|
|
725
742
|
const stateRepo = typeof repoRaw === "string" && repoRaw.trim().length > 0 ? repoRaw.trim() : `https://github.com/${String(github.owner)}/kody-state`;
|
|
726
743
|
parseStateRepoSlug(stateRepo);
|
|
727
744
|
const statePath = typeof pathRaw === "string" && pathRaw.trim().length > 0 ? pathRaw.trim() : String(github.repo);
|
|
728
745
|
return {
|
|
729
746
|
repo: stateRepo,
|
|
730
|
-
path: normalizeStatePath(statePath)
|
|
747
|
+
path: normalizeStatePath(statePath),
|
|
748
|
+
branch: typeof branchRaw === "string" && branchRaw.trim().length > 0 ? normalizeStateBranch(branchRaw) : normalizeStateBranch(void 0)
|
|
731
749
|
};
|
|
732
750
|
}
|
|
733
751
|
function parseAccessConfig(raw) {
|
|
@@ -6878,6 +6896,7 @@ function stateRepoContext(config, goalId, logPath) {
|
|
|
6878
6896
|
return {
|
|
6879
6897
|
repo: state.repo,
|
|
6880
6898
|
path: state.path,
|
|
6899
|
+
branch: state.branch,
|
|
6881
6900
|
goalStatePath: `${state.path}/${goalStateLogPath(goalId)}`,
|
|
6882
6901
|
logPath: `${state.path}/${logPath}`
|
|
6883
6902
|
};
|
|
@@ -6976,16 +6995,17 @@ function linkContext(stateRepo) {
|
|
|
6976
6995
|
const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
6977
6996
|
if (runId && repository) links.workflowRun = `${server}/${repository}/actions/runs/${runId}`;
|
|
6978
6997
|
const repo = stringValue(stateRepo?.repo);
|
|
6998
|
+
const branch = stringValue(stateRepo?.branch);
|
|
6979
6999
|
const goalStatePath2 = stringValue(stateRepo?.goalStatePath);
|
|
6980
7000
|
const logPath = stringValue(stateRepo?.logPath);
|
|
6981
|
-
if (repo && goalStatePath2) links.goalState = githubBlobUrl(repo, goalStatePath2);
|
|
6982
|
-
if (repo && logPath) links.log = githubBlobUrl(repo, logPath);
|
|
7001
|
+
if (repo && branch && goalStatePath2) links.goalState = githubBlobUrl(repo, branch, goalStatePath2);
|
|
7002
|
+
if (repo && branch && logPath) links.log = githubBlobUrl(repo, branch, logPath);
|
|
6983
7003
|
return Object.keys(links).length > 0 ? links : void 0;
|
|
6984
7004
|
}
|
|
6985
|
-
function githubBlobUrl(repo, filePath) {
|
|
7005
|
+
function githubBlobUrl(repo, branch, filePath) {
|
|
6986
7006
|
try {
|
|
6987
7007
|
const parsed = parseStateRepoSlug(repo);
|
|
6988
|
-
return `https://github.com/${parsed.owner}/${parsed.repo}/blob/${
|
|
7008
|
+
return `https://github.com/${parsed.owner}/${parsed.repo}/blob/${encodeURIComponent(branch)}/${filePath}`;
|
|
6989
7009
|
} catch {
|
|
6990
7010
|
return void 0;
|
|
6991
7011
|
}
|
|
@@ -7068,7 +7088,6 @@ var LOGS_KEY, LOG_RUN_KEY, LOG_STARTED_KEY;
|
|
|
7068
7088
|
var init_runLog = __esm({
|
|
7069
7089
|
"src/goal/runLog.ts"() {
|
|
7070
7090
|
"use strict";
|
|
7071
|
-
init_stateBranch();
|
|
7072
7091
|
init_stateRepo();
|
|
7073
7092
|
init_state2();
|
|
7074
7093
|
LOGS_KEY = "__goalRunLogs";
|
|
@@ -17536,7 +17555,7 @@ function overlayDirectoryChildren(cwd, sourceDir, localDir) {
|
|
|
17536
17555
|
function hydrateStateWorkspace(config, cwd) {
|
|
17537
17556
|
if (process.env.VITEST && process.env[TEST_FETCH_ENV] !== "1") return;
|
|
17538
17557
|
const parsed = parseStateRepo(config);
|
|
17539
|
-
const hydrateKey = `${path41.resolve(cwd)}|${parsed.owner}/${parsed.repo}|${parsed.basePath}|${
|
|
17558
|
+
const hydrateKey = `${path41.resolve(cwd)}|${parsed.owner}/${parsed.repo}|${parsed.basePath}|${parsed.branch}`;
|
|
17540
17559
|
if (hydratedWorkspaces.has(hydrateKey)) return;
|
|
17541
17560
|
const snapshotRoot = fetchStateSnapshot(parsed);
|
|
17542
17561
|
for (const mapping of DIR_MAPPINGS) {
|
|
@@ -17560,7 +17579,7 @@ function fetchStateSnapshot(parsed) {
|
|
|
17560
17579
|
runGit3(["clone", "--no-checkout", "--filter=blob:none", url, cacheDir]);
|
|
17561
17580
|
}
|
|
17562
17581
|
runGit3(["-C", cacheDir, "remote", "set-url", "origin", url]);
|
|
17563
|
-
runGit3(["-C", cacheDir, "fetch", "--depth=1", "origin",
|
|
17582
|
+
runGit3(["-C", cacheDir, "fetch", "--depth=1", "origin", parsed.branch]);
|
|
17564
17583
|
runGit3(["-C", cacheDir, "sparse-checkout", "init", "--cone"]);
|
|
17565
17584
|
runGit3(["-C", cacheDir, "sparse-checkout", "set", parsed.basePath]);
|
|
17566
17585
|
runGit3(["-C", cacheDir, "checkout", "--force", "--detach", "FETCH_HEAD"]);
|
|
@@ -17568,7 +17587,7 @@ function fetchStateSnapshot(parsed) {
|
|
|
17568
17587
|
} catch (err) {
|
|
17569
17588
|
const msg = err instanceof Error ? err.message : String(err);
|
|
17570
17589
|
throw new Error(
|
|
17571
|
-
`stateWorkspace: failed to fetch ${parsed.owner}/${parsed.repo}:${parsed.basePath}@${
|
|
17590
|
+
`stateWorkspace: failed to fetch ${parsed.owner}/${parsed.repo}:${parsed.basePath}@${parsed.branch}: ${msg}`
|
|
17572
17591
|
);
|
|
17573
17592
|
}
|
|
17574
17593
|
return path41.join(cacheDir, parsed.basePath);
|
|
@@ -17577,7 +17596,7 @@ function cacheRoot2() {
|
|
|
17577
17596
|
return process.env[CACHE_ENV2]?.trim() || path41.join(os7.homedir(), ".cache", "kody", "state-repo");
|
|
17578
17597
|
}
|
|
17579
17598
|
function cacheKey2(parsed) {
|
|
17580
|
-
return crypto3.createHash("sha256").update(`${parsed.owner}/${parsed.repo}#${
|
|
17599
|
+
return crypto3.createHash("sha256").update(`${parsed.owner}/${parsed.repo}#${parsed.branch}#${parsed.basePath}`).digest("hex").slice(0, 24);
|
|
17581
17600
|
}
|
|
17582
17601
|
function runGit3(args) {
|
|
17583
17602
|
try {
|
|
@@ -17612,7 +17631,6 @@ var DIR_MAPPINGS, FILE_MAPPINGS, CACHE_ENV2, TEST_FETCH_ENV, hydratedWorkspaces;
|
|
|
17612
17631
|
var init_stateWorkspace = __esm({
|
|
17613
17632
|
"src/stateWorkspace.ts"() {
|
|
17614
17633
|
"use strict";
|
|
17615
|
-
init_stateBranch();
|
|
17616
17634
|
init_stateRepo();
|
|
17617
17635
|
DIR_MAPPINGS = [
|
|
17618
17636
|
{ stateDir: "executables", localDir: path41.join(".kody", "executables") },
|
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.287",
|
|
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",
|