@kody-ade/kody-engine 0.4.246 → 0.4.248

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.
Files changed (2) hide show
  1. package/dist/bin/kody.js +58 -12
  2. package/package.json +23 -22
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.246",
18
+ version: "0.4.248",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative agentAction profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -145,11 +145,15 @@ var init_claudeBinary = __esm({
145
145
 
146
146
  // src/issue.ts
147
147
  import { execFileSync } from "child_process";
148
- function ghToken() {
149
- return process.env.GH_PAT?.trim() || process.env.GH_TOKEN;
148
+ function ghToken(preferRepoToken = false) {
149
+ const githubToken = process.env.GITHUB_TOKEN?.trim();
150
+ const kodyToken = process.env.KODY_TOKEN?.trim();
151
+ const ghToken3 = process.env.GH_TOKEN?.trim();
152
+ const ghPat = process.env.GH_PAT?.trim();
153
+ return preferRepoToken ? githubToken || kodyToken || ghToken3 || ghPat : ghPat || ghToken3 || kodyToken || githubToken;
150
154
  }
151
155
  function gh(args, options) {
152
- const token = ghToken();
156
+ const token = ghToken(options?.preferRepoToken);
153
157
  const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
154
158
  return execFileSync("gh", args, {
155
159
  encoding: "utf-8",
@@ -658,6 +662,14 @@ function parseGoalActivations(raw) {
658
662
  const idPrefix = parseSlug(r.idPrefix, "company.activeGoals.idPrefix");
659
663
  if (idPrefix) entry.idPrefix = idPrefix;
660
664
  }
665
+ if (r.preferredRunTime !== void 0) {
666
+ const preferredRunTime = parsePreferredRunTime(r.preferredRunTime);
667
+ if (!preferredRunTime)
668
+ throw new Error(
669
+ `kody.config.json: company.activeGoals preferredRunTime must be { "time": "HH:MM", "timezone": "Area/Name" }`
670
+ );
671
+ entry.preferredRunTime = preferredRunTime;
672
+ }
661
673
  const facts = recordValue(r.facts);
662
674
  if (r.facts !== void 0 && !facts)
663
675
  throw new Error(`kody.config.json: company.activeGoals facts must be an object`);
@@ -666,6 +678,13 @@ function parseGoalActivations(raw) {
666
678
  }
667
679
  return out;
668
680
  }
681
+ function parsePreferredRunTime(raw) {
682
+ const r = recordValue(raw);
683
+ if (!r) return null;
684
+ if (typeof r.time !== "string" || !/^([01]\d|2[0-3]):[0-5]\d$/.test(r.time.trim())) return null;
685
+ if (typeof r.timezone !== "string" || !r.timezone.trim()) return null;
686
+ return { time: r.time.trim(), timezone: r.timezone.trim() };
687
+ }
669
688
  function parseSlugArray(raw, field) {
670
689
  if (!Array.isArray(raw)) throw new Error(`kody.config.json: ${field} must be an array of strings`);
671
690
  const out = [];
@@ -1465,14 +1484,18 @@ function readThread(repoSlug, number, limit = 10) {
1465
1484
  };
1466
1485
  }
1467
1486
  function readCheckRuns(repoSlug, ref, ignoreNames) {
1468
- const sha = gh(["api", `repos/${repoSlug}/commits/${ref}`, "--jq", ".sha"]).trim();
1469
- const raw = gh([
1470
- "api",
1471
- `repos/${repoSlug}/commits/${sha}/check-runs`,
1472
- "--paginate",
1473
- "--jq",
1474
- ".check_runs[] | {name, status, conclusion, details_url}"
1475
- ]);
1487
+ const ghOptions = { preferRepoToken: true };
1488
+ const sha = gh(["api", `repos/${repoSlug}/commits/${ref}`, "--jq", ".sha"], ghOptions).trim();
1489
+ const raw = gh(
1490
+ [
1491
+ "api",
1492
+ `repos/${repoSlug}/commits/${sha}/check-runs`,
1493
+ "--paginate",
1494
+ "--jq",
1495
+ ".check_runs[] | {name, status, conclusion, details_url}"
1496
+ ],
1497
+ ghOptions
1498
+ );
1476
1499
  const ignore = new Set(ignoreNames.map((n) => n.toLowerCase()));
1477
1500
  const checks = raw.split("\n").map((l) => l.trim()).filter(Boolean).map((l) => JSON.parse(l)).filter((c) => !ignore.has(String(c.name).toLowerCase()));
1478
1501
  const failing = checks.filter((c) => CHECK_FAIL_CONCLUSIONS.has(String(c.conclusion ?? "").toUpperCase())).map((c) => ({ name: c.name, conclusion: String(c.conclusion), detailsUrl: c.details_url }));
@@ -17435,12 +17458,34 @@ function unpackAllSecrets(env = process.env) {
17435
17458
  }
17436
17459
  return count;
17437
17460
  }
17461
+ function recoverCheckoutToken(env = process.env, cwd = process.cwd()) {
17462
+ if (env.GITHUB_TOKEN?.trim()) return env.GITHUB_TOKEN.trim();
17463
+ let header = "";
17464
+ try {
17465
+ header = execFileSync25("git", ["config", "--local", "--get", "http.https://github.com/.extraheader"], {
17466
+ cwd,
17467
+ encoding: "utf-8",
17468
+ stdio: ["ignore", "pipe", "ignore"]
17469
+ }).trim();
17470
+ } catch {
17471
+ return void 0;
17472
+ }
17473
+ const match = /^AUTHORIZATION:\s+basic\s+(.+)$/i.exec(header);
17474
+ if (!match) return void 0;
17475
+ const decoded = Buffer.from(match[1], "base64").toString("utf-8");
17476
+ const token = decoded.includes(":") ? decoded.slice(decoded.indexOf(":") + 1).trim() : decoded.trim();
17477
+ if (!token) return void 0;
17478
+ env.GITHUB_TOKEN = token;
17479
+ process.stdout.write("\u2192 kody: GITHUB_TOKEN recovered from actions/checkout credentials\n");
17480
+ return token;
17481
+ }
17438
17482
  async function resolveAuthToken(env = process.env) {
17439
17483
  const creds = readAppCreds(env);
17440
17484
  if (creds) {
17441
17485
  try {
17442
17486
  const minted = await mintAppInstallationToken(creds);
17443
17487
  env.GH_TOKEN = minted;
17488
+ recoverCheckoutToken(env);
17444
17489
  process.stdout.write("\u2192 kody: GH_TOKEN minted from GitHub App (KODY_APP_ID/KODY_APP_PRIVATE_KEY)\n");
17445
17490
  return minted;
17446
17491
  } catch (err) {
@@ -17457,6 +17502,7 @@ async function resolveAuthToken(env = process.env) {
17457
17502
  const picked = sources.find(([, v]) => !!v);
17458
17503
  const token = picked?.[1];
17459
17504
  if (token && !env.GH_TOKEN) env.GH_TOKEN = token;
17505
+ recoverCheckoutToken(env);
17460
17506
  if (token) {
17461
17507
  process.stdout.write(`\u2192 kody: GH_TOKEN sourced from env.${picked[0]}
17462
17508
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.246",
3
+ "version": "0.4.248",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative agentAction profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,6 +12,26 @@
12
12
  "templates",
13
13
  "kody.config.schema.json"
14
14
  ],
15
+ "scripts": {
16
+ "kody:run": "tsx bin/kody.ts",
17
+ "serve": "tsx bin/kody.ts serve",
18
+ "serve:vscode": "tsx bin/kody.ts serve vscode",
19
+ "serve:claude": "tsx bin/kody.ts serve claude",
20
+ "build": "tsup && node scripts/copy-assets.cjs",
21
+ "check:modularity": "tsx scripts/check-script-modularity.ts",
22
+ "pretest": "pnpm check:modularity",
23
+ "test": "vitest run tests/unit tests/int --coverage",
24
+ "posttest": "tsx scripts/check-coverage-floor.ts",
25
+ "test:smoke": "vitest run tests/smoke --no-coverage",
26
+ "test:e2e": "vitest run tests/e2e --no-coverage",
27
+ "test:all": "vitest run tests --no-coverage",
28
+ "typecheck": "tsc --noEmit",
29
+ "lint": "biome check",
30
+ "lint:fix": "biome check --write",
31
+ "format": "biome format --write",
32
+ "brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner",
33
+ "prepublishOnly": "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build"
34
+ },
15
35
  "dependencies": {
16
36
  "@actions/cache": "^6.0.0",
17
37
  "@anthropic-ai/claude-agent-sdk": "0.2.119",
@@ -35,24 +55,5 @@
35
55
  "url": "git+https://github.com/aharonyaircohen/kody-engine.git"
36
56
  },
37
57
  "homepage": "https://github.com/aharonyaircohen/kody-engine",
38
- "bugs": "https://github.com/aharonyaircohen/kody-engine/issues",
39
- "scripts": {
40
- "kody:run": "tsx bin/kody.ts",
41
- "serve": "tsx bin/kody.ts serve",
42
- "serve:vscode": "tsx bin/kody.ts serve vscode",
43
- "serve:claude": "tsx bin/kody.ts serve claude",
44
- "build": "tsup && node scripts/copy-assets.cjs",
45
- "check:modularity": "tsx scripts/check-script-modularity.ts",
46
- "pretest": "pnpm check:modularity",
47
- "test": "vitest run tests/unit tests/int --coverage",
48
- "posttest": "tsx scripts/check-coverage-floor.ts",
49
- "test:smoke": "vitest run tests/smoke --no-coverage",
50
- "test:e2e": "vitest run tests/e2e --no-coverage",
51
- "test:all": "vitest run tests --no-coverage",
52
- "typecheck": "tsc --noEmit",
53
- "lint": "biome check",
54
- "lint:fix": "biome check --write",
55
- "format": "biome format --write",
56
- "brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner"
57
- }
58
- }
58
+ "bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
59
+ }