@agent-plan/pi-adapter 0.2.19-next.1 → 0.2.19-next.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.
@@ -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;AA0tBtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA+6F9D"}
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;AA6uBtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAg7F9D"}
package/dist/index.js CHANGED
@@ -68,6 +68,29 @@ setWriteNotifyHook(() => {
68
68
  let previousContextPercent = 0;
69
69
  let autoHandoffTriggered = false;
70
70
  let plannerSessionEnabled = false;
71
+ // In-process guard bypass (per session, NOT persisted/shared). The edit/write
72
+ // guard is advisory in Pi (warns "NO ACTIVE TASK" but does not block). When a
73
+ // bypass is active the warning is silenced for the window. Lives in memory only:
74
+ // not on disk, not in git, not shared across agents/sessions on the same folder.
75
+ let guardBypassUntil = "";
76
+ function authorizeGuardBypass(durationMinutes = 15) {
77
+ const until = new Date(Date.now() + durationMinutes * 60_000).toISOString();
78
+ guardBypassUntil = until;
79
+ return until;
80
+ }
81
+ function clearGuardBypass() { guardBypassUntil = ""; }
82
+ function isGuardBypassed() {
83
+ if (!guardBypassUntil)
84
+ return false;
85
+ const until = Date.parse(guardBypassUntil);
86
+ if (!Number.isFinite(until))
87
+ return false;
88
+ if (until <= Date.now()) {
89
+ guardBypassUntil = "";
90
+ return false;
91
+ }
92
+ return true;
93
+ }
71
94
  let startupResumePromptPending = false;
72
95
  let startupResumeSummaryPending = false;
73
96
  let plannerHeavyInitDone = false; // runs migrate/heal/refreshResume once per session, not every turn
@@ -862,6 +885,8 @@ export default function planPiExtension(pi) {
862
885
  return; // nothing to enforce yet
863
886
  if (guard.inProgressTaskIds.length > 0)
864
887
  return; // a task is open → we're good
888
+ if (isGuardBypassed())
889
+ return; // user authorized proceeding without a task
865
890
  const focusHint = guard.focusTaskId
866
891
  ? `Il task più probabile è ${guard.focusTaskId} — ${guard.focusTaskTitle}. Avvialo con: \`/planner task start ${guard.focusTaskId}\``
867
892
  : `Scegli un task dal piano e avvialo con \`/planner task start <taskId>\`.`;
@@ -2221,12 +2246,12 @@ export default function planPiExtension(pi) {
2221
2246
  try {
2222
2247
  if (a === "bypass") {
2223
2248
  const mins = parseInt(subArgs.trim(), 10);
2224
- const until = await st.authorizeGuardBypass(Number.isFinite(mins) && mins > 0 ? mins : 15);
2225
- ctx.ui.notify(`Guard bypass authorized until ${until}. edit/write will work without a task in-progress for that window.`, "info");
2249
+ const until = authorizeGuardBypass(Number.isFinite(mins) && mins > 0 ? mins : 15);
2250
+ ctx.ui.notify(`Guard bypass authorized until ${until}. edit/write advisory warnings silenced for that window (per-session, not shared).`, "info");
2226
2251
  }
2227
2252
  else {
2228
- await st.clearGuardBypass();
2229
- ctx.ui.notify("Guard bypass revoked. edit/write now requires a task in-progress again.", "info");
2253
+ clearGuardBypass();
2254
+ ctx.ui.notify("Guard bypass revoked. edit/write advisory warnings re-enabled.", "info");
2230
2255
  }
2231
2256
  }
2232
2257
  catch (e) {
@@ -2771,29 +2796,29 @@ export default function planPiExtension(pi) {
2771
2796
  pi.registerTool({
2772
2797
  name: "plan_authorize_bypass",
2773
2798
  label: "Plan Authorize Guard Bypass",
2774
- description: "Authorize a temporary guard bypass (default 15 minutes) so edit/write tools can proceed even when no task is in-progress. Use this ONLY after the user explicitly authorizes proceeding without a task. Harness-agnostic: stored in resume.json so all adapters respect it.",
2799
+ description: "Authorize a temporary guard bypass (default 15 minutes) so the edit/write advisory guard stops warning when no task is in-progress. Per-session in-memory: not persisted, not shared across agents. Use ONLY after the user explicitly authorizes proceeding without a task.",
2775
2800
  parameters: Type.Object({
2776
2801
  durationMinutes: Type.Optional(Type.Number({ description: "Bypass window in minutes. Default 15." })),
2777
2802
  }),
2778
2803
  async execute(_id, params, _signal, _onUpdate, ctx) {
2779
- const st = await requirePlan(ctx);
2780
- if (!st)
2804
+ const ok = await requirePlan(ctx);
2805
+ if (!ok)
2781
2806
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
2782
2807
  const mins = params.durationMinutes ?? 15;
2783
- const until = await st.authorizeGuardBypass(mins);
2784
- return { content: [{ type: "text", text: `Guard bypass authorized until ${until}. edit/write is allowed without a task in-progress for ${mins} minutes.` }], details: { until } };
2808
+ const until = authorizeGuardBypass(mins);
2809
+ return { content: [{ type: "text", text: `Guard bypass authorized until ${until}. Advisory edit/write warnings silenced for ${mins} minutes (per-session, not shared).` }], details: { until } };
2785
2810
  },
2786
2811
  });
2787
2812
  pi.registerTool({
2788
2813
  name: "plan_clear_bypass",
2789
2814
  label: "Plan Clear Guard Bypass",
2790
- description: "Revoke any active guard bypass so edit/write again requires a task in-progress.",
2815
+ description: "Revoke the per-session guard bypass so the edit/write advisory warnings resume.",
2791
2816
  parameters: Type.Object({}),
2792
2817
  async execute(_id, _params, _signal, _onUpdate, ctx) {
2793
- const st = await requirePlan(ctx);
2794
- if (!st)
2818
+ const ok = await requirePlan(ctx);
2819
+ if (!ok)
2795
2820
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
2796
- await st.clearGuardBypass();
2821
+ clearGuardBypass();
2797
2822
  return { content: [{ type: "text", text: "Guard bypass revoked." }], details: { cleared: true } };
2798
2823
  },
2799
2824
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-plan/pi-adapter",
3
- "version": "0.2.19-next.1",
3
+ "version": "0.2.19-next.2",
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.19-next.1",
32
- "@agent-plan/server": "0.2.19-next.1"
31
+ "@agent-plan/core": "0.2.19-next.2",
32
+ "@agent-plan/server": "0.2.19-next.2"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@earendil-works/pi-coding-agent": "^0.74.0",