@dyyz1993/pi-coding-agent 0.74.24 → 0.74.27

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 (157) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/core/agent-session.d.ts.map +1 -1
  3. package/dist/core/agent-session.js +3 -0
  4. package/dist/core/agent-session.js.map +1 -1
  5. package/dist/core/session-manager.d.ts +5 -0
  6. package/dist/core/session-manager.d.ts.map +1 -1
  7. package/dist/core/session-manager.js +8 -0
  8. package/dist/core/session-manager.js.map +1 -1
  9. package/dist/extensions/agent-permissions/index.ts +235 -0
  10. package/dist/extensions/ask-tools/index.ts +115 -0
  11. package/dist/extensions/auto-memory/contract.d.ts +51 -0
  12. package/dist/extensions/auto-memory/contract.d.ts.map +1 -0
  13. package/dist/extensions/auto-memory/contract.js +2 -0
  14. package/dist/extensions/auto-memory/contract.js.map +1 -0
  15. package/dist/extensions/auto-memory/contract.ts +56 -0
  16. package/dist/extensions/auto-memory/index.ts +969 -0
  17. package/dist/extensions/auto-memory/prompts.ts +202 -0
  18. package/dist/extensions/auto-memory/skip-rules.ts +297 -0
  19. package/dist/extensions/auto-memory/utils.ts +208 -0
  20. package/dist/extensions/auto-session-title/index.ts +83 -0
  21. package/dist/extensions/bash-ext/contract.d.ts +79 -0
  22. package/dist/extensions/bash-ext/contract.d.ts.map +1 -0
  23. package/dist/extensions/bash-ext/contract.js +2 -0
  24. package/dist/extensions/bash-ext/contract.js.map +1 -0
  25. package/dist/extensions/bash-ext/contract.ts +69 -0
  26. package/dist/extensions/bash-ext/index.ts +858 -0
  27. package/dist/extensions/claude-hooks-compat/config-loader.ts +49 -0
  28. package/dist/extensions/claude-hooks-compat/handler-runner.ts +377 -0
  29. package/dist/extensions/claude-hooks-compat/if-parser.ts +53 -0
  30. package/dist/extensions/claude-hooks-compat/index.ts +178 -0
  31. package/dist/extensions/claude-hooks-compat/matcher.ts +17 -0
  32. package/dist/extensions/claude-hooks-compat/stdin-builder.ts +27 -0
  33. package/dist/extensions/claude-hooks-compat/types.ts +77 -0
  34. package/dist/extensions/compaction-manager/config.ts +47 -0
  35. package/dist/extensions/compaction-manager/context-fold.ts +63 -0
  36. package/dist/extensions/compaction-manager/index.ts +151 -0
  37. package/dist/extensions/compaction-manager/microcompact.ts +49 -0
  38. package/dist/extensions/compaction-manager/reactive.ts +9 -0
  39. package/dist/extensions/compaction-manager/session-memory.ts +48 -0
  40. package/dist/extensions/coordinator/INTEGRATION.md +376 -0
  41. package/dist/extensions/coordinator/handler.test.ts +277 -0
  42. package/dist/extensions/coordinator/handler.ts +189 -0
  43. package/dist/extensions/coordinator/index.ts +261 -0
  44. package/dist/extensions/coordinator/types.d.ts +100 -0
  45. package/dist/extensions/coordinator/types.d.ts.map +1 -0
  46. package/dist/extensions/coordinator/types.js +2 -0
  47. package/dist/extensions/coordinator/types.js.map +1 -0
  48. package/dist/extensions/coordinator/types.ts +72 -0
  49. package/dist/extensions/file-snapshot/index.ts +131 -0
  50. package/dist/extensions/file-time-guard/README.md +133 -0
  51. package/dist/extensions/file-time-guard/config.ts +13 -0
  52. package/dist/extensions/file-time-guard/index.ts +171 -0
  53. package/dist/extensions/hooks-engine/index.ts +117 -0
  54. package/dist/extensions/lsp/lsp/client/file-tracker.ts +70 -0
  55. package/dist/extensions/lsp/lsp/client/registry.ts +305 -0
  56. package/dist/extensions/lsp/lsp/client/runtime.ts +832 -0
  57. package/dist/extensions/lsp/lsp/config/resolver.ts +573 -0
  58. package/dist/extensions/lsp/lsp/contract.d.ts +101 -0
  59. package/dist/extensions/lsp/lsp/contract.d.ts.map +1 -0
  60. package/dist/extensions/lsp/lsp/contract.js +2 -0
  61. package/dist/extensions/lsp/lsp/contract.js.map +1 -0
  62. package/dist/extensions/lsp/lsp/contract.ts +103 -0
  63. package/dist/extensions/lsp/lsp/hooks/agent-end.ts +169 -0
  64. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts +10 -0
  65. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts.map +1 -0
  66. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js +30 -0
  67. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js.map +1 -0
  68. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.ts +41 -0
  69. package/dist/extensions/lsp/lsp/hooks/writethrough.ts +342 -0
  70. package/dist/extensions/lsp/lsp/index.ts +310 -0
  71. package/dist/extensions/lsp/lsp/lsp.test.ts +684 -0
  72. package/dist/extensions/lsp/lsp/monitoring/server-metrics.ts +176 -0
  73. package/dist/extensions/lsp/lsp/tools/lsp-tool.ts +402 -0
  74. package/dist/extensions/lsp/lsp/utils/dependency-resolver.ts +147 -0
  75. package/dist/extensions/lsp/lsp/utils/diagnostics-wait.ts +41 -0
  76. package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts +20 -0
  77. package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts.map +1 -0
  78. package/dist/extensions/lsp/lsp/utils/lsp-helpers.js +64 -0
  79. package/dist/extensions/lsp/lsp/utils/lsp-helpers.js.map +1 -0
  80. package/dist/extensions/lsp/lsp/utils/lsp-helpers.ts +76 -0
  81. package/dist/extensions/message-bridge/GUIDE.md +210 -0
  82. package/dist/extensions/message-bridge/index.ts +222 -0
  83. package/dist/extensions/output-guard/index.ts +446 -0
  84. package/dist/extensions/preview/index.ts +278 -0
  85. package/dist/extensions/rules-engine/MATCH_HISTORY_RECONCILIATION.md +111 -0
  86. package/dist/extensions/rules-engine/RULES-ENGINE-GUIDE.md +470 -0
  87. package/dist/extensions/rules-engine/cache.js +232 -0
  88. package/dist/extensions/rules-engine/cache.ts +38 -0
  89. package/dist/extensions/rules-engine/config.js +63 -0
  90. package/dist/extensions/rules-engine/config.ts +70 -0
  91. package/dist/extensions/rules-engine/index.js +1530 -0
  92. package/dist/extensions/rules-engine/index.ts +552 -0
  93. package/dist/extensions/rules-engine/injector.js +68 -0
  94. package/dist/extensions/rules-engine/injector.ts +74 -0
  95. package/dist/extensions/rules-engine/loader.js +179 -0
  96. package/dist/extensions/rules-engine/loader.ts +205 -0
  97. package/dist/extensions/rules-engine/matcher.js +534 -0
  98. package/dist/extensions/rules-engine/matcher.ts +52 -0
  99. package/dist/extensions/rules-engine/types.d.ts +156 -0
  100. package/dist/extensions/rules-engine/types.d.ts.map +1 -0
  101. package/dist/extensions/rules-engine/types.js +2 -0
  102. package/dist/extensions/rules-engine/types.js.map +1 -0
  103. package/dist/extensions/rules-engine/types.ts +169 -0
  104. package/dist/extensions/session-supervisor/checker.ts +116 -0
  105. package/dist/extensions/session-supervisor/config.ts +45 -0
  106. package/dist/extensions/session-supervisor/index.ts +726 -0
  107. package/dist/extensions/session-supervisor/prompts.ts +132 -0
  108. package/dist/extensions/session-supervisor/scheduler.ts +69 -0
  109. package/dist/extensions/session-supervisor/types.ts +215 -0
  110. package/dist/extensions/subagent/README.md +172 -0
  111. package/dist/extensions/subagent/agents/explorer.md +25 -0
  112. package/dist/extensions/subagent/agents/guide.md +27 -0
  113. package/dist/extensions/subagent/agents/planner.md +37 -0
  114. package/dist/extensions/subagent/agents/reviewer.md +35 -0
  115. package/dist/extensions/subagent/agents/scout.md +50 -0
  116. package/dist/extensions/subagent/agents/verification.md +35 -0
  117. package/dist/extensions/subagent/agents/worker.md +24 -0
  118. package/dist/extensions/subagent/agents.ts +25 -0
  119. package/dist/extensions/subagent/index.ts +987 -0
  120. package/dist/extensions/subagent/prompts/implement-and-review.md +10 -0
  121. package/dist/extensions/subagent/prompts/implement.md +10 -0
  122. package/dist/extensions/subagent/prompts/scout-and-plan.md +9 -0
  123. package/dist/extensions/subagent-ext/contract.d.ts +2 -0
  124. package/dist/extensions/subagent-ext/contract.d.ts.map +1 -0
  125. package/dist/extensions/subagent-ext/contract.js +2 -0
  126. package/dist/extensions/subagent-ext/contract.js.map +1 -0
  127. package/dist/extensions/subagent-ext/contract.ts +1 -0
  128. package/dist/extensions/subagent-ext/index.ts +347 -0
  129. package/dist/extensions/subagent-shared/contract.d.ts +25 -0
  130. package/dist/extensions/subagent-shared/contract.d.ts.map +1 -0
  131. package/dist/extensions/subagent-shared/contract.js +2 -0
  132. package/dist/extensions/subagent-shared/contract.js.map +1 -0
  133. package/dist/extensions/subagent-shared/contract.ts +28 -0
  134. package/dist/extensions/subagent-shared/index.ts +4 -0
  135. package/dist/extensions/subagent-shared/render.ts +166 -0
  136. package/dist/extensions/subagent-shared/types.ts +35 -0
  137. package/dist/extensions/subagent-shared/utils.ts +112 -0
  138. package/dist/extensions/subagent-v2/contract.d.ts +2 -0
  139. package/dist/extensions/subagent-v2/contract.d.ts.map +1 -0
  140. package/dist/extensions/subagent-v2/contract.js +2 -0
  141. package/dist/extensions/subagent-v2/contract.js.map +1 -0
  142. package/dist/extensions/subagent-v2/contract.ts +1 -0
  143. package/dist/extensions/subagent-v2/index.ts +599 -0
  144. package/dist/extensions/todo-ext/contract.d.ts +27 -0
  145. package/dist/extensions/todo-ext/contract.d.ts.map +1 -0
  146. package/dist/extensions/todo-ext/contract.js +2 -0
  147. package/dist/extensions/todo-ext/contract.js.map +1 -0
  148. package/dist/extensions/todo-ext/contract.ts +30 -0
  149. package/dist/extensions/todo-ext/index.ts +419 -0
  150. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  151. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  152. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  153. package/examples/extensions/sandbox/package-lock.json +2 -2
  154. package/examples/extensions/sandbox/package.json +1 -1
  155. package/examples/extensions/with-deps/package-lock.json +2 -2
  156. package/examples/extensions/with-deps/package.json +1 -1
  157. package/package.json +6 -5
@@ -0,0 +1,305 @@
1
+ import { basename, extname } from "node:path";
2
+ import type { ResolvedLspConfig, ResolvedLspServerConfig } from "../config/resolver.js";
3
+ import {
4
+ createLspClientRuntime,
5
+ type LspClientRuntime,
6
+ type LspClientRuntimeOptions,
7
+ type LspDiagnostic,
8
+ } from "./runtime.js";
9
+ import type { ServerMetricsCollector } from "../monitoring/server-metrics.js";
10
+
11
+ export interface LspRuntimeRegistryServerStatus {
12
+ name: string;
13
+ fileTypes?: string[];
14
+ status: ReturnType<LspClientRuntime["getStatus"]>;
15
+ }
16
+
17
+ export interface LspRuntimeRegistryStatus {
18
+ state: "inactive" | "starting" | "ready" | "error";
19
+ reason: string;
20
+ configuredServers: number;
21
+ activeServers: number;
22
+ servers: LspRuntimeRegistryServerStatus[];
23
+ }
24
+
25
+ export interface LspRuntimeRegistryRequestOptions {
26
+ path?: string;
27
+ timeoutMs?: number;
28
+ }
29
+
30
+ export interface LspRuntimeRegistry {
31
+ start(config: ResolvedLspConfig): Promise<void>;
32
+ stop(): Promise<void>;
33
+ reload(config: ResolvedLspConfig): Promise<void>;
34
+ request(method: string, params: unknown, options?: LspRuntimeRegistryRequestOptions): Promise<unknown>;
35
+ requestAll(method: string, params: unknown, options?: LspRuntimeRegistryRequestOptions): Promise<unknown[]>;
36
+ notify(method: string, params: unknown, options?: LspRuntimeRegistryRequestOptions): void;
37
+ getPublishedDiagnostics(filePath?: string): LspDiagnostic[];
38
+ getStatus(): LspRuntimeRegistryStatus;
39
+ getStatusForPath(filePath: string): ReturnType<LspClientRuntime["getStatus"]> | undefined;
40
+ }
41
+
42
+ export interface LspRuntimeRegistryOptions extends Omit<LspClientRuntimeOptions, "spawn"> {
43
+ createRuntime?: () => LspClientRuntime;
44
+ metrics?: ServerMetricsCollector;
45
+ }
46
+
47
+ interface RuntimeEntry {
48
+ server: ResolvedLspServerConfig;
49
+ runtime: LspClientRuntime;
50
+ }
51
+
52
+ export function createLspRuntimeRegistry(options: LspRuntimeRegistryOptions = {}): LspRuntimeRegistry {
53
+ const createRuntime = options.createRuntime ?? (() => createLspClientRuntime(options));
54
+ const metrics = options.metrics;
55
+ const entries = new Map<string, RuntimeEntry>();
56
+
57
+ let lifecycle: LspRuntimeRegistryStatus["state"] = "inactive";
58
+ let lifecycleReason = "LSP registry has not started.";
59
+
60
+ return {
61
+ async start(config: ResolvedLspConfig): Promise<void> {
62
+ await this.stop();
63
+
64
+ const servers = normalizeServers(config);
65
+ if (servers.length === 0) {
66
+ lifecycle = "inactive";
67
+ lifecycleReason = "No LSP servers configured.";
68
+ return;
69
+ }
70
+
71
+ lifecycle = "starting";
72
+ lifecycleReason = `Starting ${servers.length} LSP server(s).`;
73
+
74
+ for (const server of servers) {
75
+ metrics?.onStarting(server.name, server.fileTypes ?? []);
76
+ const runtime = createRuntime();
77
+ entries.set(server.name, { server, runtime });
78
+ await runtime.start(server.command);
79
+ const serverStatus = runtime.getStatus();
80
+ if (serverStatus.state === "ready") {
81
+ metrics?.onReady(server.name, serverStatus.pid);
82
+ } else {
83
+ metrics?.onError(server.name);
84
+ }
85
+ }
86
+
87
+ syncLifecycle();
88
+ },
89
+
90
+ async stop(): Promise<void> {
91
+ for (const [name, { runtime }] of entries) {
92
+ metrics?.onStop(name);
93
+ }
94
+ const stopPromises = [...entries.values()].map(({ runtime }) => runtime.stop());
95
+ await Promise.allSettled(stopPromises);
96
+ entries.clear();
97
+ lifecycle = "inactive";
98
+ lifecycleReason = "LSP registry stopped.";
99
+ },
100
+
101
+ async reload(config: ResolvedLspConfig): Promise<void> {
102
+ await this.start(config);
103
+ },
104
+
105
+ async request(method: string, params: unknown, options: LspRuntimeRegistryRequestOptions = {}): Promise<unknown> {
106
+ const entry = options.path ? selectEntryForPath(options.path) : selectWorkspaceEntry();
107
+ if (!entry) {
108
+ throw new Error("No LSP server is configured.");
109
+ }
110
+ const status = entry.runtime.getStatus();
111
+ if (status.state !== "ready") {
112
+ throw new Error(`LSP server ${entry.server.name} is not ready: ${status.reason}`);
113
+ }
114
+ metrics?.onRequest(entry.server.name);
115
+ return entry.runtime.request(method, params, options.timeoutMs);
116
+ },
117
+
118
+ notify(method: string, params: unknown, options: LspRuntimeRegistryRequestOptions = {}): void {
119
+ const allEntries = [...entries.values()];
120
+ const targets = options.path
121
+ ? allEntries.filter((entry) => {
122
+ const extension = extname(options.path!).toLowerCase();
123
+ const fileName = basename(options.path!).toLowerCase();
124
+ return (
125
+ !entry.server.fileTypes ||
126
+ entry.server.fileTypes.length === 0 ||
127
+ serverMatchesFile(entry.server, extension, fileName)
128
+ );
129
+ })
130
+ : allEntries;
131
+ for (const entry of targets) {
132
+ metrics?.onNotify(entry.server.name);
133
+ entry.runtime.notify(method, params);
134
+ }
135
+ },
136
+
137
+ async requestAll(
138
+ method: string,
139
+ params: unknown,
140
+ options: LspRuntimeRegistryRequestOptions = {},
141
+ ): Promise<unknown[]> {
142
+ const allEntries = [...entries.values()];
143
+ const targets = options.path
144
+ ? allEntries.filter((entry) => {
145
+ const extension = extname(options.path!).toLowerCase();
146
+ const fileName = basename(options.path!).toLowerCase();
147
+ return (
148
+ !entry.server.fileTypes ||
149
+ entry.server.fileTypes.length === 0 ||
150
+ serverMatchesFile(entry.server, extension, fileName)
151
+ );
152
+ })
153
+ : allEntries;
154
+ for (const entry of targets) {
155
+ metrics?.onRequest(entry.server.name);
156
+ }
157
+ const results = await Promise.allSettled(
158
+ targets.map(async (entry) => {
159
+ const s = entry.runtime.getStatus();
160
+ if (s.state !== "ready") return null;
161
+ return entry.runtime.request(method, params, options.timeoutMs);
162
+ }),
163
+ );
164
+ return results.map((r) => (r.status === "fulfilled" ? r.value : null));
165
+ },
166
+
167
+ getPublishedDiagnostics(filePath?: string): LspDiagnostic[] {
168
+ if (filePath) {
169
+ const extension = extname(filePath).toLowerCase();
170
+ const fileName = basename(filePath).toLowerCase();
171
+ const allEntries = [...entries.values()];
172
+ const matching = allEntries.filter(
173
+ (entry) =>
174
+ !entry.server.fileTypes ||
175
+ entry.server.fileTypes.length === 0 ||
176
+ serverMatchesFile(entry.server, extension, fileName),
177
+ );
178
+ const diagnostics: LspDiagnostic[] = [];
179
+ for (const { runtime } of matching) {
180
+ diagnostics.push(...runtime.getPublishedDiagnostics(filePath));
181
+ }
182
+ return diagnostics;
183
+ }
184
+
185
+ const diagnostics: LspDiagnostic[] = [];
186
+ for (const { runtime } of entries.values()) {
187
+ diagnostics.push(...runtime.getPublishedDiagnostics());
188
+ }
189
+ return diagnostics;
190
+ },
191
+
192
+ getStatus(): LspRuntimeRegistryStatus {
193
+ syncLifecycle();
194
+ const servers = [...entries.values()].map((entry) => ({
195
+ name: entry.server.name,
196
+ fileTypes: entry.server.fileTypes,
197
+ status: entry.runtime.getStatus(),
198
+ }));
199
+ const activeServers = servers.filter((server) => server.status.state === "ready").length;
200
+
201
+ return {
202
+ state: lifecycle,
203
+ reason: lifecycleReason,
204
+ configuredServers: servers.length,
205
+ activeServers,
206
+ servers,
207
+ };
208
+ },
209
+
210
+ getStatusForPath(filePath: string): ReturnType<LspClientRuntime["getStatus"]> | undefined {
211
+ const entry = selectEntryForPath(filePath);
212
+ return entry?.runtime.getStatus();
213
+ },
214
+ };
215
+
216
+ function selectEntryForPath(filePath: string): RuntimeEntry | undefined {
217
+ const allEntries = [...entries.values()];
218
+ if (allEntries.length === 0) {
219
+ return undefined;
220
+ }
221
+
222
+ const extension = extname(filePath).toLowerCase();
223
+ const fileName = basename(filePath).toLowerCase();
224
+ const exactMatches = allEntries.filter((entry) => serverMatchesFile(entry.server, extension, fileName));
225
+ if (exactMatches.length > 0) {
226
+ return preferReady(exactMatches);
227
+ }
228
+
229
+ const fallbackMatches = allEntries.filter(
230
+ (entry) => !entry.server.fileTypes || entry.server.fileTypes.length === 0,
231
+ );
232
+ if (fallbackMatches.length > 0) {
233
+ return preferReady(fallbackMatches);
234
+ }
235
+
236
+ return preferReady(allEntries);
237
+ }
238
+
239
+ function selectWorkspaceEntry(): RuntimeEntry | undefined {
240
+ const allEntries = [...entries.values()];
241
+ if (allEntries.length === 0) {
242
+ return undefined;
243
+ }
244
+ return preferReady(allEntries);
245
+ }
246
+
247
+ function preferReady(candidates: RuntimeEntry[]): RuntimeEntry | undefined {
248
+ return candidates.find((candidate) => candidate.runtime.getStatus().state === "ready") ?? candidates[0];
249
+ }
250
+
251
+ function syncLifecycle(): void {
252
+ const serverStatuses = [...entries.values()].map((entry) => entry.runtime.getStatus());
253
+ if (serverStatuses.length === 0) {
254
+ lifecycle = "inactive";
255
+ lifecycleReason = "No LSP servers configured.";
256
+ return;
257
+ }
258
+
259
+ const active = serverStatuses.filter((status) => status.state === "ready").length;
260
+ if (active > 0) {
261
+ lifecycle = "ready";
262
+ lifecycleReason = `Connected to ${active} LSP server(s).`;
263
+ return;
264
+ }
265
+
266
+ if (serverStatuses.some((status) => status.state === "starting")) {
267
+ lifecycle = "starting";
268
+ lifecycleReason = "LSP servers are starting.";
269
+ return;
270
+ }
271
+
272
+ const firstError = serverStatuses.find((status) => status.state === "error");
273
+ if (firstError) {
274
+ lifecycle = "error";
275
+ lifecycleReason = firstError.reason;
276
+ return;
277
+ }
278
+
279
+ lifecycle = "inactive";
280
+ lifecycleReason = "No active LSP servers.";
281
+ }
282
+ }
283
+
284
+ function normalizeServers(config: ResolvedLspConfig): ResolvedLspServerConfig[] {
285
+ if (config.servers.length > 0) {
286
+ return config.servers;
287
+ }
288
+ if (!config.serverCommand) {
289
+ return [];
290
+ }
291
+ return [
292
+ {
293
+ name: "default",
294
+ command: config.serverCommand,
295
+ },
296
+ ];
297
+ }
298
+
299
+ function serverMatchesFile(server: ResolvedLspServerConfig, extension: string, fileName: string): boolean {
300
+ if (!server.fileTypes || server.fileTypes.length === 0) {
301
+ return false;
302
+ }
303
+ const normalized = server.fileTypes.map((value) => value.toLowerCase());
304
+ return normalized.includes(extension) || normalized.includes(fileName);
305
+ }