@dyyz1993/pi-coding-agent 0.74.46 → 0.74.48

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.
Files changed (49) hide show
  1. package/dist/core/agent-session.d.ts.map +1 -1
  2. package/dist/core/agent-session.js +16 -0
  3. package/dist/core/agent-session.js.map +1 -1
  4. package/dist/core/session-manager.d.ts +28 -1
  5. package/dist/core/session-manager.d.ts.map +1 -1
  6. package/dist/core/session-manager.js +89 -10
  7. package/dist/core/session-manager.js.map +1 -1
  8. package/dist/extensions/ask-tools/index.ts +45 -0
  9. package/dist/extensions/auto-memory/__tests__/extract-result.test.ts +42 -0
  10. package/dist/extensions/auto-memory/__tests__/prefetch-history.test.ts +136 -0
  11. package/dist/extensions/auto-memory/__tests__/prompts.test.ts +29 -0
  12. package/dist/extensions/auto-memory/__tests__/skip-rules.test.ts +366 -0
  13. package/dist/extensions/auto-memory/contract.d.ts +16 -0
  14. package/dist/extensions/auto-memory/contract.d.ts.map +1 -1
  15. package/dist/extensions/auto-memory/contract.js.map +1 -1
  16. package/dist/extensions/auto-memory/contract.ts +16 -0
  17. package/dist/extensions/auto-memory/index.ts +134 -13
  18. package/dist/extensions/auto-memory/prompts.ts +10 -0
  19. package/dist/extensions/auto-memory/skip-rules.ts +2 -0
  20. package/dist/extensions/auto-session-title/index.ts +2 -0
  21. package/dist/extensions/bash-ext/index.ts +855 -845
  22. package/dist/extensions/claude-hooks-compat/index.ts +12 -7
  23. package/dist/extensions/compaction-manager/index.ts +68 -7
  24. package/dist/extensions/coordinator/handler.test.ts +388 -123
  25. package/dist/extensions/coordinator/handler.ts +78 -12
  26. package/dist/extensions/coordinator/index.ts +306 -198
  27. package/dist/extensions/coordinator/types.d.ts +16 -0
  28. package/dist/extensions/coordinator/types.d.ts.map +1 -1
  29. package/dist/extensions/coordinator/types.js.map +1 -1
  30. package/dist/extensions/coordinator/types.ts +57 -49
  31. package/dist/extensions/hooks-engine/index.ts +3 -0
  32. package/dist/extensions/lsp/lsp/client/smart-file-tracker.ts +302 -0
  33. package/dist/extensions/lsp/lsp/index.ts +15 -9
  34. package/dist/extensions/lsp/lsp/lsp-clangd-e2e.test.ts +229 -0
  35. package/dist/extensions/lsp/lsp/utils/project-scanner.ts +101 -12
  36. package/dist/extensions/message-bridge/index.ts +14 -11
  37. package/dist/extensions/output-guard/index.ts +39 -0
  38. package/dist/extensions/preview/index.ts +23 -0
  39. package/dist/extensions/session-supervisor/index.ts +14 -8
  40. package/dist/extensions/subagent-v2/extract-parent-todos.test.ts +146 -0
  41. package/dist/extensions/subagent-v2/index.ts +430 -57
  42. package/dist/extensions/todo-ext/index.ts +62 -3
  43. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  44. package/dist/modes/interactive/interactive-mode.js +6 -0
  45. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  46. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  47. package/dist/modes/rpc/rpc-mode.js +10 -0
  48. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  49. package/package.json +1 -1
@@ -123,13 +123,18 @@ export default function (pi: ExtensionAPI) {
123
123
  if (isAsync && hookEventName === "PreToolUse") {
124
124
  const runner = getCallLLM(pi);
125
125
  runHandler(handler, stdinData, ctx, runner).then((output) => {
126
- const result = interpretHookOutput(output);
127
- if (handler.asyncRewake && output.exitCode === 2 && result.reason) {
128
- pi.sendMessage({
129
- customType: "hook_async_block",
130
- content: result.reason,
131
- display: true,
132
- });
126
+ try {
127
+ const result = interpretHookOutput(output);
128
+ if (handler.asyncRewake && output.exitCode === 2 && result.reason) {
129
+ pi.sendMessage({
130
+ customType: "hook_async_block",
131
+ content: result.reason,
132
+ display: true,
133
+ });
134
+ }
135
+ } catch (e) {
136
+ const msg = e instanceof Error ? e.message : String(e);
137
+ if (!/stale/i.test(msg)) console.debug("[hooks-compat] async handler failed:", msg);
133
138
  }
134
139
  });
135
140
  continue;
@@ -27,6 +27,8 @@ function loadConfig(): CompactionManagerConfig {
27
27
  return DEFAULT_CONFIG;
28
28
  }
29
29
 
30
+ let compactMetrics = { foldCount: 0, memoryCompactCount: 0, forceCompactCount: 0, rateLimitHits: 0, serverErrors: 0 };
31
+
30
32
  export default function (pi: ExtensionAPI) {
31
33
  const config = loadConfig();
32
34
 
@@ -70,11 +72,17 @@ export default function (pi: ExtensionAPI) {
70
72
  pi.foldEntry(entry.id, summary, tokens);
71
73
  }
72
74
 
75
+ compactMetrics.foldCount++;
73
76
  ctx.ui.notify(`Context fold: folded ${foldable.length} old message(s)`, "info");
77
+ pi.appendEntry("compaction_fold", {
78
+ count: foldable.length,
79
+ totalFolds: compactMetrics.foldCount,
80
+ timestamp: Date.now(),
81
+ });
74
82
  });
75
83
  }
76
84
 
77
- if (config.sessionMemory.enabled) {
85
+ if (config.sessionMemory.enabled) {
78
86
  pi.on("session_before_compact", async (event, ctx) => {
79
87
  const { preparation, signal } = event;
80
88
 
@@ -84,10 +92,16 @@ export default function (pi: ExtensionAPI) {
84
92
  const result = buildMemorySummary(memoryFiles, preparation, config.sessionMemory.minContentLength);
85
93
  if (!result) return;
86
94
 
95
+ compactMetrics.memoryCompactCount++;
87
96
  ctx.ui.notify(
88
97
  `Session Memory Compact: using ${memoryFiles.size} memory files instead of LLM summary`,
89
98
  "info",
90
99
  );
100
+ pi.appendEntry("compaction_session_memory", {
101
+ memoryFiles: memoryFiles.size,
102
+ totalMemory: compactMetrics.memoryCompactCount,
103
+ timestamp: Date.now(),
104
+ });
91
105
 
92
106
  return { compaction: result };
93
107
  });
@@ -98,9 +112,28 @@ export default function (pi: ExtensionAPI) {
98
112
 
99
113
  pi.on("after_provider_response", (event, ctx) => {
100
114
  if (event.status === 429) {
115
+ compactMetrics.rateLimitHits++;
101
116
  ctx.ui.notify("Rate limited — API is throttling requests", "warning");
117
+ pi.sendUserMessage(
118
+ "[System: API Rate Limited] Requests are being throttled. The session will retry automatically. Consider reducing tool call frequency or waiting.",
119
+ { deliverAs: "followUp" },
120
+ );
121
+ pi.appendEntry("compaction_rate_limit", {
122
+ total: compactMetrics.rateLimitHits,
123
+ timestamp: Date.now(),
124
+ });
102
125
  } else if (event.status >= 500) {
126
+ compactMetrics.serverErrors++;
103
127
  ctx.ui.notify(`API server error (${event.status}) — will retry automatically`, "warning");
128
+ pi.sendUserMessage(
129
+ `[System: API Error] Server error (${event.status}) encountered. The session will retry automatically.`,
130
+ { deliverAs: "followUp" },
131
+ );
132
+ pi.appendEntry("compaction_server_error", {
133
+ status: event.status,
134
+ total: compactMetrics.serverErrors,
135
+ timestamp: Date.now(),
136
+ });
104
137
  }
105
138
  });
106
139
 
@@ -111,18 +144,35 @@ export default function (pi: ExtensionAPI) {
111
144
  const { tokens, contextWindow, percent } = usage;
112
145
 
113
146
  if (shouldForceCompact(tokens, contextWindow, config.reactive.forceCompactPercent) && !warnedThisTurn) {
114
- ctx.ui.notify(
115
- `Context critical: ${percent!.toFixed(0)}% (${tokens!.toLocaleString()} / ${contextWindow.toLocaleString()} tokens). Consider /compact-force.`,
116
- "warning",
147
+ const msg = `Context critical: ${percent!.toFixed(0)}% (${tokens!.toLocaleString()} / ${contextWindow.toLocaleString()} tokens). Automatic compaction imminent.`;
148
+ ctx.ui.notify(msg, "warning");
149
+ pi.sendUserMessage(
150
+ `[System: Context Warning — Action Required]\n`
151
+ + `Context window is at ${percent!.toFixed(0)}% — critical. Automatic compaction will occur soon.\n\n`
152
+ + `Compaction is lossy: after compression, the conversation context may lose detail, making current results unreliable.\n\n`
153
+ + `Recommended actions:\n`
154
+ + `1. Return your current findings and conclusions to the parent session now (before compaction).\n`
155
+ + `2. If the task is complex, break it down: return your direction/framework to the parent,\n`
156
+ + ` so the parent can re-dispatch more targeted sub-tasks with fresh context.\n`
157
+ + `3. Use available communication tools to send results back.`,
158
+ { deliverAs: "followUp" },
117
159
  );
118
160
  warnedThisTurn = true;
119
161
  return;
120
162
  }
121
163
 
122
164
  if (shouldWarn(tokens, contextWindow, config.reactive.warnPercent) && !warnedThisTurn) {
123
- ctx.ui.notify(
124
- `Context high: ${percent!.toFixed(0)}% (${tokens!.toLocaleString()} / ${contextWindow.toLocaleString()} tokens)`,
125
- "info",
165
+ const msg = `Context high: ${percent!.toFixed(0)}% (${tokens!.toLocaleString()} / ${contextWindow.toLocaleString()} tokens)`;
166
+ ctx.ui.notify(msg, "info");
167
+ pi.sendUserMessage(
168
+ `[System: Context Warning — Proactive]\n`
169
+ + `Context window at ${percent!.toFixed(0)}% — approaching the compaction threshold.\n\n`
170
+ + `Before automatic compaction reduces context fidelity:\n`
171
+ + `- Consider completing the current task and returning results now.\n`
172
+ + `- If the task is still large, return your current findings and direction,\n`
173
+ + ` so the parent can re-dispatch with a more focused scope.\n`
174
+ + `- Lossy compaction will make current details unreliable after compression.`,
175
+ { deliverAs: "followUp" },
126
176
  );
127
177
  warnedThisTurn = true;
128
178
  }
@@ -139,10 +189,21 @@ export default function (pi: ExtensionAPI) {
139
189
  ctx.compact({
140
190
  customInstructions: instructions,
141
191
  onComplete: (result) => {
192
+ compactMetrics.forceCompactCount++;
142
193
  ctx.ui.notify(`Compaction done: ${result.tokensBefore.toLocaleString()} tokens compressed`, "info");
194
+ pi.appendEntry("compaction_force", {
195
+ tokensBefore: result.tokensBefore,
196
+ total: compactMetrics.forceCompactCount,
197
+ timestamp: Date.now(),
198
+ });
143
199
  },
144
200
  onError: (error) => {
145
201
  ctx.ui.notify(`Compaction failed: ${error.message}`, "error");
202
+ pi.appendEntry("compaction_failed", {
203
+ error: error.message,
204
+ total: compactMetrics.forceCompactCount,
205
+ timestamp: Date.now(),
206
+ });
146
207
  },
147
208
  });
148
209
  },