gsd-pi 2.34.0-dev.ed0bfbf → 2.35.0-dev.55dcc60

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 (255) hide show
  1. package/dist/resources/extensions/gsd/changelog.js +162 -0
  2. package/dist/resources/extensions/gsd/commands-bootstrap.js +1 -0
  3. package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
  4. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +5 -1
  5. package/dist/resources/extensions/gsd/commands.js +8 -1
  6. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  7. package/dist/resources/extensions/gsd/doctor-checks.js +113 -5
  8. package/dist/resources/extensions/gsd/doctor-proactive.js +22 -0
  9. package/dist/resources/extensions/gsd/doctor.js +36 -0
  10. package/dist/resources/extensions/gsd/guided-flow.js +4 -2
  11. package/dist/resources/extensions/gsd/preferences-validation.js +38 -0
  12. package/dist/resources/extensions/gsd/preferences.js +2 -0
  13. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  14. package/package.json +1 -1
  15. package/packages/pi-agent-core/dist/agent-loop.d.ts +14 -0
  16. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  17. package/packages/pi-agent-core/dist/agent-loop.js +24 -27
  18. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  19. package/packages/pi-agent-core/dist/agent.d.ts +1 -0
  20. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  21. package/packages/pi-agent-core/dist/agent.js +11 -22
  22. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  23. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  24. package/packages/pi-agent-core/dist/proxy.js +2 -8
  25. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  26. package/packages/pi-agent-core/src/agent-loop.ts +30 -27
  27. package/packages/pi-agent-core/src/agent.ts +12 -23
  28. package/packages/pi-agent-core/src/proxy.ts +2 -8
  29. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  30. package/packages/pi-ai/dist/providers/azure-openai-responses.js +5 -41
  31. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  32. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  33. package/packages/pi-ai/dist/providers/openai-completions.js +10 -73
  34. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  35. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  36. package/packages/pi-ai/dist/providers/openai-responses.js +8 -79
  37. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  38. package/packages/pi-ai/dist/providers/openai-shared.d.ts +65 -0
  39. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -0
  40. package/packages/pi-ai/dist/providers/openai-shared.js +146 -0
  41. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -0
  42. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  43. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +7 -135
  44. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  45. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  46. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +7 -135
  47. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  48. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts +46 -0
  49. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts.map +1 -0
  50. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js +160 -0
  51. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js.map +1 -0
  52. package/packages/pi-ai/src/providers/azure-openai-responses.ts +11 -45
  53. package/packages/pi-ai/src/providers/openai-completions.ts +16 -86
  54. package/packages/pi-ai/src/providers/openai-responses.ts +15 -95
  55. package/packages/pi-ai/src/providers/openai-shared.ts +193 -0
  56. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +14 -162
  57. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +13 -161
  58. package/packages/pi-ai/src/utils/oauth/google-oauth-utils.ts +201 -0
  59. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +16 -63
  60. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  61. package/packages/pi-coding-agent/dist/core/agent-session.js +104 -641
  62. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  63. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +0 -1
  64. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  65. package/packages/pi-coding-agent/dist/core/auth-storage.js +4 -35
  66. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  67. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  68. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js +5 -43
  69. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  70. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  71. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +11 -69
  72. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  73. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +40 -0
  74. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  75. package/packages/pi-coding-agent/dist/core/compaction/utils.js +78 -0
  76. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  77. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +77 -0
  78. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -0
  79. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +331 -0
  80. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -0
  81. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +2 -2
  82. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  83. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  84. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  85. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +15 -0
  86. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  87. package/packages/pi-coding-agent/dist/core/extensions/runner.js +129 -243
  88. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  89. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +49 -42
  90. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  91. package/packages/pi-coding-agent/dist/core/extensions/types.js +2 -21
  92. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  93. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts +39 -0
  94. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts.map +1 -0
  95. package/packages/pi-coding-agent/dist/core/lock-utils.js +89 -0
  96. package/packages/pi-coding-agent/dist/core/lock-utils.js.map +1 -0
  97. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +2 -0
  98. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
  99. package/packages/pi-coding-agent/dist/core/lsp/config.js +4 -1
  100. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
  101. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  102. package/packages/pi-coding-agent/dist/core/lsp/index.js +52 -107
  103. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  104. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  105. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +2 -21
  106. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  107. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +0 -1
  108. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
  109. package/packages/pi-coding-agent/dist/core/lsp/types.js +0 -28
  110. package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
  111. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  112. package/packages/pi-coding-agent/dist/core/package-manager.js +2 -4
  113. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  114. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +2 -4
  115. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  116. package/packages/pi-coding-agent/dist/core/resource-loader.js +33 -58
  117. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  118. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +87 -0
  119. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -0
  120. package/packages/pi-coding-agent/dist/core/retry-handler.js +295 -0
  121. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -0
  122. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +0 -1
  123. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  124. package/packages/pi-coding-agent/dist/core/session-manager.js +3 -28
  125. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  126. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +8 -0
  127. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  128. package/packages/pi-coding-agent/dist/core/settings-manager.js +76 -166
  129. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  130. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  131. package/packages/pi-coding-agent/dist/core/skills.js +1 -3
  132. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  133. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  134. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  135. package/packages/pi-coding-agent/dist/index.js +1 -1
  136. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +1 -1
  138. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  139. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +9 -26
  140. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  141. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -13
  143. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  144. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
  145. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
  146. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js +61 -0
  147. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
  148. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  149. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +6 -9
  150. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +65 -0
  152. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  153. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +6 -16
  154. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  155. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +12 -0
  156. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  157. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +175 -0
  158. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -0
  159. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
  160. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
  161. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js +15 -0
  162. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js.map +1 -0
  163. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  164. package/packages/pi-coding-agent/dist/modes/print-mode.js +2 -30
  165. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  167. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -28
  168. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  169. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts +19 -0
  170. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts.map +1 -0
  171. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js +45 -0
  172. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js.map +1 -0
  173. package/packages/pi-coding-agent/dist/utils/error.d.ts +5 -0
  174. package/packages/pi-coding-agent/dist/utils/error.d.ts.map +1 -0
  175. package/packages/pi-coding-agent/dist/utils/error.js +7 -0
  176. package/packages/pi-coding-agent/dist/utils/error.js.map +1 -0
  177. package/packages/pi-coding-agent/package.json +1 -1
  178. package/packages/pi-coding-agent/src/core/agent-session.ts +117 -745
  179. package/packages/pi-coding-agent/src/core/auth-storage.ts +4 -38
  180. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +7 -53
  181. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +14 -74
  182. package/packages/pi-coding-agent/src/core/compaction/utils.ts +100 -0
  183. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +424 -0
  184. package/packages/pi-coding-agent/src/core/extensions/index.ts +1 -21
  185. package/packages/pi-coding-agent/src/core/extensions/runner.ts +119 -243
  186. package/packages/pi-coding-agent/src/core/extensions/types.ts +50 -69
  187. package/packages/pi-coding-agent/src/core/lock-utils.ts +113 -0
  188. package/packages/pi-coding-agent/src/core/lsp/config.ts +4 -1
  189. package/packages/pi-coding-agent/src/core/lsp/index.ts +83 -152
  190. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +2 -22
  191. package/packages/pi-coding-agent/src/core/lsp/types.ts +0 -29
  192. package/packages/pi-coding-agent/src/core/package-manager.ts +1 -4
  193. package/packages/pi-coding-agent/src/core/resource-loader.ts +43 -67
  194. package/packages/pi-coding-agent/src/core/retry-handler.ts +359 -0
  195. package/packages/pi-coding-agent/src/core/session-manager.ts +3 -30
  196. package/packages/pi-coding-agent/src/core/settings-manager.ts +85 -164
  197. package/packages/pi-coding-agent/src/core/skills.ts +1 -4
  198. package/packages/pi-coding-agent/src/index.ts +1 -7
  199. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +17 -29
  200. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -13
  201. package/packages/pi-coding-agent/src/modes/interactive/components/tree-render-utils.ts +81 -0
  202. package/packages/pi-coding-agent/src/modes/interactive/components/tree-selector.ts +14 -19
  203. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +7 -18
  204. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +196 -0
  205. package/packages/pi-coding-agent/src/modes/interactive/utils/shorten-path.ts +14 -0
  206. package/packages/pi-coding-agent/src/modes/print-mode.ts +2 -30
  207. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -28
  208. package/packages/pi-coding-agent/src/modes/shared/command-context-actions.ts +53 -0
  209. package/packages/pi-coding-agent/src/utils/error.ts +6 -0
  210. package/packages/pi-tui/dist/components/markdown.d.ts +5 -0
  211. package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
  212. package/packages/pi-tui/dist/components/markdown.js +25 -31
  213. package/packages/pi-tui/dist/components/markdown.js.map +1 -1
  214. package/packages/pi-tui/dist/keys.d.ts +0 -4
  215. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  216. package/packages/pi-tui/dist/keys.js +94 -162
  217. package/packages/pi-tui/dist/keys.js.map +1 -1
  218. package/packages/pi-tui/src/components/markdown.ts +25 -29
  219. package/packages/pi-tui/src/keys.ts +94 -173
  220. package/pkg/dist/modes/interactive/theme/theme.d.ts +65 -0
  221. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  222. package/pkg/dist/modes/interactive/theme/theme.js +6 -16
  223. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  224. package/pkg/dist/modes/interactive/theme/themes.d.ts +12 -0
  225. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  226. package/pkg/dist/modes/interactive/theme/themes.js +175 -0
  227. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -0
  228. package/pkg/package.json +1 -1
  229. package/src/resources/extensions/gsd/changelog.ts +213 -0
  230. package/src/resources/extensions/gsd/commands-bootstrap.ts +1 -0
  231. package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
  232. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +5 -1
  233. package/src/resources/extensions/gsd/commands.ts +9 -1
  234. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  235. package/src/resources/extensions/gsd/doctor-checks.ts +107 -5
  236. package/src/resources/extensions/gsd/doctor-proactive.ts +24 -0
  237. package/src/resources/extensions/gsd/doctor-types.ts +9 -1
  238. package/src/resources/extensions/gsd/doctor.ts +35 -0
  239. package/src/resources/extensions/gsd/guided-flow.ts +4 -2
  240. package/src/resources/extensions/gsd/preferences-validation.ts +38 -0
  241. package/src/resources/extensions/gsd/preferences.ts +2 -0
  242. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
  243. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +98 -2
  244. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +59 -3
  245. package/src/resources/extensions/gsd/tests/preferences.test.ts +28 -0
  246. package/src/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  247. package/packages/pi-coding-agent/dist/modes/interactive/theme/dark.json +0 -85
  248. package/packages/pi-coding-agent/dist/modes/interactive/theme/light.json +0 -84
  249. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.json +0 -335
  250. package/packages/pi-coding-agent/src/modes/interactive/theme/dark.json +0 -85
  251. package/packages/pi-coding-agent/src/modes/interactive/theme/light.json +0 -84
  252. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
  253. package/pkg/dist/modes/interactive/theme/dark.json +0 -85
  254. package/pkg/dist/modes/interactive/theme/light.json +0 -84
  255. package/pkg/dist/modes/interactive/theme/theme-schema.json +0 -335
@@ -0,0 +1,46 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import fs from "node:fs";
6
+
7
+ import { handleInspect } from "../commands-inspect.ts";
8
+ import { closeDatabase, openDatabase } from "../gsd-db.ts";
9
+
10
+ test("/gsd inspect opens existing database when it was not yet opened in session", async () => {
11
+ closeDatabase();
12
+
13
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "gsd-inspect-db-"));
14
+ const prevCwd = process.cwd();
15
+
16
+ try {
17
+ const gsdDir = path.join(tmp, ".gsd");
18
+ fs.mkdirSync(gsdDir, { recursive: true });
19
+ const dbPath = path.join(gsdDir, "gsd.db");
20
+
21
+ assert.equal(openDatabase(dbPath), true);
22
+ closeDatabase();
23
+
24
+ process.chdir(tmp);
25
+
26
+ const notifications: Array<{ message: string; level: string }> = [];
27
+ const ctx = {
28
+ ui: {
29
+ notify(message: string, level: string) {
30
+ notifications.push({ message, level });
31
+ },
32
+ },
33
+ } as any;
34
+
35
+ await handleInspect(ctx);
36
+
37
+ assert.equal(notifications.length, 1);
38
+ assert.equal(notifications[0].level, "info");
39
+ assert.match(notifications[0].message, /=== GSD Database Inspect ===/);
40
+ assert.doesNotMatch(notifications[0].message, /No GSD database available/);
41
+ } finally {
42
+ process.chdir(prevCwd);
43
+ closeDatabase();
44
+ fs.rmSync(tmp, { recursive: true, force: true });
45
+ }
46
+ });
@@ -2,9 +2,10 @@
2
2
  * doctor-git.test.ts — Integration tests for doctor git health checks.
3
3
  *
4
4
  * Creates real temp git repos with deliberate broken state, runs runGSDDoctor,
5
- * and asserts correct detection and fixing of all 4 git issue codes:
5
+ * and asserts correct detection and fixing of git issue codes:
6
6
  * orphaned_auto_worktree, stale_milestone_branch,
7
- * corrupt_merge_state, tracked_runtime_files
7
+ * corrupt_merge_state, tracked_runtime_files,
8
+ * integration_branch_missing, worktree_directory_orphaned
8
9
  */
9
10
 
10
11
  import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, realpathSync } from "node:fs";
@@ -299,6 +300,101 @@ async function main(): Promise<void> {
299
300
  console.log("\n=== none-mode skips stale branch (skipped on Windows) ===");
300
301
  }
301
302
 
303
+ // ─── Test: Integration branch missing ──────────────────────────────
304
+ if (process.platform !== "win32") {
305
+ console.log("\n=== integration_branch_missing ===");
306
+ {
307
+ const dir = createRepoWithActiveMilestone();
308
+ cleanups.push(dir);
309
+
310
+ // Write integration branch metadata for M001 pointing to a non-existent branch
311
+ const metaPath = join(dir, ".gsd", "milestones", "M001", "M001-META.json");
312
+ writeFileSync(metaPath, JSON.stringify({ integrationBranch: "feat/does-not-exist" }, null, 2));
313
+
314
+ const detect = await runGSDDoctor(dir);
315
+ const missingBranchIssues = detect.issues.filter(i => i.code === "integration_branch_missing");
316
+ assertTrue(missingBranchIssues.length > 0, "detects missing integration branch");
317
+ assertTrue(
318
+ missingBranchIssues[0]?.message.includes("feat/does-not-exist"),
319
+ "message includes the missing branch name",
320
+ );
321
+ assertEq(missingBranchIssues[0]?.fixable, false, "integration_branch_missing is not auto-fixable");
322
+ assertEq(missingBranchIssues[0]?.severity, "error", "severity is error");
323
+ }
324
+ } else {
325
+ console.log("\n=== integration_branch_missing (skipped on Windows) ===");
326
+ }
327
+
328
+ // ─── Test: Integration branch present — no false positive ──────────
329
+ if (process.platform !== "win32") {
330
+ console.log("\n=== integration_branch_missing (no false positive) ===");
331
+ {
332
+ const dir = createRepoWithActiveMilestone();
333
+ cleanups.push(dir);
334
+
335
+ // Write integration branch metadata for M001 pointing to "main" (which exists)
336
+ const metaPath = join(dir, ".gsd", "milestones", "M001", "M001-META.json");
337
+ writeFileSync(metaPath, JSON.stringify({ integrationBranch: "main" }, null, 2));
338
+
339
+ const detect = await runGSDDoctor(dir);
340
+ const missingBranchIssues = detect.issues.filter(i => i.code === "integration_branch_missing");
341
+ assertEq(missingBranchIssues.length, 0, "existing integration branch NOT flagged");
342
+ }
343
+ } else {
344
+ console.log("\n=== integration_branch_missing (no false positive — skipped on Windows) ===");
345
+ }
346
+
347
+ // ─── Test: Orphaned worktree directory ─────────────────────────────
348
+ if (process.platform !== "win32") {
349
+ console.log("\n=== worktree_directory_orphaned ===");
350
+ {
351
+ const dir = createRepoWithActiveMilestone();
352
+ cleanups.push(dir);
353
+
354
+ // Create a worktrees/ dir with an entry that is NOT in git worktree list
355
+ const orphanDir = join(dir, ".gsd", "worktrees", "orphan-feature");
356
+ mkdirSync(orphanDir, { recursive: true });
357
+ writeFileSync(join(orphanDir, "some-file.txt"), "leftover content\n");
358
+
359
+ const detect = await runGSDDoctor(dir);
360
+ const orphanDirIssues = detect.issues.filter(i => i.code === "worktree_directory_orphaned");
361
+ assertTrue(orphanDirIssues.length > 0, "detects orphaned worktree directory");
362
+ assertTrue(
363
+ orphanDirIssues[0]?.message.includes("orphan-feature"),
364
+ "message includes the orphaned directory name",
365
+ );
366
+ assertTrue(orphanDirIssues[0]?.fixable === true, "worktree_directory_orphaned is fixable");
367
+
368
+ const fixed = await runGSDDoctor(dir, { fix: true });
369
+ assertTrue(
370
+ fixed.fixesApplied.some(f => f.includes("removed orphaned worktree directory")),
371
+ "fix removes orphaned worktree directory",
372
+ );
373
+ assertTrue(!existsSync(orphanDir), "orphaned directory removed after fix");
374
+ }
375
+ } else {
376
+ console.log("\n=== worktree_directory_orphaned (skipped on Windows) ===");
377
+ }
378
+
379
+ // ─── Test: Registered worktree NOT flagged as orphaned ─────────────
380
+ if (process.platform !== "win32") {
381
+ console.log("\n=== worktree_directory_orphaned (registered worktree not flagged) ===");
382
+ {
383
+ const dir = createRepoWithActiveMilestone();
384
+ cleanups.push(dir);
385
+
386
+ // Create a real registered worktree under .gsd/worktrees/
387
+ mkdirSync(join(dir, ".gsd", "worktrees"), { recursive: true });
388
+ run("git worktree add -b worktree/feature-1 .gsd/worktrees/feature-1", dir);
389
+
390
+ const detect = await runGSDDoctor(dir);
391
+ const orphanDirIssues = detect.issues.filter(i => i.code === "worktree_directory_orphaned");
392
+ assertEq(orphanDirIssues.length, 0, "registered worktree NOT flagged as orphaned");
393
+ }
394
+ } else {
395
+ console.log("\n=== worktree_directory_orphaned (registered worktree not flagged — skipped on Windows) ===");
396
+ }
397
+
302
398
  // ─── Test 9: none-mode still detects corrupt merge state ───────────
303
399
  console.log("\n=== none-mode keeps corrupt merge state ===");
304
400
  {
@@ -2,9 +2,9 @@
2
2
  * doctor-runtime.test.ts — Tests for doctor runtime health checks.
3
3
  *
4
4
  * Tests detection and auto-fix of:
5
- * stale_crash_lock, orphaned_completed_units, stale_hook_state,
6
- * activity_log_bloat, state_file_missing, state_file_stale,
7
- * gitignore_missing_patterns
5
+ * stale_crash_lock, stranded_lock_directory, orphaned_completed_units,
6
+ * stale_hook_state, activity_log_bloat, state_file_missing,
7
+ * state_file_stale, gitignore_missing_patterns
8
8
  */
9
9
 
10
10
  import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, readFileSync, realpathSync } from "node:fs";
@@ -290,6 +290,62 @@ node_modules/
290
290
  assertEq(content.length, 0, "all orphaned keys removed");
291
291
  }
292
292
 
293
+ // ─── Test: Stranded lock directory detection & fix ────────────────
294
+ // Skip on Windows: proper-lockfile uses advisory file locking on Windows,
295
+ // not the directory-based mechanism. The .gsd.lock/ directory pattern is
296
+ // a POSIX-specific lockfile implementation detail.
297
+ if (process.platform !== "win32") {
298
+ console.log("\n=== stranded_lock_directory ===");
299
+ {
300
+ const dir = createMinimalProject();
301
+ cleanups.push(dir);
302
+
303
+ // Create the proper-lockfile lock directory without a live lock holder.
304
+ // The lock dir sits at <parent of .gsd>/.gsd.lock (i.e., <basePath>/.gsd.lock).
305
+ const lockDir = join(dir, ".gsd.lock");
306
+ mkdirSync(lockDir, { recursive: true });
307
+
308
+ const detect = await runGSDDoctor(dir);
309
+ const strandedIssues = detect.issues.filter(i => i.code === "stranded_lock_directory");
310
+ assertTrue(strandedIssues.length > 0, "detects stranded lock directory");
311
+ assertTrue(strandedIssues[0]?.message.includes("lock directory"), "message describes stranded lock directory");
312
+ assertTrue(strandedIssues[0]?.fixable === true, "stranded lock dir is fixable");
313
+
314
+ const fixed = await runGSDDoctor(dir, { fix: true });
315
+ assertTrue(
316
+ fixed.fixesApplied.some(f => f.includes("removed stranded lock directory")),
317
+ "fix removes stranded lock directory",
318
+ );
319
+ assertTrue(!existsSync(lockDir), "lock directory removed after fix");
320
+ }
321
+
322
+ // ─── Test: Stranded lock dir with live lock holder — NOT flagged ───
323
+ console.log("\n=== stranded_lock_directory (live holder not flagged) ===");
324
+ {
325
+ const dir = createMinimalProject();
326
+ cleanups.push(dir);
327
+
328
+ // Create lock dir + auto.lock with PID 1 (init/launchd — always alive, never our own PID)
329
+ const lockDir = join(dir, ".gsd.lock");
330
+ mkdirSync(lockDir, { recursive: true });
331
+ const liveLockData = {
332
+ pid: 1,
333
+ startedAt: new Date().toISOString(),
334
+ unitType: "execute-task",
335
+ unitId: "M001/S01/T01",
336
+ unitStartedAt: new Date().toISOString(),
337
+ completedUnits: 1,
338
+ };
339
+ writeFileSync(join(dir, ".gsd", "auto.lock"), JSON.stringify(liveLockData, null, 2));
340
+
341
+ const detect = await runGSDDoctor(dir);
342
+ const strandedIssues = detect.issues.filter(i => i.code === "stranded_lock_directory");
343
+ assertEq(strandedIssues.length, 0, "live lock holder: stranded_lock_directory NOT detected");
344
+ }
345
+ } else {
346
+ console.log("\n=== stranded_lock_directory (skipped on Windows) ===");
347
+ }
348
+
293
349
  } finally {
294
350
  for (const dir of cleanups) {
295
351
  try { rmSync(dir, { recursive: true, force: true }); } catch { /* ignore */ }
@@ -175,6 +175,34 @@ test("git fields comprehensive validation", () => {
175
175
  assert.equal(preferences.git?.isolation, "branch");
176
176
  });
177
177
 
178
+ test("auto_visualize, auto_report, compression_strategy, context_selection validate correctly", () => {
179
+ const { preferences, errors } = validatePreferences({
180
+ auto_visualize: true,
181
+ auto_report: false,
182
+ compression_strategy: "compress",
183
+ context_selection: "smart",
184
+ });
185
+ assert.equal(errors.length, 0);
186
+ assert.equal(preferences.auto_visualize, true);
187
+ assert.equal(preferences.auto_report, false);
188
+ assert.equal(preferences.compression_strategy, "compress");
189
+ assert.equal(preferences.context_selection, "smart");
190
+ });
191
+
192
+ test("auto_visualize, auto_report, compression_strategy, context_selection reject invalid values", () => {
193
+ const { errors: e1 } = validatePreferences({ auto_visualize: "yes" as never });
194
+ assert.ok(e1.some(e => e.includes("auto_visualize")));
195
+
196
+ const { errors: e2 } = validatePreferences({ auto_report: 1 as never });
197
+ assert.ok(e2.some(e => e.includes("auto_report")));
198
+
199
+ const { errors: e3 } = validatePreferences({ compression_strategy: "shrink" as never });
200
+ assert.ok(e3.some(e => e.includes("compression_strategy")));
201
+
202
+ const { errors: e4 } = validatePreferences({ context_selection: "partial" as never });
203
+ assert.ok(e4.some(e => e.includes("context_selection")));
204
+ });
205
+
178
206
  test("all wizard fields together produce no errors", () => {
179
207
  const { errors, warnings } = validatePreferences({
180
208
  version: 1,
@@ -61,10 +61,10 @@ pi.on("tool_call", async (event, ctx) => {
61
61
 
62
62
  **tool_result** — Fired after tool executes. Can modify result. Handlers chain like middleware.
63
63
  ```typescript
64
- import { isBashToolResult } from "@mariozechner/pi-coding-agent";
64
+ import { isToolResultEventType } from "@mariozechner/pi-coding-agent";
65
65
 
66
66
  pi.on("tool_result", async (event, ctx) => {
67
- if (isBashToolResult(event)) {
67
+ if (isToolResultEventType("bash", event)) {
68
68
  // event.details is typed as BashToolDetails
69
69
  }
70
70
  // Return partial patch: { content, details, isError }
@@ -105,7 +105,7 @@ pi.on("model_select", async (event, ctx) => {
105
105
  Built-in type guards for tool events:
106
106
 
107
107
  ```typescript
108
- import { isToolCallEventType, isBashToolResult } from "@mariozechner/pi-coding-agent";
108
+ import { isToolCallEventType, isToolResultEventType } from "@mariozechner/pi-coding-agent";
109
109
 
110
110
  // Tool calls — narrows event.input type
111
111
  if (isToolCallEventType("bash", event)) { /* event.input: { command, timeout? } */ }
@@ -114,7 +114,7 @@ if (isToolCallEventType("write", event)) { /* event.input: { path, content } */
114
114
  if (isToolCallEventType("edit", event)) { /* event.input: { path, oldText, newText } */ }
115
115
 
116
116
  // Tool results — narrows event.details type
117
- if (isBashToolResult(event)) { /* event.details: BashToolDetails */ }
117
+ if (isToolResultEventType("bash", event)) { /* event.details: BashToolDetails */ }
118
118
  ```
119
119
 
120
120
  For custom tools, export your input type and use explicit type params:
@@ -1,85 +0,0 @@
1
- {
2
- "$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
- "name": "dark",
4
- "vars": {
5
- "cyan": "#00d7ff",
6
- "blue": "#5f87ff",
7
- "green": "#b5bd68",
8
- "red": "#cc6666",
9
- "yellow": "#ffff00",
10
- "gray": "#808080",
11
- "dimGray": "#666666",
12
- "darkGray": "#505050",
13
- "accent": "#8abeb7",
14
- "selectedBg": "#3a3a4a",
15
- "userMsgBg": "#343541",
16
- "toolPendingBg": "#282832",
17
- "toolSuccessBg": "#283228",
18
- "toolErrorBg": "#3c2828",
19
- "customMsgBg": "#2d2838"
20
- },
21
- "colors": {
22
- "accent": "accent",
23
- "border": "blue",
24
- "borderAccent": "cyan",
25
- "borderMuted": "darkGray",
26
- "success": "green",
27
- "error": "red",
28
- "warning": "yellow",
29
- "muted": "gray",
30
- "dim": "dimGray",
31
- "text": "",
32
- "thinkingText": "gray",
33
-
34
- "selectedBg": "selectedBg",
35
- "userMessageBg": "userMsgBg",
36
- "userMessageText": "",
37
- "customMessageBg": "customMsgBg",
38
- "customMessageText": "",
39
- "customMessageLabel": "#9575cd",
40
- "toolPendingBg": "toolPendingBg",
41
- "toolSuccessBg": "toolSuccessBg",
42
- "toolErrorBg": "toolErrorBg",
43
- "toolTitle": "",
44
- "toolOutput": "gray",
45
-
46
- "mdHeading": "#f0c674",
47
- "mdLink": "#81a2be",
48
- "mdLinkUrl": "dimGray",
49
- "mdCode": "accent",
50
- "mdCodeBlock": "green",
51
- "mdCodeBlockBorder": "gray",
52
- "mdQuote": "gray",
53
- "mdQuoteBorder": "gray",
54
- "mdHr": "gray",
55
- "mdListBullet": "accent",
56
-
57
- "toolDiffAdded": "green",
58
- "toolDiffRemoved": "red",
59
- "toolDiffContext": "gray",
60
-
61
- "syntaxComment": "#6A9955",
62
- "syntaxKeyword": "#569CD6",
63
- "syntaxFunction": "#DCDCAA",
64
- "syntaxVariable": "#9CDCFE",
65
- "syntaxString": "#CE9178",
66
- "syntaxNumber": "#B5CEA8",
67
- "syntaxType": "#4EC9B0",
68
- "syntaxOperator": "#D4D4D4",
69
- "syntaxPunctuation": "#D4D4D4",
70
-
71
- "thinkingOff": "darkGray",
72
- "thinkingMinimal": "#6e6e6e",
73
- "thinkingLow": "#5f87af",
74
- "thinkingMedium": "#81a2be",
75
- "thinkingHigh": "#b294bb",
76
- "thinkingXhigh": "#d183e8",
77
-
78
- "bashMode": "green"
79
- },
80
- "export": {
81
- "pageBg": "#18181e",
82
- "cardBg": "#1e1e24",
83
- "infoBg": "#3c3728"
84
- }
85
- }
@@ -1,84 +0,0 @@
1
- {
2
- "$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
- "name": "light",
4
- "vars": {
5
- "teal": "#5a8080",
6
- "blue": "#547da7",
7
- "green": "#588458",
8
- "red": "#aa5555",
9
- "yellow": "#9a7326",
10
- "mediumGray": "#6c6c6c",
11
- "dimGray": "#767676",
12
- "lightGray": "#b0b0b0",
13
- "selectedBg": "#d0d0e0",
14
- "userMsgBg": "#e8e8e8",
15
- "toolPendingBg": "#e8e8f0",
16
- "toolSuccessBg": "#e8f0e8",
17
- "toolErrorBg": "#f0e8e8",
18
- "customMsgBg": "#ede7f6"
19
- },
20
- "colors": {
21
- "accent": "teal",
22
- "border": "blue",
23
- "borderAccent": "teal",
24
- "borderMuted": "lightGray",
25
- "success": "green",
26
- "error": "red",
27
- "warning": "yellow",
28
- "muted": "mediumGray",
29
- "dim": "dimGray",
30
- "text": "",
31
- "thinkingText": "mediumGray",
32
-
33
- "selectedBg": "selectedBg",
34
- "userMessageBg": "userMsgBg",
35
- "userMessageText": "",
36
- "customMessageBg": "customMsgBg",
37
- "customMessageText": "",
38
- "customMessageLabel": "#7e57c2",
39
- "toolPendingBg": "toolPendingBg",
40
- "toolSuccessBg": "toolSuccessBg",
41
- "toolErrorBg": "toolErrorBg",
42
- "toolTitle": "",
43
- "toolOutput": "mediumGray",
44
-
45
- "mdHeading": "yellow",
46
- "mdLink": "blue",
47
- "mdLinkUrl": "dimGray",
48
- "mdCode": "teal",
49
- "mdCodeBlock": "green",
50
- "mdCodeBlockBorder": "mediumGray",
51
- "mdQuote": "mediumGray",
52
- "mdQuoteBorder": "mediumGray",
53
- "mdHr": "mediumGray",
54
- "mdListBullet": "green",
55
-
56
- "toolDiffAdded": "green",
57
- "toolDiffRemoved": "red",
58
- "toolDiffContext": "mediumGray",
59
-
60
- "syntaxComment": "#008000",
61
- "syntaxKeyword": "#0000FF",
62
- "syntaxFunction": "#795E26",
63
- "syntaxVariable": "#001080",
64
- "syntaxString": "#A31515",
65
- "syntaxNumber": "#098658",
66
- "syntaxType": "#267F99",
67
- "syntaxOperator": "#000000",
68
- "syntaxPunctuation": "#000000",
69
-
70
- "thinkingOff": "lightGray",
71
- "thinkingMinimal": "#767676",
72
- "thinkingLow": "blue",
73
- "thinkingMedium": "teal",
74
- "thinkingHigh": "#875f87",
75
- "thinkingXhigh": "#8b008b",
76
-
77
- "bashMode": "green"
78
- },
79
- "export": {
80
- "pageBg": "#f8f8f8",
81
- "cardBg": "#ffffff",
82
- "infoBg": "#fffae6"
83
- }
84
- }