@kody-ade/kody-engine 0.4.535 → 0.4.537
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.537",
|
|
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",
|
|
@@ -1956,6 +1956,7 @@ function parseCapabilityContract(raw) {
|
|
|
1956
1956
|
if (parsed.execution !== void 0 && parsed.execution !== "agent" && parsed.execution !== "script") {
|
|
1957
1957
|
throw new Error('contract.json execution must be "agent" or "script"');
|
|
1958
1958
|
}
|
|
1959
|
+
const requirements = parseCapabilityRequirements(parsed.requirements);
|
|
1959
1960
|
const secrets = parsed.secrets === void 0 ? void 0 : Array.isArray(parsed.secrets) && parsed.secrets.every((name) => typeof name === "string" && /^[A-Z][A-Z0-9_]*$/.test(name)) ? [...new Set(parsed.secrets)] : null;
|
|
1960
1961
|
if (secrets === null) {
|
|
1961
1962
|
throw new Error("contract.json secrets must contain valid environment variable names");
|
|
@@ -1978,13 +1979,14 @@ function parseCapabilityContract(raw) {
|
|
|
1978
1979
|
throw new Error('contract.json requiredSubagents are supported only when execution is "agent"');
|
|
1979
1980
|
}
|
|
1980
1981
|
const unsupported = Object.keys(parsed).filter(
|
|
1981
|
-
(key) => key !== "execution" && key !== "secrets" && key !== "timeoutMs" && key !== "requiredSubagents" && key !== "input" && key !== "output"
|
|
1982
|
+
(key) => key !== "execution" && key !== "requirements" && key !== "secrets" && key !== "timeoutMs" && key !== "requiredSubagents" && key !== "input" && key !== "output"
|
|
1982
1983
|
);
|
|
1983
1984
|
if (unsupported.length > 0) {
|
|
1984
1985
|
throw new Error(`contract.json contains unsupported fields: ${unsupported.join(", ")}`);
|
|
1985
1986
|
}
|
|
1986
1987
|
return {
|
|
1987
1988
|
...parsed.execution ? { execution: parsed.execution } : {},
|
|
1989
|
+
...requirements ? { requirements } : {},
|
|
1988
1990
|
...secrets ? { secrets } : {},
|
|
1989
1991
|
...timeoutMs !== void 0 ? { timeoutMs } : {},
|
|
1990
1992
|
...requiredSubagents ? { requiredSubagents } : {},
|
|
@@ -1992,6 +1994,28 @@ function parseCapabilityContract(raw) {
|
|
|
1992
1994
|
output: parsed.output
|
|
1993
1995
|
};
|
|
1994
1996
|
}
|
|
1997
|
+
function parseCapabilityRequirements(raw) {
|
|
1998
|
+
if (raw === void 0) return void 0;
|
|
1999
|
+
if (!isPlainObject(raw)) throw new Error("contract.json requirements must be an object");
|
|
2000
|
+
const unsupported = Object.keys(raw).filter((key) => key !== "browser" && key !== "qaCredentials");
|
|
2001
|
+
if (unsupported.length > 0) {
|
|
2002
|
+
throw new Error(`contract.json requirements contains unsupported fields: ${unsupported.join(", ")}`);
|
|
2003
|
+
}
|
|
2004
|
+
if (raw.browser !== void 0 && typeof raw.browser !== "boolean") {
|
|
2005
|
+
throw new Error("contract.json requirements.browser must be boolean");
|
|
2006
|
+
}
|
|
2007
|
+
if (raw.qaCredentials !== void 0 && typeof raw.qaCredentials !== "boolean") {
|
|
2008
|
+
throw new Error("contract.json requirements.qaCredentials must be boolean");
|
|
2009
|
+
}
|
|
2010
|
+
if (raw.qaCredentials === true && raw.browser !== true) {
|
|
2011
|
+
throw new Error("contract.json requirements.qaCredentials requires browser");
|
|
2012
|
+
}
|
|
2013
|
+
const requirements = {
|
|
2014
|
+
...raw.browser === true ? { browser: true } : {},
|
|
2015
|
+
...raw.qaCredentials === true ? { qaCredentials: true } : {}
|
|
2016
|
+
};
|
|
2017
|
+
return Object.keys(requirements).length > 0 ? requirements : void 0;
|
|
2018
|
+
}
|
|
1995
2019
|
function isRegularFile(filePath) {
|
|
1996
2020
|
try {
|
|
1997
2021
|
const stat = fs6.lstatSync(filePath);
|
|
@@ -15876,6 +15900,9 @@ var init_loadSimpleCapability = __esm({
|
|
|
15876
15900
|
ctx.data.jobCapability = slug;
|
|
15877
15901
|
ctx.data.capabilityInput = input;
|
|
15878
15902
|
ctx.data.capabilityExecution = capability.contract?.execution ?? "agent";
|
|
15903
|
+
if (capability.contract?.requirements) {
|
|
15904
|
+
ctx.data.capabilityRequirements = capability.contract.requirements;
|
|
15905
|
+
}
|
|
15879
15906
|
if (ctx.data.capabilityExecution === "agent") {
|
|
15880
15907
|
registerCapabilitySubagents(profile, toolRoot, toolFiles);
|
|
15881
15908
|
}
|
|
@@ -17703,6 +17730,53 @@ var init_prepareBrowserAuth = __esm({
|
|
|
17703
17730
|
}
|
|
17704
17731
|
});
|
|
17705
17732
|
|
|
17733
|
+
// src/scripts/prepareSimpleCapabilityRuntime.ts
|
|
17734
|
+
function requirementsFrom(ctx) {
|
|
17735
|
+
const raw = ctx.data.capabilityRequirements;
|
|
17736
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
17737
|
+
}
|
|
17738
|
+
function configureBrowser(profile) {
|
|
17739
|
+
if (!profile.claudeCode.tools.includes("mcp__playwright")) {
|
|
17740
|
+
profile.claudeCode.tools = [...profile.claudeCode.tools, "mcp__playwright"];
|
|
17741
|
+
}
|
|
17742
|
+
if (!profile.claudeCode.mcpServers.some(({ name }) => name === PLAYWRIGHT_SERVER.name)) {
|
|
17743
|
+
profile.claudeCode.mcpServers = [...profile.claudeCode.mcpServers, PLAYWRIGHT_SERVER];
|
|
17744
|
+
}
|
|
17745
|
+
}
|
|
17746
|
+
function appendPrompt(ctx, section) {
|
|
17747
|
+
const prompt = typeof ctx.data.prompt === "string" ? ctx.data.prompt.trim() : "";
|
|
17748
|
+
ctx.data.prompt = [prompt, section.trim()].filter(Boolean).join("\n\n");
|
|
17749
|
+
}
|
|
17750
|
+
var PLAYWRIGHT_SERVER, prepareSimpleCapabilityRuntime;
|
|
17751
|
+
var init_prepareSimpleCapabilityRuntime = __esm({
|
|
17752
|
+
"src/scripts/prepareSimpleCapabilityRuntime.ts"() {
|
|
17753
|
+
"use strict";
|
|
17754
|
+
init_loadQaContext();
|
|
17755
|
+
PLAYWRIGHT_SERVER = {
|
|
17756
|
+
name: "playwright",
|
|
17757
|
+
command: "npx",
|
|
17758
|
+
args: ["-y", "--package=@playwright/mcp@latest", "--", "playwright-mcp", "--headless"]
|
|
17759
|
+
};
|
|
17760
|
+
prepareSimpleCapabilityRuntime = async (ctx, profile) => {
|
|
17761
|
+
const requirements = requirementsFrom(ctx);
|
|
17762
|
+
if (!requirements.browser) return;
|
|
17763
|
+
configureBrowser(profile);
|
|
17764
|
+
if (!requirements.qaCredentials) return;
|
|
17765
|
+
await loadQaContext(ctx, profile);
|
|
17766
|
+
appendPrompt(
|
|
17767
|
+
ctx,
|
|
17768
|
+
[
|
|
17769
|
+
"## QA authentication",
|
|
17770
|
+
"",
|
|
17771
|
+
String(ctx.data.qaAuthBlock ?? ""),
|
|
17772
|
+
"",
|
|
17773
|
+
"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."
|
|
17774
|
+
].join("\n")
|
|
17775
|
+
);
|
|
17776
|
+
};
|
|
17777
|
+
}
|
|
17778
|
+
});
|
|
17779
|
+
|
|
17706
17780
|
// src/capabilityDelivery.ts
|
|
17707
17781
|
function capabilityDeliveryTarget(input) {
|
|
17708
17782
|
if (!input || typeof input !== "object" || Array.isArray(input)) return null;
|
|
@@ -20983,6 +21057,7 @@ var init_scripts = __esm({
|
|
|
20983
21057
|
init_postResearchComment();
|
|
20984
21058
|
init_postReviewResult();
|
|
20985
21059
|
init_prepareBrowserAuth();
|
|
21060
|
+
init_prepareSimpleCapabilityRuntime();
|
|
20986
21061
|
init_prepareCapabilityDelivery();
|
|
20987
21062
|
init_promoteQaGoal();
|
|
20988
21063
|
init_publishReport();
|
|
@@ -21046,6 +21121,7 @@ var init_scripts = __esm({
|
|
|
21046
21121
|
loadPriorArt,
|
|
21047
21122
|
loadQaContext,
|
|
21048
21123
|
prepareBrowserAuth,
|
|
21124
|
+
prepareSimpleCapabilityRuntime,
|
|
21049
21125
|
prepareCapabilityDelivery,
|
|
21050
21126
|
buildSyntheticPlugin,
|
|
21051
21127
|
resolveArtifacts,
|
|
@@ -22566,13 +22642,12 @@ async function runJob(job, base) {
|
|
|
22566
22642
|
}
|
|
22567
22643
|
if (valid.workflowRunId && workflowIdentity && hasGitHubActionsIdentity()) {
|
|
22568
22644
|
const facts = result.workflowState?.facts ?? {};
|
|
22569
|
-
const pr = typeof facts.pr === "number" ? facts.pr : typeof valid.cliArgs.pr === "number" ? valid.cliArgs.pr : void 0;
|
|
22570
|
-
const headSha = typeof facts.headSha === "string" ? facts.headSha : typeof valid.cliArgs.headSha === "string" ? valid.cliArgs.headSha : void 0;
|
|
22571
22645
|
await notifyWorkflowCompleted({
|
|
22572
22646
|
workflowId: workflowIdentity,
|
|
22573
22647
|
runId: valid.workflowRunId,
|
|
22574
|
-
status: result.exitCode === 0 ? "success" : "failed",
|
|
22575
|
-
...
|
|
22648
|
+
status: result.workflowState?.status === "blocked" ? "blocked" : result.exitCode === 0 ? "success" : "failed",
|
|
22649
|
+
...result.reason ? { summary: result.reason } : {},
|
|
22650
|
+
...Object.keys(facts).length > 0 ? { output: facts } : {}
|
|
22576
22651
|
});
|
|
22577
22652
|
}
|
|
22578
22653
|
return result;
|
|
@@ -22691,9 +22766,10 @@ async function runCapabilityWorkflow(parent, workflow, capability, base, checkpo
|
|
|
22691
22766
|
}
|
|
22692
22767
|
return result;
|
|
22693
22768
|
}
|
|
22694
|
-
return runLinearCapabilityWorkflow(parent, workflow, capability, base);
|
|
22769
|
+
return runLinearCapabilityWorkflow(parent, workflow, capability, base, checkpoint);
|
|
22695
22770
|
}
|
|
22696
|
-
async function runLinearCapabilityWorkflow(parent, workflow, capability, base) {
|
|
22771
|
+
async function runLinearCapabilityWorkflow(parent, workflow, capability, base, checkpoint) {
|
|
22772
|
+
const state = initialWorkflowState(parent, workflow);
|
|
22697
22773
|
let chainData = {
|
|
22698
22774
|
...base.preloadedData ?? {},
|
|
22699
22775
|
runSubjectType: "workflow",
|
|
@@ -22744,6 +22820,10 @@ async function runLinearCapabilityWorkflow(parent, workflow, capability, base) {
|
|
|
22744
22820
|
workflowContinueOn: step.continueOn ?? []
|
|
22745
22821
|
}
|
|
22746
22822
|
});
|
|
22823
|
+
mergeWorkflowResults(state, result.capabilityResults);
|
|
22824
|
+
if (result.capabilityOutput && typeof result.capabilityOutput === "object" && !Array.isArray(result.capabilityOutput)) {
|
|
22825
|
+
Object.assign(state.facts, result.capabilityOutput);
|
|
22826
|
+
}
|
|
22747
22827
|
const outcome = workflowOutcome(result);
|
|
22748
22828
|
const prUrl = result.prUrl ?? result.taskState?.core.prUrl ?? (typeof chainData.workflowPrUrl === "string" ? chainData.workflowPrUrl : void 0);
|
|
22749
22829
|
chainData = {
|
|
@@ -22758,13 +22838,20 @@ async function runLinearCapabilityWorkflow(parent, workflow, capability, base) {
|
|
|
22758
22838
|
...parsePrNumber5(prUrl) ? { workflowPrNumber: parsePrNumber5(prUrl) } : {}
|
|
22759
22839
|
};
|
|
22760
22840
|
if (result.exitCode !== 0 && !canContinueWorkflow(step, outcome)) {
|
|
22841
|
+
state.status = result.capabilityResults?.at(-1)?.status === "blocked" ? "blocked" : "failed";
|
|
22842
|
+
state.blocker = result.reason ?? `workflow ${capability.slug} stopped at step ${index + 1}/${workflow.steps.length}: ${label}`;
|
|
22843
|
+
await checkpoint?.(state);
|
|
22761
22844
|
return withWorkflowBoundaryEval(capability, {
|
|
22762
22845
|
...result,
|
|
22763
|
-
reason:
|
|
22846
|
+
reason: state.blocker,
|
|
22847
|
+
workflowState: state
|
|
22764
22848
|
});
|
|
22765
22849
|
}
|
|
22766
22850
|
}
|
|
22767
|
-
|
|
22851
|
+
state.status = "done";
|
|
22852
|
+
delete state.blocker;
|
|
22853
|
+
await checkpoint?.(state);
|
|
22854
|
+
return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
|
|
22768
22855
|
}
|
|
22769
22856
|
function isGraphWorkflow(workflow) {
|
|
22770
22857
|
return workflow.startAt !== void 0 || workflow.steps.some((step) => step.id !== void 0 || step.next !== void 0);
|
|
@@ -22804,7 +22891,11 @@ function initialWorkflowState(parent, workflow) {
|
|
|
22804
22891
|
...currentStepId ? { currentStepId } : {},
|
|
22805
22892
|
completedStepIds: [...prior?.completedStepIds ?? []],
|
|
22806
22893
|
transitionCounts: { ...prior?.transitionCounts ?? {} },
|
|
22807
|
-
facts: {
|
|
22894
|
+
facts: {
|
|
22895
|
+
...workflowInputContext(parent.cliArgs),
|
|
22896
|
+
...parent.workflowFacts ?? {},
|
|
22897
|
+
...prior?.facts ?? {}
|
|
22898
|
+
},
|
|
22808
22899
|
evidence: { ...prior?.evidence ?? {} },
|
|
22809
22900
|
artifacts: (prior?.artifacts ?? []).map((artifact) => ({ ...artifact }))
|
|
22810
22901
|
};
|
|
@@ -22891,6 +22982,9 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
|
|
|
22891
22982
|
}
|
|
22892
22983
|
});
|
|
22893
22984
|
mergeWorkflowResults(state, result.capabilityResults);
|
|
22985
|
+
if (result.capabilityOutput && typeof result.capabilityOutput === "object" && !Array.isArray(result.capabilityOutput)) {
|
|
22986
|
+
Object.assign(state.facts, result.capabilityOutput);
|
|
22987
|
+
}
|
|
22894
22988
|
const outcome = workflowOutcome(result);
|
|
22895
22989
|
const prUrl = result.prUrl ?? result.taskState?.core.prUrl ?? (typeof chainData.workflowPrUrl === "string" ? chainData.workflowPrUrl : void 0);
|
|
22896
22990
|
chainData = {
|
|
@@ -22907,7 +23001,8 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
|
|
|
22907
23001
|
};
|
|
22908
23002
|
if (!state.completedStepIds.includes(step.id)) state.completedStepIds.push(step.id);
|
|
22909
23003
|
if (result.exitCode !== 0 && !canContinueWorkflow(step, outcome)) {
|
|
22910
|
-
|
|
23004
|
+
const lastResult = result.capabilityResults?.at(-1);
|
|
23005
|
+
state.status = lastResult?.status === "blocked" ? "blocked" : "failed";
|
|
22911
23006
|
state.blocker = result.reason ?? `workflow step ${step.id} failed`;
|
|
22912
23007
|
await checkpoint?.(state);
|
|
22913
23008
|
return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
|
|
@@ -22950,14 +23045,17 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
|
|
|
22950
23045
|
}
|
|
22951
23046
|
async function completeWorkflowAtTerminal(capability, state, output, checkpoint) {
|
|
22952
23047
|
const result = output.capabilityResults?.at(-1);
|
|
22953
|
-
|
|
22954
|
-
|
|
22955
|
-
|
|
23048
|
+
const customStatus = output.capabilityOutput && typeof output.capabilityOutput === "object" && !Array.isArray(output.capabilityOutput) && typeof output.capabilityOutput.status === "string" ? output.capabilityOutput.status : void 0;
|
|
23049
|
+
const terminalFailure = result?.status === "fail" || customStatus === "fail" ? "failed" : result?.status === "blocked" || customStatus === "blocked" ? "blocked" : null;
|
|
23050
|
+
if (terminalFailure) {
|
|
23051
|
+
const summary = result?.summary ?? (typeof output.capabilityOutput?.summary === "string" ? output.capabilityOutput.summary : "Workflow ended without a usable result");
|
|
23052
|
+
state.status = terminalFailure;
|
|
23053
|
+
state.blocker = summary;
|
|
22956
23054
|
await checkpoint?.(state);
|
|
22957
23055
|
return withWorkflowBoundaryEval(capability, {
|
|
22958
23056
|
...output,
|
|
22959
|
-
exitCode:
|
|
22960
|
-
reason:
|
|
23057
|
+
exitCode: terminalFailure === "failed" ? 1 : 64,
|
|
23058
|
+
reason: summary,
|
|
22961
23059
|
workflowState: state
|
|
22962
23060
|
});
|
|
22963
23061
|
}
|
|
@@ -38,6 +38,10 @@
|
|
|
38
38
|
"scripts": {
|
|
39
39
|
"preflight": [
|
|
40
40
|
{ "script": "loadSimpleCapability" },
|
|
41
|
+
{
|
|
42
|
+
"script": "prepareSimpleCapabilityRuntime",
|
|
43
|
+
"runWhen": { "data.capabilityExecution": "agent" }
|
|
44
|
+
},
|
|
41
45
|
{
|
|
42
46
|
"script": "runSimpleCapabilityScript",
|
|
43
47
|
"runWhen": { "data.capabilityExecution": "script" }
|
|
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.537",
|
|
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
|
+
}
|