@kody-ade/kody-engine 0.4.259 → 0.4.261

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/README.md CHANGED
@@ -27,7 +27,7 @@ kody: reads the issue → writes the code → runs your tests → opens a PR
27
27
  - **No infrastructure.** Runs on the GitHub Actions you already have. One ~20-line
28
28
  workflow file, installed via `npx`. Nothing to deploy or keep online.
29
29
  - **Whole PR lifecycle, not just authoring.** `run`, `resolve`, `sync`, `merge`,
30
- `revert`, previews, releases, and scheduled agentResponsibilities — one executor, many verbs.
30
+ `revert`, previews, releases, and scheduled capabilities — one executor, many verbs.
31
31
  - **Declarative & extensible.** Every command is a folder of `profile.json` +
32
32
  `prompt.md` + shell. Add a command by dropping a folder — no engine changes.
33
33
  - **Bring your own model.** Anthropic native, or any provider via the built-in
@@ -74,19 +74,31 @@ See [SECURITY.md](SECURITY.md) to report a vulnerability.
74
74
  ┌─────────────────────────────────────────────┐
75
75
  │ kody-engine CLI (@kody-ade/kody-engine) │
76
76
  │ bin/kody.ts — entrypoint │
77
- │ src/dispatch.ts — agentResponsibility-driven routing
78
- │ src/executor.ts — runs agentResponsibility implementations│
77
+ │ src/dispatch.ts — capability-driven routing
78
+ │ src/executor.ts — runs capability implementations
79
+ │ .kody/capabilities/<slug>/ │
80
+ │ profile.json · capability.md · optional skills/scripts │
79
81
  │ .kody/agent-responsibilities/<slug>/ │
80
- │ profile.json · agent-responsibility.md
81
- src/agent-actions/<name>/
82
- │ profile.json · prompt.md · *.sh
82
+ legacy fallback: profile.json · agent-responsibility.md
83
+ .kody/agent-actions/<name>/
84
+ legacy fallback: profile.json · prompt.md · *.sh
83
85
  │ src/scripts/*.ts — cross-cutting catalog │
84
86
  └─────────────────────────────────────────────┘
85
87
  ```
86
88
 
87
- Every top-level command is an auto-discovered agentResponsibility action. The router has **zero agentAction names hardcoded** — comment dispatch resolves the first token after `@kody` through `config.aliases`, then falls back to the legacy-named `config.defaultAgentAction` / `config.defaultPrAgentAction` fields as default agentResponsibility actions. Drop a new `.kody/agent-responsibilities/<slug>/` directory with `profile.json` + `agent-responsibility.md`; that agentResponsibility chooses its implementation agentAction.
89
+ Every top-level command is an auto-discovered capability action. The router has
90
+ **zero agentAction names hardcoded** - comment dispatch resolves the first token
91
+ after `@kody` through `config.aliases`, then falls back to the legacy-named
92
+ `config.defaultAgentAction` / `config.defaultPrAgentAction` fields as default
93
+ capability actions. Drop a new `.kody/capabilities/<slug>/` directory with
94
+ `profile.json` + `capability.md`; legacy `.kody/agent-responsibilities/` and
95
+ `.kody/agent-actions/` roots still load while repos migrate.
88
96
 
89
- AgentAction directories are private implementation units and contain **only** three kinds of files: `profile.json` (declaration), `prompt.md` (agent instructions), and `.sh` scripts (mechanical side-effect work). Cross-cutting TypeScript lives in [src/scripts/](src/scripts/); it can't import from `src/agent-actions/` and can't branch on `profile.name`.
97
+ Legacy AgentAction directories are private implementation units and contain
98
+ **only** three kinds of files: `profile.json` (declaration), `prompt.md` (agent
99
+ instructions), and `.sh` scripts (mechanical side-effect work). Cross-cutting
100
+ TypeScript lives in [src/scripts/](src/scripts/); it can't import from
101
+ `src/agent-actions/` and can't branch on `profile.name`.
90
102
 
91
103
  ## Install in a consumer repo
92
104
 
@@ -94,7 +106,10 @@ AgentAction directories are private implementation units and contain **only** th
94
106
  npx -y -p @kody-ade/kody-engine@latest kody-engine init
95
107
  ```
96
108
 
97
- `kody-engine init` scaffolds [kody.config.json](kody.config.schema.json), `.github/workflows/kody.yml` (generated from `WORKFLOW_TEMPLATE` in [src/scripts/initFlow.ts](src/scripts/initFlow.ts)), and per-scheduled-agentResponsibility workflow files. Idempotent — pass `--force` to overwrite.
109
+ `kody-engine init` scaffolds [kody.config.json](kody.config.schema.json),
110
+ `.github/workflows/kody.yml` (generated from `WORKFLOW_TEMPLATE` in
111
+ [src/scripts/initFlow.ts](src/scripts/initFlow.ts)), and scheduled capability
112
+ workflow files. Idempotent — pass `--force` to overwrite.
98
113
 
99
114
  Required repo secrets: at least one model provider key (e.g. `MINIMAX_API_KEY`, `ANTHROPIC_API_KEY`). Recommended: `KODY_TOKEN` PAT so kody's commits trigger downstream CI and can modify `.github/workflows/*`.
100
115
 
@@ -123,10 +138,10 @@ kody-engine release-publish --issue <N> [--dry-run]
123
138
  kody-engine release-deploy --issue <N> [--dry-run]
124
139
  kody-engine npm-publish [--tag latest] [--access public] [--dry-run]
125
140
 
126
- # scheduled agentResponsibilities and goals
127
- kody-engine agent-responsibility-scheduler # fan out due .kody/agent-responsibilities/<slug>/ folders
128
- kody-engine agent-responsibility-tick --agentResponsibility <slug> [--force] # one agent tick for one agentResponsibility
129
- kody-engine agent-responsibility-tick-scripted --agentResponsibility <slug> [--force] # one deterministic tickScript agentResponsibility tick
141
+ # scheduled capabilities and goals
142
+ kody-engine agent-responsibility-scheduler # fan out due .kody/capabilities/<slug>/ folders plus legacy fallbacks
143
+ kody-engine agent-responsibility-tick --agentResponsibility <slug> [--force] # one agent tick for one capability
144
+ kody-engine agent-responsibility-tick-scripted --agentResponsibility <slug> [--force] # one deterministic tickScript capability tick
130
145
  kody-engine goal-scheduler # fan out active goal instances in configured state repo
131
146
  kody-engine goal-manager --goal <id> # advance one managed goal instance
132
147
 
@@ -142,11 +157,19 @@ kody-engine agent-ask --agent <slug> --message "..." # ad-hoc agent run
142
157
  kody-engine stats # inspect run/event history
143
158
  ```
144
159
 
145
- ### AgentResponsibilities
160
+ ### Capabilities
146
161
 
147
- A **agentResponsibility** is a folder at `.kody/agent-responsibilities/<slug>/` with `profile.json` metadata (`every`, `agent`, `action`, `agentAction`, `stage`, and related fields) plus human-owned prose in `agent-responsibility.md`. `agent-responsibility-scheduler` wakes on cron, finds due agentResponsibilities, and dispatches either `agent-responsibility-tick` for an agent tick or `agent-responsibility-tick-scripted` for a deterministic `tickScript` agentResponsibility. `kody-engine init` copies built-in starter agentResponsibilities and scaffolds `.kody/agents/kody.md`.
162
+ A **capability** is a folder at `.kody/capabilities/<slug>/` with
163
+ `profile.json` metadata (`action`, `capabilityKind`, `agent`, `every`, and
164
+ related fields) plus human-owned prose in `capability.md`. The scheduler wakes
165
+ on cron, finds due capabilities, and dispatches either
166
+ `agent-responsibility-tick` for an agent tick or
167
+ `agent-responsibility-tick-scripted` for a deterministic `tickScript`
168
+ capability. The CLI names are still legacy during migration.
148
169
 
149
- Locked-toolbox agentResponsibilities can declare `"tools": [...]` in `profile.json` to run with only the named high-level MCP intents plus `submit_state`; agentResponsibilities without `tools` keep the legacy Bash/gh toolbox.
170
+ Locked-toolbox capabilities can declare `"tools": [...]` in `profile.json` to
171
+ run with only the named high-level MCP intents plus `submit_state`; capabilities
172
+ without `tools` keep the legacy Bash/gh toolbox.
150
173
 
151
174
  ### `release`
152
175
 
@@ -154,7 +177,11 @@ Locked-toolbox agentResponsibilities can declare `"tools": [...]` in `profile.js
154
177
 
155
178
  ## Profiles
156
179
 
157
- A profile is declarative JSON + an adjacent `prompt.md`. See any directory under [src/agent-actions/](src/agent-actions/) for examples. Adding a new command = new directory + profile + prompt + any `.sh` scripts + registering any new shared TS utilities under [src/scripts/](src/scripts/). No executor, entry, or dispatch changes.
180
+ A profile is declarative JSON plus an adjacent markdown body. New public work
181
+ should live under `.kody/capabilities/<slug>/` with `capability.md`; legacy
182
+ implementations under [src/agent-actions/](src/agent-actions/) still show the
183
+ older split profile + prompt shape. Adding a new capability should not require
184
+ executor, entry, or dispatch changes.
158
185
 
159
186
  See [AGENTS.md](AGENTS.md) for the full architectural contract.
160
187
 
@@ -22,10 +22,16 @@ Design the smallest Kody model structure that satisfies the request. You may cre
22
22
 
23
23
  Use the current Kody vocabulary:
24
24
 
25
+ - intent: why the agency should care
26
+ - goal: what should become true
27
+ - loop: when to check or wake work
25
28
  - agent: who runs
26
- - agentResponsibility: why/when and public action ownership
27
- - agentAction: how work runs
28
- - goal: related task list/state
29
+ - capability: how the agency can produce a result
30
+
31
+ Use current storage names when producing files:
32
+
33
+ - agentResponsibility: capability contract, public action ownership, kind, agent, cadence, and output contract
34
+ - agentAction: capability implementation
29
35
 
30
36
  # Boundaries
31
37
 
@@ -56,11 +56,12 @@ export interface Profile {
56
56
  */
57
57
  role: "primitive" | "orchestrator" | "container" | "watch" | "utility"
58
58
  /**
59
- * A agentResponsibility is the WHY layer: it references an agentAction (the HOW) by name
60
- * rather than embedding it. When set, loader resolves the agentAction's
61
- * full profile (claudeCode/scripts/prompt/agents) and overlays agentResponsibility's
62
- * name + agent (WHO) + mentions. Absent -> this profile IS an
63
- * agentAction (defines its own how). agentAction = how, agent = who, agentResponsibility = why.
59
+ * A agentResponsibility is the capability contract storage layer: it references
60
+ * an agentAction implementation by name rather than embedding it. When set,
61
+ * loader resolves the agentAction's full profile (claudeCode/scripts/prompt/agents)
62
+ * and overlays agentResponsibility name + agent (who) + mentions. Absent -> this
63
+ * profile IS an agentAction implementation. Intent = why, agent = who,
64
+ * capability = how, agentAction = implementation.
64
65
  */
65
66
  agentAction?: string
66
67
  /**
@@ -517,8 +518,9 @@ export type AnyScript = PreflightScript | PostflightScript
517
518
  // Job — the unified work request (task-state jobs collect run attempts).
518
519
  //
519
520
  // A Job is the required work the engine tries to execute, regardless of how it
520
- // was triggered. It must reference a agentResponsibility/action (why). The agentAction is only
521
- // the agentResponsibility-selected implementation detail (how), never a standalone request.
521
+ // was triggered. It must reference an agentResponsibility/action capability
522
+ // contract. The agentAction is only the selected implementation detail, never a
523
+ // standalone request.
522
524
  // Task state stores this durable job separately from individual run attempts.
523
525
  // Two flavors:
524
526
  // - "instant" — run once now (an `@kody <verb>` comment or a manual dispatch)
@@ -552,6 +554,6 @@ export interface Job {
552
554
  flavor: JobFlavor
553
555
  /** Manual force-run (bypass cadence) for a scheduled job. */
554
556
  force?: boolean
555
- /** Ask the owning goal/loop to refresh reports/<goal-or-loop>.md after it applies evidence. */
557
+ /** Ask the owning goal/loop to refresh reports/<goal-or-loop>.md after its persisted decision. */
556
558
  saveReport?: boolean
557
559
  }
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.259",
18
+ version: "0.4.261",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative agentAction profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -1364,12 +1364,14 @@ function listAgentResponsibilityFolderSlugs(absDir) {
1364
1364
  return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).filter((e) => isAgentResponsibilityFolder(path6.join(absDir, e.name))).map((e) => e.name).sort();
1365
1365
  }
1366
1366
  function isAgentResponsibilityFolder(dir) {
1367
- return fs4.existsSync(path6.join(dir, AGENT_RESPONSIBILITY_PROFILE_FILE)) && fs4.existsSync(path6.join(dir, AGENT_RESPONSIBILITY_BODY_FILE));
1367
+ return fs4.existsSync(path6.join(dir, AGENT_RESPONSIBILITY_PROFILE_FILE)) && (fs4.existsSync(path6.join(dir, CAPABILITY_BODY_FILE)) || fs4.existsSync(path6.join(dir, AGENT_RESPONSIBILITY_BODY_FILE)));
1368
1368
  }
1369
1369
  function readAgentResponsibilityFolder(root, slug2) {
1370
1370
  const dir = path6.join(root, slug2);
1371
1371
  const profilePath = path6.join(dir, AGENT_RESPONSIBILITY_PROFILE_FILE);
1372
- const bodyPath = path6.join(dir, AGENT_RESPONSIBILITY_BODY_FILE);
1372
+ const capabilityBodyPath = path6.join(dir, CAPABILITY_BODY_FILE);
1373
+ const legacyBodyPath = path6.join(dir, AGENT_RESPONSIBILITY_BODY_FILE);
1374
+ const bodyPath = fs4.existsSync(capabilityBodyPath) ? capabilityBodyPath : legacyBodyPath;
1373
1375
  if (!fs4.existsSync(profilePath) || !fs4.statSync(profilePath).isFile()) return null;
1374
1376
  if (!fs4.existsSync(bodyPath) || !fs4.statSync(bodyPath).isFile()) return null;
1375
1377
  try {
@@ -1403,6 +1405,7 @@ function parseAgentResponsibilityConfig(raw) {
1403
1405
  tools,
1404
1406
  agentActions: stringList(raw.agentActions),
1405
1407
  capabilityKind: capabilityKindField(raw.capabilityKind),
1408
+ role: stringField(raw.role),
1406
1409
  describe: stringField(raw.describe),
1407
1410
  stage: stringField(raw.stage),
1408
1411
  readsFrom: stringList(raw.readsFrom ?? raw.reads_from),
@@ -1446,12 +1449,13 @@ function capabilityKindField(value) {
1446
1449
  if (value === "observe" || value === "act" || value === "verify") return value;
1447
1450
  return void 0;
1448
1451
  }
1449
- var AGENT_RESPONSIBILITY_PROFILE_FILE, AGENT_RESPONSIBILITY_BODY_FILE;
1452
+ var AGENT_RESPONSIBILITY_PROFILE_FILE, AGENT_RESPONSIBILITY_BODY_FILE, CAPABILITY_BODY_FILE;
1450
1453
  var init_agent_responsibilityFolders = __esm({
1451
1454
  "src/agent-responsibilityFolders.ts"() {
1452
1455
  "use strict";
1453
1456
  AGENT_RESPONSIBILITY_PROFILE_FILE = "profile.json";
1454
1457
  AGENT_RESPONSIBILITY_BODY_FILE = "agent-responsibility.md";
1458
+ CAPABILITY_BODY_FILE = "capability.md";
1455
1459
  }
1456
1460
  });
1457
1461
 
@@ -1474,6 +1478,7 @@ function getCompanyStoreAssetRoot(kind) {
1474
1478
  const root = getCompanyStoreRoot();
1475
1479
  if (!root) return null;
1476
1480
  const folderByKind = {
1481
+ capabilities: "capabilities",
1477
1482
  agentResponsibilities: "agent-responsibilities",
1478
1483
  agentActions: "agent-actions",
1479
1484
  goals: "goals",
@@ -1583,12 +1588,18 @@ function getAgentActionsRoot() {
1583
1588
  function getProjectAgentActionsRoot() {
1584
1589
  return path8.join(process.cwd(), ".kody", "agent-actions");
1585
1590
  }
1591
+ function getProjectCapabilitiesRoot() {
1592
+ return path8.join(process.cwd(), ".kody", "capabilities");
1593
+ }
1586
1594
  function getProjectAgentResponsibilitiesRoot() {
1587
1595
  return path8.join(process.cwd(), ".kody", "agent-responsibilities");
1588
1596
  }
1589
1597
  function getCompanyStoreAgentActionsRoot() {
1590
1598
  return getCompanyStoreAssetRoot("agentActions");
1591
1599
  }
1600
+ function getCompanyStoreCapabilitiesRoot() {
1601
+ return getCompanyStoreAssetRoot("capabilities");
1602
+ }
1592
1603
  function getCompanyStoreAgentResponsibilitiesRoot() {
1593
1604
  return getCompanyStoreAssetRoot("agentResponsibilities");
1594
1605
  }
@@ -1608,12 +1619,28 @@ function getBuiltinAgentResponsibilitiesRoot() {
1608
1619
  return candidates[0];
1609
1620
  }
1610
1621
  function getAgentActionRoots() {
1622
+ const projectCapabilitiesRoot = getProjectCapabilitiesRoot();
1623
+ const storeCapabilitiesRoot = getCompanyStoreCapabilitiesRoot();
1611
1624
  const storeRoot = getCompanyStoreAgentActionsRoot();
1612
- return [getProjectAgentActionsRoot(), ...storeRoot ? [storeRoot] : [], getAgentActionsRoot()];
1625
+ return [
1626
+ projectCapabilitiesRoot,
1627
+ getProjectAgentActionsRoot(),
1628
+ ...storeCapabilitiesRoot ? [storeCapabilitiesRoot] : [],
1629
+ ...storeRoot ? [storeRoot] : [],
1630
+ getAgentActionsRoot()
1631
+ ];
1613
1632
  }
1614
1633
  function getAgentResponsibilityRoots(projectAgentResponsibilitiesRoot = getProjectAgentResponsibilitiesRoot()) {
1634
+ const projectCapabilitiesRoot = getProjectCapabilitiesRoot();
1635
+ const storeCapabilitiesRoot = getCompanyStoreCapabilitiesRoot();
1615
1636
  const storeRoot = getCompanyStoreAgentResponsibilitiesRoot();
1616
- return [projectAgentResponsibilitiesRoot, ...storeRoot ? [storeRoot] : [], getBuiltinAgentResponsibilitiesRoot()];
1637
+ return [
1638
+ projectCapabilitiesRoot,
1639
+ projectAgentResponsibilitiesRoot,
1640
+ ...storeCapabilitiesRoot ? [storeCapabilitiesRoot] : [],
1641
+ ...storeRoot ? [storeRoot] : [],
1642
+ getBuiltinAgentResponsibilitiesRoot()
1643
+ ];
1617
1644
  }
1618
1645
  function listAgentActions(roots = getAgentActionRoots()) {
1619
1646
  const rootList = typeof roots === "string" ? [roots] : roots;
@@ -1621,12 +1648,13 @@ function listAgentActions(roots = getAgentActionRoots()) {
1621
1648
  const out = [];
1622
1649
  for (const root of rootList) {
1623
1650
  if (!fs6.existsSync(root)) continue;
1651
+ const requireImplementationProfile = isCapabilityRoot(root);
1624
1652
  const entries = fs6.readdirSync(root, { withFileTypes: true });
1625
1653
  for (const ent of entries) {
1626
1654
  if (!ent.isDirectory()) continue;
1627
1655
  if (seen.has(ent.name)) continue;
1628
1656
  const profilePath = path8.join(root, ent.name, AGENT_RESPONSIBILITY_PROFILE_FILE);
1629
- if (fs6.existsSync(profilePath) && fs6.statSync(profilePath).isFile()) {
1657
+ if (fs6.existsSync(profilePath) && fs6.statSync(profilePath).isFile() && isImplementationProfile(profilePath, requireImplementationProfile)) {
1630
1658
  out.push({ name: ent.name, profilePath });
1631
1659
  seen.add(ent.name);
1632
1660
  }
@@ -1639,7 +1667,7 @@ function resolveAgentAction(name, roots = getAgentActionRoots()) {
1639
1667
  const rootList = typeof roots === "string" ? [roots] : roots;
1640
1668
  for (const root of rootList) {
1641
1669
  const profilePath = path8.join(root, name, "profile.json");
1642
- if (fs6.existsSync(profilePath) && fs6.statSync(profilePath).isFile()) {
1670
+ if (fs6.existsSync(profilePath) && fs6.statSync(profilePath).isFile() && isImplementationProfile(profilePath, isCapabilityRoot(root))) {
1643
1671
  return profilePath;
1644
1672
  }
1645
1673
  }
@@ -1654,18 +1682,29 @@ function listAgentResponsibilityActions(projectAgentResponsibilitiesRoot = getPr
1654
1682
  seen.add(action.action);
1655
1683
  out.push(action);
1656
1684
  };
1657
- const roots = getAgentResponsibilityRoots(projectAgentResponsibilitiesRoot);
1658
1685
  const executableRoots = getAgentActionRoots();
1659
- for (const action of listFolderAgentResponsibilityActions(roots[0], "project-folder")) add(action);
1660
- for (const action of listAgentActionResponsibilityActions(executableRoots[0], "project-agentAction")) add(action);
1661
- if (roots.length === 3) {
1662
- for (const action of listFolderAgentResponsibilityActions(roots[1], "company-store")) add(action);
1663
- for (const action of listAgentActionResponsibilityActions(executableRoots[1], "company-store-agentAction"))
1664
- add(action);
1665
- for (const action of listBuiltinAgentResponsibilityActions(roots[2])) add(action);
1666
- } else {
1667
- for (const action of listBuiltinAgentResponsibilityActions(roots[1])) add(action);
1668
- }
1686
+ const projectCapabilitiesRoot = getProjectCapabilitiesRoot();
1687
+ const projectLegacyRoot = projectAgentResponsibilitiesRoot;
1688
+ const storeCapabilitiesRoot = getCompanyStoreCapabilitiesRoot();
1689
+ const storeLegacyRoot = getCompanyStoreAgentResponsibilitiesRoot();
1690
+ const projectExecutableRoots = executableRoots.slice(0, 2);
1691
+ const storeExecutableRoots = executableRoots.slice(2, -1);
1692
+ for (const action of listFolderAgentResponsibilityActions(projectCapabilitiesRoot, "project-folder", true))
1693
+ add(action);
1694
+ for (const action of listFolderAgentResponsibilityActions(projectLegacyRoot, "project-folder")) add(action);
1695
+ for (const root of projectExecutableRoots) {
1696
+ for (const action of listAgentActionResponsibilityActions(root, "project-agentAction")) add(action);
1697
+ }
1698
+ if (storeCapabilitiesRoot) {
1699
+ for (const action of listFolderAgentResponsibilityActions(storeCapabilitiesRoot, "company-store", true)) add(action);
1700
+ }
1701
+ if (storeLegacyRoot) {
1702
+ for (const action of listFolderAgentResponsibilityActions(storeLegacyRoot, "company-store")) add(action);
1703
+ }
1704
+ for (const root of storeExecutableRoots) {
1705
+ for (const action of listAgentActionResponsibilityActions(root, "company-store-agentAction")) add(action);
1706
+ }
1707
+ for (const action of listBuiltinAgentResponsibilityActions(getBuiltinAgentResponsibilitiesRoot())) add(action);
1669
1708
  return out.sort((a, b) => a.action.localeCompare(b.action));
1670
1709
  }
1671
1710
  function resolveAgentResponsibilityAction(action, projectAgentResponsibilitiesRoot = getProjectAgentResponsibilitiesRoot()) {
@@ -1684,7 +1723,7 @@ function resolveAgentResponsibilityFolder(slug2, projectAgentResponsibilitiesRoo
1684
1723
  return null;
1685
1724
  }
1686
1725
  function resolveAgentResponsibilityExecution(agentResponsibility) {
1687
- const agentAction = agentResponsibility.config.agentAction ?? agentResponsibility.config.agentActions?.[0] ?? (agentResponsibility.config.tickScript ? "agent-responsibility-tick-scripted" : "agent-responsibility-tick");
1726
+ const agentAction = agentResponsibility.config.agentAction ?? agentResponsibility.config.agentActions?.[0] ?? (agentResponsibility.config.role ? agentResponsibility.slug : void 0) ?? (agentResponsibility.config.tickScript ? "agent-responsibility-tick-scripted" : "agent-responsibility-tick");
1688
1727
  const cliArgs = agentActionDeclaresInput(agentAction, "agentResponsibility") ? { agentResponsibility: agentResponsibility.slug } : {};
1689
1728
  return { agentAction, cliArgs };
1690
1729
  }
@@ -1706,6 +1745,19 @@ function agentActionDeclaresInput(agentAction, inputName) {
1706
1745
  function isSafeName(name) {
1707
1746
  return /^[a-z][a-z0-9-]*$/.test(name) && !name.includes("..");
1708
1747
  }
1748
+ function isCapabilityRoot(root) {
1749
+ const normalized = path8.normalize(root);
1750
+ return path8.basename(normalized) === "capabilities" && path8.basename(path8.dirname(normalized)) === ".kody";
1751
+ }
1752
+ function isImplementationProfile(profilePath, requireImplementationProfile) {
1753
+ if (!requireImplementationProfile) return true;
1754
+ try {
1755
+ const raw = JSON.parse(fs6.readFileSync(profilePath, "utf-8"));
1756
+ return typeof raw.role === "string" && PUBLIC_AGENT_ACTION_ACTION_ROLES.has(raw.role);
1757
+ } catch {
1758
+ return false;
1759
+ }
1760
+ }
1709
1761
  function listAgentActionResponsibilityActions(root, source) {
1710
1762
  if (!fs6.existsSync(root) || !fs6.statSync(root).isDirectory()) return [];
1711
1763
  const out = [];
@@ -1734,13 +1786,14 @@ function listAgentActionResponsibilityActions(root, source) {
1734
1786
  }
1735
1787
  return out.sort((a, b) => a.action.localeCompare(b.action));
1736
1788
  }
1737
- function listFolderAgentResponsibilityActions(root, source) {
1789
+ function listFolderAgentResponsibilityActions(root, source, requireCapabilityKind = false) {
1738
1790
  if (!fs6.existsSync(root) || !fs6.statSync(root).isDirectory()) return [];
1739
1791
  const out = [];
1740
1792
  for (const slug2 of listAgentResponsibilityFolderSlugs(root)) {
1741
1793
  if (!isSafeName(slug2)) continue;
1742
1794
  const agentResponsibility = readAgentResponsibilityFolder(root, slug2);
1743
1795
  if (!agentResponsibility) continue;
1796
+ if (requireCapabilityKind && !agentResponsibility.config.capabilityKind) continue;
1744
1797
  const action = agentResponsibility.config.action ?? slug2;
1745
1798
  const { agentAction, cliArgs } = resolveAgentResponsibilityExecution(agentResponsibility);
1746
1799
  out.push({
@@ -8241,73 +8294,84 @@ var init_agent_responsibilityEvidence = __esm({
8241
8294
  }
8242
8295
  });
8243
8296
 
8244
- // src/scripts/applyAgentResponsibilityReports.ts
8245
- function flushLogs(ctx) {
8246
- try {
8247
- flushGoalRunLogEvents(ctx.config, ctx.cwd, ctx.data);
8248
- } catch (err) {
8249
- process.stderr.write(
8250
- `[kody agentResponsibility-report] goal log persist failed (${err instanceof Error ? err.message : String(err)})
8251
- `
8252
- );
8253
- }
8254
- }
8255
- function writeGoalDashboardReport(ctx, goalId, state, snapshot, evidenceItems) {
8256
- if (ctx.data.jobSaveReport !== true) return;
8257
- if (!REPORT_SLUG_RE.test(goalId)) {
8258
- fail(ctx, `goal report: invalid goal id "${goalId}"`);
8259
- return;
8260
- }
8261
- const filePath = `reports/${goalId}.md`;
8262
- const body = goalReportBody(goalId, state, snapshot, evidenceItems);
8263
- try {
8264
- const current = readStateText(ctx.config, ctx.cwd, filePath);
8265
- if (current?.content === body) {
8266
- recordGoalReport(ctx.data, { slug: goalId, path: current.path, changed: false });
8267
- return;
8268
- }
8269
- upsertStateText(ctx.config, ctx.cwd, filePath, body, `chore(reports): refresh ${goalId}`);
8270
- recordGoalReport(ctx.data, { slug: goalId, path: filePath, changed: true });
8271
- } catch (err) {
8272
- fail(ctx, `goal report: ${err instanceof Error ? err.message : String(err)}`);
8297
+ // src/goal/report.ts
8298
+ function goalDashboardReportRequested(data, state) {
8299
+ return data.jobSaveReport === true || state?.extra.saveReport === true;
8300
+ }
8301
+ function refreshGoalDashboardReport(input) {
8302
+ const evidenceItems = input.evidenceItems ?? [];
8303
+ if (!goalDashboardReportRequested(input.data, input.state)) return null;
8304
+ if (!REPORT_SLUG_RE.test(input.goalId)) {
8305
+ throw new Error(`goal report: invalid goal id "${input.goalId}"`);
8306
+ }
8307
+ const filePath = `reports/${input.goalId}.md`;
8308
+ const body = goalReportBody(
8309
+ input.goalId,
8310
+ input.state,
8311
+ snapshotFromState(input.goalId, input.state),
8312
+ latestGoalRunLogEvent(input.data, input.goalId),
8313
+ evidenceItems
8314
+ );
8315
+ const current = readStateText(input.config, input.cwd, filePath);
8316
+ if (current?.content === body) {
8317
+ const report2 = { slug: input.goalId, path: current.path, changed: false };
8318
+ recordGoalReport(input.data, report2);
8319
+ return report2;
8273
8320
  }
8321
+ upsertStateText(input.config, input.cwd, filePath, body, `chore(reports): refresh ${input.goalId}`);
8322
+ const report = { slug: input.goalId, path: filePath, changed: true };
8323
+ recordGoalReport(input.data, report);
8324
+ return report;
8274
8325
  }
8275
- function recordGoalReport(data, report) {
8276
- const prior = Array.isArray(data.goalReports) ? data.goalReports : [];
8277
- data.goalReports = [...prior, report];
8326
+ function responsibilityEvidenceOutput(evidence) {
8327
+ return {
8328
+ kind: "responsibility-evidence",
8329
+ sources: evidence.sources,
8330
+ status: evidence.status,
8331
+ summary: evidence.summary,
8332
+ evidence: evidence.evidence ?? {},
8333
+ facts: evidence.facts,
8334
+ artifacts: evidence.artifacts,
8335
+ missingEvidence: evidence.missingEvidence,
8336
+ blockers: evidence.blockers
8337
+ };
8278
8338
  }
8279
- function goalReportBody(goalId, state, snapshot, evidenceItems) {
8339
+ function goalReportBody(goalId, state, snapshot, latestEvent, evidenceItems) {
8280
8340
  const outputs = evidenceItems.map(responsibilityEvidenceOutput);
8281
8341
  const latestOutput = outputs.at(-1);
8282
- const nextStep = state.state === "done" ? "done" : latestOutput ? nextStepFromEvidence(snapshot, latestOutput) : "wait";
8283
8342
  const facts = recordField2(snapshot, "facts") ?? recordField2(state.extra, "facts") ?? {};
8284
8343
  const blockers = uniqueStrings2([
8285
8344
  ...stringArrayField(snapshot, "blockers"),
8345
+ ...stringArrayField(latestEvent, "blockers"),
8286
8346
  ...evidenceItems.flatMap((item) => item.blockers)
8287
8347
  ]);
8288
8348
  const missingEvidence = uniqueStrings2([
8289
8349
  ...stringArrayField(snapshot, "missingEvidence"),
8290
8350
  ...evidenceItems.flatMap((item) => item.missingEvidence)
8291
8351
  ]);
8292
- const artifacts = uniqueArtifacts2(evidenceItems.flatMap((item) => item.artifacts));
8352
+ const artifacts = uniqueArtifacts2([
8353
+ ...evidenceItems.flatMap((item) => item.artifacts),
8354
+ ...artifactArrayField(latestEvent, "artifacts")
8355
+ ]);
8293
8356
  return [
8294
8357
  `# ${goalId}`,
8295
8358
  "",
8296
8359
  "## Status",
8297
8360
  `- State: ${state.state}`,
8298
8361
  `- Stage: ${stringField3(snapshot, "stage") ?? stringField3(state.extra, "stage") ?? "unknown"}`,
8299
- `- Next step: ${nextStep}`,
8362
+ `- Next step: ${nextStepFromEvent(state, snapshot, latestOutput, latestEvent)}`,
8300
8363
  `- Updated: ${state.updatedAt ?? state.createdAt ?? state.startedAt ?? "unknown"}`,
8301
8364
  "",
8302
8365
  "## Decision",
8303
- `- Reason: ${decisionReason(state, latestOutput, missingEvidence, blockers)}`,
8366
+ `- Event: ${stringField3(latestEvent, "event") ?? "unknown"}`,
8367
+ `- Reason: ${decisionReason(state, latestEvent, latestOutput, missingEvidence, blockers)}`,
8304
8368
  `- Required evidence: ${listOrNone(stringArrayField(snapshot, "requiredEvidence"))}`,
8305
8369
  `- Satisfied evidence: ${listOrNone(stringArrayField(snapshot, "satisfiedEvidence"))}`,
8306
8370
  `- Missing evidence: ${listOrNone(missingEvidence)}`,
8307
8371
  `- Blockers: ${listOrNone(blockers)}`,
8308
8372
  "",
8309
8373
  "## Responsibility Evidence",
8310
- ...outputs.flatMap((output, index) => evidenceOutputMarkdown(index + 1, output)),
8374
+ ...responsibilityEvidenceMarkdown(outputs),
8311
8375
  "",
8312
8376
  "## Facts",
8313
8377
  fencedJson(facts),
@@ -8317,9 +8381,15 @@ function goalReportBody(goalId, state, snapshot, evidenceItems) {
8317
8381
  ""
8318
8382
  ].join("\n");
8319
8383
  }
8320
- function decisionReason(state, latestOutput, missingEvidence, blockers) {
8384
+ function responsibilityEvidenceMarkdown(outputs) {
8385
+ if (outputs.length === 0) return ["- none"];
8386
+ return outputs.flatMap((output, index) => evidenceOutputMarkdown(index + 1, output));
8387
+ }
8388
+ function decisionReason(state, latestEvent, latestOutput, missingEvidence, blockers) {
8321
8389
  if (state.state === "done") return "destination evidence satisfied";
8322
8390
  if (blockers.length > 0) return blockers[0] ?? "blocked";
8391
+ const eventReason = stringField3(latestEvent, "reason") ?? stringField3(recordField2(latestEvent, "decision"), "reason");
8392
+ if (eventReason) return eventReason;
8323
8393
  const summary = stringField3(latestOutput, "summary");
8324
8394
  if (summary) return summary;
8325
8395
  if (missingEvidence.length > 0) return `waiting for ${missingEvidence[0]}`;
@@ -8364,6 +8434,20 @@ function recordField2(record2, key) {
8364
8434
  const value = record2?.[key];
8365
8435
  return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : void 0;
8366
8436
  }
8437
+ function stringArrayField(record2, key) {
8438
+ const value = record2?.[key];
8439
+ return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
8440
+ }
8441
+ function artifactArrayField(record2, key) {
8442
+ const value = record2?.[key];
8443
+ if (!Array.isArray(value)) return [];
8444
+ return value.filter(isArtifact);
8445
+ }
8446
+ function isArtifact(value) {
8447
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
8448
+ const record2 = value;
8449
+ return typeof record2.label === "string" && (record2.url === void 0 || typeof record2.url === "string") && (record2.path === void 0 || typeof record2.path === "string");
8450
+ }
8367
8451
  function uniqueArtifacts2(artifacts) {
8368
8452
  const seen = /* @__PURE__ */ new Set();
8369
8453
  const out = [];
@@ -8377,6 +8461,82 @@ ${artifact.path ?? ""}`;
8377
8461
  }
8378
8462
  return out;
8379
8463
  }
8464
+ function nextStepFromEvent(state, goalAfter, responsibilityOutput, latestEvent) {
8465
+ if (state.state === "done") return "done";
8466
+ const decisionKind = stringField3(recordField2(latestEvent, "decision"), "kind") ?? stringField3(latestEvent, "status");
8467
+ if (decisionKind === "done") return "done";
8468
+ if (decisionKind === "dispatch") return "dispatch";
8469
+ if (decisionKind === "blocked" || decisionKind === "reject-evidence") return "block";
8470
+ if (decisionKind === "wait" || decisionKind === "idle" || decisionKind === "no-state-change") return "wait";
8471
+ if (responsibilityOutput) return nextStepFromEvidence(goalAfter, responsibilityOutput);
8472
+ return "wait";
8473
+ }
8474
+ function nextStepFromEvidence(goalAfter, responsibilityOutput) {
8475
+ const status = typeof responsibilityOutput.status === "string" ? responsibilityOutput.status : "";
8476
+ const outputBlockers = stringArrayField(responsibilityOutput, "blockers");
8477
+ const goalBlockers = stringArrayField(goalAfter, "blockers");
8478
+ const missingEvidence = stringArrayField(goalAfter, "missingEvidence");
8479
+ if (goalAfter && missingEvidence.length === 0) return "done";
8480
+ if (status === "fail" || status === "blocked" || outputBlockers.length > 0) return "rescue";
8481
+ if (goalBlockers.length > 0) return "block";
8482
+ if (missingEvidence.length > 0 && status !== "noop") return "dispatch";
8483
+ return "wait";
8484
+ }
8485
+ function snapshotFromState(goalId, state) {
8486
+ const managed = managedGoalFromState(state);
8487
+ return managed ? goalRunLogSnapshot(goalId, state.state, managed) : null;
8488
+ }
8489
+ function latestGoalRunLogEvent(data, goalId) {
8490
+ const logs = data[GOAL_LOGS_KEY];
8491
+ if (!logs || typeof logs !== "object" || Array.isArray(logs)) return void 0;
8492
+ const log2 = logs[goalId];
8493
+ if (!log2 || typeof log2 !== "object" || Array.isArray(log2)) return void 0;
8494
+ const events = log2.events;
8495
+ if (!Array.isArray(events)) return void 0;
8496
+ const latest = events.at(-1);
8497
+ return latest && typeof latest === "object" && !Array.isArray(latest) ? latest : void 0;
8498
+ }
8499
+ function recordGoalReport(data, report) {
8500
+ const prior = Array.isArray(data.goalReports) ? data.goalReports : [];
8501
+ data.goalReports = [...prior, report];
8502
+ }
8503
+ var REPORT_SLUG_RE, GOAL_LOGS_KEY;
8504
+ var init_report = __esm({
8505
+ "src/goal/report.ts"() {
8506
+ "use strict";
8507
+ init_stateRepo();
8508
+ init_manager();
8509
+ init_runLog();
8510
+ REPORT_SLUG_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
8511
+ GOAL_LOGS_KEY = "__goalRunLogs";
8512
+ }
8513
+ });
8514
+
8515
+ // src/scripts/applyAgentResponsibilityReports.ts
8516
+ function flushLogs(ctx) {
8517
+ try {
8518
+ flushGoalRunLogEvents(ctx.config, ctx.cwd, ctx.data);
8519
+ } catch (err) {
8520
+ process.stderr.write(
8521
+ `[kody agentResponsibility-report] goal log persist failed (${err instanceof Error ? err.message : String(err)})
8522
+ `
8523
+ );
8524
+ }
8525
+ }
8526
+ function refreshReportOrFail(ctx, goalId, state, evidenceItems) {
8527
+ try {
8528
+ refreshGoalDashboardReport({
8529
+ config: ctx.config,
8530
+ cwd: ctx.cwd,
8531
+ data: ctx.data,
8532
+ goalId,
8533
+ state,
8534
+ evidenceItems
8535
+ });
8536
+ } catch (err) {
8537
+ fail(ctx, err instanceof Error ? err.message : String(err));
8538
+ }
8539
+ }
8380
8540
  function fail(ctx, reason) {
8381
8541
  ctx.output.reason = ctx.output.reason ? `${ctx.output.reason}; ${reason}` : reason;
8382
8542
  if (ctx.output.exitCode === 0) ctx.output.exitCode = 99;
@@ -8433,23 +8593,10 @@ function completeSatisfiedManagedGoal(state) {
8433
8593
  if (decision.kind !== "done") return state;
8434
8594
  return writeManagedGoalToState({ ...state, state: "done" }, managed);
8435
8595
  }
8436
- function snapshotFromState(goalId, state) {
8596
+ function snapshotFromState2(goalId, state) {
8437
8597
  const managed = managedGoalFromState(state);
8438
8598
  return managed ? goalRunLogSnapshot(goalId, state.state, managed) : null;
8439
8599
  }
8440
- function responsibilityEvidenceOutput(evidence) {
8441
- return {
8442
- kind: "responsibility-evidence",
8443
- sources: evidence.sources,
8444
- status: evidence.status,
8445
- summary: evidence.summary,
8446
- evidence: evidence.evidence ?? {},
8447
- facts: evidence.facts,
8448
- artifacts: evidence.artifacts,
8449
- missingEvidence: evidence.missingEvidence,
8450
- blockers: evidence.blockers
8451
- };
8452
- }
8453
8600
  function evidenceInspection(goalBefore, goalAfter, responsibilityOutput, explicitEvidence) {
8454
8601
  return {
8455
8602
  expectedEvidence: {
@@ -8471,22 +8618,22 @@ function evidenceDecision(change, goalAfter, responsibilityOutput) {
8471
8618
  return {
8472
8619
  kind: change ? "accept-evidence" : "no-state-change",
8473
8620
  status: responsibilityOutput.status,
8474
- nextStep: nextStepFromEvidence(goalAfter, responsibilityOutput),
8621
+ nextStep: nextStepFromEvidence2(goalAfter, responsibilityOutput),
8475
8622
  reason: responsibilityOutput.summary
8476
8623
  };
8477
8624
  }
8478
- function nextStepFromEvidence(goalAfter, responsibilityOutput) {
8625
+ function nextStepFromEvidence2(goalAfter, responsibilityOutput) {
8479
8626
  const status = typeof responsibilityOutput.status === "string" ? responsibilityOutput.status : "";
8480
- const outputBlockers = stringArrayField(responsibilityOutput, "blockers");
8481
- const goalBlockers = stringArrayField(goalAfter, "blockers");
8482
- const missingEvidence = stringArrayField(goalAfter, "missingEvidence");
8627
+ const outputBlockers = stringArrayField2(responsibilityOutput, "blockers");
8628
+ const goalBlockers = stringArrayField2(goalAfter, "blockers");
8629
+ const missingEvidence = stringArrayField2(goalAfter, "missingEvidence");
8483
8630
  if (goalAfter && missingEvidence.length === 0) return "done";
8484
8631
  if (status === "fail" || status === "blocked" || outputBlockers.length > 0) return "rescue";
8485
8632
  if (goalBlockers.length > 0) return "block";
8486
8633
  if (missingEvidence.length > 0 && status !== "noop") return "dispatch";
8487
8634
  return "wait";
8488
8635
  }
8489
- function stringArrayField(record2, key) {
8636
+ function stringArrayField2(record2, key) {
8490
8637
  const value = record2?.[key];
8491
8638
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
8492
8639
  }
@@ -8494,7 +8641,7 @@ function describeMessage(goalId, evidenceItems) {
8494
8641
  const pieces = evidenceItems.map((evidence) => `${evidence.sources.join("+")}:${evidence.status}`);
8495
8642
  return `Apply agentResponsibility output to ${goalId}${pieces.length > 0 ? ` (${pieces.join("; ")})` : ""}`;
8496
8643
  }
8497
- var REPORT_SLUG_RE, applyAgentResponsibilityReports;
8644
+ var applyAgentResponsibilityReports;
8498
8645
  var init_applyAgentResponsibilityReports = __esm({
8499
8646
  "src/scripts/applyAgentResponsibilityReports.ts"() {
8500
8647
  "use strict";
@@ -8502,11 +8649,10 @@ var init_applyAgentResponsibilityReports = __esm({
8502
8649
  init_agent_responsibilityReport();
8503
8650
  init_agent_responsibilityResult();
8504
8651
  init_manager();
8652
+ init_report();
8505
8653
  init_runLog();
8506
8654
  init_state2();
8507
8655
  init_stateStore();
8508
- init_stateRepo();
8509
- REPORT_SLUG_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
8510
8656
  applyAgentResponsibilityReports = async (ctx, _profile, agentResult) => {
8511
8657
  const reports = collectReports(ctx.data.agentResponsibilityReports, agentResult);
8512
8658
  const results = collectResults(ctx.data.dutyResults, agentResult);
@@ -8541,9 +8687,9 @@ var init_applyAgentResponsibilityReports = __esm({
8541
8687
  }
8542
8688
  let next = prior;
8543
8689
  for (const evidence of goalEvidence) {
8544
- const beforeSnapshot = snapshotFromState(goalId, next);
8690
+ const beforeSnapshot = snapshotFromState2(goalId, next);
8545
8691
  next = applyAgentResponsibilityEvidenceToGoalState(next, evidence);
8546
- const afterSnapshot = snapshotFromState(goalId, next);
8692
+ const afterSnapshot = snapshotFromState2(goalId, next);
8547
8693
  const change = goalRunLogChange(beforeSnapshot, afterSnapshot);
8548
8694
  const output = responsibilityEvidenceOutput(evidence);
8549
8695
  stageGoalRunLogEvent(ctx.data, goalId, {
@@ -8566,9 +8712,9 @@ var init_applyAgentResponsibilityReports = __esm({
8566
8712
  change
8567
8713
  });
8568
8714
  }
8569
- const beforeCompletionSnapshot = snapshotFromState(goalId, next);
8715
+ const beforeCompletionSnapshot = snapshotFromState2(goalId, next);
8570
8716
  next = completeSatisfiedManagedGoal(next);
8571
- const afterCompletionSnapshot = snapshotFromState(goalId, next);
8717
+ const afterCompletionSnapshot = snapshotFromState2(goalId, next);
8572
8718
  if (prior.state !== "done" && next.state === "done") {
8573
8719
  stageGoalRunLogEvent(ctx.data, goalId, {
8574
8720
  source: "goal-loop",
@@ -8588,19 +8734,14 @@ var init_applyAgentResponsibilityReports = __esm({
8588
8734
  }
8589
8735
  const changed = serializeGoalState(next) !== serializeGoalState(prior);
8590
8736
  const nextForOutput = changed ? { ...next, updatedAt: nowIso() } : next;
8591
- writeGoalDashboardReport(
8592
- ctx,
8593
- goalId,
8594
- nextForOutput,
8595
- afterCompletionSnapshot ?? beforeCompletionSnapshot,
8596
- goalEvidence
8597
- );
8598
- if (!changed) {
8737
+ try {
8738
+ if (changed) {
8739
+ putGoalState(ctx.config, goalId, nextForOutput, describeMessage(goalId, goalEvidence), ctx.cwd);
8740
+ }
8741
+ refreshReportOrFail(ctx, goalId, nextForOutput, goalEvidence);
8742
+ } finally {
8599
8743
  flushLogs(ctx);
8600
- continue;
8601
8744
  }
8602
- putGoalState(ctx.config, goalId, nextForOutput, describeMessage(goalId, goalEvidence), ctx.cwd);
8603
- flushLogs(ctx);
8604
8745
  }
8605
8746
  };
8606
8747
  }
@@ -8872,6 +9013,22 @@ var init_commitAndPush = __esm({
8872
9013
  });
8873
9014
 
8874
9015
  // src/scripts/commitGoalState.ts
9016
+ function refreshReportOrFail2(ctx, goalId, state) {
9017
+ if (!state) return;
9018
+ try {
9019
+ refreshGoalDashboardReport({
9020
+ config: ctx.config,
9021
+ cwd: ctx.cwd,
9022
+ data: ctx.data,
9023
+ goalId,
9024
+ state
9025
+ });
9026
+ } catch (err) {
9027
+ const reason = err instanceof Error ? err.message : String(err);
9028
+ ctx.output.reason = ctx.output.reason ? `${ctx.output.reason}; ${reason}` : reason;
9029
+ if (ctx.output.exitCode === 0) ctx.output.exitCode = 99;
9030
+ }
9031
+ }
8875
9032
  function flushLogs2(ctx) {
8876
9033
  try {
8877
9034
  flushGoalRunLogEvents(ctx.config, ctx.cwd, ctx.data);
@@ -8890,6 +9047,7 @@ var commitGoalState;
8890
9047
  var init_commitGoalState = __esm({
8891
9048
  "src/scripts/commitGoalState.ts"() {
8892
9049
  "use strict";
9050
+ init_report();
8893
9051
  init_runLog();
8894
9052
  init_stateStore();
8895
9053
  commitGoalState = async (ctx) => {
@@ -8899,6 +9057,7 @@ var init_commitGoalState = __esm({
8899
9057
  return;
8900
9058
  }
8901
9059
  if (ctx.data.goalPersistChanged !== true) {
9060
+ refreshReportOrFail2(ctx, goal.id, goal.raw);
8902
9061
  flushLogs2(ctx);
8903
9062
  return;
8904
9063
  }
@@ -8909,6 +9068,7 @@ var init_commitGoalState = __esm({
8909
9068
  }
8910
9069
  try {
8911
9070
  putGoalState(ctx.config, goal.id, updated, describeCommitMessage(goal), ctx.cwd);
9071
+ refreshReportOrFail2(ctx, goal.id, updated);
8912
9072
  } catch (err) {
8913
9073
  process.stderr.write(
8914
9074
  `[goal-manager] commitGoalState: persist to state repo failed (${err instanceof Error ? err.message : String(err)}); will retry next tick
@@ -22078,9 +22238,9 @@ Usage:
22078
22238
  kody-engine help
22079
22239
  kody-engine version
22080
22240
 
22081
- Top-level work commands are agentResponsibility actions. A agentResponsibility owns the public action name
22082
- and selects an implementation agentAction. Use exec only for internal agentAction
22083
- profiles such as scheduled helpers.
22241
+ Top-level work commands are capabilities. A capability owns the public command name
22242
+ and resolves the implementation that runs it. Use exec only for internal implementation
22243
+ profiles and legacy scheduled helpers.
22084
22244
 
22085
22245
  Exit codes:
22086
22246
  0 success (PR opened, verify passed \u2014 or resolve produced a merge commit)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.259",
3
+ "version": "0.4.261",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative agentAction profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",