@kody-ade/kody-engine 0.4.255 → 0.4.257

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.
Files changed (2) hide show
  1. package/dist/bin/kody.js +782 -246
  2. 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.255",
18
+ version: "0.4.257",
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",
@@ -3069,9 +3069,9 @@ function parseAgentResponsibilityReportsFromText(text) {
3069
3069
  function parseAgentResponsibilityReport(raw) {
3070
3070
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
3071
3071
  const obj = raw;
3072
- const target = parseTarget(obj.target);
3072
+ const target = parseAgentResponsibilityReportTarget(obj.target);
3073
3073
  if (!target) return null;
3074
- const evidence = parseBooleanRecord(obj.evidence);
3074
+ const evidence = parseAgentResponsibilityReportEvidence(obj.evidence);
3075
3075
  const facts = parseFacts(obj.facts);
3076
3076
  if (!evidence && !facts) return null;
3077
3077
  return {
@@ -3080,36 +3080,14 @@ function parseAgentResponsibilityReport(raw) {
3080
3080
  ...facts ? { facts } : {}
3081
3081
  };
3082
3082
  }
3083
- function applyAgentResponsibilityReportToGoalState(state, report) {
3084
- const priorFacts = parseFacts(state.extra.facts) ?? {};
3085
- const nextFacts = { ...priorFacts };
3086
- for (const [key, value] of Object.entries(report.facts ?? {})) {
3087
- if (CONTROL_FACT_KEYS.has(key)) continue;
3088
- nextFacts[key] = value;
3089
- }
3090
- for (const [key, value] of Object.entries(report.evidence ?? {})) {
3091
- nextFacts[key] = value;
3092
- }
3093
- const pending = nextFacts.pendingEvidence;
3094
- if (typeof pending === "string" && Object.hasOwn(report.evidence ?? {}, pending)) {
3095
- delete nextFacts.pendingEvidence;
3096
- }
3097
- return {
3098
- ...state,
3099
- extra: {
3100
- ...state.extra,
3101
- facts: nextFacts
3102
- }
3103
- };
3104
- }
3105
- function parseTarget(raw) {
3083
+ function parseAgentResponsibilityReportTarget(raw) {
3106
3084
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
3107
3085
  const target = raw;
3108
3086
  if (target.type !== "goal" && target.type !== "task" && target.type !== "agentResponsibility") return null;
3109
3087
  if (typeof target.id !== "string" || target.id.trim().length === 0) return null;
3110
3088
  return { type: target.type, id: target.id.trim() };
3111
3089
  }
3112
- function parseBooleanRecord(raw) {
3090
+ function parseAgentResponsibilityReportEvidence(raw) {
3113
3091
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
3114
3092
  const out = {};
3115
3093
  for (const [key, value] of Object.entries(raw)) {
@@ -3158,50 +3136,28 @@ function parseAgentResponsibilityResult(raw) {
3158
3136
  if (!isAgentResponsibilityResultStatus(obj.status)) return null;
3159
3137
  const summary = typeof obj.summary === "string" ? obj.summary.trim() : "";
3160
3138
  if (!summary) return null;
3139
+ const target = obj.target === void 0 ? void 0 : parseAgentResponsibilityReportTarget(obj.target);
3140
+ if (obj.target !== void 0 && !target) return null;
3141
+ const evidence = obj.evidence === void 0 ? void 0 : parseAgentResponsibilityReportEvidence(obj.evidence);
3142
+ if (obj.evidence !== void 0 && !evidence) return null;
3161
3143
  const facts = parseFacts2(obj.facts);
3162
3144
  if (!facts) return null;
3163
3145
  const artifacts = parseArtifacts(obj.artifacts);
3164
3146
  if (!artifacts) return null;
3147
+ const missingEvidence = parseOptionalStringArray(obj.missingEvidence);
3148
+ if (!missingEvidence) return null;
3149
+ const blockers = parseOptionalStringArray(obj.blockers);
3150
+ if (!blockers) return null;
3165
3151
  return {
3166
3152
  version: 1,
3153
+ ...target ? { target } : {},
3167
3154
  status: obj.status,
3168
3155
  summary,
3156
+ ...evidence ? { evidence } : {},
3169
3157
  facts,
3170
- artifacts
3171
- };
3172
- }
3173
- function applyAgentResponsibilityResultToObjectiveState(state, result, evidenceOverride) {
3174
- const priorFacts = parseFacts2(state.extra.facts) ?? {};
3175
- const nextFacts = { ...priorFacts };
3176
- for (const [key, value] of Object.entries(result.facts)) {
3177
- if (CONTROL_FACT_KEYS2.has(key)) continue;
3178
- nextFacts[key] = value;
3179
- }
3180
- const evidence = evidenceOverride || (typeof nextFacts.pendingEvidence === "string" ? nextFacts.pendingEvidence : "");
3181
- if (evidence) {
3182
- if (result.status === "pass") nextFacts[evidence] = true;
3183
- if (result.status === "fail" || result.status === "blocked") nextFacts[evidence] = false;
3184
- if ((result.status === "pass" || result.status === "fail" || result.status === "blocked") && nextFacts.pendingEvidence === evidence) {
3185
- delete nextFacts.pendingEvidence;
3186
- }
3187
- }
3188
- const blockers = parseStringArray(state.extra.blockers) ?? [];
3189
- if ((result.status === "fail" || result.status === "blocked") && !blockers.includes(result.summary)) {
3190
- blockers.push(result.summary);
3191
- }
3192
- return {
3193
- ...state,
3194
- extra: {
3195
- ...state.extra,
3196
- facts: nextFacts,
3197
- blockers,
3198
- lastAgentResponsibilityResult: {
3199
- status: result.status,
3200
- summary: result.summary,
3201
- facts: result.facts,
3202
- artifacts: result.artifacts
3203
- }
3204
- }
3158
+ artifacts,
3159
+ missingEvidence,
3160
+ blockers
3205
3161
  };
3206
3162
  }
3207
3163
  function isAgentResponsibilityResultStatus(value) {
@@ -3227,6 +3183,10 @@ function parseStringArray(raw) {
3227
3183
  }
3228
3184
  return out;
3229
3185
  }
3186
+ function parseOptionalStringArray(raw) {
3187
+ if (raw === void 0) return [];
3188
+ return parseStringArray(raw);
3189
+ }
3230
3190
  function parseArtifacts(raw) {
3231
3191
  if (raw === void 0) return [];
3232
3192
  if (!Array.isArray(raw)) return null;
@@ -3250,6 +3210,7 @@ var RESULT_LINE, STATUSES, CONTROL_FACT_KEYS2;
3250
3210
  var init_agent_responsibilityResult = __esm({
3251
3211
  "src/agent-responsibilityResult.ts"() {
3252
3212
  "use strict";
3213
+ init_agent_responsibilityReport();
3253
3214
  RESULT_LINE = /^KODY_AGENT_RESPONSIBILITY_RESULT=(.+)$/gm;
3254
3215
  STATUSES = /* @__PURE__ */ new Set(["pass", "fail", "blocked", "changed", "noop"]);
3255
3216
  CONTROL_FACT_KEYS2 = /* @__PURE__ */ new Set(["blockers", "destination", "agent-responsibilities", "route", "stage", "state"]);
@@ -6180,6 +6141,7 @@ var init_state2 = __esm({
6180
6141
  });
6181
6142
 
6182
6143
  // src/goal/runLog.ts
6144
+ import * as fs25 from "fs";
6183
6145
  function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
6184
6146
  const logs = goalRunLogs(data);
6185
6147
  const existing = logs[goalId];
@@ -6201,7 +6163,7 @@ function flushGoalRunLogEvents(config, cwd, data) {
6201
6163
  const logs = goalRunLogs(data);
6202
6164
  for (const [goalId, log2] of Object.entries(logs)) {
6203
6165
  if (log2.events.length === 0) continue;
6204
- const lines = `${log2.events.map((event) => JSON.stringify(event)).join("\n")}
6166
+ const lines = `${log2.events.map((event) => JSON.stringify(enrichGoalRunLogEvent(config, data, log2.path, event))).join("\n")}
6205
6167
  `;
6206
6168
  appendStateLine(config, cwd, log2.path, lines, `chore(goal-logs): append ${goalId}`);
6207
6169
  log2.events = [];
@@ -6212,6 +6174,55 @@ function goalRunLogPath(goalId, data) {
6212
6174
  const runId = goalRunId(data);
6213
6175
  return `logs/goals/${safePathSegment(goalId)}/runs/${startedAt}-${runId}.jsonl`;
6214
6176
  }
6177
+ function goalStateLogPath(goalId) {
6178
+ return `goals/instances/${safePathSegment(goalId)}/state.json`;
6179
+ }
6180
+ function goalRunLogSnapshot(goalId, goalState, goal) {
6181
+ const requiredEvidence = [...goal.destination.evidence];
6182
+ const pendingEvidence = typeof goal.facts.pendingEvidence === "string" ? goal.facts.pendingEvidence : void 0;
6183
+ return {
6184
+ id: goalId,
6185
+ type: goal.type,
6186
+ state: goalState,
6187
+ stage: goal.stage,
6188
+ outcome: goal.destination.outcome,
6189
+ requiredEvidence,
6190
+ satisfiedEvidence: requiredEvidence.filter((evidence) => goal.facts[evidence] === true),
6191
+ failedEvidence: requiredEvidence.filter((evidence) => goal.facts[evidence] === false),
6192
+ missingEvidence: requiredEvidence.filter((evidence) => goal.facts[evidence] !== true),
6193
+ pendingEvidence,
6194
+ agentResponsibilities: [...goal.agentResponsibilities],
6195
+ route: goal.route.map(routeStepForLog),
6196
+ schedule: goal.schedule,
6197
+ preferredRunTime: goal.preferredRunTime,
6198
+ loopTarget: goal.loopTarget,
6199
+ blockers: [...goal.blockers],
6200
+ facts: { ...goal.facts }
6201
+ };
6202
+ }
6203
+ function goalRunLogChange(before, after) {
6204
+ if (!before || !after) return void 0;
6205
+ const change = {};
6206
+ addScalarChange(change, "state", before.state, after.state);
6207
+ addScalarChange(change, "stage", before.stage, after.stage);
6208
+ addScalarChange(change, "pendingEvidence", before.pendingEvidence, after.pendingEvidence);
6209
+ const beforeFacts = recordValue2(before.facts);
6210
+ const afterFacts = recordValue2(after.facts);
6211
+ if (beforeFacts || afterFacts) change.facts = diffRecordKeys(beforeFacts ?? {}, afterFacts ?? {});
6212
+ const beforeBlockers = stringArrayValue(before.blockers);
6213
+ const afterBlockers = stringArrayValue(after.blockers);
6214
+ if (beforeBlockers || afterBlockers) {
6215
+ const blockers = diffStringArrays(beforeBlockers ?? [], afterBlockers ?? []);
6216
+ if (blockers.added.length > 0 || blockers.removed.length > 0) change.blockers = blockers;
6217
+ }
6218
+ const beforeSatisfied = stringArrayValue(before.satisfiedEvidence);
6219
+ const afterSatisfied = stringArrayValue(after.satisfiedEvidence);
6220
+ if (beforeSatisfied || afterSatisfied) {
6221
+ const evidence = diffStringArrays(beforeSatisfied ?? [], afterSatisfied ?? []);
6222
+ if (evidence.added.length > 0 || evidence.removed.length > 0) change.satisfiedEvidence = evidence;
6223
+ }
6224
+ return Object.keys(change).length > 0 ? change : void 0;
6225
+ }
6215
6226
  function goalRunLogs(data) {
6216
6227
  const existing = data[LOGS_KEY];
6217
6228
  if (existing && typeof existing === "object" && !Array.isArray(existing)) {
@@ -6242,6 +6253,176 @@ function githubRunId() {
6242
6253
  const attempt = process.env.GITHUB_RUN_ATTEMPT?.trim();
6243
6254
  return attempt ? `gh-${runId}-${attempt}` : `gh-${runId}`;
6244
6255
  }
6256
+ function enrichGoalRunLogEvent(config, data, logPath, event) {
6257
+ const stateRepo = stateRepoContext(config, event.goalId, logPath);
6258
+ return pruneUndefined({
6259
+ ...event,
6260
+ run: event.run ?? runContext(data),
6261
+ repo: event.repo ?? repoContext(config),
6262
+ stateRepo: event.stateRepo ?? stateRepo,
6263
+ trigger: event.trigger ?? triggerContext(),
6264
+ job: event.job ?? jobContext(data),
6265
+ links: event.links ?? linkContext(stateRepo)
6266
+ });
6267
+ }
6268
+ function runContext(data) {
6269
+ const runId = process.env.GITHUB_RUN_ID?.trim();
6270
+ const attempt = process.env.GITHUB_RUN_ATTEMPT?.trim();
6271
+ const repository = process.env.GITHUB_REPOSITORY?.trim();
6272
+ const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
6273
+ return pruneUndefined({
6274
+ id: goalRunId(data),
6275
+ provider: runId ? "github-actions" : "local",
6276
+ githubRunId: runId || void 0,
6277
+ githubRunAttempt: attempt || void 0,
6278
+ workflow: process.env.GITHUB_WORKFLOW?.trim() || void 0,
6279
+ job: process.env.GITHUB_JOB?.trim() || void 0,
6280
+ url: runId && repository ? `${server}/${repository}/actions/runs/${runId}` : void 0,
6281
+ startedAt: data[LOG_STARTED_KEY]
6282
+ });
6283
+ }
6284
+ function repoContext(config) {
6285
+ const owner = config.github?.owner;
6286
+ const repo = config.github?.repo;
6287
+ return pruneUndefined({
6288
+ owner,
6289
+ repo,
6290
+ fullName: owner && repo ? `${owner}/${repo}` : process.env.GITHUB_REPOSITORY?.trim() || void 0,
6291
+ ref: process.env.GITHUB_REF?.trim() || void 0,
6292
+ sha: process.env.GITHUB_SHA?.trim() || void 0
6293
+ });
6294
+ }
6295
+ function stateRepoContext(config, goalId, logPath) {
6296
+ try {
6297
+ const state = resolveStateRepoConfig(config);
6298
+ return {
6299
+ repo: state.repo,
6300
+ path: state.path,
6301
+ goalStatePath: `${state.path}/${goalStateLogPath(goalId)}`,
6302
+ logPath: `${state.path}/${logPath}`
6303
+ };
6304
+ } catch {
6305
+ return void 0;
6306
+ }
6307
+ }
6308
+ function triggerContext() {
6309
+ const event = readGithubEvent();
6310
+ const inputs = recordValue2(event?.inputs);
6311
+ return pruneUndefined({
6312
+ eventName: process.env.GITHUB_EVENT_NAME?.trim() || void 0,
6313
+ actor: process.env.GITHUB_ACTOR?.trim() || void 0,
6314
+ eventPath: process.env.GITHUB_EVENT_PATH?.trim() || void 0,
6315
+ issue: numberValue(recordValue2(event?.issue)?.number),
6316
+ pullRequest: numberValue(recordValue2(event?.pull_request)?.number),
6317
+ comment: numberValue(recordValue2(event?.comment)?.id),
6318
+ schedule: stringValue(event?.schedule),
6319
+ inputs: inputs ? pickRecord(inputs, ["issue_number", "sessionId", "message", "model", "title", "agentAction", "base"]) : void 0
6320
+ });
6321
+ }
6322
+ function jobContext(data) {
6323
+ const job = pruneUndefined({
6324
+ id: stringValue(data.jobId),
6325
+ key: stringValue(data.jobKey),
6326
+ flavor: stringValue(data.jobFlavor),
6327
+ action: stringValue(data.jobAction),
6328
+ agentResponsibility: stringValue(data.jobAgentResponsibility),
6329
+ agentAction: stringValue(data.jobAgentAction),
6330
+ agent: stringValue(data.jobAgent),
6331
+ schedule: stringValue(data.jobSchedule),
6332
+ target: data.jobTarget,
6333
+ why: truncateString(stringValue(data.jobWhy), 1e3),
6334
+ saveReport: data.jobSaveReport === true ? true : void 0
6335
+ });
6336
+ return Object.keys(job).length > 0 ? job : void 0;
6337
+ }
6338
+ function linkContext(stateRepo) {
6339
+ const links = {};
6340
+ const runId = process.env.GITHUB_RUN_ID?.trim();
6341
+ const repository = process.env.GITHUB_REPOSITORY?.trim();
6342
+ const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
6343
+ if (runId && repository) links.workflowRun = `${server}/${repository}/actions/runs/${runId}`;
6344
+ const repo = stringValue(stateRepo?.repo);
6345
+ const goalStatePath = stringValue(stateRepo?.goalStatePath);
6346
+ const logPath = stringValue(stateRepo?.logPath);
6347
+ if (repo && goalStatePath) links.goalState = githubBlobUrl(repo, goalStatePath);
6348
+ if (repo && logPath) links.log = githubBlobUrl(repo, logPath);
6349
+ return Object.keys(links).length > 0 ? links : void 0;
6350
+ }
6351
+ function githubBlobUrl(repo, filePath) {
6352
+ try {
6353
+ const parsed = parseStateRepoSlug(repo);
6354
+ return `https://github.com/${parsed.owner}/${parsed.repo}/blob/main/${filePath}`;
6355
+ } catch {
6356
+ return void 0;
6357
+ }
6358
+ }
6359
+ function routeStepForLog(step) {
6360
+ return pruneUndefined({
6361
+ evidence: step.evidence,
6362
+ stage: step.stage,
6363
+ agentResponsibility: step.agentResponsibility,
6364
+ agentAction: step.agentAction,
6365
+ args: step.args,
6366
+ saveReport: step.saveReport === true ? true : void 0
6367
+ });
6368
+ }
6369
+ function readGithubEvent() {
6370
+ const eventPath = process.env.GITHUB_EVENT_PATH;
6371
+ if (!eventPath) return null;
6372
+ try {
6373
+ if (!fs25.existsSync(eventPath)) return null;
6374
+ const parsed = JSON.parse(fs25.readFileSync(eventPath, "utf-8"));
6375
+ return recordValue2(parsed);
6376
+ } catch {
6377
+ return null;
6378
+ }
6379
+ }
6380
+ function addScalarChange(change, field, before, after) {
6381
+ if (before === after) return;
6382
+ change[field] = pruneUndefined({ from: before, to: after });
6383
+ }
6384
+ function diffRecordKeys(before, after) {
6385
+ const beforeKeys = new Set(Object.keys(before));
6386
+ const afterKeys = new Set(Object.keys(after));
6387
+ const added = [...afterKeys].filter((key) => !beforeKeys.has(key)).sort();
6388
+ const removed = [...beforeKeys].filter((key) => !afterKeys.has(key)).sort();
6389
+ const changed = [...afterKeys].filter((key) => beforeKeys.has(key) && JSON.stringify(before[key]) !== JSON.stringify(after[key])).sort();
6390
+ return { added, removed, changed };
6391
+ }
6392
+ function diffStringArrays(before, after) {
6393
+ const beforeSet = new Set(before);
6394
+ const afterSet = new Set(after);
6395
+ return {
6396
+ added: after.filter((item) => !beforeSet.has(item)).sort(),
6397
+ removed: before.filter((item) => !afterSet.has(item)).sort()
6398
+ };
6399
+ }
6400
+ function recordValue2(value) {
6401
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
6402
+ }
6403
+ function stringArrayValue(value) {
6404
+ return Array.isArray(value) && value.every((item) => typeof item === "string") ? [...value] : null;
6405
+ }
6406
+ function numberValue(value) {
6407
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
6408
+ }
6409
+ function pickRecord(input, keys) {
6410
+ const out = {};
6411
+ for (const key of keys) {
6412
+ if (input[key] !== void 0 && input[key] !== "") out[key] = input[key];
6413
+ }
6414
+ return out;
6415
+ }
6416
+ function pruneUndefined(input) {
6417
+ for (const key of Object.keys(input)) {
6418
+ if (input[key] === void 0) delete input[key];
6419
+ }
6420
+ return input;
6421
+ }
6422
+ function truncateString(value, max) {
6423
+ if (!value) return void 0;
6424
+ return value.length > max ? `${value.slice(0, max)}...` : value;
6425
+ }
6245
6426
  function stringValue(value) {
6246
6427
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
6247
6428
  }
@@ -6587,7 +6768,7 @@ var init_contentsApiBackend = __esm({
6587
6768
  });
6588
6769
 
6589
6770
  // src/scripts/jobState/localFileBackend.ts
6590
- import * as fs25 from "fs";
6771
+ import * as fs26 from "fs";
6591
6772
  import * as path24 from "path";
6592
6773
  function sanitizeKey(s) {
6593
6774
  return s.replace(/[^A-Za-z0-9._-]/g, "-");
@@ -6659,7 +6840,7 @@ var init_localFileBackend = __esm({
6659
6840
  `);
6660
6841
  return;
6661
6842
  }
6662
- fs25.mkdirSync(this.absDir, { recursive: true });
6843
+ fs26.mkdirSync(this.absDir, { recursive: true });
6663
6844
  const prefix = this.cacheKeyPrefix();
6664
6845
  const probeKey = `${prefix}probe-${Date.now()}`;
6665
6846
  try {
@@ -6688,7 +6869,7 @@ var init_localFileBackend = __esm({
6688
6869
  `);
6689
6870
  return;
6690
6871
  }
6691
- if (!fs25.existsSync(this.absDir)) {
6872
+ if (!fs26.existsSync(this.absDir)) {
6692
6873
  return;
6693
6874
  }
6694
6875
  const key = `${this.cacheKeyPrefix()}${process.env.GITHUB_RUN_ID ?? "norunid"}-${Date.now()}`;
@@ -6705,10 +6886,10 @@ var init_localFileBackend = __esm({
6705
6886
  load(slug2) {
6706
6887
  const relPath = stateFilePath(this.jobsDir, slug2);
6707
6888
  const absPath = path24.join(this.cwd, relPath);
6708
- if (!fs25.existsSync(absPath)) {
6889
+ if (!fs26.existsSync(absPath)) {
6709
6890
  return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
6710
6891
  }
6711
- const raw = fs25.readFileSync(absPath, "utf-8");
6892
+ const raw = fs26.readFileSync(absPath, "utf-8");
6712
6893
  let parsed;
6713
6894
  try {
6714
6895
  parsed = JSON.parse(raw);
@@ -6726,12 +6907,12 @@ var init_localFileBackend = __esm({
6726
6907
  return false;
6727
6908
  }
6728
6909
  const absPath = path24.join(this.cwd, loaded.path);
6729
- fs25.mkdirSync(path24.dirname(absPath), { recursive: true });
6910
+ fs26.mkdirSync(path24.dirname(absPath), { recursive: true });
6730
6911
  const body = `${JSON.stringify(next, null, 2)}
6731
6912
  `;
6732
6913
  const tmpPath = `${absPath}.${process.pid}.tmp`;
6733
- fs25.writeFileSync(tmpPath, body, "utf-8");
6734
- fs25.renameSync(tmpPath, absPath);
6914
+ fs26.writeFileSync(tmpPath, body, "utf-8");
6915
+ fs26.renameSync(tmpPath, absPath);
6735
6916
  return true;
6736
6917
  }
6737
6918
  cacheKeyPrefix() {
@@ -7000,7 +7181,7 @@ var init_goalAgentResponsibilityScheduling = __esm({
7000
7181
  });
7001
7182
 
7002
7183
  // src/scripts/advanceManagedGoal.ts
7003
- function stageManagedGoalDecision(data, goalId, goal, goalState, decision) {
7184
+ function stageManagedGoalDecision(data, goalId, goal, goalState, decision, details) {
7004
7185
  if (decision.kind === "dispatch") {
7005
7186
  stageGoalRunLogEvent(data, goalId, {
7006
7187
  source: "goal-manager",
@@ -7014,7 +7195,18 @@ function stageManagedGoalDecision(data, goalId, goal, goalState, decision) {
7014
7195
  agentResponsibility: decision.agentResponsibility,
7015
7196
  agentAction: decision.agentAction,
7016
7197
  cliArgs: decision.cliArgs
7017
- }
7198
+ },
7199
+ goal: details.goalSnapshot,
7200
+ inspection: details.inspection,
7201
+ decision: {
7202
+ kind: decision.kind,
7203
+ evidence: decision.evidence,
7204
+ stage: decision.stage,
7205
+ agentResponsibility: decision.agentResponsibility,
7206
+ agentAction: decision.agentAction,
7207
+ cliArgs: decision.cliArgs
7208
+ },
7209
+ change: details.change
7018
7210
  });
7019
7211
  return;
7020
7212
  }
@@ -7026,7 +7218,11 @@ function stageManagedGoalDecision(data, goalId, goal, goalState, decision) {
7026
7218
  goalState: "done",
7027
7219
  stage: "done",
7028
7220
  status: decision.kind,
7029
- reason: "managed goal complete"
7221
+ reason: "managed goal complete",
7222
+ goal: details.goalSnapshot,
7223
+ inspection: details.inspection,
7224
+ decision: { kind: decision.kind, reason: "managed goal complete" },
7225
+ change: details.change
7030
7226
  });
7031
7227
  return;
7032
7228
  }
@@ -7038,7 +7234,11 @@ function stageManagedGoalDecision(data, goalId, goal, goalState, decision) {
7038
7234
  goalState,
7039
7235
  stage: goal.stage,
7040
7236
  status: decision.kind,
7041
- reason: decision.reason
7237
+ reason: decision.reason,
7238
+ goal: details.goalSnapshot,
7239
+ inspection: details.inspection,
7240
+ decision: { kind: decision.kind, reason: decision.reason },
7241
+ change: details.change
7042
7242
  });
7043
7243
  return;
7044
7244
  }
@@ -7050,7 +7250,16 @@ function stageManagedGoalDecision(data, goalId, goal, goalState, decision) {
7050
7250
  stage: decision.stage,
7051
7251
  evidence: decision.evidence,
7052
7252
  status: decision.kind,
7053
- reason: decision.reason
7253
+ reason: decision.reason,
7254
+ goal: details.goalSnapshot,
7255
+ inspection: details.inspection,
7256
+ decision: {
7257
+ kind: decision.kind,
7258
+ evidence: decision.evidence,
7259
+ stage: decision.stage,
7260
+ reason: decision.reason
7261
+ },
7262
+ change: details.change
7054
7263
  });
7055
7264
  }
7056
7265
  function readSimpleGoalTaskSummary(goalId, cwd) {
@@ -7139,16 +7348,25 @@ var init_advanceManagedGoal = __esm({
7139
7348
  ctx.output.reason = "goal has no managed-goal contract; nothing to advance";
7140
7349
  return;
7141
7350
  }
7351
+ const previousGoalIdFact = managed.facts.goalId;
7352
+ managed.facts.goalId = goal.id;
7353
+ const startSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
7142
7354
  stageGoalRunLogEvent(ctx.data, goal.id, {
7143
7355
  source: "goal-manager",
7144
7356
  event: "goal.tick.start",
7145
7357
  goalType: managed.type,
7146
7358
  goalState: goal.state,
7147
7359
  stage: managed.stage,
7360
+ goal: startSnapshot,
7361
+ inspection: {
7362
+ requiredEvidence: startSnapshot.requiredEvidence,
7363
+ satisfiedEvidence: startSnapshot.satisfiedEvidence,
7364
+ missingEvidence: startSnapshot.missingEvidence,
7365
+ pendingEvidence: startSnapshot.pendingEvidence,
7366
+ blockers: startSnapshot.blockers
7367
+ },
7148
7368
  facts: managed.facts
7149
7369
  });
7150
- const previousGoalIdFact = managed.facts.goalId;
7151
- managed.facts.goalId = goal.id;
7152
7370
  const restoreGoalIdFact = () => {
7153
7371
  if (previousGoalIdFact === void 0) delete managed.facts.goalId;
7154
7372
  else managed.facts.goalId = previousGoalIdFact;
@@ -7161,6 +7379,7 @@ var init_advanceManagedGoal = __esm({
7161
7379
  if (!managed.blockers.includes(reason)) managed.blockers.push(reason);
7162
7380
  restoreGoalIdFact();
7163
7381
  goal.raw = writeManagedGoalToState({ ...goal.raw, state: goal.state }, managed);
7382
+ const blockedSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
7164
7383
  stageGoalRunLogEvent(ctx.data, goal.id, {
7165
7384
  source: "goal-manager",
7166
7385
  event: "goal.tick.blocked",
@@ -7168,12 +7387,20 @@ var init_advanceManagedGoal = __esm({
7168
7387
  goalState: goal.state,
7169
7388
  stage: managed.stage,
7170
7389
  status: "blocked",
7171
- reason
7390
+ reason,
7391
+ goal: blockedSnapshot,
7392
+ inspection: {
7393
+ purpose: "prepare goal issue fact before dispatch",
7394
+ routeNeedsIssueFact: true
7395
+ },
7396
+ decision: { kind: "blocked", reason },
7397
+ change: goalRunLogChange(startSnapshot, blockedSnapshot)
7172
7398
  });
7173
7399
  ctx.output.reason = reason;
7174
7400
  return;
7175
7401
  }
7176
7402
  if (isGoalTargetLoop(managed)) {
7403
+ const beforeSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
7177
7404
  const previousScheduleState = goal.raw.extra.scheduleState && typeof goal.raw.extra.scheduleState === "object" ? goal.raw.extra.scheduleState : void 0;
7178
7405
  const decision2 = planGoalTargetLoopSchedule({ goal: managed, previousScheduleState });
7179
7406
  restoreGoalIdFact();
@@ -7196,12 +7423,32 @@ var init_advanceManagedGoal = __esm({
7196
7423
  status: decision2.kind,
7197
7424
  reason: decision2.reason,
7198
7425
  target: decision2.dispatch?.cliArgs.goal && typeof decision2.dispatch.cliArgs.goal === "string" ? { type: "goal", id: decision2.dispatch.cliArgs.goal } : managed.loopTarget,
7199
- dispatch: decision2.dispatch
7426
+ dispatch: decision2.dispatch,
7427
+ goal: goalRunLogSnapshot(goal.id, goal.state, managed),
7428
+ inspection: {
7429
+ loopTarget: managed.loopTarget,
7430
+ preferredRunTime: managed.preferredRunTime,
7431
+ previousScheduleState,
7432
+ scheduleState: decision2.scheduleState
7433
+ },
7434
+ decision: {
7435
+ kind: decision2.kind,
7436
+ reason: decision2.reason,
7437
+ dispatch: decision2.dispatch
7438
+ },
7439
+ change: {
7440
+ ...goalRunLogChange(beforeSnapshot, goalRunLogSnapshot(goal.id, goal.state, managed)) ?? {},
7441
+ scheduleState: {
7442
+ previousDecision: previousScheduleState?.lastDecision,
7443
+ nextDecision: decision2.scheduleState.lastDecision
7444
+ }
7445
+ }
7200
7446
  });
7201
7447
  ctx.output.reason = decision2.reason;
7202
7448
  return;
7203
7449
  }
7204
7450
  if (isAgentResponsibilityCadenceGoal(managed, goal.raw.extra)) {
7451
+ const beforeSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
7205
7452
  const previousScheduleState = goal.raw.extra.scheduleState && typeof goal.raw.extra.scheduleState === "object" ? goal.raw.extra.scheduleState : void 0;
7206
7453
  const decision2 = await planGoalAgentResponsibilitySchedule({
7207
7454
  goal: managed,
@@ -7229,22 +7476,55 @@ var init_advanceManagedGoal = __esm({
7229
7476
  stage: managed.stage,
7230
7477
  status: decision2.kind,
7231
7478
  reason: decision2.reason,
7232
- dispatch: decision2.dispatch
7479
+ dispatch: decision2.dispatch,
7480
+ goal: goalRunLogSnapshot(goal.id, goal.state, managed),
7481
+ inspection: {
7482
+ agentResponsibilities: decision2.scheduleState.agentResponsibilities,
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
+ }
7233
7498
  });
7234
7499
  ctx.output.reason = decision2.reason;
7235
7500
  return;
7236
7501
  }
7502
+ let simpleTaskSummary;
7237
7503
  if (isSimpleGoal(managed)) {
7238
- applySimpleGoalTaskSummary(managed, readSimpleGoalTaskSummary(goal.id, ctx.cwd));
7504
+ simpleTaskSummary = readSimpleGoalTaskSummary(goal.id, ctx.cwd);
7505
+ applySimpleGoalTaskSummary(managed, simpleTaskSummary);
7239
7506
  }
7507
+ const beforeDecisionSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
7240
7508
  const decision = planManagedGoalTick(managed);
7241
7509
  restoreGoalIdFact();
7242
7510
  ctx.data.managedGoalDecision = decision;
7243
- stageManagedGoalDecision(ctx.data, goal.id, managed, goal.state, decision);
7244
7511
  if (decision.kind === "done") {
7245
7512
  goal.state = "done";
7246
7513
  }
7247
7514
  goal.raw = writeManagedGoalToState({ ...goal.raw, state: goal.state }, managed);
7515
+ const afterDecisionSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
7516
+ stageManagedGoalDecision(ctx.data, goal.id, managed, goal.state, decision, {
7517
+ goalSnapshot: afterDecisionSnapshot,
7518
+ inspection: {
7519
+ requiredEvidence: beforeDecisionSnapshot.requiredEvidence,
7520
+ satisfiedEvidence: beforeDecisionSnapshot.satisfiedEvidence,
7521
+ missingEvidence: beforeDecisionSnapshot.missingEvidence,
7522
+ pendingEvidence: beforeDecisionSnapshot.pendingEvidence,
7523
+ route: beforeDecisionSnapshot.route,
7524
+ simpleTaskSummary
7525
+ },
7526
+ change: goalRunLogChange(beforeDecisionSnapshot, afterDecisionSnapshot)
7527
+ });
7248
7528
  if (decision.kind === "blocked" || decision.kind === "wait" || decision.kind === "idle" || decision.kind === "done") {
7249
7529
  ctx.output.reason = decision.kind === "done" ? "managed goal complete" : decision.reason;
7250
7530
  return;
@@ -7790,6 +8070,174 @@ var init_appendCompanyIntentDecision = __esm({
7790
8070
  }
7791
8071
  });
7792
8072
 
8073
+ // src/agent-responsibilityEvidence.ts
8074
+ function agentResponsibilityReportToEvidence(report) {
8075
+ if (report.target.type !== "goal") return null;
8076
+ const evidence = report.evidence ?? {};
8077
+ const values = Object.values(evidence);
8078
+ const status = values.some((value) => value === false) ? "fail" : values.length > 0 || report.facts ? "changed" : "noop";
8079
+ return {
8080
+ version: 1,
8081
+ target: { type: "goal", id: report.target.id },
8082
+ status,
8083
+ summary: "responsibility reported goal evidence",
8084
+ evidence,
8085
+ facts: report.facts ?? {},
8086
+ artifacts: [],
8087
+ missingEvidence: [],
8088
+ blockers: [],
8089
+ sources: ["report"]
8090
+ };
8091
+ }
8092
+ function agentResponsibilityResultToEvidence(result, fallbackGoalId, explicitEvidence) {
8093
+ const targetId = result.target?.type === "goal" ? result.target.id : fallbackGoalId;
8094
+ if (!targetId) return null;
8095
+ return {
8096
+ version: 1,
8097
+ target: { type: "goal", id: targetId },
8098
+ status: result.status,
8099
+ summary: result.summary,
8100
+ evidence: result.evidence,
8101
+ explicitEvidence,
8102
+ facts: result.facts,
8103
+ artifacts: result.artifacts,
8104
+ missingEvidence: result.missingEvidence,
8105
+ blockers: result.blockers,
8106
+ sources: ["result"]
8107
+ };
8108
+ }
8109
+ function mergeResponsibilityEvidence(items) {
8110
+ const reports = items.filter((item) => item.sources.includes("report") && !item.sources.includes("result"));
8111
+ const results = items.filter((item) => item.sources.includes("result"));
8112
+ const usedReports = /* @__PURE__ */ new Set();
8113
+ const merged = [];
8114
+ for (const result of results) {
8115
+ const reportIndex = reports.findIndex(
8116
+ (report, index) => !usedReports.has(index) && evidenceMatches(report, result, reports)
8117
+ );
8118
+ if (reportIndex >= 0) {
8119
+ usedReports.add(reportIndex);
8120
+ merged.push(mergeReportAndResult(reports[reportIndex], result));
8121
+ } else {
8122
+ merged.push(result);
8123
+ }
8124
+ }
8125
+ for (let i = 0; i < reports.length; i += 1) {
8126
+ if (!usedReports.has(i)) merged.push(reports[i]);
8127
+ }
8128
+ return merged;
8129
+ }
8130
+ function applyAgentResponsibilityEvidenceToGoalState(state, evidence) {
8131
+ const priorFacts = parseFacts3(state.extra.facts) ?? {};
8132
+ const nextFacts = { ...priorFacts };
8133
+ for (const [key, value] of Object.entries(evidence.facts)) {
8134
+ if (CONTROL_FACT_KEYS3.has(key)) continue;
8135
+ nextFacts[key] = value;
8136
+ }
8137
+ for (const [key, value] of Object.entries(evidence.evidence ?? {})) {
8138
+ nextFacts[key] = value;
8139
+ }
8140
+ const pending = typeof nextFacts.pendingEvidence === "string" ? nextFacts.pendingEvidence : "";
8141
+ const statusEvidence = evidence.explicitEvidence || pending;
8142
+ const hasPendingEvidenceValue = pending ? Object.hasOwn(evidence.evidence ?? {}, pending) : false;
8143
+ const terminalStatus = evidence.status === "pass" || evidence.status === "fail" || evidence.status === "blocked";
8144
+ if (statusEvidence && !Object.hasOwn(evidence.evidence ?? {}, statusEvidence)) {
8145
+ if (evidence.status === "pass") nextFacts[statusEvidence] = true;
8146
+ if (evidence.status === "fail" || evidence.status === "blocked") nextFacts[statusEvidence] = false;
8147
+ }
8148
+ if (pending && (hasPendingEvidenceValue || statusEvidence === pending && terminalStatus)) {
8149
+ delete nextFacts.pendingEvidence;
8150
+ }
8151
+ const blockers = parseStringArray3(state.extra.blockers) ?? [];
8152
+ const evidenceBlockers = evidence.blockers.length > 0 || evidence.status !== "fail" && evidence.status !== "blocked" ? evidence.blockers : [evidence.summary];
8153
+ for (const blocker of evidenceBlockers) {
8154
+ if (!blockers.includes(blocker)) blockers.push(blocker);
8155
+ }
8156
+ const nextExtra = {
8157
+ ...state.extra,
8158
+ facts: nextFacts
8159
+ };
8160
+ if (blockers.length > 0 || Array.isArray(state.extra.blockers)) {
8161
+ nextExtra.blockers = blockers;
8162
+ }
8163
+ return {
8164
+ ...state,
8165
+ extra: nextExtra
8166
+ };
8167
+ }
8168
+ function evidenceMatches(report, result, allReports) {
8169
+ if (report.target.id !== result.target.id) return false;
8170
+ if (result.explicitEvidence && Object.hasOwn(report.evidence ?? {}, result.explicitEvidence)) return true;
8171
+ const resultEvidenceKeys = Object.keys(result.evidence ?? {});
8172
+ if (resultEvidenceKeys.length > 0 && resultEvidenceKeys.some((key) => Object.hasOwn(report.evidence ?? {}, key))) {
8173
+ return true;
8174
+ }
8175
+ return !result.explicitEvidence && resultEvidenceKeys.length === 0 && allReports.filter((item) => item.target.id === result.target.id).length === 1;
8176
+ }
8177
+ function mergeReportAndResult(report, result) {
8178
+ return {
8179
+ ...result,
8180
+ evidence: mergeOptionalRecords(report.evidence, result.evidence),
8181
+ facts: { ...report.facts, ...result.facts },
8182
+ artifacts: uniqueArtifacts([...report.artifacts, ...result.artifacts]),
8183
+ missingEvidence: uniqueStrings([...report.missingEvidence, ...result.missingEvidence]),
8184
+ blockers: uniqueStrings([...report.blockers, ...result.blockers]),
8185
+ sources: uniqueSources([...report.sources, ...result.sources])
8186
+ };
8187
+ }
8188
+ function mergeOptionalRecords(left, right) {
8189
+ const merged = { ...left ?? {}, ...right ?? {} };
8190
+ return Object.keys(merged).length > 0 ? merged : void 0;
8191
+ }
8192
+ function uniqueStrings(values) {
8193
+ return [...new Set(values)].sort();
8194
+ }
8195
+ function uniqueSources(values) {
8196
+ const order = ["report", "result"];
8197
+ const set = new Set(values);
8198
+ return order.filter((source) => set.has(source));
8199
+ }
8200
+ function uniqueArtifacts(artifacts) {
8201
+ const seen = /* @__PURE__ */ new Set();
8202
+ const out = [];
8203
+ for (const artifact of artifacts) {
8204
+ const key = `${artifact.label}
8205
+ ${artifact.url ?? ""}
8206
+ ${artifact.path ?? ""}`;
8207
+ if (seen.has(key)) continue;
8208
+ seen.add(key);
8209
+ out.push(artifact);
8210
+ }
8211
+ return out;
8212
+ }
8213
+ function parseFacts3(raw) {
8214
+ if (raw === void 0) return {};
8215
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
8216
+ const facts = {};
8217
+ for (const [key, value] of Object.entries(raw)) {
8218
+ if (!key.trim()) return null;
8219
+ if (CONTROL_FACT_KEYS3.has(key)) continue;
8220
+ facts[key] = value;
8221
+ }
8222
+ return facts;
8223
+ }
8224
+ function parseStringArray3(raw) {
8225
+ if (!Array.isArray(raw)) return null;
8226
+ const out = [];
8227
+ for (const item of raw) {
8228
+ if (typeof item !== "string") return null;
8229
+ out.push(item);
8230
+ }
8231
+ return out;
8232
+ }
8233
+ var CONTROL_FACT_KEYS3;
8234
+ var init_agent_responsibilityEvidence = __esm({
8235
+ "src/agent-responsibilityEvidence.ts"() {
8236
+ "use strict";
8237
+ CONTROL_FACT_KEYS3 = /* @__PURE__ */ new Set(["blockers", "destination", "agent-responsibilities", "route", "stage", "state"]);
8238
+ }
8239
+ });
8240
+
7793
8241
  // src/scripts/applyAgentResponsibilityReports.ts
7794
8242
  function flushLogs(ctx) {
7795
8243
  try {
@@ -7823,13 +8271,24 @@ function collectResults(raw, agentResult) {
7823
8271
  if (agentResult?.finalText) out.push(...parseAgentResponsibilityResultsFromText(agentResult.finalText));
7824
8272
  return out;
7825
8273
  }
7826
- function groupGoalReports(reports) {
7827
- const grouped = /* @__PURE__ */ new Map();
8274
+ function collectGoalResponsibilityEvidence(reports, results, fallbackGoalId, explicitEvidence) {
8275
+ const items = [];
7828
8276
  for (const report of reports) {
7829
- if (report.target.type !== "goal") continue;
7830
- const list = grouped.get(report.target.id) ?? [];
7831
- list.push(report);
7832
- grouped.set(report.target.id, list);
8277
+ const evidence = agentResponsibilityReportToEvidence(report);
8278
+ if (evidence) items.push(evidence);
8279
+ }
8280
+ for (const result of results) {
8281
+ const evidence = agentResponsibilityResultToEvidence(result, fallbackGoalId, explicitEvidence);
8282
+ if (evidence) items.push(evidence);
8283
+ }
8284
+ return mergeResponsibilityEvidence(items);
8285
+ }
8286
+ function groupGoalEvidence(evidenceItems) {
8287
+ const grouped = /* @__PURE__ */ new Map();
8288
+ for (const evidence of evidenceItems) {
8289
+ const list = grouped.get(evidence.target.id) ?? [];
8290
+ list.push(evidence);
8291
+ grouped.set(evidence.target.id, list);
7833
8292
  }
7834
8293
  return grouped;
7835
8294
  }
@@ -7842,16 +8301,72 @@ function completeSatisfiedManagedGoal(state) {
7842
8301
  if (decision.kind !== "done") return state;
7843
8302
  return writeManagedGoalToState({ ...state, state: "done" }, managed);
7844
8303
  }
7845
- function describeMessage(goalId, reports, results) {
7846
- const pieces = [];
7847
- if (reports && reports.length > 0) pieces.push(`report=${reports.length}`);
7848
- if (results.length > 0) pieces.push(`result=${results.map((result) => result.status).join(",")}`);
8304
+ function snapshotFromState(goalId, state) {
8305
+ const managed = managedGoalFromState(state);
8306
+ return managed ? goalRunLogSnapshot(goalId, state.state, managed) : null;
8307
+ }
8308
+ function responsibilityEvidenceOutput(evidence) {
8309
+ return {
8310
+ kind: "responsibility-evidence",
8311
+ sources: evidence.sources,
8312
+ status: evidence.status,
8313
+ summary: evidence.summary,
8314
+ evidence: evidence.evidence ?? {},
8315
+ facts: evidence.facts,
8316
+ artifacts: evidence.artifacts,
8317
+ missingEvidence: evidence.missingEvidence,
8318
+ blockers: evidence.blockers
8319
+ };
8320
+ }
8321
+ function evidenceInspection(goalBefore, goalAfter, responsibilityOutput, explicitEvidence) {
8322
+ return {
8323
+ expectedEvidence: {
8324
+ required: goalBefore?.requiredEvidence,
8325
+ missingBefore: goalBefore?.missingEvidence,
8326
+ pendingBefore: goalBefore?.pendingEvidence,
8327
+ explicit: explicitEvidence
8328
+ },
8329
+ responsibilityOutput,
8330
+ actualGoalState: {
8331
+ satisfiedEvidence: goalAfter?.satisfiedEvidence,
8332
+ missingEvidence: goalAfter?.missingEvidence,
8333
+ pendingEvidence: goalAfter?.pendingEvidence,
8334
+ blockers: goalAfter?.blockers
8335
+ }
8336
+ };
8337
+ }
8338
+ function evidenceDecision(change, goalAfter, responsibilityOutput) {
8339
+ return {
8340
+ kind: change ? "accept-evidence" : "no-state-change",
8341
+ status: responsibilityOutput.status,
8342
+ nextStep: nextStepFromEvidence(goalAfter, responsibilityOutput),
8343
+ reason: responsibilityOutput.summary
8344
+ };
8345
+ }
8346
+ function nextStepFromEvidence(goalAfter, responsibilityOutput) {
8347
+ const status = typeof responsibilityOutput.status === "string" ? responsibilityOutput.status : "";
8348
+ const outputBlockers = stringArrayField(responsibilityOutput, "blockers");
8349
+ const goalBlockers = stringArrayField(goalAfter, "blockers");
8350
+ const missingEvidence = stringArrayField(goalAfter, "missingEvidence");
8351
+ if (goalAfter && missingEvidence.length === 0) return "done";
8352
+ if (status === "fail" || status === "blocked" || outputBlockers.length > 0) return "rescue";
8353
+ if (goalBlockers.length > 0) return "block";
8354
+ if (missingEvidence.length > 0 && status !== "noop") return "dispatch";
8355
+ return "wait";
8356
+ }
8357
+ function stringArrayField(record2, key) {
8358
+ const value = record2?.[key];
8359
+ return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
8360
+ }
8361
+ function describeMessage(goalId, evidenceItems) {
8362
+ const pieces = evidenceItems.map((evidence) => `${evidence.sources.join("+")}:${evidence.status}`);
7849
8363
  return `Apply agentResponsibility output to ${goalId}${pieces.length > 0 ? ` (${pieces.join("; ")})` : ""}`;
7850
8364
  }
7851
8365
  var applyAgentResponsibilityReports;
7852
8366
  var init_applyAgentResponsibilityReports = __esm({
7853
8367
  "src/scripts/applyAgentResponsibilityReports.ts"() {
7854
8368
  "use strict";
8369
+ init_agent_responsibilityEvidence();
7855
8370
  init_agent_responsibilityReport();
7856
8371
  init_agent_responsibilityResult();
7857
8372
  init_manager();
@@ -7862,65 +8377,86 @@ var init_applyAgentResponsibilityReports = __esm({
7862
8377
  const reports = collectReports(ctx.data.agentResponsibilityReports, agentResult);
7863
8378
  const results = collectResults(ctx.data.dutyResults, agentResult);
7864
8379
  const resultGoalId = typeof ctx.args.goal === "string" && ctx.args.goal.length > 0 ? ctx.args.goal : null;
7865
- if (reports.length === 0 && (results.length === 0 || !resultGoalId)) return;
7866
- const reportsByGoal = groupGoalReports(reports);
7867
- const goalIds = new Set(reportsByGoal.keys());
7868
- if (results.length > 0 && resultGoalId) goalIds.add(resultGoalId);
7869
- for (const goalId of goalIds) {
8380
+ const explicitEvidence = typeof ctx.args.evidence === "string" && ctx.args.evidence.length > 0 ? ctx.args.evidence : void 0;
8381
+ const evidenceItems = collectGoalResponsibilityEvidence(reports, results, resultGoalId, explicitEvidence);
8382
+ if (evidenceItems.length === 0) return;
8383
+ const evidenceByGoal = groupGoalEvidence(evidenceItems);
8384
+ for (const [goalId, goalEvidence] of evidenceByGoal) {
7870
8385
  const prior = fetchGoalState(ctx.config, goalId, ctx.cwd);
7871
8386
  if (!prior) {
8387
+ stageGoalRunLogEvent(ctx.data, goalId, {
8388
+ source: "goal-loop",
8389
+ event: "goal.evidence.rejected",
8390
+ status: "rejected",
8391
+ reason: "goal missing in state repo",
8392
+ inspection: {
8393
+ responsibilityOutput: {
8394
+ kind: "responsibility-evidence",
8395
+ count: goalEvidence.length,
8396
+ items: goalEvidence.map(responsibilityEvidenceOutput)
8397
+ },
8398
+ missingEvidence: [],
8399
+ blockers: ["goal missing in state repo"]
8400
+ },
8401
+ decision: { kind: "reject-evidence", nextStep: "block", reason: "goal missing in state repo" }
8402
+ });
8403
+ flushLogs(ctx);
7872
8404
  process.stderr.write(`[kody agentResponsibility-report] goal ${goalId} missing in state repo; report skipped
7873
8405
  `);
7874
8406
  continue;
7875
8407
  }
7876
8408
  let next = prior;
7877
- for (const report of reportsByGoal.get(goalId) ?? []) {
8409
+ for (const evidence of goalEvidence) {
8410
+ const beforeSnapshot = snapshotFromState(goalId, next);
8411
+ next = applyAgentResponsibilityEvidenceToGoalState(next, evidence);
8412
+ const afterSnapshot = snapshotFromState(goalId, next);
8413
+ const change = goalRunLogChange(beforeSnapshot, afterSnapshot);
8414
+ const output = responsibilityEvidenceOutput(evidence);
7878
8415
  stageGoalRunLogEvent(ctx.data, goalId, {
7879
- source: "goal-report",
7880
- event: "goal.evidence.reported",
7881
- goalState: prior.state,
7882
- evidenceValues: report.evidence,
7883
- facts: report.facts
8416
+ source: "goal-loop",
8417
+ event: change ? "goal.evidence.applied" : "goal.evidence.unchanged",
8418
+ goalState: next.state,
8419
+ evidence: evidence.explicitEvidence,
8420
+ evidenceValues: evidence.evidence,
8421
+ status: evidence.status,
8422
+ reason: evidence.summary,
8423
+ facts: evidence.facts,
8424
+ artifacts: evidence.artifacts,
8425
+ goal: afterSnapshot ?? void 0,
8426
+ inspection: evidenceInspection(beforeSnapshot, afterSnapshot, output, evidence.explicitEvidence),
8427
+ decision: {
8428
+ ...evidenceDecision(change, afterSnapshot, output),
8429
+ evidence: evidence.explicitEvidence,
8430
+ evidenceValues: evidence.evidence
8431
+ },
8432
+ change
7884
8433
  });
7885
- next = applyAgentResponsibilityReportToGoalState(next, report);
7886
- }
7887
- if (goalId === resultGoalId) {
7888
- const evidence = typeof ctx.args.evidence === "string" && ctx.args.evidence.length > 0 ? ctx.args.evidence : void 0;
7889
- for (const result of results) {
7890
- stageGoalRunLogEvent(ctx.data, goalId, {
7891
- source: "goal-report",
7892
- event: "goal.result.applied",
7893
- goalState: prior.state,
7894
- evidence,
7895
- status: result.status,
7896
- reason: result.summary,
7897
- facts: result.facts,
7898
- artifacts: result.artifacts
7899
- });
7900
- next = applyAgentResponsibilityResultToObjectiveState(next, result, evidence);
7901
- }
7902
8434
  }
8435
+ const beforeCompletionSnapshot = snapshotFromState(goalId, next);
7903
8436
  next = completeSatisfiedManagedGoal(next);
8437
+ const afterCompletionSnapshot = snapshotFromState(goalId, next);
7904
8438
  if (prior.state !== "done" && next.state === "done") {
7905
8439
  stageGoalRunLogEvent(ctx.data, goalId, {
7906
- source: "goal-report",
7907
- event: "goal.completed",
8440
+ source: "goal-loop",
8441
+ event: "goal.decision.done",
7908
8442
  goalState: "done",
7909
8443
  status: "done",
7910
- reason: "destination evidence satisfied"
8444
+ reason: "destination evidence satisfied",
8445
+ goal: afterCompletionSnapshot ?? void 0,
8446
+ inspection: {
8447
+ requiredEvidence: beforeCompletionSnapshot?.requiredEvidence,
8448
+ satisfiedEvidence: beforeCompletionSnapshot?.satisfiedEvidence,
8449
+ missingEvidence: beforeCompletionSnapshot?.missingEvidence
8450
+ },
8451
+ decision: { kind: "done", nextStep: "done", reason: "destination evidence satisfied" },
8452
+ change: goalRunLogChange(beforeCompletionSnapshot, afterCompletionSnapshot)
7911
8453
  });
7912
8454
  }
7913
8455
  if (serializeGoalState(next) === serializeGoalState(prior)) {
7914
8456
  flushLogs(ctx);
7915
8457
  continue;
7916
8458
  }
7917
- putGoalState(
7918
- ctx.config,
7919
- goalId,
7920
- { ...next, updatedAt: nowIso() },
7921
- describeMessage(goalId, reportsByGoal.get(goalId), results),
7922
- ctx.cwd
7923
- );
8459
+ putGoalState(ctx.config, goalId, { ...next, updatedAt: nowIso() }, describeMessage(goalId, goalEvidence), ctx.cwd);
7924
8460
  flushLogs(ctx);
7925
8461
  }
7926
8462
  };
@@ -8093,7 +8629,7 @@ var init_classifyByLabel = __esm({
8093
8629
  });
8094
8630
 
8095
8631
  // src/scripts/commitAndPush.ts
8096
- import * as fs26 from "fs";
8632
+ import * as fs27 from "fs";
8097
8633
  import * as path26 from "path";
8098
8634
  function sentinelPathForStage(cwd, profileName) {
8099
8635
  const runId = resolveRunId();
@@ -8115,9 +8651,9 @@ var init_commitAndPush = __esm({
8115
8651
  }
8116
8652
  const idempotencyEnabled = process.env.KODY_COMMIT_IDEMPOTENCY !== "0";
8117
8653
  const sentinel = idempotencyEnabled ? sentinelPathForStage(ctx.cwd, profile.name) : null;
8118
- if (sentinel && fs26.existsSync(sentinel)) {
8654
+ if (sentinel && fs27.existsSync(sentinel)) {
8119
8655
  try {
8120
- const replay = JSON.parse(fs26.readFileSync(sentinel, "utf-8"));
8656
+ const replay = JSON.parse(fs27.readFileSync(sentinel, "utf-8"));
8121
8657
  ctx.data.commitResult = replay.commitResult ?? { committed: false, pushed: false };
8122
8658
  if (Array.isArray(replay.changedFiles)) ctx.data.changedFiles = replay.changedFiles;
8123
8659
  if (typeof replay.hasCommitsAhead === "boolean") ctx.data.hasCommitsAhead = replay.hasCommitsAhead;
@@ -8170,8 +8706,8 @@ var init_commitAndPush = __esm({
8170
8706
  const result = ctx.data.commitResult;
8171
8707
  if (sentinel && result?.committed) {
8172
8708
  try {
8173
- fs26.mkdirSync(path26.dirname(sentinel), { recursive: true });
8174
- fs26.writeFileSync(
8709
+ fs27.mkdirSync(path26.dirname(sentinel), { recursive: true });
8710
+ fs27.writeFileSync(
8175
8711
  sentinel,
8176
8712
  JSON.stringify(
8177
8713
  {
@@ -8243,7 +8779,7 @@ var init_commitGoalState = __esm({
8243
8779
  });
8244
8780
 
8245
8781
  // src/scripts/composePrompt.ts
8246
- import * as fs27 from "fs";
8782
+ import * as fs28 from "fs";
8247
8783
  import * as path27 from "path";
8248
8784
  function fenceUntrusted(value) {
8249
8785
  if (value.trim().length === 0) return value;
@@ -8383,7 +8919,7 @@ var init_composePrompt = __esm({
8383
8919
  break;
8384
8920
  }
8385
8921
  try {
8386
- template = fs27.readFileSync(c, "utf-8");
8922
+ template = fs28.readFileSync(c, "utf-8");
8387
8923
  templatePath = c;
8388
8924
  break;
8389
8925
  } catch (err) {
@@ -8394,7 +8930,7 @@ var init_composePrompt = __esm({
8394
8930
  if (!templatePath) {
8395
8931
  let dirState;
8396
8932
  try {
8397
- dirState = `dir contents: [${fs27.readdirSync(profile.dir).join(", ")}]`;
8933
+ dirState = `dir contents: [${fs28.readdirSync(profile.dir).join(", ")}]`;
8398
8934
  } catch (err) {
8399
8935
  dirState = `readdir(${profile.dir}) failed: ${err?.code ?? String(err)}`;
8400
8936
  }
@@ -8966,7 +9502,7 @@ var init_deriveQaScopeFromIssue = __esm({
8966
9502
 
8967
9503
  // src/scripts/diagMcp.ts
8968
9504
  import { execFileSync as execFileSync10 } from "child_process";
8969
- import * as fs28 from "fs";
9505
+ import * as fs29 from "fs";
8970
9506
  import * as os6 from "os";
8971
9507
  import * as path28 from "path";
8972
9508
  var diagMcp;
@@ -8978,7 +9514,7 @@ var init_diagMcp = __esm({
8978
9514
  const cacheDir = path28.join(home, ".cache", "ms-playwright");
8979
9515
  let entries = [];
8980
9516
  try {
8981
- entries = fs28.readdirSync(cacheDir);
9517
+ entries = fs29.readdirSync(cacheDir);
8982
9518
  } catch {
8983
9519
  }
8984
9520
  const hasChromium = entries.some((e) => e.startsWith("chromium"));
@@ -9006,13 +9542,13 @@ var init_diagMcp = __esm({
9006
9542
  });
9007
9543
 
9008
9544
  // src/scripts/frameworkDetectors.ts
9009
- import * as fs29 from "fs";
9545
+ import * as fs30 from "fs";
9010
9546
  import * as path29 from "path";
9011
9547
  function detectFrameworks(cwd) {
9012
9548
  const out = [];
9013
9549
  let deps = {};
9014
9550
  try {
9015
- const pkg = JSON.parse(fs29.readFileSync(path29.join(cwd, "package.json"), "utf-8"));
9551
+ const pkg = JSON.parse(fs30.readFileSync(path29.join(cwd, "package.json"), "utf-8"));
9016
9552
  deps = { ...pkg.dependencies, ...pkg.devDependencies };
9017
9553
  } catch {
9018
9554
  return out;
@@ -9049,7 +9585,7 @@ function detectFrameworks(cwd) {
9049
9585
  }
9050
9586
  function findFile(cwd, candidates) {
9051
9587
  for (const c of candidates) {
9052
- if (fs29.existsSync(path29.join(cwd, c))) return c;
9588
+ if (fs30.existsSync(path29.join(cwd, c))) return c;
9053
9589
  }
9054
9590
  return null;
9055
9591
  }
@@ -9057,17 +9593,17 @@ function discoverPayloadCollections(cwd) {
9057
9593
  const out = [];
9058
9594
  for (const dir of COLLECTION_DIRS) {
9059
9595
  const full = path29.join(cwd, dir);
9060
- if (!fs29.existsSync(full)) continue;
9596
+ if (!fs30.existsSync(full)) continue;
9061
9597
  let files;
9062
9598
  try {
9063
- files = fs29.readdirSync(full).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
9599
+ files = fs30.readdirSync(full).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
9064
9600
  } catch {
9065
9601
  continue;
9066
9602
  }
9067
9603
  for (const file of files) {
9068
9604
  try {
9069
9605
  const filePath = path29.join(full, file);
9070
- const content = fs29.readFileSync(filePath, "utf-8").slice(0, 1e4);
9606
+ const content = fs30.readFileSync(filePath, "utf-8").slice(0, 1e4);
9071
9607
  const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
9072
9608
  if (!slugMatch) continue;
9073
9609
  const slug2 = slugMatch[1];
@@ -9095,10 +9631,10 @@ function discoverAdminComponents(cwd, collections) {
9095
9631
  const out = [];
9096
9632
  for (const dir of ADMIN_COMPONENT_DIRS) {
9097
9633
  const full = path29.join(cwd, dir);
9098
- if (!fs29.existsSync(full)) continue;
9634
+ if (!fs30.existsSync(full)) continue;
9099
9635
  let entries;
9100
9636
  try {
9101
- entries = fs29.readdirSync(full, { withFileTypes: true });
9637
+ entries = fs30.readdirSync(full, { withFileTypes: true });
9102
9638
  } catch {
9103
9639
  continue;
9104
9640
  }
@@ -9108,7 +9644,7 @@ function discoverAdminComponents(cwd, collections) {
9108
9644
  let filePath;
9109
9645
  if (entry.isDirectory()) {
9110
9646
  const indexFile = ["index.tsx", "index.ts", "index.jsx", "index.js"].find(
9111
- (f) => fs29.existsSync(path29.join(entryPath, f))
9647
+ (f) => fs30.existsSync(path29.join(entryPath, f))
9112
9648
  );
9113
9649
  if (!indexFile) continue;
9114
9650
  name = entry.name;
@@ -9123,7 +9659,7 @@ function discoverAdminComponents(cwd, collections) {
9123
9659
  if (collections) {
9124
9660
  for (const col of collections) {
9125
9661
  try {
9126
- const colContent = fs29.readFileSync(path29.join(cwd, col.filePath), "utf-8");
9662
+ const colContent = fs30.readFileSync(path29.join(cwd, col.filePath), "utf-8");
9127
9663
  if (colContent.includes(name)) {
9128
9664
  usedInCollection = col.slug;
9129
9665
  break;
@@ -9142,7 +9678,7 @@ function scanApiRoutes(cwd) {
9142
9678
  const appDirs = ["src/app", "app"];
9143
9679
  for (const appDir of appDirs) {
9144
9680
  const apiDir = path29.join(cwd, appDir, "api");
9145
- if (!fs29.existsSync(apiDir)) continue;
9681
+ if (!fs30.existsSync(apiDir)) continue;
9146
9682
  walkApiRoutes(apiDir, "/api", cwd, out);
9147
9683
  break;
9148
9684
  }
@@ -9151,14 +9687,14 @@ function scanApiRoutes(cwd) {
9151
9687
  function walkApiRoutes(dir, prefix, cwd, out) {
9152
9688
  let entries;
9153
9689
  try {
9154
- entries = fs29.readdirSync(dir, { withFileTypes: true });
9690
+ entries = fs30.readdirSync(dir, { withFileTypes: true });
9155
9691
  } catch {
9156
9692
  return;
9157
9693
  }
9158
9694
  const routeFile = entries.find((e) => e.isFile() && /^route\.(ts|js|tsx|jsx)$/.test(e.name));
9159
9695
  if (routeFile) {
9160
9696
  try {
9161
- const content = fs29.readFileSync(path29.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
9697
+ const content = fs30.readFileSync(path29.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
9162
9698
  const methods = HTTP_METHODS.filter(
9163
9699
  (m) => new RegExp(`export\\s+(?:async\\s+)?function\\s+${m}\\b`).test(content)
9164
9700
  );
@@ -9192,9 +9728,9 @@ function scanEnvVars(cwd) {
9192
9728
  const candidates = [".env.example", ".env.local.example", ".env.template"];
9193
9729
  for (const envFile of candidates) {
9194
9730
  const envPath = path29.join(cwd, envFile);
9195
- if (!fs29.existsSync(envPath)) continue;
9731
+ if (!fs30.existsSync(envPath)) continue;
9196
9732
  try {
9197
- const content = fs29.readFileSync(envPath, "utf-8");
9733
+ const content = fs30.readFileSync(envPath, "utf-8");
9198
9734
  const vars = [];
9199
9735
  for (const line of content.split("\n")) {
9200
9736
  const trimmed = line.trim();
@@ -9239,7 +9775,7 @@ var init_frameworkDetectors = __esm({
9239
9775
  });
9240
9776
 
9241
9777
  // src/scripts/discoverQaContext.ts
9242
- import * as fs30 from "fs";
9778
+ import * as fs31 from "fs";
9243
9779
  import * as path30 from "path";
9244
9780
  function runQaDiscovery(cwd) {
9245
9781
  const out = {
@@ -9271,9 +9807,9 @@ function runQaDiscovery(cwd) {
9271
9807
  }
9272
9808
  function detectDevServer(cwd, out) {
9273
9809
  try {
9274
- const pkg = JSON.parse(fs30.readFileSync(path30.join(cwd, "package.json"), "utf-8"));
9810
+ const pkg = JSON.parse(fs31.readFileSync(path30.join(cwd, "package.json"), "utf-8"));
9275
9811
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
9276
- const pm = fs30.existsSync(path30.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs30.existsSync(path30.join(cwd, "yarn.lock")) ? "yarn" : fs30.existsSync(path30.join(cwd, "bun.lockb")) ? "bun" : "npm";
9812
+ 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";
9277
9813
  if (pkg.scripts?.dev) out.devCommand = `${pm} dev`;
9278
9814
  if (allDeps.next || allDeps.nuxt) out.devPort = 3e3;
9279
9815
  else if (allDeps.vite) out.devPort = 5173;
@@ -9284,7 +9820,7 @@ function scanFrontendRoutes(cwd, out) {
9284
9820
  const appDirs = ["src/app", "app"];
9285
9821
  for (const appDir of appDirs) {
9286
9822
  const full = path30.join(cwd, appDir);
9287
- if (!fs30.existsSync(full)) continue;
9823
+ if (!fs31.existsSync(full)) continue;
9288
9824
  walkFrontendRoutes(full, "", out);
9289
9825
  break;
9290
9826
  }
@@ -9292,7 +9828,7 @@ function scanFrontendRoutes(cwd, out) {
9292
9828
  function walkFrontendRoutes(dir, prefix, out) {
9293
9829
  let entries;
9294
9830
  try {
9295
- entries = fs30.readdirSync(dir, { withFileTypes: true });
9831
+ entries = fs31.readdirSync(dir, { withFileTypes: true });
9296
9832
  } catch {
9297
9833
  return;
9298
9834
  }
@@ -9334,23 +9870,23 @@ function detectAuthFiles(cwd, out) {
9334
9870
  "src/app/api/oauth"
9335
9871
  ];
9336
9872
  for (const c of candidates) {
9337
- if (fs30.existsSync(path30.join(cwd, c))) out.authFiles.push(c);
9873
+ if (fs31.existsSync(path30.join(cwd, c))) out.authFiles.push(c);
9338
9874
  }
9339
9875
  }
9340
9876
  function detectRoles(cwd, out) {
9341
9877
  const rolePaths = ["src/types", "src/lib", "src/utils", "src/constants", "src/access", "src/collections"];
9342
9878
  for (const rp of rolePaths) {
9343
9879
  const dir = path30.join(cwd, rp);
9344
- if (!fs30.existsSync(dir)) continue;
9880
+ if (!fs31.existsSync(dir)) continue;
9345
9881
  let files;
9346
9882
  try {
9347
- files = fs30.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
9883
+ files = fs31.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
9348
9884
  } catch {
9349
9885
  continue;
9350
9886
  }
9351
9887
  for (const f of files) {
9352
9888
  try {
9353
- const content = fs30.readFileSync(path30.join(dir, f), "utf-8").slice(0, 5e3);
9889
+ const content = fs31.readFileSync(path30.join(dir, f), "utf-8").slice(0, 5e3);
9354
9890
  const roleMatches = content.match(/(?:role|Role|ROLE)\s*[=:]\s*['"](\w+)['"]/g);
9355
9891
  if (roleMatches) {
9356
9892
  for (const m of roleMatches) {
@@ -10564,12 +11100,12 @@ var init_fixFlow = __esm({
10564
11100
 
10565
11101
  // src/scripts/initFlow.ts
10566
11102
  import { execFileSync as execFileSync15 } from "child_process";
10567
- import * as fs31 from "fs";
11103
+ import * as fs32 from "fs";
10568
11104
  import * as path31 from "path";
10569
11105
  function detectPackageManager(cwd) {
10570
- if (fs31.existsSync(path31.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
10571
- if (fs31.existsSync(path31.join(cwd, "yarn.lock"))) return "yarn";
10572
- if (fs31.existsSync(path31.join(cwd, "bun.lockb"))) return "bun";
11106
+ if (fs32.existsSync(path31.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
11107
+ if (fs32.existsSync(path31.join(cwd, "yarn.lock"))) return "yarn";
11108
+ if (fs32.existsSync(path31.join(cwd, "bun.lockb"))) return "bun";
10573
11109
  return "npm";
10574
11110
  }
10575
11111
  function qualityCommandsFor(pm) {
@@ -10642,21 +11178,21 @@ function performInit(cwd, force) {
10642
11178
  const ownerRepo = detectOwnerRepo(cwd);
10643
11179
  const defaultBranch = defaultBranchFromGit(cwd);
10644
11180
  const configPath = path31.join(cwd, "kody.config.json");
10645
- if (fs31.existsSync(configPath) && !force) {
11181
+ if (fs32.existsSync(configPath) && !force) {
10646
11182
  skipped.push("kody.config.json");
10647
11183
  } else {
10648
11184
  const cfg = makeConfig(pm, ownerRepo, defaultBranch);
10649
- fs31.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
11185
+ fs32.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
10650
11186
  `);
10651
11187
  wrote.push("kody.config.json");
10652
11188
  }
10653
11189
  const workflowDir = path31.join(cwd, ".github", "workflows");
10654
11190
  const workflowPath = path31.join(workflowDir, "kody.yml");
10655
- if (fs31.existsSync(workflowPath) && !force) {
11191
+ if (fs32.existsSync(workflowPath) && !force) {
10656
11192
  skipped.push(".github/workflows/kody.yml");
10657
11193
  } else {
10658
- fs31.mkdirSync(workflowDir, { recursive: true });
10659
- fs31.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
11194
+ fs32.mkdirSync(workflowDir, { recursive: true });
11195
+ fs32.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
10660
11196
  wrote.push(".github/workflows/kody.yml");
10661
11197
  }
10662
11198
  for (const exe of listAgentActions()) {
@@ -10668,11 +11204,11 @@ function performInit(cwd, force) {
10668
11204
  }
10669
11205
  if (profile.kind !== "scheduled" || !profile.schedule) continue;
10670
11206
  const target = path31.join(workflowDir, `kody-${exe.name}.yml`);
10671
- if (fs31.existsSync(target) && !force) {
11207
+ if (fs32.existsSync(target) && !force) {
10672
11208
  skipped.push(`.github/workflows/kody-${exe.name}.yml`);
10673
11209
  continue;
10674
11210
  }
10675
- fs31.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
11211
+ fs32.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
10676
11212
  wrote.push(`.github/workflows/kody-${exe.name}.yml`);
10677
11213
  }
10678
11214
  let labels;
@@ -10825,7 +11361,7 @@ Nothing to do. All files already present. (Use --force to overwrite.)
10825
11361
  });
10826
11362
 
10827
11363
  // src/scripts/loadAgentAdhoc.ts
10828
- import * as fs32 from "fs";
11364
+ import * as fs33 from "fs";
10829
11365
  function resolveMessage(messageArg) {
10830
11366
  const fromComment = readCommentBody();
10831
11367
  if (fromComment) return stripDirective(fromComment);
@@ -10833,9 +11369,9 @@ function resolveMessage(messageArg) {
10833
11369
  }
10834
11370
  function readCommentBody() {
10835
11371
  const eventPath = process.env.GITHUB_EVENT_PATH;
10836
- if (!eventPath || !fs32.existsSync(eventPath)) return "";
11372
+ if (!eventPath || !fs33.existsSync(eventPath)) return "";
10837
11373
  try {
10838
- const event = JSON.parse(fs32.readFileSync(eventPath, "utf-8"));
11374
+ const event = JSON.parse(fs33.readFileSync(eventPath, "utf-8"));
10839
11375
  return String(event.comment?.body ?? "");
10840
11376
  } catch {
10841
11377
  return "";
@@ -10888,10 +11424,10 @@ var init_loadAgentAdhoc = __esm({
10888
11424
  throw new Error("loadAgentAdhoc: ctx.args.agent must be a non-empty slug");
10889
11425
  }
10890
11426
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
10891
- if (!fs32.existsSync(agentPath)) {
11427
+ if (!fs33.existsSync(agentPath)) {
10892
11428
  throw new Error(`loadAgentAdhoc: agent identity not found: ${agentPath}`);
10893
11429
  }
10894
- const { title, body } = parseAgentFile(fs32.readFileSync(agentPath, "utf-8"), agentSlug);
11430
+ const { title, body } = parseAgentFile(fs33.readFileSync(agentPath, "utf-8"), agentSlug);
10895
11431
  const message = resolveMessage(ctx.args.message);
10896
11432
  if (!message) {
10897
11433
  throw new Error(
@@ -11129,7 +11665,7 @@ var init_loadIssueStateComment = __esm({
11129
11665
  });
11130
11666
 
11131
11667
  // src/scripts/loadJobFromFile.ts
11132
- import * as fs33 from "fs";
11668
+ import * as fs34 from "fs";
11133
11669
  import * as path32 from "path";
11134
11670
  function parseJobFile(raw, slug2) {
11135
11671
  let stripped = raw;
@@ -11181,12 +11717,12 @@ var init_loadJobFromFile = __esm({
11181
11717
  let agentIdentity = "";
11182
11718
  if (agentSlug) {
11183
11719
  const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
11184
- if (!fs33.existsSync(agentPath)) {
11720
+ if (!fs34.existsSync(agentPath)) {
11185
11721
  throw new Error(
11186
11722
  `loadJobFromFile: agentResponsibility '${slug2}' declares agent '${agentSlug}' but ${agentPath} does not exist`
11187
11723
  );
11188
11724
  }
11189
- const agentRaw = fs33.readFileSync(agentPath, "utf-8");
11725
+ const agentRaw = fs34.readFileSync(agentPath, "utf-8");
11190
11726
  const parsed = parseJobFile(agentRaw, agentSlug);
11191
11727
  agentTitle = parsed.title;
11192
11728
  agentIdentity = parsed.body;
@@ -11260,13 +11796,13 @@ ${truncate(issue.body, FINDING_BODY_MAX_BYTES)}`;
11260
11796
  });
11261
11797
 
11262
11798
  // src/scripts/kodyVariables.ts
11263
- import * as fs34 from "fs";
11799
+ import * as fs35 from "fs";
11264
11800
  import * as path33 from "path";
11265
11801
  function readKodyVariables(cwd) {
11266
11802
  const full = path33.join(cwd, KODY_VARIABLES_REL_PATH);
11267
11803
  let raw;
11268
11804
  try {
11269
- raw = fs34.readFileSync(full, "utf-8");
11805
+ raw = fs35.readFileSync(full, "utf-8");
11270
11806
  } catch {
11271
11807
  return {};
11272
11808
  }
@@ -11291,7 +11827,7 @@ var init_kodyVariables = __esm({
11291
11827
  });
11292
11828
 
11293
11829
  // src/scripts/loadQaContext.ts
11294
- import * as fs35 from "fs";
11830
+ import * as fs36 from "fs";
11295
11831
  import * as path34 from "path";
11296
11832
  function parseSlugList(value) {
11297
11833
  const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
@@ -11322,17 +11858,17 @@ function readProfileAgents(raw) {
11322
11858
  }
11323
11859
  function readProfile(cwd) {
11324
11860
  const dir = path34.join(cwd, CONTEXT_DIR_REL_PATH);
11325
- if (!fs35.existsSync(dir)) return "";
11861
+ if (!fs36.existsSync(dir)) return "";
11326
11862
  let entries;
11327
11863
  try {
11328
- entries = fs35.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
11864
+ entries = fs36.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
11329
11865
  } catch {
11330
11866
  return "";
11331
11867
  }
11332
11868
  const blocks = [];
11333
11869
  for (const file of entries) {
11334
11870
  try {
11335
- const raw = fs35.readFileSync(path34.join(dir, file), "utf-8");
11871
+ const raw = fs36.readFileSync(path34.join(dir, file), "utf-8");
11336
11872
  const { agent, body } = readProfileAgents(raw);
11337
11873
  if (!agent.includes(QA_AGENT) && !agent.includes(ALL_AGENTS)) continue;
11338
11874
  blocks.push(`## ${file}
@@ -11378,7 +11914,7 @@ var init_loadQaContext = __esm({
11378
11914
  });
11379
11915
 
11380
11916
  // src/taskContext.ts
11381
- import * as fs36 from "fs";
11917
+ import * as fs37 from "fs";
11382
11918
  import * as path35 from "path";
11383
11919
  function buildTaskContext(args) {
11384
11920
  return {
@@ -11395,9 +11931,9 @@ function buildTaskContext(args) {
11395
11931
  function persistTaskContext(cwd, ctx) {
11396
11932
  try {
11397
11933
  const dir = runtimeStatePath(cwd, "agent-runs", ctx.runId);
11398
- fs36.mkdirSync(dir, { recursive: true });
11934
+ fs37.mkdirSync(dir, { recursive: true });
11399
11935
  const file = path35.join(dir, "task-context.json");
11400
- fs36.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
11936
+ fs37.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
11401
11937
  `);
11402
11938
  return file;
11403
11939
  } catch (err) {
@@ -13742,9 +14278,9 @@ fi
13742
14278
  });
13743
14279
 
13744
14280
  // src/stateRepoGithub.ts
13745
- import * as fs37 from "fs";
14281
+ import * as fs38 from "fs";
13746
14282
  import * as path36 from "path";
13747
- function recordValue2(value) {
14283
+ function recordValue3(value) {
13748
14284
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
13749
14285
  }
13750
14286
  function contentsUrl(owner, repo, filePath) {
@@ -13800,12 +14336,12 @@ async function loadGithubStateConfig(opts) {
13800
14336
  throw new Error(`kody.config.json is invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
13801
14337
  }
13802
14338
  }
13803
- const githubRaw = recordValue2(raw.github) ?? {};
14339
+ const githubRaw = recordValue3(raw.github) ?? {};
13804
14340
  const github = {
13805
14341
  owner: typeof githubRaw.owner === "string" && githubRaw.owner.trim() ? githubRaw.owner.trim() : opts.owner,
13806
14342
  repo: typeof githubRaw.repo === "string" && githubRaw.repo.trim() ? githubRaw.repo.trim() : opts.repo
13807
14343
  };
13808
- const nestedState = recordValue2(raw.state) ?? {};
14344
+ const nestedState = recordValue3(raw.state) ?? {};
13809
14345
  const repoRaw = typeof raw.stateRepo === "string" ? raw.stateRepo : nestedState.repo;
13810
14346
  const pathRaw = typeof raw.statePath === "string" ? raw.statePath : nestedState.path;
13811
14347
  const stateRepo = typeof repoRaw === "string" && repoRaw.trim().length > 0 ? repoRaw.trim() : `https://github.com/${github.owner}/kody-state`;
@@ -13883,15 +14419,15 @@ function mergeJsonl(localText, remoteText) {
13883
14419
  async function syncJsonlFileFromGithubState(opts) {
13884
14420
  const remote = await readGithubStateTextWithConfig(opts);
13885
14421
  if (!remote) return;
13886
- const local = fs37.existsSync(opts.localPath) ? fs37.readFileSync(opts.localPath, "utf-8") : "";
14422
+ const local = fs38.existsSync(opts.localPath) ? fs38.readFileSync(opts.localPath, "utf-8") : "";
13887
14423
  const next = mergeJsonl(local, remote.content);
13888
14424
  if (next === local) return;
13889
- fs37.mkdirSync(path36.dirname(opts.localPath), { recursive: true });
13890
- fs37.writeFileSync(opts.localPath, next);
14425
+ fs38.mkdirSync(path36.dirname(opts.localPath), { recursive: true });
14426
+ fs38.writeFileSync(opts.localPath, next);
13891
14427
  }
13892
14428
  async function persistJsonlFileToGithubState(opts) {
13893
- if (!fs37.existsSync(opts.localPath)) return;
13894
- const localText = fs37.readFileSync(opts.localPath, "utf-8");
14429
+ if (!fs38.existsSync(opts.localPath)) return;
14430
+ const localText = fs38.readFileSync(opts.localPath, "utf-8");
13895
14431
  for (let attempt = 1; attempt <= 3; attempt += 1) {
13896
14432
  const remote = await readGithubStateTextWithConfig(opts);
13897
14433
  const body = mergeJsonl(localText, remote?.content ?? "");
@@ -14368,7 +14904,7 @@ var init_tickShellRunner = __esm({
14368
14904
  });
14369
14905
 
14370
14906
  // src/scripts/runScheduledAgentActionTick.ts
14371
- import * as fs38 from "fs";
14907
+ import * as fs39 from "fs";
14372
14908
  import * as path38 from "path";
14373
14909
  var runScheduledAgentActionTick;
14374
14910
  var init_runScheduledAgentActionTick = __esm({
@@ -14396,7 +14932,7 @@ var init_runScheduledAgentActionTick = __esm({
14396
14932
  return;
14397
14933
  }
14398
14934
  const shellPath = path38.join(profile.dir, shell);
14399
- if (!fs38.existsSync(shellPath)) {
14935
+ if (!fs39.existsSync(shellPath)) {
14400
14936
  ctx.output.exitCode = 99;
14401
14937
  ctx.output.reason = `runScheduledAgentActionTick: shell not found: ${shell} (looked in ${profile.dir})`;
14402
14938
  return;
@@ -14427,7 +14963,7 @@ var init_runScheduledAgentActionTick = __esm({
14427
14963
  });
14428
14964
 
14429
14965
  // src/scripts/runTickScript.ts
14430
- import * as fs39 from "fs";
14966
+ import * as fs40 from "fs";
14431
14967
  import * as path39 from "path";
14432
14968
  var runTickScript;
14433
14969
  var init_runTickScript = __esm({
@@ -14460,7 +14996,7 @@ var init_runTickScript = __esm({
14460
14996
  return;
14461
14997
  }
14462
14998
  const scriptPath = path39.isAbsolute(tickScript) ? tickScript : path39.join(ctx.cwd, tickScript);
14463
- if (!fs39.existsSync(scriptPath)) {
14999
+ if (!fs40.existsSync(scriptPath)) {
14464
15000
  ctx.output.exitCode = 99;
14465
15001
  ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
14466
15002
  return;
@@ -15282,7 +15818,7 @@ var init_warmupMcp = __esm({
15282
15818
  });
15283
15819
 
15284
15820
  // src/scripts/writeAgentRunSummary.ts
15285
- import * as fs40 from "fs";
15821
+ import * as fs41 from "fs";
15286
15822
  var writeAgentRunSummary;
15287
15823
  var init_writeAgentRunSummary = __esm({
15288
15824
  "src/scripts/writeAgentRunSummary.ts"() {
@@ -15308,7 +15844,7 @@ var init_writeAgentRunSummary = __esm({
15308
15844
  if (reason) lines.push(`- **Reason:** ${reason}`);
15309
15845
  lines.push("");
15310
15846
  try {
15311
- fs40.appendFileSync(summaryPath, `${lines.join("\n")}
15847
+ fs41.appendFileSync(summaryPath, `${lines.join("\n")}
15312
15848
  `);
15313
15849
  } catch {
15314
15850
  }
@@ -15710,17 +16246,17 @@ var init_scripts = __esm({
15710
16246
  });
15711
16247
 
15712
16248
  // src/stateWorkspace.ts
15713
- import * as fs41 from "fs";
16249
+ import * as fs42 from "fs";
15714
16250
  import * as path40 from "path";
15715
16251
  function writeLocalFile(cwd, relativePath, content) {
15716
16252
  const fullPath = path40.join(cwd, relativePath);
15717
- fs41.mkdirSync(path40.dirname(fullPath), { recursive: true });
15718
- fs41.writeFileSync(fullPath, content);
16253
+ fs42.mkdirSync(path40.dirname(fullPath), { recursive: true });
16254
+ fs42.writeFileSync(fullPath, content);
15719
16255
  }
15720
16256
  function hydrateDirectory(config, cwd, stateDir, localDir) {
15721
16257
  const entries = listStateDirectory(config, cwd, stateDir);
15722
16258
  if (entries.length === 0) return;
15723
- fs41.rmSync(path40.join(cwd, localDir), { recursive: true, force: true });
16259
+ fs42.rmSync(path40.join(cwd, localDir), { recursive: true, force: true });
15724
16260
  for (const entry of entries) {
15725
16261
  if (!entry.name || !entry.type) continue;
15726
16262
  const childState = path40.posix.join(stateDir, entry.name);
@@ -15828,7 +16364,7 @@ var init_tools = __esm({
15828
16364
 
15829
16365
  // src/executor.ts
15830
16366
  import { spawn as spawn7 } from "child_process";
15831
- import * as fs42 from "fs";
16367
+ import * as fs43 from "fs";
15832
16368
  import * as path41 from "path";
15833
16369
  function isMutatingPostflight(scriptName) {
15834
16370
  return MUTATING_POSTFLIGHTS.has(scriptName ?? "");
@@ -16405,7 +16941,7 @@ function resolveProfilePath(profileName) {
16405
16941
  // fallback
16406
16942
  ];
16407
16943
  for (const c of candidates) {
16408
- if (fs42.existsSync(c)) return c;
16944
+ if (fs43.existsSync(c)) return c;
16409
16945
  }
16410
16946
  return candidates[0];
16411
16947
  }
@@ -16504,7 +17040,7 @@ function resolveShellTimeoutMs(entry) {
16504
17040
  async function runShellEntry(entry, ctx, profile) {
16505
17041
  const shellName = entry.shell;
16506
17042
  const shellPath = path41.join(profile.dir, shellName);
16507
- if (!fs42.existsSync(shellPath)) {
17043
+ if (!fs43.existsSync(shellPath)) {
16508
17044
  ctx.skipAgent = true;
16509
17045
  ctx.output.exitCode = 99;
16510
17046
  ctx.output.reason = `shell script not found: ${shellName} (looked in ${profile.dir})`;
@@ -16916,7 +17452,7 @@ function translateOpenAISseToBrain(opts) {
16916
17452
  }
16917
17453
 
16918
17454
  // src/servers/brain-serve.ts
16919
- import * as fs45 from "fs";
17455
+ import * as fs46 from "fs";
16920
17456
  import { createServer } from "http";
16921
17457
  import * as path45 from "path";
16922
17458
 
@@ -17478,7 +18014,7 @@ init_config();
17478
18014
 
17479
18015
  // src/kody-cli.ts
17480
18016
  import { execFileSync as execFileSync25 } from "child_process";
17481
- import * as fs43 from "fs";
18017
+ import * as fs44 from "fs";
17482
18018
  import * as path43 from "path";
17483
18019
 
17484
18020
  // src/app-auth.ts
@@ -18100,9 +18636,9 @@ async function resolveAuthToken(env = process.env) {
18100
18636
  return void 0;
18101
18637
  }
18102
18638
  function detectPackageManager2(cwd) {
18103
- if (fs43.existsSync(path43.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
18104
- if (fs43.existsSync(path43.join(cwd, "yarn.lock"))) return "yarn";
18105
- if (fs43.existsSync(path43.join(cwd, "bun.lockb"))) return "bun";
18639
+ if (fs44.existsSync(path43.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
18640
+ if (fs44.existsSync(path43.join(cwd, "yarn.lock"))) return "yarn";
18641
+ if (fs44.existsSync(path43.join(cwd, "bun.lockb"))) return "bun";
18106
18642
  return "npm";
18107
18643
  }
18108
18644
  function shouldChainScheduledWatch(match) {
@@ -18195,8 +18731,8 @@ function postFailureTail(issueNumber, cwd, reason) {
18195
18731
  const logPath = lastRunLogPath(cwd);
18196
18732
  let tail = "";
18197
18733
  try {
18198
- if (fs43.existsSync(logPath)) {
18199
- const content = fs43.readFileSync(logPath, "utf-8");
18734
+ if (fs44.existsSync(logPath)) {
18735
+ const content = fs44.readFileSync(logPath, "utf-8");
18200
18736
  tail = content.slice(-3e3);
18201
18737
  }
18202
18738
  } catch {
@@ -18236,9 +18772,9 @@ async function runCi(argv) {
18236
18772
  let manualWorkflowDispatch = false;
18237
18773
  let forceRunAction = null;
18238
18774
  let forceRunCliArgs = {};
18239
- if (!args.issueNumber && !autoFallback && eventName === "workflow_dispatch" && dispatchEventPath && fs43.existsSync(dispatchEventPath)) {
18775
+ if (!args.issueNumber && !autoFallback && eventName === "workflow_dispatch" && dispatchEventPath && fs44.existsSync(dispatchEventPath)) {
18240
18776
  try {
18241
- const evt = JSON.parse(fs43.readFileSync(dispatchEventPath, "utf-8"));
18777
+ const evt = JSON.parse(fs44.readFileSync(dispatchEventPath, "utf-8"));
18242
18778
  const issueInput = parseInt(String(evt?.inputs?.issue_number ?? ""), 10);
18243
18779
  const sessionInput = String(evt?.inputs?.sessionId ?? "");
18244
18780
  const dutyInput = String(evt?.inputs?.agentResponsibility ?? evt?.inputs?.agentAction ?? "").trim();
@@ -18570,7 +19106,7 @@ init_repoWorkspace();
18570
19106
 
18571
19107
  // src/scripts/brainTurnLog.ts
18572
19108
  init_runtimePaths();
18573
- import * as fs44 from "fs";
19109
+ import * as fs45 from "fs";
18574
19110
  import * as path44 from "path";
18575
19111
  import posixPath4 from "path/posix";
18576
19112
  var live = /* @__PURE__ */ new Map();
@@ -18582,8 +19118,8 @@ function brainEventsStatePath(chatId) {
18582
19118
  }
18583
19119
  function lastPersistedSeq(dir, chatId) {
18584
19120
  const p = brainEventsFilePath(dir, chatId);
18585
- if (!fs44.existsSync(p)) return 0;
18586
- const lines = fs44.readFileSync(p, "utf-8").split("\n").filter(Boolean);
19121
+ if (!fs45.existsSync(p)) return 0;
19122
+ const lines = fs45.readFileSync(p, "utf-8").split("\n").filter(Boolean);
18587
19123
  if (lines.length === 0) return 0;
18588
19124
  try {
18589
19125
  return JSON.parse(lines[lines.length - 1]).seq || 0;
@@ -18593,9 +19129,9 @@ function lastPersistedSeq(dir, chatId) {
18593
19129
  }
18594
19130
  function readSince(dir, chatId, since) {
18595
19131
  const p = brainEventsFilePath(dir, chatId);
18596
- if (!fs44.existsSync(p)) return [];
19132
+ if (!fs45.existsSync(p)) return [];
18597
19133
  const out = [];
18598
- for (const line of fs44.readFileSync(p, "utf-8").split("\n")) {
19134
+ for (const line of fs45.readFileSync(p, "utf-8").split("\n")) {
18599
19135
  if (!line) continue;
18600
19136
  try {
18601
19137
  const rec = JSON.parse(line);
@@ -18621,12 +19157,12 @@ function beginTurn(dir, chatId) {
18621
19157
  };
18622
19158
  live.set(chatId, state);
18623
19159
  const p = brainEventsFilePath(dir, chatId);
18624
- fs44.mkdirSync(path44.dirname(p), { recursive: true });
19160
+ fs45.mkdirSync(path44.dirname(p), { recursive: true });
18625
19161
  return (event) => {
18626
19162
  state.seq += 1;
18627
19163
  const rec = { seq: state.seq, turn, ts: Date.now(), event };
18628
19164
  try {
18629
- fs44.appendFileSync(p, `${JSON.stringify(rec)}
19165
+ fs45.appendFileSync(p, `${JSON.stringify(rec)}
18630
19166
  `);
18631
19167
  } catch (err) {
18632
19168
  process.stderr.write(
@@ -18665,7 +19201,7 @@ function endTurnIfUnterminated(dir, chatId, errMessage) {
18665
19201
  event: { type: "error", error: errMessage || "turn ended unexpectedly", chatId }
18666
19202
  };
18667
19203
  try {
18668
- fs44.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
19204
+ fs45.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
18669
19205
  `);
18670
19206
  } catch {
18671
19207
  }
@@ -18971,7 +19507,7 @@ async function handleChatTurn(req, res, chatId, opts) {
18971
19507
  );
18972
19508
  }
18973
19509
  }
18974
- fs45.mkdirSync(path45.dirname(sessionFile), { recursive: true });
19510
+ fs46.mkdirSync(path45.dirname(sessionFile), { recursive: true });
18975
19511
  appendTurn(sessionFile, {
18976
19512
  role: "user",
18977
19513
  content: message,
@@ -19631,7 +20167,7 @@ async function loadConfigSafe() {
19631
20167
  }
19632
20168
 
19633
20169
  // src/chat-cli.ts
19634
- import * as fs47 from "fs";
20170
+ import * as fs48 from "fs";
19635
20171
  import * as path47 from "path";
19636
20172
 
19637
20173
  // src/chat/inbox.ts
@@ -19704,7 +20240,7 @@ function currentBranch(cwd) {
19704
20240
 
19705
20241
  // src/chat/state-sync.ts
19706
20242
  init_stateRepo();
19707
- import * as fs46 from "fs";
20243
+ import * as fs47 from "fs";
19708
20244
  import * as path46 from "path";
19709
20245
  function jsonlLines2(text) {
19710
20246
  return text.split("\n").filter((line) => line.length > 0);
@@ -19722,15 +20258,15 @@ function mergeJsonl2(localText, remoteText) {
19722
20258
  function syncJsonlFileFromState(opts) {
19723
20259
  const remote = readStateText(opts.config, opts.cwd, opts.statePath);
19724
20260
  if (!remote) return;
19725
- const local = fs46.existsSync(opts.localPath) ? fs46.readFileSync(opts.localPath, "utf-8") : "";
20261
+ const local = fs47.existsSync(opts.localPath) ? fs47.readFileSync(opts.localPath, "utf-8") : "";
19726
20262
  const next = mergeJsonl2(local, remote.content);
19727
20263
  if (next === local) return;
19728
- fs46.mkdirSync(path46.dirname(opts.localPath), { recursive: true });
19729
- fs46.writeFileSync(opts.localPath, next);
20264
+ fs47.mkdirSync(path46.dirname(opts.localPath), { recursive: true });
20265
+ fs47.writeFileSync(opts.localPath, next);
19730
20266
  }
19731
20267
  function persistJsonlFileToState(opts) {
19732
- if (!fs46.existsSync(opts.localPath)) return;
19733
- const localText = fs46.readFileSync(opts.localPath, "utf-8");
20268
+ if (!fs47.existsSync(opts.localPath)) return;
20269
+ const localText = fs47.readFileSync(opts.localPath, "utf-8");
19734
20270
  for (let attempt = 1; attempt <= 3; attempt += 1) {
19735
20271
  const remote = readStateText(opts.config, opts.cwd, opts.statePath);
19736
20272
  const body = mergeJsonl2(localText, remote?.content ?? "");
@@ -20051,7 +20587,7 @@ ${CHAT_HELP}`);
20051
20587
  const sink = buildSink(cwd, sessionId, args.dashboardUrl);
20052
20588
  const meta = readMeta(sessionFile);
20053
20589
  process.stdout.write(
20054
- `\u2192 kody:chat: session file=${sessionFile} exists=${fs47.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
20590
+ `\u2192 kody:chat: session file=${sessionFile} exists=${fs48.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
20055
20591
  `
20056
20592
  );
20057
20593
  try {
@@ -20938,7 +21474,7 @@ async function poolServe() {
20938
21474
 
20939
21475
  // src/servers/runner-serve.ts
20940
21476
  import { spawn as spawn8 } from "child_process";
20941
- import * as fs48 from "fs";
21477
+ import * as fs49 from "fs";
20942
21478
  import { createServer as createServer5 } from "http";
20943
21479
  var DEFAULT_PORT2 = 8080;
20944
21480
  var DEFAULT_WORKDIR = "/workspace/repo";
@@ -21018,8 +21554,8 @@ async function defaultRunJob(job) {
21018
21554
  const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
21019
21555
  const branch = job.ref ?? "main";
21020
21556
  const authUrl = `https://x-access-token:${job.githubToken}@github.com/${job.repo}.git`;
21021
- fs48.rmSync(workdir, { recursive: true, force: true });
21022
- fs48.mkdirSync(workdir, { recursive: true });
21557
+ fs49.rmSync(workdir, { recursive: true, force: true });
21558
+ fs49.mkdirSync(workdir, { recursive: true });
21023
21559
  const allSecrets = typeof job.allSecrets === "string" ? job.allSecrets : JSON.stringify(job.allSecrets ?? {});
21024
21560
  const interactive = job.mode === "interactive";
21025
21561
  const scheduled = job.mode === "scheduled";
@@ -21154,7 +21690,7 @@ async function runnerServe() {
21154
21690
  init_config();
21155
21691
  init_litellm();
21156
21692
  import { spawn as spawn9 } from "child_process";
21157
- function parseTarget2(positional) {
21693
+ function parseTarget(positional) {
21158
21694
  if (!Array.isArray(positional) || positional.length === 0) return "none";
21159
21695
  const first = String(positional[0]).toLowerCase();
21160
21696
  if (first === "vscode" || first === "code") return "vscode";
@@ -21169,7 +21705,7 @@ function buildProxyEnv(url) {
21169
21705
  };
21170
21706
  }
21171
21707
  async function serve(opts) {
21172
- const target = parseTarget2(opts.args);
21708
+ const target = parseTarget(opts.args);
21173
21709
  const model = parseProviderModel(opts.config.agent.model);
21174
21710
  const usesProxy = needsLitellmProxy(model);
21175
21711
  let handle = null;