@kody-ade/kody-engine 0.4.323 → 0.4.324
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 +442 -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.324",
|
|
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,217 @@ 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) : [];
|
|
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 runSubjectType(data) {
|
|
6552
|
+
const value = data.runSubjectType;
|
|
6553
|
+
return isRunSubjectType(value) ? value : null;
|
|
6554
|
+
}
|
|
6555
|
+
function statusFromGoalEvent(event, decision) {
|
|
6556
|
+
const status = stringValue2(event.status)?.toLowerCase();
|
|
6557
|
+
const eventName = stringValue2(event.event)?.toLowerCase() ?? "";
|
|
6558
|
+
const decisionKind = stringValue2(decision?.kind)?.toLowerCase();
|
|
6559
|
+
if (status === "success" || status === "completed" || decisionKind === "done") return "success";
|
|
6560
|
+
if (status === "failure" || status === "failed" || eventName.includes("fail")) return "failed";
|
|
6561
|
+
if (status === "cancelled") return "cancelled";
|
|
6562
|
+
if (decisionKind === "blocked") return "blocked";
|
|
6563
|
+
if (status === "running" || status === "dispatch" || eventName.includes("dispatch")) return "running";
|
|
6564
|
+
return "recorded";
|
|
6565
|
+
}
|
|
6566
|
+
function triggerKindFromEnv() {
|
|
6567
|
+
const eventName = process.env.GITHUB_EVENT_NAME?.trim();
|
|
6568
|
+
if (!eventName) return void 0;
|
|
6569
|
+
if (eventName === "schedule") return "schedule";
|
|
6570
|
+
if (eventName === "workflow_dispatch") return "manual-workflow-dispatch";
|
|
6571
|
+
return eventName;
|
|
6572
|
+
}
|
|
6573
|
+
function triggerMode(kind) {
|
|
6574
|
+
if (!kind) return void 0;
|
|
6575
|
+
if (kind === "schedule") return "scheduled";
|
|
6576
|
+
if (kind === "manual-workflow-dispatch") return "manual";
|
|
6577
|
+
if (kind === "local") return "local";
|
|
6578
|
+
return "event";
|
|
6579
|
+
}
|
|
6580
|
+
function isConflict(err) {
|
|
6581
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6582
|
+
return /HTTP 409/i.test(msg) || /HTTP 422/i.test(msg) || /does not match|is at|but expected/i.test(msg);
|
|
6583
|
+
}
|
|
6584
|
+
function recordValue2(value) {
|
|
6585
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
6586
|
+
}
|
|
6587
|
+
function stringValue2(value) {
|
|
6588
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
6589
|
+
}
|
|
6590
|
+
function pruneUndefined(input) {
|
|
6591
|
+
for (const key of Object.keys(input)) {
|
|
6592
|
+
if (input[key] === void 0) delete input[key];
|
|
6593
|
+
}
|
|
6594
|
+
return input;
|
|
6595
|
+
}
|
|
6596
|
+
var RUN_INDEX_PATH, MAX_RUNS;
|
|
6597
|
+
var init_runIndex = __esm({
|
|
6598
|
+
"src/runIndex.ts"() {
|
|
6599
|
+
"use strict";
|
|
6600
|
+
init_stateRepo();
|
|
6601
|
+
RUN_INDEX_PATH = "runs/index.json";
|
|
6602
|
+
MAX_RUNS = 200;
|
|
6603
|
+
}
|
|
6604
|
+
});
|
|
6605
|
+
|
|
6395
6606
|
// src/pushWithRetry.ts
|
|
6396
6607
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
6397
6608
|
function sleepSync2(ms) {
|
|
@@ -6904,6 +7115,32 @@ function planManagedGoalTick(goal) {
|
|
|
6904
7115
|
goal.nextAction = "done";
|
|
6905
7116
|
return { kind: "done" };
|
|
6906
7117
|
}
|
|
7118
|
+
const workflow = goal.workflowRef;
|
|
7119
|
+
if (workflow) {
|
|
7120
|
+
const workflowStep = { evidence: missing, stage: "workflow", capability: workflow.id };
|
|
7121
|
+
const progressDecision2 = decisionFromEvidenceProgress(goal, workflowStep, missing);
|
|
7122
|
+
if (progressDecision2) return progressDecision2;
|
|
7123
|
+
const resolved2 = resolveWorkflowRefArgs(goal, workflow);
|
|
7124
|
+
if (!resolved2.ok) {
|
|
7125
|
+
goal.stage = "blocked";
|
|
7126
|
+
goal.reason = resolved2.reason;
|
|
7127
|
+
goal.nextAction = "fix workflow args";
|
|
7128
|
+
pushBlocker(goal, resolved2.reason);
|
|
7129
|
+
return { kind: "blocked", evidence: missing, stage: "workflow", reason: resolved2.reason };
|
|
7130
|
+
}
|
|
7131
|
+
goal.stage = "workflow";
|
|
7132
|
+
goal.facts.pendingEvidence = missing;
|
|
7133
|
+
goal.reason = `dispatch workflow ${workflow.id} for ${missing}`;
|
|
7134
|
+
goal.nextAction = "dispatch workflow";
|
|
7135
|
+
return {
|
|
7136
|
+
kind: "dispatchWorkflow",
|
|
7137
|
+
evidence: missing,
|
|
7138
|
+
stage: "workflow",
|
|
7139
|
+
workflow: workflow.id,
|
|
7140
|
+
cliArgs: resolved2.cliArgs,
|
|
7141
|
+
...workflow.saveReport === true ? { saveReport: true } : {}
|
|
7142
|
+
};
|
|
7143
|
+
}
|
|
6907
7144
|
const step = goal.route.find((candidate) => candidate.evidence === missing);
|
|
6908
7145
|
if (!step) {
|
|
6909
7146
|
if (isSimpleGoal(goal) && missing === SIMPLE_GOAL_EVIDENCE) {
|
|
@@ -6959,6 +7196,15 @@ function planManagedGoalTick(goal) {
|
|
|
6959
7196
|
...step.saveReport === true ? { saveReport: true } : {}
|
|
6960
7197
|
};
|
|
6961
7198
|
}
|
|
7199
|
+
function resolveWorkflowRefArgs(goal, workflow) {
|
|
7200
|
+
const step = {
|
|
7201
|
+
evidence: "__workflow__",
|
|
7202
|
+
stage: "workflow",
|
|
7203
|
+
capability: workflow.id,
|
|
7204
|
+
args: workflow.args
|
|
7205
|
+
};
|
|
7206
|
+
return resolveRouteArgs(goal, step);
|
|
7207
|
+
}
|
|
6962
7208
|
function decisionFromEvidenceProgress(goal, step, evidence) {
|
|
6963
7209
|
const progress = goal.evidenceState?.[evidence];
|
|
6964
7210
|
if (!progress) return null;
|
|
@@ -7095,6 +7341,19 @@ function asLoopTarget(value) {
|
|
|
7095
7341
|
if (typeof raw.id !== "string" || raw.id.trim().length === 0) return void 0;
|
|
7096
7342
|
return { type: raw.type, id: raw.id };
|
|
7097
7343
|
}
|
|
7344
|
+
function asWorkflowRef(value) {
|
|
7345
|
+
const raw = asRecord(value);
|
|
7346
|
+
if (!raw) return void 0;
|
|
7347
|
+
if (typeof raw.id !== "string" || raw.id.trim().length === 0) return void 0;
|
|
7348
|
+
const args = raw.args === void 0 ? void 0 : asRecord(raw.args);
|
|
7349
|
+
if (raw.args !== void 0 && !args) return void 0;
|
|
7350
|
+
return {
|
|
7351
|
+
id: raw.id.trim(),
|
|
7352
|
+
...typeof raw.source === "string" && raw.source.trim().length > 0 ? { source: raw.source.trim() } : {},
|
|
7353
|
+
...args ? { args } : {},
|
|
7354
|
+
...raw.saveReport === true ? { saveReport: true } : {}
|
|
7355
|
+
};
|
|
7356
|
+
}
|
|
7098
7357
|
function managedGoalFromState(state) {
|
|
7099
7358
|
const extra = state.extra;
|
|
7100
7359
|
const destination = asRecord(extra.destination);
|
|
@@ -7111,6 +7370,7 @@ function managedGoalFromState(state) {
|
|
|
7111
7370
|
destination: { outcome: destination.outcome, evidence },
|
|
7112
7371
|
capabilities,
|
|
7113
7372
|
route,
|
|
7373
|
+
workflowRef: asWorkflowRef(extra.workflowRef),
|
|
7114
7374
|
schedule: typeof extra.schedule === "string" ? extra.schedule : void 0,
|
|
7115
7375
|
preferredRunTime: asPreferredRunTime(extra.preferredRunTime),
|
|
7116
7376
|
loopTarget: asLoopTarget(extra.loopTarget),
|
|
@@ -7131,6 +7391,7 @@ function writeManagedGoalToState(state, goal) {
|
|
|
7131
7391
|
destination: goal.destination,
|
|
7132
7392
|
capabilities: goal.capabilities,
|
|
7133
7393
|
route: goal.route,
|
|
7394
|
+
workflowRef: goal.workflowRef,
|
|
7134
7395
|
stage: goal.stage,
|
|
7135
7396
|
facts: goal.facts,
|
|
7136
7397
|
blockers: goal.blockers,
|
|
@@ -7220,9 +7481,15 @@ function flushGoalRunLogEvents(config, cwd, data) {
|
|
|
7220
7481
|
const logs = goalRunLogs(data);
|
|
7221
7482
|
for (const [goalId, log2] of Object.entries(logs)) {
|
|
7222
7483
|
if (log2.events.length === 0) continue;
|
|
7223
|
-
const
|
|
7484
|
+
const enrichedEvents = log2.events.map((event) => enrichGoalRunLogEvent(config, data, log2.path, event));
|
|
7485
|
+
const lines = `${enrichedEvents.map((event) => JSON.stringify(event)).join("\n")}
|
|
7224
7486
|
`;
|
|
7225
7487
|
appendStateLine(config, cwd, log2.path, lines, `chore(goal-logs): append ${goalId}`);
|
|
7488
|
+
upsertRunIndexRowBestEffort(
|
|
7489
|
+
config,
|
|
7490
|
+
cwd,
|
|
7491
|
+
runIndexRowFromGoalEvents(goalId, log2.path, enrichedEvents)
|
|
7492
|
+
);
|
|
7226
7493
|
log2.events = [];
|
|
7227
7494
|
}
|
|
7228
7495
|
}
|
|
@@ -7250,6 +7517,7 @@ function goalRunLogSnapshot(goalId, goalState, goal) {
|
|
|
7250
7517
|
pendingEvidence,
|
|
7251
7518
|
capabilities: [...goal.capabilities],
|
|
7252
7519
|
route: goal.route.map(routeStepForLog),
|
|
7520
|
+
workflowRef: goal.workflowRef,
|
|
7253
7521
|
schedule: goal.schedule,
|
|
7254
7522
|
preferredRunTime: goal.preferredRunTime,
|
|
7255
7523
|
loopTarget: goal.loopTarget,
|
|
@@ -7264,8 +7532,8 @@ function goalRunLogChange(before, after) {
|
|
|
7264
7532
|
addScalarChange(change, "state", before.state, after.state);
|
|
7265
7533
|
addScalarChange(change, "stage", before.stage, after.stage);
|
|
7266
7534
|
addScalarChange(change, "pendingEvidence", before.pendingEvidence, after.pendingEvidence);
|
|
7267
|
-
const beforeFacts =
|
|
7268
|
-
const afterFacts =
|
|
7535
|
+
const beforeFacts = recordValue3(before.facts);
|
|
7536
|
+
const afterFacts = recordValue3(after.facts);
|
|
7269
7537
|
if (beforeFacts || afterFacts) change.facts = diffRecordKeys(beforeFacts ?? {}, afterFacts ?? {});
|
|
7270
7538
|
const beforeBlockers = stringArrayValue(before.blockers);
|
|
7271
7539
|
const afterBlockers = stringArrayValue(after.blockers);
|
|
@@ -7279,8 +7547,8 @@ function goalRunLogChange(before, after) {
|
|
|
7279
7547
|
const evidence = diffStringArrays(beforeSatisfied ?? [], afterSatisfied ?? []);
|
|
7280
7548
|
if (evidence.added.length > 0 || evidence.removed.length > 0) change.satisfiedEvidence = evidence;
|
|
7281
7549
|
}
|
|
7282
|
-
const beforeEvidenceState =
|
|
7283
|
-
const afterEvidenceState =
|
|
7550
|
+
const beforeEvidenceState = recordValue3(before.evidenceState);
|
|
7551
|
+
const afterEvidenceState = recordValue3(after.evidenceState);
|
|
7284
7552
|
if (beforeEvidenceState || afterEvidenceState) {
|
|
7285
7553
|
change.evidenceState = diffRecordKeys(beforeEvidenceState ?? {}, afterEvidenceState ?? {});
|
|
7286
7554
|
}
|
|
@@ -7305,7 +7573,7 @@ function goalRunStartedAt(data) {
|
|
|
7305
7573
|
function goalRunId(data) {
|
|
7306
7574
|
const existing = data[LOG_RUN_KEY];
|
|
7307
7575
|
if (typeof existing === "string" && existing.length > 0) return existing;
|
|
7308
|
-
const raw =
|
|
7576
|
+
const raw = stringValue3(data.jobId) ?? githubRunId() ?? `local-${process.pid}-${Date.now()}`;
|
|
7309
7577
|
const safe = safePathSegment(raw);
|
|
7310
7578
|
data[LOG_RUN_KEY] = safe;
|
|
7311
7579
|
return safe;
|
|
@@ -7337,7 +7605,7 @@ function enrichGoalRunLogEvent(config, data, logPath, event) {
|
|
|
7337
7605
|
const job = event.job ?? jobContext(data);
|
|
7338
7606
|
const run = event.run ?? runContext(data);
|
|
7339
7607
|
const links = event.links ?? linkContext(stateRepo);
|
|
7340
|
-
const enriched =
|
|
7608
|
+
const enriched = pruneUndefined2({
|
|
7341
7609
|
...event,
|
|
7342
7610
|
run,
|
|
7343
7611
|
repo: event.repo ?? repoContext(config),
|
|
@@ -7351,23 +7619,23 @@ function enrichGoalRunLogEvent(config, data, logPath, event) {
|
|
|
7351
7619
|
return enriched;
|
|
7352
7620
|
}
|
|
7353
7621
|
function goalRunTrace(event) {
|
|
7354
|
-
const run =
|
|
7355
|
-
const trigger =
|
|
7356
|
-
const goal =
|
|
7357
|
-
const inspection =
|
|
7358
|
-
const capabilityOutput =
|
|
7359
|
-
return
|
|
7622
|
+
const run = recordValue3(event.run);
|
|
7623
|
+
const trigger = recordValue3(event.trigger);
|
|
7624
|
+
const goal = recordValue3(event.goal);
|
|
7625
|
+
const inspection = recordValue3(event.inspection);
|
|
7626
|
+
const capabilityOutput = recordValue3(inspection?.capabilityOutput);
|
|
7627
|
+
return pruneUndefined2({
|
|
7360
7628
|
version: 1,
|
|
7361
|
-
runId:
|
|
7362
|
-
workflowRunId:
|
|
7363
|
-
triggerKind:
|
|
7629
|
+
runId: stringValue3(run?.id) ?? void 0,
|
|
7630
|
+
workflowRunId: stringValue3(run?.githubRunId) ?? void 0,
|
|
7631
|
+
triggerKind: stringValue3(trigger?.kind) ?? void 0,
|
|
7364
7632
|
source: event.source,
|
|
7365
7633
|
event: event.event,
|
|
7366
|
-
goal:
|
|
7634
|
+
goal: pruneUndefined2({
|
|
7367
7635
|
id: event.goalId,
|
|
7368
|
-
type: event.goalType ??
|
|
7369
|
-
state: event.goalState ??
|
|
7370
|
-
stage: event.stage ??
|
|
7636
|
+
type: event.goalType ?? stringValue3(goal?.type) ?? void 0,
|
|
7637
|
+
state: event.goalState ?? stringValue3(goal?.state) ?? void 0,
|
|
7638
|
+
stage: event.stage ?? stringValue3(goal?.stage) ?? void 0
|
|
7371
7639
|
}),
|
|
7372
7640
|
evidence: goalTraceEvidence(event, goal, inspection),
|
|
7373
7641
|
capability: event.dispatch ?? capabilityDispatchFromOutput(capabilityOutput),
|
|
@@ -7377,30 +7645,30 @@ function goalRunTrace(event) {
|
|
|
7377
7645
|
});
|
|
7378
7646
|
}
|
|
7379
7647
|
function goalTraceEvidence(event, goal, inspection) {
|
|
7380
|
-
const expectedEvidence =
|
|
7381
|
-
const out =
|
|
7648
|
+
const expectedEvidence = recordValue3(inspection?.expectedEvidence);
|
|
7649
|
+
const out = pruneUndefined2({
|
|
7382
7650
|
current: event.evidence,
|
|
7383
7651
|
required: stringArrayValue(goal?.requiredEvidence) ?? stringArrayValue(inspection?.requiredEvidence) ?? void 0,
|
|
7384
7652
|
satisfied: stringArrayValue(goal?.satisfiedEvidence) ?? stringArrayValue(inspection?.satisfiedEvidence) ?? void 0,
|
|
7385
7653
|
missing: stringArrayValue(goal?.missingEvidence) ?? stringArrayValue(inspection?.missingEvidence) ?? stringArrayValue(expectedEvidence?.missingBefore) ?? void 0,
|
|
7386
|
-
pending:
|
|
7654
|
+
pending: stringValue3(goal?.pendingEvidence) ?? stringValue3(inspection?.pendingEvidence) ?? stringValue3(expectedEvidence?.pendingBefore) ?? void 0,
|
|
7387
7655
|
values: event.evidenceValues
|
|
7388
7656
|
});
|
|
7389
7657
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
7390
7658
|
}
|
|
7391
7659
|
function capabilityDispatchFromOutput(output) {
|
|
7392
7660
|
if (!output) return void 0;
|
|
7393
|
-
const dispatch2 =
|
|
7394
|
-
capability:
|
|
7395
|
-
executable:
|
|
7396
|
-
action:
|
|
7661
|
+
const dispatch2 = pruneUndefined2({
|
|
7662
|
+
capability: stringValue3(output.capability) ?? void 0,
|
|
7663
|
+
executable: stringValue3(output.executable) ?? void 0,
|
|
7664
|
+
action: stringValue3(output.action) ?? void 0
|
|
7397
7665
|
});
|
|
7398
7666
|
return Object.keys(dispatch2).length > 0 ? dispatch2 : void 0;
|
|
7399
7667
|
}
|
|
7400
7668
|
function goalTraceResult(event, capabilityOutput) {
|
|
7401
|
-
const result =
|
|
7402
|
-
status: event.status ??
|
|
7403
|
-
summary: event.reason ??
|
|
7669
|
+
const result = pruneUndefined2({
|
|
7670
|
+
status: event.status ?? stringValue3(capabilityOutput?.status) ?? void 0,
|
|
7671
|
+
summary: event.reason ?? stringValue3(capabilityOutput?.summary) ?? void 0,
|
|
7404
7672
|
blockers: event.inspection ? stringArrayValue(capabilityOutput?.blockers) ?? void 0 : void 0,
|
|
7405
7673
|
artifacts: event.artifacts
|
|
7406
7674
|
});
|
|
@@ -7411,7 +7679,7 @@ function runContext(data) {
|
|
|
7411
7679
|
const attempt = process.env.GITHUB_RUN_ATTEMPT?.trim();
|
|
7412
7680
|
const repository = process.env.GITHUB_REPOSITORY?.trim();
|
|
7413
7681
|
const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
7414
|
-
return
|
|
7682
|
+
return pruneUndefined2({
|
|
7415
7683
|
id: goalRunId(data),
|
|
7416
7684
|
provider: runId ? "github-actions" : "local",
|
|
7417
7685
|
githubRunId: runId || void 0,
|
|
@@ -7425,7 +7693,7 @@ function runContext(data) {
|
|
|
7425
7693
|
function repoContext(config) {
|
|
7426
7694
|
const owner = config.github?.owner;
|
|
7427
7695
|
const repo = config.github?.repo;
|
|
7428
|
-
return
|
|
7696
|
+
return pruneUndefined2({
|
|
7429
7697
|
owner,
|
|
7430
7698
|
repo,
|
|
7431
7699
|
fullName: owner && repo ? `${owner}/${repo}` : process.env.GITHUB_REPOSITORY?.trim() || void 0,
|
|
@@ -7449,11 +7717,11 @@ function stateRepoContext(config, goalId, logPath) {
|
|
|
7449
7717
|
}
|
|
7450
7718
|
function triggerContext() {
|
|
7451
7719
|
const event = readGithubEvent();
|
|
7452
|
-
const inputs =
|
|
7720
|
+
const inputs = recordValue3(event?.inputs);
|
|
7453
7721
|
const eventName = process.env.GITHUB_EVENT_NAME?.trim() || void 0;
|
|
7454
7722
|
const githubActor = process.env.GITHUB_ACTOR?.trim() || void 0;
|
|
7455
7723
|
if (!eventName && !githubActor && !process.env.GITHUB_EVENT_PATH) return void 0;
|
|
7456
|
-
const trigger =
|
|
7724
|
+
const trigger = pruneUndefined2({
|
|
7457
7725
|
source: eventName ? "github-actions" : "local",
|
|
7458
7726
|
kind: triggerKind(eventName),
|
|
7459
7727
|
eventName,
|
|
@@ -7461,10 +7729,10 @@ function triggerContext() {
|
|
|
7461
7729
|
githubActor,
|
|
7462
7730
|
actorRole: triggerActorRole(eventName),
|
|
7463
7731
|
eventPath: process.env.GITHUB_EVENT_PATH?.trim() || void 0,
|
|
7464
|
-
issue: numberValue(
|
|
7465
|
-
pullRequest: numberValue(
|
|
7466
|
-
comment: numberValue(
|
|
7467
|
-
schedule:
|
|
7732
|
+
issue: numberValue(recordValue3(event?.issue)?.number),
|
|
7733
|
+
pullRequest: numberValue(recordValue3(event?.pull_request)?.number),
|
|
7734
|
+
comment: numberValue(recordValue3(event?.comment)?.id),
|
|
7735
|
+
schedule: stringValue3(event?.schedule),
|
|
7468
7736
|
inputs: inputs ? pickRecord(inputs, ["issue_number", "sessionId", "message", "model", "title", "executable", "base"]) : void 0
|
|
7469
7737
|
});
|
|
7470
7738
|
return Object.keys(trigger).length > 0 ? trigger : void 0;
|
|
@@ -7482,17 +7750,21 @@ function triggerActorRole(eventName) {
|
|
|
7482
7750
|
return "github event actor";
|
|
7483
7751
|
}
|
|
7484
7752
|
function jobContext(data) {
|
|
7485
|
-
const job =
|
|
7486
|
-
id:
|
|
7487
|
-
key:
|
|
7488
|
-
flavor:
|
|
7489
|
-
action:
|
|
7490
|
-
capability:
|
|
7491
|
-
executable:
|
|
7492
|
-
agent:
|
|
7493
|
-
schedule:
|
|
7753
|
+
const job = pruneUndefined2({
|
|
7754
|
+
id: stringValue3(data.jobId) ?? void 0,
|
|
7755
|
+
key: stringValue3(data.jobKey) ?? void 0,
|
|
7756
|
+
flavor: stringValue3(data.jobFlavor) ?? void 0,
|
|
7757
|
+
action: stringValue3(data.jobAction) ?? void 0,
|
|
7758
|
+
capability: stringValue3(data.jobCapability) ?? void 0,
|
|
7759
|
+
executable: stringValue3(data.jobExecutable) ?? void 0,
|
|
7760
|
+
agent: stringValue3(data.jobAgent) ?? void 0,
|
|
7761
|
+
schedule: stringValue3(data.jobSchedule) ?? void 0,
|
|
7494
7762
|
target: data.jobTarget ?? void 0,
|
|
7495
|
-
|
|
7763
|
+
model: stringValue3(data.jobModel) ?? void 0,
|
|
7764
|
+
modelProvider: stringValue3(data.jobModelProvider) ?? void 0,
|
|
7765
|
+
modelName: stringValue3(data.jobModelName) ?? void 0,
|
|
7766
|
+
reasoningEffort: stringValue3(data.jobReasoningEffort) ?? void 0,
|
|
7767
|
+
why: truncateString(stringValue3(data.jobWhy), 1e3),
|
|
7496
7768
|
saveReport: data.jobSaveReport === true ? true : void 0
|
|
7497
7769
|
});
|
|
7498
7770
|
return Object.keys(job).length > 0 ? job : void 0;
|
|
@@ -7500,23 +7772,23 @@ function jobContext(data) {
|
|
|
7500
7772
|
function dispatchContext(event, trigger, job) {
|
|
7501
7773
|
if (!event.dispatch && event.status !== "dispatch") return void 0;
|
|
7502
7774
|
const dispatch2 = event.dispatch ?? {};
|
|
7503
|
-
const context =
|
|
7775
|
+
const context = pruneUndefined2({
|
|
7504
7776
|
triggeredBy: triggerLabel(trigger),
|
|
7505
|
-
triggerKind:
|
|
7777
|
+
triggerKind: stringValue3(trigger?.kind),
|
|
7506
7778
|
dispatchMode: dispatchMode(trigger),
|
|
7507
|
-
githubActor:
|
|
7508
|
-
githubActorRole:
|
|
7779
|
+
githubActor: stringValue3(trigger?.githubActor) ?? stringValue3(trigger?.actor),
|
|
7780
|
+
githubActorRole: stringValue3(trigger?.actorRole),
|
|
7509
7781
|
decidedBy: event.source,
|
|
7510
7782
|
dispatchedBy: event.source,
|
|
7511
7783
|
target: event.target,
|
|
7512
|
-
action: dispatch2.action ??
|
|
7513
|
-
capability: dispatch2.capability ??
|
|
7784
|
+
action: dispatch2.action ?? stringValue3(job?.action),
|
|
7785
|
+
capability: dispatch2.capability ?? stringValue3(job?.capability),
|
|
7514
7786
|
reason: event.reason
|
|
7515
7787
|
});
|
|
7516
7788
|
return Object.keys(context).length > 0 ? context : void 0;
|
|
7517
7789
|
}
|
|
7518
7790
|
function triggerLabel(trigger) {
|
|
7519
|
-
const kind =
|
|
7791
|
+
const kind = stringValue3(trigger?.kind);
|
|
7520
7792
|
if (kind === "schedule") return "GitHub schedule";
|
|
7521
7793
|
if (kind === "manual-workflow-dispatch") return "manual workflow dispatch";
|
|
7522
7794
|
if (kind === "issue_comment") return "GitHub issue comment";
|
|
@@ -7525,7 +7797,7 @@ function triggerLabel(trigger) {
|
|
|
7525
7797
|
return "local run";
|
|
7526
7798
|
}
|
|
7527
7799
|
function dispatchMode(trigger) {
|
|
7528
|
-
const kind =
|
|
7800
|
+
const kind = stringValue3(trigger?.kind);
|
|
7529
7801
|
if (kind === "schedule") return "automated";
|
|
7530
7802
|
if (kind === "manual-workflow-dispatch") return "manual";
|
|
7531
7803
|
if (kind) return "event-driven";
|
|
@@ -7537,10 +7809,10 @@ function linkContext(stateRepo) {
|
|
|
7537
7809
|
const repository = process.env.GITHUB_REPOSITORY?.trim();
|
|
7538
7810
|
const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
7539
7811
|
if (runId && repository) links.workflowRun = `${server}/${repository}/actions/runs/${runId}`;
|
|
7540
|
-
const repo =
|
|
7541
|
-
const branch =
|
|
7542
|
-
const goalStatePath2 =
|
|
7543
|
-
const logPath =
|
|
7812
|
+
const repo = stringValue3(stateRepo?.repo);
|
|
7813
|
+
const branch = stringValue3(stateRepo?.branch);
|
|
7814
|
+
const goalStatePath2 = stringValue3(stateRepo?.goalStatePath);
|
|
7815
|
+
const logPath = stringValue3(stateRepo?.logPath);
|
|
7544
7816
|
if (repo && branch && goalStatePath2) links.goalState = githubBlobUrl(repo, branch, goalStatePath2);
|
|
7545
7817
|
if (repo && branch && logPath) links.log = githubBlobUrl(repo, branch, logPath);
|
|
7546
7818
|
return Object.keys(links).length > 0 ? links : void 0;
|
|
@@ -7554,7 +7826,7 @@ function githubBlobUrl(repo, branch, filePath) {
|
|
|
7554
7826
|
}
|
|
7555
7827
|
}
|
|
7556
7828
|
function routeStepForLog(step) {
|
|
7557
|
-
return
|
|
7829
|
+
return pruneUndefined2({
|
|
7558
7830
|
evidence: step.evidence,
|
|
7559
7831
|
stage: step.stage,
|
|
7560
7832
|
capability: step.capability,
|
|
@@ -7569,14 +7841,14 @@ function readGithubEvent() {
|
|
|
7569
7841
|
try {
|
|
7570
7842
|
if (!fs25.existsSync(eventPath)) return null;
|
|
7571
7843
|
const parsed = JSON.parse(fs25.readFileSync(eventPath, "utf-8"));
|
|
7572
|
-
return
|
|
7844
|
+
return recordValue3(parsed);
|
|
7573
7845
|
} catch {
|
|
7574
7846
|
return null;
|
|
7575
7847
|
}
|
|
7576
7848
|
}
|
|
7577
7849
|
function addScalarChange(change, field, before, after) {
|
|
7578
7850
|
if (before === after) return;
|
|
7579
|
-
change[field] =
|
|
7851
|
+
change[field] = pruneUndefined2({ from: before, to: after });
|
|
7580
7852
|
}
|
|
7581
7853
|
function diffRecordKeys(before, after) {
|
|
7582
7854
|
const beforeKeys = new Set(Object.keys(before));
|
|
@@ -7594,7 +7866,7 @@ function diffStringArrays(before, after) {
|
|
|
7594
7866
|
removed: before.filter((item) => !afterSet.has(item)).sort()
|
|
7595
7867
|
};
|
|
7596
7868
|
}
|
|
7597
|
-
function
|
|
7869
|
+
function recordValue3(value) {
|
|
7598
7870
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
7599
7871
|
}
|
|
7600
7872
|
function stringArrayValue(value) {
|
|
@@ -7610,7 +7882,7 @@ function pickRecord(input, keys) {
|
|
|
7610
7882
|
}
|
|
7611
7883
|
return out;
|
|
7612
7884
|
}
|
|
7613
|
-
function
|
|
7885
|
+
function pruneUndefined2(input) {
|
|
7614
7886
|
for (const key of Object.keys(input)) {
|
|
7615
7887
|
if (input[key] === void 0) delete input[key];
|
|
7616
7888
|
}
|
|
@@ -7620,7 +7892,7 @@ function truncateString(value, max) {
|
|
|
7620
7892
|
if (!value) return void 0;
|
|
7621
7893
|
return value.length > max ? `${value.slice(0, max)}...` : value;
|
|
7622
7894
|
}
|
|
7623
|
-
function
|
|
7895
|
+
function stringValue3(value) {
|
|
7624
7896
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
7625
7897
|
}
|
|
7626
7898
|
function safePathSegment(value) {
|
|
@@ -7632,6 +7904,7 @@ var init_runLog = __esm({
|
|
|
7632
7904
|
"src/goal/runLog.ts"() {
|
|
7633
7905
|
"use strict";
|
|
7634
7906
|
init_stateRepo();
|
|
7907
|
+
init_runIndex();
|
|
7635
7908
|
init_state2();
|
|
7636
7909
|
LOGS_KEY = "__goalRunLogs";
|
|
7637
7910
|
LOG_RUN_KEY = "__goalRunLogRunId";
|
|
@@ -8824,7 +9097,7 @@ var init_goalCapabilityScheduling = __esm({
|
|
|
8824
9097
|
|
|
8825
9098
|
// src/scripts/advanceManagedGoal.ts
|
|
8826
9099
|
function stageManagedGoalDecision(data, goalId, goal, goalState, decision, details) {
|
|
8827
|
-
if (decision.kind === "dispatch") {
|
|
9100
|
+
if (decision.kind === "dispatch" || decision.kind === "dispatchWorkflow") {
|
|
8828
9101
|
stageGoalRunLogEvent(data, goalId, {
|
|
8829
9102
|
source: "goal-manager",
|
|
8830
9103
|
event: "goal.tick.dispatch",
|
|
@@ -8833,14 +9106,23 @@ function stageManagedGoalDecision(data, goalId, goal, goalState, decision, detai
|
|
|
8833
9106
|
stage: decision.stage,
|
|
8834
9107
|
evidence: decision.evidence,
|
|
8835
9108
|
status: decision.kind,
|
|
8836
|
-
dispatch: {
|
|
9109
|
+
dispatch: decision.kind === "dispatchWorkflow" ? {
|
|
9110
|
+
workflow: decision.workflow,
|
|
9111
|
+
cliArgs: decision.cliArgs
|
|
9112
|
+
} : {
|
|
8837
9113
|
capability: decision.capability,
|
|
8838
9114
|
cliArgs: decision.cliArgs,
|
|
8839
9115
|
...decision.executable ? { executable: decision.executable } : {}
|
|
8840
9116
|
},
|
|
8841
9117
|
goal: details.goalSnapshot,
|
|
8842
9118
|
inspection: details.inspection,
|
|
8843
|
-
decision: {
|
|
9119
|
+
decision: decision.kind === "dispatchWorkflow" ? {
|
|
9120
|
+
kind: decision.kind,
|
|
9121
|
+
evidence: decision.evidence,
|
|
9122
|
+
stage: decision.stage,
|
|
9123
|
+
workflow: decision.workflow,
|
|
9124
|
+
cliArgs: decision.cliArgs
|
|
9125
|
+
} : {
|
|
8844
9126
|
kind: decision.kind,
|
|
8845
9127
|
evidence: decision.evidence,
|
|
8846
9128
|
stage: decision.stage,
|
|
@@ -8923,7 +9205,7 @@ function previousDispatchWasTargetInstance(managed, previousScheduleState) {
|
|
|
8923
9205
|
return previous.targetId === targetId || previous.targetId.startsWith(`${targetId}-`);
|
|
8924
9206
|
}
|
|
8925
9207
|
function ensureIssueFactIfNeeded(goal, goalId, cwd) {
|
|
8926
|
-
if (!routeNeedsIssueFact(goal)) return;
|
|
9208
|
+
if (!routeNeedsIssueFact(goal) && !workflowNeedsIssueFact(goal)) return;
|
|
8927
9209
|
const existing = normalizeIssueNumber(goal.facts.issue);
|
|
8928
9210
|
if (existing !== null) {
|
|
8929
9211
|
goal.facts.issue = existing;
|
|
@@ -8940,6 +9222,14 @@ function routeNeedsIssueFact(goal) {
|
|
|
8940
9222
|
})
|
|
8941
9223
|
);
|
|
8942
9224
|
}
|
|
9225
|
+
function workflowNeedsIssueFact(goal) {
|
|
9226
|
+
return Object.values(goal.workflowRef?.args ?? {}).some(isIssueFactReference);
|
|
9227
|
+
}
|
|
9228
|
+
function isIssueFactReference(value) {
|
|
9229
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
9230
|
+
const record2 = value;
|
|
9231
|
+
return Object.keys(record2).length === 1 && record2.fact === "issue";
|
|
9232
|
+
}
|
|
8943
9233
|
function normalizeIssueNumber(value) {
|
|
8944
9234
|
if (typeof value === "number" && Number.isInteger(value) && value > 0) return value;
|
|
8945
9235
|
if (typeof value === "string" && /^\d+$/.test(value)) return Number(value);
|
|
@@ -9202,6 +9492,16 @@ var init_advanceManagedGoal = __esm({
|
|
|
9202
9492
|
ctx.output.reason = decision.kind === "done" ? "managed goal complete" : decision.reason;
|
|
9203
9493
|
return;
|
|
9204
9494
|
}
|
|
9495
|
+
if (decision.kind === "dispatchWorkflow") {
|
|
9496
|
+
ctx.output.nextDispatch = {
|
|
9497
|
+
workflow: decision.workflow,
|
|
9498
|
+
cliArgs: decision.cliArgs,
|
|
9499
|
+
...decision.saveReport === true ? { saveReport: true } : {},
|
|
9500
|
+
resultTarget: { type: "goal", id: goal.id }
|
|
9501
|
+
};
|
|
9502
|
+
ctx.output.reason = `dispatch workflow ${decision.workflow} for ${decision.evidence}`;
|
|
9503
|
+
return;
|
|
9504
|
+
}
|
|
9205
9505
|
ctx.output.nextDispatch = {
|
|
9206
9506
|
capability: decision.capability,
|
|
9207
9507
|
cliArgs: decision.cliArgs,
|
|
@@ -14180,7 +14480,7 @@ var init_keys = __esm({
|
|
|
14180
14480
|
// src/stateRepoGithub.ts
|
|
14181
14481
|
import * as fs38 from "fs";
|
|
14182
14482
|
import * as path36 from "path";
|
|
14183
|
-
function
|
|
14483
|
+
function recordValue4(value) {
|
|
14184
14484
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
14185
14485
|
}
|
|
14186
14486
|
function contentsUrl(owner, repo, filePath) {
|
|
@@ -14236,12 +14536,12 @@ async function loadGithubStateConfig(opts) {
|
|
|
14236
14536
|
throw new Error(`kody.config.json is invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
14237
14537
|
}
|
|
14238
14538
|
}
|
|
14239
|
-
const githubRaw =
|
|
14539
|
+
const githubRaw = recordValue4(raw.github) ?? {};
|
|
14240
14540
|
const github = {
|
|
14241
14541
|
owner: typeof githubRaw.owner === "string" && githubRaw.owner.trim() ? githubRaw.owner.trim() : opts.owner,
|
|
14242
14542
|
repo: typeof githubRaw.repo === "string" && githubRaw.repo.trim() ? githubRaw.repo.trim() : opts.repo
|
|
14243
14543
|
};
|
|
14244
|
-
const nestedState =
|
|
14544
|
+
const nestedState = recordValue4(raw.state) ?? {};
|
|
14245
14545
|
const repoRaw = typeof raw.stateRepo === "string" ? raw.stateRepo : nestedState.repo;
|
|
14246
14546
|
const pathRaw = typeof raw.statePath === "string" ? raw.statePath : nestedState.path;
|
|
14247
14547
|
const stateRepo = typeof repoRaw === "string" && repoRaw.trim().length > 0 ? repoRaw.trim() : `https://github.com/${github.owner}/kody-state`;
|
|
@@ -19040,8 +19340,10 @@ function jobReferenceBlock(profileName, profile, data) {
|
|
|
19040
19340
|
}
|
|
19041
19341
|
async function runExecutable(profileName, input) {
|
|
19042
19342
|
const stageStartedAt = Date.now();
|
|
19343
|
+
let finishRunIndex = null;
|
|
19043
19344
|
emitEvent(input.cwd, { executable: profileName, kind: "stage_start" });
|
|
19044
19345
|
const finishAndEnd = (out) => {
|
|
19346
|
+
finishRunIndex?.(out);
|
|
19045
19347
|
emitEvent(input.cwd, {
|
|
19046
19348
|
executable: profileName,
|
|
19047
19349
|
kind: "stage_end",
|
|
@@ -19126,6 +19428,41 @@ async function runExecutable(profileName, input) {
|
|
|
19126
19428
|
data: { ...input.preloadedData ?? {} },
|
|
19127
19429
|
output: { exitCode: 0 }
|
|
19128
19430
|
};
|
|
19431
|
+
ctx.data.jobModel = modelSpec;
|
|
19432
|
+
ctx.data.jobModelProvider = model.provider;
|
|
19433
|
+
ctx.data.jobModelName = model.model;
|
|
19434
|
+
if (reasoningEffort) ctx.data.jobReasoningEffort = reasoningEffort;
|
|
19435
|
+
const runIndexStartedAt = new Date(stageStartedAt).toISOString();
|
|
19436
|
+
if (!input.skipConfig) {
|
|
19437
|
+
upsertRunIndexRowBestEffort(
|
|
19438
|
+
config,
|
|
19439
|
+
input.cwd,
|
|
19440
|
+
runIndexRowFromJobContext({
|
|
19441
|
+
data: ctx.data,
|
|
19442
|
+
profileName,
|
|
19443
|
+
profile,
|
|
19444
|
+
status: "running",
|
|
19445
|
+
startedAt: runIndexStartedAt,
|
|
19446
|
+
updatedAt: runIndexStartedAt
|
|
19447
|
+
})
|
|
19448
|
+
);
|
|
19449
|
+
finishRunIndex = (out) => {
|
|
19450
|
+
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19451
|
+
upsertRunIndexRowBestEffort(
|
|
19452
|
+
config,
|
|
19453
|
+
input.cwd,
|
|
19454
|
+
runIndexRowFromJobContext({
|
|
19455
|
+
data: ctx.data,
|
|
19456
|
+
profileName,
|
|
19457
|
+
profile,
|
|
19458
|
+
status: statusFromExitCode(out.exitCode),
|
|
19459
|
+
startedAt: runIndexStartedAt,
|
|
19460
|
+
updatedAt: finishedAt,
|
|
19461
|
+
reason: out.reason
|
|
19462
|
+
})
|
|
19463
|
+
);
|
|
19464
|
+
};
|
|
19465
|
+
}
|
|
19129
19466
|
const taskTarget = args.issue ?? args.pr;
|
|
19130
19467
|
const taskArtifacts = typeof taskTarget === "number" && Number.isFinite(taskTarget) ? (() => {
|
|
19131
19468
|
const taskType = args.issue ? "issue" : "pr";
|
|
@@ -19820,6 +20157,7 @@ var init_executor = __esm({
|
|
|
19820
20157
|
init_litellm();
|
|
19821
20158
|
init_profile();
|
|
19822
20159
|
init_registry();
|
|
20160
|
+
init_runIndex();
|
|
19823
20161
|
init_runtimePaths();
|
|
19824
20162
|
init_scripts();
|
|
19825
20163
|
init_stateWorkspace();
|
|
@@ -20095,6 +20433,10 @@ function shouldRunCapabilityWorkflow(job, workflow, capabilityIdentity, selected
|
|
|
20095
20433
|
async function runCapabilityWorkflow(parent, workflow, capability, base) {
|
|
20096
20434
|
let chainData = {
|
|
20097
20435
|
...base.preloadedData ?? {},
|
|
20436
|
+
runSubjectType: "workflow",
|
|
20437
|
+
runSubjectId: capability.slug,
|
|
20438
|
+
runSubjectLabel: capability.title,
|
|
20439
|
+
runSubjectWorkflow: capability.slug,
|
|
20098
20440
|
workflowCapability: capability.slug,
|
|
20099
20441
|
workflowTitle: capability.title,
|
|
20100
20442
|
workflowStepCount: workflow.steps.length,
|
|
@@ -22655,6 +22997,10 @@ function emitSse(res, event) {
|
|
|
22655
22997
|
|
|
22656
22998
|
`);
|
|
22657
22999
|
}
|
|
23000
|
+
function openSseStream(res, chatId) {
|
|
23001
|
+
writeSseHeaders(res);
|
|
23002
|
+
emitSse(res, { type: "chat", chatId });
|
|
23003
|
+
}
|
|
22658
23004
|
function envGithubToken() {
|
|
22659
23005
|
return (process.env.KODY_TOKEN ?? process.env.GH_TOKEN ?? process.env.GITHUB_TOKEN ?? process.env.GH_PAT ?? "").trim();
|
|
22660
23006
|
}
|
|
@@ -22664,16 +23010,6 @@ function parseRepoSlug(repo) {
|
|
|
22664
23010
|
if (!owner || !name) return null;
|
|
22665
23011
|
return { owner, repo: name };
|
|
22666
23012
|
}
|
|
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
23013
|
function translateChatEvent(event, chatId) {
|
|
22678
23014
|
switch (event.event) {
|
|
22679
23015
|
case "chat.message": {
|
|
@@ -22727,9 +23063,10 @@ function enqueue(chatId, fn) {
|
|
|
22727
23063
|
);
|
|
22728
23064
|
return next;
|
|
22729
23065
|
}
|
|
22730
|
-
function streamToRes(res, dir, chatId, since) {
|
|
22731
|
-
|
|
22732
|
-
|
|
23066
|
+
function streamToRes(res, dir, chatId, since, opts = {}) {
|
|
23067
|
+
if (!opts.opened) {
|
|
23068
|
+
openSseStream(res, chatId);
|
|
23069
|
+
}
|
|
22733
23070
|
let maxSent = since;
|
|
22734
23071
|
const unsubscribe = subscribe(
|
|
22735
23072
|
dir,
|
|
@@ -22773,7 +23110,17 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22773
23110
|
const storeRepoUrl = strField(body, "storeRepoUrl");
|
|
22774
23111
|
const storeRef = strField(body, "storeRef");
|
|
22775
23112
|
const allowCrossRepo = boolField(body, "allowCrossRepo");
|
|
23113
|
+
const firstTurn = boolField(body, "firstTurn");
|
|
22776
23114
|
const agentIdentity = agentIdentityField(body);
|
|
23115
|
+
openSseStream(res, chatId);
|
|
23116
|
+
if (repo) {
|
|
23117
|
+
emitSse(res, {
|
|
23118
|
+
type: "tool_use",
|
|
23119
|
+
chatId,
|
|
23120
|
+
name: "prepare_repo",
|
|
23121
|
+
input: { repo }
|
|
23122
|
+
});
|
|
23123
|
+
}
|
|
22777
23124
|
let agentCwd;
|
|
22778
23125
|
try {
|
|
22779
23126
|
agentCwd = await ensureRepoCwd({
|
|
@@ -22784,7 +23131,12 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22784
23131
|
cloneRepo: opts.cloneRepo
|
|
22785
23132
|
});
|
|
22786
23133
|
} catch (err) {
|
|
22787
|
-
|
|
23134
|
+
emitSse(res, {
|
|
23135
|
+
type: "error",
|
|
23136
|
+
chatId,
|
|
23137
|
+
error: err instanceof Error ? err.message : String(err)
|
|
23138
|
+
});
|
|
23139
|
+
res.end();
|
|
22788
23140
|
return;
|
|
22789
23141
|
}
|
|
22790
23142
|
const stateToken = repoToken || envGithubToken();
|
|
@@ -22807,7 +23159,7 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22807
23159
|
}
|
|
22808
23160
|
const sessionFile = sessionFilePath(agentCwd, chatId);
|
|
22809
23161
|
const brainEventsFile = brainEventsFilePath(agentCwd, chatId);
|
|
22810
|
-
if (stateConfig && stateToken) {
|
|
23162
|
+
if (!firstTurn && stateConfig && stateToken) {
|
|
22811
23163
|
try {
|
|
22812
23164
|
await syncJsonlFileFromGithubState({
|
|
22813
23165
|
config: stateConfig,
|
|
@@ -22900,7 +23252,7 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22900
23252
|
}
|
|
22901
23253
|
}
|
|
22902
23254
|
});
|
|
22903
|
-
streamToRes(res, agentCwd, chatId, sinceFloor);
|
|
23255
|
+
streamToRes(res, agentCwd, chatId, sinceFloor, { opened: true });
|
|
22904
23256
|
}
|
|
22905
23257
|
function buildServer(opts) {
|
|
22906
23258
|
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.324",
|
|
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",
|