@gxp-dev/tools 2.0.62 → 2.0.64

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 (182) hide show
  1. package/README.md +32 -31
  2. package/bin/gx-devtools.js +74 -54
  3. package/bin/lib/cli.js +23 -21
  4. package/bin/lib/commands/add-dependency.js +366 -325
  5. package/bin/lib/commands/assets.js +137 -139
  6. package/bin/lib/commands/build.js +169 -174
  7. package/bin/lib/commands/datastore.js +181 -183
  8. package/bin/lib/commands/dev.js +127 -131
  9. package/bin/lib/commands/extensions.js +147 -149
  10. package/bin/lib/commands/extract-config.js +73 -67
  11. package/bin/lib/commands/index.js +12 -12
  12. package/bin/lib/commands/init.js +342 -240
  13. package/bin/lib/commands/publish.js +69 -75
  14. package/bin/lib/commands/socket.js +69 -69
  15. package/bin/lib/commands/ssl.js +14 -14
  16. package/bin/lib/constants.js +10 -24
  17. package/bin/lib/tui/App.tsx +761 -705
  18. package/bin/lib/tui/components/AIPanel.tsx +191 -171
  19. package/bin/lib/tui/components/CommandInput.tsx +394 -343
  20. package/bin/lib/tui/components/GeminiPanel.tsx +175 -151
  21. package/bin/lib/tui/components/Header.tsx +23 -21
  22. package/bin/lib/tui/components/LogPanel.tsx +244 -220
  23. package/bin/lib/tui/components/TabBar.tsx +50 -48
  24. package/bin/lib/tui/components/WelcomeScreen.tsx +126 -71
  25. package/bin/lib/tui/index.tsx +37 -39
  26. package/bin/lib/tui/services/AIService.ts +518 -462
  27. package/bin/lib/tui/services/ExtensionService.ts +140 -129
  28. package/bin/lib/tui/services/GeminiService.ts +367 -337
  29. package/bin/lib/tui/services/ServiceManager.ts +344 -322
  30. package/bin/lib/tui/services/SocketService.ts +168 -168
  31. package/bin/lib/tui/services/ViteService.ts +88 -88
  32. package/bin/lib/tui/services/index.ts +47 -22
  33. package/bin/lib/utils/ai-scaffold.js +291 -280
  34. package/bin/lib/utils/extract-config.js +157 -140
  35. package/bin/lib/utils/files.js +82 -86
  36. package/bin/lib/utils/index.js +7 -7
  37. package/bin/lib/utils/paths.js +34 -34
  38. package/bin/lib/utils/prompts.js +194 -169
  39. package/bin/lib/utils/ssl.js +79 -81
  40. package/browser-extensions/README.md +0 -1
  41. package/browser-extensions/chrome/background.js +244 -237
  42. package/browser-extensions/chrome/content.js +32 -29
  43. package/browser-extensions/chrome/devtools.html +7 -7
  44. package/browser-extensions/chrome/devtools.js +19 -19
  45. package/browser-extensions/chrome/inspector.js +802 -767
  46. package/browser-extensions/chrome/manifest.json +71 -63
  47. package/browser-extensions/chrome/panel.html +674 -636
  48. package/browser-extensions/chrome/panel.js +722 -712
  49. package/browser-extensions/chrome/popup.html +586 -543
  50. package/browser-extensions/chrome/popup.js +282 -244
  51. package/browser-extensions/chrome/rules.json +1 -1
  52. package/browser-extensions/chrome/test-chrome.html +216 -136
  53. package/browser-extensions/chrome/test-mixed-content.html +284 -189
  54. package/browser-extensions/chrome/test-uri-pattern.html +221 -198
  55. package/browser-extensions/firefox/README.md +9 -6
  56. package/browser-extensions/firefox/background.js +221 -218
  57. package/browser-extensions/firefox/content.js +55 -52
  58. package/browser-extensions/firefox/debug-errors.html +386 -228
  59. package/browser-extensions/firefox/debug-https.html +153 -105
  60. package/browser-extensions/firefox/devtools.html +7 -7
  61. package/browser-extensions/firefox/devtools.js +23 -20
  62. package/browser-extensions/firefox/inspector.js +802 -767
  63. package/browser-extensions/firefox/manifest.json +68 -68
  64. package/browser-extensions/firefox/panel.html +674 -636
  65. package/browser-extensions/firefox/panel.js +722 -712
  66. package/browser-extensions/firefox/popup.html +572 -535
  67. package/browser-extensions/firefox/popup.js +281 -236
  68. package/browser-extensions/firefox/test-gramercy.html +170 -125
  69. package/browser-extensions/firefox/test-imports.html +59 -55
  70. package/browser-extensions/firefox/test-masking.html +231 -140
  71. package/browser-extensions/firefox/test-uri-pattern.html +221 -198
  72. package/dist/tui/App.d.ts +1 -1
  73. package/dist/tui/App.d.ts.map +1 -1
  74. package/dist/tui/App.js +154 -150
  75. package/dist/tui/App.js.map +1 -1
  76. package/dist/tui/components/AIPanel.d.ts.map +1 -1
  77. package/dist/tui/components/AIPanel.js +42 -35
  78. package/dist/tui/components/AIPanel.js.map +1 -1
  79. package/dist/tui/components/CommandInput.d.ts +1 -1
  80. package/dist/tui/components/CommandInput.d.ts.map +1 -1
  81. package/dist/tui/components/CommandInput.js +92 -62
  82. package/dist/tui/components/CommandInput.js.map +1 -1
  83. package/dist/tui/components/GeminiPanel.d.ts.map +1 -1
  84. package/dist/tui/components/GeminiPanel.js +37 -30
  85. package/dist/tui/components/GeminiPanel.js.map +1 -1
  86. package/dist/tui/components/Header.d.ts.map +1 -1
  87. package/dist/tui/components/Header.js +1 -1
  88. package/dist/tui/components/Header.js.map +1 -1
  89. package/dist/tui/components/LogPanel.d.ts +1 -1
  90. package/dist/tui/components/LogPanel.d.ts.map +1 -1
  91. package/dist/tui/components/LogPanel.js +26 -24
  92. package/dist/tui/components/LogPanel.js.map +1 -1
  93. package/dist/tui/components/TabBar.d.ts +2 -2
  94. package/dist/tui/components/TabBar.d.ts.map +1 -1
  95. package/dist/tui/components/TabBar.js +11 -11
  96. package/dist/tui/components/TabBar.js.map +1 -1
  97. package/dist/tui/components/WelcomeScreen.d.ts.map +1 -1
  98. package/dist/tui/components/WelcomeScreen.js +6 -6
  99. package/dist/tui/components/WelcomeScreen.js.map +1 -1
  100. package/dist/tui/index.d.ts.map +1 -1
  101. package/dist/tui/index.js +8 -8
  102. package/dist/tui/index.js.map +1 -1
  103. package/dist/tui/services/AIService.d.ts +2 -2
  104. package/dist/tui/services/AIService.d.ts.map +1 -1
  105. package/dist/tui/services/AIService.js +165 -125
  106. package/dist/tui/services/AIService.js.map +1 -1
  107. package/dist/tui/services/ExtensionService.d.ts +1 -1
  108. package/dist/tui/services/ExtensionService.d.ts.map +1 -1
  109. package/dist/tui/services/ExtensionService.js +33 -26
  110. package/dist/tui/services/ExtensionService.js.map +1 -1
  111. package/dist/tui/services/GeminiService.d.ts +1 -1
  112. package/dist/tui/services/GeminiService.d.ts.map +1 -1
  113. package/dist/tui/services/GeminiService.js +87 -76
  114. package/dist/tui/services/GeminiService.js.map +1 -1
  115. package/dist/tui/services/ServiceManager.d.ts +3 -3
  116. package/dist/tui/services/ServiceManager.d.ts.map +1 -1
  117. package/dist/tui/services/ServiceManager.js +72 -58
  118. package/dist/tui/services/ServiceManager.js.map +1 -1
  119. package/dist/tui/services/SocketService.d.ts.map +1 -1
  120. package/dist/tui/services/SocketService.js +32 -32
  121. package/dist/tui/services/SocketService.js.map +1 -1
  122. package/dist/tui/services/ViteService.d.ts.map +1 -1
  123. package/dist/tui/services/ViteService.js +26 -28
  124. package/dist/tui/services/ViteService.js.map +1 -1
  125. package/dist/tui/services/index.d.ts +6 -6
  126. package/dist/tui/services/index.d.ts.map +1 -1
  127. package/dist/tui/services/index.js +6 -6
  128. package/dist/tui/services/index.js.map +1 -1
  129. package/mcp/gxp-api-server.js +83 -81
  130. package/package.json +109 -93
  131. package/runtime/PortalContainer.vue +258 -234
  132. package/runtime/dev-tools/DevToolsModal.vue +153 -155
  133. package/runtime/dev-tools/LayoutSwitcher.vue +144 -140
  134. package/runtime/dev-tools/MockDataEditor.vue +456 -433
  135. package/runtime/dev-tools/SocketSimulator.vue +379 -371
  136. package/runtime/dev-tools/StoreInspector.vue +517 -455
  137. package/runtime/dev-tools/index.js +5 -5
  138. package/runtime/fallback-layouts/PrivateLayout.vue +2 -2
  139. package/runtime/fallback-layouts/PublicLayout.vue +2 -2
  140. package/runtime/fallback-layouts/SystemLayout.vue +2 -2
  141. package/runtime/gxpStringsPlugin.js +159 -134
  142. package/runtime/index.html +17 -19
  143. package/runtime/main.js +24 -22
  144. package/runtime/mock-api/auth-middleware.js +15 -15
  145. package/runtime/mock-api/image-generator.js +46 -46
  146. package/runtime/mock-api/index.js +55 -55
  147. package/runtime/mock-api/response-generator.js +116 -105
  148. package/runtime/mock-api/route-generator.js +107 -84
  149. package/runtime/mock-api/socket-triggers.js +94 -93
  150. package/runtime/mock-api/spec-loader.js +79 -80
  151. package/runtime/package.json +3 -0
  152. package/runtime/server.js +68 -68
  153. package/runtime/stores/gxpPortalConfigStore.js +204 -186
  154. package/runtime/stores/index.js +2 -2
  155. package/runtime/vite-inspector-plugin.js +858 -707
  156. package/runtime/vite-source-tracker-plugin.js +132 -113
  157. package/runtime/vite.config.js +207 -132
  158. package/scripts/launch-chrome.js +41 -41
  159. package/scripts/pack-chrome.js +38 -39
  160. package/socket-events/AiSessionMessageCreated.json +17 -17
  161. package/socket-events/SocialStreamPostCreated.json +23 -23
  162. package/socket-events/SocialStreamPostVariantCompleted.json +22 -22
  163. package/template/.claude/agents/gxp-developer.md +100 -99
  164. package/template/.claude/settings.json +7 -7
  165. package/template/AGENTS.md +30 -23
  166. package/template/GEMINI.md +20 -20
  167. package/template/README.md +70 -53
  168. package/template/app-manifest.json +2 -4
  169. package/template/configuration.json +10 -10
  170. package/template/default-styling.css +1 -1
  171. package/template/index.html +18 -20
  172. package/template/main.js +24 -22
  173. package/template/src/DemoPage.vue +415 -362
  174. package/template/src/Plugin.vue +76 -85
  175. package/template/src/stores/index.js +3 -3
  176. package/template/src/stores/test-data.json +164 -172
  177. package/template/theme-layouts/AdditionalStyling.css +50 -50
  178. package/template/theme-layouts/PrivateLayout.vue +8 -12
  179. package/template/theme-layouts/PublicLayout.vue +8 -12
  180. package/template/theme-layouts/SystemLayout.vue +8 -12
  181. package/template/vite.extend.js +45 -0
  182. package/template/vite.config.js +0 -409
@@ -1,204 +1,204 @@
1
- import { serviceManager, ServiceConfig } from './ServiceManager.js';
2
- import path from 'path';
3
- import fs from 'fs';
4
- import { fileURLToPath } from 'url';
5
- import https from 'https';
6
- import http from 'http';
1
+ import { serviceManager, ServiceConfig } from "./ServiceManager.js"
2
+ import path from "path"
3
+ import fs from "fs"
4
+ import { fileURLToPath } from "url"
5
+ import https from "https"
6
+ import http from "http"
7
7
 
8
8
  export interface SocketOptions {
9
- cwd?: string;
10
- withMock?: boolean;
9
+ cwd?: string
10
+ withMock?: boolean
11
11
  }
12
12
 
13
13
  export interface SocketEvent {
14
- name: string;
15
- event: string;
16
- channel: string;
17
- data: Record<string, unknown>;
14
+ name: string
15
+ event: string
16
+ channel: string
17
+ data: Record<string, unknown>
18
18
  }
19
19
 
20
20
  // Get toolkit root
21
21
  function getToolkitRoot(): string {
22
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
23
- // From dist/tui/services/ go up 3 levels to toolkit root
24
- return path.resolve(__dirname, '..', '..', '..');
22
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
23
+ // From dist/tui/services/ go up 3 levels to toolkit root
24
+ return path.resolve(__dirname, "..", "..", "..")
25
25
  }
26
26
 
27
27
  // Get the path to the runtime server.js
28
28
  function getServerPath(): string {
29
- const toolkitRoot = getToolkitRoot();
30
- return path.join(toolkitRoot, 'runtime', 'server.js');
29
+ const toolkitRoot = getToolkitRoot()
30
+ return path.join(toolkitRoot, "runtime", "server.js")
31
31
  }
32
32
 
33
33
  // Get the socket events directory
34
34
  function getSocketEventsDir(cwd: string): string | null {
35
- // Check local project first
36
- const localDir = path.join(cwd, 'socket-events');
37
- if (fs.existsSync(localDir)) {
38
- return localDir;
39
- }
40
-
41
- // Fall back to toolkit's socket-events
42
- const toolkitDir = path.join(getToolkitRoot(), 'socket-events');
43
- if (fs.existsSync(toolkitDir)) {
44
- return toolkitDir;
45
- }
46
-
47
- return null;
35
+ // Check local project first
36
+ const localDir = path.join(cwd, "socket-events")
37
+ if (fs.existsSync(localDir)) {
38
+ return localDir
39
+ }
40
+
41
+ // Fall back to toolkit's socket-events
42
+ const toolkitDir = path.join(getToolkitRoot(), "socket-events")
43
+ if (fs.existsSync(toolkitDir)) {
44
+ return toolkitDir
45
+ }
46
+
47
+ return null
48
48
  }
49
49
 
50
50
  export function startSocket(options: SocketOptions = {}): void {
51
- const cwd = options.cwd || process.cwd();
52
- const withMock = options.withMock || false;
53
-
54
- const env: Record<string, string> = {
55
- FORCE_COLOR: '1',
56
- };
57
-
58
- // Enable mock API if requested
59
- if (withMock) {
60
- env.MOCK_API_ENABLED = 'true';
61
- }
62
-
63
- const config: ServiceConfig = {
64
- id: 'socket',
65
- name: withMock ? 'Socket.IO + Mock API' : 'Socket.IO',
66
- command: 'node',
67
- args: [getServerPath()],
68
- cwd,
69
- env,
70
- };
71
-
72
- serviceManager.start(config);
51
+ const cwd = options.cwd || process.cwd()
52
+ const withMock = options.withMock || false
53
+
54
+ const env: Record<string, string> = {
55
+ FORCE_COLOR: "1",
56
+ }
57
+
58
+ // Enable mock API if requested
59
+ if (withMock) {
60
+ env.MOCK_API_ENABLED = "true"
61
+ }
62
+
63
+ const config: ServiceConfig = {
64
+ id: "socket",
65
+ name: withMock ? "Socket.IO + Mock API" : "Socket.IO",
66
+ command: "node",
67
+ args: [getServerPath()],
68
+ cwd,
69
+ env,
70
+ }
71
+
72
+ serviceManager.start(config)
73
73
  }
74
74
 
75
75
  export function stopSocket(): boolean {
76
- return serviceManager.stop('socket');
76
+ return serviceManager.stop("socket")
77
77
  }
78
78
 
79
79
  export function isSocketRunning(): boolean {
80
- return serviceManager.isRunning('socket');
80
+ return serviceManager.isRunning("socket")
81
81
  }
82
82
 
83
83
  // List available socket events
84
84
  export function listSocketEvents(cwd?: string): SocketEvent[] {
85
- const eventsDir = getSocketEventsDir(cwd || process.cwd());
86
- if (!eventsDir) {
87
- return [];
88
- }
89
-
90
- const events: SocketEvent[] = [];
91
- const files = fs.readdirSync(eventsDir).filter(f => f.endsWith('.json'));
92
-
93
- for (const file of files) {
94
- try {
95
- const content = fs.readFileSync(path.join(eventsDir, file), 'utf-8');
96
- const data = JSON.parse(content);
97
- events.push({
98
- name: path.basename(file, '.json'),
99
- event: data.event,
100
- channel: data.channel,
101
- data: data.data,
102
- });
103
- } catch {
104
- // Skip invalid files
105
- }
106
- }
107
-
108
- return events;
85
+ const eventsDir = getSocketEventsDir(cwd || process.cwd())
86
+ if (!eventsDir) {
87
+ return []
88
+ }
89
+
90
+ const events: SocketEvent[] = []
91
+ const files = fs.readdirSync(eventsDir).filter((f) => f.endsWith(".json"))
92
+
93
+ for (const file of files) {
94
+ try {
95
+ const content = fs.readFileSync(path.join(eventsDir, file), "utf-8")
96
+ const data = JSON.parse(content)
97
+ events.push({
98
+ name: path.basename(file, ".json"),
99
+ event: data.event,
100
+ channel: data.channel,
101
+ data: data.data,
102
+ })
103
+ } catch {
104
+ // Skip invalid files
105
+ }
106
+ }
107
+
108
+ return events
109
109
  }
110
110
 
111
111
  // Send a socket event
112
112
  export async function sendSocketEvent(
113
- eventName: string,
114
- identifier?: string,
115
- cwd?: string
113
+ eventName: string,
114
+ identifier?: string,
115
+ cwd?: string,
116
116
  ): Promise<{ success: boolean; message: string }> {
117
- const eventsDir = getSocketEventsDir(cwd || process.cwd());
118
- if (!eventsDir) {
119
- return { success: false, message: 'Socket events directory not found' };
120
- }
121
-
122
- const eventPath = path.join(eventsDir, `${eventName}.json`);
123
- if (!fs.existsSync(eventPath)) {
124
- return { success: false, message: `Event "${eventName}" not found` };
125
- }
126
-
127
- try {
128
- const content = fs.readFileSync(eventPath, 'utf-8');
129
- const eventData = JSON.parse(content);
130
-
131
- // Update channel if identifier provided
132
- if (identifier) {
133
- const channelParts = eventData.channel.split('.');
134
- if (channelParts.length >= 2) {
135
- const model = channelParts[1];
136
- eventData.channel = `private.${model}.${identifier}`;
137
- }
138
- }
139
-
140
- const socketPort = process.env.SOCKET_IO_PORT || 3069;
141
- const payload = JSON.stringify({
142
- event: eventData.event,
143
- channel: eventData.channel,
144
- data: eventData.data,
145
- });
146
-
147
- return new Promise((resolve) => {
148
- // Try HTTPS first, then HTTP
149
- const tryRequest = (useHttps: boolean) => {
150
- const protocol = useHttps ? https : http;
151
- const url = `${useHttps ? 'https' : 'http'}://localhost:${socketPort}/emit`;
152
-
153
- const req = protocol.request(
154
- url,
155
- {
156
- method: 'POST',
157
- headers: {
158
- 'Content-Type': 'application/json',
159
- 'Content-Length': Buffer.byteLength(payload),
160
- },
161
- rejectUnauthorized: false, // Allow self-signed certs
162
- },
163
- (res) => {
164
- if (res.statusCode === 200) {
165
- resolve({
166
- success: true,
167
- message: `Sent "${eventData.event}" to channel "${eventData.channel}"`,
168
- });
169
- } else {
170
- resolve({
171
- success: false,
172
- message: `Server returned status ${res.statusCode}`,
173
- });
174
- }
175
- }
176
- );
177
-
178
- req.on('error', (err) => {
179
- if (useHttps && err.message.includes('ECONNREFUSED')) {
180
- // Try HTTP if HTTPS fails
181
- tryRequest(false);
182
- } else {
183
- resolve({
184
- success: false,
185
- message: err.message.includes('ECONNREFUSED')
186
- ? 'Socket.IO server not running. Start it with /socket'
187
- : `Error: ${err.message}`,
188
- });
189
- }
190
- });
191
-
192
- req.write(payload);
193
- req.end();
194
- };
195
-
196
- tryRequest(true);
197
- });
198
- } catch (err) {
199
- return {
200
- success: false,
201
- message: `Error reading event file: ${err instanceof Error ? err.message : 'Unknown error'}`,
202
- };
203
- }
117
+ const eventsDir = getSocketEventsDir(cwd || process.cwd())
118
+ if (!eventsDir) {
119
+ return { success: false, message: "Socket events directory not found" }
120
+ }
121
+
122
+ const eventPath = path.join(eventsDir, `${eventName}.json`)
123
+ if (!fs.existsSync(eventPath)) {
124
+ return { success: false, message: `Event "${eventName}" not found` }
125
+ }
126
+
127
+ try {
128
+ const content = fs.readFileSync(eventPath, "utf-8")
129
+ const eventData = JSON.parse(content)
130
+
131
+ // Update channel if identifier provided
132
+ if (identifier) {
133
+ const channelParts = eventData.channel.split(".")
134
+ if (channelParts.length >= 2) {
135
+ const model = channelParts[1]
136
+ eventData.channel = `private.${model}.${identifier}`
137
+ }
138
+ }
139
+
140
+ const socketPort = process.env.SOCKET_IO_PORT || 3069
141
+ const payload = JSON.stringify({
142
+ event: eventData.event,
143
+ channel: eventData.channel,
144
+ data: eventData.data,
145
+ })
146
+
147
+ return new Promise((resolve) => {
148
+ // Try HTTPS first, then HTTP
149
+ const tryRequest = (useHttps: boolean) => {
150
+ const protocol = useHttps ? https : http
151
+ const url = `${useHttps ? "https" : "http"}://localhost:${socketPort}/emit`
152
+
153
+ const req = protocol.request(
154
+ url,
155
+ {
156
+ method: "POST",
157
+ headers: {
158
+ "Content-Type": "application/json",
159
+ "Content-Length": Buffer.byteLength(payload),
160
+ },
161
+ rejectUnauthorized: false, // Allow self-signed certs
162
+ },
163
+ (res) => {
164
+ if (res.statusCode === 200) {
165
+ resolve({
166
+ success: true,
167
+ message: `Sent "${eventData.event}" to channel "${eventData.channel}"`,
168
+ })
169
+ } else {
170
+ resolve({
171
+ success: false,
172
+ message: `Server returned status ${res.statusCode}`,
173
+ })
174
+ }
175
+ },
176
+ )
177
+
178
+ req.on("error", (err) => {
179
+ if (useHttps && err.message.includes("ECONNREFUSED")) {
180
+ // Try HTTP if HTTPS fails
181
+ tryRequest(false)
182
+ } else {
183
+ resolve({
184
+ success: false,
185
+ message: err.message.includes("ECONNREFUSED")
186
+ ? "Socket.IO server not running. Start it with /socket"
187
+ : `Error: ${err.message}`,
188
+ })
189
+ }
190
+ })
191
+
192
+ req.write(payload)
193
+ req.end()
194
+ }
195
+
196
+ tryRequest(true)
197
+ })
198
+ } catch (err) {
199
+ return {
200
+ success: false,
201
+ message: `Error reading event file: ${err instanceof Error ? err.message : "Unknown error"}`,
202
+ }
203
+ }
204
204
  }
@@ -1,107 +1,107 @@
1
- import { serviceManager, ServiceConfig } from './ServiceManager.js';
2
- import path from 'path';
3
- import fs from 'fs';
4
- import { fileURLToPath } from 'url';
5
- import dotenv from 'dotenv';
1
+ import { serviceManager, ServiceConfig } from "./ServiceManager.js"
2
+ import path from "path"
3
+ import fs from "fs"
4
+ import { fileURLToPath } from "url"
5
+ import dotenv from "dotenv"
6
6
 
7
7
  export interface ViteOptions {
8
- noHttps?: boolean;
9
- cwd?: string;
8
+ noHttps?: boolean
9
+ cwd?: string
10
10
  }
11
11
 
12
12
  // Get the toolkit root directory
13
13
  function getToolkitRoot(): string {
14
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
- // Navigate from dist/tui/services to project root (3 levels up)
16
- return path.resolve(__dirname, '..', '..', '..');
14
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
15
+ // Navigate from dist/tui/services to project root (3 levels up)
16
+ return path.resolve(__dirname, "..", "..", "..")
17
17
  }
18
18
 
19
19
  // Find existing SSL certificates in a directory
20
- function findExistingCertificates(certsDir: string): { certPath: string; keyPath: string } | null {
21
- if (!fs.existsSync(certsDir)) return null;
22
-
23
- const files = fs.readdirSync(certsDir);
24
- const certFile = files.find(f => f.endsWith('.pem') && !f.includes('key'));
25
- const keyFile = files.find(f => f.includes('key') && f.endsWith('.pem'));
26
-
27
- if (certFile && keyFile) {
28
- return {
29
- certPath: path.join(certsDir, certFile),
30
- keyPath: path.join(certsDir, keyFile),
31
- };
32
- }
33
- return null;
20
+ function findExistingCertificates(
21
+ certsDir: string,
22
+ ): { certPath: string; keyPath: string } | null {
23
+ if (!fs.existsSync(certsDir)) return null
24
+
25
+ const files = fs.readdirSync(certsDir)
26
+ const certFile = files.find((f) => f.endsWith(".pem") && !f.includes("key"))
27
+ const keyFile = files.find((f) => f.includes("key") && f.endsWith(".pem"))
28
+
29
+ if (certFile && keyFile) {
30
+ return {
31
+ certPath: path.join(certsDir, certFile),
32
+ keyPath: path.join(certsDir, keyFile),
33
+ }
34
+ }
35
+ return null
34
36
  }
35
37
 
36
38
  export function startVite(options: ViteOptions = {}): void {
37
- const cwd = options.cwd || process.cwd();
38
- const toolkitRoot = getToolkitRoot();
39
-
40
- // Load .env file if it exists
41
- const envPath = path.join(cwd, '.env');
42
- let envVars: Record<string, string> = {};
43
-
44
- if (fs.existsSync(envPath)) {
45
- const envResult = dotenv.config({ path: envPath });
46
- if (envResult.parsed) {
47
- envVars = { ...envResult.parsed };
48
- }
49
- }
50
-
51
- // Determine HTTPS settings
52
- let useHttps = !options.noHttps;
53
- let certPath = '';
54
- let keyPath = '';
55
-
56
- if (useHttps) {
57
- const certsDir = path.join(cwd, '.certs');
58
- const existingCerts = findExistingCertificates(certsDir);
59
- if (existingCerts) {
60
- certPath = existingCerts.certPath;
61
- keyPath = existingCerts.keyPath;
62
- } else {
63
- useHttps = false; // No certs found, fall back to HTTP
64
- }
65
- }
66
-
67
- // Determine the port (priority: .env > default)
68
- const port = envVars.NODE_PORT || '3060';
69
-
70
- // Find vite.config.js (local or toolkit runtime)
71
- const localViteConfig = path.join(cwd, 'vite.config.js');
72
- // The correct vite.config.js is in the runtime directory, not the root
73
- const toolkitViteConfig = path.join(toolkitRoot, 'runtime', 'vite.config.js');
74
- const viteConfigPath = fs.existsSync(localViteConfig) ? localViteConfig : toolkitViteConfig;
75
-
76
- // Build final environment variables
77
- const env: Record<string, string> = {
78
- ...envVars,
79
- FORCE_COLOR: '1',
80
- NODE_PORT: port,
81
- USE_HTTPS: useHttps ? 'true' : 'false',
82
- CERT_PATH: certPath,
83
- KEY_PATH: keyPath,
84
- COMPONENT_PATH: envVars.COMPONENT_PATH || './src/Plugin.vue',
85
- NODE_LOG_LEVEL: envVars.NODE_LOG_LEVEL || 'info',
86
- };
87
-
88
- // Run vite directly with the correct config
89
- const config: ServiceConfig = {
90
- id: 'vite',
91
- name: 'Vite',
92
- command: 'npx',
93
- args: ['vite', 'dev', '--config', viteConfigPath],
94
- cwd,
95
- env,
96
- };
97
-
98
- serviceManager.start(config);
39
+ const cwd = options.cwd || process.cwd()
40
+ const toolkitRoot = getToolkitRoot()
41
+
42
+ // Load .env file if it exists
43
+ const envPath = path.join(cwd, ".env")
44
+ let envVars: Record<string, string> = {}
45
+
46
+ if (fs.existsSync(envPath)) {
47
+ const envResult = dotenv.config({ path: envPath })
48
+ if (envResult.parsed) {
49
+ envVars = { ...envResult.parsed }
50
+ }
51
+ }
52
+
53
+ // Determine HTTPS settings
54
+ let useHttps = !options.noHttps
55
+ let certPath = ""
56
+ let keyPath = ""
57
+
58
+ if (useHttps) {
59
+ const certsDir = path.join(cwd, ".certs")
60
+ const existingCerts = findExistingCertificates(certsDir)
61
+ if (existingCerts) {
62
+ certPath = existingCerts.certPath
63
+ keyPath = existingCerts.keyPath
64
+ } else {
65
+ useHttps = false // No certs found, fall back to HTTP
66
+ }
67
+ }
68
+
69
+ // Determine the port (priority: .env > default)
70
+ const port = envVars.NODE_PORT || "3060"
71
+
72
+ // Vite config always comes from the runtime. Projects extend it via an
73
+ // optional `vite.extend.js` at the project root.
74
+ const viteConfigPath = path.join(toolkitRoot, "runtime", "vite.config.js")
75
+
76
+ // Build final environment variables
77
+ const env: Record<string, string> = {
78
+ ...envVars,
79
+ FORCE_COLOR: "1",
80
+ NODE_PORT: port,
81
+ USE_HTTPS: useHttps ? "true" : "false",
82
+ CERT_PATH: certPath,
83
+ KEY_PATH: keyPath,
84
+ COMPONENT_PATH: envVars.COMPONENT_PATH || "./src/Plugin.vue",
85
+ NODE_LOG_LEVEL: envVars.NODE_LOG_LEVEL || "info",
86
+ }
87
+
88
+ // Run vite directly with the correct config
89
+ const config: ServiceConfig = {
90
+ id: "vite",
91
+ name: "Vite",
92
+ command: "npx",
93
+ args: ["vite", "dev", "--config", viteConfigPath],
94
+ cwd,
95
+ env,
96
+ }
97
+
98
+ serviceManager.start(config)
99
99
  }
100
100
 
101
101
  export function stopVite(): boolean {
102
- return serviceManager.stop('vite');
102
+ return serviceManager.stop("vite")
103
103
  }
104
104
 
105
105
  export function isViteRunning(): boolean {
106
- return serviceManager.isRunning('vite');
106
+ return serviceManager.isRunning("vite")
107
107
  }
@@ -1,24 +1,49 @@
1
- export { serviceManager, ServiceManager, ServiceStatus, ServiceConfig, ServiceState } from './ServiceManager.js';
2
- export { startVite, stopVite, isViteRunning, ViteOptions } from './ViteService.js';
3
- export { startSocket, stopSocket, isSocketRunning, listSocketEvents, sendSocketEvent, SocketOptions, SocketEvent } from './SocketService.js';
4
- export { startExtension, stopExtension, isExtensionRunning, BrowserType, ExtensionOptions } from './ExtensionService.js';
5
1
  export {
6
- geminiService,
7
- GeminiService,
8
- GeminiConfig,
9
- isAuthenticated,
10
- loadGeminiConfig,
11
- saveGeminiConfig,
12
- clearAuthTokens
13
- } from './GeminiService.js';
2
+ serviceManager,
3
+ ServiceManager,
4
+ ServiceStatus,
5
+ ServiceConfig,
6
+ ServiceState,
7
+ } from "./ServiceManager.js"
14
8
  export {
15
- aiService,
16
- AIService,
17
- AIProvider,
18
- AIProviderInfo,
19
- AIConfig,
20
- loadAIConfig,
21
- saveAIConfig,
22
- getAvailableProviders,
23
- getProviderStatus
24
- } from './AIService.js';
9
+ startVite,
10
+ stopVite,
11
+ isViteRunning,
12
+ ViteOptions,
13
+ } from "./ViteService.js"
14
+ export {
15
+ startSocket,
16
+ stopSocket,
17
+ isSocketRunning,
18
+ listSocketEvents,
19
+ sendSocketEvent,
20
+ SocketOptions,
21
+ SocketEvent,
22
+ } from "./SocketService.js"
23
+ export {
24
+ startExtension,
25
+ stopExtension,
26
+ isExtensionRunning,
27
+ BrowserType,
28
+ ExtensionOptions,
29
+ } from "./ExtensionService.js"
30
+ export {
31
+ geminiService,
32
+ GeminiService,
33
+ GeminiConfig,
34
+ isAuthenticated,
35
+ loadGeminiConfig,
36
+ saveGeminiConfig,
37
+ clearAuthTokens,
38
+ } from "./GeminiService.js"
39
+ export {
40
+ aiService,
41
+ AIService,
42
+ AIProvider,
43
+ AIProviderInfo,
44
+ AIConfig,
45
+ loadAIConfig,
46
+ saveAIConfig,
47
+ getAvailableProviders,
48
+ getProviderStatus,
49
+ } from "./AIService.js"