@kody-ade/kody-engine 0.4.323 → 0.4.325
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 +449 -90
- 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.325",
|
|
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",
|
|
@@ -6392,6 +6392,224 @@ var init_litellm = __esm({
|
|
|
6392
6392
|
}
|
|
6393
6393
|
});
|
|
6394
6394
|
|
|
6395
|
+
// src/runIndex.ts
|
|
6396
|
+
function upsertRunIndexRow(config, cwd, row) {
|
|
6397
|
+
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
6398
|
+
const current = readStateText(config, cwd, RUN_INDEX_PATH);
|
|
6399
|
+
const next = mergeRunIndexRow(current?.content, row);
|
|
6400
|
+
try {
|
|
6401
|
+
writeStateText(
|
|
6402
|
+
config,
|
|
6403
|
+
cwd,
|
|
6404
|
+
RUN_INDEX_PATH,
|
|
6405
|
+
JSON.stringify(next, null, 2),
|
|
6406
|
+
"chore(runs): update run index",
|
|
6407
|
+
current?.sha
|
|
6408
|
+
);
|
|
6409
|
+
return;
|
|
6410
|
+
} catch (err) {
|
|
6411
|
+
if (!isConflict(err) || attempt === 3) throw err;
|
|
6412
|
+
}
|
|
6413
|
+
}
|
|
6414
|
+
}
|
|
6415
|
+
function upsertRunIndexRowBestEffort(config, cwd, row) {
|
|
6416
|
+
if (!row) return;
|
|
6417
|
+
try {
|
|
6418
|
+
upsertRunIndexRow(config, cwd, row);
|
|
6419
|
+
} catch (err) {
|
|
6420
|
+
process.stderr.write(`[kody runs] index update failed: ${err instanceof Error ? err.message : String(err)}
|
|
6421
|
+
`);
|
|
6422
|
+
}
|
|
6423
|
+
}
|
|
6424
|
+
function mergeRunIndexRow(raw, row) {
|
|
6425
|
+
const parsed = parseRunIndex(raw);
|
|
6426
|
+
const runs = [row, ...parsed.runs.filter((existing) => existing.id !== row.id)].slice(0, MAX_RUNS);
|
|
6427
|
+
return {
|
|
6428
|
+
version: 1,
|
|
6429
|
+
updatedAt: row.updatedAt,
|
|
6430
|
+
runs
|
|
6431
|
+
};
|
|
6432
|
+
}
|
|
6433
|
+
function runIndexRowFromJobContext(input) {
|
|
6434
|
+
const subjectType = runSubjectType(input.data);
|
|
6435
|
+
const subjectId = stringValue2(input.data.runSubjectId);
|
|
6436
|
+
if (!subjectType || !subjectId) return null;
|
|
6437
|
+
const kodyRunId = stringValue2(input.data.jobId) ?? `${input.profileName}-${Date.now()}`;
|
|
6438
|
+
const workflow = stringValue2(input.data.runSubjectWorkflow) ?? stringValue2(input.data.workflowCapability);
|
|
6439
|
+
const title = stringValue2(input.data.runSubjectLabel) ?? subjectId;
|
|
6440
|
+
const githubRunId2 = process.env.GITHUB_RUN_ID?.trim() || void 0;
|
|
6441
|
+
const githubRunAttempt = process.env.GITHUB_RUN_ATTEMPT?.trim() || void 0;
|
|
6442
|
+
const githubRepository = process.env.GITHUB_REPOSITORY?.trim();
|
|
6443
|
+
const githubServer = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
6444
|
+
const triggerKind2 = triggerKindFromEnv();
|
|
6445
|
+
return pruneUndefined({
|
|
6446
|
+
version: 1,
|
|
6447
|
+
id: `${subjectType}:${subjectId}:${kodyRunId}`,
|
|
6448
|
+
subjectType,
|
|
6449
|
+
subjectId,
|
|
6450
|
+
subjectLabel: title,
|
|
6451
|
+
subjectModel: stringValue2(input.data.runSubjectModel) ?? void 0,
|
|
6452
|
+
status: input.status,
|
|
6453
|
+
title,
|
|
6454
|
+
summary: input.reason ?? stringValue2(input.data.workflowStepReason) ?? input.profile.describe,
|
|
6455
|
+
currentStep: stringValue2(input.data.workflowStep) ?? input.profileName,
|
|
6456
|
+
startedAt: input.startedAt,
|
|
6457
|
+
updatedAt: input.updatedAt,
|
|
6458
|
+
kodyRunId,
|
|
6459
|
+
githubRunId: githubRunId2,
|
|
6460
|
+
githubRunAttempt,
|
|
6461
|
+
githubRunUrl: githubRunId2 && githubRepository ? `${githubServer}/${githubRepository}/actions/runs/${githubRunId2}` : void 0,
|
|
6462
|
+
triggerKind: triggerKind2,
|
|
6463
|
+
triggerMode: triggerMode(triggerKind2),
|
|
6464
|
+
actor: process.env.GITHUB_ACTOR?.trim() || void 0,
|
|
6465
|
+
action: stringValue2(input.data.jobAction) ?? void 0,
|
|
6466
|
+
capability: stringValue2(input.data.jobCapability) ?? void 0,
|
|
6467
|
+
workflow: workflow ?? void 0,
|
|
6468
|
+
executable: stringValue2(input.data.jobExecutable) ?? input.profileName,
|
|
6469
|
+
agent: stringValue2(input.data.jobAgent) ?? input.profile.agent ?? void 0,
|
|
6470
|
+
model: stringValue2(input.data.jobModel) ?? void 0,
|
|
6471
|
+
modelProvider: stringValue2(input.data.jobModelProvider) ?? void 0,
|
|
6472
|
+
modelName: stringValue2(input.data.jobModelName) ?? void 0,
|
|
6473
|
+
reasoningEffort: stringValue2(input.data.jobReasoningEffort) ?? void 0,
|
|
6474
|
+
target: input.data.jobTarget,
|
|
6475
|
+
sourceType: "job"
|
|
6476
|
+
});
|
|
6477
|
+
}
|
|
6478
|
+
function runIndexRowFromGoalEvents(goalId, logPath, events) {
|
|
6479
|
+
if (events.length === 0) return null;
|
|
6480
|
+
const first = events[0];
|
|
6481
|
+
const last = events[events.length - 1];
|
|
6482
|
+
const goal = recordValue2(last.goal) ?? recordValue2(first.goal);
|
|
6483
|
+
const goalType = stringValue2(last.goalType) ?? stringValue2(first.goalType) ?? stringValue2(goal?.type);
|
|
6484
|
+
const subjectType = goalType === "agentLoop" ? "loop" : "goal";
|
|
6485
|
+
const run = recordValue2(first.run) ?? recordValue2(last.run);
|
|
6486
|
+
const job = recordValue2(last.job) ?? recordValue2(first.job);
|
|
6487
|
+
const trigger = recordValue2(last.trigger) ?? recordValue2(first.trigger);
|
|
6488
|
+
const links = recordValue2(last.links) ?? recordValue2(first.links);
|
|
6489
|
+
const decision = recordValue2(last.decision);
|
|
6490
|
+
const trace = recordValue2(last.trace);
|
|
6491
|
+
const traceResult = recordValue2(trace?.result);
|
|
6492
|
+
const kodyRunId = stringValue2(run?.id) ?? stringValue2(job?.id) ?? logPath;
|
|
6493
|
+
const updatedAt = stringValue2(last.time) ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
6494
|
+
return pruneUndefined({
|
|
6495
|
+
version: 1,
|
|
6496
|
+
id: `${subjectType}:${goalId}:${kodyRunId}`,
|
|
6497
|
+
subjectType,
|
|
6498
|
+
subjectId: goalId,
|
|
6499
|
+
subjectLabel: goalId,
|
|
6500
|
+
subjectModel: goalType ?? void 0,
|
|
6501
|
+
status: statusFromGoalEvent(last, decision),
|
|
6502
|
+
title: goalId,
|
|
6503
|
+
summary: stringValue2(last.summary) ?? stringValue2(last.reason) ?? stringValue2(traceResult?.summary) ?? stringValue2(last.event) ?? void 0,
|
|
6504
|
+
currentStep: stringValue2(last.stage) ?? stringValue2(goal?.stage) ?? stringValue2(last.event) ?? void 0,
|
|
6505
|
+
decision: [stringValue2(decision?.kind), stringValue2(decision?.reason) ?? stringValue2(last.reason)].filter(Boolean).join(" - ") || void 0,
|
|
6506
|
+
startedAt: stringValue2(first.time) ?? void 0,
|
|
6507
|
+
updatedAt,
|
|
6508
|
+
kodyRunId,
|
|
6509
|
+
githubRunId: stringValue2(run?.githubRunId) ?? void 0,
|
|
6510
|
+
githubRunAttempt: stringValue2(run?.githubRunAttempt) ?? void 0,
|
|
6511
|
+
githubRunUrl: stringValue2(links?.workflowRun) ?? stringValue2(run?.url) ?? void 0,
|
|
6512
|
+
triggerKind: stringValue2(trigger?.kind) ?? void 0,
|
|
6513
|
+
triggerMode: triggerMode(stringValue2(trigger?.kind)),
|
|
6514
|
+
actor: stringValue2(trigger?.githubActor) ?? stringValue2(trigger?.actor) ?? void 0,
|
|
6515
|
+
action: stringValue2(job?.action) ?? void 0,
|
|
6516
|
+
capability: stringValue2(job?.capability) ?? void 0,
|
|
6517
|
+
executable: stringValue2(job?.executable) ?? void 0,
|
|
6518
|
+
agent: stringValue2(job?.agent) ?? void 0,
|
|
6519
|
+
model: stringValue2(job?.model) ?? void 0,
|
|
6520
|
+
modelProvider: stringValue2(job?.modelProvider) ?? void 0,
|
|
6521
|
+
modelName: stringValue2(job?.modelName) ?? void 0,
|
|
6522
|
+
reasoningEffort: stringValue2(job?.reasoningEffort) ?? void 0,
|
|
6523
|
+
target: last.target,
|
|
6524
|
+
sourceType: "goal-run-log",
|
|
6525
|
+
sourcePath: logPath,
|
|
6526
|
+
detailUrl: stringValue2(links?.log) ?? void 0,
|
|
6527
|
+
statePath: stringValue2(recordValue2(last.stateRepo)?.goalStatePath) ?? void 0
|
|
6528
|
+
});
|
|
6529
|
+
}
|
|
6530
|
+
function statusFromExitCode(exitCode) {
|
|
6531
|
+
return exitCode === 0 ? "success" : "failed";
|
|
6532
|
+
}
|
|
6533
|
+
function parseRunIndex(raw) {
|
|
6534
|
+
if (!raw) return { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), runs: [] };
|
|
6535
|
+
try {
|
|
6536
|
+
const parsed = JSON.parse(raw);
|
|
6537
|
+
const record2 = recordValue2(parsed);
|
|
6538
|
+
const runs = Array.isArray(record2?.runs) ? record2.runs.filter(isRunIndexRow).map(normalizeRunIndexRow) : [];
|
|
6539
|
+
return { version: 1, updatedAt: stringValue2(record2?.updatedAt) ?? (/* @__PURE__ */ new Date()).toISOString(), runs };
|
|
6540
|
+
} catch {
|
|
6541
|
+
return { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), runs: [] };
|
|
6542
|
+
}
|
|
6543
|
+
}
|
|
6544
|
+
function isRunIndexRow(value) {
|
|
6545
|
+
const record2 = recordValue2(value);
|
|
6546
|
+
return record2?.version === 1 && isRunSubjectType(record2.subjectType) && typeof record2.subjectId === "string" && typeof record2.id === "string" && typeof record2.status === "string" && typeof record2.title === "string" && typeof record2.updatedAt === "string";
|
|
6547
|
+
}
|
|
6548
|
+
function isRunSubjectType(value) {
|
|
6549
|
+
return value === "goal" || value === "loop" || value === "workflow";
|
|
6550
|
+
}
|
|
6551
|
+
function normalizeRunIndexRow(row) {
|
|
6552
|
+
if (row.status === "running" && (row.decision?.toLowerCase().startsWith("dispatch") || row.summary?.toLowerCase().startsWith("dispatch") || row.currentStep?.toLowerCase().includes("dispatch"))) {
|
|
6553
|
+
return { ...row, status: "waiting" };
|
|
6554
|
+
}
|
|
6555
|
+
return row;
|
|
6556
|
+
}
|
|
6557
|
+
function runSubjectType(data) {
|
|
6558
|
+
const value = data.runSubjectType;
|
|
6559
|
+
return isRunSubjectType(value) ? value : null;
|
|
6560
|
+
}
|
|
6561
|
+
function statusFromGoalEvent(event, decision) {
|
|
6562
|
+
const status = stringValue2(event.status)?.toLowerCase();
|
|
6563
|
+
const eventName = stringValue2(event.event)?.toLowerCase() ?? "";
|
|
6564
|
+
const decisionKind = stringValue2(decision?.kind)?.toLowerCase();
|
|
6565
|
+
if (status === "success" || status === "completed" || decisionKind === "done") return "success";
|
|
6566
|
+
if (status === "failure" || status === "failed" || eventName.includes("fail")) return "failed";
|
|
6567
|
+
if (status === "cancelled") return "cancelled";
|
|
6568
|
+
if (decisionKind === "blocked") return "blocked";
|
|
6569
|
+
if (status === "dispatch" || decisionKind === "dispatch" || eventName.includes("dispatch")) return "waiting";
|
|
6570
|
+
if (status === "running") return "running";
|
|
6571
|
+
return "recorded";
|
|
6572
|
+
}
|
|
6573
|
+
function triggerKindFromEnv() {
|
|
6574
|
+
const eventName = process.env.GITHUB_EVENT_NAME?.trim();
|
|
6575
|
+
if (!eventName) return void 0;
|
|
6576
|
+
if (eventName === "schedule") return "schedule";
|
|
6577
|
+
if (eventName === "workflow_dispatch") return "manual-workflow-dispatch";
|
|
6578
|
+
return eventName;
|
|
6579
|
+
}
|
|
6580
|
+
function triggerMode(kind) {
|
|
6581
|
+
if (!kind) return void 0;
|
|
6582
|
+
if (kind === "schedule") return "scheduled";
|
|
6583
|
+
if (kind === "manual-workflow-dispatch") return "manual";
|
|
6584
|
+
if (kind === "local") return "local";
|
|
6585
|
+
return "event";
|
|
6586
|
+
}
|
|
6587
|
+
function isConflict(err) {
|
|
6588
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6589
|
+
return /HTTP 409/i.test(msg) || /HTTP 422/i.test(msg) || /does not match|is at|but expected/i.test(msg);
|
|
6590
|
+
}
|
|
6591
|
+
function recordValue2(value) {
|
|
6592
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
6593
|
+
}
|
|
6594
|
+
function stringValue2(value) {
|
|
6595
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
6596
|
+
}
|
|
6597
|
+
function pruneUndefined(input) {
|
|
6598
|
+
for (const key of Object.keys(input)) {
|
|
6599
|
+
if (input[key] === void 0) delete input[key];
|
|
6600
|
+
}
|
|
6601
|
+
return input;
|
|
6602
|
+
}
|
|
6603
|
+
var RUN_INDEX_PATH, MAX_RUNS;
|
|
6604
|
+
var init_runIndex = __esm({
|
|
6605
|
+
"src/runIndex.ts"() {
|
|
6606
|
+
"use strict";
|
|
6607
|
+
init_stateRepo();
|
|
6608
|
+
RUN_INDEX_PATH = "runs/index.json";
|
|
6609
|
+
MAX_RUNS = 200;
|
|
6610
|
+
}
|
|
6611
|
+
});
|
|
6612
|
+
|
|
6395
6613
|
// src/pushWithRetry.ts
|
|
6396
6614
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
6397
6615
|
function sleepSync2(ms) {
|
|
@@ -6904,6 +7122,32 @@ function planManagedGoalTick(goal) {
|
|
|
6904
7122
|
goal.nextAction = "done";
|
|
6905
7123
|
return { kind: "done" };
|
|
6906
7124
|
}
|
|
7125
|
+
const workflow = goal.workflowRef;
|
|
7126
|
+
if (workflow) {
|
|
7127
|
+
const workflowStep = { evidence: missing, stage: "workflow", capability: workflow.id };
|
|
7128
|
+
const progressDecision2 = decisionFromEvidenceProgress(goal, workflowStep, missing);
|
|
7129
|
+
if (progressDecision2) return progressDecision2;
|
|
7130
|
+
const resolved2 = resolveWorkflowRefArgs(goal, workflow);
|
|
7131
|
+
if (!resolved2.ok) {
|
|
7132
|
+
goal.stage = "blocked";
|
|
7133
|
+
goal.reason = resolved2.reason;
|
|
7134
|
+
goal.nextAction = "fix workflow args";
|
|
7135
|
+
pushBlocker(goal, resolved2.reason);
|
|
7136
|
+
return { kind: "blocked", evidence: missing, stage: "workflow", reason: resolved2.reason };
|
|
7137
|
+
}
|
|
7138
|
+
goal.stage = "workflow";
|
|
7139
|
+
goal.facts.pendingEvidence = missing;
|
|
7140
|
+
goal.reason = `dispatch workflow ${workflow.id} for ${missing}`;
|
|
7141
|
+
goal.nextAction = "dispatch workflow";
|
|
7142
|
+
return {
|
|
7143
|
+
kind: "dispatchWorkflow",
|
|
7144
|
+
evidence: missing,
|
|
7145
|
+
stage: "workflow",
|
|
7146
|
+
workflow: workflow.id,
|
|
7147
|
+
cliArgs: resolved2.cliArgs,
|
|
7148
|
+
...workflow.saveReport === true ? { saveReport: true } : {}
|
|
7149
|
+
};
|
|
7150
|
+
}
|
|
6907
7151
|
const step = goal.route.find((candidate) => candidate.evidence === missing);
|
|
6908
7152
|
if (!step) {
|
|
6909
7153
|
if (isSimpleGoal(goal) && missing === SIMPLE_GOAL_EVIDENCE) {
|
|
@@ -6959,6 +7203,15 @@ function planManagedGoalTick(goal) {
|
|
|
6959
7203
|
...step.saveReport === true ? { saveReport: true } : {}
|
|
6960
7204
|
};
|
|
6961
7205
|
}
|
|
7206
|
+
function resolveWorkflowRefArgs(goal, workflow) {
|
|
7207
|
+
const step = {
|
|
7208
|
+
evidence: "__workflow__",
|
|
7209
|
+
stage: "workflow",
|
|
7210
|
+
capability: workflow.id,
|
|
7211
|
+
args: workflow.args
|
|
7212
|
+
};
|
|
7213
|
+
return resolveRouteArgs(goal, step);
|
|
7214
|
+
}
|
|
6962
7215
|
function decisionFromEvidenceProgress(goal, step, evidence) {
|
|
6963
7216
|
const progress = goal.evidenceState?.[evidence];
|
|
6964
7217
|
if (!progress) return null;
|
|
@@ -7095,6 +7348,19 @@ function asLoopTarget(value) {
|
|
|
7095
7348
|
if (typeof raw.id !== "string" || raw.id.trim().length === 0) return void 0;
|
|
7096
7349
|
return { type: raw.type, id: raw.id };
|
|
7097
7350
|
}
|
|
7351
|
+
function asWorkflowRef(value) {
|
|
7352
|
+
const raw = asRecord(value);
|
|
7353
|
+
if (!raw) return void 0;
|
|
7354
|
+
if (typeof raw.id !== "string" || raw.id.trim().length === 0) return void 0;
|
|
7355
|
+
const args = raw.args === void 0 ? void 0 : asRecord(raw.args);
|
|
7356
|
+
if (raw.args !== void 0 && !args) return void 0;
|
|
7357
|
+
return {
|
|
7358
|
+
id: raw.id.trim(),
|
|
7359
|
+
...typeof raw.source === "string" && raw.source.trim().length > 0 ? { source: raw.source.trim() } : {},
|
|
7360
|
+
...args ? { args } : {},
|
|
7361
|
+
...raw.saveReport === true ? { saveReport: true } : {}
|
|
7362
|
+
};
|
|
7363
|
+
}
|
|
7098
7364
|
function managedGoalFromState(state) {
|
|
7099
7365
|
const extra = state.extra;
|
|
7100
7366
|
const destination = asRecord(extra.destination);
|
|
@@ -7111,6 +7377,7 @@ function managedGoalFromState(state) {
|
|
|
7111
7377
|
destination: { outcome: destination.outcome, evidence },
|
|
7112
7378
|
capabilities,
|
|
7113
7379
|
route,
|
|
7380
|
+
workflowRef: asWorkflowRef(extra.workflowRef),
|
|
7114
7381
|
schedule: typeof extra.schedule === "string" ? extra.schedule : void 0,
|
|
7115
7382
|
preferredRunTime: asPreferredRunTime(extra.preferredRunTime),
|
|
7116
7383
|
loopTarget: asLoopTarget(extra.loopTarget),
|
|
@@ -7131,6 +7398,7 @@ function writeManagedGoalToState(state, goal) {
|
|
|
7131
7398
|
destination: goal.destination,
|
|
7132
7399
|
capabilities: goal.capabilities,
|
|
7133
7400
|
route: goal.route,
|
|
7401
|
+
workflowRef: goal.workflowRef,
|
|
7134
7402
|
stage: goal.stage,
|
|
7135
7403
|
facts: goal.facts,
|
|
7136
7404
|
blockers: goal.blockers,
|
|
@@ -7220,9 +7488,15 @@ function flushGoalRunLogEvents(config, cwd, data) {
|
|
|
7220
7488
|
const logs = goalRunLogs(data);
|
|
7221
7489
|
for (const [goalId, log2] of Object.entries(logs)) {
|
|
7222
7490
|
if (log2.events.length === 0) continue;
|
|
7223
|
-
const
|
|
7491
|
+
const enrichedEvents = log2.events.map((event) => enrichGoalRunLogEvent(config, data, log2.path, event));
|
|
7492
|
+
const lines = `${enrichedEvents.map((event) => JSON.stringify(event)).join("\n")}
|
|
7224
7493
|
`;
|
|
7225
7494
|
appendStateLine(config, cwd, log2.path, lines, `chore(goal-logs): append ${goalId}`);
|
|
7495
|
+
upsertRunIndexRowBestEffort(
|
|
7496
|
+
config,
|
|
7497
|
+
cwd,
|
|
7498
|
+
runIndexRowFromGoalEvents(goalId, log2.path, enrichedEvents)
|
|
7499
|
+
);
|
|
7226
7500
|
log2.events = [];
|
|
7227
7501
|
}
|
|
7228
7502
|
}
|
|
@@ -7250,6 +7524,7 @@ function goalRunLogSnapshot(goalId, goalState, goal) {
|
|
|
7250
7524
|
pendingEvidence,
|
|
7251
7525
|
capabilities: [...goal.capabilities],
|
|
7252
7526
|
route: goal.route.map(routeStepForLog),
|
|
7527
|
+
workflowRef: goal.workflowRef,
|
|
7253
7528
|
schedule: goal.schedule,
|
|
7254
7529
|
preferredRunTime: goal.preferredRunTime,
|
|
7255
7530
|
loopTarget: goal.loopTarget,
|
|
@@ -7264,8 +7539,8 @@ function goalRunLogChange(before, after) {
|
|
|
7264
7539
|
addScalarChange(change, "state", before.state, after.state);
|
|
7265
7540
|
addScalarChange(change, "stage", before.stage, after.stage);
|
|
7266
7541
|
addScalarChange(change, "pendingEvidence", before.pendingEvidence, after.pendingEvidence);
|
|
7267
|
-
const beforeFacts =
|
|
7268
|
-
const afterFacts =
|
|
7542
|
+
const beforeFacts = recordValue3(before.facts);
|
|
7543
|
+
const afterFacts = recordValue3(after.facts);
|
|
7269
7544
|
if (beforeFacts || afterFacts) change.facts = diffRecordKeys(beforeFacts ?? {}, afterFacts ?? {});
|
|
7270
7545
|
const beforeBlockers = stringArrayValue(before.blockers);
|
|
7271
7546
|
const afterBlockers = stringArrayValue(after.blockers);
|
|
@@ -7279,8 +7554,8 @@ function goalRunLogChange(before, after) {
|
|
|
7279
7554
|
const evidence = diffStringArrays(beforeSatisfied ?? [], afterSatisfied ?? []);
|
|
7280
7555
|
if (evidence.added.length > 0 || evidence.removed.length > 0) change.satisfiedEvidence = evidence;
|
|
7281
7556
|
}
|
|
7282
|
-
const beforeEvidenceState =
|
|
7283
|
-
const afterEvidenceState =
|
|
7557
|
+
const beforeEvidenceState = recordValue3(before.evidenceState);
|
|
7558
|
+
const afterEvidenceState = recordValue3(after.evidenceState);
|
|
7284
7559
|
if (beforeEvidenceState || afterEvidenceState) {
|
|
7285
7560
|
change.evidenceState = diffRecordKeys(beforeEvidenceState ?? {}, afterEvidenceState ?? {});
|
|
7286
7561
|
}
|
|
@@ -7305,7 +7580,7 @@ function goalRunStartedAt(data) {
|
|
|
7305
7580
|
function goalRunId(data) {
|
|
7306
7581
|
const existing = data[LOG_RUN_KEY];
|
|
7307
7582
|
if (typeof existing === "string" && existing.length > 0) return existing;
|
|
7308
|
-
const raw =
|
|
7583
|
+
const raw = stringValue3(data.jobId) ?? githubRunId() ?? `local-${process.pid}-${Date.now()}`;
|
|
7309
7584
|
const safe = safePathSegment(raw);
|
|
7310
7585
|
data[LOG_RUN_KEY] = safe;
|
|
7311
7586
|
return safe;
|
|
@@ -7337,7 +7612,7 @@ function enrichGoalRunLogEvent(config, data, logPath, event) {
|
|
|
7337
7612
|
const job = event.job ?? jobContext(data);
|
|
7338
7613
|
const run = event.run ?? runContext(data);
|
|
7339
7614
|
const links = event.links ?? linkContext(stateRepo);
|
|
7340
|
-
const enriched =
|
|
7615
|
+
const enriched = pruneUndefined2({
|
|
7341
7616
|
...event,
|
|
7342
7617
|
run,
|
|
7343
7618
|
repo: event.repo ?? repoContext(config),
|
|
@@ -7351,23 +7626,23 @@ function enrichGoalRunLogEvent(config, data, logPath, event) {
|
|
|
7351
7626
|
return enriched;
|
|
7352
7627
|
}
|
|
7353
7628
|
function goalRunTrace(event) {
|
|
7354
|
-
const run =
|
|
7355
|
-
const trigger =
|
|
7356
|
-
const goal =
|
|
7357
|
-
const inspection =
|
|
7358
|
-
const capabilityOutput =
|
|
7359
|
-
return
|
|
7629
|
+
const run = recordValue3(event.run);
|
|
7630
|
+
const trigger = recordValue3(event.trigger);
|
|
7631
|
+
const goal = recordValue3(event.goal);
|
|
7632
|
+
const inspection = recordValue3(event.inspection);
|
|
7633
|
+
const capabilityOutput = recordValue3(inspection?.capabilityOutput);
|
|
7634
|
+
return pruneUndefined2({
|
|
7360
7635
|
version: 1,
|
|
7361
|
-
runId:
|
|
7362
|
-
workflowRunId:
|
|
7363
|
-
triggerKind:
|
|
7636
|
+
runId: stringValue3(run?.id) ?? void 0,
|
|
7637
|
+
workflowRunId: stringValue3(run?.githubRunId) ?? void 0,
|
|
7638
|
+
triggerKind: stringValue3(trigger?.kind) ?? void 0,
|
|
7364
7639
|
source: event.source,
|
|
7365
7640
|
event: event.event,
|
|
7366
|
-
goal:
|
|
7641
|
+
goal: pruneUndefined2({
|
|
7367
7642
|
id: event.goalId,
|
|
7368
|
-
type: event.goalType ??
|
|
7369
|
-
state: event.goalState ??
|
|
7370
|
-
stage: event.stage ??
|
|
7643
|
+
type: event.goalType ?? stringValue3(goal?.type) ?? void 0,
|
|
7644
|
+
state: event.goalState ?? stringValue3(goal?.state) ?? void 0,
|
|
7645
|
+
stage: event.stage ?? stringValue3(goal?.stage) ?? void 0
|
|
7371
7646
|
}),
|
|
7372
7647
|
evidence: goalTraceEvidence(event, goal, inspection),
|
|
7373
7648
|
capability: event.dispatch ?? capabilityDispatchFromOutput(capabilityOutput),
|
|
@@ -7377,30 +7652,30 @@ function goalRunTrace(event) {
|
|
|
7377
7652
|
});
|
|
7378
7653
|
}
|
|
7379
7654
|
function goalTraceEvidence(event, goal, inspection) {
|
|
7380
|
-
const expectedEvidence =
|
|
7381
|
-
const out =
|
|
7655
|
+
const expectedEvidence = recordValue3(inspection?.expectedEvidence);
|
|
7656
|
+
const out = pruneUndefined2({
|
|
7382
7657
|
current: event.evidence,
|
|
7383
7658
|
required: stringArrayValue(goal?.requiredEvidence) ?? stringArrayValue(inspection?.requiredEvidence) ?? void 0,
|
|
7384
7659
|
satisfied: stringArrayValue(goal?.satisfiedEvidence) ?? stringArrayValue(inspection?.satisfiedEvidence) ?? void 0,
|
|
7385
7660
|
missing: stringArrayValue(goal?.missingEvidence) ?? stringArrayValue(inspection?.missingEvidence) ?? stringArrayValue(expectedEvidence?.missingBefore) ?? void 0,
|
|
7386
|
-
pending:
|
|
7661
|
+
pending: stringValue3(goal?.pendingEvidence) ?? stringValue3(inspection?.pendingEvidence) ?? stringValue3(expectedEvidence?.pendingBefore) ?? void 0,
|
|
7387
7662
|
values: event.evidenceValues
|
|
7388
7663
|
});
|
|
7389
7664
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
7390
7665
|
}
|
|
7391
7666
|
function capabilityDispatchFromOutput(output) {
|
|
7392
7667
|
if (!output) return void 0;
|
|
7393
|
-
const dispatch2 =
|
|
7394
|
-
capability:
|
|
7395
|
-
executable:
|
|
7396
|
-
action:
|
|
7668
|
+
const dispatch2 = pruneUndefined2({
|
|
7669
|
+
capability: stringValue3(output.capability) ?? void 0,
|
|
7670
|
+
executable: stringValue3(output.executable) ?? void 0,
|
|
7671
|
+
action: stringValue3(output.action) ?? void 0
|
|
7397
7672
|
});
|
|
7398
7673
|
return Object.keys(dispatch2).length > 0 ? dispatch2 : void 0;
|
|
7399
7674
|
}
|
|
7400
7675
|
function goalTraceResult(event, capabilityOutput) {
|
|
7401
|
-
const result =
|
|
7402
|
-
status: event.status ??
|
|
7403
|
-
summary: event.reason ??
|
|
7676
|
+
const result = pruneUndefined2({
|
|
7677
|
+
status: event.status ?? stringValue3(capabilityOutput?.status) ?? void 0,
|
|
7678
|
+
summary: event.reason ?? stringValue3(capabilityOutput?.summary) ?? void 0,
|
|
7404
7679
|
blockers: event.inspection ? stringArrayValue(capabilityOutput?.blockers) ?? void 0 : void 0,
|
|
7405
7680
|
artifacts: event.artifacts
|
|
7406
7681
|
});
|
|
@@ -7411,7 +7686,7 @@ function runContext(data) {
|
|
|
7411
7686
|
const attempt = process.env.GITHUB_RUN_ATTEMPT?.trim();
|
|
7412
7687
|
const repository = process.env.GITHUB_REPOSITORY?.trim();
|
|
7413
7688
|
const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
7414
|
-
return
|
|
7689
|
+
return pruneUndefined2({
|
|
7415
7690
|
id: goalRunId(data),
|
|
7416
7691
|
provider: runId ? "github-actions" : "local",
|
|
7417
7692
|
githubRunId: runId || void 0,
|
|
@@ -7425,7 +7700,7 @@ function runContext(data) {
|
|
|
7425
7700
|
function repoContext(config) {
|
|
7426
7701
|
const owner = config.github?.owner;
|
|
7427
7702
|
const repo = config.github?.repo;
|
|
7428
|
-
return
|
|
7703
|
+
return pruneUndefined2({
|
|
7429
7704
|
owner,
|
|
7430
7705
|
repo,
|
|
7431
7706
|
fullName: owner && repo ? `${owner}/${repo}` : process.env.GITHUB_REPOSITORY?.trim() || void 0,
|
|
@@ -7449,11 +7724,11 @@ function stateRepoContext(config, goalId, logPath) {
|
|
|
7449
7724
|
}
|
|
7450
7725
|
function triggerContext() {
|
|
7451
7726
|
const event = readGithubEvent();
|
|
7452
|
-
const inputs =
|
|
7727
|
+
const inputs = recordValue3(event?.inputs);
|
|
7453
7728
|
const eventName = process.env.GITHUB_EVENT_NAME?.trim() || void 0;
|
|
7454
7729
|
const githubActor = process.env.GITHUB_ACTOR?.trim() || void 0;
|
|
7455
7730
|
if (!eventName && !githubActor && !process.env.GITHUB_EVENT_PATH) return void 0;
|
|
7456
|
-
const trigger =
|
|
7731
|
+
const trigger = pruneUndefined2({
|
|
7457
7732
|
source: eventName ? "github-actions" : "local",
|
|
7458
7733
|
kind: triggerKind(eventName),
|
|
7459
7734
|
eventName,
|
|
@@ -7461,10 +7736,10 @@ function triggerContext() {
|
|
|
7461
7736
|
githubActor,
|
|
7462
7737
|
actorRole: triggerActorRole(eventName),
|
|
7463
7738
|
eventPath: process.env.GITHUB_EVENT_PATH?.trim() || void 0,
|
|
7464
|
-
issue: numberValue(
|
|
7465
|
-
pullRequest: numberValue(
|
|
7466
|
-
comment: numberValue(
|
|
7467
|
-
schedule:
|
|
7739
|
+
issue: numberValue(recordValue3(event?.issue)?.number),
|
|
7740
|
+
pullRequest: numberValue(recordValue3(event?.pull_request)?.number),
|
|
7741
|
+
comment: numberValue(recordValue3(event?.comment)?.id),
|
|
7742
|
+
schedule: stringValue3(event?.schedule),
|
|
7468
7743
|
inputs: inputs ? pickRecord(inputs, ["issue_number", "sessionId", "message", "model", "title", "executable", "base"]) : void 0
|
|
7469
7744
|
});
|
|
7470
7745
|
return Object.keys(trigger).length > 0 ? trigger : void 0;
|
|
@@ -7482,17 +7757,21 @@ function triggerActorRole(eventName) {
|
|
|
7482
7757
|
return "github event actor";
|
|
7483
7758
|
}
|
|
7484
7759
|
function jobContext(data) {
|
|
7485
|
-
const job =
|
|
7486
|
-
id:
|
|
7487
|
-
key:
|
|
7488
|
-
flavor:
|
|
7489
|
-
action:
|
|
7490
|
-
capability:
|
|
7491
|
-
executable:
|
|
7492
|
-
agent:
|
|
7493
|
-
schedule:
|
|
7760
|
+
const job = pruneUndefined2({
|
|
7761
|
+
id: stringValue3(data.jobId) ?? void 0,
|
|
7762
|
+
key: stringValue3(data.jobKey) ?? void 0,
|
|
7763
|
+
flavor: stringValue3(data.jobFlavor) ?? void 0,
|
|
7764
|
+
action: stringValue3(data.jobAction) ?? void 0,
|
|
7765
|
+
capability: stringValue3(data.jobCapability) ?? void 0,
|
|
7766
|
+
executable: stringValue3(data.jobExecutable) ?? void 0,
|
|
7767
|
+
agent: stringValue3(data.jobAgent) ?? void 0,
|
|
7768
|
+
schedule: stringValue3(data.jobSchedule) ?? void 0,
|
|
7494
7769
|
target: data.jobTarget ?? void 0,
|
|
7495
|
-
|
|
7770
|
+
model: stringValue3(data.jobModel) ?? void 0,
|
|
7771
|
+
modelProvider: stringValue3(data.jobModelProvider) ?? void 0,
|
|
7772
|
+
modelName: stringValue3(data.jobModelName) ?? void 0,
|
|
7773
|
+
reasoningEffort: stringValue3(data.jobReasoningEffort) ?? void 0,
|
|
7774
|
+
why: truncateString(stringValue3(data.jobWhy), 1e3),
|
|
7496
7775
|
saveReport: data.jobSaveReport === true ? true : void 0
|
|
7497
7776
|
});
|
|
7498
7777
|
return Object.keys(job).length > 0 ? job : void 0;
|
|
@@ -7500,23 +7779,23 @@ function jobContext(data) {
|
|
|
7500
7779
|
function dispatchContext(event, trigger, job) {
|
|
7501
7780
|
if (!event.dispatch && event.status !== "dispatch") return void 0;
|
|
7502
7781
|
const dispatch2 = event.dispatch ?? {};
|
|
7503
|
-
const context =
|
|
7782
|
+
const context = pruneUndefined2({
|
|
7504
7783
|
triggeredBy: triggerLabel(trigger),
|
|
7505
|
-
triggerKind:
|
|
7784
|
+
triggerKind: stringValue3(trigger?.kind),
|
|
7506
7785
|
dispatchMode: dispatchMode(trigger),
|
|
7507
|
-
githubActor:
|
|
7508
|
-
githubActorRole:
|
|
7786
|
+
githubActor: stringValue3(trigger?.githubActor) ?? stringValue3(trigger?.actor),
|
|
7787
|
+
githubActorRole: stringValue3(trigger?.actorRole),
|
|
7509
7788
|
decidedBy: event.source,
|
|
7510
7789
|
dispatchedBy: event.source,
|
|
7511
7790
|
target: event.target,
|
|
7512
|
-
action: dispatch2.action ??
|
|
7513
|
-
capability: dispatch2.capability ??
|
|
7791
|
+
action: dispatch2.action ?? stringValue3(job?.action),
|
|
7792
|
+
capability: dispatch2.capability ?? stringValue3(job?.capability),
|
|
7514
7793
|
reason: event.reason
|
|
7515
7794
|
});
|
|
7516
7795
|
return Object.keys(context).length > 0 ? context : void 0;
|
|
7517
7796
|
}
|
|
7518
7797
|
function triggerLabel(trigger) {
|
|
7519
|
-
const kind =
|
|
7798
|
+
const kind = stringValue3(trigger?.kind);
|
|
7520
7799
|
if (kind === "schedule") return "GitHub schedule";
|
|
7521
7800
|
if (kind === "manual-workflow-dispatch") return "manual workflow dispatch";
|
|
7522
7801
|
if (kind === "issue_comment") return "GitHub issue comment";
|
|
@@ -7525,7 +7804,7 @@ function triggerLabel(trigger) {
|
|
|
7525
7804
|
return "local run";
|
|
7526
7805
|
}
|
|
7527
7806
|
function dispatchMode(trigger) {
|
|
7528
|
-
const kind =
|
|
7807
|
+
const kind = stringValue3(trigger?.kind);
|
|
7529
7808
|
if (kind === "schedule") return "automated";
|
|
7530
7809
|
if (kind === "manual-workflow-dispatch") return "manual";
|
|
7531
7810
|
if (kind) return "event-driven";
|
|
@@ -7537,10 +7816,10 @@ function linkContext(stateRepo) {
|
|
|
7537
7816
|
const repository = process.env.GITHUB_REPOSITORY?.trim();
|
|
7538
7817
|
const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
7539
7818
|
if (runId && repository) links.workflowRun = `${server}/${repository}/actions/runs/${runId}`;
|
|
7540
|
-
const repo =
|
|
7541
|
-
const branch =
|
|
7542
|
-
const goalStatePath2 =
|
|
7543
|
-
const logPath =
|
|
7819
|
+
const repo = stringValue3(stateRepo?.repo);
|
|
7820
|
+
const branch = stringValue3(stateRepo?.branch);
|
|
7821
|
+
const goalStatePath2 = stringValue3(stateRepo?.goalStatePath);
|
|
7822
|
+
const logPath = stringValue3(stateRepo?.logPath);
|
|
7544
7823
|
if (repo && branch && goalStatePath2) links.goalState = githubBlobUrl(repo, branch, goalStatePath2);
|
|
7545
7824
|
if (repo && branch && logPath) links.log = githubBlobUrl(repo, branch, logPath);
|
|
7546
7825
|
return Object.keys(links).length > 0 ? links : void 0;
|
|
@@ -7554,7 +7833,7 @@ function githubBlobUrl(repo, branch, filePath) {
|
|
|
7554
7833
|
}
|
|
7555
7834
|
}
|
|
7556
7835
|
function routeStepForLog(step) {
|
|
7557
|
-
return
|
|
7836
|
+
return pruneUndefined2({
|
|
7558
7837
|
evidence: step.evidence,
|
|
7559
7838
|
stage: step.stage,
|
|
7560
7839
|
capability: step.capability,
|
|
@@ -7569,14 +7848,14 @@ function readGithubEvent() {
|
|
|
7569
7848
|
try {
|
|
7570
7849
|
if (!fs25.existsSync(eventPath)) return null;
|
|
7571
7850
|
const parsed = JSON.parse(fs25.readFileSync(eventPath, "utf-8"));
|
|
7572
|
-
return
|
|
7851
|
+
return recordValue3(parsed);
|
|
7573
7852
|
} catch {
|
|
7574
7853
|
return null;
|
|
7575
7854
|
}
|
|
7576
7855
|
}
|
|
7577
7856
|
function addScalarChange(change, field, before, after) {
|
|
7578
7857
|
if (before === after) return;
|
|
7579
|
-
change[field] =
|
|
7858
|
+
change[field] = pruneUndefined2({ from: before, to: after });
|
|
7580
7859
|
}
|
|
7581
7860
|
function diffRecordKeys(before, after) {
|
|
7582
7861
|
const beforeKeys = new Set(Object.keys(before));
|
|
@@ -7594,7 +7873,7 @@ function diffStringArrays(before, after) {
|
|
|
7594
7873
|
removed: before.filter((item) => !afterSet.has(item)).sort()
|
|
7595
7874
|
};
|
|
7596
7875
|
}
|
|
7597
|
-
function
|
|
7876
|
+
function recordValue3(value) {
|
|
7598
7877
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
7599
7878
|
}
|
|
7600
7879
|
function stringArrayValue(value) {
|
|
@@ -7610,7 +7889,7 @@ function pickRecord(input, keys) {
|
|
|
7610
7889
|
}
|
|
7611
7890
|
return out;
|
|
7612
7891
|
}
|
|
7613
|
-
function
|
|
7892
|
+
function pruneUndefined2(input) {
|
|
7614
7893
|
for (const key of Object.keys(input)) {
|
|
7615
7894
|
if (input[key] === void 0) delete input[key];
|
|
7616
7895
|
}
|
|
@@ -7620,7 +7899,7 @@ function truncateString(value, max) {
|
|
|
7620
7899
|
if (!value) return void 0;
|
|
7621
7900
|
return value.length > max ? `${value.slice(0, max)}...` : value;
|
|
7622
7901
|
}
|
|
7623
|
-
function
|
|
7902
|
+
function stringValue3(value) {
|
|
7624
7903
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
7625
7904
|
}
|
|
7626
7905
|
function safePathSegment(value) {
|
|
@@ -7632,6 +7911,7 @@ var init_runLog = __esm({
|
|
|
7632
7911
|
"src/goal/runLog.ts"() {
|
|
7633
7912
|
"use strict";
|
|
7634
7913
|
init_stateRepo();
|
|
7914
|
+
init_runIndex();
|
|
7635
7915
|
init_state2();
|
|
7636
7916
|
LOGS_KEY = "__goalRunLogs";
|
|
7637
7917
|
LOG_RUN_KEY = "__goalRunLogRunId";
|
|
@@ -8824,7 +9104,7 @@ var init_goalCapabilityScheduling = __esm({
|
|
|
8824
9104
|
|
|
8825
9105
|
// src/scripts/advanceManagedGoal.ts
|
|
8826
9106
|
function stageManagedGoalDecision(data, goalId, goal, goalState, decision, details) {
|
|
8827
|
-
if (decision.kind === "dispatch") {
|
|
9107
|
+
if (decision.kind === "dispatch" || decision.kind === "dispatchWorkflow") {
|
|
8828
9108
|
stageGoalRunLogEvent(data, goalId, {
|
|
8829
9109
|
source: "goal-manager",
|
|
8830
9110
|
event: "goal.tick.dispatch",
|
|
@@ -8833,14 +9113,23 @@ function stageManagedGoalDecision(data, goalId, goal, goalState, decision, detai
|
|
|
8833
9113
|
stage: decision.stage,
|
|
8834
9114
|
evidence: decision.evidence,
|
|
8835
9115
|
status: decision.kind,
|
|
8836
|
-
dispatch: {
|
|
9116
|
+
dispatch: decision.kind === "dispatchWorkflow" ? {
|
|
9117
|
+
workflow: decision.workflow,
|
|
9118
|
+
cliArgs: decision.cliArgs
|
|
9119
|
+
} : {
|
|
8837
9120
|
capability: decision.capability,
|
|
8838
9121
|
cliArgs: decision.cliArgs,
|
|
8839
9122
|
...decision.executable ? { executable: decision.executable } : {}
|
|
8840
9123
|
},
|
|
8841
9124
|
goal: details.goalSnapshot,
|
|
8842
9125
|
inspection: details.inspection,
|
|
8843
|
-
decision: {
|
|
9126
|
+
decision: decision.kind === "dispatchWorkflow" ? {
|
|
9127
|
+
kind: decision.kind,
|
|
9128
|
+
evidence: decision.evidence,
|
|
9129
|
+
stage: decision.stage,
|
|
9130
|
+
workflow: decision.workflow,
|
|
9131
|
+
cliArgs: decision.cliArgs
|
|
9132
|
+
} : {
|
|
8844
9133
|
kind: decision.kind,
|
|
8845
9134
|
evidence: decision.evidence,
|
|
8846
9135
|
stage: decision.stage,
|
|
@@ -8923,7 +9212,7 @@ function previousDispatchWasTargetInstance(managed, previousScheduleState) {
|
|
|
8923
9212
|
return previous.targetId === targetId || previous.targetId.startsWith(`${targetId}-`);
|
|
8924
9213
|
}
|
|
8925
9214
|
function ensureIssueFactIfNeeded(goal, goalId, cwd) {
|
|
8926
|
-
if (!routeNeedsIssueFact(goal)) return;
|
|
9215
|
+
if (!routeNeedsIssueFact(goal) && !workflowNeedsIssueFact(goal)) return;
|
|
8927
9216
|
const existing = normalizeIssueNumber(goal.facts.issue);
|
|
8928
9217
|
if (existing !== null) {
|
|
8929
9218
|
goal.facts.issue = existing;
|
|
@@ -8940,6 +9229,14 @@ function routeNeedsIssueFact(goal) {
|
|
|
8940
9229
|
})
|
|
8941
9230
|
);
|
|
8942
9231
|
}
|
|
9232
|
+
function workflowNeedsIssueFact(goal) {
|
|
9233
|
+
return Object.values(goal.workflowRef?.args ?? {}).some(isIssueFactReference);
|
|
9234
|
+
}
|
|
9235
|
+
function isIssueFactReference(value) {
|
|
9236
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
9237
|
+
const record2 = value;
|
|
9238
|
+
return Object.keys(record2).length === 1 && record2.fact === "issue";
|
|
9239
|
+
}
|
|
8943
9240
|
function normalizeIssueNumber(value) {
|
|
8944
9241
|
if (typeof value === "number" && Number.isInteger(value) && value > 0) return value;
|
|
8945
9242
|
if (typeof value === "string" && /^\d+$/.test(value)) return Number(value);
|
|
@@ -9202,6 +9499,16 @@ var init_advanceManagedGoal = __esm({
|
|
|
9202
9499
|
ctx.output.reason = decision.kind === "done" ? "managed goal complete" : decision.reason;
|
|
9203
9500
|
return;
|
|
9204
9501
|
}
|
|
9502
|
+
if (decision.kind === "dispatchWorkflow") {
|
|
9503
|
+
ctx.output.nextDispatch = {
|
|
9504
|
+
workflow: decision.workflow,
|
|
9505
|
+
cliArgs: decision.cliArgs,
|
|
9506
|
+
...decision.saveReport === true ? { saveReport: true } : {},
|
|
9507
|
+
resultTarget: { type: "goal", id: goal.id }
|
|
9508
|
+
};
|
|
9509
|
+
ctx.output.reason = `dispatch workflow ${decision.workflow} for ${decision.evidence}`;
|
|
9510
|
+
return;
|
|
9511
|
+
}
|
|
9205
9512
|
ctx.output.nextDispatch = {
|
|
9206
9513
|
capability: decision.capability,
|
|
9207
9514
|
cliArgs: decision.cliArgs,
|
|
@@ -14180,7 +14487,7 @@ var init_keys = __esm({
|
|
|
14180
14487
|
// src/stateRepoGithub.ts
|
|
14181
14488
|
import * as fs38 from "fs";
|
|
14182
14489
|
import * as path36 from "path";
|
|
14183
|
-
function
|
|
14490
|
+
function recordValue4(value) {
|
|
14184
14491
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
14185
14492
|
}
|
|
14186
14493
|
function contentsUrl(owner, repo, filePath) {
|
|
@@ -14236,12 +14543,12 @@ async function loadGithubStateConfig(opts) {
|
|
|
14236
14543
|
throw new Error(`kody.config.json is invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
14237
14544
|
}
|
|
14238
14545
|
}
|
|
14239
|
-
const githubRaw =
|
|
14546
|
+
const githubRaw = recordValue4(raw.github) ?? {};
|
|
14240
14547
|
const github = {
|
|
14241
14548
|
owner: typeof githubRaw.owner === "string" && githubRaw.owner.trim() ? githubRaw.owner.trim() : opts.owner,
|
|
14242
14549
|
repo: typeof githubRaw.repo === "string" && githubRaw.repo.trim() ? githubRaw.repo.trim() : opts.repo
|
|
14243
14550
|
};
|
|
14244
|
-
const nestedState =
|
|
14551
|
+
const nestedState = recordValue4(raw.state) ?? {};
|
|
14245
14552
|
const repoRaw = typeof raw.stateRepo === "string" ? raw.stateRepo : nestedState.repo;
|
|
14246
14553
|
const pathRaw = typeof raw.statePath === "string" ? raw.statePath : nestedState.path;
|
|
14247
14554
|
const stateRepo = typeof repoRaw === "string" && repoRaw.trim().length > 0 ? repoRaw.trim() : `https://github.com/${github.owner}/kody-state`;
|
|
@@ -19040,8 +19347,10 @@ function jobReferenceBlock(profileName, profile, data) {
|
|
|
19040
19347
|
}
|
|
19041
19348
|
async function runExecutable(profileName, input) {
|
|
19042
19349
|
const stageStartedAt = Date.now();
|
|
19350
|
+
let finishRunIndex = null;
|
|
19043
19351
|
emitEvent(input.cwd, { executable: profileName, kind: "stage_start" });
|
|
19044
19352
|
const finishAndEnd = (out) => {
|
|
19353
|
+
finishRunIndex?.(out);
|
|
19045
19354
|
emitEvent(input.cwd, {
|
|
19046
19355
|
executable: profileName,
|
|
19047
19356
|
kind: "stage_end",
|
|
@@ -19126,6 +19435,41 @@ async function runExecutable(profileName, input) {
|
|
|
19126
19435
|
data: { ...input.preloadedData ?? {} },
|
|
19127
19436
|
output: { exitCode: 0 }
|
|
19128
19437
|
};
|
|
19438
|
+
ctx.data.jobModel = modelSpec;
|
|
19439
|
+
ctx.data.jobModelProvider = model.provider;
|
|
19440
|
+
ctx.data.jobModelName = model.model;
|
|
19441
|
+
if (reasoningEffort) ctx.data.jobReasoningEffort = reasoningEffort;
|
|
19442
|
+
const runIndexStartedAt = new Date(stageStartedAt).toISOString();
|
|
19443
|
+
if (!input.skipConfig) {
|
|
19444
|
+
upsertRunIndexRowBestEffort(
|
|
19445
|
+
config,
|
|
19446
|
+
input.cwd,
|
|
19447
|
+
runIndexRowFromJobContext({
|
|
19448
|
+
data: ctx.data,
|
|
19449
|
+
profileName,
|
|
19450
|
+
profile,
|
|
19451
|
+
status: "running",
|
|
19452
|
+
startedAt: runIndexStartedAt,
|
|
19453
|
+
updatedAt: runIndexStartedAt
|
|
19454
|
+
})
|
|
19455
|
+
);
|
|
19456
|
+
finishRunIndex = (out) => {
|
|
19457
|
+
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19458
|
+
upsertRunIndexRowBestEffort(
|
|
19459
|
+
config,
|
|
19460
|
+
input.cwd,
|
|
19461
|
+
runIndexRowFromJobContext({
|
|
19462
|
+
data: ctx.data,
|
|
19463
|
+
profileName,
|
|
19464
|
+
profile,
|
|
19465
|
+
status: statusFromExitCode(out.exitCode),
|
|
19466
|
+
startedAt: runIndexStartedAt,
|
|
19467
|
+
updatedAt: finishedAt,
|
|
19468
|
+
reason: out.reason
|
|
19469
|
+
})
|
|
19470
|
+
);
|
|
19471
|
+
};
|
|
19472
|
+
}
|
|
19129
19473
|
const taskTarget = args.issue ?? args.pr;
|
|
19130
19474
|
const taskArtifacts = typeof taskTarget === "number" && Number.isFinite(taskTarget) ? (() => {
|
|
19131
19475
|
const taskType = args.issue ? "issue" : "pr";
|
|
@@ -19820,6 +20164,7 @@ var init_executor = __esm({
|
|
|
19820
20164
|
init_litellm();
|
|
19821
20165
|
init_profile();
|
|
19822
20166
|
init_registry();
|
|
20167
|
+
init_runIndex();
|
|
19823
20168
|
init_runtimePaths();
|
|
19824
20169
|
init_scripts();
|
|
19825
20170
|
init_stateWorkspace();
|
|
@@ -20095,6 +20440,10 @@ function shouldRunCapabilityWorkflow(job, workflow, capabilityIdentity, selected
|
|
|
20095
20440
|
async function runCapabilityWorkflow(parent, workflow, capability, base) {
|
|
20096
20441
|
let chainData = {
|
|
20097
20442
|
...base.preloadedData ?? {},
|
|
20443
|
+
runSubjectType: "workflow",
|
|
20444
|
+
runSubjectId: capability.slug,
|
|
20445
|
+
runSubjectLabel: capability.title,
|
|
20446
|
+
runSubjectWorkflow: capability.slug,
|
|
20098
20447
|
workflowCapability: capability.slug,
|
|
20099
20448
|
workflowTitle: capability.title,
|
|
20100
20449
|
workflowStepCount: workflow.steps.length,
|
|
@@ -22655,6 +23004,10 @@ function emitSse(res, event) {
|
|
|
22655
23004
|
|
|
22656
23005
|
`);
|
|
22657
23006
|
}
|
|
23007
|
+
function openSseStream(res, chatId) {
|
|
23008
|
+
writeSseHeaders(res);
|
|
23009
|
+
emitSse(res, { type: "chat", chatId });
|
|
23010
|
+
}
|
|
22658
23011
|
function envGithubToken() {
|
|
22659
23012
|
return (process.env.KODY_TOKEN ?? process.env.GH_TOKEN ?? process.env.GITHUB_TOKEN ?? process.env.GH_PAT ?? "").trim();
|
|
22660
23013
|
}
|
|
@@ -22664,16 +23017,6 @@ function parseRepoSlug(repo) {
|
|
|
22664
23017
|
if (!owner || !name) return null;
|
|
22665
23018
|
return { owner, repo: name };
|
|
22666
23019
|
}
|
|
22667
|
-
function streamStartupError(res, dir, chatId, err) {
|
|
22668
|
-
const sinceFloor = getLastSeq(dir, chatId);
|
|
22669
|
-
const emitToLog = beginTurn(dir, chatId);
|
|
22670
|
-
emitToLog({
|
|
22671
|
-
type: "error",
|
|
22672
|
-
chatId,
|
|
22673
|
-
error: err instanceof Error ? err.message : String(err)
|
|
22674
|
-
});
|
|
22675
|
-
streamToRes(res, dir, chatId, sinceFloor);
|
|
22676
|
-
}
|
|
22677
23020
|
function translateChatEvent(event, chatId) {
|
|
22678
23021
|
switch (event.event) {
|
|
22679
23022
|
case "chat.message": {
|
|
@@ -22727,9 +23070,10 @@ function enqueue(chatId, fn) {
|
|
|
22727
23070
|
);
|
|
22728
23071
|
return next;
|
|
22729
23072
|
}
|
|
22730
|
-
function streamToRes(res, dir, chatId, since) {
|
|
22731
|
-
|
|
22732
|
-
|
|
23073
|
+
function streamToRes(res, dir, chatId, since, opts = {}) {
|
|
23074
|
+
if (!opts.opened) {
|
|
23075
|
+
openSseStream(res, chatId);
|
|
23076
|
+
}
|
|
22733
23077
|
let maxSent = since;
|
|
22734
23078
|
const unsubscribe = subscribe(
|
|
22735
23079
|
dir,
|
|
@@ -22773,7 +23117,17 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22773
23117
|
const storeRepoUrl = strField(body, "storeRepoUrl");
|
|
22774
23118
|
const storeRef = strField(body, "storeRef");
|
|
22775
23119
|
const allowCrossRepo = boolField(body, "allowCrossRepo");
|
|
23120
|
+
const firstTurn = boolField(body, "firstTurn");
|
|
22776
23121
|
const agentIdentity = agentIdentityField(body);
|
|
23122
|
+
openSseStream(res, chatId);
|
|
23123
|
+
if (repo) {
|
|
23124
|
+
emitSse(res, {
|
|
23125
|
+
type: "tool_use",
|
|
23126
|
+
chatId,
|
|
23127
|
+
name: "prepare_repo",
|
|
23128
|
+
input: { repo }
|
|
23129
|
+
});
|
|
23130
|
+
}
|
|
22777
23131
|
let agentCwd;
|
|
22778
23132
|
try {
|
|
22779
23133
|
agentCwd = await ensureRepoCwd({
|
|
@@ -22784,7 +23138,12 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22784
23138
|
cloneRepo: opts.cloneRepo
|
|
22785
23139
|
});
|
|
22786
23140
|
} catch (err) {
|
|
22787
|
-
|
|
23141
|
+
emitSse(res, {
|
|
23142
|
+
type: "error",
|
|
23143
|
+
chatId,
|
|
23144
|
+
error: err instanceof Error ? err.message : String(err)
|
|
23145
|
+
});
|
|
23146
|
+
res.end();
|
|
22788
23147
|
return;
|
|
22789
23148
|
}
|
|
22790
23149
|
const stateToken = repoToken || envGithubToken();
|
|
@@ -22807,7 +23166,7 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22807
23166
|
}
|
|
22808
23167
|
const sessionFile = sessionFilePath(agentCwd, chatId);
|
|
22809
23168
|
const brainEventsFile = brainEventsFilePath(agentCwd, chatId);
|
|
22810
|
-
if (stateConfig && stateToken) {
|
|
23169
|
+
if (!firstTurn && stateConfig && stateToken) {
|
|
22811
23170
|
try {
|
|
22812
23171
|
await syncJsonlFileFromGithubState({
|
|
22813
23172
|
config: stateConfig,
|
|
@@ -22900,7 +23259,7 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22900
23259
|
}
|
|
22901
23260
|
}
|
|
22902
23261
|
});
|
|
22903
|
-
streamToRes(res, agentCwd, chatId, sinceFloor);
|
|
23262
|
+
streamToRes(res, agentCwd, chatId, sinceFloor, { opened: true });
|
|
22904
23263
|
}
|
|
22905
23264
|
function buildServer(opts) {
|
|
22906
23265
|
const runTurn = opts.runTurn ?? runChatTurn;
|
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.325",
|
|
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",
|