@kody-ade/kody-engine 0.4.547 → 0.4.549
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
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.549",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -2093,11 +2093,13 @@ function parseWorkflowStep(value) {
|
|
|
2093
2093
|
const delivery = stringField(raw.delivery);
|
|
2094
2094
|
const targetFact = stringField(raw.targetFact ?? raw.target_fact);
|
|
2095
2095
|
const hasInput = Object.hasOwn(raw, "input");
|
|
2096
|
+
const inputs = parseWorkflowInputBindings(raw.inputs);
|
|
2096
2097
|
const next = parseWorkflowTransitions(raw.next);
|
|
2097
2098
|
const report = parseReportPublication(raw.report);
|
|
2098
2099
|
return {
|
|
2099
2100
|
capability,
|
|
2100
2101
|
...hasInput ? { input: raw.input } : {},
|
|
2102
|
+
...inputs ? { inputs } : {},
|
|
2101
2103
|
...id && isSafeStepId(id) ? { id } : {},
|
|
2102
2104
|
...action && isSafeSlug(action) ? { action } : {},
|
|
2103
2105
|
...evidence ? { evidence } : {},
|
|
@@ -2112,6 +2114,15 @@ function parseWorkflowStep(value) {
|
|
|
2112
2114
|
...report ? { report } : {}
|
|
2113
2115
|
};
|
|
2114
2116
|
}
|
|
2117
|
+
function parseWorkflowInputBindings(value) {
|
|
2118
|
+
if (!isPlainObject(value)) return void 0;
|
|
2119
|
+
const entries = Object.entries(value).flatMap(([name, binding]) => {
|
|
2120
|
+
if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(name) || !isPlainObject(binding)) return [];
|
|
2121
|
+
const from = stringField(binding.from);
|
|
2122
|
+
return from ? [[name, { from }]] : [];
|
|
2123
|
+
});
|
|
2124
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
2125
|
+
}
|
|
2115
2126
|
function parseWorkflowTransitions(value) {
|
|
2116
2127
|
const rawTransitions = Array.isArray(value) ? value : value === void 0 ? [] : [value];
|
|
2117
2128
|
const transitions = rawTransitions.map((raw) => {
|
|
@@ -4448,6 +4459,15 @@ function validateWorkflow(value, options = {}) {
|
|
|
4448
4459
|
if (step.input !== void 0 && !isJsonValue(step.input)) {
|
|
4449
4460
|
issue(issues, "invalid_input", `${base}.input`, "workflow step input must be one JSON value");
|
|
4450
4461
|
}
|
|
4462
|
+
if (step.input !== void 0 && step.inputs !== void 0) {
|
|
4463
|
+
issue(issues, "conflicting_inputs", base, "workflow step cannot declare both input and inputs");
|
|
4464
|
+
}
|
|
4465
|
+
validateInputBindings(
|
|
4466
|
+
step.inputs,
|
|
4467
|
+
`${base}.inputs`,
|
|
4468
|
+
issues,
|
|
4469
|
+
capability ? options.capabilityInputs?.get(capability) : void 0
|
|
4470
|
+
);
|
|
4451
4471
|
});
|
|
4452
4472
|
if (!graphMode) return issues;
|
|
4453
4473
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -4461,11 +4481,24 @@ function validateWorkflow(value, options = {}) {
|
|
|
4461
4481
|
}
|
|
4462
4482
|
const adjacency = /* @__PURE__ */ new Map();
|
|
4463
4483
|
const explicitEndSources = /* @__PURE__ */ new Set();
|
|
4484
|
+
const capabilitiesByStep = /* @__PURE__ */ new Map();
|
|
4485
|
+
steps.forEach((step) => {
|
|
4486
|
+
const id = text(step?.id);
|
|
4487
|
+
const capability = text(step?.capability ?? step?.action);
|
|
4488
|
+
if (id && capability) capabilitiesByStep.set(id, capability);
|
|
4489
|
+
});
|
|
4464
4490
|
steps.forEach((step, index) => {
|
|
4465
4491
|
if (!step) return;
|
|
4466
4492
|
const id = text(step.id);
|
|
4467
4493
|
if (!id) return;
|
|
4468
4494
|
const sourceCapability = text(step.capability ?? step.action);
|
|
4495
|
+
validateInputBindingSources(
|
|
4496
|
+
step.inputs,
|
|
4497
|
+
`steps[${index}].inputs`,
|
|
4498
|
+
issues,
|
|
4499
|
+
capabilitiesByStep,
|
|
4500
|
+
options.capabilityOutputs
|
|
4501
|
+
);
|
|
4469
4502
|
const transitions = transitionList(step.next);
|
|
4470
4503
|
adjacency.set(id, []);
|
|
4471
4504
|
if (transitions.length > maxTransitions) {
|
|
@@ -4581,6 +4614,63 @@ function validateWorkflow(value, options = {}) {
|
|
|
4581
4614
|
}
|
|
4582
4615
|
return issues;
|
|
4583
4616
|
}
|
|
4617
|
+
function validateInputBindings(value, path53, issues, declaredInputs) {
|
|
4618
|
+
if (value === void 0) return;
|
|
4619
|
+
const bindings = asRecord(value);
|
|
4620
|
+
if (!bindings || Object.keys(bindings).length === 0) {
|
|
4621
|
+
issue(issues, "invalid_inputs", path53, "workflow step inputs must contain at least one named mapping");
|
|
4622
|
+
return;
|
|
4623
|
+
}
|
|
4624
|
+
for (const [name, value2] of Object.entries(bindings)) {
|
|
4625
|
+
const bindingPath = `${path53}.${name}`;
|
|
4626
|
+
if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(name)) {
|
|
4627
|
+
issue(issues, "invalid_input_name", bindingPath, `workflow input name ${name} is invalid`);
|
|
4628
|
+
}
|
|
4629
|
+
if (declaredInputs && !declaredInputs.has(name)) {
|
|
4630
|
+
issue(issues, "undeclared_input", bindingPath, `target capability does not declare input ${name}`);
|
|
4631
|
+
}
|
|
4632
|
+
const binding = asRecord(value2);
|
|
4633
|
+
const from = text(binding?.from);
|
|
4634
|
+
if (!binding || Object.keys(binding).some((field) => field !== "from") || !from || !SAFE_INPUT_SOURCE.test(from)) {
|
|
4635
|
+
issue(
|
|
4636
|
+
issues,
|
|
4637
|
+
"invalid_input_source",
|
|
4638
|
+
`${bindingPath}.from`,
|
|
4639
|
+
"workflow input mapping must read from workflow input/state or a prior step result"
|
|
4640
|
+
);
|
|
4641
|
+
}
|
|
4642
|
+
}
|
|
4643
|
+
}
|
|
4644
|
+
function validateInputBindingSources(value, path53, issues, capabilitiesByStep, capabilityOutputs) {
|
|
4645
|
+
const bindings = asRecord(value);
|
|
4646
|
+
if (!bindings) return;
|
|
4647
|
+
for (const [name, rawBinding] of Object.entries(bindings)) {
|
|
4648
|
+
const from = text(asRecord(rawBinding)?.from);
|
|
4649
|
+
if (!from?.startsWith("steps.")) continue;
|
|
4650
|
+
const parts = from.split(".");
|
|
4651
|
+
const sourceStep = parts[1];
|
|
4652
|
+
const sourceCapability = sourceStep ? capabilitiesByStep.get(sourceStep) : void 0;
|
|
4653
|
+
if (!sourceStep || !sourceCapability) {
|
|
4654
|
+
issue(
|
|
4655
|
+
issues,
|
|
4656
|
+
"missing_input_step",
|
|
4657
|
+
`${path53}.${name}.from`,
|
|
4658
|
+
`workflow input mapping references missing step ${sourceStep ?? "<none>"}`
|
|
4659
|
+
);
|
|
4660
|
+
continue;
|
|
4661
|
+
}
|
|
4662
|
+
const outputPath = parts.slice(2).join(".");
|
|
4663
|
+
const declaredOutputs = capabilityOutputs?.get(sourceCapability);
|
|
4664
|
+
if (declaredOutputs && !declaredOutputs.has(outputPath)) {
|
|
4665
|
+
issue(
|
|
4666
|
+
issues,
|
|
4667
|
+
"undeclared_step_output",
|
|
4668
|
+
`${path53}.${name}.from`,
|
|
4669
|
+
`workflow input mapping reads ${outputPath}, but step ${sourceStep} does not declare it`
|
|
4670
|
+
);
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4584
4674
|
function formatWorkflowValidationIssues(issues) {
|
|
4585
4675
|
return issues.map((entry) => `${entry.path}: ${entry.message}`);
|
|
4586
4676
|
}
|
|
@@ -4636,17 +4726,19 @@ function isJsonValue(value) {
|
|
|
4636
4726
|
function issue(issues, code, path53, message) {
|
|
4637
4727
|
issues.push({ code, path: path53, message });
|
|
4638
4728
|
}
|
|
4639
|
-
var SAFE_NAME, SAFE_STEP_ID, SAFE_DATA_PATH, SUPPORTED_STEP_FIELDS, SUPPORTED_TRANSITION_FIELDS;
|
|
4729
|
+
var SAFE_NAME, SAFE_STEP_ID, SAFE_DATA_PATH, SAFE_INPUT_SOURCE, SUPPORTED_STEP_FIELDS, SUPPORTED_TRANSITION_FIELDS;
|
|
4640
4730
|
var init_workflowValidation = __esm({
|
|
4641
4731
|
"src/workflowValidation.ts"() {
|
|
4642
4732
|
"use strict";
|
|
4643
4733
|
SAFE_NAME = /^[a-z][a-z0-9-]*$/;
|
|
4644
4734
|
SAFE_STEP_ID = /^[A-Za-z][A-Za-z0-9_-]*$/;
|
|
4645
4735
|
SAFE_DATA_PATH = /^(facts|evidence|artifacts|result|workflow|lastOutcome)(?:\.[A-Za-z_][A-Za-z0-9_-]*)+$/;
|
|
4736
|
+
SAFE_INPUT_SOURCE = /^(?:workflow\.(?:input|facts|evidence)(?:\.[A-Za-z_][A-Za-z0-9_-]*)+|steps\.[A-Za-z][A-Za-z0-9_-]*\.result(?:\.[A-Za-z_][A-Za-z0-9_-]*)+)$/;
|
|
4646
4737
|
SUPPORTED_STEP_FIELDS = /* @__PURE__ */ new Set([
|
|
4647
4738
|
"id",
|
|
4648
4739
|
"capability",
|
|
4649
4740
|
"input",
|
|
4741
|
+
"inputs",
|
|
4650
4742
|
"action",
|
|
4651
4743
|
"evidence",
|
|
4652
4744
|
"target",
|
|
@@ -16954,6 +17046,10 @@ function parseOutput(text2) {
|
|
|
16954
17046
|
if (labelledOutput.found) return labelledOutput.value;
|
|
16955
17047
|
const plainOutput = parseSingleJsonCandidate(fences.filter((match) => !match[1]).map((match) => match[2]));
|
|
16956
17048
|
if (plainOutput.found) return plainOutput.value;
|
|
17049
|
+
const finalStatusOutput = parseSingleJsonCandidate(
|
|
17050
|
+
[...text2.matchAll(/<final_status>\s*([\s\S]*?)\s*<\/final_status>/gi)].map((match) => match[1])
|
|
17051
|
+
);
|
|
17052
|
+
if (finalStatusOutput.found) return finalStatusOutput.value;
|
|
16957
17053
|
const legacyText = text2.trim();
|
|
16958
17054
|
return legacyText ? { summary: legacyText, output: legacyText } : void 0;
|
|
16959
17055
|
}
|
|
@@ -17743,53 +17839,6 @@ var init_prepareBrowserAuth = __esm({
|
|
|
17743
17839
|
}
|
|
17744
17840
|
});
|
|
17745
17841
|
|
|
17746
|
-
// src/scripts/prepareSimpleCapabilityRuntime.ts
|
|
17747
|
-
function requirementsFrom(ctx) {
|
|
17748
|
-
const raw = ctx.data.capabilityRequirements;
|
|
17749
|
-
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
17750
|
-
}
|
|
17751
|
-
function configureBrowser(profile) {
|
|
17752
|
-
if (!profile.claudeCode.tools.includes("mcp__playwright")) {
|
|
17753
|
-
profile.claudeCode.tools = [...profile.claudeCode.tools, "mcp__playwright"];
|
|
17754
|
-
}
|
|
17755
|
-
if (!profile.claudeCode.mcpServers.some(({ name }) => name === PLAYWRIGHT_SERVER.name)) {
|
|
17756
|
-
profile.claudeCode.mcpServers = [...profile.claudeCode.mcpServers, PLAYWRIGHT_SERVER];
|
|
17757
|
-
}
|
|
17758
|
-
}
|
|
17759
|
-
function appendPrompt(ctx, section) {
|
|
17760
|
-
const prompt = typeof ctx.data.prompt === "string" ? ctx.data.prompt.trim() : "";
|
|
17761
|
-
ctx.data.prompt = [prompt, section.trim()].filter(Boolean).join("\n\n");
|
|
17762
|
-
}
|
|
17763
|
-
var PLAYWRIGHT_SERVER, prepareSimpleCapabilityRuntime;
|
|
17764
|
-
var init_prepareSimpleCapabilityRuntime = __esm({
|
|
17765
|
-
"src/scripts/prepareSimpleCapabilityRuntime.ts"() {
|
|
17766
|
-
"use strict";
|
|
17767
|
-
init_loadQaContext();
|
|
17768
|
-
PLAYWRIGHT_SERVER = {
|
|
17769
|
-
name: "playwright",
|
|
17770
|
-
command: "npx",
|
|
17771
|
-
args: ["-y", "--package=@playwright/mcp@latest", "--", "playwright-mcp", "--headless"]
|
|
17772
|
-
};
|
|
17773
|
-
prepareSimpleCapabilityRuntime = async (ctx, profile) => {
|
|
17774
|
-
const requirements = requirementsFrom(ctx);
|
|
17775
|
-
if (!requirements.browser) return;
|
|
17776
|
-
configureBrowser(profile);
|
|
17777
|
-
if (!requirements.qaCredentials) return;
|
|
17778
|
-
await loadQaContext(ctx, profile);
|
|
17779
|
-
appendPrompt(
|
|
17780
|
-
ctx,
|
|
17781
|
-
[
|
|
17782
|
-
"## QA authentication",
|
|
17783
|
-
"",
|
|
17784
|
-
String(ctx.data.qaAuthBlock ?? ""),
|
|
17785
|
-
"",
|
|
17786
|
-
"If the changed surface requires authentication and the credentials are missing or the login is rejected, return a blocked result with a safe explanation. Do not include usernames, passwords, tokens, or other credential values in the result."
|
|
17787
|
-
].join("\n")
|
|
17788
|
-
);
|
|
17789
|
-
};
|
|
17790
|
-
}
|
|
17791
|
-
});
|
|
17792
|
-
|
|
17793
17842
|
// src/capabilityDelivery.ts
|
|
17794
17843
|
function capabilityDeliveryTarget(input) {
|
|
17795
17844
|
if (!input || typeof input !== "object" || Array.isArray(input)) return null;
|
|
@@ -17901,6 +17950,53 @@ var init_prepareCapabilityDelivery = __esm({
|
|
|
17901
17950
|
}
|
|
17902
17951
|
});
|
|
17903
17952
|
|
|
17953
|
+
// src/scripts/prepareSimpleCapabilityRuntime.ts
|
|
17954
|
+
function requirementsFrom(ctx) {
|
|
17955
|
+
const raw = ctx.data.capabilityRequirements;
|
|
17956
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
17957
|
+
}
|
|
17958
|
+
function configureBrowser(profile) {
|
|
17959
|
+
if (!profile.claudeCode.tools.includes("mcp__playwright")) {
|
|
17960
|
+
profile.claudeCode.tools = [...profile.claudeCode.tools, "mcp__playwright"];
|
|
17961
|
+
}
|
|
17962
|
+
if (!profile.claudeCode.mcpServers.some(({ name }) => name === PLAYWRIGHT_SERVER.name)) {
|
|
17963
|
+
profile.claudeCode.mcpServers = [...profile.claudeCode.mcpServers, PLAYWRIGHT_SERVER];
|
|
17964
|
+
}
|
|
17965
|
+
}
|
|
17966
|
+
function appendPrompt(ctx, section) {
|
|
17967
|
+
const prompt = typeof ctx.data.prompt === "string" ? ctx.data.prompt.trim() : "";
|
|
17968
|
+
ctx.data.prompt = [prompt, section.trim()].filter(Boolean).join("\n\n");
|
|
17969
|
+
}
|
|
17970
|
+
var PLAYWRIGHT_SERVER, prepareSimpleCapabilityRuntime;
|
|
17971
|
+
var init_prepareSimpleCapabilityRuntime = __esm({
|
|
17972
|
+
"src/scripts/prepareSimpleCapabilityRuntime.ts"() {
|
|
17973
|
+
"use strict";
|
|
17974
|
+
init_loadQaContext();
|
|
17975
|
+
PLAYWRIGHT_SERVER = {
|
|
17976
|
+
name: "playwright",
|
|
17977
|
+
command: "npx",
|
|
17978
|
+
args: ["-y", "--package=@playwright/mcp@latest", "--", "playwright-mcp", "--headless"]
|
|
17979
|
+
};
|
|
17980
|
+
prepareSimpleCapabilityRuntime = async (ctx, profile) => {
|
|
17981
|
+
const requirements = requirementsFrom(ctx);
|
|
17982
|
+
if (!requirements.browser) return;
|
|
17983
|
+
configureBrowser(profile);
|
|
17984
|
+
if (!requirements.qaCredentials) return;
|
|
17985
|
+
await loadQaContext(ctx, profile);
|
|
17986
|
+
appendPrompt(
|
|
17987
|
+
ctx,
|
|
17988
|
+
[
|
|
17989
|
+
"## QA authentication",
|
|
17990
|
+
"",
|
|
17991
|
+
String(ctx.data.qaAuthBlock ?? ""),
|
|
17992
|
+
"",
|
|
17993
|
+
"If the changed surface requires authentication and the credentials are missing or the login is rejected, return a blocked result with a safe explanation. Do not include usernames, passwords, tokens, or other credential values in the result."
|
|
17994
|
+
].join("\n")
|
|
17995
|
+
);
|
|
17996
|
+
};
|
|
17997
|
+
}
|
|
17998
|
+
});
|
|
17999
|
+
|
|
17904
18000
|
// src/scripts/promoteQaGoal.ts
|
|
17905
18001
|
var REPORT_JSON_OPEN2, promoteQaGoal;
|
|
17906
18002
|
var init_promoteQaGoal = __esm({
|
|
@@ -18463,45 +18559,6 @@ var init_requirePlanDeviations = __esm({
|
|
|
18463
18559
|
}
|
|
18464
18560
|
});
|
|
18465
18561
|
|
|
18466
|
-
// src/scripts/retryMissingDeliveryChange.ts
|
|
18467
|
-
function claimsChange(output) {
|
|
18468
|
-
if (!output || typeof output !== "object" || Array.isArray(output)) return false;
|
|
18469
|
-
const status = output.status;
|
|
18470
|
-
return status === "fixed" || status === "changed";
|
|
18471
|
-
}
|
|
18472
|
-
var retryMissingDeliveryChange;
|
|
18473
|
-
var init_retryMissingDeliveryChange = __esm({
|
|
18474
|
-
"src/scripts/retryMissingDeliveryChange.ts"() {
|
|
18475
|
-
"use strict";
|
|
18476
|
-
init_commit();
|
|
18477
|
-
init_parseAgentResult();
|
|
18478
|
-
init_parseSimpleCapabilityOutput();
|
|
18479
|
-
retryMissingDeliveryChange = async (ctx, profile) => {
|
|
18480
|
-
if (ctx.data.jobDelivery !== "pull-request") return;
|
|
18481
|
-
if (!claimsChange(ctx.data.capabilityOutput)) return;
|
|
18482
|
-
if (listChangedFiles(ctx.cwd).some((file) => !isForbiddenPath(file))) return;
|
|
18483
|
-
const invoker = ctx.data.__invokeAgent;
|
|
18484
|
-
const prompt = ctx.data.prompt;
|
|
18485
|
-
if (!invoker || !prompt) return;
|
|
18486
|
-
process.stderr.write("[kody] capability claimed a pull-request fix without a file change; retrying once\n");
|
|
18487
|
-
const retry = await invoker(
|
|
18488
|
-
[
|
|
18489
|
-
prompt,
|
|
18490
|
-
"",
|
|
18491
|
-
"# Missing delivery change (retry)",
|
|
18492
|
-
"",
|
|
18493
|
-
"Your previous result claimed the pull request was fixed, but no repository file changed.",
|
|
18494
|
-
"Inspect the supplied input and failure evidence, make the actual repair, and verify it.",
|
|
18495
|
-
"If no safe change is possible, return a blocked result instead of claiming fixed.",
|
|
18496
|
-
"This is the only retry."
|
|
18497
|
-
].join("\n")
|
|
18498
|
-
);
|
|
18499
|
-
await parseAgentResult2(ctx, profile, retry);
|
|
18500
|
-
await parseSimpleCapabilityOutput(ctx, profile, retry);
|
|
18501
|
-
};
|
|
18502
|
-
}
|
|
18503
|
-
});
|
|
18504
|
-
|
|
18505
18562
|
// src/scripts/resolveArtifacts.ts
|
|
18506
18563
|
var resolveArtifacts;
|
|
18507
18564
|
var init_resolveArtifacts = __esm({
|
|
@@ -21118,8 +21175,8 @@ var init_scripts = __esm({
|
|
|
21118
21175
|
init_postResearchComment();
|
|
21119
21176
|
init_postReviewResult();
|
|
21120
21177
|
init_prepareBrowserAuth();
|
|
21121
|
-
init_prepareSimpleCapabilityRuntime();
|
|
21122
21178
|
init_prepareCapabilityDelivery();
|
|
21179
|
+
init_prepareSimpleCapabilityRuntime();
|
|
21123
21180
|
init_promoteQaGoal();
|
|
21124
21181
|
init_publishReport();
|
|
21125
21182
|
init_recordClassification();
|
|
@@ -21127,7 +21184,6 @@ var init_scripts = __esm({
|
|
|
21127
21184
|
init_requireDeliveryArtifacts();
|
|
21128
21185
|
init_requireFeedbackActions();
|
|
21129
21186
|
init_requirePlanDeviations();
|
|
21130
|
-
init_retryMissingDeliveryChange();
|
|
21131
21187
|
init_resolveArtifacts();
|
|
21132
21188
|
init_resolveFlow();
|
|
21133
21189
|
init_resolvePreviewUrl();
|
|
@@ -21226,7 +21282,6 @@ var init_scripts = __esm({
|
|
|
21226
21282
|
requireFeedbackActions,
|
|
21227
21283
|
requireDeliveryArtifacts,
|
|
21228
21284
|
requirePlanDeviations,
|
|
21229
|
-
retryMissingDeliveryChange,
|
|
21230
21285
|
verify,
|
|
21231
21286
|
verifyWithRetry,
|
|
21232
21287
|
verifyReproFails,
|
|
@@ -22499,6 +22554,8 @@ function parseWorkflowRunState(raw) {
|
|
|
22499
22554
|
)
|
|
22500
22555
|
) : {};
|
|
22501
22556
|
const facts = state.facts && typeof state.facts === "object" && !Array.isArray(state.facts) ? state.facts : {};
|
|
22557
|
+
const input = state.input && typeof state.input === "object" && !Array.isArray(state.input) ? state.input : void 0;
|
|
22558
|
+
const steps = parseWorkflowSteps(state.steps);
|
|
22502
22559
|
const evidenceEntries = state.evidence && typeof state.evidence === "object" && !Array.isArray(state.evidence) ? Object.entries(state.evidence).filter((entry) => typeof entry[1] === "boolean") : [];
|
|
22503
22560
|
const artifacts = Array.isArray(state.artifacts) ? state.artifacts.filter(
|
|
22504
22561
|
(artifact) => !!artifact && typeof artifact === "object" && typeof artifact.label === "string" && (artifact.url === void 0 || typeof artifact.url === "string") && (artifact.path === void 0 || typeof artifact.path === "string")
|
|
@@ -22508,12 +22565,35 @@ function parseWorkflowRunState(raw) {
|
|
|
22508
22565
|
...typeof state.currentStepId === "string" ? { currentStepId: state.currentStepId } : {},
|
|
22509
22566
|
completedStepIds,
|
|
22510
22567
|
transitionCounts,
|
|
22568
|
+
...input ? { input: { ...input } } : {},
|
|
22569
|
+
...typeof state.definitionHash === "string" && state.definitionHash.trim() ? { definitionHash: state.definitionHash.trim() } : {},
|
|
22570
|
+
...steps ? { steps } : {},
|
|
22511
22571
|
facts: { ...facts },
|
|
22512
22572
|
evidence: Object.fromEntries(evidenceEntries),
|
|
22513
22573
|
artifacts: artifacts.map((artifact) => ({ ...artifact })),
|
|
22514
22574
|
...typeof state.blocker === "string" ? { blocker: state.blocker } : {}
|
|
22515
22575
|
};
|
|
22516
22576
|
}
|
|
22577
|
+
function parseWorkflowSteps(value) {
|
|
22578
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
22579
|
+
const steps = {};
|
|
22580
|
+
for (const [stepId, raw] of Object.entries(value)) {
|
|
22581
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
22582
|
+
const step = raw;
|
|
22583
|
+
if (step.status !== "running" && step.status !== "completed" && step.status !== "blocked" && step.status !== "failed") {
|
|
22584
|
+
continue;
|
|
22585
|
+
}
|
|
22586
|
+
steps[stepId] = {
|
|
22587
|
+
status: step.status,
|
|
22588
|
+
...typeof step.capability === "string" ? { capability: step.capability } : {},
|
|
22589
|
+
...Object.hasOwn(step, "input") ? { input: step.input } : {},
|
|
22590
|
+
...Object.hasOwn(step, "output") ? { output: step.output } : {},
|
|
22591
|
+
...typeof step.startedAt === "string" ? { startedAt: step.startedAt } : {},
|
|
22592
|
+
...typeof step.completedAt === "string" ? { completedAt: step.completedAt } : {}
|
|
22593
|
+
};
|
|
22594
|
+
}
|
|
22595
|
+
return Object.keys(steps).length > 0 ? steps : void 0;
|
|
22596
|
+
}
|
|
22517
22597
|
async function readWorkflowRunState(config, _cwd, workflowId, runId) {
|
|
22518
22598
|
const tenantId2 = runtimeTenant(config);
|
|
22519
22599
|
const row = await createStateBackendFromEnv().getWorkflowRun(tenantId2, workflowId, runId);
|
|
@@ -22556,6 +22636,7 @@ __export(job_exports, {
|
|
|
22556
22636
|
stableJobKey: () => stableJobKey,
|
|
22557
22637
|
validateJob: () => validateJob
|
|
22558
22638
|
});
|
|
22639
|
+
import { createHash as createHash8 } from "crypto";
|
|
22559
22640
|
function newJobId(flavor) {
|
|
22560
22641
|
localJobSeq += 1;
|
|
22561
22642
|
const runId = process.env.GITHUB_RUN_ID;
|
|
@@ -22844,6 +22925,8 @@ async function runLinearCapabilityWorkflow(parent, workflow, capability, base, c
|
|
|
22844
22925
|
workflowStepCount: workflow.steps.length,
|
|
22845
22926
|
workflowIssueNumber: workflowIssueNumber(parent),
|
|
22846
22927
|
workflowContext: workflowInputContext(parent.cliArgs),
|
|
22928
|
+
workflowInput: state.input ?? {},
|
|
22929
|
+
workflowStepResults: workflowStepResults(state.steps),
|
|
22847
22930
|
workflowFacts: parent.workflowFacts ?? {},
|
|
22848
22931
|
workflowStack: [
|
|
22849
22932
|
...Array.isArray(base.preloadedData?.workflowStack) ? base.preloadedData.workflowStack.filter((entry) => typeof entry === "string") : [],
|
|
@@ -22864,6 +22947,8 @@ async function runLinearCapabilityWorkflow(parent, workflow, capability, base, c
|
|
|
22864
22947
|
continue;
|
|
22865
22948
|
}
|
|
22866
22949
|
const child = workflowStepToJob(step, parent, chainData, base.cwd);
|
|
22950
|
+
beginWorkflowStep(state, step, child);
|
|
22951
|
+
await checkpoint?.(state);
|
|
22867
22952
|
process.stdout.write(
|
|
22868
22953
|
`\u2192 kody: workflow ${capability.slug} step ${index + 1}/${workflow.steps.length} \u2192 ${label}
|
|
22869
22954
|
|
|
@@ -22883,6 +22968,7 @@ async function runLinearCapabilityWorkflow(parent, workflow, capability, base, c
|
|
|
22883
22968
|
workflowContinueOn: step.continueOn ?? []
|
|
22884
22969
|
}
|
|
22885
22970
|
});
|
|
22971
|
+
finishWorkflowStep(state, step, result);
|
|
22886
22972
|
mergeWorkflowResults(state, result.capabilityResults);
|
|
22887
22973
|
if (result.capabilityOutput && typeof result.capabilityOutput === "object" && !Array.isArray(result.capabilityOutput)) {
|
|
22888
22974
|
Object.assign(state.facts, result.capabilityOutput);
|
|
@@ -22891,6 +22977,7 @@ async function runLinearCapabilityWorkflow(parent, workflow, capability, base, c
|
|
|
22891
22977
|
const prUrl = result.prUrl ?? result.taskState?.core.prUrl ?? (typeof chainData.workflowPrUrl === "string" ? chainData.workflowPrUrl : void 0);
|
|
22892
22978
|
chainData = {
|
|
22893
22979
|
...chainData,
|
|
22980
|
+
workflowStepResults: workflowStepResults(state.steps),
|
|
22894
22981
|
...result.taskState ? { taskState: result.taskState } : {},
|
|
22895
22982
|
...outcome ? { workflowLastOutcome: outcome } : {},
|
|
22896
22983
|
...result.capabilityOutput !== void 0 ? {
|
|
@@ -22922,6 +23009,7 @@ function isGraphWorkflow(workflow) {
|
|
|
22922
23009
|
function workflowError(workflow, base) {
|
|
22923
23010
|
const projectCapabilitiesRoot = hydratedCapabilitiesRoot(base.cwd);
|
|
22924
23011
|
const knownCapabilities = /* @__PURE__ */ new Set();
|
|
23012
|
+
const capabilityInputs = /* @__PURE__ */ new Map();
|
|
22925
23013
|
const capabilityOutputs = /* @__PURE__ */ new Map();
|
|
22926
23014
|
for (const step of workflow.steps) {
|
|
22927
23015
|
const action = step.action ?? step.capability;
|
|
@@ -22929,10 +23017,14 @@ function workflowError(workflow, base) {
|
|
|
22929
23017
|
const resolvedFolder = resolveCapabilityFolder(step.capability, projectCapabilitiesRoot);
|
|
22930
23018
|
if (!resolvedAction && !resolvedFolder) continue;
|
|
22931
23019
|
knownCapabilities.add(step.capability);
|
|
23020
|
+
const inputNames = resolvedFolder ? capabilityInputNames(resolvedFolder) : /* @__PURE__ */ new Set();
|
|
23021
|
+
if (inputNames.size > 0) capabilityInputs.set(step.capability, inputNames);
|
|
22932
23022
|
const outputPaths = resolvedFolder ? capabilityOutputConditionPaths(resolvedFolder.config) : /* @__PURE__ */ new Set();
|
|
22933
23023
|
if (outputPaths.size > 0) capabilityOutputs.set(step.capability, outputPaths);
|
|
22934
23024
|
}
|
|
22935
|
-
return formatWorkflowValidationIssues(
|
|
23025
|
+
return formatWorkflowValidationIssues(
|
|
23026
|
+
validateWorkflow(workflow, { knownCapabilities, capabilityInputs, capabilityOutputs })
|
|
23027
|
+
)[0] ?? null;
|
|
22936
23028
|
}
|
|
22937
23029
|
function initialWorkflowState(parent, workflow) {
|
|
22938
23030
|
const prior = parent.workflowState;
|
|
@@ -22942,6 +23034,8 @@ function initialWorkflowState(parent, workflow) {
|
|
|
22942
23034
|
status: "done",
|
|
22943
23035
|
completedStepIds: [...prior.completedStepIds],
|
|
22944
23036
|
transitionCounts: { ...prior.transitionCounts },
|
|
23037
|
+
...prior.input ? { input: { ...prior.input } } : {},
|
|
23038
|
+
...prior.steps ? { steps: cloneWorkflowSteps(prior.steps) } : {},
|
|
22945
23039
|
facts: { ...prior.facts },
|
|
22946
23040
|
evidence: { ...prior.evidence },
|
|
22947
23041
|
artifacts: prior.artifacts.map((artifact) => ({ ...artifact }))
|
|
@@ -22951,9 +23045,12 @@ function initialWorkflowState(parent, workflow) {
|
|
|
22951
23045
|
const currentStepId = prior?.currentStepId ?? firstStepId;
|
|
22952
23046
|
return {
|
|
22953
23047
|
status: "running",
|
|
23048
|
+
input: { ...prior?.input ?? workflowInputContext(parent.cliArgs) },
|
|
23049
|
+
definitionHash: prior?.definitionHash ?? workflowDefinitionHash(workflow),
|
|
22954
23050
|
...currentStepId ? { currentStepId } : {},
|
|
22955
23051
|
completedStepIds: [...prior?.completedStepIds ?? []],
|
|
22956
23052
|
transitionCounts: { ...prior?.transitionCounts ?? {} },
|
|
23053
|
+
steps: cloneWorkflowSteps(prior?.steps ?? {}),
|
|
22957
23054
|
facts: {
|
|
22958
23055
|
...workflowInputContext(parent.cliArgs),
|
|
22959
23056
|
...parent.workflowFacts ?? {},
|
|
@@ -22975,6 +23072,8 @@ function workflowChainData(parent, capability, base, state) {
|
|
|
22975
23072
|
workflowStepCount: capability.config.workflow?.steps.length ?? 0,
|
|
22976
23073
|
workflowIssueNumber: workflowIssueNumber(parent),
|
|
22977
23074
|
workflowContext: base.preloadedData?.workflowContext ?? workflowInputContext(parent.cliArgs),
|
|
23075
|
+
workflowInput: state.input ?? {},
|
|
23076
|
+
workflowStepResults: workflowStepResults(state.steps),
|
|
22978
23077
|
workflowFacts: state.facts,
|
|
22979
23078
|
workflowEvidence: state.evidence,
|
|
22980
23079
|
workflowArtifacts: state.artifacts,
|
|
@@ -23017,9 +23116,18 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
|
|
|
23017
23116
|
const reason = error instanceof Error ? error.message : String(error);
|
|
23018
23117
|
state.status = "blocked";
|
|
23019
23118
|
state.blocker = reason;
|
|
23119
|
+
state.steps = state.steps ?? {};
|
|
23120
|
+
state.steps[step.id] = {
|
|
23121
|
+
capability: step.capability,
|
|
23122
|
+
status: "blocked",
|
|
23123
|
+
output: { status: "blocked", summary: reason },
|
|
23124
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23125
|
+
};
|
|
23020
23126
|
await checkpoint?.(state);
|
|
23021
23127
|
return { exitCode: 64, reason, workflowState: state };
|
|
23022
23128
|
}
|
|
23129
|
+
beginWorkflowStep(state, step, child);
|
|
23130
|
+
await checkpoint?.(state);
|
|
23023
23131
|
process.stdout.write(
|
|
23024
23132
|
`\u2192 kody: workflow ${capability.slug} step ${index + 1}/${workflow.steps.length} \u2192 ${label}
|
|
23025
23133
|
|
|
@@ -23044,6 +23152,7 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
|
|
|
23044
23152
|
workflowContinueOn: step.continueOn ?? []
|
|
23045
23153
|
}
|
|
23046
23154
|
});
|
|
23155
|
+
finishWorkflowStep(state, step, result);
|
|
23047
23156
|
mergeWorkflowResults(state, result.capabilityResults);
|
|
23048
23157
|
if (result.capabilityOutput && typeof result.capabilityOutput === "object" && !Array.isArray(result.capabilityOutput)) {
|
|
23049
23158
|
Object.assign(state.facts, result.capabilityOutput);
|
|
@@ -23201,9 +23310,8 @@ function withWorkflowBoundaryEval(capability, result) {
|
|
|
23201
23310
|
function workflowStepToJob(step, parent, chainData, cwd) {
|
|
23202
23311
|
const action = step.action ?? step.capability;
|
|
23203
23312
|
const targetNumber = workflowStepTargetNumber(step, parent, chainData);
|
|
23204
|
-
const
|
|
23205
|
-
|
|
23206
|
-
};
|
|
23313
|
+
const mappedInputs = resolveWorkflowStepInputs(step, chainData);
|
|
23314
|
+
const rawArgs = mappedInputs ? { ...mappedInputs } : { ...parent.cliArgs };
|
|
23207
23315
|
if (step.target === "pr") {
|
|
23208
23316
|
if (typeof targetNumber !== "number") {
|
|
23209
23317
|
throw new InvalidJobError(`workflow step ${action} needs a PR target but no prior PR URL is available`);
|
|
@@ -23213,7 +23321,7 @@ function workflowStepToJob(step, parent, chainData, cwd) {
|
|
|
23213
23321
|
rawArgs.issue = targetNumber;
|
|
23214
23322
|
}
|
|
23215
23323
|
const genericInput = capabilityStepInput(
|
|
23216
|
-
step.input ??
|
|
23324
|
+
step.input ?? mappedInputs ?? chainData.workflowInput ?? genericInputFromArgs(rawArgs),
|
|
23217
23325
|
step.target,
|
|
23218
23326
|
targetNumber
|
|
23219
23327
|
);
|
|
@@ -23236,6 +23344,74 @@ function workflowStepToJob(step, parent, chainData, cwd) {
|
|
|
23236
23344
|
...parent.resultTarget ? { resultTarget: parent.resultTarget } : {}
|
|
23237
23345
|
};
|
|
23238
23346
|
}
|
|
23347
|
+
function resolveWorkflowStepInputs(step, chainData) {
|
|
23348
|
+
if (!step.inputs) return void 0;
|
|
23349
|
+
const source = {
|
|
23350
|
+
workflow: {
|
|
23351
|
+
input: chainData.workflowInput ?? {},
|
|
23352
|
+
facts: chainData.workflowFacts ?? {},
|
|
23353
|
+
evidence: chainData.workflowEvidence ?? {}
|
|
23354
|
+
},
|
|
23355
|
+
steps: chainData.workflowStepResults ?? {}
|
|
23356
|
+
};
|
|
23357
|
+
const input = {};
|
|
23358
|
+
for (const [name, binding] of Object.entries(step.inputs)) {
|
|
23359
|
+
const value = resolveDottedPath2(source, binding.from);
|
|
23360
|
+
if (value === void 0) {
|
|
23361
|
+
throw new InvalidJobError(`workflow step ${step.id ?? step.capability} needs missing input ${binding.from}`);
|
|
23362
|
+
}
|
|
23363
|
+
input[name] = value;
|
|
23364
|
+
}
|
|
23365
|
+
return input;
|
|
23366
|
+
}
|
|
23367
|
+
function capabilityInputNames(folder) {
|
|
23368
|
+
const properties = folder.config.inputSchema?.properties;
|
|
23369
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) return /* @__PURE__ */ new Set();
|
|
23370
|
+
return new Set(Object.keys(properties));
|
|
23371
|
+
}
|
|
23372
|
+
function workflowDefinitionHash(workflow) {
|
|
23373
|
+
return createHash8("sha256").update(stableJson(workflow)).digest("hex");
|
|
23374
|
+
}
|
|
23375
|
+
function stableJson(value) {
|
|
23376
|
+
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
23377
|
+
if (value && typeof value === "object") {
|
|
23378
|
+
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`).join(",")}}`;
|
|
23379
|
+
}
|
|
23380
|
+
return JSON.stringify(value);
|
|
23381
|
+
}
|
|
23382
|
+
function cloneWorkflowSteps(steps) {
|
|
23383
|
+
return Object.fromEntries(Object.entries(steps).map(([id, step]) => [id, { ...step }]));
|
|
23384
|
+
}
|
|
23385
|
+
function workflowStepResults(steps) {
|
|
23386
|
+
return Object.fromEntries(
|
|
23387
|
+
Object.entries(steps ?? {}).map(([id, step]) => [id, Object.hasOwn(step, "output") ? { result: step.output } : {}])
|
|
23388
|
+
);
|
|
23389
|
+
}
|
|
23390
|
+
function workflowStepAuditInput(job) {
|
|
23391
|
+
if (Object.hasOwn(job.cliArgs, "input")) return genericInputFromArgs(job.cliArgs);
|
|
23392
|
+
return { ...job.cliArgs };
|
|
23393
|
+
}
|
|
23394
|
+
function beginWorkflowStep(state, step, job) {
|
|
23395
|
+
const id = step.id ?? step.action ?? step.capability;
|
|
23396
|
+
state.steps = state.steps ?? {};
|
|
23397
|
+
state.steps[id] = {
|
|
23398
|
+
capability: step.capability,
|
|
23399
|
+
status: "running",
|
|
23400
|
+
input: workflowStepAuditInput(job),
|
|
23401
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23402
|
+
};
|
|
23403
|
+
}
|
|
23404
|
+
function finishWorkflowStep(state, step, result) {
|
|
23405
|
+
const id = step.id ?? step.action ?? step.capability;
|
|
23406
|
+
const prior = state.steps?.[id];
|
|
23407
|
+
state.steps = state.steps ?? {};
|
|
23408
|
+
state.steps[id] = {
|
|
23409
|
+
...prior ?? { capability: step.capability, status: "running" },
|
|
23410
|
+
status: result.exitCode === 0 ? "completed" : result.capabilityResults?.at(-1)?.status === "blocked" ? "blocked" : "failed",
|
|
23411
|
+
...result.capabilityOutput !== void 0 ? { output: result.capabilityOutput } : {},
|
|
23412
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23413
|
+
};
|
|
23414
|
+
}
|
|
23239
23415
|
function usesGenericCapabilityInput(action, cwd) {
|
|
23240
23416
|
const inputs = getCapabilityActionInputs(action, hydratedCapabilitiesRoot(cwd));
|
|
23241
23417
|
return Boolean(inputs?.length === 1 && inputs[0]?.name === "input" && inputs[0]?.flag === "--input");
|
|
@@ -23418,10 +23594,10 @@ var init_job = __esm({
|
|
|
23418
23594
|
init_config();
|
|
23419
23595
|
init_definition_paths();
|
|
23420
23596
|
init_executor();
|
|
23597
|
+
init_kody_api_client();
|
|
23421
23598
|
init_registry();
|
|
23422
23599
|
init_runIndex();
|
|
23423
23600
|
init_publishReport();
|
|
23424
|
-
init_kody_api_client();
|
|
23425
23601
|
init_simpleCapabilityRuntime();
|
|
23426
23602
|
init_state_backend();
|
|
23427
23603
|
init_workflowDefinitions();
|
|
@@ -595,9 +595,25 @@ export interface Job {
|
|
|
595
595
|
|
|
596
596
|
export interface WorkflowRunState {
|
|
597
597
|
status: "running" | "blocked" | "failed" | "done"
|
|
598
|
+
/** Immutable input supplied when this workflow run started. */
|
|
599
|
+
input?: Record<string, unknown>
|
|
600
|
+
/** Hash of the workflow definition used by this run. */
|
|
601
|
+
definitionHash?: string
|
|
598
602
|
currentStepId?: string
|
|
599
603
|
completedStepIds: string[]
|
|
600
604
|
transitionCounts: Record<string, number>
|
|
605
|
+
/** Exact per-step handoffs for audit, resume, and debugging. */
|
|
606
|
+
steps?: Record<
|
|
607
|
+
string,
|
|
608
|
+
{
|
|
609
|
+
capability?: string
|
|
610
|
+
status: "running" | "completed" | "blocked" | "failed"
|
|
611
|
+
input?: unknown
|
|
612
|
+
output?: unknown
|
|
613
|
+
startedAt?: string
|
|
614
|
+
completedAt?: string
|
|
615
|
+
}
|
|
616
|
+
>
|
|
601
617
|
facts: Record<string, unknown>
|
|
602
618
|
evidence: Record<string, boolean>
|
|
603
619
|
artifacts: Array<{ label: string; url?: string; path?: string }>
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "kody
|
|
3
|
+
"version": "0.4.549",
|
|
4
|
+
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -12,29 +12,6 @@
|
|
|
12
12
|
"templates",
|
|
13
13
|
"kody.config.schema.json"
|
|
14
14
|
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"kody:run": "tsx bin/kody.ts",
|
|
17
|
-
"serve": "tsx bin/kody.ts serve",
|
|
18
|
-
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
19
|
-
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
20
|
-
"clean:dist": "node scripts/clean-dist.cjs",
|
|
21
|
-
"build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
|
|
22
|
-
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
23
|
-
"pretest": "pnpm check:modularity",
|
|
24
|
-
"test": "vitest run tests/unit tests/int --coverage",
|
|
25
|
-
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
26
|
-
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
27
|
-
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
28
|
-
"test:runtime-services": "node --test \"tests/runtime-services/*.test.mjs\"",
|
|
29
|
-
"test:all": "vitest run tests --no-coverage",
|
|
30
|
-
"typecheck": "tsc --noEmit",
|
|
31
|
-
"lint": "biome check",
|
|
32
|
-
"lint:fix": "biome check --write",
|
|
33
|
-
"format": "biome format --write",
|
|
34
|
-
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
35
|
-
"brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain --build-arg KODY_ENGINE_REF=$(git rev-parse HEAD) -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner",
|
|
36
|
-
"prepublishOnly": "pnpm typecheck && pnpm test:runtime-services && pnpm build && pnpm verify:package"
|
|
37
|
-
},
|
|
38
15
|
"dependencies": {
|
|
39
16
|
"@actions/cache": "^6.0.0",
|
|
40
17
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
@@ -61,5 +38,27 @@
|
|
|
61
38
|
"url": "git+https://github.com/aharonyaircohen/kody-engine.git"
|
|
62
39
|
},
|
|
63
40
|
"homepage": "https://github.com/aharonyaircohen/kody-engine",
|
|
64
|
-
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
65
|
-
|
|
41
|
+
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues",
|
|
42
|
+
"scripts": {
|
|
43
|
+
"kody:run": "tsx bin/kody.ts",
|
|
44
|
+
"serve": "tsx bin/kody.ts serve",
|
|
45
|
+
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
46
|
+
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
47
|
+
"clean:dist": "node scripts/clean-dist.cjs",
|
|
48
|
+
"build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
|
|
49
|
+
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
50
|
+
"pretest": "pnpm check:modularity",
|
|
51
|
+
"test": "vitest run tests/unit tests/int --coverage",
|
|
52
|
+
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
53
|
+
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
54
|
+
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
55
|
+
"test:runtime-services": "node --test \"tests/runtime-services/*.test.mjs\"",
|
|
56
|
+
"test:all": "vitest run tests --no-coverage",
|
|
57
|
+
"typecheck": "tsc --noEmit",
|
|
58
|
+
"lint": "biome check",
|
|
59
|
+
"lint:fix": "biome check --write",
|
|
60
|
+
"format": "biome format --write",
|
|
61
|
+
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
62
|
+
"brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain --build-arg KODY_ENGINE_REF=$(git rev-parse HEAD) -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner"
|
|
63
|
+
}
|
|
64
|
+
}
|