@kody-ade/kody-engine 0.4.245 → 0.4.246
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 +128 -1
- package/package.json +22 -23
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.246",
|
|
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",
|
|
@@ -5958,6 +5958,20 @@ function asRoute(value) {
|
|
|
5958
5958
|
}
|
|
5959
5959
|
return route;
|
|
5960
5960
|
}
|
|
5961
|
+
function asPreferredRunTime(value) {
|
|
5962
|
+
const raw = asRecord(value);
|
|
5963
|
+
if (!raw) return void 0;
|
|
5964
|
+
if (typeof raw.time !== "string" || !/^([01]\d|2[0-3]):[0-5]\d$/.test(raw.time)) return void 0;
|
|
5965
|
+
if (typeof raw.timezone !== "string" || raw.timezone.trim().length === 0) return void 0;
|
|
5966
|
+
return { time: raw.time, timezone: raw.timezone };
|
|
5967
|
+
}
|
|
5968
|
+
function asLoopTarget(value) {
|
|
5969
|
+
const raw = asRecord(value);
|
|
5970
|
+
if (!raw) return void 0;
|
|
5971
|
+
if (raw.type !== "goal" && raw.type !== "agentResponsibility") return void 0;
|
|
5972
|
+
if (typeof raw.id !== "string" || raw.id.trim().length === 0) return void 0;
|
|
5973
|
+
return { type: raw.type, id: raw.id };
|
|
5974
|
+
}
|
|
5961
5975
|
function managedGoalFromState(state) {
|
|
5962
5976
|
const extra = state.extra;
|
|
5963
5977
|
const destination = asRecord(extra.destination);
|
|
@@ -5974,6 +5988,9 @@ function managedGoalFromState(state) {
|
|
|
5974
5988
|
destination: { outcome: destination.outcome, evidence },
|
|
5975
5989
|
agentResponsibilities,
|
|
5976
5990
|
route,
|
|
5991
|
+
schedule: typeof extra.schedule === "string" ? extra.schedule : void 0,
|
|
5992
|
+
preferredRunTime: asPreferredRunTime(extra.preferredRunTime),
|
|
5993
|
+
loopTarget: asLoopTarget(extra.loopTarget),
|
|
5977
5994
|
stage: typeof extra.stage === "string" ? extra.stage : void 0,
|
|
5978
5995
|
facts,
|
|
5979
5996
|
blockers
|
|
@@ -6572,6 +6589,41 @@ import * as path25 from "path";
|
|
|
6572
6589
|
function isAgentResponsibilityCadenceGoal(goal, extra) {
|
|
6573
6590
|
return extra.scheduleMode === "agentLoop" || extra.scheduler === "agentLoop" || goal.type === "standing" && goal.agentResponsibilities.length > 0;
|
|
6574
6591
|
}
|
|
6592
|
+
function isGoalTargetLoop(goal) {
|
|
6593
|
+
return goal.type === "agentLoop" && goal.loopTarget?.type === "goal" && goal.loopTarget.id.trim().length > 0;
|
|
6594
|
+
}
|
|
6595
|
+
function planGoalTargetLoopSchedule(opts) {
|
|
6596
|
+
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
6597
|
+
const at = now.toISOString();
|
|
6598
|
+
const targetId = opts.goal.loopTarget?.type === "goal" ? opts.goal.loopTarget.id.trim() : "";
|
|
6599
|
+
if (!targetId) {
|
|
6600
|
+
const reason = "goal target loop missing target goal";
|
|
6601
|
+
return targetLoopDecision("blocked", reason, at);
|
|
6602
|
+
}
|
|
6603
|
+
const preferred = opts.goal.preferredRunTime;
|
|
6604
|
+
if (preferred) {
|
|
6605
|
+
const gate = preferredRunTimeGate(preferred, now, opts.previousScheduleState);
|
|
6606
|
+
if (!gate.ok) return targetLoopDecision("idle", gate.reason, at);
|
|
6607
|
+
}
|
|
6608
|
+
return {
|
|
6609
|
+
kind: "dispatch",
|
|
6610
|
+
reason: `dispatch goal ${targetId}`,
|
|
6611
|
+
dispatch: { action: "goal-manager", agentAction: "goal-manager", cliArgs: { goal: targetId } },
|
|
6612
|
+
scheduleState: {
|
|
6613
|
+
mode: "agentLoop",
|
|
6614
|
+
lastGoalTickAt: at,
|
|
6615
|
+
lastDecision: {
|
|
6616
|
+
kind: "dispatch",
|
|
6617
|
+
targetType: "goal",
|
|
6618
|
+
targetId,
|
|
6619
|
+
agentAction: "goal-manager",
|
|
6620
|
+
reason: preferred ? `preferred time ${preferred.time} ${preferred.timezone}` : "ready target loop tick",
|
|
6621
|
+
at
|
|
6622
|
+
},
|
|
6623
|
+
agentResponsibilities: {}
|
|
6624
|
+
}
|
|
6625
|
+
};
|
|
6626
|
+
}
|
|
6575
6627
|
async function planGoalAgentResponsibilitySchedule(opts) {
|
|
6576
6628
|
const jobsDir = opts.jobsDir ?? ".kody/agent-responsibilities";
|
|
6577
6629
|
const jobsRoot = path25.join(opts.cwd, jobsDir);
|
|
@@ -6695,6 +6747,64 @@ function validIso(value) {
|
|
|
6695
6747
|
function markAgentResponsibilitySelected(status, now) {
|
|
6696
6748
|
return { ...status, lastFiredAt: now.toISOString() };
|
|
6697
6749
|
}
|
|
6750
|
+
function targetLoopDecision(kind, reason, at) {
|
|
6751
|
+
return {
|
|
6752
|
+
kind,
|
|
6753
|
+
reason,
|
|
6754
|
+
scheduleState: {
|
|
6755
|
+
mode: "agentLoop",
|
|
6756
|
+
lastGoalTickAt: at,
|
|
6757
|
+
lastDecision: { kind, reason, at },
|
|
6758
|
+
agentResponsibilities: {}
|
|
6759
|
+
}
|
|
6760
|
+
};
|
|
6761
|
+
}
|
|
6762
|
+
function preferredRunTimeGate(preferred, now, previous) {
|
|
6763
|
+
const current = zonedTimeParts(now, preferred.timezone);
|
|
6764
|
+
if (!current) return { ok: false, reason: `invalid preferred timezone: ${preferred.timezone}` };
|
|
6765
|
+
const preferredMinute = preferredTimeToMinute(preferred.time);
|
|
6766
|
+
if (preferredMinute === null) return { ok: false, reason: `invalid preferred time: ${preferred.time}` };
|
|
6767
|
+
const currentMinute = current.hour * 60 + current.minute;
|
|
6768
|
+
if (currentMinute < preferredMinute) {
|
|
6769
|
+
return { ok: false, reason: `waiting preferred time ${preferred.time} ${preferred.timezone}` };
|
|
6770
|
+
}
|
|
6771
|
+
const lastDispatchAt = previous?.lastDecision.kind === "dispatch" ? previous.lastDecision.at : void 0;
|
|
6772
|
+
if (lastDispatchAt) {
|
|
6773
|
+
const last = zonedTimeParts(new Date(lastDispatchAt), preferred.timezone);
|
|
6774
|
+
if (last?.date === current.date) {
|
|
6775
|
+
return { ok: false, reason: `already dispatched today at preferred time ${preferred.time} ${preferred.timezone}` };
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
return { ok: true };
|
|
6779
|
+
}
|
|
6780
|
+
function preferredTimeToMinute(value) {
|
|
6781
|
+
const match = value.match(/^([01]\d|2[0-3]):([0-5]\d)$/);
|
|
6782
|
+
if (!match) return null;
|
|
6783
|
+
return Number(match[1]) * 60 + Number(match[2]);
|
|
6784
|
+
}
|
|
6785
|
+
function zonedTimeParts(date, timezone) {
|
|
6786
|
+
try {
|
|
6787
|
+
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
6788
|
+
timeZone: timezone,
|
|
6789
|
+
year: "numeric",
|
|
6790
|
+
month: "2-digit",
|
|
6791
|
+
day: "2-digit",
|
|
6792
|
+
hour: "2-digit",
|
|
6793
|
+
minute: "2-digit",
|
|
6794
|
+
hourCycle: "h23"
|
|
6795
|
+
}).formatToParts(date);
|
|
6796
|
+
const get = (type) => parts.find((part) => part.type === type)?.value;
|
|
6797
|
+
const year = get("year");
|
|
6798
|
+
const month = get("month");
|
|
6799
|
+
const day = get("day");
|
|
6800
|
+
const hour = get("hour");
|
|
6801
|
+
const minute = get("minute");
|
|
6802
|
+
if (!year || !month || !day || !hour || !minute) return null;
|
|
6803
|
+
return { date: `${year}-${month}-${day}`, hour: Number(hour), minute: Number(minute) };
|
|
6804
|
+
} catch {
|
|
6805
|
+
return null;
|
|
6806
|
+
}
|
|
6807
|
+
}
|
|
6698
6808
|
var init_goalAgentResponsibilityScheduling = __esm({
|
|
6699
6809
|
"src/scripts/goalAgentResponsibilityScheduling.ts"() {
|
|
6700
6810
|
"use strict";
|
|
@@ -6806,6 +6916,23 @@ var init_advanceManagedGoal = __esm({
|
|
|
6806
6916
|
ctx.output.reason = reason;
|
|
6807
6917
|
return;
|
|
6808
6918
|
}
|
|
6919
|
+
if (isGoalTargetLoop(managed)) {
|
|
6920
|
+
const previousScheduleState = goal.raw.extra.scheduleState && typeof goal.raw.extra.scheduleState === "object" ? goal.raw.extra.scheduleState : void 0;
|
|
6921
|
+
const decision2 = planGoalTargetLoopSchedule({ goal: managed, previousScheduleState });
|
|
6922
|
+
restoreGoalIdFact();
|
|
6923
|
+
goal.raw = writeManagedGoalToState({ ...goal.raw, state: goal.state }, managed);
|
|
6924
|
+
goal.raw.extra.scheduleState = decision2.scheduleState;
|
|
6925
|
+
ctx.data.managedGoalDecision = decision2;
|
|
6926
|
+
if (decision2.kind === "dispatch" && decision2.dispatch) {
|
|
6927
|
+
ctx.output.nextDispatch = {
|
|
6928
|
+
action: decision2.dispatch.action,
|
|
6929
|
+
agentAction: decision2.dispatch.agentAction,
|
|
6930
|
+
cliArgs: decision2.dispatch.cliArgs
|
|
6931
|
+
};
|
|
6932
|
+
}
|
|
6933
|
+
ctx.output.reason = decision2.reason;
|
|
6934
|
+
return;
|
|
6935
|
+
}
|
|
6809
6936
|
if (isAgentResponsibilityCadenceGoal(managed, goal.raw.extra)) {
|
|
6810
6937
|
const previousScheduleState = goal.raw.extra.scheduleState && typeof goal.raw.extra.scheduleState === "object" ? goal.raw.extra.scheduleState : void 0;
|
|
6811
6938
|
const decision2 = await planGoalAgentResponsibilitySchedule({
|
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.246",
|
|
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",
|
|
@@ -12,26 +12,6 @@
|
|
|
12
12
|
"templates",
|
|
13
13
|
"kody.config.schema.json"
|
|
14
14
|
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"kody:run": "tsx bin/kody.ts",
|
|
17
|
-
"serve": "tsx bin/kody.ts serve",
|
|
18
|
-
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
19
|
-
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
20
|
-
"build": "tsup && node scripts/copy-assets.cjs",
|
|
21
|
-
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
22
|
-
"pretest": "pnpm check:modularity",
|
|
23
|
-
"test": "vitest run tests/unit tests/int --coverage",
|
|
24
|
-
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
25
|
-
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
26
|
-
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
27
|
-
"test:all": "vitest run tests --no-coverage",
|
|
28
|
-
"typecheck": "tsc --noEmit",
|
|
29
|
-
"lint": "biome check",
|
|
30
|
-
"lint:fix": "biome check --write",
|
|
31
|
-
"format": "biome format --write",
|
|
32
|
-
"brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner",
|
|
33
|
-
"prepublishOnly": "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build"
|
|
34
|
-
},
|
|
35
15
|
"dependencies": {
|
|
36
16
|
"@actions/cache": "^6.0.0",
|
|
37
17
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
@@ -55,5 +35,24 @@
|
|
|
55
35
|
"url": "git+https://github.com/aharonyaircohen/kody-engine.git"
|
|
56
36
|
},
|
|
57
37
|
"homepage": "https://github.com/aharonyaircohen/kody-engine",
|
|
58
|
-
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
59
|
-
|
|
38
|
+
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues",
|
|
39
|
+
"scripts": {
|
|
40
|
+
"kody:run": "tsx bin/kody.ts",
|
|
41
|
+
"serve": "tsx bin/kody.ts serve",
|
|
42
|
+
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
43
|
+
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
44
|
+
"build": "tsup && node scripts/copy-assets.cjs",
|
|
45
|
+
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
46
|
+
"pretest": "pnpm check:modularity",
|
|
47
|
+
"test": "vitest run tests/unit tests/int --coverage",
|
|
48
|
+
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
49
|
+
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
50
|
+
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
51
|
+
"test:all": "vitest run tests --no-coverage",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"lint": "biome check",
|
|
54
|
+
"lint:fix": "biome check --write",
|
|
55
|
+
"format": "biome format --write",
|
|
56
|
+
"brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner"
|
|
57
|
+
}
|
|
58
|
+
}
|