@kody-ade/kody-engine 0.4.285 → 0.4.286
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 +37 -10
- package/package.json +1 -1
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.286",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -7270,12 +7270,10 @@ var init_stateStore = __esm({
|
|
|
7270
7270
|
// src/goal/targetLoopResolution.ts
|
|
7271
7271
|
import * as fs26 from "fs";
|
|
7272
7272
|
import * as path24 from "path";
|
|
7273
|
-
function
|
|
7273
|
+
function resolveActiveGoalLoopTarget(config, cwd, loopGoalId, loopGoal) {
|
|
7274
7274
|
const targetId = loopGoal.loopTarget?.id.trim() ?? "";
|
|
7275
7275
|
assertSafeGoalId(targetId, "loop target");
|
|
7276
|
-
if (!hasExplicitStateRepo(config))
|
|
7277
|
-
return { targetId, templateId: targetId, reason: "literal target; state repo not configured" };
|
|
7278
|
-
}
|
|
7276
|
+
if (!hasExplicitStateRepo(config)) return null;
|
|
7279
7277
|
const activeInstance = findActiveTargetInstance(config, cwd, loopGoalId, targetId);
|
|
7280
7278
|
if (activeInstance) {
|
|
7281
7279
|
return {
|
|
@@ -7288,6 +7286,17 @@ function resolveGoalLoopTarget(config, cwd, loopGoalId, loopGoal, now) {
|
|
|
7288
7286
|
if (directTarget?.state === "active") {
|
|
7289
7287
|
return { targetId, templateId: targetId, reason: "active target goal" };
|
|
7290
7288
|
}
|
|
7289
|
+
return null;
|
|
7290
|
+
}
|
|
7291
|
+
function resolveGoalLoopTarget(config, cwd, loopGoalId, loopGoal, now) {
|
|
7292
|
+
const targetId = loopGoal.loopTarget?.id.trim() ?? "";
|
|
7293
|
+
assertSafeGoalId(targetId, "loop target");
|
|
7294
|
+
if (!hasExplicitStateRepo(config)) {
|
|
7295
|
+
return { targetId, templateId: targetId, reason: "literal target; state repo not configured" };
|
|
7296
|
+
}
|
|
7297
|
+
const activeTarget = resolveActiveGoalLoopTarget(config, cwd, loopGoalId, loopGoal);
|
|
7298
|
+
if (activeTarget) return activeTarget;
|
|
7299
|
+
const directTarget = fetchGoalState(config, targetId, cwd);
|
|
7291
7300
|
const template = loadGoalTemplate(cwd, targetId);
|
|
7292
7301
|
if (!template) {
|
|
7293
7302
|
if (directTarget) {
|
|
@@ -7961,7 +7970,9 @@ function planTargetLoopSchedule(opts) {
|
|
|
7961
7970
|
}
|
|
7962
7971
|
const preferred = opts.goal.preferredRunTime;
|
|
7963
7972
|
if (preferred) {
|
|
7964
|
-
const gate = preferredRunTimeGate(preferred, now, opts.previousScheduleState
|
|
7973
|
+
const gate = preferredRunTimeGate(preferred, now, opts.previousScheduleState, {
|
|
7974
|
+
allowRepeatAfterCompletedTarget: opts.allowRepeatAfterCompletedTarget === true
|
|
7975
|
+
});
|
|
7965
7976
|
if (!gate.ok) return targetLoopDecision("idle", gate.reason, at);
|
|
7966
7977
|
}
|
|
7967
7978
|
const dispatchTargetId = target.type === "goal" && opts.resolvedGoalTargetId?.trim() ? opts.resolvedGoalTargetId.trim() : targetId;
|
|
@@ -8123,7 +8134,7 @@ function targetLoopDecision(kind, reason, at) {
|
|
|
8123
8134
|
}
|
|
8124
8135
|
};
|
|
8125
8136
|
}
|
|
8126
|
-
function preferredRunTimeGate(preferred, now, previous) {
|
|
8137
|
+
function preferredRunTimeGate(preferred, now, previous, opts) {
|
|
8127
8138
|
const current = zonedTimeParts(now, preferred.timezone);
|
|
8128
8139
|
if (!current) return { ok: false, reason: `invalid preferred timezone: ${preferred.timezone}` };
|
|
8129
8140
|
const preferredMinute = preferredTimeToMinute(preferred.time);
|
|
@@ -8135,7 +8146,7 @@ function preferredRunTimeGate(preferred, now, previous) {
|
|
|
8135
8146
|
const lastDispatchAt = previous?.lastDecision.kind === "dispatch" ? previous.lastDecision.at : void 0;
|
|
8136
8147
|
if (lastDispatchAt) {
|
|
8137
8148
|
const last = zonedTimeParts(new Date(lastDispatchAt), preferred.timezone);
|
|
8138
|
-
if (last?.date === current.date) {
|
|
8149
|
+
if (last?.date === current.date && opts?.allowRepeatAfterCompletedTarget !== true) {
|
|
8139
8150
|
return { ok: false, reason: `already dispatched today at preferred time ${preferred.time} ${preferred.timezone}` };
|
|
8140
8151
|
}
|
|
8141
8152
|
}
|
|
@@ -8269,6 +8280,14 @@ function readSimpleGoalTaskSummary(goalId, cwd) {
|
|
|
8269
8280
|
const open = issues.filter((issue) => String(issue.state ?? "").toLowerCase() === "open").length;
|
|
8270
8281
|
return { total, open };
|
|
8271
8282
|
}
|
|
8283
|
+
function previousDispatchWasTargetInstance(managed, previousScheduleState) {
|
|
8284
|
+
const targetId = managed.loopTarget?.id.trim();
|
|
8285
|
+
const previous = previousScheduleState?.lastDecision;
|
|
8286
|
+
if (!targetId || previous?.kind !== "dispatch" || !("targetType" in previous) || previous.targetType !== "goal") {
|
|
8287
|
+
return false;
|
|
8288
|
+
}
|
|
8289
|
+
return previous.targetId === targetId || previous.targetId.startsWith(`${targetId}-`);
|
|
8290
|
+
}
|
|
8272
8291
|
function ensureIssueFactIfNeeded(goal, goalId, cwd) {
|
|
8273
8292
|
if (!routeNeedsIssueFact(goal)) return;
|
|
8274
8293
|
const existing = normalizeIssueNumber(goal.facts.issue);
|
|
@@ -8401,7 +8420,14 @@ var init_advanceManagedGoal = __esm({
|
|
|
8401
8420
|
const beforeSnapshot = goalRunLogSnapshot(goal.id, goal.state, managed);
|
|
8402
8421
|
const previousScheduleState = goal.raw.extra.scheduleState && typeof goal.raw.extra.scheduleState === "object" ? goal.raw.extra.scheduleState : void 0;
|
|
8403
8422
|
const now = goalLoopNow();
|
|
8404
|
-
|
|
8423
|
+
const activeTarget = isGoalTargetLoop(managed) ? resolveActiveGoalLoopTarget(ctx.config, ctx.cwd, goal.id, managed) : null;
|
|
8424
|
+
const allowRepeatAfterCompletedTarget = isGoalTargetLoop(managed) && !activeTarget && previousDispatchWasTargetInstance(managed, previousScheduleState);
|
|
8425
|
+
let decision2 = planTargetLoopSchedule({
|
|
8426
|
+
goal: managed,
|
|
8427
|
+
previousScheduleState,
|
|
8428
|
+
now,
|
|
8429
|
+
allowRepeatAfterCompletedTarget
|
|
8430
|
+
});
|
|
8405
8431
|
let targetResolution;
|
|
8406
8432
|
if (decision2.kind === "dispatch" && decision2.dispatch && isGoalTargetLoop(managed)) {
|
|
8407
8433
|
targetResolution = resolveGoalLoopTarget(ctx.config, ctx.cwd, goal.id, managed, now);
|
|
@@ -8409,7 +8435,8 @@ var init_advanceManagedGoal = __esm({
|
|
|
8409
8435
|
goal: managed,
|
|
8410
8436
|
previousScheduleState,
|
|
8411
8437
|
now,
|
|
8412
|
-
resolvedGoalTargetId: targetResolution.targetId
|
|
8438
|
+
resolvedGoalTargetId: targetResolution.targetId,
|
|
8439
|
+
allowRepeatAfterCompletedTarget
|
|
8413
8440
|
});
|
|
8414
8441
|
}
|
|
8415
8442
|
restoreGoalIdFact();
|
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.286",
|
|
4
4
|
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|