@kody-ade/kody-engine 0.4.467 → 0.4.468
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
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.468",
|
|
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",
|
|
@@ -54,6 +54,7 @@ var init_package = __esm({
|
|
|
54
54
|
"@actions/cache": "^6.0.0",
|
|
55
55
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
56
56
|
"@kody-ade/agency-domain": "0.5.1",
|
|
57
|
+
"@kody-ade/engine-contracts": "0.1.0",
|
|
57
58
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
58
59
|
ajv: "^8.18.0",
|
|
59
60
|
convex: "^1.17.0",
|
|
@@ -14053,6 +14054,11 @@ var init_loopDefinitions = __esm({
|
|
|
14053
14054
|
|
|
14054
14055
|
// src/scripts/dispatchSimpleLoops.ts
|
|
14055
14056
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
14057
|
+
function selectRunnableLoops(loops, now, options) {
|
|
14058
|
+
return loops.filter(
|
|
14059
|
+
(loop) => loop.enabled && loop.trigger.type === "schedule" && (!options.loopId || loop.id === options.loopId) && (options.force || dueSlot(loop, now) !== null)
|
|
14060
|
+
);
|
|
14061
|
+
}
|
|
14056
14062
|
function loopDispatchSlot(loop, now, force, nonce) {
|
|
14057
14063
|
return force ? `manual:${now.toISOString()}:${nonce}` : dueSlot(loop, now);
|
|
14058
14064
|
}
|
|
@@ -14110,9 +14116,11 @@ var init_dispatchSimpleLoops = __esm({
|
|
|
14110
14116
|
if (!tenantId2) throw new Error("Repository identity is required for Loop dispatch");
|
|
14111
14117
|
const now = /* @__PURE__ */ new Date();
|
|
14112
14118
|
const force = ctx.data.jobForce === true;
|
|
14113
|
-
const
|
|
14114
|
-
|
|
14115
|
-
|
|
14119
|
+
const requestedLoopId = typeof ctx.args.loop === "string" ? ctx.args.loop.trim() : "";
|
|
14120
|
+
const due = selectRunnableLoops(listLoopDefinitions(ctx.cwd), now, {
|
|
14121
|
+
force,
|
|
14122
|
+
...requestedLoopId ? { loopId: requestedLoopId } : {}
|
|
14123
|
+
});
|
|
14116
14124
|
process.stdout.write(
|
|
14117
14125
|
`\u2192 kody: Loop scheduler found ${due.length} runnable Loop(s)${force ? " (manual)" : ""}
|
|
14118
14126
|
`
|
|
@@ -25172,63 +25180,15 @@ init_loopDefinitions();
|
|
|
25172
25180
|
init_registry();
|
|
25173
25181
|
|
|
25174
25182
|
// src/run-request.ts
|
|
25175
|
-
|
|
25176
|
-
|
|
25177
|
-
|
|
25178
|
-
|
|
25179
|
-
|
|
25180
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25181
|
-
}
|
|
25182
|
-
function readString(value) {
|
|
25183
|
-
return typeof value === "string" ? value.trim() : "";
|
|
25184
|
-
}
|
|
25185
|
-
function parseTarget(input) {
|
|
25186
|
-
if (!isRecord2(input)) return { error: "runRequest.target must be an object" };
|
|
25187
|
-
const type = readString(input.type);
|
|
25188
|
-
if (!TARGET_TYPES.has(type)) return { error: "runRequest.target.type is invalid" };
|
|
25189
|
-
if (type === "issue") {
|
|
25190
|
-
const id2 = Number(input.id);
|
|
25191
|
-
if (!Number.isInteger(id2) || id2 <= 0) return { error: "runRequest.target.id must be a positive issue number" };
|
|
25192
|
-
return { target: { type, id: id2 } };
|
|
25193
|
-
}
|
|
25194
|
-
const id = readString(input.id);
|
|
25195
|
-
if (!id) return { error: "runRequest.target.id is required" };
|
|
25196
|
-
return { target: { type, id } };
|
|
25197
|
-
}
|
|
25198
|
-
function parseRunRequest(input) {
|
|
25199
|
-
let body = input;
|
|
25200
|
-
if (typeof input === "string") {
|
|
25201
|
-
const raw = input.trim();
|
|
25202
|
-
if (!raw) return { error: `${RUN_REQUEST_ENV} is empty` };
|
|
25203
|
-
try {
|
|
25204
|
-
body = JSON.parse(raw);
|
|
25205
|
-
} catch {
|
|
25206
|
-
return { error: `${RUN_REQUEST_ENV} must be valid JSON` };
|
|
25207
|
-
}
|
|
25208
|
-
}
|
|
25209
|
-
if (!isRecord2(body)) return { error: "runRequest must be an object" };
|
|
25210
|
-
const parsedTarget = parseTarget(body.target);
|
|
25211
|
-
if ("error" in parsedTarget) return parsedTarget;
|
|
25212
|
-
const intent = readString(body.intent);
|
|
25213
|
-
if (!INTENTS.has(intent)) return { error: "runRequest.intent is invalid" };
|
|
25214
|
-
const source = readString(body.source);
|
|
25215
|
-
if (!SOURCES.has(source)) return { error: "runRequest.source is invalid" };
|
|
25216
|
-
if (body.input !== void 0 && !isRecord2(body.input)) {
|
|
25217
|
-
return { error: "runRequest.input must be an object when provided" };
|
|
25218
|
-
}
|
|
25219
|
-
return {
|
|
25220
|
-
request: {
|
|
25221
|
-
target: parsedTarget.target,
|
|
25222
|
-
intent,
|
|
25223
|
-
source,
|
|
25224
|
-
...body.input !== void 0 ? { input: body.input } : {}
|
|
25225
|
-
}
|
|
25226
|
-
};
|
|
25227
|
-
}
|
|
25183
|
+
import {
|
|
25184
|
+
ENGINE_EXECUTION_REQUEST_ENV,
|
|
25185
|
+
parseEngineExecutionRequest
|
|
25186
|
+
} from "@kody-ade/engine-contracts";
|
|
25187
|
+
var RUN_REQUEST_ENV = ENGINE_EXECUTION_REQUEST_ENV;
|
|
25228
25188
|
function readRunRequestFromEnv(env = process.env) {
|
|
25229
25189
|
const raw = env[RUN_REQUEST_ENV];
|
|
25230
25190
|
if (raw == null || raw.trim() === "") return null;
|
|
25231
|
-
return
|
|
25191
|
+
return parseEngineExecutionRequest(raw);
|
|
25232
25192
|
}
|
|
25233
25193
|
|
|
25234
25194
|
// src/kody-cli.ts
|
|
@@ -25322,6 +25282,16 @@ function routeRunRequest(request) {
|
|
|
25322
25282
|
cliArgs: { goal: target.id }
|
|
25323
25283
|
};
|
|
25324
25284
|
}
|
|
25285
|
+
if (target.type === "loop") {
|
|
25286
|
+
if (intent !== "run" && intent !== "tick") {
|
|
25287
|
+
return { kind: "error", error: `loop target does not support intent '${intent}'` };
|
|
25288
|
+
}
|
|
25289
|
+
return {
|
|
25290
|
+
kind: "action",
|
|
25291
|
+
action: "loop-scheduler",
|
|
25292
|
+
cliArgs: { loop: target.id }
|
|
25293
|
+
};
|
|
25294
|
+
}
|
|
25325
25295
|
if (target.type === "workflow") {
|
|
25326
25296
|
if (target.id === "scheduled-fanout") {
|
|
25327
25297
|
return { kind: "fanout", force: intent === "run" };
|
|
@@ -25329,7 +25299,8 @@ function routeRunRequest(request) {
|
|
|
25329
25299
|
if (intent !== "run" && intent !== "tick") {
|
|
25330
25300
|
return { kind: "error", error: `workflow target does not support intent '${intent}'` };
|
|
25331
25301
|
}
|
|
25332
|
-
const
|
|
25302
|
+
const requestedRunId = typeof request.input?.runId === "string" ? request.input.runId : request.requestId;
|
|
25303
|
+
const workflowRunId = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(requestedRunId) ? requestedRunId : void 0;
|
|
25333
25304
|
return { kind: "action", action: target.id, cliArgs: {}, ...workflowRunId ? { workflowRunId } : {} };
|
|
25334
25305
|
}
|
|
25335
25306
|
return { kind: "error", error: "unsupported run request target" };
|
|
@@ -27541,10 +27512,12 @@ async function runAgencyLoopTick(deps) {
|
|
|
27541
27512
|
for (const repository of repositories) {
|
|
27542
27513
|
const [owner, repo] = repository.split("/");
|
|
27543
27514
|
try {
|
|
27515
|
+
const jobId = `sched-${owner}-${repo}-${clock()}`;
|
|
27544
27516
|
const result = await deps.claim(owner, repo, {
|
|
27545
|
-
jobId
|
|
27517
|
+
jobId,
|
|
27546
27518
|
repo: repository,
|
|
27547
27519
|
runRequest: {
|
|
27520
|
+
requestId: jobId,
|
|
27548
27521
|
target: { type: "workflow", id: "scheduled-fanout" },
|
|
27549
27522
|
intent: "tick",
|
|
27550
27523
|
source: "schedule"
|
|
@@ -28131,16 +28104,8 @@ function parseClaimRequest(body) {
|
|
|
28131
28104
|
if (!jobId) return { error: "jobId required" };
|
|
28132
28105
|
const repo = typeof b.repo === "string" ? b.repo.trim() : "";
|
|
28133
28106
|
if (!/^[^/\s]+\/[^/\s]+$/.test(repo)) return { error: "repo must be 'owner/name'" };
|
|
28134
|
-
|
|
28135
|
-
const
|
|
28136
|
-
const message = typeof b.message === "string" && b.message.trim() ? b.message.trim() : void 0;
|
|
28137
|
-
const runRequest = b.runRequest !== void 0 ? parseRunRequest(b.runRequest) : synthesizeLegacyClaimRequest({
|
|
28138
|
-
mode,
|
|
28139
|
-
issueNumber: b.issueNumber,
|
|
28140
|
-
sessionId: b.sessionId,
|
|
28141
|
-
action,
|
|
28142
|
-
message
|
|
28143
|
-
});
|
|
28107
|
+
if (b.runRequest === void 0) return { error: "runRequest required" };
|
|
28108
|
+
const runRequest = parseEngineExecutionRequest(b.runRequest);
|
|
28144
28109
|
if ("error" in runRequest) return { error: runRequest.error };
|
|
28145
28110
|
const req = { jobId, repo, runRequest: runRequest.request };
|
|
28146
28111
|
if (req.runRequest.target.type === "issue") {
|
|
@@ -28155,55 +28120,6 @@ function parseClaimRequest(body) {
|
|
|
28155
28120
|
if (typeof b.dashboardUrl === "string" && b.dashboardUrl.trim()) req.dashboardUrl = b.dashboardUrl.trim();
|
|
28156
28121
|
return { req };
|
|
28157
28122
|
}
|
|
28158
|
-
function synthesizeLegacyClaimRequest(input) {
|
|
28159
|
-
if (input.mode === "issue") {
|
|
28160
|
-
const issueNumber = Number(input.issueNumber);
|
|
28161
|
-
if (!Number.isInteger(issueNumber) || issueNumber <= 0) return { error: "issueNumber required for issue mode" };
|
|
28162
|
-
return {
|
|
28163
|
-
request: {
|
|
28164
|
-
target: { type: "issue", id: issueNumber },
|
|
28165
|
-
intent: "run",
|
|
28166
|
-
source: "dashboard"
|
|
28167
|
-
}
|
|
28168
|
-
};
|
|
28169
|
-
}
|
|
28170
|
-
if (input.mode === "interactive") {
|
|
28171
|
-
const sessionId = typeof input.sessionId === "string" ? input.sessionId.trim() : "";
|
|
28172
|
-
if (!sessionId) return { error: "sessionId required for interactive mode" };
|
|
28173
|
-
return {
|
|
28174
|
-
request: {
|
|
28175
|
-
target: { type: "chat", id: sessionId },
|
|
28176
|
-
intent: "continue",
|
|
28177
|
-
source: "dashboard"
|
|
28178
|
-
}
|
|
28179
|
-
};
|
|
28180
|
-
}
|
|
28181
|
-
if (input.action === "goal-manager" && input.message) {
|
|
28182
|
-
return {
|
|
28183
|
-
request: {
|
|
28184
|
-
target: { type: "goal", id: input.message },
|
|
28185
|
-
intent: "manage",
|
|
28186
|
-
source: "dashboard"
|
|
28187
|
-
}
|
|
28188
|
-
};
|
|
28189
|
-
}
|
|
28190
|
-
if (input.action) {
|
|
28191
|
-
return {
|
|
28192
|
-
request: {
|
|
28193
|
-
target: { type: "workflow", id: input.action },
|
|
28194
|
-
intent: "run",
|
|
28195
|
-
source: "dashboard"
|
|
28196
|
-
}
|
|
28197
|
-
};
|
|
28198
|
-
}
|
|
28199
|
-
return {
|
|
28200
|
-
request: {
|
|
28201
|
-
target: { type: "workflow", id: "scheduled-fanout" },
|
|
28202
|
-
intent: "tick",
|
|
28203
|
-
source: "schedule"
|
|
28204
|
-
}
|
|
28205
|
-
};
|
|
28206
|
-
}
|
|
28207
28123
|
async function poolServe() {
|
|
28208
28124
|
const masterRaw = process.env.KODY_MASTER_KEY?.trim();
|
|
28209
28125
|
if (!masterRaw) throw new Error("KODY_MASTER_KEY required for pool-serve");
|
|
@@ -28401,16 +28317,8 @@ function parseJob(body) {
|
|
|
28401
28317
|
if (!/^[^/\s]+\/[^/\s]+$/.test(repo)) return { error: "repo must be 'owner/name'" };
|
|
28402
28318
|
const githubToken = typeof b.githubToken === "string" ? b.githubToken.trim() : "";
|
|
28403
28319
|
if (!githubToken) return { error: "githubToken required" };
|
|
28404
|
-
|
|
28405
|
-
const
|
|
28406
|
-
const mode = b.mode === "interactive" ? "interactive" : b.mode === "scheduled" ? "scheduled" : "issue";
|
|
28407
|
-
const runRequest = b.runRequest !== void 0 ? parseRunRequest(b.runRequest) : synthesizeLegacyRunRequest({
|
|
28408
|
-
mode,
|
|
28409
|
-
issueNumber: b.issueNumber,
|
|
28410
|
-
sessionId: b.sessionId,
|
|
28411
|
-
action,
|
|
28412
|
-
message
|
|
28413
|
-
});
|
|
28320
|
+
if (b.runRequest === void 0) return { error: "runRequest required" };
|
|
28321
|
+
const runRequest = parseEngineExecutionRequest(b.runRequest);
|
|
28414
28322
|
if ("error" in runRequest) return { error: runRequest.error };
|
|
28415
28323
|
const job = { jobId, repo, githubToken, runRequest: runRequest.request };
|
|
28416
28324
|
if (job.runRequest.target.type === "issue") {
|
|
@@ -28429,57 +28337,6 @@ function parseJob(body) {
|
|
|
28429
28337
|
}
|
|
28430
28338
|
return { job };
|
|
28431
28339
|
}
|
|
28432
|
-
function synthesizeLegacyRunRequest(input) {
|
|
28433
|
-
if (input.mode === "issue") {
|
|
28434
|
-
const issueNumber = Number(input.issueNumber);
|
|
28435
|
-
if (!Number.isInteger(issueNumber) || issueNumber <= 0) {
|
|
28436
|
-
return { error: "issueNumber (positive integer) required for issue mode" };
|
|
28437
|
-
}
|
|
28438
|
-
return {
|
|
28439
|
-
request: {
|
|
28440
|
-
target: { type: "issue", id: issueNumber },
|
|
28441
|
-
intent: "run",
|
|
28442
|
-
source: "dashboard"
|
|
28443
|
-
}
|
|
28444
|
-
};
|
|
28445
|
-
}
|
|
28446
|
-
if (input.mode === "interactive") {
|
|
28447
|
-
const sessionId = typeof input.sessionId === "string" ? input.sessionId.trim() : "";
|
|
28448
|
-
if (!sessionId) return { error: "sessionId required for interactive mode" };
|
|
28449
|
-
return {
|
|
28450
|
-
request: {
|
|
28451
|
-
target: { type: "chat", id: sessionId },
|
|
28452
|
-
intent: "continue",
|
|
28453
|
-
source: "dashboard"
|
|
28454
|
-
}
|
|
28455
|
-
};
|
|
28456
|
-
}
|
|
28457
|
-
if (input.action === "goal-manager" && input.message) {
|
|
28458
|
-
return {
|
|
28459
|
-
request: {
|
|
28460
|
-
target: { type: "goal", id: input.message },
|
|
28461
|
-
intent: "manage",
|
|
28462
|
-
source: "dashboard"
|
|
28463
|
-
}
|
|
28464
|
-
};
|
|
28465
|
-
}
|
|
28466
|
-
if (input.action) {
|
|
28467
|
-
return {
|
|
28468
|
-
request: {
|
|
28469
|
-
target: { type: "workflow", id: input.action },
|
|
28470
|
-
intent: "run",
|
|
28471
|
-
source: "dashboard"
|
|
28472
|
-
}
|
|
28473
|
-
};
|
|
28474
|
-
}
|
|
28475
|
-
return {
|
|
28476
|
-
request: {
|
|
28477
|
-
target: { type: "workflow", id: "scheduled-fanout" },
|
|
28478
|
-
intent: "tick",
|
|
28479
|
-
source: "schedule"
|
|
28480
|
-
}
|
|
28481
|
-
};
|
|
28482
|
-
}
|
|
28483
28340
|
async function defaultRunJob(job) {
|
|
28484
28341
|
const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
|
|
28485
28342
|
const branch = job.ref ?? "main";
|
|
@@ -28619,7 +28476,7 @@ async function runnerServe() {
|
|
|
28619
28476
|
init_config();
|
|
28620
28477
|
init_litellm();
|
|
28621
28478
|
import { spawn as spawn10 } from "child_process";
|
|
28622
|
-
function
|
|
28479
|
+
function parseTarget(positional) {
|
|
28623
28480
|
if (!Array.isArray(positional) || positional.length === 0) return "none";
|
|
28624
28481
|
const first = String(positional[0]).toLowerCase();
|
|
28625
28482
|
if (first === "vscode" || first === "code") return "vscode";
|
|
@@ -28634,7 +28491,7 @@ function buildProxyEnv(url) {
|
|
|
28634
28491
|
};
|
|
28635
28492
|
}
|
|
28636
28493
|
async function serve(opts) {
|
|
28637
|
-
const target =
|
|
28494
|
+
const target = parseTarget(opts.args);
|
|
28638
28495
|
const model = parseProviderModel(opts.config.agent.model);
|
|
28639
28496
|
const usesProxy = needsLitellmProxy(model);
|
|
28640
28497
|
let handle = null;
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
],
|
|
28
28
|
"postflight": []
|
|
29
29
|
},
|
|
30
|
-
"inputs": [
|
|
30
|
+
"inputs": [
|
|
31
|
+
{
|
|
32
|
+
"name": "loop",
|
|
33
|
+
"flag": "--loop",
|
|
34
|
+
"type": "string",
|
|
35
|
+
"required": false,
|
|
36
|
+
"description": "Optional Loop id to run without dispatching other Loops."
|
|
37
|
+
}
|
|
38
|
+
],
|
|
31
39
|
"name": "loop-scheduler"
|
|
32
40
|
}
|
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.468",
|
|
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",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"@actions/cache": "^6.0.0",
|
|
17
17
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
18
18
|
"@kody-ade/agency-domain": "0.5.1",
|
|
19
|
+
"@kody-ade/engine-contracts": "0.1.0",
|
|
19
20
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
20
21
|
"ajv": "^8.18.0",
|
|
21
22
|
"convex": "^1.17.0",
|