@kody-ade/kody-engine 0.4.254 → 0.4.256
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 +819 -131
- package/package.json +22 -23
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.256",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative agentAction profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -3162,12 +3162,18 @@ function parseAgentResponsibilityResult(raw) {
|
|
|
3162
3162
|
if (!facts) return null;
|
|
3163
3163
|
const artifacts = parseArtifacts(obj.artifacts);
|
|
3164
3164
|
if (!artifacts) return null;
|
|
3165
|
+
const missingEvidence = parseOptionalStringArray(obj.missingEvidence);
|
|
3166
|
+
if (!missingEvidence) return null;
|
|
3167
|
+
const blockers = parseOptionalStringArray(obj.blockers);
|
|
3168
|
+
if (!blockers) return null;
|
|
3165
3169
|
return {
|
|
3166
3170
|
version: 1,
|
|
3167
3171
|
status: obj.status,
|
|
3168
3172
|
summary,
|
|
3169
3173
|
facts,
|
|
3170
|
-
artifacts
|
|
3174
|
+
artifacts,
|
|
3175
|
+
missingEvidence,
|
|
3176
|
+
blockers
|
|
3171
3177
|
};
|
|
3172
3178
|
}
|
|
3173
3179
|
function applyAgentResponsibilityResultToObjectiveState(state, result, evidenceOverride) {
|
|
@@ -3186,8 +3192,9 @@ function applyAgentResponsibilityResultToObjectiveState(state, result, evidenceO
|
|
|
3186
3192
|
}
|
|
3187
3193
|
}
|
|
3188
3194
|
const blockers = parseStringArray(state.extra.blockers) ?? [];
|
|
3189
|
-
|
|
3190
|
-
|
|
3195
|
+
const resultBlockers = result.blockers.length > 0 || result.status !== "fail" && result.status !== "blocked" ? result.blockers : [result.summary];
|
|
3196
|
+
for (const blocker of resultBlockers) {
|
|
3197
|
+
if (!blockers.includes(blocker)) blockers.push(blocker);
|
|
3191
3198
|
}
|
|
3192
3199
|
return {
|
|
3193
3200
|
...state,
|
|
@@ -3199,7 +3206,9 @@ function applyAgentResponsibilityResultToObjectiveState(state, result, evidenceO
|
|
|
3199
3206
|
status: result.status,
|
|
3200
3207
|
summary: result.summary,
|
|
3201
3208
|
facts: result.facts,
|
|
3202
|
-
artifacts: result.artifacts
|
|
3209
|
+
artifacts: result.artifacts,
|
|
3210
|
+
missingEvidence: result.missingEvidence,
|
|
3211
|
+
blockers: result.blockers
|
|
3203
3212
|
}
|
|
3204
3213
|
}
|
|
3205
3214
|
};
|
|
@@ -3227,6 +3236,10 @@ function parseStringArray(raw) {
|
|
|
3227
3236
|
}
|
|
3228
3237
|
return out;
|
|
3229
3238
|
}
|
|
3239
|
+
function parseOptionalStringArray(raw) {
|
|
3240
|
+
if (raw === void 0) return [];
|
|
3241
|
+
return parseStringArray(raw);
|
|
3242
|
+
}
|
|
3230
3243
|
function parseArtifacts(raw) {
|
|
3231
3244
|
if (raw === void 0) return [];
|
|
3232
3245
|
if (!Array.isArray(raw)) return null;
|
|
@@ -6179,6 +6192,308 @@ var init_state2 = __esm({
|
|
|
6179
6192
|
}
|
|
6180
6193
|
});
|
|
6181
6194
|
|
|
6195
|
+
// src/goal/runLog.ts
|
|
6196
|
+
import * as fs25 from "fs";
|
|
6197
|
+
function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
|
|
6198
|
+
const logs = goalRunLogs(data);
|
|
6199
|
+
const existing = logs[goalId];
|
|
6200
|
+
const path48 = existing?.path ?? goalRunLogPath(goalId, data);
|
|
6201
|
+
logs[goalId] = {
|
|
6202
|
+
path: path48,
|
|
6203
|
+
events: [
|
|
6204
|
+
...existing?.events ?? [],
|
|
6205
|
+
{
|
|
6206
|
+
version: 1,
|
|
6207
|
+
time: at,
|
|
6208
|
+
goalId,
|
|
6209
|
+
...event
|
|
6210
|
+
}
|
|
6211
|
+
]
|
|
6212
|
+
};
|
|
6213
|
+
}
|
|
6214
|
+
function flushGoalRunLogEvents(config, cwd, data) {
|
|
6215
|
+
const logs = goalRunLogs(data);
|
|
6216
|
+
for (const [goalId, log2] of Object.entries(logs)) {
|
|
6217
|
+
if (log2.events.length === 0) continue;
|
|
6218
|
+
const lines = `${log2.events.map((event) => JSON.stringify(enrichGoalRunLogEvent(config, data, log2.path, event))).join("\n")}
|
|
6219
|
+
`;
|
|
6220
|
+
appendStateLine(config, cwd, log2.path, lines, `chore(goal-logs): append ${goalId}`);
|
|
6221
|
+
log2.events = [];
|
|
6222
|
+
}
|
|
6223
|
+
}
|
|
6224
|
+
function goalRunLogPath(goalId, data) {
|
|
6225
|
+
const startedAt = goalRunStartedAt(data);
|
|
6226
|
+
const runId = goalRunId(data);
|
|
6227
|
+
return `logs/goals/${safePathSegment(goalId)}/runs/${startedAt}-${runId}.jsonl`;
|
|
6228
|
+
}
|
|
6229
|
+
function goalStateLogPath(goalId) {
|
|
6230
|
+
return `goals/instances/${safePathSegment(goalId)}/state.json`;
|
|
6231
|
+
}
|
|
6232
|
+
function goalRunLogSnapshot(goalId, goalState, goal) {
|
|
6233
|
+
const requiredEvidence = [...goal.destination.evidence];
|
|
6234
|
+
const pendingEvidence = typeof goal.facts.pendingEvidence === "string" ? goal.facts.pendingEvidence : void 0;
|
|
6235
|
+
return {
|
|
6236
|
+
id: goalId,
|
|
6237
|
+
type: goal.type,
|
|
6238
|
+
state: goalState,
|
|
6239
|
+
stage: goal.stage,
|
|
6240
|
+
outcome: goal.destination.outcome,
|
|
6241
|
+
requiredEvidence,
|
|
6242
|
+
satisfiedEvidence: requiredEvidence.filter((evidence) => goal.facts[evidence] === true),
|
|
6243
|
+
failedEvidence: requiredEvidence.filter((evidence) => goal.facts[evidence] === false),
|
|
6244
|
+
missingEvidence: requiredEvidence.filter((evidence) => goal.facts[evidence] !== true),
|
|
6245
|
+
pendingEvidence,
|
|
6246
|
+
agentResponsibilities: [...goal.agentResponsibilities],
|
|
6247
|
+
route: goal.route.map(routeStepForLog),
|
|
6248
|
+
schedule: goal.schedule,
|
|
6249
|
+
preferredRunTime: goal.preferredRunTime,
|
|
6250
|
+
loopTarget: goal.loopTarget,
|
|
6251
|
+
blockers: [...goal.blockers],
|
|
6252
|
+
facts: { ...goal.facts }
|
|
6253
|
+
};
|
|
6254
|
+
}
|
|
6255
|
+
function goalRunLogChange(before, after) {
|
|
6256
|
+
if (!before || !after) return void 0;
|
|
6257
|
+
const change = {};
|
|
6258
|
+
addScalarChange(change, "state", before.state, after.state);
|
|
6259
|
+
addScalarChange(change, "stage", before.stage, after.stage);
|
|
6260
|
+
addScalarChange(change, "pendingEvidence", before.pendingEvidence, after.pendingEvidence);
|
|
6261
|
+
const beforeFacts = recordValue2(before.facts);
|
|
6262
|
+
const afterFacts = recordValue2(after.facts);
|
|
6263
|
+
if (beforeFacts || afterFacts) change.facts = diffRecordKeys(beforeFacts ?? {}, afterFacts ?? {});
|
|
6264
|
+
const beforeBlockers = stringArrayValue(before.blockers);
|
|
6265
|
+
const afterBlockers = stringArrayValue(after.blockers);
|
|
6266
|
+
if (beforeBlockers || afterBlockers) {
|
|
6267
|
+
const blockers = diffStringArrays(beforeBlockers ?? [], afterBlockers ?? []);
|
|
6268
|
+
if (blockers.added.length > 0 || blockers.removed.length > 0) change.blockers = blockers;
|
|
6269
|
+
}
|
|
6270
|
+
const beforeSatisfied = stringArrayValue(before.satisfiedEvidence);
|
|
6271
|
+
const afterSatisfied = stringArrayValue(after.satisfiedEvidence);
|
|
6272
|
+
if (beforeSatisfied || afterSatisfied) {
|
|
6273
|
+
const evidence = diffStringArrays(beforeSatisfied ?? [], afterSatisfied ?? []);
|
|
6274
|
+
if (evidence.added.length > 0 || evidence.removed.length > 0) change.satisfiedEvidence = evidence;
|
|
6275
|
+
}
|
|
6276
|
+
return Object.keys(change).length > 0 ? change : void 0;
|
|
6277
|
+
}
|
|
6278
|
+
function goalRunLogs(data) {
|
|
6279
|
+
const existing = data[LOGS_KEY];
|
|
6280
|
+
if (existing && typeof existing === "object" && !Array.isArray(existing)) {
|
|
6281
|
+
return existing;
|
|
6282
|
+
}
|
|
6283
|
+
const logs = {};
|
|
6284
|
+
data[LOGS_KEY] = logs;
|
|
6285
|
+
return logs;
|
|
6286
|
+
}
|
|
6287
|
+
function goalRunStartedAt(data) {
|
|
6288
|
+
const existing = data[LOG_STARTED_KEY];
|
|
6289
|
+
if (typeof existing === "string" && existing.length > 0) return existing;
|
|
6290
|
+
const stamp = nowIso().replace(/[:.]/g, "-");
|
|
6291
|
+
data[LOG_STARTED_KEY] = stamp;
|
|
6292
|
+
return stamp;
|
|
6293
|
+
}
|
|
6294
|
+
function goalRunId(data) {
|
|
6295
|
+
const existing = data[LOG_RUN_KEY];
|
|
6296
|
+
if (typeof existing === "string" && existing.length > 0) return existing;
|
|
6297
|
+
const raw = stringValue(data.jobId) ?? githubRunId() ?? `local-${process.pid}-${Date.now()}`;
|
|
6298
|
+
const safe = safePathSegment(raw);
|
|
6299
|
+
data[LOG_RUN_KEY] = safe;
|
|
6300
|
+
return safe;
|
|
6301
|
+
}
|
|
6302
|
+
function githubRunId() {
|
|
6303
|
+
const runId = process.env.GITHUB_RUN_ID?.trim();
|
|
6304
|
+
if (!runId) return null;
|
|
6305
|
+
const attempt = process.env.GITHUB_RUN_ATTEMPT?.trim();
|
|
6306
|
+
return attempt ? `gh-${runId}-${attempt}` : `gh-${runId}`;
|
|
6307
|
+
}
|
|
6308
|
+
function enrichGoalRunLogEvent(config, data, logPath, event) {
|
|
6309
|
+
const stateRepo = stateRepoContext(config, event.goalId, logPath);
|
|
6310
|
+
return pruneUndefined({
|
|
6311
|
+
...event,
|
|
6312
|
+
run: event.run ?? runContext(data),
|
|
6313
|
+
repo: event.repo ?? repoContext(config),
|
|
6314
|
+
stateRepo: event.stateRepo ?? stateRepo,
|
|
6315
|
+
trigger: event.trigger ?? triggerContext(),
|
|
6316
|
+
job: event.job ?? jobContext(data),
|
|
6317
|
+
links: event.links ?? linkContext(stateRepo)
|
|
6318
|
+
});
|
|
6319
|
+
}
|
|
6320
|
+
function runContext(data) {
|
|
6321
|
+
const runId = process.env.GITHUB_RUN_ID?.trim();
|
|
6322
|
+
const attempt = process.env.GITHUB_RUN_ATTEMPT?.trim();
|
|
6323
|
+
const repository = process.env.GITHUB_REPOSITORY?.trim();
|
|
6324
|
+
const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
6325
|
+
return pruneUndefined({
|
|
6326
|
+
id: goalRunId(data),
|
|
6327
|
+
provider: runId ? "github-actions" : "local",
|
|
6328
|
+
githubRunId: runId || void 0,
|
|
6329
|
+
githubRunAttempt: attempt || void 0,
|
|
6330
|
+
workflow: process.env.GITHUB_WORKFLOW?.trim() || void 0,
|
|
6331
|
+
job: process.env.GITHUB_JOB?.trim() || void 0,
|
|
6332
|
+
url: runId && repository ? `${server}/${repository}/actions/runs/${runId}` : void 0,
|
|
6333
|
+
startedAt: data[LOG_STARTED_KEY]
|
|
6334
|
+
});
|
|
6335
|
+
}
|
|
6336
|
+
function repoContext(config) {
|
|
6337
|
+
const owner = config.github?.owner;
|
|
6338
|
+
const repo = config.github?.repo;
|
|
6339
|
+
return pruneUndefined({
|
|
6340
|
+
owner,
|
|
6341
|
+
repo,
|
|
6342
|
+
fullName: owner && repo ? `${owner}/${repo}` : process.env.GITHUB_REPOSITORY?.trim() || void 0,
|
|
6343
|
+
ref: process.env.GITHUB_REF?.trim() || void 0,
|
|
6344
|
+
sha: process.env.GITHUB_SHA?.trim() || void 0
|
|
6345
|
+
});
|
|
6346
|
+
}
|
|
6347
|
+
function stateRepoContext(config, goalId, logPath) {
|
|
6348
|
+
try {
|
|
6349
|
+
const state = resolveStateRepoConfig(config);
|
|
6350
|
+
return {
|
|
6351
|
+
repo: state.repo,
|
|
6352
|
+
path: state.path,
|
|
6353
|
+
goalStatePath: `${state.path}/${goalStateLogPath(goalId)}`,
|
|
6354
|
+
logPath: `${state.path}/${logPath}`
|
|
6355
|
+
};
|
|
6356
|
+
} catch {
|
|
6357
|
+
return void 0;
|
|
6358
|
+
}
|
|
6359
|
+
}
|
|
6360
|
+
function triggerContext() {
|
|
6361
|
+
const event = readGithubEvent();
|
|
6362
|
+
const inputs = recordValue2(event?.inputs);
|
|
6363
|
+
return pruneUndefined({
|
|
6364
|
+
eventName: process.env.GITHUB_EVENT_NAME?.trim() || void 0,
|
|
6365
|
+
actor: process.env.GITHUB_ACTOR?.trim() || void 0,
|
|
6366
|
+
eventPath: process.env.GITHUB_EVENT_PATH?.trim() || void 0,
|
|
6367
|
+
issue: numberValue(recordValue2(event?.issue)?.number),
|
|
6368
|
+
pullRequest: numberValue(recordValue2(event?.pull_request)?.number),
|
|
6369
|
+
comment: numberValue(recordValue2(event?.comment)?.id),
|
|
6370
|
+
schedule: stringValue(event?.schedule),
|
|
6371
|
+
inputs: inputs ? pickRecord(inputs, ["issue_number", "sessionId", "message", "model", "title", "agentAction", "base"]) : void 0
|
|
6372
|
+
});
|
|
6373
|
+
}
|
|
6374
|
+
function jobContext(data) {
|
|
6375
|
+
const job = pruneUndefined({
|
|
6376
|
+
id: stringValue(data.jobId),
|
|
6377
|
+
key: stringValue(data.jobKey),
|
|
6378
|
+
flavor: stringValue(data.jobFlavor),
|
|
6379
|
+
action: stringValue(data.jobAction),
|
|
6380
|
+
agentResponsibility: stringValue(data.jobAgentResponsibility),
|
|
6381
|
+
agentAction: stringValue(data.jobAgentAction),
|
|
6382
|
+
agent: stringValue(data.jobAgent),
|
|
6383
|
+
schedule: stringValue(data.jobSchedule),
|
|
6384
|
+
target: data.jobTarget,
|
|
6385
|
+
why: truncateString(stringValue(data.jobWhy), 1e3),
|
|
6386
|
+
saveReport: data.jobSaveReport === true ? true : void 0
|
|
6387
|
+
});
|
|
6388
|
+
return Object.keys(job).length > 0 ? job : void 0;
|
|
6389
|
+
}
|
|
6390
|
+
function linkContext(stateRepo) {
|
|
6391
|
+
const links = {};
|
|
6392
|
+
const runId = process.env.GITHUB_RUN_ID?.trim();
|
|
6393
|
+
const repository = process.env.GITHUB_REPOSITORY?.trim();
|
|
6394
|
+
const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
6395
|
+
if (runId && repository) links.workflowRun = `${server}/${repository}/actions/runs/${runId}`;
|
|
6396
|
+
const repo = stringValue(stateRepo?.repo);
|
|
6397
|
+
const goalStatePath = stringValue(stateRepo?.goalStatePath);
|
|
6398
|
+
const logPath = stringValue(stateRepo?.logPath);
|
|
6399
|
+
if (repo && goalStatePath) links.goalState = githubBlobUrl(repo, goalStatePath);
|
|
6400
|
+
if (repo && logPath) links.log = githubBlobUrl(repo, logPath);
|
|
6401
|
+
return Object.keys(links).length > 0 ? links : void 0;
|
|
6402
|
+
}
|
|
6403
|
+
function githubBlobUrl(repo, filePath) {
|
|
6404
|
+
try {
|
|
6405
|
+
const parsed = parseStateRepoSlug(repo);
|
|
6406
|
+
return `https://github.com/${parsed.owner}/${parsed.repo}/blob/main/${filePath}`;
|
|
6407
|
+
} catch {
|
|
6408
|
+
return void 0;
|
|
6409
|
+
}
|
|
6410
|
+
}
|
|
6411
|
+
function routeStepForLog(step) {
|
|
6412
|
+
return pruneUndefined({
|
|
6413
|
+
evidence: step.evidence,
|
|
6414
|
+
stage: step.stage,
|
|
6415
|
+
agentResponsibility: step.agentResponsibility,
|
|
6416
|
+
agentAction: step.agentAction,
|
|
6417
|
+
args: step.args,
|
|
6418
|
+
saveReport: step.saveReport === true ? true : void 0
|
|
6419
|
+
});
|
|
6420
|
+
}
|
|
6421
|
+
function readGithubEvent() {
|
|
6422
|
+
const eventPath = process.env.GITHUB_EVENT_PATH;
|
|
6423
|
+
if (!eventPath) return null;
|
|
6424
|
+
try {
|
|
6425
|
+
if (!fs25.existsSync(eventPath)) return null;
|
|
6426
|
+
const parsed = JSON.parse(fs25.readFileSync(eventPath, "utf-8"));
|
|
6427
|
+
return recordValue2(parsed);
|
|
6428
|
+
} catch {
|
|
6429
|
+
return null;
|
|
6430
|
+
}
|
|
6431
|
+
}
|
|
6432
|
+
function addScalarChange(change, field, before, after) {
|
|
6433
|
+
if (before === after) return;
|
|
6434
|
+
change[field] = pruneUndefined({ from: before, to: after });
|
|
6435
|
+
}
|
|
6436
|
+
function diffRecordKeys(before, after) {
|
|
6437
|
+
const beforeKeys = new Set(Object.keys(before));
|
|
6438
|
+
const afterKeys = new Set(Object.keys(after));
|
|
6439
|
+
const added = [...afterKeys].filter((key) => !beforeKeys.has(key)).sort();
|
|
6440
|
+
const removed = [...beforeKeys].filter((key) => !afterKeys.has(key)).sort();
|
|
6441
|
+
const changed = [...afterKeys].filter((key) => beforeKeys.has(key) && JSON.stringify(before[key]) !== JSON.stringify(after[key])).sort();
|
|
6442
|
+
return { added, removed, changed };
|
|
6443
|
+
}
|
|
6444
|
+
function diffStringArrays(before, after) {
|
|
6445
|
+
const beforeSet = new Set(before);
|
|
6446
|
+
const afterSet = new Set(after);
|
|
6447
|
+
return {
|
|
6448
|
+
added: after.filter((item) => !beforeSet.has(item)).sort(),
|
|
6449
|
+
removed: before.filter((item) => !afterSet.has(item)).sort()
|
|
6450
|
+
};
|
|
6451
|
+
}
|
|
6452
|
+
function recordValue2(value) {
|
|
6453
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
6454
|
+
}
|
|
6455
|
+
function stringArrayValue(value) {
|
|
6456
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? [...value] : null;
|
|
6457
|
+
}
|
|
6458
|
+
function numberValue(value) {
|
|
6459
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
6460
|
+
}
|
|
6461
|
+
function pickRecord(input, keys) {
|
|
6462
|
+
const out = {};
|
|
6463
|
+
for (const key of keys) {
|
|
6464
|
+
if (input[key] !== void 0 && input[key] !== "") out[key] = input[key];
|
|
6465
|
+
}
|
|
6466
|
+
return out;
|
|
6467
|
+
}
|
|
6468
|
+
function pruneUndefined(input) {
|
|
6469
|
+
for (const key of Object.keys(input)) {
|
|
6470
|
+
if (input[key] === void 0) delete input[key];
|
|
6471
|
+
}
|
|
6472
|
+
return input;
|
|
6473
|
+
}
|
|
6474
|
+
function truncateString(value, max) {
|
|
6475
|
+
if (!value) return void 0;
|
|
6476
|
+
return value.length > max ? `${value.slice(0, max)}...` : value;
|
|
6477
|
+
}
|
|
6478
|
+
function stringValue(value) {
|
|
6479
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
6480
|
+
}
|
|
6481
|
+
function safePathSegment(value) {
|
|
6482
|
+
const safe = value.trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6483
|
+
return safe || "unknown";
|
|
6484
|
+
}
|
|
6485
|
+
var LOGS_KEY, LOG_RUN_KEY, LOG_STARTED_KEY;
|
|
6486
|
+
var init_runLog = __esm({
|
|
6487
|
+
"src/goal/runLog.ts"() {
|
|
6488
|
+
"use strict";
|
|
6489
|
+
init_stateRepo();
|
|
6490
|
+
init_state2();
|
|
6491
|
+
LOGS_KEY = "__goalRunLogs";
|
|
6492
|
+
LOG_RUN_KEY = "__goalRunLogRunId";
|
|
6493
|
+
LOG_STARTED_KEY = "__goalRunLogStartedAt";
|
|
6494
|
+
}
|
|
6495
|
+
});
|
|
6496
|
+
|
|
6182
6497
|
// src/goal/typeDefinitions.ts
|
|
6183
6498
|
function cloneRoute(route) {
|
|
6184
6499
|
return route.map((step) => ({
|
|
@@ -6505,7 +6820,7 @@ var init_contentsApiBackend = __esm({
|
|
|
6505
6820
|
});
|
|
6506
6821
|
|
|
6507
6822
|
// src/scripts/jobState/localFileBackend.ts
|
|
6508
|
-
import * as
|
|
6823
|
+
import * as fs26 from "fs";
|
|
6509
6824
|
import * as path24 from "path";
|
|
6510
6825
|
function sanitizeKey(s) {
|
|
6511
6826
|
return s.replace(/[^A-Za-z0-9._-]/g, "-");
|
|
@@ -6577,7 +6892,7 @@ var init_localFileBackend = __esm({
|
|
|
6577
6892
|
`);
|
|
6578
6893
|
return;
|
|
6579
6894
|
}
|
|
6580
|
-
|
|
6895
|
+
fs26.mkdirSync(this.absDir, { recursive: true });
|
|
6581
6896
|
const prefix = this.cacheKeyPrefix();
|
|
6582
6897
|
const probeKey = `${prefix}probe-${Date.now()}`;
|
|
6583
6898
|
try {
|
|
@@ -6606,7 +6921,7 @@ var init_localFileBackend = __esm({
|
|
|
6606
6921
|
`);
|
|
6607
6922
|
return;
|
|
6608
6923
|
}
|
|
6609
|
-
if (!
|
|
6924
|
+
if (!fs26.existsSync(this.absDir)) {
|
|
6610
6925
|
return;
|
|
6611
6926
|
}
|
|
6612
6927
|
const key = `${this.cacheKeyPrefix()}${process.env.GITHUB_RUN_ID ?? "norunid"}-${Date.now()}`;
|
|
@@ -6623,10 +6938,10 @@ var init_localFileBackend = __esm({
|
|
|
6623
6938
|
load(slug2) {
|
|
6624
6939
|
const relPath = stateFilePath(this.jobsDir, slug2);
|
|
6625
6940
|
const absPath = path24.join(this.cwd, relPath);
|
|
6626
|
-
if (!
|
|
6941
|
+
if (!fs26.existsSync(absPath)) {
|
|
6627
6942
|
return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
|
|
6628
6943
|
}
|
|
6629
|
-
const raw =
|
|
6944
|
+
const raw = fs26.readFileSync(absPath, "utf-8");
|
|
6630
6945
|
let parsed;
|
|
6631
6946
|
try {
|
|
6632
6947
|
parsed = JSON.parse(raw);
|
|
@@ -6644,12 +6959,12 @@ var init_localFileBackend = __esm({
|
|
|
6644
6959
|
return false;
|
|
6645
6960
|
}
|
|
6646
6961
|
const absPath = path24.join(this.cwd, loaded.path);
|
|
6647
|
-
|
|
6962
|
+
fs26.mkdirSync(path24.dirname(absPath), { recursive: true });
|
|
6648
6963
|
const body = `${JSON.stringify(next, null, 2)}
|
|
6649
6964
|
`;
|
|
6650
6965
|
const tmpPath = `${absPath}.${process.pid}.tmp`;
|
|
6651
|
-
|
|
6652
|
-
|
|
6966
|
+
fs26.writeFileSync(tmpPath, body, "utf-8");
|
|
6967
|
+
fs26.renameSync(tmpPath, absPath);
|
|
6653
6968
|
return true;
|
|
6654
6969
|
}
|
|
6655
6970
|
cacheKeyPrefix() {
|
|
@@ -6918,6 +7233,87 @@ var init_goalAgentResponsibilityScheduling = __esm({
|
|
|
6918
7233
|
});
|
|
6919
7234
|
|
|
6920
7235
|
// src/scripts/advanceManagedGoal.ts
|
|
7236
|
+
function stageManagedGoalDecision(data, goalId, goal, goalState, decision, details) {
|
|
7237
|
+
if (decision.kind === "dispatch") {
|
|
7238
|
+
stageGoalRunLogEvent(data, goalId, {
|
|
7239
|
+
source: "goal-manager",
|
|
7240
|
+
event: "goal.tick.dispatch",
|
|
7241
|
+
goalType: goal.type,
|
|
7242
|
+
goalState,
|
|
7243
|
+
stage: decision.stage,
|
|
7244
|
+
evidence: decision.evidence,
|
|
7245
|
+
status: decision.kind,
|
|
7246
|
+
dispatch: {
|
|
7247
|
+
agentResponsibility: decision.agentResponsibility,
|
|
7248
|
+
agentAction: decision.agentAction,
|
|
7249
|
+
cliArgs: decision.cliArgs
|
|
7250
|
+
},
|
|
7251
|
+
goal: details.goalSnapshot,
|
|
7252
|
+
inspection: details.inspection,
|
|
7253
|
+
decision: {
|
|
7254
|
+
kind: decision.kind,
|
|
7255
|
+
evidence: decision.evidence,
|
|
7256
|
+
stage: decision.stage,
|
|
7257
|
+
agentResponsibility: decision.agentResponsibility,
|
|
7258
|
+
agentAction: decision.agentAction,
|
|
7259
|
+
cliArgs: decision.cliArgs
|
|
7260
|
+
},
|
|
7261
|
+
change: details.change
|
|
7262
|
+
});
|
|
7263
|
+
return;
|
|
7264
|
+
}
|
|
7265
|
+
if (decision.kind === "done") {
|
|
7266
|
+
stageGoalRunLogEvent(data, goalId, {
|
|
7267
|
+
source: "goal-manager",
|
|
7268
|
+
event: "goal.tick.done",
|
|
7269
|
+
goalType: goal.type,
|
|
7270
|
+
goalState: "done",
|
|
7271
|
+
stage: "done",
|
|
7272
|
+
status: decision.kind,
|
|
7273
|
+
reason: "managed goal complete",
|
|
7274
|
+
goal: details.goalSnapshot,
|
|
7275
|
+
inspection: details.inspection,
|
|
7276
|
+
decision: { kind: decision.kind, reason: "managed goal complete" },
|
|
7277
|
+
change: details.change
|
|
7278
|
+
});
|
|
7279
|
+
return;
|
|
7280
|
+
}
|
|
7281
|
+
if (decision.kind === "idle") {
|
|
7282
|
+
stageGoalRunLogEvent(data, goalId, {
|
|
7283
|
+
source: "goal-manager",
|
|
7284
|
+
event: "goal.tick.idle",
|
|
7285
|
+
goalType: goal.type,
|
|
7286
|
+
goalState,
|
|
7287
|
+
stage: goal.stage,
|
|
7288
|
+
status: decision.kind,
|
|
7289
|
+
reason: decision.reason,
|
|
7290
|
+
goal: details.goalSnapshot,
|
|
7291
|
+
inspection: details.inspection,
|
|
7292
|
+
decision: { kind: decision.kind, reason: decision.reason },
|
|
7293
|
+
change: details.change
|
|
7294
|
+
});
|
|
7295
|
+
return;
|
|
7296
|
+
}
|
|
7297
|
+
stageGoalRunLogEvent(data, goalId, {
|
|
7298
|
+
source: "goal-manager",
|
|
7299
|
+
event: `goal.tick.${decision.kind}`,
|
|
7300
|
+
goalType: goal.type,
|
|
7301
|
+
goalState,
|
|
7302
|
+
stage: decision.stage,
|
|
7303
|
+
evidence: decision.evidence,
|
|
7304
|
+
status: decision.kind,
|
|
7305
|
+
reason: decision.reason,
|
|
7306
|
+
goal: details.goalSnapshot,
|
|
7307
|
+
inspection: details.inspection,
|
|
7308
|
+
decision: {
|
|
7309
|
+
kind: decision.kind,
|
|
7310
|
+
evidence: decision.evidence,
|
|
7311
|
+
stage: decision.stage,
|
|
7312
|
+
reason: decision.reason
|
|
7313
|
+
},
|
|
7314
|
+
change: details.change
|
|
7315
|
+
});
|
|
7316
|
+
}
|
|
6921
7317
|
function readSimpleGoalTaskSummary(goalId, cwd) {
|
|
6922
7318
|
const raw = gh(
|
|
6923
7319
|
["issue", "list", "--state", "all", "--label", `goal:${goalId}`, "--limit", "1000", "--json", "number,state"],
|
|
@@ -6984,6 +7380,7 @@ var init_advanceManagedGoal = __esm({
|
|
|
6984
7380
|
"src/scripts/advanceManagedGoal.ts"() {
|
|
6985
7381
|
"use strict";
|
|
6986
7382
|
init_manager();
|
|
7383
|
+
init_runLog();
|
|
6987
7384
|
init_state2();
|
|
6988
7385
|
init_typeDefinitions();
|
|
6989
7386
|
init_issue();
|
|
@@ -7005,6 +7402,23 @@ var init_advanceManagedGoal = __esm({
|
|
|
7005
7402
|
}
|
|
7006
7403
|
const previousGoalIdFact = managed.facts.goalId;
|
|
7007
7404
|
managed.facts.goalId = goal.id;
|
|
7405
|
+
const startSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
|
|
7406
|
+
stageGoalRunLogEvent(ctx.data, goal.id, {
|
|
7407
|
+
source: "goal-manager",
|
|
7408
|
+
event: "goal.tick.start",
|
|
7409
|
+
goalType: managed.type,
|
|
7410
|
+
goalState: goal.state,
|
|
7411
|
+
stage: managed.stage,
|
|
7412
|
+
goal: startSnapshot,
|
|
7413
|
+
inspection: {
|
|
7414
|
+
requiredEvidence: startSnapshot.requiredEvidence,
|
|
7415
|
+
satisfiedEvidence: startSnapshot.satisfiedEvidence,
|
|
7416
|
+
missingEvidence: startSnapshot.missingEvidence,
|
|
7417
|
+
pendingEvidence: startSnapshot.pendingEvidence,
|
|
7418
|
+
blockers: startSnapshot.blockers
|
|
7419
|
+
},
|
|
7420
|
+
facts: managed.facts
|
|
7421
|
+
});
|
|
7008
7422
|
const restoreGoalIdFact = () => {
|
|
7009
7423
|
if (previousGoalIdFact === void 0) delete managed.facts.goalId;
|
|
7010
7424
|
else managed.facts.goalId = previousGoalIdFact;
|
|
@@ -7017,10 +7431,28 @@ var init_advanceManagedGoal = __esm({
|
|
|
7017
7431
|
if (!managed.blockers.includes(reason)) managed.blockers.push(reason);
|
|
7018
7432
|
restoreGoalIdFact();
|
|
7019
7433
|
goal.raw = writeManagedGoalToState({ ...goal.raw, state: goal.state }, managed);
|
|
7434
|
+
const blockedSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
|
|
7435
|
+
stageGoalRunLogEvent(ctx.data, goal.id, {
|
|
7436
|
+
source: "goal-manager",
|
|
7437
|
+
event: "goal.tick.blocked",
|
|
7438
|
+
goalType: managed.type,
|
|
7439
|
+
goalState: goal.state,
|
|
7440
|
+
stage: managed.stage,
|
|
7441
|
+
status: "blocked",
|
|
7442
|
+
reason,
|
|
7443
|
+
goal: blockedSnapshot,
|
|
7444
|
+
inspection: {
|
|
7445
|
+
purpose: "prepare goal issue fact before dispatch",
|
|
7446
|
+
routeNeedsIssueFact: true
|
|
7447
|
+
},
|
|
7448
|
+
decision: { kind: "blocked", reason },
|
|
7449
|
+
change: goalRunLogChange(startSnapshot, blockedSnapshot)
|
|
7450
|
+
});
|
|
7020
7451
|
ctx.output.reason = reason;
|
|
7021
7452
|
return;
|
|
7022
7453
|
}
|
|
7023
7454
|
if (isGoalTargetLoop(managed)) {
|
|
7455
|
+
const beforeSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
|
|
7024
7456
|
const previousScheduleState = goal.raw.extra.scheduleState && typeof goal.raw.extra.scheduleState === "object" ? goal.raw.extra.scheduleState : void 0;
|
|
7025
7457
|
const decision2 = planGoalTargetLoopSchedule({ goal: managed, previousScheduleState });
|
|
7026
7458
|
restoreGoalIdFact();
|
|
@@ -7034,10 +7466,41 @@ var init_advanceManagedGoal = __esm({
|
|
|
7034
7466
|
cliArgs: decision2.dispatch.cliArgs
|
|
7035
7467
|
};
|
|
7036
7468
|
}
|
|
7469
|
+
stageGoalRunLogEvent(ctx.data, goal.id, {
|
|
7470
|
+
source: "goal-manager",
|
|
7471
|
+
event: decision2.kind === "dispatch" ? "loop.tick.dispatch" : `loop.tick.${decision2.kind}`,
|
|
7472
|
+
goalType: managed.type,
|
|
7473
|
+
goalState: goal.state,
|
|
7474
|
+
stage: managed.stage,
|
|
7475
|
+
status: decision2.kind,
|
|
7476
|
+
reason: decision2.reason,
|
|
7477
|
+
target: decision2.dispatch?.cliArgs.goal && typeof decision2.dispatch.cliArgs.goal === "string" ? { type: "goal", id: decision2.dispatch.cliArgs.goal } : managed.loopTarget,
|
|
7478
|
+
dispatch: decision2.dispatch,
|
|
7479
|
+
goal: goalRunLogSnapshot(goal.id, goal.state, managed),
|
|
7480
|
+
inspection: {
|
|
7481
|
+
loopTarget: managed.loopTarget,
|
|
7482
|
+
preferredRunTime: managed.preferredRunTime,
|
|
7483
|
+
previousScheduleState,
|
|
7484
|
+
scheduleState: decision2.scheduleState
|
|
7485
|
+
},
|
|
7486
|
+
decision: {
|
|
7487
|
+
kind: decision2.kind,
|
|
7488
|
+
reason: decision2.reason,
|
|
7489
|
+
dispatch: decision2.dispatch
|
|
7490
|
+
},
|
|
7491
|
+
change: {
|
|
7492
|
+
...goalRunLogChange(beforeSnapshot, goalRunLogSnapshot(goal.id, goal.state, managed)) ?? {},
|
|
7493
|
+
scheduleState: {
|
|
7494
|
+
previousDecision: previousScheduleState?.lastDecision,
|
|
7495
|
+
nextDecision: decision2.scheduleState.lastDecision
|
|
7496
|
+
}
|
|
7497
|
+
}
|
|
7498
|
+
});
|
|
7037
7499
|
ctx.output.reason = decision2.reason;
|
|
7038
7500
|
return;
|
|
7039
7501
|
}
|
|
7040
7502
|
if (isAgentResponsibilityCadenceGoal(managed, goal.raw.extra)) {
|
|
7503
|
+
const beforeSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
|
|
7041
7504
|
const previousScheduleState = goal.raw.extra.scheduleState && typeof goal.raw.extra.scheduleState === "object" ? goal.raw.extra.scheduleState : void 0;
|
|
7042
7505
|
const decision2 = await planGoalAgentResponsibilitySchedule({
|
|
7043
7506
|
goal: managed,
|
|
@@ -7057,12 +7520,43 @@ var init_advanceManagedGoal = __esm({
|
|
|
7057
7520
|
...goal.raw.extra.saveReport === true ? { saveReport: true } : {}
|
|
7058
7521
|
};
|
|
7059
7522
|
}
|
|
7523
|
+
stageGoalRunLogEvent(ctx.data, goal.id, {
|
|
7524
|
+
source: "goal-manager",
|
|
7525
|
+
event: decision2.kind === "dispatch" ? "loop.tick.dispatch" : `loop.tick.${decision2.kind}`,
|
|
7526
|
+
goalType: managed.type,
|
|
7527
|
+
goalState: goal.state,
|
|
7528
|
+
stage: managed.stage,
|
|
7529
|
+
status: decision2.kind,
|
|
7530
|
+
reason: decision2.reason,
|
|
7531
|
+
dispatch: decision2.dispatch,
|
|
7532
|
+
goal: goalRunLogSnapshot(goal.id, goal.state, managed),
|
|
7533
|
+
inspection: {
|
|
7534
|
+
agentResponsibilities: decision2.scheduleState.agentResponsibilities,
|
|
7535
|
+
previousScheduleState,
|
|
7536
|
+
scheduleState: decision2.scheduleState
|
|
7537
|
+
},
|
|
7538
|
+
decision: {
|
|
7539
|
+
kind: decision2.kind,
|
|
7540
|
+
reason: decision2.reason,
|
|
7541
|
+
dispatch: decision2.dispatch
|
|
7542
|
+
},
|
|
7543
|
+
change: {
|
|
7544
|
+
...goalRunLogChange(beforeSnapshot, goalRunLogSnapshot(goal.id, goal.state, managed)) ?? {},
|
|
7545
|
+
scheduleState: {
|
|
7546
|
+
previousDecision: previousScheduleState?.lastDecision,
|
|
7547
|
+
nextDecision: decision2.scheduleState.lastDecision
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7550
|
+
});
|
|
7060
7551
|
ctx.output.reason = decision2.reason;
|
|
7061
7552
|
return;
|
|
7062
7553
|
}
|
|
7554
|
+
let simpleTaskSummary;
|
|
7063
7555
|
if (isSimpleGoal(managed)) {
|
|
7064
|
-
|
|
7556
|
+
simpleTaskSummary = readSimpleGoalTaskSummary(goal.id, ctx.cwd);
|
|
7557
|
+
applySimpleGoalTaskSummary(managed, simpleTaskSummary);
|
|
7065
7558
|
}
|
|
7559
|
+
const beforeDecisionSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
|
|
7066
7560
|
const decision = planManagedGoalTick(managed);
|
|
7067
7561
|
restoreGoalIdFact();
|
|
7068
7562
|
ctx.data.managedGoalDecision = decision;
|
|
@@ -7070,6 +7564,19 @@ var init_advanceManagedGoal = __esm({
|
|
|
7070
7564
|
goal.state = "done";
|
|
7071
7565
|
}
|
|
7072
7566
|
goal.raw = writeManagedGoalToState({ ...goal.raw, state: goal.state }, managed);
|
|
7567
|
+
const afterDecisionSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
|
|
7568
|
+
stageManagedGoalDecision(ctx.data, goal.id, managed, goal.state, decision, {
|
|
7569
|
+
goalSnapshot: afterDecisionSnapshot,
|
|
7570
|
+
inspection: {
|
|
7571
|
+
requiredEvidence: beforeDecisionSnapshot.requiredEvidence,
|
|
7572
|
+
satisfiedEvidence: beforeDecisionSnapshot.satisfiedEvidence,
|
|
7573
|
+
missingEvidence: beforeDecisionSnapshot.missingEvidence,
|
|
7574
|
+
pendingEvidence: beforeDecisionSnapshot.pendingEvidence,
|
|
7575
|
+
route: beforeDecisionSnapshot.route,
|
|
7576
|
+
simpleTaskSummary
|
|
7577
|
+
},
|
|
7578
|
+
change: goalRunLogChange(beforeDecisionSnapshot, afterDecisionSnapshot)
|
|
7579
|
+
});
|
|
7073
7580
|
if (decision.kind === "blocked" || decision.kind === "wait" || decision.kind === "idle" || decision.kind === "done") {
|
|
7074
7581
|
ctx.output.reason = decision.kind === "done" ? "managed goal complete" : decision.reason;
|
|
7075
7582
|
return;
|
|
@@ -7616,6 +8123,16 @@ var init_appendCompanyIntentDecision = __esm({
|
|
|
7616
8123
|
});
|
|
7617
8124
|
|
|
7618
8125
|
// src/scripts/applyAgentResponsibilityReports.ts
|
|
8126
|
+
function flushLogs(ctx) {
|
|
8127
|
+
try {
|
|
8128
|
+
flushGoalRunLogEvents(ctx.config, ctx.cwd, ctx.data);
|
|
8129
|
+
} catch (err) {
|
|
8130
|
+
process.stderr.write(
|
|
8131
|
+
`[kody agentResponsibility-report] goal log persist failed (${err instanceof Error ? err.message : String(err)})
|
|
8132
|
+
`
|
|
8133
|
+
);
|
|
8134
|
+
}
|
|
8135
|
+
}
|
|
7619
8136
|
function collectReports(raw, agentResult) {
|
|
7620
8137
|
const out = [];
|
|
7621
8138
|
if (Array.isArray(raw)) {
|
|
@@ -7657,6 +8174,76 @@ function completeSatisfiedManagedGoal(state) {
|
|
|
7657
8174
|
if (decision.kind !== "done") return state;
|
|
7658
8175
|
return writeManagedGoalToState({ ...state, state: "done" }, managed);
|
|
7659
8176
|
}
|
|
8177
|
+
function snapshotFromState(goalId, state) {
|
|
8178
|
+
const managed = managedGoalFromState(state);
|
|
8179
|
+
return managed ? goalRunLogSnapshot(goalId, state.state, managed) : null;
|
|
8180
|
+
}
|
|
8181
|
+
function responsibilityReportOutput(report, goalAfter) {
|
|
8182
|
+
const evidence = report.evidence ?? {};
|
|
8183
|
+
const values = Object.values(evidence);
|
|
8184
|
+
const status = values.some((value) => value === false) ? "fail" : values.length > 0 || report.facts ? "changed" : "noop";
|
|
8185
|
+
return {
|
|
8186
|
+
kind: "report",
|
|
8187
|
+
status,
|
|
8188
|
+
summary: "responsibility reported goal evidence",
|
|
8189
|
+
evidence,
|
|
8190
|
+
facts: report.facts ?? {},
|
|
8191
|
+
artifacts: [],
|
|
8192
|
+
missingEvidence: stringArrayField(goalAfter, "missingEvidence"),
|
|
8193
|
+
blockers: stringArrayField(goalAfter, "blockers")
|
|
8194
|
+
};
|
|
8195
|
+
}
|
|
8196
|
+
function responsibilityResultOutput(result) {
|
|
8197
|
+
return {
|
|
8198
|
+
kind: "result",
|
|
8199
|
+
status: result.status,
|
|
8200
|
+
summary: result.summary,
|
|
8201
|
+
facts: result.facts,
|
|
8202
|
+
artifacts: result.artifacts,
|
|
8203
|
+
missingEvidence: result.missingEvidence,
|
|
8204
|
+
blockers: result.blockers
|
|
8205
|
+
};
|
|
8206
|
+
}
|
|
8207
|
+
function evidenceInspection(goalBefore, goalAfter, responsibilityOutput, explicitEvidence) {
|
|
8208
|
+
return {
|
|
8209
|
+
expectedEvidence: {
|
|
8210
|
+
required: goalBefore?.requiredEvidence,
|
|
8211
|
+
missingBefore: goalBefore?.missingEvidence,
|
|
8212
|
+
pendingBefore: goalBefore?.pendingEvidence,
|
|
8213
|
+
explicit: explicitEvidence
|
|
8214
|
+
},
|
|
8215
|
+
responsibilityOutput,
|
|
8216
|
+
actualGoalState: {
|
|
8217
|
+
satisfiedEvidence: goalAfter?.satisfiedEvidence,
|
|
8218
|
+
missingEvidence: goalAfter?.missingEvidence,
|
|
8219
|
+
pendingEvidence: goalAfter?.pendingEvidence,
|
|
8220
|
+
blockers: goalAfter?.blockers
|
|
8221
|
+
}
|
|
8222
|
+
};
|
|
8223
|
+
}
|
|
8224
|
+
function evidenceDecision(change, goalAfter, responsibilityOutput) {
|
|
8225
|
+
return {
|
|
8226
|
+
kind: change ? "accept-evidence" : "no-state-change",
|
|
8227
|
+
status: responsibilityOutput.status,
|
|
8228
|
+
nextStep: nextStepFromEvidence(goalAfter, responsibilityOutput),
|
|
8229
|
+
reason: responsibilityOutput.summary
|
|
8230
|
+
};
|
|
8231
|
+
}
|
|
8232
|
+
function nextStepFromEvidence(goalAfter, responsibilityOutput) {
|
|
8233
|
+
const status = typeof responsibilityOutput.status === "string" ? responsibilityOutput.status : "";
|
|
8234
|
+
const outputBlockers = stringArrayField(responsibilityOutput, "blockers");
|
|
8235
|
+
const goalBlockers = stringArrayField(goalAfter, "blockers");
|
|
8236
|
+
const missingEvidence = stringArrayField(goalAfter, "missingEvidence");
|
|
8237
|
+
if (goalAfter && missingEvidence.length === 0) return "done";
|
|
8238
|
+
if (status === "fail" || status === "blocked" || outputBlockers.length > 0) return "rescue";
|
|
8239
|
+
if (goalBlockers.length > 0) return "block";
|
|
8240
|
+
if (missingEvidence.length > 0 && status !== "noop") return "dispatch";
|
|
8241
|
+
return "wait";
|
|
8242
|
+
}
|
|
8243
|
+
function stringArrayField(record2, key) {
|
|
8244
|
+
const value = record2?.[key];
|
|
8245
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
|
|
8246
|
+
}
|
|
7660
8247
|
function describeMessage(goalId, reports, results) {
|
|
7661
8248
|
const pieces = [];
|
|
7662
8249
|
if (reports && reports.length > 0) pieces.push(`report=${reports.length}`);
|
|
@@ -7670,6 +8257,7 @@ var init_applyAgentResponsibilityReports = __esm({
|
|
|
7670
8257
|
init_agent_responsibilityReport();
|
|
7671
8258
|
init_agent_responsibilityResult();
|
|
7672
8259
|
init_manager();
|
|
8260
|
+
init_runLog();
|
|
7673
8261
|
init_state2();
|
|
7674
8262
|
init_stateStore();
|
|
7675
8263
|
applyAgentResponsibilityReports = async (ctx, _profile, agentResult) => {
|
|
@@ -7683,22 +8271,99 @@ var init_applyAgentResponsibilityReports = __esm({
|
|
|
7683
8271
|
for (const goalId of goalIds) {
|
|
7684
8272
|
const prior = fetchGoalState(ctx.config, goalId, ctx.cwd);
|
|
7685
8273
|
if (!prior) {
|
|
8274
|
+
stageGoalRunLogEvent(ctx.data, goalId, {
|
|
8275
|
+
source: "goal-loop",
|
|
8276
|
+
event: "goal.evidence.rejected",
|
|
8277
|
+
status: "rejected",
|
|
8278
|
+
reason: "goal missing in state repo",
|
|
8279
|
+
inspection: {
|
|
8280
|
+
responsibilityOutput: {
|
|
8281
|
+
reports: reportsByGoal.get(goalId)?.length ?? 0,
|
|
8282
|
+
results: goalId === resultGoalId ? results.length : 0
|
|
8283
|
+
},
|
|
8284
|
+
missingEvidence: [],
|
|
8285
|
+
blockers: ["goal missing in state repo"]
|
|
8286
|
+
},
|
|
8287
|
+
decision: { kind: "reject-evidence", nextStep: "block", reason: "goal missing in state repo" }
|
|
8288
|
+
});
|
|
8289
|
+
flushLogs(ctx);
|
|
7686
8290
|
process.stderr.write(`[kody agentResponsibility-report] goal ${goalId} missing in state repo; report skipped
|
|
7687
8291
|
`);
|
|
7688
8292
|
continue;
|
|
7689
8293
|
}
|
|
7690
8294
|
let next = prior;
|
|
7691
8295
|
for (const report of reportsByGoal.get(goalId) ?? []) {
|
|
8296
|
+
const beforeSnapshot = snapshotFromState(goalId, next);
|
|
7692
8297
|
next = applyAgentResponsibilityReportToGoalState(next, report);
|
|
8298
|
+
const afterSnapshot = snapshotFromState(goalId, next);
|
|
8299
|
+
const change = goalRunLogChange(beforeSnapshot, afterSnapshot);
|
|
8300
|
+
const output = responsibilityReportOutput(report, afterSnapshot);
|
|
8301
|
+
stageGoalRunLogEvent(ctx.data, goalId, {
|
|
8302
|
+
source: "goal-loop",
|
|
8303
|
+
event: change ? "goal.evidence.applied" : "goal.evidence.unchanged",
|
|
8304
|
+
goalState: next.state,
|
|
8305
|
+
evidenceValues: report.evidence,
|
|
8306
|
+
facts: report.facts,
|
|
8307
|
+
goal: afterSnapshot ?? void 0,
|
|
8308
|
+
inspection: evidenceInspection(beforeSnapshot, afterSnapshot, output),
|
|
8309
|
+
decision: {
|
|
8310
|
+
...evidenceDecision(change, afterSnapshot, output),
|
|
8311
|
+
evidence: report.evidence
|
|
8312
|
+
},
|
|
8313
|
+
change
|
|
8314
|
+
});
|
|
7693
8315
|
}
|
|
7694
8316
|
if (goalId === resultGoalId) {
|
|
7695
8317
|
const evidence = typeof ctx.args.evidence === "string" && ctx.args.evidence.length > 0 ? ctx.args.evidence : void 0;
|
|
7696
8318
|
for (const result of results) {
|
|
8319
|
+
const beforeSnapshot = snapshotFromState(goalId, next);
|
|
7697
8320
|
next = applyAgentResponsibilityResultToObjectiveState(next, result, evidence);
|
|
8321
|
+
const afterSnapshot = snapshotFromState(goalId, next);
|
|
8322
|
+
const change = goalRunLogChange(beforeSnapshot, afterSnapshot);
|
|
8323
|
+
const output = responsibilityResultOutput(result);
|
|
8324
|
+
stageGoalRunLogEvent(ctx.data, goalId, {
|
|
8325
|
+
source: "goal-loop",
|
|
8326
|
+
event: change ? "goal.evidence.applied" : "goal.evidence.unchanged",
|
|
8327
|
+
goalState: next.state,
|
|
8328
|
+
evidence,
|
|
8329
|
+
status: result.status,
|
|
8330
|
+
reason: result.summary,
|
|
8331
|
+
facts: result.facts,
|
|
8332
|
+
artifacts: result.artifacts,
|
|
8333
|
+
goal: afterSnapshot ?? beforeSnapshot ?? void 0,
|
|
8334
|
+
inspection: evidenceInspection(beforeSnapshot, afterSnapshot, output, evidence),
|
|
8335
|
+
decision: {
|
|
8336
|
+
...evidenceDecision(change, afterSnapshot, output),
|
|
8337
|
+
evidence
|
|
8338
|
+
},
|
|
8339
|
+
change
|
|
8340
|
+
});
|
|
7698
8341
|
}
|
|
7699
8342
|
}
|
|
8343
|
+
const beforeCompletionSnapshot = snapshotFromState(goalId, next);
|
|
7700
8344
|
next = completeSatisfiedManagedGoal(next);
|
|
7701
|
-
|
|
8345
|
+
const afterCompletionSnapshot = snapshotFromState(goalId, next);
|
|
8346
|
+
if (prior.state !== "done" && next.state === "done") {
|
|
8347
|
+
stageGoalRunLogEvent(ctx.data, goalId, {
|
|
8348
|
+
source: "goal-loop",
|
|
8349
|
+
event: "goal.decision.done",
|
|
8350
|
+
goalState: "done",
|
|
8351
|
+
status: "done",
|
|
8352
|
+
reason: "destination evidence satisfied",
|
|
8353
|
+
goal: afterCompletionSnapshot ?? void 0,
|
|
8354
|
+
inspection: {
|
|
8355
|
+
requiredEvidence: beforeCompletionSnapshot?.requiredEvidence,
|
|
8356
|
+
satisfiedEvidence: beforeCompletionSnapshot?.satisfiedEvidence,
|
|
8357
|
+
missingEvidence: beforeCompletionSnapshot?.missingEvidence
|
|
8358
|
+
},
|
|
8359
|
+
decision: { kind: "done", nextStep: "done", reason: "destination evidence satisfied" },
|
|
8360
|
+
change: goalRunLogChange(beforeCompletionSnapshot, afterCompletionSnapshot)
|
|
8361
|
+
});
|
|
8362
|
+
}
|
|
8363
|
+
if (serializeGoalState(next) === serializeGoalState(prior)) {
|
|
8364
|
+
flushLogs(ctx);
|
|
8365
|
+
continue;
|
|
8366
|
+
}
|
|
7702
8367
|
putGoalState(
|
|
7703
8368
|
ctx.config,
|
|
7704
8369
|
goalId,
|
|
@@ -7706,6 +8371,7 @@ var init_applyAgentResponsibilityReports = __esm({
|
|
|
7706
8371
|
describeMessage(goalId, reportsByGoal.get(goalId), results),
|
|
7707
8372
|
ctx.cwd
|
|
7708
8373
|
);
|
|
8374
|
+
flushLogs(ctx);
|
|
7709
8375
|
}
|
|
7710
8376
|
};
|
|
7711
8377
|
}
|
|
@@ -7877,7 +8543,7 @@ var init_classifyByLabel = __esm({
|
|
|
7877
8543
|
});
|
|
7878
8544
|
|
|
7879
8545
|
// src/scripts/commitAndPush.ts
|
|
7880
|
-
import * as
|
|
8546
|
+
import * as fs27 from "fs";
|
|
7881
8547
|
import * as path26 from "path";
|
|
7882
8548
|
function sentinelPathForStage(cwd, profileName) {
|
|
7883
8549
|
const runId = resolveRunId();
|
|
@@ -7899,9 +8565,9 @@ var init_commitAndPush = __esm({
|
|
|
7899
8565
|
}
|
|
7900
8566
|
const idempotencyEnabled = process.env.KODY_COMMIT_IDEMPOTENCY !== "0";
|
|
7901
8567
|
const sentinel = idempotencyEnabled ? sentinelPathForStage(ctx.cwd, profile.name) : null;
|
|
7902
|
-
if (sentinel &&
|
|
8568
|
+
if (sentinel && fs27.existsSync(sentinel)) {
|
|
7903
8569
|
try {
|
|
7904
|
-
const replay = JSON.parse(
|
|
8570
|
+
const replay = JSON.parse(fs27.readFileSync(sentinel, "utf-8"));
|
|
7905
8571
|
ctx.data.commitResult = replay.commitResult ?? { committed: false, pushed: false };
|
|
7906
8572
|
if (Array.isArray(replay.changedFiles)) ctx.data.changedFiles = replay.changedFiles;
|
|
7907
8573
|
if (typeof replay.hasCommitsAhead === "boolean") ctx.data.hasCommitsAhead = replay.hasCommitsAhead;
|
|
@@ -7954,8 +8620,8 @@ var init_commitAndPush = __esm({
|
|
|
7954
8620
|
const result = ctx.data.commitResult;
|
|
7955
8621
|
if (sentinel && result?.committed) {
|
|
7956
8622
|
try {
|
|
7957
|
-
|
|
7958
|
-
|
|
8623
|
+
fs27.mkdirSync(path26.dirname(sentinel), { recursive: true });
|
|
8624
|
+
fs27.writeFileSync(
|
|
7959
8625
|
sentinel,
|
|
7960
8626
|
JSON.stringify(
|
|
7961
8627
|
{
|
|
@@ -7977,6 +8643,16 @@ var init_commitAndPush = __esm({
|
|
|
7977
8643
|
});
|
|
7978
8644
|
|
|
7979
8645
|
// src/scripts/commitGoalState.ts
|
|
8646
|
+
function flushLogs2(ctx) {
|
|
8647
|
+
try {
|
|
8648
|
+
flushGoalRunLogEvents(ctx.config, ctx.cwd, ctx.data);
|
|
8649
|
+
} catch (err) {
|
|
8650
|
+
process.stderr.write(
|
|
8651
|
+
`[goal-manager] goal log persist failed (${err instanceof Error ? err.message : String(err)})
|
|
8652
|
+
`
|
|
8653
|
+
);
|
|
8654
|
+
}
|
|
8655
|
+
}
|
|
7980
8656
|
function describeCommitMessage(goal) {
|
|
7981
8657
|
if (goal.state === "done") return `chore(goals): complete ${goal.id}`;
|
|
7982
8658
|
return `chore(goals): update ${goal.id}`;
|
|
@@ -7985,13 +8661,23 @@ var commitGoalState;
|
|
|
7985
8661
|
var init_commitGoalState = __esm({
|
|
7986
8662
|
"src/scripts/commitGoalState.ts"() {
|
|
7987
8663
|
"use strict";
|
|
8664
|
+
init_runLog();
|
|
7988
8665
|
init_stateStore();
|
|
7989
8666
|
commitGoalState = async (ctx) => {
|
|
7990
8667
|
const goal = ctx.data.goal;
|
|
7991
|
-
if (!goal)
|
|
7992
|
-
|
|
8668
|
+
if (!goal) {
|
|
8669
|
+
flushLogs2(ctx);
|
|
8670
|
+
return;
|
|
8671
|
+
}
|
|
8672
|
+
if (ctx.data.goalPersistChanged !== true) {
|
|
8673
|
+
flushLogs2(ctx);
|
|
8674
|
+
return;
|
|
8675
|
+
}
|
|
7993
8676
|
const updated = ctx.data.goalPersistState;
|
|
7994
|
-
if (!updated)
|
|
8677
|
+
if (!updated) {
|
|
8678
|
+
flushLogs2(ctx);
|
|
8679
|
+
return;
|
|
8680
|
+
}
|
|
7995
8681
|
try {
|
|
7996
8682
|
putGoalState(ctx.config, goal.id, updated, describeCommitMessage(goal), ctx.cwd);
|
|
7997
8683
|
} catch (err) {
|
|
@@ -7999,13 +8685,15 @@ var init_commitGoalState = __esm({
|
|
|
7999
8685
|
`[goal-manager] commitGoalState: persist to state repo failed (${err instanceof Error ? err.message : String(err)}); will retry next tick
|
|
8000
8686
|
`
|
|
8001
8687
|
);
|
|
8688
|
+
} finally {
|
|
8689
|
+
flushLogs2(ctx);
|
|
8002
8690
|
}
|
|
8003
8691
|
};
|
|
8004
8692
|
}
|
|
8005
8693
|
});
|
|
8006
8694
|
|
|
8007
8695
|
// src/scripts/composePrompt.ts
|
|
8008
|
-
import * as
|
|
8696
|
+
import * as fs28 from "fs";
|
|
8009
8697
|
import * as path27 from "path";
|
|
8010
8698
|
function fenceUntrusted(value) {
|
|
8011
8699
|
if (value.trim().length === 0) return value;
|
|
@@ -8145,7 +8833,7 @@ var init_composePrompt = __esm({
|
|
|
8145
8833
|
break;
|
|
8146
8834
|
}
|
|
8147
8835
|
try {
|
|
8148
|
-
template =
|
|
8836
|
+
template = fs28.readFileSync(c, "utf-8");
|
|
8149
8837
|
templatePath = c;
|
|
8150
8838
|
break;
|
|
8151
8839
|
} catch (err) {
|
|
@@ -8156,7 +8844,7 @@ var init_composePrompt = __esm({
|
|
|
8156
8844
|
if (!templatePath) {
|
|
8157
8845
|
let dirState;
|
|
8158
8846
|
try {
|
|
8159
|
-
dirState = `dir contents: [${
|
|
8847
|
+
dirState = `dir contents: [${fs28.readdirSync(profile.dir).join(", ")}]`;
|
|
8160
8848
|
} catch (err) {
|
|
8161
8849
|
dirState = `readdir(${profile.dir}) failed: ${err?.code ?? String(err)}`;
|
|
8162
8850
|
}
|
|
@@ -8728,7 +9416,7 @@ var init_deriveQaScopeFromIssue = __esm({
|
|
|
8728
9416
|
|
|
8729
9417
|
// src/scripts/diagMcp.ts
|
|
8730
9418
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
8731
|
-
import * as
|
|
9419
|
+
import * as fs29 from "fs";
|
|
8732
9420
|
import * as os6 from "os";
|
|
8733
9421
|
import * as path28 from "path";
|
|
8734
9422
|
var diagMcp;
|
|
@@ -8740,7 +9428,7 @@ var init_diagMcp = __esm({
|
|
|
8740
9428
|
const cacheDir = path28.join(home, ".cache", "ms-playwright");
|
|
8741
9429
|
let entries = [];
|
|
8742
9430
|
try {
|
|
8743
|
-
entries =
|
|
9431
|
+
entries = fs29.readdirSync(cacheDir);
|
|
8744
9432
|
} catch {
|
|
8745
9433
|
}
|
|
8746
9434
|
const hasChromium = entries.some((e) => e.startsWith("chromium"));
|
|
@@ -8768,13 +9456,13 @@ var init_diagMcp = __esm({
|
|
|
8768
9456
|
});
|
|
8769
9457
|
|
|
8770
9458
|
// src/scripts/frameworkDetectors.ts
|
|
8771
|
-
import * as
|
|
9459
|
+
import * as fs30 from "fs";
|
|
8772
9460
|
import * as path29 from "path";
|
|
8773
9461
|
function detectFrameworks(cwd) {
|
|
8774
9462
|
const out = [];
|
|
8775
9463
|
let deps = {};
|
|
8776
9464
|
try {
|
|
8777
|
-
const pkg = JSON.parse(
|
|
9465
|
+
const pkg = JSON.parse(fs30.readFileSync(path29.join(cwd, "package.json"), "utf-8"));
|
|
8778
9466
|
deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
8779
9467
|
} catch {
|
|
8780
9468
|
return out;
|
|
@@ -8811,7 +9499,7 @@ function detectFrameworks(cwd) {
|
|
|
8811
9499
|
}
|
|
8812
9500
|
function findFile(cwd, candidates) {
|
|
8813
9501
|
for (const c of candidates) {
|
|
8814
|
-
if (
|
|
9502
|
+
if (fs30.existsSync(path29.join(cwd, c))) return c;
|
|
8815
9503
|
}
|
|
8816
9504
|
return null;
|
|
8817
9505
|
}
|
|
@@ -8819,17 +9507,17 @@ function discoverPayloadCollections(cwd) {
|
|
|
8819
9507
|
const out = [];
|
|
8820
9508
|
for (const dir of COLLECTION_DIRS) {
|
|
8821
9509
|
const full = path29.join(cwd, dir);
|
|
8822
|
-
if (!
|
|
9510
|
+
if (!fs30.existsSync(full)) continue;
|
|
8823
9511
|
let files;
|
|
8824
9512
|
try {
|
|
8825
|
-
files =
|
|
9513
|
+
files = fs30.readdirSync(full).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
|
|
8826
9514
|
} catch {
|
|
8827
9515
|
continue;
|
|
8828
9516
|
}
|
|
8829
9517
|
for (const file of files) {
|
|
8830
9518
|
try {
|
|
8831
9519
|
const filePath = path29.join(full, file);
|
|
8832
|
-
const content =
|
|
9520
|
+
const content = fs30.readFileSync(filePath, "utf-8").slice(0, 1e4);
|
|
8833
9521
|
const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
|
|
8834
9522
|
if (!slugMatch) continue;
|
|
8835
9523
|
const slug2 = slugMatch[1];
|
|
@@ -8857,10 +9545,10 @@ function discoverAdminComponents(cwd, collections) {
|
|
|
8857
9545
|
const out = [];
|
|
8858
9546
|
for (const dir of ADMIN_COMPONENT_DIRS) {
|
|
8859
9547
|
const full = path29.join(cwd, dir);
|
|
8860
|
-
if (!
|
|
9548
|
+
if (!fs30.existsSync(full)) continue;
|
|
8861
9549
|
let entries;
|
|
8862
9550
|
try {
|
|
8863
|
-
entries =
|
|
9551
|
+
entries = fs30.readdirSync(full, { withFileTypes: true });
|
|
8864
9552
|
} catch {
|
|
8865
9553
|
continue;
|
|
8866
9554
|
}
|
|
@@ -8870,7 +9558,7 @@ function discoverAdminComponents(cwd, collections) {
|
|
|
8870
9558
|
let filePath;
|
|
8871
9559
|
if (entry.isDirectory()) {
|
|
8872
9560
|
const indexFile = ["index.tsx", "index.ts", "index.jsx", "index.js"].find(
|
|
8873
|
-
(f) =>
|
|
9561
|
+
(f) => fs30.existsSync(path29.join(entryPath, f))
|
|
8874
9562
|
);
|
|
8875
9563
|
if (!indexFile) continue;
|
|
8876
9564
|
name = entry.name;
|
|
@@ -8885,7 +9573,7 @@ function discoverAdminComponents(cwd, collections) {
|
|
|
8885
9573
|
if (collections) {
|
|
8886
9574
|
for (const col of collections) {
|
|
8887
9575
|
try {
|
|
8888
|
-
const colContent =
|
|
9576
|
+
const colContent = fs30.readFileSync(path29.join(cwd, col.filePath), "utf-8");
|
|
8889
9577
|
if (colContent.includes(name)) {
|
|
8890
9578
|
usedInCollection = col.slug;
|
|
8891
9579
|
break;
|
|
@@ -8904,7 +9592,7 @@ function scanApiRoutes(cwd) {
|
|
|
8904
9592
|
const appDirs = ["src/app", "app"];
|
|
8905
9593
|
for (const appDir of appDirs) {
|
|
8906
9594
|
const apiDir = path29.join(cwd, appDir, "api");
|
|
8907
|
-
if (!
|
|
9595
|
+
if (!fs30.existsSync(apiDir)) continue;
|
|
8908
9596
|
walkApiRoutes(apiDir, "/api", cwd, out);
|
|
8909
9597
|
break;
|
|
8910
9598
|
}
|
|
@@ -8913,14 +9601,14 @@ function scanApiRoutes(cwd) {
|
|
|
8913
9601
|
function walkApiRoutes(dir, prefix, cwd, out) {
|
|
8914
9602
|
let entries;
|
|
8915
9603
|
try {
|
|
8916
|
-
entries =
|
|
9604
|
+
entries = fs30.readdirSync(dir, { withFileTypes: true });
|
|
8917
9605
|
} catch {
|
|
8918
9606
|
return;
|
|
8919
9607
|
}
|
|
8920
9608
|
const routeFile = entries.find((e) => e.isFile() && /^route\.(ts|js|tsx|jsx)$/.test(e.name));
|
|
8921
9609
|
if (routeFile) {
|
|
8922
9610
|
try {
|
|
8923
|
-
const content =
|
|
9611
|
+
const content = fs30.readFileSync(path29.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
|
|
8924
9612
|
const methods = HTTP_METHODS.filter(
|
|
8925
9613
|
(m) => new RegExp(`export\\s+(?:async\\s+)?function\\s+${m}\\b`).test(content)
|
|
8926
9614
|
);
|
|
@@ -8954,9 +9642,9 @@ function scanEnvVars(cwd) {
|
|
|
8954
9642
|
const candidates = [".env.example", ".env.local.example", ".env.template"];
|
|
8955
9643
|
for (const envFile of candidates) {
|
|
8956
9644
|
const envPath = path29.join(cwd, envFile);
|
|
8957
|
-
if (!
|
|
9645
|
+
if (!fs30.existsSync(envPath)) continue;
|
|
8958
9646
|
try {
|
|
8959
|
-
const content =
|
|
9647
|
+
const content = fs30.readFileSync(envPath, "utf-8");
|
|
8960
9648
|
const vars = [];
|
|
8961
9649
|
for (const line of content.split("\n")) {
|
|
8962
9650
|
const trimmed = line.trim();
|
|
@@ -9001,7 +9689,7 @@ var init_frameworkDetectors = __esm({
|
|
|
9001
9689
|
});
|
|
9002
9690
|
|
|
9003
9691
|
// src/scripts/discoverQaContext.ts
|
|
9004
|
-
import * as
|
|
9692
|
+
import * as fs31 from "fs";
|
|
9005
9693
|
import * as path30 from "path";
|
|
9006
9694
|
function runQaDiscovery(cwd) {
|
|
9007
9695
|
const out = {
|
|
@@ -9033,9 +9721,9 @@ function runQaDiscovery(cwd) {
|
|
|
9033
9721
|
}
|
|
9034
9722
|
function detectDevServer(cwd, out) {
|
|
9035
9723
|
try {
|
|
9036
|
-
const pkg = JSON.parse(
|
|
9724
|
+
const pkg = JSON.parse(fs31.readFileSync(path30.join(cwd, "package.json"), "utf-8"));
|
|
9037
9725
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
9038
|
-
const pm =
|
|
9726
|
+
const pm = fs31.existsSync(path30.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs31.existsSync(path30.join(cwd, "yarn.lock")) ? "yarn" : fs31.existsSync(path30.join(cwd, "bun.lockb")) ? "bun" : "npm";
|
|
9039
9727
|
if (pkg.scripts?.dev) out.devCommand = `${pm} dev`;
|
|
9040
9728
|
if (allDeps.next || allDeps.nuxt) out.devPort = 3e3;
|
|
9041
9729
|
else if (allDeps.vite) out.devPort = 5173;
|
|
@@ -9046,7 +9734,7 @@ function scanFrontendRoutes(cwd, out) {
|
|
|
9046
9734
|
const appDirs = ["src/app", "app"];
|
|
9047
9735
|
for (const appDir of appDirs) {
|
|
9048
9736
|
const full = path30.join(cwd, appDir);
|
|
9049
|
-
if (!
|
|
9737
|
+
if (!fs31.existsSync(full)) continue;
|
|
9050
9738
|
walkFrontendRoutes(full, "", out);
|
|
9051
9739
|
break;
|
|
9052
9740
|
}
|
|
@@ -9054,7 +9742,7 @@ function scanFrontendRoutes(cwd, out) {
|
|
|
9054
9742
|
function walkFrontendRoutes(dir, prefix, out) {
|
|
9055
9743
|
let entries;
|
|
9056
9744
|
try {
|
|
9057
|
-
entries =
|
|
9745
|
+
entries = fs31.readdirSync(dir, { withFileTypes: true });
|
|
9058
9746
|
} catch {
|
|
9059
9747
|
return;
|
|
9060
9748
|
}
|
|
@@ -9096,23 +9784,23 @@ function detectAuthFiles(cwd, out) {
|
|
|
9096
9784
|
"src/app/api/oauth"
|
|
9097
9785
|
];
|
|
9098
9786
|
for (const c of candidates) {
|
|
9099
|
-
if (
|
|
9787
|
+
if (fs31.existsSync(path30.join(cwd, c))) out.authFiles.push(c);
|
|
9100
9788
|
}
|
|
9101
9789
|
}
|
|
9102
9790
|
function detectRoles(cwd, out) {
|
|
9103
9791
|
const rolePaths = ["src/types", "src/lib", "src/utils", "src/constants", "src/access", "src/collections"];
|
|
9104
9792
|
for (const rp of rolePaths) {
|
|
9105
9793
|
const dir = path30.join(cwd, rp);
|
|
9106
|
-
if (!
|
|
9794
|
+
if (!fs31.existsSync(dir)) continue;
|
|
9107
9795
|
let files;
|
|
9108
9796
|
try {
|
|
9109
|
-
files =
|
|
9797
|
+
files = fs31.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
|
|
9110
9798
|
} catch {
|
|
9111
9799
|
continue;
|
|
9112
9800
|
}
|
|
9113
9801
|
for (const f of files) {
|
|
9114
9802
|
try {
|
|
9115
|
-
const content =
|
|
9803
|
+
const content = fs31.readFileSync(path30.join(dir, f), "utf-8").slice(0, 5e3);
|
|
9116
9804
|
const roleMatches = content.match(/(?:role|Role|ROLE)\s*[=:]\s*['"](\w+)['"]/g);
|
|
9117
9805
|
if (roleMatches) {
|
|
9118
9806
|
for (const m of roleMatches) {
|
|
@@ -10326,12 +11014,12 @@ var init_fixFlow = __esm({
|
|
|
10326
11014
|
|
|
10327
11015
|
// src/scripts/initFlow.ts
|
|
10328
11016
|
import { execFileSync as execFileSync15 } from "child_process";
|
|
10329
|
-
import * as
|
|
11017
|
+
import * as fs32 from "fs";
|
|
10330
11018
|
import * as path31 from "path";
|
|
10331
11019
|
function detectPackageManager(cwd) {
|
|
10332
|
-
if (
|
|
10333
|
-
if (
|
|
10334
|
-
if (
|
|
11020
|
+
if (fs32.existsSync(path31.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
11021
|
+
if (fs32.existsSync(path31.join(cwd, "yarn.lock"))) return "yarn";
|
|
11022
|
+
if (fs32.existsSync(path31.join(cwd, "bun.lockb"))) return "bun";
|
|
10335
11023
|
return "npm";
|
|
10336
11024
|
}
|
|
10337
11025
|
function qualityCommandsFor(pm) {
|
|
@@ -10404,21 +11092,21 @@ function performInit(cwd, force) {
|
|
|
10404
11092
|
const ownerRepo = detectOwnerRepo(cwd);
|
|
10405
11093
|
const defaultBranch = defaultBranchFromGit(cwd);
|
|
10406
11094
|
const configPath = path31.join(cwd, "kody.config.json");
|
|
10407
|
-
if (
|
|
11095
|
+
if (fs32.existsSync(configPath) && !force) {
|
|
10408
11096
|
skipped.push("kody.config.json");
|
|
10409
11097
|
} else {
|
|
10410
11098
|
const cfg = makeConfig(pm, ownerRepo, defaultBranch);
|
|
10411
|
-
|
|
11099
|
+
fs32.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
|
|
10412
11100
|
`);
|
|
10413
11101
|
wrote.push("kody.config.json");
|
|
10414
11102
|
}
|
|
10415
11103
|
const workflowDir = path31.join(cwd, ".github", "workflows");
|
|
10416
11104
|
const workflowPath = path31.join(workflowDir, "kody.yml");
|
|
10417
|
-
if (
|
|
11105
|
+
if (fs32.existsSync(workflowPath) && !force) {
|
|
10418
11106
|
skipped.push(".github/workflows/kody.yml");
|
|
10419
11107
|
} else {
|
|
10420
|
-
|
|
10421
|
-
|
|
11108
|
+
fs32.mkdirSync(workflowDir, { recursive: true });
|
|
11109
|
+
fs32.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
|
|
10422
11110
|
wrote.push(".github/workflows/kody.yml");
|
|
10423
11111
|
}
|
|
10424
11112
|
for (const exe of listAgentActions()) {
|
|
@@ -10430,11 +11118,11 @@ function performInit(cwd, force) {
|
|
|
10430
11118
|
}
|
|
10431
11119
|
if (profile.kind !== "scheduled" || !profile.schedule) continue;
|
|
10432
11120
|
const target = path31.join(workflowDir, `kody-${exe.name}.yml`);
|
|
10433
|
-
if (
|
|
11121
|
+
if (fs32.existsSync(target) && !force) {
|
|
10434
11122
|
skipped.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
10435
11123
|
continue;
|
|
10436
11124
|
}
|
|
10437
|
-
|
|
11125
|
+
fs32.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
|
|
10438
11126
|
wrote.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
10439
11127
|
}
|
|
10440
11128
|
let labels;
|
|
@@ -10587,7 +11275,7 @@ Nothing to do. All files already present. (Use --force to overwrite.)
|
|
|
10587
11275
|
});
|
|
10588
11276
|
|
|
10589
11277
|
// src/scripts/loadAgentAdhoc.ts
|
|
10590
|
-
import * as
|
|
11278
|
+
import * as fs33 from "fs";
|
|
10591
11279
|
function resolveMessage(messageArg) {
|
|
10592
11280
|
const fromComment = readCommentBody();
|
|
10593
11281
|
if (fromComment) return stripDirective(fromComment);
|
|
@@ -10595,9 +11283,9 @@ function resolveMessage(messageArg) {
|
|
|
10595
11283
|
}
|
|
10596
11284
|
function readCommentBody() {
|
|
10597
11285
|
const eventPath = process.env.GITHUB_EVENT_PATH;
|
|
10598
|
-
if (!eventPath || !
|
|
11286
|
+
if (!eventPath || !fs33.existsSync(eventPath)) return "";
|
|
10599
11287
|
try {
|
|
10600
|
-
const event = JSON.parse(
|
|
11288
|
+
const event = JSON.parse(fs33.readFileSync(eventPath, "utf-8"));
|
|
10601
11289
|
return String(event.comment?.body ?? "");
|
|
10602
11290
|
} catch {
|
|
10603
11291
|
return "";
|
|
@@ -10650,10 +11338,10 @@ var init_loadAgentAdhoc = __esm({
|
|
|
10650
11338
|
throw new Error("loadAgentAdhoc: ctx.args.agent must be a non-empty slug");
|
|
10651
11339
|
}
|
|
10652
11340
|
const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
|
|
10653
|
-
if (!
|
|
11341
|
+
if (!fs33.existsSync(agentPath)) {
|
|
10654
11342
|
throw new Error(`loadAgentAdhoc: agent identity not found: ${agentPath}`);
|
|
10655
11343
|
}
|
|
10656
|
-
const { title, body } = parseAgentFile(
|
|
11344
|
+
const { title, body } = parseAgentFile(fs33.readFileSync(agentPath, "utf-8"), agentSlug);
|
|
10657
11345
|
const message = resolveMessage(ctx.args.message);
|
|
10658
11346
|
if (!message) {
|
|
10659
11347
|
throw new Error(
|
|
@@ -10891,7 +11579,7 @@ var init_loadIssueStateComment = __esm({
|
|
|
10891
11579
|
});
|
|
10892
11580
|
|
|
10893
11581
|
// src/scripts/loadJobFromFile.ts
|
|
10894
|
-
import * as
|
|
11582
|
+
import * as fs34 from "fs";
|
|
10895
11583
|
import * as path32 from "path";
|
|
10896
11584
|
function parseJobFile(raw, slug2) {
|
|
10897
11585
|
let stripped = raw;
|
|
@@ -10943,12 +11631,12 @@ var init_loadJobFromFile = __esm({
|
|
|
10943
11631
|
let agentIdentity = "";
|
|
10944
11632
|
if (agentSlug) {
|
|
10945
11633
|
const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
|
|
10946
|
-
if (!
|
|
11634
|
+
if (!fs34.existsSync(agentPath)) {
|
|
10947
11635
|
throw new Error(
|
|
10948
11636
|
`loadJobFromFile: agentResponsibility '${slug2}' declares agent '${agentSlug}' but ${agentPath} does not exist`
|
|
10949
11637
|
);
|
|
10950
11638
|
}
|
|
10951
|
-
const agentRaw =
|
|
11639
|
+
const agentRaw = fs34.readFileSync(agentPath, "utf-8");
|
|
10952
11640
|
const parsed = parseJobFile(agentRaw, agentSlug);
|
|
10953
11641
|
agentTitle = parsed.title;
|
|
10954
11642
|
agentIdentity = parsed.body;
|
|
@@ -11022,13 +11710,13 @@ ${truncate(issue.body, FINDING_BODY_MAX_BYTES)}`;
|
|
|
11022
11710
|
});
|
|
11023
11711
|
|
|
11024
11712
|
// src/scripts/kodyVariables.ts
|
|
11025
|
-
import * as
|
|
11713
|
+
import * as fs35 from "fs";
|
|
11026
11714
|
import * as path33 from "path";
|
|
11027
11715
|
function readKodyVariables(cwd) {
|
|
11028
11716
|
const full = path33.join(cwd, KODY_VARIABLES_REL_PATH);
|
|
11029
11717
|
let raw;
|
|
11030
11718
|
try {
|
|
11031
|
-
raw =
|
|
11719
|
+
raw = fs35.readFileSync(full, "utf-8");
|
|
11032
11720
|
} catch {
|
|
11033
11721
|
return {};
|
|
11034
11722
|
}
|
|
@@ -11053,7 +11741,7 @@ var init_kodyVariables = __esm({
|
|
|
11053
11741
|
});
|
|
11054
11742
|
|
|
11055
11743
|
// src/scripts/loadQaContext.ts
|
|
11056
|
-
import * as
|
|
11744
|
+
import * as fs36 from "fs";
|
|
11057
11745
|
import * as path34 from "path";
|
|
11058
11746
|
function parseSlugList(value) {
|
|
11059
11747
|
const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
|
|
@@ -11084,17 +11772,17 @@ function readProfileAgents(raw) {
|
|
|
11084
11772
|
}
|
|
11085
11773
|
function readProfile(cwd) {
|
|
11086
11774
|
const dir = path34.join(cwd, CONTEXT_DIR_REL_PATH);
|
|
11087
|
-
if (!
|
|
11775
|
+
if (!fs36.existsSync(dir)) return "";
|
|
11088
11776
|
let entries;
|
|
11089
11777
|
try {
|
|
11090
|
-
entries =
|
|
11778
|
+
entries = fs36.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
|
|
11091
11779
|
} catch {
|
|
11092
11780
|
return "";
|
|
11093
11781
|
}
|
|
11094
11782
|
const blocks = [];
|
|
11095
11783
|
for (const file of entries) {
|
|
11096
11784
|
try {
|
|
11097
|
-
const raw =
|
|
11785
|
+
const raw = fs36.readFileSync(path34.join(dir, file), "utf-8");
|
|
11098
11786
|
const { agent, body } = readProfileAgents(raw);
|
|
11099
11787
|
if (!agent.includes(QA_AGENT) && !agent.includes(ALL_AGENTS)) continue;
|
|
11100
11788
|
blocks.push(`## ${file}
|
|
@@ -11140,7 +11828,7 @@ var init_loadQaContext = __esm({
|
|
|
11140
11828
|
});
|
|
11141
11829
|
|
|
11142
11830
|
// src/taskContext.ts
|
|
11143
|
-
import * as
|
|
11831
|
+
import * as fs37 from "fs";
|
|
11144
11832
|
import * as path35 from "path";
|
|
11145
11833
|
function buildTaskContext(args) {
|
|
11146
11834
|
return {
|
|
@@ -11157,9 +11845,9 @@ function buildTaskContext(args) {
|
|
|
11157
11845
|
function persistTaskContext(cwd, ctx) {
|
|
11158
11846
|
try {
|
|
11159
11847
|
const dir = runtimeStatePath(cwd, "agent-runs", ctx.runId);
|
|
11160
|
-
|
|
11848
|
+
fs37.mkdirSync(dir, { recursive: true });
|
|
11161
11849
|
const file = path35.join(dir, "task-context.json");
|
|
11162
|
-
|
|
11850
|
+
fs37.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
|
|
11163
11851
|
`);
|
|
11164
11852
|
return file;
|
|
11165
11853
|
} catch (err) {
|
|
@@ -13504,9 +14192,9 @@ fi
|
|
|
13504
14192
|
});
|
|
13505
14193
|
|
|
13506
14194
|
// src/stateRepoGithub.ts
|
|
13507
|
-
import * as
|
|
14195
|
+
import * as fs38 from "fs";
|
|
13508
14196
|
import * as path36 from "path";
|
|
13509
|
-
function
|
|
14197
|
+
function recordValue3(value) {
|
|
13510
14198
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
13511
14199
|
}
|
|
13512
14200
|
function contentsUrl(owner, repo, filePath) {
|
|
@@ -13562,12 +14250,12 @@ async function loadGithubStateConfig(opts) {
|
|
|
13562
14250
|
throw new Error(`kody.config.json is invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
13563
14251
|
}
|
|
13564
14252
|
}
|
|
13565
|
-
const githubRaw =
|
|
14253
|
+
const githubRaw = recordValue3(raw.github) ?? {};
|
|
13566
14254
|
const github = {
|
|
13567
14255
|
owner: typeof githubRaw.owner === "string" && githubRaw.owner.trim() ? githubRaw.owner.trim() : opts.owner,
|
|
13568
14256
|
repo: typeof githubRaw.repo === "string" && githubRaw.repo.trim() ? githubRaw.repo.trim() : opts.repo
|
|
13569
14257
|
};
|
|
13570
|
-
const nestedState =
|
|
14258
|
+
const nestedState = recordValue3(raw.state) ?? {};
|
|
13571
14259
|
const repoRaw = typeof raw.stateRepo === "string" ? raw.stateRepo : nestedState.repo;
|
|
13572
14260
|
const pathRaw = typeof raw.statePath === "string" ? raw.statePath : nestedState.path;
|
|
13573
14261
|
const stateRepo = typeof repoRaw === "string" && repoRaw.trim().length > 0 ? repoRaw.trim() : `https://github.com/${github.owner}/kody-state`;
|
|
@@ -13645,15 +14333,15 @@ function mergeJsonl(localText, remoteText) {
|
|
|
13645
14333
|
async function syncJsonlFileFromGithubState(opts) {
|
|
13646
14334
|
const remote = await readGithubStateTextWithConfig(opts);
|
|
13647
14335
|
if (!remote) return;
|
|
13648
|
-
const local =
|
|
14336
|
+
const local = fs38.existsSync(opts.localPath) ? fs38.readFileSync(opts.localPath, "utf-8") : "";
|
|
13649
14337
|
const next = mergeJsonl(local, remote.content);
|
|
13650
14338
|
if (next === local) return;
|
|
13651
|
-
|
|
13652
|
-
|
|
14339
|
+
fs38.mkdirSync(path36.dirname(opts.localPath), { recursive: true });
|
|
14340
|
+
fs38.writeFileSync(opts.localPath, next);
|
|
13653
14341
|
}
|
|
13654
14342
|
async function persistJsonlFileToGithubState(opts) {
|
|
13655
|
-
if (!
|
|
13656
|
-
const localText =
|
|
14343
|
+
if (!fs38.existsSync(opts.localPath)) return;
|
|
14344
|
+
const localText = fs38.readFileSync(opts.localPath, "utf-8");
|
|
13657
14345
|
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
13658
14346
|
const remote = await readGithubStateTextWithConfig(opts);
|
|
13659
14347
|
const body = mergeJsonl(localText, remote?.content ?? "");
|
|
@@ -14130,7 +14818,7 @@ var init_tickShellRunner = __esm({
|
|
|
14130
14818
|
});
|
|
14131
14819
|
|
|
14132
14820
|
// src/scripts/runScheduledAgentActionTick.ts
|
|
14133
|
-
import * as
|
|
14821
|
+
import * as fs39 from "fs";
|
|
14134
14822
|
import * as path38 from "path";
|
|
14135
14823
|
var runScheduledAgentActionTick;
|
|
14136
14824
|
var init_runScheduledAgentActionTick = __esm({
|
|
@@ -14158,7 +14846,7 @@ var init_runScheduledAgentActionTick = __esm({
|
|
|
14158
14846
|
return;
|
|
14159
14847
|
}
|
|
14160
14848
|
const shellPath = path38.join(profile.dir, shell);
|
|
14161
|
-
if (!
|
|
14849
|
+
if (!fs39.existsSync(shellPath)) {
|
|
14162
14850
|
ctx.output.exitCode = 99;
|
|
14163
14851
|
ctx.output.reason = `runScheduledAgentActionTick: shell not found: ${shell} (looked in ${profile.dir})`;
|
|
14164
14852
|
return;
|
|
@@ -14189,7 +14877,7 @@ var init_runScheduledAgentActionTick = __esm({
|
|
|
14189
14877
|
});
|
|
14190
14878
|
|
|
14191
14879
|
// src/scripts/runTickScript.ts
|
|
14192
|
-
import * as
|
|
14880
|
+
import * as fs40 from "fs";
|
|
14193
14881
|
import * as path39 from "path";
|
|
14194
14882
|
var runTickScript;
|
|
14195
14883
|
var init_runTickScript = __esm({
|
|
@@ -14222,7 +14910,7 @@ var init_runTickScript = __esm({
|
|
|
14222
14910
|
return;
|
|
14223
14911
|
}
|
|
14224
14912
|
const scriptPath = path39.isAbsolute(tickScript) ? tickScript : path39.join(ctx.cwd, tickScript);
|
|
14225
|
-
if (!
|
|
14913
|
+
if (!fs40.existsSync(scriptPath)) {
|
|
14226
14914
|
ctx.output.exitCode = 99;
|
|
14227
14915
|
ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
|
|
14228
14916
|
return;
|
|
@@ -15044,7 +15732,7 @@ var init_warmupMcp = __esm({
|
|
|
15044
15732
|
});
|
|
15045
15733
|
|
|
15046
15734
|
// src/scripts/writeAgentRunSummary.ts
|
|
15047
|
-
import * as
|
|
15735
|
+
import * as fs41 from "fs";
|
|
15048
15736
|
var writeAgentRunSummary;
|
|
15049
15737
|
var init_writeAgentRunSummary = __esm({
|
|
15050
15738
|
"src/scripts/writeAgentRunSummary.ts"() {
|
|
@@ -15070,7 +15758,7 @@ var init_writeAgentRunSummary = __esm({
|
|
|
15070
15758
|
if (reason) lines.push(`- **Reason:** ${reason}`);
|
|
15071
15759
|
lines.push("");
|
|
15072
15760
|
try {
|
|
15073
|
-
|
|
15761
|
+
fs41.appendFileSync(summaryPath, `${lines.join("\n")}
|
|
15074
15762
|
`);
|
|
15075
15763
|
} catch {
|
|
15076
15764
|
}
|
|
@@ -15472,17 +16160,17 @@ var init_scripts = __esm({
|
|
|
15472
16160
|
});
|
|
15473
16161
|
|
|
15474
16162
|
// src/stateWorkspace.ts
|
|
15475
|
-
import * as
|
|
16163
|
+
import * as fs42 from "fs";
|
|
15476
16164
|
import * as path40 from "path";
|
|
15477
16165
|
function writeLocalFile(cwd, relativePath, content) {
|
|
15478
16166
|
const fullPath = path40.join(cwd, relativePath);
|
|
15479
|
-
|
|
15480
|
-
|
|
16167
|
+
fs42.mkdirSync(path40.dirname(fullPath), { recursive: true });
|
|
16168
|
+
fs42.writeFileSync(fullPath, content);
|
|
15481
16169
|
}
|
|
15482
16170
|
function hydrateDirectory(config, cwd, stateDir, localDir) {
|
|
15483
16171
|
const entries = listStateDirectory(config, cwd, stateDir);
|
|
15484
16172
|
if (entries.length === 0) return;
|
|
15485
|
-
|
|
16173
|
+
fs42.rmSync(path40.join(cwd, localDir), { recursive: true, force: true });
|
|
15486
16174
|
for (const entry of entries) {
|
|
15487
16175
|
if (!entry.name || !entry.type) continue;
|
|
15488
16176
|
const childState = path40.posix.join(stateDir, entry.name);
|
|
@@ -15590,7 +16278,7 @@ var init_tools = __esm({
|
|
|
15590
16278
|
|
|
15591
16279
|
// src/executor.ts
|
|
15592
16280
|
import { spawn as spawn7 } from "child_process";
|
|
15593
|
-
import * as
|
|
16281
|
+
import * as fs43 from "fs";
|
|
15594
16282
|
import * as path41 from "path";
|
|
15595
16283
|
function isMutatingPostflight(scriptName) {
|
|
15596
16284
|
return MUTATING_POSTFLIGHTS.has(scriptName ?? "");
|
|
@@ -16167,7 +16855,7 @@ function resolveProfilePath(profileName) {
|
|
|
16167
16855
|
// fallback
|
|
16168
16856
|
];
|
|
16169
16857
|
for (const c of candidates) {
|
|
16170
|
-
if (
|
|
16858
|
+
if (fs43.existsSync(c)) return c;
|
|
16171
16859
|
}
|
|
16172
16860
|
return candidates[0];
|
|
16173
16861
|
}
|
|
@@ -16266,7 +16954,7 @@ function resolveShellTimeoutMs(entry) {
|
|
|
16266
16954
|
async function runShellEntry(entry, ctx, profile) {
|
|
16267
16955
|
const shellName = entry.shell;
|
|
16268
16956
|
const shellPath = path41.join(profile.dir, shellName);
|
|
16269
|
-
if (!
|
|
16957
|
+
if (!fs43.existsSync(shellPath)) {
|
|
16270
16958
|
ctx.skipAgent = true;
|
|
16271
16959
|
ctx.output.exitCode = 99;
|
|
16272
16960
|
ctx.output.reason = `shell script not found: ${shellName} (looked in ${profile.dir})`;
|
|
@@ -16678,7 +17366,7 @@ function translateOpenAISseToBrain(opts) {
|
|
|
16678
17366
|
}
|
|
16679
17367
|
|
|
16680
17368
|
// src/servers/brain-serve.ts
|
|
16681
|
-
import * as
|
|
17369
|
+
import * as fs46 from "fs";
|
|
16682
17370
|
import { createServer } from "http";
|
|
16683
17371
|
import * as path45 from "path";
|
|
16684
17372
|
|
|
@@ -17240,7 +17928,7 @@ init_config();
|
|
|
17240
17928
|
|
|
17241
17929
|
// src/kody-cli.ts
|
|
17242
17930
|
import { execFileSync as execFileSync25 } from "child_process";
|
|
17243
|
-
import * as
|
|
17931
|
+
import * as fs44 from "fs";
|
|
17244
17932
|
import * as path43 from "path";
|
|
17245
17933
|
|
|
17246
17934
|
// src/app-auth.ts
|
|
@@ -17862,9 +18550,9 @@ async function resolveAuthToken(env = process.env) {
|
|
|
17862
18550
|
return void 0;
|
|
17863
18551
|
}
|
|
17864
18552
|
function detectPackageManager2(cwd) {
|
|
17865
|
-
if (
|
|
17866
|
-
if (
|
|
17867
|
-
if (
|
|
18553
|
+
if (fs44.existsSync(path43.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
18554
|
+
if (fs44.existsSync(path43.join(cwd, "yarn.lock"))) return "yarn";
|
|
18555
|
+
if (fs44.existsSync(path43.join(cwd, "bun.lockb"))) return "bun";
|
|
17868
18556
|
return "npm";
|
|
17869
18557
|
}
|
|
17870
18558
|
function shouldChainScheduledWatch(match) {
|
|
@@ -17957,8 +18645,8 @@ function postFailureTail(issueNumber, cwd, reason) {
|
|
|
17957
18645
|
const logPath = lastRunLogPath(cwd);
|
|
17958
18646
|
let tail = "";
|
|
17959
18647
|
try {
|
|
17960
|
-
if (
|
|
17961
|
-
const content =
|
|
18648
|
+
if (fs44.existsSync(logPath)) {
|
|
18649
|
+
const content = fs44.readFileSync(logPath, "utf-8");
|
|
17962
18650
|
tail = content.slice(-3e3);
|
|
17963
18651
|
}
|
|
17964
18652
|
} catch {
|
|
@@ -17998,9 +18686,9 @@ async function runCi(argv) {
|
|
|
17998
18686
|
let manualWorkflowDispatch = false;
|
|
17999
18687
|
let forceRunAction = null;
|
|
18000
18688
|
let forceRunCliArgs = {};
|
|
18001
|
-
if (!args.issueNumber && !autoFallback && eventName === "workflow_dispatch" && dispatchEventPath &&
|
|
18689
|
+
if (!args.issueNumber && !autoFallback && eventName === "workflow_dispatch" && dispatchEventPath && fs44.existsSync(dispatchEventPath)) {
|
|
18002
18690
|
try {
|
|
18003
|
-
const evt = JSON.parse(
|
|
18691
|
+
const evt = JSON.parse(fs44.readFileSync(dispatchEventPath, "utf-8"));
|
|
18004
18692
|
const issueInput = parseInt(String(evt?.inputs?.issue_number ?? ""), 10);
|
|
18005
18693
|
const sessionInput = String(evt?.inputs?.sessionId ?? "");
|
|
18006
18694
|
const dutyInput = String(evt?.inputs?.agentResponsibility ?? evt?.inputs?.agentAction ?? "").trim();
|
|
@@ -18332,7 +19020,7 @@ init_repoWorkspace();
|
|
|
18332
19020
|
|
|
18333
19021
|
// src/scripts/brainTurnLog.ts
|
|
18334
19022
|
init_runtimePaths();
|
|
18335
|
-
import * as
|
|
19023
|
+
import * as fs45 from "fs";
|
|
18336
19024
|
import * as path44 from "path";
|
|
18337
19025
|
import posixPath4 from "path/posix";
|
|
18338
19026
|
var live = /* @__PURE__ */ new Map();
|
|
@@ -18344,8 +19032,8 @@ function brainEventsStatePath(chatId) {
|
|
|
18344
19032
|
}
|
|
18345
19033
|
function lastPersistedSeq(dir, chatId) {
|
|
18346
19034
|
const p = brainEventsFilePath(dir, chatId);
|
|
18347
|
-
if (!
|
|
18348
|
-
const lines =
|
|
19035
|
+
if (!fs45.existsSync(p)) return 0;
|
|
19036
|
+
const lines = fs45.readFileSync(p, "utf-8").split("\n").filter(Boolean);
|
|
18349
19037
|
if (lines.length === 0) return 0;
|
|
18350
19038
|
try {
|
|
18351
19039
|
return JSON.parse(lines[lines.length - 1]).seq || 0;
|
|
@@ -18355,9 +19043,9 @@ function lastPersistedSeq(dir, chatId) {
|
|
|
18355
19043
|
}
|
|
18356
19044
|
function readSince(dir, chatId, since) {
|
|
18357
19045
|
const p = brainEventsFilePath(dir, chatId);
|
|
18358
|
-
if (!
|
|
19046
|
+
if (!fs45.existsSync(p)) return [];
|
|
18359
19047
|
const out = [];
|
|
18360
|
-
for (const line of
|
|
19048
|
+
for (const line of fs45.readFileSync(p, "utf-8").split("\n")) {
|
|
18361
19049
|
if (!line) continue;
|
|
18362
19050
|
try {
|
|
18363
19051
|
const rec = JSON.parse(line);
|
|
@@ -18383,12 +19071,12 @@ function beginTurn(dir, chatId) {
|
|
|
18383
19071
|
};
|
|
18384
19072
|
live.set(chatId, state);
|
|
18385
19073
|
const p = brainEventsFilePath(dir, chatId);
|
|
18386
|
-
|
|
19074
|
+
fs45.mkdirSync(path44.dirname(p), { recursive: true });
|
|
18387
19075
|
return (event) => {
|
|
18388
19076
|
state.seq += 1;
|
|
18389
19077
|
const rec = { seq: state.seq, turn, ts: Date.now(), event };
|
|
18390
19078
|
try {
|
|
18391
|
-
|
|
19079
|
+
fs45.appendFileSync(p, `${JSON.stringify(rec)}
|
|
18392
19080
|
`);
|
|
18393
19081
|
} catch (err) {
|
|
18394
19082
|
process.stderr.write(
|
|
@@ -18427,7 +19115,7 @@ function endTurnIfUnterminated(dir, chatId, errMessage) {
|
|
|
18427
19115
|
event: { type: "error", error: errMessage || "turn ended unexpectedly", chatId }
|
|
18428
19116
|
};
|
|
18429
19117
|
try {
|
|
18430
|
-
|
|
19118
|
+
fs45.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
|
|
18431
19119
|
`);
|
|
18432
19120
|
} catch {
|
|
18433
19121
|
}
|
|
@@ -18733,7 +19421,7 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
18733
19421
|
);
|
|
18734
19422
|
}
|
|
18735
19423
|
}
|
|
18736
|
-
|
|
19424
|
+
fs46.mkdirSync(path45.dirname(sessionFile), { recursive: true });
|
|
18737
19425
|
appendTurn(sessionFile, {
|
|
18738
19426
|
role: "user",
|
|
18739
19427
|
content: message,
|
|
@@ -19393,7 +20081,7 @@ async function loadConfigSafe() {
|
|
|
19393
20081
|
}
|
|
19394
20082
|
|
|
19395
20083
|
// src/chat-cli.ts
|
|
19396
|
-
import * as
|
|
20084
|
+
import * as fs48 from "fs";
|
|
19397
20085
|
import * as path47 from "path";
|
|
19398
20086
|
|
|
19399
20087
|
// src/chat/inbox.ts
|
|
@@ -19466,7 +20154,7 @@ function currentBranch(cwd) {
|
|
|
19466
20154
|
|
|
19467
20155
|
// src/chat/state-sync.ts
|
|
19468
20156
|
init_stateRepo();
|
|
19469
|
-
import * as
|
|
20157
|
+
import * as fs47 from "fs";
|
|
19470
20158
|
import * as path46 from "path";
|
|
19471
20159
|
function jsonlLines2(text) {
|
|
19472
20160
|
return text.split("\n").filter((line) => line.length > 0);
|
|
@@ -19484,15 +20172,15 @@ function mergeJsonl2(localText, remoteText) {
|
|
|
19484
20172
|
function syncJsonlFileFromState(opts) {
|
|
19485
20173
|
const remote = readStateText(opts.config, opts.cwd, opts.statePath);
|
|
19486
20174
|
if (!remote) return;
|
|
19487
|
-
const local =
|
|
20175
|
+
const local = fs47.existsSync(opts.localPath) ? fs47.readFileSync(opts.localPath, "utf-8") : "";
|
|
19488
20176
|
const next = mergeJsonl2(local, remote.content);
|
|
19489
20177
|
if (next === local) return;
|
|
19490
|
-
|
|
19491
|
-
|
|
20178
|
+
fs47.mkdirSync(path46.dirname(opts.localPath), { recursive: true });
|
|
20179
|
+
fs47.writeFileSync(opts.localPath, next);
|
|
19492
20180
|
}
|
|
19493
20181
|
function persistJsonlFileToState(opts) {
|
|
19494
|
-
if (!
|
|
19495
|
-
const localText =
|
|
20182
|
+
if (!fs47.existsSync(opts.localPath)) return;
|
|
20183
|
+
const localText = fs47.readFileSync(opts.localPath, "utf-8");
|
|
19496
20184
|
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
19497
20185
|
const remote = readStateText(opts.config, opts.cwd, opts.statePath);
|
|
19498
20186
|
const body = mergeJsonl2(localText, remote?.content ?? "");
|
|
@@ -19813,7 +20501,7 @@ ${CHAT_HELP}`);
|
|
|
19813
20501
|
const sink = buildSink(cwd, sessionId, args.dashboardUrl);
|
|
19814
20502
|
const meta = readMeta(sessionFile);
|
|
19815
20503
|
process.stdout.write(
|
|
19816
|
-
`\u2192 kody:chat: session file=${sessionFile} exists=${
|
|
20504
|
+
`\u2192 kody:chat: session file=${sessionFile} exists=${fs48.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
|
|
19817
20505
|
`
|
|
19818
20506
|
);
|
|
19819
20507
|
try {
|
|
@@ -20700,7 +21388,7 @@ async function poolServe() {
|
|
|
20700
21388
|
|
|
20701
21389
|
// src/servers/runner-serve.ts
|
|
20702
21390
|
import { spawn as spawn8 } from "child_process";
|
|
20703
|
-
import * as
|
|
21391
|
+
import * as fs49 from "fs";
|
|
20704
21392
|
import { createServer as createServer5 } from "http";
|
|
20705
21393
|
var DEFAULT_PORT2 = 8080;
|
|
20706
21394
|
var DEFAULT_WORKDIR = "/workspace/repo";
|
|
@@ -20780,8 +21468,8 @@ async function defaultRunJob(job) {
|
|
|
20780
21468
|
const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
|
|
20781
21469
|
const branch = job.ref ?? "main";
|
|
20782
21470
|
const authUrl = `https://x-access-token:${job.githubToken}@github.com/${job.repo}.git`;
|
|
20783
|
-
|
|
20784
|
-
|
|
21471
|
+
fs49.rmSync(workdir, { recursive: true, force: true });
|
|
21472
|
+
fs49.mkdirSync(workdir, { recursive: true });
|
|
20785
21473
|
const allSecrets = typeof job.allSecrets === "string" ? job.allSecrets : JSON.stringify(job.allSecrets ?? {});
|
|
20786
21474
|
const interactive = job.mode === "interactive";
|
|
20787
21475
|
const scheduled = job.mode === "scheduled";
|