@kody-ade/kody-engine 0.4.259 → 0.4.260
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 +44 -17
- package/dist/agent-actions/agent-factory/prompt.md +9 -3
- package/dist/agent-actions/types.ts +10 -8
- package/dist/bin/kody.js +258 -98
- package/package.json +1 -1
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
|
|
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 —
|
|
78
|
-
│ src/executor.ts — runs
|
|
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
|
-
│
|
|
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
|
|
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
|
|
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),
|
|
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
|
|
127
|
-
kody-engine agent-responsibility-scheduler # fan out due .kody/
|
|
128
|
-
kody-engine agent-responsibility-tick --agentResponsibility <slug> [--force] # one agent tick for one
|
|
129
|
-
kody-engine agent-responsibility-tick-scripted --agentResponsibility <slug> [--force] # one deterministic tickScript
|
|
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
|
-
###
|
|
160
|
+
### Capabilities
|
|
146
161
|
|
|
147
|
-
A **
|
|
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
|
|
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
|
|
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
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
60
|
-
* rather than embedding it. When set,
|
|
61
|
-
* full profile (claudeCode/scripts/prompt/agents)
|
|
62
|
-
* name + agent (
|
|
63
|
-
*
|
|
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
|
|
521
|
-
// the
|
|
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
|
|
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.
|
|
18
|
+
version: "0.4.260",
|
|
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
|
|
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 [
|
|
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 [
|
|
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
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
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/
|
|
8245
|
-
function
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
);
|
|
8253
|
-
}
|
|
8254
|
-
}
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
const
|
|
8263
|
-
|
|
8264
|
-
const
|
|
8265
|
-
|
|
8266
|
-
|
|
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
|
|
8276
|
-
|
|
8277
|
-
|
|
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(
|
|
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: ${
|
|
8362
|
+
`- Next step: ${nextStepFromEvent(state, snapshot, latestOutput, latestEvent)}`,
|
|
8300
8363
|
`- Updated: ${state.updatedAt ?? state.createdAt ?? state.startedAt ?? "unknown"}`,
|
|
8301
8364
|
"",
|
|
8302
8365
|
"## Decision",
|
|
8303
|
-
`-
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
8621
|
+
nextStep: nextStepFromEvidence2(goalAfter, responsibilityOutput),
|
|
8475
8622
|
reason: responsibilityOutput.summary
|
|
8476
8623
|
};
|
|
8477
8624
|
}
|
|
8478
|
-
function
|
|
8625
|
+
function nextStepFromEvidence2(goalAfter, responsibilityOutput) {
|
|
8479
8626
|
const status = typeof responsibilityOutput.status === "string" ? responsibilityOutput.status : "";
|
|
8480
|
-
const outputBlockers =
|
|
8481
|
-
const goalBlockers =
|
|
8482
|
-
const 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
|
|
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
|
|
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 =
|
|
8690
|
+
const beforeSnapshot = snapshotFromState2(goalId, next);
|
|
8545
8691
|
next = applyAgentResponsibilityEvidenceToGoalState(next, evidence);
|
|
8546
|
-
const afterSnapshot =
|
|
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 =
|
|
8715
|
+
const beforeCompletionSnapshot = snapshotFromState2(goalId, next);
|
|
8570
8716
|
next = completeSatisfiedManagedGoal(next);
|
|
8571
|
-
const afterCompletionSnapshot =
|
|
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
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
|
|
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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.260",
|
|
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",
|