@kody-ade/kody-engine 0.4.449 → 0.4.451

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 +60 -53
  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.449",
18
+ version: "0.4.451",
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",
@@ -1104,7 +1104,7 @@ function cmsHeaders(opts) {
1104
1104
  }
1105
1105
  };
1106
1106
  }
1107
- async function callDashboardCms(opts, path54, init = {}) {
1107
+ async function callDashboardCms(opts, path53, init = {}) {
1108
1108
  const baseUrl = dashboardBaseUrl(opts);
1109
1109
  if (!baseUrl) {
1110
1110
  return {
@@ -1116,7 +1116,7 @@ async function callDashboardCms(opts, path54, init = {}) {
1116
1116
  const headerResult = cmsHeaders(opts);
1117
1117
  if (!headerResult.ok) return headerResult;
1118
1118
  try {
1119
- const res = await fetch(`${baseUrl}${path54}`, {
1119
+ const res = await fetch(`${baseUrl}${path53}`, {
1120
1120
  ...init,
1121
1121
  headers: {
1122
1122
  ...headerResult.headers,
@@ -1188,8 +1188,8 @@ function documentArg(value) {
1188
1188
  function normalizeCmsDocumentIdInput(input) {
1189
1189
  const trimmed = stripWrappingQuotes(input.trim());
1190
1190
  const withoutQuery = trimmed.split(/[?#]/, 1)[0] ?? trimmed;
1191
- const path54 = parseDocumentPath(withoutQuery);
1192
- return path54 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
1191
+ const path53 = parseDocumentPath(withoutQuery);
1192
+ return path53 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
1193
1193
  }
1194
1194
  function stripWrappingQuotes(value) {
1195
1195
  let current = value;
@@ -1200,9 +1200,9 @@ function stripWrappingQuotes(value) {
1200
1200
  }
1201
1201
  }
1202
1202
  function parseDocumentPath(value) {
1203
- const path54 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
1204
- if (!path54?.includes("/content/entries/")) return null;
1205
- const parts = path54.split("/").filter(Boolean).map(decodePathPart);
1203
+ const path53 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
1204
+ if (!path53?.includes("/content/entries/")) return null;
1205
+ const parts = path53.split("/").filter(Boolean).map(decodePathPart);
1206
1206
  const entriesIndex = parts.findIndex((part, index) => part === "content" && parts[index + 1] === "entries");
1207
1207
  const idPart = parts[entriesIndex + 3];
1208
1208
  if (!idPart || idPart === "new") return null;
@@ -8097,9 +8097,9 @@ import * as fs27 from "fs";
8097
8097
  function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
8098
8098
  const logs = goalRunLogs(data);
8099
8099
  const existing = logs[goalId];
8100
- const path54 = existing?.path ?? goalRunLogPath(goalId, data);
8100
+ const path53 = existing?.path ?? goalRunLogPath(goalId, data);
8101
8101
  logs[goalId] = {
8102
- path: path54,
8102
+ path: path53,
8103
8103
  events: [...existing?.events ?? [], buildGoalRunLogEvent(data, goalId, event, at)]
8104
8104
  };
8105
8105
  }
@@ -9050,11 +9050,11 @@ function validateWorkflow(value, options = {}) {
9050
9050
  function formatWorkflowValidationIssues(issues) {
9051
9051
  return issues.map((entry) => `${entry.path}: ${entry.message}`);
9052
9052
  }
9053
- function validateDataMatch(value, path54, issues, capabilityOutputs) {
9053
+ function validateDataMatch(value, path53, issues, capabilityOutputs) {
9054
9054
  if (value === void 0) return;
9055
9055
  const match = asRecord2(value);
9056
9056
  if (!match || Object.keys(match).length === 0) {
9057
- issue(issues, "invalid_condition", path54, "workflow condition must contain at least one match");
9057
+ issue(issues, "invalid_condition", path53, "workflow condition must contain at least one match");
9058
9058
  return;
9059
9059
  }
9060
9060
  for (const [field, expected] of Object.entries(match)) {
@@ -9062,7 +9062,7 @@ function validateDataMatch(value, path54, issues, capabilityOutputs) {
9062
9062
  issue(
9063
9063
  issues,
9064
9064
  "invalid_data_path",
9065
- `${path54}.${field}`,
9065
+ `${path53}.${field}`,
9066
9066
  `workflow condition must read from facts, evidence, artifacts, result, workflow, or lastOutcome`
9067
9067
  );
9068
9068
  }
@@ -9070,12 +9070,12 @@ function validateDataMatch(value, path54, issues, capabilityOutputs) {
9070
9070
  issue(
9071
9071
  issues,
9072
9072
  "undeclared_result_path",
9073
- `${path54}.${field}`,
9073
+ `${path53}.${field}`,
9074
9074
  `workflow condition reads ${field}, but the source capability does not declare it`
9075
9075
  );
9076
9076
  }
9077
9077
  if (!isComparable(expected)) {
9078
- issue(issues, "invalid_condition_value", `${path54}.${field}`, "workflow condition value must be a JSON scalar");
9078
+ issue(issues, "invalid_condition_value", `${path53}.${field}`, "workflow condition value must be a JSON scalar");
9079
9079
  }
9080
9080
  }
9081
9081
  }
@@ -9099,8 +9099,8 @@ function isJsonValue(value) {
9099
9099
  if (!value || typeof value !== "object") return false;
9100
9100
  return Object.values(value).every(isJsonValue);
9101
9101
  }
9102
- function issue(issues, code, path54, message) {
9103
- issues.push({ code, path: path54, message });
9102
+ function issue(issues, code, path53, message) {
9103
+ issues.push({ code, path: path53, message });
9104
9104
  }
9105
9105
  var SAFE_NAME, SAFE_STEP_ID, SAFE_DATA_PATH, SUPPORTED_STEP_FIELDS, SUPPORTED_TRANSITION_FIELDS;
9106
9106
  var init_workflowValidation = __esm({
@@ -9365,15 +9365,15 @@ var init_backendStateBackend = __esm({
9365
9365
  this.jobsDir = opts.jobsDir.replace(/\/+$/, "");
9366
9366
  }
9367
9367
  async load(slug) {
9368
- const path54 = stateFilePath(this.jobsDir, slug);
9368
+ const path53 = stateFilePath(this.jobsDir, slug);
9369
9369
  const loaded = await createStateBackendFromEnv().get(this.tenantId, `capabilities/${slug}`, "job-state");
9370
9370
  if (!loaded) {
9371
- return { path: path54, handle: null, state: initialStateEnvelope("seed"), created: true };
9371
+ return { path: path53, handle: null, state: initialStateEnvelope("seed"), created: true };
9372
9372
  }
9373
9373
  if (!isStateEnvelope(loaded.doc)) {
9374
9374
  throw new Error(`BackendStateBackend: capabilities/${slug} is not a StateEnvelope`);
9375
9375
  }
9376
- return { path: path54, handle: loaded.updatedAt, state: loaded.doc, created: false };
9376
+ return { path: path53, handle: loaded.updatedAt, state: loaded.doc, created: false };
9377
9377
  }
9378
9378
  async save(loaded, next) {
9379
9379
  if (!loaded.created && isStateUnchanged(loaded.state, next)) return false;
@@ -13851,7 +13851,7 @@ function normalizeLoopDefinition(value) {
13851
13851
  }
13852
13852
  function readLoopDefinition(cwd, id) {
13853
13853
  if (!ID.test(id)) return null;
13854
- const roots = [path34.join(cwd, ".kody-engine", "runtime"), definitionsRoot(cwd)];
13854
+ const roots = loopRoots(cwd);
13855
13855
  for (const root of roots) {
13856
13856
  const filePath = path34.join(root, "loops", id, "loop.json");
13857
13857
  if (!fs36.existsSync(filePath)) continue;
@@ -13872,7 +13872,7 @@ function readLoopDefinition(cwd, id) {
13872
13872
  return null;
13873
13873
  }
13874
13874
  function listLoopDefinitions(cwd) {
13875
- const roots = [path34.join(cwd, ".kody-engine", "runtime"), definitionsRoot(cwd)];
13875
+ const roots = loopRoots(cwd);
13876
13876
  const byId = /* @__PURE__ */ new Map();
13877
13877
  for (const root of roots.reverse()) {
13878
13878
  const loopsDir = path34.join(root, "loops");
@@ -13892,6 +13892,13 @@ function listLoopDefinitions(cwd) {
13892
13892
  }
13893
13893
  return [...byId.values()].sort((left, right) => left.id.localeCompare(right.id));
13894
13894
  }
13895
+ function loopRoots(cwd) {
13896
+ return [
13897
+ path34.join(cwd, ".kody-engine", "runtime"),
13898
+ path34.join(cwd, ".kody-engine", "definitions"),
13899
+ definitionsRoot(cwd)
13900
+ ].filter((root, index, roots) => roots.indexOf(root) === index);
13901
+ }
13895
13902
  function normalizeTrigger(raw) {
13896
13903
  if (raw.type === "manual" && Object.keys(raw).length === 1) return { type: "manual" };
13897
13904
  if (raw.type === "schedule" && typeof raw.every === "string" && /^\d+[mhd]$/.test(raw.every)) {
@@ -15535,13 +15542,13 @@ var init_loadSimpleCapability = __esm({
15535
15542
  function isCompanyIntentId(value) {
15536
15543
  return SLUG_RE2.test(value);
15537
15544
  }
15538
- function normalizeCompanyIntent(path54, raw) {
15545
+ function normalizeCompanyIntent(path53, raw) {
15539
15546
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
15540
- throw new Error(`${path54}: intent must be JSON object`);
15547
+ throw new Error(`${path53}: intent must be JSON object`);
15541
15548
  }
15542
15549
  const input = raw;
15543
15550
  const id = stringField4(input.id);
15544
- if (!id || !isCompanyIntentId(id)) throw new Error(`${path54}: invalid intent id`);
15551
+ if (!id || !isCompanyIntentId(id)) throw new Error(`${path53}: invalid intent id`);
15545
15552
  const createdAt = stringField4(input.createdAt) || nowIso();
15546
15553
  const updatedAt = stringField4(input.updatedAt) || createdAt;
15547
15554
  const description = stringField4(input.description);
@@ -16688,19 +16695,19 @@ function parseAgencyModelProposal(raw) {
16688
16695
  function normalizeBundleFiles(bundle) {
16689
16696
  const seen = /* @__PURE__ */ new Set();
16690
16697
  return bundle.files.map((file, index) => {
16691
- const path54 = file.path.replace(/^\/+/, "");
16692
- const parts = path54.split("/");
16693
- if (!path54 || file.path.startsWith("/") || file.path.includes("\\") || parts.some((part) => !part || part === "." || part === "..")) {
16698
+ const path53 = file.path.replace(/^\/+/, "");
16699
+ const parts = path53.split("/");
16700
+ if (!path53 || file.path.startsWith("/") || file.path.includes("\\") || parts.some((part) => !part || part === "." || part === "..")) {
16694
16701
  throw new Error(`openAgencyModelReviewPr: files[${index}].path is unsafe`);
16695
16702
  }
16696
16703
  if (!/^(agents\/[^/]+\.md|capabilities\/[^/]+\/.+|goals\/(?:templates\/)?[^/]+\/.+|workflows\/[^/]+\.json)$/.test(
16697
- path54
16704
+ path53
16698
16705
  )) {
16699
16706
  throw new Error(`openAgencyModelReviewPr: files[${index}].path is not a supported definition path`);
16700
16707
  }
16701
- if (seen.has(path54)) throw new Error(`openAgencyModelReviewPr: duplicate generated file path: ${path54}`);
16702
- seen.add(path54);
16703
- return { path: path54, content: file.content.replace(/\r\n?/g, "\n") };
16708
+ if (seen.has(path53)) throw new Error(`openAgencyModelReviewPr: duplicate generated file path: ${path53}`);
16709
+ seen.add(path53);
16710
+ return { path: path53, content: file.content.replace(/\r\n?/g, "\n") };
16704
16711
  });
16705
16712
  }
16706
16713
  function buildProposalId(issueNumber, bundle, sourceLabel) {
@@ -17987,9 +17994,9 @@ function latestResult(raw, agentResult) {
17987
17994
  function recordField4(value) {
17988
17995
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
17989
17996
  }
17990
- function resolveDotted(root, path54) {
17991
- if (!path54) return void 0;
17992
- return path54.split(".").reduce((value, key) => recordField4(value)?.[key], root);
17997
+ function resolveDotted(root, path53) {
17998
+ if (!path53) return void 0;
17999
+ return path53.split(".").reduce((value, key) => recordField4(value)?.[key], root);
17993
18000
  }
17994
18001
  function stringValue5(value) {
17995
18002
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -22257,7 +22264,6 @@ __export(job_exports, {
22257
22264
  stableJobKey: () => stableJobKey,
22258
22265
  validateJob: () => validateJob
22259
22266
  });
22260
- import * as path49 from "path";
22261
22267
  function newJobId(flavor) {
22262
22268
  localJobSeq += 1;
22263
22269
  const runId = process.env.GITHUB_RUN_ID;
@@ -22777,11 +22783,11 @@ function selectWorkflowTransition(step, data, counts) {
22777
22783
  }
22778
22784
  function workflowResultConditionPaths(transitions) {
22779
22785
  return transitions.flatMap(
22780
- (transition) => Object.keys(transition.when ?? {}).filter((path54) => path54.startsWith("result."))
22786
+ (transition) => Object.keys(transition.when ?? {}).filter((path53) => path53.startsWith("result."))
22781
22787
  );
22782
22788
  }
22783
22789
  function conditionMatches(condition, context) {
22784
- return Object.entries(condition).every(([path54, expected]) => valueMatches(resolveDottedPath2(context, path54), expected));
22790
+ return Object.entries(condition).every(([path53, expected]) => valueMatches(resolveDottedPath2(context, path53), expected));
22785
22791
  }
22786
22792
  function withWorkflowBoundaryEval(capability, result) {
22787
22793
  const capabilityKind = capability.config.capabilityKind;
@@ -22965,7 +22971,7 @@ function loadCapabilityContext(slug, cwd) {
22965
22971
  return resolveCapabilityFolder(slug, hydratedCapabilitiesRoot(cwd));
22966
22972
  }
22967
22973
  function hydratedCapabilitiesRoot(cwd) {
22968
- return path49.join(cwd, ".kody-engine", "definitions", "capabilities");
22974
+ return capabilitiesRoot(cwd);
22969
22975
  }
22970
22976
  function loadWorkflowContext(slug, base) {
22971
22977
  if (!slug || !isWorkflowDefinitionId(slug)) return null;
@@ -23003,6 +23009,7 @@ var init_job = __esm({
23003
23009
  "use strict";
23004
23010
  init_agencyBoundaryEval();
23005
23011
  init_capabilityFolders();
23012
+ init_definition_paths();
23006
23013
  init_executor();
23007
23014
  init_registry();
23008
23015
  init_runIndex();
@@ -23131,7 +23138,7 @@ function translateOpenAISseToBrain(opts) {
23131
23138
 
23132
23139
  // src/servers/brain-serve.ts
23133
23140
  import { createServer as createServer2 } from "http";
23134
- import * as path52 from "path";
23141
+ import * as path51 from "path";
23135
23142
 
23136
23143
  // src/chat/loop.ts
23137
23144
  init_agent();
@@ -24306,7 +24313,7 @@ async function hydrateDefinitionsFromEnv(cwd = process.cwd(), env = process.env)
24306
24313
  // src/kody-cli.ts
24307
24314
  import { execFileSync as execFileSync24 } from "child_process";
24308
24315
  import * as fs51 from "fs";
24309
- import * as path50 from "path";
24316
+ import * as path49 from "path";
24310
24317
 
24311
24318
  // src/app-auth.ts
24312
24319
  import { createSign } from "crypto";
@@ -25120,9 +25127,9 @@ async function resolveAuthToken(env = process.env) {
25120
25127
  return void 0;
25121
25128
  }
25122
25129
  function detectPackageManager2(cwd) {
25123
- if (fs51.existsSync(path50.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
25124
- if (fs51.existsSync(path50.join(cwd, "yarn.lock"))) return "yarn";
25125
- if (fs51.existsSync(path50.join(cwd, "bun.lockb"))) return "bun";
25130
+ if (fs51.existsSync(path49.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
25131
+ if (fs51.existsSync(path49.join(cwd, "yarn.lock"))) return "yarn";
25132
+ if (fs51.existsSync(path49.join(cwd, "bun.lockb"))) return "bun";
25126
25133
  return "npm";
25127
25134
  }
25128
25135
  function shouldChainScheduledWatch(match) {
@@ -25245,7 +25252,7 @@ async function runCi(argv) {
25245
25252
  return 0;
25246
25253
  }
25247
25254
  const args = parseCiArgs(argv);
25248
- const cwd = args.cwd ? path50.resolve(args.cwd) : process.cwd();
25255
+ const cwd = args.cwd ? path49.resolve(args.cwd) : process.cwd();
25249
25256
  try {
25250
25257
  const n = unpackAllSecrets();
25251
25258
  if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
@@ -25717,7 +25724,7 @@ init_repoWorkspace();
25717
25724
  // src/scripts/brainTurnLog.ts
25718
25725
  init_runtimePaths();
25719
25726
  import * as fs52 from "fs";
25720
- import * as path51 from "path";
25727
+ import * as path50 from "path";
25721
25728
  import posixPath4 from "path/posix";
25722
25729
  var live = /* @__PURE__ */ new Map();
25723
25730
  function brainEventsFilePath(dir, chatId) {
@@ -25764,7 +25771,7 @@ function beginTurn(dir, chatId) {
25764
25771
  };
25765
25772
  live.set(chatId, state);
25766
25773
  const p = brainEventsFilePath(dir, chatId);
25767
- fs52.mkdirSync(path51.dirname(p), { recursive: true });
25774
+ fs52.mkdirSync(path50.dirname(p), { recursive: true });
25768
25775
  return (event) => {
25769
25776
  state.seq += 1;
25770
25777
  const rec = { seq: state.seq, turn, ts: Date.now(), event };
@@ -26201,7 +26208,7 @@ function buildServer(opts) {
26201
26208
  const runTurn = opts.runTurn ?? runChatTurn;
26202
26209
  const createStore = opts.createStore ?? createSessionStore;
26203
26210
  const cloneRepo = opts.cloneRepo ?? defaultCloneRepo;
26204
- const reposRoot = opts.reposRoot ?? path52.join(path52.dirname(path52.resolve(opts.cwd)), "repos");
26211
+ const reposRoot = opts.reposRoot ?? path51.join(path51.dirname(path51.resolve(opts.cwd)), "repos");
26205
26212
  return createServer2(async (req, res) => {
26206
26213
  if (!req.method || !req.url) {
26207
26214
  sendJson(res, 400, { error: "bad request" });
@@ -26805,7 +26812,7 @@ async function loadConfigSafe() {
26805
26812
  }
26806
26813
 
26807
26814
  // src/chat-cli.ts
26808
- import * as path53 from "path";
26815
+ import * as path52 from "path";
26809
26816
 
26810
26817
  // src/chat/inbox.ts
26811
26818
  import { execFileSync as execFileSync25 } from "child_process";
@@ -27086,7 +27093,7 @@ async function runChat(argv) {
27086
27093
  ${CHAT_HELP}`);
27087
27094
  return 64;
27088
27095
  }
27089
- const cwd = args.cwd ? path53.resolve(args.cwd) : process.cwd();
27096
+ const cwd = args.cwd ? path52.resolve(args.cwd) : process.cwd();
27090
27097
  const sessionId = args.sessionId;
27091
27098
  const runRequest = readRunRequestFromEnv();
27092
27099
  if (runRequest && "request" in runRequest) {
@@ -27276,8 +27283,8 @@ var FlyClient = class {
27276
27283
  get fetch() {
27277
27284
  return this.opts.fetchImpl ?? fetch;
27278
27285
  }
27279
- async call(path54, init = {}) {
27280
- const res = await this.fetch(`${FLY_API_BASE}${path54}`, {
27286
+ async call(path53, init = {}) {
27287
+ const res = await this.fetch(`${FLY_API_BASE}${path53}`, {
27281
27288
  method: init.method ?? "GET",
27282
27289
  headers: {
27283
27290
  Authorization: `Bearer ${this.opts.token}`,
@@ -27288,7 +27295,7 @@ var FlyClient = class {
27288
27295
  if (res.status === 404 && init.allow404) return null;
27289
27296
  if (!res.ok) {
27290
27297
  const text2 = await res.text().catch(() => "");
27291
- throw new Error(`Fly API ${res.status} on ${path54}: ${text2.slice(0, 200) || res.statusText}`);
27298
+ throw new Error(`Fly API ${res.status} on ${path53}: ${text2.slice(0, 200) || res.statusText}`);
27292
27299
  }
27293
27300
  if (res.status === 204) return null;
27294
27301
  const raw = await res.text();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.449",
3
+ "version": "0.4.451",
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",