@pellux/goodvibes-tui 0.18.12 → 0.18.13

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 (157) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +1 -1
  3. package/docs/foundation-artifacts/operator-contract.json +1 -1
  4. package/package.json +2 -2
  5. package/src/config/index.ts +1 -138
  6. package/src/config/subscription-providers.ts +1 -127
  7. package/src/core/conversation-rendering.ts +3 -3
  8. package/src/core/conversation.ts +176 -423
  9. package/src/core/history.ts +45 -0
  10. package/src/core/orchestrator.ts +3 -735
  11. package/src/core/system-message-router.ts +19 -58
  12. package/src/input/handler-content-actions.ts +2 -2
  13. package/src/input/handler-feed.ts +1 -1
  14. package/src/input/handler-modal-token-routes.ts +1 -1
  15. package/src/input/handler-ui-state.ts +1 -1
  16. package/src/input/handler.ts +1 -1
  17. package/src/input/search.ts +1 -1
  18. package/src/input/selection.ts +2 -2
  19. package/src/main.ts +1 -1
  20. package/src/panels/agent-inspector-panel.ts +3 -3
  21. package/src/panels/agent-logs-panel.ts +3 -3
  22. package/src/panels/approval-panel.ts +2 -2
  23. package/src/panels/automation-control-panel.ts +3 -3
  24. package/src/panels/base-panel.ts +14 -14
  25. package/src/panels/builtin/operations.ts +1 -1
  26. package/src/panels/builtin/session.ts +1 -1
  27. package/src/panels/builtin/shared.ts +3 -3
  28. package/src/panels/cockpit-panel.ts +2 -2
  29. package/src/panels/communication-panel.ts +3 -3
  30. package/src/panels/context-visualizer-panel.ts +2 -2
  31. package/src/panels/control-plane-panel.ts +3 -3
  32. package/src/panels/cost-tracker-panel.ts +3 -3
  33. package/src/panels/debug-panel.ts +2 -2
  34. package/src/panels/diff-panel.ts +2 -2
  35. package/src/panels/docs-panel.ts +1 -1
  36. package/src/panels/eval-panel.ts +2 -2
  37. package/src/panels/file-explorer-panel.ts +3 -3
  38. package/src/panels/file-preview-panel.ts +3 -3
  39. package/src/panels/forensics-panel.ts +2 -2
  40. package/src/panels/git-panel.ts +1 -1
  41. package/src/panels/hooks-panel.ts +3 -3
  42. package/src/panels/incident-review-panel.ts +1 -1
  43. package/src/panels/intelligence-panel.ts +2 -2
  44. package/src/panels/knowledge-panel.ts +1 -1
  45. package/src/panels/local-auth-panel.ts +2 -2
  46. package/src/panels/marketplace-panel.ts +1 -1
  47. package/src/panels/mcp-panel.ts +3 -3
  48. package/src/panels/memory-panel.ts +1 -1
  49. package/src/panels/ops-control-panel.ts +3 -3
  50. package/src/panels/ops-strategy-panel.ts +2 -2
  51. package/src/panels/orchestration-panel.ts +2 -2
  52. package/src/panels/panel-list-panel.ts +6 -6
  53. package/src/panels/plan-dashboard-panel.ts +1 -1
  54. package/src/panels/plugins-panel.ts +2 -2
  55. package/src/panels/policy-panel.ts +2 -2
  56. package/src/panels/polish.ts +3 -3
  57. package/src/panels/provider-accounts-panel.ts +2 -2
  58. package/src/panels/provider-health-panel.ts +2 -2
  59. package/src/panels/provider-stats-panel.ts +3 -3
  60. package/src/panels/remote-panel.ts +3 -3
  61. package/src/panels/routes-panel.ts +3 -3
  62. package/src/panels/sandbox-panel.ts +2 -2
  63. package/src/panels/schedule-panel.ts +1 -1
  64. package/src/panels/security-panel.ts +2 -2
  65. package/src/panels/services-panel.ts +2 -2
  66. package/src/panels/session-browser-panel.ts +2 -2
  67. package/src/panels/settings-sync-panel.ts +2 -2
  68. package/src/panels/skills-panel.ts +6 -6
  69. package/src/panels/subscription-panel.ts +2 -2
  70. package/src/panels/symbol-outline-panel.ts +3 -3
  71. package/src/panels/system-messages-panel.ts +4 -4
  72. package/src/panels/tasks-panel.ts +2 -2
  73. package/src/panels/thinking-panel.ts +3 -3
  74. package/src/panels/token-budget-panel.ts +1 -1
  75. package/src/panels/tool-inspector-panel.ts +3 -3
  76. package/src/panels/types.ts +5 -5
  77. package/src/panels/watchers-panel.ts +3 -3
  78. package/src/panels/welcome-panel.ts +1 -1
  79. package/src/panels/worktree-panel.ts +2 -2
  80. package/src/panels/wrfc-panel.ts +3 -3
  81. package/src/permissions/prompt.ts +3 -22
  82. package/src/plugins/loader.ts +15 -304
  83. package/src/renderer/agent-detail-modal.ts +1 -1
  84. package/src/renderer/autocomplete-overlay.ts +2 -2
  85. package/src/renderer/bookmark-modal.ts +1 -1
  86. package/src/renderer/bottom-bar.ts +2 -2
  87. package/src/renderer/buffer.ts +1 -1
  88. package/src/renderer/code-block.ts +2 -2
  89. package/src/renderer/compositor.ts +2 -2
  90. package/src/renderer/context-inspector.ts +1 -1
  91. package/src/renderer/conversation-layout.ts +2 -2
  92. package/src/renderer/conversation-overlays.ts +1 -1
  93. package/src/renderer/conversation-surface.ts +2 -2
  94. package/src/renderer/diff-view.ts +2 -2
  95. package/src/renderer/diff.ts +1 -1
  96. package/src/renderer/file-picker-overlay.ts +2 -2
  97. package/src/renderer/file-tree.ts +2 -2
  98. package/src/renderer/help-overlay.ts +1 -1
  99. package/src/renderer/history-search-overlay.ts +2 -2
  100. package/src/renderer/live-tail-modal.ts +1 -1
  101. package/src/renderer/markdown.ts +2 -2
  102. package/src/renderer/modal-factory.ts +3 -3
  103. package/src/renderer/model-picker-overlay.ts +2 -2
  104. package/src/renderer/overlay-box.ts +2 -2
  105. package/src/renderer/panel-composite.ts +1 -1
  106. package/src/renderer/panel-picker-overlay.ts +2 -2
  107. package/src/renderer/panel-tab-bar.ts +1 -1
  108. package/src/renderer/panel-workspace-bar.ts +1 -1
  109. package/src/renderer/process-indicator.ts +2 -2
  110. package/src/renderer/process-modal.ts +1 -1
  111. package/src/renderer/profile-picker-modal.ts +2 -2
  112. package/src/renderer/progress.ts +2 -2
  113. package/src/renderer/search-overlay.ts +2 -2
  114. package/src/renderer/selection-modal-overlay.ts +2 -2
  115. package/src/renderer/session-picker-modal.ts +2 -2
  116. package/src/renderer/settings-modal.ts +2 -2
  117. package/src/renderer/shell-surface.ts +1 -1
  118. package/src/renderer/system-message.ts +1 -1
  119. package/src/renderer/tab-strip.ts +2 -2
  120. package/src/renderer/text-layout.ts +1 -1
  121. package/src/renderer/thinking.ts +1 -1
  122. package/src/renderer/tool-call.ts +2 -2
  123. package/src/renderer/ui-factory.ts +2 -2
  124. package/src/runtime/bootstrap-command-context.ts +4 -5
  125. package/src/runtime/bootstrap-command-parts.ts +1 -3
  126. package/src/runtime/bootstrap-core.ts +3 -2
  127. package/src/runtime/bootstrap-hook-bridge.ts +15 -174
  128. package/src/runtime/bootstrap-shell.ts +4 -4
  129. package/src/runtime/bootstrap.ts +1 -1
  130. package/src/runtime/context.ts +4 -20
  131. package/src/runtime/diagnostics/panels/index.ts +1 -1
  132. package/src/runtime/diagnostics/panels/ops.ts +1 -1
  133. package/src/runtime/diagnostics/panels/panel-resources.ts +118 -0
  134. package/src/runtime/perf/panel-contracts.ts +32 -0
  135. package/src/runtime/perf/panel-health-monitor.ts +18 -0
  136. package/src/runtime/services.ts +4 -4
  137. package/src/runtime/store/domains/conversation.ts +1 -181
  138. package/src/runtime/store/domains/permissions.ts +1 -143
  139. package/src/runtime/store/helpers/reducers/conversation.ts +1 -228
  140. package/src/runtime/store/helpers/reducers/lifecycle.ts +1 -440
  141. package/src/runtime/store/selectors/index.ts +11 -6
  142. package/src/runtime/store/state.ts +12 -4
  143. package/src/runtime/ui-events.ts +46 -0
  144. package/src/runtime/ui-services.ts +1 -1
  145. package/src/shell/ui-openers.ts +1 -1
  146. package/src/tools/index.ts +1 -186
  147. package/src/types/grid.ts +48 -0
  148. package/src/utils/clipboard.ts +21 -0
  149. package/src/utils/splash-lines.ts +1 -1
  150. package/src/utils/terminal-width.ts +185 -0
  151. package/src/version.ts +1 -1
  152. package/src/daemon/facade-composition.ts +0 -398
  153. package/src/daemon/facade.ts +0 -638
  154. package/src/daemon/surface-policy.ts +0 -60
  155. package/src/daemon/types.ts +0 -191
  156. package/src/runtime/ui-read-models-core.ts +0 -95
  157. package/src/runtime/ui-read-models-operations.ts +0 -203
package/CHANGELOG.md CHANGED
@@ -4,6 +4,56 @@ All notable changes to GoodVibes TUI.
4
4
 
5
5
  ---
6
6
 
7
+ ## [0.18.13] — 2026-04-16
8
+
9
+ ### SDK/TUI Boundary Separation
10
+
11
+ Major cleanup of the SDK/TUI boundary. The TUI is now a thin rendering/input/wiring layer built on `@pellux/goodvibes-sdk@0.18.29`. Thousands of lines of duplicated, forked, and dead code have been removed and replaced with SDK imports.
12
+
13
+ #### Dead Code Removed
14
+
15
+ - Deleted 4 dead daemon files that nothing imported (`facade.ts`, `facade-composition.ts`, `surface-policy.ts`, `types.ts`) — 1,291 lines removed
16
+ - Deleted 2 dead UI read-model files (`ui-read-models-core.ts`, `ui-read-models-operations.ts`) — the barrel already delegates to SDK
17
+
18
+ #### Forks Replaced with SDK Imports
19
+
20
+ - Replaced `src/core/orchestrator.ts` (736 lines) with a 3-line re-export from SDK — the SDK's Orchestrator already includes `getSpinner()`
21
+ - Replaced `src/plugins/loader.ts` (305 lines) with re-exports from SDK — the SDK now supports `additionalDirectories` and `entryDefault` options
22
+ - Replaced `src/tools/index.ts` (187 lines) with re-export of SDK's `registerAllTools`
23
+ - Replaced `src/config/subscription-providers.ts` (128 lines) with `export *` from SDK
24
+ - Replaced `src/config/index.ts` API key functions with re-exports from SDK's new `config/api-keys.ts`
25
+ - Replaced `src/permissions/prompt.ts` type definitions with imports from SDK — kept `PermissionPromptUI` class (TUI-specific rendering)
26
+ - Replaced 4 store/runtime duplicate files with SDK re-exports (conversation domain, permissions domain, conversation reducers, lifecycle reducers)
27
+
28
+ #### ConversationManager Refactored
29
+
30
+ - Refactored `src/core/conversation.ts` from a 776-line standalone class to a ~450-line subclass extending SDK's `ConversationManager`
31
+ - Removed all duplicated message management methods (CRUD, branching, persistence, compaction, undo/redo) — now inherited from SDK
32
+ - Defined `TuiBlockMeta extends BlockMeta` with rendering fields (`blockIndex`, `startLine`, `lineCount`, `collapseKey`)
33
+ - Kept all TUI-specific rendering methods (history buffer, block registry, collapse state, display navigation)
34
+
35
+ #### Health Monitoring Renamed
36
+
37
+ - Renamed `panelHealthMonitor` to `componentHealthMonitor` throughout the TUI to align with SDK 0.18.29's generic naming
38
+ - Updated 20 files across runtime, panels, diagnostics, bootstrap, and tests
39
+ - Added deprecated `Panel*` type aliases for backward compatibility
40
+
41
+ #### RuntimeState Aligned with SDK
42
+
43
+ - Updated `store/state.ts` to use SDK's `surfacePerf: SurfacePerfDomainState` instead of `uiPerf: UiPerfDomainState`
44
+ - Updated `store/selectors/index.ts` to match SDK's selector shape
45
+ - Health monitoring perf files rewritten as SDK re-export shims
46
+
47
+ #### Clipboard Split
48
+
49
+ - Created `src/utils/clipboard.ts` with TUI-specific OSC 52 `copyToClipboard` function
50
+ - Platform clipboard paste functions remain in SDK
51
+
52
+ ### Verification
53
+
54
+ - Full typecheck passes: `bun x tsc --noEmit` — 0 errors
55
+ - Updated to `@pellux/goodvibes-sdk@0.18.29`
56
+
7
57
  ## [0.18.12] — 2026-04-15
8
58
 
9
59
  ### SDK `0.18.28` Session-Persistence Boundary Fix
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![CI](https://github.com/mgd34msu/goodvibes-tui/actions/workflows/ci.yml/badge.svg)](https://github.com/mgd34msu/goodvibes-tui/actions/workflows/ci.yml)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Version](https://img.shields.io/badge/version-0.18.12-blue.svg)](https://github.com/mgd34msu/goodvibes-tui)
5
+ [![Version](https://img.shields.io/badge/version-0.18.13-blue.svg)](https://github.com/mgd34msu/goodvibes-tui)
6
6
 
7
7
  A terminal-native AI coding, operations, automation, knowledge, and integration console with a typed runtime, omnichannel surfaces, structured memory/knowledge, and a raw ANSI renderer.
8
8
 
@@ -3,7 +3,7 @@
3
3
  "product": {
4
4
  "id": "goodvibes",
5
5
  "surface": "operator",
6
- "version": "0.18.28"
6
+ "version": "0.18.29"
7
7
  },
8
8
  "auth": {
9
9
  "modes": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-tui",
3
- "version": "0.18.12",
3
+ "version": "0.18.13",
4
4
  "description": "Terminal-native GoodVibes product for coding, operations, automation, knowledge, channels, and daemon-backed control-plane workflows.",
5
5
  "type": "module",
6
6
  "main": "src/main.ts",
@@ -88,7 +88,7 @@
88
88
  "@anthropic-ai/vertex-sdk": "^0.16.0",
89
89
  "@ast-grep/napi": "^0.42.0",
90
90
  "@aws/bedrock-token-generator": "^1.1.0",
91
- "@pellux/goodvibes-sdk": "0.18.28",
91
+ "@pellux/goodvibes-sdk": "0.18.29",
92
92
  "bash-language-server": "^5.6.0",
93
93
  "fuse.js": "^7.1.0",
94
94
  "graphql": "^16.13.2",
@@ -15,7 +15,6 @@ export { ConfigError } from '@pellux/goodvibes-sdk/platform/types/errors';
15
15
  import { readFileSync } from 'fs';
16
16
  import { ConfigManager } from '@pellux/goodvibes-sdk/platform/config/manager';
17
17
  import type { GoodVibesConfig } from '@pellux/goodvibes-sdk/platform/config/schema';
18
- import { SecretsManager } from './secrets.ts';
19
18
  import { logger } from '@pellux/goodvibes-sdk/platform/utils/logger';
20
19
  import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
21
20
 
@@ -54,140 +53,4 @@ export function getConfiguredSystemPrompt(configManager: Pick<ConfigManager, 'ge
54
53
  }
55
54
  }
56
55
 
57
- export function getConfiguredApiKeys(): Record<string, string> {
58
- return loadEnvApiKeys();
59
- }
60
-
61
- function loadEnvApiKeys(): Record<string, string> {
62
- const keys: Record<string, string> = {};
63
- const mapping: Record<string, string> = {
64
- openai: 'OPENAI_API_KEY',
65
- anthropic: 'ANTHROPIC_API_KEY',
66
- gemini: 'GEMINI_API_KEY',
67
- inceptionlabs: 'INCEPTION_API_KEY',
68
- openrouter: 'OPENROUTER_API_KEY',
69
- aihubmix: 'AIHUBMIX_API_KEY',
70
- groq: 'GROQ_API_KEY',
71
- cerebras: 'CEREBRAS_API_KEY',
72
- mistral: 'MISTRAL_API_KEY',
73
- 'ollama-cloud': 'OLLAMA_CLOUD_API_KEY',
74
- // Note: also checked as OLLAMA_API_KEY below
75
- huggingface: 'HF_API_KEY',
76
- nvidia: 'NVIDIA_API_KEY',
77
- llm7: 'LLM7_API_KEY',
78
- deepseek: 'DEEPSEEK_API_KEY',
79
- fireworks: 'FIREWORKS_API_KEY',
80
- 'github-copilot': 'COPILOT_GITHUB_TOKEN',
81
- 'microsoft-foundry': 'AZURE_OPENAI_API_KEY',
82
- minimax: 'MINIMAX_API_KEY',
83
- moonshot: 'MOONSHOT_API_KEY',
84
- qianfan: 'QIANFAN_API_KEY',
85
- qwen: 'QWEN_API_KEY',
86
- sglang: 'SGLANG_API_KEY',
87
- stepfun: 'STEPFUN_API_KEY',
88
- together: 'TOGETHER_API_KEY',
89
- venice: 'VENICE_API_KEY',
90
- volcengine: 'VOLCANO_ENGINE_API_KEY',
91
- xai: 'XAI_API_KEY',
92
- xiaomi: 'XIAOMI_API_KEY',
93
- zai: 'ZAI_API_KEY',
94
- 'cloudflare-ai-gateway': 'CLOUDFLARE_AI_GATEWAY_API_KEY',
95
- 'vercel-ai-gateway': 'AI_GATEWAY_API_KEY',
96
- litellm: 'LITELLM_API_KEY',
97
- 'copilot-proxy': 'COPILOT_PROXY_API_KEY',
98
- };
99
- for (const [prov, envVar] of Object.entries(mapping)) {
100
- let value = process.env[envVar];
101
- // Fallback env var names
102
- if (!value && prov === 'gemini') value = process.env['GOOGLE_API_KEY'] ?? process.env['GOOGLE_GEMINI_API_KEY'];
103
- if (!value && prov === 'openai') value = process.env['OPENAI_KEY'];
104
- if (!value && prov === 'anthropic') value = process.env['CLAUDE_API_KEY'];
105
- if (!value && prov === 'ollama-cloud') value = process.env['OLLAMA_API_KEY'];
106
- if (!value && prov === 'huggingface') value = process.env['HUGGINGFACE_API_KEY'] ?? process.env['HF_TOKEN'];
107
- if (!value && prov === 'github-copilot') value = process.env['GH_TOKEN'] ?? process.env['GITHUB_TOKEN'];
108
- if (!value && prov === 'qwen') value = process.env['DASHSCOPE_API_KEY'] ?? process.env['MODELSTUDIO_API_KEY'];
109
- if (!value && prov === 'zai') value = process.env['Z_AI_API_KEY'];
110
- if (value) keys[prov] = value;
111
- }
112
- return keys;
113
- }
114
-
115
- /**
116
- * resolveApiKeys — three-tier async resolution for all provider API keys.
117
- *
118
- * Resolution order per key:
119
- * 1. Environment variable (process.env)
120
- * 2. SecretsManager hierarchy-aware stores (secure preferred, plaintext policy-aware)
121
- * 3. Omitted from result (null → skip)
122
- *
123
- * Returns a map of provider → apiKey for all providers where a key is found.
124
- */
125
- export async function resolveApiKeys(
126
- secrets: Pick<SecretsManager, 'get'>,
127
- ): Promise<Record<string, string>> {
128
- const mapping: Array<{ prov: string; envVars: string[] }> = [
129
- { prov: 'openai', envVars: ['OPENAI_API_KEY', 'OPENAI_KEY'] },
130
- { prov: 'anthropic', envVars: ['ANTHROPIC_API_KEY', 'CLAUDE_API_KEY'] },
131
- { prov: 'gemini', envVars: ['GEMINI_API_KEY', 'GOOGLE_API_KEY', 'GOOGLE_GEMINI_API_KEY'] },
132
- { prov: 'inceptionlabs', envVars: ['INCEPTION_API_KEY'] },
133
- { prov: 'openrouter', envVars: ['OPENROUTER_API_KEY'] },
134
- { prov: 'aihubmix', envVars: ['AIHUBMIX_API_KEY'] },
135
- { prov: 'groq', envVars: ['GROQ_API_KEY'] },
136
- { prov: 'cerebras', envVars: ['CEREBRAS_API_KEY'] },
137
- { prov: 'mistral', envVars: ['MISTRAL_API_KEY'] },
138
- { prov: 'ollama-cloud', envVars: ['OLLAMA_CLOUD_API_KEY', 'OLLAMA_API_KEY'] },
139
- { prov: 'huggingface', envVars: ['HF_API_KEY', 'HUGGINGFACE_API_KEY', 'HF_TOKEN'] },
140
- { prov: 'nvidia', envVars: ['NVIDIA_API_KEY'] },
141
- { prov: 'llm7', envVars: ['LLM7_API_KEY'] },
142
- { prov: 'deepseek', envVars: ['DEEPSEEK_API_KEY'] },
143
- { prov: 'fireworks', envVars: ['FIREWORKS_API_KEY'] },
144
- { prov: 'github-copilot', envVars: ['COPILOT_GITHUB_TOKEN', 'GH_TOKEN', 'GITHUB_TOKEN'] },
145
- { prov: 'microsoft-foundry', envVars: ['AZURE_OPENAI_API_KEY'] },
146
- { prov: 'minimax', envVars: ['MINIMAX_API_KEY'] },
147
- { prov: 'moonshot', envVars: ['MOONSHOT_API_KEY'] },
148
- { prov: 'qianfan', envVars: ['QIANFAN_API_KEY'] },
149
- { prov: 'qwen', envVars: ['QWEN_API_KEY', 'DASHSCOPE_API_KEY', 'MODELSTUDIO_API_KEY'] },
150
- { prov: 'sglang', envVars: ['SGLANG_API_KEY'] },
151
- { prov: 'stepfun', envVars: ['STEPFUN_API_KEY'] },
152
- { prov: 'together', envVars: ['TOGETHER_API_KEY'] },
153
- { prov: 'venice', envVars: ['VENICE_API_KEY'] },
154
- { prov: 'volcengine', envVars: ['VOLCANO_ENGINE_API_KEY'] },
155
- { prov: 'xai', envVars: ['XAI_API_KEY'] },
156
- { prov: 'xiaomi', envVars: ['XIAOMI_API_KEY'] },
157
- { prov: 'zai', envVars: ['ZAI_API_KEY', 'Z_AI_API_KEY'] },
158
- { prov: 'cloudflare-ai-gateway', envVars: ['CLOUDFLARE_AI_GATEWAY_API_KEY'] },
159
- { prov: 'vercel-ai-gateway', envVars: ['AI_GATEWAY_API_KEY'] },
160
- { prov: 'litellm', envVars: ['LITELLM_API_KEY'] },
161
- { prov: 'copilot-proxy', envVars: ['COPILOT_PROXY_API_KEY'] },
162
- ];
163
-
164
- const result: Record<string, string> = {};
165
-
166
- for (const { prov, envVars } of mapping) {
167
- // Tier 1: environment variables
168
- let value: string | null = null;
169
- for (const envVar of envVars) {
170
- if (process.env[envVar]) {
171
- value = process.env[envVar]!;
172
- break;
173
- }
174
- }
175
-
176
- // Tier 2: SecretsManager hierarchy-aware secure/plaintext stores
177
- if (value === null) {
178
- for (const envVar of envVars) {
179
- const stored = await secrets.get(envVar);
180
- if (stored !== null) {
181
- value = stored;
182
- break;
183
- }
184
- }
185
- }
186
-
187
- if (value !== null) {
188
- result[prov] = value;
189
- }
190
- }
191
-
192
- return result;
193
- }
56
+ export { getConfiguredApiKeys, resolveApiKeys } from '@pellux/goodvibes-sdk/platform/config/api-keys';
@@ -1,127 +1 @@
1
- import type { OAuthProviderConfig } from '@pellux/goodvibes-sdk/platform/config/subscriptions';
2
- import type { ServiceConfig } from './service-registry.ts';
3
-
4
- export interface BuiltinSubscriptionProvider {
5
- readonly provider: string;
6
- readonly displayName: string;
7
- readonly authType: 'oauth';
8
- readonly tokenKey: string;
9
- readonly providerId: string;
10
- readonly oauth: OAuthProviderConfig;
11
- readonly notes: readonly string[];
12
- }
13
-
14
- export interface AvailableSubscriptionProvider {
15
- readonly provider: string;
16
- readonly displayName: string;
17
- readonly source: 'builtin' | 'service';
18
- readonly oauth: OAuthProviderConfig;
19
- readonly tokenKey: string;
20
- readonly providerId: string;
21
- readonly notes: readonly string[];
22
- }
23
-
24
- const OPENAI_SUBSCRIPTION_PROVIDER: BuiltinSubscriptionProvider = {
25
- provider: 'openai',
26
- displayName: 'OpenAI Codex',
27
- authType: 'oauth',
28
- tokenKey: 'OPENAI_API_KEY',
29
- providerId: 'openai',
30
- oauth: {
31
- authUrl: 'https://auth.openai.com/oauth/authorize',
32
- tokenUrl: 'https://auth.openai.com/oauth/token',
33
- clientId: 'app_EMoamEEZ73f0CkXaXp7hrann',
34
- redirectUri: 'http://localhost:1455/auth/callback',
35
- scopes: ['openid', 'profile', 'email', 'offline_access'],
36
- usePkce: true,
37
- tokenRequestEncoding: 'form',
38
- refreshRequestEncoding: 'form',
39
- overrideAmbientApiKeys: false,
40
- authParams: {
41
- id_token_add_organizations: 'true',
42
- codex_cli_simplified_flow: 'true',
43
- originator: 'pi',
44
- },
45
- localCallback: {
46
- host: 'localhost',
47
- port: 1455,
48
- path: '/auth/callback',
49
- autoComplete: true,
50
- },
51
- },
52
- notes: [
53
- 'Built-in OpenAI Codex / ChatGPT subscription login path.',
54
- 'Uses the Codex/ChatGPT OAuth flow rather than the standard OpenAI API-key path.',
55
- ],
56
- };
57
-
58
- const BUILTIN_SUBSCRIPTION_PROVIDERS: Record<string, BuiltinSubscriptionProvider> = {
59
- openai: OPENAI_SUBSCRIPTION_PROVIDER,
60
- };
61
-
62
- export function listBuiltinSubscriptionProviders(): BuiltinSubscriptionProvider[] {
63
- return Object.values(BUILTIN_SUBSCRIPTION_PROVIDERS)
64
- .slice()
65
- .sort((a, b) => a.provider.localeCompare(b.provider));
66
- }
67
-
68
- export function getBuiltinSubscriptionProvider(provider: string): BuiltinSubscriptionProvider | null {
69
- return BUILTIN_SUBSCRIPTION_PROVIDERS[provider] ?? null;
70
- }
71
-
72
- export function getSubscriptionProviderConfig(
73
- provider: string,
74
- serviceConfig?: ServiceConfig | null,
75
- ): { oauth: OAuthProviderConfig; source: 'service' | 'builtin'; tokenKey: string; providerId: string } | null {
76
- if (serviceConfig?.authType === 'oauth' && serviceConfig.oauth) {
77
- return {
78
- oauth: serviceConfig.oauth,
79
- source: 'service',
80
- tokenKey: serviceConfig.tokenKey,
81
- providerId: serviceConfig.providerId ?? serviceConfig.name,
82
- };
83
- }
84
-
85
- const builtin = getBuiltinSubscriptionProvider(provider);
86
- if (!builtin) return null;
87
- return {
88
- oauth: builtin.oauth,
89
- source: 'builtin',
90
- tokenKey: builtin.tokenKey,
91
- providerId: builtin.providerId,
92
- };
93
- }
94
-
95
- export function listAvailableSubscriptionProviders(
96
- services: Record<string, ServiceConfig>,
97
- ): AvailableSubscriptionProvider[] {
98
- const providers = new Map<string, AvailableSubscriptionProvider>();
99
-
100
- for (const builtin of listBuiltinSubscriptionProviders()) {
101
- providers.set(builtin.provider, {
102
- provider: builtin.provider,
103
- displayName: builtin.displayName,
104
- source: 'builtin',
105
- oauth: builtin.oauth,
106
- tokenKey: builtin.tokenKey,
107
- providerId: builtin.providerId,
108
- notes: builtin.notes,
109
- });
110
- }
111
-
112
- for (const service of Object.values(services)) {
113
- if (service.authType !== 'oauth' || !service.oauth) continue;
114
- const provider = service.providerId ?? service.name;
115
- providers.set(provider, {
116
- provider,
117
- displayName: service.name,
118
- source: 'service',
119
- oauth: service.oauth,
120
- tokenKey: service.tokenKey,
121
- providerId: provider,
122
- notes: ['Configured through .goodvibes/tui/services.json'],
123
- });
124
- }
125
-
126
- return [...providers.values()].sort((a, b) => a.provider.localeCompare(b.provider));
127
- }
1
+ export * from '@pellux/goodvibes-sdk/platform/config/subscription-providers';
@@ -3,9 +3,9 @@ import { renderMarkdown, renderMarkdownTracked } from '../renderer/markdown.ts';
3
3
  import { renderToolCallBlock } from '../renderer/tool-call.ts';
4
4
  import { renderThinkingBlock } from '../renderer/thinking.ts';
5
5
  import { renderSystemMessage } from '../renderer/system-message.ts';
6
- import { createEmptyLine, type Line, type Cell } from '@pellux/goodvibes-sdk/platform/types/grid';
7
- import { getSplashLines, type SplashOptions } from '@pellux/goodvibes-sdk/platform/utils/splash-lines';
8
- import { interpolateColor, getDisplayWidth, wrapText } from '@pellux/goodvibes-sdk/platform/utils/terminal-width';
6
+ import { createEmptyLine, type Line, type Cell } from '../types/grid.ts';
7
+ import { getSplashLines, type SplashOptions } from '../utils/splash-lines.ts';
8
+ import { interpolateColor, getDisplayWidth, wrapText } from '../utils/terminal-width.ts';
9
9
  import { LAYOUT } from '../renderer/layout.ts';
10
10
  import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config/manager';
11
11
  import { renderConversationCollapsedFragment, renderConversationEventLine } from '../renderer/conversation-surface.ts';