@gxp-dev/tools 2.0.94 → 2.1.1
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/bin/lib/commands/dev.js +39 -9
- package/package.json +3 -1
- package/template/.claude/agents/gxp-developer.md +11 -4
- package/template/AGENTS.md +10 -4
- package/template/GEMINI.md +15 -3
package/bin/lib/commands/dev.js
CHANGED
|
@@ -7,9 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
const path = require("path")
|
|
9
9
|
const fs = require("fs")
|
|
10
|
-
const
|
|
10
|
+
const childProcess = require("child_process")
|
|
11
11
|
const shell = require("shelljs")
|
|
12
12
|
const dotenv = require("dotenv")
|
|
13
|
+
|
|
14
|
+
// Module-private spawn reference so tests can swap in a stub via
|
|
15
|
+
// `setSpawnForTesting`. Production code paths still call the real
|
|
16
|
+
// `child_process.spawn` because the default closes over it.
|
|
17
|
+
let _spawn = childProcess.spawn
|
|
18
|
+
function setSpawnForTesting(fn) {
|
|
19
|
+
_spawn = fn || childProcess.spawn
|
|
20
|
+
}
|
|
13
21
|
const {
|
|
14
22
|
findProjectRoot,
|
|
15
23
|
resolveGxPaths,
|
|
@@ -53,7 +61,7 @@ function createLogger(jsonMode) {
|
|
|
53
61
|
* Returns the child process.
|
|
54
62
|
*/
|
|
55
63
|
function spawnService(name, command, logger) {
|
|
56
|
-
const child =
|
|
64
|
+
const child = _spawn(command, {
|
|
57
65
|
shell: true,
|
|
58
66
|
stdio: ["ignore", "pipe", "pipe"],
|
|
59
67
|
env: process.env,
|
|
@@ -289,8 +297,9 @@ function devCommand(argv) {
|
|
|
289
297
|
logger.info("🎭 Mock API will be enabled")
|
|
290
298
|
}
|
|
291
299
|
|
|
292
|
-
// Socket server starts by default unless --no-socket is passed
|
|
293
|
-
|
|
300
|
+
// Socket server starts by default unless --no-socket is passed. See
|
|
301
|
+
// shouldDisableSocket() for the yargs-negation quirk it papers over.
|
|
302
|
+
const noSocket = shouldDisableSocket(argv)
|
|
294
303
|
let serverJsPath = ""
|
|
295
304
|
if (!noSocket) {
|
|
296
305
|
// Check for local server.js first, then runtime directory
|
|
@@ -340,9 +349,10 @@ function devCommand(argv) {
|
|
|
340
349
|
if (!process.env.NODE_LOG_LEVEL) {
|
|
341
350
|
process.env.NODE_LOG_LEVEL = argv["node-log-level"] || "info"
|
|
342
351
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
352
|
+
// NODE_PORT is the source of truth for the socket server (server.cjs reads
|
|
353
|
+
// process.env). Always set it to the resolved finalPort so that a CLI
|
|
354
|
+
// `--port` overrides anything that dotenv loaded from .env earlier.
|
|
355
|
+
process.env.NODE_PORT = String(finalPort)
|
|
346
356
|
if (!process.env.COMPONENT_PATH) {
|
|
347
357
|
process.env.COMPONENT_PATH = argv["component-path"] || "./src/Plugin.vue"
|
|
348
358
|
}
|
|
@@ -401,12 +411,15 @@ function devCommand(argv) {
|
|
|
401
411
|
// Normalize path separators to forward slashes for cross-platform shell compatibility
|
|
402
412
|
const normalizedViteConfigPath = viteConfigPath.replace(/\\/g, "/")
|
|
403
413
|
|
|
404
|
-
// Build the canonical service list (raw commands, no concurrently wrapping)
|
|
414
|
+
// Build the canonical service list (raw commands, no concurrently wrapping).
|
|
415
|
+
// Pass --port to vite directly: vite's loadEnv() only reads .env files —
|
|
416
|
+
// it does NOT inherit from process.env — so setting NODE_PORT above isn't
|
|
417
|
+
// enough on its own. The CLI flag wins over the config every time.
|
|
405
418
|
const services = []
|
|
406
419
|
services.push({
|
|
407
420
|
name: "VITE",
|
|
408
421
|
color: "cyan",
|
|
409
|
-
command: `npx vite dev --config "${normalizedViteConfigPath}"`,
|
|
422
|
+
command: `npx vite dev --config "${normalizedViteConfigPath}" --port ${finalPort}`,
|
|
410
423
|
})
|
|
411
424
|
|
|
412
425
|
if (serverJsPath) {
|
|
@@ -455,6 +468,23 @@ function devCommand(argv) {
|
|
|
455
468
|
shell.exec(command)
|
|
456
469
|
}
|
|
457
470
|
|
|
471
|
+
/**
|
|
472
|
+
* Pure helper exposed for unit testing the `--no-socket` flag-parsing fix.
|
|
473
|
+
* yargs interprets `--no-socket` from the CLI as `argv.socket = false`
|
|
474
|
+
* (boolean negation), NOT as `argv["no-socket"] = true`. We accept either
|
|
475
|
+
* form so the flag behaves the way the help text advertises.
|
|
476
|
+
*/
|
|
477
|
+
function shouldDisableSocket(argv) {
|
|
478
|
+
return argv["no-socket"] === true || argv.socket === false
|
|
479
|
+
}
|
|
480
|
+
|
|
458
481
|
module.exports = {
|
|
459
482
|
devCommand,
|
|
483
|
+
// Exposed for unit testing. These are pure-ish helpers that drive the
|
|
484
|
+
// NDJSON logger and child-process orchestration used by `gxdev dev`.
|
|
485
|
+
createLogger,
|
|
486
|
+
spawnService,
|
|
487
|
+
runServicesJson,
|
|
488
|
+
shouldDisableSocket,
|
|
489
|
+
setSpawnForTesting,
|
|
460
490
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gxp-dev/tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Dev tools to create platform plugins",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,8 +20,10 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"prepare": "git config core.hooksPath .githooks || true",
|
|
22
22
|
"test": "vitest run",
|
|
23
|
+
"test:run": "vitest run",
|
|
23
24
|
"test:watch": "vitest",
|
|
24
25
|
"test:coverage": "vitest run --coverage",
|
|
26
|
+
"test:e2e": "RUN_CLI_E2E=1 vitest run --config vitest.e2e.config.js",
|
|
25
27
|
"dev": "concurrently 'vite dev' 'nodemon config/server.js'",
|
|
26
28
|
"dev-app": "vite dev",
|
|
27
29
|
"ext:firefox": "web-ext run --source-dir browser-extensions/firefox",
|
|
@@ -685,7 +685,7 @@ async function handleAction() {
|
|
|
685
685
|
|
|
686
686
|
onMounted(() => {
|
|
687
687
|
// Listen for real-time updates
|
|
688
|
-
store.
|
|
688
|
+
store.listen("primary", "DataUpdated", (eventData) => {
|
|
689
689
|
data.value = eventData
|
|
690
690
|
})
|
|
691
691
|
})
|
|
@@ -743,11 +743,18 @@ npm run dev # HTTPS with Socket.IO
|
|
|
743
743
|
npm run dev-http # HTTP only
|
|
744
744
|
|
|
745
745
|
# Test socket events
|
|
746
|
-
gxdev socket list
|
|
747
|
-
gxdev socket send --event Name
|
|
746
|
+
gxdev socket list # List available events
|
|
747
|
+
gxdev socket send --event Name # Send test broadcast
|
|
748
|
+
gxdev socket send --event Name --identifier id # Send to a specific channel
|
|
749
|
+
|
|
750
|
+
# Dependencies
|
|
751
|
+
gxdev add-dependency # Interactive wizard: search endpoints and add dependency to app-manifest.json
|
|
752
|
+
|
|
753
|
+
# UIKit components
|
|
754
|
+
gxdev storybook # Browse components at http://localhost:6006
|
|
748
755
|
|
|
749
756
|
# Lint
|
|
750
|
-
gxdev lint --all
|
|
757
|
+
gxdev lint --all # Validate configuration.json + app-manifest.json
|
|
751
758
|
|
|
752
759
|
# Build for production
|
|
753
760
|
gxdev build # Creates dist/ with .gxpapp package
|
package/template/AGENTS.md
CHANGED
|
@@ -37,7 +37,7 @@ Use the `gxp-api` MCP server to ground the implementation in the real platform
|
|
|
37
37
|
- **Inspect a specific endpoint** — `api_get_operation_parameters`, `get_endpoint_details`.
|
|
38
38
|
- **Find endpoints by payload shape** — `api_find_endpoints_by_schema` (search by request/response field names).
|
|
39
39
|
- **Find WebSocket events** — `api_find_events_for_operation` (given an operationId, returns events via `x-triggered-by`), `api_list_events`, `search_websocket_events`, `get_asyncapi_spec`. Run `api_find_events_for_operation` for every operationId you plan to call so you subscribe instead of polling.
|
|
40
|
-
- **Generate dependency JSON** — `api_generate_dependency` produces the canonical entry for `app-manifest.json` → `dependencies`.
|
|
40
|
+
- **Generate dependency JSON** — `api_generate_dependency` produces the canonical entry for `app-manifest.json` → `dependencies`. Alternatively, `gxdev add-dependency` runs an interactive CLI wizard that searches endpoints and writes the entry directly to `app-manifest.json`.
|
|
41
41
|
- **Read the docs** — `docs_list_pages`, `docs_search`, `docs_get_page` (full-text search across docs.gxp.dev).
|
|
42
42
|
|
|
43
43
|
Output of this step: a short list of the operationIds, WebSocket events, and dependencies the plugin will use.
|
|
@@ -89,7 +89,7 @@ As soon as you've added a new `store.callApi`, `store.listen`, `gxp-string`, or
|
|
|
89
89
|
Before declaring done, exercise the plugin against real event shapes:
|
|
90
90
|
|
|
91
91
|
- List available events — `gxdev socket list`.
|
|
92
|
-
- Send one — `gxdev socket send --event <EventName>` (edit or add payloads under `socket-events/`).
|
|
92
|
+
- Send one — `gxdev socket send --event <EventName>` (edit or add payloads under `socket-events/`). Use `--identifier <id>` to override which channel the event fires on.
|
|
93
93
|
- Hit endpoints against the local mock API via the `test_api_route` MCP tool.
|
|
94
94
|
- Scaffold unit tests with `test_scaffold_component_test` for any non-trivial component.
|
|
95
95
|
|
|
@@ -452,7 +452,11 @@ Strings, assets, dependencies, colors → `additionalTabs`. Quiz/survey question
|
|
|
452
452
|
|
|
453
453
|
Finish with `gxdev lint --all`. The linter validates both roots against the same card/field schema, so malformed questions fail in the same way malformed admin fields do.
|
|
454
454
|
|
|
455
|
-
|
|
455
|
+
## Component Kit
|
|
456
|
+
|
|
457
|
+
Use `@gxp-dev/uikit` for all UI components. Run `gxdev storybook` to browse available components and their stories at `http://localhost:6006`. When storybook is running, the `gxp-uikit-storybook` MCP server (registered in `.mcp.json`) provides tools to inspect stories, documentation, and run story tests directly from your AI assistant.
|
|
458
|
+
|
|
459
|
+
Key components: `GxButton`, `GxCard`, `GxInput`, `GxModal`, `GxSpinner`, `GxAlert`, `GxBadge`, `GxAvatar`, `GxProgress`, `GxTabs`, `GxAccordion`
|
|
456
460
|
|
|
457
461
|
## Configuration Files
|
|
458
462
|
|
|
@@ -471,9 +475,10 @@ gxdev lint --json # machine-readable output
|
|
|
471
475
|
|
|
472
476
|
## Testing
|
|
473
477
|
|
|
474
|
-
- Socket events: `gxdev socket send --event EventName`
|
|
478
|
+
- Socket events: `gxdev socket send --event EventName` (add `--identifier <id>` to target a specific channel)
|
|
475
479
|
- API calls against local mock: `test_api_route` MCP tool
|
|
476
480
|
- Component tests: `test_scaffold_component_test` MCP tool
|
|
481
|
+
- UIKit components: `gxdev storybook` — browse components at `http://localhost:6006`
|
|
477
482
|
- Dev Tools: Press Ctrl+Shift+D
|
|
478
483
|
- Console: `window.gxDevTools.store()` to inspect store
|
|
479
484
|
|
|
@@ -482,6 +487,7 @@ gxdev lint --json # machine-readable output
|
|
|
482
487
|
Set `VITE_API_ENV` in `.env`:
|
|
483
488
|
|
|
484
489
|
- `mock` - Local mock server (default)
|
|
490
|
+
- `local` - https://dashboard.eventfinity.test
|
|
485
491
|
- `develop` - https://api.zenith-develop.env.eventfinity.app
|
|
486
492
|
- `staging` - https://api.efz-staging.env.eventfinity.app
|
|
487
493
|
- `production` - https://api.gramercy.cloud
|
package/template/GEMINI.md
CHANGED
|
@@ -31,7 +31,7 @@ Ground the implementation in real platform endpoints and events. Do not invent A
|
|
|
31
31
|
- Endpoints — `api_list_tags`, `api_list_operation_ids`, `search_api_endpoints`, `api_get_operation_parameters`, `get_endpoint_details`.
|
|
32
32
|
- Find by payload shape — `api_find_endpoints_by_schema`.
|
|
33
33
|
- WebSocket events — `api_find_events_for_operation` (maps operationId → events via `x-triggered-by`), `api_list_events`, `search_websocket_events`, `get_asyncapi_spec`. Run for every planned operationId so you subscribe instead of polling.
|
|
34
|
-
- Canonical dependency JSON — `api_generate_dependency`.
|
|
34
|
+
- Canonical dependency JSON — `api_generate_dependency`. Or run `gxdev add-dependency` for an interactive CLI wizard that writes the entry directly to `app-manifest.json`.
|
|
35
35
|
- Documentation — `docs_list_pages`, `docs_search`, `docs_get_page`.
|
|
36
36
|
|
|
37
37
|
### 3. Plan with the client
|
|
@@ -67,7 +67,7 @@ Whenever you add or change a `store.callApi`, `store.listen`, `gxp-string`, or `
|
|
|
67
67
|
### 6. Test broadcasts
|
|
68
68
|
|
|
69
69
|
- `gxdev socket list` — see available events.
|
|
70
|
-
- `gxdev socket send --event <EventName>` — fire a test broadcast.
|
|
70
|
+
- `gxdev socket send --event <EventName>` — fire a test broadcast. Add `--identifier <id>` to target a specific channel.
|
|
71
71
|
- `test_api_route` MCP tool — hit endpoints against the local mock.
|
|
72
72
|
- `test_scaffold_component_test` MCP tool — generate Vitest files.
|
|
73
73
|
|
|
@@ -280,7 +280,19 @@ Tools: `config_list_card_types`, `config_list_field_types`, `config_get_field_sc
|
|
|
280
280
|
|
|
281
281
|
## Component Kit
|
|
282
282
|
|
|
283
|
-
Use `@gxp-dev/uikit` for UI
|
|
283
|
+
Use `@gxp-dev/uikit` for all UI components. Run `gxdev storybook` to browse available components at `http://localhost:6006`. When storybook is running, the `gxp-uikit-storybook` MCP server (registered in `.mcp.json`) provides tools to inspect stories and documentation.
|
|
284
|
+
|
|
285
|
+
Key components: `GxButton`, `GxCard`, `GxInput`, `GxModal`, `GxSpinner`, `GxAlert`, `GxBadge`, `GxAvatar`, `GxProgress`, `GxTabs`, `GxAccordion`
|
|
286
|
+
|
|
287
|
+
## API Environments
|
|
288
|
+
|
|
289
|
+
Set `VITE_API_ENV` in `.env`:
|
|
290
|
+
|
|
291
|
+
- `mock` - Local mock server (default)
|
|
292
|
+
- `local` - https://dashboard.eventfinity.test
|
|
293
|
+
- `develop` - https://api.zenith-develop.env.eventfinity.app
|
|
294
|
+
- `staging` - https://api.efz-staging.env.eventfinity.app
|
|
295
|
+
- `production` - https://api.gramercy.cloud
|
|
284
296
|
|
|
285
297
|
## API Specs
|
|
286
298
|
|