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.
- package/dist/cli.js +7 -2
- package/dist/resource-loader.d.ts +1 -1
- package/dist/resource-loader.js +13 -1
- package/dist/resources/extensions/async-jobs/await-tool.js +0 -2
- package/dist/resources/extensions/async-jobs/job-manager.js +0 -6
- package/dist/resources/extensions/bg-shell/output-formatter.js +1 -19
- package/dist/resources/extensions/bg-shell/process-manager.js +0 -4
- package/dist/resources/extensions/bg-shell/types.js +0 -2
- package/dist/resources/extensions/context7/index.js +5 -0
- package/dist/resources/extensions/get-secrets-from-user.js +2 -30
- package/dist/resources/extensions/google-search/index.js +5 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +43 -1
- package/dist/resources/extensions/gsd/auto-loop.js +10 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +35 -0
- package/dist/resources/extensions/gsd/auto-start.js +35 -2
- package/dist/resources/extensions/gsd/auto.js +59 -4
- package/dist/resources/extensions/gsd/changelog.js +162 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +1 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +2 -2
- package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +5 -1
- package/dist/resources/extensions/gsd/commands.js +8 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/dist/resources/extensions/gsd/doctor-checks.js +113 -5
- package/dist/resources/extensions/gsd/doctor-environment.js +26 -17
- package/dist/resources/extensions/gsd/doctor-proactive.js +22 -0
- package/dist/resources/extensions/gsd/doctor.js +36 -0
- package/dist/resources/extensions/gsd/files.js +11 -2
- package/dist/resources/extensions/gsd/gitignore.js +54 -7
- package/dist/resources/extensions/gsd/guided-flow.js +5 -3
- package/dist/resources/extensions/gsd/health-widget-core.js +96 -0
- package/dist/resources/extensions/gsd/health-widget.js +97 -46
- package/dist/resources/extensions/gsd/index.js +10 -1
- package/dist/resources/extensions/gsd/migrate-external.js +55 -2
- package/dist/resources/extensions/gsd/paths.js +74 -7
- package/dist/resources/extensions/gsd/post-unit-hooks.js +4 -1
- package/dist/resources/extensions/gsd/preferences-validation.js +54 -1
- package/dist/resources/extensions/gsd/preferences.js +2 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
- package/dist/resources/extensions/gsd/roadmap-mutations.js +55 -0
- package/dist/resources/extensions/gsd/session-lock.js +26 -2
- package/dist/resources/extensions/gsd/templates/plan.md +8 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +12 -0
- package/dist/resources/extensions/remote-questions/remote-command.js +2 -22
- package/dist/resources/extensions/shared/mod.js +1 -1
- package/dist/resources/extensions/shared/sanitize.js +30 -0
- package/dist/resources/extensions/subagent/index.js +6 -14
- package/dist/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
- package/package.json +2 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts +14 -0
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +24 -27
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +1 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +11 -22
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/proxy.js +2 -8
- package/packages/pi-agent-core/dist/proxy.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +30 -27
- package/packages/pi-agent-core/src/agent.ts +12 -23
- package/packages/pi-agent-core/src/proxy.ts +2 -8
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.js +5 -41
- package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +10 -73
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +9 -80
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-shared.d.ts +65 -0
- package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-shared.js +146 -0
- package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +7 -135
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +7 -135
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts +46 -0
- package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js +160 -0
- package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js.map +1 -0
- package/packages/pi-ai/src/providers/azure-openai-responses.ts +11 -45
- package/packages/pi-ai/src/providers/openai-completions.ts +16 -86
- package/packages/pi-ai/src/providers/openai-responses.ts +16 -96
- package/packages/pi-ai/src/providers/openai-shared.ts +193 -0
- package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +14 -162
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +13 -161
- package/packages/pi-ai/src/utils/oauth/google-oauth-utils.ts +201 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +16 -63
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +104 -641
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +0 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +4 -35
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js +5 -43
- package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +11 -69
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +40 -0
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +78 -0
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +77 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +331 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +129 -243
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +49 -42
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js +2 -21
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lock-utils.d.ts +39 -0
- package/packages/pi-coding-agent/dist/core/lock-utils.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lock-utils.js +89 -0
- package/packages/pi-coding-agent/dist/core/lock-utils.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js +4 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.js +52 -107
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +2 -21
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +0 -1
- package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/types.js +0 -28
- package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +2 -4
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +2 -4
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +46 -60
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +87 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.js +295 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts +0 -1
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +3 -28
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +76 -166
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +1 -3
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +9 -26
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js +61 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +6 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +65 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +6 -16
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +175 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js +15 -0
- package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/print-mode.js +2 -30
- package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -28
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts +19 -0
- package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js +45 -0
- package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js.map +1 -0
- package/packages/pi-coding-agent/dist/utils/error.d.ts +5 -0
- package/packages/pi-coding-agent/dist/utils/error.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/utils/error.js +7 -0
- package/packages/pi-coding-agent/dist/utils/error.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +117 -745
- package/packages/pi-coding-agent/src/core/auth-storage.ts +4 -38
- package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +7 -53
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +14 -74
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +100 -0
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +424 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +1 -21
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +119 -243
- package/packages/pi-coding-agent/src/core/extensions/types.ts +50 -69
- package/packages/pi-coding-agent/src/core/lock-utils.ts +113 -0
- package/packages/pi-coding-agent/src/core/lsp/config.ts +4 -1
- package/packages/pi-coding-agent/src/core/lsp/index.ts +83 -152
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +2 -22
- package/packages/pi-coding-agent/src/core/lsp/types.ts +0 -29
- package/packages/pi-coding-agent/src/core/package-manager.ts +1 -4
- package/packages/pi-coding-agent/src/core/resource-loader.ts +56 -69
- package/packages/pi-coding-agent/src/core/retry-handler.ts +359 -0
- package/packages/pi-coding-agent/src/core/session-manager.ts +3 -30
- package/packages/pi-coding-agent/src/core/settings-manager.ts +85 -164
- package/packages/pi-coding-agent/src/core/skills.ts +1 -4
- package/packages/pi-coding-agent/src/index.ts +1 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +17 -29
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -13
- package/packages/pi-coding-agent/src/modes/interactive/components/tree-render-utils.ts +81 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tree-selector.ts +14 -19
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +7 -18
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +196 -0
- package/packages/pi-coding-agent/src/modes/interactive/utils/shorten-path.ts +14 -0
- package/packages/pi-coding-agent/src/modes/print-mode.ts +2 -30
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -28
- package/packages/pi-coding-agent/src/modes/shared/command-context-actions.ts +53 -0
- package/packages/pi-coding-agent/src/utils/error.ts +6 -0
- package/packages/pi-tui/dist/components/markdown.d.ts +5 -0
- package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/markdown.js +25 -31
- package/packages/pi-tui/dist/components/markdown.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts +0 -4
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +94 -162
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/src/components/markdown.ts +25 -29
- package/packages/pi-tui/src/keys.ts +94 -173
- package/pkg/dist/modes/interactive/theme/theme.d.ts +65 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +6 -16
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts +12 -0
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -0
- package/pkg/dist/modes/interactive/theme/themes.js +175 -0
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/async-jobs/await-tool.ts +0 -2
- package/src/resources/extensions/async-jobs/job-manager.ts +0 -7
- package/src/resources/extensions/bg-shell/output-formatter.ts +0 -17
- package/src/resources/extensions/bg-shell/process-manager.ts +0 -4
- package/src/resources/extensions/bg-shell/types.ts +0 -12
- package/src/resources/extensions/context7/index.ts +7 -0
- package/src/resources/extensions/get-secrets-from-user.ts +2 -35
- package/src/resources/extensions/google-search/index.ts +7 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +49 -1
- package/src/resources/extensions/gsd/auto-loop.ts +11 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +39 -0
- package/src/resources/extensions/gsd/auto-start.ts +42 -2
- package/src/resources/extensions/gsd/auto.ts +61 -3
- package/src/resources/extensions/gsd/changelog.ts +213 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +1 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -2
- package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +5 -1
- package/src/resources/extensions/gsd/commands.ts +9 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/src/resources/extensions/gsd/doctor-checks.ts +107 -5
- package/src/resources/extensions/gsd/doctor-environment.ts +26 -16
- package/src/resources/extensions/gsd/doctor-proactive.ts +24 -0
- package/src/resources/extensions/gsd/doctor-types.ts +9 -1
- package/src/resources/extensions/gsd/doctor.ts +35 -0
- package/src/resources/extensions/gsd/files.ts +12 -2
- package/src/resources/extensions/gsd/gitignore.ts +54 -7
- package/src/resources/extensions/gsd/guided-flow.ts +5 -3
- package/src/resources/extensions/gsd/health-widget-core.ts +129 -0
- package/src/resources/extensions/gsd/health-widget.ts +103 -59
- package/src/resources/extensions/gsd/index.ts +10 -1
- package/src/resources/extensions/gsd/migrate-external.ts +47 -2
- package/src/resources/extensions/gsd/paths.ts +73 -7
- package/src/resources/extensions/gsd/post-unit-hooks.ts +5 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +54 -1
- package/src/resources/extensions/gsd/preferences.ts +2 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
- package/src/resources/extensions/gsd/roadmap-mutations.ts +66 -0
- package/src/resources/extensions/gsd/session-lock.ts +29 -2
- package/src/resources/extensions/gsd/templates/plan.md +8 -0
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +98 -2
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +59 -3
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +214 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/paths.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +40 -2
- package/src/resources/extensions/gsd/tests/test-utils.ts +165 -0
- package/src/resources/extensions/gsd/tests/validate-directory.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +32 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +11 -0
- package/src/resources/extensions/remote-questions/remote-command.ts +2 -23
- package/src/resources/extensions/shared/mod.ts +1 -1
- package/src/resources/extensions/shared/sanitize.ts +36 -0
- package/src/resources/extensions/subagent/index.ts +6 -12
- package/src/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
- package/dist/resources/extensions/shared/wizard-ui.js +0 -478
- package/packages/pi-coding-agent/dist/modes/interactive/theme/dark.json +0 -85
- package/packages/pi-coding-agent/dist/modes/interactive/theme/light.json +0 -84
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.json +0 -335
- package/packages/pi-coding-agent/src/modes/interactive/theme/dark.json +0 -85
- package/packages/pi-coding-agent/src/modes/interactive/theme/light.json +0 -84
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
- package/pkg/dist/modes/interactive/theme/dark.json +0 -85
- package/pkg/dist/modes/interactive/theme/light.json +0 -84
- package/pkg/dist/modes/interactive/theme/theme-schema.json +0 -335
- 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
|
|
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
|
|
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
|
-
|
|
130
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
270
|
+
const email = await getGoogleUserEmail(tokenData.access_token);
|
|
419
271
|
|
|
420
272
|
// Discover project
|
|
421
273
|
const projectId = await discoverProject(tokenData.access_token, onProgress);
|