@agent-plan/pi-adapter 0.2.5 → 0.2.6
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/index.d.ts.map +1 -1
- package/dist/index.js +42 -3
- package/package.json +7 -7
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAszBtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAqxF9D"}
|
package/dist/index.js
CHANGED
|
@@ -429,6 +429,24 @@ async function buildHandoffMarkdown(st, reason, overrides) {
|
|
|
429
429
|
: inferredRecentChanges.length > 0
|
|
430
430
|
? inferredRecentChanges.map((entry) => `- ${entry}`)
|
|
431
431
|
: ["- No recent activity recorded"];
|
|
432
|
+
// Auto-derived: all task statuses for the current phase, so a resuming agent
|
|
433
|
+
// sees the full picture (not just the single in-progress task).
|
|
434
|
+
const currentPhaseTaskLines = currentPhase && currentPhase.tasks.length > 0
|
|
435
|
+
? [...currentPhase.tasks]
|
|
436
|
+
.sort((a, b) => a.number - b.number || a.createdAt.localeCompare(b.createdAt))
|
|
437
|
+
.map((task) => `- ${statusIcon(task.status)} \`${task.id}\` — ${task.title} (${task.status})`)
|
|
438
|
+
: [];
|
|
439
|
+
// Caller-supplied rich context sections (locked design decisions,
|
|
440
|
+
// architecture, mode/state flows, plugin/API contracts, data mappings,
|
|
441
|
+
// known gaps, ...) injected between "What was being done" and "How to resume".
|
|
442
|
+
const extraSectionLines = (overrides?.extraSections ?? []).flatMap((section) => [
|
|
443
|
+
"",
|
|
444
|
+
`## ${section.heading}`,
|
|
445
|
+
section.body,
|
|
446
|
+
]);
|
|
447
|
+
const autoCurrentTaskSection = currentPhaseTaskLines.length > 0
|
|
448
|
+
? ["", `## Current Task Statuses (phase ${currentPhase.id})`, ...currentPhaseTaskLines]
|
|
449
|
+
: [];
|
|
432
450
|
return [
|
|
433
451
|
"# Handoff",
|
|
434
452
|
"",
|
|
@@ -448,6 +466,8 @@ async function buildHandoffMarkdown(st, reason, overrides) {
|
|
|
448
466
|
"",
|
|
449
467
|
"## What was being done",
|
|
450
468
|
whatWasBeingDone || "No additional execution notes were captured.",
|
|
469
|
+
...extraSectionLines,
|
|
470
|
+
...autoCurrentTaskSection,
|
|
451
471
|
"",
|
|
452
472
|
"## How to resume",
|
|
453
473
|
howToResume,
|
|
@@ -865,7 +885,9 @@ export default function planPiExtension(pi) {
|
|
|
865
885
|
await st.ensureStructureOrdering().catch(() => { });
|
|
866
886
|
// Reconcile derived statuses once on startup: backfills any drift from
|
|
867
887
|
// manual edits, pre-fix data, or tools that bypassed the rollup.
|
|
868
|
-
|
|
888
|
+
// Uses maybeHealStatuses (idempotent via healedStatusRoots guard) so the
|
|
889
|
+
// later call below and before_agent_start don't re-run it (startup dedup).
|
|
890
|
+
await maybeHealStatuses(st).catch(() => { });
|
|
869
891
|
// Decide whether to start the web UI based on persisted prefs or prompt.
|
|
870
892
|
let startWeb = false;
|
|
871
893
|
if (project?.plannerAutoStartWeb) {
|
|
@@ -917,13 +939,19 @@ export default function planPiExtension(pi) {
|
|
|
917
939
|
const url = server?.url ?? "Starting server...";
|
|
918
940
|
ctx.ui.notify(`Planner enabled. Dashboard: ${url}\nAnalyzing project state and preparing resume summary...`, "info");
|
|
919
941
|
await ensureProjectLanguagePreferences(st).catch(() => null);
|
|
920
|
-
|
|
942
|
+
// (maybeHealStatuses already ran above — skipped here thanks to the guard.)
|
|
921
943
|
// Background cleanup of orphan .bak/.tmp.* files (non-blocking)
|
|
922
944
|
st.cleanupOrphanBackups().catch(() => { });
|
|
923
945
|
const handoff = await st.loadHandoff().catch(() => null);
|
|
924
946
|
if (handoff?.content) {
|
|
925
947
|
ctx.ui.notify(`Handoff detected at .planner/HANDOFF.md (updated ${handoff.updatedAt}). It will be loaded automatically when the agent starts.`, "info");
|
|
926
948
|
}
|
|
949
|
+
// Mark heavy init done so before_agent_start doesn't re-run migration,
|
|
950
|
+
// status healing, and language prefs on the first turn (startup dedup:
|
|
951
|
+
// all of these already ran in this session_start block). refreshResume is
|
|
952
|
+
// safe to skip here because the per-turn context builder falls back to
|
|
953
|
+
// loadResume() ?? refreshResume() when building the system prompt.
|
|
954
|
+
plannerHeavyInitDone = true;
|
|
927
955
|
pi.sendMessage({
|
|
928
956
|
customType: "planner-resume-trigger",
|
|
929
957
|
content: "Emit the mandatory planner startup resume summary now.",
|
|
@@ -2748,11 +2776,15 @@ export default function planPiExtension(pi) {
|
|
|
2748
2776
|
pi.registerTool({
|
|
2749
2777
|
name: "plan_write_handoff",
|
|
2750
2778
|
label: "Plan Write Handoff",
|
|
2751
|
-
description: "Write or refresh the canonical .planner/HANDOFF.md document.",
|
|
2779
|
+
description: "Write or refresh the canonical .planner/HANDOFF.md document. Capture full design context, not just operational resume steps: pass extraSections with locked decisions, architecture (with file:line refs), mode/state flows, plugin/API contracts, data mappings, files touched, and known gaps so a resuming agent doesn't re-discover decisions already made.",
|
|
2752
2780
|
parameters: Type.Object({
|
|
2753
2781
|
reason: Type.Optional(Type.String({ description: "Why the handoff is being written" })),
|
|
2754
2782
|
whatWasBeingDone: Type.Optional(Type.String({ description: "Optional override for the current work summary" })),
|
|
2755
2783
|
howToResume: Type.Optional(Type.String({ description: "Optional override for resume instructions" })),
|
|
2784
|
+
extraSections: Type.Optional(Type.Array(Type.Object({
|
|
2785
|
+
heading: Type.String({ description: "Section heading (without the leading ## markers)" }),
|
|
2786
|
+
body: Type.String({ description: "Markdown body of the section. Use file:line refs, IDs, and concrete mappings." }),
|
|
2787
|
+
}), { description: "Rich context sections injected between 'What was being done' and 'How to resume'. Use for: Locked Design Decisions ({id,title,decision,rationale}), Architecture (new modules with file:line), Mode/State Flow (textual diagrams), Plugin/API Contracts, Data Mappings, Files Touched (new/modified/planner), Known Gaps. Maximize the design context a resuming agent needs." })),
|
|
2756
2788
|
}),
|
|
2757
2789
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
2758
2790
|
const st = await requirePlan(ctx);
|
|
@@ -2761,6 +2793,13 @@ export default function planPiExtension(pi) {
|
|
|
2761
2793
|
await writeProjectHandoff(st, params.reason?.trim() || "manual tool handoff", {
|
|
2762
2794
|
...(params.whatWasBeingDone?.trim() ? { whatWasBeingDone: params.whatWasBeingDone.trim() } : {}),
|
|
2763
2795
|
...(params.howToResume?.trim() ? { howToResume: params.howToResume.trim() } : {}),
|
|
2796
|
+
...(params.extraSections && params.extraSections.length > 0
|
|
2797
|
+
? {
|
|
2798
|
+
extraSections: params.extraSections
|
|
2799
|
+
.map((section) => ({ heading: section.heading?.trim() ?? "", body: section.body ?? "" }))
|
|
2800
|
+
.filter((section) => section.heading),
|
|
2801
|
+
}
|
|
2802
|
+
: {}),
|
|
2764
2803
|
});
|
|
2765
2804
|
const handoff = await st.loadHandoff();
|
|
2766
2805
|
return { content: [{ type: "text", text: "Wrote .planner/HANDOFF.md" }], details: handoff ?? {} };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-plan/pi-adapter",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Pi agent extension for Agent Plan — structured project planning in .planner/",
|
|
6
6
|
"keywords": [
|
|
@@ -25,11 +25,6 @@
|
|
|
25
25
|
"."
|
|
26
26
|
]
|
|
27
27
|
},
|
|
28
|
-
"scripts": {
|
|
29
|
-
"build": "tsc -p tsconfig.json && rm -f dist/.tsbuildinfo",
|
|
30
|
-
"build:full": "pnpm build && ../../scripts/copy-web-ui.sh",
|
|
31
|
-
"check": "tsc -p tsconfig.json --noEmit"
|
|
32
|
-
},
|
|
33
28
|
"dependencies": {
|
|
34
29
|
"@agent-plan/core": "^0.2.0",
|
|
35
30
|
"@agent-plan/server": "^0.2.0",
|
|
@@ -39,5 +34,10 @@
|
|
|
39
34
|
"devDependencies": {
|
|
40
35
|
"@earendil-works/pi-coding-agent": "^0.74.0",
|
|
41
36
|
"@earendil-works/pi-ai": "^0.74.0"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc -p tsconfig.json && rm -f dist/.tsbuildinfo",
|
|
40
|
+
"build:full": "pnpm build && ../../scripts/copy-web-ui.sh",
|
|
41
|
+
"check": "tsc -p tsconfig.json --noEmit"
|
|
42
42
|
}
|
|
43
|
-
}
|
|
43
|
+
}
|