pi-ui-extend 0.1.3 → 0.1.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.
Files changed (37) hide show
  1. package/dist/app/app.d.ts +0 -1
  2. package/dist/app/app.js +1 -4
  3. package/dist/app/conversation-entry-renderer.d.ts +0 -1
  4. package/dist/app/conversation-entry-renderer.js +2 -6
  5. package/dist/app/conversation-tool-renderer.js +2 -3
  6. package/dist/app/conversation-viewport.d.ts +0 -1
  7. package/dist/app/conversation-viewport.js +0 -1
  8. package/dist/config.d.ts +0 -3
  9. package/dist/config.js +0 -79
  10. package/dist/default-pix-config.js +2 -2
  11. package/dist/markdown-format.js +18 -1
  12. package/external/pi-tools-suite/README.md +4 -4
  13. package/external/pi-tools-suite/licenses/opencode-dynamic-context-pruning-AGPL-3.0.txt +619 -0
  14. package/external/pi-tools-suite/package.json +1 -1
  15. package/external/pi-tools-suite/src/config.ts +5 -1
  16. package/external/pi-tools-suite/src/{compress → dcp}/config.ts +10 -70
  17. package/external/pi-tools-suite/src/{compress → dcp}/index.ts +16 -66
  18. package/external/pi-tools-suite/src/dcp/ui.ts +45 -0
  19. package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +3 -2
  20. package/external/pi-tools-suite/src/index.ts +1 -1
  21. package/external/pi-tools-suite/src/tool-descriptions.ts +1 -1
  22. package/package.json +1 -1
  23. package/external/pi-tools-suite/src/compress/dcp-tui-filter.ts +0 -498
  24. package/external/pi-tools-suite/src/compress/ui.ts +0 -308
  25. /package/external/pi-tools-suite/src/{compress → dcp}/commands.ts +0 -0
  26. /package/external/pi-tools-suite/src/{compress → dcp}/compress-tool.ts +0 -0
  27. /package/external/pi-tools-suite/src/{compress → dcp}/compression-blocks.ts +0 -0
  28. /package/external/pi-tools-suite/src/{compress → dcp}/prompts.ts +0 -0
  29. /package/external/pi-tools-suite/src/{compress → dcp}/pruner-candidates.ts +0 -0
  30. /package/external/pi-tools-suite/src/{compress → dcp}/pruner-compression-blocks.ts +0 -0
  31. /package/external/pi-tools-suite/src/{compress → dcp}/pruner-message-ids.ts +0 -0
  32. /package/external/pi-tools-suite/src/{compress → dcp}/pruner-metadata.ts +0 -0
  33. /package/external/pi-tools-suite/src/{compress → dcp}/pruner-nudge.ts +0 -0
  34. /package/external/pi-tools-suite/src/{compress → dcp}/pruner-tools.ts +0 -0
  35. /package/external/pi-tools-suite/src/{compress → dcp}/pruner-types.ts +0 -0
  36. /package/external/pi-tools-suite/src/{compress → dcp}/pruner.ts +0 -0
  37. /package/external/pi-tools-suite/src/{compress → dcp}/state.ts +0 -0
package/dist/app/app.d.ts CHANGED
@@ -19,7 +19,6 @@ export declare class PiUiExtendApp {
19
19
  private readonly extensionActions;
20
20
  private readonly pixConfig;
21
21
  private readonly outputFilters;
22
- private readonly suppressPendingDcpIdMetadata;
23
22
  private readonly commandController;
24
23
  private readonly inputActions;
25
24
  private readonly inputController;
package/dist/app/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { THEMES } from "../theme.js";
2
2
  import { InputEditor } from "../input-editor.js";
3
- import { compileOutputFilterPatterns, loadPixConfig, outputFiltersRemoveDcpIdMetadataLine, resolveToolRule, } from "../config.js";
3
+ import { compileOutputFilterPatterns, loadPixConfig, resolveToolRule, } from "../config.js";
4
4
  import { AppCommandController } from "./command-controller.js";
5
5
  import { ConversationViewport } from "./conversation-viewport.js";
6
6
  import { EditorLayoutRenderer } from "./editor-layout-renderer.js";
@@ -64,7 +64,6 @@ export class PiUiExtendApp {
64
64
  extensionActions;
65
65
  pixConfig;
66
66
  outputFilters;
67
- suppressPendingDcpIdMetadata;
68
67
  commandController;
69
68
  inputActions;
70
69
  inputController;
@@ -367,7 +366,6 @@ export class PiUiExtendApp {
367
366
  suppressExtensionWidget: (key) => this.extensionUiController.suppressWidget(key),
368
367
  });
369
368
  this.outputFilters = compileOutputFilterPatterns(this.pixConfig.outputFilters.patterns);
370
- this.suppressPendingDcpIdMetadata = outputFiltersRemoveDcpIdMetadataLine(this.outputFilters);
371
369
  this.conversationViewport = new ConversationViewport({
372
370
  get entries() { return app.entries; },
373
371
  get session() { return app.runtime?.session; },
@@ -379,7 +377,6 @@ export class PiUiExtendApp {
379
377
  colors: this.theme.colors,
380
378
  pixConfig: this.pixConfig,
381
379
  outputFilters: this.outputFilters,
382
- suppressPendingDcpIdMetadata: this.suppressPendingDcpIdMetadata,
383
380
  hasDynamicConversationBlock: () => this.popupMenus.hasDynamicConversationBlock(),
384
381
  isDynamicConversationBlock: (entry) => this.popupMenus.isDynamicConversationBlock(entry),
385
382
  renderInlineUserMessageMenu: (entry, context) => this.popupMenus.renderInlineUserMessageMenu(entry, context),
@@ -11,7 +11,6 @@ export type ConversationEntryRenderOptions = {
11
11
  colors: Theme["colors"];
12
12
  pixConfig: PixConfig;
13
13
  outputFilters: readonly RegExp[];
14
- suppressPendingDcpIdMetadata: boolean;
15
14
  superCompactTools?: boolean;
16
15
  allThinkingExpanded?: boolean;
17
16
  renderInlineUserMessageMenu: (entry: Extract<Entry, {
@@ -1,4 +1,4 @@
1
- import { applyOutputFilters, stripDcpDisplayMetadata, suppressPendingDcpIdMetadataLine } from "../config.js";
1
+ import { applyOutputFilters } from "../config.js";
2
2
  import { renderMarkdownTextLines } from "../markdown-format.js";
3
3
  import { attachImageClickTargets } from "./image-click-targets.js";
4
4
  import { horizontalPaddingLayout, padHorizontalText, wrapText } from "./render-text.js";
@@ -65,7 +65,7 @@ function renderCustomEntry(entry, width) {
65
65
  }));
66
66
  }
67
67
  function renderAssistantLines(text, width, options) {
68
- const displayText = displayAssistantText(text, options.outputFilters, options.suppressPendingDcpIdMetadata);
68
+ const displayText = applyOutputFilters(text, options.outputFilters).trimEnd();
69
69
  if (!displayText)
70
70
  return [];
71
71
  return renderMarkdownTextLines(displayText, width).map((line) => ({
@@ -75,7 +75,3 @@ function renderAssistantLines(text, width, options) {
75
75
  ...(line.syntaxHighlight ? { syntaxHighlight: line.syntaxHighlight } : {}),
76
76
  }));
77
77
  }
78
- function displayAssistantText(text, outputFilters, suppressPendingDcpIdMetadata) {
79
- const filtered = stripDcpDisplayMetadata(applyOutputFilters(text, outputFilters)).trimEnd();
80
- return suppressPendingDcpIdMetadata ? suppressPendingDcpIdMetadataLine(filtered) : filtered;
81
- }
@@ -1,4 +1,4 @@
1
- import { resolveColor, resolveToolRule, stripDcpDisplayMetadata } from "../config.js";
1
+ import { resolveColor, resolveToolRule } from "../config.js";
2
2
  import { formatMarkdownTables, markdownSyntaxHighlightsForText } from "../markdown-format.js";
3
3
  import { renderToolDisplay } from "../tool-renderers/index.js";
4
4
  import { DEFAULT_THINKING_TOOL_RULE, SUBAGENT_STATUSES, THINKING_TOOL_NAME, TODO_TOOL_NAME } from "./constants.js";
@@ -47,8 +47,7 @@ export function renderConversationToolEntry(entry, width, options) {
47
47
  }
48
48
  export function renderThinkingEntry(entry, width, options) {
49
49
  const rule = resolveThinkingToolRule(options.pixConfig);
50
- const displayText = stripDcpDisplayMetadata(entry.text);
51
- const markdownText = displayText ? formatMarkdownTables(displayText, Math.max(1, width - 2)) : "";
50
+ const markdownText = entry.text ? formatMarkdownTables(entry.text, Math.max(1, width - 2)) : "";
52
51
  const expandedText = trimTrailingBlankLines(markdownText);
53
52
  const compactExpandedText = options.superCompactTools ? removeBlankLines(expandedText) : expandedText;
54
53
  const forceExpanded = Boolean(options.allThinkingExpanded);
@@ -12,7 +12,6 @@ export type ConversationViewportHost = {
12
12
  readonly colors: Theme["colors"];
13
13
  readonly pixConfig: PixConfig;
14
14
  readonly outputFilters: readonly RegExp[];
15
- readonly suppressPendingDcpIdMetadata: boolean;
16
15
  readonly superCompactTools?: boolean;
17
16
  readonly allThinkingExpanded?: boolean;
18
17
  hasDynamicConversationBlock?(): boolean;
@@ -65,7 +65,6 @@ export class ConversationViewport {
65
65
  colors: this.host.colors,
66
66
  pixConfig: this.host.pixConfig,
67
67
  outputFilters: this.host.outputFilters,
68
- suppressPendingDcpIdMetadata: this.host.suppressPendingDcpIdMetadata,
69
68
  superCompactTools: Boolean(this.host.superCompactTools),
70
69
  allThinkingExpanded: Boolean(this.host.allThinkingExpanded),
71
70
  renderInlineUserMessageMenu: (userEntry, context) => this.host.renderInlineUserMessageMenu(userEntry, context),
package/dist/config.d.ts CHANGED
@@ -54,9 +54,6 @@ export declare function savePixDictationLanguage(language: string): void;
54
54
  export declare function upsertPixDictationLanguageInJsonc(source: string, language: string): string;
55
55
  export declare function resolveModelColor(modelRef: string, config: ModelColorsConfig): string | undefined;
56
56
  export declare function compileOutputFilterPatterns(patterns: readonly string[]): RegExp[];
57
- export declare function stripDcpDisplayMetadata(text: string): string;
58
57
  export declare function applyOutputFilters(text: string, filters: readonly RegExp[]): string;
59
- export declare function outputFiltersRemoveDcpIdMetadataLine(filters: readonly RegExp[]): boolean;
60
- export declare function suppressPendingDcpIdMetadataLine(text: string): string;
61
58
  export declare function resolveToolRule(toolName: string, config: ToolRendererConfig): ResolvedToolRule;
62
59
  export declare function resolveColor(colorRef: string, themeColors: Record<string, string>): string;
package/dist/config.js CHANGED
@@ -77,17 +77,6 @@ const DEFAULT_DICTATION = {
77
77
  },
78
78
  },
79
79
  };
80
- const DCP_ID_METADATA_SAMPLE = "<dcp-id>m001</dcp-id>";
81
- const DCP_ID_METADATA_PREFIX = "<dcp-id>m";
82
- const DCP_ID_METADATA_SUFFIX = "</dcp-id>";
83
- const DCP_XML_PAIRED_TAG_RE = /<dcp[^>]*>[\s\S]*?<\/dcp[^>]*>/gi;
84
- const DCP_XML_OPEN_TAG_TO_END_RE = /<dcp[^>]*>[\s\S]*$/gi;
85
- const DCP_XML_UNPAIRED_TAG_RE = /<\/?dcp[^>]*>/gi;
86
- const DCP_MARKDOWN_REFERENCE_RE = /[ \t]*\[dcp(?:-[a-z0-9-]+)?\]:[ \t]*#(?:[ \t]+\([^\n]*\))?[ \t]*/gi;
87
- const DCP_MARKDOWN_REFERENCE_LINE_RE = /^[ \t]*\[dcp(?:-[a-z0-9-]+)?\]:[ \t]*#(?:[ \t]+\([^\n]*\))?[ \t]*$/i;
88
- const DCP_MARKDOWN_REFERENCE_PENDING_RE = /^\[d(?:c(?:p(?:-[a-z0-9-]*)?)?)?(?:\]?(?::[ \t]*#?(?:[ \t]*\([^\)\n]*)?)?)?$/i;
89
- const DCP_XML_METADATA_LINE_RE = /^[ \t]*<dcp[^>]*>(?:[\s\S]*?<\/dcp[^>]*>)?[ \t]*$/i;
90
- const DCP_DISPLAY_QUICK_CHECK_RE = /<\/?d(?:c(?:p)?)?|\[d(?:c(?:p)?)?/i;
91
80
  function parseJsonc(text) {
92
81
  return parse(text, undefined, { allowTrailingComma: true });
93
82
  }
@@ -322,37 +311,6 @@ export function resolveModelColor(modelRef, config) {
322
311
  export function compileOutputFilterPatterns(patterns) {
323
312
  return patterns.flatMap((pattern) => compileOutputFilterPattern(pattern));
324
313
  }
325
- export function stripDcpDisplayMetadata(text) {
326
- if (text.length === 0 || !DCP_DISPLAY_QUICK_CHECK_RE.test(text))
327
- return text;
328
- let cleaned = stripDcpDisplayMetadataLines(text);
329
- // Strip fully paired XML-style DCP tags first. During streaming, strip an
330
- // unterminated opening XML tag and everything after it before removing
331
- // orphan tags, otherwise `<dcp-id>m123` would leave `m123` behind.
332
- cleaned = cleaned
333
- .replace(DCP_XML_PAIRED_TAG_RE, "")
334
- .replace(DCP_XML_OPEN_TAG_TO_END_RE, "")
335
- .replace(DCP_XML_UNPAIRED_TAG_RE, "");
336
- // Hide a partially streamed markdown reference line before the complete-line
337
- // regex can strip the prefix and strand the `(m123` payload.
338
- cleaned = suppressPendingDcpIdMetadataLine(cleaned).replace(DCP_MARKDOWN_REFERENCE_RE, "");
339
- cleaned = suppressPendingDcpIdMetadataLine(cleaned);
340
- cleaned = stripDcpDisplayMetadataLines(cleaned);
341
- return cleaned.replace(/\n{3,}/g, "\n\n").trimEnd();
342
- }
343
- function stripDcpDisplayMetadataLines(text) {
344
- if (text.length === 0)
345
- return text;
346
- let removed = false;
347
- const keptLines = text.split("\n").filter((line) => {
348
- const normalizedLine = line.replace(/\r$/u, "");
349
- const isMetadataLine = DCP_MARKDOWN_REFERENCE_LINE_RE.test(normalizedLine) || DCP_XML_METADATA_LINE_RE.test(normalizedLine);
350
- if (isMetadataLine)
351
- removed = true;
352
- return !isMetadataLine;
353
- });
354
- return removed ? keptLines.join("\n") : text;
355
- }
356
314
  export function applyOutputFilters(text, filters) {
357
315
  if (filters.length === 0 || text.length === 0)
358
316
  return text;
@@ -374,43 +332,6 @@ export function applyOutputFilters(text, filters) {
374
332
  }
375
333
  return filteredLines.join("\n");
376
334
  }
377
- export function outputFiltersRemoveDcpIdMetadataLine(filters) {
378
- return filters.length > 0 && applyOutputFilters(DCP_ID_METADATA_SAMPLE, filters).length === 0;
379
- }
380
- export function suppressPendingDcpIdMetadataLine(text) {
381
- if (text.length === 0)
382
- return text;
383
- const lineStart = text.lastIndexOf("\n") + 1;
384
- const line = text.slice(lineStart);
385
- if (!isPendingDcpIdMetadataLine(line))
386
- return text;
387
- // Hide the still-streaming metadata line and its line break until it either
388
- // becomes a complete filtered line or diverges from the metadata prefix.
389
- return lineStart > 0 ? text.slice(0, lineStart - 1) : "";
390
- }
391
- function isPendingDcpIdMetadataLine(line) {
392
- const candidate = line.trimStart();
393
- if (candidate.length === 0)
394
- return false;
395
- return isPendingXmlDcpIdMetadataLine(candidate) || isPendingMarkdownDcpMetadataLine(candidate);
396
- }
397
- function isPendingXmlDcpIdMetadataLine(candidate) {
398
- if (DCP_ID_METADATA_PREFIX.startsWith(candidate))
399
- return true;
400
- if (!candidate.startsWith(DCP_ID_METADATA_PREFIX))
401
- return false;
402
- const afterPrefix = candidate.slice(DCP_ID_METADATA_PREFIX.length);
403
- const digits = afterPrefix.match(/^\d*/)?.[0] ?? "";
404
- const afterDigits = afterPrefix.slice(digits.length);
405
- if (afterDigits.length === 0)
406
- return true;
407
- return DCP_ID_METADATA_SUFFIX.startsWith(afterDigits) && afterDigits.length < DCP_ID_METADATA_SUFFIX.length;
408
- }
409
- function isPendingMarkdownDcpMetadataLine(candidate) {
410
- if (DCP_MARKDOWN_REFERENCE_LINE_RE.test(candidate))
411
- return false;
412
- return DCP_MARKDOWN_REFERENCE_PENDING_RE.test(candidate);
413
- }
414
335
  function applyOutputFiltersToLine(line, filters) {
415
336
  let filtered = line;
416
337
  for (const filter of filters) {
@@ -169,10 +169,10 @@ export const DEFAULT_PIX_CONFIG_JSONC = String.raw `{
169
169
  },
170
170
 
171
171
  // Output filters applied to assistant text in the renderer.
172
- // Supports glob-style * wildcards, or regex literals like "/<dcp-id>m\\d+<\\/dcp-id>/".
172
+ // Supports glob-style * wildcards, or regex literals like "/token=\\w+/".
173
173
  // "outputFilters": {
174
174
  // "patterns": [
175
- // "<dcp-id>m*</dcp-id>"
175
+ // "secret-*"
176
176
  // ]
177
177
  // },
178
178
 
@@ -4,6 +4,7 @@ export function formatMarkdownTables(text, maxWidth) {
4
4
  const lines = text.split("\n");
5
5
  const formatted = [];
6
6
  let fence;
7
+ let skipBlankAfterHiddenReference = false;
7
8
  for (let index = 0; index < lines.length;) {
8
9
  const line = lines[index] ?? "";
9
10
  const nextFence = markdownFence(line);
@@ -16,6 +17,16 @@ export function formatMarkdownTables(text, maxWidth) {
16
17
  index += 1;
17
18
  continue;
18
19
  }
20
+ if (!fence && isMarkdownReferenceDefinition(line)) {
21
+ skipBlankAfterHiddenReference = formatted.length === 0 || (formatted.at(-1) ?? "").trim().length === 0;
22
+ index += 1;
23
+ continue;
24
+ }
25
+ if (!fence && skipBlankAfterHiddenReference && line.trim().length === 0) {
26
+ index += 1;
27
+ continue;
28
+ }
29
+ skipBlankAfterHiddenReference = false;
19
30
  if (!fence) {
20
31
  const table = parseMarkdownTableBlock(lines, index);
21
32
  if (table) {
@@ -61,7 +72,10 @@ export function renderMarkdownLine(text, start = 0) {
61
72
  export function renderMarkdownTextLines(text, width, start = 0) {
62
73
  const lines = [];
63
74
  let fence;
64
- for (const rawLine of formatMarkdownTables(sanitizeMarkdownText(text), width).split("\n")) {
75
+ const formattedText = formatMarkdownTables(sanitizeMarkdownText(text), width);
76
+ if (formattedText.length === 0)
77
+ return [];
78
+ for (const rawLine of formattedText.split("\n")) {
65
79
  const nextFence = markdownFence(rawLine);
66
80
  const closesFence = Boolean(fence && nextFence && fence.marker === nextFence.marker && nextFence.length >= fence.length);
67
81
  const opensFence = !fence && nextFence !== undefined;
@@ -533,6 +547,9 @@ function markdownLineSyntaxHighlight(fence, fenceDelimiterLine, start) {
533
547
  function sanitizeMarkdownText(text) {
534
548
  return expandTabs(text.replace(/\x1b/g, "␛").replace(/\r/g, ""));
535
549
  }
550
+ function isMarkdownReferenceDefinition(line) {
551
+ return /^ {0,3}\[[^\]\n]+\]:[ \t]*\S.*$/u.test(line);
552
+ }
536
553
  function markdownFence(line) {
537
554
  const match = /^\s{0,3}(`{3,}|~{3,})(.*)$/.exec(line);
538
555
  const marker = match?.[1];
@@ -14,12 +14,12 @@ This package keeps the former standalone extensions as ordinary source folders u
14
14
  - `src/model-tools` — model-specific tool aliases such as Claude/GLM-style `Read` / `Edit` / `Write` / `Bash` / `Grep` / `Glob` / `LS`, GPT/Codex-style `shell`, and model-gated `apply_patch`
15
15
  - `src/usage` — `/usage` command and startup hint for read-only AI quota checks across OpenAI, Zhipu AI, Z.ai, and Google Antigravity, including Antigravity quota by model
16
16
  - `src/web-search` — `web_search` and `web_fetch` tools migrated from `@ollama/pi-web-search`; calls the local Ollama experimental web search/fetch APIs, honors `OLLAMA_HOST`, supports request timeouts via `timeout_ms` / `PI_WEB_SEARCH_TIMEOUT_MS`, and reports targeted `ollama signin`, unsupported-endpoint, invalid-response, timeout, DNS, and Ollama-not-running errors
17
- - `src/compress` — Dynamic Context Pruning: explicit `compress` tool with range and message modes, `/dcp` commands (context, stats, sweep, manual, decompress, recompress, compress), same-call overlap validation, recoverable compressed-block rollups, grouped message-mode skip diagnostics, stable raw-message anchors when available, protected user/tool preservation, deduplication, error purging, context nudges, and footer status visualization
17
+ - `src/dcp` — headless Dynamic Context Pruning ported from `opencode-dynamic-context-pruning` for the Pi SDK: explicit `compress` tool with range and message modes, `/dcp` commands (context, stats, sweep, manual, decompress, recompress, compress), same-call overlap validation, recoverable compressed-block rollups, grouped message-mode skip diagnostics, stable raw-message anchors when available, protected user/tool preservation, deduplication, error purging, and context nudges; visualization is left to `compress` tool responses and the renderer-owned context-percent click dialog
18
18
  - `src/prompt-commands` — user slash-command builder: `/prompt-commands` opens a CRUD menu for saved prompt-backed slash commands, stores them under `promptCommands` in `~/.config/pi/pi-tools-suite.jsonc`, reloads after edits, and runs each saved prompt as a normal user message
19
19
 
20
20
  `index.ts` is intentionally only a thin auto-discovery shim that re-exports `src/index.ts`. There is no `pi.extensions` manifest here, so local Pi auto-discovery loads the suite once via `~/.pi/agent/extensions/pi-tools-suite/index.ts` and does not double-register tools.
21
21
 
22
- Registration order is preserved in `src/index.ts`: ast-grep, async-subagents, terminal-bell, lsp, repo-discovery command/tool gate, antigravity-auth provider, todo, model-tools, usage, web-search, compress, then prompt-commands. Tool metadata and active model-specific tool sets have two modes: standard and repo-aware. When `.indexer-cli` enables `repo_*`, those tools stay active ahead of overlapping lower-level aliases so the indexed discovery surface has priority.
22
+ Registration order is preserved in `src/index.ts`: ast-grep, async-subagents, terminal-bell, lsp, repo-discovery command/tool gate, antigravity-auth provider, todo, model-tools, usage, web-search, dcp, then prompt-commands. Tool metadata and active model-specific tool sets have two modes: standard and repo-aware. When `.indexer-cli` enables `repo_*`, those tools stay active ahead of overlapping lower-level aliases so the indexed discovery surface has priority.
23
23
 
24
24
  ## Disabling modules
25
25
 
@@ -55,7 +55,7 @@ Saved prompt slash commands are stored under `promptCommands`. Use `/prompt-comm
55
55
  }
56
56
  ```
57
57
 
58
- DCP/compress settings are stored under `dcp` in the same shared config files. Legacy standalone `dcp.jsonc` files are still read for compatibility, but the `dcp` section in `pi-tools-suite.jsonc` wins at the same global/env/project layer.
58
+ DCP settings are stored only under `dcp` in the user shared config file `~/.config/pi/pi-tools-suite.jsonc`. Legacy standalone `dcp.jsonc`, `$PI_CONFIG_DIR`, and project-local `.pi/pi-tools-suite.jsonc` DCP settings are intentionally ignored by the ported headless DCP module.
59
59
 
60
60
  ```jsonc
61
61
  {
@@ -214,7 +214,7 @@ pi-tools-suite/
214
214
  model-tools/
215
215
  usage/
216
216
  web-search/
217
- compress/
217
+ dcp/
218
218
  prompt-commands/
219
219
  docs/
220
220
  licenses/