@owdproject/core 3.3.1 → 4.0.0-alpha.3

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 (93) hide show
  1. package/README.md +91 -59
  2. package/dist/dom/index.d.mts +65 -0
  3. package/dist/dom/index.d.ts +65 -0
  4. package/dist/dom/index.mjs +224 -0
  5. package/dist/events/index.d.mts +70 -0
  6. package/dist/events/index.d.ts +70 -0
  7. package/dist/events/index.mjs +3 -0
  8. package/dist/index.d.mts +73 -0
  9. package/dist/index.d.ts +73 -0
  10. package/dist/index.mjs +115 -0
  11. package/dist/layout/index.d.mts +41 -0
  12. package/dist/layout/index.d.ts +41 -0
  13. package/dist/layout/index.mjs +64 -0
  14. package/dist/machines/index.d.mts +31 -0
  15. package/dist/machines/index.d.ts +31 -0
  16. package/dist/machines/index.mjs +2 -0
  17. package/dist/managers/index.d.mts +117 -0
  18. package/dist/managers/index.d.ts +117 -0
  19. package/dist/managers/index.mjs +6 -0
  20. package/dist/session/index.d.mts +57 -0
  21. package/dist/session/index.d.ts +57 -0
  22. package/dist/session/index.mjs +65 -0
  23. package/dist/shared/core.B0B0KfVK.mjs +865 -0
  24. package/dist/shared/core.B1XxB289.mjs +239 -0
  25. package/dist/shared/core.B3mp7ztE.mjs +237 -0
  26. package/dist/shared/core.BOvFdEVQ.d.ts +114 -0
  27. package/dist/shared/core.CsDFgGnX.mjs +40 -0
  28. package/dist/shared/core.Di1eFcr_.d.mts +114 -0
  29. package/dist/shared/core.Pd_Ogt4g.mjs +101 -0
  30. package/dist/shared/core.b3Xldzyu.mjs +29 -0
  31. package/dist/types/index.d.mts +266 -0
  32. package/dist/types/index.d.ts +266 -0
  33. package/dist/types/index.mjs +1 -0
  34. package/package.json +60 -87
  35. package/bin/cli.js +0 -395
  36. package/bin/desktop.js +0 -5
  37. package/bin/lib/catalog.js +0 -293
  38. package/bin/lib/config.js +0 -109
  39. package/bin/lib/desktopConfig.js +0 -56
  40. package/bin/lib/generateTemplate.js +0 -389
  41. package/bin/lib/install.js +0 -408
  42. package/bin/lib/migrateModulePlayground.config.mjs +0 -164
  43. package/bin/lib/migrateModulePlayground.mjs +0 -313
  44. package/bin/lib/npmVersions.js +0 -124
  45. package/bin/lib/playgroundContext.js +0 -188
  46. package/bin/lib/scaffold.js +0 -197
  47. package/bin/lib/status.js +0 -289
  48. package/bin/lib/validateModule.js +0 -697
  49. package/bin/lib/workspace.js +0 -182
  50. package/bin/owd.js +0 -5
  51. package/bin/tui.js +0 -1379
  52. package/dist/module.d.mts +0 -13
  53. package/dist/module.json +0 -9
  54. package/dist/module.mjs +0 -268
  55. package/dist/types.d.mts +0 -7
  56. package/index.ts +0 -5
  57. package/module.ts +0 -223
  58. package/runtime/components/Desktop/Application/DesktopApplicationRender.vue +0 -20
  59. package/runtime/components/Desktop/Application/DesktopApplicationWindowsRender.vue +0 -38
  60. package/runtime/components/Desktop/Background/DesktopBackground.vue +0 -16
  61. package/runtime/components/Desktop/Core/DesktopCore.vue +0 -90
  62. package/runtime/components/Desktop/Time/DesktopTime.vue +0 -56
  63. package/runtime/components/Desktop/Window/DesktopWindow.vue +0 -204
  64. package/runtime/components/Desktop/Window/DesktopWindowContent.vue +0 -28
  65. package/runtime/components/Desktop/Window/DesktopWindowNav.vue +0 -66
  66. package/runtime/composables/useApplicationEntries.ts +0 -51
  67. package/runtime/composables/useApplicationManager.ts +0 -285
  68. package/runtime/composables/useDesktopManager.ts +0 -49
  69. package/runtime/composables/useTerminalManager.ts +0 -66
  70. package/runtime/composables/useWorkspaceManager.ts +0 -41
  71. package/runtime/internal/controllers/ApplicationController.ts +0 -345
  72. package/runtime/internal/controllers/WindowController.ts +0 -462
  73. package/runtime/plugins/02.desktop-register-desktop-apps.client.ts +0 -17
  74. package/runtime/plugins/resize.client.ts +0 -6
  75. package/runtime/stores/storeApplicationMeta.ts +0 -59
  76. package/runtime/stores/storeApplicationWindows.ts +0 -20
  77. package/runtime/stores/storeDesktop.ts +0 -111
  78. package/runtime/stores/storeDesktopDefaultApps.ts +0 -53
  79. package/runtime/stores/storeDesktopVolume.ts +0 -18
  80. package/runtime/stores/storeDesktopWindow.ts +0 -20
  81. package/runtime/stores/storeDesktopWorkspace.ts +0 -75
  82. package/runtime/utils/captureElementToCanvas.ts +0 -21
  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/utilApp.ts +0 -37
  87. package/runtime/utils/utilCommon.ts +0 -26
  88. package/runtime/utils/utilDebug.ts +0 -30
  89. package/runtime/utils/utilDesktop.ts +0 -35
  90. package/runtime/utils/utilTerminal.ts +0 -6
  91. package/runtime/utils/utilWindow.ts +0 -15
  92. package/runtime/utils/validateDesktopUserConfig.ts +0 -44
  93. package/types/index.d.ts +0 -420
@@ -1,197 +0,0 @@
1
- import { execSync, spawnSync } from 'node:child_process'
2
- import {
3
- cpSync,
4
- existsSync,
5
- mkdirSync,
6
- mkdtempSync,
7
- readFileSync,
8
- rmSync,
9
- writeFileSync,
10
- } from 'node:fs'
11
- import { tmpdir } from 'node:os'
12
- import { basename, dirname, join, resolve } from 'node:path'
13
- import { fileURLToPath } from 'node:url'
14
-
15
- const __dirname = dirname(fileURLToPath(import.meta.url))
16
- const CLIENT_TEMPLATE = resolve(__dirname, '../../../../template')
17
- const DEFAULT_CLIENT_REPO = 'https://github.com/owdproject/client.git'
18
-
19
- /**
20
- * @param {string} [startDir]
21
- */
22
- export function resolveLocalTemplatePath(startDir = process.cwd()) {
23
- const fromEnv = process.env.OWD_TEMPLATE_PATH?.trim()
24
- if (fromEnv && existsSync(join(fromEnv, 'package.json'))) {
25
- return resolve(fromEnv)
26
- }
27
-
28
- if (existsSync(join(CLIENT_TEMPLATE, 'package.json'))) {
29
- return CLIENT_TEMPLATE
30
- }
31
-
32
- let dir = startDir
33
- for (;;) {
34
- const candidate = join(dir, 'template')
35
- if (
36
- existsSync(join(candidate, 'package.json')) &&
37
- existsSync(join(dir, 'pnpm-workspace.yaml'))
38
- ) {
39
- return candidate
40
- }
41
- const parent = dirname(dir)
42
- if (parent === dir) break
43
- dir = parent
44
- }
45
-
46
- return null
47
- }
48
-
49
- /**
50
- * @param {string} templatePath
51
- * @param {string} targetDir
52
- */
53
- export function copyTemplate(templatePath, targetDir) {
54
- cpSync(templatePath, targetDir, { recursive: true, filter: (src) => !src.includes('node_modules') })
55
- }
56
-
57
- /**
58
- * @param {string} targetDir
59
- * @param {{ repo?: string, templatePath?: string | null, cwd?: string }} [options]
60
- */
61
- export async function cloneTemplate(targetDir, options = {}) {
62
- const localTemplate = options.templatePath ?? resolveLocalTemplatePath(options.cwd)
63
-
64
- if (localTemplate) {
65
- copyTemplate(localTemplate, targetDir)
66
- return { source: 'local', path: localTemplate }
67
- }
68
-
69
- const repo = options.repo ?? DEFAULT_CLIENT_REPO
70
- const tempParent = mkdtempSync(join(tmpdir(), 'owd-scaffold-'))
71
- const tempClone = join(tempParent, 'client')
72
-
73
- try {
74
- execSync(`git clone --depth 1 ${JSON.stringify(repo)} ${JSON.stringify(tempClone)}`, {
75
- stdio: 'inherit',
76
- })
77
-
78
- const templatePath = join(tempClone, 'template')
79
- if (!existsSync(templatePath)) {
80
- throw new Error('Template directory does not exist in the cloned repository.')
81
- }
82
-
83
- copyTemplate(templatePath, targetDir)
84
- return { source: 'git', path: repo }
85
- } finally {
86
- try {
87
- rmSync(tempParent, { recursive: true, force: true })
88
- } catch {
89
- /* ignore */
90
- }
91
- }
92
- }
93
-
94
- /**
95
- * @param {string} targetDir
96
- */
97
- export function runPostScaffold(targetDir) {
98
- execSync('pnpm install', { cwd: targetDir, stdio: 'inherit' })
99
- }
100
-
101
- export function canLaunchUi() {
102
- return Boolean(process.stdout.isTTY) && !process.env.CI
103
- }
104
-
105
- /**
106
- * @param {string} targetDir
107
- * @param {string} [commandName]
108
- */
109
- export function launchControlPanel(targetDir, commandName = 'desktop') {
110
- const relDir = basename(targetDir)
111
-
112
- if (!canLaunchUi()) {
113
- console.log(`\nNext: cd ${relDir} && pnpm desktop\n`)
114
- return false
115
- }
116
-
117
- console.log('\nOpening control panel…\n')
118
- const result = spawnSync('pnpm', ['exec', commandName], {
119
- cwd: targetDir,
120
- stdio: 'inherit',
121
- shell: false,
122
- })
123
-
124
- if (result.status !== 0 && result.status !== null) {
125
- console.log(`\nControl panel exited. Run again with: cd ${relDir} && pnpm desktop\n`)
126
- }
127
-
128
- return true
129
- }
130
-
131
- /**
132
- * @param {{ dir?: string, cwd?: string, commandName?: string, skipInstall?: boolean, skipUi?: boolean, repo?: string }} [options]
133
- */
134
- export async function scaffoldProject(options = {}) {
135
- const cwd = options.cwd ?? process.cwd()
136
- const dir = (options.dir ?? 'owd-client').trim()
137
- const commandName = options.commandName ?? 'desktop'
138
-
139
- if (!dir) {
140
- throw new Error('Project directory name is required.')
141
- }
142
-
143
- const targetDir = resolve(cwd, dir)
144
-
145
- if (existsSync(targetDir)) {
146
- if (existsSync(join(targetDir, 'package.json'))) {
147
- throw new Error(`Directory "${dir}" already exists and contains a package.json.`)
148
- }
149
- throw new Error(`Directory "${dir}" already exists.`)
150
- }
151
-
152
- mkdirSync(targetDir, { recursive: true })
153
-
154
- console.log(`\nScaffolding Open Web Desktop project in ${dir}/…\n`)
155
- const cloneResult = await cloneTemplate(targetDir, {
156
- repo: options.repo,
157
- cwd,
158
- })
159
-
160
- if (cloneResult.source === 'local') {
161
- console.log(`Using local template: ${cloneResult.path}\n`)
162
- }
163
-
164
- if (!options.skipInstall) {
165
- console.log('Installing dependencies (pnpm install)…\n')
166
- runPostScaffold(targetDir)
167
- }
168
-
169
- console.log('\n✓ Project ready\n')
170
-
171
- if (!options.skipUi) {
172
- const launched = launchControlPanel(targetDir, commandName)
173
- if (launched) {
174
- console.log(`\nLater: cd ${dir} && pnpm run dev · pnpm desktop\n`)
175
- } else {
176
- console.log(` cd ${dir}`)
177
- console.log(' pnpm desktop # control panel ([m] menu, [s] start, [x] stop, [R] reboot)')
178
- console.log(' pnpm run dev # Nuxt dev server\n')
179
- }
180
- } else {
181
- console.log(` cd ${dir}`)
182
- console.log(' pnpm desktop')
183
- console.log(' pnpm run dev\n')
184
- }
185
-
186
- return { targetDir, dir }
187
- }
188
-
189
- /** Copy scaffold.js into create-owd for npm publish (run from repo root). */
190
- export function vendorScaffoldForCreateOwd(createOwdRoot) {
191
- const src = join(__dirname, 'scaffold.js')
192
- const destDir = join(createOwdRoot, 'src/lib')
193
- const dest = join(destDir, 'scaffold.js')
194
- mkdirSync(destDir, { recursive: true })
195
- writeFileSync(dest, readFileSync(src, 'utf8'))
196
- return dest
197
- }
package/bin/lib/status.js DELETED
@@ -1,289 +0,0 @@
1
- import { execSync, spawn } from 'node:child_process'
2
- import {
3
- existsSync,
4
- readFileSync,
5
- mkdirSync,
6
- writeFileSync,
7
- unlinkSync,
8
- appendFileSync,
9
- } from 'node:fs'
10
- import { join } from 'node:path'
11
- import { desktopMetaDir } from './workspace.js'
12
- import {
13
- devSpawnCwd,
14
- devTargetLogLabel,
15
- normalizeDevTarget,
16
- } from './playgroundContext.js'
17
-
18
- function sleep(ms) {
19
- return new Promise((resolve) => setTimeout(resolve, ms))
20
- }
21
-
22
- export function devPidPath(workspaceRoot) {
23
- return join(desktopMetaDir(workspaceRoot), 'dev.pid')
24
- }
25
-
26
- export function devLogPath(workspaceRoot) {
27
- return join(desktopMetaDir(workspaceRoot), 'dev.log')
28
- }
29
-
30
- function readPidFile(workspaceRoot) {
31
- const path = devPidPath(workspaceRoot)
32
- if (!existsSync(path)) return null
33
- const pid = Number.parseInt(readFileSync(path, 'utf8').trim(), 10)
34
- if (!Number.isFinite(pid)) return null
35
- try {
36
- process.kill(pid, 0)
37
- return pid
38
- } catch {
39
- try {
40
- unlinkSync(path)
41
- } catch {
42
- /* ignore */
43
- }
44
- return null
45
- }
46
- }
47
-
48
- export function findDevProcess() {
49
- const patterns = [
50
- 'nuxt dev',
51
- 'nuxi dev',
52
- 'nx run desktop:serve',
53
- 'node.*\\.nuxt',
54
- 'desktop.*nuxt',
55
- ]
56
-
57
- for (const pattern of patterns) {
58
- try {
59
- const out = execSync(`pgrep -af ${JSON.stringify(pattern)}`, {
60
- encoding: 'utf8',
61
- stdio: ['ignore', 'pipe', 'ignore'],
62
- })
63
- for (const line of out.split('\n').filter(Boolean)) {
64
- if (line.includes('pgrep')) continue
65
- const pid = Number.parseInt(line.trim().split(/\s+/)[0], 10)
66
- if (Number.isFinite(pid)) return { pid, cmdline: line.trim() }
67
- }
68
- } catch {
69
- /* try next pattern */
70
- }
71
- }
72
-
73
- return null
74
- }
75
-
76
- export function findProcessOnPort(port) {
77
- try {
78
- const out = execSync(`ss -tlnp 2>/dev/null | grep :${port} || lsof -i :${port} -t 2>/dev/null | head -1`, {
79
- encoding: 'utf8',
80
- stdio: ['ignore', 'pipe', 'ignore'],
81
- })
82
- const pidMatch = out.match(/pid=(\d+)/) ?? out.match(/^(\d+)/m)
83
- if (pidMatch) {
84
- const pid = Number.parseInt(pidMatch[1], 10)
85
- if (Number.isFinite(pid)) return pid
86
- }
87
- } catch {
88
- /* ignore */
89
- }
90
- return null
91
- }
92
-
93
- export function readProcessStats(pid) {
94
- if (!pid || !existsSync(`/proc/${pid}/status`)) {
95
- return { memMb: 0, threads: 0, rssKb: 0 }
96
- }
97
-
98
- try {
99
- const status = readFileSync(`/proc/${pid}/status`, 'utf8')
100
- const vmRss = status.match(/^VmRSS:\s+(\d+)/m)?.[1]
101
- const threads = status.match(/^Threads:\s+(\d+)/m)?.[1]
102
- const rssKb = vmRss ? Number(vmRss) : 0
103
- return {
104
- memMb: rssKb ? Math.round(rssKb / 1024) : 0,
105
- rssKb,
106
- threads: threads ? Number(threads) : 0,
107
- }
108
- } catch {
109
- return { memMb: 0, threads: 0, rssKb: 0 }
110
- }
111
- }
112
-
113
- const SPARK_CHARS = '▁▂▃▄▅▆▇█'
114
-
115
- /** @param {number[]} samples RSS in MiB */
116
- export function formatSparkline(samples) {
117
- if (!samples.length) return '—'
118
- const min = Math.min(...samples)
119
- const max = Math.max(...samples)
120
- const span = max - min || 1
121
- return samples
122
- .map((v) => {
123
- const idx = Math.min(
124
- SPARK_CHARS.length - 1,
125
- Math.floor(((v - min) / span) * (SPARK_CHARS.length - 1)),
126
- )
127
- return SPARK_CHARS[idx]
128
- })
129
- .join('')
130
- }
131
-
132
- /** @param {number} value @param {number} max @param {number} [width] */
133
- export function formatBar(value, max, width = 12) {
134
- if (max <= 0) return '░'.repeat(width)
135
- const filled = Math.round((value / max) * width)
136
- return '█'.repeat(Math.min(width, filled)) + '░'.repeat(Math.max(0, width - filled))
137
- }
138
-
139
- export async function probeDevServer(port) {
140
- const url = `http://127.0.0.1:${port}/`
141
- try {
142
- const controller = new AbortController()
143
- const timer = setTimeout(() => controller.abort(), 1200)
144
- const res = await fetch(url, { signal: controller.signal, redirect: 'manual' })
145
- clearTimeout(timer)
146
- return { up: true, status: res.status, url }
147
- } catch {
148
- return { up: false, status: 0, url }
149
- }
150
- }
151
-
152
- export async function getClientStatus(workspaceRoot, port) {
153
- const http = await probeDevServer(port)
154
- const fromFile = readPidFile(workspaceRoot)
155
- const fromPg = findDevProcess()
156
- const portPid = findProcessOnPort(port)
157
-
158
- const pid = fromPg?.pid ?? portPid ?? fromFile ?? null
159
- const stats = pid ? readProcessStats(pid) : { memMb: 0, threads: 0 }
160
- const running = http.up || Boolean(fromPg) || Boolean(portPid) || Boolean(fromFile)
161
-
162
- return {
163
- running,
164
- pid,
165
- http,
166
- stats,
167
- port,
168
- cmdline: fromPg?.cmdline ?? null,
169
- }
170
- }
171
-
172
- let devChild = null
173
-
174
- /**
175
- * @param {import('./playgroundContext.js').DevTarget | string} target
176
- */
177
- export function startDev(target) {
178
- const resolved = normalizeDevTarget(target)
179
- if (!resolved) {
180
- throw new Error('startDev: missing workspace root')
181
- }
182
-
183
- const { workspaceRoot } = resolved
184
- const spawnCwd = devSpawnCwd(resolved)
185
-
186
- if (devChild?.pid) {
187
- try {
188
- process.kill(devChild.pid, 0)
189
- return devChild
190
- } catch {
191
- devChild = null
192
- }
193
- }
194
-
195
- mkdirSync(desktopMetaDir(workspaceRoot), { recursive: true })
196
- const logPath = devLogPath(workspaceRoot)
197
-
198
- devChild = spawn('pnpm', ['run', 'dev'], {
199
- cwd: spawnCwd,
200
- detached: true,
201
- stdio: ['ignore', 'pipe', 'pipe'],
202
- })
203
-
204
- const appendLog = (chunk) => {
205
- try {
206
- appendFileSync(logPath, chunk)
207
- } catch {
208
- /* ignore */
209
- }
210
- }
211
- try {
212
- appendFileSync(
213
- logPath,
214
- `[owd] dev target: ${devTargetLogLabel(resolved)} (cwd ${spawnCwd})\n`,
215
- )
216
- } catch {
217
- /* ignore */
218
- }
219
- devChild.stdout?.on('data', appendLog)
220
- devChild.stderr?.on('data', appendLog)
221
-
222
- devChild.unref()
223
- writeFileSync(devPidPath(workspaceRoot), String(devChild.pid))
224
- return devChild
225
- }
226
-
227
- export function stopDev(workspaceRoot, pid) {
228
- const targets = new Set([pid, readPidFile(workspaceRoot)].filter(Boolean))
229
-
230
- for (const p of targets) {
231
- try {
232
- process.kill(-p, 'SIGTERM')
233
- } catch {
234
- try {
235
- process.kill(p, 'SIGTERM')
236
- } catch {
237
- /* ignore */
238
- }
239
- }
240
- }
241
-
242
- try {
243
- unlinkSync(devPidPath(workspaceRoot))
244
- } catch {
245
- /* ignore */
246
- }
247
-
248
- devChild = null
249
- return targets.size > 0
250
- }
251
-
252
- export async function waitForDev(workspaceRoot, port, timeoutMs = 90_000) {
253
- const started = Date.now()
254
- while (Date.now() - started < timeoutMs) {
255
- const status = await getClientStatus(workspaceRoot, port)
256
- if (status.http.up) return status
257
- await sleep(1500)
258
- }
259
- return getClientStatus(workspaceRoot, port)
260
- }
261
-
262
- export function runScript(workspaceRoot, script) {
263
- return spawn('pnpm', ['run', script], {
264
- cwd: workspaceRoot,
265
- stdio: 'inherit',
266
- shell: false,
267
- })
268
- }
269
-
270
- /** Run dev in the foreground (`desktop dev`). */
271
- export function runDevForeground(target) {
272
- const resolved = normalizeDevTarget(target)
273
- if (!resolved) {
274
- console.error('Not inside an OWD workspace.')
275
- process.exit(1)
276
- }
277
-
278
- const spawnCwd = devSpawnCwd(resolved)
279
- if (resolved.mode === 'playground' && resolved.packageName) {
280
- console.log(`Starting playground: ${resolved.packageName}`)
281
- }
282
-
283
- const child = spawn('pnpm', ['run', 'dev'], {
284
- cwd: spawnCwd,
285
- stdio: 'inherit',
286
- shell: false,
287
- })
288
- child.on('exit', (code) => process.exit(code ?? 0))
289
- }