@kody-ade/kody-engine 0.4.428 → 0.4.430

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin/kody.js +62 -14
  2. package/package.json +25 -26
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.428",
18
+ version: "0.4.430",
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",
@@ -52,7 +52,7 @@ var init_package = __esm({
52
52
  dependencies: {
53
53
  "@actions/cache": "^6.0.0",
54
54
  "@anthropic-ai/claude-agent-sdk": "0.2.119",
55
- "@kody-ade/agency-domain": "0.5.0",
55
+ "@kody-ade/agency-domain": "0.5.1",
56
56
  "@modelcontextprotocol/sdk": "^1.29.0",
57
57
  convex: "^1.17.0",
58
58
  zod: "^4.0.0"
@@ -2455,9 +2455,10 @@ function createStateBackendFromEnv(env = process.env, client) {
2455
2455
  });
2456
2456
  return Array.isArray(result) ? result : [];
2457
2457
  },
2458
- async getAgencyState(tenantId2, definitionId2) {
2458
+ async getAgencyState(tenantId2, kind, definitionId2) {
2459
2459
  const result = await transport.query(anyApi.agencyModel.getState, {
2460
2460
  tenantId: requireTenant(tenantId2),
2461
+ kind,
2461
2462
  definitionId: requireNonEmpty(definitionId2, "definitionId")
2462
2463
  });
2463
2464
  return result ?? null;
@@ -13028,11 +13029,13 @@ import {
13028
13029
  createWorkflowDefinition,
13029
13030
  relationshipIssues
13030
13031
  } from "@kody-ade/agency-domain";
13031
- function goalProgressFromOutputs(definition, outputs) {
13032
+ function goalProgressFromOutputs(definition, revision, outputs) {
13032
13033
  const required2 = definition.objective.requiredEvidence;
13033
13034
  if (required2.length === 0) return 1;
13034
13035
  const satisfied = new Set(
13035
- outputs.filter((output) => output.kind === "evidence" && output.value === true).map((output) => output.key)
13036
+ outputs.filter(
13037
+ (output) => output.kind === "evidence" && output.value === true && output.parentRef?.kind === "goal" && output.parentRef.id === definition.id && output.parentRef.revision === revision
13038
+ ).map((output) => output.key)
13036
13039
  );
13037
13040
  return required2.filter((key) => satisfied.has(key)).length / required2.length;
13038
13041
  }
@@ -13123,7 +13126,11 @@ var init_agencyModelRepository = __esm({
13123
13126
  definition: record2.definition,
13124
13127
  revision: record2.revision,
13125
13128
  state: parseState(
13126
- await this.backend.getAgencyState(this.tenantId, record2.definition.id),
13129
+ await this.backend.getAgencyState(
13130
+ this.tenantId,
13131
+ record2.kind,
13132
+ record2.definition.id
13133
+ ),
13127
13134
  record2.definition,
13128
13135
  record2.kind
13129
13136
  )
@@ -13169,7 +13176,11 @@ var init_agencyModelRepository = __esm({
13169
13176
  const state = createGoalState({
13170
13177
  definitionId: record2.definition.id,
13171
13178
  lifecycle: previous?.lifecycle ?? "draft",
13172
- progress: goalProgressFromOutputs(record2.definition, await this.listOutputs()),
13179
+ progress: goalProgressFromOutputs(
13180
+ record2.definition,
13181
+ record2.revision,
13182
+ await this.listOutputs()
13183
+ ),
13173
13184
  blockers: previous?.blockers ?? [],
13174
13185
  updatedAt
13175
13186
  });
@@ -13187,8 +13198,7 @@ function decideTrigger(input) {
13187
13198
  return { kind: "skip", reason: `loop is ${input.state.lifecycle}` };
13188
13199
  }
13189
13200
  const trigger = input.definition.trigger;
13190
- if (trigger.type === "manual") {
13191
- if (!input.manualRequestId?.trim()) return { kind: "skip", reason: "manual trigger was not requested" };
13201
+ if (input.manualRequestId?.trim()) {
13192
13202
  return {
13193
13203
  kind: "fire",
13194
13204
  reason: "manual trigger was requested",
@@ -13196,6 +13206,9 @@ function decideTrigger(input) {
13196
13206
  idempotencyKey: `${input.definition.id}:manual:${input.manualRequestId.trim()}`
13197
13207
  };
13198
13208
  }
13209
+ if (trigger.type === "manual") {
13210
+ return { kind: "skip", reason: "manual trigger was not requested" };
13211
+ }
13199
13212
  if (trigger.type !== "schedule") {
13200
13213
  return { kind: "skip", reason: `${trigger.type} trigger is not enabled yet` };
13201
13214
  }
@@ -13331,7 +13344,15 @@ async function dispatchAgencyLoopsWith(input) {
13331
13344
  );
13332
13345
  const results = [];
13333
13346
  for (const record2 of loops) {
13334
- const decision = decideTrigger({ definition: record2.definition, state: record2.state, now: input.now });
13347
+ if (input.manualRequest && record2.definition.id !== input.manualRequest.loopId) {
13348
+ continue;
13349
+ }
13350
+ const decision = decideTrigger({
13351
+ definition: record2.definition,
13352
+ state: record2.state,
13353
+ now: input.now,
13354
+ ...input.manualRequest ? { manualRequestId: input.manualRequest.requestId } : {}
13355
+ });
13335
13356
  const now = input.now.toISOString();
13336
13357
  if (decision.kind === "skip") {
13337
13358
  const key = `${record2.definition.id}:skip:${now}`;
@@ -13493,14 +13514,25 @@ async function dispatchAgencyLoopsWith(input) {
13493
13514
  const goalRecord = record2.definition.targetRef.kind === "goal" ? records.find(
13494
13515
  (candidate) => "executionRef" in candidate.definition && candidate.definition.id === record2.definition.targetRef.id
13495
13516
  ) : void 0;
13496
- if (succeeded && goalRecord && finalRunId) {
13517
+ if (succeeded && finalRunId) {
13497
13518
  await appendCapabilityOutputs(
13498
13519
  repository,
13499
13520
  finalRunId,
13500
13521
  target.reference,
13522
+ goalRecord ? {
13523
+ kind: "goal",
13524
+ id: goalRecord.definition.id,
13525
+ revision: goalRecord.revision
13526
+ } : {
13527
+ kind: "loop",
13528
+ id: record2.definition.id,
13529
+ revision: record2.revision
13530
+ },
13501
13531
  finalCapabilityResults,
13502
13532
  finishedAt
13503
13533
  );
13534
+ }
13535
+ if (succeeded && goalRecord) {
13504
13536
  await repository.refreshGoalProgress(goalRecord, finishedAt);
13505
13537
  }
13506
13538
  await input.backend.finishAgencyDispatch(
@@ -13581,7 +13613,7 @@ async function runAttempt(run, job, timeoutSeconds) {
13581
13613
  if (timer) clearTimeout(timer);
13582
13614
  }
13583
13615
  }
13584
- async function appendCapabilityOutputs(repository, runId, producer, results, createdAt) {
13616
+ async function appendCapabilityOutputs(repository, runId, producer, parentRef, results, createdAt) {
13585
13617
  for (const result of results) {
13586
13618
  const outputs = [
13587
13619
  ...Object.entries(result.facts).map(([key, value]) => ({ kind: "fact", key, value })),
@@ -13601,6 +13633,7 @@ async function appendCapabilityOutputs(repository, runId, producer, results, cre
13601
13633
  ...output,
13602
13634
  runId,
13603
13635
  producer: { kind: producer.kind, id: producer.id },
13636
+ parentRef,
13604
13637
  contract: "capability-result/v1",
13605
13638
  createdAt
13606
13639
  });
@@ -13632,10 +13665,17 @@ var init_dispatchAgencyLoops = __esm({
13632
13665
  const tenantId2 = repositoryTenant(ctx.config);
13633
13666
  if (!tenantId2) throw new Error("Repository identity is required for Agency Loop dispatch");
13634
13667
  const backend = createStateBackendFromEnv();
13668
+ const requestedLoopId = typeof ctx.args.loop === "string" ? ctx.args.loop.trim() : "";
13635
13669
  const results = await dispatchAgencyLoopsWith({
13636
13670
  tenantId: tenantId2,
13637
13671
  backend,
13638
13672
  now: /* @__PURE__ */ new Date(),
13673
+ ...requestedLoopId ? {
13674
+ manualRequest: {
13675
+ loopId: requestedLoopId,
13676
+ requestId: process.env.GITHUB_RUN_ID?.trim() || `local-${randomUUID()}`
13677
+ }
13678
+ } : {},
13639
13679
  run: (job, abortController) => runJob(job, {
13640
13680
  cwd: ctx.cwd,
13641
13681
  config: ctx.config,
@@ -24494,8 +24534,16 @@ async function runCi(argv) {
24494
24534
  const noTarget = !sessionInput && !(Number.isFinite(issueInput) && issueInput > 0);
24495
24535
  if (noTarget && capabilityInput) {
24496
24536
  forceRunAction = capabilityInput;
24497
- if (capabilityInput === "goal-manager" && messageInput) {
24498
- forceRunCliArgs = { goal: messageInput };
24537
+ if (messageInput) {
24538
+ const route = resolveCapabilityAction(capabilityInput);
24539
+ const textInputs = route?.implementation ? (getProfileInputs(route.implementation) ?? []).filter(
24540
+ (input) => input.type === "string"
24541
+ ) : [];
24542
+ if (textInputs.length === 1) {
24543
+ forceRunCliArgs = { [textInputs[0].name]: messageInput };
24544
+ } else if (capabilityInput === "goal-manager") {
24545
+ forceRunCliArgs = { goal: messageInput };
24546
+ }
24499
24547
  }
24500
24548
  } else {
24501
24549
  manualWorkflowDispatch = noTarget;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.428",
3
+ "version": "0.4.430",
4
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",
@@ -12,32 +12,10 @@
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:all": "vitest run tests --no-coverage",
29
- "typecheck": "tsc --noEmit",
30
- "lint": "biome check",
31
- "lint:fix": "biome check --write",
32
- "format": "biome format --write",
33
- "verify:package": "node scripts/verify-package-tarball.cjs",
34
- "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",
35
- "prepublishOnly": "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build && pnpm verify:package"
36
- },
37
15
  "dependencies": {
38
16
  "@actions/cache": "^6.0.0",
39
17
  "@anthropic-ai/claude-agent-sdk": "0.2.119",
40
- "@kody-ade/agency-domain": "0.5.0",
18
+ "@kody-ade/agency-domain": "0.5.1",
41
19
  "@modelcontextprotocol/sdk": "^1.29.0",
42
20
  "convex": "^1.17.0",
43
21
  "zod": "^4.0.0"
@@ -59,5 +37,26 @@
59
37
  "url": "git+https://github.com/aharonyaircohen/kody-engine.git"
60
38
  },
61
39
  "homepage": "https://github.com/aharonyaircohen/kody-engine",
62
- "bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
63
- }
40
+ "bugs": "https://github.com/aharonyaircohen/kody-engine/issues",
41
+ "scripts": {
42
+ "kody:run": "tsx bin/kody.ts",
43
+ "serve": "tsx bin/kody.ts serve",
44
+ "serve:vscode": "tsx bin/kody.ts serve vscode",
45
+ "serve:claude": "tsx bin/kody.ts serve claude",
46
+ "clean:dist": "node scripts/clean-dist.cjs",
47
+ "build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
48
+ "check:modularity": "tsx scripts/check-script-modularity.ts",
49
+ "pretest": "pnpm check:modularity",
50
+ "test": "vitest run tests/unit tests/int --coverage",
51
+ "posttest": "tsx scripts/check-coverage-floor.ts",
52
+ "test:smoke": "vitest run tests/smoke --no-coverage",
53
+ "test:e2e": "vitest run tests/e2e --no-coverage",
54
+ "test:all": "vitest run tests --no-coverage",
55
+ "typecheck": "tsc --noEmit",
56
+ "lint": "biome check",
57
+ "lint:fix": "biome check --write",
58
+ "format": "biome format --write",
59
+ "verify:package": "node scripts/verify-package-tarball.cjs",
60
+ "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"
61
+ }
62
+ }