@kody-ade/kody-engine 0.4.275 → 0.4.276
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 +279 -45
- 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.276",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -19579,6 +19579,68 @@ init_job();
|
|
|
19579
19579
|
init_registry();
|
|
19580
19580
|
init_runtimePaths();
|
|
19581
19581
|
init_stateWorkspace();
|
|
19582
|
+
|
|
19583
|
+
// src/run-request.ts
|
|
19584
|
+
var RUN_REQUEST_ENV = "KODY_RUN_REQUEST_JSON";
|
|
19585
|
+
var INTENTS = /* @__PURE__ */ new Set(["continue", "manage", "run", "tick"]);
|
|
19586
|
+
var SOURCES = /* @__PURE__ */ new Set(["dashboard", "github", "schedule"]);
|
|
19587
|
+
var TARGET_TYPES = /* @__PURE__ */ new Set(["chat", "goal", "issue", "workflow"]);
|
|
19588
|
+
function isRecord(value) {
|
|
19589
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19590
|
+
}
|
|
19591
|
+
function readString(value) {
|
|
19592
|
+
return typeof value === "string" ? value.trim() : "";
|
|
19593
|
+
}
|
|
19594
|
+
function parseTarget(input) {
|
|
19595
|
+
if (!isRecord(input)) return { error: "runRequest.target must be an object" };
|
|
19596
|
+
const type = readString(input.type);
|
|
19597
|
+
if (!TARGET_TYPES.has(type)) return { error: "runRequest.target.type is invalid" };
|
|
19598
|
+
if (type === "issue") {
|
|
19599
|
+
const id2 = Number(input.id);
|
|
19600
|
+
if (!Number.isInteger(id2) || id2 <= 0) return { error: "runRequest.target.id must be a positive issue number" };
|
|
19601
|
+
return { target: { type, id: id2 } };
|
|
19602
|
+
}
|
|
19603
|
+
const id = readString(input.id);
|
|
19604
|
+
if (!id) return { error: "runRequest.target.id is required" };
|
|
19605
|
+
return { target: { type, id } };
|
|
19606
|
+
}
|
|
19607
|
+
function parseRunRequest(input) {
|
|
19608
|
+
let body = input;
|
|
19609
|
+
if (typeof input === "string") {
|
|
19610
|
+
const raw = input.trim();
|
|
19611
|
+
if (!raw) return { error: `${RUN_REQUEST_ENV} is empty` };
|
|
19612
|
+
try {
|
|
19613
|
+
body = JSON.parse(raw);
|
|
19614
|
+
} catch {
|
|
19615
|
+
return { error: `${RUN_REQUEST_ENV} must be valid JSON` };
|
|
19616
|
+
}
|
|
19617
|
+
}
|
|
19618
|
+
if (!isRecord(body)) return { error: "runRequest must be an object" };
|
|
19619
|
+
const parsedTarget = parseTarget(body.target);
|
|
19620
|
+
if ("error" in parsedTarget) return parsedTarget;
|
|
19621
|
+
const intent = readString(body.intent);
|
|
19622
|
+
if (!INTENTS.has(intent)) return { error: "runRequest.intent is invalid" };
|
|
19623
|
+
const source = readString(body.source);
|
|
19624
|
+
if (!SOURCES.has(source)) return { error: "runRequest.source is invalid" };
|
|
19625
|
+
if (body.input !== void 0 && !isRecord(body.input)) {
|
|
19626
|
+
return { error: "runRequest.input must be an object when provided" };
|
|
19627
|
+
}
|
|
19628
|
+
return {
|
|
19629
|
+
request: {
|
|
19630
|
+
target: parsedTarget.target,
|
|
19631
|
+
intent,
|
|
19632
|
+
source,
|
|
19633
|
+
...body.input !== void 0 ? { input: body.input } : {}
|
|
19634
|
+
}
|
|
19635
|
+
};
|
|
19636
|
+
}
|
|
19637
|
+
function readRunRequestFromEnv(env = process.env) {
|
|
19638
|
+
const raw = env[RUN_REQUEST_ENV];
|
|
19639
|
+
if (raw == null || raw.trim() === "") return null;
|
|
19640
|
+
return parseRunRequest(raw);
|
|
19641
|
+
}
|
|
19642
|
+
|
|
19643
|
+
// src/kody-cli.ts
|
|
19582
19644
|
var CI_HELP = `kody ci \u2014 minimal-YAML autonomous engineer (CI preflight + run)
|
|
19583
19645
|
|
|
19584
19646
|
Usage:
|
|
@@ -19637,6 +19699,30 @@ function parseCiArgs(argv) {
|
|
|
19637
19699
|
}
|
|
19638
19700
|
return result;
|
|
19639
19701
|
}
|
|
19702
|
+
function routeRunRequest(request) {
|
|
19703
|
+
const { target, intent } = request;
|
|
19704
|
+
if (target.type === "chat" || target.type === "issue") return { kind: "ignore" };
|
|
19705
|
+
if (target.type === "goal") {
|
|
19706
|
+
if (intent !== "manage" && intent !== "run" && intent !== "tick") {
|
|
19707
|
+
return { kind: "error", error: `goal target does not support intent '${intent}'` };
|
|
19708
|
+
}
|
|
19709
|
+
return {
|
|
19710
|
+
kind: "action",
|
|
19711
|
+
action: "goal-manager",
|
|
19712
|
+
cliArgs: { goal: target.id }
|
|
19713
|
+
};
|
|
19714
|
+
}
|
|
19715
|
+
if (target.type === "workflow") {
|
|
19716
|
+
if (target.id === "scheduled-fanout") {
|
|
19717
|
+
return { kind: "fanout", force: intent === "run" };
|
|
19718
|
+
}
|
|
19719
|
+
if (intent !== "run" && intent !== "tick") {
|
|
19720
|
+
return { kind: "error", error: `workflow target does not support intent '${intent}'` };
|
|
19721
|
+
}
|
|
19722
|
+
return { kind: "action", action: target.id, cliArgs: {} };
|
|
19723
|
+
}
|
|
19724
|
+
return { kind: "error", error: "unsupported run request target" };
|
|
19725
|
+
}
|
|
19640
19726
|
function unpackAllSecrets(env = process.env) {
|
|
19641
19727
|
const raw = env.ALL_SECRETS;
|
|
19642
19728
|
if (!raw) return 0;
|
|
@@ -19848,15 +19934,38 @@ async function runCi(argv) {
|
|
|
19848
19934
|
let manualWorkflowDispatch = false;
|
|
19849
19935
|
let forceRunAction = null;
|
|
19850
19936
|
let forceRunCliArgs = {};
|
|
19937
|
+
let runRequestFanOut = false;
|
|
19938
|
+
let runRequestFanOutForce = false;
|
|
19939
|
+
const parsedRunRequest = readRunRequestFromEnv();
|
|
19940
|
+
if (parsedRunRequest && "error" in parsedRunRequest) {
|
|
19941
|
+
process.stderr.write(`[kody] ${parsedRunRequest.error}
|
|
19942
|
+
`);
|
|
19943
|
+
return 64;
|
|
19944
|
+
}
|
|
19945
|
+
if (!args.issueNumber && !autoFallback && parsedRunRequest && "request" in parsedRunRequest) {
|
|
19946
|
+
const route = routeRunRequest(parsedRunRequest.request);
|
|
19947
|
+
if (route.kind === "error") {
|
|
19948
|
+
process.stderr.write(`[kody] ${route.error}
|
|
19949
|
+
`);
|
|
19950
|
+
return 64;
|
|
19951
|
+
}
|
|
19952
|
+
if (route.kind === "fanout") {
|
|
19953
|
+
runRequestFanOut = true;
|
|
19954
|
+
runRequestFanOutForce = route.force;
|
|
19955
|
+
} else if (route.kind === "action") {
|
|
19956
|
+
forceRunAction = route.action;
|
|
19957
|
+
forceRunCliArgs = route.cliArgs;
|
|
19958
|
+
}
|
|
19959
|
+
}
|
|
19851
19960
|
const envForceAction = (process.env.KODY_FORCE_ACTION ?? "").trim();
|
|
19852
19961
|
const envForceMessage = (process.env.KODY_FORCE_MESSAGE ?? "").trim();
|
|
19853
|
-
if (!args.issueNumber && !autoFallback && envForceAction) {
|
|
19962
|
+
if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && envForceAction) {
|
|
19854
19963
|
forceRunAction = envForceAction;
|
|
19855
19964
|
if (envForceAction === "goal-manager" && envForceMessage) {
|
|
19856
19965
|
forceRunCliArgs = { goal: envForceMessage };
|
|
19857
19966
|
}
|
|
19858
19967
|
}
|
|
19859
|
-
if (!args.issueNumber && !autoFallback && !forceRunAction && eventName === "workflow_dispatch" && dispatchEventPath && fs46.existsSync(dispatchEventPath)) {
|
|
19968
|
+
if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs46.existsSync(dispatchEventPath)) {
|
|
19860
19969
|
try {
|
|
19861
19970
|
const evt = JSON.parse(fs46.readFileSync(dispatchEventPath, "utf-8"));
|
|
19862
19971
|
const issueInput = parseInt(String(evt?.inputs?.issue_number ?? ""), 10);
|
|
@@ -19948,6 +20057,9 @@ async function runCi(argv) {
|
|
|
19948
20057
|
const ec = result.exitCode;
|
|
19949
20058
|
return ec === 0 || ec === 1 || ec === 2 ? ec : 99;
|
|
19950
20059
|
}
|
|
20060
|
+
if (!args.issueNumber && !autoFallback && runRequestFanOut) {
|
|
20061
|
+
return runScheduledFanOut(cwd, args, { force: runRequestFanOutForce });
|
|
20062
|
+
}
|
|
19951
20063
|
if (!args.issueNumber && !autoFallback && (eventName === "schedule" || manualWorkflowDispatch)) {
|
|
19952
20064
|
return runScheduledFanOut(cwd, args, { force: manualWorkflowDispatch });
|
|
19953
20065
|
}
|
|
@@ -21571,6 +21683,10 @@ function parseChatArgs(argv, env = process.env) {
|
|
|
21571
21683
|
else if (arg?.startsWith("--")) result.errors.push(`unknown arg: ${arg}`);
|
|
21572
21684
|
else if (arg) result.errors.push(`unexpected positional: ${arg}`);
|
|
21573
21685
|
}
|
|
21686
|
+
const runRequest = readRunRequestFromEnv(env);
|
|
21687
|
+
if (runRequest && "error" in runRequest) result.errors.push(runRequest.error);
|
|
21688
|
+
const chatTarget = runRequest && "request" in runRequest && runRequest.request.target.type === "chat" ? runRequest.request.target.id : void 0;
|
|
21689
|
+
result.sessionId = result.sessionId ?? chatTarget;
|
|
21574
21690
|
result.sessionId = result.sessionId ?? env.SESSION_ID ?? void 0;
|
|
21575
21691
|
result.initMessage = result.initMessage ?? env.INIT_MESSAGE ?? void 0;
|
|
21576
21692
|
result.model = result.model ?? env.MODEL ?? void 0;
|
|
@@ -21764,7 +21880,11 @@ async function runCapabilityFallbackTick(deps) {
|
|
|
21764
21880
|
const res = await deps.claim(owner, repo, {
|
|
21765
21881
|
jobId: `sched-${owner}-${repo}-${clock()}`,
|
|
21766
21882
|
repo: tag,
|
|
21767
|
-
|
|
21883
|
+
runRequest: {
|
|
21884
|
+
target: { type: "workflow", id: "scheduled-fanout" },
|
|
21885
|
+
intent: "tick",
|
|
21886
|
+
source: "schedule"
|
|
21887
|
+
}
|
|
21768
21888
|
});
|
|
21769
21889
|
if (res.ok) {
|
|
21770
21890
|
claimed++;
|
|
@@ -22339,7 +22459,7 @@ var PoolRegistry = class {
|
|
|
22339
22459
|
jobId: req.jobId,
|
|
22340
22460
|
repo: `${owner}/${repo}`,
|
|
22341
22461
|
githubToken: this.cfg.githubToken,
|
|
22342
|
-
|
|
22462
|
+
runRequest: req.runRequest,
|
|
22343
22463
|
issueNumber: req.issueNumber,
|
|
22344
22464
|
sessionId: req.sessionId,
|
|
22345
22465
|
idleExitMs: req.idleExitMs,
|
|
@@ -22425,24 +22545,78 @@ function parseClaimRequest(body) {
|
|
|
22425
22545
|
const repo = typeof b.repo === "string" ? b.repo.trim() : "";
|
|
22426
22546
|
if (!/^[^/\s]+\/[^/\s]+$/.test(repo)) return { error: "repo must be 'owner/name'" };
|
|
22427
22547
|
const mode = b.mode === "interactive" ? "interactive" : b.mode === "scheduled" ? "scheduled" : "issue";
|
|
22428
|
-
const
|
|
22429
|
-
|
|
22430
|
-
|
|
22431
|
-
|
|
22432
|
-
|
|
22433
|
-
|
|
22434
|
-
|
|
22435
|
-
|
|
22436
|
-
|
|
22548
|
+
const action = typeof b.action === "string" && b.action.trim() ? b.action.trim() : void 0;
|
|
22549
|
+
const message = typeof b.message === "string" && b.message.trim() ? b.message.trim() : void 0;
|
|
22550
|
+
const runRequest = b.runRequest !== void 0 ? parseRunRequest(b.runRequest) : synthesizeLegacyClaimRequest({
|
|
22551
|
+
mode,
|
|
22552
|
+
issueNumber: b.issueNumber,
|
|
22553
|
+
sessionId: b.sessionId,
|
|
22554
|
+
action,
|
|
22555
|
+
message
|
|
22556
|
+
});
|
|
22557
|
+
if ("error" in runRequest) return { error: runRequest.error };
|
|
22558
|
+
const req = { jobId, repo, runRequest: runRequest.request };
|
|
22559
|
+
if (req.runRequest.target.type === "issue") {
|
|
22560
|
+
req.issueNumber = req.runRequest.target.id;
|
|
22561
|
+
} else if (req.runRequest.target.type === "chat") {
|
|
22562
|
+
req.sessionId = req.runRequest.target.id;
|
|
22437
22563
|
if (Number.isFinite(Number(b.idleExitMs))) req.idleExitMs = Number(b.idleExitMs);
|
|
22438
22564
|
if (Number.isFinite(Number(b.hardCapMs))) req.hardCapMs = Number(b.hardCapMs);
|
|
22439
22565
|
}
|
|
22440
22566
|
if (typeof b.ref === "string" && b.ref.trim()) req.ref = b.ref.trim();
|
|
22441
22567
|
if (typeof b.model === "string" && b.model.trim()) req.model = b.model.trim();
|
|
22442
|
-
if (typeof b.sessionId === "string" && b.sessionId.trim()) req.sessionId = b.sessionId.trim();
|
|
22443
22568
|
if (typeof b.dashboardUrl === "string" && b.dashboardUrl.trim()) req.dashboardUrl = b.dashboardUrl.trim();
|
|
22444
22569
|
return { req };
|
|
22445
22570
|
}
|
|
22571
|
+
function synthesizeLegacyClaimRequest(input) {
|
|
22572
|
+
if (input.mode === "issue") {
|
|
22573
|
+
const issueNumber = Number(input.issueNumber);
|
|
22574
|
+
if (!Number.isInteger(issueNumber) || issueNumber <= 0) return { error: "issueNumber required for issue mode" };
|
|
22575
|
+
return {
|
|
22576
|
+
request: {
|
|
22577
|
+
target: { type: "issue", id: issueNumber },
|
|
22578
|
+
intent: "run",
|
|
22579
|
+
source: "dashboard"
|
|
22580
|
+
}
|
|
22581
|
+
};
|
|
22582
|
+
}
|
|
22583
|
+
if (input.mode === "interactive") {
|
|
22584
|
+
const sessionId = typeof input.sessionId === "string" ? input.sessionId.trim() : "";
|
|
22585
|
+
if (!sessionId) return { error: "sessionId required for interactive mode" };
|
|
22586
|
+
return {
|
|
22587
|
+
request: {
|
|
22588
|
+
target: { type: "chat", id: sessionId },
|
|
22589
|
+
intent: "continue",
|
|
22590
|
+
source: "dashboard"
|
|
22591
|
+
}
|
|
22592
|
+
};
|
|
22593
|
+
}
|
|
22594
|
+
if (input.action === "goal-manager" && input.message) {
|
|
22595
|
+
return {
|
|
22596
|
+
request: {
|
|
22597
|
+
target: { type: "goal", id: input.message },
|
|
22598
|
+
intent: "manage",
|
|
22599
|
+
source: "dashboard"
|
|
22600
|
+
}
|
|
22601
|
+
};
|
|
22602
|
+
}
|
|
22603
|
+
if (input.action) {
|
|
22604
|
+
return {
|
|
22605
|
+
request: {
|
|
22606
|
+
target: { type: "workflow", id: input.action },
|
|
22607
|
+
intent: "run",
|
|
22608
|
+
source: "dashboard"
|
|
22609
|
+
}
|
|
22610
|
+
};
|
|
22611
|
+
}
|
|
22612
|
+
return {
|
|
22613
|
+
request: {
|
|
22614
|
+
target: { type: "workflow", id: "scheduled-fanout" },
|
|
22615
|
+
intent: "tick",
|
|
22616
|
+
source: "schedule"
|
|
22617
|
+
}
|
|
22618
|
+
};
|
|
22619
|
+
}
|
|
22446
22620
|
async function poolServe() {
|
|
22447
22621
|
const masterRaw = process.env.KODY_MASTER_KEY?.trim();
|
|
22448
22622
|
if (!masterRaw) throw new Error("KODY_MASTER_KEY required for pool-serve");
|
|
@@ -22610,33 +22784,85 @@ function parseJob(body) {
|
|
|
22610
22784
|
if (!/^[^/\s]+\/[^/\s]+$/.test(repo)) return { error: "repo must be 'owner/name'" };
|
|
22611
22785
|
const githubToken = typeof b.githubToken === "string" ? b.githubToken.trim() : "";
|
|
22612
22786
|
if (!githubToken) return { error: "githubToken required" };
|
|
22787
|
+
const action = typeof b.action === "string" && b.action.trim() ? b.action.trim() : void 0;
|
|
22788
|
+
const message = typeof b.message === "string" && b.message.trim() ? b.message.trim() : void 0;
|
|
22613
22789
|
const mode = b.mode === "interactive" ? "interactive" : b.mode === "scheduled" ? "scheduled" : "issue";
|
|
22614
|
-
const
|
|
22615
|
-
|
|
22616
|
-
|
|
22617
|
-
|
|
22618
|
-
|
|
22619
|
-
|
|
22620
|
-
|
|
22621
|
-
|
|
22622
|
-
|
|
22623
|
-
|
|
22624
|
-
job.
|
|
22790
|
+
const runRequest = b.runRequest !== void 0 ? parseRunRequest(b.runRequest) : synthesizeLegacyRunRequest({
|
|
22791
|
+
mode,
|
|
22792
|
+
issueNumber: b.issueNumber,
|
|
22793
|
+
sessionId: b.sessionId,
|
|
22794
|
+
action,
|
|
22795
|
+
message
|
|
22796
|
+
});
|
|
22797
|
+
if ("error" in runRequest) return { error: runRequest.error };
|
|
22798
|
+
const job = { jobId, repo, githubToken, runRequest: runRequest.request };
|
|
22799
|
+
if (job.runRequest.target.type === "issue") {
|
|
22800
|
+
job.issueNumber = job.runRequest.target.id;
|
|
22801
|
+
} else if (job.runRequest.target.type === "chat") {
|
|
22802
|
+
job.sessionId = job.runRequest.target.id;
|
|
22625
22803
|
if (Number.isFinite(Number(b.idleExitMs))) job.idleExitMs = Number(b.idleExitMs);
|
|
22626
22804
|
if (Number.isFinite(Number(b.hardCapMs))) job.hardCapMs = Number(b.hardCapMs);
|
|
22627
22805
|
}
|
|
22628
22806
|
if (typeof b.ref === "string" && b.ref.trim()) job.ref = b.ref.trim();
|
|
22629
22807
|
if (typeof b.model === "string" && b.model.trim()) job.model = b.model.trim();
|
|
22630
22808
|
if (typeof b.reasoningEffort === "string" && b.reasoningEffort.trim()) job.reasoningEffort = b.reasoningEffort.trim();
|
|
22631
|
-
if (typeof b.action === "string" && b.action.trim()) job.action = b.action.trim();
|
|
22632
|
-
if (typeof b.message === "string" && b.message.trim()) job.message = b.message.trim();
|
|
22633
|
-
if (typeof b.sessionId === "string" && b.sessionId.trim()) job.sessionId = b.sessionId.trim();
|
|
22634
22809
|
if (typeof b.dashboardUrl === "string" && b.dashboardUrl.trim()) job.dashboardUrl = b.dashboardUrl.trim();
|
|
22635
22810
|
if (b.allSecrets && (typeof b.allSecrets === "object" || typeof b.allSecrets === "string")) {
|
|
22636
22811
|
job.allSecrets = b.allSecrets;
|
|
22637
22812
|
}
|
|
22638
22813
|
return { job };
|
|
22639
22814
|
}
|
|
22815
|
+
function synthesizeLegacyRunRequest(input) {
|
|
22816
|
+
if (input.mode === "issue") {
|
|
22817
|
+
const issueNumber = Number(input.issueNumber);
|
|
22818
|
+
if (!Number.isInteger(issueNumber) || issueNumber <= 0) {
|
|
22819
|
+
return { error: "issueNumber (positive integer) required for issue mode" };
|
|
22820
|
+
}
|
|
22821
|
+
return {
|
|
22822
|
+
request: {
|
|
22823
|
+
target: { type: "issue", id: issueNumber },
|
|
22824
|
+
intent: "run",
|
|
22825
|
+
source: "dashboard"
|
|
22826
|
+
}
|
|
22827
|
+
};
|
|
22828
|
+
}
|
|
22829
|
+
if (input.mode === "interactive") {
|
|
22830
|
+
const sessionId = typeof input.sessionId === "string" ? input.sessionId.trim() : "";
|
|
22831
|
+
if (!sessionId) return { error: "sessionId required for interactive mode" };
|
|
22832
|
+
return {
|
|
22833
|
+
request: {
|
|
22834
|
+
target: { type: "chat", id: sessionId },
|
|
22835
|
+
intent: "continue",
|
|
22836
|
+
source: "dashboard"
|
|
22837
|
+
}
|
|
22838
|
+
};
|
|
22839
|
+
}
|
|
22840
|
+
if (input.action === "goal-manager" && input.message) {
|
|
22841
|
+
return {
|
|
22842
|
+
request: {
|
|
22843
|
+
target: { type: "goal", id: input.message },
|
|
22844
|
+
intent: "manage",
|
|
22845
|
+
source: "dashboard"
|
|
22846
|
+
}
|
|
22847
|
+
};
|
|
22848
|
+
}
|
|
22849
|
+
if (input.action) {
|
|
22850
|
+
return {
|
|
22851
|
+
request: {
|
|
22852
|
+
target: { type: "workflow", id: input.action },
|
|
22853
|
+
intent: "run",
|
|
22854
|
+
source: "dashboard"
|
|
22855
|
+
}
|
|
22856
|
+
};
|
|
22857
|
+
}
|
|
22858
|
+
return {
|
|
22859
|
+
request: {
|
|
22860
|
+
target: { type: "workflow", id: "scheduled-fanout" },
|
|
22861
|
+
intent: "tick",
|
|
22862
|
+
source: "schedule"
|
|
22863
|
+
}
|
|
22864
|
+
};
|
|
22865
|
+
}
|
|
22640
22866
|
async function defaultRunJob(job) {
|
|
22641
22867
|
const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
|
|
22642
22868
|
const branch = job.ref ?? "main";
|
|
@@ -22644,20 +22870,17 @@ async function defaultRunJob(job) {
|
|
|
22644
22870
|
fs51.rmSync(workdir, { recursive: true, force: true });
|
|
22645
22871
|
fs51.mkdirSync(workdir, { recursive: true });
|
|
22646
22872
|
const allSecrets = typeof job.allSecrets === "string" ? job.allSecrets : JSON.stringify(job.allSecrets ?? {});
|
|
22647
|
-
const
|
|
22648
|
-
const
|
|
22649
|
-
const
|
|
22873
|
+
const target = job.runRequest.target;
|
|
22874
|
+
const interactive = target.type === "chat";
|
|
22875
|
+
const scheduled = target.type === "goal" || target.type === "workflow";
|
|
22876
|
+
const issueNumber = target.type === "issue" ? target.id : void 0;
|
|
22877
|
+
const sessionId = target.type === "chat" ? target.id : void 0;
|
|
22650
22878
|
const childEnv = {
|
|
22651
22879
|
...process.env,
|
|
22652
22880
|
REPO: job.repo,
|
|
22653
22881
|
REF: branch,
|
|
22654
22882
|
GITHUB_TOKEN: job.githubToken,
|
|
22655
|
-
|
|
22656
|
-
// Scheduled mode drives the engine down the same path GitHub Actions' cron
|
|
22657
|
-
// takes (runScheduledFanOut → due capabilities/goals). Bare `kody` routes on this.
|
|
22658
|
-
...scheduled ? { GITHUB_EVENT_NAME: "schedule" } : {},
|
|
22659
|
-
...job.action ? { KODY_FORCE_ACTION: job.action } : {},
|
|
22660
|
-
...job.message ? { KODY_FORCE_MESSAGE: job.message } : {},
|
|
22883
|
+
[RUN_REQUEST_ENV]: JSON.stringify(job.runRequest),
|
|
22661
22884
|
// GITHUB_REPOSITORY + GH_TOKEN are normally injected by GitHub Actions.
|
|
22662
22885
|
// The engine's interactive mode needs GITHUB_REPOSITORY to resolve the
|
|
22663
22886
|
// configured state repo and persist chat.ready / events (the durable signal
|
|
@@ -22665,11 +22888,9 @@ async function defaultRunJob(job) {
|
|
|
22665
22888
|
// and the session never appears "ready". GH_TOKEN auths the `gh` CLI.
|
|
22666
22889
|
GITHUB_REPOSITORY: job.repo,
|
|
22667
22890
|
GH_TOKEN: job.githubToken,
|
|
22668
|
-
|
|
22669
|
-
// sets SESSION_ID so the engine boots a chat session.
|
|
22670
|
-
ISSUE_NUMBER: interactive || scheduled ? "" : String(job.issueNumber),
|
|
22891
|
+
ISSUE_NUMBER: issueNumber ? String(issueNumber) : "",
|
|
22671
22892
|
ALL_SECRETS: allSecrets,
|
|
22672
|
-
SESSION_ID:
|
|
22893
|
+
SESSION_ID: sessionId ?? "",
|
|
22673
22894
|
DASHBOARD_URL: job.dashboardUrl ?? "",
|
|
22674
22895
|
MODEL: job.model ?? "",
|
|
22675
22896
|
REASONING_EFFORT: job.reasoningEffort ?? "",
|
|
@@ -22698,7 +22919,7 @@ async function defaultRunJob(job) {
|
|
|
22698
22919
|
const authorEmail = process.env.GIT_AUTHOR_EMAIL ?? "kody-bot@users.noreply.github.com";
|
|
22699
22920
|
await run("git", ["config", "user.name", authorName], workdir);
|
|
22700
22921
|
await run("git", ["config", "user.email", authorEmail], workdir);
|
|
22701
|
-
const jobDesc = interactive ? `
|
|
22922
|
+
const jobDesc = interactive ? `chat session ${sessionId}` : scheduled ? `${target.type} ${target.id}` : `issue #${issueNumber}`;
|
|
22702
22923
|
process.stdout.write(`[runner-serve] job ${job.jobId}: ${jobDesc}
|
|
22703
22924
|
`);
|
|
22704
22925
|
const runCode = await run("kody", [], workdir);
|
|
@@ -22781,7 +23002,7 @@ async function runnerServe() {
|
|
|
22781
23002
|
init_config();
|
|
22782
23003
|
init_litellm();
|
|
22783
23004
|
import { spawn as spawn9 } from "child_process";
|
|
22784
|
-
function
|
|
23005
|
+
function parseTarget2(positional) {
|
|
22785
23006
|
if (!Array.isArray(positional) || positional.length === 0) return "none";
|
|
22786
23007
|
const first = String(positional[0]).toLowerCase();
|
|
22787
23008
|
if (first === "vscode" || first === "code") return "vscode";
|
|
@@ -22796,7 +23017,7 @@ function buildProxyEnv(url) {
|
|
|
22796
23017
|
};
|
|
22797
23018
|
}
|
|
22798
23019
|
async function serve(opts) {
|
|
22799
|
-
const target =
|
|
23020
|
+
const target = parseTarget2(opts.args);
|
|
22800
23021
|
const model = parseProviderModel(opts.config.agent.model);
|
|
22801
23022
|
const usesProxy = needsLitellmProxy(model);
|
|
22802
23023
|
let handle = null;
|
|
@@ -23110,6 +23331,17 @@ function envRunMode(env = process.env) {
|
|
|
23110
23331
|
}
|
|
23111
23332
|
return { ...result, errors: [`unknown KODY_RUN_MODE: ${mode}`] };
|
|
23112
23333
|
}
|
|
23334
|
+
function envRunRequest(env = process.env) {
|
|
23335
|
+
const result = { command: "help", errors: [] };
|
|
23336
|
+
const parsed = readRunRequestFromEnv(env);
|
|
23337
|
+
if (!parsed) return null;
|
|
23338
|
+
if ("error" in parsed) return { ...result, errors: [parsed.error] };
|
|
23339
|
+
const { target } = parsed.request;
|
|
23340
|
+
if (target.type === "chat") return { ...result, command: "chat", chatArgv: [] };
|
|
23341
|
+
if (target.type === "issue") return { ...result, command: "ci", ciArgv: ["--issue", String(target.id)] };
|
|
23342
|
+
if (target.type === "goal" || target.type === "workflow") return { ...result, command: "ci", ciArgv: [] };
|
|
23343
|
+
return { ...result, errors: [`unsupported runRequest target: ${target.type ?? "unknown"}`] };
|
|
23344
|
+
}
|
|
23113
23345
|
var HELP_TEXT = `kody-engine \u2014 single-session autonomous engineer
|
|
23114
23346
|
|
|
23115
23347
|
Usage:
|
|
@@ -23146,6 +23378,8 @@ Exit codes:
|
|
|
23146
23378
|
function parseArgs(argv) {
|
|
23147
23379
|
const result = { command: "help", errors: [] };
|
|
23148
23380
|
if (argv.length === 0) {
|
|
23381
|
+
const runRequest = envRunRequest();
|
|
23382
|
+
if (runRequest) return runRequest;
|
|
23149
23383
|
const mode = envRunMode();
|
|
23150
23384
|
if (mode) return mode;
|
|
23151
23385
|
if (process.env.SESSION_ID) return { ...result, command: "chat", chatArgv: [] };
|
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.276",
|
|
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",
|