@kody-ade/kody-engine 0.4.402 → 0.4.404

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 +130 -182
  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.402",
18
+ version: "0.4.404",
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",
@@ -21590,8 +21590,8 @@ init_agents();
21590
21590
  init_config();
21591
21591
  init_registry();
21592
21592
  init_task_artifacts();
21593
- import * as fs15 from "fs";
21594
- import * as path16 from "path";
21593
+ import * as fs14 from "fs";
21594
+ import * as path15 from "path";
21595
21595
 
21596
21596
  // src/chat/attachments.ts
21597
21597
  init_runtimePaths();
@@ -21999,163 +21999,70 @@ function makeRunId(sessionId, suffix) {
21999
21999
  // src/chat/session-store.ts
22000
22000
  init_convex_client();
22001
22001
  import { anyApi as anyApi2 } from "convex/server";
22002
-
22003
- // src/chat/session.ts
22004
- import * as fs14 from "fs";
22005
- import * as path15 from "path";
22006
- import posixPath3 from "path/posix";
22007
- function sessionFilePath(cwd, sessionId) {
22008
- return path15.join(cwd, ".kody-engine", "runtime", "sessions", `${sessionId}.jsonl`);
22009
- }
22010
- function readMeta(file) {
22011
- if (!fs14.existsSync(file)) return null;
22012
- const raw = fs14.readFileSync(file, "utf-8");
22013
- const firstLine2 = raw.split("\n", 1)[0]?.trim();
22014
- if (!firstLine2) return null;
22015
- try {
22016
- const parsed = JSON.parse(firstLine2);
22017
- if (parsed.type !== "meta") return null;
22018
- if (parsed.mode !== "one-shot" && parsed.mode !== "interactive") return null;
22019
- return parsed;
22020
- } catch {
22021
- return null;
22022
- }
22023
- }
22024
- function readSession(file) {
22025
- if (!fs14.existsSync(file)) return [];
22026
- const raw = fs14.readFileSync(file, "utf-8").trim();
22027
- if (!raw) return [];
22028
- const turns = [];
22029
- for (const line of raw.split("\n")) {
22030
- if (!line.trim()) continue;
22031
- try {
22032
- const parsed = JSON.parse(line);
22033
- if (parsed.role !== "user" && parsed.role !== "assistant") continue;
22034
- if (typeof parsed.content !== "string") continue;
22035
- turns.push(parsed);
22036
- } catch {
22037
- }
22038
- }
22039
- return turns;
22040
- }
22041
- function appendTurn(file, turn) {
22042
- fs14.mkdirSync(path15.dirname(file), { recursive: true });
22043
- const line = JSON.stringify({
22044
- role: turn.role,
22045
- content: turn.content,
22046
- timestamp: turn.timestamp,
22047
- toolCalls: turn.toolCalls ?? []
22048
- });
22049
- fs14.appendFileSync(file, `${line}
22050
- `);
22051
- }
22052
- function seedInitialMessage(file, message) {
22053
- if (!message.trim()) return false;
22054
- const turns = readSession(file);
22055
- const lastUser = [...turns].reverse().find((t) => t.role === "user");
22056
- if (lastUser && lastUser.content === message) return false;
22057
- appendTurn(file, {
22058
- role: "user",
22059
- content: message,
22060
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
22061
- });
22062
- return true;
22002
+ function currentEpochTurns(result) {
22003
+ const ordered = [...result.entries].sort((left, right) => left.seq - right.seq);
22004
+ const lastHandoffSeq = ordered.filter((item) => item.entry.kind === "agent-handoff").at(-1)?.seq ?? -1;
22005
+ return ordered.flatMap(
22006
+ (item) => item.seq > lastHandoffSeq && item.entry.kind === "message" && (item.entry.status === "committed" || item.entry.status === "pending") ? [
22007
+ {
22008
+ role: item.entry.role,
22009
+ content: item.entry.content,
22010
+ timestamp: item.entry.createdAt,
22011
+ toolCalls: []
22012
+ }
22013
+ ] : []
22014
+ );
22063
22015
  }
22064
-
22065
- // src/chat/session-store.ts
22066
- function isChatTurn(value) {
22067
- if (!value || typeof value !== "object") return false;
22068
- const t = value;
22069
- return (t.role === "user" || t.role === "assistant") && typeof t.content === "string";
22016
+ function entryKey(sessionId, turn) {
22017
+ const safeTime = turn.timestamp.replace(/[^a-zA-Z0-9._-]/g, "-");
22018
+ return `engine-${sessionId}-${turn.role}-${safeTime}`;
22070
22019
  }
22071
22020
  function createSessionStore(opts) {
22072
22021
  const logger = opts.logger ?? {
22073
- info: (m) => process.stdout.write(`[kody:chat:store] ${m}
22022
+ info: (message) => process.stdout.write(`[kody:chat:store] ${message}
22074
22023
  `),
22075
- warn: (m) => process.stderr.write(`[kody:chat:store] ${m}
22024
+ warn: (message) => process.stderr.write(`[kody:chat:store] ${message}
22076
22025
  `)
22077
22026
  };
22078
22027
  const client = opts.client !== void 0 ? opts.client : createConvexClientFromEnv();
22079
22028
  const tenantId2 = opts.tenantId ?? process.env.GITHUB_REPOSITORY ?? "";
22080
- if (client && tenantId2) {
22081
- logger.info(`session ${opts.sessionId}: using Convex transcript store (tenant ${tenantId2})`);
22082
- return createConvexStore({
22083
- client,
22029
+ if (!client || !tenantId2) {
22030
+ throw new Error(
22031
+ "Canonical Convex conversation storage is required (CONVEX_URL, KODY_SERVICE_KEY, and GITHUB_REPOSITORY)"
22032
+ );
22033
+ }
22034
+ logger.info(`conversation ${opts.sessionId}: using canonical Convex store (tenant ${tenantId2})`);
22035
+ const read = async () => {
22036
+ const result = await client.query(anyApi2.conversations.get, {
22084
22037
  tenantId: tenantId2,
22085
- sessionId: opts.sessionId,
22086
- sessionFile: opts.sessionFile,
22087
- logger
22038
+ conversationId: opts.sessionId
22088
22039
  });
22089
- }
22090
- if (client && !tenantId2) {
22091
- if (process.env.GITHUB_ACTIONS === "true") {
22092
- throw new Error("Convex chat backend requires GITHUB_REPOSITORY in GitHub Actions");
22093
- }
22094
- logger.warn(`session ${opts.sessionId}: Convex configured without a tenant; using local runtime storage`);
22095
- } else {
22096
- if (process.env.GITHUB_ACTIONS === "true") {
22097
- throw new Error("Convex chat backend is required in GitHub Actions (CONVEX_URL and KODY_SERVICE_KEY)");
22098
- }
22099
- logger.info(`session ${opts.sessionId}: backend unavailable; using local runtime storage`);
22100
- }
22101
- return createLocalStore(opts.sessionFile);
22102
- }
22103
- function createLocalStore(sessionFile) {
22104
- return {
22105
- backend: "local",
22106
- readTurns: async () => readSession(sessionFile),
22107
- appendTurn: async (turn) => {
22108
- appendTurn(sessionFile, turn);
22109
- }
22110
- };
22111
- }
22112
- function normalizeTurn(turn) {
22113
- return {
22114
- role: turn.role,
22115
- content: turn.content,
22116
- timestamp: turn.timestamp,
22117
- toolCalls: turn.toolCalls ?? []
22118
- };
22119
- }
22120
- function createConvexStore(args) {
22121
- const { client, tenantId: tenantId2, sessionId, sessionFile, logger } = args;
22122
- let sessionUpserted = false;
22123
- const appendToConvex = async (turn) => {
22124
- if (!sessionUpserted) {
22125
- try {
22126
- const meta = readMeta(sessionFile) ?? { type: "meta", mode: "one-shot" };
22127
- await client.mutation(anyApi2.chatSessions.upsert, {
22128
- tenantId: tenantId2,
22129
- sessionId,
22130
- meta,
22131
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
22132
- });
22133
- sessionUpserted = true;
22134
- } catch (err) {
22135
- logger.warn(
22136
- `session ${sessionId}: chatSessions.upsert failed: ${err instanceof Error ? err.message : String(err)}`
22137
- );
22138
- }
22139
- }
22140
- await client.mutation(anyApi2.chatTurns.append, { tenantId: tenantId2, sessionId, turn });
22040
+ if (!result) throw new Error(`Conversation not found: ${opts.sessionId}`);
22041
+ return result;
22141
22042
  };
22142
22043
  return {
22143
22044
  backend: "convex",
22144
- readTurns: async () => {
22145
- const docs = await client.query(anyApi2.chatTurns.list, { tenantId: tenantId2, sessionId });
22146
- const convexTurns = [...docs].sort((a, b) => a.seq - b.seq).map((doc) => doc.turn).filter(isChatTurn);
22147
- if (convexTurns.length > 0) return convexTurns;
22148
- const tail = readSession(sessionFile).map(normalizeTurn);
22149
- if (tail.length === 0) return convexTurns;
22150
- logger.info(`session ${sessionId}: importing ${tail.length} runtime turn(s) into Convex`);
22151
- for (const turn of tail) {
22152
- await appendToConvex(turn);
22153
- }
22154
- return tail;
22155
- },
22045
+ readMode: async () => (await read()).conversation.runtime?.kind === "live" ? "interactive" : "one-shot",
22046
+ readActiveAgent: async () => (await read()).conversation.activeAgent,
22047
+ readTurns: async () => currentEpochTurns(await read()),
22156
22048
  appendTurn: async (turn) => {
22157
- const normalized = normalizeTurn(turn);
22158
- await appendToConvex(normalized);
22049
+ const result = await read();
22050
+ const id = entryKey(opts.sessionId, turn);
22051
+ await client.mutation(anyApi2.conversations.appendEntry, {
22052
+ tenantId: tenantId2,
22053
+ conversationId: opts.sessionId,
22054
+ entryId: id,
22055
+ idempotencyKey: id,
22056
+ entry: {
22057
+ kind: "message",
22058
+ role: turn.role,
22059
+ author: turn.role === "assistant" ? { kind: "agent", ...result.conversation.activeAgent } : { kind: "user", actorId: "engine-runtime" },
22060
+ content: turn.content,
22061
+ status: "committed",
22062
+ turnId: id,
22063
+ createdAt: turn.timestamp
22064
+ }
22065
+ });
22159
22066
  }
22160
22067
  };
22161
22068
  }
@@ -22279,7 +22186,7 @@ function buildImplementationCatalog() {
22279
22186
  const entries = [];
22280
22187
  for (const { name, profilePath } of discovered) {
22281
22188
  try {
22282
- const raw = JSON.parse(fs15.readFileSync(profilePath, "utf-8"));
22189
+ const raw = JSON.parse(fs14.readFileSync(profilePath, "utf-8"));
22283
22190
  const describe = typeof raw.describe === "string" ? raw.describe : "";
22284
22191
  const firstSentence = describe.split(/(?<=[.!?])\s+/, 1)[0] ?? "";
22285
22192
  entries.push({ name, describe: firstSentence.trim() });
@@ -22320,7 +22227,8 @@ async function runChatTurn(opts) {
22320
22227
  }
22321
22228
  const { turns: promptTurns, imagePaths } = prepareAttachments(turns, opts.cwd, opts.sessionId);
22322
22229
  const basePrompt = opts.systemPrompt ?? readSystemPromptOverride(opts.cwd) ?? (opts.model.protocol === "openai" ? OPENAI_CHAT_SYSTEM_PROMPT : CHAT_SYSTEM_PROMPT);
22323
- const agentIdentityBlock = readAgentIdentityBlock(opts.cwd, opts.agentIdentity);
22230
+ const activeAgent = await store.readActiveAgent();
22231
+ const agentIdentityBlock = readAgentIdentityBlock(opts.cwd, opts.agentIdentity ?? { slug: activeAgent.slug });
22324
22232
  const catalog = buildImplementationCatalog();
22325
22233
  const taskArtifactsPaths = {
22326
22234
  ...prepareTaskArtifactsDir(opts.cwd, opts.sessionId),
@@ -22386,7 +22294,7 @@ async function runChatTurn(opts) {
22386
22294
  quiet: opts.quiet,
22387
22295
  additionalDirectories: [
22388
22296
  taskArtifactsPaths.absDir,
22389
- ...Array.from(new Set(imagePaths.map((p2) => path16.dirname(p2))))
22297
+ ...Array.from(new Set(imagePaths.map((p2) => path15.dirname(p2))))
22390
22298
  ],
22391
22299
  systemPromptAppend: systemPrompt,
22392
22300
  ...opts.reasoningEffort ? { reasoningEffort: opts.reasoningEffort } : {},
@@ -22569,10 +22477,10 @@ async function emit(sink, type, sessionId, suffix, payload) {
22569
22477
  var MEMORY_INDEX_REL = ".kody-engine/runtime/memory/INDEX.md";
22570
22478
  var MAX_INDEX_BYTES = 8e3;
22571
22479
  function readMemoryIndexBlock(cwd) {
22572
- const indexPath = path16.join(cwd, MEMORY_INDEX_REL);
22480
+ const indexPath = path15.join(cwd, MEMORY_INDEX_REL);
22573
22481
  let raw;
22574
22482
  try {
22575
- raw = fs15.readFileSync(indexPath, "utf-8");
22483
+ raw = fs14.readFileSync(indexPath, "utf-8");
22576
22484
  } catch {
22577
22485
  return "";
22578
22486
  }
@@ -22592,17 +22500,17 @@ _\u2026 (memory index truncated; use recall_search to read more)_` : trimmed;
22592
22500
  var CONTEXT_DIR_REL = ".kody-engine/runtime/context";
22593
22501
  var MAX_CONTEXT_BYTES = 12e3;
22594
22502
  function readContextBlock(cwd) {
22595
- const dir = path16.join(cwd, CONTEXT_DIR_REL);
22503
+ const dir = path15.join(cwd, CONTEXT_DIR_REL);
22596
22504
  let files;
22597
22505
  try {
22598
- files = fs15.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
22506
+ files = fs14.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
22599
22507
  } catch {
22600
22508
  return "";
22601
22509
  }
22602
22510
  const sections = [];
22603
22511
  for (const file of files) {
22604
22512
  try {
22605
- const content = fs15.readFileSync(path16.join(dir, file), "utf-8").trim();
22513
+ const content = fs14.readFileSync(path15.join(dir, file), "utf-8").trim();
22606
22514
  if (content) sections.push(`### ${file.replace(/\.md$/, "")}
22607
22515
 
22608
22516
  ${content}`);
@@ -22628,7 +22536,7 @@ var SYSTEM_PROMPT_OVERRIDE_REL = ".kody-engine/runtime/system-prompt.md";
22628
22536
  function readSystemPromptOverride(cwd) {
22629
22537
  let raw;
22630
22538
  try {
22631
- raw = fs15.readFileSync(path16.join(cwd, SYSTEM_PROMPT_OVERRIDE_REL), "utf-8");
22539
+ raw = fs14.readFileSync(path15.join(cwd, SYSTEM_PROMPT_OVERRIDE_REL), "utf-8");
22632
22540
  } catch {
22633
22541
  return null;
22634
22542
  }
@@ -22636,10 +22544,10 @@ function readSystemPromptOverride(cwd) {
22636
22544
  return trimmed.length > 0 ? trimmed : null;
22637
22545
  }
22638
22546
  function readInstructionsBlock(cwd) {
22639
- const instructionsPath = path16.join(cwd, INSTRUCTIONS_REL);
22547
+ const instructionsPath = path15.join(cwd, INSTRUCTIONS_REL);
22640
22548
  let raw;
22641
22549
  try {
22642
- raw = fs15.readFileSync(instructionsPath, "utf-8");
22550
+ raw = fs14.readFileSync(instructionsPath, "utf-8");
22643
22551
  } catch {
22644
22552
  return "";
22645
22553
  }
@@ -22672,6 +22580,31 @@ function resolveBrainDriver(runtime) {
22672
22580
  return driver;
22673
22581
  }
22674
22582
 
22583
+ // src/chat/session.ts
22584
+ import * as fs15 from "fs";
22585
+ import * as path16 from "path";
22586
+ import posixPath3 from "path/posix";
22587
+ function sessionFilePath(cwd, sessionId) {
22588
+ return path16.join(cwd, ".kody-engine", "runtime", "sessions", `${sessionId}.jsonl`);
22589
+ }
22590
+ function readSession(file) {
22591
+ if (!fs15.existsSync(file)) return [];
22592
+ const raw = fs15.readFileSync(file, "utf-8").trim();
22593
+ if (!raw) return [];
22594
+ const turns = [];
22595
+ for (const line of raw.split("\n")) {
22596
+ if (!line.trim()) continue;
22597
+ try {
22598
+ const parsed = JSON.parse(line);
22599
+ if (parsed.role !== "user" && parsed.role !== "assistant") continue;
22600
+ if (typeof parsed.content !== "string") continue;
22601
+ turns.push(parsed);
22602
+ } catch {
22603
+ }
22604
+ }
22605
+ return turns;
22606
+ }
22607
+
22675
22608
  // src/servers/brain-serve.ts
22676
22609
  init_config();
22677
22610
 
@@ -24436,7 +24369,7 @@ async function handleChatTurn(req, res, chatId, opts) {
24436
24369
  }
24437
24370
  const stateToken = repoToken || envGithubToken();
24438
24371
  const sessionFile = sessionFilePath(agentCwd, chatId);
24439
- const sessionStore = createSessionStore({
24372
+ const sessionStore = opts.createStore({
24440
24373
  sessionId: chatId,
24441
24374
  sessionFile,
24442
24375
  ...repo ? { tenantId: repo } : {}
@@ -24491,6 +24424,7 @@ async function handleChatTurn(req, res, chatId, opts) {
24491
24424
  }
24492
24425
  function buildServer(opts) {
24493
24426
  const runTurn = opts.runTurn ?? runChatTurn;
24427
+ const createStore = opts.createStore ?? createSessionStore;
24494
24428
  const cloneRepo = opts.cloneRepo ?? defaultCloneRepo;
24495
24429
  const reposRoot = opts.reposRoot ?? path48.join(path48.dirname(path48.resolve(opts.cwd)), "repos");
24496
24430
  return createServer2(async (req, res) => {
@@ -24521,6 +24455,7 @@ function buildServer(opts) {
24521
24455
  model: opts.model,
24522
24456
  litellmUrl: opts.litellmUrl,
24523
24457
  runTurn,
24458
+ createStore,
24524
24459
  driver: opts.driver
24525
24460
  });
24526
24461
  return;
@@ -25095,7 +25030,6 @@ async function loadConfigSafe() {
25095
25030
  }
25096
25031
 
25097
25032
  // src/chat-cli.ts
25098
- import * as fs49 from "fs";
25099
25033
  import * as path49 from "path";
25100
25034
 
25101
25035
  // src/chat/inbox.ts
@@ -25425,15 +25359,27 @@ ${CHAT_HELP}`);
25425
25359
  process.stdout.write(`\u2192 kody:chat: litellm proxy ready (url=${litellm?.url ?? "skipped"})
25426
25360
  `);
25427
25361
  const sessionFile = sessionFilePath(cwd, sessionId);
25428
- if (args.initMessage) seedInitialMessage(sessionFile, args.initMessage);
25362
+ const store = createSessionStore({ sessionId, sessionFile });
25363
+ if (args.initMessage) {
25364
+ await store.appendTurn({
25365
+ role: "user",
25366
+ content: args.initMessage,
25367
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
25368
+ });
25369
+ }
25429
25370
  const sink = buildSink(cwd, sessionId, args.dashboardUrl);
25430
- const meta = readMeta(sessionFile);
25431
- process.stdout.write(
25432
- `\u2192 kody:chat: session file=${sessionFile} exists=${fs49.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
25433
- `
25434
- );
25371
+ const mode = await store.readMode();
25372
+ const meta = {
25373
+ type: "meta",
25374
+ mode,
25375
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
25376
+ ...process.env.KODY_IDLE_EXIT_MS ? { idleExitMs: Number(process.env.KODY_IDLE_EXIT_MS) } : {},
25377
+ ...process.env.KODY_HARD_CAP_MS ? { hardCapMs: Number(process.env.KODY_HARD_CAP_MS) } : {}
25378
+ };
25379
+ process.stdout.write(`\u2192 kody:chat: canonical conversation mode=${mode}
25380
+ `);
25435
25381
  try {
25436
- if (meta?.mode === "interactive") {
25382
+ if (mode === "interactive") {
25437
25383
  const result2 = await runInteractiveMode({
25438
25384
  sessionId,
25439
25385
  cwd,
@@ -25444,6 +25390,7 @@ ${CHAT_HELP}`);
25444
25390
  verbose: args.verbose,
25445
25391
  quiet: args.quiet,
25446
25392
  config,
25393
+ store,
25447
25394
  ...reasoningEffort ? { reasoningEffort } : {}
25448
25395
  });
25449
25396
  return result2.exitCode;
@@ -25458,6 +25405,7 @@ ${CHAT_HELP}`);
25458
25405
  verbose: args.verbose,
25459
25406
  quiet: args.quiet,
25460
25407
  config,
25408
+ store,
25461
25409
  ...reasoningEffort ? { reasoningEffort } : {}
25462
25410
  });
25463
25411
  return result.exitCode;
@@ -25475,7 +25423,7 @@ init_config();
25475
25423
  // src/definition-hydration.ts
25476
25424
  init_state_backend();
25477
25425
  import { createHash as createHash5 } from "crypto";
25478
- import * as fs50 from "fs";
25426
+ import * as fs49 from "fs";
25479
25427
  import * as path50 from "path";
25480
25428
  var SLUG_RE2 = /^[a-z0-9][a-z0-9_-]{0,63}$/;
25481
25429
  function assertSafeDefinitionPath(filePath) {
@@ -25510,32 +25458,32 @@ function writeDefinition(root, kind, definition) {
25510
25458
  if (kind === "agent") {
25511
25459
  const raw = bundle.files["agent.md"];
25512
25460
  if (typeof raw !== "string") throw new Error(`agent definition ${definition.slug} is missing agent.md`);
25513
- fs50.writeFileSync(path50.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
25461
+ fs49.writeFileSync(path50.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
25514
25462
  return;
25515
25463
  }
25516
25464
  if (kind === "goal") {
25517
25465
  const goalRoot = path50.join(root, "goals", definition.slug);
25518
25466
  for (const [filePath, contents] of Object.entries(bundle.files)) {
25519
25467
  const target = path50.join(goalRoot, filePath);
25520
- fs50.mkdirSync(path50.dirname(target), { recursive: true });
25521
- fs50.writeFileSync(target, contents, "utf8");
25468
+ fs49.mkdirSync(path50.dirname(target), { recursive: true });
25469
+ fs49.writeFileSync(target, contents, "utf8");
25522
25470
  }
25523
25471
  return;
25524
25472
  }
25525
25473
  const capabilityRoot = path50.join(root, "capabilities", definition.slug);
25526
25474
  for (const [filePath, contents] of Object.entries(bundle.files)) {
25527
25475
  const target = path50.join(capabilityRoot, filePath);
25528
- fs50.mkdirSync(path50.dirname(target), { recursive: true });
25529
- fs50.writeFileSync(target, contents, "utf8");
25476
+ fs49.mkdirSync(path50.dirname(target), { recursive: true });
25477
+ fs49.writeFileSync(target, contents, "utf8");
25530
25478
  }
25531
25479
  }
25532
25480
  async function hydrateDefinitions(options) {
25533
25481
  const root = path50.join(options.cwd, ".kody-engine", "definitions");
25534
25482
  const staging = `${root}.tmp-${process.pid}-${Date.now()}`;
25535
- fs50.rmSync(staging, { recursive: true, force: true });
25536
- fs50.mkdirSync(path50.join(staging, "agents"), { recursive: true });
25537
- fs50.mkdirSync(path50.join(staging, "capabilities"), { recursive: true });
25538
- fs50.mkdirSync(path50.join(staging, "goals"), { recursive: true });
25483
+ fs49.rmSync(staging, { recursive: true, force: true });
25484
+ fs49.mkdirSync(path50.join(staging, "agents"), { recursive: true });
25485
+ fs49.mkdirSync(path50.join(staging, "capabilities"), { recursive: true });
25486
+ fs49.mkdirSync(path50.join(staging, "goals"), { recursive: true });
25539
25487
  try {
25540
25488
  const [capabilities, agents, goals] = await Promise.all([
25541
25489
  options.backend.listDefinitions(options.tenantId, "capability"),
@@ -25561,13 +25509,13 @@ async function hydrateDefinitions(options) {
25561
25509
  hydratedAt: (/* @__PURE__ */ new Date()).toISOString(),
25562
25510
  versions: Object.fromEntries(Object.entries(versions).sort(([left], [right]) => left.localeCompare(right)))
25563
25511
  };
25564
- fs50.writeFileSync(path50.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
25512
+ fs49.writeFileSync(path50.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
25565
25513
  `, "utf8");
25566
- fs50.rmSync(root, { recursive: true, force: true });
25567
- fs50.renameSync(staging, root);
25514
+ fs49.rmSync(root, { recursive: true, force: true });
25515
+ fs49.renameSync(staging, root);
25568
25516
  return { root, tenantId: options.tenantId, versions: manifest.versions };
25569
25517
  } catch (error) {
25570
- fs50.rmSync(staging, { recursive: true, force: true });
25518
+ fs49.rmSync(staging, { recursive: true, force: true });
25571
25519
  throw error;
25572
25520
  }
25573
25521
  }
@@ -26426,7 +26374,7 @@ async function poolServe() {
26426
26374
 
26427
26375
  // src/servers/runner-serve.ts
26428
26376
  import { spawn as spawn9 } from "child_process";
26429
- import * as fs51 from "fs";
26377
+ import * as fs50 from "fs";
26430
26378
  import { createServer as createServer6 } from "http";
26431
26379
  var DEFAULT_PORT2 = 8080;
26432
26380
  var DEFAULT_WORKDIR = "/workspace/repo";
@@ -26561,8 +26509,8 @@ async function defaultRunJob(job) {
26561
26509
  const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
26562
26510
  const branch = job.ref ?? "main";
26563
26511
  const authUrl = `https://x-access-token:${job.githubToken}@github.com/${job.repo}.git`;
26564
- fs51.rmSync(workdir, { recursive: true, force: true });
26565
- fs51.mkdirSync(workdir, { recursive: true });
26512
+ fs50.rmSync(workdir, { recursive: true, force: true });
26513
+ fs50.mkdirSync(workdir, { recursive: true });
26566
26514
  const allSecrets = typeof job.allSecrets === "string" ? job.allSecrets : JSON.stringify(job.allSecrets ?? {});
26567
26515
  const target = job.runRequest.target;
26568
26516
  const interactive = target.type === "chat";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.402",
3
+ "version": "0.4.404",
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",