@gjsify/cli 0.51.1 → 0.52.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 (61) hide show
  1. package/dist/cli.gjs.mjs +505 -490
  2. package/lib/cli-app.js +3 -1
  3. package/lib/commands/affected-classify.d.ts +7 -1
  4. package/lib/commands/affected-classify.js +66 -9
  5. package/lib/commands/affected-script-refs.d.ts +20 -0
  6. package/lib/commands/affected-script-refs.js +218 -0
  7. package/lib/commands/affected.js +24 -2
  8. package/lib/commands/flatpak/diff.js +8 -2
  9. package/lib/commands/flatpak/init.js +4 -1
  10. package/lib/commands/flatpak/sources.js +4 -3
  11. package/lib/commands/flatpak/sync-flathub.d.ts +2 -0
  12. package/lib/commands/flatpak/sync-flathub.js +149 -7
  13. package/lib/commands/flatpak/utils.d.ts +10 -0
  14. package/lib/commands/flatpak/utils.js +10 -0
  15. package/lib/commands/index.d.ts +1 -0
  16. package/lib/commands/index.js +1 -0
  17. package/lib/commands/install.js +76 -0
  18. package/lib/commands/link.d.ts +13 -0
  19. package/lib/commands/link.js +243 -0
  20. package/lib/commands/onboard.js +18 -2
  21. package/lib/commands/publish.d.ts +34 -0
  22. package/lib/commands/publish.js +153 -8
  23. package/lib/commands/ship.js +19 -1
  24. package/lib/types/config-data.d.ts +1 -1
  25. package/lib/utils/check-system-deps.d.ts +1 -17
  26. package/lib/utils/check-system-deps.js +10 -68
  27. package/lib/utils/dev-link.d.ts +222 -0
  28. package/lib/utils/dev-link.js +632 -0
  29. package/lib/utils/hang-watchdog.d.ts +95 -0
  30. package/lib/utils/hang-watchdog.js +194 -0
  31. package/lib/utils/install-backend-native.d.ts +14 -0
  32. package/lib/utils/install-backend-native.js +91 -13
  33. package/lib/utils/install-extraneous.d.ts +90 -0
  34. package/lib/utils/install-extraneous.js +120 -0
  35. package/lib/utils/install-tarball-cache.d.ts +37 -9
  36. package/lib/utils/install-tarball-cache.js +59 -14
  37. package/lib/utils/normalize-bundler-options.js +11 -0
  38. package/lib/utils/publish-pins.d.ts +38 -0
  39. package/lib/utils/publish-pins.js +47 -0
  40. package/lib/utils/publish-readback.d.ts +103 -17
  41. package/lib/utils/publish-readback.js +326 -47
  42. package/lib/utils/run-gjs.js +82 -6
  43. package/lib/utils/ship/icns.d.ts +14 -0
  44. package/lib/utils/ship/icns.js +83 -0
  45. package/lib/utils/ship/ico.d.ts +25 -0
  46. package/lib/utils/ship/ico.js +120 -0
  47. package/lib/utils/ship/icons.d.ts +191 -0
  48. package/lib/utils/ship/icons.js +398 -0
  49. package/lib/utils/ship/launcher.js +16 -1
  50. package/lib/utils/ship/layout.d.ts +32 -0
  51. package/lib/utils/ship/layout.js +112 -38
  52. package/lib/utils/ship/msi.d.ts +1 -1
  53. package/lib/utils/ship/msi.js +30 -5
  54. package/lib/utils/ship/pe-launcher.d.ts +18 -0
  55. package/lib/utils/ship/pe-launcher.js +125 -4
  56. package/lib/utils/ship/plan.d.ts +1 -34
  57. package/lib/utils/ship/plan.js +7 -56
  58. package/lib/utils/ship/plist.d.ts +20 -10
  59. package/lib/utils/ship/plist.js +29 -12
  60. package/lib/utils/ship/settings.js +3 -2
  61. package/package.json +20 -20
@@ -2,6 +2,8 @@ import type { LayoutMetadataInput } from './layout.js';
2
2
  /** Where the two files live inside a bundle. Apple's names, not ours. */
3
3
  export declare const BUNDLE_INFO_PLIST = "Contents/Info.plist";
4
4
  export declare const BUNDLE_PKGINFO = "Contents/PkgInfo";
5
+ /** Where `CFBundleIconFile` is resolved: the bundle's resources directory, and nowhere else. */
6
+ export declare const BUNDLE_RESOURCES = "Contents/Resources";
5
7
  /**
6
8
  * Render `Contents/Info.plist`.
7
9
  *
@@ -30,19 +32,12 @@ export declare const BUNDLE_PKGINFO = "Contents/PkgInfo";
30
32
  * release). Emitting `version` twice would throw the distinction away on the one
31
33
  * OS that has a field for it.
32
34
  *
33
- * KEYS DELIBERATELY ABSENT are listed in this module's header. `CFBundleIconFile`
34
- * is the one a reader will reach for first, and it is absent for a reason that
35
- * outlives the key: M2a ships NO icon. `png2icns`, `icnsutil` and `iconutil` are
36
- * all absent from this workstation and from the CI image, so an `.icns` written
37
- * here could only be read back by a reader written here — `selfReading: true`,
38
- * which `flatpak.spec.ts` reds. The unblocker is an independent Linux ICNS reader
39
- * entering the CI image; until one does, the hicolor PNG/SVG the payload already
40
- * carries stays the only icon, unread on macOS.
35
+ * KEYS DELIBERATELY ABSENT are listed in this module's header.
41
36
  *
42
37
  * A TWELFTH KEY, `ATSApplicationFontsPath`, is emitted when the bundle carries
43
38
  * faces, and it is the first one here NOT cited to `refs/` — so the exception is
44
39
  * stated rather than left to be noticed (ADR 0038). The rule this module opens
45
- * with exists against DECORATION: the five absent keys are cosmetic, nothing a
40
+ * with exists against DECORATION: the four absent keys are cosmetic, nothing a
46
41
  * reader here can open contains them, and emitting one would be a guess with no
47
42
  * observable behind it. This key is a MECHANISM, and its citation is Apple's own
48
43
  * *Information Property List Key Reference*, which states the scope in the terms
@@ -51,6 +46,21 @@ export declare const BUNDLE_PKGINFO = "Contents/PkgInfo";
51
46
  * app and not for the system as a whole."* The value is a path relative to
52
47
  * `Contents/Resources`.
53
48
  *
49
+ * A THIRTEENTH, `CFBundleIconFile`, is the same shape of exception and closes the
50
+ * gap the previous version of this comment recorded: M2a shipped NO icon because
51
+ * nothing on Linux could read an `.icns` back. Two things changed. `icns.ts` now
52
+ * writes the container from rasters `icons.ts` renders through librsvg, and the
53
+ * readers were measured rather than assumed: CPython `struct` walks the element
54
+ * table in `verify-app-plist.py` (in CI), Pillow 12.3 opens all ten elements (on
55
+ * the workstation), `icns2png` reads three of ten and is NOT relied on, and
56
+ * `iconutil` on macOS is the reader with authority — a VM run, recorded with the
57
+ * change that lands this key. The citation is the same key reference: *"The name
58
+ * of the bundle's icon file, located in the Resources folder"*, and the
59
+ * measurement that motivates it is the released 0.8.0 bundle of one app on macOS
60
+ * 15.7 with no key, no `.icns` and the generic Finder icon. `CFBundleIconName` is
61
+ * NOT emitted: it names an asset-catalog entry (`Assets.car`), which this tree
62
+ * does not produce, and a name with no catalog is a dangling reference.
63
+ *
54
64
  * It is also the only route there is. Pango on macOS is CoreText-backed, GTK is
55
65
  * not built against fontconfig on that platform, and
56
66
  * `pango_font_map_add_font_file()` answers `G_IO_ERROR_NOT_SUPPORTED` on the
@@ -63,7 +73,7 @@ export declare const BUNDLE_PKGINFO = "Contents/PkgInfo";
63
73
  * Pango's CoreText map then holds the family, is unverified here — which is what
64
74
  * `Layout.fontGap` says out loud rather than letting a green stage imply.
65
75
  */
66
- export declare function renderInfoPlist(input: LayoutMetadataInput, fontsPath?: string): string;
76
+ export declare function renderInfoPlist(input: LayoutMetadataInput, fontsPath?: string, iconFile?: string): string;
67
77
  /**
68
78
  * Render `Contents/PkgInfo`: the package type and the signature, eight bytes, no
69
79
  * newline.
@@ -14,8 +14,10 @@
14
14
  // (`.github/ship-oracle/verify-modes.py`), and it parses the XML form.
15
15
  //
16
16
  // EVERY KEY BELOW IS CITED to a file in `refs/` that a real macOS toolchain
17
- // produced or consumes. Keys that are merely plausible — `CFBundleIconFile`,
18
- // `LSMinimumSystemVersion`, `NSHighResolutionCapable`, `LSApplicationCategoryType`,
17
+ // produced or consumes, or — for the two MECHANISM keys, `ATSApplicationFontsPath`
18
+ // and `CFBundleIconFile` — to Apple's own key reference plus a measurement on a
19
+ // Mac. Keys that are merely plausible — `LSMinimumSystemVersion`,
20
+ // `NSHighResolutionCapable`, `LSApplicationCategoryType`,
19
21
  // `NSHumanReadableCopyright` — are not emitted, because nothing a reader here can
20
22
  // open contains them.
21
23
  //
@@ -32,6 +34,8 @@
32
34
  /** Where the two files live inside a bundle. Apple's names, not ours. */
33
35
  export const BUNDLE_INFO_PLIST = 'Contents/Info.plist';
34
36
  export const BUNDLE_PKGINFO = 'Contents/PkgInfo';
37
+ /** Where `CFBundleIconFile` is resolved: the bundle's resources directory, and nowhere else. */
38
+ export const BUNDLE_RESOURCES = 'Contents/Resources';
35
39
  /**
36
40
  * The four-character bundle type of an application, and the signature that says
37
41
  * "none".
@@ -139,19 +143,12 @@ function arrayEntry(key, values) {
139
143
  * release). Emitting `version` twice would throw the distinction away on the one
140
144
  * OS that has a field for it.
141
145
  *
142
- * KEYS DELIBERATELY ABSENT are listed in this module's header. `CFBundleIconFile`
143
- * is the one a reader will reach for first, and it is absent for a reason that
144
- * outlives the key: M2a ships NO icon. `png2icns`, `icnsutil` and `iconutil` are
145
- * all absent from this workstation and from the CI image, so an `.icns` written
146
- * here could only be read back by a reader written here — `selfReading: true`,
147
- * which `flatpak.spec.ts` reds. The unblocker is an independent Linux ICNS reader
148
- * entering the CI image; until one does, the hicolor PNG/SVG the payload already
149
- * carries stays the only icon, unread on macOS.
146
+ * KEYS DELIBERATELY ABSENT are listed in this module's header.
150
147
  *
151
148
  * A TWELFTH KEY, `ATSApplicationFontsPath`, is emitted when the bundle carries
152
149
  * faces, and it is the first one here NOT cited to `refs/` — so the exception is
153
150
  * stated rather than left to be noticed (ADR 0038). The rule this module opens
154
- * with exists against DECORATION: the five absent keys are cosmetic, nothing a
151
+ * with exists against DECORATION: the four absent keys are cosmetic, nothing a
155
152
  * reader here can open contains them, and emitting one would be a guess with no
156
153
  * observable behind it. This key is a MECHANISM, and its citation is Apple's own
157
154
  * *Information Property List Key Reference*, which states the scope in the terms
@@ -160,6 +157,21 @@ function arrayEntry(key, values) {
160
157
  * app and not for the system as a whole."* The value is a path relative to
161
158
  * `Contents/Resources`.
162
159
  *
160
+ * A THIRTEENTH, `CFBundleIconFile`, is the same shape of exception and closes the
161
+ * gap the previous version of this comment recorded: M2a shipped NO icon because
162
+ * nothing on Linux could read an `.icns` back. Two things changed. `icns.ts` now
163
+ * writes the container from rasters `icons.ts` renders through librsvg, and the
164
+ * readers were measured rather than assumed: CPython `struct` walks the element
165
+ * table in `verify-app-plist.py` (in CI), Pillow 12.3 opens all ten elements (on
166
+ * the workstation), `icns2png` reads three of ten and is NOT relied on, and
167
+ * `iconutil` on macOS is the reader with authority — a VM run, recorded with the
168
+ * change that lands this key. The citation is the same key reference: *"The name
169
+ * of the bundle's icon file, located in the Resources folder"*, and the
170
+ * measurement that motivates it is the released 0.8.0 bundle of one app on macOS
171
+ * 15.7 with no key, no `.icns` and the generic Finder icon. `CFBundleIconName` is
172
+ * NOT emitted: it names an asset-catalog entry (`Assets.car`), which this tree
173
+ * does not produce, and a name with no catalog is a dangling reference.
174
+ *
163
175
  * It is also the only route there is. Pango on macOS is CoreText-backed, GTK is
164
176
  * not built against fontconfig on that platform, and
165
177
  * `pango_font_map_add_font_file()` answers `G_IO_ERROR_NOT_SUPPORTED` on the
@@ -172,7 +184,7 @@ function arrayEntry(key, values) {
172
184
  * Pango's CoreText map then holds the family, is unverified here — which is what
173
185
  * `Layout.fontGap` says out loud rather than letting a green stage imply.
174
186
  */
175
- export function renderInfoPlist(input, fontsPath) {
187
+ export function renderInfoPlist(input, fontsPath, iconFile) {
176
188
  const name = assertPlistText(input.name, 'CFBundleName', 'gjsify.ship.name');
177
189
  const executable = assertPlistText(input.binaryName, 'CFBundleExecutable', 'gjsify.ship.binaryName');
178
190
  const appId = assertPlistText(input.appId, 'CFBundleIdentifier', 'gjsify.ship.appId');
@@ -195,6 +207,11 @@ export function renderInfoPlist(input, fontsPath) {
195
207
  stringEntry('CFBundleDevelopmentRegion', 'en'),
196
208
  stringEntry('CFBundleDisplayName', name),
197
209
  stringEntry('CFBundleExecutable', executable),
210
+ // Between Executable and Identifier is where the alphabet puts it. Absent,
211
+ // not empty, for a bundle that carries no icon (`kind: 'cli'`): an empty
212
+ // name is a file lookup that fails, which macOS answers with the same
213
+ // generic icon and no diagnostic.
214
+ ...(iconFile === undefined ? [] : [stringEntry('CFBundleIconFile', iconFile)]),
198
215
  stringEntry('CFBundleIdentifier', appId),
199
216
  stringEntry('CFBundleInfoDictionaryVersion', '6.0'),
200
217
  stringEntry('CFBundleName', name),
@@ -175,8 +175,9 @@ export function resolveShipSettings(input) {
175
175
  const description = descriptionParagraphs(metadata.description) ?? [summary];
176
176
  const sections = sectionsFor(metadata.categories);
177
177
  if (kind === 'app' && discovered.iconFiles.length === 0) {
178
- warnings.push(`gjsify ship: no icon found — the installed app will show a placeholder in menus and app stores. ` +
179
- 'Point `gjsify.ship.icon` at an SVG (or a directory of sized PNGs).');
178
+ warnings.push(`gjsify ship: no icon found — the installed app will show a placeholder in menus and app stores ` +
179
+ 'on Linux, and the darwin and windows layouts refuse to stage without one. Point ' +
180
+ '`gjsify.ship.icon` at an SVG (or a directory of sized PNGs).');
180
181
  }
181
182
  // Resolved here rather than in the packer, because the packer may run on a
182
183
  // host with no `package.json` at all (ADR 0024 § A2) — and because the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/cli",
3
- "version": "0.51.1",
3
+ "version": "0.52.0",
4
4
  "description": "CLI for Gjsify",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -131,7 +131,7 @@
131
131
  "build:test:node": "node lib/index.js build src/test.mts --app node --outfile dist/test.node.mjs",
132
132
  "test:node": "node dist/test.node.mjs",
133
133
  "test:bun": "bun dist/test.node.mjs",
134
- "test:deno": "deno run -A --no-lock --node-modules-dir=none dist/test.node.mjs",
134
+ "test:deno": "deno run -A --no-lock --node-modules-dir=none --min-dep-age=0 dist/test.node.mjs",
135
135
  "test:cross-runtime": "gjsify run build:test:node && gjsify run test:node && gjsify run test:bun && gjsify run test:deno",
136
136
  "test": "gjsify run build:test:node && gjsify run test:node"
137
137
  },
@@ -142,21 +142,21 @@
142
142
  "cli"
143
143
  ],
144
144
  "dependencies": {
145
- "@gjsify/buffer": "^0.51.1",
146
- "@gjsify/create-app": "^0.51.1",
147
- "@gjsify/node-globals": "^0.51.1",
148
- "@gjsify/node-polyfills": "^0.51.1",
149
- "@gjsify/npm-registry": "^0.51.1",
150
- "@gjsify/resolve-npm": "^0.51.1",
151
- "@gjsify/rolldown-plugin-gjsify": "^0.51.1",
152
- "@gjsify/vite-plugin-blueprint": "^0.51.1",
153
- "@gjsify/rolldown-plugin-pnp": "^0.51.1",
154
- "@gjsify/semver": "^0.51.1",
155
- "@gjsify/tar": "^0.51.1",
156
- "@gjsify/tsc": "^0.51.1",
157
- "@gjsify/utils": "^0.51.1",
158
- "@gjsify/web-polyfills": "^0.51.1",
159
- "@gjsify/workspace": "^0.51.1",
145
+ "@gjsify/buffer": "^0.52.0",
146
+ "@gjsify/create-app": "^0.52.0",
147
+ "@gjsify/node-globals": "^0.52.0",
148
+ "@gjsify/node-polyfills": "^0.52.0",
149
+ "@gjsify/npm-registry": "^0.52.0",
150
+ "@gjsify/resolve-npm": "^0.52.0",
151
+ "@gjsify/rolldown-plugin-gjsify": "^0.52.0",
152
+ "@gjsify/vite-plugin-blueprint": "^0.52.0",
153
+ "@gjsify/rolldown-plugin-pnp": "^0.52.0",
154
+ "@gjsify/semver": "^0.52.0",
155
+ "@gjsify/tar": "^0.52.0",
156
+ "@gjsify/tsc": "^0.52.0",
157
+ "@gjsify/utils": "^0.52.0",
158
+ "@gjsify/web-polyfills": "^0.52.0",
159
+ "@gjsify/workspace": "^0.52.0",
160
160
  "acorn": "^8.17.0",
161
161
  "cosmiconfig": "^9.0.2",
162
162
  "get-tsconfig": "^4.14.0",
@@ -165,13 +165,13 @@
165
165
  "yargs": "^18.0.0"
166
166
  },
167
167
  "devDependencies": {
168
- "@gjsify/unit": "^0.51.1",
168
+ "@gjsify/unit": "^0.52.0",
169
169
  "@types/yargs": "^17.0.35",
170
170
  "typescript": "^6.0.3"
171
171
  },
172
172
  "peerDependencies": {
173
- "@gjsify/oxfmt-native": "^0.51.1",
174
- "@gjsify/rolldown-native": "^0.51.1"
173
+ "@gjsify/oxfmt-native": "^0.52.0",
174
+ "@gjsify/rolldown-native": "^0.52.0"
175
175
  },
176
176
  "peerDependenciesMeta": {
177
177
  "@gjsify/oxfmt-native": {