craft-native 0.0.91 → 0.0.94

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/dist/index.cjs CHANGED
@@ -218,6 +218,7 @@ __export(exports_src, {
218
218
  createArcSidebar: () => createArcSidebar,
219
219
  createApp: () => createApp,
220
220
  craftUnavailableMessage: () => craftUnavailableMessage,
221
+ craftProcessFailedMessage: () => craftProcessFailedMessage,
221
222
  craftBinaryNotFoundMessage: () => craftBinaryNotFoundMessage,
222
223
  copy: () => copy,
223
224
  components: () => exports_components,
@@ -291,6 +292,7 @@ function resolveCraftBinary(explicit) {
291
292
  }
292
293
  return "craft";
293
294
  }
295
+ var CRAFT_CLI_SPAWN_MARKER = "CRAFT_CLI_SPAWNED_FROM";
294
296
  function craftBinaryNotFoundMessage(triedPath) {
295
297
  return [
296
298
  `Craft native binary not found (tried "${triedPath}").`,
@@ -307,6 +309,11 @@ function craftBinaryNotFoundMessage(triedPath) {
307
309
  ].join(`
308
310
  `);
309
311
  }
312
+ // package.json
313
+ var version = "0.0.94";
314
+
315
+ // src/sdk-version.ts
316
+ var SDK_VERSION = version;
310
317
 
311
318
  // src/package.ts
312
319
  var import_child_process = require("child_process");
@@ -422,13 +429,13 @@ async function packageApp(config) {
422
429
  }
423
430
  async function packageMacOS(config, outDir) {
424
431
  const results = [];
425
- const { name, version, bundleId = `com.myapp.${name.toLowerCase()}` } = config;
432
+ const { name, version: version2, bundleId = `com.myapp.${name.toLowerCase()}` } = config;
426
433
  const opts = config.macos || {};
427
434
  const hardenedRuntime = !opts.appStore;
428
435
  const appBundlePath = import_path.join(outDir, `${name}.app`);
429
436
  const appBundle = createMacOSAppBundle({
430
437
  name,
431
- version,
438
+ version: version2,
432
439
  bundleId,
433
440
  buildNumber: opts.buildNumber,
434
441
  category: opts.category,
@@ -472,7 +479,7 @@ async function packageMacOS(config, outDir) {
472
479
  }
473
480
  results.push({ success: true, platform: "macos", format: "app", outputPath: appBundlePath });
474
481
  if (opts.dmg !== false) {
475
- const outputPath = import_path.join(outDir, `${name}-${version}.dmg`);
482
+ const outputPath = import_path.join(outDir, `${name}-${version2}.dmg`);
476
483
  const dmgResult = await createDMG({ appBundlePath, outputPath, volumeName: name });
477
484
  results.push({
478
485
  success: dmgResult.success,
@@ -485,12 +492,12 @@ async function packageMacOS(config, outDir) {
485
492
  results.push(...await notarizeIfRequested(opts, outputPath, "dmg"));
486
493
  }
487
494
  if (opts.pkg || opts.appStore) {
488
- const outputPath = import_path.join(outDir, `${name}-${version}.pkg`);
495
+ const outputPath = import_path.join(outDir, `${name}-${version2}.pkg`);
489
496
  const pkgResult = await createPKG({
490
497
  appBundlePath,
491
498
  outputPath,
492
499
  identifier: bundleId,
493
- version,
500
+ version: version2,
494
501
  appStore: opts.appStore === true,
495
502
  installerIdentity: opts.installerIdentity
496
503
  });
@@ -536,14 +543,14 @@ async function notarizeIfRequested(opts, artifactPath, format) {
536
543
  }
537
544
  async function packageWindows(config, outDir) {
538
545
  const results = [];
539
- const { name, version } = config;
546
+ const { name, version: version2 } = config;
540
547
  const opts = config.windows || {};
541
548
  if (opts.msi !== false) {
542
549
  const msiResult = await createMSI({
543
550
  name,
544
- version,
551
+ version: version2,
545
552
  binaryPath: config.binaryPath,
546
- outputPath: import_path.join(outDir, `${name}-${version}.msi`),
553
+ outputPath: import_path.join(outDir, `${name}-${version2}.msi`),
547
554
  manufacturer: config.author || "Unknown",
548
555
  architecture: opts.architecture || windowsArchitecture(process.arch),
549
556
  certificatePath: opts.certificatePath,
@@ -560,9 +567,9 @@ async function packageWindows(config, outDir) {
560
567
  if (opts.zip || opts.msi === false) {
561
568
  const zipResult = await createZIP({
562
569
  name,
563
- version,
570
+ version: version2,
564
571
  binaryPath: config.binaryPath,
565
- outputPath: import_path.join(outDir, `${name}-${version}-windows.zip`)
572
+ outputPath: import_path.join(outDir, `${name}-${version2}-windows.zip`)
566
573
  });
567
574
  results.push({
568
575
  success: zipResult.success,
@@ -576,14 +583,14 @@ async function packageWindows(config, outDir) {
576
583
  }
577
584
  async function packageLinux(config, outDir) {
578
585
  const results = [];
579
- const { name, version } = config;
586
+ const { name, version: version2 } = config;
580
587
  const opts = config.linux || {};
581
588
  if (opts.deb !== false) {
582
589
  const debResult = await createDEB({
583
590
  name,
584
- version,
591
+ version: version2,
585
592
  binaryPath: config.binaryPath,
586
- outputPath: import_path.join(outDir, `${name}_${version}_amd64.deb`),
593
+ outputPath: import_path.join(outDir, `${name}_${version2}_amd64.deb`),
587
594
  description: config.description || "",
588
595
  maintainer: config.author || "Unknown",
589
596
  dependencies: opts.debDependencies || ["libgtk-3-0", "libwebkit2gtk-4.1-37"]
@@ -599,9 +606,9 @@ async function packageLinux(config, outDir) {
599
606
  if (opts.rpm) {
600
607
  const rpmResult = await createRPM({
601
608
  name,
602
- version,
609
+ version: version2,
603
610
  binaryPath: config.binaryPath,
604
- outputPath: import_path.join(outDir, `${name}-${version}-1.x86_64.rpm`),
611
+ outputPath: import_path.join(outDir, `${name}-${version2}-1.x86_64.rpm`),
605
612
  description: config.description || "",
606
613
  requires: opts.rpmDependencies || ["gtk3", "webkit2gtk3"]
607
614
  });
@@ -616,9 +623,9 @@ async function packageLinux(config, outDir) {
616
623
  if (opts.appImage) {
617
624
  const appImageResult = await createAppImage({
618
625
  name,
619
- version,
626
+ version: version2,
620
627
  binaryPath: config.binaryPath,
621
- outputPath: import_path.join(outDir, `${name}-${version}-x86_64.AppImage`),
628
+ outputPath: import_path.join(outDir, `${name}-${version2}-x86_64.AppImage`),
622
629
  iconPath: config.iconPath
623
630
  });
624
631
  results.push({
@@ -2809,7 +2816,7 @@ class SystemTray {
2809
2816
  }
2810
2817
  async setIcon(icon) {
2811
2818
  this._options.icon = icon;
2812
- await this._call("setIcon", icon);
2819
+ await this._call("setIcon", JSON.stringify({ icon }));
2813
2820
  }
2814
2821
  async setTooltip(tooltip) {
2815
2822
  this._options.tooltip = tooltip;
@@ -2823,6 +2830,9 @@ class SystemTray {
2823
2830
  if (!processedItem.id && processedItem.label) {
2824
2831
  processedItem.id = `menu_${index}_${Date.now()}`;
2825
2832
  }
2833
+ if (!processedItem.action && processedItem.id && processedItem.type !== "separator") {
2834
+ processedItem.action = processedItem.id;
2835
+ }
2826
2836
  if (processedItem.submenu) {
2827
2837
  processedItem.submenu = processItems(processedItem.submenu);
2828
2838
  }
@@ -2885,9 +2895,9 @@ class SystemTray {
2885
2895
  return new Promise((resolve, reject) => {
2886
2896
  try {
2887
2897
  window.webkit.messageHandlers.craft.postMessage({
2888
- type: "tray",
2889
- action,
2890
- data: typeof data === "string" ? data : JSON.stringify(data)
2898
+ t: "tray",
2899
+ a: action,
2900
+ d: typeof data === "string" ? data : JSON.stringify(data)
2891
2901
  });
2892
2902
  resolve(undefined);
2893
2903
  } catch (error) {
@@ -4167,8 +4177,8 @@ var crypto = {
4167
4177
  if (combined.length < 1 + SALT_LEN + IV_LEN + TAG_LEN) {
4168
4178
  throw new CraftCryptoError("Ciphertext too short to be valid");
4169
4179
  }
4170
- const version = combined[0];
4171
- if (version !== FORMAT_VERSION) {
4180
+ const version2 = combined[0];
4181
+ if (version2 !== FORMAT_VERSION) {
4172
4182
  throw new LegacyCiphertextError;
4173
4183
  }
4174
4184
  const salt = combined.slice(1, 1 + SALT_LEN);
@@ -5089,11 +5099,18 @@ var share = {
5089
5099
  return craft.share.share(options);
5090
5100
  }
5091
5101
  if (navigator.share) {
5092
- await navigator.share({
5093
- title: options.title,
5094
- text: options.text,
5095
- url: options.url
5096
- });
5102
+ try {
5103
+ await navigator.share({
5104
+ title: options.title,
5105
+ text: options.text,
5106
+ url: options.url
5107
+ });
5108
+ return true;
5109
+ } catch (error) {
5110
+ if (error instanceof DOMException && error.name === "AbortError")
5111
+ return false;
5112
+ throw error;
5113
+ }
5097
5114
  } else {
5098
5115
  throw new Error("Share API not available");
5099
5116
  }
@@ -5126,6 +5143,13 @@ var lifecycle = {
5126
5143
  return () => document.removeEventListener("visibilitychange", handler);
5127
5144
  }
5128
5145
  };
5146
+ function bridgeNotification(options, now = Date.now()) {
5147
+ const { scheduleAt, ...rest } = options;
5148
+ if (scheduleAt === undefined)
5149
+ return rest;
5150
+ const wait = Math.ceil(scheduleAt - now);
5151
+ return wait > 0 ? { ...rest, delay: wait } : rest;
5152
+ }
5129
5153
  var notifications = {
5130
5154
  async show(options) {
5131
5155
  const craft = getCraftMobile();
@@ -5139,7 +5163,7 @@ var notifications = {
5139
5163
  async schedule(options) {
5140
5164
  const craft = getCraftMobile();
5141
5165
  if (typeof window !== "undefined" && craft?.notifications) {
5142
- return craft.notifications.schedule(options);
5166
+ return craft.notifications.schedule(bridgeNotification(options));
5143
5167
  }
5144
5168
  throw new Error("Scheduled notifications not available in web");
5145
5169
  },
@@ -10815,14 +10839,14 @@ async function updaterCommand(args) {
10815
10839
  switch (subcommand) {
10816
10840
  case "check": {
10817
10841
  const url = rest[0];
10818
- const version = rest[1] || "0.0.0";
10842
+ const version2 = rest[1] || "0.0.0";
10819
10843
  if (!url) {
10820
10844
  console.error("Usage: craft updater check <update-url> [current-version]");
10821
10845
  process.exit(1);
10822
10846
  }
10823
10847
  const updater = new AutoUpdater({
10824
10848
  updateUrl: url,
10825
- currentVersion: version,
10849
+ currentVersion: version2,
10826
10850
  appPath: process.cwd(),
10827
10851
  autoDownload: false
10828
10852
  });
@@ -10856,14 +10880,14 @@ ${update.releaseNotes}`);
10856
10880
  break;
10857
10881
  }
10858
10882
  case "generate-manifest": {
10859
- const version = rest[0];
10883
+ const version2 = rest[0];
10860
10884
  const outputPath = rest[1] || "update.json";
10861
- if (!version) {
10885
+ if (!version2) {
10862
10886
  console.error("Usage: craft updater generate-manifest <version> [output]");
10863
10887
  process.exit(1);
10864
10888
  }
10865
10889
  const manifest = {
10866
- version,
10890
+ version: version2,
10867
10891
  releaseDate: new Date().toISOString(),
10868
10892
  platforms: {}
10869
10893
  };
@@ -10895,21 +10919,13 @@ var updater_default = AutoUpdater;
10895
10919
  // src/index.ts
10896
10920
  var execFileAsync2 = import_node_util.promisify(import_node_child_process.execFile);
10897
10921
  var versionMismatchWarned = false;
10898
- function getSdkVersion() {
10899
- try {
10900
- const pkgPath = import_node_path.join("/home/runner/work/craft/craft/packages/typescript/src", "..", "package.json");
10901
- return JSON.parse(import_node_fs2.readFileSync(pkgPath, "utf-8")).version ?? "unknown";
10902
- } catch {
10903
- return "unknown";
10904
- }
10905
- }
10906
10922
  async function probeBinaryVersion(craftPath) {
10907
10923
  if (versionMismatchWarned)
10908
10924
  return;
10909
10925
  try {
10910
10926
  const { stdout } = await execFileAsync2(craftPath, ["--version"], { timeout: 2000 });
10911
10927
  const nativeVersion = parseCraftVersionOutput(stdout);
10912
- const sdkVersion = getSdkVersion();
10928
+ const sdkVersion = SDK_VERSION;
10913
10929
  if (sdkVersion !== "unknown" && nativeVersion && nativeVersion !== sdkVersion) {
10914
10930
  versionMismatchWarned = true;
10915
10931
  console.warn(`⚠️ Craft binary/SDK version mismatch: SDK=${sdkVersion}, native=${nativeVersion}.
@@ -10919,7 +10935,27 @@ async function probeBinaryVersion(craftPath) {
10919
10935
  }
10920
10936
  function parseCraftVersionOutput(output) {
10921
10937
  const firstLine = output.trim().split(/\r?\n/, 1)[0] ?? "";
10922
- return firstLine.replace(/^craft version\s+/i, "").replace(/^v/, "").trim();
10938
+ const withoutName = firstLine.replace(/^craft(?:\s+version)?[\s/]+/i, "").trim();
10939
+ const firstToken = withoutName.split(/\s+/, 1)[0] ?? "";
10940
+ return firstToken.replace(/^v/, "").trim();
10941
+ }
10942
+ var STDERR_TAIL_LIMIT = 4000;
10943
+ function craftProcessFailedMessage(code, stderr, quiet) {
10944
+ const said = stderr.trim();
10945
+ const header = `❌ Craft process exited with code ${code}`;
10946
+ if (said)
10947
+ return `${header}
10948
+
10949
+ ${said}`;
10950
+ const where = quiet ? "It wrote nothing to stderr. Re-run without `quiet` to see its full output." : "Check the console output above for more details.";
10951
+ return `${header}
10952
+
10953
+ ` + `This may indicate:
10954
+ ` + ` • Invalid window configuration
10955
+ ` + ` • Malformed HTML content
10956
+ ` + ` • System resource constraints
10957
+
10958
+ ` + where;
10923
10959
  }
10924
10960
  function detectDevMode() {
10925
10961
  if (typeof process === "undefined")
@@ -10982,8 +11018,14 @@ class CraftApp {
10982
11018
  const args = this.buildArgs();
10983
11019
  const craftPath = await this.findCraftBinary();
10984
11020
  probeBinaryVersion(craftPath);
11021
+ const quiet = this.config.quiet === true;
10985
11022
  this.process = import_node_child_process.spawn(craftPath, args, {
10986
- stdio: this.config.quiet ? "ignore" : "inherit"
11023
+ stdio: quiet ? ["ignore", "ignore", "pipe"] : "inherit",
11024
+ env: { ...process.env, [CRAFT_CLI_SPAWN_MARKER]: craftPath }
11025
+ });
11026
+ let stderrTail = "";
11027
+ this.process.stderr?.on("data", (chunk) => {
11028
+ stderrTail = (stderrTail + chunk.toString()).slice(-STDERR_TAIL_LIMIT);
10987
11029
  });
10988
11030
  return new Promise((resolve, reject) => {
10989
11031
  this.process?.on("error", (error) => {
@@ -11003,18 +11045,11 @@ class CraftApp {
11003
11045
  ` + `For troubleshooting, visit:
11004
11046
  ` + " https://github.com/home-lang/craft/issues"));
11005
11047
  });
11006
- this.process?.on("exit", (code) => {
11048
+ this.process?.on("close", (code) => {
11007
11049
  if (code === 0 || code === null) {
11008
11050
  resolve();
11009
11051
  } else {
11010
- reject(new Error(`❌ Craft process exited with code ${code}
11011
-
11012
- ` + `This may indicate:
11013
- ` + ` • Invalid window configuration
11014
- ` + ` • Malformed HTML content
11015
- ` + ` • System resource constraints
11016
-
11017
- ` + "Check the console output above for more details."));
11052
+ reject(new Error(craftProcessFailedMessage(code, stderrTail, quiet)));
11018
11053
  }
11019
11054
  });
11020
11055
  });
package/dist/index.d.cts CHANGED
@@ -3,7 +3,27 @@
3
3
  * TypeScript SDK powered by Bun
4
4
  */
5
5
  import type { AppConfig, WindowOptions } from './types.js';
6
+ /**
7
+ * The version a `craft --version` first line reports, whichever form it takes:
8
+ * `craft version 0.0.92`, `craft/0.0.92 darwin-arm64 bun-v1.4.1`,
9
+ * `craft 0.0.92`, `v0.0.92`, or a bare `0.0.92`.
10
+ *
11
+ * The slash form is the CLI's own, and used to survive the strip intact, so
12
+ * the whole line was compared against a semver and never matched — two
13
+ * identical versions reported as drift, on the one path where the real fault
14
+ * was that PATH had resolved to the CLI at all (#236).
15
+ */
6
16
  export declare function parseCraftVersionOutput(output: string): string;
17
+ /**
18
+ * The rejection for a child that exited non-zero.
19
+ *
20
+ * Whatever the child managed to say comes first, because it is the only part
21
+ * that can name the actual fault. `quiet` used to map to `stdio: 'ignore'`,
22
+ * which threw that away and then told the caller to read output that no
23
+ * longer existed — leaving `exited with code 1` as the whole of the error
24
+ * (#236).
25
+ */
26
+ export declare function craftProcessFailedMessage(code: number | null, stderr: string, quiet: boolean): string;
7
27
  export { packageApp, pack, type PackageConfig, type PackageResult } from './package.js';
8
28
  export { craftBinaryNotFoundMessage, resolveCraftBinary } from './binary-resolver.js';
9
29
  export * from './utils/index.js';
package/dist/index.d.ts CHANGED
@@ -3,7 +3,27 @@
3
3
  * TypeScript SDK powered by Bun
4
4
  */
5
5
  import type { AppConfig, WindowOptions } from './types.js';
6
+ /**
7
+ * The version a `craft --version` first line reports, whichever form it takes:
8
+ * `craft version 0.0.92`, `craft/0.0.92 darwin-arm64 bun-v1.4.1`,
9
+ * `craft 0.0.92`, `v0.0.92`, or a bare `0.0.92`.
10
+ *
11
+ * The slash form is the CLI's own, and used to survive the strip intact, so
12
+ * the whole line was compared against a semver and never matched — two
13
+ * identical versions reported as drift, on the one path where the real fault
14
+ * was that PATH had resolved to the CLI at all (#236).
15
+ */
6
16
  export declare function parseCraftVersionOutput(output: string): string;
17
+ /**
18
+ * The rejection for a child that exited non-zero.
19
+ *
20
+ * Whatever the child managed to say comes first, because it is the only part
21
+ * that can name the actual fault. `quiet` used to map to `stdio: 'ignore'`,
22
+ * which threw that away and then told the caller to read output that no
23
+ * longer existed — leaving `exited with code 1` as the whole of the error
24
+ * (#236).
25
+ */
26
+ export declare function craftProcessFailedMessage(code: number | null, stderr: string, quiet: boolean): string;
7
27
  export { packageApp, pack, type PackageConfig, type PackageResult } from './package.js';
8
28
  export { craftBinaryNotFoundMessage, resolveCraftBinary } from './binary-resolver.js';
9
29
  export * from './utils/index.js';