@gxp-dev/tools 2.0.73 → 2.0.74
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/gx-devtools.js +71 -99
- package/bin/lib/cli.js +62 -7
- package/package.json +1 -1
package/bin/gx-devtools.js
CHANGED
|
@@ -1,118 +1,90 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* GxToolkit CLI
|
|
4
|
+
* GxToolkit CLI dispatcher.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Default mode is the plain CLI. The interactive Terminal UI (TUI) only
|
|
7
|
+
* launches when the user either runs `gxdev ui` or passes `--ui` alongside
|
|
8
|
+
* another command. Running `gxdev` with no command prints the help menu.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* setup-ssl - Setup SSL certificates for HTTPS development
|
|
13
|
-
* dev - Start development server (launches TUI with auto-start)
|
|
14
|
-
* build - Build plugin for production
|
|
15
|
-
* publish [file] - Publish package files to local project
|
|
16
|
-
* datastore - Manage GxP datastore
|
|
17
|
-
* socket - Simulate socket events (launches TUI with auto-start)
|
|
18
|
-
* assets - Manage development assets and placeholders
|
|
19
|
-
* ext:firefox - Launch Firefox with browser extension (launches TUI)
|
|
20
|
-
* ext:chrome - Launch Chrome with browser extension (launches TUI)
|
|
21
|
-
* ext:build - Build browser extensions for distribution
|
|
10
|
+
* Launching into the TUI still supports auto-starting well-known long-running
|
|
11
|
+
* commands (dev, socket, ext:chrome, ext:firefox) so that `gxdev dev --ui`
|
|
12
|
+
* boots the TUI with the dev server already running.
|
|
22
13
|
*/
|
|
23
14
|
|
|
24
|
-
// Commands that should use the traditional CLI (one-shot commands)
|
|
25
|
-
const ONE_SHOT_COMMANDS = [
|
|
26
|
-
"init",
|
|
27
|
-
"build",
|
|
28
|
-
"publish",
|
|
29
|
-
"setup-ssl",
|
|
30
|
-
"ext:build",
|
|
31
|
-
"add-dependency",
|
|
32
|
-
"extract-config",
|
|
33
|
-
"--help",
|
|
34
|
-
"-h",
|
|
35
|
-
"--version",
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
// Commands that should launch TUI with auto-start
|
|
39
|
-
const TUI_AUTO_START_COMMANDS = [
|
|
40
|
-
"dev",
|
|
41
|
-
"socket",
|
|
42
|
-
"ext:firefox",
|
|
43
|
-
"ext:chrome",
|
|
44
|
-
"datastore",
|
|
45
|
-
"assets",
|
|
46
|
-
]
|
|
47
|
-
|
|
48
15
|
const args = process.argv.slice(2)
|
|
49
16
|
const command = args[0]
|
|
50
17
|
|
|
51
|
-
//
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// Check if we should use TUI with auto-start
|
|
56
|
-
const isTuiCommand = TUI_AUTO_START_COMMANDS.includes(command)
|
|
18
|
+
// TUI activation: bare `ui` command OR any invocation with `--ui`.
|
|
19
|
+
const uiFlagPresent = args.includes("--ui")
|
|
20
|
+
const isBareUiCommand = command === "ui"
|
|
21
|
+
const wantsUi = uiFlagPresent || isBareUiCommand
|
|
57
22
|
|
|
58
|
-
|
|
59
|
-
|
|
23
|
+
if (!wantsUi) {
|
|
24
|
+
// Default path — delegate straight to yargs-driven CLI.
|
|
25
|
+
require("./lib/cli")
|
|
26
|
+
return
|
|
27
|
+
}
|
|
60
28
|
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const path = require("path")
|
|
66
|
-
// TUI output is in project root's dist/tui, not bin/dist/tui
|
|
67
|
-
const tuiPath = path.join(__dirname, "..", "dist", "tui", "index.js")
|
|
29
|
+
// TUI path — locate the compiled TUI bundle and hand off.
|
|
30
|
+
const fs = require("fs")
|
|
31
|
+
const path = require("path")
|
|
32
|
+
const tuiPath = path.join(__dirname, "..", "dist", "tui", "index.js")
|
|
68
33
|
|
|
69
|
-
|
|
70
|
-
|
|
34
|
+
if (!fs.existsSync(tuiPath)) {
|
|
35
|
+
console.error("TUI bundle not found.")
|
|
36
|
+
console.error('Run "npm run build:tui" in gx-devtools to compile it.')
|
|
37
|
+
process.exit(1)
|
|
38
|
+
}
|
|
71
39
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
40
|
+
const isTTY = process.stdout.isTTY && process.stdin.isTTY
|
|
41
|
+
if (!isTTY) {
|
|
42
|
+
console.error(
|
|
43
|
+
"The GxP TUI requires an interactive terminal (TTY). Run the plain CLI form without --ui.",
|
|
44
|
+
)
|
|
45
|
+
process.exit(1)
|
|
46
|
+
}
|
|
77
47
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
// Work out which TUI services to auto-start from the command that was paired
|
|
49
|
+
// with --ui. `gxdev ui` on its own launches the TUI idle.
|
|
50
|
+
const autoStart = []
|
|
51
|
+
const tuiArgs = {}
|
|
81
52
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
53
|
+
switch (isBareUiCommand ? null : command) {
|
|
54
|
+
case "dev":
|
|
55
|
+
autoStart.push("dev")
|
|
56
|
+
if (args.includes("--with-socket") || args.includes("-s")) {
|
|
57
|
+
autoStart.push("socket")
|
|
58
|
+
}
|
|
59
|
+
tuiArgs.noHttps = args.includes("--no-https")
|
|
60
|
+
break
|
|
61
|
+
case "socket":
|
|
62
|
+
autoStart.push("socket")
|
|
63
|
+
break
|
|
64
|
+
case "ext:firefox":
|
|
65
|
+
autoStart.push("ext firefox")
|
|
66
|
+
break
|
|
67
|
+
case "ext:chrome":
|
|
68
|
+
autoStart.push("ext chrome")
|
|
69
|
+
break
|
|
70
|
+
default:
|
|
71
|
+
// No known auto-start for this command (or no command) — launch idle.
|
|
72
|
+
break
|
|
73
|
+
}
|
|
95
74
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
} else {
|
|
109
|
-
// TUI not compiled yet, use traditional CLI
|
|
110
|
-
console.log(
|
|
111
|
-
'Note: TUI not yet available. Run "npm run build:tui" to enable interactive mode.',
|
|
75
|
+
;(async () => {
|
|
76
|
+
try {
|
|
77
|
+
const { startTUI } = await import(tuiPath)
|
|
78
|
+
startTUI({ autoStart, args: tuiArgs })
|
|
79
|
+
} catch (err) {
|
|
80
|
+
if (err && err.message === "NO_TTY") {
|
|
81
|
+
console.error("The GxP TUI requires an interactive terminal (TTY).")
|
|
82
|
+
process.exit(1)
|
|
83
|
+
}
|
|
84
|
+
console.error(
|
|
85
|
+
"Failed to start TUI:",
|
|
86
|
+
err && err.message ? err.message : err,
|
|
112
87
|
)
|
|
113
|
-
|
|
88
|
+
process.exit(1)
|
|
114
89
|
}
|
|
115
|
-
}
|
|
116
|
-
// One-shot command, use traditional CLI
|
|
117
|
-
require("./lib/cli")
|
|
118
|
-
}
|
|
90
|
+
})()
|
package/bin/lib/cli.js
CHANGED
|
@@ -31,12 +31,42 @@ const {
|
|
|
31
31
|
const globalConfig = loadGlobalConfig()
|
|
32
32
|
|
|
33
33
|
// Set up yargs CLI
|
|
34
|
-
yargs
|
|
35
|
-
.
|
|
34
|
+
const cli = yargs
|
|
35
|
+
.scriptName("gxdev")
|
|
36
|
+
.usage(
|
|
37
|
+
[
|
|
38
|
+
"Usage: gxdev <command> [options]",
|
|
39
|
+
"",
|
|
40
|
+
"By default every command runs in the plain CLI. Pass --ui to any",
|
|
41
|
+
"command to launch it inside the interactive Terminal UI, or run",
|
|
42
|
+
"`gxdev ui` to open the TUI without starting anything.",
|
|
43
|
+
].join("\n"),
|
|
44
|
+
)
|
|
36
45
|
.config(globalConfig)
|
|
46
|
+
.option("ui", {
|
|
47
|
+
describe:
|
|
48
|
+
"Launch the interactive Terminal UI (auto-starts dev/socket/ext when paired with those commands)",
|
|
49
|
+
type: "boolean",
|
|
50
|
+
default: false,
|
|
51
|
+
global: true,
|
|
52
|
+
})
|
|
53
|
+
.command(
|
|
54
|
+
"ui",
|
|
55
|
+
"Open the interactive Terminal UI without auto-starting anything",
|
|
56
|
+
{},
|
|
57
|
+
() => {
|
|
58
|
+
// The dispatcher in bin/gx-devtools.js intercepts `ui` before yargs
|
|
59
|
+
// ever runs. Reaching this handler means the TUI bundle couldn't be
|
|
60
|
+
// launched (e.g. not built); bubble a helpful hint.
|
|
61
|
+
console.error(
|
|
62
|
+
'TUI is not available. Run "npm run build:tui" inside gx-devtools and try again.',
|
|
63
|
+
)
|
|
64
|
+
process.exit(1)
|
|
65
|
+
},
|
|
66
|
+
)
|
|
37
67
|
.command(
|
|
38
68
|
"init [name]",
|
|
39
|
-
"Initialize a new GxP project or update existing one",
|
|
69
|
+
"Initialize a new GxP project or update an existing one in the current directory",
|
|
40
70
|
{
|
|
41
71
|
name: {
|
|
42
72
|
describe: "Project name (for new projects)",
|
|
@@ -49,12 +79,13 @@ yargs
|
|
|
49
79
|
},
|
|
50
80
|
build: {
|
|
51
81
|
describe:
|
|
52
|
-
"AI
|
|
82
|
+
"Non-interactive AI scaffold: describe what to build and apply it directly",
|
|
53
83
|
type: "string",
|
|
54
84
|
alias: "b",
|
|
55
85
|
},
|
|
56
86
|
provider: {
|
|
57
|
-
describe:
|
|
87
|
+
describe:
|
|
88
|
+
"AI provider for --build scaffolding (interactive mode picks from available CLIs)",
|
|
58
89
|
type: "string",
|
|
59
90
|
alias: "p",
|
|
60
91
|
choices: ["claude", "codex", "gemini"],
|
|
@@ -333,7 +364,31 @@ yargs
|
|
|
333
364
|
},
|
|
334
365
|
addDependencyCommand,
|
|
335
366
|
)
|
|
336
|
-
.
|
|
367
|
+
.command("$0", false, {}, () => {
|
|
368
|
+
cli.showHelp()
|
|
369
|
+
})
|
|
370
|
+
.example("gxdev init my-plugin", "Scaffold a new plugin called my-plugin")
|
|
371
|
+
.example(
|
|
372
|
+
"gxdev init",
|
|
373
|
+
"Add the toolkit to the current project (detects existing package.json)",
|
|
374
|
+
)
|
|
375
|
+
.example("gxdev dev", "Start Vite + Socket.IO in plain CLI mode")
|
|
376
|
+
.example("gxdev dev --ui", "Start the dev server inside the interactive TUI")
|
|
377
|
+
.example("gxdev ui", "Open the TUI without auto-starting anything")
|
|
378
|
+
.example("gxdev lint --all", "Lint configuration.json and app-manifest.json")
|
|
379
|
+
.example(
|
|
380
|
+
"gxdev extract-config",
|
|
381
|
+
"Sync app-manifest.json from gxp-string / gxp-src / store usage in src/",
|
|
382
|
+
)
|
|
383
|
+
.epilog(
|
|
384
|
+
[
|
|
385
|
+
"Docs: https://docs.gxp.dev",
|
|
386
|
+
"AI/MCP: the gxp-api MCP server (bin: gxp-api-server) exposes 29 tools",
|
|
387
|
+
" across API specs, config editing, docs search, and test helpers.",
|
|
388
|
+
].join("\n"),
|
|
389
|
+
)
|
|
337
390
|
.help("h")
|
|
338
391
|
.alias("h", "help")
|
|
339
|
-
.
|
|
392
|
+
.strict(false)
|
|
393
|
+
|
|
394
|
+
cli.parse()
|