@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
@@ -9,8 +9,10 @@ export interface ProcessManagerApi {
9
9
  delegate_status(sessionId: string): Promise<{ status: SessionStatus }>;
10
10
  delegate_list(): Promise<Array<{ sessionId: string; status: SessionStatus; projectPath: string }>>;
11
11
  delegate_stop(sessionId: string): Promise<boolean>;
12
- delegate_fork(sessionId: string, task: string, title?: string): Promise<{ sessionId: string; status: "started" | "already_running" }>;
12
+ delegate_fork(sessionId: string, task: string, title?: string, projectPath?: string): Promise<{ sessionId: string; status: "started" | "already_running" }>;
13
13
  delegate_compact_status(sessionId: string): Promise<{ isCompacting: boolean; contextUsage: { tokens: number | null; contextWindow: number; percent: number | null } }>;
14
+ delegate_remove(sessionId: string): Promise<boolean>;
15
+ delegate_clear_stopped(): Promise<number>;
14
16
  }
15
17
 
16
18
  export class TaskStore {
@@ -43,6 +45,9 @@ export class TaskStore {
43
45
  }
44
46
 
45
47
  add(task: DelegatedTask): void {
48
+ if (!task.sessionId) {
49
+ throw new Error("[coordinator] cannot add task with empty sessionId");
50
+ }
46
51
  this.tasks.set(task.sessionId, task);
47
52
  this.save();
48
53
  }
@@ -67,15 +72,35 @@ export class TaskStore {
67
72
  return Array.from(this.tasks.values());
68
73
  }
69
74
 
75
+ clearStopped(): number {
76
+ let removed = 0;
77
+ for (const [id, task] of this.tasks) {
78
+ if (task.status === "stopped" || task.status === "completed") {
79
+ this.tasks.delete(id);
80
+ removed++;
81
+ }
82
+ }
83
+ if (removed > 0) this.save();
84
+ return removed;
85
+ }
86
+
70
87
  buildPrompt(): string {
71
- const tasks = this.list();
88
+ const FINISHED_MAX_AGE_MS = 5 * 60 * 1000; // 5 minutes
89
+ const now = Date.now();
90
+ const tasks = this.list().filter((t) => {
91
+ if ((t.status === "stopped" || t.status === "completed") && t.completedAt && now - t.completedAt > FINISHED_MAX_AGE_MS) {
92
+ return false;
93
+ }
94
+ return true;
95
+ });
72
96
  if (tasks.length === 0) return "";
73
97
 
74
98
  const lines = ["## Delegated Tasks", ""];
75
99
  for (const t of tasks) {
76
100
  const status = t.status === "completed" ? "DONE" : t.status === "stopped" ? "STOPPED" : t.status.toUpperCase();
77
- const compactTag = (t as any).isCompacting ? " COMPACTING" : "";
78
- const ctxTag = (t as any).contextUsage?.percent != null ? ` ctx:${Math.round((t as any).contextUsage.percent)}%` : "";
101
+ const compactTag = (t as Record<string, unknown>).isCompacting ? " COMPACTING" : "";
102
+ const ctxUsage = (t as Record<string, unknown>).contextUsage as { percent: number | null } | undefined;
103
+ const ctxTag = ctxUsage?.percent != null ? ` ctx:${Math.round(ctxUsage.percent)}%` : "";
79
104
  const elapsed = t.completedAt
80
105
  ? `${((t.completedAt - t.dispatchedAt) / 1000).toFixed(1)}s`
81
106
  : `${((Date.now() - t.dispatchedAt) / 1000).toFixed(0)}s elapsed`;
@@ -96,9 +121,19 @@ export function createCoordinatorHandler(
96
121
  getStore: () => TaskStore,
97
122
  ): void {
98
123
  channel.handle("session_delegate", async (params: unknown) => {
99
- const { task, title } = params as { task: string; title?: string };
100
- const projectPath = process.cwd();
101
- const result = await pm.delegate(task, projectPath);
124
+ const { task, title, projectPath: rawProjectPath } = params as { task: string; title?: string; projectPath?: string };
125
+ const projectPath = rawProjectPath || process.cwd();
126
+
127
+ let result: { sessionId: string; status: "started" | "already_running" };
128
+ try {
129
+ result = await pm.delegate(task, projectPath);
130
+ } catch (err) {
131
+ return { __error: err instanceof Error ? err.message : String(err) };
132
+ }
133
+
134
+ if (!result.sessionId) {
135
+ return { __error: "[coordinator] delegate failed: no sessionId returned" };
136
+ }
102
137
 
103
138
  getStore().add({
104
139
  sessionId: result.sessionId,
@@ -126,7 +161,7 @@ export function createCoordinatorHandler(
126
161
  const store = getStore();
127
162
  const task = store.get(targetSessionId);
128
163
  if (task && task.status === "stopped") {
129
- store.update(targetSessionId, { status: "idle" });
164
+ store.update(targetSessionId, { status: "idle", completedAt: undefined });
130
165
  }
131
166
  }
132
167
 
@@ -160,20 +195,51 @@ export function createCoordinatorHandler(
160
195
  const { sessionId } = params as { sessionId: string };
161
196
  const ok = await pm.delegate_stop(sessionId);
162
197
  if (ok) {
163
- getStore().update(sessionId, { status: "stopped" });
198
+ const store = getStore();
199
+ store.update(sessionId, { status: "stopped", completedAt: Date.now() });
164
200
  channel.emit("task_stopped", { sessionId });
165
201
  }
166
202
  return { ok };
167
203
  });
168
204
 
205
+ channel.handle("session_delegate_remove", async (params: unknown) => {
206
+ const { sessionId } = params as { sessionId: string };
207
+ const store = getStore();
208
+ const task = store.get(sessionId);
209
+ if (!task) {
210
+ return { ok: false };
211
+ }
212
+ await pm.delegate_stop(sessionId).catch(() => {});
213
+ store.remove(sessionId);
214
+ return { ok: true };
215
+ });
216
+
217
+ channel.handle("session_delegate_clear_stopped", async () => {
218
+ const store = getStore();
219
+ const removed = store.clearStopped();
220
+ return { removed };
221
+ });
222
+
169
223
  channel.handle("session_delegate_fork", async (params: unknown) => {
170
- const { sessionId, task, title } = params as { sessionId: string; task: string; title?: string };
171
- const result = await pm.delegate_fork(sessionId, task, title);
224
+ const { sessionId, task, title, projectPath: rawProjectPath } = params as { sessionId: string; task: string; title?: string; projectPath?: string };
225
+ const projectPath = rawProjectPath || process.cwd();
226
+
227
+ let result: { sessionId: string; status: "started" | "already_running" };
228
+ try {
229
+ result = await pm.delegate_fork(sessionId, task, title, projectPath);
230
+ } catch (err) {
231
+ return { __error: err instanceof Error ? err.message : String(err) };
232
+ }
233
+
234
+ if (!result.sessionId) {
235
+ return { __error: "[coordinator] fork failed: no sessionId returned" };
236
+ }
237
+
172
238
  getStore().add({
173
239
  sessionId: result.sessionId,
174
240
  title: title || task.slice(0, 60),
175
241
  task,
176
- projectPath: process.cwd(),
242
+ projectPath,
177
243
  dispatchedAt: Date.now(),
178
244
  status: "idle",
179
245
  });