@kody-ade/kody-engine 0.4.385 → 0.4.387

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 +75 -7
  2. 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.385",
18
+ version: "0.4.387",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -3892,6 +3892,26 @@ function createStateBackendFromEnv(env = process.env, client) {
3892
3892
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
3893
3893
  ...expectedUpdatedAt ? { expectedUpdatedAt } : {}
3894
3894
  });
3895
+ },
3896
+ async getGoal(tenantId, goalId) {
3897
+ const result = await transport.query(anyApi.goals.get, {
3898
+ tenantId: requireTenant(tenantId),
3899
+ goalId: requireNonEmpty(goalId, "goalId")
3900
+ });
3901
+ return result ?? null;
3902
+ },
3903
+ async listGoals(tenantId) {
3904
+ const result = await transport.query(anyApi.goals.list, { tenantId: requireTenant(tenantId) });
3905
+ return Array.isArray(result) ? result : [];
3906
+ },
3907
+ async saveGoal(tenantId, goalId, state, updatedAt, expectedUpdatedAt) {
3908
+ await transport.mutation(anyApi.goals.save, {
3909
+ tenantId: requireTenant(tenantId),
3910
+ goalId: requireNonEmpty(goalId, "goalId"),
3911
+ state,
3912
+ updatedAt,
3913
+ ...expectedUpdatedAt ? { expectedUpdatedAt } : {}
3914
+ });
3895
3915
  }
3896
3916
  };
3897
3917
  }
@@ -3931,6 +3951,9 @@ function taskArtifactStatePath(taskId, file) {
3931
3951
  }
3932
3952
  async function persistTaskArtifactsToState(config, cwd, artifacts) {
3933
3953
  const tenantId = config.github?.owner && config.github.repo ? `${config.github.owner}/${config.github.repo}` : process.env.GITHUB_REPOSITORY?.trim();
3954
+ if (process.env.GITHUB_ACTIONS === "true" && (!process.env.CONVEX_URL || !process.env.KODY_SERVICE_KEY || !tenantId)) {
3955
+ throw new Error("Convex artifact backend is required in GitHub Actions (CONVEX_URL, KODY_SERVICE_KEY, and repository identity)");
3956
+ }
3934
3957
  if (process.env.CONVEX_URL && process.env.KODY_SERVICE_KEY && tenantId) {
3935
3958
  const backend = createStateBackendFromEnv();
3936
3959
  for (const file of TASK_ARTIFACT_FILES) {
@@ -5662,7 +5685,11 @@ function readTaskStateLegacy(target, number, cwd, config) {
5662
5685
  }
5663
5686
  function backendScope(config) {
5664
5687
  const tenantId = config?.github?.owner && config.github.repo ? `${config.github.owner}/${config.github.repo}` : process.env.GITHUB_REPOSITORY?.trim();
5665
- if (!process.env.CONVEX_URL || !process.env.KODY_SERVICE_KEY || !tenantId) return null;
5688
+ const configured = !!process.env.CONVEX_URL && !!process.env.KODY_SERVICE_KEY && !!tenantId;
5689
+ if (!configured && process.env.GITHUB_ACTIONS === "true") {
5690
+ throw new Error("Convex task-state backend is required in GitHub Actions (CONVEX_URL, KODY_SERVICE_KEY, and repository identity)");
5691
+ }
5692
+ if (!configured) return null;
5666
5693
  return { tenantId };
5667
5694
  }
5668
5695
  async function readTaskState(target, number, cwd, config) {
@@ -8707,7 +8734,7 @@ import * as path24 from "path";
8707
8734
  function goalStatePath(goalId) {
8708
8735
  return `todos/${goalId}.json`;
8709
8736
  }
8710
- function fetchGoalState(config, goalId, cwd) {
8737
+ function fetchGoalStateLegacy(config, goalId, cwd) {
8711
8738
  const filePath = goalStatePath(goalId);
8712
8739
  const loaded = readStateText(config, cwd, filePath);
8713
8740
  if (!loaded) return null;
@@ -8762,14 +8789,14 @@ function readStoreGoalTemplate(templateId) {
8762
8789
  function recordField2(value) {
8763
8790
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
8764
8791
  }
8765
- function putGoalState(config, goalId, state, message = `chore(goals): update ${goalId}`, cwd) {
8792
+ function putGoalStateLegacy(config, goalId, state, message = `chore(goals): update ${goalId}`, cwd) {
8766
8793
  const previous = readStateText(config, cwd, goalStatePath(goalId));
8767
8794
  if (previous && !isManagedTodoRaw(previous.content)) {
8768
8795
  throw new Error(`Cannot overwrite regular todo list ${goalId} as managed goal`);
8769
8796
  }
8770
8797
  upsertStateText(config, cwd, goalStatePath(goalId), serializeTodoGoalState(goalId, state, previous?.content), message);
8771
8798
  }
8772
- function listGoalStateIds(config, cwd) {
8799
+ function listGoalStateIdsLegacy(config, cwd) {
8773
8800
  const ids = /* @__PURE__ */ new Set();
8774
8801
  const todoEntries = listStateDirectory(config, cwd, "todos");
8775
8802
  for (const entry of todoEntries) {
@@ -8780,11 +8807,46 @@ function listGoalStateIds(config, cwd) {
8780
8807
  }
8781
8808
  return [...ids].sort();
8782
8809
  }
8810
+ function backendTenant(config) {
8811
+ const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
8812
+ const repo = config.github?.repo?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[1]?.trim();
8813
+ return owner && repo ? `${owner}/${repo}` : null;
8814
+ }
8815
+ function backendEnabled(config) {
8816
+ return Boolean(process.env.CONVEX_URL?.trim() && process.env.KODY_SERVICE_KEY?.trim() && backendTenant(config));
8817
+ }
8818
+ function backendRequired() {
8819
+ return process.env.GITHUB_ACTIONS === "true";
8820
+ }
8821
+ function decodeGoal(doc) {
8822
+ if (!doc || !doc.state || typeof doc.state !== "object" || Array.isArray(doc.state)) return null;
8823
+ const state = doc.state;
8824
+ if (typeof state.state !== "string" || !state.extra || typeof state.extra !== "object") return null;
8825
+ return resolveStoreBackedGoalState(state);
8826
+ }
8827
+ async function fetchGoalStateAsync(config, goalId, cwd) {
8828
+ const tenantId = backendTenant(config);
8829
+ if (backendEnabled(config) && tenantId) {
8830
+ return decodeGoal(await createStateBackendFromEnv().getGoal(tenantId, goalId));
8831
+ }
8832
+ if (backendRequired()) throw new Error("Convex backend is required for goal state in GitHub Actions");
8833
+ return fetchGoalStateLegacy(config, goalId, cwd);
8834
+ }
8835
+ function fetchGoalState(config, goalId, cwd) {
8836
+ return fetchGoalStateLegacy(config, goalId, cwd);
8837
+ }
8838
+ function putGoalState(config, goalId, state, message = `chore(goals): update ${goalId}`, cwd) {
8839
+ putGoalStateLegacy(config, goalId, state, message, cwd);
8840
+ }
8841
+ function listGoalStateIds(config, cwd) {
8842
+ return listGoalStateIdsLegacy(config, cwd);
8843
+ }
8783
8844
  var init_stateStore = __esm({
8784
8845
  "src/goal/stateStore.ts"() {
8785
8846
  "use strict";
8786
8847
  init_companyStore();
8787
8848
  init_stateRepo();
8849
+ init_state_backend();
8788
8850
  init_managedTodoState();
8789
8851
  }
8790
8852
  });
@@ -14987,11 +15049,11 @@ function sleep(ms) {
14987
15049
  return new Promise((resolve10) => setTimeout(resolve10, ms));
14988
15050
  }
14989
15051
  async function fetchGoalStateWithRetry(config, goalId, cwd) {
14990
- let state = fetchGoalState(config, goalId, cwd);
15052
+ let state = await fetchGoalStateAsync(config, goalId, cwd);
14991
15053
  if (state) return state;
14992
15054
  for (const delay of retryDelaysMs()) {
14993
15055
  await sleep(delay);
14994
- state = fetchGoalState(config, goalId, cwd);
15056
+ state = await fetchGoalStateAsync(config, goalId, cwd);
14995
15057
  if (state) {
14996
15058
  process.stdout.write(`[goal-manager] loaded goal state for ${goalId} after retry
14997
15059
  `);
@@ -22837,8 +22899,14 @@ function createSessionStore(opts) {
22837
22899
  });
22838
22900
  }
22839
22901
  if (client && !tenantId) {
22902
+ if (process.env.GITHUB_ACTIONS === "true") {
22903
+ throw new Error("Convex chat backend requires GITHUB_REPOSITORY in GitHub Actions");
22904
+ }
22840
22905
  logger.warn(`session ${opts.sessionId}: CONVEX_URL set but no tenant (GITHUB_REPOSITORY unset) \u2014 using JSONL`);
22841
22906
  } else {
22907
+ if (process.env.GITHUB_ACTIONS === "true") {
22908
+ throw new Error("Convex chat backend is required in GitHub Actions (CONVEX_URL and KODY_SERVICE_KEY)");
22909
+ }
22842
22910
  logger.info(`session ${opts.sessionId}: CONVEX_URL unset \u2014 using legacy state-repo JSONL store`);
22843
22911
  }
22844
22912
  return createJsonlStore(opts.sessionFile);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.385",
3
+ "version": "0.4.387",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",