@kody-ade/kody-engine 0.4.55 → 0.4.57
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 +129 -56
- package/dist/executables/classify/profile.json +1 -0
- package/dist/executables/fix/profile.json +1 -0
- package/dist/executables/fix-ci/profile.json +1 -0
- package/dist/executables/goal-scheduler/scheduler.sh +0 -0
- package/dist/executables/release-deploy/deploy.sh +0 -0
- package/dist/executables/release-prepare/prepare.sh +0 -0
- package/dist/executables/release-publish/publish.sh +0 -0
- package/dist/executables/resolve/apply-prefer.sh +0 -0
- package/dist/executables/revert/revert.sh +0 -0
- package/dist/executables/run/profile.json +1 -0
- package/dist/executables/types.ts +14 -0
- package/package.json +15 -14
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.
|
|
6
|
+
version: "0.4.57",
|
|
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",
|
|
@@ -52,8 +52,8 @@ var package_default = {
|
|
|
52
52
|
|
|
53
53
|
// src/chat-cli.ts
|
|
54
54
|
import { execFileSync as execFileSync31 } from "child_process";
|
|
55
|
-
import * as
|
|
56
|
-
import * as
|
|
55
|
+
import * as fs32 from "fs";
|
|
56
|
+
import * as path30 from "path";
|
|
57
57
|
|
|
58
58
|
// src/chat/events.ts
|
|
59
59
|
import * as fs from "fs";
|
|
@@ -472,7 +472,19 @@ async function runAgent(opts) {
|
|
|
472
472
|
queryOptions.maxThinkingTokens = opts.maxThinkingTokens;
|
|
473
473
|
}
|
|
474
474
|
if (typeof opts.systemPromptAppend === "string" && opts.systemPromptAppend.length > 0) {
|
|
475
|
-
|
|
475
|
+
const systemPrompt = {
|
|
476
|
+
type: "preset",
|
|
477
|
+
preset: "claude_code",
|
|
478
|
+
append: opts.systemPromptAppend
|
|
479
|
+
};
|
|
480
|
+
if (opts.cacheable) systemPrompt.excludeDynamicSections = true;
|
|
481
|
+
queryOptions.systemPrompt = systemPrompt;
|
|
482
|
+
} else if (opts.cacheable) {
|
|
483
|
+
queryOptions.systemPrompt = {
|
|
484
|
+
type: "preset",
|
|
485
|
+
preset: "claude_code",
|
|
486
|
+
excludeDynamicSections: true
|
|
487
|
+
};
|
|
476
488
|
}
|
|
477
489
|
queryOptions.settingSources = opts.settingSources ?? ["project", "local"];
|
|
478
490
|
const result = query({
|
|
@@ -1001,8 +1013,8 @@ async function emit2(sink, type, sessionId, suffix, payload) {
|
|
|
1001
1013
|
|
|
1002
1014
|
// src/kody-cli.ts
|
|
1003
1015
|
import { execFileSync as execFileSync30 } from "child_process";
|
|
1004
|
-
import * as
|
|
1005
|
-
import * as
|
|
1016
|
+
import * as fs31 from "fs";
|
|
1017
|
+
import * as path29 from "path";
|
|
1006
1018
|
|
|
1007
1019
|
// src/dispatch.ts
|
|
1008
1020
|
import * as fs7 from "fs";
|
|
@@ -1581,8 +1593,8 @@ function postPrReviewComment(prNumber, body, cwd) {
|
|
|
1581
1593
|
|
|
1582
1594
|
// src/executor.ts
|
|
1583
1595
|
import { execFileSync as execFileSync29, spawn as spawn5 } from "child_process";
|
|
1584
|
-
import * as
|
|
1585
|
-
import * as
|
|
1596
|
+
import * as fs30 from "fs";
|
|
1597
|
+
import * as path28 from "path";
|
|
1586
1598
|
|
|
1587
1599
|
// src/events.ts
|
|
1588
1600
|
import * as crypto from "crypto";
|
|
@@ -1779,6 +1791,7 @@ function parseClaudeCode(p, raw) {
|
|
|
1779
1791
|
maxThinkingTokens: typeof r.maxThinkingTokens === "number" ? r.maxThinkingTokens : null,
|
|
1780
1792
|
maxTurnTimeoutSec: typeof r.maxTurnTimeoutSec === "number" ? r.maxTurnTimeoutSec : null,
|
|
1781
1793
|
systemPromptAppend: typeof r.systemPromptAppend === "string" ? r.systemPromptAppend : null,
|
|
1794
|
+
cacheable: r.cacheable === true,
|
|
1782
1795
|
tools,
|
|
1783
1796
|
hooks: Array.isArray(r.hooks) ? r.hooks : [],
|
|
1784
1797
|
skills: Array.isArray(r.skills) ? r.skills : [],
|
|
@@ -5429,6 +5442,19 @@ var finalizeGoal = async (ctx) => {
|
|
|
5429
5442
|
return;
|
|
5430
5443
|
}
|
|
5431
5444
|
const ordered = [...taskPrs].sort((a, b) => extractIssueNumber(a) - extractIssueNumber(b));
|
|
5445
|
+
for (const pr of ordered) {
|
|
5446
|
+
if (pr.baseRefName === goal.defaultBranch) continue;
|
|
5447
|
+
process.stdout.write(
|
|
5448
|
+
`[goal-tick] retargeting PR #${pr.number} base ${pr.baseRefName} \u2192 ${goal.defaultBranch}
|
|
5449
|
+
`
|
|
5450
|
+
);
|
|
5451
|
+
const retarget = editPrBase(pr.number, goal.defaultBranch, ctx.cwd);
|
|
5452
|
+
if (!retarget.ok) {
|
|
5453
|
+
process.stderr.write(`[goal-tick] finalizeGoal: editPrBase #${pr.number} failed: ${retarget.error}
|
|
5454
|
+
`);
|
|
5455
|
+
return;
|
|
5456
|
+
}
|
|
5457
|
+
}
|
|
5432
5458
|
for (const pr of ordered) {
|
|
5433
5459
|
if (pr.isDraft) {
|
|
5434
5460
|
process.stdout.write(`[goal-tick] promoting draft PR #${pr.number} \u2192 ready
|
|
@@ -5436,18 +5462,6 @@ var finalizeGoal = async (ctx) => {
|
|
|
5436
5462
|
const ready = markPrReady(pr.number, ctx.cwd);
|
|
5437
5463
|
if (!ready.ok) {
|
|
5438
5464
|
process.stderr.write(`[goal-tick] finalizeGoal: markPrReady #${pr.number} failed: ${ready.error}
|
|
5439
|
-
`);
|
|
5440
|
-
return;
|
|
5441
|
-
}
|
|
5442
|
-
}
|
|
5443
|
-
if (pr.baseRefName !== goal.defaultBranch) {
|
|
5444
|
-
process.stdout.write(
|
|
5445
|
-
`[goal-tick] retargeting PR #${pr.number} base ${pr.baseRefName} \u2192 ${goal.defaultBranch}
|
|
5446
|
-
`
|
|
5447
|
-
);
|
|
5448
|
-
const retarget = editPrBase(pr.number, goal.defaultBranch, ctx.cwd);
|
|
5449
|
-
if (!retarget.ok) {
|
|
5450
|
-
process.stderr.write(`[goal-tick] finalizeGoal: editPrBase #${pr.number} failed: ${retarget.error}
|
|
5451
5465
|
`);
|
|
5452
5466
|
return;
|
|
5453
5467
|
}
|
|
@@ -6297,10 +6311,10 @@ import * as fs24 from "fs";
|
|
|
6297
6311
|
import * as path23 from "path";
|
|
6298
6312
|
var VALID_STATES = /* @__PURE__ */ new Set(["active", "abandoned", "closed", "done"]);
|
|
6299
6313
|
var GoalStateError = class extends Error {
|
|
6300
|
-
constructor(
|
|
6301
|
-
super(`Invalid goal state at ${
|
|
6314
|
+
constructor(path31, message) {
|
|
6315
|
+
super(`Invalid goal state at ${path31}:
|
|
6302
6316
|
${message}`);
|
|
6303
|
-
this.path =
|
|
6317
|
+
this.path = path31;
|
|
6304
6318
|
this.name = "GoalStateError";
|
|
6305
6319
|
}
|
|
6306
6320
|
path;
|
|
@@ -6730,6 +6744,63 @@ function formatReviewComments(raw) {
|
|
|
6730
6744
|
}
|
|
6731
6745
|
}
|
|
6732
6746
|
|
|
6747
|
+
// src/taskContext.ts
|
|
6748
|
+
import * as fs27 from "fs";
|
|
6749
|
+
import * as path26 from "path";
|
|
6750
|
+
var TASK_CONTEXT_SCHEMA_VERSION = 1;
|
|
6751
|
+
function buildTaskContext(args) {
|
|
6752
|
+
return {
|
|
6753
|
+
schemaVersion: TASK_CONTEXT_SCHEMA_VERSION,
|
|
6754
|
+
builtAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6755
|
+
runId: args.runId,
|
|
6756
|
+
issue: args.issue,
|
|
6757
|
+
conventions: args.conventions ?? [],
|
|
6758
|
+
priorArt: args.priorArt ?? "",
|
|
6759
|
+
memoryContext: args.memoryContext ?? "",
|
|
6760
|
+
coverageRules: args.coverageRules ?? []
|
|
6761
|
+
};
|
|
6762
|
+
}
|
|
6763
|
+
function persistTaskContext(cwd, ctx) {
|
|
6764
|
+
try {
|
|
6765
|
+
const dir = path26.join(cwd, ".kody", "runs", ctx.runId);
|
|
6766
|
+
fs27.mkdirSync(dir, { recursive: true });
|
|
6767
|
+
const file = path26.join(dir, "task-context.json");
|
|
6768
|
+
fs27.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
|
|
6769
|
+
`);
|
|
6770
|
+
return file;
|
|
6771
|
+
} catch (err) {
|
|
6772
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6773
|
+
process.stderr.write(`[kody taskContext] persist failed: ${msg}
|
|
6774
|
+
`);
|
|
6775
|
+
return null;
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
|
|
6779
|
+
// src/scripts/loadTaskContext.ts
|
|
6780
|
+
var loadTaskContext = async (ctx) => {
|
|
6781
|
+
const runId = resolveRunId();
|
|
6782
|
+
const rawIssue = ctx.data.issue;
|
|
6783
|
+
const issue = rawIssue ? {
|
|
6784
|
+
...rawIssue,
|
|
6785
|
+
commentsFormatted: rawIssue.commentsFormatted ?? "",
|
|
6786
|
+
labelsFormatted: rawIssue.labelsFormatted ?? ""
|
|
6787
|
+
} : void 0;
|
|
6788
|
+
const taskContext = buildTaskContext({
|
|
6789
|
+
runId,
|
|
6790
|
+
issue,
|
|
6791
|
+
conventions: ctx.data.conventions,
|
|
6792
|
+
priorArt: typeof ctx.data.priorArt === "string" ? ctx.data.priorArt : "",
|
|
6793
|
+
memoryContext: typeof ctx.data.memoryContext === "string" ? ctx.data.memoryContext : "",
|
|
6794
|
+
coverageRules: ctx.data.coverageRules
|
|
6795
|
+
});
|
|
6796
|
+
ctx.data.taskContext = taskContext;
|
|
6797
|
+
const persistedPath = persistTaskContext(ctx.cwd, taskContext);
|
|
6798
|
+
if (persistedPath && ctx.verbose) {
|
|
6799
|
+
process.stderr.write(`[kody taskContext] persisted ${persistedPath}
|
|
6800
|
+
`);
|
|
6801
|
+
}
|
|
6802
|
+
};
|
|
6803
|
+
|
|
6733
6804
|
// src/scripts/loadTaskState.ts
|
|
6734
6805
|
var loadTaskState = async (ctx) => {
|
|
6735
6806
|
const target = ctx.data.commentTargetType;
|
|
@@ -8049,8 +8120,8 @@ function resolveBaseOverride(value) {
|
|
|
8049
8120
|
|
|
8050
8121
|
// src/scripts/runTickScript.ts
|
|
8051
8122
|
import { spawnSync } from "child_process";
|
|
8052
|
-
import * as
|
|
8053
|
-
import * as
|
|
8123
|
+
import * as fs28 from "fs";
|
|
8124
|
+
import * as path27 from "path";
|
|
8054
8125
|
var runTickScript = async (ctx, _profile, args) => {
|
|
8055
8126
|
ctx.skipAgent = true;
|
|
8056
8127
|
const jobsDir = String(args?.jobsDir ?? ".kody/jobs");
|
|
@@ -8062,13 +8133,13 @@ var runTickScript = async (ctx, _profile, args) => {
|
|
|
8062
8133
|
ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
|
|
8063
8134
|
return;
|
|
8064
8135
|
}
|
|
8065
|
-
const jobPath =
|
|
8066
|
-
if (!
|
|
8136
|
+
const jobPath = path27.join(ctx.cwd, jobsDir, `${slug}.md`);
|
|
8137
|
+
if (!fs28.existsSync(jobPath)) {
|
|
8067
8138
|
ctx.output.exitCode = 99;
|
|
8068
8139
|
ctx.output.reason = `runTickScript: job file not found: ${jobPath}`;
|
|
8069
8140
|
return;
|
|
8070
8141
|
}
|
|
8071
|
-
const raw =
|
|
8142
|
+
const raw = fs28.readFileSync(jobPath, "utf-8");
|
|
8072
8143
|
const { frontmatter } = splitFrontmatter(raw);
|
|
8073
8144
|
const tickScript = frontmatter.tickScript;
|
|
8074
8145
|
if (!tickScript) {
|
|
@@ -8076,8 +8147,8 @@ var runTickScript = async (ctx, _profile, args) => {
|
|
|
8076
8147
|
ctx.output.reason = `runTickScript: job ${slug} has no \`tickScript:\` frontmatter \u2014 route via job-tick instead`;
|
|
8077
8148
|
return;
|
|
8078
8149
|
}
|
|
8079
|
-
const scriptPath =
|
|
8080
|
-
if (!
|
|
8150
|
+
const scriptPath = path27.isAbsolute(tickScript) ? tickScript : path27.join(ctx.cwd, tickScript);
|
|
8151
|
+
if (!fs28.existsSync(scriptPath)) {
|
|
8081
8152
|
ctx.output.exitCode = 99;
|
|
8082
8153
|
ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
|
|
8083
8154
|
return;
|
|
@@ -9014,7 +9085,7 @@ var writeJobStateFile = async (ctx, _profile, _agentResult, args) => {
|
|
|
9014
9085
|
};
|
|
9015
9086
|
|
|
9016
9087
|
// src/scripts/writeRunSummary.ts
|
|
9017
|
-
import * as
|
|
9088
|
+
import * as fs29 from "fs";
|
|
9018
9089
|
var writeRunSummary = async (ctx, profile) => {
|
|
9019
9090
|
const summaryPath = process.env.GITHUB_STEP_SUMMARY;
|
|
9020
9091
|
if (!summaryPath) return;
|
|
@@ -9036,7 +9107,7 @@ var writeRunSummary = async (ctx, profile) => {
|
|
|
9036
9107
|
if (reason) lines.push(`- **Reason:** ${reason}`);
|
|
9037
9108
|
lines.push("");
|
|
9038
9109
|
try {
|
|
9039
|
-
|
|
9110
|
+
fs29.appendFileSync(summaryPath, `${lines.join("\n")}
|
|
9040
9111
|
`);
|
|
9041
9112
|
} catch {
|
|
9042
9113
|
}
|
|
@@ -9053,6 +9124,7 @@ var preflightScripts = {
|
|
|
9053
9124
|
syncFlow,
|
|
9054
9125
|
initFlow,
|
|
9055
9126
|
loadTaskState,
|
|
9127
|
+
loadTaskContext,
|
|
9056
9128
|
loadIssueContext,
|
|
9057
9129
|
loadIssueStateComment,
|
|
9058
9130
|
loadJobFromFile,
|
|
@@ -9252,9 +9324,9 @@ async function runExecutable(profileName, input) {
|
|
|
9252
9324
|
data: {},
|
|
9253
9325
|
output: { exitCode: 0 }
|
|
9254
9326
|
};
|
|
9255
|
-
const ndjsonDir =
|
|
9327
|
+
const ndjsonDir = path28.join(input.cwd, ".kody");
|
|
9256
9328
|
const invokeAgent = async (prompt) => {
|
|
9257
|
-
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) =>
|
|
9329
|
+
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path28.isAbsolute(p) ? p : path28.resolve(profile.dir, p)).filter((p) => p.length > 0);
|
|
9258
9330
|
const syntheticPath = ctx.data.syntheticPluginPath;
|
|
9259
9331
|
const pluginPaths = [...externalPlugins, ...syntheticPath ? [syntheticPath] : []];
|
|
9260
9332
|
return runAgent({
|
|
@@ -9273,6 +9345,7 @@ async function runExecutable(profileName, input) {
|
|
|
9273
9345
|
maxThinkingTokens: profile.claudeCode.maxThinkingTokens,
|
|
9274
9346
|
maxTurnTimeoutMs: typeof profile.claudeCode.maxTurnTimeoutSec === "number" ? Math.floor(profile.claudeCode.maxTurnTimeoutSec * 1e3) : void 0,
|
|
9275
9347
|
systemPromptAppend: profile.claudeCode.systemPromptAppend,
|
|
9348
|
+
cacheable: profile.claudeCode.cacheable,
|
|
9276
9349
|
settingSources: profile.claudeCode.settingSources
|
|
9277
9350
|
});
|
|
9278
9351
|
};
|
|
@@ -9417,7 +9490,7 @@ function clearStampedLifecycleLabels(profile, ctx) {
|
|
|
9417
9490
|
function getProfileInputsForChild(profileName, _cwd) {
|
|
9418
9491
|
try {
|
|
9419
9492
|
const profilePath = resolveProfilePath(profileName);
|
|
9420
|
-
if (!
|
|
9493
|
+
if (!fs30.existsSync(profilePath)) return null;
|
|
9421
9494
|
return loadProfile(profilePath).inputs;
|
|
9422
9495
|
} catch {
|
|
9423
9496
|
return null;
|
|
@@ -9426,17 +9499,17 @@ function getProfileInputsForChild(profileName, _cwd) {
|
|
|
9426
9499
|
function resolveProfilePath(profileName) {
|
|
9427
9500
|
const found = resolveExecutable(profileName);
|
|
9428
9501
|
if (found) return found;
|
|
9429
|
-
const here =
|
|
9502
|
+
const here = path28.dirname(new URL(import.meta.url).pathname);
|
|
9430
9503
|
const candidates = [
|
|
9431
|
-
|
|
9504
|
+
path28.join(here, "executables", profileName, "profile.json"),
|
|
9432
9505
|
// same-dir sibling (dev)
|
|
9433
|
-
|
|
9506
|
+
path28.join(here, "..", "executables", profileName, "profile.json"),
|
|
9434
9507
|
// up one (prod: dist/bin → dist/executables)
|
|
9435
|
-
|
|
9508
|
+
path28.join(here, "..", "src", "executables", profileName, "profile.json")
|
|
9436
9509
|
// fallback
|
|
9437
9510
|
];
|
|
9438
9511
|
for (const c of candidates) {
|
|
9439
|
-
if (
|
|
9512
|
+
if (fs30.existsSync(c)) return c;
|
|
9440
9513
|
}
|
|
9441
9514
|
return candidates[0];
|
|
9442
9515
|
}
|
|
@@ -9533,8 +9606,8 @@ function resolveShellTimeoutMs(entry) {
|
|
|
9533
9606
|
var SIGKILL_GRACE_MS = 5e3;
|
|
9534
9607
|
async function runShellEntry(entry, ctx, profile) {
|
|
9535
9608
|
const shellName = entry.shell;
|
|
9536
|
-
const shellPath =
|
|
9537
|
-
if (!
|
|
9609
|
+
const shellPath = path28.join(profile.dir, shellName);
|
|
9610
|
+
if (!fs30.existsSync(shellPath)) {
|
|
9538
9611
|
ctx.skipAgent = true;
|
|
9539
9612
|
ctx.output.exitCode = 99;
|
|
9540
9613
|
ctx.output.reason = `shell script not found: ${shellName} (looked in ${profile.dir})`;
|
|
@@ -9979,9 +10052,9 @@ function resolveAuthToken(env = process.env) {
|
|
|
9979
10052
|
return token;
|
|
9980
10053
|
}
|
|
9981
10054
|
function detectPackageManager2(cwd) {
|
|
9982
|
-
if (
|
|
9983
|
-
if (
|
|
9984
|
-
if (
|
|
10055
|
+
if (fs31.existsSync(path29.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
10056
|
+
if (fs31.existsSync(path29.join(cwd, "yarn.lock"))) return "yarn";
|
|
10057
|
+
if (fs31.existsSync(path29.join(cwd, "bun.lockb"))) return "bun";
|
|
9985
10058
|
return "npm";
|
|
9986
10059
|
}
|
|
9987
10060
|
function shellOut(cmd, args, cwd, stream = true) {
|
|
@@ -10068,11 +10141,11 @@ function configureGitIdentity(cwd) {
|
|
|
10068
10141
|
}
|
|
10069
10142
|
function postFailureTail(issueNumber, cwd, reason) {
|
|
10070
10143
|
if (!issueNumber) return;
|
|
10071
|
-
const logPath =
|
|
10144
|
+
const logPath = path29.join(cwd, ".kody", "last-run.jsonl");
|
|
10072
10145
|
let tail = "";
|
|
10073
10146
|
try {
|
|
10074
|
-
if (
|
|
10075
|
-
const content =
|
|
10147
|
+
if (fs31.existsSync(logPath)) {
|
|
10148
|
+
const content = fs31.readFileSync(logPath, "utf-8");
|
|
10076
10149
|
tail = content.slice(-3e3);
|
|
10077
10150
|
}
|
|
10078
10151
|
} catch {
|
|
@@ -10097,7 +10170,7 @@ async function runCi(argv) {
|
|
|
10097
10170
|
return 0;
|
|
10098
10171
|
}
|
|
10099
10172
|
const args = parseCiArgs(argv);
|
|
10100
|
-
const cwd = args.cwd ?
|
|
10173
|
+
const cwd = args.cwd ? path29.resolve(args.cwd) : process.cwd();
|
|
10101
10174
|
let earlyConfig;
|
|
10102
10175
|
try {
|
|
10103
10176
|
earlyConfig = loadConfig(cwd);
|
|
@@ -10107,9 +10180,9 @@ async function runCi(argv) {
|
|
|
10107
10180
|
const eventName = process.env.GITHUB_EVENT_NAME;
|
|
10108
10181
|
const dispatchEventPath = process.env.GITHUB_EVENT_PATH;
|
|
10109
10182
|
let manualWorkflowDispatch = false;
|
|
10110
|
-
if (!args.issueNumber && !autoFallback && eventName === "workflow_dispatch" && dispatchEventPath &&
|
|
10183
|
+
if (!args.issueNumber && !autoFallback && eventName === "workflow_dispatch" && dispatchEventPath && fs31.existsSync(dispatchEventPath)) {
|
|
10111
10184
|
try {
|
|
10112
|
-
const evt = JSON.parse(
|
|
10185
|
+
const evt = JSON.parse(fs31.readFileSync(dispatchEventPath, "utf-8"));
|
|
10113
10186
|
const issueInput = parseInt(String(evt?.inputs?.issue_number ?? ""), 10);
|
|
10114
10187
|
const sessionInput = String(evt?.inputs?.sessionId ?? "");
|
|
10115
10188
|
manualWorkflowDispatch = !sessionInput && !(Number.isFinite(issueInput) && issueInput > 0);
|
|
@@ -10368,9 +10441,9 @@ function parseChatArgs(argv, env = process.env) {
|
|
|
10368
10441
|
return result;
|
|
10369
10442
|
}
|
|
10370
10443
|
function commitChatFiles(cwd, sessionId, verbose) {
|
|
10371
|
-
const sessionFile =
|
|
10372
|
-
const eventsFile =
|
|
10373
|
-
const paths = [sessionFile, eventsFile].filter((p) =>
|
|
10444
|
+
const sessionFile = path30.relative(cwd, sessionFilePath(cwd, sessionId));
|
|
10445
|
+
const eventsFile = path30.relative(cwd, eventsFilePath(cwd, sessionId));
|
|
10446
|
+
const paths = [sessionFile, eventsFile].filter((p) => fs32.existsSync(path30.join(cwd, p)));
|
|
10374
10447
|
if (paths.length === 0) return;
|
|
10375
10448
|
const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
|
|
10376
10449
|
try {
|
|
@@ -10408,7 +10481,7 @@ async function runChat(argv) {
|
|
|
10408
10481
|
${CHAT_HELP}`);
|
|
10409
10482
|
return 64;
|
|
10410
10483
|
}
|
|
10411
|
-
const cwd = args.cwd ?
|
|
10484
|
+
const cwd = args.cwd ? path30.resolve(args.cwd) : process.cwd();
|
|
10412
10485
|
const sessionId = args.sessionId;
|
|
10413
10486
|
const unpackedSecrets = unpackAllSecrets();
|
|
10414
10487
|
if (unpackedSecrets > 0) {
|
|
@@ -10460,7 +10533,7 @@ ${CHAT_HELP}`);
|
|
|
10460
10533
|
const sink = buildSink(cwd, sessionId, args.dashboardUrl);
|
|
10461
10534
|
const meta = readMeta(sessionFile);
|
|
10462
10535
|
process.stdout.write(
|
|
10463
|
-
`\u2192 kody:chat: session file=${sessionFile} exists=${
|
|
10536
|
+
`\u2192 kody:chat: session file=${sessionFile} exists=${fs32.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
|
|
10464
10537
|
`
|
|
10465
10538
|
);
|
|
10466
10539
|
try {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -163,6 +163,20 @@ export interface ClaudeCodeSpec {
|
|
|
163
163
|
maxTurnTimeoutSec?: number | null
|
|
164
164
|
/** Text appended on top of Claude Code's baseline system prompt. */
|
|
165
165
|
systemPromptAppend: string | null
|
|
166
|
+
/**
|
|
167
|
+
* Cross-process prompt caching opt-in. When true, the agent invocation
|
|
168
|
+
* sets `systemPrompt.excludeDynamicSections: true` so per-user dynamic
|
|
169
|
+
* content (cwd, git status, auto-memory) is stripped from the preset
|
|
170
|
+
* and re-injected as the first user message. The remaining preset
|
|
171
|
+
* becomes byte-identical across runs and benefits from Anthropic's
|
|
172
|
+
* 5-min server-side prompt cache. Recommended for hot-path stages
|
|
173
|
+
* (`run`, `fix`, `classify`) where the same workflow fires many
|
|
174
|
+
* times in a short window.
|
|
175
|
+
*
|
|
176
|
+
* Default: false (preserves legacy behaviour). No-op if the SDK does
|
|
177
|
+
* not support `excludeDynamicSections` (forward-compatible).
|
|
178
|
+
*/
|
|
179
|
+
cacheable?: boolean
|
|
166
180
|
/** SDK built-in tools this executable is allowed to use (capability pack). */
|
|
167
181
|
tools: string[]
|
|
168
182
|
/**
|
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.57",
|
|
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
|
-
|
|
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
|
+
}
|