@agent-plan/core 0.4.1 → 0.4.2
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/api-v1.d.ts +194 -0
- package/dist/api-v1.d.ts.map +1 -0
- package/dist/api-v1.js +231 -0
- package/dist/handoff-reply.d.ts +9 -10
- package/dist/handoff-reply.d.ts.map +1 -1
- package/dist/handoff-reply.js +7 -7
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/plan-store.d.ts +20 -5
- package/dist/plan-store.d.ts.map +1 -1
- package/dist/plan-store.js +69 -16
- package/dist/recap.d.ts +2 -0
- package/dist/recap.d.ts.map +1 -1
- package/dist/recap.js +5 -3
- package/dist/schema.d.ts +54 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +4 -0
- package/dist/session-focus.d.ts +25 -0
- package/dist/session-focus.d.ts.map +1 -0
- package/dist/session-focus.js +33 -0
- package/dist/task-selection.d.ts.map +1 -1
- package/dist/task-selection.js +13 -2
- package/package.json +1 -1
- package/planner-skill.md +2 -2
package/dist/task-selection.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { deviationsForSession } from "./session-focus.js";
|
|
1
2
|
import { listOnHoldWork, startedOpenPhaseIds } from "./on-hold.js";
|
|
2
3
|
const hardUnavailable = new Set(["blocked", "deferred", "canceled", "rejected"]);
|
|
3
4
|
const terminal = new Set(["done", "canceled", "rejected"]);
|
|
@@ -177,7 +178,7 @@ export function recommendNextTask(features, phases, deviations = [], currentPhas
|
|
|
177
178
|
// explicit instead of two bare string literals that look like an
|
|
178
179
|
// accidental inclusion of a "closed" state in an "open" list.
|
|
179
180
|
const returnRequiredStates = new Set(["resume-required", "resolved"]);
|
|
180
|
-
const liveDeviations = deviations
|
|
181
|
+
const liveDeviations = deviationsForSession(deviations, sessionId)
|
|
181
182
|
.filter((deviation) => deviation.state === "approved"
|
|
182
183
|
|| deviation.state === "active"
|
|
183
184
|
|| returnRequiredStates.has(deviation.state))
|
|
@@ -198,10 +199,18 @@ export function recommendNextTask(features, phases, deviations = [], currentPhas
|
|
|
198
199
|
return { kind: "resume", candidate: temporary, deviation: top, reason: "Continue the temporary task of the most recent approved deviation." };
|
|
199
200
|
}
|
|
200
201
|
}
|
|
202
|
+
// Tasks another session set aside on purpose (its live side task still points back at
|
|
203
|
+
// them). They are that session's to return to: never offer them to this one.
|
|
204
|
+
const heldByOtherSessions = new Set(sessionId
|
|
205
|
+
? deviations
|
|
206
|
+
.filter((deviation) => deviation.ownerSession !== "" && deviation.ownerSession !== sessionId
|
|
207
|
+
&& (deviation.state === "approved" || deviation.state === "active" || returnRequiredStates.has(deviation.state)))
|
|
208
|
+
.map((deviation) => deviation.resumeTaskId)
|
|
209
|
+
: []);
|
|
201
210
|
// A saved checkpoint without a surviving deviation must never disappear
|
|
202
211
|
// behind new priority work. Select the most recent checkpoint (LIFO).
|
|
203
212
|
const checkpointed = candidates
|
|
204
|
-
.filter(({ task }) => task.status === "planned" && task.pauseSnapshot)
|
|
213
|
+
.filter(({ task }) => task.status === "planned" && task.pauseSnapshot && !heldByOtherSessions.has(task.id))
|
|
205
214
|
.sort((left, right) => right.task.pauseSnapshot.pausedAt.localeCompare(left.task.pauseSnapshot.pausedAt));
|
|
206
215
|
if (checkpointed[0]) {
|
|
207
216
|
return {
|
|
@@ -213,6 +222,8 @@ export function recommendNextTask(features, phases, deviations = [], currentPhas
|
|
|
213
222
|
const ready = candidates.filter(({ feature, phase, task }) => {
|
|
214
223
|
if (task.status !== "planned")
|
|
215
224
|
return false;
|
|
225
|
+
if (heldByOtherSessions.has(task.id))
|
|
226
|
+
return false;
|
|
216
227
|
if (hardUnavailable.has(phase.status) || (feature && hardUnavailable.has(feature.status)))
|
|
217
228
|
return false;
|
|
218
229
|
return task.dependsOn.every((id) => byTaskId.get(id)?.task.status === "done");
|
package/package.json
CHANGED
package/planner-skill.md
CHANGED
|
@@ -121,9 +121,9 @@ Then call `handoff_write` / `planner-handoff-write` once with the preparation to
|
|
|
121
121
|
|
|
122
122
|
If a write fails for any reason, the planner retains the exact capsule you submitted against that phase and preparation token. **Do not redraft or resend `content`/`markdown_content` on the retry** — fix only what the error named (a missing field, a stale token needs a fresh `handoff_prepare`, a corrected supporting-document manifest, etc.) and call `handoff_write` again with the same `expectedHandoffUpdatedAt`, omitting `content`; the retained capsule is reused automatically. Only pass `content` again if you are deliberately changing the body — the new one replaces the retained one. Omitting it when nothing was ever retained for that exact phase + token (a first attempt, an aged-out draft, or a phase that has since gone terminal) is itself a typed failure (`HANDOFF_RETAINED_CONTENT_NOT_FOUND`) naming the fix. A stale token is still refused even when a capsule is retained for it — retention makes the retry cheap, it never lets outdated content overwrite newer state.
|
|
123
123
|
|
|
124
|
-
A successful write persists only a **handoff candidate** and returns `resumeReady: false`. Immediately call `handoff_show` / `planner-handoff-show` with the exact phase reference and read the persisted capsule. If the capsule omits resume-critical context, rewrite it; otherwise call `handoff_verify` / `planner-handoff-verify` with the content hash. Source reviews and omission lists are optional legacy evidence; the planner derives them when omitted. Only a successful verification result with `resumeReady: true` authorizes telling the user that the handoff is resume-ready.
|
|
124
|
+
A successful write persists only a **handoff candidate** and returns `resumeReady: false`. Immediately call `handoff_show` / `planner-handoff-show` with the exact phase reference and read the persisted capsule from the tool result text first, then from structured `content` when the host exposes it. Some hosts show only minimal structured keys while still exposing the full text body; do not mistake `structuredContent` with only identifiers for a missing handoff body. If neither text nor structured content includes the capsule body, retry the planner tool and report the tool or transport issue. Reading raw `.planner/*.json` or `.planner/EXPORT.md` is only a diagnostic/recovery fallback when the tool is unavailable or demonstrably failed; label it as a fallback and do not treat it as a successful `handoff_show` read-back. If the capsule omits resume-critical context, rewrite it; otherwise call `handoff_verify` / `planner-handoff-verify` with the content hash. Source reviews and omission lists are optional legacy evidence; the planner derives them when omitted. Only a successful verification result with `resumeReady: true` authorizes telling the user that the handoff is resume-ready.
|
|
125
125
|
|
|
126
|
-
`handoff_list` is a compact paginated index of active handoffs and exposes whether each is resume-ready. Use `handoff_show` for one bounded active body and its metadata; after phase completion/rejection/cancellation, the same exact phase-scoped show call returns the latest terminal archive so its closeout and `.planner/docs/` references remain discoverable. Clear/archive only after explicit intent or when phase completion makes the handoff non-operational.
|
|
126
|
+
`handoff_list` is a compact paginated index of active handoffs and exposes whether each is resume-ready. Use `handoff_show` for one bounded active body and its metadata; after phase completion/rejection/cancellation, the same exact phase-scoped show call returns the latest terminal archive so its closeout and `.planner/docs/` references remain discoverable. If `handoff_show` text is visible, use that body even when structured metadata is minimal. If the body is genuinely absent, diagnose the tool/client path before falling back to storage files, and never run export merely to refresh a handoff read unless the user explicitly asked for an export. Clear/archive only after explicit intent or when phase completion makes the handoff non-operational.
|
|
127
127
|
|
|
128
128
|
## Hierarchical description freshness
|
|
129
129
|
|