@kody-ade/kody-engine 0.4.630 → 0.4.632
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/kody.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@kody-ade/kody-engine",
|
|
18
|
-
version: "0.4.
|
|
18
|
+
version: "0.4.632",
|
|
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
|
repository: {
|
|
@@ -2563,6 +2563,7 @@ function parseReportPublication(value) {
|
|
|
2563
2563
|
const slugFact = stringField(value.slugFact);
|
|
2564
2564
|
const title = stringField(value.title);
|
|
2565
2565
|
const titleFact = stringField(value.titleFact);
|
|
2566
|
+
const bodyFact = stringField(value.bodyFact);
|
|
2566
2567
|
const publishWhenFact = stringField(value.publishWhenFact);
|
|
2567
2568
|
const reviewStatus = stringField(value.reviewStatus);
|
|
2568
2569
|
const reviewArea = stringField(value.reviewArea);
|
|
@@ -2575,6 +2576,7 @@ function parseReportPublication(value) {
|
|
|
2575
2576
|
...slugFact ? { slugFact } : {},
|
|
2576
2577
|
...title ? { title } : {},
|
|
2577
2578
|
...titleFact ? { titleFact } : {},
|
|
2579
|
+
...bodyFact ? { bodyFact } : {},
|
|
2578
2580
|
...publishWhenFact ? { publishWhenFact } : {},
|
|
2579
2581
|
...reviewStatus ? { reviewStatus } : {},
|
|
2580
2582
|
...reviewArea ? { reviewArea } : {}
|
|
@@ -3388,6 +3390,12 @@ function createStateBackendFromEnv(env = process.env, client) {
|
|
|
3388
3390
|
updatedAt
|
|
3389
3391
|
});
|
|
3390
3392
|
},
|
|
3393
|
+
async listReports(tenantId2) {
|
|
3394
|
+
const result = await transport.query(anyApi.reports.list, {
|
|
3395
|
+
tenantId: requireTenant(tenantId2)
|
|
3396
|
+
});
|
|
3397
|
+
return Array.isArray(result) ? result : [];
|
|
3398
|
+
},
|
|
3391
3399
|
async listIntents(tenantId2) {
|
|
3392
3400
|
const result = await transport.query(anyApi.intents.list, { tenantId: requireTenant(tenantId2) });
|
|
3393
3401
|
return Array.isArray(result) ? result : [];
|
|
@@ -3989,6 +3997,105 @@ function capabilityToolDefinitions(opts) {
|
|
|
3989
3997
|
return { content: [{ type: "text", text: text2 }] };
|
|
3990
3998
|
}
|
|
3991
3999
|
};
|
|
4000
|
+
const readLatestReportTool = {
|
|
4001
|
+
name: "read_latest_report",
|
|
4002
|
+
description: "Read the newest persisted Kody Report for this repository. Optionally restrict to one stable report slug or reports newer than an ISO timestamp. Returns the Report body and metadata; use it as evidence before deciding whether work is needed.",
|
|
4003
|
+
inputSchema: {
|
|
4004
|
+
slug: z3.string().regex(/^[a-z0-9][a-z0-9_-]{0,79}$/).optional(),
|
|
4005
|
+
since: z3.string().datetime().optional()
|
|
4006
|
+
},
|
|
4007
|
+
handler: async (args) => {
|
|
4008
|
+
const slug = typeof args.slug === "string" ? args.slug : void 0;
|
|
4009
|
+
const since = typeof args.since === "string" ? args.since : void 0;
|
|
4010
|
+
const reports = await createStateBackendFromEnv().listReports(opts.repoSlug);
|
|
4011
|
+
const report = reports.filter((candidate) => (!slug || candidate.slug === slug) && (!since || candidate.updatedAt > since)).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt))[0];
|
|
4012
|
+
return {
|
|
4013
|
+
content: [
|
|
4014
|
+
{
|
|
4015
|
+
type: "text",
|
|
4016
|
+
text: JSON.stringify(
|
|
4017
|
+
report ? {
|
|
4018
|
+
found: true,
|
|
4019
|
+
slug: report.slug,
|
|
4020
|
+
runId: report.runId,
|
|
4021
|
+
title: report.title,
|
|
4022
|
+
body: report.body,
|
|
4023
|
+
meta: report.meta,
|
|
4024
|
+
updatedAt: report.updatedAt
|
|
4025
|
+
} : { found: false },
|
|
4026
|
+
null,
|
|
4027
|
+
2
|
|
4028
|
+
)
|
|
4029
|
+
}
|
|
4030
|
+
]
|
|
4031
|
+
};
|
|
4032
|
+
}
|
|
4033
|
+
};
|
|
4034
|
+
const reconcileTodoTool = {
|
|
4035
|
+
name: "reconcile_todo",
|
|
4036
|
+
description: "Idempotently create, update, close, or reopen one canonical repository Todo for a recurring problem. The stable slug and item id prevent duplicates. Repeating the same state is a no-op; unrelated items in an existing Todo are preserved.",
|
|
4037
|
+
inputSchema: {
|
|
4038
|
+
slug: z3.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/),
|
|
4039
|
+
itemId: z3.string().regex(/^[a-z0-9][a-z0-9_-]{0,79}$/).optional(),
|
|
4040
|
+
title: z3.string().min(1).max(160),
|
|
4041
|
+
description: z3.string().max(2e4).optional(),
|
|
4042
|
+
status: z3.enum(["open", "resolved"]),
|
|
4043
|
+
reportSlug: z3.string().regex(/^[a-z0-9][a-z0-9_-]{0,79}$/),
|
|
4044
|
+
reportRunId: z3.string().max(160).optional(),
|
|
4045
|
+
evidence: z3.string().max(2e4).optional()
|
|
4046
|
+
},
|
|
4047
|
+
handler: async (args) => {
|
|
4048
|
+
const slug = String(args.slug);
|
|
4049
|
+
const itemId = typeof args.itemId === "string" ? args.itemId : "finding";
|
|
4050
|
+
const title = String(args.title).trim();
|
|
4051
|
+
const description = typeof args.description === "string" ? args.description.trim() : "";
|
|
4052
|
+
const status = args.status === "resolved" ? "resolved" : "open";
|
|
4053
|
+
const reportSlug = String(args.reportSlug);
|
|
4054
|
+
const reportRunId = typeof args.reportRunId === "string" ? args.reportRunId : void 0;
|
|
4055
|
+
const evidence = typeof args.evidence === "string" ? args.evidence.trim() : "";
|
|
4056
|
+
const backend = createStateBackendFromEnv();
|
|
4057
|
+
const existing = await backend.getRepoDoc(opts.repoSlug, `todo:${slug}`);
|
|
4058
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4059
|
+
const current = existing?.doc && typeof existing.doc === "object" && !Array.isArray(existing.doc) ? existing.doc : {};
|
|
4060
|
+
const currentItems = Array.isArray(current.items) ? current.items.filter((item) => Boolean(item && typeof item === "object" && !Array.isArray(item))) : [];
|
|
4061
|
+
const previous = currentItems.find((item) => item.id === itemId);
|
|
4062
|
+
const completed = status === "resolved";
|
|
4063
|
+
const previousMeta = previous?.meta && typeof previous.meta === "object" && !Array.isArray(previous.meta) ? previous.meta : {};
|
|
4064
|
+
const unchanged = Boolean(
|
|
4065
|
+
previous && previous.completed === completed && previous.title === title && String(previous.body ?? "") === evidence && previousMeta.reportSlug === reportSlug
|
|
4066
|
+
);
|
|
4067
|
+
if (unchanged) {
|
|
4068
|
+
return { content: [{ type: "text", text: JSON.stringify({ changed: false, slug, status }) }] };
|
|
4069
|
+
}
|
|
4070
|
+
const nextItem = {
|
|
4071
|
+
id: itemId,
|
|
4072
|
+
title,
|
|
4073
|
+
body: evidence,
|
|
4074
|
+
assignee: null,
|
|
4075
|
+
completed,
|
|
4076
|
+
createdAt: typeof previous?.createdAt === "string" ? previous.createdAt : now,
|
|
4077
|
+
completedAt: completed ? now : null,
|
|
4078
|
+
meta: {
|
|
4079
|
+
...previousMeta,
|
|
4080
|
+
source: "live-agent",
|
|
4081
|
+
reportSlug,
|
|
4082
|
+
...reportRunId ? { reportRunId } : {},
|
|
4083
|
+
status
|
|
4084
|
+
}
|
|
4085
|
+
};
|
|
4086
|
+
const items = previous ? currentItems.map((item) => item.id === itemId ? nextItem : item) : [...currentItems, nextItem];
|
|
4087
|
+
const doc = {
|
|
4088
|
+
...current,
|
|
4089
|
+
version: 1,
|
|
4090
|
+
title,
|
|
4091
|
+
description,
|
|
4092
|
+
createdAt: typeof current.createdAt === "string" ? current.createdAt : now,
|
|
4093
|
+
items
|
|
4094
|
+
};
|
|
4095
|
+
await backend.saveRepoDoc(opts.repoSlug, `todo:${slug}`, doc, existing?.updatedAt);
|
|
4096
|
+
return { content: [{ type: "text", text: JSON.stringify({ changed: true, slug, status }) }] };
|
|
4097
|
+
}
|
|
4098
|
+
};
|
|
3992
4099
|
const cmsTools = dashboardCmsToolDefinitions({
|
|
3993
4100
|
repoSlug: opts.repoSlug,
|
|
3994
4101
|
assertWriteAllowed: () => assertCmsWriteAllowed(opts)
|
|
@@ -4005,6 +4112,8 @@ function capabilityToolDefinitions(opts) {
|
|
|
4005
4112
|
ensureIssueTool,
|
|
4006
4113
|
ensureCommentTool,
|
|
4007
4114
|
startCapabilityTool,
|
|
4115
|
+
readLatestReportTool,
|
|
4116
|
+
reconcileTodoTool,
|
|
4008
4117
|
...cmsTools
|
|
4009
4118
|
];
|
|
4010
4119
|
}
|
|
@@ -4033,6 +4142,7 @@ var init_capabilityMcp = __esm({
|
|
|
4033
4142
|
init_issue();
|
|
4034
4143
|
init_registry();
|
|
4035
4144
|
init_trustPolicy();
|
|
4145
|
+
init_state_backend();
|
|
4036
4146
|
FAIL_CONCLUSIONS = /* @__PURE__ */ new Set(["FAILURE", "TIMED_OUT", "ACTION_REQUIRED", "STARTUP_FAILURE", "CANCELLED"]);
|
|
4037
4147
|
RUNNING_STATUSES = /* @__PURE__ */ new Set(["IN_PROGRESS", "QUEUED", "PENDING", "WAITING", "REQUESTED"]);
|
|
4038
4148
|
THREAD_BODY_MAX = 4e3;
|
|
@@ -4052,6 +4162,8 @@ var init_capabilityMcp = __esm({
|
|
|
4052
4162
|
"ensure_issue",
|
|
4053
4163
|
"ensure_comment",
|
|
4054
4164
|
"start_capability",
|
|
4165
|
+
"read_latest_report",
|
|
4166
|
+
"reconcile_todo",
|
|
4055
4167
|
...DASHBOARD_CMS_MCP_TOOL_NAMES
|
|
4056
4168
|
];
|
|
4057
4169
|
}
|
|
@@ -16693,7 +16805,7 @@ var init_loadLiveAgent = __esm({
|
|
|
16693
16805
|
}
|
|
16694
16806
|
};
|
|
16695
16807
|
ctx.data.jobStateJson = JSON.stringify(state, null, 2);
|
|
16696
|
-
ctx.data.capabilityTools = ["start_capability"];
|
|
16808
|
+
ctx.data.capabilityTools = ["start_capability", "read_latest_report", "reconcile_todo"];
|
|
16697
16809
|
ctx.data.capabilityToolMode = "lock";
|
|
16698
16810
|
profile.claudeCode.enableSubmitTool = true;
|
|
16699
16811
|
};
|
|
@@ -13,7 +13,12 @@
|
|
|
13
13
|
"maxThinkingTokens": null,
|
|
14
14
|
"systemPromptAppend": null,
|
|
15
15
|
"enableSubmitTool": true,
|
|
16
|
-
"tools": [
|
|
16
|
+
"tools": [
|
|
17
|
+
"mcp__kody-capability__start_capability",
|
|
18
|
+
"mcp__kody-capability__read_latest_report",
|
|
19
|
+
"mcp__kody-capability__reconcile_todo",
|
|
20
|
+
"mcp__kody-submit__submit_state"
|
|
21
|
+
],
|
|
17
22
|
"hooks": [], "skills": [], "commands": [], "subagents": [], "plugins": [], "mcpServers": []
|
|
18
23
|
},
|
|
19
24
|
"cliTools": [],
|
|
@@ -30,7 +30,9 @@ You are a persistent Kody Agent completing one scheduled cycle.
|
|
|
30
30
|
{{jobStateJson}}
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
Inspect current conditions, decide the best next action toward the Intent, and use only assigned capabilities.
|
|
33
|
+
Inspect current conditions, decide the best next action toward the Intent, and use only assigned capabilities. A dispatched capability may finish after this cycle: record its run, then inspect its Report on a later cycle. Treat the Report as evidence; you make the decision.
|
|
34
|
+
|
|
35
|
+
For an actionable recurring problem, reconcile one stable Todo whose slug identifies the problem. Reuse and update that Todo while the problem remains open, close it when a later Report proves recovery, and reopen the same Todo if the problem returns. Do not create work merely to appear active. If the newest Report was already handled or waiting is correct, make no change and record what is being awaited.
|
|
34
36
|
|
|
35
37
|
As your final action, call `submit_state` exactly once with:
|
|
36
38
|
- `cursor`: the next continuation cursor;
|
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.632",
|
|
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
|
"repository": {
|