pi-context 1.1.0 → 1.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-context",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Agentic Context Management for the Pi",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -111,6 +111,13 @@ If you fail 3 times:
111
111
  3. Summarize the failure in the checkout message ("Tried X, failed because Y").
112
112
  4. Try a new approach from the clean state.
113
113
 
114
+ ### After Checkout: Execute Next Step
115
+
116
+ When `context_checkout` completes and injects a summary, you are in a **new context**.
117
+
118
+ 1. **READ** the injected summary carefully
119
+ 2. **EXECUTE** the `Next Step` from the summary - this is your new task.
120
+
114
121
  ## Decision Matrix: When to Act
115
122
 
116
123
  | Situation | Action | Reason |
@@ -132,24 +139,24 @@ If you cannot answer these, run `context_log`:
132
139
  | **Is this history useful?** | If "No" -> **SQUASH IT.** |
133
140
  | **Am I in a loop?** | Repeated entries in the graph. |
134
141
 
135
-
136
142
  ## Good Checkout Messages
137
143
 
138
144
  The `message` is your lifeline to your past self.
139
145
  A good message preserves critical context that would otherwise be lost.
140
146
 
141
- Structure: `[Key Finding/Status] + [Reason] + [Important Changes]`
147
+ Structure: `[Key Finding/Status] + [Reason] + [Important Changes] + [Next Step]`
142
148
 
143
149
  * **Key Finding/Status**: What did you discover or complete? Include specific numbers, errors, or outcomes.
144
150
  * **Reason**: Why are you branching/moving? (e.g., "Task complete", "Approach failed", "Need raw logs")
145
151
  * **Important Changes**: What files or logic have been modified? (This checkout only resets *conversation history*, NOT disk files, so you must remember what changed.)
152
+ * **Next Step**: What should you do immediately after this squash? Be specific. (e.g., "Wait for user feedback", "Implement the recommended fix", "Revert file X and try approach Y")
146
153
 
147
154
  Examples:
148
155
 
149
- * *Good (Resetting after failure)*: "Recursive parser hit stack overflow at depth 8000. Switching to iterative. **Reason**: Stack limit reached. **Important Changes**: Modified `utils/recursion.ts`."
150
- * *Good (Cleaning up)*: "Auth module complete: JWT + OAuth2 + RBAC. 23 tests passing. **Reason**: Task done, cleaning context. **Important Changes**: Created `auth/`, modified `routes.ts` and `middleware.ts`."
156
+ * *Good (Resetting after failure)*: "Recursive parser hit stack overflow at depth 8000. Switching to iterative. **Reason**: Stack limit reached. **Important Changes**: Modified `utils/recursion.ts`. **Next Step**: Inform user of the failure and propose iterative approach."
157
+ * *Good (Cleaning up)*: "Auth module complete: JWT + OAuth2 + RBAC. 23 tests passing. **Reason**: Task done, cleaning context. **Important Changes**: Created `auth/`, modified `routes.ts` and `middleware.ts`. **Next Step**: Report completion to user, ask if they want to review or test."
151
158
  * *Bad*: "Switching context." (Too vague - you will forget why)
152
- * *Bad*: "Done." (What is done? What did we learn?)
159
+ * *Bad*: "Done." (What is done? What should you do next?)
153
160
 
154
161
  ## Anti-Patterns
155
162
 
@@ -162,6 +169,7 @@ Examples:
162
169
  | **Blind Checkout** (Guessing IDs) | **Look** (`context_log`) first to get valid IDs. |
163
170
  | **Vague Summaries** ("Done", "Fixed") | **Detailed Summaries** ("Found bug in line 40. Fixed with patch X.") |
164
171
  | **Generic Tag Names** (`task-start`, `phase-1`) | **Semantic Names** (`auth-jwt-start`, `db-schema-plan`) |
172
+ | **Missing Next Step** in checkout message | **Always specify** what to do after squash (e.g., "Wait for user", "Implement fix X") |
165
173
 
166
174
  ## Recipes (Copy-Paste)
167
175
 
@@ -180,7 +188,7 @@ context_tag({ name: "timeout-analysis-start" });
180
188
  // 2. Squash IMMEDIATELY. Do not wait for user.
181
189
  context_checkout({
182
190
  target: "timeout-analysis-start",
183
- message: "Found DB connection pool exhaustion as root cause (pool size: 10, peak load: 1000 req/s). Recommended fix: increase to 50. **Reason**: Context cleanup after research. **Important Changes**: None (read-only).",
191
+ message: "Found DB connection pool exhaustion as root cause (pool size: 10, peak load: 1000 req/s). Recommended fix: increase to 50. **Reason**: Context cleanup after research. **Important Changes**: None (read-only). **Next Step**: Report findings to user and await approval to implement fix.",
184
192
  backupTag: "timeout-analysis-raw-history" // Safety backup
185
193
  });
186
194
  context_tag({ name: "timeout-analysis-done" });
@@ -197,7 +205,7 @@ context_tag({ name: "timeout-analysis-done" });
197
205
  // Squash to Summary (Optimistic Cleanup)
198
206
  context_checkout({
199
207
  target: "oauth-impl-start", // Squash range: Start -> Now
200
- message: "OAuth2 flow implemented with PKCE, Google + GitHub providers. All 12 tests passing. **Reason**: Task complete, cleaning up. **Important Changes**: Created `auth/oauth.ts`, modified `routes.ts`, `config.ts`. Backup at 'oauth-impl-raw-history'.",
208
+ message: "OAuth2 flow implemented with PKCE, Google + GitHub providers. All 12 tests passing. **Reason**: Task complete, cleaning up. **Important Changes**: Created `auth/oauth.ts`, modified `routes.ts`, `config.ts`. **Next Step**: Report completion to user, summarize what was implemented.",
201
209
  backupTag: "oauth-impl-raw-history"
202
210
  });
203
211
  context_tag({ name: "oauth-impl-candidate" });
@@ -213,7 +221,7 @@ context_tag({ name: "oauth-impl-candidate" });
213
221
  // Jump back to the raw history
214
222
  context_checkout({
215
223
  target: "oauth-impl-raw-history",
216
- message: "Reviewing token refresh logic - user reports 401 after 15 min idle. Suspect refresh token not firing. **Reason**: Need raw logs to trace the bug. **Important Changes**: None."
224
+ message: "Reviewing token refresh logic - user reports 401 after 15 min idle. Suspect refresh token not firing. **Reason**: Need raw logs to trace the bug. **Important Changes**: None. **Next Step**: Re-read token refresh implementation and identify the bug."
217
225
  });
218
226
  context_tag({ name: "oauth-review-start" });
219
227
  ```
@@ -228,7 +236,7 @@ context_tag({ name: "oauth-review-start" });
228
236
  // Method A (weak references) failed, trying Method B (object pooling)
229
237
  context_checkout({
230
238
  target: "memory-leak-fix-start",
231
- message: "WeakRef approach failed: objects GC'd within 30s (expected: 5min). Cache hit rate dropped from 95% to 12%. **Reason**: Switching to object pooling approach. **Important Changes**: `CacheManager.ts` modified (will revert)."
239
+ message: "WeakRef approach failed: objects GC'd within 30s (expected: 5min). Cache hit rate dropped from 95% to 12%. **Reason**: Switching to object pooling approach. **Important Changes**: `CacheManager.ts` modified (will revert). **Next Step**: Revert `CacheManager.ts` changes and implement object pooling strategy."
232
240
  });
233
241
  context_tag({ name: "memory-leak-pool-approach-start" });
234
242
  ```
@@ -243,7 +251,7 @@ You tried to fix a bug but broke everything.
243
251
  // Attempted mutex-based fix, but introduced deadlock
244
252
  context_checkout({
245
253
  target: "race-condition-fix-start",
246
- message: "Mutex caused deadlock: Thread A holds mutex, awaits callback; callback needs mutex held by B; B waits for A. Circular wait detected. **Reason**: Trying lock-free CAS approach next. **Important Changes**: `AsyncQueue.ts` lines 70-90 modified (backup saved).",
254
+ message: "Mutex caused deadlock: Thread A holds mutex, awaits callback; callback needs mutex held by B; B waits for A. Circular wait detected. **Reason**: Trying lock-free CAS approach next. **Important Changes**: `AsyncQueue.ts` lines 70-90 modified (backup saved). **Next Step**: Revert `AsyncQueue.ts` and implement lock-free compare-and-swap approach.",
247
255
  backupTag: "race-condition-mutex-fail" // Save the failure for reference
248
256
  });
249
257
  context_tag({ name: "race-condition-lockfree-start" });
package/src/index.ts CHANGED
@@ -64,18 +64,30 @@ export default function (pi: ExtensionAPI) {
64
64
  description: "Enable agentic context management for the current session",
65
65
  handler: async (args, ctx) => {
66
66
  CommandCtx = ctx;
67
- pi.setActiveTools(pi.getActiveTools().concat(InternalTools));
68
67
  ctx.ui.notify("Agentic Context Management enabled.", "info");
69
68
  pi.sendMessage({
70
69
  customType: "pi-context",
71
- content: "read context-management skill",
70
+ content: "use context-management skill",
72
71
  display: false,
73
72
  }, {
74
73
  deliverAs: "followUp"
75
74
  });
75
+ if (args) {
76
+ pi.sendUserMessage(args)
77
+ }
76
78
  }
77
79
  });
78
80
 
81
+ // Helper: Check if a tag name already exists in the tree
82
+ const findTagInTree = (sm: SessionManager, nodes: SessionTreeNode[], tagName: string): string | null => {
83
+ for (const n of nodes) {
84
+ if (sm.getLabel(n.entry.id) === tagName) return n.entry.id;
85
+ const r = findTagInTree(sm, n.children, tagName);
86
+ if (r) return r;
87
+ }
88
+ return null;
89
+ };
90
+
79
91
  pi.registerTool({
80
92
  name: "context_tag",
81
93
  label: "Context Tag",
@@ -83,6 +95,19 @@ export default function (pi: ExtensionAPI) {
83
95
  parameters: ContextTagParams,
84
96
  async execute(_id, params: Static<typeof ContextTagParams>, _signal, _onUpdate, ctx) {
85
97
  const sm = ctx.sessionManager as SessionManager;
98
+
99
+ // Deduplication check: ensure tag name is unique
100
+ const existingTagId = findTagInTree(sm, sm.getTree(), params.name);
101
+ if (existingTagId) {
102
+ return {
103
+ content: [{
104
+ type: "text",
105
+ text: `Error: Tag '${params.name}' already exists at ${existingTagId}. Tag names must be unique. Use a different name or delete the existing tag first.`
106
+ }],
107
+ details: {}
108
+ };
109
+ }
110
+
86
111
  let id = params.target ? resolveTargetId(sm, params.target) : undefined;
87
112
 
88
113
  if (!id) {
@@ -343,7 +368,14 @@ export default function (pi: ExtensionAPI) {
343
368
  parameters: ContextCheckoutParams,
344
369
  async execute(_id, params: Static<typeof ContextCheckoutParams>, _signal, _onUpdate, ctx) {
345
370
  if (!CommandCtx) {
346
- return { content: [{ type: "text", text: "Command context not available, require /acm command first." }], details: {} };
371
+ ctx.ui.setEditorText(`/acm ${ctx.ui.getEditorText() || "continue"}`)
372
+ return {
373
+ content: [{
374
+ type: "text",
375
+ text: "Agentic context management is not enabled. Ask the user to run `/acm` in the pi to enable it, then retry."
376
+ }],
377
+ details: {}
378
+ };
347
379
  }
348
380
  const sm = ctx.sessionManager as SessionManager;
349
381
 
@@ -395,15 +427,10 @@ export default function (pi: ExtensionAPI) {
395
427
 
396
428
  pi.sendMessage({
397
429
  customType: "pi-context",
398
- content: "context_checkout done, continue",
430
+ content: "context_checkout complete. A summary of your previous branch was injected above. Read it to understand your new state. Execute the 'Next Step' from the summary",
399
431
  display: false,
400
432
  }, {
401
433
  triggerTurn: true,
402
434
  });
403
435
  });
404
-
405
- pi.on("session_start", () => {
406
- // hide tools by default
407
- pi.setActiveTools(pi.getActiveTools().filter(n => !InternalTools.includes(n)));
408
- });
409
436
  }