@kody-ade/kody-engine 0.4.307 → 0.4.309
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 +581 -316
- package/package.json +1 -1
package/dist/bin/kody.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@kody-ade/kody-engine",
|
|
18
|
-
version: "0.4.
|
|
18
|
+
version: "0.4.309",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -1610,7 +1610,7 @@ function cmsHeaders(opts) {
|
|
|
1610
1610
|
}
|
|
1611
1611
|
};
|
|
1612
1612
|
}
|
|
1613
|
-
async function callDashboardCms(opts,
|
|
1613
|
+
async function callDashboardCms(opts, path51, init = {}) {
|
|
1614
1614
|
const baseUrl = dashboardBaseUrl(opts);
|
|
1615
1615
|
if (!baseUrl) {
|
|
1616
1616
|
return {
|
|
@@ -1622,7 +1622,7 @@ async function callDashboardCms(opts, path50, init = {}) {
|
|
|
1622
1622
|
const headerResult = cmsHeaders(opts);
|
|
1623
1623
|
if (!headerResult.ok) return headerResult;
|
|
1624
1624
|
try {
|
|
1625
|
-
const res = await fetch(`${baseUrl}${
|
|
1625
|
+
const res = await fetch(`${baseUrl}${path51}`, {
|
|
1626
1626
|
...init,
|
|
1627
1627
|
headers: {
|
|
1628
1628
|
...headerResult.headers,
|
|
@@ -1694,8 +1694,8 @@ function documentArg(value) {
|
|
|
1694
1694
|
function normalizeCmsDocumentIdInput(input) {
|
|
1695
1695
|
const trimmed = stripWrappingQuotes(input.trim());
|
|
1696
1696
|
const withoutQuery = trimmed.split(/[?#]/, 1)[0] ?? trimmed;
|
|
1697
|
-
const
|
|
1698
|
-
return
|
|
1697
|
+
const path51 = parseDocumentPath(withoutQuery);
|
|
1698
|
+
return path51 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
|
|
1699
1699
|
}
|
|
1700
1700
|
function stripWrappingQuotes(value) {
|
|
1701
1701
|
let current = value;
|
|
@@ -1706,9 +1706,9 @@ function stripWrappingQuotes(value) {
|
|
|
1706
1706
|
}
|
|
1707
1707
|
}
|
|
1708
1708
|
function parseDocumentPath(value) {
|
|
1709
|
-
const
|
|
1710
|
-
if (!
|
|
1711
|
-
const parts =
|
|
1709
|
+
const path51 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
|
|
1710
|
+
if (!path51?.includes("/content/entries/")) return null;
|
|
1711
|
+
const parts = path51.split("/").filter(Boolean).map(decodePathPart);
|
|
1712
1712
|
const entriesIndex = parts.findIndex((part, index) => part === "content" && parts[index + 1] === "entries");
|
|
1713
1713
|
const idPart = parts[entriesIndex + 3];
|
|
1714
1714
|
if (!idPart || idPart === "new") return null;
|
|
@@ -2041,6 +2041,23 @@ function getCompanyStoreAssetRoot(kind) {
|
|
|
2041
2041
|
if (fs5.existsSync(rootLayoutPath)) return rootLayoutPath;
|
|
2042
2042
|
return path7.join(root, ".kody", folderByKind[kind]);
|
|
2043
2043
|
}
|
|
2044
|
+
function resetCompanyStoreCacheForTests() {
|
|
2045
|
+
memo = null;
|
|
2046
|
+
}
|
|
2047
|
+
function applyCompanyStoreRuntimeConfig(input, env = process.env) {
|
|
2048
|
+
const repo = stringValue(input?.storeRepoUrl ?? input?.storeRepo);
|
|
2049
|
+
const ref = stringValue(input?.storeRef);
|
|
2050
|
+
let changed = false;
|
|
2051
|
+
if (repo && env[STORE_ENV] !== repo) {
|
|
2052
|
+
env[STORE_ENV] = repo;
|
|
2053
|
+
changed = true;
|
|
2054
|
+
}
|
|
2055
|
+
if (ref && env[REF_ENV] !== ref) {
|
|
2056
|
+
env[REF_ENV] = ref;
|
|
2057
|
+
changed = true;
|
|
2058
|
+
}
|
|
2059
|
+
if (changed) resetCompanyStoreCacheForTests();
|
|
2060
|
+
}
|
|
2044
2061
|
function resolveCompanyStore() {
|
|
2045
2062
|
const envStore = process.env[STORE_ENV]?.trim();
|
|
2046
2063
|
if (!envStore && process.env.VITEST) return null;
|
|
@@ -2050,6 +2067,9 @@ function resolveCompanyStore() {
|
|
|
2050
2067
|
if (!ref) return null;
|
|
2051
2068
|
return { repo, ref };
|
|
2052
2069
|
}
|
|
2070
|
+
function stringValue(value) {
|
|
2071
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
2072
|
+
}
|
|
2053
2073
|
function fetchCompanyStore(repo, ref) {
|
|
2054
2074
|
const localRoot = localStoreRoot(repo);
|
|
2055
2075
|
if (localRoot) return localRoot;
|
|
@@ -6897,10 +6917,10 @@ var init_state2 = __esm({
|
|
|
6897
6917
|
"use strict";
|
|
6898
6918
|
VALID_STATES = /* @__PURE__ */ new Set(["active", "abandoned", "closed", "done"]);
|
|
6899
6919
|
GoalStateError = class extends Error {
|
|
6900
|
-
constructor(
|
|
6901
|
-
super(`Invalid goal state at ${
|
|
6920
|
+
constructor(path51, message) {
|
|
6921
|
+
super(`Invalid goal state at ${path51}:
|
|
6902
6922
|
${message}`);
|
|
6903
|
-
this.path =
|
|
6923
|
+
this.path = path51;
|
|
6904
6924
|
this.name = "GoalStateError";
|
|
6905
6925
|
}
|
|
6906
6926
|
path;
|
|
@@ -6913,9 +6933,9 @@ import * as fs25 from "fs";
|
|
|
6913
6933
|
function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
|
|
6914
6934
|
const logs = goalRunLogs(data);
|
|
6915
6935
|
const existing = logs[goalId];
|
|
6916
|
-
const
|
|
6936
|
+
const path51 = existing?.path ?? goalRunLogPath(goalId, data);
|
|
6917
6937
|
logs[goalId] = {
|
|
6918
|
-
path:
|
|
6938
|
+
path: path51,
|
|
6919
6939
|
events: [...existing?.events ?? [], buildGoalRunLogEvent(data, goalId, event, at)]
|
|
6920
6940
|
};
|
|
6921
6941
|
}
|
|
@@ -7002,7 +7022,7 @@ function goalRunStartedAt(data) {
|
|
|
7002
7022
|
function goalRunId(data) {
|
|
7003
7023
|
const existing = data[LOG_RUN_KEY];
|
|
7004
7024
|
if (typeof existing === "string" && existing.length > 0) return existing;
|
|
7005
|
-
const raw =
|
|
7025
|
+
const raw = stringValue2(data.jobId) ?? githubRunId() ?? `local-${process.pid}-${Date.now()}`;
|
|
7006
7026
|
const safe = safePathSegment(raw);
|
|
7007
7027
|
data[LOG_RUN_KEY] = safe;
|
|
7008
7028
|
return safe;
|
|
@@ -7032,17 +7052,77 @@ function enrichGoalRunLogEvent(config, data, logPath, event) {
|
|
|
7032
7052
|
const stateRepo = stateRepoContext(config, event.goalId, logPath);
|
|
7033
7053
|
const trigger = event.trigger ?? triggerContext();
|
|
7034
7054
|
const job = event.job ?? jobContext(data);
|
|
7035
|
-
|
|
7055
|
+
const run = event.run ?? runContext(data);
|
|
7056
|
+
const links = event.links ?? linkContext(stateRepo);
|
|
7057
|
+
const enriched = pruneUndefined({
|
|
7036
7058
|
...event,
|
|
7037
|
-
run
|
|
7059
|
+
run,
|
|
7038
7060
|
repo: event.repo ?? repoContext(config),
|
|
7039
7061
|
stateRepo: event.stateRepo ?? stateRepo,
|
|
7040
7062
|
trigger,
|
|
7041
7063
|
job,
|
|
7042
7064
|
dispatchContext: event.dispatchContext ?? dispatchContext(event, trigger, job),
|
|
7043
|
-
links
|
|
7065
|
+
links
|
|
7066
|
+
});
|
|
7067
|
+
enriched.trace = event.trace ?? goalRunTrace(enriched);
|
|
7068
|
+
return enriched;
|
|
7069
|
+
}
|
|
7070
|
+
function goalRunTrace(event) {
|
|
7071
|
+
const run = recordValue2(event.run);
|
|
7072
|
+
const trigger = recordValue2(event.trigger);
|
|
7073
|
+
const goal = recordValue2(event.goal);
|
|
7074
|
+
const inspection = recordValue2(event.inspection);
|
|
7075
|
+
const capabilityOutput = recordValue2(inspection?.capabilityOutput);
|
|
7076
|
+
return pruneUndefined({
|
|
7077
|
+
version: 1,
|
|
7078
|
+
runId: stringValue2(run?.id) ?? void 0,
|
|
7079
|
+
workflowRunId: stringValue2(run?.githubRunId) ?? void 0,
|
|
7080
|
+
triggerKind: stringValue2(trigger?.kind) ?? void 0,
|
|
7081
|
+
source: event.source,
|
|
7082
|
+
event: event.event,
|
|
7083
|
+
goal: pruneUndefined({
|
|
7084
|
+
id: event.goalId,
|
|
7085
|
+
type: event.goalType ?? stringValue2(goal?.type) ?? void 0,
|
|
7086
|
+
state: event.goalState ?? stringValue2(goal?.state) ?? void 0,
|
|
7087
|
+
stage: event.stage ?? stringValue2(goal?.stage) ?? void 0
|
|
7088
|
+
}),
|
|
7089
|
+
evidence: goalTraceEvidence(event, goal, inspection),
|
|
7090
|
+
capability: event.dispatch ?? capabilityDispatchFromOutput(capabilityOutput),
|
|
7091
|
+
result: goalTraceResult(event, capabilityOutput),
|
|
7092
|
+
change: event.change,
|
|
7093
|
+
links: event.links
|
|
7044
7094
|
});
|
|
7045
7095
|
}
|
|
7096
|
+
function goalTraceEvidence(event, goal, inspection) {
|
|
7097
|
+
const expectedEvidence = recordValue2(inspection?.expectedEvidence);
|
|
7098
|
+
const out = pruneUndefined({
|
|
7099
|
+
current: event.evidence,
|
|
7100
|
+
required: stringArrayValue(goal?.requiredEvidence) ?? stringArrayValue(inspection?.requiredEvidence) ?? void 0,
|
|
7101
|
+
satisfied: stringArrayValue(goal?.satisfiedEvidence) ?? stringArrayValue(inspection?.satisfiedEvidence) ?? void 0,
|
|
7102
|
+
missing: stringArrayValue(goal?.missingEvidence) ?? stringArrayValue(inspection?.missingEvidence) ?? stringArrayValue(expectedEvidence?.missingBefore) ?? void 0,
|
|
7103
|
+
pending: stringValue2(goal?.pendingEvidence) ?? stringValue2(inspection?.pendingEvidence) ?? stringValue2(expectedEvidence?.pendingBefore) ?? void 0,
|
|
7104
|
+
values: event.evidenceValues
|
|
7105
|
+
});
|
|
7106
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
7107
|
+
}
|
|
7108
|
+
function capabilityDispatchFromOutput(output) {
|
|
7109
|
+
if (!output) return void 0;
|
|
7110
|
+
const dispatch2 = pruneUndefined({
|
|
7111
|
+
capability: stringValue2(output.capability) ?? void 0,
|
|
7112
|
+
executable: stringValue2(output.executable) ?? void 0,
|
|
7113
|
+
action: stringValue2(output.action) ?? void 0
|
|
7114
|
+
});
|
|
7115
|
+
return Object.keys(dispatch2).length > 0 ? dispatch2 : void 0;
|
|
7116
|
+
}
|
|
7117
|
+
function goalTraceResult(event, capabilityOutput) {
|
|
7118
|
+
const result = pruneUndefined({
|
|
7119
|
+
status: event.status ?? stringValue2(capabilityOutput?.status) ?? void 0,
|
|
7120
|
+
summary: event.reason ?? stringValue2(capabilityOutput?.summary) ?? void 0,
|
|
7121
|
+
blockers: event.inspection ? stringArrayValue(capabilityOutput?.blockers) ?? void 0 : void 0,
|
|
7122
|
+
artifacts: event.artifacts
|
|
7123
|
+
});
|
|
7124
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
7125
|
+
}
|
|
7046
7126
|
function runContext(data) {
|
|
7047
7127
|
const runId = process.env.GITHUB_RUN_ID?.trim();
|
|
7048
7128
|
const attempt = process.env.GITHUB_RUN_ATTEMPT?.trim();
|
|
@@ -7101,7 +7181,7 @@ function triggerContext() {
|
|
|
7101
7181
|
issue: numberValue(recordValue2(event?.issue)?.number),
|
|
7102
7182
|
pullRequest: numberValue(recordValue2(event?.pull_request)?.number),
|
|
7103
7183
|
comment: numberValue(recordValue2(event?.comment)?.id),
|
|
7104
|
-
schedule:
|
|
7184
|
+
schedule: stringValue2(event?.schedule),
|
|
7105
7185
|
inputs: inputs ? pickRecord(inputs, ["issue_number", "sessionId", "message", "model", "title", "executable", "base"]) : void 0
|
|
7106
7186
|
});
|
|
7107
7187
|
return Object.keys(trigger).length > 0 ? trigger : void 0;
|
|
@@ -7120,16 +7200,16 @@ function triggerActorRole(eventName) {
|
|
|
7120
7200
|
}
|
|
7121
7201
|
function jobContext(data) {
|
|
7122
7202
|
const job = pruneUndefined({
|
|
7123
|
-
id:
|
|
7124
|
-
key:
|
|
7125
|
-
flavor:
|
|
7126
|
-
action:
|
|
7127
|
-
capability:
|
|
7128
|
-
executable:
|
|
7129
|
-
agent:
|
|
7130
|
-
schedule:
|
|
7203
|
+
id: stringValue2(data.jobId) ?? void 0,
|
|
7204
|
+
key: stringValue2(data.jobKey) ?? void 0,
|
|
7205
|
+
flavor: stringValue2(data.jobFlavor) ?? void 0,
|
|
7206
|
+
action: stringValue2(data.jobAction) ?? void 0,
|
|
7207
|
+
capability: stringValue2(data.jobCapability) ?? void 0,
|
|
7208
|
+
executable: stringValue2(data.jobExecutable) ?? void 0,
|
|
7209
|
+
agent: stringValue2(data.jobAgent) ?? void 0,
|
|
7210
|
+
schedule: stringValue2(data.jobSchedule) ?? void 0,
|
|
7131
7211
|
target: data.jobTarget ?? void 0,
|
|
7132
|
-
why: truncateString(
|
|
7212
|
+
why: truncateString(stringValue2(data.jobWhy), 1e3),
|
|
7133
7213
|
saveReport: data.jobSaveReport === true ? true : void 0
|
|
7134
7214
|
});
|
|
7135
7215
|
return Object.keys(job).length > 0 ? job : void 0;
|
|
@@ -7139,21 +7219,21 @@ function dispatchContext(event, trigger, job) {
|
|
|
7139
7219
|
const dispatch2 = event.dispatch ?? {};
|
|
7140
7220
|
const context = pruneUndefined({
|
|
7141
7221
|
triggeredBy: triggerLabel(trigger),
|
|
7142
|
-
triggerKind:
|
|
7222
|
+
triggerKind: stringValue2(trigger?.kind),
|
|
7143
7223
|
dispatchMode: dispatchMode(trigger),
|
|
7144
|
-
githubActor:
|
|
7145
|
-
githubActorRole:
|
|
7224
|
+
githubActor: stringValue2(trigger?.githubActor) ?? stringValue2(trigger?.actor),
|
|
7225
|
+
githubActorRole: stringValue2(trigger?.actorRole),
|
|
7146
7226
|
decidedBy: event.source,
|
|
7147
7227
|
dispatchedBy: event.source,
|
|
7148
7228
|
target: event.target,
|
|
7149
|
-
action: dispatch2.action ??
|
|
7150
|
-
capability: dispatch2.capability ??
|
|
7229
|
+
action: dispatch2.action ?? stringValue2(job?.action),
|
|
7230
|
+
capability: dispatch2.capability ?? stringValue2(job?.capability),
|
|
7151
7231
|
reason: event.reason
|
|
7152
7232
|
});
|
|
7153
7233
|
return Object.keys(context).length > 0 ? context : void 0;
|
|
7154
7234
|
}
|
|
7155
7235
|
function triggerLabel(trigger) {
|
|
7156
|
-
const kind =
|
|
7236
|
+
const kind = stringValue2(trigger?.kind);
|
|
7157
7237
|
if (kind === "schedule") return "GitHub schedule";
|
|
7158
7238
|
if (kind === "manual-workflow-dispatch") return "manual workflow dispatch";
|
|
7159
7239
|
if (kind === "issue_comment") return "GitHub issue comment";
|
|
@@ -7162,7 +7242,7 @@ function triggerLabel(trigger) {
|
|
|
7162
7242
|
return "local run";
|
|
7163
7243
|
}
|
|
7164
7244
|
function dispatchMode(trigger) {
|
|
7165
|
-
const kind =
|
|
7245
|
+
const kind = stringValue2(trigger?.kind);
|
|
7166
7246
|
if (kind === "schedule") return "automated";
|
|
7167
7247
|
if (kind === "manual-workflow-dispatch") return "manual";
|
|
7168
7248
|
if (kind) return "event-driven";
|
|
@@ -7174,10 +7254,10 @@ function linkContext(stateRepo) {
|
|
|
7174
7254
|
const repository = process.env.GITHUB_REPOSITORY?.trim();
|
|
7175
7255
|
const server = process.env.GITHUB_SERVER_URL?.trim() || "https://github.com";
|
|
7176
7256
|
if (runId && repository) links.workflowRun = `${server}/${repository}/actions/runs/${runId}`;
|
|
7177
|
-
const repo =
|
|
7178
|
-
const branch =
|
|
7179
|
-
const goalStatePath2 =
|
|
7180
|
-
const logPath =
|
|
7257
|
+
const repo = stringValue2(stateRepo?.repo);
|
|
7258
|
+
const branch = stringValue2(stateRepo?.branch);
|
|
7259
|
+
const goalStatePath2 = stringValue2(stateRepo?.goalStatePath);
|
|
7260
|
+
const logPath = stringValue2(stateRepo?.logPath);
|
|
7181
7261
|
if (repo && branch && goalStatePath2) links.goalState = githubBlobUrl(repo, branch, goalStatePath2);
|
|
7182
7262
|
if (repo && branch && logPath) links.log = githubBlobUrl(repo, branch, logPath);
|
|
7183
7263
|
return Object.keys(links).length > 0 ? links : void 0;
|
|
@@ -7257,7 +7337,7 @@ function truncateString(value, max) {
|
|
|
7257
7337
|
if (!value) return void 0;
|
|
7258
7338
|
return value.length > max ? `${value.slice(0, max)}...` : value;
|
|
7259
7339
|
}
|
|
7260
|
-
function
|
|
7340
|
+
function stringValue2(value) {
|
|
7261
7341
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
7262
7342
|
}
|
|
7263
7343
|
function safePathSegment(value) {
|
|
@@ -7430,6 +7510,8 @@ var init_managedTodoState = __esm({
|
|
|
7430
7510
|
});
|
|
7431
7511
|
|
|
7432
7512
|
// src/goal/stateStore.ts
|
|
7513
|
+
import * as fs26 from "fs";
|
|
7514
|
+
import * as path24 from "path";
|
|
7433
7515
|
function goalStatePath(goalId) {
|
|
7434
7516
|
return `todos/${goalId}.json`;
|
|
7435
7517
|
}
|
|
@@ -7438,7 +7520,55 @@ function fetchGoalState(config, goalId, cwd) {
|
|
|
7438
7520
|
const loaded = readStateText(config, cwd, filePath);
|
|
7439
7521
|
if (!loaded) return null;
|
|
7440
7522
|
if (!isManagedTodoRaw(loaded.content)) return null;
|
|
7441
|
-
return parseTodoGoalState(goalId, loaded.path, loaded.content);
|
|
7523
|
+
return resolveStoreBackedGoalState(parseTodoGoalState(goalId, loaded.path, loaded.content));
|
|
7524
|
+
}
|
|
7525
|
+
function resolveStoreBackedGoalState(state) {
|
|
7526
|
+
const templateId = templateIdFromGoalState(state);
|
|
7527
|
+
if (!templateId) return state;
|
|
7528
|
+
const template = readStoreGoalTemplate(templateId);
|
|
7529
|
+
if (!template) return state;
|
|
7530
|
+
const nextExtra = { ...state.extra };
|
|
7531
|
+
for (const key of [
|
|
7532
|
+
"type",
|
|
7533
|
+
"destination",
|
|
7534
|
+
"capabilities",
|
|
7535
|
+
"route",
|
|
7536
|
+
"schedule",
|
|
7537
|
+
"scheduleMode",
|
|
7538
|
+
"loopTarget",
|
|
7539
|
+
"preferredRunTime",
|
|
7540
|
+
"saveReport"
|
|
7541
|
+
]) {
|
|
7542
|
+
if (Object.hasOwn(template, key)) nextExtra[key] = template[key];
|
|
7543
|
+
else if (["schedule", "loopTarget", "preferredRunTime", "saveReport"].includes(key)) delete nextExtra[key];
|
|
7544
|
+
}
|
|
7545
|
+
nextExtra.facts = {
|
|
7546
|
+
...recordField2(template.facts) ?? {},
|
|
7547
|
+
...recordField2(state.extra.facts) ?? {}
|
|
7548
|
+
};
|
|
7549
|
+
return { ...state, extra: nextExtra };
|
|
7550
|
+
}
|
|
7551
|
+
function templateIdFromGoalState(state) {
|
|
7552
|
+
for (const key of ["sourceTemplate", "templateId", "template"]) {
|
|
7553
|
+
const value = state.extra[key];
|
|
7554
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
7555
|
+
}
|
|
7556
|
+
return "";
|
|
7557
|
+
}
|
|
7558
|
+
function readStoreGoalTemplate(templateId) {
|
|
7559
|
+
const root = getCompanyStoreAssetRoot("goals");
|
|
7560
|
+
if (!root) return null;
|
|
7561
|
+
const file = path24.join(root, "templates", templateId, "state.json");
|
|
7562
|
+
if (!fs26.existsSync(file)) return null;
|
|
7563
|
+
try {
|
|
7564
|
+
const parsed = JSON.parse(fs26.readFileSync(file, "utf8"));
|
|
7565
|
+
return recordField2(parsed);
|
|
7566
|
+
} catch {
|
|
7567
|
+
return null;
|
|
7568
|
+
}
|
|
7569
|
+
}
|
|
7570
|
+
function recordField2(value) {
|
|
7571
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
7442
7572
|
}
|
|
7443
7573
|
function putGoalState(config, goalId, state, message = `chore(goals): update ${goalId}`, cwd) {
|
|
7444
7574
|
const previous = readStateText(config, cwd, goalStatePath(goalId));
|
|
@@ -7463,12 +7593,13 @@ var init_stateStore = __esm({
|
|
|
7463
7593
|
"use strict";
|
|
7464
7594
|
init_stateRepo();
|
|
7465
7595
|
init_managedTodoState();
|
|
7596
|
+
init_companyStore();
|
|
7466
7597
|
}
|
|
7467
7598
|
});
|
|
7468
7599
|
|
|
7469
7600
|
// src/goal/targetLoopResolution.ts
|
|
7470
|
-
import * as
|
|
7471
|
-
import * as
|
|
7601
|
+
import * as fs27 from "fs";
|
|
7602
|
+
import * as path25 from "path";
|
|
7472
7603
|
function resolveActiveGoalLoopTarget(config, cwd, loopGoalId, loopGoal) {
|
|
7473
7604
|
const targetId = loopGoal.loopTarget?.id.trim() ?? "";
|
|
7474
7605
|
assertSafeGoalId(targetId, "loop target");
|
|
@@ -7554,16 +7685,16 @@ function goalInstanceTime(state) {
|
|
|
7554
7685
|
return Number.isNaN(parsed) ? 0 : parsed;
|
|
7555
7686
|
}
|
|
7556
7687
|
function loadGoalTemplate(cwd, targetId) {
|
|
7557
|
-
const local =
|
|
7688
|
+
const local = path25.join(cwd, ".kody", "goals", "templates", targetId, "state.json");
|
|
7558
7689
|
const localTemplate = readJsonObject(local);
|
|
7559
7690
|
if (localTemplate) return localTemplate;
|
|
7560
7691
|
const storeGoalRoot = getCompanyStoreAssetRoot("goals");
|
|
7561
7692
|
if (!storeGoalRoot) return null;
|
|
7562
|
-
return readJsonObject(
|
|
7693
|
+
return readJsonObject(path25.join(storeGoalRoot, "templates", targetId, "state.json"));
|
|
7563
7694
|
}
|
|
7564
7695
|
function readJsonObject(filePath) {
|
|
7565
|
-
if (!
|
|
7566
|
-
const parsed = JSON.parse(
|
|
7696
|
+
if (!fs27.existsSync(filePath)) return null;
|
|
7697
|
+
const parsed = JSON.parse(fs27.readFileSync(filePath, "utf8"));
|
|
7567
7698
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
7568
7699
|
throw new Error(`goal template ${filePath} must be a JSON object`);
|
|
7569
7700
|
}
|
|
@@ -7959,8 +8090,8 @@ var init_contentsApiBackend = __esm({
|
|
|
7959
8090
|
});
|
|
7960
8091
|
|
|
7961
8092
|
// src/scripts/jobState/localFileBackend.ts
|
|
7962
|
-
import * as
|
|
7963
|
-
import * as
|
|
8093
|
+
import * as fs28 from "fs";
|
|
8094
|
+
import * as path26 from "path";
|
|
7964
8095
|
function sanitizeKey(s) {
|
|
7965
8096
|
return s.replace(/[^A-Za-z0-9._-]/g, "-");
|
|
7966
8097
|
}
|
|
@@ -8016,7 +8147,7 @@ var init_localFileBackend = __esm({
|
|
|
8016
8147
|
if (!opts.owner || !opts.repo) throw new Error("LocalFileBackend: owner and repo are required");
|
|
8017
8148
|
this.cwd = opts.cwd;
|
|
8018
8149
|
this.jobsDir = opts.jobsDir;
|
|
8019
|
-
this.absDir =
|
|
8150
|
+
this.absDir = path26.join(opts.cwd, opts.jobsDir);
|
|
8020
8151
|
this.owner = opts.owner;
|
|
8021
8152
|
this.repo = opts.repo;
|
|
8022
8153
|
this.cache = opts.cache ?? defaultCacheAdapter();
|
|
@@ -8031,7 +8162,7 @@ var init_localFileBackend = __esm({
|
|
|
8031
8162
|
`);
|
|
8032
8163
|
return;
|
|
8033
8164
|
}
|
|
8034
|
-
|
|
8165
|
+
fs28.mkdirSync(this.absDir, { recursive: true });
|
|
8035
8166
|
const prefix = this.cacheKeyPrefix();
|
|
8036
8167
|
const probeKey = `${prefix}probe-${Date.now()}`;
|
|
8037
8168
|
try {
|
|
@@ -8060,7 +8191,7 @@ var init_localFileBackend = __esm({
|
|
|
8060
8191
|
`);
|
|
8061
8192
|
return;
|
|
8062
8193
|
}
|
|
8063
|
-
if (!
|
|
8194
|
+
if (!fs28.existsSync(this.absDir)) {
|
|
8064
8195
|
return;
|
|
8065
8196
|
}
|
|
8066
8197
|
const key = `${this.cacheKeyPrefix()}${process.env.GITHUB_RUN_ID ?? "norunid"}-${Date.now()}`;
|
|
@@ -8076,11 +8207,11 @@ var init_localFileBackend = __esm({
|
|
|
8076
8207
|
}
|
|
8077
8208
|
load(slug2) {
|
|
8078
8209
|
const relPath = stateFilePath(this.jobsDir, slug2);
|
|
8079
|
-
const absPath =
|
|
8080
|
-
if (!
|
|
8210
|
+
const absPath = path26.join(this.cwd, relPath);
|
|
8211
|
+
if (!fs28.existsSync(absPath)) {
|
|
8081
8212
|
return { path: relPath, handle: null, state: initialStateEnvelope("seed"), created: true };
|
|
8082
8213
|
}
|
|
8083
|
-
const raw =
|
|
8214
|
+
const raw = fs28.readFileSync(absPath, "utf-8");
|
|
8084
8215
|
let parsed;
|
|
8085
8216
|
try {
|
|
8086
8217
|
parsed = JSON.parse(raw);
|
|
@@ -8097,13 +8228,13 @@ var init_localFileBackend = __esm({
|
|
|
8097
8228
|
if (!loaded.created && isStateUnchanged(loaded.state, next)) {
|
|
8098
8229
|
return false;
|
|
8099
8230
|
}
|
|
8100
|
-
const absPath =
|
|
8101
|
-
|
|
8231
|
+
const absPath = path26.join(this.cwd, loaded.path);
|
|
8232
|
+
fs28.mkdirSync(path26.dirname(absPath), { recursive: true });
|
|
8102
8233
|
const body = `${JSON.stringify(next, null, 2)}
|
|
8103
8234
|
`;
|
|
8104
8235
|
const tmpPath = `${absPath}.${process.pid}.tmp`;
|
|
8105
|
-
|
|
8106
|
-
|
|
8236
|
+
fs28.writeFileSync(tmpPath, body, "utf-8");
|
|
8237
|
+
fs28.renameSync(tmpPath, absPath);
|
|
8107
8238
|
return true;
|
|
8108
8239
|
}
|
|
8109
8240
|
cacheKeyPrefix() {
|
|
@@ -8143,7 +8274,7 @@ var init_jobState = __esm({
|
|
|
8143
8274
|
});
|
|
8144
8275
|
|
|
8145
8276
|
// src/scripts/goalCapabilityScheduling.ts
|
|
8146
|
-
import * as
|
|
8277
|
+
import * as path27 from "path";
|
|
8147
8278
|
function isCapabilityCadenceGoal(goal, extra) {
|
|
8148
8279
|
return extra.scheduleMode === "agentLoop" || extra.scheduler === "agentLoop" || goal.type === "standing" && goal.capabilities.length > 0;
|
|
8149
8280
|
}
|
|
@@ -8199,7 +8330,7 @@ function planTargetLoopSchedule(opts) {
|
|
|
8199
8330
|
}
|
|
8200
8331
|
async function planGoalCapabilitySchedule(opts) {
|
|
8201
8332
|
const jobsDir = opts.jobsDir ?? ".kody/capabilities";
|
|
8202
|
-
const jobsRoot =
|
|
8333
|
+
const jobsRoot = path27.join(opts.cwd, jobsDir);
|
|
8203
8334
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
8204
8335
|
const at = now.toISOString();
|
|
8205
8336
|
const backend = resolveBackend({ config: opts.config, cwd: opts.cwd, jobsDir });
|
|
@@ -9010,13 +9141,13 @@ function companyIntentPath(id) {
|
|
|
9010
9141
|
assertIntentId(id);
|
|
9011
9142
|
return `intents/${id}/intent.json`;
|
|
9012
9143
|
}
|
|
9013
|
-
function normalizeCompanyIntent(
|
|
9144
|
+
function normalizeCompanyIntent(path51, raw) {
|
|
9014
9145
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
9015
|
-
throw new Error(`${
|
|
9146
|
+
throw new Error(`${path51}: intent must be JSON object`);
|
|
9016
9147
|
}
|
|
9017
9148
|
const input = raw;
|
|
9018
9149
|
const id = stringField3(input.id);
|
|
9019
|
-
if (!id || !isCompanyIntentId(id)) throw new Error(`${
|
|
9150
|
+
if (!id || !isCompanyIntentId(id)) throw new Error(`${path51}: invalid intent id`);
|
|
9020
9151
|
const createdAt = stringField3(input.createdAt) || nowIso();
|
|
9021
9152
|
const updatedAt = stringField3(input.updatedAt) || createdAt;
|
|
9022
9153
|
const description = stringField3(input.description);
|
|
@@ -9033,21 +9164,21 @@ function normalizeCompanyIntent(path50, raw) {
|
|
|
9033
9164
|
"balanced"
|
|
9034
9165
|
),
|
|
9035
9166
|
scope: {
|
|
9036
|
-
repos: stringArray4(
|
|
9037
|
-
areas: stringArray4(
|
|
9167
|
+
repos: stringArray4(recordField3(input.scope)?.repos),
|
|
9168
|
+
areas: stringArray4(recordField3(input.scope)?.areas)
|
|
9038
9169
|
},
|
|
9039
9170
|
principles: stringArray4(input.principles),
|
|
9040
9171
|
metrics: stringArray4(input.metrics),
|
|
9041
9172
|
policy: {
|
|
9042
|
-
release: normalizeReleasePolicy(
|
|
9043
|
-
automation: normalizeAutomationPolicy(
|
|
9173
|
+
release: normalizeReleasePolicy(recordField3(recordField3(input.policy)?.release)),
|
|
9174
|
+
automation: normalizeAutomationPolicy(recordField3(recordField3(input.policy)?.automation))
|
|
9044
9175
|
},
|
|
9045
9176
|
portfolio: {
|
|
9046
|
-
goals: stringArray4(
|
|
9047
|
-
loops: stringArray4(
|
|
9048
|
-
capabilities: stringArray4(
|
|
9177
|
+
goals: stringArray4(recordField3(input.portfolio)?.goals).filter(isCompanyIntentId),
|
|
9178
|
+
loops: stringArray4(recordField3(input.portfolio)?.loops).filter(isCompanyIntentId),
|
|
9179
|
+
capabilities: stringArray4(recordField3(input.portfolio)?.capabilities).filter(isCompanyIntentId)
|
|
9049
9180
|
},
|
|
9050
|
-
manager: normalizeManager(
|
|
9181
|
+
manager: normalizeManager(recordField3(input.manager)),
|
|
9051
9182
|
createdAt,
|
|
9052
9183
|
updatedAt
|
|
9053
9184
|
};
|
|
@@ -9057,8 +9188,8 @@ function listCompanyIntents(config, cwd) {
|
|
|
9057
9188
|
const records = [];
|
|
9058
9189
|
for (const entry of entries) {
|
|
9059
9190
|
if (entry.type !== "dir" || !entry.name || !isCompanyIntentId(entry.name)) continue;
|
|
9060
|
-
const
|
|
9061
|
-
const file = readStateText(config, cwd,
|
|
9191
|
+
const path51 = companyIntentPath(entry.name);
|
|
9192
|
+
const file = readStateText(config, cwd, path51);
|
|
9062
9193
|
if (!file) continue;
|
|
9063
9194
|
records.push({
|
|
9064
9195
|
id: entry.name,
|
|
@@ -9069,8 +9200,8 @@ function listCompanyIntents(config, cwd) {
|
|
|
9069
9200
|
return records.sort((a, b) => a.intent.priority - b.intent.priority || a.id.localeCompare(b.id));
|
|
9070
9201
|
}
|
|
9071
9202
|
function readCompanyIntent(config, cwd, id) {
|
|
9072
|
-
const
|
|
9073
|
-
const file = readStateText(config, cwd,
|
|
9203
|
+
const path51 = companyIntentPath(id);
|
|
9204
|
+
const file = readStateText(config, cwd, path51);
|
|
9074
9205
|
if (!file) return null;
|
|
9075
9206
|
return { id, path: file.path, intent: normalizeCompanyIntent(file.path, JSON.parse(file.content)) };
|
|
9076
9207
|
}
|
|
@@ -9088,7 +9219,7 @@ function listCompanyPortfolio(config, cwd) {
|
|
|
9088
9219
|
if (!isCompanyIntentId(id)) continue;
|
|
9089
9220
|
const state = fetchGoalState(config, id, cwd);
|
|
9090
9221
|
if (!state) continue;
|
|
9091
|
-
const destination =
|
|
9222
|
+
const destination = recordField3(state.extra.destination);
|
|
9092
9223
|
goals.push({
|
|
9093
9224
|
id,
|
|
9094
9225
|
state: state.state,
|
|
@@ -9114,7 +9245,7 @@ function stringField3(value) {
|
|
|
9114
9245
|
function numberField(value, fallback) {
|
|
9115
9246
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
9116
9247
|
}
|
|
9117
|
-
function
|
|
9248
|
+
function recordField3(value) {
|
|
9118
9249
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
9119
9250
|
}
|
|
9120
9251
|
function stringArray4(value) {
|
|
@@ -9502,7 +9633,7 @@ function capabilityEvidenceOutput(evidence) {
|
|
|
9502
9633
|
function goalReportBody(goalId, state, snapshot, latestEvent, evidenceItems) {
|
|
9503
9634
|
const outputs = evidenceItems.map(capabilityEvidenceOutput);
|
|
9504
9635
|
const latestOutput = outputs.at(-1);
|
|
9505
|
-
const facts =
|
|
9636
|
+
const facts = recordField4(snapshot, "facts") ?? recordField4(state.extra, "facts") ?? {};
|
|
9506
9637
|
const blockers = uniqueStrings2([
|
|
9507
9638
|
...stringArrayField(snapshot, "blockers"),
|
|
9508
9639
|
...stringArrayField(latestEvent, "blockers"),
|
|
@@ -9554,7 +9685,7 @@ function capabilityEvidenceMarkdown(outputs) {
|
|
|
9554
9685
|
function decisionReason(state, latestEvent, latestOutput, missingEvidence, blockers) {
|
|
9555
9686
|
if (state.state === "done") return "destination evidence satisfied";
|
|
9556
9687
|
if (blockers.length > 0) return blockers[0] ?? "blocked";
|
|
9557
|
-
const eventReason = stringField4(latestEvent, "reason") ?? stringField4(
|
|
9688
|
+
const eventReason = stringField4(latestEvent, "reason") ?? stringField4(recordField4(latestEvent, "decision"), "reason");
|
|
9558
9689
|
if (eventReason) return eventReason;
|
|
9559
9690
|
const summary = stringField4(latestOutput, "summary");
|
|
9560
9691
|
if (summary) return summary;
|
|
@@ -9567,18 +9698,18 @@ function evidenceOutputMarkdown(index, output) {
|
|
|
9567
9698
|
`- Status: ${stringField4(output, "status") ?? "unknown"}`,
|
|
9568
9699
|
`- Summary: ${stringField4(output, "summary") ?? "no summary"}`,
|
|
9569
9700
|
`- Sources: ${listOrNone(stringArrayField(output, "sources"))}`,
|
|
9570
|
-
`- Evidence values: ${inlineJson(
|
|
9701
|
+
`- Evidence values: ${inlineJson(recordField4(output, "evidence") ?? {})}`,
|
|
9571
9702
|
`- Missing evidence: ${listOrNone(stringArrayField(output, "missingEvidence"))}`,
|
|
9572
9703
|
`- Blockers: ${listOrNone(stringArrayField(output, "blockers"))}`,
|
|
9573
9704
|
""
|
|
9574
9705
|
];
|
|
9575
9706
|
}
|
|
9576
9707
|
function dispatchContextMarkdown(latestEvent) {
|
|
9577
|
-
const context =
|
|
9708
|
+
const context = recordField4(latestEvent, "dispatchContext");
|
|
9578
9709
|
if (!context) return ["- none"];
|
|
9579
9710
|
const githubActor = stringField4(context, "githubActor");
|
|
9580
9711
|
const githubActorRole = stringField4(context, "githubActorRole");
|
|
9581
|
-
const target = dispatchTargetLabel(
|
|
9712
|
+
const target = dispatchTargetLabel(recordField4(context, "target"));
|
|
9582
9713
|
return [
|
|
9583
9714
|
`- Triggered by: ${stringField4(context, "triggeredBy") ?? "unknown"}`,
|
|
9584
9715
|
`- Mode: ${stringField4(context, "dispatchMode") ?? "unknown"}`,
|
|
@@ -9617,7 +9748,7 @@ function stringField4(record2, key) {
|
|
|
9617
9748
|
const value = record2?.[key];
|
|
9618
9749
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
9619
9750
|
}
|
|
9620
|
-
function
|
|
9751
|
+
function recordField4(record2, key) {
|
|
9621
9752
|
const value = record2?.[key];
|
|
9622
9753
|
return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : void 0;
|
|
9623
9754
|
}
|
|
@@ -9650,7 +9781,7 @@ ${artifact.path ?? ""}`;
|
|
|
9650
9781
|
}
|
|
9651
9782
|
function nextStepFromEvent(state, goalAfter, capabilityOutput, latestEvent) {
|
|
9652
9783
|
if (state.state === "done") return "done";
|
|
9653
|
-
const decisionKind = stringField4(
|
|
9784
|
+
const decisionKind = stringField4(recordField4(latestEvent, "decision"), "kind") ?? stringField4(latestEvent, "status");
|
|
9654
9785
|
if (decisionKind === "done") return "done";
|
|
9655
9786
|
if (decisionKind === "dispatch") return "dispatch";
|
|
9656
9787
|
if (decisionKind === "blocked" || decisionKind === "reject-evidence") return "block";
|
|
@@ -10113,8 +10244,8 @@ var init_classifyByLabel = __esm({
|
|
|
10113
10244
|
});
|
|
10114
10245
|
|
|
10115
10246
|
// src/scripts/commitAndPush.ts
|
|
10116
|
-
import * as
|
|
10117
|
-
import * as
|
|
10247
|
+
import * as fs29 from "fs";
|
|
10248
|
+
import * as path28 from "path";
|
|
10118
10249
|
function sentinelPathForStage(cwd, profileName) {
|
|
10119
10250
|
const runId = resolveRunId();
|
|
10120
10251
|
return runtimeStatePath(cwd, "agent-runs", runId, `commit-${profileName}.lock`);
|
|
@@ -10135,9 +10266,9 @@ var init_commitAndPush = __esm({
|
|
|
10135
10266
|
}
|
|
10136
10267
|
const idempotencyEnabled = process.env.KODY_COMMIT_IDEMPOTENCY !== "0";
|
|
10137
10268
|
const sentinel = idempotencyEnabled ? sentinelPathForStage(ctx.cwd, profile.name) : null;
|
|
10138
|
-
if (sentinel &&
|
|
10269
|
+
if (sentinel && fs29.existsSync(sentinel)) {
|
|
10139
10270
|
try {
|
|
10140
|
-
const replay = JSON.parse(
|
|
10271
|
+
const replay = JSON.parse(fs29.readFileSync(sentinel, "utf-8"));
|
|
10141
10272
|
ctx.data.commitResult = replay.commitResult ?? { committed: false, pushed: false };
|
|
10142
10273
|
if (Array.isArray(replay.changedFiles)) ctx.data.changedFiles = replay.changedFiles;
|
|
10143
10274
|
if (typeof replay.hasCommitsAhead === "boolean") ctx.data.hasCommitsAhead = replay.hasCommitsAhead;
|
|
@@ -10190,8 +10321,8 @@ var init_commitAndPush = __esm({
|
|
|
10190
10321
|
const result = ctx.data.commitResult;
|
|
10191
10322
|
if (sentinel && result?.committed) {
|
|
10192
10323
|
try {
|
|
10193
|
-
|
|
10194
|
-
|
|
10324
|
+
fs29.mkdirSync(path28.dirname(sentinel), { recursive: true });
|
|
10325
|
+
fs29.writeFileSync(
|
|
10195
10326
|
sentinel,
|
|
10196
10327
|
JSON.stringify(
|
|
10197
10328
|
{
|
|
@@ -10282,8 +10413,8 @@ var init_commitGoalState = __esm({
|
|
|
10282
10413
|
});
|
|
10283
10414
|
|
|
10284
10415
|
// src/scripts/composePrompt.ts
|
|
10285
|
-
import * as
|
|
10286
|
-
import * as
|
|
10416
|
+
import * as fs30 from "fs";
|
|
10417
|
+
import * as path29 from "path";
|
|
10287
10418
|
function fenceUntrusted(value) {
|
|
10288
10419
|
if (value.trim().length === 0) return value;
|
|
10289
10420
|
const safe = value.replace(/-{3,}\s*END UNTRUSTED INPUT\s*-{3,}/gi, "[END UNTRUSTED INPUT]");
|
|
@@ -10406,10 +10537,10 @@ var init_composePrompt = __esm({
|
|
|
10406
10537
|
const explicit = ctx.data.promptTemplate;
|
|
10407
10538
|
const mode = ctx.args.mode;
|
|
10408
10539
|
const candidates = [
|
|
10409
|
-
explicit ?
|
|
10410
|
-
mode ?
|
|
10411
|
-
|
|
10412
|
-
|
|
10540
|
+
explicit ? path29.join(profile.dir, explicit) : null,
|
|
10541
|
+
mode ? path29.join(profile.dir, "prompts", `${mode}.md`) : null,
|
|
10542
|
+
path29.join(profile.dir, "prompt.md"),
|
|
10543
|
+
path29.join(profile.dir, "capability.md")
|
|
10413
10544
|
].filter(Boolean);
|
|
10414
10545
|
let templatePath = "";
|
|
10415
10546
|
let template = "";
|
|
@@ -10422,7 +10553,7 @@ var init_composePrompt = __esm({
|
|
|
10422
10553
|
break;
|
|
10423
10554
|
}
|
|
10424
10555
|
try {
|
|
10425
|
-
template =
|
|
10556
|
+
template = fs30.readFileSync(c, "utf-8");
|
|
10426
10557
|
templatePath = c;
|
|
10427
10558
|
break;
|
|
10428
10559
|
} catch (err) {
|
|
@@ -10433,7 +10564,7 @@ var init_composePrompt = __esm({
|
|
|
10433
10564
|
if (!templatePath) {
|
|
10434
10565
|
let dirState;
|
|
10435
10566
|
try {
|
|
10436
|
-
dirState = `dir contents: [${
|
|
10567
|
+
dirState = `dir contents: [${fs30.readdirSync(profile.dir).join(", ")}]`;
|
|
10437
10568
|
} catch (err) {
|
|
10438
10569
|
dirState = `readdir(${profile.dir}) failed: ${err?.code ?? String(err)}`;
|
|
10439
10570
|
}
|
|
@@ -11118,19 +11249,19 @@ var init_deriveQaScopeFromIssue = __esm({
|
|
|
11118
11249
|
|
|
11119
11250
|
// src/scripts/diagMcp.ts
|
|
11120
11251
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
11121
|
-
import * as
|
|
11252
|
+
import * as fs31 from "fs";
|
|
11122
11253
|
import * as os6 from "os";
|
|
11123
|
-
import * as
|
|
11254
|
+
import * as path30 from "path";
|
|
11124
11255
|
var diagMcp;
|
|
11125
11256
|
var init_diagMcp = __esm({
|
|
11126
11257
|
"src/scripts/diagMcp.ts"() {
|
|
11127
11258
|
"use strict";
|
|
11128
11259
|
diagMcp = async (_ctx) => {
|
|
11129
11260
|
const home = os6.homedir();
|
|
11130
|
-
const cacheDir =
|
|
11261
|
+
const cacheDir = path30.join(home, ".cache", "ms-playwright");
|
|
11131
11262
|
let entries = [];
|
|
11132
11263
|
try {
|
|
11133
|
-
entries =
|
|
11264
|
+
entries = fs31.readdirSync(cacheDir);
|
|
11134
11265
|
} catch {
|
|
11135
11266
|
}
|
|
11136
11267
|
const hasChromium = entries.some((e) => e.startsWith("chromium"));
|
|
@@ -11158,13 +11289,13 @@ var init_diagMcp = __esm({
|
|
|
11158
11289
|
});
|
|
11159
11290
|
|
|
11160
11291
|
// src/scripts/frameworkDetectors.ts
|
|
11161
|
-
import * as
|
|
11162
|
-
import * as
|
|
11292
|
+
import * as fs32 from "fs";
|
|
11293
|
+
import * as path31 from "path";
|
|
11163
11294
|
function detectFrameworks(cwd) {
|
|
11164
11295
|
const out = [];
|
|
11165
11296
|
let deps = {};
|
|
11166
11297
|
try {
|
|
11167
|
-
const pkg = JSON.parse(
|
|
11298
|
+
const pkg = JSON.parse(fs32.readFileSync(path31.join(cwd, "package.json"), "utf-8"));
|
|
11168
11299
|
deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
11169
11300
|
} catch {
|
|
11170
11301
|
return out;
|
|
@@ -11201,25 +11332,25 @@ function detectFrameworks(cwd) {
|
|
|
11201
11332
|
}
|
|
11202
11333
|
function findFile(cwd, candidates) {
|
|
11203
11334
|
for (const c of candidates) {
|
|
11204
|
-
if (
|
|
11335
|
+
if (fs32.existsSync(path31.join(cwd, c))) return c;
|
|
11205
11336
|
}
|
|
11206
11337
|
return null;
|
|
11207
11338
|
}
|
|
11208
11339
|
function discoverPayloadCollections(cwd) {
|
|
11209
11340
|
const out = [];
|
|
11210
11341
|
for (const dir of COLLECTION_DIRS) {
|
|
11211
|
-
const full =
|
|
11212
|
-
if (!
|
|
11342
|
+
const full = path31.join(cwd, dir);
|
|
11343
|
+
if (!fs32.existsSync(full)) continue;
|
|
11213
11344
|
let files;
|
|
11214
11345
|
try {
|
|
11215
|
-
files =
|
|
11346
|
+
files = fs32.readdirSync(full).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
|
|
11216
11347
|
} catch {
|
|
11217
11348
|
continue;
|
|
11218
11349
|
}
|
|
11219
11350
|
for (const file of files) {
|
|
11220
11351
|
try {
|
|
11221
|
-
const filePath =
|
|
11222
|
-
const content =
|
|
11352
|
+
const filePath = path31.join(full, file);
|
|
11353
|
+
const content = fs32.readFileSync(filePath, "utf-8").slice(0, 1e4);
|
|
11223
11354
|
const slugMatch = content.match(/slug:\s*['"]([a-z0-9-]+)['"]/);
|
|
11224
11355
|
if (!slugMatch) continue;
|
|
11225
11356
|
const slug2 = slugMatch[1];
|
|
@@ -11233,7 +11364,7 @@ function discoverPayloadCollections(cwd) {
|
|
|
11233
11364
|
out.push({
|
|
11234
11365
|
name,
|
|
11235
11366
|
slug: slug2,
|
|
11236
|
-
filePath:
|
|
11367
|
+
filePath: path31.relative(cwd, filePath),
|
|
11237
11368
|
fields: fields.slice(0, 20),
|
|
11238
11369
|
hasAdmin
|
|
11239
11370
|
});
|
|
@@ -11246,28 +11377,28 @@ function discoverPayloadCollections(cwd) {
|
|
|
11246
11377
|
function discoverAdminComponents(cwd, collections) {
|
|
11247
11378
|
const out = [];
|
|
11248
11379
|
for (const dir of ADMIN_COMPONENT_DIRS) {
|
|
11249
|
-
const full =
|
|
11250
|
-
if (!
|
|
11380
|
+
const full = path31.join(cwd, dir);
|
|
11381
|
+
if (!fs32.existsSync(full)) continue;
|
|
11251
11382
|
let entries;
|
|
11252
11383
|
try {
|
|
11253
|
-
entries =
|
|
11384
|
+
entries = fs32.readdirSync(full, { withFileTypes: true });
|
|
11254
11385
|
} catch {
|
|
11255
11386
|
continue;
|
|
11256
11387
|
}
|
|
11257
11388
|
for (const entry of entries) {
|
|
11258
|
-
const entryPath =
|
|
11389
|
+
const entryPath = path31.join(full, entry.name);
|
|
11259
11390
|
let name;
|
|
11260
11391
|
let filePath;
|
|
11261
11392
|
if (entry.isDirectory()) {
|
|
11262
11393
|
const indexFile = ["index.tsx", "index.ts", "index.jsx", "index.js"].find(
|
|
11263
|
-
(f) =>
|
|
11394
|
+
(f) => fs32.existsSync(path31.join(entryPath, f))
|
|
11264
11395
|
);
|
|
11265
11396
|
if (!indexFile) continue;
|
|
11266
11397
|
name = entry.name;
|
|
11267
|
-
filePath =
|
|
11398
|
+
filePath = path31.relative(cwd, path31.join(entryPath, indexFile));
|
|
11268
11399
|
} else if (/\.(tsx?|jsx?)$/.test(entry.name)) {
|
|
11269
11400
|
name = entry.name.replace(/\.(tsx?|jsx?)$/, "");
|
|
11270
|
-
filePath =
|
|
11401
|
+
filePath = path31.relative(cwd, entryPath);
|
|
11271
11402
|
} else {
|
|
11272
11403
|
continue;
|
|
11273
11404
|
}
|
|
@@ -11275,7 +11406,7 @@ function discoverAdminComponents(cwd, collections) {
|
|
|
11275
11406
|
if (collections) {
|
|
11276
11407
|
for (const col of collections) {
|
|
11277
11408
|
try {
|
|
11278
|
-
const colContent =
|
|
11409
|
+
const colContent = fs32.readFileSync(path31.join(cwd, col.filePath), "utf-8");
|
|
11279
11410
|
if (colContent.includes(name)) {
|
|
11280
11411
|
usedInCollection = col.slug;
|
|
11281
11412
|
break;
|
|
@@ -11293,8 +11424,8 @@ function scanApiRoutes(cwd) {
|
|
|
11293
11424
|
const out = [];
|
|
11294
11425
|
const appDirs = ["src/app", "app"];
|
|
11295
11426
|
for (const appDir of appDirs) {
|
|
11296
|
-
const apiDir =
|
|
11297
|
-
if (!
|
|
11427
|
+
const apiDir = path31.join(cwd, appDir, "api");
|
|
11428
|
+
if (!fs32.existsSync(apiDir)) continue;
|
|
11298
11429
|
walkApiRoutes(apiDir, "/api", cwd, out);
|
|
11299
11430
|
break;
|
|
11300
11431
|
}
|
|
@@ -11303,14 +11434,14 @@ function scanApiRoutes(cwd) {
|
|
|
11303
11434
|
function walkApiRoutes(dir, prefix, cwd, out) {
|
|
11304
11435
|
let entries;
|
|
11305
11436
|
try {
|
|
11306
|
-
entries =
|
|
11437
|
+
entries = fs32.readdirSync(dir, { withFileTypes: true });
|
|
11307
11438
|
} catch {
|
|
11308
11439
|
return;
|
|
11309
11440
|
}
|
|
11310
11441
|
const routeFile = entries.find((e) => e.isFile() && /^route\.(ts|js|tsx|jsx)$/.test(e.name));
|
|
11311
11442
|
if (routeFile) {
|
|
11312
11443
|
try {
|
|
11313
|
-
const content =
|
|
11444
|
+
const content = fs32.readFileSync(path31.join(dir, routeFile.name), "utf-8").slice(0, 5e3);
|
|
11314
11445
|
const methods = HTTP_METHODS.filter(
|
|
11315
11446
|
(m) => new RegExp(`export\\s+(?:async\\s+)?function\\s+${m}\\b`).test(content)
|
|
11316
11447
|
);
|
|
@@ -11318,7 +11449,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
|
|
|
11318
11449
|
out.push({
|
|
11319
11450
|
path: prefix,
|
|
11320
11451
|
methods,
|
|
11321
|
-
filePath:
|
|
11452
|
+
filePath: path31.relative(cwd, path31.join(dir, routeFile.name))
|
|
11322
11453
|
});
|
|
11323
11454
|
}
|
|
11324
11455
|
} catch {
|
|
@@ -11329,7 +11460,7 @@ function walkApiRoutes(dir, prefix, cwd, out) {
|
|
|
11329
11460
|
if (entry.name === "node_modules" || entry.name === ".next") continue;
|
|
11330
11461
|
let segment = entry.name;
|
|
11331
11462
|
if (segment.startsWith("(") && segment.endsWith(")")) {
|
|
11332
|
-
walkApiRoutes(
|
|
11463
|
+
walkApiRoutes(path31.join(dir, entry.name), prefix, cwd, out);
|
|
11333
11464
|
continue;
|
|
11334
11465
|
}
|
|
11335
11466
|
if (segment.startsWith("[[") && segment.endsWith("]]")) {
|
|
@@ -11337,16 +11468,16 @@ function walkApiRoutes(dir, prefix, cwd, out) {
|
|
|
11337
11468
|
} else if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
11338
11469
|
segment = `:${segment.slice(1, -1)}`;
|
|
11339
11470
|
}
|
|
11340
|
-
walkApiRoutes(
|
|
11471
|
+
walkApiRoutes(path31.join(dir, entry.name), `${prefix}/${segment}`, cwd, out);
|
|
11341
11472
|
}
|
|
11342
11473
|
}
|
|
11343
11474
|
function scanEnvVars(cwd) {
|
|
11344
11475
|
const candidates = [".env.example", ".env.local.example", ".env.template"];
|
|
11345
11476
|
for (const envFile of candidates) {
|
|
11346
|
-
const envPath =
|
|
11347
|
-
if (!
|
|
11477
|
+
const envPath = path31.join(cwd, envFile);
|
|
11478
|
+
if (!fs32.existsSync(envPath)) continue;
|
|
11348
11479
|
try {
|
|
11349
|
-
const content =
|
|
11480
|
+
const content = fs32.readFileSync(envPath, "utf-8");
|
|
11350
11481
|
const vars = [];
|
|
11351
11482
|
for (const line of content.split("\n")) {
|
|
11352
11483
|
const trimmed = line.trim();
|
|
@@ -11391,8 +11522,8 @@ var init_frameworkDetectors = __esm({
|
|
|
11391
11522
|
});
|
|
11392
11523
|
|
|
11393
11524
|
// src/scripts/discoverQaContext.ts
|
|
11394
|
-
import * as
|
|
11395
|
-
import * as
|
|
11525
|
+
import * as fs33 from "fs";
|
|
11526
|
+
import * as path32 from "path";
|
|
11396
11527
|
function runQaDiscovery(cwd) {
|
|
11397
11528
|
const out = {
|
|
11398
11529
|
routes: [],
|
|
@@ -11423,9 +11554,9 @@ function runQaDiscovery(cwd) {
|
|
|
11423
11554
|
}
|
|
11424
11555
|
function detectDevServer(cwd, out) {
|
|
11425
11556
|
try {
|
|
11426
|
-
const pkg = JSON.parse(
|
|
11557
|
+
const pkg = JSON.parse(fs33.readFileSync(path32.join(cwd, "package.json"), "utf-8"));
|
|
11427
11558
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
11428
|
-
const pm =
|
|
11559
|
+
const pm = fs33.existsSync(path32.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs33.existsSync(path32.join(cwd, "yarn.lock")) ? "yarn" : fs33.existsSync(path32.join(cwd, "bun.lockb")) ? "bun" : "npm";
|
|
11429
11560
|
if (pkg.scripts?.dev) out.devCommand = `${pm} dev`;
|
|
11430
11561
|
if (allDeps.next || allDeps.nuxt) out.devPort = 3e3;
|
|
11431
11562
|
else if (allDeps.vite) out.devPort = 5173;
|
|
@@ -11435,8 +11566,8 @@ function detectDevServer(cwd, out) {
|
|
|
11435
11566
|
function scanFrontendRoutes(cwd, out) {
|
|
11436
11567
|
const appDirs = ["src/app", "app"];
|
|
11437
11568
|
for (const appDir of appDirs) {
|
|
11438
|
-
const full =
|
|
11439
|
-
if (!
|
|
11569
|
+
const full = path32.join(cwd, appDir);
|
|
11570
|
+
if (!fs33.existsSync(full)) continue;
|
|
11440
11571
|
walkFrontendRoutes(full, "", out);
|
|
11441
11572
|
break;
|
|
11442
11573
|
}
|
|
@@ -11444,7 +11575,7 @@ function scanFrontendRoutes(cwd, out) {
|
|
|
11444
11575
|
function walkFrontendRoutes(dir, prefix, out) {
|
|
11445
11576
|
let entries;
|
|
11446
11577
|
try {
|
|
11447
|
-
entries =
|
|
11578
|
+
entries = fs33.readdirSync(dir, { withFileTypes: true });
|
|
11448
11579
|
} catch {
|
|
11449
11580
|
return;
|
|
11450
11581
|
}
|
|
@@ -11461,7 +11592,7 @@ function walkFrontendRoutes(dir, prefix, out) {
|
|
|
11461
11592
|
if (entry.name === "node_modules" || entry.name === ".next") continue;
|
|
11462
11593
|
let segment = entry.name;
|
|
11463
11594
|
if (segment.startsWith("(") && segment.endsWith(")")) {
|
|
11464
|
-
walkFrontendRoutes(
|
|
11595
|
+
walkFrontendRoutes(path32.join(dir, entry.name), prefix, out);
|
|
11465
11596
|
continue;
|
|
11466
11597
|
}
|
|
11467
11598
|
if (segment.startsWith("[[") && segment.endsWith("]]")) {
|
|
@@ -11469,7 +11600,7 @@ function walkFrontendRoutes(dir, prefix, out) {
|
|
|
11469
11600
|
} else if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
11470
11601
|
segment = `:${segment.slice(1, -1)}`;
|
|
11471
11602
|
}
|
|
11472
|
-
walkFrontendRoutes(
|
|
11603
|
+
walkFrontendRoutes(path32.join(dir, entry.name), `${prefix}/${segment}`, out);
|
|
11473
11604
|
}
|
|
11474
11605
|
}
|
|
11475
11606
|
function detectAuthFiles(cwd, out) {
|
|
@@ -11486,23 +11617,23 @@ function detectAuthFiles(cwd, out) {
|
|
|
11486
11617
|
"src/app/api/oauth"
|
|
11487
11618
|
];
|
|
11488
11619
|
for (const c of candidates) {
|
|
11489
|
-
if (
|
|
11620
|
+
if (fs33.existsSync(path32.join(cwd, c))) out.authFiles.push(c);
|
|
11490
11621
|
}
|
|
11491
11622
|
}
|
|
11492
11623
|
function detectRoles(cwd, out) {
|
|
11493
11624
|
const rolePaths = ["src/types", "src/lib", "src/utils", "src/constants", "src/access", "src/collections"];
|
|
11494
11625
|
for (const rp of rolePaths) {
|
|
11495
|
-
const dir =
|
|
11496
|
-
if (!
|
|
11626
|
+
const dir = path32.join(cwd, rp);
|
|
11627
|
+
if (!fs33.existsSync(dir)) continue;
|
|
11497
11628
|
let files;
|
|
11498
11629
|
try {
|
|
11499
|
-
files =
|
|
11630
|
+
files = fs33.readdirSync(dir).filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
|
|
11500
11631
|
} catch {
|
|
11501
11632
|
continue;
|
|
11502
11633
|
}
|
|
11503
11634
|
for (const f of files) {
|
|
11504
11635
|
try {
|
|
11505
|
-
const content =
|
|
11636
|
+
const content = fs33.readFileSync(path32.join(dir, f), "utf-8").slice(0, 5e3);
|
|
11506
11637
|
const roleMatches = content.match(/(?:role|Role|ROLE)\s*[=:]\s*['"](\w+)['"]/g);
|
|
11507
11638
|
if (roleMatches) {
|
|
11508
11639
|
for (const m of roleMatches) {
|
|
@@ -12147,6 +12278,126 @@ var init_ensurePr = __esm({
|
|
|
12147
12278
|
}
|
|
12148
12279
|
});
|
|
12149
12280
|
|
|
12281
|
+
// src/agencyBoundaryEval.ts
|
|
12282
|
+
function evaluateAgencyBoundaries(input) {
|
|
12283
|
+
const findings = [];
|
|
12284
|
+
const results = input.results ?? [];
|
|
12285
|
+
findings.push(evaluateObserveBoundary(input.capabilityKind, results));
|
|
12286
|
+
findings.push(evaluateVerifyBoundary(input.capabilityKind, results));
|
|
12287
|
+
findings.push(evaluateGoalOwnershipBoundary(results));
|
|
12288
|
+
return {
|
|
12289
|
+
version: 1,
|
|
12290
|
+
status: findings.some((finding) => finding.status === "fail") ? "fail" : "pass",
|
|
12291
|
+
...input.capability ? { capability: input.capability } : {},
|
|
12292
|
+
...input.capabilityKind ? { capabilityKind: input.capabilityKind } : {},
|
|
12293
|
+
findings
|
|
12294
|
+
};
|
|
12295
|
+
}
|
|
12296
|
+
function evaluateObserveBoundary(capabilityKind, results) {
|
|
12297
|
+
if (capabilityKind !== "observe") {
|
|
12298
|
+
return pass("observe-does-not-act", "capability is not observe", { capabilityKind });
|
|
12299
|
+
}
|
|
12300
|
+
const actionResults = results.filter(resultLooksLikeAction);
|
|
12301
|
+
if (actionResults.length === 0) {
|
|
12302
|
+
return pass("observe-does-not-act", "observe capability reported facts without action output", {
|
|
12303
|
+
resultCount: results.length
|
|
12304
|
+
});
|
|
12305
|
+
}
|
|
12306
|
+
return fail2("observe-does-not-act", "observe capability returned action-shaped output", {
|
|
12307
|
+
resultCount: results.length,
|
|
12308
|
+
actionResults: actionResults.map(resultSummary)
|
|
12309
|
+
});
|
|
12310
|
+
}
|
|
12311
|
+
function evaluateVerifyBoundary(capabilityKind, results) {
|
|
12312
|
+
if (capabilityKind !== "verify") {
|
|
12313
|
+
return pass("verify-does-not-fix", "capability is not verify", { capabilityKind });
|
|
12314
|
+
}
|
|
12315
|
+
const actionResults = results.filter(resultLooksLikeAction);
|
|
12316
|
+
if (actionResults.length === 0) {
|
|
12317
|
+
return pass("verify-does-not-fix", "verify capability returned verdict evidence without action output", {
|
|
12318
|
+
resultCount: results.length
|
|
12319
|
+
});
|
|
12320
|
+
}
|
|
12321
|
+
return fail2("verify-does-not-fix", "verify capability returned fix/change output", {
|
|
12322
|
+
resultCount: results.length,
|
|
12323
|
+
actionResults: actionResults.map(resultSummary)
|
|
12324
|
+
});
|
|
12325
|
+
}
|
|
12326
|
+
function evaluateGoalOwnershipBoundary(results) {
|
|
12327
|
+
const targetBearing = results.filter((result) => result.target?.type === "goal");
|
|
12328
|
+
if (targetBearing.length === 0) {
|
|
12329
|
+
return pass("capability-does-not-own-goal-progress", "capability output is parent-neutral", {
|
|
12330
|
+
resultCount: results.length
|
|
12331
|
+
});
|
|
12332
|
+
}
|
|
12333
|
+
return fail2("capability-does-not-own-goal-progress", "capability output names a goal target", {
|
|
12334
|
+
resultCount: results.length,
|
|
12335
|
+
targetBearingResults: targetBearing.map(resultSummary)
|
|
12336
|
+
});
|
|
12337
|
+
}
|
|
12338
|
+
function resultLooksLikeAction(result) {
|
|
12339
|
+
if (result.status === "changed") return true;
|
|
12340
|
+
return Object.keys(result.facts).some((key) => ACTION_FACT_KEYS.has(key));
|
|
12341
|
+
}
|
|
12342
|
+
function resultSummary(result) {
|
|
12343
|
+
return {
|
|
12344
|
+
status: result.status,
|
|
12345
|
+
summary: result.summary,
|
|
12346
|
+
target: result.target,
|
|
12347
|
+
actionFactKeys: Object.keys(result.facts).filter((key) => ACTION_FACT_KEYS.has(key))
|
|
12348
|
+
};
|
|
12349
|
+
}
|
|
12350
|
+
function pass(rule, message, evidence) {
|
|
12351
|
+
return { rule, status: "pass", message, evidence };
|
|
12352
|
+
}
|
|
12353
|
+
function fail2(rule, message, evidence) {
|
|
12354
|
+
return { rule, status: "fail", message, evidence };
|
|
12355
|
+
}
|
|
12356
|
+
var ACTION_FACT_KEYS;
|
|
12357
|
+
var init_agencyBoundaryEval = __esm({
|
|
12358
|
+
"src/agencyBoundaryEval.ts"() {
|
|
12359
|
+
"use strict";
|
|
12360
|
+
ACTION_FACT_KEYS = /* @__PURE__ */ new Set(["changedResources", "createdResources", "actionResult"]);
|
|
12361
|
+
}
|
|
12362
|
+
});
|
|
12363
|
+
|
|
12364
|
+
// src/scripts/evaluateAgencyBoundaries.ts
|
|
12365
|
+
function collectResults2(raw, agentResult) {
|
|
12366
|
+
const out = [];
|
|
12367
|
+
if (Array.isArray(raw)) {
|
|
12368
|
+
for (const item of raw) {
|
|
12369
|
+
const parsed = parseCapabilityResult(item);
|
|
12370
|
+
if (parsed) out.push(parsed);
|
|
12371
|
+
}
|
|
12372
|
+
}
|
|
12373
|
+
if (agentResult?.finalText) out.push(...parseCapabilityResultsFromText(agentResult.finalText));
|
|
12374
|
+
return out;
|
|
12375
|
+
}
|
|
12376
|
+
var evaluateAgencyBoundariesScript;
|
|
12377
|
+
var init_evaluateAgencyBoundaries = __esm({
|
|
12378
|
+
"src/scripts/evaluateAgencyBoundaries.ts"() {
|
|
12379
|
+
"use strict";
|
|
12380
|
+
init_agencyBoundaryEval();
|
|
12381
|
+
init_capabilityResult();
|
|
12382
|
+
evaluateAgencyBoundariesScript = async (ctx, profile, agentResult) => {
|
|
12383
|
+
const results = collectResults2(ctx.data.capabilityResults ?? ctx.data.dutyResults, agentResult);
|
|
12384
|
+
const evalResult = evaluateAgencyBoundaries({
|
|
12385
|
+
capability: profile.name,
|
|
12386
|
+
capabilityKind: profile.capabilityKind,
|
|
12387
|
+
results
|
|
12388
|
+
});
|
|
12389
|
+
ctx.data.agencyBoundaryEval = evalResult;
|
|
12390
|
+
process.stdout.write(`KODY_AGENCY_BOUNDARY_EVAL=${JSON.stringify(evalResult)}
|
|
12391
|
+
`);
|
|
12392
|
+
if (evalResult.status === "fail") {
|
|
12393
|
+
const failed = evalResult.findings.filter((finding) => finding.status === "fail").map((finding) => finding.rule);
|
|
12394
|
+
ctx.output.exitCode = ctx.output.exitCode === 0 ? 99 : ctx.output.exitCode;
|
|
12395
|
+
ctx.output.reason = ctx.output.reason ? `${ctx.output.reason}; agency boundary eval failed: ${failed.join(", ")}` : `agency boundary eval failed: ${failed.join(", ")}`;
|
|
12396
|
+
}
|
|
12397
|
+
};
|
|
12398
|
+
}
|
|
12399
|
+
});
|
|
12400
|
+
|
|
12150
12401
|
// src/scripts/failOnceTaskJob.ts
|
|
12151
12402
|
var failOnceTaskJob;
|
|
12152
12403
|
var init_failOnceTaskJob = __esm({
|
|
@@ -12742,12 +12993,12 @@ var init_fixFlow = __esm({
|
|
|
12742
12993
|
|
|
12743
12994
|
// src/scripts/initFlow.ts
|
|
12744
12995
|
import { execFileSync as execFileSync15 } from "child_process";
|
|
12745
|
-
import * as
|
|
12746
|
-
import * as
|
|
12996
|
+
import * as fs34 from "fs";
|
|
12997
|
+
import * as path33 from "path";
|
|
12747
12998
|
function detectPackageManager(cwd) {
|
|
12748
|
-
if (
|
|
12749
|
-
if (
|
|
12750
|
-
if (
|
|
12999
|
+
if (fs34.existsSync(path33.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
13000
|
+
if (fs34.existsSync(path33.join(cwd, "yarn.lock"))) return "yarn";
|
|
13001
|
+
if (fs34.existsSync(path33.join(cwd, "bun.lockb"))) return "bun";
|
|
12751
13002
|
return "npm";
|
|
12752
13003
|
}
|
|
12753
13004
|
function qualityCommandsFor(pm) {
|
|
@@ -12819,22 +13070,22 @@ function performInit(cwd, force) {
|
|
|
12819
13070
|
const pm = detectPackageManager(cwd);
|
|
12820
13071
|
const ownerRepo = detectOwnerRepo(cwd);
|
|
12821
13072
|
const defaultBranch = defaultBranchFromGit(cwd);
|
|
12822
|
-
const configPath =
|
|
12823
|
-
if (
|
|
13073
|
+
const configPath = path33.join(cwd, "kody.config.json");
|
|
13074
|
+
if (fs34.existsSync(configPath) && !force) {
|
|
12824
13075
|
skipped.push("kody.config.json");
|
|
12825
13076
|
} else {
|
|
12826
13077
|
const cfg = makeConfig(pm, ownerRepo, defaultBranch);
|
|
12827
|
-
|
|
13078
|
+
fs34.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
|
|
12828
13079
|
`);
|
|
12829
13080
|
wrote.push("kody.config.json");
|
|
12830
13081
|
}
|
|
12831
|
-
const workflowDir =
|
|
12832
|
-
const workflowPath =
|
|
12833
|
-
if (
|
|
13082
|
+
const workflowDir = path33.join(cwd, ".github", "workflows");
|
|
13083
|
+
const workflowPath = path33.join(workflowDir, "kody.yml");
|
|
13084
|
+
if (fs34.existsSync(workflowPath) && !force) {
|
|
12834
13085
|
skipped.push(".github/workflows/kody.yml");
|
|
12835
13086
|
} else {
|
|
12836
|
-
|
|
12837
|
-
|
|
13087
|
+
fs34.mkdirSync(workflowDir, { recursive: true });
|
|
13088
|
+
fs34.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
|
|
12838
13089
|
wrote.push(".github/workflows/kody.yml");
|
|
12839
13090
|
}
|
|
12840
13091
|
for (const exe of listExecutables()) {
|
|
@@ -12845,12 +13096,12 @@ function performInit(cwd, force) {
|
|
|
12845
13096
|
continue;
|
|
12846
13097
|
}
|
|
12847
13098
|
if (profile.kind !== "scheduled" || !profile.schedule) continue;
|
|
12848
|
-
const target =
|
|
12849
|
-
if (
|
|
13099
|
+
const target = path33.join(workflowDir, `kody-${exe.name}.yml`);
|
|
13100
|
+
if (fs34.existsSync(target) && !force) {
|
|
12850
13101
|
skipped.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
12851
13102
|
continue;
|
|
12852
13103
|
}
|
|
12853
|
-
|
|
13104
|
+
fs34.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
|
|
12854
13105
|
wrote.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
12855
13106
|
}
|
|
12856
13107
|
let labels;
|
|
@@ -12998,7 +13249,7 @@ Nothing to do. All files already present. (Use --force to overwrite.)
|
|
|
12998
13249
|
});
|
|
12999
13250
|
|
|
13000
13251
|
// src/scripts/loadAgentAdhoc.ts
|
|
13001
|
-
import * as
|
|
13252
|
+
import * as fs35 from "fs";
|
|
13002
13253
|
function resolveMessage(messageArg) {
|
|
13003
13254
|
const fromComment = readCommentBody();
|
|
13004
13255
|
if (fromComment) return stripDirective(fromComment);
|
|
@@ -13006,9 +13257,9 @@ function resolveMessage(messageArg) {
|
|
|
13006
13257
|
}
|
|
13007
13258
|
function readCommentBody() {
|
|
13008
13259
|
const eventPath = process.env.GITHUB_EVENT_PATH;
|
|
13009
|
-
if (!eventPath || !
|
|
13260
|
+
if (!eventPath || !fs35.existsSync(eventPath)) return "";
|
|
13010
13261
|
try {
|
|
13011
|
-
const event = JSON.parse(
|
|
13262
|
+
const event = JSON.parse(fs35.readFileSync(eventPath, "utf-8"));
|
|
13012
13263
|
return String(event.comment?.body ?? "");
|
|
13013
13264
|
} catch {
|
|
13014
13265
|
return "";
|
|
@@ -13061,10 +13312,10 @@ var init_loadAgentAdhoc = __esm({
|
|
|
13061
13312
|
throw new Error("loadAgentAdhoc: ctx.args.agent must be a non-empty slug");
|
|
13062
13313
|
}
|
|
13063
13314
|
const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
|
|
13064
|
-
if (!
|
|
13315
|
+
if (!fs35.existsSync(agentPath)) {
|
|
13065
13316
|
throw new Error(`loadAgentAdhoc: agent identity not found: ${agentPath}`);
|
|
13066
13317
|
}
|
|
13067
|
-
const { title, body } = parseAgentFile(
|
|
13318
|
+
const { title, body } = parseAgentFile(fs35.readFileSync(agentPath, "utf-8"), agentSlug);
|
|
13068
13319
|
const message = resolveMessage(ctx.args.message);
|
|
13069
13320
|
if (!message) {
|
|
13070
13321
|
throw new Error(
|
|
@@ -13308,8 +13559,8 @@ var init_loadIssueStateComment = __esm({
|
|
|
13308
13559
|
});
|
|
13309
13560
|
|
|
13310
13561
|
// src/scripts/loadJobFromFile.ts
|
|
13311
|
-
import * as
|
|
13312
|
-
import * as
|
|
13562
|
+
import * as fs36 from "fs";
|
|
13563
|
+
import * as path34 from "path";
|
|
13313
13564
|
function parseJobFile(raw, slug2) {
|
|
13314
13565
|
let stripped = raw;
|
|
13315
13566
|
if (stripped.startsWith("---\n")) {
|
|
@@ -13347,9 +13598,9 @@ var init_loadJobFromFile = __esm({
|
|
|
13347
13598
|
if (!slug2) {
|
|
13348
13599
|
throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
|
|
13349
13600
|
}
|
|
13350
|
-
const capability = resolveCapabilityFolder(slug2,
|
|
13601
|
+
const capability = resolveCapabilityFolder(slug2, path34.join(ctx.cwd, jobsDir));
|
|
13351
13602
|
if (!capability) {
|
|
13352
|
-
throw new Error(`loadJobFromFile: capability folder not found or incomplete: ${
|
|
13603
|
+
throw new Error(`loadJobFromFile: capability folder not found or incomplete: ${path34.join(ctx.cwd, jobsDir, slug2)}`);
|
|
13353
13604
|
}
|
|
13354
13605
|
const { title, body, config } = capability;
|
|
13355
13606
|
const mentions = (config.mentions ?? []).map((login) => `@${login}`).join(" ");
|
|
@@ -13358,12 +13609,12 @@ var init_loadJobFromFile = __esm({
|
|
|
13358
13609
|
let agentIdentity = "";
|
|
13359
13610
|
if (agentSlug) {
|
|
13360
13611
|
const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
|
|
13361
|
-
if (!
|
|
13612
|
+
if (!fs36.existsSync(agentPath)) {
|
|
13362
13613
|
throw new Error(
|
|
13363
13614
|
`loadJobFromFile: capability '${slug2}' declares agent '${agentSlug}' but ${agentPath} does not exist`
|
|
13364
13615
|
);
|
|
13365
13616
|
}
|
|
13366
|
-
const agentRaw =
|
|
13617
|
+
const agentRaw = fs36.readFileSync(agentPath, "utf-8");
|
|
13367
13618
|
const parsed = parseJobFile(agentRaw, agentSlug);
|
|
13368
13619
|
agentTitle = parsed.title;
|
|
13369
13620
|
agentIdentity = parsed.body;
|
|
@@ -13443,13 +13694,13 @@ ${truncate(issue.body, FINDING_BODY_MAX_BYTES)}`;
|
|
|
13443
13694
|
});
|
|
13444
13695
|
|
|
13445
13696
|
// src/scripts/kodyVariables.ts
|
|
13446
|
-
import * as
|
|
13447
|
-
import * as
|
|
13697
|
+
import * as fs37 from "fs";
|
|
13698
|
+
import * as path35 from "path";
|
|
13448
13699
|
function readKodyVariables(cwd) {
|
|
13449
|
-
const full =
|
|
13700
|
+
const full = path35.join(cwd, KODY_VARIABLES_REL_PATH);
|
|
13450
13701
|
let raw;
|
|
13451
13702
|
try {
|
|
13452
|
-
raw =
|
|
13703
|
+
raw = fs37.readFileSync(full, "utf-8");
|
|
13453
13704
|
} catch {
|
|
13454
13705
|
return {};
|
|
13455
13706
|
}
|
|
@@ -13517,8 +13768,8 @@ var init_keys = __esm({
|
|
|
13517
13768
|
});
|
|
13518
13769
|
|
|
13519
13770
|
// src/stateRepoGithub.ts
|
|
13520
|
-
import * as
|
|
13521
|
-
import * as
|
|
13771
|
+
import * as fs38 from "fs";
|
|
13772
|
+
import * as path36 from "path";
|
|
13522
13773
|
function recordValue3(value) {
|
|
13523
13774
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
13524
13775
|
}
|
|
@@ -13658,15 +13909,15 @@ function mergeJsonl(localText, remoteText) {
|
|
|
13658
13909
|
async function syncJsonlFileFromGithubState(opts) {
|
|
13659
13910
|
const remote = await readGithubStateTextWithConfig(opts);
|
|
13660
13911
|
if (!remote) return;
|
|
13661
|
-
const local =
|
|
13912
|
+
const local = fs38.existsSync(opts.localPath) ? fs38.readFileSync(opts.localPath, "utf-8") : "";
|
|
13662
13913
|
const next = mergeJsonl(local, remote.content);
|
|
13663
13914
|
if (next === local) return;
|
|
13664
|
-
|
|
13665
|
-
|
|
13915
|
+
fs38.mkdirSync(path36.dirname(opts.localPath), { recursive: true });
|
|
13916
|
+
fs38.writeFileSync(opts.localPath, next);
|
|
13666
13917
|
}
|
|
13667
13918
|
async function persistJsonlFileToGithubState(opts) {
|
|
13668
|
-
if (!
|
|
13669
|
-
const localText =
|
|
13919
|
+
if (!fs38.existsSync(opts.localPath)) return;
|
|
13920
|
+
const localText = fs38.readFileSync(opts.localPath, "utf-8");
|
|
13670
13921
|
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
13671
13922
|
const remote = await readGithubStateTextWithConfig(opts);
|
|
13672
13923
|
const body = mergeJsonl(localText, remote?.content ?? "");
|
|
@@ -13805,8 +14056,8 @@ var init_runtimeSecrets = __esm({
|
|
|
13805
14056
|
});
|
|
13806
14057
|
|
|
13807
14058
|
// src/scripts/loadQaContext.ts
|
|
13808
|
-
import * as
|
|
13809
|
-
import * as
|
|
14059
|
+
import * as fs39 from "fs";
|
|
14060
|
+
import * as path37 from "path";
|
|
13810
14061
|
function parseSlugList(value) {
|
|
13811
14062
|
const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
|
|
13812
14063
|
return inner.split(",").map(
|
|
@@ -13835,18 +14086,18 @@ function readProfileAgents(raw) {
|
|
|
13835
14086
|
return { agent: agent ?? legacy ?? ["kody"], body };
|
|
13836
14087
|
}
|
|
13837
14088
|
function readProfile(cwd) {
|
|
13838
|
-
const dir =
|
|
13839
|
-
if (!
|
|
14089
|
+
const dir = path37.join(cwd, CONTEXT_DIR_REL_PATH);
|
|
14090
|
+
if (!fs39.existsSync(dir)) return "";
|
|
13840
14091
|
let entries;
|
|
13841
14092
|
try {
|
|
13842
|
-
entries =
|
|
14093
|
+
entries = fs39.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
|
|
13843
14094
|
} catch {
|
|
13844
14095
|
return "";
|
|
13845
14096
|
}
|
|
13846
14097
|
const blocks = [];
|
|
13847
14098
|
for (const file of entries) {
|
|
13848
14099
|
try {
|
|
13849
|
-
const raw =
|
|
14100
|
+
const raw = fs39.readFileSync(path37.join(dir, file), "utf-8");
|
|
13850
14101
|
const { agent, body } = readProfileAgents(raw);
|
|
13851
14102
|
if (!agent.includes(QA_AGENT) && !agent.includes(ALL_AGENTS)) continue;
|
|
13852
14103
|
blocks.push(`## ${file}
|
|
@@ -13895,8 +14146,8 @@ var init_loadQaContext = __esm({
|
|
|
13895
14146
|
});
|
|
13896
14147
|
|
|
13897
14148
|
// src/taskContext.ts
|
|
13898
|
-
import * as
|
|
13899
|
-
import * as
|
|
14149
|
+
import * as fs40 from "fs";
|
|
14150
|
+
import * as path38 from "path";
|
|
13900
14151
|
function buildTaskContext(args) {
|
|
13901
14152
|
return {
|
|
13902
14153
|
schemaVersion: TASK_CONTEXT_SCHEMA_VERSION,
|
|
@@ -13912,9 +14163,9 @@ function buildTaskContext(args) {
|
|
|
13912
14163
|
function persistTaskContext(cwd, ctx) {
|
|
13913
14164
|
try {
|
|
13914
14165
|
const dir = runtimeStatePath(cwd, "agent-runs", ctx.runId);
|
|
13915
|
-
|
|
13916
|
-
const file =
|
|
13917
|
-
|
|
14166
|
+
fs40.mkdirSync(dir, { recursive: true });
|
|
14167
|
+
const file = path38.join(dir, "task-context.json");
|
|
14168
|
+
fs40.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
|
|
13918
14169
|
`);
|
|
13919
14170
|
return file;
|
|
13920
14171
|
} catch (err) {
|
|
@@ -14017,7 +14268,7 @@ var init_markFlowSuccess = __esm({
|
|
|
14017
14268
|
});
|
|
14018
14269
|
|
|
14019
14270
|
// src/goal/operations.ts
|
|
14020
|
-
function
|
|
14271
|
+
function fail3(err) {
|
|
14021
14272
|
if (err instanceof Error) {
|
|
14022
14273
|
const lines = err.message.split("\n").filter(Boolean);
|
|
14023
14274
|
return { ok: false, error: lines[0] ?? err.message };
|
|
@@ -14029,7 +14280,7 @@ function commentOnIssue(issueNumber, body, cwd) {
|
|
|
14029
14280
|
gh(["issue", "comment", String(issueNumber), "--body", body], { cwd });
|
|
14030
14281
|
return { ok: true };
|
|
14031
14282
|
} catch (err) {
|
|
14032
|
-
return
|
|
14283
|
+
return fail3(err);
|
|
14033
14284
|
}
|
|
14034
14285
|
}
|
|
14035
14286
|
function mergePrSquash(prNumber, cwd) {
|
|
@@ -14037,7 +14288,7 @@ function mergePrSquash(prNumber, cwd) {
|
|
|
14037
14288
|
gh(["pr", "merge", String(prNumber), "--squash", "--delete-branch"], { cwd });
|
|
14038
14289
|
return { ok: true };
|
|
14039
14290
|
} catch (err) {
|
|
14040
|
-
return
|
|
14291
|
+
return fail3(err);
|
|
14041
14292
|
}
|
|
14042
14293
|
}
|
|
14043
14294
|
var init_operations = __esm({
|
|
@@ -16394,12 +16645,12 @@ fi
|
|
|
16394
16645
|
|
|
16395
16646
|
// src/scripts/runPreviewBuild.ts
|
|
16396
16647
|
import { copyFile, writeFile } from "fs/promises";
|
|
16397
|
-
import * as
|
|
16648
|
+
import * as path39 from "path";
|
|
16398
16649
|
import { fileURLToPath } from "url";
|
|
16399
16650
|
function bundledDockerfilePath(mode) {
|
|
16400
|
-
const here =
|
|
16651
|
+
const here = path39.dirname(fileURLToPath(import.meta.url));
|
|
16401
16652
|
const file = mode === "dev" ? "default-Dockerfile.preview.dev" : "default-Dockerfile.preview.prod";
|
|
16402
|
-
return
|
|
16653
|
+
return path39.join(here, "preview-build-templates", file);
|
|
16403
16654
|
}
|
|
16404
16655
|
function required(name) {
|
|
16405
16656
|
const v = (process.env[name] ?? "").trim();
|
|
@@ -16650,10 +16901,10 @@ var init_runPreviewBuild = __esm({
|
|
|
16650
16901
|
console.log(`[preview-build] vault: ${Object.keys(buildEnv).length} secrets, mode=${buildMode}`);
|
|
16651
16902
|
if (Object.keys(buildEnv).length > 0) {
|
|
16652
16903
|
const lines = Object.entries(buildEnv).map(([k, v]) => `${k}=${JSON.stringify(v)}`);
|
|
16653
|
-
await writeFile(
|
|
16904
|
+
await writeFile(path39.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
|
|
16654
16905
|
`, "utf8");
|
|
16655
16906
|
}
|
|
16656
|
-
const consumerDockerfile =
|
|
16907
|
+
const consumerDockerfile = path39.join(ctx.cwd, "Dockerfile.preview");
|
|
16657
16908
|
const { stat } = await import("fs/promises");
|
|
16658
16909
|
let hasConsumerDockerfile = false;
|
|
16659
16910
|
try {
|
|
@@ -16837,8 +17088,8 @@ var init_tickShellRunner = __esm({
|
|
|
16837
17088
|
});
|
|
16838
17089
|
|
|
16839
17090
|
// src/scripts/runScheduledExecutableTick.ts
|
|
16840
|
-
import * as
|
|
16841
|
-
import * as
|
|
17091
|
+
import * as fs41 from "fs";
|
|
17092
|
+
import * as path40 from "path";
|
|
16842
17093
|
var runScheduledExecutableTick;
|
|
16843
17094
|
var init_runScheduledExecutableTick = __esm({
|
|
16844
17095
|
"src/scripts/runScheduledExecutableTick.ts"() {
|
|
@@ -16858,14 +17109,14 @@ var init_runScheduledExecutableTick = __esm({
|
|
|
16858
17109
|
ctx.output.reason = `runScheduledExecutableTick: args.slug or ctx.args.${slugArg} must be non-empty capability slug`;
|
|
16859
17110
|
return;
|
|
16860
17111
|
}
|
|
16861
|
-
const capability = resolveCapabilityFolder(slug2,
|
|
17112
|
+
const capability = resolveCapabilityFolder(slug2, path40.join(ctx.cwd, jobsDir));
|
|
16862
17113
|
if (!capability) {
|
|
16863
17114
|
ctx.output.exitCode = 99;
|
|
16864
17115
|
ctx.output.reason = `runScheduledExecutableTick: capability folder not found or incomplete: ${slug2} (searched ${jobsDir} and company store)`;
|
|
16865
17116
|
return;
|
|
16866
17117
|
}
|
|
16867
|
-
const shellPath =
|
|
16868
|
-
if (!
|
|
17118
|
+
const shellPath = path40.join(profile.dir, shell);
|
|
17119
|
+
if (!fs41.existsSync(shellPath)) {
|
|
16869
17120
|
ctx.output.exitCode = 99;
|
|
16870
17121
|
ctx.output.reason = `runScheduledExecutableTick: shell not found: ${shell} (looked in ${profile.dir})`;
|
|
16871
17122
|
return;
|
|
@@ -16896,8 +17147,8 @@ var init_runScheduledExecutableTick = __esm({
|
|
|
16896
17147
|
});
|
|
16897
17148
|
|
|
16898
17149
|
// src/scripts/runTickScript.ts
|
|
16899
|
-
import * as
|
|
16900
|
-
import * as
|
|
17150
|
+
import * as fs42 from "fs";
|
|
17151
|
+
import * as path41 from "path";
|
|
16901
17152
|
var runTickScript;
|
|
16902
17153
|
var init_runTickScript = __esm({
|
|
16903
17154
|
"src/scripts/runTickScript.ts"() {
|
|
@@ -16916,10 +17167,10 @@ var init_runTickScript = __esm({
|
|
|
16916
17167
|
ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
|
|
16917
17168
|
return;
|
|
16918
17169
|
}
|
|
16919
|
-
const capability = readCapabilityFolder(
|
|
17170
|
+
const capability = readCapabilityFolder(path41.join(ctx.cwd, jobsDir), slug2);
|
|
16920
17171
|
if (!capability) {
|
|
16921
17172
|
ctx.output.exitCode = 99;
|
|
16922
|
-
ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${
|
|
17173
|
+
ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path41.join(ctx.cwd, jobsDir, slug2)}`;
|
|
16923
17174
|
return;
|
|
16924
17175
|
}
|
|
16925
17176
|
const tickScript = capability.config.tickScript;
|
|
@@ -16928,8 +17179,8 @@ var init_runTickScript = __esm({
|
|
|
16928
17179
|
ctx.output.reason = `runTickScript: capability ${slug2} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
|
|
16929
17180
|
return;
|
|
16930
17181
|
}
|
|
16931
|
-
const scriptPath =
|
|
16932
|
-
if (!
|
|
17182
|
+
const scriptPath = path41.isAbsolute(tickScript) ? tickScript : path41.join(ctx.cwd, tickScript);
|
|
17183
|
+
if (!fs42.existsSync(scriptPath)) {
|
|
16933
17184
|
ctx.output.exitCode = 99;
|
|
16934
17185
|
ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
|
|
16935
17186
|
return;
|
|
@@ -17752,7 +18003,7 @@ var init_warmupMcp = __esm({
|
|
|
17752
18003
|
});
|
|
17753
18004
|
|
|
17754
18005
|
// src/scripts/writeAgentRunSummary.ts
|
|
17755
|
-
import * as
|
|
18006
|
+
import * as fs43 from "fs";
|
|
17756
18007
|
var writeAgentRunSummary;
|
|
17757
18008
|
var init_writeAgentRunSummary = __esm({
|
|
17758
18009
|
"src/scripts/writeAgentRunSummary.ts"() {
|
|
@@ -17778,7 +18029,7 @@ var init_writeAgentRunSummary = __esm({
|
|
|
17778
18029
|
if (reason) lines.push(`- **Reason:** ${reason}`);
|
|
17779
18030
|
lines.push("");
|
|
17780
18031
|
try {
|
|
17781
|
-
|
|
18032
|
+
fs43.appendFileSync(summaryPath, `${lines.join("\n")}
|
|
17782
18033
|
`);
|
|
17783
18034
|
} catch {
|
|
17784
18035
|
}
|
|
@@ -17917,6 +18168,7 @@ var init_scripts = __esm({
|
|
|
17917
18168
|
init_dispatchClassified();
|
|
17918
18169
|
init_dispatchNextTaskJob();
|
|
17919
18170
|
init_ensurePr();
|
|
18171
|
+
init_evaluateAgencyBoundaries();
|
|
17920
18172
|
init_failOnceTaskJob();
|
|
17921
18173
|
init_finalizeTerminal();
|
|
17922
18174
|
init_finishFlow();
|
|
@@ -18061,6 +18313,7 @@ var init_scripts = __esm({
|
|
|
18061
18313
|
stageMergeConflicts,
|
|
18062
18314
|
commitAndPush: commitAndPush2,
|
|
18063
18315
|
ensurePr: ensurePr2,
|
|
18316
|
+
evaluateAgencyBoundaries: evaluateAgencyBoundariesScript,
|
|
18064
18317
|
postAgentComment,
|
|
18065
18318
|
postIssueComment: postIssueComment2,
|
|
18066
18319
|
postPlanComment,
|
|
@@ -18100,53 +18353,53 @@ var init_scripts = __esm({
|
|
|
18100
18353
|
// src/stateWorkspace.ts
|
|
18101
18354
|
import { execFileSync as execFileSync24 } from "child_process";
|
|
18102
18355
|
import * as crypto3 from "crypto";
|
|
18103
|
-
import * as
|
|
18356
|
+
import * as fs44 from "fs";
|
|
18104
18357
|
import * as os7 from "os";
|
|
18105
|
-
import * as
|
|
18358
|
+
import * as path42 from "path";
|
|
18106
18359
|
function writeLocalFile(cwd, relativePath, content) {
|
|
18107
|
-
const fullPath =
|
|
18108
|
-
|
|
18109
|
-
|
|
18360
|
+
const fullPath = path42.join(cwd, relativePath);
|
|
18361
|
+
fs44.mkdirSync(path42.dirname(fullPath), { recursive: true });
|
|
18362
|
+
fs44.writeFileSync(fullPath, content);
|
|
18110
18363
|
}
|
|
18111
18364
|
function copyPath(source, target) {
|
|
18112
|
-
const st =
|
|
18113
|
-
|
|
18365
|
+
const st = fs44.lstatSync(source);
|
|
18366
|
+
fs44.rmSync(target, { recursive: true, force: true });
|
|
18114
18367
|
if (st.isSymbolicLink()) return;
|
|
18115
|
-
|
|
18116
|
-
|
|
18368
|
+
fs44.mkdirSync(path42.dirname(target), { recursive: true });
|
|
18369
|
+
fs44.cpSync(source, target, { recursive: true, force: true });
|
|
18117
18370
|
}
|
|
18118
18371
|
function overlayDirectoryChildren(cwd, sourceDir, localDir) {
|
|
18119
|
-
if (!
|
|
18120
|
-
for (const entry of
|
|
18121
|
-
const source =
|
|
18122
|
-
const target =
|
|
18372
|
+
if (!fs44.existsSync(sourceDir)) return;
|
|
18373
|
+
for (const entry of fs44.readdirSync(sourceDir, { withFileTypes: true })) {
|
|
18374
|
+
const source = path42.join(sourceDir, entry.name);
|
|
18375
|
+
const target = path42.join(cwd, localDir, entry.name);
|
|
18123
18376
|
copyPath(source, target);
|
|
18124
18377
|
}
|
|
18125
18378
|
}
|
|
18126
18379
|
function hydrateStateWorkspace(config, cwd) {
|
|
18127
18380
|
if (process.env.VITEST && process.env[TEST_FETCH_ENV] !== "1") return;
|
|
18128
18381
|
const parsed = parseStateRepo(config);
|
|
18129
|
-
const hydrateKey = `${
|
|
18382
|
+
const hydrateKey = `${path42.resolve(cwd)}|${parsed.owner}/${parsed.repo}|${parsed.basePath}|${parsed.branch}`;
|
|
18130
18383
|
if (hydratedWorkspaces.has(hydrateKey)) return;
|
|
18131
18384
|
const snapshotRoot = fetchStateSnapshot(parsed);
|
|
18132
18385
|
for (const mapping of DIR_MAPPINGS) {
|
|
18133
|
-
overlayDirectoryChildren(cwd,
|
|
18386
|
+
overlayDirectoryChildren(cwd, path42.join(snapshotRoot, mapping.stateDir), mapping.localDir);
|
|
18134
18387
|
}
|
|
18135
18388
|
for (const mapping of FILE_MAPPINGS) {
|
|
18136
|
-
const source =
|
|
18137
|
-
if (
|
|
18138
|
-
writeLocalFile(cwd, mapping.localPath,
|
|
18389
|
+
const source = path42.join(snapshotRoot, mapping.statePath);
|
|
18390
|
+
if (fs44.existsSync(source) && !fs44.lstatSync(source).isSymbolicLink() && fs44.statSync(source).isFile()) {
|
|
18391
|
+
writeLocalFile(cwd, mapping.localPath, fs44.readFileSync(source, "utf-8"));
|
|
18139
18392
|
}
|
|
18140
18393
|
}
|
|
18141
18394
|
hydratedWorkspaces.add(hydrateKey);
|
|
18142
18395
|
}
|
|
18143
18396
|
function fetchStateSnapshot(parsed) {
|
|
18144
|
-
const cacheDir =
|
|
18397
|
+
const cacheDir = path42.join(cacheRoot2(), cacheKey3(parsed));
|
|
18145
18398
|
const url = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
|
|
18146
18399
|
try {
|
|
18147
|
-
|
|
18148
|
-
if (!
|
|
18149
|
-
|
|
18400
|
+
fs44.mkdirSync(path42.dirname(cacheDir), { recursive: true });
|
|
18401
|
+
if (!fs44.existsSync(path42.join(cacheDir, ".git"))) {
|
|
18402
|
+
fs44.rmSync(cacheDir, { recursive: true, force: true });
|
|
18150
18403
|
runGit3(["clone", "--no-checkout", "--filter=blob:none", url, cacheDir]);
|
|
18151
18404
|
}
|
|
18152
18405
|
runGit3(["-C", cacheDir, "remote", "set-url", "origin", url]);
|
|
@@ -18161,10 +18414,10 @@ function fetchStateSnapshot(parsed) {
|
|
|
18161
18414
|
`stateWorkspace: failed to fetch ${parsed.owner}/${parsed.repo}:${parsed.basePath}@${parsed.branch}: ${msg}`
|
|
18162
18415
|
);
|
|
18163
18416
|
}
|
|
18164
|
-
return
|
|
18417
|
+
return path42.join(cacheDir, parsed.basePath);
|
|
18165
18418
|
}
|
|
18166
18419
|
function cacheRoot2() {
|
|
18167
|
-
return process.env[CACHE_ENV2]?.trim() ||
|
|
18420
|
+
return process.env[CACHE_ENV2]?.trim() || path42.join(os7.homedir(), ".cache", "kody", "state-repo");
|
|
18168
18421
|
}
|
|
18169
18422
|
function cacheKey3(parsed) {
|
|
18170
18423
|
return crypto3.createHash("sha256").update(`${parsed.owner}/${parsed.repo}#${parsed.branch}#${parsed.basePath}`).digest("hex").slice(0, 24);
|
|
@@ -18204,15 +18457,15 @@ var init_stateWorkspace = __esm({
|
|
|
18204
18457
|
"use strict";
|
|
18205
18458
|
init_stateRepo();
|
|
18206
18459
|
DIR_MAPPINGS = [
|
|
18207
|
-
{ stateDir: "capabilities", localDir:
|
|
18208
|
-
{ stateDir: "agents", localDir:
|
|
18209
|
-
{ stateDir: "context", localDir:
|
|
18210
|
-
{ stateDir: "memory", localDir:
|
|
18460
|
+
{ stateDir: "capabilities", localDir: path42.join(".kody", "capabilities") },
|
|
18461
|
+
{ stateDir: "agents", localDir: path42.join(".kody", "agents") },
|
|
18462
|
+
{ stateDir: "context", localDir: path42.join(".kody", "context") },
|
|
18463
|
+
{ stateDir: "memory", localDir: path42.join(".kody", "memory") }
|
|
18211
18464
|
];
|
|
18212
18465
|
FILE_MAPPINGS = [
|
|
18213
|
-
{ statePath: "instructions.md", localPath:
|
|
18214
|
-
{ statePath: "variables.json", localPath:
|
|
18215
|
-
{ statePath: "secrets.enc", localPath:
|
|
18466
|
+
{ statePath: "instructions.md", localPath: path42.join(".kody", "instructions.md") },
|
|
18467
|
+
{ statePath: "variables.json", localPath: path42.join(".kody", "variables.json") },
|
|
18468
|
+
{ statePath: "secrets.enc", localPath: path42.join(".kody", "secrets.enc") }
|
|
18216
18469
|
];
|
|
18217
18470
|
CACHE_ENV2 = "KODY_STATE_REPO_CACHE";
|
|
18218
18471
|
TEST_FETCH_ENV = "KODY_STATE_WORKSPACE_FETCH_FOR_TESTS";
|
|
@@ -18286,8 +18539,8 @@ var init_tools = __esm({
|
|
|
18286
18539
|
|
|
18287
18540
|
// src/executor.ts
|
|
18288
18541
|
import { spawn as spawn7 } from "child_process";
|
|
18289
|
-
import * as
|
|
18290
|
-
import * as
|
|
18542
|
+
import * as fs45 from "fs";
|
|
18543
|
+
import * as path43 from "path";
|
|
18291
18544
|
function isMutatingPostflight(scriptName) {
|
|
18292
18545
|
return MUTATING_POSTFLIGHTS.has(scriptName ?? "");
|
|
18293
18546
|
}
|
|
@@ -18468,7 +18721,7 @@ async function runExecutable(profileName, input) {
|
|
|
18468
18721
|
const jobWhyBlock = typeof ctx.data.jobWhy === "string" ? operatorRequestBlock(ctx.data.jobWhy) : null;
|
|
18469
18722
|
const jobRefBlock = jobReferenceBlock(profileName, profile, ctx.data);
|
|
18470
18723
|
const invokeAgent = async (prompt) => {
|
|
18471
|
-
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) =>
|
|
18724
|
+
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path43.isAbsolute(p) ? p : path43.resolve(profile.dir, p)).filter((p) => p.length > 0);
|
|
18472
18725
|
const syntheticPath = ctx.data.syntheticPluginPath;
|
|
18473
18726
|
const pluginPaths = [...externalPlugins, ...syntheticPath ? [syntheticPath] : []];
|
|
18474
18727
|
const agents = loadSubagents(profile);
|
|
@@ -18861,17 +19114,17 @@ function clearStampedLifecycleLabels(profile, ctx) {
|
|
|
18861
19114
|
function resolveProfilePath(profileName) {
|
|
18862
19115
|
const found = resolveExecutable(profileName);
|
|
18863
19116
|
if (found) return found;
|
|
18864
|
-
const here =
|
|
19117
|
+
const here = path43.dirname(new URL(import.meta.url).pathname);
|
|
18865
19118
|
const candidates = [
|
|
18866
|
-
|
|
19119
|
+
path43.join(here, "executables", profileName, "profile.json"),
|
|
18867
19120
|
// same-dir sibling (dev)
|
|
18868
|
-
|
|
19121
|
+
path43.join(here, "..", "executables", profileName, "profile.json"),
|
|
18869
19122
|
// up one (prod: dist/bin → dist/executables)
|
|
18870
|
-
|
|
19123
|
+
path43.join(here, "..", "src", "executables", profileName, "profile.json")
|
|
18871
19124
|
// fallback
|
|
18872
19125
|
];
|
|
18873
19126
|
for (const c of candidates) {
|
|
18874
|
-
if (
|
|
19127
|
+
if (fs45.existsSync(c)) return c;
|
|
18875
19128
|
}
|
|
18876
19129
|
return candidates[0];
|
|
18877
19130
|
}
|
|
@@ -18986,8 +19239,8 @@ function resolveShellTimeoutMs(entry) {
|
|
|
18986
19239
|
}
|
|
18987
19240
|
async function runShellEntry(entry, ctx, profile) {
|
|
18988
19241
|
const shellName = entry.shell;
|
|
18989
|
-
const shellPath =
|
|
18990
|
-
if (!
|
|
19242
|
+
const shellPath = path43.join(profile.dir, shellName);
|
|
19243
|
+
if (!fs45.existsSync(shellPath)) {
|
|
18991
19244
|
ctx.skipAgent = true;
|
|
18992
19245
|
ctx.output.exitCode = 99;
|
|
18993
19246
|
ctx.output.reason = `shell script not found: ${shellName} (looked in ${profile.dir})`;
|
|
@@ -19137,8 +19390,8 @@ var init_executor = __esm({
|
|
|
19137
19390
|
});
|
|
19138
19391
|
|
|
19139
19392
|
// src/workflowDefinitions.ts
|
|
19140
|
-
import * as
|
|
19141
|
-
import * as
|
|
19393
|
+
import * as fs46 from "fs";
|
|
19394
|
+
import * as path44 from "path";
|
|
19142
19395
|
function isWorkflowDefinitionId(value) {
|
|
19143
19396
|
return WORKFLOW_ID_PATTERN.test(value);
|
|
19144
19397
|
}
|
|
@@ -19152,13 +19405,11 @@ function normalizeWorkflowDefinition(value) {
|
|
|
19152
19405
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
19153
19406
|
const raw = value;
|
|
19154
19407
|
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
19155
|
-
const instructions = typeof raw.instructions === "string" ? raw.instructions.trim() : "";
|
|
19156
19408
|
const capabilities = normalizeWorkflowCapabilities(raw.capabilities);
|
|
19157
|
-
if (!name ||
|
|
19409
|
+
if (!name || capabilities.length === 0) return null;
|
|
19158
19410
|
return {
|
|
19159
19411
|
version: 1,
|
|
19160
19412
|
name,
|
|
19161
|
-
instructions,
|
|
19162
19413
|
capabilities,
|
|
19163
19414
|
...typeof raw.createdAt === "string" ? { createdAt: raw.createdAt } : {},
|
|
19164
19415
|
...typeof raw.updatedAt === "string" ? { updatedAt: raw.updatedAt } : {}
|
|
@@ -19172,17 +19423,17 @@ function readWorkflowDefinition(config, cwd, id) {
|
|
|
19172
19423
|
function workflowDefinitionToCapabilityFolder(id, workflow, source = workflowDefinitionPath(id)) {
|
|
19173
19424
|
return {
|
|
19174
19425
|
slug: id,
|
|
19175
|
-
dir:
|
|
19426
|
+
dir: path44.dirname(source),
|
|
19176
19427
|
profilePath: source,
|
|
19177
19428
|
bodyPath: source,
|
|
19178
19429
|
title: workflow.name,
|
|
19179
|
-
body:
|
|
19180
|
-
rawBody:
|
|
19430
|
+
body: "",
|
|
19431
|
+
rawBody: "",
|
|
19181
19432
|
rawProfile: { name: id, workflow },
|
|
19182
19433
|
config: {
|
|
19183
19434
|
action: id,
|
|
19184
19435
|
workflow: workflowDefinitionToConfig(workflow),
|
|
19185
|
-
describe: workflow.
|
|
19436
|
+
describe: workflow.name
|
|
19186
19437
|
}
|
|
19187
19438
|
};
|
|
19188
19439
|
}
|
|
@@ -19207,9 +19458,9 @@ function workflowDefinitionToConfig(workflow) {
|
|
|
19207
19458
|
function readCompanyStoreWorkflowDefinition(id) {
|
|
19208
19459
|
const root = getCompanyStoreAssetRoot("workflows");
|
|
19209
19460
|
if (!root) return null;
|
|
19210
|
-
const filePath =
|
|
19211
|
-
if (!
|
|
19212
|
-
return parseWorkflowDefinition(
|
|
19461
|
+
const filePath = path44.join(root, id, "workflow.json");
|
|
19462
|
+
if (!fs46.existsSync(filePath)) return null;
|
|
19463
|
+
return parseWorkflowDefinition(fs46.readFileSync(filePath, "utf8"));
|
|
19213
19464
|
}
|
|
19214
19465
|
function parseWorkflowDefinition(content) {
|
|
19215
19466
|
try {
|
|
@@ -19241,7 +19492,7 @@ __export(job_exports, {
|
|
|
19241
19492
|
stableJobKey: () => stableJobKey,
|
|
19242
19493
|
validateJob: () => validateJob
|
|
19243
19494
|
});
|
|
19244
|
-
import * as
|
|
19495
|
+
import * as path45 from "path";
|
|
19245
19496
|
function newJobId(flavor) {
|
|
19246
19497
|
localJobSeq += 1;
|
|
19247
19498
|
const runId = process.env.GITHUB_RUN_ID;
|
|
@@ -19293,7 +19544,7 @@ function parseCapabilityResultTarget(raw) {
|
|
|
19293
19544
|
async function runJob(job, base) {
|
|
19294
19545
|
const valid = validateJob(job);
|
|
19295
19546
|
const action = valid.action ?? valid.capability;
|
|
19296
|
-
const projectCapabilitiesRoot =
|
|
19547
|
+
const projectCapabilitiesRoot = path45.join(base.cwd, ".kody", "capabilities");
|
|
19297
19548
|
const resolvedCapability = !valid.workflow && action ? resolveCapabilityAction(action, projectCapabilitiesRoot) : null;
|
|
19298
19549
|
const capabilityIdentity = valid.capability ?? resolvedCapability?.capability;
|
|
19299
19550
|
const capabilityContext = valid.workflow ? null : loadCapabilityContext(capabilityIdentity, base.cwd);
|
|
@@ -19306,7 +19557,7 @@ async function runJob(job, base) {
|
|
|
19306
19557
|
}
|
|
19307
19558
|
const workflow = capabilityContext?.config.workflow ?? workflowContext?.config.workflow;
|
|
19308
19559
|
const workflowIdentity = valid.workflow ?? capabilityIdentity ?? workflowContext?.slug;
|
|
19309
|
-
const capabilitySelectedExecutable = resolvedCapability?.executable ?? capabilityContext?.config.executable ?? capabilityContext?.config.executables?.[0] ?? (capabilityContext?.config.role ? capabilityContext.slug : void 0) ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
|
|
19560
|
+
const capabilitySelectedExecutable = resolvedCapability?.executable ?? capabilityContext?.config.implementation ?? capabilityContext?.config.executable ?? capabilityContext?.config.executables?.[0] ?? (capabilityContext?.config.role ? capabilityContext.slug : void 0) ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
|
|
19310
19561
|
const profileName = valid.executable ?? capabilitySelectedExecutable;
|
|
19311
19562
|
if (workflow && shouldRunCapabilityWorkflow(valid, workflow, workflowIdentity, capabilitySelectedExecutable, base)) {
|
|
19312
19563
|
const workflowCapability = capabilityContext ?? workflowContext;
|
|
@@ -19479,7 +19730,7 @@ function shouldRunWorkflowStep(step, data) {
|
|
|
19479
19730
|
if (!step.runWhen) return true;
|
|
19480
19731
|
const context = workflowConditionContext(data);
|
|
19481
19732
|
return Object.entries(step.runWhen).every(
|
|
19482
|
-
([
|
|
19733
|
+
([path51, expected]) => valueMatches(resolveDottedPath2(context, path51), expected)
|
|
19483
19734
|
);
|
|
19484
19735
|
}
|
|
19485
19736
|
function canContinueWorkflow(step, outcome) {
|
|
@@ -19549,7 +19800,7 @@ function composeStepWhy(parentWhy, step) {
|
|
|
19549
19800
|
}
|
|
19550
19801
|
function loadCapabilityContext(slug2, cwd) {
|
|
19551
19802
|
if (!slug2) return null;
|
|
19552
|
-
return resolveCapabilityFolder(slug2,
|
|
19803
|
+
return resolveCapabilityFolder(slug2, path45.join(cwd, ".kody", "capabilities"));
|
|
19553
19804
|
}
|
|
19554
19805
|
function loadWorkflowContext(slug2, base) {
|
|
19555
19806
|
if (!slug2 || !base.config || !isWorkflowDefinitionId(slug2)) return null;
|
|
@@ -19707,9 +19958,9 @@ function translateOpenAISseToBrain(opts) {
|
|
|
19707
19958
|
}
|
|
19708
19959
|
|
|
19709
19960
|
// src/servers/brain-serve.ts
|
|
19710
|
-
import * as
|
|
19961
|
+
import * as fs49 from "fs";
|
|
19711
19962
|
import { createServer as createServer2 } from "http";
|
|
19712
|
-
import * as
|
|
19963
|
+
import * as path48 from "path";
|
|
19713
19964
|
|
|
19714
19965
|
// src/chat/loop.ts
|
|
19715
19966
|
init_agent();
|
|
@@ -20385,8 +20636,8 @@ init_config();
|
|
|
20385
20636
|
|
|
20386
20637
|
// src/kody-cli.ts
|
|
20387
20638
|
import { execFileSync as execFileSync26 } from "child_process";
|
|
20388
|
-
import * as
|
|
20389
|
-
import * as
|
|
20639
|
+
import * as fs47 from "fs";
|
|
20640
|
+
import * as path46 from "path";
|
|
20390
20641
|
|
|
20391
20642
|
// src/app-auth.ts
|
|
20392
20643
|
import { createSign } from "crypto";
|
|
@@ -20889,6 +21140,7 @@ init_gha();
|
|
|
20889
21140
|
init_issue();
|
|
20890
21141
|
init_job();
|
|
20891
21142
|
init_lifecycleLabels();
|
|
21143
|
+
init_companyStore();
|
|
20892
21144
|
init_registry();
|
|
20893
21145
|
|
|
20894
21146
|
// src/run-request.ts
|
|
@@ -20959,6 +21211,9 @@ var FAILED_DISPATCH_LABEL = {
|
|
|
20959
21211
|
color: "e11d21",
|
|
20960
21212
|
description: "Kody failed or rejected the run"
|
|
20961
21213
|
};
|
|
21214
|
+
function objectValue2(value) {
|
|
21215
|
+
return value && typeof value === "object" ? value : void 0;
|
|
21216
|
+
}
|
|
20962
21217
|
var CI_HELP = `kody ci \u2014 minimal-YAML autonomous engineer (CI preflight + run)
|
|
20963
21218
|
|
|
20964
21219
|
Usage:
|
|
@@ -21116,9 +21371,9 @@ async function resolveAuthToken(env = process.env) {
|
|
|
21116
21371
|
return void 0;
|
|
21117
21372
|
}
|
|
21118
21373
|
function detectPackageManager2(cwd) {
|
|
21119
|
-
if (
|
|
21120
|
-
if (
|
|
21121
|
-
if (
|
|
21374
|
+
if (fs47.existsSync(path46.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
21375
|
+
if (fs47.existsSync(path46.join(cwd, "yarn.lock"))) return "yarn";
|
|
21376
|
+
if (fs47.existsSync(path46.join(cwd, "bun.lockb"))) return "bun";
|
|
21122
21377
|
return "npm";
|
|
21123
21378
|
}
|
|
21124
21379
|
function shouldChainScheduledWatch(match) {
|
|
@@ -21211,8 +21466,8 @@ function postFailureTail(issueNumber, cwd, reason) {
|
|
|
21211
21466
|
const logPath = lastRunLogPath(cwd);
|
|
21212
21467
|
let tail = "";
|
|
21213
21468
|
try {
|
|
21214
|
-
if (
|
|
21215
|
-
const content =
|
|
21469
|
+
if (fs47.existsSync(logPath)) {
|
|
21470
|
+
const content = fs47.readFileSync(logPath, "utf-8");
|
|
21216
21471
|
tail = content.slice(-3e3);
|
|
21217
21472
|
}
|
|
21218
21473
|
} catch {
|
|
@@ -21241,7 +21496,7 @@ async function runCi(argv) {
|
|
|
21241
21496
|
return 0;
|
|
21242
21497
|
}
|
|
21243
21498
|
const args = parseCiArgs(argv);
|
|
21244
|
-
const cwd = args.cwd ?
|
|
21499
|
+
const cwd = args.cwd ? path46.resolve(args.cwd) : process.cwd();
|
|
21245
21500
|
let earlyConfig;
|
|
21246
21501
|
let earlyConfigError;
|
|
21247
21502
|
try {
|
|
@@ -21264,6 +21519,9 @@ async function runCi(argv) {
|
|
|
21264
21519
|
`);
|
|
21265
21520
|
return 64;
|
|
21266
21521
|
}
|
|
21522
|
+
if (parsedRunRequest && "request" in parsedRunRequest) {
|
|
21523
|
+
applyCompanyStoreRuntimeConfig(parsedRunRequest.request.input);
|
|
21524
|
+
}
|
|
21267
21525
|
if (!args.issueNumber && !autoFallback && parsedRunRequest && "request" in parsedRunRequest) {
|
|
21268
21526
|
const route = routeRunRequest(parsedRunRequest.request);
|
|
21269
21527
|
if (route.kind === "error") {
|
|
@@ -21287,13 +21545,15 @@ async function runCi(argv) {
|
|
|
21287
21545
|
forceRunCliArgs = { goal: envForceMessage };
|
|
21288
21546
|
}
|
|
21289
21547
|
}
|
|
21290
|
-
if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath &&
|
|
21548
|
+
if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs47.existsSync(dispatchEventPath)) {
|
|
21291
21549
|
try {
|
|
21292
|
-
const evt = JSON.parse(
|
|
21293
|
-
const
|
|
21294
|
-
|
|
21295
|
-
const
|
|
21296
|
-
const
|
|
21550
|
+
const evt = JSON.parse(fs47.readFileSync(dispatchEventPath, "utf-8"));
|
|
21551
|
+
const inputs = objectValue2(evt.inputs);
|
|
21552
|
+
applyCompanyStoreRuntimeConfig(inputs);
|
|
21553
|
+
const issueInput = parseInt(String(inputs?.issue_number ?? ""), 10);
|
|
21554
|
+
const sessionInput = String(inputs?.sessionId ?? "");
|
|
21555
|
+
const capabilityInput = String(inputs?.capability ?? inputs?.executable ?? "").trim();
|
|
21556
|
+
const messageInput = String(inputs?.message ?? "").trim();
|
|
21297
21557
|
const noTarget = !sessionInput && !(Number.isFinite(issueInput) && issueInput > 0);
|
|
21298
21558
|
if (noTarget && capabilityInput) {
|
|
21299
21559
|
forceRunAction = capabilityInput;
|
|
@@ -21651,8 +21911,8 @@ init_repoWorkspace();
|
|
|
21651
21911
|
|
|
21652
21912
|
// src/scripts/brainTurnLog.ts
|
|
21653
21913
|
init_runtimePaths();
|
|
21654
|
-
import * as
|
|
21655
|
-
import * as
|
|
21914
|
+
import * as fs48 from "fs";
|
|
21915
|
+
import * as path47 from "path";
|
|
21656
21916
|
import posixPath4 from "path/posix";
|
|
21657
21917
|
var live = /* @__PURE__ */ new Map();
|
|
21658
21918
|
function brainEventsFilePath(dir, chatId) {
|
|
@@ -21663,8 +21923,8 @@ function brainEventsStatePath(chatId) {
|
|
|
21663
21923
|
}
|
|
21664
21924
|
function lastPersistedSeq(dir, chatId) {
|
|
21665
21925
|
const p = brainEventsFilePath(dir, chatId);
|
|
21666
|
-
if (!
|
|
21667
|
-
const lines =
|
|
21926
|
+
if (!fs48.existsSync(p)) return 0;
|
|
21927
|
+
const lines = fs48.readFileSync(p, "utf-8").split("\n").filter(Boolean);
|
|
21668
21928
|
if (lines.length === 0) return 0;
|
|
21669
21929
|
try {
|
|
21670
21930
|
return JSON.parse(lines[lines.length - 1]).seq || 0;
|
|
@@ -21674,9 +21934,9 @@ function lastPersistedSeq(dir, chatId) {
|
|
|
21674
21934
|
}
|
|
21675
21935
|
function readSince(dir, chatId, since) {
|
|
21676
21936
|
const p = brainEventsFilePath(dir, chatId);
|
|
21677
|
-
if (!
|
|
21937
|
+
if (!fs48.existsSync(p)) return [];
|
|
21678
21938
|
const out = [];
|
|
21679
|
-
for (const line of
|
|
21939
|
+
for (const line of fs48.readFileSync(p, "utf-8").split("\n")) {
|
|
21680
21940
|
if (!line) continue;
|
|
21681
21941
|
try {
|
|
21682
21942
|
const rec = JSON.parse(line);
|
|
@@ -21702,12 +21962,12 @@ function beginTurn(dir, chatId) {
|
|
|
21702
21962
|
};
|
|
21703
21963
|
live.set(chatId, state);
|
|
21704
21964
|
const p = brainEventsFilePath(dir, chatId);
|
|
21705
|
-
|
|
21965
|
+
fs48.mkdirSync(path47.dirname(p), { recursive: true });
|
|
21706
21966
|
return (event) => {
|
|
21707
21967
|
state.seq += 1;
|
|
21708
21968
|
const rec = { seq: state.seq, turn, ts: Date.now(), event };
|
|
21709
21969
|
try {
|
|
21710
|
-
|
|
21970
|
+
fs48.appendFileSync(p, `${JSON.stringify(rec)}
|
|
21711
21971
|
`);
|
|
21712
21972
|
} catch (err) {
|
|
21713
21973
|
process.stderr.write(
|
|
@@ -21746,7 +22006,7 @@ function endTurnIfUnterminated(dir, chatId, errMessage) {
|
|
|
21746
22006
|
event: { type: "error", error: errMessage || "turn ended unexpectedly", chatId }
|
|
21747
22007
|
};
|
|
21748
22008
|
try {
|
|
21749
|
-
|
|
22009
|
+
fs48.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
|
|
21750
22010
|
`);
|
|
21751
22011
|
} catch {
|
|
21752
22012
|
}
|
|
@@ -22070,7 +22330,7 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22070
22330
|
);
|
|
22071
22331
|
}
|
|
22072
22332
|
}
|
|
22073
|
-
|
|
22333
|
+
fs49.mkdirSync(path48.dirname(sessionFile), { recursive: true });
|
|
22074
22334
|
appendTurn(sessionFile, {
|
|
22075
22335
|
role: "user",
|
|
22076
22336
|
content: message,
|
|
@@ -22145,7 +22405,7 @@ async function handleChatTurn(req, res, chatId, opts) {
|
|
|
22145
22405
|
function buildServer(opts) {
|
|
22146
22406
|
const runTurn = opts.runTurn ?? runChatTurn;
|
|
22147
22407
|
const cloneRepo = opts.cloneRepo ?? defaultCloneRepo;
|
|
22148
|
-
const reposRoot = opts.reposRoot ??
|
|
22408
|
+
const reposRoot = opts.reposRoot ?? path48.join(path48.dirname(path48.resolve(opts.cwd)), "repos");
|
|
22149
22409
|
return createServer2(async (req, res) => {
|
|
22150
22410
|
if (!req.method || !req.url) {
|
|
22151
22411
|
sendJson(res, 400, { error: "bad request" });
|
|
@@ -22748,8 +23008,8 @@ async function loadConfigSafe() {
|
|
|
22748
23008
|
}
|
|
22749
23009
|
|
|
22750
23010
|
// src/chat-cli.ts
|
|
22751
|
-
import * as
|
|
22752
|
-
import * as
|
|
23011
|
+
import * as fs51 from "fs";
|
|
23012
|
+
import * as path50 from "path";
|
|
22753
23013
|
|
|
22754
23014
|
// src/chat/inbox.ts
|
|
22755
23015
|
import { execFileSync as execFileSync27 } from "child_process";
|
|
@@ -22821,8 +23081,8 @@ function currentBranch(cwd) {
|
|
|
22821
23081
|
|
|
22822
23082
|
// src/chat/state-sync.ts
|
|
22823
23083
|
init_stateRepo();
|
|
22824
|
-
import * as
|
|
22825
|
-
import * as
|
|
23084
|
+
import * as fs50 from "fs";
|
|
23085
|
+
import * as path49 from "path";
|
|
22826
23086
|
function jsonlLines2(text) {
|
|
22827
23087
|
return text.split("\n").filter((line) => line.length > 0);
|
|
22828
23088
|
}
|
|
@@ -22839,15 +23099,15 @@ function mergeJsonl2(localText, remoteText) {
|
|
|
22839
23099
|
function syncJsonlFileFromState(opts) {
|
|
22840
23100
|
const remote = readStateText(opts.config, opts.cwd, opts.statePath);
|
|
22841
23101
|
if (!remote) return;
|
|
22842
|
-
const local =
|
|
23102
|
+
const local = fs50.existsSync(opts.localPath) ? fs50.readFileSync(opts.localPath, "utf-8") : "";
|
|
22843
23103
|
const next = mergeJsonl2(local, remote.content);
|
|
22844
23104
|
if (next === local) return;
|
|
22845
|
-
|
|
22846
|
-
|
|
23105
|
+
fs50.mkdirSync(path49.dirname(opts.localPath), { recursive: true });
|
|
23106
|
+
fs50.writeFileSync(opts.localPath, next);
|
|
22847
23107
|
}
|
|
22848
23108
|
function persistJsonlFileToState(opts) {
|
|
22849
|
-
if (!
|
|
22850
|
-
const localText =
|
|
23109
|
+
if (!fs50.existsSync(opts.localPath)) return;
|
|
23110
|
+
const localText = fs50.readFileSync(opts.localPath, "utf-8");
|
|
22851
23111
|
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
22852
23112
|
const remote = readStateText(opts.config, opts.cwd, opts.statePath);
|
|
22853
23113
|
const body = mergeJsonl2(localText, remote?.content ?? "");
|
|
@@ -23031,6 +23291,7 @@ async function emit2(sink, type, sessionId, suffix, payload) {
|
|
|
23031
23291
|
init_config();
|
|
23032
23292
|
init_litellm();
|
|
23033
23293
|
init_stateWorkspace();
|
|
23294
|
+
init_companyStore();
|
|
23034
23295
|
var DEFAULT_MODEL2 = "claude/claude-haiku-4-5-20251001";
|
|
23035
23296
|
var CHAT_HELP = `kody chat \u2014 dashboard-driven chat session
|
|
23036
23297
|
|
|
@@ -23111,8 +23372,12 @@ async function runChat(argv) {
|
|
|
23111
23372
|
${CHAT_HELP}`);
|
|
23112
23373
|
return 64;
|
|
23113
23374
|
}
|
|
23114
|
-
const cwd = args.cwd ?
|
|
23375
|
+
const cwd = args.cwd ? path50.resolve(args.cwd) : process.cwd();
|
|
23115
23376
|
const sessionId = args.sessionId;
|
|
23377
|
+
const runRequest = readRunRequestFromEnv();
|
|
23378
|
+
if (runRequest && "request" in runRequest) {
|
|
23379
|
+
applyCompanyStoreRuntimeConfig(runRequest.request.input);
|
|
23380
|
+
}
|
|
23116
23381
|
const unpackedSecrets = unpackAllSecrets();
|
|
23117
23382
|
if (unpackedSecrets > 0) {
|
|
23118
23383
|
process.stdout.write(`\u2192 kody: unpacked ${unpackedSecrets} secret(s) from ALL_SECRETS
|
|
@@ -23172,7 +23437,7 @@ ${CHAT_HELP}`);
|
|
|
23172
23437
|
const sink = buildSink(cwd, sessionId, args.dashboardUrl);
|
|
23173
23438
|
const meta = readMeta(sessionFile);
|
|
23174
23439
|
process.stdout.write(
|
|
23175
|
-
`\u2192 kody:chat: session file=${sessionFile} exists=${
|
|
23440
|
+
`\u2192 kody:chat: session file=${sessionFile} exists=${fs51.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
|
|
23176
23441
|
`
|
|
23177
23442
|
);
|
|
23178
23443
|
try {
|
|
@@ -23302,8 +23567,8 @@ var FlyClient = class {
|
|
|
23302
23567
|
get fetch() {
|
|
23303
23568
|
return this.opts.fetchImpl ?? fetch;
|
|
23304
23569
|
}
|
|
23305
|
-
async call(
|
|
23306
|
-
const res = await this.fetch(`${FLY_API_BASE}${
|
|
23570
|
+
async call(path51, init = {}) {
|
|
23571
|
+
const res = await this.fetch(`${FLY_API_BASE}${path51}`, {
|
|
23307
23572
|
method: init.method ?? "GET",
|
|
23308
23573
|
headers: {
|
|
23309
23574
|
Authorization: `Bearer ${this.opts.token}`,
|
|
@@ -23314,7 +23579,7 @@ var FlyClient = class {
|
|
|
23314
23579
|
if (res.status === 404 && init.allow404) return null;
|
|
23315
23580
|
if (!res.ok) {
|
|
23316
23581
|
const text = await res.text().catch(() => "");
|
|
23317
|
-
throw new Error(`Fly API ${res.status} on ${
|
|
23582
|
+
throw new Error(`Fly API ${res.status} on ${path51}: ${text.slice(0, 200) || res.statusText}`);
|
|
23318
23583
|
}
|
|
23319
23584
|
if (res.status === 204) return null;
|
|
23320
23585
|
const raw = await res.text();
|
|
@@ -24032,7 +24297,7 @@ async function poolServe() {
|
|
|
24032
24297
|
|
|
24033
24298
|
// src/servers/runner-serve.ts
|
|
24034
24299
|
import { spawn as spawn8 } from "child_process";
|
|
24035
|
-
import * as
|
|
24300
|
+
import * as fs52 from "fs";
|
|
24036
24301
|
import { createServer as createServer6 } from "http";
|
|
24037
24302
|
var DEFAULT_PORT2 = 8080;
|
|
24038
24303
|
var DEFAULT_WORKDIR = "/workspace/repo";
|
|
@@ -24167,8 +24432,8 @@ async function defaultRunJob(job) {
|
|
|
24167
24432
|
const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
|
|
24168
24433
|
const branch = job.ref ?? "main";
|
|
24169
24434
|
const authUrl = `https://x-access-token:${job.githubToken}@github.com/${job.repo}.git`;
|
|
24170
|
-
|
|
24171
|
-
|
|
24435
|
+
fs52.rmSync(workdir, { recursive: true, force: true });
|
|
24436
|
+
fs52.mkdirSync(workdir, { recursive: true });
|
|
24172
24437
|
const allSecrets = typeof job.allSecrets === "string" ? job.allSecrets : JSON.stringify(job.allSecrets ?? {});
|
|
24173
24438
|
const target = job.runRequest.target;
|
|
24174
24439
|
const interactive = target.type === "chat";
|