@kody-ade/kody-engine 0.4.45 → 0.4.47

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@kody-ade/kody-engine",
6
- version: "0.4.45",
6
+ version: "0.4.47",
7
7
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
8
8
  license: "MIT",
9
9
  type: "module",
@@ -401,7 +401,7 @@ function classifySubtype(subtype) {
401
401
  return "generic_failed";
402
402
  }
403
403
  var DEFAULT_ALLOWED_TOOLS = ["Bash", "Edit", "Read", "Write", "Glob", "Grep"];
404
- var DEFAULT_TURN_TIMEOUT_MS = 3e5;
404
+ var DEFAULT_TURN_TIMEOUT_MS = 6e5;
405
405
  function resolveTurnTimeoutMs(opts) {
406
406
  if (opts.maxTurnTimeoutMs !== void 0 && opts.maxTurnTimeoutMs !== null) {
407
407
  return opts.maxTurnTimeoutMs > 0 ? opts.maxTurnTimeoutMs : 0;
@@ -1777,6 +1777,7 @@ function parseClaudeCode(p, raw) {
1777
1777
  permissionMode,
1778
1778
  maxTurns: typeof r.maxTurns === "number" ? r.maxTurns : null,
1779
1779
  maxThinkingTokens: typeof r.maxThinkingTokens === "number" ? r.maxThinkingTokens : null,
1780
+ maxTurnTimeoutSec: typeof r.maxTurnTimeoutSec === "number" ? r.maxTurnTimeoutSec : null,
1780
1781
  systemPromptAppend: typeof r.systemPromptAppend === "string" ? r.systemPromptAppend : null,
1781
1782
  tools,
1782
1783
  hooks: Array.isArray(r.hooks) ? r.hooks : [],
@@ -3828,14 +3829,6 @@ function markPrReady(prNumber, cwd) {
3828
3829
  return fail(err);
3829
3830
  }
3830
3831
  }
3831
- function fetchDefaultBranch(cwd) {
3832
- try {
3833
- const out = gh(["api", "repos/{owner}/{repo}", "--jq", ".default_branch"], { cwd });
3834
- return { ok: true, value: out.trim() };
3835
- } catch (err) {
3836
- return fail(err);
3837
- }
3838
- }
3839
3832
 
3840
3833
  // src/goal/phase.ts
3841
3834
  function derivePhase(snap) {
@@ -3859,15 +3852,6 @@ function pickNextDispatchable(snap) {
3859
3852
  var deriveGoalPhase = async (ctx) => {
3860
3853
  const goal = ctx.data.goal;
3861
3854
  if (!goal) return;
3862
- const defaultBranchResult = fetchDefaultBranch(ctx.cwd);
3863
- if (defaultBranchResult.ok && defaultBranchResult.value) {
3864
- goal.defaultBranch = defaultBranchResult.value;
3865
- } else if (defaultBranchResult.error) {
3866
- process.stderr.write(
3867
- `[goal-tick] deriveGoalPhase: fetchDefaultBranch failed (${defaultBranchResult.error}); falling back to ${goal.defaultBranch}
3868
- `
3869
- );
3870
- }
3871
3855
  const issues = listGoalIssues(goal.id, ctx.cwd);
3872
3856
  if (!issues.ok) {
3873
3857
  process.stderr.write(`[goal-tick] deriveGoalPhase: list issues failed: ${issues.error}
@@ -5463,11 +5447,11 @@ var STATUS_ICON = {
5463
5447
  "review-failed": "\u26A0\uFE0F",
5464
5448
  aborted: "\u26A0\uFE0F"
5465
5449
  };
5466
- var finishFlow = async (ctx, _profile, _agentResult, args) => {
5450
+ var finishFlow = async (ctx, profile, _agentResult, args) => {
5467
5451
  const reason = args?.reason ?? "completed";
5468
5452
  const issueNumber = ctx.args.issue;
5469
5453
  const state = ctx.data.taskState;
5470
- const flowName = state?.flow?.name ?? "(unknown flow)";
5454
+ const flowName = state?.flow?.name || profile.name || "(unknown flow)";
5471
5455
  if (state) state.flow = void 0;
5472
5456
  if (!issueNumber) return;
5473
5457
  const label = typeof args?.label === "string" ? args.label : void 0;
@@ -7992,9 +7976,10 @@ function tryPost(issueNumber, body, cwd) {
7992
7976
  }
7993
7977
  function resolveBaseOverride(value) {
7994
7978
  if (!value) return null;
7995
- if (/^\d+-[a-z0-9-]+$/.test(value)) return value;
7996
- if (/^goal-[a-z0-9-]+$/.test(value)) return value;
7997
- return null;
7979
+ if (value.length > 200) return null;
7980
+ if (value.includes("..")) return null;
7981
+ if (!/^[a-z0-9][a-z0-9/._-]*$/.test(value)) return null;
7982
+ return value;
7998
7983
  }
7999
7984
 
8000
7985
  // src/scripts/runTickScript.ts
@@ -9221,6 +9206,7 @@ async function runExecutable(profileName, input) {
9221
9206
  pluginPaths: pluginPaths.length > 0 ? pluginPaths : void 0,
9222
9207
  maxTurns: profile.claudeCode.maxTurns,
9223
9208
  maxThinkingTokens: profile.claudeCode.maxThinkingTokens,
9209
+ maxTurnTimeoutMs: typeof profile.claudeCode.maxTurnTimeoutSec === "number" ? Math.floor(profile.claudeCode.maxTurnTimeoutSec * 1e3) : void 0,
9224
9210
  systemPromptAppend: profile.claudeCode.systemPromptAppend,
9225
9211
  settingSources: profile.claudeCode.settingSources
9226
9212
  });
@@ -9363,6 +9349,15 @@ function clearStampedLifecycleLabels(profile, ctx) {
9363
9349
  }
9364
9350
  }
9365
9351
  }
9352
+ function getProfileInputsForChild(profileName, _cwd) {
9353
+ try {
9354
+ const profilePath = resolveProfilePath(profileName);
9355
+ if (!fs29.existsSync(profilePath)) return null;
9356
+ return loadProfile(profilePath).inputs;
9357
+ } catch {
9358
+ return null;
9359
+ }
9360
+ }
9366
9361
  function resolveProfilePath(profileName) {
9367
9362
  const found = resolveExecutable(profileName);
9368
9363
  if (found) return found;
@@ -9648,6 +9643,16 @@ async function runContainerLoop(profile, ctx, input) {
9648
9643
  }
9649
9644
  cliArgs = { issue: issueNumber };
9650
9645
  }
9646
+ const childInputs = getProfileInputsForChild(child.exec, input.cwd);
9647
+ if (childInputs) {
9648
+ for (const spec of childInputs) {
9649
+ if (spec.name === "issue" || spec.name === "pr") continue;
9650
+ const parentValue = ctx.args[spec.name];
9651
+ if (parentValue !== void 0 && cliArgs[spec.name] === void 0) {
9652
+ cliArgs[spec.name] = parentValue;
9653
+ }
9654
+ }
9655
+ }
9651
9656
  let childOut;
9652
9657
  const childStartedAt = Date.now();
9653
9658
  try {
@@ -10740,7 +10745,7 @@ ${HELP_TEXT}`);
10740
10745
  }
10741
10746
  }
10742
10747
  const cwd = args.cwd ?? process.cwd();
10743
- const configlessCommands = /* @__PURE__ */ new Set(["init", "goal-tick", "goal-scheduler"]);
10748
+ const configlessCommands = /* @__PURE__ */ new Set(["init", "goal-scheduler"]);
10744
10749
  const skipConfig = configlessCommands.has(args.executableName ?? "");
10745
10750
  try {
10746
10751
  const result = await runExecutable(args.executableName, {
@@ -23,6 +23,7 @@
23
23
  "model": "inherit",
24
24
  "permissionMode": "acceptEdits",
25
25
  "maxTurns": null,
26
+ "maxTurnTimeoutSec": 1200,
26
27
  "systemPromptAppend": null,
27
28
  "tools": [
28
29
  "Read",
@@ -22,6 +22,7 @@
22
22
  "model": "inherit",
23
23
  "permissionMode": "acceptEdits",
24
24
  "maxTurns": null,
25
+ "maxTurnTimeoutSec": 1200,
25
26
  "systemPromptAppend": null,
26
27
  "tools": [
27
28
  "Read",
File without changes
File without changes
File without changes
File without changes
@@ -15,6 +15,7 @@
15
15
  "model": "inherit",
16
16
  "permissionMode": "acceptEdits",
17
17
  "maxTurns": null,
18
+ "maxTurnTimeoutSec": 900,
18
19
  "systemPromptAppend": null,
19
20
  "tools": [
20
21
  "Read",
File without changes
File without changes
@@ -15,13 +15,14 @@
15
15
  "flag": "--base",
16
16
  "type": "string",
17
17
  "required": false,
18
- "describe": "Optional base branch override. Must match /^goal-[a-z0-9-]+$/; used by goal-tick so the feature branch forks from the shared goal branch and the PR targets it."
18
+ "describe": "Optional base branch override. Used by goal-tick's stacked-PR dispatch so each task PR forks from the previous task's head ref. Accepts any safe git ref (see resolveBaseOverride in runFlow.ts)."
19
19
  }
20
20
  ],
21
21
  "claudeCode": {
22
22
  "model": "inherit",
23
23
  "permissionMode": "acceptEdits",
24
24
  "maxTurns": null,
25
+ "maxTurnTimeoutSec": 1200,
25
26
  "systemPromptAppend": null,
26
27
  "tools": [
27
28
  "Read",
@@ -153,6 +153,14 @@ export interface ClaudeCodeSpec {
153
153
  maxTurns: number | null
154
154
  /** Extended-thinking token budget. null = SDK default. */
155
155
  maxThinkingTokens: number | null
156
+ /**
157
+ * Watchdog: abort the agent if no SDK message arrives within this many
158
+ * seconds. Per-profile override for the global 600s default. Useful on
159
+ * `run`/`fix` stages where a long test suite can leave the SDK silent
160
+ * longer than the default. Set to 0 or a negative number to disable
161
+ * the watchdog entirely. null/undefined → use the global default.
162
+ */
163
+ maxTurnTimeoutSec?: number | null
156
164
  /** Text appended on top of Claude Code's baseline system prompt. */
157
165
  systemPromptAppend: string | null
158
166
  /** SDK built-in tools this executable is allowed to use (capability pack). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.45",
3
+ "version": "0.4.47",
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",
@@ -12,6 +12,18 @@
12
12
  "templates",
13
13
  "kody.config.schema.json"
14
14
  ],
15
+ "scripts": {
16
+ "kody": "tsx bin/kody.ts",
17
+ "build": "tsup && node scripts/copy-assets.cjs",
18
+ "test": "vitest run tests/unit tests/int --no-coverage",
19
+ "test:e2e": "vitest run tests/e2e --no-coverage",
20
+ "test:all": "vitest run tests --no-coverage",
21
+ "typecheck": "tsc --noEmit",
22
+ "lint": "biome check",
23
+ "lint:fix": "biome check --write",
24
+ "format": "biome format --write",
25
+ "prepublishOnly": "pnpm build"
26
+ },
15
27
  "dependencies": {
16
28
  "@actions/cache": "^6.0.0",
17
29
  "@anthropic-ai/claude-agent-sdk": "0.2.119"
@@ -32,16 +44,5 @@
32
44
  "url": "git+https://github.com/aharonyaircohen/kody-engine.git"
33
45
  },
34
46
  "homepage": "https://github.com/aharonyaircohen/kody-engine",
35
- "bugs": "https://github.com/aharonyaircohen/kody-engine/issues",
36
- "scripts": {
37
- "kody": "tsx bin/kody.ts",
38
- "build": "tsup && node scripts/copy-assets.cjs",
39
- "test": "vitest run tests/unit tests/int --no-coverage",
40
- "test:e2e": "vitest run tests/e2e --no-coverage",
41
- "test:all": "vitest run tests --no-coverage",
42
- "typecheck": "tsc --noEmit",
43
- "lint": "biome check",
44
- "lint:fix": "biome check --write",
45
- "format": "biome format --write"
46
- }
47
- }
47
+ "bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
48
+ }