@kody-ade/kody-engine 0.4.430 → 0.4.432

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.430",
18
+ version: "0.4.432",
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",
@@ -40,6 +40,7 @@ var init_package = __esm({
40
40
  posttest: "tsx scripts/check-coverage-floor.ts",
41
41
  "test:smoke": "vitest run tests/smoke --no-coverage",
42
42
  "test:e2e": "vitest run tests/e2e --no-coverage",
43
+ "test:runtime-services": 'node --test "tests/runtime-services/*.test.mjs"',
43
44
  "test:all": "vitest run tests --no-coverage",
44
45
  typecheck: "tsc --noEmit",
45
46
  lint: "biome check",
@@ -47,13 +48,14 @@ var init_package = __esm({
47
48
  format: "biome format --write",
48
49
  "verify:package": "node scripts/verify-package-tarball.cjs",
49
50
  "brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner",
50
- prepublishOnly: "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build && pnpm verify:package"
51
+ prepublishOnly: "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm test:runtime-services && pnpm build && pnpm verify:package"
51
52
  },
52
53
  dependencies: {
53
54
  "@actions/cache": "^6.0.0",
54
55
  "@anthropic-ai/claude-agent-sdk": "0.2.119",
55
56
  "@kody-ade/agency-domain": "0.5.1",
56
57
  "@modelcontextprotocol/sdk": "^1.29.0",
58
+ ajv: "^8.18.0",
57
59
  convex: "^1.17.0",
58
60
  zod: "^4.0.0"
59
61
  },
@@ -255,6 +257,7 @@ function loadConfig(projectDir = process.cwd()) {
255
257
  ...parsePerImplementationReasoningEffort(agent.perImplementationReasoningEffort),
256
258
  ...parseAgentReasoningEffort(agent.reasoningEffort)
257
259
  },
260
+ execution: parseExecutionConfig(raw.execution),
258
261
  issueContext: parseIssueContext(raw.issueContext),
259
262
  testRequirements: parseTestRequirements(raw.testRequirements),
260
263
  defaultImplementation: typeof raw.defaultImplementation === "string" && raw.defaultImplementation.length > 0 ? raw.defaultImplementation : "run",
@@ -267,6 +270,18 @@ function loadConfig(projectDir = process.cwd()) {
267
270
  access: parseAccessConfig(raw.access)
268
271
  };
269
272
  }
273
+ function parseExecutionConfig(value) {
274
+ const execution = recordValue(value);
275
+ const bindings = recordValue(execution?.capabilityBindings);
276
+ if (!bindings) return void 0;
277
+ const capabilityBindings = {};
278
+ for (const [capabilityId, implementationId] of Object.entries(bindings)) {
279
+ if (/^[a-z][a-z0-9-]*$/.test(capabilityId) && typeof implementationId === "string" && /^[a-z][a-z0-9-]*$/.test(implementationId)) {
280
+ capabilityBindings[capabilityId] = implementationId;
281
+ }
282
+ }
283
+ return Object.keys(capabilityBindings).length > 0 ? { capabilityBindings } : void 0;
284
+ }
270
285
  function parseAccessConfig(raw) {
271
286
  if (raw === void 0 || raw === null) {
272
287
  return { allowedAssociations: [...DEFAULT_ALLOWED_ASSOCIATIONS] };
@@ -747,7 +762,7 @@ function buildVerifyEnv(source = process.env) {
747
762
  return env;
748
763
  }
749
764
  function runCommand(command, cwd) {
750
- return new Promise((resolve17) => {
765
+ return new Promise((resolve19) => {
751
766
  const start = Date.now();
752
767
  const child = spawn(command, {
753
768
  cwd,
@@ -776,11 +791,11 @@ function runCommand(command, cwd) {
776
791
  child.on("exit", (code) => {
777
792
  clearTimeout(timer);
778
793
  const tail = Buffer.concat(buffers).toString("utf-8").slice(-TAIL_CHARS);
779
- resolve17({ exitCode: code ?? -1, durationMs: Date.now() - start, tail });
794
+ resolve19({ exitCode: code ?? -1, durationMs: Date.now() - start, tail });
780
795
  });
781
796
  child.on("error", (err) => {
782
797
  clearTimeout(timer);
783
- resolve17({ exitCode: -1, durationMs: Date.now() - start, tail: err.message });
798
+ resolve19({ exitCode: -1, durationMs: Date.now() - start, tail: err.message });
784
799
  });
785
800
  });
786
801
  }
@@ -1631,10 +1646,71 @@ var init_issue = __esm({
1631
1646
  }
1632
1647
  });
1633
1648
 
1649
+ // src/agency/implementation-resolution.ts
1650
+ function resolveCapabilityImplementation(input) {
1651
+ const compatible = input.implementations.filter(
1652
+ (implementation) => implementation.capabilityRef.id === input.capabilityId && implementation.compatibleCapabilityRevision === input.capabilityRevision
1653
+ );
1654
+ if (input.explicitOverride) {
1655
+ if (!input.authorizeOverride?.(input.explicitOverride)) {
1656
+ throw new ImplementationResolutionError(`Implementation override "${input.explicitOverride}" is not authorized`);
1657
+ }
1658
+ return selectNamed(input.explicitOverride, input, compatible, "override");
1659
+ }
1660
+ if (input.repositoryBinding) {
1661
+ return selectNamed(input.repositoryBinding, input, compatible, "repository binding");
1662
+ }
1663
+ if (compatible.length === 1) return compatible[0];
1664
+ if (compatible.length === 0) {
1665
+ throw new ImplementationResolutionError(
1666
+ `No compatible Implementation is available for Capability "${input.capabilityId}" at revision "${input.capabilityRevision}"`
1667
+ );
1668
+ }
1669
+ throw new ImplementationResolutionError(
1670
+ `Capability "${input.capabilityId}" has ${compatible.length} compatible Implementations; configure a repository binding`
1671
+ );
1672
+ }
1673
+ function selectNamed(id, input, compatible, source) {
1674
+ const known = input.implementations.find((implementation) => implementation.id === id);
1675
+ if (!known) {
1676
+ throw new ImplementationResolutionError(`Implementation ${source} "${id}" is not available`);
1677
+ }
1678
+ const selected = compatible.find((implementation) => implementation.id === id);
1679
+ if (!selected) {
1680
+ throw new ImplementationResolutionError(
1681
+ `Implementation ${source} "${id}" is not compatible with Capability "${input.capabilityId}" at revision "${input.capabilityRevision}"`
1682
+ );
1683
+ }
1684
+ return selected;
1685
+ }
1686
+ var ImplementationResolutionError;
1687
+ var init_implementation_resolution = __esm({
1688
+ "src/agency/implementation-resolution.ts"() {
1689
+ "use strict";
1690
+ ImplementationResolutionError = class extends Error {
1691
+ constructor(message) {
1692
+ super(message);
1693
+ this.name = "ImplementationResolutionError";
1694
+ }
1695
+ };
1696
+ }
1697
+ });
1698
+
1634
1699
  // src/capabilityFolders.ts
1635
1700
  import * as fs4 from "fs";
1636
1701
  import * as path5 from "path";
1637
1702
  function capabilityOutputConditionPaths(config) {
1703
+ if (config.outputSchema) {
1704
+ const properties = isPlainObject(config.outputSchema.properties) ? config.outputSchema.properties : void 0;
1705
+ const factContract = isPlainObject(properties?.facts) ? properties.facts : void 0;
1706
+ const facts = isPlainObject(factContract?.properties) ? factContract.properties : void 0;
1707
+ return /* @__PURE__ */ new Set([
1708
+ ...properties?.status ? ["result.status"] : [],
1709
+ ...properties?.summary ? ["result.summary"] : [],
1710
+ ...properties?.resultClass ? ["result.resultClass"] : [],
1711
+ ...Object.keys(facts ?? {}).map((fact) => `result.facts.${fact}`)
1712
+ ]);
1713
+ }
1638
1714
  const result = config.output?.result;
1639
1715
  if (!result) return /* @__PURE__ */ new Set();
1640
1716
  return /* @__PURE__ */ new Set([
@@ -1655,16 +1731,19 @@ function listCapabilityFolderSlugs(absDir) {
1655
1731
  return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).filter((e) => isCapabilityFolder(path5.join(absDir, e.name))).map((e) => e.name).sort();
1656
1732
  }
1657
1733
  function isCapabilityFolder(dir) {
1658
- return fs4.existsSync(path5.join(dir, CAPABILITY_PROFILE_FILE)) && fs4.existsSync(path5.join(dir, CAPABILITY_BODY_FILE));
1734
+ return (fs4.existsSync(path5.join(dir, CAPABILITY_DEFINITION_FILE)) || fs4.existsSync(path5.join(dir, CAPABILITY_PROFILE_FILE))) && fs4.existsSync(path5.join(dir, CAPABILITY_BODY_FILE));
1659
1735
  }
1660
1736
  function readCapabilityFolder(root, slug) {
1661
1737
  const dir = path5.join(root, slug);
1662
- const profilePath = path5.join(dir, CAPABILITY_PROFILE_FILE);
1738
+ const definitionPath = path5.join(dir, CAPABILITY_DEFINITION_FILE);
1739
+ const legacyProfilePath = path5.join(dir, CAPABILITY_PROFILE_FILE);
1740
+ const profilePath = fs4.existsSync(definitionPath) ? definitionPath : legacyProfilePath;
1663
1741
  const bodyPath = path5.join(dir, CAPABILITY_BODY_FILE);
1664
1742
  if (!fs4.existsSync(profilePath) || !fs4.statSync(profilePath).isFile()) return null;
1665
1743
  if (!fs4.existsSync(bodyPath) || !fs4.statSync(bodyPath).isFile()) return null;
1666
1744
  try {
1667
- const rawProfile = JSON.parse(fs4.readFileSync(profilePath, "utf-8"));
1745
+ const rawDefinition = JSON.parse(fs4.readFileSync(profilePath, "utf-8"));
1746
+ const rawProfile = rawDefinition;
1668
1747
  const rawBody = fs4.readFileSync(bodyPath, "utf-8");
1669
1748
  const { title, body } = parseCapabilityBody(rawBody, slug);
1670
1749
  return {
@@ -1700,11 +1779,12 @@ function parseCapabilityConfig(raw) {
1700
1779
  capabilityToolMode: parseCapabilityToolMode(raw.capabilityToolMode),
1701
1780
  implementations,
1702
1781
  role: stringField(raw.role),
1703
- describe: stringField(raw.describe),
1782
+ describe: stringField(raw.describe) ?? stringField(raw.purpose),
1704
1783
  stage: stringField(raw.stage),
1705
1784
  readsFrom: stringList(raw.readsFrom ?? raw.reads_from),
1706
1785
  writesTo: stringList(raw.writesTo ?? raw.writes_to),
1707
1786
  output: parseCapabilityOutput(raw.output),
1787
+ outputSchema: isPlainObject(raw.outputSchema) ? raw.outputSchema : void 0,
1708
1788
  workflow: parseCapabilityWorkflow(raw.workflow)
1709
1789
  };
1710
1790
  }
@@ -1873,11 +1953,12 @@ function isSafeSlug(value) {
1873
1953
  function isSafeStepId(value) {
1874
1954
  return /^[A-Za-z][A-Za-z0-9_-]*$/.test(value) && !value.includes("..");
1875
1955
  }
1876
- var CAPABILITY_PROFILE_FILE, CAPABILITY_BODY_FILE;
1956
+ var CAPABILITY_PROFILE_FILE, CAPABILITY_DEFINITION_FILE, CAPABILITY_BODY_FILE;
1877
1957
  var init_capabilityFolders = __esm({
1878
1958
  "src/capabilityFolders.ts"() {
1879
1959
  "use strict";
1880
1960
  CAPABILITY_PROFILE_FILE = "profile.json";
1961
+ CAPABILITY_DEFINITION_FILE = "definition.json";
1881
1962
  CAPABILITY_BODY_FILE = "capability.md";
1882
1963
  }
1883
1964
  });
@@ -1903,6 +1984,9 @@ function hasExplicitDefinitionsRoot(cwd = process.cwd(), env = process.env) {
1903
1984
  function capabilitiesRoot(cwd = process.cwd()) {
1904
1985
  return path6.join(definitionsRoot(cwd), "capabilities");
1905
1986
  }
1987
+ function implementationsRoot(cwd = process.cwd()) {
1988
+ return path6.join(definitionsRoot(cwd), "implementations");
1989
+ }
1906
1990
  function agentsRoot(cwd = process.cwd()) {
1907
1991
  return path6.join(definitionsRoot(cwd), "agents");
1908
1992
  }
@@ -1913,6 +1997,7 @@ var init_definition_paths = __esm({
1913
1997
  });
1914
1998
 
1915
1999
  // src/registry.ts
2000
+ import { createHash as createHash2 } from "crypto";
1916
2001
  import * as fs6 from "fs";
1917
2002
  import * as path7 from "path";
1918
2003
  function getImplementationsRoot() {
@@ -1930,6 +2015,18 @@ function getImplementationsRoot() {
1930
2015
  }
1931
2016
  return candidates[0];
1932
2017
  }
2018
+ function getRuntimeServicesRoot() {
2019
+ const here = path7.dirname(new URL(import.meta.url).pathname);
2020
+ const candidates = [
2021
+ path7.join(here, "runtime-services"),
2022
+ path7.join(here, "..", "runtime-services"),
2023
+ path7.join(here, "..", "src", "runtime-services")
2024
+ ];
2025
+ for (const candidate of candidates) {
2026
+ if (fs6.existsSync(candidate) && fs6.statSync(candidate).isDirectory()) return candidate;
2027
+ }
2028
+ return candidates[0];
2029
+ }
1933
2030
  function getProjectCapabilitiesRoot() {
1934
2031
  return capabilitiesRoot();
1935
2032
  }
@@ -1952,7 +2049,10 @@ function getImplementationRoots() {
1952
2049
  return getImplementationRootsForCwd(process.cwd());
1953
2050
  }
1954
2051
  function getImplementationRootsForCwd(cwd) {
1955
- return [capabilitiesRoot(cwd), getImplementationsRoot()];
2052
+ return [implementationsRoot(cwd), getImplementationsRoot()];
2053
+ }
2054
+ function getRuntimeProfileRootsForCwd(cwd) {
2055
+ return [...getImplementationRootsForCwd(cwd), getRuntimeServicesRoot()];
1956
2056
  }
1957
2057
  function getCapabilityRoots(projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
1958
2058
  return [projectCapabilitiesRoot, getBuiltinCapabilitiesRoot()];
@@ -1968,7 +2068,7 @@ function listImplementations(roots = getImplementationRoots()) {
1968
2068
  for (const ent of entries) {
1969
2069
  if (!ent.isDirectory()) continue;
1970
2070
  if (seen.has(ent.name)) continue;
1971
- const profilePath = path7.join(root, ent.name, CAPABILITY_PROFILE_FILE);
2071
+ const profilePath = implementationRuntimePath(root, ent.name);
1972
2072
  if (fs6.existsSync(profilePath) && fs6.statSync(profilePath).isFile() && isImplementationProfile(profilePath, requireImplementationProfile)) {
1973
2073
  out.push({ name: ent.name, profilePath });
1974
2074
  seen.add(ent.name);
@@ -1977,15 +2077,18 @@ function listImplementations(roots = getImplementationRoots()) {
1977
2077
  }
1978
2078
  return out.sort((a, b) => a.name.localeCompare(b.name));
1979
2079
  }
1980
- function resolveImplementation(name, roots = getImplementationRoots()) {
2080
+ function listRuntimeProfilesForCwd(cwd) {
2081
+ return listImplementations(getRuntimeProfileRootsForCwd(cwd));
2082
+ }
2083
+ function resolveImplementation(name, roots = getRuntimeProfileRootsForCwd(process.cwd())) {
1981
2084
  return resolveImplementationCandidates(name, roots)[0] ?? null;
1982
2085
  }
1983
- function resolveImplementationCandidates(name, roots = getImplementationRoots()) {
2086
+ function resolveImplementationCandidates(name, roots = getRuntimeProfileRootsForCwd(process.cwd())) {
1984
2087
  if (!isSafeName(name)) return [];
1985
2088
  const rootList = typeof roots === "string" ? [roots] : roots;
1986
2089
  const out = [];
1987
2090
  for (const root of rootList) {
1988
- const profilePath = path7.join(root, name, "profile.json");
2091
+ const profilePath = implementationRuntimePath(root, name);
1989
2092
  if (fs6.existsSync(profilePath) && fs6.statSync(profilePath).isFile() && isImplementationProfile(profilePath, isCapabilityRoot(root))) {
1990
2093
  out.push(profilePath);
1991
2094
  }
@@ -2023,9 +2126,43 @@ function resolveCapabilityFolder(slug, projectCapabilitiesRoot = getProjectCapab
2023
2126
  function getCapabilityActionInputs(action, projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
2024
2127
  const resolved = resolveCapabilityAction(action, projectCapabilitiesRoot);
2025
2128
  if (!resolved) return null;
2129
+ const capability = resolveCapabilityFolder(resolved.capability, projectCapabilitiesRoot);
2130
+ if (capability && path7.basename(capability.profilePath) === "definition.json") {
2131
+ const schema = capability.rawProfile.inputSchema;
2132
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) return [];
2133
+ const properties = schema.properties;
2134
+ if (!properties || typeof properties !== "object" || Array.isArray(properties)) return [];
2135
+ const required2 = new Set(
2136
+ Array.isArray(schema.required) ? schema.required.filter((value) => typeof value === "string") : []
2137
+ );
2138
+ return Object.entries(properties).map(([name, value]) => {
2139
+ const property = value && typeof value === "object" && !Array.isArray(value) ? value : {};
2140
+ const type = property.type === "integer" ? "int" : property.type === "boolean" ? "bool" : Array.isArray(property.enum) ? "enum" : "string";
2141
+ return {
2142
+ name,
2143
+ flag: `--${name}`,
2144
+ type,
2145
+ required: required2.has(name),
2146
+ ...type === "enum" && Array.isArray(property.enum) ? { values: property.enum.filter((item) => typeof item === "string") } : {},
2147
+ describe: typeof property.description === "string" ? property.description : name
2148
+ };
2149
+ });
2150
+ }
2026
2151
  return getProfileInputs(resolved.implementation);
2027
2152
  }
2028
2153
  function resolveCapabilityExecution(capability, cwd = process.cwd()) {
2154
+ if (path7.basename(capability.profilePath) === "definition.json") {
2155
+ const implementations = readExternalImplementations(cwd);
2156
+ const definition = JSON.parse(fs6.readFileSync(capability.profilePath, "utf-8"));
2157
+ const capabilityRevision = createHash2("sha256").update(canonical(definition)).digest("hex");
2158
+ const selected = resolveCapabilityImplementation({
2159
+ capabilityId: capability.slug,
2160
+ capabilityRevision,
2161
+ implementations,
2162
+ repositoryBinding: repositoryImplementationBinding(capability.slug, cwd)
2163
+ });
2164
+ return { implementation: selected.id, cliArgs: {} };
2165
+ }
2029
2166
  const firstWorkflowStep = capability.config.workflow?.steps[0];
2030
2167
  if (firstWorkflowStep) {
2031
2168
  const implementation2 = firstWorkflowStep.implementation ?? firstWorkflowStep.capability;
@@ -2035,11 +2172,42 @@ function resolveCapabilityExecution(capability, cwd = process.cwd()) {
2035
2172
  const cliArgs = implementationDeclaresInput(implementation, "capability", cwd) ? { capability: capability.slug } : {};
2036
2173
  return { implementation, cliArgs };
2037
2174
  }
2175
+ function repositoryImplementationBinding(capabilityId, cwd) {
2176
+ try {
2177
+ return loadConfig(cwd).execution?.capabilityBindings[capabilityId];
2178
+ } catch {
2179
+ return void 0;
2180
+ }
2181
+ }
2182
+ function readExternalImplementations(cwd) {
2183
+ const root = implementationsRoot(cwd);
2184
+ if (!fs6.existsSync(root)) return [];
2185
+ const definitions = [];
2186
+ for (const entry of fs6.readdirSync(root, { withFileTypes: true })) {
2187
+ if (!entry.isDirectory() || !isSafeName(entry.name)) continue;
2188
+ const definitionPath = path7.join(root, entry.name, "definition.json");
2189
+ if (!fs6.existsSync(definitionPath)) continue;
2190
+ try {
2191
+ const definition = JSON.parse(fs6.readFileSync(definitionPath, "utf-8"));
2192
+ definitions.push(definition);
2193
+ } catch {
2194
+ }
2195
+ }
2196
+ return definitions;
2197
+ }
2198
+ function canonical(value) {
2199
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
2200
+ if (value && typeof value === "object") {
2201
+ return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
2202
+ }
2203
+ return JSON.stringify(value);
2204
+ }
2038
2205
  function implementationDeclaresInput(implementation, inputName, cwd = process.cwd()) {
2039
- const profilePath = resolveImplementation(implementation, getImplementationRootsForCwd(cwd));
2206
+ const profilePath = resolveImplementation(implementation, getRuntimeProfileRootsForCwd(cwd));
2040
2207
  if (!profilePath) return false;
2041
2208
  try {
2042
- const raw = JSON.parse(fs6.readFileSync(profilePath, "utf-8"));
2209
+ const document = JSON.parse(fs6.readFileSync(profilePath, "utf-8"));
2210
+ const raw = document.config ?? document;
2043
2211
  if (!Array.isArray(raw.inputs)) return false;
2044
2212
  return raw.inputs.some((entry) => {
2045
2213
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
@@ -2059,6 +2227,10 @@ function isCapabilityRoot(root) {
2059
2227
  const knownRoots = [getProjectCapabilitiesRoot(), getBuiltinCapabilitiesRoot()];
2060
2228
  return knownRoots.some((candidate) => candidate && path7.normalize(candidate) === normalized);
2061
2229
  }
2230
+ function implementationRuntimePath(root, name) {
2231
+ const runtimePath = path7.join(root, name, "runtime.json");
2232
+ return fs6.existsSync(runtimePath) ? runtimePath : path7.join(root, name, CAPABILITY_PROFILE_FILE);
2233
+ }
2062
2234
  function isImplementationProfile(profilePath, requireImplementationProfile) {
2063
2235
  if (!requireImplementationProfile) return true;
2064
2236
  try {
@@ -2126,8 +2298,10 @@ function getProfileInputs(name, roots = getImplementationRoots()) {
2126
2298
  const profilePath = resolveImplementation(name, roots);
2127
2299
  if (!profilePath) return null;
2128
2300
  try {
2129
- const raw = JSON.parse(fs6.readFileSync(profilePath, "utf-8"));
2130
- if (!raw || typeof raw !== "object" || !Array.isArray(raw.inputs)) return [];
2301
+ const document = JSON.parse(fs6.readFileSync(profilePath, "utf-8"));
2302
+ if (!document || typeof document !== "object") return [];
2303
+ const raw = "config" in document && document.config && typeof document.config === "object" ? document.config : document;
2304
+ if (!Array.isArray(raw.inputs)) return [];
2131
2305
  return raw.inputs;
2132
2306
  } catch {
2133
2307
  return null;
@@ -2162,7 +2336,9 @@ var PUBLIC_IMPLEMENTATION_ROLES;
2162
2336
  var init_registry = __esm({
2163
2337
  "src/registry.ts"() {
2164
2338
  "use strict";
2339
+ init_implementation_resolution();
2165
2340
  init_capabilityFolders();
2341
+ init_config();
2166
2342
  init_definition_paths();
2167
2343
  PUBLIC_IMPLEMENTATION_ROLES = /* @__PURE__ */ new Set(["primitive", "orchestrator", "container", "watch", "utility"]);
2168
2344
  }
@@ -3256,7 +3432,7 @@ var init_repoWorkspace = __esm({
3256
3432
  defaultCloneRepo = (repo, token, dir) => {
3257
3433
  fs7.mkdirSync(path8.dirname(dir), { recursive: true });
3258
3434
  const clone = buildCloneProcess(repo, token);
3259
- return new Promise((resolve17, reject) => {
3435
+ return new Promise((resolve19, reject) => {
3260
3436
  const child = spawn2("git", ["clone", "--depth=1", clone.url, dir], {
3261
3437
  env: clone.env,
3262
3438
  stdio: "inherit"
@@ -3276,7 +3452,7 @@ var init_repoWorkspace = __esm({
3276
3452
  }
3277
3453
  } catch {
3278
3454
  }
3279
- resolve17();
3455
+ resolve19();
3280
3456
  });
3281
3457
  child.on("error", reject);
3282
3458
  });
@@ -3590,10 +3766,10 @@ async function runAgent(opts) {
3590
3766
  let timer;
3591
3767
  let next;
3592
3768
  if (turnTimeoutMs > 0) {
3593
- const timeoutPromise = new Promise((resolve17) => {
3769
+ const timeoutPromise = new Promise((resolve19) => {
3594
3770
  timer = setTimeout(() => {
3595
3771
  timedOut = true;
3596
- resolve17({ done: true, value: void 0 });
3772
+ resolve19({ done: true, value: void 0 });
3597
3773
  }, turnTimeoutMs);
3598
3774
  });
3599
3775
  next = await Promise.race([nextPromise, timeoutPromise]);
@@ -3609,7 +3785,7 @@ async function runAgent(opts) {
3609
3785
  try {
3610
3786
  await Promise.race([
3611
3787
  iterator.return(void 0).catch(() => void 0),
3612
- new Promise((resolve17) => setTimeout(resolve17, 1e4).unref())
3788
+ new Promise((resolve19) => setTimeout(resolve19, 1e4).unref())
3613
3789
  ]);
3614
3790
  } catch {
3615
3791
  }
@@ -4166,6 +4342,40 @@ var init_agencyBoundaryEval = __esm({
4166
4342
  }
4167
4343
  });
4168
4344
 
4345
+ // src/agency/capability-contract-validation.ts
4346
+ import Ajv from "ajv";
4347
+ function validateCapabilityContractValue(boundary, schema, value) {
4348
+ const validate = validator.compile(schema);
4349
+ if (!validate(value)) {
4350
+ throw new CapabilityContractValidationError(boundary, validate.errors ?? []);
4351
+ }
4352
+ }
4353
+ var validator, CapabilityContractValidationError;
4354
+ var init_capability_contract_validation = __esm({
4355
+ "src/agency/capability-contract-validation.ts"() {
4356
+ "use strict";
4357
+ validator = new Ajv({
4358
+ allErrors: true,
4359
+ strict: true,
4360
+ validateFormats: false
4361
+ });
4362
+ CapabilityContractValidationError = class extends Error {
4363
+ constructor(boundary, errors) {
4364
+ super(
4365
+ `Capability ${boundary} does not match its canonical contract: ${validator.errorsText([...errors], {
4366
+ separator: "; "
4367
+ })}`
4368
+ );
4369
+ this.boundary = boundary;
4370
+ this.errors = errors;
4371
+ this.name = "CapabilityContractValidationError";
4372
+ }
4373
+ boundary;
4374
+ errors;
4375
+ };
4376
+ }
4377
+ });
4378
+
4169
4379
  // src/capabilityReport.ts
4170
4380
  function parseCapabilityReportsFromText(text2) {
4171
4381
  const reports = [];
@@ -4603,10 +4813,12 @@ var init_buildSyntheticPlugin = __esm({
4603
4813
  const resolvePart = (bucket, entry) => {
4604
4814
  const local = path17.join(profile.dir, bucket, entry);
4605
4815
  if (fs18.existsSync(local)) return local;
4816
+ const shared = path17.resolve(profile.dir, "..", "..", "shared", bucket, entry);
4817
+ if (fs18.existsSync(shared)) return shared;
4606
4818
  const central = path17.join(catalog, bucket, entry);
4607
4819
  if (fs18.existsSync(central)) return central;
4608
4820
  throw new Error(
4609
- `buildSyntheticPlugin: ${bucket} entry '${entry}' not found in implementation dir (${profile.dir}/${bucket}/) or catalog (${catalog}/${bucket}/)`
4821
+ `buildSyntheticPlugin: ${bucket} entry '${entry}' not found in implementation dir (${profile.dir}/${bucket}/), Store shared assets (${path17.dirname(shared)}/), or catalog (${catalog}/${bucket}/)`
4610
4822
  );
4611
4823
  };
4612
4824
  if (cc.skills.length > 0) {
@@ -4670,9 +4882,13 @@ function splitFrontmatter(raw) {
4670
4882
  function resolveAgentFile2(profileDir, name) {
4671
4883
  const local = path18.join(profileDir, "agents", `${name}.md`);
4672
4884
  if (fs19.existsSync(local)) return local;
4885
+ const shared = path18.resolve(profileDir, "..", "..", "shared", "agents", `${name}.md`);
4886
+ if (fs19.existsSync(shared)) return shared;
4673
4887
  const central = path18.join(getPluginsCatalogRoot(), "agents", `${name}.md`);
4674
4888
  if (fs19.existsSync(central)) return central;
4675
- throw new Error(`loadSubagents: agent '${name}' not found in ${profileDir}/agents/ or shared catalog`);
4889
+ throw new Error(
4890
+ `loadSubagents: agent '${name}' not found in ${profileDir}/agents/, hydrated shared assets, or engine catalog`
4891
+ );
4676
4892
  }
4677
4893
  function captureSubagentTemplates(profile) {
4678
4894
  const names = profile.claudeCode.subagents;
@@ -4715,6 +4931,7 @@ var init_subagents = __esm({
4715
4931
  });
4716
4932
 
4717
4933
  // src/profile.ts
4934
+ import { createHash as createHash3 } from "crypto";
4718
4935
  import * as fs20 from "fs";
4719
4936
  import * as path19 from "path";
4720
4937
  function loadProfile(profilePath) {
@@ -4730,7 +4947,8 @@ function loadProfile(profilePath) {
4730
4947
  if (!raw || typeof raw !== "object") {
4731
4948
  throw new ProfileError(profilePath, "profile must be a JSON object");
4732
4949
  }
4733
- const r = raw;
4950
+ const document = raw;
4951
+ const r = compileRuntimeDocument(profilePath, document);
4734
4952
  const unknownKeys = Object.keys(r).filter((k) => !KNOWN_PROFILE_KEYS.has(k));
4735
4953
  if (unknownKeys.length > 0) {
4736
4954
  process.stderr.write(
@@ -4877,6 +5095,67 @@ function loadProfile(profilePath) {
4877
5095
  profile.subagentTemplates = captureSubagentTemplates(profile);
4878
5096
  return profile;
4879
5097
  }
5098
+ function compileRuntimeDocument(runtimePath, document) {
5099
+ if (path19.basename(runtimePath) !== "runtime.json") return document;
5100
+ if (document.adapter !== "kody-engine-profile") {
5101
+ throw new ProfileError(runtimePath, "unsupported runtime adapter document");
5102
+ }
5103
+ const implementationDir = path19.dirname(runtimePath);
5104
+ const implementation = readJsonObject(path19.join(implementationDir, "definition.json"), "Implementation definition");
5105
+ const definitionsRoot2 = path19.dirname(path19.dirname(implementationDir));
5106
+ const capabilityId = implementation.capabilityRef && typeof implementation.capabilityRef === "object" && !Array.isArray(implementation.capabilityRef) ? implementation.capabilityRef.id : void 0;
5107
+ if (typeof capabilityId !== "string" || !capabilityId) {
5108
+ throw new ProfileError(runtimePath, "Implementation capabilityRef is invalid");
5109
+ }
5110
+ const capability = readJsonObject(
5111
+ path19.join(definitionsRoot2, "capabilities", capabilityId, "definition.json"),
5112
+ "Capability definition"
5113
+ );
5114
+ const {
5115
+ adapter: _adapter,
5116
+ inputBindings: _inputBindings,
5117
+ outputBindings: _outputBindings,
5118
+ requirements: _requirements,
5119
+ config: nestedConfig,
5120
+ ...inlineConfig
5121
+ } = document;
5122
+ const config = nestedConfig && typeof nestedConfig === "object" && !Array.isArray(nestedConfig) ? nestedConfig : inlineConfig;
5123
+ const agentRef = implementation.agentRef && typeof implementation.agentRef === "object" && !Array.isArray(implementation.agentRef) ? implementation.agentRef.id : void 0;
5124
+ return {
5125
+ ...config,
5126
+ name: implementation.id,
5127
+ action: capability.action,
5128
+ describe: capability.purpose,
5129
+ inputs: config.inputs ?? [],
5130
+ agent: agentRef,
5131
+ canonicalContract: {
5132
+ capabilityId,
5133
+ capabilityRevision: createHash3("sha256").update(canonical2(capability)).digest("hex"),
5134
+ implementationId: String(implementation.id),
5135
+ implementationRevision: createHash3("sha256").update(canonical2(implementation)).digest("hex"),
5136
+ inputSchema: capability.inputSchema,
5137
+ outputSchema: capability.outputSchema
5138
+ }
5139
+ };
5140
+ }
5141
+ function canonical2(value) {
5142
+ if (Array.isArray(value)) return `[${value.map(canonical2).join(",")}]`;
5143
+ if (value && typeof value === "object") {
5144
+ return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${canonical2(item)}`).join(",")}}`;
5145
+ }
5146
+ return JSON.stringify(value);
5147
+ }
5148
+ function readJsonObject(filePath, label) {
5149
+ try {
5150
+ const value = JSON.parse(fs20.readFileSync(filePath, "utf-8"));
5151
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
5152
+ throw new Error("must be an object");
5153
+ }
5154
+ return value;
5155
+ } catch (error) {
5156
+ throw new ProfileError(filePath, `${label} is invalid: ${error instanceof Error ? error.message : String(error)}`);
5157
+ }
5158
+ }
4880
5159
  function parseCapabilityToolMode2(profilePath, raw) {
4881
5160
  if (raw === void 0 || raw === null || raw === "") return void 0;
4882
5161
  if (raw === "lock" || raw === "append") return raw;
@@ -5256,6 +5535,7 @@ var init_profile = __esm({
5256
5535
  VALID_CONTAINER_CHILD_TARGETS = /* @__PURE__ */ new Set(["issue", "pr"]);
5257
5536
  VALID_PHASES = /* @__PURE__ */ new Set(["research", "planning", "implementing", "reviewing", "shipped", "failed", "idle"]);
5258
5537
  KNOWN_PROFILE_KEYS = /* @__PURE__ */ new Set([
5538
+ "canonicalContract",
5259
5539
  "name",
5260
5540
  "action",
5261
5541
  "implementation",
@@ -6779,11 +7059,11 @@ async function nextAvailableLitellmUrl(url) {
6779
7059
  throw new Error(`no free LiteLLM port found after ${startPort}`);
6780
7060
  }
6781
7061
  function canListen(port, host) {
6782
- return new Promise((resolve17) => {
7062
+ return new Promise((resolve19) => {
6783
7063
  const server = net.createServer();
6784
- server.once("error", () => resolve17(false));
7064
+ server.once("error", () => resolve19(false));
6785
7065
  server.once("listening", () => {
6786
- server.close(() => resolve17(true));
7066
+ server.close(() => resolve19(true));
6787
7067
  });
6788
7068
  server.listen(port, host);
6789
7069
  });
@@ -6899,6 +7179,9 @@ function runIndexRowFromJobContext(input) {
6899
7179
  capability: stringValue(input.data.jobCapability) ?? void 0,
6900
7180
  workflow: workflow ?? void 0,
6901
7181
  implementation: stringValue(input.data.selectedImplementation) ?? input.profileName,
7182
+ parentRunId: stringValue(input.data.parentRunId) ?? void 0,
7183
+ capabilityRevision: stringValue(input.data.capabilityRevision) ?? void 0,
7184
+ implementationRevision: stringValue(input.data.implementationRevision) ?? void 0,
6902
7185
  agent: stringValue(input.data.jobAgent) ?? input.profile.agent ?? void 0,
6903
7186
  model: stringValue(input.data.jobModel) ?? void 0,
6904
7187
  modelProvider: stringValue(input.data.jobModelProvider) ?? void 0,
@@ -6963,7 +7246,7 @@ function statusFromExitCode(exitCode) {
6963
7246
  return exitCode === 0 ? "success" : "failed";
6964
7247
  }
6965
7248
  function isRunSubjectType(value) {
6966
- return value === "goal" || value === "loop" || value === "workflow";
7249
+ return value === "goal" || value === "loop" || value === "workflow" || value === "capability";
6967
7250
  }
6968
7251
  function stagedRunIndexRows(data) {
6969
7252
  const value = data[STAGED_RUN_INDEX_ROWS_KEY];
@@ -8472,9 +8755,9 @@ function goalInstanceTime(state) {
8472
8755
  return Number.isNaN(parsed) ? 0 : parsed;
8473
8756
  }
8474
8757
  function loadGoalTemplate(cwd, targetId) {
8475
- return readJsonObject(path24.join(cwd, ".kody-engine", "definitions", "goals", targetId, "state.json"));
8758
+ return readJsonObject2(path24.join(cwd, ".kody-engine", "definitions", "goals", targetId, "state.json"));
8476
8759
  }
8477
- function readJsonObject(filePath) {
8760
+ function readJsonObject2(filePath) {
8478
8761
  if (!fs27.existsSync(filePath)) return null;
8479
8762
  const parsed = JSON.parse(fs27.readFileSync(filePath, "utf8"));
8480
8763
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
@@ -9504,6 +9787,7 @@ async function planGoalCapabilitySchedule(opts) {
9504
9787
  capability2,
9505
9788
  slug,
9506
9789
  backend,
9790
+ opts.cwd,
9507
9791
  opts.previousScheduleState?.capabilities[slug]
9508
9792
  );
9509
9793
  statuses[slug] = status;
@@ -9558,21 +9842,19 @@ async function planGoalCapabilitySchedule(opts) {
9558
9842
  }
9559
9843
  };
9560
9844
  }
9561
- async function describeCapabilitySchedule(capability, slug, backend, previous) {
9845
+ async function describeCapabilitySchedule(capability, slug, backend, cwd, previous) {
9562
9846
  if (!capability) return { slug, state: "blocked", reason: "capability folder missing" };
9563
- const { config } = capability;
9564
- if (config.disabled === true) {
9847
+ if (capability.config.disabled === true) {
9565
9848
  return { slug, title: capability.title, state: "disabled", reason: "disabled" };
9566
9849
  }
9567
- if (!config.agent || config.agent.trim().length === 0) {
9568
- return { slug, title: capability.title, state: "blocked", reason: "no agent assigned" };
9569
- }
9570
- if (config.implementations && config.implementations.length > 1) {
9850
+ try {
9851
+ resolveCapabilityExecution(capability, cwd);
9852
+ } catch (error) {
9571
9853
  return {
9572
9854
  slug,
9573
9855
  title: capability.title,
9574
9856
  state: "blocked",
9575
- reason: "multi-implementation capability needs task-jobs route"
9857
+ reason: error instanceof Error ? error.message : "Implementation unavailable"
9576
9858
  };
9577
9859
  }
9578
9860
  let lastFiredAt = validIso(previous?.lastFiredAt) ? previous?.lastFiredAt : void 0;
@@ -13242,7 +13524,7 @@ var init_triggerDispatcher = __esm({
13242
13524
  });
13243
13525
 
13244
13526
  // src/goal/policyResolver.ts
13245
- import { createHash as createHash2 } from "crypto";
13527
+ import { createHash as createHash4 } from "crypto";
13246
13528
  function resolveDispatchPolicy(input) {
13247
13529
  const operation = input.catalog.operations.get(input.owner.definition.operationId);
13248
13530
  if (!operation) throw new Error(`Dispatch blocked: Operation "${input.owner.definition.operationId}" is unresolved`);
@@ -13260,7 +13542,7 @@ function resolveDispatchPolicy(input) {
13260
13542
  const snapshotValue = { policy, constraints };
13261
13543
  return {
13262
13544
  snapshot: {
13263
- hash: createHash2("sha256").update(stableJson(snapshotValue)).digest("hex"),
13545
+ hash: createHash4("sha256").update(stableJson(snapshotValue)).digest("hex"),
13264
13546
  ...snapshotValue
13265
13547
  },
13266
13548
  operation,
@@ -13602,10 +13884,10 @@ async function runAttempt(run, job, timeoutSeconds) {
13602
13884
  exitCode: 99,
13603
13885
  reason: error instanceof Error ? error.message : String(error)
13604
13886
  })),
13605
- new Promise((resolve17) => {
13887
+ new Promise((resolve19) => {
13606
13888
  timer = setTimeout(() => {
13607
13889
  abortController.abort();
13608
- resolve17({ exitCode: 124, reason: `target timed out after ${formatSeconds(timeoutSeconds)}s` });
13890
+ resolve19({ exitCode: 124, reason: `target timed out after ${formatSeconds(timeoutSeconds)}s` });
13609
13891
  }, timeoutSeconds * 1e3);
13610
13892
  })
13611
13893
  ]);
@@ -13645,7 +13927,7 @@ function formatSeconds(seconds) {
13645
13927
  }
13646
13928
  async function wait(milliseconds) {
13647
13929
  if (milliseconds <= 0) return;
13648
- await new Promise((resolve17) => setTimeout(resolve17, milliseconds));
13930
+ await new Promise((resolve19) => setTimeout(resolve19, milliseconds));
13649
13931
  }
13650
13932
  function repositoryTenant(config) {
13651
13933
  const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
@@ -14825,7 +15107,7 @@ function performInit(cwd, force) {
14825
15107
  fs36.writeFileSync(workflowPath, loadKodyWorkflowTemplate());
14826
15108
  wrote.push(".github/workflows/kody.yml");
14827
15109
  }
14828
- for (const exe of listImplementations()) {
15110
+ for (const exe of listRuntimeProfilesForCwd(cwd)) {
14829
15111
  let profile;
14830
15112
  try {
14831
15113
  profile = loadProfile(exe.profilePath);
@@ -15233,7 +15515,7 @@ function retryDelaysMs() {
15233
15515
  }
15234
15516
  function sleep(ms) {
15235
15517
  if (ms <= 0) return Promise.resolve();
15236
- return new Promise((resolve17) => setTimeout(resolve17, ms));
15518
+ return new Promise((resolve19) => setTimeout(resolve19, ms));
15237
15519
  }
15238
15520
  async function fetchGoalStateWithRetry(config, goalId, cwd) {
15239
15521
  let state = await fetchGoalStateAsync(config, goalId, cwd);
@@ -15531,9 +15813,9 @@ var init_kodyVariables = __esm({
15531
15813
  });
15532
15814
 
15533
15815
  // src/backendVault.ts
15534
- import { createDecipheriv, createHash as createHash3 } from "crypto";
15816
+ import { createDecipheriv, createHash as createHash5 } from "crypto";
15535
15817
  function cacheKey(owner, repo, masterKey) {
15536
- const keyHash = createHash3("sha256").update(masterKey).digest("hex").slice(0, 16);
15818
+ const keyHash = createHash5("sha256").update(masterKey).digest("hex").slice(0, 16);
15537
15819
  return `${owner}/${repo}:${keyHash}`.toLowerCase();
15538
15820
  }
15539
15821
  function decryptVault(payload, masterKey) {
@@ -16182,7 +16464,7 @@ var init_notifyTerminal = __esm({
16182
16464
  });
16183
16465
 
16184
16466
  // src/scripts/openAgencyModelReviewPr.ts
16185
- import { createHash as createHash4 } from "crypto";
16467
+ import { createHash as createHash6 } from "crypto";
16186
16468
  function parseAgencyModelProposal(raw) {
16187
16469
  const text2 = raw.trim();
16188
16470
  const jsonText = (text2.match(/^```(?:json)?\s*\n([\s\S]*?)\n```$/i)?.[1] ?? text2).trim();
@@ -16234,7 +16516,7 @@ function normalizeBundleFiles(bundle) {
16234
16516
  });
16235
16517
  }
16236
16518
  function buildProposalId(issueNumber, bundle, sourceLabel) {
16237
- const digest = createHash4("sha256").update(JSON.stringify({ issueNumber, sourceLabel, title: bundle.title, files: normalizeBundleFiles(bundle) })).digest("hex").slice(0, 16);
16519
+ const digest = createHash6("sha256").update(JSON.stringify({ issueNumber, sourceLabel, title: bundle.title, files: normalizeBundleFiles(bundle) })).digest("hex").slice(0, 16);
16238
16520
  return `issue-${issueNumber}-${digest}`;
16239
16521
  }
16240
16522
  function isDryRun(ctx) {
@@ -18306,9 +18588,9 @@ var init_runFlow = __esm({
18306
18588
  });
18307
18589
 
18308
18590
  // src/scripts/previewBuildHelpers.ts
18309
- import { createDecipheriv as createDecipheriv2, createHash as createHash5, hkdfSync as hkdfSync2 } from "crypto";
18591
+ import { createDecipheriv as createDecipheriv2, createHash as createHash7, hkdfSync as hkdfSync2 } from "crypto";
18310
18592
  function shortHash(s) {
18311
- return createHash5("sha256").update(s).digest("hex").slice(0, 6);
18593
+ return createHash7("sha256").update(s).digest("hex").slice(0, 6);
18312
18594
  }
18313
18595
  function previewAppName(repo, pr) {
18314
18596
  const [owner, name] = repo.split("/");
@@ -18341,7 +18623,7 @@ function formatPreviewComment(args) {
18341
18623
  ].join("\n");
18342
18624
  }
18343
18625
  function defaultImageTag(repo, ref) {
18344
- return createHash5("sha256").update(`${repo}@${ref}`).digest("hex").slice(0, 12);
18626
+ return createHash7("sha256").update(`${repo}@${ref}`).digest("hex").slice(0, 12);
18345
18627
  }
18346
18628
  var init_previewBuildHelpers = __esm({
18347
18629
  "src/scripts/previewBuildHelpers.ts"() {
@@ -18352,7 +18634,7 @@ var init_previewBuildHelpers = __esm({
18352
18634
  // src/scripts/previewBuildRun.ts
18353
18635
  import { spawn as spawn5 } from "child_process";
18354
18636
  async function runCmd(cmd, args, opts = {}) {
18355
- await new Promise((resolve17, reject) => {
18637
+ await new Promise((resolve19, reject) => {
18356
18638
  const child = spawn5(cmd, args, {
18357
18639
  cwd: opts.cwd,
18358
18640
  env: { ...process.env, ...opts.env ?? {} },
@@ -18364,7 +18646,7 @@ async function runCmd(cmd, args, opts = {}) {
18364
18646
  }
18365
18647
  child.on("error", reject);
18366
18648
  child.on("close", (code) => {
18367
- if (code === 0) resolve17();
18649
+ if (code === 0) resolve19();
18368
18650
  else reject(new Error(`${cmd} ${args.join(" ")} exited ${code}`));
18369
18651
  });
18370
18652
  });
@@ -19628,7 +19910,7 @@ function stripAnsi2(s) {
19628
19910
  return s.replace(ANSI_RE2, "");
19629
19911
  }
19630
19912
  function runCommand2(command, cwd) {
19631
- return new Promise((resolve17) => {
19913
+ return new Promise((resolve19) => {
19632
19914
  const child = spawn6(command, {
19633
19915
  cwd,
19634
19916
  shell: true,
@@ -19655,11 +19937,11 @@ function runCommand2(command, cwd) {
19655
19937
  }, TEST_TIMEOUT_MS);
19656
19938
  child.on("exit", (code) => {
19657
19939
  clearTimeout(timer);
19658
- resolve17({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
19940
+ resolve19({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
19659
19941
  });
19660
19942
  child.on("error", (err) => {
19661
19943
  clearTimeout(timer);
19662
- resolve17({ exitCode: -1, output: err.message });
19944
+ resolve19({ exitCode: -1, output: err.message });
19663
19945
  });
19664
19946
  });
19665
19947
  }
@@ -20065,21 +20347,21 @@ function lineStream(stream) {
20065
20347
  tryDeliver();
20066
20348
  });
20067
20349
  return {
20068
- next: (timeoutMs) => new Promise((resolve17) => {
20350
+ next: (timeoutMs) => new Promise((resolve19) => {
20069
20351
  if (queue.length > 0) {
20070
- resolve17(queue.shift());
20352
+ resolve19(queue.shift());
20071
20353
  return;
20072
20354
  }
20073
20355
  if (ended) {
20074
- resolve17(null);
20356
+ resolve19(null);
20075
20357
  return;
20076
20358
  }
20077
- waiter = resolve17;
20359
+ waiter = resolve19;
20078
20360
  const t = setTimeout(
20079
20361
  () => {
20080
- if (waiter === resolve17) {
20362
+ if (waiter === resolve19) {
20081
20363
  waiter = null;
20082
- resolve17(null);
20364
+ resolve19(null);
20083
20365
  }
20084
20366
  },
20085
20367
  Math.max(0, timeoutMs)
@@ -20747,6 +21029,9 @@ async function runImplementation(profileName, input) {
20747
21029
  let args;
20748
21030
  try {
20749
21031
  args = validateInputs(profile.inputs, input.cliArgs);
21032
+ if (profile.canonicalContract) {
21033
+ validateCapabilityContractValue("input", profile.canonicalContract.inputSchema, args);
21034
+ }
20750
21035
  } catch (err) {
20751
21036
  return finishAndEnd({ exitCode: 64, reason: err instanceof Error ? err.message : String(err) });
20752
21037
  }
@@ -20807,6 +21092,12 @@ async function runImplementation(profileName, input) {
20807
21092
  ctx.data.jobModelProvider = model.provider;
20808
21093
  ctx.data.jobModelName = model.model;
20809
21094
  if (reasoningEffort) ctx.data.jobReasoningEffort = reasoningEffort;
21095
+ if (profile.canonicalContract) {
21096
+ ctx.data.jobCapability = profile.canonicalContract.capabilityId;
21097
+ ctx.data.selectedImplementation = profile.canonicalContract.implementationId;
21098
+ ctx.data.capabilityRevision = profile.canonicalContract.capabilityRevision;
21099
+ ctx.data.implementationRevision = profile.canonicalContract.implementationRevision;
21100
+ }
20810
21101
  const runIndexStartedAt = new Date(stageStartedAt).toISOString();
20811
21102
  if (!input.skipConfig) {
20812
21103
  await upsertRunIndexRowBestEffortAsync(
@@ -21116,6 +21407,25 @@ async function runImplementation(profileName, input) {
21116
21407
  outcome: postOutcome
21117
21408
  });
21118
21409
  }
21410
+ const capabilityResults = Array.isArray(ctx.data.capabilityResults) ? ctx.data.capabilityResults : void 0;
21411
+ if (profile.canonicalContract) {
21412
+ try {
21413
+ validateCapabilityContractValue(
21414
+ "output",
21415
+ profile.canonicalContract.outputSchema,
21416
+ capabilityResults?.at(-1) ?? {
21417
+ exitCode: ctx.output.exitCode ?? 0,
21418
+ reason: ctx.output.reason,
21419
+ prUrl: ctx.output.prUrl
21420
+ }
21421
+ );
21422
+ } catch (error) {
21423
+ return finishAndEnd({
21424
+ exitCode: 99,
21425
+ reason: error instanceof Error ? error.message : String(error)
21426
+ });
21427
+ }
21428
+ }
21119
21429
  return finishAndEnd({
21120
21430
  exitCode: ctx.output.exitCode ?? 0,
21121
21431
  prUrl: ctx.output.prUrl,
@@ -21124,7 +21434,7 @@ async function runImplementation(profileName, input) {
21124
21434
  nextJob: ctx.output.nextJob,
21125
21435
  afterNextJob: ctx.output.afterNextJob,
21126
21436
  taskState: ctx.data.taskState,
21127
- capabilityResults: Array.isArray(ctx.data.capabilityResults) ? ctx.data.capabilityResults : void 0
21437
+ capabilityResults
21128
21438
  });
21129
21439
  } catch (err) {
21130
21440
  const msg = err instanceof Error ? err.message : String(err);
@@ -21311,7 +21621,7 @@ function clearStampedLifecycleLabels(profile, ctx) {
21311
21621
  }
21312
21622
  }
21313
21623
  function resolveProfilePath(profileName, cwd = process.cwd()) {
21314
- const found = resolveImplementation(profileName, getImplementationRootsForCwd(cwd));
21624
+ const found = resolveImplementation(profileName, getRuntimeProfileRootsForCwd(cwd));
21315
21625
  if (found) return found;
21316
21626
  const here = path45.dirname(new URL(import.meta.url).pathname);
21317
21627
  const candidates = [
@@ -21328,10 +21638,7 @@ function resolveProfilePath(profileName, cwd = process.cwd()) {
21328
21638
  return candidates[0];
21329
21639
  }
21330
21640
  function loadRunnableProfile(profileName, cwd) {
21331
- const candidates = resolveImplementationCandidates(
21332
- profileName,
21333
- getImplementationRootsForCwd(cwd)
21334
- );
21641
+ const candidates = resolveImplementationCandidates(profileName, getRuntimeProfileRootsForCwd(cwd));
21335
21642
  const skipped = [];
21336
21643
  for (const profilePath2 of candidates) {
21337
21644
  const profile2 = loadProfile(profilePath2);
@@ -21484,14 +21791,14 @@ async function runShellEntry(entry, ctx, profile) {
21484
21791
  let killTimer;
21485
21792
  let escalateTimer;
21486
21793
  const result = await new Promise(
21487
- (resolve17) => {
21794
+ (resolve19) => {
21488
21795
  let settled = false;
21489
21796
  const settle = (code, signal, spawnErr) => {
21490
21797
  if (settled) return;
21491
21798
  settled = true;
21492
21799
  if (killTimer) clearTimeout(killTimer);
21493
21800
  if (escalateTimer) clearTimeout(escalateTimer);
21494
- resolve17({ code, signal, spawnErr });
21801
+ resolve19({ code, signal, spawnErr });
21495
21802
  };
21496
21803
  child.on("error", (err) => settle(null, null, err));
21497
21804
  child.on("close", (code, signal) => settle(code, signal));
@@ -21583,6 +21890,7 @@ var MUTATING_POSTFLIGHTS, SHELL_MARKER_RE, TASK_ARTIFACT_WRITE_TOOLS, MAX_CHAIN_
21583
21890
  var init_executor = __esm({
21584
21891
  "src/executor.ts"() {
21585
21892
  "use strict";
21893
+ init_capability_contract_validation();
21586
21894
  init_agent();
21587
21895
  init_agents();
21588
21896
  init_capabilityReport();
@@ -21786,7 +22094,52 @@ async function runJob(job, base) {
21786
22094
  ...valid.workflowState ?? persistedState ? { workflowState: valid.workflowState ?? persistedState ?? void 0 } : {}
21787
22095
  };
21788
22096
  const checkpoint = valid.workflowRunId && workflowIdentity && base.config ? (state) => writeWorkflowRunState(base.config, base.cwd, workflowIdentity, valid.workflowRunId, state) : void 0;
21789
- const result = await runCapabilityWorkflow(workflowJob, workflow, workflowCapability, base, checkpoint);
22097
+ const parentRunId = `workflow:${workflowIdentity}:${valid.workflowRunId ?? newJobId(valid.flavor)}`;
22098
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
22099
+ const parentRow = {
22100
+ version: 1,
22101
+ id: parentRunId,
22102
+ subjectType: "workflow",
22103
+ subjectId: workflowIdentity,
22104
+ subjectLabel: workflowCapability.title,
22105
+ status: "running",
22106
+ title: workflowCapability.title,
22107
+ startedAt,
22108
+ updatedAt: startedAt,
22109
+ workflow: workflowIdentity,
22110
+ kodyRunId: valid.workflowRunId,
22111
+ sourceType: "job"
22112
+ };
22113
+ const persistRun = Boolean(base.config && !base.skipConfig && hasStateBackendConfig());
22114
+ if (base.config && persistRun) {
22115
+ await upsertRunIndexRowBestEffortAsync(base.config, base.cwd, parentRow);
22116
+ }
22117
+ const workflowBase = {
22118
+ ...base,
22119
+ preloadedData: { ...base.preloadedData ?? {}, parentRunId }
22120
+ };
22121
+ let result;
22122
+ try {
22123
+ result = await runCapabilityWorkflow(workflowJob, workflow, workflowCapability, workflowBase, checkpoint);
22124
+ } catch (error) {
22125
+ if (base.config && persistRun) {
22126
+ await upsertRunIndexRowBestEffortAsync(base.config, base.cwd, {
22127
+ ...parentRow,
22128
+ status: "failed",
22129
+ summary: error instanceof Error ? error.message : String(error),
22130
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
22131
+ });
22132
+ }
22133
+ throw error;
22134
+ }
22135
+ if (base.config && persistRun) {
22136
+ await upsertRunIndexRowBestEffortAsync(base.config, base.cwd, {
22137
+ ...parentRow,
22138
+ status: result.exitCode === 0 ? "success" : "failed",
22139
+ summary: result.reason,
22140
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
22141
+ });
22142
+ }
21790
22143
  if (valid.workflowRunId && workflowIdentity && base.config && result.workflowState) {
21791
22144
  await writeWorkflowRunState(base.config, base.cwd, workflowIdentity, valid.workflowRunId, result.workflowState);
21792
22145
  }
@@ -21926,6 +22279,9 @@ async function runLinearCapabilityWorkflow(parent, workflow, capability, base) {
21926
22279
  ...base,
21927
22280
  preloadedData: {
21928
22281
  ...chainData,
22282
+ runSubjectType: "capability",
22283
+ runSubjectId: step.capability,
22284
+ runSubjectLabel: label,
21929
22285
  workflowStep: label,
21930
22286
  workflowStepIndex: index + 1,
21931
22287
  workflowStepReason: step.reason,
@@ -22070,6 +22426,9 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
22070
22426
  ...base,
22071
22427
  preloadedData: {
22072
22428
  ...chainData,
22429
+ runSubjectType: "capability",
22430
+ runSubjectId: step.capability,
22431
+ runSubjectLabel: step.id,
22073
22432
  workflowStep: step.id,
22074
22433
  workflowStepIndex: index + 1,
22075
22434
  workflowStepReason: step.reason,
@@ -22323,7 +22682,7 @@ function hydratedCapabilitiesRoot(cwd) {
22323
22682
  return path46.join(cwd, ".kody-engine", "definitions", "capabilities");
22324
22683
  }
22325
22684
  function loadWorkflowContext(slug, base) {
22326
- if (!slug || !base.config || !isWorkflowDefinitionId(slug)) return null;
22685
+ if (!slug || !isWorkflowDefinitionId(slug)) return null;
22327
22686
  const workflow = readWorkflowDefinition(base.config, base.cwd, slug);
22328
22687
  return workflow ? workflowDefinitionToCapabilityFolder(slug, workflow) : null;
22329
22688
  }
@@ -22359,6 +22718,8 @@ var init_job = __esm({
22359
22718
  init_capabilityFolders();
22360
22719
  init_executor();
22361
22720
  init_registry();
22721
+ init_runIndex();
22722
+ init_state_backend();
22362
22723
  init_workflowDefinitions();
22363
22724
  init_workflowRunState();
22364
22725
  init_workflowValidation();
@@ -22637,9 +22998,9 @@ var CodexAppServerClient = class {
22637
22998
  await this.request("thread/resume", { threadId });
22638
22999
  }
22639
23000
  async runTurn(args) {
22640
- await new Promise((resolve17, reject) => {
23001
+ await new Promise((resolve19, reject) => {
22641
23002
  this.process.turnWaiters.set(args.threadId, {
22642
- resolve: resolve17,
23003
+ resolve: resolve19,
22643
23004
  reject,
22644
23005
  onNotification: args.onNotification,
22645
23006
  queue: Promise.resolve()
@@ -22656,8 +23017,8 @@ var CodexAppServerClient = class {
22656
23017
  }
22657
23018
  request(method, params) {
22658
23019
  const id = this.process.nextId++;
22659
- return new Promise((resolve17, reject) => {
22660
- this.process.pending.set(id, { resolve: resolve17, reject });
23020
+ return new Promise((resolve19, reject) => {
23021
+ this.process.pending.set(id, { resolve: resolve19, reject });
22661
23022
  this.process.child.stdin.write(`${JSON.stringify({ method, id, params })}
22662
23023
  `);
22663
23024
  });
@@ -23941,7 +24302,7 @@ function dispatchScheduledWatches(opts) {
23941
24302
  const envWindow = Number(process.env.KODY_SCHEDULE_WINDOW_SEC);
23942
24303
  const windowSec = opts?.windowSec ?? (Number.isFinite(envWindow) && envWindow > 0 ? envWindow : 300);
23943
24304
  const out = [];
23944
- for (const exe of listImplementations()) {
24305
+ for (const exe of listRuntimeProfilesForCwd(opts?.cwd ?? process.cwd())) {
23945
24306
  let raw;
23946
24307
  try {
23947
24308
  raw = fs16.readFileSync(exe.profilePath, "utf-8");
@@ -24535,8 +24896,14 @@ async function runCi(argv) {
24535
24896
  if (noTarget && capabilityInput) {
24536
24897
  forceRunAction = capabilityInput;
24537
24898
  if (messageInput) {
24538
- const route = resolveCapabilityAction(capabilityInput);
24539
- const textInputs = route?.implementation ? (getProfileInputs(route.implementation) ?? []).filter(
24899
+ const route = resolveCapabilityAction(
24900
+ capabilityInput,
24901
+ capabilitiesRoot(cwd)
24902
+ );
24903
+ const textInputs = route?.implementation ? (getProfileInputs(
24904
+ route.implementation,
24905
+ getRuntimeProfileRootsForCwd(cwd)
24906
+ ) ?? []).filter(
24540
24907
  (input) => input.type === "string"
24541
24908
  ) : [];
24542
24909
  if (textInputs.length === 1) {
@@ -24569,7 +24936,7 @@ async function runCi(argv) {
24569
24936
  workflow: forceRunAction,
24570
24937
  cliArgs: {}
24571
24938
  };
24572
- const scheduledWatchRoute = manualGoalManager || capabilityRoute || workflowRoute ? void 0 : dispatchScheduledWatches({ force: true }).find(
24939
+ const scheduledWatchRoute = manualGoalManager || capabilityRoute || workflowRoute ? void 0 : dispatchScheduledWatches({ force: true, cwd }).find(
24573
24940
  (match) => match.action === forceRunAction || match.capability === forceRunAction || match.implementation === forceRunAction
24574
24941
  );
24575
24942
  const route = manualGoalManager ? {
@@ -24822,7 +25189,10 @@ ${CI_HELP}`);
24822
25189
  }
24823
25190
  }
24824
25191
  async function runScheduledFanOut(cwd, args, opts) {
24825
- const matches = dispatchScheduledWatches({ force: opts.force });
25192
+ const matches = dispatchScheduledWatches({
25193
+ force: opts.force,
25194
+ cwd
25195
+ });
24826
25196
  if (matches.length === 0) {
24827
25197
  process.stdout.write(
24828
25198
  `\u2192 kody: scheduled wake \u2014 no watches matched ${opts.force ? "(force mode, no watches discovered)" : "(window)"}, exiting cleanly
@@ -25109,17 +25479,17 @@ function authOk(req, expected) {
25109
25479
  return false;
25110
25480
  }
25111
25481
  function readJsonBody(req) {
25112
- return new Promise((resolve17, reject) => {
25482
+ return new Promise((resolve19, reject) => {
25113
25483
  const chunks = [];
25114
25484
  req.on("data", (c) => chunks.push(c));
25115
25485
  req.on("end", () => {
25116
25486
  const raw = Buffer.concat(chunks).toString("utf-8");
25117
25487
  if (!raw.trim()) {
25118
- resolve17({});
25488
+ resolve19({});
25119
25489
  return;
25120
25490
  }
25121
25491
  try {
25122
- resolve17(JSON.parse(raw));
25492
+ resolve19(JSON.parse(raw));
25123
25493
  } catch (err) {
25124
25494
  reject(err instanceof Error ? err : new Error(String(err)));
25125
25495
  }
@@ -25459,11 +25829,11 @@ async function brainServe(opts) {
25459
25829
  litellmUrl,
25460
25830
  driver
25461
25831
  });
25462
- await new Promise((resolve17) => {
25832
+ await new Promise((resolve19) => {
25463
25833
  server.listen(port, "0.0.0.0", () => {
25464
25834
  process.stdout.write(`[brain-serve] listening on 0.0.0.0:${port} (cwd=${opts.cwd})
25465
25835
  `);
25466
- resolve17();
25836
+ resolve19();
25467
25837
  });
25468
25838
  });
25469
25839
  const shutdown = (signal) => {
@@ -25718,14 +26088,14 @@ async function startBrainProxy(opts) {
25718
26088
  const { httpServer, handler } = buildBrainProxy(opts);
25719
26089
  const port = opts.port ?? 0;
25720
26090
  const host = opts.host ?? "127.0.0.1";
25721
- await new Promise((resolve17) => httpServer.listen(port, host, () => resolve17()));
26091
+ await new Promise((resolve19) => httpServer.listen(port, host, () => resolve19()));
25722
26092
  const addr = httpServer.address();
25723
26093
  return {
25724
26094
  httpServer,
25725
26095
  port: addr.port,
25726
26096
  url: `http://${host}:${addr.port}`,
25727
- stop: () => new Promise((resolve17) => {
25728
- httpServer.close(() => resolve17());
26097
+ stop: () => new Promise((resolve19) => {
26098
+ httpServer.close(() => resolve19());
25729
26099
  }),
25730
26100
  handler
25731
26101
  };
@@ -25875,23 +26245,23 @@ function buildMcpHttpServer(opts) {
25875
26245
  httpServer,
25876
26246
  routes,
25877
26247
  port,
25878
- stop: () => new Promise((resolve17) => {
26248
+ stop: () => new Promise((resolve19) => {
25879
26249
  let pending = transports.size;
25880
26250
  if (pending === 0) {
25881
- httpServer.close(() => resolve17());
26251
+ httpServer.close(() => resolve19());
25882
26252
  return;
25883
26253
  }
25884
26254
  for (const transport of transports.values()) {
25885
26255
  void transport.close().finally(() => {
25886
26256
  pending--;
25887
- if (pending === 0) httpServer.close(() => resolve17());
26257
+ if (pending === 0) httpServer.close(() => resolve19());
25888
26258
  });
25889
26259
  }
25890
26260
  })
25891
26261
  };
25892
26262
  }
25893
26263
  function listenMcpHttpServer(server, host = "127.0.0.1") {
25894
- return new Promise((resolve17, reject) => {
26264
+ return new Promise((resolve19, reject) => {
25895
26265
  server.httpServer.once("error", reject);
25896
26266
  server.httpServer.listen(server.port, host, () => {
25897
26267
  server.httpServer.off("error", reject);
@@ -25899,7 +26269,7 @@ function listenMcpHttpServer(server, host = "127.0.0.1") {
25899
26269
  if (addr && typeof addr === "object") {
25900
26270
  server.port = addr.port;
25901
26271
  }
25902
- resolve17();
26272
+ resolve19();
25903
26273
  });
25904
26274
  });
25905
26275
  }
@@ -26049,7 +26419,7 @@ async function waitForNextUserMessage(opts) {
26049
26419
  }
26050
26420
  }
26051
26421
  function sleep3(ms) {
26052
- return new Promise((resolve17) => setTimeout(resolve17, ms));
26422
+ return new Promise((resolve19) => setTimeout(resolve19, ms));
26053
26423
  }
26054
26424
  function currentBranch(cwd) {
26055
26425
  try {
@@ -26384,10 +26754,10 @@ init_definition_paths();
26384
26754
 
26385
26755
  // src/definition-hydration.ts
26386
26756
  init_state_backend();
26387
- import { createHash as createHash6 } from "crypto";
26757
+ import { createHash as createHash8 } from "crypto";
26388
26758
  import * as fs50 from "fs";
26389
26759
  import * as path51 from "path";
26390
- var SLUG_RE2 = /^[a-z0-9][a-z0-9_-]{0,63}$/;
26760
+ var SLUG_RE2 = /^[a-z0-9][a-z0-9_-]{0,127}$/;
26391
26761
  function assertSafeDefinitionPath(filePath) {
26392
26762
  const segments = filePath.split("/");
26393
26763
  if (!filePath || filePath.startsWith("/") || filePath.includes("\\") || filePath.includes("\0") || segments.some((segment) => !segment || segment === "." || segment === "..")) {
@@ -26405,7 +26775,7 @@ function normalizeDefinitionBundle(bundle) {
26405
26775
  return { schemaVersion: 1, files };
26406
26776
  }
26407
26777
  function definitionVersion(bundle) {
26408
- return `sha256:${createHash6("sha256").update(JSON.stringify(normalizeDefinitionBundle(bundle))).digest("hex")}`;
26778
+ return `sha256:${createHash8("sha256").update(JSON.stringify(normalizeDefinitionBundle(bundle))).digest("hex")}`;
26409
26779
  }
26410
26780
  function verifyDefinition(definition) {
26411
26781
  if (!SLUG_RE2.test(definition.slug)) throw new Error(`invalid definition slug: ${definition.slug}`);
@@ -26415,6 +26785,13 @@ function verifyDefinition(definition) {
26415
26785
  }
26416
26786
  return bundle;
26417
26787
  }
26788
+ function writeBundle(root, bundle) {
26789
+ for (const [filePath, contents] of Object.entries(bundle.files)) {
26790
+ const target = path51.join(root, filePath);
26791
+ fs50.mkdirSync(path51.dirname(target), { recursive: true });
26792
+ fs50.writeFileSync(target, contents, "utf8");
26793
+ }
26794
+ }
26418
26795
  function writeDefinition(root, kind, definition) {
26419
26796
  const bundle = verifyDefinition(definition);
26420
26797
  if (kind === "agent") {
@@ -26424,20 +26801,18 @@ function writeDefinition(root, kind, definition) {
26424
26801
  return;
26425
26802
  }
26426
26803
  if (kind === "goal") {
26427
- const goalRoot = path51.join(root, "goals", definition.slug);
26428
- for (const [filePath, contents] of Object.entries(bundle.files)) {
26429
- const target = path51.join(goalRoot, filePath);
26430
- fs50.mkdirSync(path51.dirname(target), { recursive: true });
26431
- fs50.writeFileSync(target, contents, "utf8");
26432
- }
26804
+ writeBundle(path51.join(root, "goals", definition.slug), bundle);
26433
26805
  return;
26434
26806
  }
26435
- const capabilityRoot = path51.join(root, "capabilities", definition.slug);
26436
- for (const [filePath, contents] of Object.entries(bundle.files)) {
26437
- const target = path51.join(capabilityRoot, filePath);
26438
- fs50.mkdirSync(path51.dirname(target), { recursive: true });
26439
- fs50.writeFileSync(target, contents, "utf8");
26807
+ if (kind === "implementation") {
26808
+ writeBundle(path51.join(root, "implementations", definition.slug), bundle);
26809
+ return;
26440
26810
  }
26811
+ if (kind === "asset") {
26812
+ writeBundle(path51.join(root, "shared"), bundle);
26813
+ return;
26814
+ }
26815
+ writeBundle(path51.join(root, "capabilities", definition.slug), bundle);
26441
26816
  }
26442
26817
  async function hydrateDefinitions(options) {
26443
26818
  const root = path51.join(options.cwd, ".kody-engine", "definitions");
@@ -26446,11 +26821,15 @@ async function hydrateDefinitions(options) {
26446
26821
  fs50.mkdirSync(path51.join(staging, "agents"), { recursive: true });
26447
26822
  fs50.mkdirSync(path51.join(staging, "capabilities"), { recursive: true });
26448
26823
  fs50.mkdirSync(path51.join(staging, "goals"), { recursive: true });
26824
+ fs50.mkdirSync(path51.join(staging, "implementations"), { recursive: true });
26825
+ fs50.mkdirSync(path51.join(staging, "shared"), { recursive: true });
26449
26826
  try {
26450
- const [capabilities, agents, goals] = await Promise.all([
26827
+ const [capabilities, agents, goals, implementations, assets] = await Promise.all([
26451
26828
  options.backend.listDefinitions(options.tenantId, "capability"),
26452
26829
  options.backend.listDefinitions(options.tenantId, "agent"),
26453
- options.backend.listDefinitions(options.tenantId, "goal")
26830
+ options.backend.listDefinitions(options.tenantId, "goal"),
26831
+ options.backend.listDefinitions(options.tenantId, "implementation"),
26832
+ options.backend.listDefinitions(options.tenantId, "asset")
26454
26833
  ]);
26455
26834
  const versions = {};
26456
26835
  for (const definition of capabilities) {
@@ -26465,6 +26844,14 @@ async function hydrateDefinitions(options) {
26465
26844
  writeDefinition(staging, "goal", definition);
26466
26845
  versions[`goal:${definition.slug}`] = definition.version;
26467
26846
  }
26847
+ for (const definition of implementations) {
26848
+ writeDefinition(staging, "implementation", definition);
26849
+ versions[`implementation:${definition.slug}`] = definition.version;
26850
+ }
26851
+ for (const definition of assets) {
26852
+ writeDefinition(staging, "asset", definition);
26853
+ versions[`asset:${definition.slug}`] = definition.version;
26854
+ }
26468
26855
  const manifest = {
26469
26856
  schemaVersion: 1,
26470
26857
  tenantId: options.tenantId,
@@ -27095,14 +27482,14 @@ function sendJson2(res, status, body) {
27095
27482
  res.end(JSON.stringify(body));
27096
27483
  }
27097
27484
  function readJsonBody2(req) {
27098
- return new Promise((resolve17, reject) => {
27485
+ return new Promise((resolve19, reject) => {
27099
27486
  const chunks = [];
27100
27487
  req.on("data", (c) => chunks.push(c));
27101
27488
  req.on("end", () => {
27102
27489
  const raw = Buffer.concat(chunks).toString("utf-8");
27103
- if (!raw.trim()) return resolve17({});
27490
+ if (!raw.trim()) return resolve19({});
27104
27491
  try {
27105
- resolve17(JSON.parse(raw));
27492
+ resolve19(JSON.parse(raw));
27106
27493
  } catch (err) {
27107
27494
  reject(err instanceof Error ? err : new Error(String(err)));
27108
27495
  }
@@ -27313,10 +27700,10 @@ async function poolServe() {
27313
27700
  }
27314
27701
  });
27315
27702
  const apiHost = process.env.POOL_API_HOST ?? "::";
27316
- await new Promise((resolve17) => {
27703
+ await new Promise((resolve19) => {
27317
27704
  server.listen(apiPort, apiHost, () => {
27318
27705
  log(`listening on ${apiHost}:${apiPort} (min=${min}, app=${app}, region=${region})`);
27319
- resolve17();
27706
+ resolve19();
27320
27707
  });
27321
27708
  });
27322
27709
  if (loopTickEnabled) void runLoopTick();
@@ -27356,17 +27743,17 @@ function authOk2(req, expected) {
27356
27743
  return false;
27357
27744
  }
27358
27745
  function readJsonBody3(req) {
27359
- return new Promise((resolve17, reject) => {
27746
+ return new Promise((resolve19, reject) => {
27360
27747
  const chunks = [];
27361
27748
  req.on("data", (c) => chunks.push(c));
27362
27749
  req.on("end", () => {
27363
27750
  const raw = Buffer.concat(chunks).toString("utf-8");
27364
27751
  if (!raw.trim()) {
27365
- resolve17({});
27752
+ resolve19({});
27366
27753
  return;
27367
27754
  }
27368
27755
  try {
27369
- resolve17(JSON.parse(raw));
27756
+ resolve19(JSON.parse(raw));
27370
27757
  } catch (err) {
27371
27758
  reject(err instanceof Error ? err : new Error(String(err)));
27372
27759
  }
@@ -27500,13 +27887,13 @@ async function defaultRunJob(job) {
27500
27887
  ...interactive && job.idleExitMs ? { KODY_IDLE_EXIT_MS: String(job.idleExitMs) } : {},
27501
27888
  ...interactive && job.hardCapMs ? { KODY_HARD_CAP_MS: String(job.hardCapMs) } : {}
27502
27889
  };
27503
- const run = (cmd, args, cwd) => new Promise((resolve17) => {
27890
+ const run = (cmd, args, cwd) => new Promise((resolve19) => {
27504
27891
  const child = spawn9(cmd, args, { stdio: "inherit", env: childEnv, cwd });
27505
- child.on("exit", (code) => resolve17(code ?? 0));
27892
+ child.on("exit", (code) => resolve19(code ?? 0));
27506
27893
  child.on("error", (err) => {
27507
27894
  process.stderr.write(`[runner-serve] ${cmd} failed: ${err.message}
27508
27895
  `);
27509
- resolve17(1);
27896
+ resolve19(1);
27510
27897
  });
27511
27898
  });
27512
27899
  process.stdout.write(`[runner-serve] job ${job.jobId}: cloning ${job.repo}@${branch}
@@ -27582,11 +27969,11 @@ async function runnerServe() {
27582
27969
  const port = Number(process.env.PORT ?? DEFAULT_PORT2);
27583
27970
  const server = buildServer2({ apiKey });
27584
27971
  const host = process.env.RUNNER_HOST ?? "::";
27585
- await new Promise((resolve17) => {
27972
+ await new Promise((resolve19) => {
27586
27973
  server.listen(port, host, () => {
27587
27974
  process.stdout.write(`[runner-serve] listening on ${host}:${port} (idle, awaiting job)
27588
27975
  `);
27589
- resolve17();
27976
+ resolve19();
27590
27977
  });
27591
27978
  });
27592
27979
  const shutdown = (signal) => {
@@ -27655,14 +28042,14 @@ async function serve(opts) {
27655
28042
  `);
27656
28043
  const args = ["--dangerously-skip-permissions", "--model", model.model];
27657
28044
  const child = spawn10("claude", args, { stdio: "inherit", env: editorEnv, cwd: opts.cwd });
27658
- const exitCode = await new Promise((resolve17) => {
27659
- child.on("exit", (code) => resolve17(code ?? 0));
28045
+ const exitCode = await new Promise((resolve19) => {
28046
+ child.on("exit", (code) => resolve19(code ?? 0));
27660
28047
  child.on("error", (err) => {
27661
28048
  process.stderr.write(`[kody serve] failed to launch Claude Code: ${err.message}
27662
28049
  `);
27663
28050
  process.stderr.write(` Install: https://docs.anthropic.com/claude/docs/claude-code
27664
28051
  `);
27665
- resolve17(1);
28052
+ resolve19(1);
27666
28053
  });
27667
28054
  });
27668
28055
  killProxy();