@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.
- package/dist/bin/kody.js +130 -182
- 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.
|
|
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
|
|
21594
|
-
import * as
|
|
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
|
-
|
|
22004
|
-
|
|
22005
|
-
|
|
22006
|
-
|
|
22007
|
-
|
|
22008
|
-
|
|
22009
|
-
|
|
22010
|
-
|
|
22011
|
-
|
|
22012
|
-
|
|
22013
|
-
|
|
22014
|
-
|
|
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
|
-
|
|
22066
|
-
|
|
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: (
|
|
22022
|
+
info: (message) => process.stdout.write(`[kody:chat:store] ${message}
|
|
22074
22023
|
`),
|
|
22075
|
-
warn: (
|
|
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
|
|
22081
|
-
|
|
22082
|
-
|
|
22083
|
-
|
|
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
|
-
|
|
22086
|
-
sessionFile: opts.sessionFile,
|
|
22087
|
-
logger
|
|
22038
|
+
conversationId: opts.sessionId
|
|
22088
22039
|
});
|
|
22089
|
-
|
|
22090
|
-
|
|
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
|
-
|
|
22145
|
-
|
|
22146
|
-
|
|
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
|
|
22158
|
-
|
|
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(
|
|
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
|
|
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) =>
|
|
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 =
|
|
22480
|
+
const indexPath = path15.join(cwd, MEMORY_INDEX_REL);
|
|
22573
22481
|
let raw;
|
|
22574
22482
|
try {
|
|
22575
|
-
raw =
|
|
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 =
|
|
22503
|
+
const dir = path15.join(cwd, CONTEXT_DIR_REL);
|
|
22596
22504
|
let files;
|
|
22597
22505
|
try {
|
|
22598
|
-
files =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
22547
|
+
const instructionsPath = path15.join(cwd, INSTRUCTIONS_REL);
|
|
22640
22548
|
let raw;
|
|
22641
22549
|
try {
|
|
22642
|
-
raw =
|
|
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 =
|
|
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
|
-
|
|
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
|
|
25431
|
-
|
|
25432
|
-
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
25521
|
-
|
|
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
|
-
|
|
25529
|
-
|
|
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
|
-
|
|
25536
|
-
|
|
25537
|
-
|
|
25538
|
-
|
|
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
|
-
|
|
25512
|
+
fs49.writeFileSync(path50.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
|
|
25565
25513
|
`, "utf8");
|
|
25566
|
-
|
|
25567
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
26565
|
-
|
|
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.
|
|
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",
|