@mrclrchtr/supi-debug 2.0.2 → 2.0.4

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/README.md CHANGED
@@ -72,8 +72,10 @@ keeps the conversation focused; expand only when you need the details.
72
72
 
73
73
  ### Seeing full details without expanding
74
74
 
75
- The agent-facing `supi_debug` tool always returns the expanded plain-text
76
- representation, which is useful for automated troubleshooting flows.
75
+ The agent-facing `supi_debug` tool returns the expanded plain-text
76
+ representation, subject to PI's standard tool-output truncation limits. This is
77
+ useful for automated troubleshooting flows while protecting the model context
78
+ from very large event payloads.
77
79
 
78
80
  ## Filters
79
81
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "SuPi core — shared infrastructure for SuPi extensions (XML context tags, config system)",
5
5
  "license": "MIT",
6
6
  "repository": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-debug",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "SuPi Debug extension — shared debug event inspection for SuPi extensions",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,17 +31,21 @@
31
31
  "README.md"
32
32
  ],
33
33
  "dependencies": {
34
- "@mrclrchtr/supi-core": "2.0.2"
34
+ "@mrclrchtr/supi-core": "2.0.4"
35
35
  },
36
36
  "bundledDependencies": [
37
37
  "@mrclrchtr/supi-core"
38
38
  ],
39
39
  "peerDependencies": {
40
+ "@earendil-works/pi-ai": "*",
40
41
  "@earendil-works/pi-coding-agent": "*",
41
42
  "@earendil-works/pi-tui": "*",
42
43
  "typebox": "*"
43
44
  },
44
45
  "peerDependenciesMeta": {
46
+ "@earendil-works/pi-ai": {
47
+ "optional": true
48
+ },
45
49
  "@earendil-works/pi-coding-agent": {
46
50
  "optional": true
47
51
  },
package/src/debug.ts CHANGED
@@ -1,4 +1,12 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
1
+ import { StringEnum } from "@earendil-works/pi-ai";
2
+ import {
3
+ DEFAULT_MAX_BYTES,
4
+ DEFAULT_MAX_LINES,
5
+ type ExtensionAPI,
6
+ formatSize,
7
+ type TruncationResult,
8
+ truncateHead,
9
+ } from "@earendil-works/pi-coding-agent";
2
10
  import { loadSupiConfig, registerConfigSettings } from "@mrclrchtr/supi-core/config";
3
11
  import { registerContextProvider } from "@mrclrchtr/supi-core/context";
4
12
  import {
@@ -207,9 +215,25 @@ function formatEvents(events: DebugEventView[], rawAccessDenied: boolean): strin
207
215
  return lines;
208
216
  }
209
217
 
210
- function formatEventLines(query: DebugEventQuery): string[] {
211
- const { events, rawAccessDenied } = getDebugEvents(query);
212
- return formatEvents(events, rawAccessDenied);
218
+ function appendTruncationNote(content: string, truncation: TruncationResult): string {
219
+ if (!truncation.truncated) return content;
220
+
221
+ const omittedLines = truncation.totalLines - truncation.outputLines;
222
+ const omittedBytes = truncation.totalBytes - truncation.outputBytes;
223
+ const separator = content.length > 0 ? "\n\n" : "";
224
+ return `${content}${separator}[Output truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${formatSize(truncation.outputBytes)} of ${formatSize(truncation.totalBytes)}). ${omittedLines} lines (${formatSize(omittedBytes)}) omitted. Use filters or a smaller limit to narrow results.]`;
225
+ }
226
+
227
+ function truncateDebugOutput(content: string): { text: string; truncation?: TruncationResult } {
228
+ const truncation = truncateHead(content, {
229
+ maxLines: DEFAULT_MAX_LINES,
230
+ maxBytes: DEFAULT_MAX_BYTES,
231
+ });
232
+
233
+ return {
234
+ text: appendTruncationNote(truncation.content, truncation),
235
+ truncation: truncation.truncated ? truncation : undefined,
236
+ };
213
237
  }
214
238
 
215
239
  function buildSummaryData(): Record<string, string | number> | null {
@@ -232,24 +256,13 @@ function toolAccessAllowed(config: DebugConfig): boolean {
232
256
 
233
257
  function buildToolResult(params: DebugToolParams, config: DebugConfig) {
234
258
  if (!config.enabled) {
235
- return {
236
- content: [
237
- {
238
- type: "text" as const,
239
- text: "SuPi debug event capture is disabled. Enable Debug in /supi-settings to retain events.",
240
- },
241
- ],
242
- isError: true,
243
- details: { enabled: false },
244
- };
259
+ throw new Error(
260
+ "SuPi debug event capture is disabled. Enable Debug in /supi-settings to retain events.",
261
+ );
245
262
  }
246
263
 
247
264
  if (!toolAccessAllowed(config)) {
248
- return {
249
- content: [{ type: "text" as const, text: "Agent access to SuPi debug events is disabled." }],
250
- isError: true,
251
- details: { enabled: true, agentAccess: config.agentAccess },
252
- };
265
+ throw new Error("Agent access to SuPi debug events is disabled.");
253
266
  }
254
267
 
255
268
  const query: DebugEventQuery = {
@@ -261,14 +274,17 @@ function buildToolResult(params: DebugToolParams, config: DebugConfig) {
261
274
  allowRaw: config.agentAccess === "raw",
262
275
  };
263
276
  const result = getDebugEvents(query);
264
- const lines = formatEventLines(query);
277
+ const output = truncateDebugOutput(
278
+ formatEvents(result.events, result.rawAccessDenied).join("\n"),
279
+ );
265
280
  return {
266
- content: [{ type: "text" as const, text: lines.join("\n") }],
281
+ content: [{ type: "text" as const, text: output.text }],
267
282
  details: {
268
283
  enabled: true,
269
284
  agentAccess: config.agentAccess,
270
285
  rawAccessDenied: result.rawAccessDenied,
271
286
  events: result.events,
287
+ truncation: output.truncation,
272
288
  },
273
289
  };
274
290
  }
@@ -306,12 +322,12 @@ export default function debugExtension(pi: ExtensionAPI) {
306
322
 
307
323
  const query = parseCommandArgs(args);
308
324
  const { events, rawAccessDenied } = getDebugEvents(query);
309
- const lines = formatEvents(events, rawAccessDenied);
325
+ const output = truncateDebugOutput(formatEvents(events, rawAccessDenied).join("\n"));
310
326
  pi.sendMessage({
311
327
  customType: DEBUG_REPORT_TYPE,
312
- content: lines.join("\n"),
328
+ content: output.text,
313
329
  display: true,
314
- details: { events, rawAccessDenied },
330
+ details: { events, rawAccessDenied, truncation: output.truncation },
315
331
  });
316
332
  },
317
333
  });
@@ -325,12 +341,9 @@ export default function debugExtension(pi: ExtensionAPI) {
325
341
  parameters: Type.Object({
326
342
  source: Type.Optional(Type.String({ description: "Filter by extension source, e.g. lsp" })),
327
343
  level: Type.Optional(
328
- Type.Union([
329
- Type.Literal("debug"),
330
- Type.Literal("info"),
331
- Type.Literal("warning"),
332
- Type.Literal("error"),
333
- ]),
344
+ StringEnum(["debug", "info", "warning", "error"], {
345
+ description: "Filter by debug level",
346
+ }),
334
347
  ),
335
348
  category: Type.Optional(Type.String({ description: "Filter by event category" })),
336
349
  limit: Type.Optional(Type.Number({ description: "Maximum number of events to return" })),
package/src/status-log.ts CHANGED
@@ -9,7 +9,6 @@ const EXPECTED_SUPI_TOOLS = [
9
9
  "code_orientation",
10
10
  "code_graph",
11
11
  "code_impact",
12
- "code_affected",
13
12
  "code_find",
14
13
  "code_health",
15
14
  "code_refactor_plan",
@@ -1,7 +1,8 @@
1
1
  // Prompt guidance and tool description for the supi_debug tool.
2
2
 
3
- export const toolDescription =
4
- "Fetch recent session-local SuPi debug events, with optional filters and optional raw data when allowed.";
3
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize } from "@earendil-works/pi-coding-agent";
4
+
5
+ export const toolDescription = `Fetch recent session-local SuPi debug events, with optional filters and optional raw data when allowed. Output is truncated to ${DEFAULT_MAX_LINES} lines or ${formatSize(DEFAULT_MAX_BYTES)} (whichever is hit first).`;
5
6
 
6
7
  export const promptSnippet = "supi_debug — fetch recent SuPi debug events";
7
8