gsd-pi 2.29.0 → 2.30.0-dev.7e1bbce

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 (328) hide show
  1. package/README.md +24 -17
  2. package/dist/cli.js +51 -0
  3. package/dist/extension-registry.d.ts +63 -0
  4. package/dist/extension-registry.js +166 -0
  5. package/dist/headless.js +4 -0
  6. package/dist/help-text.js +35 -0
  7. package/dist/loader.js +10 -1
  8. package/dist/resource-loader.js +11 -1
  9. package/dist/resources/extensions/async-jobs/extension-manifest.json +13 -0
  10. package/dist/resources/extensions/bg-shell/extension-manifest.json +14 -0
  11. package/dist/resources/extensions/bg-shell/process-manager.ts +13 -0
  12. package/dist/resources/extensions/browser-tools/extension-manifest.json +37 -0
  13. package/dist/resources/extensions/context7/extension-manifest.json +12 -0
  14. package/dist/resources/extensions/google-search/extension-manifest.json +12 -0
  15. package/dist/resources/extensions/gsd/auto-dashboard.ts +31 -0
  16. package/dist/resources/extensions/gsd/auto-dispatch.ts +32 -3
  17. package/dist/resources/extensions/gsd/auto-post-unit.ts +45 -13
  18. package/dist/resources/extensions/gsd/auto-prompts.ts +40 -17
  19. package/dist/resources/extensions/gsd/auto-recovery.ts +18 -23
  20. package/dist/resources/extensions/gsd/auto-start.ts +18 -32
  21. package/dist/resources/extensions/gsd/auto-worktree.ts +21 -182
  22. package/dist/resources/extensions/gsd/auto.ts +2 -24
  23. package/dist/resources/extensions/gsd/captures.ts +4 -10
  24. package/dist/resources/extensions/gsd/commands-extensions.ts +328 -0
  25. package/dist/resources/extensions/gsd/commands-handlers.ts +22 -2
  26. package/dist/resources/extensions/gsd/commands-logs.ts +13 -14
  27. package/dist/resources/extensions/gsd/commands-prefs-wizard.ts +44 -14
  28. package/dist/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
  29. package/dist/resources/extensions/gsd/commands.ts +108 -24
  30. package/dist/resources/extensions/gsd/dashboard-overlay.ts +2 -1
  31. package/dist/resources/extensions/gsd/detection.ts +2 -1
  32. package/dist/resources/extensions/gsd/doctor-checks.ts +49 -1
  33. package/dist/resources/extensions/gsd/doctor-types.ts +3 -1
  34. package/dist/resources/extensions/gsd/extension-manifest.json +18 -0
  35. package/dist/resources/extensions/gsd/forensics.ts +2 -2
  36. package/dist/resources/extensions/gsd/git-service.ts +3 -2
  37. package/dist/resources/extensions/gsd/gitignore.ts +9 -63
  38. package/dist/resources/extensions/gsd/gsd-db.ts +1 -165
  39. package/dist/resources/extensions/gsd/guided-flow.ts +8 -5
  40. package/dist/resources/extensions/gsd/index.ts +16 -3
  41. package/dist/resources/extensions/gsd/json-persistence.ts +16 -1
  42. package/dist/resources/extensions/gsd/md-importer.ts +3 -2
  43. package/dist/resources/extensions/gsd/mechanical-completion.ts +430 -0
  44. package/dist/resources/extensions/gsd/migrate/command.ts +3 -2
  45. package/dist/resources/extensions/gsd/migrate/writer.ts +2 -1
  46. package/dist/resources/extensions/gsd/migrate-external.ts +123 -0
  47. package/dist/resources/extensions/gsd/paths.ts +24 -2
  48. package/dist/resources/extensions/gsd/post-unit-hooks.ts +6 -5
  49. package/dist/resources/extensions/gsd/preferences-models.ts +7 -1
  50. package/dist/resources/extensions/gsd/preferences-validation.ts +2 -1
  51. package/dist/resources/extensions/gsd/preferences.ts +10 -5
  52. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
  53. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  54. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
  55. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -1
  56. package/dist/resources/extensions/gsd/prompts/workflow-start.md +28 -0
  57. package/dist/resources/extensions/gsd/queue-order.ts +10 -11
  58. package/dist/resources/extensions/gsd/repo-identity.ts +148 -0
  59. package/dist/resources/extensions/gsd/resource-version.ts +99 -0
  60. package/dist/resources/extensions/gsd/roadmap-slices.ts +22 -7
  61. package/dist/resources/extensions/gsd/session-forensics.ts +4 -3
  62. package/dist/resources/extensions/gsd/session-lock.ts +53 -4
  63. package/dist/resources/extensions/gsd/session-status-io.ts +23 -41
  64. package/dist/resources/extensions/gsd/tests/activity-log.test.ts +2 -2
  65. package/dist/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
  66. package/dist/resources/extensions/gsd/tests/auto-recovery.test.ts +3 -3
  67. package/dist/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
  68. package/dist/resources/extensions/gsd/tests/auto-worktree.test.ts +0 -58
  69. package/dist/resources/extensions/gsd/tests/doctor-runtime.test.ts +3 -4
  70. package/dist/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
  71. package/dist/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +5 -18
  72. package/dist/resources/extensions/gsd/tests/git-service.test.ts +10 -37
  73. package/dist/resources/extensions/gsd/tests/knowledge.test.ts +4 -4
  74. package/dist/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
  75. package/dist/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
  76. package/dist/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
  77. package/dist/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
  78. package/dist/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
  79. package/dist/resources/extensions/gsd/triage-resolution.ts +2 -1
  80. package/dist/resources/extensions/gsd/types.ts +2 -0
  81. package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
  82. package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
  83. package/dist/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
  84. package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
  85. package/dist/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
  86. package/dist/resources/extensions/gsd/workflow-templates/registry.json +85 -0
  87. package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
  88. package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
  89. package/dist/resources/extensions/gsd/workflow-templates/spike.md +69 -0
  90. package/dist/resources/extensions/gsd/workflow-templates.ts +241 -0
  91. package/dist/resources/extensions/gsd/worktree-command.ts +1 -11
  92. package/dist/resources/extensions/gsd/worktree-manager.ts +3 -2
  93. package/dist/resources/extensions/gsd/worktree.ts +42 -5
  94. package/dist/resources/extensions/mac-tools/extension-manifest.json +16 -0
  95. package/dist/resources/extensions/mcp-client/index.ts +459 -0
  96. package/dist/resources/extensions/mcporter/extension-manifest.json +12 -0
  97. package/dist/resources/extensions/remote-questions/discord-adapter.ts +8 -19
  98. package/dist/resources/extensions/remote-questions/extension-manifest.json +11 -0
  99. package/dist/resources/extensions/remote-questions/http-client.ts +76 -0
  100. package/dist/resources/extensions/remote-questions/slack-adapter.ts +11 -17
  101. package/dist/resources/extensions/remote-questions/telegram-adapter.ts +8 -19
  102. package/dist/resources/extensions/search-the-web/extension-manifest.json +13 -0
  103. package/dist/resources/extensions/slash-commands/extension-manifest.json +11 -0
  104. package/dist/resources/extensions/subagent/extension-manifest.json +13 -0
  105. package/dist/resources/extensions/ttsr/extension-manifest.json +11 -0
  106. package/dist/resources/extensions/universal-config/extension-manifest.json +13 -0
  107. package/dist/resources/extensions/voice/extension-manifest.json +12 -0
  108. package/dist/resources/skills/create-gsd-extension/SKILL.md +87 -0
  109. package/dist/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
  110. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
  111. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
  112. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
  113. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
  114. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
  115. package/dist/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
  116. package/dist/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
  117. package/dist/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
  118. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
  119. package/dist/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
  120. package/dist/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
  121. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
  122. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
  123. package/dist/resources/skills/create-gsd-extension/references/state-management.md +70 -0
  124. package/dist/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
  125. package/dist/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
  126. package/dist/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
  127. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
  128. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
  129. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
  130. package/dist/resources/skills/create-skill/SKILL.md +184 -0
  131. package/dist/resources/skills/create-skill/references/api-security.md +226 -0
  132. package/dist/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
  133. package/dist/resources/skills/create-skill/references/common-patterns.md +595 -0
  134. package/dist/resources/skills/create-skill/references/core-principles.md +437 -0
  135. package/dist/resources/skills/create-skill/references/executable-code.md +175 -0
  136. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
  137. package/dist/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
  138. package/dist/resources/skills/create-skill/references/recommended-structure.md +168 -0
  139. package/dist/resources/skills/create-skill/references/skill-structure.md +372 -0
  140. package/dist/resources/skills/create-skill/references/use-xml-tags.md +466 -0
  141. package/dist/resources/skills/create-skill/references/using-scripts.md +113 -0
  142. package/dist/resources/skills/create-skill/references/using-templates.md +112 -0
  143. package/dist/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
  144. package/dist/resources/skills/create-skill/templates/router-skill.md +73 -0
  145. package/dist/resources/skills/create-skill/templates/simple-skill.md +33 -0
  146. package/dist/resources/skills/create-skill/workflows/add-reference.md +96 -0
  147. package/dist/resources/skills/create-skill/workflows/add-script.md +93 -0
  148. package/dist/resources/skills/create-skill/workflows/add-template.md +74 -0
  149. package/dist/resources/skills/create-skill/workflows/add-workflow.md +120 -0
  150. package/dist/resources/skills/create-skill/workflows/audit-skill.md +148 -0
  151. package/dist/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
  152. package/dist/resources/skills/create-skill/workflows/get-guidance.md +121 -0
  153. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
  154. package/dist/resources/skills/create-skill/workflows/verify-skill.md +204 -0
  155. package/dist/resources/skills/react-best-practices/SKILL.md +1 -1
  156. package/dist/worktree-cli.d.ts +34 -0
  157. package/dist/worktree-cli.js +294 -0
  158. package/dist/worktree-name-gen.d.ts +7 -0
  159. package/dist/worktree-name-gen.js +44 -0
  160. package/package.json +1 -1
  161. package/packages/native/dist/native.d.ts +2 -0
  162. package/packages/native/dist/native.js +19 -5
  163. package/packages/native/src/native.ts +23 -9
  164. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  165. package/packages/pi-coding-agent/dist/core/extensions/loader.js +13 -0
  166. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  167. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -0
  169. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  170. package/packages/pi-coding-agent/package.json +1 -1
  171. package/packages/pi-coding-agent/src/core/extensions/loader.ts +13 -0
  172. package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -0
  173. package/pkg/package.json +1 -1
  174. package/src/resources/extensions/async-jobs/extension-manifest.json +13 -0
  175. package/src/resources/extensions/bg-shell/extension-manifest.json +14 -0
  176. package/src/resources/extensions/bg-shell/process-manager.ts +13 -0
  177. package/src/resources/extensions/browser-tools/extension-manifest.json +37 -0
  178. package/src/resources/extensions/context7/extension-manifest.json +12 -0
  179. package/src/resources/extensions/google-search/extension-manifest.json +12 -0
  180. package/src/resources/extensions/gsd/auto-dashboard.ts +31 -0
  181. package/src/resources/extensions/gsd/auto-dispatch.ts +32 -3
  182. package/src/resources/extensions/gsd/auto-post-unit.ts +45 -13
  183. package/src/resources/extensions/gsd/auto-prompts.ts +40 -17
  184. package/src/resources/extensions/gsd/auto-recovery.ts +18 -23
  185. package/src/resources/extensions/gsd/auto-start.ts +18 -32
  186. package/src/resources/extensions/gsd/auto-worktree.ts +21 -182
  187. package/src/resources/extensions/gsd/auto.ts +2 -24
  188. package/src/resources/extensions/gsd/captures.ts +4 -10
  189. package/src/resources/extensions/gsd/commands-extensions.ts +328 -0
  190. package/src/resources/extensions/gsd/commands-handlers.ts +22 -2
  191. package/src/resources/extensions/gsd/commands-logs.ts +13 -14
  192. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +44 -14
  193. package/src/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
  194. package/src/resources/extensions/gsd/commands.ts +108 -24
  195. package/src/resources/extensions/gsd/dashboard-overlay.ts +2 -1
  196. package/src/resources/extensions/gsd/detection.ts +2 -1
  197. package/src/resources/extensions/gsd/doctor-checks.ts +49 -1
  198. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  199. package/src/resources/extensions/gsd/extension-manifest.json +18 -0
  200. package/src/resources/extensions/gsd/forensics.ts +2 -2
  201. package/src/resources/extensions/gsd/git-service.ts +3 -2
  202. package/src/resources/extensions/gsd/gitignore.ts +9 -63
  203. package/src/resources/extensions/gsd/gsd-db.ts +1 -165
  204. package/src/resources/extensions/gsd/guided-flow.ts +8 -5
  205. package/src/resources/extensions/gsd/index.ts +16 -3
  206. package/src/resources/extensions/gsd/json-persistence.ts +16 -1
  207. package/src/resources/extensions/gsd/md-importer.ts +3 -2
  208. package/src/resources/extensions/gsd/mechanical-completion.ts +430 -0
  209. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  210. package/src/resources/extensions/gsd/migrate/writer.ts +2 -1
  211. package/src/resources/extensions/gsd/migrate-external.ts +123 -0
  212. package/src/resources/extensions/gsd/paths.ts +24 -2
  213. package/src/resources/extensions/gsd/post-unit-hooks.ts +6 -5
  214. package/src/resources/extensions/gsd/preferences-models.ts +7 -1
  215. package/src/resources/extensions/gsd/preferences-validation.ts +2 -1
  216. package/src/resources/extensions/gsd/preferences.ts +10 -5
  217. package/src/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
  218. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  219. package/src/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
  220. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -1
  221. package/src/resources/extensions/gsd/prompts/workflow-start.md +28 -0
  222. package/src/resources/extensions/gsd/queue-order.ts +10 -11
  223. package/src/resources/extensions/gsd/repo-identity.ts +148 -0
  224. package/src/resources/extensions/gsd/resource-version.ts +99 -0
  225. package/src/resources/extensions/gsd/roadmap-slices.ts +22 -7
  226. package/src/resources/extensions/gsd/session-forensics.ts +4 -3
  227. package/src/resources/extensions/gsd/session-lock.ts +53 -4
  228. package/src/resources/extensions/gsd/session-status-io.ts +23 -41
  229. package/src/resources/extensions/gsd/tests/activity-log.test.ts +2 -2
  230. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
  231. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +3 -3
  232. package/src/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
  233. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +0 -58
  234. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +3 -4
  235. package/src/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
  236. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +5 -18
  237. package/src/resources/extensions/gsd/tests/git-service.test.ts +10 -37
  238. package/src/resources/extensions/gsd/tests/knowledge.test.ts +4 -4
  239. package/src/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
  240. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
  241. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
  242. package/src/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
  243. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
  244. package/src/resources/extensions/gsd/triage-resolution.ts +2 -1
  245. package/src/resources/extensions/gsd/types.ts +2 -0
  246. package/src/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
  247. package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
  248. package/src/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
  249. package/src/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
  250. package/src/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
  251. package/src/resources/extensions/gsd/workflow-templates/registry.json +85 -0
  252. package/src/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
  253. package/src/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
  254. package/src/resources/extensions/gsd/workflow-templates/spike.md +69 -0
  255. package/src/resources/extensions/gsd/workflow-templates.ts +241 -0
  256. package/src/resources/extensions/gsd/worktree-command.ts +1 -11
  257. package/src/resources/extensions/gsd/worktree-manager.ts +3 -2
  258. package/src/resources/extensions/gsd/worktree.ts +42 -5
  259. package/src/resources/extensions/mac-tools/extension-manifest.json +16 -0
  260. package/src/resources/extensions/mcp-client/index.ts +459 -0
  261. package/src/resources/extensions/mcporter/extension-manifest.json +12 -0
  262. package/src/resources/extensions/remote-questions/discord-adapter.ts +8 -19
  263. package/src/resources/extensions/remote-questions/extension-manifest.json +11 -0
  264. package/src/resources/extensions/remote-questions/http-client.ts +76 -0
  265. package/src/resources/extensions/remote-questions/slack-adapter.ts +11 -17
  266. package/src/resources/extensions/remote-questions/telegram-adapter.ts +8 -19
  267. package/src/resources/extensions/search-the-web/extension-manifest.json +13 -0
  268. package/src/resources/extensions/slash-commands/extension-manifest.json +11 -0
  269. package/src/resources/extensions/subagent/extension-manifest.json +13 -0
  270. package/src/resources/extensions/ttsr/extension-manifest.json +11 -0
  271. package/src/resources/extensions/universal-config/extension-manifest.json +13 -0
  272. package/src/resources/extensions/voice/extension-manifest.json +12 -0
  273. package/src/resources/skills/create-gsd-extension/SKILL.md +87 -0
  274. package/src/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
  275. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
  276. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
  277. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
  278. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
  279. package/src/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
  280. package/src/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
  281. package/src/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
  282. package/src/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
  283. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
  284. package/src/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
  285. package/src/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
  286. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
  287. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
  288. package/src/resources/skills/create-gsd-extension/references/state-management.md +70 -0
  289. package/src/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
  290. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
  291. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
  292. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
  293. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
  294. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
  295. package/src/resources/skills/create-skill/SKILL.md +184 -0
  296. package/src/resources/skills/create-skill/references/api-security.md +226 -0
  297. package/src/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
  298. package/src/resources/skills/create-skill/references/common-patterns.md +595 -0
  299. package/src/resources/skills/create-skill/references/core-principles.md +437 -0
  300. package/src/resources/skills/create-skill/references/executable-code.md +175 -0
  301. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
  302. package/src/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
  303. package/src/resources/skills/create-skill/references/recommended-structure.md +168 -0
  304. package/src/resources/skills/create-skill/references/skill-structure.md +372 -0
  305. package/src/resources/skills/create-skill/references/use-xml-tags.md +466 -0
  306. package/src/resources/skills/create-skill/references/using-scripts.md +113 -0
  307. package/src/resources/skills/create-skill/references/using-templates.md +112 -0
  308. package/src/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
  309. package/src/resources/skills/create-skill/templates/router-skill.md +73 -0
  310. package/src/resources/skills/create-skill/templates/simple-skill.md +33 -0
  311. package/src/resources/skills/create-skill/workflows/add-reference.md +96 -0
  312. package/src/resources/skills/create-skill/workflows/add-script.md +93 -0
  313. package/src/resources/skills/create-skill/workflows/add-template.md +74 -0
  314. package/src/resources/skills/create-skill/workflows/add-workflow.md +120 -0
  315. package/src/resources/skills/create-skill/workflows/audit-skill.md +148 -0
  316. package/src/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
  317. package/src/resources/skills/create-skill/workflows/get-guidance.md +121 -0
  318. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
  319. package/src/resources/skills/create-skill/workflows/verify-skill.md +204 -0
  320. package/src/resources/skills/react-best-practices/SKILL.md +1 -1
  321. package/dist/resources/extensions/gsd/auto-worktree-sync.ts +0 -198
  322. package/dist/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -205
  323. package/dist/resources/extensions/gsd/tests/worktree-db.test.ts +0 -442
  324. package/dist/resources/extensions/mcporter/index.ts +0 -525
  325. package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -198
  326. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -205
  327. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +0 -442
  328. package/src/resources/extensions/mcporter/index.ts +0 -525
@@ -0,0 +1,490 @@
1
+ <overview>
2
+ Complete custom UI reference — dialogs, persistent elements, custom components, overlays, custom editors, built-in components, keyboard input, performance, theming, and common mistakes.
3
+ </overview>
4
+
5
+ <ui_architecture>
6
+ ```
7
+ ┌─────────────────────────────────────────────────┐
8
+ │ Custom Header (ctx.ui.setHeader) │
9
+ ├─────────────────────────────────────────────────┤
10
+ │ Message Area │
11
+ │ - User/assistant messages │
12
+ │ - Tool calls ◄── renderCall/renderResult │
13
+ │ - Custom messages ◄── registerMessageRenderer │
14
+ ├─────────────────────────────────────────────────┤
15
+ │ Widgets (above editor) ◄── ctx.ui.setWidget │
16
+ ├─────────────────────────────────────────────────┤
17
+ │ Editor ◄── ctx.ui.custom() / setEditorComponent│
18
+ ├─────────────────────────────────────────────────┤
19
+ │ Widgets (below editor) ◄── ctx.ui.setWidget │
20
+ ├─────────────────────────────────────────────────┤
21
+ │ Footer ◄── ctx.ui.setFooter / setStatus │
22
+ └─────────────────────────────────────────────────┘
23
+ ┌─────────────────────┐
24
+ │ Overlay (floating) │ ◄── ctx.ui.custom({ overlay })
25
+ └─────────────────────┘
26
+ ```
27
+
28
+ **11 ways to get UI on screen:**
29
+
30
+ | Method | Blocks? | Replaces editor? |
31
+ |--------|---------|-------------------|
32
+ | `ctx.ui.select/confirm/input/editor` | Yes | Temporarily |
33
+ | `ctx.ui.notify` | No | No |
34
+ | `ctx.ui.setStatus` | No | No (footer) |
35
+ | `ctx.ui.setWidget` | No | No |
36
+ | `ctx.ui.setFooter` | No | No (replaces footer) |
37
+ | `ctx.ui.setHeader` | No | No (replaces header) |
38
+ | `ctx.ui.custom()` | Yes | Temporarily |
39
+ | `ctx.ui.custom({overlay})` | Yes | No (renders on top) |
40
+ | `ctx.ui.setEditorComponent` | No | Yes (permanently) |
41
+ | `renderCall/renderResult` | No | No (inline in messages) |
42
+ | `registerMessageRenderer` | No | No (inline in messages) |
43
+ </ui_architecture>
44
+
45
+ <component_interface>
46
+ Every visual element implements:
47
+
48
+ ```typescript
49
+ interface Component {
50
+ render(width: number): string[]; // Required — each line ≤ width visible chars
51
+ handleInput?(data: string): void; // Optional — receive keyboard input
52
+ wantsKeyRelease?: boolean; // Optional — receive key release events (Kitty protocol)
53
+ invalidate(): void; // Required — clear cached render state
54
+ }
55
+ ```
56
+
57
+ **Render contract:**
58
+ - Return array of strings, one per line
59
+ - Each string MUST NOT exceed `width` in visible characters
60
+ - ANSI escape codes don't count toward visible width
61
+ - **Styles are reset at end of each line** — reapply per line
62
+ - Return `[]` for zero-height component
63
+
64
+ **Invalidation contract:**
65
+ - Clear ALL cached render output
66
+ - Clear any pre-baked themed strings
67
+ - Call `super.invalidate()` if extending a built-in component
68
+ </component_interface>
69
+
70
+ <dialogs>
71
+ Blocking dialog methods on `ctx.ui`:
72
+
73
+ ```typescript
74
+ const choice = await ctx.ui.select("Pick one:", ["A", "B", "C"]); // string | undefined
75
+ const ok = await ctx.ui.confirm("Delete?", "This cannot be undone"); // boolean
76
+ const name = await ctx.ui.input("Name:", "placeholder"); // string | undefined
77
+ const text = await ctx.ui.editor("Edit:", "prefilled text"); // string | undefined
78
+
79
+ // Timed auto-dismiss with countdown
80
+ const ok = await ctx.ui.confirm("Proceed?", "Auto-continues in 5s", { timeout: 5000 });
81
+ // Returns false on timeout, undefined for select/input
82
+
83
+ // Manual dismissal with AbortSignal (distinguish timeout from cancel)
84
+ const controller = new AbortController();
85
+ const timeoutId = setTimeout(() => controller.abort(), 5000);
86
+ const ok = await ctx.ui.confirm("Timed", "Auto-cancels in 5s", { signal: controller.signal });
87
+ clearTimeout(timeoutId);
88
+ if (controller.signal.aborted) { /* timed out */ }
89
+ ```
90
+ </dialogs>
91
+
92
+ <persistent_ui>
93
+ ```typescript
94
+ // Footer status (multiple extensions can set independent entries)
95
+ ctx.ui.setStatus("my-ext", "● Active");
96
+ ctx.ui.setStatus("my-ext", undefined); // Clear
97
+
98
+ // Widgets
99
+ ctx.ui.setWidget("my-id", ["Line 1", "Line 2"]); // Above editor
100
+ ctx.ui.setWidget("my-id", ["Below"], { placement: "belowEditor" }); // Below editor
101
+ ctx.ui.setWidget("my-id", (_tui, theme) => ({ // Themed
102
+ render: () => [theme.fg("accent", "Styled")],
103
+ invalidate: () => {},
104
+ }));
105
+ ctx.ui.setWidget("my-id", undefined); // Clear
106
+
107
+ // Working message during streaming
108
+ ctx.ui.setWorkingMessage("Analyzing code...");
109
+ ctx.ui.setWorkingMessage(); // Restore default
110
+
111
+ // Custom footer (full replacement)
112
+ ctx.ui.setFooter((tui, theme, footerData) => ({
113
+ render(width) {
114
+ const branch = footerData.getGitBranch(); // Only available here
115
+ const statuses = footerData.getExtensionStatuses(); // All setStatus values
116
+ return [truncateToWidth(`${branch} | model`, width)];
117
+ },
118
+ invalidate() {},
119
+ dispose: footerData.onBranchChange(() => tui.requestRender()), // Reactive
120
+ }));
121
+ ctx.ui.setFooter(undefined); // Restore default
122
+
123
+ // Custom header
124
+ ctx.ui.setHeader((tui, theme) => ({
125
+ render(width) { return [theme.fg("accent", theme.bold("My Header"))]; },
126
+ invalidate() {},
127
+ }));
128
+
129
+ // Editor control
130
+ ctx.ui.setEditorText("Prefill");
131
+ const current = ctx.ui.getEditorText();
132
+ ctx.ui.pasteToEditor("pasted content"); // Triggers paste handling
133
+
134
+ // Tool expansion
135
+ ctx.ui.setToolsExpanded(true);
136
+ const expanded = ctx.ui.getToolsExpanded();
137
+
138
+ // Theme management
139
+ const themes = ctx.ui.getAllThemes();
140
+ ctx.ui.setTheme("light");
141
+ ctx.ui.theme.fg("accent", "text"); // Access current theme
142
+ ```
143
+ </persistent_ui>
144
+
145
+ <custom_components>
146
+ `ctx.ui.custom()` temporarily replaces the editor. Returns a value when `done()` is called.
147
+
148
+ **Factory callback args:**
149
+
150
+ | Argument | Type | Purpose |
151
+ |----------|------|---------|
152
+ | `tui` | `TUI` | `tui.requestRender()` triggers re-render after state changes |
153
+ | `theme` | `Theme` | Current theme for styling |
154
+ | `keybindings` | `KeybindingsManager` | App keybinding config |
155
+ | `done` | `(value: T) => void` | Close component and return value |
156
+
157
+ **Inline pattern:**
158
+ ```typescript
159
+ const result = await ctx.ui.custom<string | null>((tui, theme, keybindings, done) => ({
160
+ render(width: number): string[] {
161
+ return [truncateToWidth("Press Enter to confirm, Escape to cancel", width)];
162
+ },
163
+ handleInput(data: string) {
164
+ if (matchesKey(data, Key.enter)) done("confirmed");
165
+ if (matchesKey(data, Key.escape)) done(null);
166
+ },
167
+ invalidate() {},
168
+ }));
169
+ ```
170
+
171
+ **Class-based pattern (recommended for complex UI):**
172
+ ```typescript
173
+ class MyComponent {
174
+ private selected = 0;
175
+ private cachedWidth?: number;
176
+ private cachedLines?: string[];
177
+
178
+ constructor(
179
+ private tui: { requestRender: () => void },
180
+ private theme: Theme,
181
+ private items: string[],
182
+ private done: (value: string | null) => void,
183
+ ) {}
184
+
185
+ handleInput(data: string) {
186
+ if (matchesKey(data, Key.up) && this.selected > 0) this.selected--;
187
+ else if (matchesKey(data, Key.down) && this.selected < this.items.length - 1) this.selected++;
188
+ else if (matchesKey(data, Key.enter)) { this.done(this.items[this.selected]); return; }
189
+ else if (matchesKey(data, Key.escape)) { this.done(null); return; }
190
+ else return;
191
+ this.invalidate();
192
+ this.tui.requestRender();
193
+ }
194
+
195
+ render(width: number): string[] {
196
+ if (this.cachedLines && this.cachedWidth === width) return this.cachedLines;
197
+ this.cachedLines = this.items.map((item, i) =>
198
+ truncateToWidth((i === this.selected ? "> " : " ") + item, width)
199
+ );
200
+ this.cachedWidth = width;
201
+ return this.cachedLines;
202
+ }
203
+
204
+ invalidate() { this.cachedWidth = undefined; this.cachedLines = undefined; }
205
+ }
206
+
207
+ const result = await ctx.ui.custom<string | null>((tui, theme, _kb, done) =>
208
+ new MyComponent(tui, theme, ["A", "B", "C"], done)
209
+ );
210
+ ```
211
+
212
+ **Composing with built-in components:**
213
+ ```typescript
214
+ const result = await ctx.ui.custom<string | null>((tui, theme, _kb, done) => {
215
+ const container = new Container();
216
+ container.addChild(new DynamicBorder((s: string) => theme.fg("accent", s)));
217
+ container.addChild(new Text(theme.fg("accent", theme.bold("Title")), 1, 0));
218
+
219
+ const selectList = new SelectList(items, 10, {
220
+ selectedPrefix: (t) => theme.fg("accent", t),
221
+ selectedText: (t) => theme.fg("accent", t),
222
+ description: (t) => theme.fg("muted", t),
223
+ scrollInfo: (t) => theme.fg("dim", t),
224
+ noMatch: (t) => theme.fg("warning", t),
225
+ });
226
+ selectList.onSelect = (item) => done(item.value);
227
+ selectList.onCancel = () => done(null);
228
+ container.addChild(selectList);
229
+
230
+ return {
231
+ render: (w) => container.render(w),
232
+ invalidate: () => container.invalidate(),
233
+ handleInput: (data) => { selectList.handleInput(data); tui.requestRender(); },
234
+ };
235
+ });
236
+ ```
237
+ </custom_components>
238
+
239
+ <overlays>
240
+ Floating modals rendered on top of everything:
241
+
242
+ ```typescript
243
+ const result = await ctx.ui.custom<string | null>(
244
+ (tui, theme, _kb, done) => new MyDialog({ onClose: done }),
245
+ {
246
+ overlay: true,
247
+ overlayOptions: {
248
+ anchor: "center", // 9 positions (see below)
249
+ width: "50%", // number = columns, string = percentage
250
+ minWidth: 40,
251
+ maxHeight: "80%",
252
+ margin: 2, // All sides, or { top, right, bottom, left }
253
+ offsetX: 0, offsetY: 0, // Fine-tune position
254
+ visible: (w, h) => w >= 80, // Hide on narrow terminals
255
+ },
256
+ onHandle: (handle) => {
257
+ // handle.setHidden(true/false) — temporarily hide
258
+ // handle.hide() — permanently remove
259
+ },
260
+ }
261
+ );
262
+ ```
263
+
264
+ **Anchor positions:**
265
+ ```
266
+ top-left top-center top-right
267
+ left-center center right-center
268
+ bottom-left bottom-center bottom-right
269
+ ```
270
+
271
+ **Stacked overlays:** Multiple overlays stack (newest on top). Closing one gives focus to the one below.
272
+
273
+ **⚠️ Overlay lifecycle:** Components are disposed when closed. Never reuse references — create fresh instances each time.
274
+ </overlays>
275
+
276
+ <custom_editor>
277
+ Replace the main input editor permanently:
278
+
279
+ ```typescript
280
+ import { CustomEditor } from "@mariozechner/pi-coding-agent";
281
+
282
+ class VimEditor extends CustomEditor {
283
+ private mode: "normal" | "insert" = "insert";
284
+
285
+ handleInput(data: string): void {
286
+ if (matchesKey(data, "escape") && this.mode === "insert") {
287
+ this.mode = "normal"; return;
288
+ }
289
+ if (this.mode === "insert") { super.handleInput(data); return; }
290
+ switch (data) {
291
+ case "i": this.mode = "insert"; return;
292
+ case "h": super.handleInput("\x1b[D"); return; // Left
293
+ case "j": super.handleInput("\x1b[B"); return; // Down
294
+ case "k": super.handleInput("\x1b[A"); return; // Up
295
+ case "l": super.handleInput("\x1b[C"); return; // Right
296
+ }
297
+ if (data.length === 1 && data.charCodeAt(0) >= 32) return; // Block printable in normal
298
+ super.handleInput(data);
299
+ }
300
+ }
301
+
302
+ ctx.ui.setEditorComponent((_tui, theme, keybindings) => new VimEditor(theme, keybindings));
303
+ ctx.ui.setEditorComponent(undefined); // Restore default
304
+ ```
305
+
306
+ **Critical:** Extend `CustomEditor` (NOT `Editor`) to get app keybindings (escape to abort, ctrl+d, model switching).
307
+ </custom_editor>
308
+
309
+ <built_in_components>
310
+ **From `@mariozechner/pi-tui`:**
311
+
312
+ | Component | Constructor | Purpose |
313
+ |-----------|-------------|---------|
314
+ | `Text` | `new Text(content, paddingX, paddingY, bgFn?)` | Multi-line text with word wrap |
315
+ | `Box` | `new Box(paddingX, paddingY, bgFn)` | Container with padding+background, `.addChild()` |
316
+ | `Container` | `new Container()` | Vertical stack, `.addChild()`, `.removeChild()`, `.clear()` |
317
+ | `Spacer` | `new Spacer(lines)` | Empty vertical space |
318
+ | `Markdown` | `new Markdown(content, padX, padY, getMarkdownTheme())` | Rendered markdown with syntax highlighting |
319
+ | `Image` | `new Image(base64, mimeType, theme, opts?)` | Image rendering (Kitty, iTerm2) |
320
+ | `SelectList` | `new SelectList(items, maxVisible, themeOpts)` | Interactive selection with search and scrolling |
321
+ | `SettingsList` | `new SettingsList(items, maxVisible, theme, onChange, onClose, opts?)` | Toggle settings with left/right arrows |
322
+ | `Input` | `new Input()` | Text input field |
323
+ | `Editor` | `new Editor(tui, editorTheme)` | Multi-line editor with undo |
324
+
325
+ **SelectList usage:**
326
+ ```typescript
327
+ const items: SelectItem[] = [
328
+ { value: "opt1", label: "Option 1", description: "First option" },
329
+ { value: "opt2", label: "Option 2" },
330
+ ];
331
+ const selectList = new SelectList(items, 10, {
332
+ selectedPrefix: (t) => theme.fg("accent", t),
333
+ selectedText: (t) => theme.fg("accent", t),
334
+ description: (t) => theme.fg("muted", t),
335
+ scrollInfo: (t) => theme.fg("dim", t),
336
+ noMatch: (t) => theme.fg("warning", t),
337
+ });
338
+ selectList.onSelect = (item) => { /* item.value */ };
339
+ selectList.onCancel = () => { /* escape pressed */ };
340
+ ```
341
+
342
+ **SettingsList usage:**
343
+ ```typescript
344
+ const items: SettingItem[] = [
345
+ { id: "verbose", label: "Verbose mode", currentValue: "off", values: ["on", "off"] },
346
+ { id: "theme", label: "Theme", currentValue: "dark", values: ["dark", "light", "auto"] },
347
+ ];
348
+ const settings = new SettingsList(items, 15, getSettingsListTheme(),
349
+ (id, newValue) => { /* setting changed */ },
350
+ () => { /* close requested */ },
351
+ { enableSearch: true },
352
+ );
353
+ ```
354
+
355
+ **From `@mariozechner/pi-coding-agent`:**
356
+
357
+ | Component | Constructor | Purpose |
358
+ |-----------|-------------|---------|
359
+ | `DynamicBorder` | `new DynamicBorder((s: string) => theme.fg("accent", s))` | Border line |
360
+ | `BorderedLoader` | — | Spinner with cancel support |
361
+ | `CustomEditor` | `new CustomEditor(theme, keybindings)` | Base class for custom editors |
362
+ </built_in_components>
363
+
364
+ <keyboard_input>
365
+ ```typescript
366
+ import { matchesKey, Key } from "@mariozechner/pi-tui";
367
+
368
+ handleInput(data: string) {
369
+ // Basic keys
370
+ if (matchesKey(data, Key.up)) {}
371
+ if (matchesKey(data, Key.down)) {}
372
+ if (matchesKey(data, Key.enter)) {}
373
+ if (matchesKey(data, Key.escape)) {}
374
+ if (matchesKey(data, Key.tab)) {}
375
+ if (matchesKey(data, Key.space)) {}
376
+ if (matchesKey(data, Key.backspace)) {}
377
+ if (matchesKey(data, Key.home)) {}
378
+ if (matchesKey(data, Key.end)) {}
379
+
380
+ // With modifiers
381
+ if (matchesKey(data, Key.ctrl("c"))) {}
382
+ if (matchesKey(data, Key.shift("tab"))) {}
383
+ if (matchesKey(data, Key.alt("left"))) {}
384
+ if (matchesKey(data, Key.ctrlShift("p"))) {}
385
+
386
+ // String format also works: "enter", "ctrl+c", "shift+tab"
387
+
388
+ // Printable character detection
389
+ if (data.length === 1 && data.charCodeAt(0) >= 32) {
390
+ // Letter, number, symbol
391
+ }
392
+ }
393
+ ```
394
+
395
+ **handleInput contract:**
396
+ 1. Check for your keys
397
+ 2. Update state
398
+ 3. Call `this.invalidate()` if render output changes
399
+ 4. Call `tui.requestRender()` to trigger re-render
400
+ </keyboard_input>
401
+
402
+ <line_width_rule>
403
+ **Cardinal rule: each line from render() must not exceed `width` visible characters.**
404
+
405
+ ```typescript
406
+ import { visibleWidth, truncateToWidth, wrapTextWithAnsi } from "@mariozechner/pi-tui";
407
+
408
+ visibleWidth("\x1b[32mHello\x1b[0m"); // Returns 5 (ignores ANSI codes)
409
+ truncateToWidth("Very long text here", 10); // "Very lo..."
410
+ truncateToWidth("Very long text here", 10, ""); // "Very long " (no ellipsis)
411
+ wrapTextWithAnsi("\x1b[32mLong green text\x1b[0m", 10); // Word wrap preserving ANSI
412
+ ```
413
+
414
+ If lines exceed `width`, terminal wraps cause visual corruption.
415
+ </line_width_rule>
416
+
417
+ <performance_caching>
418
+ Always cache render output:
419
+
420
+ ```typescript
421
+ class CachedComponent {
422
+ private cachedWidth?: number;
423
+ private cachedLines?: string[];
424
+
425
+ render(width: number): string[] {
426
+ if (this.cachedLines && this.cachedWidth === width) return this.cachedLines;
427
+ const lines = this.computeLines(width);
428
+ this.cachedWidth = width;
429
+ this.cachedLines = lines;
430
+ return lines;
431
+ }
432
+
433
+ invalidate() { this.cachedWidth = undefined; this.cachedLines = undefined; }
434
+ }
435
+ ```
436
+
437
+ **Update cycle:** State changes → `invalidate()` → `tui.requestRender()` → `render(width)` called
438
+
439
+ **Game loop pattern** (real-time updates):
440
+ ```typescript
441
+ this.interval = setInterval(() => {
442
+ this.tick();
443
+ this.version++;
444
+ this.tui.requestRender();
445
+ }, 100); // 10 FPS
446
+
447
+ // Clean up in dispose()
448
+ clearInterval(this.interval);
449
+ ```
450
+ </performance_caching>
451
+
452
+ <theme_colors>
453
+ Always use theme from callback params, never import directly.
454
+
455
+ **All foreground colors:**
456
+
457
+ | Category | Colors |
458
+ |----------|--------|
459
+ | General | `text`, `accent`, `muted`, `dim` |
460
+ | Status | `success`, `error`, `warning` |
461
+ | Borders | `border`, `borderAccent`, `borderMuted` |
462
+ | Messages | `userMessageText`, `customMessageText`, `customMessageLabel` |
463
+ | Tools | `toolTitle`, `toolOutput` |
464
+ | Diffs | `toolDiffAdded`, `toolDiffRemoved`, `toolDiffContext` |
465
+ | Markdown | `mdHeading`, `mdLink`, `mdLinkUrl`, `mdCode`, `mdCodeBlock`, `mdCodeBlockBorder`, `mdQuote`, `mdQuoteBorder`, `mdHr`, `mdListBullet` |
466
+ | Syntax | `syntaxComment`, `syntaxKeyword`, `syntaxFunction`, `syntaxVariable`, `syntaxString`, `syntaxNumber`, `syntaxType`, `syntaxOperator`, `syntaxPunctuation` |
467
+ | Thinking | `thinkingOff`, `thinkingMinimal`, `thinkingLow`, `thinkingMedium`, `thinkingHigh`, `thinkingXhigh` |
468
+
469
+ **All background colors:** `selectedBg`, `userMessageBg`, `customMessageBg`, `toolPendingBg`, `toolSuccessBg`, `toolErrorBg`
470
+
471
+ **Syntax highlighting:**
472
+ ```typescript
473
+ import { highlightCode, getLanguageFromPath } from "@mariozechner/pi-coding-agent";
474
+ const lang = getLanguageFromPath("/file.rs"); // "rust"
475
+ const highlighted = highlightCode(code, lang, theme);
476
+ ```
477
+ </theme_colors>
478
+
479
+ <common_mistakes>
480
+ 1. **Lines exceed width** → Visual corruption. Use `truncateToWidth()` on every line.
481
+ 2. **Forgetting `tui.requestRender()`** → UI doesn't update. Call after invalidate().
482
+ 3. **Importing theme directly** → Wrong colors after theme switch. Use theme from callback.
483
+ 4. **Not typing DynamicBorder param** → `new DynamicBorder((s: string) => theme.fg("accent", s))`.
484
+ 5. **Reusing disposed overlay components** → Create fresh instances each time.
485
+ 6. **Styles bleeding across lines** → TUI resets per line. Reapply styles, or use `wrapTextWithAnsi()`.
486
+ 7. **Not implementing invalidate()** → Theme changes don't take effect.
487
+ 8. **Forgetting super.invalidate()** → `override invalidate() { super.invalidate(); /* cleanup */ }`
488
+ 9. **Timer not cleaned up** → Call `clearInterval` before `done()`.
489
+ 10. **Using ctx.ui in non-interactive mode** → Check `ctx.hasUI` first.
490
+ </common_mistakes>
@@ -0,0 +1,126 @@
1
+ <overview>
2
+ Complete event reference with handler signatures, return types, and type narrowing utilities.
3
+ </overview>
4
+
5
+ <event_categories>
6
+
7
+ **Session events:** `session_start`, `session_before_switch`, `session_switch`, `session_before_fork`, `session_fork`, `session_before_compact`, `session_compact`, `session_before_tree`, `session_tree`, `session_shutdown`
8
+
9
+ **Agent events:** `before_agent_start`, `agent_start`, `agent_end`, `turn_start`, `turn_end`, `context`, `before_provider_request`, `message_start`, `message_update`, `message_end`
10
+
11
+ **Tool events:** `tool_call`, `tool_execution_start`, `tool_execution_update`, `tool_execution_end`, `tool_result`
12
+
13
+ **Input events:** `input`
14
+
15
+ **Model events:** `model_select`
16
+
17
+ **User bash events:** `user_bash`
18
+
19
+ **Special:** `session_directory` (CLI startup only, no `ctx` — receives only event)
20
+
21
+ </event_categories>
22
+
23
+ <handler_signature>
24
+ ```typescript
25
+ pi.on("event_name", async (event, ctx: ExtensionContext) => {
26
+ // event — typed payload for this event
27
+ // ctx — access to UI, session, model, control flow
28
+ // Return undefined for no action, or a typed response
29
+ });
30
+ ```
31
+ </handler_signature>
32
+
33
+ <key_events>
34
+
35
+ **before_agent_start** — Fired after user prompt, before agent loop. Primary hook for context injection and system prompt modification.
36
+ ```typescript
37
+ pi.on("before_agent_start", async (event, ctx) => {
38
+ // event.prompt — user's prompt text
39
+ // event.images — attached images
40
+ // event.systemPrompt — current system prompt
41
+ return {
42
+ message: { customType: "my-ext", content: "Extra context", display: true },
43
+ systemPrompt: event.systemPrompt + "\n\nExtra instructions...",
44
+ };
45
+ });
46
+ ```
47
+
48
+ **tool_call** — Fired before tool executes. Can block.
49
+ ```typescript
50
+ import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
51
+
52
+ pi.on("tool_call", async (event, ctx) => {
53
+ if (isToolCallEventType("bash", event)) {
54
+ // event.input is typed as { command: string; timeout?: number }
55
+ if (event.input.command.includes("rm -rf")) {
56
+ return { block: true, reason: "Dangerous command" };
57
+ }
58
+ }
59
+ });
60
+ ```
61
+
62
+ **tool_result** — Fired after tool executes. Can modify result. Handlers chain like middleware.
63
+ ```typescript
64
+ import { isBashToolResult } from "@mariozechner/pi-coding-agent";
65
+
66
+ pi.on("tool_result", async (event, ctx) => {
67
+ if (isBashToolResult(event)) {
68
+ // event.details is typed as BashToolDetails
69
+ }
70
+ // Return partial patch: { content, details, isError }
71
+ // Omitted fields keep current values
72
+ });
73
+ ```
74
+
75
+ **context** — Fired before each LLM call. Modify messages non-destructively.
76
+ ```typescript
77
+ pi.on("context", async (event, ctx) => {
78
+ // event.messages is a deep copy — safe to modify
79
+ const filtered = event.messages.filter(m => !shouldPrune(m));
80
+ return { messages: filtered };
81
+ });
82
+ ```
83
+
84
+ **input** — Fired when user input is received, before skill/template expansion.
85
+ ```typescript
86
+ pi.on("input", async (event, ctx) => {
87
+ // event.text — raw input
88
+ // event.source — "interactive", "rpc", or "extension"
89
+ if (event.text.startsWith("?quick "))
90
+ return { action: "transform", text: `Respond briefly: ${event.text.slice(7)}` };
91
+ return { action: "continue" };
92
+ });
93
+ ```
94
+
95
+ **model_select** — Fired when model changes.
96
+ ```typescript
97
+ pi.on("model_select", async (event, ctx) => {
98
+ // event.model, event.previousModel, event.source ("set"|"cycle"|"restore")
99
+ });
100
+ ```
101
+
102
+ </key_events>
103
+
104
+ <type_narrowing>
105
+ Built-in type guards for tool events:
106
+
107
+ ```typescript
108
+ import { isToolCallEventType, isBashToolResult } from "@mariozechner/pi-coding-agent";
109
+
110
+ // Tool calls — narrows event.input type
111
+ if (isToolCallEventType("bash", event)) { /* event.input: { command, timeout? } */ }
112
+ if (isToolCallEventType("read", event)) { /* event.input: { path, offset?, limit? } */ }
113
+ if (isToolCallEventType("write", event)) { /* event.input: { path, content } */ }
114
+ if (isToolCallEventType("edit", event)) { /* event.input: { path, oldText, newText } */ }
115
+
116
+ // Tool results — narrows event.details type
117
+ if (isBashToolResult(event)) { /* event.details: BashToolDetails */ }
118
+ ```
119
+
120
+ For custom tools, export your input type and use explicit type params:
121
+ ```typescript
122
+ if (isToolCallEventType<"my_tool", MyToolInput>("my_tool", event)) {
123
+ event.input.action; // typed
124
+ }
125
+ ```
126
+ </type_narrowing>
@@ -0,0 +1,64 @@
1
+ <overview>
2
+ The extension lifecycle from load to shutdown, including the full event flow.
3
+ </overview>
4
+
5
+ <loading>
6
+ Extensions load when GSD starts (or on `/reload`). The default export function runs synchronously — subscribe to events and register tools/commands during this call.
7
+
8
+ ```
9
+ GSD starts
10
+ └─► Extension default function runs
11
+ ├── pi.on("event", handler) ← Subscribe
12
+ ├── pi.registerTool({...}) ← Register tools
13
+ ├── pi.registerCommand(...) ← Register commands
14
+ └── pi.registerShortcut(...) ← Register shortcuts
15
+ └─► session_start fires
16
+ ```
17
+ </loading>
18
+
19
+ <event_flow>
20
+ Full event flow per user prompt:
21
+
22
+ ```
23
+ user sends prompt
24
+ ├─► Extension commands checked (bypass if match)
25
+ ├─► input event (can intercept/transform/handle)
26
+ ├─► Skill/template expansion
27
+ ├─► before_agent_start (inject message, modify system prompt)
28
+ ├─► agent_start
29
+
30
+ │ ┌── Turn loop (repeats while LLM calls tools) ──┐
31
+ │ │ turn_start │
32
+ │ │ context (can modify messages sent to LLM) │
33
+ │ │ before_provider_request (inspect/replace payload)│
34
+ │ │ LLM responds → may call tools: │
35
+ │ │ tool_call (can BLOCK) │
36
+ │ │ tool_execution_start/update/end │
37
+ │ │ tool_result (can MODIFY) │
38
+ │ │ turn_end │
39
+ │ └────────────────────────────────────────────────┘
40
+
41
+ └─► agent_end
42
+ ```
43
+ </event_flow>
44
+
45
+ <session_events>
46
+ | Event | When | Can Return |
47
+ |-------|------|------------|
48
+ | `session_start` | Session loads | — |
49
+ | `session_before_switch` | Before `/new` or `/resume` | `{ cancel: true }` |
50
+ | `session_switch` | After switch | — |
51
+ | `session_before_fork` | Before `/fork` | `{ cancel: true }`, `{ skipConversationRestore: true }` |
52
+ | `session_fork` | After fork | — |
53
+ | `session_before_compact` | Before compaction | `{ cancel: true }`, `{ compaction: {...} }` |
54
+ | `session_compact` | After compaction | — |
55
+ | `session_shutdown` | On exit | — |
56
+ </session_events>
57
+
58
+ <hot_reload>
59
+ Extensions in auto-discovered locations hot-reload with `/reload`:
60
+ - `session_shutdown` fires for old runtime
61
+ - Resources re-scanned
62
+ - `session_start` fires for new runtime
63
+ - Code after `await ctx.reload()` still runs from the pre-reload version — treat as terminal
64
+ </hot_reload>