@agent-plan/pi-adapter 0.2.27 → 0.2.29
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
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;AA0/BtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,
|
|
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;AA0/BtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAquK9D"}
|
package/dist/index.js
CHANGED
|
@@ -3839,8 +3839,8 @@ export default function planPiExtension(pi) {
|
|
|
3839
3839
|
&& phase.handoffAudit.contentLength === phase.handoff.length);
|
|
3840
3840
|
const resumeReady = persistenceVerified && Boolean(phase.handoffAudit?.resumeReadyAt);
|
|
3841
3841
|
const status = resumeReady
|
|
3842
|
-
? "Resume-ready: persisted read-back
|
|
3843
|
-
: "NOT resume-ready: after reading this
|
|
3842
|
+
? "Resume-ready: persisted compact capsule read-back completed."
|
|
3843
|
+
: "NOT resume-ready: after reading this persisted capsule, call handoff_verify with its contentHash. The planner derives legacy evidence from persisted state; rewrite only if the capsule itself omits resume-critical context.";
|
|
3844
3844
|
return {
|
|
3845
3845
|
content: [{ type: "text", text: `Handoff for ${r.compositeRef}\n${status}\nContent hash: ${contentHash}\n\n${phaseWorkMap.content}\n\nBefore proposing new work, reread the canonical phase and relevant sibling task full view; do not duplicate an already-owned capability.\n\n${bounded.content}` }],
|
|
3846
3846
|
details: { phaseRef: r.compositeRef, phaseId: r.phase.id, phaseWorkMap, ...bounded, contentHash, persistenceVerified, resumeReady, verificationRequired: !resumeReady, handoffAudit: phase.handoffAudit },
|
|
@@ -3850,15 +3850,15 @@ export default function planPiExtension(pi) {
|
|
|
3850
3850
|
pi.registerTool({
|
|
3851
3851
|
name: "handoff_verify",
|
|
3852
3852
|
label: "Handoff Verify",
|
|
3853
|
-
description: "Finalize one persisted handoff as resume-ready
|
|
3853
|
+
description: "Finalize one persisted handoff as resume-ready after handoff_show confirms the persisted compact resume capsule. Legacy sourceReviews and omissionsFound evidence remains accepted but is optional; the planner derives omitted evidence from persisted state.",
|
|
3854
3854
|
parameters: Type.Object({
|
|
3855
3855
|
phaseRef: Type.String(),
|
|
3856
3856
|
expectedContentHash: Type.String({ pattern: "^[a-f0-9]{64}$" }),
|
|
3857
|
-
sourceReviews: Type.Array(Type.Object({
|
|
3857
|
+
sourceReviews: Type.Optional(Type.Array(Type.Object({
|
|
3858
3858
|
source: Type.Union([Type.Literal("conversation"), Type.Literal("planner-entities"), Type.Literal("working-tree"), Type.Literal("verification-runtime"), Type.Literal("peer-agent-output")]),
|
|
3859
3859
|
detail: Type.String({ minLength: 12 }),
|
|
3860
|
-
})),
|
|
3861
|
-
omissionsFound: Type.Array(Type.String({ minLength: 1 })),
|
|
3860
|
+
}))),
|
|
3861
|
+
omissionsFound: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),
|
|
3862
3862
|
}),
|
|
3863
3863
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
3864
3864
|
const st = await requirePlan(ctx);
|
|
@@ -3870,8 +3870,8 @@ export default function planPiExtension(pi) {
|
|
|
3870
3870
|
try {
|
|
3871
3871
|
const result = await st.verifyPhaseHandoffReadBack(r.phase.id, {
|
|
3872
3872
|
expectedContentHash: params.expectedContentHash,
|
|
3873
|
-
sourceReviews: params.sourceReviews,
|
|
3874
|
-
omissionsFound: params.omissionsFound,
|
|
3873
|
+
...(params.sourceReviews ? { sourceReviews: params.sourceReviews } : {}),
|
|
3874
|
+
...(params.omissionsFound ? { omissionsFound: params.omissionsFound } : {}),
|
|
3875
3875
|
});
|
|
3876
3876
|
await st.writeGenerated();
|
|
3877
3877
|
return {
|
|
@@ -3890,7 +3890,7 @@ export default function planPiExtension(pi) {
|
|
|
3890
3890
|
pi.registerTool({
|
|
3891
3891
|
name: "handoff_prepare",
|
|
3892
3892
|
label: "Handoff Prepare",
|
|
3893
|
-
description: "
|
|
3893
|
+
description: "Prepare one exact phase before writing a handoff. Returns a compact resume capsule scaffold, bounded phase work map, current token, missing task evidence, and inline budget. Reread the canonical phase and relevant sibling tasks before proposing work; do not duplicate planner evidence in Markdown.",
|
|
3894
3894
|
parameters: Type.Object({ phaseRef: Type.String({ description: "Exact confirmed phase ref: P00x | P00x(F00x) | UUID | title." }) }),
|
|
3895
3895
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
3896
3896
|
const st = await requirePlan(ctx);
|
|
@@ -3901,7 +3901,7 @@ export default function planPiExtension(pi) {
|
|
|
3901
3901
|
return { content: [{ type: "text", text: `❌ ${r.error}` }], details: { error: r.error } };
|
|
3902
3902
|
try {
|
|
3903
3903
|
const audit = await st.preparePhaseHandoff(r.phase.id);
|
|
3904
|
-
const { handoff, ...auditDetails } = audit;
|
|
3904
|
+
const { handoff, completenessCategories: _completenessCategories, coldStartSourceReviews: _coldStartSourceReviews, coldStartInventoryCategories: _coldStartInventoryCategories, ...auditDetails } = audit;
|
|
3905
3905
|
const boundedExisting = boundedHandoffForTransport(handoff);
|
|
3906
3906
|
const missing = audit.missingCompletionTasks.map((task) => `- T${String(task.number).padStart(3, "0")} — ${task.title}`).join("\n") || "- None";
|
|
3907
3907
|
const existing = boundedExisting.content.trim() || "(none)";
|
|
@@ -3918,19 +3918,21 @@ export default function planPiExtension(pi) {
|
|
|
3918
3918
|
"Done tasks missing durable completion/verification evidence:",
|
|
3919
3919
|
missing,
|
|
3920
3920
|
"",
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
"",
|
|
3924
|
-
`
|
|
3925
|
-
...audit.coldStartSourceReviews.map((entry) => `- ${entry.id} — ${entry.label}`),
|
|
3926
|
-
"Required cold-start inventory — every category needs a concrete item (use an explicit verified-negative statement when nothing exists), and every item must appear verbatim in the handoff or a validated supporting document:",
|
|
3927
|
-
...audit.coldStartInventoryCategories.map((entry) => `- ${entry.id} — ${entry.label}`),
|
|
3928
|
-
`Maximum canonical inline content: ${audit.maxContentChars} characters. Link extended material from .planner/docs/.`,
|
|
3921
|
+
"Compact handoff contract: include only the exact focus/resume point, current or partial state, preservation constraints, blockers, decisions, verification, and ordered next actions needed by the next agent.",
|
|
3922
|
+
"No Markdown heading is mandatory: concise free-form resume prose is accepted. Use headings only when they make the capsule clearer.",
|
|
3923
|
+
"Completeness audit and cold-start evidence are planner-owned metadata. Do not copy their categories or source reviews into Markdown; provide legacy evidence only when it already exists.",
|
|
3924
|
+
`Inline target: ${audit.targetContentChars} characters; absolute compatibility ceiling: ${audit.maxContentChars}. Extended detail is externalized automatically when needed.`,
|
|
3929
3925
|
"",
|
|
3930
3926
|
"Existing active handoff (reconcile all still-relevant content):",
|
|
3931
3927
|
existing,
|
|
3932
3928
|
].join("\n") }],
|
|
3933
|
-
details: {
|
|
3929
|
+
details: {
|
|
3930
|
+
phaseRef: r.compositeRef,
|
|
3931
|
+
...auditDetails,
|
|
3932
|
+
evidenceContract: "Planner-owned completeness and cold-start evidence is derived from persisted state; no category inventory is required from the agent.",
|
|
3933
|
+
existingHandoffLength: boundedExisting.fullLength,
|
|
3934
|
+
existingHandoffTruncated: boundedExisting.truncated,
|
|
3935
|
+
},
|
|
3934
3936
|
};
|
|
3935
3937
|
}
|
|
3936
3938
|
catch (error) {
|
|
@@ -3942,7 +3944,7 @@ export default function planPiExtension(pi) {
|
|
|
3942
3944
|
pi.registerTool({
|
|
3943
3945
|
name: "handoff_write",
|
|
3944
3946
|
label: "Handoff Write",
|
|
3945
|
-
description: "Persist a reconciled handoff candidate with durable context synchronization
|
|
3947
|
+
description: "Persist a compact reconciled handoff candidate with durable context synchronization. The result always has resumeReady=false until a separate handoff_show read-back and handoff_verify succeeds. Run handoff_prepare first; extended detail belongs in linked .planner/docs/ Markdown.",
|
|
3946
3948
|
parameters: Type.Object({
|
|
3947
3949
|
phaseRef: Type.String({ description: "Exact confirmed phase ref: P00x | P00x(F00x) | UUID | title." }),
|
|
3948
3950
|
title: Type.Optional(Type.String({ description: "Meaningful handoff title summarizing the work (becomes the H1 / first line in lists)." })),
|
|
@@ -3957,7 +3959,7 @@ export default function planPiExtension(pi) {
|
|
|
3957
3959
|
entries: Type.Array(Type.Object({
|
|
3958
3960
|
category: Type.String({ description: `One required category id from handoff_prepare: ${HANDOFF_COMPLETENESS_CATEGORIES.map((entry) => entry.id).join(", ")}` }),
|
|
3959
3961
|
status: Type.Union([Type.Literal("captured"), Type.Literal("not-applicable")]),
|
|
3960
|
-
detail: Type.String({ description: "
|
|
3962
|
+
detail: Type.String({ description: "Legacy evidence detail; omit the entire audit for compact handoffs." }),
|
|
3961
3963
|
})),
|
|
3962
3964
|
})),
|
|
3963
3965
|
coldStartInventory: Type.Optional(Type.Object({
|
|
@@ -3968,8 +3970,8 @@ export default function planPiExtension(pi) {
|
|
|
3968
3970
|
})),
|
|
3969
3971
|
entries: Type.Array(Type.Object({
|
|
3970
3972
|
category: Type.String({ description: `One required cold-start category id from handoff_prepare: ${HANDOFF_COLD_START_INVENTORY_CATEGORIES.map((entry) => entry.id).join(", ")}` }),
|
|
3971
|
-
items: Type.Array(Type.String({ description: "
|
|
3972
|
-
notApplicableReason: Type.Optional(Type.String({ description: "
|
|
3973
|
+
items: Type.Array(Type.String({ description: "Legacy resume evidence item; omit the entire inventory for compact handoffs." })),
|
|
3974
|
+
notApplicableReason: Type.Optional(Type.String({ description: "Legacy evidence explanation." })),
|
|
3973
3975
|
})),
|
|
3974
3976
|
})),
|
|
3975
3977
|
supportingDocuments: Type.Optional(Type.Array(Type.Object({
|
|
@@ -4064,7 +4066,7 @@ export default function planPiExtension(pi) {
|
|
|
4064
4066
|
});
|
|
4065
4067
|
await st.writeGenerated();
|
|
4066
4068
|
return {
|
|
4067
|
-
content: [{ type: "text", text: `⚠️ Handoff candidate persisted on ${r.compositeRef}, but it is NOT resume-ready yet. Required next action: call handoff_show ${r.compositeRef}, read the
|
|
4069
|
+
content: [{ type: "text", text: `⚠️ Handoff candidate persisted on ${r.compositeRef}, but it is NOT resume-ready yet. Required next action: call handoff_show ${r.compositeRef}, read the persisted compact capsule, then call handoff_verify with the returned contentHash. Rewrite only if resume-critical context is missing.` }],
|
|
4068
4070
|
details: {
|
|
4069
4071
|
phaseRef: r.compositeRef,
|
|
4070
4072
|
phaseId: r.phase.id,
|
|
@@ -4075,9 +4077,8 @@ export default function planPiExtension(pi) {
|
|
|
4075
4077
|
resumeReady: false,
|
|
4076
4078
|
verificationRequired: true,
|
|
4077
4079
|
nextActions: [
|
|
4078
|
-
`Call handoff_show ${r.compositeRef} and read the
|
|
4079
|
-
"
|
|
4080
|
-
"If any omission exists, run handoff_prepare and handoff_write again; otherwise call handoff_verify with the shown contentHash.",
|
|
4080
|
+
`Call handoff_show ${r.compositeRef} and read the persisted compact capsule.`,
|
|
4081
|
+
"Call handoff_verify with the shown contentHash; legacy sourceReviews and omissionsFound are optional because the planner derives omitted evidence from persisted state.",
|
|
4081
4082
|
],
|
|
4082
4083
|
},
|
|
4083
4084
|
};
|
|
@@ -4846,10 +4847,7 @@ export default function planPiExtension(pi) {
|
|
|
4846
4847
|
const staleParentRefs = descriptionFreshness?.diagnostics
|
|
4847
4848
|
.filter((entry) => entry.state === "stale" && entry.ownerId === phase.featureId)
|
|
4848
4849
|
.map((entry) => entry.ownerRef) ?? [];
|
|
4849
|
-
|
|
4850
|
-
? `\n⚠️ Parent description review required: ${staleParentRefs.join(", ")}. Run description_freshness for the non-mutating reconciliation preview.`
|
|
4851
|
-
: "";
|
|
4852
|
-
return { content: [{ type: "text", text: `✅ Phase updated: ${formatPhaseRef(phase.number, featureNumberOfPhase(phase, phaseUpdateFeatures))} — ${phase.title}${phase.shortId ? ` · ${phase.shortId}` : ""}. Fields saved: ${receivedFields.join(", ")}.${freshnessNotice}` }], details: { ...phase, updated: true, updatedFields: receivedFields, ...(descriptionFreshness ? { descriptionFreshness, staleParentRefs } : {}) } };
|
|
4850
|
+
return { content: [{ type: "text", text: `✅ Phase updated: ${formatPhaseRef(phase.number, featureNumberOfPhase(phase, phaseUpdateFeatures))} — ${phase.title}${phase.shortId ? ` · ${phase.shortId}` : ""}. Fields saved: ${receivedFields.join(", ")}.` }], details: { ...phase, updated: true, updatedFields: receivedFields, ...(descriptionFreshness ? { descriptionFreshness, staleParentRefs } : {}) } };
|
|
4853
4851
|
},
|
|
4854
4852
|
});
|
|
4855
4853
|
pi.registerTool({
|
|
@@ -5420,10 +5418,7 @@ export default function planPiExtension(pi) {
|
|
|
5420
5418
|
});
|
|
5421
5419
|
}
|
|
5422
5420
|
try {
|
|
5423
|
-
const updatedPhase = await st.
|
|
5424
|
-
const task = phase.tasks.find((t) => t.id === found.task.id);
|
|
5425
|
-
if (!task)
|
|
5426
|
-
return phase;
|
|
5421
|
+
const updatedPhase = await st.updateTask(hostPhase.id, found.task.id, (task) => {
|
|
5427
5422
|
if (params.title !== undefined)
|
|
5428
5423
|
task.title = params.title;
|
|
5429
5424
|
if (params.priority !== undefined)
|
|
@@ -5466,17 +5461,21 @@ export default function planPiExtension(pi) {
|
|
|
5466
5461
|
applyTaskLifecycleDates(task, params.status, now);
|
|
5467
5462
|
}
|
|
5468
5463
|
task.updatedAt = now;
|
|
5469
|
-
phase.updatedAt = now;
|
|
5470
5464
|
updatedTask = task;
|
|
5471
|
-
return
|
|
5465
|
+
return task;
|
|
5472
5466
|
});
|
|
5473
5467
|
void updatedPhase;
|
|
5474
5468
|
}
|
|
5475
5469
|
catch (e) {
|
|
5476
|
-
|
|
5470
|
+
const errorCode = e instanceof PlanStoreError ? e.details?.errorCode : undefined;
|
|
5471
|
+
return {
|
|
5472
|
+
content: [{ type: "text", text: `Update failed: ${e instanceof Error ? e.message : String(e)}` }],
|
|
5473
|
+
details: { updated: false, errorCode: errorCode ?? "TASK_UPDATE_FAILED" },
|
|
5474
|
+
isError: true,
|
|
5475
|
+
};
|
|
5477
5476
|
}
|
|
5478
5477
|
if (!updatedTask)
|
|
5479
|
-
return { content: [{ type: "text", text: `Task not found: ${params.taskId}` }], details: {} };
|
|
5478
|
+
return { content: [{ type: "text", text: `Task not found: ${params.taskId}` }], details: { updated: false, errorCode: "TASK_NOT_FOUND" }, isError: true };
|
|
5480
5479
|
await st.syncTaskStatusRollup(found.phase.id);
|
|
5481
5480
|
await st.writeGenerated();
|
|
5482
5481
|
const descriptionFreshness = receivedFields.some((field) => field === "description" || field === "descriptionRef")
|
|
@@ -5486,10 +5485,7 @@ export default function planPiExtension(pi) {
|
|
|
5486
5485
|
const staleParentRefs = descriptionFreshness?.diagnostics
|
|
5487
5486
|
.filter((entry) => entry.state === "stale" && ownerIds.has(entry.ownerId))
|
|
5488
5487
|
.map((entry) => entry.ownerRef) ?? [];
|
|
5489
|
-
|
|
5490
|
-
? `\n⚠️ Parent description review required: ${staleParentRefs.join(", ")}. Run description_freshness for the non-mutating reconciliation preview.`
|
|
5491
|
-
: "";
|
|
5492
|
-
return { content: [{ type: "text", text: `Task updated: ${updatedTask.id} (${updatedTask.status}). Fields saved: ${receivedFields.join(", ")}.${freshnessNotice}` }], details: { ...updatedTask, updated: true, updatedFields: receivedFields, ...(descriptionFreshness ? { descriptionFreshness, staleParentRefs } : {}) } };
|
|
5488
|
+
return { content: [{ type: "text", text: `Task updated: ${updatedTask.id} (${updatedTask.status}). Fields saved: ${receivedFields.join(", ")}.` }], details: { ...updatedTask, updated: true, updatedFields: receivedFields, ...(descriptionFreshness ? { descriptionFreshness, staleParentRefs } : {}) } };
|
|
5493
5489
|
},
|
|
5494
5490
|
});
|
|
5495
5491
|
pi.registerTool({
|
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.29",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Pi agent extension for Agent Plan — structured project planning in .planner/",
|
|
6
6
|
"keywords": [
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"typebox": "^1.1.24",
|
|
30
30
|
"zod": "^3.24.0",
|
|
31
|
-
"@agent-plan/core": "0.2.
|
|
32
|
-
"@agent-plan/server": "0.2.
|
|
31
|
+
"@agent-plan/core": "0.2.29",
|
|
32
|
+
"@agent-plan/server": "0.2.29"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@earendil-works/pi-coding-agent": "^0.74.0",
|