pi-ui-extend 0.1.6 → 0.1.9

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 (174) hide show
  1. package/README.md +34 -0
  2. package/bin/pix.mjs +4 -4
  3. package/dist/app/app.js +38 -38
  4. package/dist/app/{cli.d.ts → cli/cli.d.ts} +1 -1
  5. package/dist/app/{cli.js → cli/cli.js} +1 -1
  6. package/dist/app/{install.js → cli/install.js} +2 -2
  7. package/dist/app/{command-controller.d.ts → commands/command-controller.d.ts} +1 -1
  8. package/dist/app/{command-host.d.ts → commands/command-host.d.ts} +3 -3
  9. package/dist/app/{command-model-actions.d.ts → commands/command-model-actions.d.ts} +1 -1
  10. package/dist/app/{command-model-actions.js → commands/command-model-actions.js} +2 -2
  11. package/dist/app/{command-navigation-actions.d.ts → commands/command-navigation-actions.d.ts} +1 -1
  12. package/dist/app/{command-navigation-actions.js → commands/command-navigation-actions.js} +5 -5
  13. package/dist/app/{command-registry.d.ts → commands/command-registry.d.ts} +1 -1
  14. package/dist/app/{command-runtime.js → commands/command-runtime.js} +1 -1
  15. package/dist/app/{command-session-actions.js → commands/command-session-actions.js} +3 -3
  16. package/dist/app/{shell-controller.d.ts → commands/shell-controller.d.ts} +1 -1
  17. package/dist/app/{shell-controller.js → commands/shell-controller.js} +1 -1
  18. package/dist/app/{slash-commands.d.ts → commands/slash-commands.d.ts} +2 -2
  19. package/dist/app/{slash-commands.js → commands/slash-commands.js} +1 -1
  20. package/dist/app/{extension-actions-controller.d.ts → extensions/extension-actions-controller.d.ts} +1 -1
  21. package/dist/app/{extension-actions-controller.js → extensions/extension-actions-controller.js} +1 -1
  22. package/dist/app/{extension-ui-controller.d.ts → extensions/extension-ui-controller.d.ts} +3 -3
  23. package/dist/app/{extension-ui-controller.js → extensions/extension-ui-controller.js} +4 -3
  24. package/dist/app/{input-action-controller.d.ts → input/input-action-controller.d.ts} +7 -7
  25. package/dist/app/{input-action-controller.js → input/input-action-controller.js} +3 -3
  26. package/dist/app/{input-controller.d.ts → input/input-controller.d.ts} +3 -3
  27. package/dist/app/{input-controller.js → input/input-controller.js} +1 -1
  28. package/dist/app/{input-paste-handler.d.ts → input/input-paste-handler.d.ts} +1 -1
  29. package/dist/app/{input-paste-handler.js → input/input-paste-handler.js} +3 -3
  30. package/dist/app/{native-modifiers.js → input/native-modifiers.js} +2 -2
  31. package/dist/app/{prompt-enhancer-controller.d.ts → input/prompt-enhancer-controller.d.ts} +5 -5
  32. package/dist/app/{prompt-enhancer-controller.js → input/prompt-enhancer-controller.js} +3 -3
  33. package/dist/app/{voice-controller.d.ts → input/voice-controller.d.ts} +1 -1
  34. package/dist/app/{voice-controller.js → input/voice-controller.js} +2 -2
  35. package/dist/app/{model-ref.d.ts → model/model-ref.d.ts} +1 -1
  36. package/dist/app/{model-ref.js → model/model-ref.js} +1 -1
  37. package/dist/app/{model-usage-controller.js → model/model-usage-controller.js} +1 -1
  38. package/dist/app/{model-usage-status.d.ts → model/model-usage-status.d.ts} +1 -1
  39. package/dist/app/{model-usage-status.js → model/model-usage-status.js} +1 -1
  40. package/dist/app/{menu-items-controller.d.ts → popup/menu-items-controller.d.ts} +4 -4
  41. package/dist/app/{menu-items-controller.js → popup/menu-items-controller.js} +5 -5
  42. package/dist/app/{popup-action-controller.d.ts → popup/popup-action-controller.d.ts} +4 -4
  43. package/dist/app/{popup-action-controller.js → popup/popup-action-controller.js} +2 -2
  44. package/dist/app/{popup-menu-controller.d.ts → popup/popup-menu-controller.d.ts} +4 -4
  45. package/dist/app/{popup-menu-controller.js → popup/popup-menu-controller.js} +7 -7
  46. package/dist/app/{conversation-entry-renderer.d.ts → rendering/conversation-entry-renderer.d.ts} +3 -3
  47. package/dist/app/{conversation-entry-renderer.js → rendering/conversation-entry-renderer.js} +3 -3
  48. package/dist/app/{conversation-shell-renderer.d.ts → rendering/conversation-shell-renderer.d.ts} +1 -1
  49. package/dist/app/{conversation-shell-renderer.js → rendering/conversation-shell-renderer.js} +1 -1
  50. package/dist/app/{conversation-tool-renderer.d.ts → rendering/conversation-tool-renderer.d.ts} +3 -3
  51. package/dist/app/{conversation-tool-renderer.js → rendering/conversation-tool-renderer.js} +7 -7
  52. package/dist/app/{conversation-viewport.d.ts → rendering/conversation-viewport.d.ts} +3 -3
  53. package/dist/app/{dcp-stats.js → rendering/dcp-stats.js} +1 -1
  54. package/dist/app/{editor-layout-renderer.d.ts → rendering/editor-layout-renderer.d.ts} +3 -3
  55. package/dist/app/{editor-layout-renderer.js → rendering/editor-layout-renderer.js} +2 -2
  56. package/dist/app/{editor-panels.d.ts → rendering/editor-panels.d.ts} +2 -2
  57. package/dist/app/{editor-panels.js → rendering/editor-panels.js} +4 -4
  58. package/dist/app/{message-content.d.ts → rendering/message-content.d.ts} +1 -1
  59. package/dist/app/{message-content.js → rendering/message-content.js} +1 -1
  60. package/dist/app/{render-controller.d.ts → rendering/render-controller.d.ts} +6 -6
  61. package/dist/app/{render-controller.js → rendering/render-controller.js} +5 -5
  62. package/dist/app/{render-text.d.ts → rendering/render-text.d.ts} +2 -2
  63. package/dist/app/{render-text.js → rendering/render-text.js} +3 -3
  64. package/dist/app/{status-line-renderer.d.ts → rendering/status-line-renderer.d.ts} +4 -4
  65. package/dist/app/{status-line-renderer.js → rendering/status-line-renderer.js} +4 -4
  66. package/dist/app/{tab-line-renderer.d.ts → rendering/tab-line-renderer.d.ts} +3 -3
  67. package/dist/app/{tab-line-renderer.js → rendering/tab-line-renderer.js} +2 -2
  68. package/dist/app/{toast-controller.d.ts → rendering/toast-controller.d.ts} +1 -1
  69. package/dist/app/{toast-controller.js → rendering/toast-controller.js} +2 -2
  70. package/dist/app/{toast-renderer.d.ts → rendering/toast-renderer.d.ts} +3 -3
  71. package/dist/app/{toast-renderer.js → rendering/toast-renderer.js} +3 -3
  72. package/dist/app/{tool-block-renderer.d.ts → rendering/tool-block-renderer.d.ts} +5 -5
  73. package/dist/app/{tool-block-renderer.js → rendering/tool-block-renderer.js} +2 -2
  74. package/dist/app/runtime.js +1 -1
  75. package/dist/app/{blink-controller.js → screen/blink-controller.js} +1 -1
  76. package/dist/app/{image-click-targets.d.ts → screen/image-click-targets.d.ts} +2 -2
  77. package/dist/app/{image-opener.d.ts → screen/image-opener.d.ts} +1 -1
  78. package/dist/app/{mouse-controller.d.ts → screen/mouse-controller.d.ts} +13 -9
  79. package/dist/app/{mouse-controller.js → screen/mouse-controller.js} +56 -28
  80. package/dist/app/{screen-selection.d.ts → screen/screen-selection.d.ts} +1 -1
  81. package/dist/app/{screen-styler.d.ts → screen/screen-styler.d.ts} +2 -2
  82. package/dist/app/{screen-styler.js → screen/screen-styler.js} +4 -4
  83. package/dist/app/{scroll-controller.d.ts → screen/scroll-controller.d.ts} +3 -3
  84. package/dist/app/{scroll-controller.js → screen/scroll-controller.js} +1 -1
  85. package/dist/app/{status-controller.d.ts → screen/status-controller.d.ts} +2 -2
  86. package/dist/app/{status-controller.js → screen/status-controller.js} +1 -1
  87. package/dist/app/{queued-message-controller.d.ts → session/queued-message-controller.d.ts} +2 -2
  88. package/dist/app/{queued-message-controller.js → session/queued-message-controller.js} +2 -2
  89. package/dist/app/{request-history.js → session/request-history.js} +2 -2
  90. package/dist/app/{session-event-controller.d.ts → session/session-event-controller.d.ts} +3 -3
  91. package/dist/app/{session-event-controller.js → session/session-event-controller.js} +3 -3
  92. package/dist/app/{session-history.d.ts → session/session-history.d.ts} +1 -1
  93. package/dist/app/{session-history.js → session/session-history.js} +3 -3
  94. package/dist/app/{session-lifecycle-controller.d.ts → session/session-lifecycle-controller.d.ts} +2 -2
  95. package/dist/app/{session-lifecycle-controller.js → session/session-lifecycle-controller.js} +7 -7
  96. package/dist/app/{session-search.d.ts → session/session-search.d.ts} +1 -1
  97. package/dist/app/{session-search.js → session/session-search.js} +3 -3
  98. package/dist/app/{tabs-controller.d.ts → session/tabs-controller.d.ts} +2 -2
  99. package/dist/app/{tabs-controller.js → session/tabs-controller.js} +4 -4
  100. package/dist/app/{subagents-files.d.ts → subagents/subagents-files.d.ts} +1 -1
  101. package/dist/app/{subagents-files.js → subagents/subagents-files.js} +1 -1
  102. package/dist/app/{subagents-model.d.ts → subagents/subagents-model.d.ts} +1 -1
  103. package/dist/app/{subagents-model.js → subagents/subagents-model.js} +4 -4
  104. package/dist/app/{subagents-widget-controller.d.ts → subagents/subagents-widget-controller.d.ts} +1 -1
  105. package/dist/app/{subagents-widget-controller.js → subagents/subagents-widget-controller.js} +2 -2
  106. package/dist/app/{terminal-bell-sound-controller.js → terminal/terminal-bell-sound-controller.js} +1 -1
  107. package/dist/app/{terminal-controller.js → terminal/terminal-controller.js} +2 -2
  108. package/dist/app/{todo-model.d.ts → todo/todo-model.d.ts} +1 -1
  109. package/dist/app/{todo-model.js → todo/todo-model.js} +3 -3
  110. package/dist/app/{todo-widget-controller.d.ts → todo/todo-widget-controller.d.ts} +1 -1
  111. package/dist/app/{todo-widget-controller.js → todo/todo-widget-controller.js} +2 -2
  112. package/dist/app/types.d.ts +2 -2
  113. package/dist/app/{workspace-actions-controller.d.ts → workspace/workspace-actions-controller.d.ts} +1 -1
  114. package/dist/app/{workspace-actions-controller.js → workspace/workspace-actions-controller.js} +3 -3
  115. package/dist/main.js +2 -2
  116. package/external/pi-tools-suite/README.md +82 -50
  117. package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +4 -0
  118. package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +6 -2
  119. package/external/pi-tools-suite/src/dcp/prompts.ts +4 -0
  120. package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +272 -2
  121. package/external/pi-tools-suite/src/index.ts +1 -1
  122. package/external/pi-tools-suite/src/lsp/_shared/config.ts +38 -13
  123. package/external/pi-tools-suite/src/lsp/_shared/paths.ts +11 -1
  124. package/external/pi-tools-suite/src/lsp/async.ts +6 -1
  125. package/external/pi-tools-suite/src/lsp/child-process.ts +16 -2
  126. package/external/pi-tools-suite/src/lsp/client.ts +183 -4
  127. package/external/pi-tools-suite/src/lsp/manager.ts +44 -5
  128. package/external/pi-tools-suite/src/lsp/markdown-diagnostics.ts +157 -0
  129. package/external/pi-tools-suite/src/opencode-import/commands.ts +86 -0
  130. package/external/pi-tools-suite/src/opencode-import/importer.ts +208 -0
  131. package/external/pi-tools-suite/src/opencode-import/index.ts +25 -0
  132. package/package.json +1 -1
  133. package/external/pi-tools-suite/src/terminal-bell/index.ts +0 -339
  134. /package/dist/app/{install.d.ts → cli/install.d.ts} +0 -0
  135. /package/dist/app/{startup-checks.d.ts → cli/startup-checks.d.ts} +0 -0
  136. /package/dist/app/{startup-checks.js → cli/startup-checks.js} +0 -0
  137. /package/dist/app/{startup-info.d.ts → cli/startup-info.d.ts} +0 -0
  138. /package/dist/app/{startup-info.js → cli/startup-info.js} +0 -0
  139. /package/dist/app/{update.d.ts → cli/update.d.ts} +0 -0
  140. /package/dist/app/{update.js → cli/update.js} +0 -0
  141. /package/dist/app/{command-controller.js → commands/command-controller.js} +0 -0
  142. /package/dist/app/{command-host.js → commands/command-host.js} +0 -0
  143. /package/dist/app/{command-registry.js → commands/command-registry.js} +0 -0
  144. /package/dist/app/{command-runtime.d.ts → commands/command-runtime.d.ts} +0 -0
  145. /package/dist/app/{command-session-actions.d.ts → commands/command-session-actions.d.ts} +0 -0
  146. /package/dist/app/{shell-command.d.ts → commands/shell-command.d.ts} +0 -0
  147. /package/dist/app/{shell-command.js → commands/shell-command.js} +0 -0
  148. /package/dist/app/{extension-event-bus.d.ts → extensions/extension-event-bus.d.ts} +0 -0
  149. /package/dist/app/{extension-event-bus.js → extensions/extension-event-bus.js} +0 -0
  150. /package/dist/app/{native-modifiers.d.ts → input/native-modifiers.d.ts} +0 -0
  151. /package/dist/app/{terminal-edit-shortcuts.d.ts → input/terminal-edit-shortcuts.d.ts} +0 -0
  152. /package/dist/app/{terminal-edit-shortcuts.js → input/terminal-edit-shortcuts.js} +0 -0
  153. /package/dist/app/{model-usage-controller.d.ts → model/model-usage-controller.d.ts} +0 -0
  154. /package/dist/app/{conversation-viewport.js → rendering/conversation-viewport.js} +0 -0
  155. /package/dist/app/{dcp-stats.d.ts → rendering/dcp-stats.d.ts} +0 -0
  156. /package/dist/app/{blink-controller.d.ts → screen/blink-controller.d.ts} +0 -0
  157. /package/dist/app/{clipboard.d.ts → screen/clipboard.d.ts} +0 -0
  158. /package/dist/app/{clipboard.js → screen/clipboard.js} +0 -0
  159. /package/dist/app/{file-link-opener.d.ts → screen/file-link-opener.d.ts} +0 -0
  160. /package/dist/app/{file-link-opener.js → screen/file-link-opener.js} +0 -0
  161. /package/dist/app/{file-links.d.ts → screen/file-links.d.ts} +0 -0
  162. /package/dist/app/{file-links.js → screen/file-links.js} +0 -0
  163. /package/dist/app/{image-click-targets.js → screen/image-click-targets.js} +0 -0
  164. /package/dist/app/{image-opener.js → screen/image-opener.js} +0 -0
  165. /package/dist/app/{screen-selection.js → screen/screen-selection.js} +0 -0
  166. /package/dist/app/{request-history.d.ts → session/request-history.d.ts} +0 -0
  167. /package/dist/app/{nerd-font-controller.d.ts → terminal/nerd-font-controller.d.ts} +0 -0
  168. /package/dist/app/{nerd-font-controller.js → terminal/nerd-font-controller.js} +0 -0
  169. /package/dist/app/{terminal-bell-sound-controller.d.ts → terminal/terminal-bell-sound-controller.d.ts} +0 -0
  170. /package/dist/app/{terminal-controller.d.ts → terminal/terminal-controller.d.ts} +0 -0
  171. /package/dist/app/{terminal-output-buffer.d.ts → terminal/terminal-output-buffer.d.ts} +0 -0
  172. /package/dist/app/{terminal-output-buffer.js → terminal/terminal-output-buffer.js} +0 -0
  173. /package/dist/app/{workspace-undo.d.ts → workspace/workspace-undo.d.ts} +0 -0
  174. /package/dist/app/{workspace-undo.js → workspace/workspace-undo.js} +0 -0
@@ -5,10 +5,10 @@ export const DEFAULT_PI_TOOLS_SUITE_CONFIG_JSONC = `{
5
5
  "disabledModules": [
6
6
  // "ast-grep",
7
7
  // "async-subagents",
8
- // "terminal-bell",
9
8
  // "lsp",
10
9
  // "repo-discovery",
11
10
  // "antigravity-auth",
11
+ // "opencode-import",
12
12
  // "todo",
13
13
  // "model-tools",
14
14
  // "usage",
@@ -16,7 +16,7 @@ export const DEFAULT_PI_TOOLS_SUITE_CONFIG_JSONC = `{
16
16
  // "dcp"
17
17
  ],
18
18
 
19
- // Terminal bell notification settings.
19
+ // Renderer bundled terminal-bell notification settings.
20
20
  "terminalBell": {
21
21
  // Toggle terminal-bell attention signals across supported OSes:
22
22
  // terminal BEL, macOS notification sound, and system notifications
@@ -359,6 +359,276 @@ export const DEFAULT_PI_TOOLS_SUITE_CONFIG_JSONC = `{
359
359
  "prompt": "Commit all changes"
360
360
  }
361
361
  }
362
+ },
363
+
364
+ // LSP language servers. TypeScript/JavaScript is enabled by default;
365
+ // uncomment additional server blocks after installing their binaries.
366
+ "lsp": {
367
+ "servers": [
368
+ {
369
+ "id": "typescript",
370
+ "include": [
371
+ "**/*.ts",
372
+ "**/*.tsx",
373
+ "**/*.js",
374
+ "**/*.jsx",
375
+ "**/*.mjs"
376
+ ],
377
+ "exclude": [
378
+ "**/node_modules/**",
379
+ "**/.next/**"
380
+ ],
381
+ "rootMarkers": [
382
+ "tsconfig.json",
383
+ "package.json"
384
+ ],
385
+ "bin": "typescript-language-server",
386
+ "args": [
387
+ "--stdio"
388
+ ],
389
+ "languageIdByExtension": {
390
+ ".ts": "typescript",
391
+ ".tsx": "typescriptreact",
392
+ ".js": "javascript",
393
+ ".jsx": "javascriptreact",
394
+ ".mjs": "javascript"
395
+ }
396
+ }
397
+ // ,
398
+ // {
399
+ // "id": "python",
400
+ // "include": [
401
+ // "**/*.py",
402
+ // "**/*.pyi"
403
+ // ],
404
+ // "exclude": [
405
+ // "**/.git/**",
406
+ // "**/node_modules/**",
407
+ // "**/__pycache__/**",
408
+ // "**/.venv/**",
409
+ // "**/venv/**",
410
+ // "**/.tox/**",
411
+ // "**/.mypy_cache/**",
412
+ // "**/.ruff_cache/**"
413
+ // ],
414
+ // "rootMarkers": [
415
+ // "pyproject.toml",
416
+ // "setup.py",
417
+ // "setup.cfg",
418
+ // "requirements.txt",
419
+ // "Pipfile",
420
+ // "poetry.lock",
421
+ // ".git"
422
+ // ],
423
+ // "bin": "pylsp",
424
+ // "args": [],
425
+ // "languageIdByExtension": {
426
+ // ".py": "python",
427
+ // ".pyi": "python"
428
+ // }
429
+ // }
430
+ // ,
431
+ // {
432
+ // "id": "csharp",
433
+ // "include": [
434
+ // "**/*.cs",
435
+ // "**/*.csx"
436
+ // ],
437
+ // "exclude": [
438
+ // "**/.git/**",
439
+ // "**/node_modules/**",
440
+ // "**/bin/**",
441
+ // "**/obj/**",
442
+ // "**/.vs/**",
443
+ // "**/Library/**",
444
+ // "**/Temp/**",
445
+ // "**/Logs/**"
446
+ // ],
447
+ // "rootMarkers": [
448
+ // "*.sln",
449
+ // "*.csproj",
450
+ // "global.json",
451
+ // "Directory.Build.props",
452
+ // "Directory.Packages.props",
453
+ // "Packages/manifest.json",
454
+ // "ProjectSettings/ProjectVersion.txt",
455
+ // ".git"
456
+ // ],
457
+ // "bin": "~/.dotnet/tools/roslyn-language-server",
458
+ // "args": [
459
+ // "--stdio",
460
+ // "--autoLoadProjects",
461
+ // "--logLevel",
462
+ // "Error"
463
+ // ],
464
+ // "startupTimeoutMs": 30000,
465
+ // "diagnosticsWaitMs": 15000,
466
+ // "languageIdByExtension": {
467
+ // ".cs": "csharp",
468
+ // ".csx": "csharp"
469
+ // }
470
+ // }
471
+ // ,
472
+ // {
473
+ // "id": "gdscript",
474
+ // "include": [
475
+ // "**/*.gd",
476
+ // "**/*.gdshader",
477
+ // "**/*.gdshaderinc"
478
+ // ],
479
+ // "exclude": [
480
+ // "**/.git/**",
481
+ // "**/node_modules/**",
482
+ // "**/.godot/**",
483
+ // "**/imported/**"
484
+ // ],
485
+ // "rootMarkers": [
486
+ // "project.godot"
487
+ // ],
488
+ // "bin": "bash",
489
+ // "args": [
490
+ // "-lc",
491
+ // "port=$(python3 -c 'import socket; s=socket.socket(); s.bind((\\"127.0.0.1\\", 0)); print(s.getsockname()[1]); s.close()'); log=\\"\${TMPDIR:-/tmp}/pi-godot-lsp-\${1##*/}-\${port}.log\\"; godot --headless --editor --path \\"$1\\" --lsp-port \\"$port\\" >\\"$log\\" 2>&1 & pid=$!; cleanup(){ kill \\"$pid\\" 2>/dev/null || true; wait \\"$pid\\" 2>/dev/null || true; }; trap 'cleanup; exit 143' TERM INT HUP; trap cleanup EXIT; for i in $(seq 1 80); do nc -z 127.0.0.1 \\"$port\\" 2>/dev/null && break; if ! kill -0 \\"$pid\\" 2>/dev/null; then cat \\"$log\\" >&2; exit 1; fi; sleep 0.25; done; if ! nc -z 127.0.0.1 \\"$port\\" 2>/dev/null; then echo \\"Godot LSP did not open 127.0.0.1:$port; see $log\\" >&2; exit 1; fi; nc 127.0.0.1 \\"$port\\"; status=$?; exit $status",
492
+ // "pi-godot-lsp",
493
+ // "{root}"
494
+ // ],
495
+ // "startupTimeoutMs": 30000,
496
+ // "diagnosticsWaitMs": 6000,
497
+ // "languageIdByExtension": {
498
+ // ".gd": "gdscript",
499
+ // ".gdshader": "gdshader",
500
+ // ".gdshaderinc": "gdshader"
501
+ // }
502
+ // }
503
+ // ,
504
+ // {
505
+ // "id": "ruby",
506
+ // "include": [
507
+ // "**/*.rb",
508
+ // "**/*.rake",
509
+ // "**/Gemfile",
510
+ // "**/Rakefile",
511
+ // "**/*.gemspec"
512
+ // ],
513
+ // "exclude": [
514
+ // "**/.git/**",
515
+ // "**/node_modules/**",
516
+ // "**/vendor/bundle/**",
517
+ // "**/.bundle/**",
518
+ // "**/tmp/**",
519
+ // "**/log/**"
520
+ // ],
521
+ // "rootMarkers": [
522
+ // "Gemfile.lock",
523
+ // "*.gemspec",
524
+ // "Rakefile",
525
+ // ".ruby-version",
526
+ // ".git"
527
+ // ],
528
+ // "bin": "ruby-lsp",
529
+ // "args": [],
530
+ // "startupTimeoutMs": 60000,
531
+ // "diagnosticsWaitMs": 10000,
532
+ // "languageIdByExtension": {
533
+ // ".rb": "ruby",
534
+ // ".rake": "ruby",
535
+ // ".gemspec": "ruby"
536
+ // }
537
+ // }
538
+ // ,
539
+ // {
540
+ // "id": "rust",
541
+ // "include": [
542
+ // "**/*.rs"
543
+ // ],
544
+ // "exclude": [
545
+ // "**/.git/**",
546
+ // "**/node_modules/**",
547
+ // "**/target/**"
548
+ // ],
549
+ // "rootMarkers": [
550
+ // "Cargo.toml",
551
+ // "rust-project.json",
552
+ // ".git"
553
+ // ],
554
+ // "bin": "rust-analyzer",
555
+ // "args": [],
556
+ // "startupTimeoutMs": 20000,
557
+ // "diagnosticsWaitMs": 8000,
558
+ // "languageIdByExtension": {
559
+ // ".rs": "rust"
560
+ // }
561
+ // }
562
+ // ,
563
+ // {
564
+ // "id": "markdown",
565
+ // "include": [
566
+ // "**/*.md",
567
+ // "**/*.markdown",
568
+ // "**/*.mdown",
569
+ // "**/*.mkd",
570
+ // "**/*.mmd",
571
+ // "**/*.mermaid"
572
+ // ],
573
+ // "exclude": [
574
+ // "**/.git/**",
575
+ // "**/node_modules/**"
576
+ // ],
577
+ // "rootMarkers": [
578
+ // ".git",
579
+ // "package.json",
580
+ // "README.md"
581
+ // ],
582
+ // "bin": "vscode-markdown-language-server",
583
+ // "args": [
584
+ // "--stdio"
585
+ // ],
586
+ // "startupTimeoutMs": 15000,
587
+ // "diagnosticsWaitMs": 5000,
588
+ // "languageIdByExtension": {
589
+ // ".md": "markdown",
590
+ // ".markdown": "markdown",
591
+ // ".mdown": "markdown",
592
+ // ".mkd": "markdown",
593
+ // ".mmd": "markdown",
594
+ // ".mermaid": "markdown"
595
+ // },
596
+ // "initializationOptions": {
597
+ // "markdownFileExtensions": [
598
+ // "md",
599
+ // "markdown",
600
+ // "mdown",
601
+ // "mkd",
602
+ // "mmd",
603
+ // "mermaid"
604
+ // ]
605
+ // },
606
+ // "settings": {
607
+ // "markdown": {
608
+ // "validate": {
609
+ // "enabled": true,
610
+ // "referenceLinks": {
611
+ // "enabled": "error"
612
+ // },
613
+ // "fragmentLinks": {
614
+ // "enabled": "error"
615
+ // },
616
+ // "fileLinks": {
617
+ // "enabled": "error",
618
+ // "markdownFragmentLinks": "inherit"
619
+ // },
620
+ // "unusedLinkDefinitions": {
621
+ // "enabled": "hint"
622
+ // },
623
+ // "duplicateLinkDefinitions": {
624
+ // "enabled": "warning"
625
+ // },
626
+ // "ignoredLinks": []
627
+ // }
628
+ // }
629
+ // }
630
+ // }
631
+ ]
362
632
  }
363
633
  }
364
634
  `;
@@ -12,10 +12,10 @@ type ExtensionModule = {
12
12
  const MODULES: Array<{ name: string; load: () => Promise<ExtensionModule> }> = [
13
13
  { name: "ast-grep", load: () => import("./ast-grep/index") },
14
14
  { name: "async-subagents", load: () => import("./async-subagents/index") },
15
- { name: "terminal-bell", load: () => import("./terminal-bell/index") },
16
15
  { name: "lsp", load: () => import("./lsp/index") },
17
16
  { name: "repo-discovery", load: () => import("./repo-discovery/index") },
18
17
  { name: "antigravity-auth", load: () => import("./antigravity-auth/index") },
18
+ { name: "opencode-import", load: () => import("./opencode-import/index") },
19
19
  { name: "todo", load: () => import("./todo/index") },
20
20
  { name: "model-tools", load: () => import("./model-tools/index") },
21
21
  { name: "usage", load: () => import("./usage/index") },
@@ -1,12 +1,19 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
4
+ import { parse as parseJsonc } from "jsonc-parser";
5
+ import { getPiToolsSuiteUserConfigPath } from "../../config";
4
6
  import { findUp } from "./paths";
5
7
  import { askProjectConfigTrust, sha256 } from "./trust";
6
8
  import type { ConfigLayer, LoadedConfig, LspConfigFile, LspServerConfig, MatchableConfig } from "./types";
7
9
 
8
- function defaultAgentDir(): string {
9
- return process.env.PI_AGENT_DIR ?? path.join(process.env.HOME ?? "", ".pi", "agent");
10
+ function getPiConfigDir(): string | undefined {
11
+ const configured = process.env.PI_CONFIG_DIR;
12
+ return configured && configured.trim() !== "" ? configured : undefined;
13
+ }
14
+
15
+ function findProjectSuiteConfig(startDir: string): string | undefined {
16
+ return findUp(startDir, path.join(".pi", "pi-tools-suite.jsonc"));
10
17
  }
11
18
 
12
19
  function asObject(value: unknown): Record<string, unknown> | undefined {
@@ -78,9 +85,16 @@ function parseLspItems(parsed: unknown): LspServerConfig[] {
78
85
  return out;
79
86
  }
80
87
 
81
- async function readJsonLayer<TItem extends MatchableConfig>(options: {
88
+ function extractLspConfig(parsed: unknown): unknown {
89
+ const root = asObject(parsed);
90
+ if (!root) return undefined;
91
+ return root.lsp;
92
+ }
93
+
94
+ async function readJsoncLayer<TItem extends MatchableConfig>(options: {
82
95
  scope: "global" | "project";
83
96
  filePath: string;
97
+ selectConfig?: (parsed: unknown) => unknown;
84
98
  parseItems: (parsed: unknown) => TItem[];
85
99
  }): Promise<ConfigLayer<TItem> | undefined> {
86
100
  let raw: string;
@@ -91,14 +105,19 @@ async function readJsonLayer<TItem extends MatchableConfig>(options: {
91
105
  throw error;
92
106
  }
93
107
 
94
- const parsed = JSON.parse(raw) as unknown;
108
+ const parsed = parseJsonc(raw) as unknown;
109
+ const selected = options.selectConfig ? options.selectConfig(parsed) : parsed;
110
+ if (selected === undefined) return undefined;
111
+ const items = options.parseItems(selected);
112
+ if (items.length === 0) return undefined;
113
+
95
114
  return {
96
115
  scope: options.scope,
97
116
  path: options.filePath,
98
117
  dir: path.dirname(options.filePath),
99
118
  raw,
100
119
  hash: sha256(raw),
101
- items: options.parseItems(parsed),
120
+ items,
102
121
  };
103
122
  }
104
123
 
@@ -123,19 +142,25 @@ function binariesForLsp(items: LspServerConfig[]): string[] {
123
142
  export async function loadLspConfig(ctx: ExtensionContext): Promise<LoadedConfig<LspServerConfig>> {
124
143
  const warnings: string[] = [];
125
144
  const layers: ConfigLayer<LspServerConfig>[] = [];
126
- const globalPath = path.join(defaultAgentDir(), "lsp.json");
145
+ const piConfigDir = getPiConfigDir();
146
+ const globalPaths = [
147
+ getPiToolsSuiteUserConfigPath(process.env.HOME),
148
+ piConfigDir ? path.join(piConfigDir, "pi-tools-suite.jsonc") : undefined,
149
+ ].filter((item): item is string => typeof item === "string");
127
150
 
128
- try {
129
- const globalLayer = await readJsonLayer({ scope: "global", filePath: globalPath, parseItems: parseLspItems });
130
- if (globalLayer) layers.push(globalLayer);
131
- } catch (error) {
132
- warnings.push(`Failed to load global lsp config: ${(error as Error).message}`);
151
+ for (const globalPath of globalPaths) {
152
+ try {
153
+ const globalLayer = await readJsoncLayer({ scope: "global", filePath: globalPath, selectConfig: extractLspConfig, parseItems: parseLspItems });
154
+ if (globalLayer) layers.push(globalLayer);
155
+ } catch (error) {
156
+ warnings.push(`Failed to load global lsp config ${globalPath}: ${(error as Error).message}`);
157
+ }
133
158
  }
134
159
 
135
- const projectPath = findUp(ctx.cwd, path.join(".pi", "lsp.json"));
160
+ const projectPath = findProjectSuiteConfig(ctx.cwd);
136
161
  if (projectPath) {
137
162
  try {
138
- const projectLayer = await readJsonLayer({ scope: "project", filePath: projectPath, parseItems: parseLspItems });
163
+ const projectLayer = await readJsoncLayer({ scope: "project", filePath: projectPath, selectConfig: extractLspConfig, parseItems: parseLspItems });
139
164
  if (projectLayer) {
140
165
  const decision = await askProjectConfigTrust({
141
166
  ctx,
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import { fileURLToPath, pathToFileURL } from "node:url";
4
4
  import type { CommandConfig, PathPlaceholders, ResolvedCommand } from "./types";
5
5
  import { applyTemplate, applyTemplateArray, applyTemplateRecord } from "./template";
6
+ import { matchesGlob } from "./glob";
6
7
 
7
8
  export function expandHome(input: string): string {
8
9
  if (input === "~") return process.env.HOME ?? input;
@@ -26,7 +27,16 @@ export function isSubPathOrSame(parent: string, child: string): boolean {
26
27
  }
27
28
 
28
29
  export function markerExists(candidateDir: string, marker: string): boolean {
29
- return fs.existsSync(path.resolve(candidateDir, marker));
30
+ if (!/[?*[]/.test(marker)) return fs.existsSync(path.resolve(candidateDir, marker));
31
+
32
+ const markerDir = path.dirname(marker);
33
+ const markerPattern = path.basename(marker);
34
+ const absoluteMarkerDir = path.resolve(candidateDir, markerDir === "." ? "" : markerDir);
35
+ try {
36
+ return fs.readdirSync(absoluteMarkerDir).some((entry) => matchesGlob(markerPattern, entry));
37
+ } catch {
38
+ return false;
39
+ }
30
40
  }
31
41
 
32
42
  export function findProjectRoot(filePath: string, rootMarkers: string[] | undefined, fallbackRoot: string): string | undefined {
@@ -18,12 +18,17 @@ export function delay(ms: number, signal?: AbortSignal): Promise<void> {
18
18
  });
19
19
  }
20
20
 
21
- export async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T> {
21
+ export async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string, signal?: AbortSignal): Promise<T> {
22
+ if (signal?.aborted) throw new Error("aborted");
22
23
  let timeout: NodeJS.Timeout | undefined;
24
+ let abort: (() => void) | undefined;
23
25
  const timeoutPromise = new Promise<never>((_resolve, reject) => {
24
26
  timeout = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
27
+ abort = () => reject(new Error("aborted"));
28
+ signal?.addEventListener("abort", abort, { once: true });
25
29
  });
26
30
  return Promise.race([promise, timeoutPromise]).finally(() => {
27
31
  if (timeout) clearTimeout(timeout);
32
+ if (abort) signal?.removeEventListener("abort", abort);
28
33
  });
29
34
  }
@@ -10,6 +10,7 @@ function canWriteToChild(child: ChildProcessWithoutNullStreams): boolean {
10
10
  }
11
11
 
12
12
  export function killChild(child: ChildProcessWithoutNullStreams, signal: NodeJS.Signals): boolean {
13
+ let signaled = false;
13
14
  try {
14
15
  if (process.platform === "win32" && child.pid) {
15
16
  const result = spawnSync("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
@@ -19,9 +20,22 @@ export function killChild(child: ChildProcessWithoutNullStreams, signal: NodeJS.
19
20
  });
20
21
  if (!result.error && result.status === 0) return true;
21
22
  }
22
- return child.kill(signal);
23
+
24
+ if (child.pid) {
25
+ try {
26
+ // LSP clients are spawned in their own process group on POSIX. Kill the
27
+ // whole group so wrapper scripts also lose children such as Godot and nc.
28
+ process.kill(-child.pid, signal);
29
+ signaled = true;
30
+ } catch {
31
+ // Fall back to the direct child below. The process may not be detached
32
+ // or may have already exited.
33
+ }
34
+ }
35
+
36
+ return child.kill(signal) || signaled;
23
37
  } catch {
24
- return false;
38
+ return signaled;
25
39
  }
26
40
  }
27
41