gsd-pi 2.8.2 → 2.9.0

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 (193) hide show
  1. package/README.md +2 -1
  2. package/dist/cli.js +5 -0
  3. package/dist/loader.js +1 -1
  4. package/dist/update-check.d.ts +24 -0
  5. package/dist/update-check.js +93 -0
  6. package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.d.ts +4 -2
  7. package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  8. package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  9. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.d.ts +46 -0
  10. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -0
  11. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.js +758 -0
  12. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.js.map +1 -0
  13. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.d.ts +23 -0
  14. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -0
  15. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.js +267 -0
  16. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.js.map +1 -0
  17. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.d.ts +17 -0
  18. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -0
  19. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.js +101 -0
  20. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.js.map +1 -0
  21. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.d.ts +15 -0
  22. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.d.ts.map +1 -0
  23. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.js +46 -0
  24. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.js.map +1 -0
  25. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.d.ts +35 -0
  26. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -0
  27. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.js +709 -0
  28. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.js.map +1 -0
  29. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts +2 -0
  30. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts.map +1 -0
  31. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +308 -0
  32. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -0
  33. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.d.ts +34 -0
  34. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -0
  35. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.js +136 -0
  36. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -0
  37. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.d.ts +262 -0
  38. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -0
  39. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.js +64 -0
  40. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.js.map +1 -0
  41. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.d.ts +50 -0
  42. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -0
  43. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.js +574 -0
  44. package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.js.map +1 -0
  45. package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  46. package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.js +1 -0
  47. package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  48. package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.d.ts +13 -0
  49. package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  50. package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.js +4 -0
  51. package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  52. package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +10 -1
  53. package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  54. package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +2 -2
  55. package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  56. package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  57. package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  58. package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.js +80 -1
  59. package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  60. package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  61. package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  62. package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +5 -0
  63. package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  64. package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  65. package/node_modules/@gsd/pi-coding-agent/src/core/extensions/types.ts +4 -2
  66. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/client.ts +880 -0
  67. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/config.ts +325 -0
  68. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/defaults.json +456 -0
  69. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/edits.ts +109 -0
  70. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/helpers.ts +54 -0
  71. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/index.ts +943 -0
  72. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +407 -0
  73. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lsp.md +33 -0
  74. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lspmux.ts +199 -0
  75. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/types.ts +421 -0
  76. package/node_modules/@gsd/pi-coding-agent/src/core/lsp/utils.ts +682 -0
  77. package/node_modules/@gsd/pi-coding-agent/src/core/slash-commands.ts +1 -0
  78. package/node_modules/@gsd/pi-coding-agent/src/core/tools/index.ts +10 -0
  79. package/node_modules/@gsd/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +2 -2
  80. package/node_modules/@gsd/pi-coding-agent/src/modes/interactive/interactive-mode.ts +94 -2
  81. package/node_modules/@gsd/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
  82. package/node_modules/@gsd/pi-coding-agent/src/modes/rpc/rpc-types.ts +2 -1
  83. package/package.json +1 -1
  84. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +4 -2
  85. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  86. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  87. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +46 -0
  88. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -0
  89. package/packages/pi-coding-agent/dist/core/lsp/client.js +758 -0
  90. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -0
  91. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +23 -0
  92. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -0
  93. package/packages/pi-coding-agent/dist/core/lsp/config.js +267 -0
  94. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -0
  95. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts +17 -0
  96. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -0
  97. package/packages/pi-coding-agent/dist/core/lsp/edits.js +101 -0
  98. package/packages/pi-coding-agent/dist/core/lsp/edits.js.map +1 -0
  99. package/packages/pi-coding-agent/dist/core/lsp/helpers.d.ts +15 -0
  100. package/packages/pi-coding-agent/dist/core/lsp/helpers.d.ts.map +1 -0
  101. package/packages/pi-coding-agent/dist/core/lsp/helpers.js +46 -0
  102. package/packages/pi-coding-agent/dist/core/lsp/helpers.js.map +1 -0
  103. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts +35 -0
  104. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -0
  105. package/packages/pi-coding-agent/dist/core/lsp/index.js +709 -0
  106. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -0
  107. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts +2 -0
  108. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts.map +1 -0
  109. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +308 -0
  110. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -0
  111. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts +34 -0
  112. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -0
  113. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +136 -0
  114. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -0
  115. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +262 -0
  116. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -0
  117. package/packages/pi-coding-agent/dist/core/lsp/types.js +64 -0
  118. package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -0
  119. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +50 -0
  120. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -0
  121. package/packages/pi-coding-agent/dist/core/lsp/utils.js +574 -0
  122. package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -0
  123. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  124. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  125. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  126. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +13 -0
  127. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  128. package/packages/pi-coding-agent/dist/core/tools/index.js +4 -0
  129. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  130. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +10 -1
  131. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  132. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +2 -2
  133. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  134. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  135. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  136. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +80 -1
  137. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  138. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  139. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  140. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +5 -0
  141. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  143. package/packages/pi-coding-agent/src/core/extensions/types.ts +4 -2
  144. package/packages/pi-coding-agent/src/core/lsp/client.ts +880 -0
  145. package/packages/pi-coding-agent/src/core/lsp/config.ts +325 -0
  146. package/packages/pi-coding-agent/src/core/lsp/defaults.json +456 -0
  147. package/packages/pi-coding-agent/src/core/lsp/edits.ts +109 -0
  148. package/packages/pi-coding-agent/src/core/lsp/helpers.ts +54 -0
  149. package/packages/pi-coding-agent/src/core/lsp/index.ts +943 -0
  150. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +407 -0
  151. package/packages/pi-coding-agent/src/core/lsp/lsp.md +33 -0
  152. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +199 -0
  153. package/packages/pi-coding-agent/src/core/lsp/types.ts +421 -0
  154. package/packages/pi-coding-agent/src/core/lsp/utils.ts +682 -0
  155. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  156. package/packages/pi-coding-agent/src/core/tools/index.ts +10 -0
  157. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +2 -2
  158. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +94 -2
  159. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
  160. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +2 -1
  161. package/src/resources/extensions/ask-user-questions.ts +42 -2
  162. package/src/resources/extensions/bg-shell/index.ts +34 -37
  163. package/src/resources/extensions/browser-tools/core.d.ts +205 -0
  164. package/src/resources/extensions/browser-tools/index.ts +2 -2
  165. package/src/resources/extensions/browser-tools/refs.ts +1 -1
  166. package/src/resources/extensions/browser-tools/tools/session.ts +1 -1
  167. package/src/resources/extensions/context7/index.ts +2 -2
  168. package/src/resources/extensions/get-secrets-from-user.ts +3 -2
  169. package/src/resources/extensions/google-search/index.ts +1 -1
  170. package/src/resources/extensions/gsd/auto.ts +126 -12
  171. package/src/resources/extensions/gsd/commands.ts +218 -3
  172. package/src/resources/extensions/gsd/doctor.ts +1 -1
  173. package/src/resources/extensions/gsd/git-service.ts +163 -13
  174. package/src/resources/extensions/gsd/guided-flow.ts +19 -9
  175. package/src/resources/extensions/gsd/index.ts +17 -7
  176. package/src/resources/extensions/gsd/preferences.ts +1 -1
  177. package/src/resources/extensions/gsd/tests/git-service.test.ts +226 -0
  178. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +2 -2
  179. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +1 -1
  180. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +10 -10
  181. package/src/resources/extensions/gsd/tests/next-milestone-id.test.ts +87 -0
  182. package/src/resources/extensions/gsd/tests/worktree.test.ts +352 -0
  183. package/src/resources/extensions/gsd/types.ts +1 -0
  184. package/src/resources/extensions/gsd/worktree.ts +20 -1
  185. package/src/resources/extensions/mac-tools/index.ts +1 -1
  186. package/src/resources/extensions/search-the-web/command-search-provider.ts +1 -1
  187. package/src/resources/extensions/search-the-web/format.ts +1 -1
  188. package/src/resources/extensions/search-the-web/index.ts +5 -5
  189. package/src/resources/extensions/search-the-web/native-search.ts +5 -6
  190. package/src/resources/extensions/search-the-web/tool-fetch-page.ts +7 -7
  191. package/src/resources/extensions/search-the-web/tool-llm-context.ts +11 -11
  192. package/src/resources/extensions/search-the-web/tool-search.ts +10 -10
  193. package/src/resources/extensions/shared/interview-ui.ts +2 -2
@@ -0,0 +1,456 @@
1
+ {
2
+ "rust-analyzer": {
3
+ "command": "rust-analyzer",
4
+ "args": [],
5
+ "fileTypes": [".rs"],
6
+ "rootMarkers": ["Cargo.toml", "rust-analyzer.toml"],
7
+ "initOptions": {},
8
+ "settings": {},
9
+ "capabilities": {
10
+ "flycheck": true,
11
+ "ssr": true,
12
+ "expandMacro": true,
13
+ "runnables": true,
14
+ "relatedTests": true
15
+ }
16
+ },
17
+ "clangd": {
18
+ "command": "clangd",
19
+ "args": ["--background-index", "--clang-tidy", "--header-insertion=iwyu"],
20
+ "fileTypes": [".c", ".cpp", ".cc", ".cxx", ".h", ".hpp", ".hxx", ".m", ".mm"],
21
+ "rootMarkers": ["compile_commands.json", "CMakeLists.txt", ".clangd", ".clang-format", "Makefile"]
22
+ },
23
+ "zls": {
24
+ "command": "zls",
25
+ "args": [],
26
+ "fileTypes": [".zig"],
27
+ "rootMarkers": ["build.zig", "build.zig.zon", "zls.json"]
28
+ },
29
+ "gopls": {
30
+ "command": "gopls",
31
+ "args": ["serve"],
32
+ "fileTypes": [".go", ".mod", ".sum"],
33
+ "rootMarkers": ["go.mod", "go.work", "go.sum"],
34
+ "settings": {
35
+ "gopls": {
36
+ "analyses": { "unusedparams": true, "shadow": true },
37
+ "staticcheck": true,
38
+ "gofumpt": true
39
+ }
40
+ }
41
+ },
42
+ "typescript-language-server": {
43
+ "command": "typescript-language-server",
44
+ "args": ["--stdio"],
45
+ "fileTypes": [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
46
+ "rootMarkers": ["package.json", "tsconfig.json", "jsconfig.json"],
47
+ "initOptions": {
48
+ "hostInfo": "gsd-coding-agent",
49
+ "preferences": {
50
+ "includeInlayParameterNameHints": "all",
51
+ "includeInlayVariableTypeHints": true,
52
+ "includeInlayFunctionParameterTypeHints": true
53
+ }
54
+ }
55
+ },
56
+ "biome": {
57
+ "command": "biome",
58
+ "args": ["lsp-proxy"],
59
+ "fileTypes": [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".json", ".jsonc"],
60
+ "rootMarkers": ["biome.json", "biome.jsonc"],
61
+ "isLinter": true
62
+ },
63
+ "eslint": {
64
+ "command": "vscode-eslint-language-server",
65
+ "args": ["--stdio"],
66
+ "fileTypes": [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".vue", ".svelte"],
67
+ "rootMarkers": [
68
+ ".eslintrc",
69
+ ".eslintrc.js",
70
+ ".eslintrc.json",
71
+ ".eslintrc.yml",
72
+ "eslint.config.js",
73
+ "eslint.config.mjs"
74
+ ],
75
+ "isLinter": true,
76
+ "settings": {
77
+ "validate": "on",
78
+ "run": "onType"
79
+ }
80
+ },
81
+ "denols": {
82
+ "command": "deno",
83
+ "args": ["lsp"],
84
+ "fileTypes": [".ts", ".tsx", ".js", ".jsx"],
85
+ "rootMarkers": ["deno.json", "deno.jsonc", "deno.lock"],
86
+ "initOptions": {
87
+ "enable": true,
88
+ "lint": true,
89
+ "unstable": true
90
+ }
91
+ },
92
+ "vscode-html-language-server": {
93
+ "command": "vscode-html-language-server",
94
+ "args": ["--stdio"],
95
+ "fileTypes": [".html", ".htm"],
96
+ "rootMarkers": ["package.json", ".git"],
97
+ "initOptions": {
98
+ "provideFormatter": true
99
+ }
100
+ },
101
+ "vscode-css-language-server": {
102
+ "command": "vscode-css-language-server",
103
+ "args": ["--stdio"],
104
+ "fileTypes": [".css", ".scss", ".sass", ".less"],
105
+ "rootMarkers": ["package.json", ".git"],
106
+ "initOptions": {
107
+ "provideFormatter": true
108
+ }
109
+ },
110
+ "vscode-json-language-server": {
111
+ "command": "vscode-json-language-server",
112
+ "args": ["--stdio"],
113
+ "fileTypes": [".json", ".jsonc"],
114
+ "rootMarkers": ["package.json", ".git"],
115
+ "initOptions": {
116
+ "provideFormatter": true
117
+ }
118
+ },
119
+ "tailwindcss": {
120
+ "command": "tailwindcss-language-server",
121
+ "args": ["--stdio"],
122
+ "fileTypes": [".html", ".css", ".scss", ".js", ".jsx", ".ts", ".tsx", ".vue", ".svelte"],
123
+ "rootMarkers": ["tailwind.config.js", "tailwind.config.ts", "tailwind.config.mjs", "tailwind.config.cjs"]
124
+ },
125
+ "svelte": {
126
+ "command": "svelteserver",
127
+ "args": ["--stdio"],
128
+ "fileTypes": [".svelte"],
129
+ "rootMarkers": ["svelte.config.js", "svelte.config.mjs", "package.json"]
130
+ },
131
+ "vue-language-server": {
132
+ "command": "vue-language-server",
133
+ "args": ["--stdio"],
134
+ "fileTypes": [".vue"],
135
+ "rootMarkers": ["vue.config.js", "nuxt.config.js", "nuxt.config.ts", "package.json"]
136
+ },
137
+ "astro": {
138
+ "command": "astro-ls",
139
+ "args": ["--stdio"],
140
+ "fileTypes": [".astro"],
141
+ "rootMarkers": ["astro.config.mjs", "astro.config.js", "astro.config.ts"]
142
+ },
143
+ "pyright": {
144
+ "command": "pyright-langserver",
145
+ "args": ["--stdio"],
146
+ "fileTypes": [".py", ".pyi"],
147
+ "rootMarkers": ["pyproject.toml", "pyrightconfig.json", "setup.py", "setup.cfg", "requirements.txt", "Pipfile"],
148
+ "settings": {
149
+ "python": {
150
+ "analysis": {
151
+ "autoSearchPaths": true,
152
+ "diagnosticMode": "openFilesOnly",
153
+ "useLibraryCodeForTypes": true
154
+ }
155
+ }
156
+ }
157
+ },
158
+ "basedpyright": {
159
+ "command": "basedpyright-langserver",
160
+ "args": ["--stdio"],
161
+ "fileTypes": [".py", ".pyi"],
162
+ "rootMarkers": ["pyproject.toml", "pyrightconfig.json", "setup.py", "requirements.txt"],
163
+ "settings": {
164
+ "basedpyright": {
165
+ "analysis": {
166
+ "autoSearchPaths": true,
167
+ "diagnosticMode": "openFilesOnly",
168
+ "useLibraryCodeForTypes": true
169
+ }
170
+ }
171
+ }
172
+ },
173
+ "pylsp": {
174
+ "command": "pylsp",
175
+ "args": [],
176
+ "fileTypes": [".py"],
177
+ "rootMarkers": ["pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile"]
178
+ },
179
+ "ruff": {
180
+ "command": "ruff",
181
+ "args": ["server"],
182
+ "fileTypes": [".py", ".pyi"],
183
+ "rootMarkers": ["pyproject.toml", "ruff.toml", ".ruff.toml"],
184
+ "isLinter": true
185
+ },
186
+ "jdtls": {
187
+ "command": "jdtls",
188
+ "args": [],
189
+ "fileTypes": [".java"],
190
+ "rootMarkers": ["pom.xml", "build.gradle", "build.gradle.kts", "settings.gradle", ".project"]
191
+ },
192
+ "kotlin-language-server": {
193
+ "command": "kotlin-language-server",
194
+ "args": [],
195
+ "fileTypes": [".kt", ".kts"],
196
+ "rootMarkers": ["build.gradle", "build.gradle.kts", "pom.xml", "settings.gradle", "settings.gradle.kts"]
197
+ },
198
+ "metals": {
199
+ "command": "metals",
200
+ "args": [],
201
+ "fileTypes": [".scala", ".sbt", ".sc"],
202
+ "rootMarkers": ["build.sbt", "build.sc", "build.gradle", "pom.xml"],
203
+ "initOptions": {
204
+ "statusBarProvider": "show-message",
205
+ "isHttpEnabled": true
206
+ }
207
+ },
208
+ "hls": {
209
+ "command": "haskell-language-server-wrapper",
210
+ "args": ["--lsp"],
211
+ "fileTypes": [".hs", ".lhs"],
212
+ "rootMarkers": ["stack.yaml", "cabal.project", "hie.yaml", "package.yaml", "*.cabal"],
213
+ "settings": {
214
+ "haskell": {
215
+ "formattingProvider": "ormolu",
216
+ "checkProject": true
217
+ }
218
+ }
219
+ },
220
+ "ocamllsp": {
221
+ "command": "ocamllsp",
222
+ "args": [],
223
+ "fileTypes": [".ml", ".mli", ".mll", ".mly"],
224
+ "rootMarkers": ["dune-project", "dune-workspace", "*.opam", ".ocamlformat"]
225
+ },
226
+ "elixirls": {
227
+ "command": "elixir-ls",
228
+ "args": [],
229
+ "fileTypes": [".ex", ".exs", ".heex", ".eex"],
230
+ "rootMarkers": ["mix.exs", "mix.lock"],
231
+ "settings": {
232
+ "elixirLS": {
233
+ "dialyzerEnabled": true,
234
+ "fetchDeps": false
235
+ }
236
+ }
237
+ },
238
+ "erlangls": {
239
+ "command": "erlang_ls",
240
+ "args": [],
241
+ "fileTypes": [".erl", ".hrl"],
242
+ "rootMarkers": ["rebar.config", "erlang.mk", "rebar.lock"]
243
+ },
244
+ "gleam": {
245
+ "command": "gleam",
246
+ "args": ["lsp"],
247
+ "fileTypes": [".gleam"],
248
+ "rootMarkers": ["gleam.toml"]
249
+ },
250
+ "solargraph": {
251
+ "command": "solargraph",
252
+ "args": ["stdio"],
253
+ "fileTypes": [".rb", ".rake", ".gemspec"],
254
+ "rootMarkers": ["Gemfile", ".solargraph.yml", "Rakefile"],
255
+ "initOptions": {
256
+ "formatting": true
257
+ },
258
+ "settings": {
259
+ "solargraph": {
260
+ "diagnostics": true,
261
+ "completion": true,
262
+ "hover": true,
263
+ "formatting": true,
264
+ "references": true,
265
+ "rename": true,
266
+ "symbols": true
267
+ }
268
+ }
269
+ },
270
+ "ruby-lsp": {
271
+ "command": "ruby-lsp",
272
+ "args": [],
273
+ "fileTypes": [".rb", ".rake", ".gemspec", ".erb"],
274
+ "rootMarkers": ["Gemfile", ".ruby-version", ".ruby-gemset"],
275
+ "initOptions": {
276
+ "formatter": "auto"
277
+ }
278
+ },
279
+ "rubocop": {
280
+ "command": "rubocop",
281
+ "args": ["--lsp"],
282
+ "fileTypes": [".rb", ".rake"],
283
+ "rootMarkers": [".rubocop.yml", "Gemfile"],
284
+ "isLinter": true
285
+ },
286
+ "bashls": {
287
+ "command": "bash-language-server",
288
+ "args": ["start"],
289
+ "fileTypes": [".sh", ".bash", ".zsh"],
290
+ "rootMarkers": [".git"],
291
+ "settings": {
292
+ "bashIde": {
293
+ "globPattern": "*@(.sh|.inc|.bash|.command)"
294
+ }
295
+ }
296
+ },
297
+ "lua-language-server": {
298
+ "command": "lua-language-server",
299
+ "args": [],
300
+ "fileTypes": [".lua"],
301
+ "rootMarkers": [".luarc.json", ".luarc.jsonc", ".luacheckrc", ".stylua.toml", "stylua.toml"],
302
+ "settings": {
303
+ "Lua": {
304
+ "runtime": { "version": "LuaJIT" },
305
+ "diagnostics": { "globals": ["vim"] },
306
+ "workspace": { "checkThirdParty": false },
307
+ "telemetry": { "enable": false }
308
+ }
309
+ }
310
+ },
311
+ "intelephense": {
312
+ "command": "intelephense",
313
+ "args": ["--stdio"],
314
+ "fileTypes": [".php", ".phtml"],
315
+ "rootMarkers": ["composer.json", "composer.lock", ".git"]
316
+ },
317
+ "phpactor": {
318
+ "command": "phpactor",
319
+ "args": ["language-server"],
320
+ "fileTypes": [".php"],
321
+ "rootMarkers": ["composer.json", ".phpactor.json", ".phpactor.yml"]
322
+ },
323
+ "omnisharp": {
324
+ "command": "omnisharp",
325
+ "args": ["-z", "--hostPID", "$PID", "--encoding", "utf-8", "--languageserver"],
326
+ "fileTypes": [".cs", ".csx"],
327
+ "rootMarkers": ["*.sln", "*.csproj", "omnisharp.json", ".git"],
328
+ "settings": {
329
+ "FormattingOptions": { "EnableEditorConfigSupport": true },
330
+ "RoslynExtensionsOptions": { "EnableAnalyzersSupport": true }
331
+ }
332
+ },
333
+ "yamlls": {
334
+ "command": "yaml-language-server",
335
+ "args": ["--stdio"],
336
+ "fileTypes": [".yaml", ".yml"],
337
+ "rootMarkers": [".git"],
338
+ "settings": {
339
+ "yaml": {
340
+ "validate": true,
341
+ "format": { "enable": true },
342
+ "hover": true,
343
+ "completion": true
344
+ },
345
+ "redhat": { "telemetry": { "enabled": false } }
346
+ }
347
+ },
348
+ "taplo": {
349
+ "command": "taplo",
350
+ "args": ["lsp", "stdio"],
351
+ "fileTypes": [".toml"],
352
+ "rootMarkers": [".taplo.toml", "taplo.toml", ".git"]
353
+ },
354
+ "terraformls": {
355
+ "command": "terraform-ls",
356
+ "args": ["serve"],
357
+ "fileTypes": [".tf", ".tfvars"],
358
+ "rootMarkers": [".terraform", "terraform.tfstate", "*.tf"]
359
+ },
360
+ "dockerls": {
361
+ "command": "docker-langserver",
362
+ "args": ["--stdio"],
363
+ "fileTypes": [".dockerfile", "Dockerfile"],
364
+ "rootMarkers": ["Dockerfile", "docker-compose.yml", "docker-compose.yaml", ".dockerignore"]
365
+ },
366
+ "helm-ls": {
367
+ "command": "helm_ls",
368
+ "args": ["serve"],
369
+ "fileTypes": [".yaml", ".yml", ".tpl"],
370
+ "rootMarkers": ["Chart.yaml", "Chart.yml"]
371
+ },
372
+ "nixd": {
373
+ "command": "nixd",
374
+ "args": [],
375
+ "fileTypes": [".nix"],
376
+ "rootMarkers": ["flake.nix", "default.nix", "shell.nix"]
377
+ },
378
+ "nil": {
379
+ "command": "nil",
380
+ "args": [],
381
+ "fileTypes": [".nix"],
382
+ "rootMarkers": ["flake.nix", "default.nix", "shell.nix"]
383
+ },
384
+ "ols": {
385
+ "command": "ols",
386
+ "args": [],
387
+ "fileTypes": [".odin"],
388
+ "rootMarkers": ["ols.json", ".git"]
389
+ },
390
+ "dartls": {
391
+ "command": "dart",
392
+ "args": ["language-server", "--protocol=lsp"],
393
+ "fileTypes": [".dart"],
394
+ "rootMarkers": ["pubspec.yaml", "pubspec.lock"],
395
+ "initOptions": {
396
+ "closingLabels": true,
397
+ "flutterOutline": true,
398
+ "outline": true
399
+ }
400
+ },
401
+ "marksman": {
402
+ "command": "marksman",
403
+ "args": ["server"],
404
+ "fileTypes": [".md", ".markdown"],
405
+ "rootMarkers": [".marksman.toml", ".git"]
406
+ },
407
+ "texlab": {
408
+ "command": "texlab",
409
+ "args": [],
410
+ "fileTypes": [".tex", ".bib", ".sty", ".cls"],
411
+ "rootMarkers": [".latexmkrc", "latexmkrc", ".texlabroot", "texlabroot", "Tectonic.toml"],
412
+ "settings": {
413
+ "texlab": {
414
+ "build": {
415
+ "executable": "latexmk",
416
+ "args": ["-pdf", "-interaction=nonstopmode", "-synctex=1", "%f"]
417
+ },
418
+ "chktex": { "onOpenAndSave": true }
419
+ }
420
+ }
421
+ },
422
+ "graphql": {
423
+ "command": "graphql-lsp",
424
+ "args": ["server", "-m", "stream"],
425
+ "fileTypes": [".graphql", ".gql"],
426
+ "rootMarkers": [".graphqlrc", ".graphqlrc.json", ".graphqlrc.yml", ".graphqlrc.yaml", "graphql.config.js"]
427
+ },
428
+ "prismals": {
429
+ "command": "prisma-language-server",
430
+ "args": ["--stdio"],
431
+ "fileTypes": [".prisma"],
432
+ "rootMarkers": ["schema.prisma", "prisma/schema.prisma"]
433
+ },
434
+ "vimls": {
435
+ "command": "vim-language-server",
436
+ "args": ["--stdio"],
437
+ "fileTypes": [".vim", ".vimrc"],
438
+ "rootMarkers": [".git"],
439
+ "initOptions": {
440
+ "isNeovim": true,
441
+ "diagnostic": { "enable": true }
442
+ }
443
+ },
444
+ "emmet-language-server": {
445
+ "command": "emmet-language-server",
446
+ "args": ["--stdio"],
447
+ "fileTypes": [".html", ".css", ".scss", ".less", ".jsx", ".tsx", ".vue", ".svelte"],
448
+ "rootMarkers": [".git"]
449
+ },
450
+ "sourcekit-lsp": {
451
+ "command": "sourcekit-lsp",
452
+ "args": [],
453
+ "fileTypes": [".swift"],
454
+ "rootMarkers": ["Package.swift", "*.xcodeproj", "*.xcworkspace", "project.yml", ".swiftpm"]
455
+ }
456
+ }
@@ -0,0 +1,109 @@
1
+ import * as fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import type { CreateFile, DeleteFile, RenameFile, TextDocumentEdit, TextEdit, WorkspaceEdit } from "./types.js";
4
+ import { uriToFile } from "./utils.js";
5
+
6
+ // =============================================================================
7
+ // Text Edit Application
8
+ // =============================================================================
9
+
10
+ /**
11
+ * Apply text edits to a string in-memory.
12
+ * Edits are applied in reverse order (bottom-to-top) to preserve line/character indices.
13
+ */
14
+ export function applyTextEditsToString(content: string, edits: TextEdit[]): string {
15
+ const lines = content.split("\n");
16
+
17
+ // Sort edits in reverse order (bottom-to-top, right-to-left)
18
+ const sortedEdits = [...edits].sort((a, b) => {
19
+ if (a.range.start.line !== b.range.start.line) {
20
+ return b.range.start.line - a.range.start.line;
21
+ }
22
+ return b.range.start.character - a.range.start.character;
23
+ });
24
+
25
+ for (const edit of sortedEdits) {
26
+ const { start, end } = edit.range;
27
+
28
+ // Single-line edit: replace substring within same line
29
+ if (start.line === end.line) {
30
+ const line = lines[start.line] || "";
31
+ lines[start.line] = line.slice(0, start.character) + edit.newText + line.slice(end.character);
32
+ } else {
33
+ // Multi-line edit: splice across multiple lines
34
+ const startLine = lines[start.line] || "";
35
+ const endLine = lines[end.line] || "";
36
+ const newContent = startLine.slice(0, start.character) + edit.newText + endLine.slice(end.character);
37
+ lines.splice(start.line, end.line - start.line + 1, ...newContent.split("\n"));
38
+ }
39
+ }
40
+
41
+ return lines.join("\n");
42
+ }
43
+
44
+ /**
45
+ * Apply text edits to a file.
46
+ * Edits are applied in reverse order (bottom-to-top) to preserve line/character indices.
47
+ */
48
+ export async function applyTextEdits(filePath: string, edits: TextEdit[]): Promise<void> {
49
+ const content = await fs.readFile(filePath, "utf-8");
50
+ const result = applyTextEditsToString(content, edits);
51
+ await fs.writeFile(filePath, result);
52
+ }
53
+
54
+ // =============================================================================
55
+ // Workspace Edit Application
56
+ // =============================================================================
57
+
58
+ /**
59
+ * Apply a workspace edit (collection of file changes).
60
+ * Returns array of applied change descriptions.
61
+ */
62
+ export async function applyWorkspaceEdit(edit: WorkspaceEdit, cwd: string): Promise<string[]> {
63
+ const applied: string[] = [];
64
+
65
+ // Handle changes map (legacy format)
66
+ if (edit.changes) {
67
+ for (const [uri, textEdits] of Object.entries(edit.changes)) {
68
+ const filePath = uriToFile(uri);
69
+ await applyTextEdits(filePath, textEdits);
70
+ applied.push(`Applied ${textEdits.length} edit(s) to ${path.relative(cwd, filePath)}`);
71
+ }
72
+ }
73
+
74
+ // Handle documentChanges array (modern format)
75
+ if (edit.documentChanges) {
76
+ for (const change of edit.documentChanges) {
77
+ if ("textDocument" in change && change.textDocument && "edits" in change && change.edits) {
78
+ // TextDocumentEdit
79
+ const docChange = change as TextDocumentEdit;
80
+ const filePath = uriToFile(docChange.textDocument.uri);
81
+ const textEdits = docChange.edits.filter((e): e is TextEdit => "range" in e && "newText" in e);
82
+ await applyTextEdits(filePath, textEdits);
83
+ applied.push(`Applied ${textEdits.length} edit(s) to ${path.relative(cwd, filePath)}`);
84
+ } else if ("kind" in change && change.kind) {
85
+ // Resource operations
86
+ if (change.kind === "create") {
87
+ const createOp = change as CreateFile;
88
+ const filePath = uriToFile(createOp.uri);
89
+ await fs.writeFile(filePath, "");
90
+ applied.push(`Created ${path.relative(cwd, filePath)}`);
91
+ } else if (change.kind === "rename") {
92
+ const renameOp = change as RenameFile;
93
+ const oldPath = uriToFile(renameOp.oldUri);
94
+ const newPath = uriToFile(renameOp.newUri);
95
+ await fs.mkdir(path.dirname(newPath), { recursive: true });
96
+ await fs.rename(oldPath, newPath);
97
+ applied.push(`Renamed ${path.relative(cwd, oldPath)} → ${path.relative(cwd, newPath)}`);
98
+ } else if (change.kind === "delete") {
99
+ const deleteOp = change as DeleteFile;
100
+ const filePath = uriToFile(deleteOp.uri);
101
+ await fs.rm(filePath, { recursive: true });
102
+ applied.push(`Deleted ${path.relative(cwd, filePath)}`);
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ return applied;
109
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Local helpers replacing @oh-my-pi/pi-utils and tool-errors/tool-timeouts imports.
3
+ */
4
+
5
+ export class ToolAbortError extends Error {
6
+ constructor() {
7
+ super("Tool execution aborted");
8
+ this.name = "ToolAbortError";
9
+ }
10
+ }
11
+
12
+ export function throwIfAborted(signal?: AbortSignal): void {
13
+ if (signal?.aborted) {
14
+ throw new ToolAbortError();
15
+ }
16
+ }
17
+
18
+ export function isEnoent(err: unknown): boolean {
19
+ return (err as any)?.code === "ENOENT";
20
+ }
21
+
22
+ export function isRecord(v: unknown): v is Record<string, unknown> {
23
+ return typeof v === "object" && v !== null && !Array.isArray(v);
24
+ }
25
+
26
+ export function clampTimeout(timeout?: number): number {
27
+ return Math.max(5, Math.min(60, timeout ?? 20));
28
+ }
29
+
30
+ /**
31
+ * Run a promise, rejecting if the signal aborts.
32
+ */
33
+ export async function untilAborted<T>(signal: AbortSignal | undefined, fn: () => Promise<T>): Promise<T> {
34
+ if (signal?.aborted) {
35
+ throw new ToolAbortError();
36
+ }
37
+ if (!signal) {
38
+ return fn();
39
+ }
40
+ return new Promise<T>((resolve, reject) => {
41
+ const onAbort = () => reject(new ToolAbortError());
42
+ signal.addEventListener("abort", onAbort, { once: true });
43
+ fn().then(
44
+ result => {
45
+ signal.removeEventListener("abort", onAbort);
46
+ resolve(result);
47
+ },
48
+ err => {
49
+ signal.removeEventListener("abort", onAbort);
50
+ reject(err);
51
+ },
52
+ );
53
+ });
54
+ }