@owdproject/cli 0.0.3 → 0.2.0
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/LICENSE +20 -0
- package/README.md +50 -16
- package/bin/bridge.js +129 -0
- package/bin/cli.js +491 -0
- package/bin/cp.js +3542 -0
- package/bin/desktop.js +5 -0
- package/bin/lib/catalog.js +504 -0
- package/bin/lib/config.js +173 -0
- package/bin/lib/cpAscii.js +39 -0
- package/bin/lib/cpFormat.js +343 -0
- package/bin/lib/create.js +246 -0
- package/bin/lib/desktopConfig.js +48 -0
- package/bin/lib/generateTemplate.js +427 -0
- package/bin/lib/install.js +521 -0
- package/bin/lib/installWizardFlow.js +792 -0
- package/bin/lib/migrateModulePlayground.config.mjs +187 -0
- package/bin/lib/migrateModulePlayground.mjs +318 -0
- package/bin/lib/npmVersions.js +124 -0
- package/bin/lib/packageSources.js +375 -0
- package/bin/lib/playgroundContext.js +188 -0
- package/bin/lib/scaffold.js +205 -0
- package/bin/lib/status.js +319 -0
- package/bin/lib/validateModule.js +978 -0
- package/bin/lib/workspace.js +289 -0
- package/bin/owd.js +2 -118
- package/go/bridge/bridge.go +220 -0
- package/go/desktop-go +0 -0
- package/go/go.mod +33 -0
- package/go/go.sum +52 -0
- package/go/main.go +34 -0
- package/go/owd-cli +0 -0
- package/go/tui/engine.go +472 -0
- package/go/tui/engine_test.go +40 -0
- package/go/tui/handlers.go +604 -0
- package/go/tui/helpers.go +916 -0
- package/go/tui/helpers_test.go +97 -0
- package/go/tui/modals.go +423 -0
- package/go/tui/resolver.go +377 -0
- package/go/tui/resolver_test.go +86 -0
- package/go/tui/styles.go +153 -0
- package/go/tui/tasks.go +850 -0
- package/go/tui/tui.go +869 -0
- package/go/tui/tui_test.go +69 -0
- package/go/tui/types.go +230 -0
- package/go/tui/view.go +812 -0
- package/go/tui/workqueue.go +179 -0
- package/go/tui/workqueue_test.go +90 -0
- package/package.json +33 -22
- package/src/commands/create.js +0 -11
- package/src/commands/generate.js +0 -12
- package/src/commands/installApp.js +0 -9
- package/src/commands/installTheme.js +0 -9
- package/src/commands/start.js +0 -13
- package/src/utils/cloneRepo.js +0 -25
- package/src/utils/installPackage.js +0 -15
- package/src/utils/logging.js +0 -15
package/bin/cli.js
ADDED
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
import { spawn, execSync } from 'node:child_process'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { runDevForeground } from './lib/status.js'
|
|
4
|
+
import { existsSync } from 'node:fs'
|
|
5
|
+
import { join } from 'node:path'
|
|
6
|
+
import getopts from 'getopts'
|
|
7
|
+
import {
|
|
8
|
+
resolveSource,
|
|
9
|
+
printPlan,
|
|
10
|
+
printNextSteps,
|
|
11
|
+
runWorkspaceInstall,
|
|
12
|
+
runNpmInstall,
|
|
13
|
+
} from './lib/install.js'
|
|
14
|
+
import { findWorkspaceRoot, inferKind } from './lib/workspace.js'
|
|
15
|
+
import { resolveDevTarget } from './lib/playgroundContext.js'
|
|
16
|
+
import { scaffoldProject } from './lib/scaffold.js'
|
|
17
|
+
|
|
18
|
+
const SCOPE = '@owdproject/'
|
|
19
|
+
|
|
20
|
+
/** @type {Record<string, { configKey: string, workspaceDir: string, nx: string, label: string }>} */
|
|
21
|
+
const KINDS = {
|
|
22
|
+
app: {
|
|
23
|
+
label: 'app',
|
|
24
|
+
configKey: 'apps',
|
|
25
|
+
workspaceDir: 'apps',
|
|
26
|
+
nx: 'desktop:install-app',
|
|
27
|
+
},
|
|
28
|
+
module: {
|
|
29
|
+
label: 'module',
|
|
30
|
+
configKey: 'modules',
|
|
31
|
+
workspaceDir: 'packages',
|
|
32
|
+
nx: 'desktop:install-module',
|
|
33
|
+
},
|
|
34
|
+
theme: {
|
|
35
|
+
label: 'theme',
|
|
36
|
+
configKey: 'theme',
|
|
37
|
+
workspaceDir: 'themes',
|
|
38
|
+
nx: 'desktop:install-theme',
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const LEGACY_COMMANDS = {
|
|
43
|
+
'install-app': 'app',
|
|
44
|
+
'install-module': 'module',
|
|
45
|
+
'install-theme': 'theme',
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** @type {string} */
|
|
49
|
+
let commandName = 'desktop'
|
|
50
|
+
|
|
51
|
+
function buildHelp(name) {
|
|
52
|
+
return `
|
|
53
|
+
${name} — add apps, modules, and themes to your Open Web Desktop
|
|
54
|
+
|
|
55
|
+
USAGE
|
|
56
|
+
${name} Open the control panel (interactive TUI)
|
|
57
|
+
${name} dev [--playground] Start dev server (auto-detects module playground)
|
|
58
|
+
|
|
59
|
+
CONTROL PANEL (TUI)
|
|
60
|
+
m Open command menu (all actions)
|
|
61
|
+
s Start the Nuxt dev server
|
|
62
|
+
x Stop the Nuxt dev server
|
|
63
|
+
R Reboot the Nuxt dev server (stop + start)
|
|
64
|
+
w Save catalog/theme changes to desktop.config.ts
|
|
65
|
+
1 / 2 / 3 Apps / Modules / Themes catalog tabs
|
|
66
|
+
o / O Cycle sort (o) or open sort picker (O)
|
|
67
|
+
i Open in-app docs (when module-docs is installed)
|
|
68
|
+
g Settings (GitHub user, SSH, trusted orgs)
|
|
69
|
+
r Refresh package list from GitHub (detects new modules)
|
|
70
|
+
b Run pnpm run generate
|
|
71
|
+
n Create a new app or module (interactive wizard)
|
|
72
|
+
q / Esc Quit
|
|
73
|
+
${name} init [dir] Create a new OWD project (then opens the control panel)
|
|
74
|
+
${name} create Create a new app or module (interactive wizard)
|
|
75
|
+
${name} create <kind> <name> Scaffold a new app or module (e.g. desktop create app todo)
|
|
76
|
+
${name} add <package> [options]
|
|
77
|
+
${name} add <kind> <name> [options]
|
|
78
|
+
${name} validate [path...] Check Nuxt module + playground layout
|
|
79
|
+
${name} template [--dry-run] [--check] Regenerate client/template/ (maintainers)
|
|
80
|
+
|
|
81
|
+
TEMPLATE (monorepo maintainers)
|
|
82
|
+
${name} template Write template/ from blueprint + desktop/ + latest npm versions
|
|
83
|
+
${name} template --dry-run Show planned @owdproject/* and starter versions
|
|
84
|
+
${name} template --check Fail if committed template/ differs (CI)
|
|
85
|
+
|
|
86
|
+
VALIDATE
|
|
87
|
+
${name} validate Validate cwd package, or all apps/themes/modules at repo root
|
|
88
|
+
${name} validate . Validate explicit package directory
|
|
89
|
+
${name} validate apps Validate every @owdproject/* module under apps/
|
|
90
|
+
--json Machine-readable output
|
|
91
|
+
--strict Treat warnings as failures
|
|
92
|
+
--smoke Run dev:prepare + nuxt build playground (slow, CI)
|
|
93
|
+
|
|
94
|
+
INSTALL SOURCES (control panel or CLI)
|
|
95
|
+
npm registry (default for desktop add)
|
|
96
|
+
--dev clone github.com/owdproject/<package>
|
|
97
|
+
--from <user> clone from GitHub user or full git URL (SSH supported)
|
|
98
|
+
|
|
99
|
+
EXAMPLES
|
|
100
|
+
pnpm ${name} # control panel
|
|
101
|
+
pnpm ${name} dev # monorepo desktop (from repo root)
|
|
102
|
+
cd apps/app-about && pnpm ${name} dev # app-about playground
|
|
103
|
+
pnpm ${name} dev --playground # force playground when cwd is in a module
|
|
104
|
+
${name} init my-desktop # scaffold + pnpm install + control panel
|
|
105
|
+
${name} add app-todo --npm
|
|
106
|
+
${name} add app-todo --dev
|
|
107
|
+
${name} add module-persistence --from dxlliv
|
|
108
|
+
|
|
109
|
+
KINDS (optional — inferred from the package name)
|
|
110
|
+
app app-* → apps/
|
|
111
|
+
module module-* → packages/ (kit-* and *-template are not listed in the control panel)
|
|
112
|
+
theme theme-* → themes/
|
|
113
|
+
|
|
114
|
+
OPTIONS
|
|
115
|
+
--playground Start the module playground dev server (when cwd is inside an @owdproject/* package with playground/)
|
|
116
|
+
--from <source> Git source (user, user/repo, or URL)
|
|
117
|
+
--branch <name> Git branch to clone
|
|
118
|
+
--npm Install from npm (default when --from is omitted)
|
|
119
|
+
--dev, --workspace Clone from github.com/owdproject/<package>
|
|
120
|
+
--protocol https|ssh With --from <user>, use HTTPS (default) or SSH clone URL
|
|
121
|
+
--dry-run Print the plan without changing anything
|
|
122
|
+
-h, --help Show this help
|
|
123
|
+
|
|
124
|
+
--from <source>
|
|
125
|
+
(omit) npm registry (default)
|
|
126
|
+
npm npm registry
|
|
127
|
+
owdproject Clone official repo (monorepo only)
|
|
128
|
+
<github-user> Clone github.com/<user>/<package> (your fork)
|
|
129
|
+
<user>/<repo> Explicit GitHub repo
|
|
130
|
+
<git-url> Full clone URL
|
|
131
|
+
|
|
132
|
+
LEGACY (still supported)
|
|
133
|
+
${name} install-app @owdproject/app-todo
|
|
134
|
+
→ prefer: ${name} add app-todo
|
|
135
|
+
`
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function openControlPanel(name) {
|
|
139
|
+
const cliDir = join(fileURLToPath(import.meta.url), '..')
|
|
140
|
+
const goDir = join(cliDir, '../go')
|
|
141
|
+
const binaryPath = join(goDir, 'desktop-go')
|
|
142
|
+
const readline = await import('node:readline/promises')
|
|
143
|
+
|
|
144
|
+
// Compile the Go Control Panel if binary doesn't exist
|
|
145
|
+
if (!existsSync(binaryPath)) {
|
|
146
|
+
console.log('Go Control Panel binary not found. Compiling...')
|
|
147
|
+
try {
|
|
148
|
+
execSync('go build -o desktop-go .', { cwd: goDir, stdio: 'inherit' })
|
|
149
|
+
console.log('Go Control Panel compiled successfully!')
|
|
150
|
+
} catch (err) {
|
|
151
|
+
console.warn('Failed to compile Go Control Panel, falling back to legacy CP:', err.message)
|
|
152
|
+
const child = spawn(process.execPath, [
|
|
153
|
+
'-e',
|
|
154
|
+
`import('./cp.js').then(m => m.runCp(${JSON.stringify(name)}))`
|
|
155
|
+
], {
|
|
156
|
+
cwd: cliDir,
|
|
157
|
+
stdio: 'inherit',
|
|
158
|
+
})
|
|
159
|
+
child.on('exit', async (code) => {
|
|
160
|
+
if (code === 10) {
|
|
161
|
+
const { runCreateCli } = await import('./lib/create.js')
|
|
162
|
+
const workspaceRoot = findWorkspaceRoot()
|
|
163
|
+
try {
|
|
164
|
+
await runCreateCli({ workspaceRoot })
|
|
165
|
+
} catch (err) {
|
|
166
|
+
console.error('\n✗ Error creating package:', err.message)
|
|
167
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
|
168
|
+
await rl.question('\nPress Enter to return to the control panel...')
|
|
169
|
+
rl.close()
|
|
170
|
+
}
|
|
171
|
+
await openControlPanel(name)
|
|
172
|
+
} else {
|
|
173
|
+
process.exit(code ?? 0)
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Execute Go TUI
|
|
181
|
+
const child = spawn(binaryPath, [], { stdio: 'inherit' })
|
|
182
|
+
child.on('exit', async (code) => {
|
|
183
|
+
if (code === 10) {
|
|
184
|
+
const { runCreateCli } = await import('./lib/create.js')
|
|
185
|
+
const workspaceRoot = findWorkspaceRoot()
|
|
186
|
+
try {
|
|
187
|
+
await runCreateCli({ workspaceRoot })
|
|
188
|
+
} catch (err) {
|
|
189
|
+
console.error('\n✗ Error creating package:', err.message)
|
|
190
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
|
191
|
+
await rl.question('\nPress Enter to return to the control panel...')
|
|
192
|
+
rl.close()
|
|
193
|
+
}
|
|
194
|
+
await openControlPanel(name)
|
|
195
|
+
} else {
|
|
196
|
+
process.exit(code ?? 0)
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function fail(message, hint) {
|
|
202
|
+
console.error(`\n✗ ${message}`)
|
|
203
|
+
if (hint) console.error(` ${hint}`)
|
|
204
|
+
console.error(`\nRun \`${commandName} --help\` for usage.\n`)
|
|
205
|
+
process.exit(1)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function warn(message) {
|
|
209
|
+
console.warn(`\n⚠ ${message}\n`)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @param {string} input
|
|
214
|
+
* @param {string | undefined} explicitKind
|
|
215
|
+
*/
|
|
216
|
+
function normalizePackage(input, explicitKind) {
|
|
217
|
+
let raw = input.trim()
|
|
218
|
+
if (raw.startsWith(SCOPE)) raw = raw.slice(SCOPE.length)
|
|
219
|
+
|
|
220
|
+
if (!raw) {
|
|
221
|
+
fail('Package name is required.', `Example: ${commandName} add app-todo`)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const kind = explicitKind ?? inferKind(raw)
|
|
225
|
+
|
|
226
|
+
if (explicitKind) {
|
|
227
|
+
const prefixes = {
|
|
228
|
+
app: 'app-',
|
|
229
|
+
theme: 'theme-',
|
|
230
|
+
module: ['module-', 'kit-'],
|
|
231
|
+
}
|
|
232
|
+
const expected = prefixes[explicitKind]
|
|
233
|
+
const list = Array.isArray(expected) ? expected : [expected]
|
|
234
|
+
if (!list.some((p) => raw.startsWith(p))) {
|
|
235
|
+
raw = `${list[0]}${raw}`
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return { pkgName: `${SCOPE}${raw}`, shortName: raw, kind }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function mapLegacyFlags(parsed) {
|
|
243
|
+
const { dev, workspace, fork, repo, branch, from, npm } = parsed
|
|
244
|
+
let mappedFrom = from
|
|
245
|
+
let mappedNpm = npm
|
|
246
|
+
const forceDev = dev || workspace
|
|
247
|
+
|
|
248
|
+
if (fork || repo) {
|
|
249
|
+
warn('`--fork` and `--repo` are deprecated — use `--from` instead.')
|
|
250
|
+
mappedFrom = repo || fork
|
|
251
|
+
}
|
|
252
|
+
if (forceDev && !mappedFrom && !mappedNpm) {
|
|
253
|
+
mappedFrom = 'owdproject'
|
|
254
|
+
}
|
|
255
|
+
if (mappedNpm) mappedFrom = 'npm'
|
|
256
|
+
|
|
257
|
+
return { from: mappedFrom, branch, npm: mappedNpm, dev: forceDev }
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function parseAddArgs(positionals) {
|
|
261
|
+
const kindNames = Object.keys(KINDS)
|
|
262
|
+
if (positionals.length === 0) {
|
|
263
|
+
fail('Missing package name.', `Example: ${commandName} add app-todo`)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (kindNames.includes(positionals[0])) {
|
|
267
|
+
const kind = positionals[0]
|
|
268
|
+
const name = positionals[1]
|
|
269
|
+
if (!name) {
|
|
270
|
+
fail(`Missing name for kind "${kind}".`, `Example: ${commandName} add ${kind} todo`)
|
|
271
|
+
}
|
|
272
|
+
return normalizePackage(name, kind)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return normalizePackage(positionals[0])
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function parseLegacyInstall(cmd, positionals) {
|
|
279
|
+
const kind = LEGACY_COMMANDS[cmd]
|
|
280
|
+
const raw = positionals[0]
|
|
281
|
+
if (!raw) {
|
|
282
|
+
fail('Missing package name.', `Example: ${commandName} ${cmd} ${SCOPE}app-todo`)
|
|
283
|
+
}
|
|
284
|
+
warn(`\`${cmd}\` is deprecated — use \`${commandName} add …\` instead.`)
|
|
285
|
+
return normalizePackage(raw, kind)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* @param {string} name CLI binary name (`desktop` or deprecated `owd`)
|
|
290
|
+
* @param {string[]} argv Arguments (without node and script path)
|
|
291
|
+
* @param {{ deprecated?: boolean }} [options]
|
|
292
|
+
*/
|
|
293
|
+
export async function runCli(name, argv, options = {}) {
|
|
294
|
+
commandName = name
|
|
295
|
+
|
|
296
|
+
if (options.deprecated) {
|
|
297
|
+
warn('The `owd` command is deprecated. Use `desktop` instead.')
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const parsed = getopts(argv, {
|
|
301
|
+
alias: { h: 'help', b: 'branch' },
|
|
302
|
+
boolean: ['help', 'npm', 'dry-run', 'dev', 'workspace', 'playground', 'json', 'strict', 'smoke', 'check'],
|
|
303
|
+
string: ['from', 'branch', 'fork', 'repo', 'protocol'],
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
const { _, help, npm: npmFlag } = parsed
|
|
307
|
+
const dryRun = parsed['dry-run'] === true
|
|
308
|
+
const { from, branch, npm: npmFromLegacy, dev: devFlag } = mapLegacyFlags(parsed)
|
|
309
|
+
const protocol = parsed.protocol === 'ssh' ? 'ssh' : 'https'
|
|
310
|
+
const useNpm = npmFlag || npmFromLegacy || (!from && !devFlag)
|
|
311
|
+
|
|
312
|
+
if (help || _[0] === 'help') {
|
|
313
|
+
console.log(buildHelp(name))
|
|
314
|
+
process.exit(0)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const cmd = _[0]
|
|
318
|
+
|
|
319
|
+
if (cmd === 'init') {
|
|
320
|
+
const projectDir = (_[1] || 'owd-client').trim()
|
|
321
|
+
const cwd = process.cwd()
|
|
322
|
+
|
|
323
|
+
if (findWorkspaceRoot(cwd)) {
|
|
324
|
+
fail(
|
|
325
|
+
'Already inside an OWD workspace.',
|
|
326
|
+
`Use \`${name}\` to manage this project, or run init from a parent directory.`,
|
|
327
|
+
)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
await scaffoldProject({ dir: projectDir, cwd, commandName: name })
|
|
332
|
+
} catch (error) {
|
|
333
|
+
fail(error.message ?? String(error))
|
|
334
|
+
}
|
|
335
|
+
return
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const workspaceRoot = findWorkspaceRoot()
|
|
339
|
+
|
|
340
|
+
if (cmd === 'dev') {
|
|
341
|
+
if (!workspaceRoot) {
|
|
342
|
+
fail(
|
|
343
|
+
'Not inside an OWD workspace.',
|
|
344
|
+
'Run from the client repo, or try: desktop · desktop add <package>',
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
const forcePlayground = parsed.playground === true
|
|
348
|
+
const devTarget = resolveDevTarget(process.cwd(), workspaceRoot, { forcePlayground })
|
|
349
|
+
if (forcePlayground && !devTarget) {
|
|
350
|
+
fail(
|
|
351
|
+
'No @owdproject module with playground/desktop.config.ts found from this directory.',
|
|
352
|
+
'Run from an app/theme/module package (e.g. apps/app-about), or omit --playground for the monorepo desktop.',
|
|
353
|
+
)
|
|
354
|
+
}
|
|
355
|
+
runDevForeground(devTarget)
|
|
356
|
+
return
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (cmd === 'validate') {
|
|
360
|
+
const { runValidateCli, formatValidationReport } = await import('./lib/validateModule.js')
|
|
361
|
+
const strict = parsed.strict === true
|
|
362
|
+
const json = parsed.json === true
|
|
363
|
+
const smoke = parsed.smoke === true
|
|
364
|
+
const paths = _.slice(1).map(String)
|
|
365
|
+
const { exitCode, results } = runValidateCli(paths, {
|
|
366
|
+
workspaceRoot,
|
|
367
|
+
json,
|
|
368
|
+
strict,
|
|
369
|
+
smoke,
|
|
370
|
+
})
|
|
371
|
+
for (const result of results) {
|
|
372
|
+
console.log(formatValidationReport(result, { json }))
|
|
373
|
+
if (!json) console.log('')
|
|
374
|
+
}
|
|
375
|
+
process.exit(exitCode)
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (cmd === 'template') {
|
|
379
|
+
if (!workspaceRoot) {
|
|
380
|
+
fail(
|
|
381
|
+
'Not inside an OWD workspace.',
|
|
382
|
+
`Run from the client monorepo root to regenerate template/.`,
|
|
383
|
+
)
|
|
384
|
+
}
|
|
385
|
+
const { runGenerateTemplateCli } = await import('./lib/generateTemplate.js')
|
|
386
|
+
await runGenerateTemplateCli({
|
|
387
|
+
workspaceRoot,
|
|
388
|
+
dryRun: parsed['dry-run'] === true,
|
|
389
|
+
check: parsed.check === true,
|
|
390
|
+
})
|
|
391
|
+
return
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (cmd === 'create' || cmd === 'new') {
|
|
395
|
+
if (!workspaceRoot) {
|
|
396
|
+
fail(
|
|
397
|
+
'Not inside an OWD workspace.',
|
|
398
|
+
`Run from inside an OWD workspace directory to scaffold a new package.`,
|
|
399
|
+
)
|
|
400
|
+
}
|
|
401
|
+
const { runCreateCli } = await import('./lib/create.js')
|
|
402
|
+
const kind = _[1]
|
|
403
|
+
const name = _[2]
|
|
404
|
+
await runCreateCli({ kind, name, workspaceRoot })
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (!cmd) {
|
|
409
|
+
if (!workspaceRoot) {
|
|
410
|
+
fail(
|
|
411
|
+
'Not inside an OWD workspace.',
|
|
412
|
+
'Run from the client repo, or try: desktop · desktop add <package>',
|
|
413
|
+
)
|
|
414
|
+
}
|
|
415
|
+
await openControlPanel(name)
|
|
416
|
+
return
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (cmd === 'ui') {
|
|
420
|
+
fail('The `ui` subcommand was removed.', `Use \`${name}\` to open the control panel.`)
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (!workspaceRoot) {
|
|
424
|
+
fail(
|
|
425
|
+
'Not inside an OWD workspace.',
|
|
426
|
+
'Run from the client repo (needs pnpm-workspace.yaml + nx.json), or use a generated project with the same layout.',
|
|
427
|
+
)
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
let pkgInfo
|
|
431
|
+
|
|
432
|
+
if (cmd === 'add') {
|
|
433
|
+
pkgInfo = parseAddArgs(_.slice(1))
|
|
434
|
+
} else if (LEGACY_COMMANDS[cmd]) {
|
|
435
|
+
pkgInfo = parseLegacyInstall(cmd, _.slice(1))
|
|
436
|
+
} else {
|
|
437
|
+
fail(`Unknown command: ${cmd}`, `Use \`${name}\`, \`${name} dev\`, or \`${name} add <package>\`.`)
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const { pkgName, shortName, kind } = pkgInfo
|
|
441
|
+
const inMonorepo = Boolean(workspaceRoot)
|
|
442
|
+
let resolvedFrom = useNpm ? 'npm' : from
|
|
443
|
+
if (
|
|
444
|
+
!useNpm &&
|
|
445
|
+
resolvedFrom &&
|
|
446
|
+
resolvedFrom !== 'npm' &&
|
|
447
|
+
resolvedFrom !== 'owdproject' &&
|
|
448
|
+
resolvedFrom !== 'official' &&
|
|
449
|
+
protocol === 'ssh' &&
|
|
450
|
+
!/[@/]/.test(resolvedFrom)
|
|
451
|
+
) {
|
|
452
|
+
resolvedFrom = `git@github.com:${resolvedFrom}/${shortName}.git`
|
|
453
|
+
}
|
|
454
|
+
const source = resolveSource(resolvedFrom, shortName, inMonorepo, {
|
|
455
|
+
npm: useNpm,
|
|
456
|
+
dev: devFlag,
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
if (source.mode === 'npm') {
|
|
460
|
+
if (dryRun) {
|
|
461
|
+
printPlan({
|
|
462
|
+
pkgName,
|
|
463
|
+
kind,
|
|
464
|
+
targetDir: '(npm → node_modules)',
|
|
465
|
+
source,
|
|
466
|
+
branch: null,
|
|
467
|
+
dryRun: true,
|
|
468
|
+
})
|
|
469
|
+
process.exit(0)
|
|
470
|
+
}
|
|
471
|
+
try {
|
|
472
|
+
await runNpmInstall(kind, pkgName, workspaceRoot)
|
|
473
|
+
} catch (error) {
|
|
474
|
+
fail(error.message ?? String(error))
|
|
475
|
+
}
|
|
476
|
+
} else {
|
|
477
|
+
try {
|
|
478
|
+
await runWorkspaceInstall({
|
|
479
|
+
pkgName,
|
|
480
|
+
shortName,
|
|
481
|
+
kind,
|
|
482
|
+
workspaceRoot,
|
|
483
|
+
source,
|
|
484
|
+
branch,
|
|
485
|
+
dryRun,
|
|
486
|
+
})
|
|
487
|
+
} catch (error) {
|
|
488
|
+
fail(error.message ?? String(error))
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|