gsd-pi 2.34.0-dev.ed0bfbf → 2.35.0-dev.30eec3f

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 (334) hide show
  1. package/dist/cli.js +7 -2
  2. package/dist/resource-loader.d.ts +1 -1
  3. package/dist/resource-loader.js +13 -1
  4. package/dist/resources/extensions/async-jobs/await-tool.js +0 -2
  5. package/dist/resources/extensions/async-jobs/job-manager.js +0 -6
  6. package/dist/resources/extensions/bg-shell/output-formatter.js +1 -19
  7. package/dist/resources/extensions/bg-shell/process-manager.js +0 -4
  8. package/dist/resources/extensions/bg-shell/types.js +0 -2
  9. package/dist/resources/extensions/context7/index.js +5 -0
  10. package/dist/resources/extensions/get-secrets-from-user.js +2 -30
  11. package/dist/resources/extensions/google-search/index.js +5 -0
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +43 -1
  13. package/dist/resources/extensions/gsd/auto-loop.js +10 -1
  14. package/dist/resources/extensions/gsd/auto-recovery.js +35 -0
  15. package/dist/resources/extensions/gsd/auto-start.js +35 -2
  16. package/dist/resources/extensions/gsd/auto.js +59 -4
  17. package/dist/resources/extensions/gsd/changelog.js +162 -0
  18. package/dist/resources/extensions/gsd/commands-bootstrap.js +1 -0
  19. package/dist/resources/extensions/gsd/commands-handlers.js +2 -2
  20. package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
  21. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +5 -1
  22. package/dist/resources/extensions/gsd/commands.js +8 -1
  23. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  24. package/dist/resources/extensions/gsd/doctor-checks.js +113 -5
  25. package/dist/resources/extensions/gsd/doctor-environment.js +26 -17
  26. package/dist/resources/extensions/gsd/doctor-proactive.js +22 -0
  27. package/dist/resources/extensions/gsd/doctor.js +36 -0
  28. package/dist/resources/extensions/gsd/files.js +11 -2
  29. package/dist/resources/extensions/gsd/gitignore.js +54 -7
  30. package/dist/resources/extensions/gsd/guided-flow.js +5 -3
  31. package/dist/resources/extensions/gsd/health-widget-core.js +96 -0
  32. package/dist/resources/extensions/gsd/health-widget.js +97 -46
  33. package/dist/resources/extensions/gsd/index.js +10 -1
  34. package/dist/resources/extensions/gsd/migrate-external.js +55 -2
  35. package/dist/resources/extensions/gsd/paths.js +74 -7
  36. package/dist/resources/extensions/gsd/post-unit-hooks.js +4 -1
  37. package/dist/resources/extensions/gsd/preferences-validation.js +54 -1
  38. package/dist/resources/extensions/gsd/preferences.js +2 -0
  39. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  40. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  41. package/dist/resources/extensions/gsd/roadmap-mutations.js +55 -0
  42. package/dist/resources/extensions/gsd/session-lock.js +26 -2
  43. package/dist/resources/extensions/gsd/templates/plan.md +8 -0
  44. package/dist/resources/extensions/gsd/worktree-resolver.js +12 -0
  45. package/dist/resources/extensions/remote-questions/remote-command.js +2 -22
  46. package/dist/resources/extensions/shared/mod.js +1 -1
  47. package/dist/resources/extensions/shared/sanitize.js +30 -0
  48. package/dist/resources/extensions/subagent/index.js +6 -14
  49. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  50. package/package.json +2 -1
  51. package/packages/pi-agent-core/dist/agent-loop.d.ts +14 -0
  52. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  53. package/packages/pi-agent-core/dist/agent-loop.js +24 -27
  54. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  55. package/packages/pi-agent-core/dist/agent.d.ts +1 -0
  56. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  57. package/packages/pi-agent-core/dist/agent.js +11 -22
  58. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  59. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  60. package/packages/pi-agent-core/dist/proxy.js +2 -8
  61. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  62. package/packages/pi-agent-core/src/agent-loop.ts +30 -27
  63. package/packages/pi-agent-core/src/agent.ts +12 -23
  64. package/packages/pi-agent-core/src/proxy.ts +2 -8
  65. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  66. package/packages/pi-ai/dist/providers/azure-openai-responses.js +5 -41
  67. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  68. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  69. package/packages/pi-ai/dist/providers/openai-completions.js +10 -73
  70. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  71. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  72. package/packages/pi-ai/dist/providers/openai-responses.js +9 -80
  73. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  74. package/packages/pi-ai/dist/providers/openai-shared.d.ts +65 -0
  75. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -0
  76. package/packages/pi-ai/dist/providers/openai-shared.js +146 -0
  77. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -0
  78. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  79. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +7 -135
  80. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  81. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  82. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +7 -135
  83. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  84. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts +46 -0
  85. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts.map +1 -0
  86. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js +160 -0
  87. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js.map +1 -0
  88. package/packages/pi-ai/src/providers/azure-openai-responses.ts +11 -45
  89. package/packages/pi-ai/src/providers/openai-completions.ts +16 -86
  90. package/packages/pi-ai/src/providers/openai-responses.ts +16 -96
  91. package/packages/pi-ai/src/providers/openai-shared.ts +193 -0
  92. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +14 -162
  93. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +13 -161
  94. package/packages/pi-ai/src/utils/oauth/google-oauth-utils.ts +201 -0
  95. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +16 -63
  96. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  97. package/packages/pi-coding-agent/dist/core/agent-session.js +104 -641
  98. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  99. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +0 -1
  100. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  101. package/packages/pi-coding-agent/dist/core/auth-storage.js +4 -35
  102. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  103. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  104. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js +5 -43
  105. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  106. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  107. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +11 -69
  108. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  109. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +40 -0
  110. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  111. package/packages/pi-coding-agent/dist/core/compaction/utils.js +78 -0
  112. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  113. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +77 -0
  114. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -0
  115. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +331 -0
  116. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -0
  117. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +2 -2
  118. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  119. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  120. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  121. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +15 -0
  122. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  123. package/packages/pi-coding-agent/dist/core/extensions/runner.js +129 -243
  124. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  125. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +49 -42
  126. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  127. package/packages/pi-coding-agent/dist/core/extensions/types.js +2 -21
  128. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  129. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts +39 -0
  130. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts.map +1 -0
  131. package/packages/pi-coding-agent/dist/core/lock-utils.js +89 -0
  132. package/packages/pi-coding-agent/dist/core/lock-utils.js.map +1 -0
  133. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +2 -0
  134. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
  135. package/packages/pi-coding-agent/dist/core/lsp/config.js +4 -1
  136. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  138. package/packages/pi-coding-agent/dist/core/lsp/index.js +52 -107
  139. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  140. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  141. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +2 -21
  142. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  143. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +0 -1
  144. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
  145. package/packages/pi-coding-agent/dist/core/lsp/types.js +0 -28
  146. package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  148. package/packages/pi-coding-agent/dist/core/package-manager.js +2 -4
  149. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  150. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +2 -4
  151. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  152. package/packages/pi-coding-agent/dist/core/resource-loader.js +46 -60
  153. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +87 -0
  155. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -0
  156. package/packages/pi-coding-agent/dist/core/retry-handler.js +295 -0
  157. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -0
  158. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +0 -1
  159. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/session-manager.js +3 -28
  161. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +8 -0
  163. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  164. package/packages/pi-coding-agent/dist/core/settings-manager.js +76 -166
  165. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  167. package/packages/pi-coding-agent/dist/core/skills.js +1 -3
  168. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  169. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  170. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  171. package/packages/pi-coding-agent/dist/index.js +1 -1
  172. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  173. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +1 -1
  174. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  175. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +9 -26
  176. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  177. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  178. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -13
  179. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  180. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
  181. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
  182. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js +61 -0
  183. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
  184. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  185. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +6 -9
  186. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +65 -0
  188. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  189. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +6 -16
  190. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +12 -0
  192. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  193. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +175 -0
  194. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -0
  195. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
  196. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
  197. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js +15 -0
  198. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js.map +1 -0
  199. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  200. package/packages/pi-coding-agent/dist/modes/print-mode.js +2 -30
  201. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  202. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  203. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -28
  204. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts +19 -0
  206. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts.map +1 -0
  207. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js +45 -0
  208. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js.map +1 -0
  209. package/packages/pi-coding-agent/dist/utils/error.d.ts +5 -0
  210. package/packages/pi-coding-agent/dist/utils/error.d.ts.map +1 -0
  211. package/packages/pi-coding-agent/dist/utils/error.js +7 -0
  212. package/packages/pi-coding-agent/dist/utils/error.js.map +1 -0
  213. package/packages/pi-coding-agent/package.json +1 -1
  214. package/packages/pi-coding-agent/src/core/agent-session.ts +117 -745
  215. package/packages/pi-coding-agent/src/core/auth-storage.ts +4 -38
  216. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +7 -53
  217. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +14 -74
  218. package/packages/pi-coding-agent/src/core/compaction/utils.ts +100 -0
  219. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +424 -0
  220. package/packages/pi-coding-agent/src/core/extensions/index.ts +1 -21
  221. package/packages/pi-coding-agent/src/core/extensions/runner.ts +119 -243
  222. package/packages/pi-coding-agent/src/core/extensions/types.ts +50 -69
  223. package/packages/pi-coding-agent/src/core/lock-utils.ts +113 -0
  224. package/packages/pi-coding-agent/src/core/lsp/config.ts +4 -1
  225. package/packages/pi-coding-agent/src/core/lsp/index.ts +83 -152
  226. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +2 -22
  227. package/packages/pi-coding-agent/src/core/lsp/types.ts +0 -29
  228. package/packages/pi-coding-agent/src/core/package-manager.ts +1 -4
  229. package/packages/pi-coding-agent/src/core/resource-loader.ts +56 -69
  230. package/packages/pi-coding-agent/src/core/retry-handler.ts +359 -0
  231. package/packages/pi-coding-agent/src/core/session-manager.ts +3 -30
  232. package/packages/pi-coding-agent/src/core/settings-manager.ts +85 -164
  233. package/packages/pi-coding-agent/src/core/skills.ts +1 -4
  234. package/packages/pi-coding-agent/src/index.ts +1 -7
  235. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +17 -29
  236. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -13
  237. package/packages/pi-coding-agent/src/modes/interactive/components/tree-render-utils.ts +81 -0
  238. package/packages/pi-coding-agent/src/modes/interactive/components/tree-selector.ts +14 -19
  239. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +7 -18
  240. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +196 -0
  241. package/packages/pi-coding-agent/src/modes/interactive/utils/shorten-path.ts +14 -0
  242. package/packages/pi-coding-agent/src/modes/print-mode.ts +2 -30
  243. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -28
  244. package/packages/pi-coding-agent/src/modes/shared/command-context-actions.ts +53 -0
  245. package/packages/pi-coding-agent/src/utils/error.ts +6 -0
  246. package/packages/pi-tui/dist/components/markdown.d.ts +5 -0
  247. package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
  248. package/packages/pi-tui/dist/components/markdown.js +25 -31
  249. package/packages/pi-tui/dist/components/markdown.js.map +1 -1
  250. package/packages/pi-tui/dist/keys.d.ts +0 -4
  251. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  252. package/packages/pi-tui/dist/keys.js +94 -162
  253. package/packages/pi-tui/dist/keys.js.map +1 -1
  254. package/packages/pi-tui/src/components/markdown.ts +25 -29
  255. package/packages/pi-tui/src/keys.ts +94 -173
  256. package/pkg/dist/modes/interactive/theme/theme.d.ts +65 -0
  257. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  258. package/pkg/dist/modes/interactive/theme/theme.js +6 -16
  259. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  260. package/pkg/dist/modes/interactive/theme/themes.d.ts +12 -0
  261. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  262. package/pkg/dist/modes/interactive/theme/themes.js +175 -0
  263. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -0
  264. package/pkg/package.json +1 -1
  265. package/src/resources/extensions/async-jobs/await-tool.ts +0 -2
  266. package/src/resources/extensions/async-jobs/job-manager.ts +0 -7
  267. package/src/resources/extensions/bg-shell/output-formatter.ts +0 -17
  268. package/src/resources/extensions/bg-shell/process-manager.ts +0 -4
  269. package/src/resources/extensions/bg-shell/types.ts +0 -12
  270. package/src/resources/extensions/context7/index.ts +7 -0
  271. package/src/resources/extensions/get-secrets-from-user.ts +2 -35
  272. package/src/resources/extensions/google-search/index.ts +7 -0
  273. package/src/resources/extensions/gsd/auto-dispatch.ts +49 -1
  274. package/src/resources/extensions/gsd/auto-loop.ts +11 -1
  275. package/src/resources/extensions/gsd/auto-recovery.ts +39 -0
  276. package/src/resources/extensions/gsd/auto-start.ts +42 -2
  277. package/src/resources/extensions/gsd/auto.ts +61 -3
  278. package/src/resources/extensions/gsd/changelog.ts +213 -0
  279. package/src/resources/extensions/gsd/commands-bootstrap.ts +1 -0
  280. package/src/resources/extensions/gsd/commands-handlers.ts +2 -2
  281. package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
  282. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +5 -1
  283. package/src/resources/extensions/gsd/commands.ts +9 -1
  284. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  285. package/src/resources/extensions/gsd/doctor-checks.ts +107 -5
  286. package/src/resources/extensions/gsd/doctor-environment.ts +26 -16
  287. package/src/resources/extensions/gsd/doctor-proactive.ts +24 -0
  288. package/src/resources/extensions/gsd/doctor-types.ts +9 -1
  289. package/src/resources/extensions/gsd/doctor.ts +35 -0
  290. package/src/resources/extensions/gsd/files.ts +12 -2
  291. package/src/resources/extensions/gsd/gitignore.ts +54 -7
  292. package/src/resources/extensions/gsd/guided-flow.ts +5 -3
  293. package/src/resources/extensions/gsd/health-widget-core.ts +129 -0
  294. package/src/resources/extensions/gsd/health-widget.ts +103 -59
  295. package/src/resources/extensions/gsd/index.ts +10 -1
  296. package/src/resources/extensions/gsd/migrate-external.ts +47 -2
  297. package/src/resources/extensions/gsd/paths.ts +73 -7
  298. package/src/resources/extensions/gsd/post-unit-hooks.ts +5 -1
  299. package/src/resources/extensions/gsd/preferences-validation.ts +54 -1
  300. package/src/resources/extensions/gsd/preferences.ts +2 -0
  301. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  302. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  303. package/src/resources/extensions/gsd/roadmap-mutations.ts +66 -0
  304. package/src/resources/extensions/gsd/session-lock.ts +29 -2
  305. package/src/resources/extensions/gsd/templates/plan.md +8 -0
  306. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
  307. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +98 -2
  308. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +59 -3
  309. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +20 -0
  310. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +214 -0
  311. package/src/resources/extensions/gsd/tests/health-widget.test.ts +158 -0
  312. package/src/resources/extensions/gsd/tests/paths.test.ts +113 -0
  313. package/src/resources/extensions/gsd/tests/preferences.test.ts +40 -2
  314. package/src/resources/extensions/gsd/tests/test-utils.ts +165 -0
  315. package/src/resources/extensions/gsd/tests/validate-directory.test.ts +15 -0
  316. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -0
  317. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +32 -0
  318. package/src/resources/extensions/gsd/worktree-resolver.ts +11 -0
  319. package/src/resources/extensions/remote-questions/remote-command.ts +2 -23
  320. package/src/resources/extensions/shared/mod.ts +1 -1
  321. package/src/resources/extensions/shared/sanitize.ts +36 -0
  322. package/src/resources/extensions/subagent/index.ts +6 -12
  323. package/src/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  324. package/dist/resources/extensions/shared/wizard-ui.js +0 -478
  325. package/packages/pi-coding-agent/dist/modes/interactive/theme/dark.json +0 -85
  326. package/packages/pi-coding-agent/dist/modes/interactive/theme/light.json +0 -84
  327. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.json +0 -335
  328. package/packages/pi-coding-agent/src/modes/interactive/theme/dark.json +0 -85
  329. package/packages/pi-coding-agent/src/modes/interactive/theme/light.json +0 -84
  330. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
  331. package/pkg/dist/modes/interactive/theme/dark.json +0 -85
  332. package/pkg/dist/modes/interactive/theme/light.json +0 -84
  333. package/pkg/dist/modes/interactive/theme/theme-schema.json +0 -335
  334. package/src/resources/extensions/shared/wizard-ui.ts +0 -551
@@ -1,12 +1,9 @@
1
1
  // Lazy-loaded: OpenAI SDK is imported on first use, not at startup.
2
2
  // This avoids penalizing users who don't use OpenAI models.
3
- import type OpenAI from "openai";
4
3
  import type { ResponseCreateParamsStreaming } from "openai/resources/responses/responses.js";
5
4
  import { getEnvApiKey } from "../env-api-keys.js";
6
5
  import { supportsXhigh } from "../models.js";
7
6
  import type {
8
- Api,
9
- AssistantMessage,
10
7
  CacheRetention,
11
8
  Context,
12
9
  Model,
@@ -16,29 +13,17 @@ import type {
16
13
  Usage,
17
14
  } from "../types.js";
18
15
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
19
- import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
20
16
  import { convertResponsesMessages, convertResponsesTools, processResponsesStream } from "./openai-responses-shared.js";
17
+ import {
18
+ assertStreamSuccess,
19
+ buildInitialOutput,
20
+ clampReasoningForModel,
21
+ createOpenAIClient,
22
+ finalizeStream,
23
+ handleStreamError,
24
+ } from "./openai-shared.js";
21
25
  import { buildBaseOptions, clampReasoning } from "./simple-options.js";
22
26
 
23
- let _OpenAIResponsesClass: typeof OpenAI | undefined;
24
- async function getOpenAIResponsesClass(): Promise<typeof OpenAI> {
25
- if (!_OpenAIResponsesClass) {
26
- const mod = await import("openai");
27
- _OpenAIResponsesClass = mod.default;
28
- }
29
- return _OpenAIResponsesClass;
30
- }
31
-
32
- /**
33
- * Clamp reasoning effort for models that don't support all levels.
34
- * gpt-5.x models don't support "minimal" — map to "low".
35
- */
36
- function clampReasoningForModel(modelName: string, effort: string): string {
37
- const name = modelName.includes("/") ? modelName.split("/").pop()! : modelName;
38
- if (name.startsWith("gpt-5") && effort === "minimal") return "low";
39
- return effort;
40
- }
41
-
42
27
  const OPENAI_TOOL_CALL_PROVIDERS = new Set(["openai", "openai-codex", "opencode"]);
43
28
 
44
29
  /**
@@ -88,28 +73,14 @@ export const streamOpenAIResponses: StreamFunction<"openai-responses", OpenAIRes
88
73
 
89
74
  // Start async processing
90
75
  (async () => {
91
- const output: AssistantMessage = {
92
- role: "assistant",
93
- content: [],
94
- api: model.api as Api,
95
- provider: model.provider,
96
- model: model.id,
97
- usage: {
98
- input: 0,
99
- output: 0,
100
- cacheRead: 0,
101
- cacheWrite: 0,
102
- totalTokens: 0,
103
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
104
- },
105
- stopReason: "stop",
106
- timestamp: Date.now(),
107
- };
76
+ const output = buildInitialOutput(model);
108
77
 
109
78
  try {
110
79
  // Create OpenAI client
111
80
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
112
- const client = await createClient(model, context, apiKey, options?.headers);
81
+ const client = await createOpenAIClient(model, context, apiKey, {
82
+ optionsHeaders: options?.headers,
83
+ });
113
84
  let params = buildParams(model, context, options);
114
85
  const nextParams = await options?.onPayload?.(params, model);
115
86
  if (nextParams !== undefined) {
@@ -126,22 +97,10 @@ export const streamOpenAIResponses: StreamFunction<"openai-responses", OpenAIRes
126
97
  applyServiceTierPricing,
127
98
  });
128
99
 
129
- if (options?.signal?.aborted) {
130
- throw new Error("Request was aborted");
131
- }
132
-
133
- if (output.stopReason === "aborted" || output.stopReason === "error") {
134
- throw new Error("An unknown error occurred");
135
- }
136
-
137
- stream.push({ type: "done", reason: output.stopReason, message: output });
138
- stream.end();
100
+ assertStreamSuccess(output, options?.signal);
101
+ finalizeStream(stream, output);
139
102
  } catch (error) {
140
- for (const block of output.content) delete (block as { index?: number }).index;
141
- output.stopReason = options?.signal?.aborted ? "aborted" : "error";
142
- output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
143
- stream.push({ type: "error", reason: output.stopReason, error: output });
144
- stream.end();
103
+ handleStreamError(stream, output, error, options?.signal);
145
104
  }
146
105
  })();
147
106
 
@@ -167,45 +126,6 @@ export const streamSimpleOpenAIResponses: StreamFunction<"openai-responses", Sim
167
126
  } satisfies OpenAIResponsesOptions);
168
127
  };
169
128
 
170
- async function createClient(
171
- model: Model<"openai-responses">,
172
- context: Context,
173
- apiKey?: string,
174
- optionsHeaders?: Record<string, string>,
175
- ) {
176
- if (!apiKey) {
177
- if (!process.env.OPENAI_API_KEY) {
178
- throw new Error(
179
- "OpenAI API key is required. Set OPENAI_API_KEY environment variable or pass it as an argument.",
180
- );
181
- }
182
- apiKey = process.env.OPENAI_API_KEY;
183
- }
184
-
185
- const headers = { ...model.headers };
186
- if (model.provider === "github-copilot") {
187
- const hasImages = hasCopilotVisionInput(context.messages);
188
- const copilotHeaders = buildCopilotDynamicHeaders({
189
- messages: context.messages,
190
- hasImages,
191
- });
192
- Object.assign(headers, copilotHeaders);
193
- }
194
-
195
- // Merge options headers last so they can override defaults
196
- if (optionsHeaders) {
197
- Object.assign(headers, optionsHeaders);
198
- }
199
-
200
- const OpenAIClass = await getOpenAIResponsesClass();
201
- return new OpenAIClass({
202
- apiKey,
203
- baseURL: model.baseUrl,
204
- dangerouslyAllowBrowser: true,
205
- defaultHeaders: headers,
206
- });
207
- }
208
-
209
129
  function buildParams(model: Model<"openai-responses">, context: Context, options?: OpenAIResponsesOptions) {
210
130
  const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS);
211
131
 
@@ -236,13 +156,13 @@ function buildParams(model: Model<"openai-responses">, context: Context, options
236
156
  }
237
157
 
238
158
  if (model.reasoning) {
159
+ params.include = ["reasoning.encrypted_content"];
239
160
  if (options?.reasoningEffort || options?.reasoningSummary) {
240
161
  const effort = clampReasoningForModel(model.name, options?.reasoningEffort || "medium") as typeof options.reasoningEffort;
241
162
  params.reasoning = {
242
163
  effort: effort || "medium",
243
164
  summary: options?.reasoningSummary || "auto",
244
165
  };
245
- params.include = ["reasoning.encrypted_content"];
246
166
  } else {
247
167
  if (model.name.startsWith("gpt-5")) {
248
168
  // Jesus Christ, see https://community.openai.com/t/need-reasoning-false-option-for-gpt-5/1351588/7
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Shared utilities for OpenAI Completions and Responses providers.
3
+ *
4
+ * This module consolidates code that is identical (or near-identical) across
5
+ * openai-completions.ts and openai-responses.ts to reduce duplication while
6
+ * preserving the subtle behavioural differences of each provider.
7
+ */
8
+
9
+ import type OpenAI from "openai";
10
+ import type {
11
+ Api,
12
+ AssistantMessage,
13
+ Context,
14
+ Model,
15
+ StopReason,
16
+ } from "../types.js";
17
+ import type { AssistantMessageEventStream } from "../utils/event-stream.js";
18
+ import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
19
+
20
+ // =============================================================================
21
+ // Lazy SDK loading
22
+ // =============================================================================
23
+
24
+ let _openAIClass: typeof OpenAI | undefined;
25
+
26
+ /**
27
+ * Lazy-load the OpenAI SDK default export.
28
+ * Shared between Completions and Responses providers so the module is only
29
+ * imported once regardless of which provider is used first.
30
+ */
31
+ export async function getOpenAIClass(): Promise<typeof OpenAI> {
32
+ if (!_openAIClass) {
33
+ const mod = await import("openai");
34
+ _openAIClass = mod.default;
35
+ }
36
+ return _openAIClass;
37
+ }
38
+
39
+ // =============================================================================
40
+ // Client creation
41
+ // =============================================================================
42
+
43
+ export interface CreateClientOptions {
44
+ /** Extra headers from the options bag (merged last, can override defaults). */
45
+ optionsHeaders?: Record<string, string>;
46
+ /** Provider-specific client constructor options (e.g. timeout, maxRetries for Z.ai). */
47
+ extraClientOptions?: Record<string, unknown>;
48
+ }
49
+
50
+ /**
51
+ * Create an OpenAI SDK client instance.
52
+ *
53
+ * Handles:
54
+ * - API key resolution (explicit > env)
55
+ * - GitHub Copilot dynamic headers
56
+ * - Options header merging
57
+ * - Lazy SDK loading
58
+ */
59
+ export async function createOpenAIClient<TApi extends Api>(
60
+ model: Model<TApi>,
61
+ context: Context,
62
+ apiKey: string | undefined,
63
+ options?: CreateClientOptions,
64
+ ): Promise<OpenAI> {
65
+ if (!apiKey) {
66
+ if (!process.env.OPENAI_API_KEY) {
67
+ throw new Error(
68
+ "OpenAI API key is required. Set OPENAI_API_KEY environment variable or pass it as an argument.",
69
+ );
70
+ }
71
+ apiKey = process.env.OPENAI_API_KEY;
72
+ }
73
+
74
+ const headers = { ...model.headers };
75
+ if (model.provider === "github-copilot") {
76
+ const hasImages = hasCopilotVisionInput(context.messages);
77
+ const copilotHeaders = buildCopilotDynamicHeaders({
78
+ messages: context.messages,
79
+ hasImages,
80
+ });
81
+ Object.assign(headers, copilotHeaders);
82
+ }
83
+
84
+ // Merge options headers last so they can override defaults
85
+ if (options?.optionsHeaders) {
86
+ Object.assign(headers, options.optionsHeaders);
87
+ }
88
+
89
+ const OpenAIClass = await getOpenAIClass();
90
+ return new OpenAIClass({
91
+ apiKey,
92
+ baseURL: model.baseUrl,
93
+ dangerouslyAllowBrowser: true,
94
+ defaultHeaders: headers,
95
+ ...options?.extraClientOptions,
96
+ });
97
+ }
98
+
99
+ // =============================================================================
100
+ // Initial output construction
101
+ // =============================================================================
102
+
103
+ /**
104
+ * Build the initial AssistantMessage output object used by all OpenAI stream
105
+ * handlers. Every field is initialised to its zero/default value.
106
+ */
107
+ export function buildInitialOutput<TApi extends Api>(model: Model<TApi>): AssistantMessage {
108
+ return {
109
+ role: "assistant",
110
+ content: [],
111
+ api: model.api as Api,
112
+ provider: model.provider,
113
+ model: model.id,
114
+ usage: {
115
+ input: 0,
116
+ output: 0,
117
+ cacheRead: 0,
118
+ cacheWrite: 0,
119
+ totalTokens: 0,
120
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
121
+ },
122
+ stopReason: "stop",
123
+ timestamp: Date.now(),
124
+ };
125
+ }
126
+
127
+ // =============================================================================
128
+ // Stream lifecycle helpers
129
+ // =============================================================================
130
+
131
+ /**
132
+ * Shared post-stream checks. Call after the provider-specific stream loop
133
+ * finishes successfully (before pushing the "done" event).
134
+ *
135
+ * Throws if the request was aborted or the output indicates an error.
136
+ */
137
+ export function assertStreamSuccess(output: AssistantMessage, signal?: AbortSignal): void {
138
+ if (signal?.aborted) {
139
+ throw new Error("Request was aborted");
140
+ }
141
+ if (output.stopReason === "aborted" || output.stopReason === "error") {
142
+ throw new Error("An unknown error occurred");
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Emit the "done" event and close the stream.
148
+ */
149
+ export function finalizeStream(
150
+ stream: AssistantMessageEventStream,
151
+ output: AssistantMessage,
152
+ ): void {
153
+ stream.push({ type: "done", reason: output.stopReason as Extract<StopReason, "stop" | "length" | "toolUse">, message: output });
154
+ stream.end();
155
+ }
156
+
157
+ /**
158
+ * Handle an error during streaming.
159
+ *
160
+ * Cleans up any leftover `index` properties on content blocks, sets the
161
+ * appropriate stop reason and error message, then emits the "error" event.
162
+ */
163
+ export function handleStreamError(
164
+ stream: AssistantMessageEventStream,
165
+ output: AssistantMessage,
166
+ error: unknown,
167
+ signal?: AbortSignal,
168
+ /** Extra error metadata to append (e.g. OpenRouter raw metadata). */
169
+ extraMessage?: string,
170
+ ): void {
171
+ for (const block of output.content) delete (block as { index?: number }).index;
172
+ output.stopReason = signal?.aborted ? "aborted" : "error";
173
+ output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
174
+ if (extraMessage) output.errorMessage += `\n${extraMessage}`;
175
+ stream.push({ type: "error", reason: output.stopReason, error: output });
176
+ stream.end();
177
+ }
178
+
179
+ // =============================================================================
180
+ // Reasoning helpers
181
+ // =============================================================================
182
+
183
+ /**
184
+ * Clamp reasoning effort for models that don't support all levels.
185
+ * gpt-5.x models don't support "minimal" -- map to "low".
186
+ *
187
+ * Used by both openai-responses.ts and azure-openai-responses.ts.
188
+ */
189
+ export function clampReasoningForModel(modelName: string, effort: string): string {
190
+ const name = modelName.includes("/") ? modelName.split("/").pop()! : modelName;
191
+ if (name.startsWith("gpt-5") && effort === "minimal") return "low";
192
+ return effort;
193
+ }
@@ -6,7 +6,13 @@
6
6
  * It is only intended for CLI use, not browser environments.
7
7
  */
8
8
 
9
- import type { Server } from "node:http";
9
+ import {
10
+ type CallbackServerInfo,
11
+ getGoogleUserEmail,
12
+ parseRedirectUrl,
13
+ refreshGoogleOAuthToken,
14
+ startCallbackServer,
15
+ } from "./google-oauth-utils.js";
10
16
  import { generatePKCE } from "./pkce.js";
11
17
  import type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from "./types.js";
12
18
 
@@ -14,14 +20,6 @@ type AntigravityCredentials = OAuthCredentials & {
14
20
  projectId: string;
15
21
  };
16
22
 
17
- let _createServer: typeof import("node:http").createServer | null = null;
18
- let _httpImportPromise: Promise<void> | null = null;
19
- if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
20
- _httpImportPromise = import("node:http").then((m) => {
21
- _createServer = m.createServer;
22
- });
23
- }
24
-
25
23
  // Antigravity OAuth credentials (different from Gemini CLI)
26
24
  const decode = (s: string) => atob(s);
27
25
  const CLIENT_ID = decode(
@@ -42,109 +40,13 @@ const SCOPES = [
42
40
  const AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
43
41
  const TOKEN_URL = "https://oauth2.googleapis.com/token";
44
42
 
43
+ // Callback server configuration
44
+ const CALLBACK_PORT = 51121;
45
+ const CALLBACK_PATH = "/oauth-callback";
46
+
45
47
  // Fallback project ID when discovery fails
46
48
  const DEFAULT_PROJECT_ID = "rising-fact-p41fc";
47
49
 
48
- type CallbackServerInfo = {
49
- server: Server;
50
- cancelWait: () => void;
51
- waitForCode: () => Promise<{ code: string; state: string } | null>;
52
- };
53
-
54
- /**
55
- * Start a local HTTP server to receive the OAuth callback
56
- */
57
- async function getNodeCreateServer(): Promise<typeof import("node:http").createServer> {
58
- if (_createServer) return _createServer;
59
- if (_httpImportPromise) {
60
- await _httpImportPromise;
61
- }
62
- if (_createServer) return _createServer;
63
- throw new Error("Antigravity OAuth is only available in Node.js environments");
64
- }
65
-
66
- async function startCallbackServer(): Promise<CallbackServerInfo> {
67
- const createServer = await getNodeCreateServer();
68
-
69
- return new Promise((resolve, reject) => {
70
- let result: { code: string; state: string } | null = null;
71
- let cancelled = false;
72
-
73
- const server = createServer((req, res) => {
74
- const url = new URL(req.url || "", `http://localhost:51121`);
75
-
76
- if (url.pathname === "/oauth-callback") {
77
- const code = url.searchParams.get("code");
78
- const state = url.searchParams.get("state");
79
- const error = url.searchParams.get("error");
80
-
81
- if (error) {
82
- res.writeHead(400, { "Content-Type": "text/html" });
83
- res.end(
84
- `<html><body><h1>Authentication Failed</h1><p>Error: ${error}</p><p>You can close this window.</p></body></html>`,
85
- );
86
- return;
87
- }
88
-
89
- if (code && state) {
90
- res.writeHead(200, { "Content-Type": "text/html" });
91
- res.end(
92
- `<html><body><h1>Authentication Successful</h1><p>You can close this window and return to the terminal.</p></body></html>`,
93
- );
94
- result = { code, state };
95
- } else {
96
- res.writeHead(400, { "Content-Type": "text/html" });
97
- res.end(
98
- `<html><body><h1>Authentication Failed</h1><p>Missing code or state parameter.</p></body></html>`,
99
- );
100
- }
101
- } else {
102
- res.writeHead(404);
103
- res.end();
104
- }
105
- });
106
-
107
- server.on("error", (err) => {
108
- reject(err);
109
- });
110
-
111
- server.listen(51121, "127.0.0.1", () => {
112
- resolve({
113
- server,
114
- cancelWait: () => {
115
- cancelled = true;
116
- },
117
- waitForCode: async () => {
118
- const sleep = () => new Promise((r) => setTimeout(r, 100));
119
- while (!result && !cancelled) {
120
- await sleep();
121
- }
122
- return result;
123
- },
124
- });
125
- });
126
- });
127
- }
128
-
129
- /**
130
- * Parse redirect URL to extract code and state
131
- */
132
- function parseRedirectUrl(input: string): { code?: string; state?: string } {
133
- const value = input.trim();
134
- if (!value) return {};
135
-
136
- try {
137
- const url = new URL(value);
138
- return {
139
- code: url.searchParams.get("code") ?? undefined,
140
- state: url.searchParams.get("state") ?? undefined,
141
- };
142
- } catch {
143
- // Not a URL, return empty
144
- return {};
145
- }
146
- }
147
-
148
50
  interface LoadCodeAssistPayload {
149
51
  cloudaicompanionProject?: string | { id?: string };
150
52
  currentTier?: { id?: string };
@@ -212,61 +114,11 @@ async function discoverProject(accessToken: string, onProgress?: (message: strin
212
114
  return DEFAULT_PROJECT_ID;
213
115
  }
214
116
 
215
- /**
216
- * Get user email from the access token
217
- */
218
- async function getUserEmail(accessToken: string): Promise<string | undefined> {
219
- try {
220
- const response = await fetch("https://www.googleapis.com/oauth2/v1/userinfo?alt=json", {
221
- headers: {
222
- Authorization: `Bearer ${accessToken}`,
223
- },
224
- signal: AbortSignal.timeout(30_000),
225
- });
226
-
227
- if (response.ok) {
228
- const data = (await response.json()) as { email?: string };
229
- return data.email;
230
- }
231
- } catch {
232
- // Ignore errors, email is optional
233
- }
234
- return undefined;
235
- }
236
-
237
117
  /**
238
118
  * Refresh Antigravity token
239
119
  */
240
120
  export async function refreshAntigravityToken(refreshToken: string, projectId: string): Promise<OAuthCredentials> {
241
- const response = await fetch(TOKEN_URL, {
242
- method: "POST",
243
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
244
- body: new URLSearchParams({
245
- client_id: CLIENT_ID,
246
- client_secret: CLIENT_SECRET,
247
- refresh_token: refreshToken,
248
- grant_type: "refresh_token",
249
- }),
250
- signal: AbortSignal.timeout(30_000),
251
- });
252
-
253
- if (!response.ok) {
254
- const error = await response.text();
255
- throw new Error(`Antigravity token refresh failed: ${error}`);
256
- }
257
-
258
- const data = (await response.json()) as {
259
- access_token: string;
260
- expires_in: number;
261
- refresh_token?: string;
262
- };
263
-
264
- return {
265
- refresh: data.refresh_token || refreshToken,
266
- access: data.access_token,
267
- expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,
268
- projectId,
269
- };
121
+ return refreshGoogleOAuthToken(refreshToken, CLIENT_ID, CLIENT_SECRET, "Antigravity", { projectId });
270
122
  }
271
123
 
272
124
  /**
@@ -286,7 +138,7 @@ export async function loginAntigravity(
286
138
 
287
139
  // Start local server for callback
288
140
  onProgress?.("Starting local server for OAuth callback...");
289
- const server = await startCallbackServer();
141
+ const server: CallbackServerInfo = await startCallbackServer(CALLBACK_PORT, CALLBACK_PATH, "Antigravity");
290
142
 
291
143
  let code: string | undefined;
292
144
 
@@ -415,7 +267,7 @@ export async function loginAntigravity(
415
267
 
416
268
  // Get user email
417
269
  onProgress?.("Getting user info...");
418
- const email = await getUserEmail(tokenData.access_token);
270
+ const email = await getGoogleUserEmail(tokenData.access_token);
419
271
 
420
272
  // Discover project
421
273
  const projectId = await discoverProject(tokenData.access_token, onProgress);