@owdproject/core 3.3.1 → 3.4.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.
Files changed (92) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/DESKTOP_KERNEL.md +232 -0
  3. package/MIGRATION_3.3.2.md +23 -0
  4. package/MIGRATION_3.4.md +126 -0
  5. package/PLAYGROUND.md +91 -0
  6. package/README.md +13 -80
  7. package/dist/module.d.mts +2 -2
  8. package/dist/module.json +3 -3
  9. package/dist/module.mjs +74 -88
  10. package/index.ts +6 -3
  11. package/kit/authoring.ts +340 -0
  12. package/kit/defineDesktopApp.ts +56 -0
  13. package/module.ts +64 -84
  14. package/package.json +70 -41
  15. package/runtime/components/{Desktop/Application/DesktopApplicationRender.vue → Application/DesktopCoreApplicationRender.vue} +2 -2
  16. package/runtime/components/{Desktop/Application/DesktopApplicationWindowsRender.vue → Application/DesktopCoreApplicationWindowsRender.vue} +1 -1
  17. package/runtime/components/core/DesktopCore.vue +43 -0
  18. package/runtime/components/{Desktop/Window/DesktopWindow.vue → window/DesktopCoreWindow.vue} +17 -6
  19. package/runtime/components/window/DesktopCoreWindowSnapHintsBase.vue +74 -0
  20. package/runtime/components/workspace/DesktopCoreWorkspaceEdgeHintsBase.vue +84 -0
  21. package/runtime/composables/useBlockNonInputContextMenu.ts +30 -0
  22. package/runtime/composables/useDesktopConfig.ts +8 -0
  23. package/runtime/composables/useDesktopDialogs.ts +16 -0
  24. package/runtime/composables/useDesktopExtension.ts +8 -0
  25. package/runtime/composables/useDesktopManager.ts +2 -0
  26. package/runtime/composables/useDesktopManifest.ts +17 -0
  27. package/runtime/composables/useDesktopSession.ts +27 -0
  28. package/runtime/composables/useDesktopShellIdentity.ts +99 -0
  29. package/runtime/composables/useDesktopShellOptions.ts +36 -0
  30. package/runtime/composables/useDesktopShellReady.ts +7 -0
  31. package/runtime/composables/useDesktopWorkArea.ts +93 -0
  32. package/runtime/composables/useTerminalManager.ts +102 -9
  33. package/runtime/composables/useToggleWindowMaximize.ts +35 -0
  34. package/runtime/composables/useWindowDragHandlers.ts +47 -0
  35. package/runtime/composables/useWindowSnapDrop.ts +112 -0
  36. package/runtime/composables/useWorkspaceEdgeDrop.ts +176 -0
  37. package/runtime/composables/useWorkspaceManager.ts +26 -0
  38. package/runtime/composables/useWorkspaceOverviewCapture.ts +92 -0
  39. package/runtime/composables/useWorkspaceOverviewLiveScale.ts +151 -0
  40. package/runtime/constants/desktopShellKeys.ts +12 -0
  41. package/runtime/constants/shellLayout.ts +5 -0
  42. package/runtime/dialogs/desktopDialogProvider.ts +73 -0
  43. package/runtime/internal/controllers/ApplicationController.ts +8 -2
  44. package/runtime/internal/controllers/WindowController.ts +93 -8
  45. package/runtime/plugins/01.desktop-shell-init.client.ts +28 -0
  46. package/runtime/plugins/02.desktop-register-desktop-apps.client.ts +2 -6
  47. package/runtime/stores/storeApplicationMeta.ts +2 -1
  48. package/runtime/stores/storeApplicationWindows.ts +2 -1
  49. package/runtime/stores/storeDesktop.ts +17 -57
  50. package/runtime/stores/storeDesktopDefaultApps.ts +2 -1
  51. package/runtime/stores/storeDesktopVolume.ts +2 -1
  52. package/runtime/stores/storeDesktopWindow.ts +20 -2
  53. package/runtime/stores/storeDesktopWorkspace.ts +31 -1
  54. package/runtime/stores/storeIds.ts +35 -0
  55. package/runtime/types/desktopMenu.ts +10 -0
  56. package/runtime/utils/initDesktopShell.ts +80 -0
  57. package/runtime/utils/migratePersistedStoreIds.ts +57 -0
  58. package/runtime/utils/utilApp.ts +0 -12
  59. package/runtime/utils/{captureElementToCanvas.ts → utilCaptureElementToCanvas.ts} +1 -1
  60. package/runtime/utils/utilDetectSnapZone.ts +57 -0
  61. package/runtime/utils/utilWindowLayout.ts +82 -0
  62. package/runtime/utils/utilWindowMaximizeLayout.ts +44 -0
  63. package/runtime/utils/utilWorkspaceWindows.ts +33 -0
  64. package/types/index.d.ts +125 -14
  65. package/bin/cli.js +0 -395
  66. package/bin/desktop.js +0 -5
  67. package/bin/lib/catalog.js +0 -293
  68. package/bin/lib/config.js +0 -109
  69. package/bin/lib/desktopConfig.js +0 -56
  70. package/bin/lib/generateTemplate.js +0 -389
  71. package/bin/lib/install.js +0 -408
  72. package/bin/lib/migrateModulePlayground.config.mjs +0 -164
  73. package/bin/lib/migrateModulePlayground.mjs +0 -313
  74. package/bin/lib/npmVersions.js +0 -124
  75. package/bin/lib/playgroundContext.js +0 -188
  76. package/bin/lib/scaffold.js +0 -197
  77. package/bin/lib/status.js +0 -289
  78. package/bin/lib/validateModule.js +0 -697
  79. package/bin/lib/workspace.js +0 -182
  80. package/bin/owd.js +0 -5
  81. package/bin/tui.js +0 -1379
  82. package/runtime/components/Desktop/Core/DesktopCore.vue +0 -90
  83. package/runtime/utils/explorerEntryPath.ts +0 -10
  84. package/runtime/utils/resolveDesktopConfigPath.ts +0 -52
  85. package/runtime/utils/splitDesktopUserConfig.ts +0 -85
  86. package/runtime/utils/utilDesktop.ts +0 -35
  87. package/runtime/utils/validateDesktopUserConfig.ts +0 -44
  88. /package/runtime/components/{Desktop/Background/DesktopBackground.vue → background/DesktopCoreBackground.vue} +0 -0
  89. /package/runtime/components/{Desktop/Time/DesktopTime.vue → time/DesktopCoreTime.vue} +0 -0
  90. /package/runtime/components/{Desktop/Window/DesktopWindowContent.vue → window/DesktopCoreWindowContent.vue} +0 -0
  91. /package/runtime/components/{Desktop/Window/DesktopWindowNav.vue → window/DesktopCoreWindowNav.vue} +0 -0
  92. /package/runtime/utils/{utilWindow.ts → utilWindowControllerAdapter.ts} +0 -0
package/types/index.d.ts CHANGED
@@ -1,16 +1,14 @@
1
1
  import type { Nuxt } from '@nuxt/schema'
2
2
  import type { ShallowRef } from 'vue'
3
- import { useApplicationManager } from '../runtime/composables/useApplicationManager'
4
3
 
5
4
  declare module 'nuxt/schema' {
6
5
  interface PublicRuntimeConfig {
7
- owd: {
8
- tailwindPaths: []
9
- }
6
+ desktop: DesktopConfig
10
7
  }
11
8
  }
12
9
 
13
- interface IApplicationManager {
10
+ declare global {
11
+ interface IApplicationManager {
14
12
  apps: Map<string, IApplicationController>
15
13
 
16
14
  get appsEntries(): Reactive<ApplicationEntry[]>
@@ -61,6 +59,7 @@ interface ApplicationConfig {
61
59
  windows?: { [key: string]: WindowConfig }
62
60
  entries: { [key: string]: ApplicationEntry }
63
61
  commands?: { [key: string]: ApplicationCommand }
62
+ terminal?: { [commandName: string]: Omit<TerminalCommand, 'name' | 'applicationId'> }
64
63
 
65
64
  onReady?(app: IApplicationController): void | Promise<void>
66
65
 
@@ -73,7 +72,8 @@ interface ApplicationConfig {
73
72
 
74
73
  interface ApplicationConfigProvide {
75
74
  name: string
76
- command: string
75
+ entry: string
76
+ command?: string
77
77
  }
78
78
 
79
79
  type IApplicationMeta = { [key: string]: any }
@@ -131,6 +131,8 @@ export interface IWindowController {
131
131
  // common
132
132
  get title(): string
133
133
 
134
+ get windowTitle(): string
135
+
134
136
  get icon(): string | undefined
135
137
 
136
138
  // sizes
@@ -173,6 +175,11 @@ export interface IWindowController {
173
175
  maximize(): boolean
174
176
  unmaximize(): boolean
175
177
 
178
+ // layout (snap / tiled zones)
179
+ setLayout(layout: WindowLayout): boolean
180
+ clearLayout(): boolean
181
+ saveBoundsBeforeLayout(): void
182
+
176
183
  // destroy
177
184
  destroy(): boolean
178
185
 
@@ -182,13 +189,15 @@ export interface IWindowController {
182
189
  // override
183
190
  setTitleOverride(title: string | undefined): void
184
191
  resetTitleOverride(): void
192
+ setWindowTitleOverride(title: string | undefined): void
193
+ resetWindowTitleOverride(): void
185
194
  }
186
195
 
187
196
  /** Payload restored with window state (e.g. explorer cwd in `path`). */
188
197
  get meta(): { path?: string } & Record<string, unknown>
189
198
 
190
- /** Chrome menu model (e.g. PrimeVue Menubar). */
191
- menu: unknown[]
199
+ /** Chrome menu model ({@link DesktopMenuItem}[]; Menubar-compatible). */
200
+ menu: import('../runtime/types/desktopMenu').DesktopMenuItem[]
192
201
 
193
202
  setMenu(menu: unknown[]): void
194
203
 
@@ -254,6 +263,7 @@ interface WindowStoredState {
254
263
 
255
264
  interface WindowOverride {
256
265
  title?: undefined | string
266
+ windowTitle?: undefined | string
257
267
  icon?: undefined | string
258
268
  }
259
269
 
@@ -289,6 +299,37 @@ interface WindowState {
289
299
 
290
300
  // draggable
291
301
  resizable?: boolean
302
+
303
+ /** Snap zone layout; `normal` is unset or explicit restore. */
304
+ layout?: WindowLayout
305
+
306
+ /** Bounds saved before first snap so restore can revert geometry. */
307
+ boundsBeforeLayout?: WindowBounds
308
+ }
309
+
310
+ export type WindowLayout =
311
+ | 'normal'
312
+ | 'maximize'
313
+ | 'bottom-half'
314
+ | 'left-half'
315
+ | 'right-half'
316
+ | 'top-left'
317
+ | 'top-right'
318
+ | 'bottom-left'
319
+ | 'bottom-right'
320
+
321
+ export interface WindowBounds {
322
+ x: number
323
+ y: number
324
+ width: number
325
+ height: number
326
+ }
327
+
328
+ export interface DesktopWorkAreaRect {
329
+ x: number
330
+ y: number
331
+ width: number
332
+ height: number
292
333
  }
293
334
 
294
335
  interface WindowSize {
@@ -351,6 +392,7 @@ interface DocsModuleConfig {
351
392
  }
352
393
 
353
394
  interface DesktopConfig {
395
+ coreVersion?: string
354
396
  theme?: string
355
397
  modules?: string[]
356
398
  apps?: string[]
@@ -364,6 +406,7 @@ interface DesktopConfig {
364
406
  systemBar?: DesktopSystemBarConfig
365
407
  dockBar?: DesktopDockBarConfig
366
408
  workspaces?: DesktopWorkspacesConfig
409
+ windows?: DesktopWindowsConfig
367
410
  }
368
411
 
369
412
  interface DesktopWindowsConfig {
@@ -387,13 +430,36 @@ interface DesktopWorkspacesConfig {
387
430
 
388
431
  // TERMINAL
389
432
 
433
+ type TerminalCommandArg = {
434
+ name: string
435
+ description?: string
436
+ required?: boolean
437
+ }
438
+
439
+ type TerminalCommandOption = {
440
+ flag: string
441
+ description?: string
442
+ }
443
+
390
444
  type TerminalCommand = {
391
445
  name: string
392
446
  applicationId: string
447
+ description?: string
448
+ usage?: string
449
+ args?: TerminalCommandArg[]
450
+ options?: TerminalCommandOption[]
451
+ }
452
+
453
+ interface ITerminalManager {
454
+ addCommand(command: TerminalCommand): void
455
+ listCommands(): string[]
456
+ getCommand(name: string): TerminalCommand | undefined
457
+ getAllCommands(): TerminalCommand[]
458
+ execCommand(input: string): Promise<CommandOutput | void>
393
459
  }
394
460
 
395
461
  interface CommandOutput {
396
- text: string
462
+ message: string
397
463
  isError?: boolean
398
464
  }
399
465
 
@@ -407,14 +473,59 @@ interface DefaultAppsConfig {
407
473
  [key: string]: DefaultAppConfig
408
474
  }
409
475
 
410
- /** Stored default for a feature: which app and which entry key to use. */
411
- interface DefaultAppConfig {
412
- applicationId: string
413
- entry: string
476
+ /** Stored default for a feature: which app and which entry key to use. */
477
+ interface DefaultAppConfig {
478
+ applicationId: string
479
+ entry: string
480
+ }
481
+
482
+ module '*.vue' {
483
+ import type { DefineComponent } from 'vue'
484
+ const component: DefineComponent<{}, {}, any>
485
+ export default component
486
+ }
414
487
  }
415
488
 
416
489
  export function defineDesktopApp(config: ApplicationConfig)
417
490
  export function defineDesktopConfig(config: DesktopConfig)
418
- export function registerTailwindPath(nuxt: Nuxt, path: string): void
491
+ export function defineDesktopModule(
492
+ definition: import('@nuxt/kit').NuxtModule<
493
+ Record<string, unknown>,
494
+ Record<string, unknown>,
495
+ false
496
+ > & { meta: { name: string; configKey: string } },
497
+ ): ReturnType<typeof import('@nuxt/kit').defineNuxtModule>
498
+
499
+ export function defineDesktopTheme(
500
+ definition: import('@nuxt/kit').NuxtModule<
501
+ Record<string, unknown>,
502
+ Record<string, unknown>,
503
+ false
504
+ >,
505
+ ): ReturnType<typeof import('@nuxt/kit').defineNuxtModule>
506
+
507
+ export function setDesktopExtensionConfig(
508
+ nuxt: Nuxt,
509
+ configKey: string,
510
+ resolved: Record<string, unknown>,
511
+ ): void
512
+
513
+ export function mergeDesktopExtensionConfig(
514
+ nuxt: Nuxt,
515
+ configKey: string,
516
+ partial: Record<string, unknown>,
517
+ ): void
518
+
519
+ export function useDesktopConfig(): import('vue').ComputedRef<DesktopConfig>
520
+ export function useDesktopExtension<K extends string>(
521
+ key: K,
522
+ ): import('vue').ComputedRef<unknown>
523
+ export function hasDesktopModule(
524
+ pkg: string,
525
+ ): import('vue').ComputedRef<boolean>
526
+ export function hasDesktopApp(pkg: string): import('vue').ComputedRef<boolean>
527
+ export function hasDesktopExtension(
528
+ key: string,
529
+ ): import('vue').ComputedRef<boolean>
419
530
 
420
531
  export {}
package/bin/cli.js DELETED
@@ -1,395 +0,0 @@
1
- import { spawn } from 'node:child_process'
2
- import { runDevForeground } from './lib/status.js'
3
- import { existsSync } from 'node:fs'
4
- import { join } from 'node:path'
5
- import getopts from 'getopts'
6
- import {
7
- resolveSource,
8
- printPlan,
9
- printNextSteps,
10
- runWorkspaceInstall,
11
- runNpmInstall,
12
- } from './lib/install.js'
13
- import { findWorkspaceRoot, inferKind } from './lib/workspace.js'
14
- import { resolveDevTarget } from './lib/playgroundContext.js'
15
- import { scaffoldProject } from './lib/scaffold.js'
16
-
17
- const SCOPE = '@owdproject/'
18
-
19
- /** @type {Record<string, { configKey: string, workspaceDir: string, nx: string, label: string }>} */
20
- const KINDS = {
21
- app: {
22
- label: 'app',
23
- configKey: 'apps',
24
- workspaceDir: 'apps',
25
- nx: 'desktop:install-app',
26
- },
27
- module: {
28
- label: 'module',
29
- configKey: 'modules',
30
- workspaceDir: 'packages',
31
- nx: 'desktop:install-module',
32
- },
33
- theme: {
34
- label: 'theme',
35
- configKey: 'theme',
36
- workspaceDir: 'themes',
37
- nx: 'desktop:install-theme',
38
- },
39
- }
40
-
41
- const LEGACY_COMMANDS = {
42
- 'install-app': 'app',
43
- 'install-module': 'module',
44
- 'install-theme': 'theme',
45
- }
46
-
47
- /** @type {string} */
48
- let commandName = 'desktop'
49
-
50
- function buildHelp(name) {
51
- return `
52
- ${name} — add apps, modules, and themes to your Open Web Desktop
53
-
54
- USAGE
55
- ${name} Open the control panel (interactive TUI)
56
- ${name} dev [--playground] Start dev server (auto-detects module playground)
57
-
58
- CONTROL PANEL (TUI)
59
- m Open command menu (all actions)
60
- s Start the Nuxt dev server
61
- x Stop the Nuxt dev server
62
- R Reboot the Nuxt dev server (stop + start)
63
- w Save catalog/theme changes to desktop.config.ts
64
- i Open in-app docs (when module-docs is installed)
65
- d Toggle User (npm) / Dev (git clone) install mode
66
- g Settings (GitHub username for fork clones)
67
- r Refresh package list from GitHub
68
- b Run pnpm run generate
69
- q / Esc Quit
70
- ${name} init [dir] Create a new OWD project (then opens the control panel)
71
- ${name} add <package> [options]
72
- ${name} add <kind> <name> [options]
73
- ${name} validate [path...] Check Nuxt module + playground layout
74
- ${name} template [--dry-run] [--check] Regenerate client/template/ (maintainers)
75
-
76
- TEMPLATE (monorepo maintainers)
77
- ${name} template Write template/ from blueprint + desktop/ + latest npm versions
78
- ${name} template --dry-run Show planned @owdproject/* and starter versions
79
- ${name} template --check Fail if committed template/ differs (CI)
80
-
81
- VALIDATE
82
- ${name} validate Validate cwd package, or all apps/themes/modules at repo root
83
- ${name} validate . Validate explicit package directory
84
- ${name} validate apps Validate every @owdproject/* module under apps/
85
- --json Machine-readable output
86
- --strict Treat warnings as failures
87
- --smoke Run dev:prepare + nuxt build playground (slow, CI)
88
-
89
- INSTALL MODES
90
- User (default) npm registry — for end users and generated projects
91
- Dev clone into apps/, packages/, or themes/ in the monorepo
92
-
93
- EXAMPLES
94
- pnpm ${name} # control panel
95
- pnpm ${name} dev # monorepo desktop (from repo root)
96
- cd apps/app-about && pnpm ${name} dev # app-about playground
97
- pnpm ${name} dev --playground # force playground when cwd is in a module
98
- ${name} init my-desktop # scaffold + pnpm install + control panel
99
- ${name} add app-todo --npm
100
- ${name} add app-todo --dev
101
- ${name} add module-persistence --from dxlliv
102
-
103
- KINDS (optional — inferred from the package name)
104
- app app-* → apps/
105
- module module-* → packages/ (kit-* and *-template are not listed in the control panel)
106
- theme theme-* → themes/
107
-
108
- OPTIONS
109
- --playground Start the module playground dev server (when cwd is inside an @owdproject/* package with playground/)
110
- --from <source> Git source (user, user/repo, or URL)
111
- --branch <name> Git branch to clone
112
- --npm Install from npm (default when --from is omitted)
113
- --dev, --workspace Clone from github.com/owdproject/<package>
114
- --dry-run Print the plan without changing anything
115
- -h, --help Show this help
116
-
117
- --from <source>
118
- (omit) npm registry (default)
119
- npm npm registry
120
- owdproject Clone official repo (monorepo only)
121
- <github-user> Clone github.com/<user>/<package> (your fork)
122
- <user>/<repo> Explicit GitHub repo
123
- <git-url> Full clone URL
124
-
125
- LEGACY (still supported)
126
- ${name} install-app @owdproject/app-todo
127
- → prefer: ${name} add app-todo
128
- `
129
- }
130
-
131
- async function openControlPanel(name) {
132
- const { runTui } = await import('./tui.js')
133
- await runTui(name)
134
- }
135
-
136
- function fail(message, hint) {
137
- console.error(`\n✗ ${message}`)
138
- if (hint) console.error(` ${hint}`)
139
- console.error(`\nRun \`${commandName} --help\` for usage.\n`)
140
- process.exit(1)
141
- }
142
-
143
- function warn(message) {
144
- console.warn(`\n⚠ ${message}\n`)
145
- }
146
-
147
- /**
148
- * @param {string} input
149
- * @param {string | undefined} explicitKind
150
- */
151
- function normalizePackage(input, explicitKind) {
152
- let raw = input.trim()
153
- if (raw.startsWith(SCOPE)) raw = raw.slice(SCOPE.length)
154
-
155
- if (!raw) {
156
- fail('Package name is required.', `Example: ${commandName} add app-todo`)
157
- }
158
-
159
- const kind = explicitKind ?? inferKind(raw)
160
-
161
- if (explicitKind) {
162
- const prefixes = {
163
- app: 'app-',
164
- theme: 'theme-',
165
- module: ['module-', 'kit-'],
166
- }
167
- const expected = prefixes[explicitKind]
168
- const list = Array.isArray(expected) ? expected : [expected]
169
- if (!list.some((p) => raw.startsWith(p))) {
170
- raw = `${list[0]}${raw}`
171
- }
172
- }
173
-
174
- return { pkgName: `${SCOPE}${raw}`, shortName: raw, kind }
175
- }
176
-
177
- function mapLegacyFlags(parsed) {
178
- const { dev, workspace, fork, repo, branch, from, npm } = parsed
179
- let mappedFrom = from
180
- let mappedNpm = npm
181
- const forceDev = dev || workspace
182
-
183
- if (fork || repo) {
184
- warn('`--fork` and `--repo` are deprecated — use `--from` instead.')
185
- mappedFrom = repo || fork
186
- }
187
- if (forceDev && !mappedFrom && !mappedNpm) {
188
- mappedFrom = 'owdproject'
189
- }
190
- if (mappedNpm) mappedFrom = 'npm'
191
-
192
- return { from: mappedFrom, branch, npm: mappedNpm, dev: forceDev }
193
- }
194
-
195
- function parseAddArgs(positionals) {
196
- const kindNames = Object.keys(KINDS)
197
- if (positionals.length === 0) {
198
- fail('Missing package name.', `Example: ${commandName} add app-todo`)
199
- }
200
-
201
- if (kindNames.includes(positionals[0])) {
202
- const kind = positionals[0]
203
- const name = positionals[1]
204
- if (!name) {
205
- fail(`Missing name for kind "${kind}".`, `Example: ${commandName} add ${kind} todo`)
206
- }
207
- return normalizePackage(name, kind)
208
- }
209
-
210
- return normalizePackage(positionals[0])
211
- }
212
-
213
- function parseLegacyInstall(cmd, positionals) {
214
- const kind = LEGACY_COMMANDS[cmd]
215
- const raw = positionals[0]
216
- if (!raw) {
217
- fail('Missing package name.', `Example: ${commandName} ${cmd} ${SCOPE}app-todo`)
218
- }
219
- warn(`\`${cmd}\` is deprecated — use \`${commandName} add …\` instead.`)
220
- return normalizePackage(raw, kind)
221
- }
222
-
223
- /**
224
- * @param {string} name CLI binary name (`desktop` or deprecated `owd`)
225
- * @param {string[]} argv Arguments (without node and script path)
226
- * @param {{ deprecated?: boolean }} [options]
227
- */
228
- export async function runCli(name, argv, options = {}) {
229
- commandName = name
230
-
231
- if (options.deprecated) {
232
- warn('The `owd` command is deprecated. Use `desktop` instead.')
233
- }
234
-
235
- const parsed = getopts(argv, {
236
- alias: { h: 'help', b: 'branch' },
237
- boolean: ['help', 'npm', 'dry-run', 'dev', 'workspace', 'playground', 'json', 'strict', 'smoke', 'check'],
238
- string: ['from', 'branch', 'fork', 'repo'],
239
- })
240
-
241
- const { _, help, npm: npmFlag } = parsed
242
- const dryRun = parsed['dry-run'] === true
243
- const { from, branch, npm: npmFromLegacy, dev: devFlag } = mapLegacyFlags(parsed)
244
- const useNpm = npmFlag || npmFromLegacy || (!from && !devFlag)
245
-
246
- if (help || _[0] === 'help') {
247
- console.log(buildHelp(name))
248
- process.exit(0)
249
- }
250
-
251
- const cmd = _[0]
252
-
253
- if (cmd === 'init') {
254
- const projectDir = (_[1] || 'owd-client').trim()
255
- const cwd = process.cwd()
256
-
257
- if (findWorkspaceRoot(cwd)) {
258
- fail(
259
- 'Already inside an OWD workspace.',
260
- `Use \`${name}\` to manage this project, or run init from a parent directory.`,
261
- )
262
- }
263
-
264
- try {
265
- await scaffoldProject({ dir: projectDir, cwd, commandName: name })
266
- } catch (error) {
267
- fail(error.message ?? String(error))
268
- }
269
- return
270
- }
271
-
272
- const workspaceRoot = findWorkspaceRoot()
273
-
274
- if (cmd === 'dev') {
275
- if (!workspaceRoot) {
276
- fail(
277
- 'Not inside an OWD workspace.',
278
- 'Run from the client repo, or try: desktop · desktop add <package>',
279
- )
280
- }
281
- const forcePlayground = parsed.playground === true
282
- const devTarget = resolveDevTarget(process.cwd(), workspaceRoot, { forcePlayground })
283
- if (forcePlayground && !devTarget) {
284
- fail(
285
- 'No @owdproject module with playground/desktop.config.ts found from this directory.',
286
- 'Run from an app/theme/module package (e.g. apps/app-about), or omit --playground for the monorepo desktop.',
287
- )
288
- }
289
- runDevForeground(devTarget)
290
- return
291
- }
292
-
293
- if (cmd === 'validate') {
294
- const { runValidateCli, formatValidationReport } = await import('./lib/validateModule.js')
295
- const strict = parsed.strict === true
296
- const json = parsed.json === true
297
- const smoke = parsed.smoke === true
298
- const paths = _.slice(1).map(String)
299
- const { exitCode, results } = runValidateCli(paths, {
300
- workspaceRoot,
301
- json,
302
- strict,
303
- smoke,
304
- })
305
- for (const result of results) {
306
- console.log(formatValidationReport(result, { json }))
307
- if (!json) console.log('')
308
- }
309
- process.exit(exitCode)
310
- }
311
-
312
- if (cmd === 'template') {
313
- if (!workspaceRoot) {
314
- fail(
315
- 'Not inside an OWD workspace.',
316
- `Run from the client monorepo root to regenerate template/.`,
317
- )
318
- }
319
- const { runGenerateTemplateCli } = await import('./lib/generateTemplate.js')
320
- await runGenerateTemplateCli({
321
- workspaceRoot,
322
- dryRun: parsed['dry-run'] === true,
323
- check: parsed.check === true,
324
- })
325
- return
326
- }
327
-
328
- if (!cmd) {
329
- if (!workspaceRoot) {
330
- fail(
331
- 'Not inside an OWD workspace.',
332
- 'Run from the client repo, or try: desktop · desktop add <package>',
333
- )
334
- }
335
- await openControlPanel(name)
336
- return
337
- }
338
-
339
- if (cmd === 'ui') {
340
- fail('The `ui` subcommand was removed.', `Use \`${name}\` to open the control panel.`)
341
- }
342
-
343
- if (!workspaceRoot) {
344
- fail(
345
- 'Not inside an OWD workspace.',
346
- 'Run from the client repo (needs pnpm-workspace.yaml + nx.json), or use a generated project with the same layout.',
347
- )
348
- }
349
-
350
- let pkgInfo
351
-
352
- if (cmd === 'add') {
353
- pkgInfo = parseAddArgs(_.slice(1))
354
- } else if (LEGACY_COMMANDS[cmd]) {
355
- pkgInfo = parseLegacyInstall(cmd, _.slice(1))
356
- } else {
357
- fail(`Unknown command: ${cmd}`, `Use \`${name}\`, \`${name} dev\`, or \`${name} add <package>\`.`)
358
- }
359
-
360
- const { pkgName, shortName, kind } = pkgInfo
361
- const inMonorepo = Boolean(workspaceRoot)
362
- const source = resolveSource(useNpm ? 'npm' : from, shortName, inMonorepo, {
363
- npm: useNpm,
364
- dev: devFlag,
365
- })
366
-
367
- if (source.mode === 'npm') {
368
- if (dryRun) {
369
- printPlan({
370
- pkgName,
371
- kind,
372
- targetDir: '(npm → node_modules)',
373
- source,
374
- branch: null,
375
- dryRun: true,
376
- })
377
- process.exit(0)
378
- }
379
- runNpmInstall(kind, pkgName, workspaceRoot)
380
- } else {
381
- try {
382
- await runWorkspaceInstall({
383
- pkgName,
384
- shortName,
385
- kind,
386
- workspaceRoot,
387
- source,
388
- branch,
389
- dryRun,
390
- })
391
- } catch (error) {
392
- fail(error.message ?? String(error))
393
- }
394
- }
395
- }
package/bin/desktop.js DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { runCli } from './cli.js'
4
-
5
- await runCli('desktop', process.argv.slice(2))