@gxp-dev/tools 2.0.5
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/.github/workflows/npm-publish.yml +48 -0
- package/CLAUDE.md +400 -0
- package/README.md +247 -0
- package/REFACTOR_PLAN.md +194 -0
- package/bin/gx-devtools.js +87 -0
- package/bin/lib/cli.js +251 -0
- package/bin/lib/commands/assets.js +337 -0
- package/bin/lib/commands/build.js +259 -0
- package/bin/lib/commands/datastore.js +433 -0
- package/bin/lib/commands/dev.js +328 -0
- package/bin/lib/commands/extensions.js +298 -0
- package/bin/lib/commands/index.js +35 -0
- package/bin/lib/commands/init.js +307 -0
- package/bin/lib/commands/publish.js +189 -0
- package/bin/lib/commands/socket.js +158 -0
- package/bin/lib/commands/ssl.js +47 -0
- package/bin/lib/constants.js +120 -0
- package/bin/lib/tui/App.tsx +600 -0
- package/bin/lib/tui/components/CommandInput.tsx +278 -0
- package/bin/lib/tui/components/GeminiPanel.tsx +161 -0
- package/bin/lib/tui/components/Header.tsx +27 -0
- package/bin/lib/tui/components/LogPanel.tsx +122 -0
- package/bin/lib/tui/components/TabBar.tsx +56 -0
- package/bin/lib/tui/components/WelcomeScreen.tsx +80 -0
- package/bin/lib/tui/index.tsx +63 -0
- package/bin/lib/tui/services/ExtensionService.ts +122 -0
- package/bin/lib/tui/services/GeminiService.ts +395 -0
- package/bin/lib/tui/services/ServiceManager.ts +336 -0
- package/bin/lib/tui/services/SocketService.ts +204 -0
- package/bin/lib/tui/services/ViteService.ts +107 -0
- package/bin/lib/tui/services/index.ts +13 -0
- package/bin/lib/utils/files.js +180 -0
- package/bin/lib/utils/index.js +17 -0
- package/bin/lib/utils/paths.js +138 -0
- package/bin/lib/utils/prompts.js +71 -0
- package/bin/lib/utils/ssl.js +233 -0
- package/browser-extensions/README.md +1 -0
- package/browser-extensions/chrome/background.js +857 -0
- package/browser-extensions/chrome/content.js +51 -0
- package/browser-extensions/chrome/devtools.html +9 -0
- package/browser-extensions/chrome/devtools.js +23 -0
- package/browser-extensions/chrome/icons/gx_off_128.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_16.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_32.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_64.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_128.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_16.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_32.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_64.png +0 -0
- package/browser-extensions/chrome/inspector.js +1087 -0
- package/browser-extensions/chrome/manifest.json +70 -0
- package/browser-extensions/chrome/panel.html +638 -0
- package/browser-extensions/chrome/panel.js +862 -0
- package/browser-extensions/chrome/popup.html +399 -0
- package/browser-extensions/chrome/popup.js +515 -0
- package/browser-extensions/chrome/rules.json +1 -0
- package/browser-extensions/chrome/test-chrome.html +145 -0
- package/browser-extensions/chrome/test-mixed-content.html +190 -0
- package/browser-extensions/chrome/test-uri-pattern.html +199 -0
- package/browser-extensions/firefox/README.md +134 -0
- package/browser-extensions/firefox/background.js +804 -0
- package/browser-extensions/firefox/content.js +120 -0
- package/browser-extensions/firefox/debug-errors.html +229 -0
- package/browser-extensions/firefox/debug-https.html +113 -0
- package/browser-extensions/firefox/devtools.html +9 -0
- package/browser-extensions/firefox/devtools.js +24 -0
- package/browser-extensions/firefox/icons/gx_off_128.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_16.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_32.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_64.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_128.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_16.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_32.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_64.png +0 -0
- package/browser-extensions/firefox/inspector.js +1087 -0
- package/browser-extensions/firefox/manifest.json +67 -0
- package/browser-extensions/firefox/panel.html +638 -0
- package/browser-extensions/firefox/panel.js +862 -0
- package/browser-extensions/firefox/popup.html +525 -0
- package/browser-extensions/firefox/popup.js +536 -0
- package/browser-extensions/firefox/test-gramercy.html +126 -0
- package/browser-extensions/firefox/test-imports.html +58 -0
- package/browser-extensions/firefox/test-masking.html +147 -0
- package/browser-extensions/firefox/test-uri-pattern.html +199 -0
- package/docs/DOCUSAURUS_IMPORT.md +378 -0
- package/docs/_category_.json +8 -0
- package/docs/app-manifest.md +272 -0
- package/docs/building-for-platform.md +315 -0
- package/docs/dev-tools.md +291 -0
- package/docs/getting-started.md +180 -0
- package/docs/gxp-store.md +305 -0
- package/docs/index.md +44 -0
- package/package.json +77 -0
- package/runtime/PortalContainer.vue +326 -0
- package/runtime/dev-tools/DevToolsModal.vue +217 -0
- package/runtime/dev-tools/LayoutSwitcher.vue +221 -0
- package/runtime/dev-tools/MockDataEditor.vue +621 -0
- package/runtime/dev-tools/SocketSimulator.vue +562 -0
- package/runtime/dev-tools/StoreInspector.vue +644 -0
- package/runtime/dev-tools/index.js +6 -0
- package/runtime/gxpStringsPlugin.js +428 -0
- package/runtime/index.html +22 -0
- package/runtime/main.js +32 -0
- package/runtime/mock-api/auth-middleware.js +97 -0
- package/runtime/mock-api/image-generator.js +221 -0
- package/runtime/mock-api/index.js +197 -0
- package/runtime/mock-api/response-generator.js +394 -0
- package/runtime/mock-api/route-generator.js +323 -0
- package/runtime/mock-api/socket-triggers.js +371 -0
- package/runtime/mock-api/spec-loader.js +300 -0
- package/runtime/server.js +180 -0
- package/runtime/stores/gxpPortalConfigStore.js +554 -0
- package/runtime/stores/index.js +6 -0
- package/runtime/vite-inspector-plugin.js +749 -0
- package/runtime/vite-source-tracker-plugin.js +232 -0
- package/runtime/vite.config.js +402 -0
- package/scripts/launch-chrome.js +90 -0
- package/scripts/pack-chrome.js +91 -0
- package/socket-events/AiSessionMessageCreated.json +18 -0
- package/socket-events/SocialStreamPostCreated.json +24 -0
- package/socket-events/SocialStreamPostVariantCompleted.json +23 -0
- package/template/README.md +332 -0
- package/template/app-manifest.json +32 -0
- package/template/dev-assets/images/avatar-placeholder.png +0 -0
- package/template/dev-assets/images/background-placeholder.jpg +0 -0
- package/template/dev-assets/images/banner-placeholder.jpg +0 -0
- package/template/dev-assets/images/icon-placeholder.png +0 -0
- package/template/dev-assets/images/logo-placeholder.png +0 -0
- package/template/dev-assets/images/product-placeholder.jpg +0 -0
- package/template/dev-assets/images/thumbnail-placeholder.jpg +0 -0
- package/template/env.example +51 -0
- package/template/gitignore +53 -0
- package/template/index.html +22 -0
- package/template/main.js +28 -0
- package/template/src/DemoPage.vue +459 -0
- package/template/src/Plugin.vue +38 -0
- package/template/src/stores/index.js +9 -0
- package/template/src/stores/test-data.json +173 -0
- package/template/theme-layouts/AdditionalStyling.css +0 -0
- package/template/theme-layouts/PrivateLayout.vue +39 -0
- package/template/theme-layouts/PublicLayout.vue +39 -0
- package/template/theme-layouts/SystemLayout.vue +39 -0
- package/template/vite.config.js +333 -0
- package/tsconfig.tui.json +21 -0
- package/vite.config.js +164 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev Command
|
|
3
|
+
*
|
|
4
|
+
* Starts the development server with optional Socket.IO support
|
|
5
|
+
* and browser extension launching.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require("path");
|
|
9
|
+
const fs = require("fs");
|
|
10
|
+
const shell = require("shelljs");
|
|
11
|
+
const dotenv = require("dotenv");
|
|
12
|
+
const { exportCmd } = require("../constants");
|
|
13
|
+
const {
|
|
14
|
+
findProjectRoot,
|
|
15
|
+
resolveGxPaths,
|
|
16
|
+
resolveFilePath,
|
|
17
|
+
findExistingCertificates,
|
|
18
|
+
} = require("../utils");
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get browser extension paths and commands
|
|
22
|
+
* @param {string} browser - "firefox" or "chrome"
|
|
23
|
+
* @param {string} projectPath - Project root path
|
|
24
|
+
* @param {Object} paths - Resolved GxP paths
|
|
25
|
+
* @param {Object} options - Additional options
|
|
26
|
+
* @param {boolean} options.useHttps - Whether HTTPS is enabled
|
|
27
|
+
* @param {number|string} options.port - Dev server port
|
|
28
|
+
*/
|
|
29
|
+
function getBrowserExtensionConfig(browser, projectPath, paths, options = {}) {
|
|
30
|
+
const { useHttps = true, port = 3060 } = options;
|
|
31
|
+
const protocol = useHttps ? "https" : "http";
|
|
32
|
+
const startUrl = `${protocol}://localhost:${port}`;
|
|
33
|
+
|
|
34
|
+
if (browser === "firefox") {
|
|
35
|
+
let extensionPath = path.join(projectPath, "browser-extensions", "firefox");
|
|
36
|
+
|
|
37
|
+
if (!fs.existsSync(extensionPath)) {
|
|
38
|
+
const toolkitExtensionPath = path.join(
|
|
39
|
+
paths.packageRoot,
|
|
40
|
+
"browser-extensions",
|
|
41
|
+
"firefox"
|
|
42
|
+
);
|
|
43
|
+
if (fs.existsSync(toolkitExtensionPath)) {
|
|
44
|
+
extensionPath = toolkitExtensionPath;
|
|
45
|
+
} else {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
name: "FIREFOX",
|
|
52
|
+
color: "yellow",
|
|
53
|
+
command: `npx web-ext run --source-dir "${extensionPath}" --start-url "${startUrl}"`,
|
|
54
|
+
extensionPath,
|
|
55
|
+
startUrl,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (browser === "chrome") {
|
|
60
|
+
let extensionPath = path.join(projectPath, "browser-extensions", "chrome");
|
|
61
|
+
let scriptPath = path.join(projectPath, "scripts", "launch-chrome.js");
|
|
62
|
+
|
|
63
|
+
if (!fs.existsSync(extensionPath)) {
|
|
64
|
+
const toolkitExtensionPath = path.join(
|
|
65
|
+
paths.packageRoot,
|
|
66
|
+
"browser-extensions",
|
|
67
|
+
"chrome"
|
|
68
|
+
);
|
|
69
|
+
if (fs.existsSync(toolkitExtensionPath)) {
|
|
70
|
+
extensionPath = toolkitExtensionPath;
|
|
71
|
+
scriptPath = path.join(
|
|
72
|
+
paths.packageRoot,
|
|
73
|
+
"scripts",
|
|
74
|
+
"launch-chrome.js"
|
|
75
|
+
);
|
|
76
|
+
} else {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!fs.existsSync(scriptPath)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
name: "CHROME",
|
|
87
|
+
color: "blue",
|
|
88
|
+
command: `CHROME_EXTENSION_PATH="${extensionPath}" USE_HTTPS="${useHttps}" NODE_PORT="${port}" node "${scriptPath}"`,
|
|
89
|
+
extensionPath,
|
|
90
|
+
startUrl,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Development command - starts the dev server
|
|
99
|
+
*/
|
|
100
|
+
function devCommand(argv) {
|
|
101
|
+
const paths = resolveGxPaths();
|
|
102
|
+
const projectPath = findProjectRoot();
|
|
103
|
+
|
|
104
|
+
// Load .env file if it exists for default values
|
|
105
|
+
const envPath = path.join(projectPath, ".env");
|
|
106
|
+
const envExamplePath = path.join(projectPath, ".env.example");
|
|
107
|
+
|
|
108
|
+
// Load .env file into process.env
|
|
109
|
+
if (fs.existsSync(envPath)) {
|
|
110
|
+
console.log("📋 Loading environment variables from .env file");
|
|
111
|
+
dotenv.config({ path: envPath });
|
|
112
|
+
} else if (fs.existsSync(envExamplePath)) {
|
|
113
|
+
console.log(
|
|
114
|
+
"💡 Tip: Create .env file from .env.example to customize your environment settings"
|
|
115
|
+
);
|
|
116
|
+
console.log(" cp .env.example .env");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Check for SSL certificates unless explicitly disabled
|
|
120
|
+
let useHttps = !argv["no-https"];
|
|
121
|
+
let certPath = "";
|
|
122
|
+
let keyPath = "";
|
|
123
|
+
|
|
124
|
+
if (useHttps) {
|
|
125
|
+
const certsDir = path.join(projectPath, ".certs");
|
|
126
|
+
const existingCerts = findExistingCertificates(certsDir);
|
|
127
|
+
|
|
128
|
+
if (!existingCerts) {
|
|
129
|
+
console.log(
|
|
130
|
+
"⚠ SSL certificates not found. Run 'npm run setup-ssl' to enable HTTPS"
|
|
131
|
+
);
|
|
132
|
+
console.log("🌐 Starting HTTP development server...");
|
|
133
|
+
useHttps = false;
|
|
134
|
+
} else {
|
|
135
|
+
console.log("🔒 Starting HTTPS development server...");
|
|
136
|
+
console.log(
|
|
137
|
+
`📁 Using certificate: ${path.basename(existingCerts.certPath)}`
|
|
138
|
+
);
|
|
139
|
+
console.log(`🔑 Using key: ${path.basename(existingCerts.keyPath)}`);
|
|
140
|
+
certPath = existingCerts.certPath;
|
|
141
|
+
keyPath = existingCerts.keyPath;
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
console.log("🌐 Starting HTTP development server...");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Determine final port value (priority: CLI arg > .env > default)
|
|
148
|
+
const finalPort = argv.port || process.env.NODE_PORT || 3000;
|
|
149
|
+
console.log(`🌐 Development server will start on port: ${finalPort}`);
|
|
150
|
+
|
|
151
|
+
// Check if mock API should be enabled
|
|
152
|
+
const withMock = argv["with-mock"];
|
|
153
|
+
if (withMock) {
|
|
154
|
+
console.log("🎭 Mock API will be enabled");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Check if socket server should be started
|
|
158
|
+
const withSocket = argv["with-socket"];
|
|
159
|
+
let serverJsPath = "";
|
|
160
|
+
if (withSocket) {
|
|
161
|
+
// Check for local server.js first, then runtime directory
|
|
162
|
+
const serverJs = resolveFilePath("server.js", "", "runtime");
|
|
163
|
+
if (!fs.existsSync(serverJs.path)) {
|
|
164
|
+
console.error("❌ server.js not found. Cannot start Socket.IO server.");
|
|
165
|
+
console.log(
|
|
166
|
+
"💡 Run 'gxdev publish server.js' to create a local copy, or ensure you're in a GxP project directory"
|
|
167
|
+
);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
serverJsPath = serverJs.path;
|
|
171
|
+
console.log(
|
|
172
|
+
`📡 Starting Socket.IO server with nodemon... (${
|
|
173
|
+
serverJs.isLocal ? "local" : "package"
|
|
174
|
+
} version)`
|
|
175
|
+
);
|
|
176
|
+
console.log(`📁 Using: ${serverJsPath}`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Check for local dev files, otherwise use runtime versions
|
|
180
|
+
// These files can be published for customization: gxdev publish vite.config.js
|
|
181
|
+
let viteConfigPath = paths.viteConfigPath;
|
|
182
|
+
const localViteConfigPath = path.join(projectPath, "vite.config.js");
|
|
183
|
+
const localIndexHtml = path.join(projectPath, "index.html");
|
|
184
|
+
const localMainJs = path.join(projectPath, "main.js");
|
|
185
|
+
|
|
186
|
+
const hasLocalViteConfig = fs.existsSync(localViteConfigPath);
|
|
187
|
+
const hasLocalIndexHtml = fs.existsSync(localIndexHtml);
|
|
188
|
+
const hasLocalMainJs = fs.existsSync(localMainJs);
|
|
189
|
+
|
|
190
|
+
if (hasLocalViteConfig) {
|
|
191
|
+
viteConfigPath = localViteConfigPath;
|
|
192
|
+
console.log("📁 Using local vite.config.js");
|
|
193
|
+
}
|
|
194
|
+
if (hasLocalIndexHtml) {
|
|
195
|
+
console.log("📁 Using local index.html");
|
|
196
|
+
}
|
|
197
|
+
if (hasLocalMainJs) {
|
|
198
|
+
console.log("📁 Using local main.js");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Log if using all runtime files (default)
|
|
202
|
+
if (!hasLocalViteConfig && !hasLocalIndexHtml && !hasLocalMainJs) {
|
|
203
|
+
console.log("📦 Using runtime dev files (publish to customize)");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Only set environment variables if they're not already set (allows .env to take precedence)
|
|
207
|
+
const envVars = [];
|
|
208
|
+
|
|
209
|
+
// Set variables only if not already defined in environment
|
|
210
|
+
if (!process.env.NODE_LOG_LEVEL) {
|
|
211
|
+
envVars.push(
|
|
212
|
+
`${exportCmd} NODE_LOG_LEVEL=${argv["node-log-level"] || "info"}`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
if (!process.env.NODE_PORT) {
|
|
216
|
+
envVars.push(`${exportCmd} NODE_PORT=${finalPort}`);
|
|
217
|
+
}
|
|
218
|
+
if (!process.env.COMPONENT_PATH) {
|
|
219
|
+
envVars.push(
|
|
220
|
+
`${exportCmd} COMPONENT_PATH=${
|
|
221
|
+
argv["component-path"] || "./src/Plugin.vue"
|
|
222
|
+
}`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Always set HTTPS-related variables (these are dynamic)
|
|
227
|
+
envVars.push(`${exportCmd} USE_HTTPS=${useHttps ? "true" : "false"}`);
|
|
228
|
+
envVars.push(`${exportCmd} CERT_PATH=${certPath}`);
|
|
229
|
+
envVars.push(`${exportCmd} KEY_PATH=${keyPath}`);
|
|
230
|
+
|
|
231
|
+
// Set mock API flag if requested
|
|
232
|
+
if (withMock) {
|
|
233
|
+
envVars.push(`${exportCmd} MOCK_API_ENABLED=true`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Check for browser extension flags
|
|
237
|
+
const launchFirefox = argv.firefox;
|
|
238
|
+
const launchChrome = argv.chrome;
|
|
239
|
+
|
|
240
|
+
// Get browser extension configurations
|
|
241
|
+
let firefoxConfig = null;
|
|
242
|
+
let chromeConfig = null;
|
|
243
|
+
|
|
244
|
+
if (launchFirefox) {
|
|
245
|
+
firefoxConfig = getBrowserExtensionConfig("firefox", projectPath, paths, {
|
|
246
|
+
useHttps,
|
|
247
|
+
port: finalPort,
|
|
248
|
+
});
|
|
249
|
+
if (firefoxConfig) {
|
|
250
|
+
console.log("🦊 Firefox extension will launch with dev server");
|
|
251
|
+
console.log(`📁 Extension path: ${firefoxConfig.extensionPath}`);
|
|
252
|
+
console.log(`🌐 Start URL: ${firefoxConfig.startUrl}`);
|
|
253
|
+
} else {
|
|
254
|
+
console.warn("⚠️ Firefox extension not found, skipping");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (launchChrome) {
|
|
259
|
+
chromeConfig = getBrowserExtensionConfig("chrome", projectPath, paths, {
|
|
260
|
+
useHttps,
|
|
261
|
+
port: finalPort,
|
|
262
|
+
});
|
|
263
|
+
if (chromeConfig) {
|
|
264
|
+
console.log("🚀 Chrome extension will launch with dev server");
|
|
265
|
+
console.log(`📁 Extension path: ${chromeConfig.extensionPath}`);
|
|
266
|
+
console.log(`🌐 Start URL: ${chromeConfig.startUrl}`);
|
|
267
|
+
} else {
|
|
268
|
+
console.warn("⚠️ Chrome extension not found, skipping");
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Build the command based on what's requested
|
|
273
|
+
let command;
|
|
274
|
+
|
|
275
|
+
// Collect all processes to run
|
|
276
|
+
const processes = [];
|
|
277
|
+
const names = [];
|
|
278
|
+
const colors = [];
|
|
279
|
+
|
|
280
|
+
// Vite is always included
|
|
281
|
+
const viteCommand = [
|
|
282
|
+
...envVars,
|
|
283
|
+
`npx vite dev --config "${viteConfigPath}"`,
|
|
284
|
+
].join(" && ");
|
|
285
|
+
processes.push(`"${viteCommand}"`);
|
|
286
|
+
names.push("VITE");
|
|
287
|
+
colors.push("cyan");
|
|
288
|
+
|
|
289
|
+
// Socket server (optional)
|
|
290
|
+
if (withSocket && serverJsPath) {
|
|
291
|
+
processes.push(`"npx nodemon \\"${serverJsPath}\\""`);
|
|
292
|
+
names.push("SOCKET");
|
|
293
|
+
colors.push("green");
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Firefox extension (optional)
|
|
297
|
+
if (firefoxConfig) {
|
|
298
|
+
processes.push(`"${firefoxConfig.command}"`);
|
|
299
|
+
names.push(firefoxConfig.name);
|
|
300
|
+
colors.push(firefoxConfig.color);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Chrome extension (optional)
|
|
304
|
+
if (chromeConfig) {
|
|
305
|
+
processes.push(`"${chromeConfig.command}"`);
|
|
306
|
+
names.push(chromeConfig.name);
|
|
307
|
+
colors.push(chromeConfig.color);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Build the final command
|
|
311
|
+
if (processes.length > 1) {
|
|
312
|
+
// Use concurrently to run multiple processes
|
|
313
|
+
command = `npx concurrently --names "${names.join(
|
|
314
|
+
","
|
|
315
|
+
)}" --prefix-colors "${colors.join(",")}" ${processes.join(" ")}`;
|
|
316
|
+
} else {
|
|
317
|
+
// Just run Vite dev server alone
|
|
318
|
+
command = [...envVars, `npx vite dev --config "${viteConfigPath}"`].join(
|
|
319
|
+
" && "
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
shell.exec(command);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
module.exports = {
|
|
327
|
+
devCommand,
|
|
328
|
+
};
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extensions Command
|
|
3
|
+
*
|
|
4
|
+
* Manages browser extensions for Firefox and Chrome.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
const shell = require("shelljs");
|
|
10
|
+
const { findProjectRoot, resolveGxPaths } = require("../utils");
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Launch Firefox with extension command
|
|
14
|
+
*/
|
|
15
|
+
function extensionFirefoxCommand() {
|
|
16
|
+
const projectPath = findProjectRoot();
|
|
17
|
+
let extensionPath = path.join(projectPath, "browser-extensions", "firefox");
|
|
18
|
+
|
|
19
|
+
// If local extension doesn't exist, try to use the toolkit's own extensions
|
|
20
|
+
if (!fs.existsSync(extensionPath)) {
|
|
21
|
+
const paths = resolveGxPaths();
|
|
22
|
+
const toolkitExtensionPath = path.join(
|
|
23
|
+
paths.packageRoot,
|
|
24
|
+
"browser-extensions",
|
|
25
|
+
"firefox"
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (fs.existsSync(toolkitExtensionPath)) {
|
|
29
|
+
console.log("🔍 Using GxToolkit's built-in Firefox extension");
|
|
30
|
+
extensionPath = toolkitExtensionPath;
|
|
31
|
+
} else {
|
|
32
|
+
console.error("❌ Firefox extension directory not found");
|
|
33
|
+
console.log(
|
|
34
|
+
"📁 Looking for extensions in:",
|
|
35
|
+
path.join(projectPath, "browser-extensions", "firefox")
|
|
36
|
+
);
|
|
37
|
+
console.log(
|
|
38
|
+
"💡 Run 'gxdev init' to create a project with browser extensions"
|
|
39
|
+
);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
console.log("🔍 Using project's Firefox extension");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
console.log("🦊 Launching Firefox with extension...");
|
|
47
|
+
console.log("📁 Extension path:", extensionPath);
|
|
48
|
+
shell.exec(`npx web-ext run --source-dir "${extensionPath}"`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Launch Chrome with extension command
|
|
53
|
+
*/
|
|
54
|
+
function extensionChromeCommand() {
|
|
55
|
+
const projectPath = findProjectRoot();
|
|
56
|
+
let extensionPath = path.join(projectPath, "browser-extensions", "chrome");
|
|
57
|
+
let scriptPath = path.join(projectPath, "scripts", "launch-chrome.js");
|
|
58
|
+
|
|
59
|
+
// Check if we have a local extension first
|
|
60
|
+
if (!fs.existsSync(extensionPath)) {
|
|
61
|
+
const paths = resolveGxPaths();
|
|
62
|
+
const toolkitExtensionPath = path.join(
|
|
63
|
+
paths.packageRoot,
|
|
64
|
+
"browser-extensions",
|
|
65
|
+
"chrome"
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (fs.existsSync(toolkitExtensionPath)) {
|
|
69
|
+
console.log("🔍 Using GxToolkit's built-in Chrome extension");
|
|
70
|
+
extensionPath = toolkitExtensionPath;
|
|
71
|
+
// Use the toolkit's script instead
|
|
72
|
+
scriptPath = path.join(paths.packageRoot, "scripts", "launch-chrome.js");
|
|
73
|
+
} else {
|
|
74
|
+
console.error("❌ Chrome extension directory not found");
|
|
75
|
+
console.log(
|
|
76
|
+
"📁 Looking for extensions in:",
|
|
77
|
+
path.join(projectPath, "browser-extensions", "chrome")
|
|
78
|
+
);
|
|
79
|
+
console.log(
|
|
80
|
+
"💡 Run 'gxdev init' to create a project with browser extensions"
|
|
81
|
+
);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
console.log("🔍 Using project's Chrome extension");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Verify script exists
|
|
89
|
+
if (!fs.existsSync(scriptPath)) {
|
|
90
|
+
console.error(
|
|
91
|
+
"❌ Chrome launcher script not found. Run 'gxdev init' to create it."
|
|
92
|
+
);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log("🚀 Launching Chrome with extension...");
|
|
97
|
+
console.log("📁 Extension path:", extensionPath);
|
|
98
|
+
|
|
99
|
+
// Set the extension path as an environment variable for the script
|
|
100
|
+
process.env.CHROME_EXTENSION_PATH = extensionPath;
|
|
101
|
+
shell.exec(`node "${scriptPath}"`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Install extension permanently in local browser
|
|
106
|
+
*/
|
|
107
|
+
function extensionInstallCommand(argv) {
|
|
108
|
+
const browser = argv.browser;
|
|
109
|
+
const paths = resolveGxPaths();
|
|
110
|
+
|
|
111
|
+
if (!browser || !["chrome", "firefox"].includes(browser)) {
|
|
112
|
+
console.log("Usage: gxdev ext:install <chrome|firefox>");
|
|
113
|
+
console.log("");
|
|
114
|
+
console.log("This command helps you permanently install the extension");
|
|
115
|
+
console.log("in your local browser for development.");
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const extensionPath = path.join(
|
|
120
|
+
paths.packageRoot,
|
|
121
|
+
"browser-extensions",
|
|
122
|
+
browser
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
if (!fs.existsSync(extensionPath)) {
|
|
126
|
+
console.error(
|
|
127
|
+
`❌ ${browser} extension directory not found at:`,
|
|
128
|
+
extensionPath
|
|
129
|
+
);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
console.log("");
|
|
134
|
+
console.log(`📦 Extension path: ${extensionPath}`);
|
|
135
|
+
console.log("");
|
|
136
|
+
|
|
137
|
+
if (browser === "chrome") {
|
|
138
|
+
console.log("🚀 Chrome Permanent Installation Instructions:");
|
|
139
|
+
console.log("─".repeat(50));
|
|
140
|
+
console.log("");
|
|
141
|
+
console.log("1. Open Chrome and navigate to:");
|
|
142
|
+
console.log(" chrome://extensions/");
|
|
143
|
+
console.log("");
|
|
144
|
+
console.log('2. Enable "Developer mode" (toggle in top right corner)');
|
|
145
|
+
console.log("");
|
|
146
|
+
console.log('3. Click "Load unpacked" button');
|
|
147
|
+
console.log("");
|
|
148
|
+
console.log("4. Select this directory:");
|
|
149
|
+
console.log(` ${extensionPath}`);
|
|
150
|
+
console.log("");
|
|
151
|
+
console.log("─".repeat(50));
|
|
152
|
+
console.log("✅ The extension will persist across browser restarts.");
|
|
153
|
+
console.log("🔄 After code changes, click the refresh icon on the");
|
|
154
|
+
console.log(" extension card in chrome://extensions/ to reload.");
|
|
155
|
+
console.log("");
|
|
156
|
+
|
|
157
|
+
// Try to open Chrome to the extensions page
|
|
158
|
+
const openCommand =
|
|
159
|
+
process.platform === "darwin"
|
|
160
|
+
? 'open -a "Google Chrome" "chrome://extensions/"'
|
|
161
|
+
: process.platform === "win32"
|
|
162
|
+
? 'start chrome "chrome://extensions/"'
|
|
163
|
+
: 'google-chrome "chrome://extensions/"';
|
|
164
|
+
|
|
165
|
+
console.log("🌐 Attempting to open Chrome extensions page...");
|
|
166
|
+
shell.exec(openCommand, { silent: true });
|
|
167
|
+
} else if (browser === "firefox") {
|
|
168
|
+
console.log("🦊 Firefox Installation Instructions:");
|
|
169
|
+
console.log("─".repeat(50));
|
|
170
|
+
console.log("");
|
|
171
|
+
console.log("Option 1: Temporary Add-on (easiest, but doesn't persist)");
|
|
172
|
+
console.log("─".repeat(50));
|
|
173
|
+
console.log("1. Open Firefox and navigate to:");
|
|
174
|
+
console.log(" about:debugging#/runtime/this-firefox");
|
|
175
|
+
console.log("");
|
|
176
|
+
console.log('2. Click "Load Temporary Add-on..."');
|
|
177
|
+
console.log("");
|
|
178
|
+
console.log("3. Select any file in this directory:");
|
|
179
|
+
console.log(` ${extensionPath}`);
|
|
180
|
+
console.log("");
|
|
181
|
+
console.log("⚠️ Note: Temporary add-ons are removed when Firefox closes.");
|
|
182
|
+
console.log("");
|
|
183
|
+
console.log("─".repeat(50));
|
|
184
|
+
console.log(
|
|
185
|
+
"Option 2: Persistent Installation (Firefox Developer/Nightly)"
|
|
186
|
+
);
|
|
187
|
+
console.log("─".repeat(50));
|
|
188
|
+
console.log("1. Use Firefox Developer Edition or Firefox Nightly");
|
|
189
|
+
console.log("");
|
|
190
|
+
console.log("2. Go to about:config and set:");
|
|
191
|
+
console.log(" xpinstall.signatures.required = false");
|
|
192
|
+
console.log("");
|
|
193
|
+
console.log("3. Then go to about:addons");
|
|
194
|
+
console.log("");
|
|
195
|
+
console.log("4. Click the gear icon and select:");
|
|
196
|
+
console.log(' "Install Add-on From File..."');
|
|
197
|
+
console.log("");
|
|
198
|
+
console.log("5. Select the manifest.json in:");
|
|
199
|
+
console.log(` ${extensionPath}`);
|
|
200
|
+
console.log("");
|
|
201
|
+
|
|
202
|
+
// Try to open Firefox to the debugging page
|
|
203
|
+
const openCommand =
|
|
204
|
+
process.platform === "darwin"
|
|
205
|
+
? 'open -a "Firefox" "about:debugging#/runtime/this-firefox"'
|
|
206
|
+
: process.platform === "win32"
|
|
207
|
+
? 'start firefox "about:debugging#/runtime/this-firefox"'
|
|
208
|
+
: 'firefox "about:debugging#/runtime/this-firefox"';
|
|
209
|
+
|
|
210
|
+
console.log("🌐 Attempting to open Firefox debugging page...");
|
|
211
|
+
shell.exec(openCommand, { silent: true });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Build extensions command
|
|
217
|
+
*/
|
|
218
|
+
function extensionBuildCommand() {
|
|
219
|
+
const projectPath = findProjectRoot();
|
|
220
|
+
const paths = resolveGxPaths();
|
|
221
|
+
|
|
222
|
+
console.log("📦 Building browser extensions...");
|
|
223
|
+
|
|
224
|
+
// Build Firefox extension
|
|
225
|
+
let firefoxPath = path.join(projectPath, "browser-extensions", "firefox");
|
|
226
|
+
let useProjectExtensions = true;
|
|
227
|
+
|
|
228
|
+
if (!fs.existsSync(firefoxPath)) {
|
|
229
|
+
// Try toolkit's extensions
|
|
230
|
+
const toolkitFirefoxPath = path.join(
|
|
231
|
+
paths.packageRoot,
|
|
232
|
+
"browser-extensions",
|
|
233
|
+
"firefox"
|
|
234
|
+
);
|
|
235
|
+
if (fs.existsSync(toolkitFirefoxPath)) {
|
|
236
|
+
firefoxPath = toolkitFirefoxPath;
|
|
237
|
+
useProjectExtensions = false;
|
|
238
|
+
console.log("🔍 Using GxToolkit's built-in Firefox extension");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (fs.existsSync(firefoxPath)) {
|
|
243
|
+
console.log("🦊 Building Firefox extension...");
|
|
244
|
+
const outputDir = useProjectExtensions
|
|
245
|
+
? "dist/firefox"
|
|
246
|
+
: path.join(projectPath, "dist/firefox");
|
|
247
|
+
shell.exec(
|
|
248
|
+
`npx web-ext build --source-dir "${firefoxPath}" --artifacts-dir "${outputDir}"`
|
|
249
|
+
);
|
|
250
|
+
} else {
|
|
251
|
+
console.log("⚠️ No Firefox extension found to build");
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Build Chrome extension
|
|
255
|
+
let chromeScriptPath = path.join(projectPath, "scripts", "pack-chrome.js");
|
|
256
|
+
let chromeExtensionPath = path.join(
|
|
257
|
+
projectPath,
|
|
258
|
+
"browser-extensions",
|
|
259
|
+
"chrome"
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
if (!fs.existsSync(chromeScriptPath) || !fs.existsSync(chromeExtensionPath)) {
|
|
263
|
+
// Try toolkit's scripts and extensions
|
|
264
|
+
const toolkitScriptPath = path.join(
|
|
265
|
+
paths.packageRoot,
|
|
266
|
+
"scripts",
|
|
267
|
+
"pack-chrome.js"
|
|
268
|
+
);
|
|
269
|
+
const toolkitChromePath = path.join(
|
|
270
|
+
paths.packageRoot,
|
|
271
|
+
"browser-extensions",
|
|
272
|
+
"chrome"
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
if (fs.existsSync(toolkitScriptPath) && fs.existsSync(toolkitChromePath)) {
|
|
276
|
+
chromeScriptPath = toolkitScriptPath;
|
|
277
|
+
chromeExtensionPath = toolkitChromePath;
|
|
278
|
+
console.log("🔍 Using GxToolkit's built-in Chrome extension");
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (fs.existsSync(chromeScriptPath)) {
|
|
283
|
+
console.log("🚀 Building Chrome extension...");
|
|
284
|
+
// Set environment variable for the script to know where the extension is
|
|
285
|
+
process.env.CHROME_EXTENSION_PATH = chromeExtensionPath;
|
|
286
|
+
process.env.CHROME_BUILD_OUTPUT = path.join(projectPath, "dist/chrome");
|
|
287
|
+
shell.exec(`node "${chromeScriptPath}"`);
|
|
288
|
+
} else {
|
|
289
|
+
console.log("⚠️ No Chrome extension found to build");
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
module.exports = {
|
|
294
|
+
extensionFirefoxCommand,
|
|
295
|
+
extensionChromeCommand,
|
|
296
|
+
extensionBuildCommand,
|
|
297
|
+
extensionInstallCommand,
|
|
298
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commands Index
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all command modules for convenient importing.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { initCommand } = require("./init");
|
|
8
|
+
const { devCommand } = require("./dev");
|
|
9
|
+
const { buildCommand } = require("./build");
|
|
10
|
+
const { publishCommand } = require("./publish");
|
|
11
|
+
const { setupSSLCommand } = require("./ssl");
|
|
12
|
+
const { datastoreCommand } = require("./datastore");
|
|
13
|
+
const { socketCommand } = require("./socket");
|
|
14
|
+
const { assetsCommand } = require("./assets");
|
|
15
|
+
const {
|
|
16
|
+
extensionFirefoxCommand,
|
|
17
|
+
extensionChromeCommand,
|
|
18
|
+
extensionBuildCommand,
|
|
19
|
+
extensionInstallCommand,
|
|
20
|
+
} = require("./extensions");
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
initCommand,
|
|
24
|
+
devCommand,
|
|
25
|
+
buildCommand,
|
|
26
|
+
publishCommand,
|
|
27
|
+
setupSSLCommand,
|
|
28
|
+
datastoreCommand,
|
|
29
|
+
socketCommand,
|
|
30
|
+
assetsCommand,
|
|
31
|
+
extensionFirefoxCommand,
|
|
32
|
+
extensionChromeCommand,
|
|
33
|
+
extensionBuildCommand,
|
|
34
|
+
extensionInstallCommand,
|
|
35
|
+
};
|