@puredesktop/create-app 2.1.8 → 2.1.9

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.
@@ -18,13 +18,13 @@ Options:
18
18
  --name <title> Display name (default: derived from dir)
19
19
  --slug <slug> App slug for settings/bridge (default: dir name)
20
20
  --port <number> Dev server port in plugin.json (default: 5300)
21
- --manifest-json-base64 <base64>
22
- Structured plugin.json manifest draft for app-builder use
23
- --agents-md-base64 <base64>
24
- Structured agents.md content for app-builder use
25
-
26
- Examples:
27
- npm create @puredesktop/app@latest my-tool
21
+ --manifest-json-file <path>
22
+ Read structured plugin.json manifest draft from a file
23
+ --agents-md-file <path>
24
+ Read structured agents.md content from a file
25
+
26
+ Examples:
27
+ npm create @puredesktop/app@latest my-tool
28
28
  npm create @puredesktop/app@latest my-tool -- --name "My Tool" --slug mytool --port 5310
29
29
  `)
30
30
  }
@@ -32,12 +32,12 @@ Examples:
32
32
  function parseArgs(argv) {
33
33
  const positional = []
34
34
  const options = {
35
- name: '',
36
- slug: '',
37
- port: 5300,
38
- manifestJsonBase64: '',
39
- agentsMdBase64: '',
40
- }
35
+ name: '',
36
+ slug: '',
37
+ port: 5300,
38
+ manifestJsonFile: '',
39
+ agentsMdFile: '',
40
+ }
41
41
 
42
42
  for (let i = 0; i < argv.length; i += 1) {
43
43
  const arg = argv[i]
@@ -57,14 +57,14 @@ function parseArgs(argv) {
57
57
  options.port = Number(argv[++i])
58
58
  continue
59
59
  }
60
- if (arg === '--manifest-json-base64') {
61
- options.manifestJsonBase64 = argv[++i] ?? ''
62
- continue
63
- }
64
- if (arg === '--agents-md-base64') {
65
- options.agentsMdBase64 = argv[++i] ?? ''
66
- continue
67
- }
60
+ if (arg === '--manifest-json-file') {
61
+ options.manifestJsonFile = argv[++i] ?? ''
62
+ continue
63
+ }
64
+ if (arg === '--agents-md-file') {
65
+ options.agentsMdFile = argv[++i] ?? ''
66
+ continue
67
+ }
68
68
  if (arg.startsWith('-')) {
69
69
  console.error(`Unknown option: ${arg}`)
70
70
  usage()
@@ -97,36 +97,27 @@ function titleCaseFromSlug(slug) {
97
97
  .join(' ')
98
98
  }
99
99
 
100
- function decodeBase64Utf8(value, label) {
101
- if (!isBase64(value)) {
102
- console.error(`${label} must be valid base64`)
103
- process.exit(1)
104
- }
105
- try {
106
- return Buffer.from(value, 'base64').toString('utf8')
107
- } catch (error) {
108
- console.error(`${label} must be valid base64: ${errorMessage(error)}`)
109
- process.exit(1)
110
- }
111
- }
112
-
113
- function readStructuredManifest(value, port) {
114
- const text = decodeBase64Utf8(value, '--manifest-json-base64')
115
- let manifest
116
- try {
117
- manifest = JSON.parse(text)
118
- } catch (error) {
119
- console.error(`--manifest-json-base64 must decode to JSON: ${errorMessage(error)}`)
120
- process.exit(1)
121
- }
122
- return normalizeStructuredManifest(manifest, port)
123
- }
124
-
125
- function normalizeStructuredManifest(manifest, port) {
126
- if (!isPlainObject(manifest)) {
127
- console.error('--manifest-json-base64 must decode to a manifest object')
128
- process.exit(1)
129
- }
100
+ function readStructuredManifestFile(path, port) {
101
+ const text = readUtf8File(path, '--manifest-json-file')
102
+ return readStructuredManifestText(text, port, '--manifest-json-file')
103
+ }
104
+
105
+ function readStructuredManifestText(text, port, label) {
106
+ let manifest
107
+ try {
108
+ manifest = JSON.parse(text)
109
+ } catch (error) {
110
+ console.error(`${label} must contain JSON: ${errorMessage(error)}`)
111
+ process.exit(1)
112
+ }
113
+ return normalizeStructuredManifest(manifest, port, label)
114
+ }
115
+
116
+ function normalizeStructuredManifest(manifest, port, label) {
117
+ if (!isPlainObject(manifest)) {
118
+ console.error(`${label} must contain a manifest object`)
119
+ process.exit(1)
120
+ }
130
121
  if (manifest.schemaVersion !== 1) {
131
122
  console.error('manifest.schemaVersion must be 1')
132
123
  process.exit(1)
@@ -161,14 +152,31 @@ function normalizeStructuredManifest(manifest, port) {
161
152
  })
162
153
  }
163
154
 
164
- function readStructuredAgentsMd(value) {
165
- const text = decodeBase64Utf8(value, '--agents-md-base64')
166
- if (!text.trim()) {
167
- console.error('--agents-md-base64 must decode to non-empty agents.md content')
168
- process.exit(1)
169
- }
170
- return text.endsWith('\n') ? text : `${text}\n`
171
- }
155
+ function readStructuredAgentsMdFile(path) {
156
+ const text = readUtf8File(path, '--agents-md-file')
157
+ return readStructuredAgentsMdText(text, '--agents-md-file')
158
+ }
159
+
160
+ function readStructuredAgentsMdText(text, label) {
161
+ if (!text.trim()) {
162
+ console.error(`${label} must contain non-empty agents.md content`)
163
+ process.exit(1)
164
+ }
165
+ return text.endsWith('\n') ? text : `${text}\n`
166
+ }
167
+
168
+ function readUtf8File(path, label) {
169
+ if (typeof path !== 'string' || !path.trim()) {
170
+ console.error(`${label} requires a file path`)
171
+ process.exit(1)
172
+ }
173
+ try {
174
+ return readFileSync(resolve(path), 'utf8')
175
+ } catch (error) {
176
+ console.error(`${label} could not be read: ${errorMessage(error)}`)
177
+ process.exit(1)
178
+ }
179
+ }
172
180
 
173
181
  function requiredString(value, label) {
174
182
  const text = typeof value === 'string' ? value.trim() : ''
@@ -183,15 +191,7 @@ function isPlainObject(value) {
183
191
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
184
192
  }
185
193
 
186
- function isBase64(value) {
187
- if (typeof value !== 'string' || !value.trim()) return false
188
- const normalized = value.trim()
189
- if (!/^[A-Za-z0-9+/]+={0,2}$/u.test(normalized)) return false
190
- if (normalized.length % 4 !== 0) return false
191
- return Buffer.from(normalized, 'base64').toString('base64') === normalized
192
- }
193
-
194
- function stripUndefinedProperties(value) {
194
+ function stripUndefinedProperties(value) {
195
195
  return Object.fromEntries(
196
196
  Object.entries(value).filter(([, entry]) => entry !== undefined),
197
197
  )
@@ -321,24 +321,24 @@ function copyTemplate(srcDir, destDir, vars) {
321
321
  }
322
322
  }
323
323
 
324
- const { targetDir, options } = parseArgs(process.argv.slice(2))
325
- const structuredManifest = options.manifestJsonBase64
326
- ? readStructuredManifest(options.manifestJsonBase64, options.port)
327
- : null
328
- const structuredAgentsMd = options.agentsMdBase64
329
- ? readStructuredAgentsMd(options.agentsMdBase64)
330
- : null
324
+ const { targetDir, options } = parseArgs(process.argv.slice(2))
325
+ const structuredManifest = options.manifestJsonFile
326
+ ? readStructuredManifestFile(options.manifestJsonFile, options.port)
327
+ : null
328
+ const structuredAgentsMd = options.agentsMdFile
329
+ ? readStructuredAgentsMdFile(options.agentsMdFile)
330
+ : null
331
331
  const dirName = targetDir
332
- const structuredSlug = structuredManifest?.app.slug ?? ''
333
- const structuredTitle = structuredManifest?.app.name ?? ''
334
- if (structuredManifest && options.slug && options.slug !== structuredSlug) {
335
- console.error('--slug must match manifest.app.slug when --manifest-json-base64 is used')
336
- process.exit(1)
337
- }
338
- if (structuredManifest && options.name && options.name !== structuredTitle) {
339
- console.error('--name must match manifest.app.name when --manifest-json-base64 is used')
340
- process.exit(1)
341
- }
332
+ const structuredSlug = structuredManifest?.app.slug ?? ''
333
+ const structuredTitle = structuredManifest?.app.name ?? ''
334
+ if (structuredManifest && options.slug && options.slug !== structuredSlug) {
335
+ console.error('--slug must match manifest.app.slug when a structured manifest is used')
336
+ process.exit(1)
337
+ }
338
+ if (structuredManifest && options.name && options.name !== structuredTitle) {
339
+ console.error('--name must match manifest.app.name when a structured manifest is used')
340
+ process.exit(1)
341
+ }
342
342
  const slug = structuredSlug || options.slug || slugify(dirName) || 'my-app'
343
343
  const title = structuredTitle || options.name || titleCaseFromSlug(slug) || 'My App'
344
344
  const pluginId = structuredManifest?.id ?? slug
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@puredesktop/create-app",
3
- "version": "2.1.8",
3
+ "version": "2.1.9",
4
4
  "description": "Scaffold a PureDesktop plugin app (Vite + bridge SDK)",
5
5
  "type": "module",
6
6
  "bin": {