@vibecook/ghosttead 0.5.1 → 0.6.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.
package/README.md CHANGED
@@ -32,5 +32,15 @@ supported targets and the `GHOSTTEAD_BIN` way out.
32
32
  ## Bundlers
33
33
 
34
34
  Resolution walks `node_modules` at runtime. An Electron main process that
35
- bundles its dependencies should keep this package external, or resolve the
36
- path at build time and carry it into the bundle.
35
+ bundles its dependencies should keep this package external — the exports map
36
+ carries a `require` condition, so a CommonJS bundle can `require()` it on
37
+ Node 22.12+ — or call `ghostteadPath()` at build time and stage the binary
38
+ beside the bundle, which a packaged application needs to do anyway.
39
+
40
+ The resolver also tolerates being inlined: when the direct walk finds
41
+ nothing — the platform packages are dependencies of this package, and
42
+ pnpm's layout makes them visible only from beside its real directory — it
43
+ locates the installed `@vibecook/ghosttead` from the bundle's own position
44
+ and resolves the platform package from there. When even that fails, the
45
+ error names bundling as the cause instead of a missing package. External
46
+ remains the recommendation; it keeps resolution on Node's own semantics.
package/dist/index.d.ts CHANGED
@@ -9,6 +9,8 @@ export interface ResolveGhostteadOptions {
9
9
  env?: Readonly<Record<string, string | undefined>>;
10
10
  /** Defaults to resolving from this package; injectable so tests reach every failure without a registry. */
11
11
  resolvePackage?: (specifier: string) => string;
12
+ /** Defaults to `import.meta.url`; injectable so tests can stand where a bundler would put this code. */
13
+ resolutionBase?: string | URL;
12
14
  }
13
15
  /**
14
16
  * Absolute path of the daemon for the current platform.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAsBA,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAyD,CAAC;AAEzG,MAAM,WAAW,uBAAuB;IACtC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACnD,2GAA2G;IAC3G,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;CAChD;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,uBAA4B,GAAG,MAAM,CAqC3E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuBA,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAyD,CAAC;AAEzG,MAAM,WAAW,uBAAuB;IACtC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACnD,2GAA2G;IAC3G,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,wGAAwG;IACxG,cAAc,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAC/B;AAsED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,uBAA4B,GAAG,MAAM,CAoC3E"}
package/dist/index.js CHANGED
@@ -5,12 +5,13 @@
5
5
  * carry it everywhere: each supported target ships in its own npm package,
6
6
  * gated by `os`/`cpu`, and installing this package pulls exactly the one
7
7
  * that matches. This module names the installed binary — or says precisely
8
- * which of the three possible reasons it cannot: the platform has no
9
- * prebuild, the optional dependency was pruned, or the platform package is
10
- * present with nothing staged into it, a state that exists only inside the
11
- * Ghosttea repository where these packages are workspace links.
8
+ * which of the four possible reasons it cannot: the platform has no
9
+ * prebuild, a bundler inlined this resolver and severed its view of
10
+ * `node_modules`, the optional dependency was pruned, or the platform
11
+ * package is present with nothing staged into it, a state that exists only
12
+ * inside the Ghosttea repository where these packages are workspace links.
12
13
  */
13
- import { existsSync } from "node:fs";
14
+ import { existsSync, realpathSync } from "node:fs";
14
15
  import { createRequire } from "node:module";
15
16
  import { dirname, join } from "node:path";
16
17
  /** Platform packages keyed by `${platform}-${arch}` — the targets release CI builds and validates. */
@@ -20,7 +21,69 @@ const PLATFORM_PACKAGES = Object.freeze({
20
21
  });
21
22
  /** Targets a prebuilt daemon exists for. */
22
23
  export const SUPPORTED_TARGETS = Object.freeze(Object.keys(PLATFORM_PACKAGES).sort());
23
- const defaultResolvePackage = (specifier) => createRequire(import.meta.url).resolve(specifier);
24
+ function notInstalled(packageName, cause) {
25
+ return new Error(`${packageName} is not installed. It arrives as an optional dependency of @vibecook/ghosttead, so an ` +
26
+ "install that skips optional dependencies loses the daemon; reinstall with them enabled or set GHOSTTEAD_BIN.", { cause });
27
+ }
28
+ function inlinedByBundler(packageName, cause) {
29
+ return new Error(`${packageName} cannot be resolved, and no reachable node_modules contains @vibecook/ghosttead either — ` +
30
+ "the signature of this resolver having been inlined into a bundle, which severs the node_modules walk " +
31
+ "it depends on. Mark @vibecook/ghosttead external in the bundler (see its README) or set GHOSTTEAD_BIN.", { cause });
32
+ }
33
+ /**
34
+ * The platform package's manifest path, resolved the way installs actually
35
+ * lay packages out.
36
+ *
37
+ * The platform packages are dependencies of this package, not of the
38
+ * consumer, and pnpm's strict layout makes them visible only from beside
39
+ * this package's real directory. From the unbundled module that is one
40
+ * resolution — but a bundler that inlines this code moves it into the
41
+ * consumer's output, where the direct walk finds nothing. The consumer does
42
+ * depend on `@vibecook/ghosttead`, so its installed directory is usually
43
+ * still reachable from the bundle; resolving the platform package from that
44
+ * directory's real path restores exactly the walk the unbundled module
45
+ * would have done. The lookup scans `require.resolve.paths()` by hand
46
+ * because this package's `exports` map would otherwise stand between a
47
+ * `require`-based probe and its own `package.json`.
48
+ *
49
+ * A base that cannot see even `@vibecook/ghosttead` is not a layout problem
50
+ * at all, and is reported as what it is: bundling without `external`.
51
+ */
52
+ function resolveInstalledManifest(packageName, base) {
53
+ let requireFromBase;
54
+ try {
55
+ requireFromBase = createRequire(base);
56
+ }
57
+ catch (cause) {
58
+ // A bundler that erased `import.meta.url` outright lands here.
59
+ throw inlinedByBundler(packageName, cause);
60
+ }
61
+ let directFailure;
62
+ try {
63
+ return requireFromBase.resolve(`${packageName}/package.json`);
64
+ }
65
+ catch (error) {
66
+ directFailure = error;
67
+ }
68
+ let selfManifest;
69
+ for (const directory of requireFromBase.resolve.paths("@vibecook/ghosttead") ?? []) {
70
+ const candidate = join(directory, "@vibecook", "ghosttead", "package.json");
71
+ if (existsSync(candidate)) {
72
+ // Follow the package manager's link so the sibling walk starts from
73
+ // the store directory that actually holds the platform packages.
74
+ selfManifest = realpathSync(candidate);
75
+ break;
76
+ }
77
+ }
78
+ if (!selfManifest)
79
+ throw inlinedByBundler(packageName, directFailure);
80
+ try {
81
+ return createRequire(selfManifest).resolve(`${packageName}/package.json`);
82
+ }
83
+ catch (cause) {
84
+ throw notInstalled(packageName, cause);
85
+ }
86
+ }
24
87
  /**
25
88
  * Absolute path of the daemon for the current platform.
26
89
  *
@@ -33,7 +96,6 @@ export function ghostteadPath(options = {}) {
33
96
  const platform = options.platform ?? process.platform;
34
97
  const arch = options.arch ?? process.arch;
35
98
  const env = options.env ?? process.env;
36
- const resolvePackage = options.resolvePackage ?? defaultResolvePackage;
37
99
  const override = env.GHOSTTEAD_BIN;
38
100
  if (override)
39
101
  return override;
@@ -44,12 +106,16 @@ export function ghostteadPath(options = {}) {
44
106
  "Set GHOSTTEAD_BIN to a daemon built from source to run on this platform.");
45
107
  }
46
108
  let manifest;
47
- try {
48
- manifest = resolvePackage(`${packageName}/package.json`);
109
+ if (options.resolvePackage) {
110
+ try {
111
+ manifest = options.resolvePackage(`${packageName}/package.json`);
112
+ }
113
+ catch (cause) {
114
+ throw notInstalled(packageName, cause);
115
+ }
49
116
  }
50
- catch (cause) {
51
- throw new Error(`${packageName} is not installed. It arrives as an optional dependency of @vibecook/ghosttead, so an ` +
52
- "install that skips optional dependencies loses the daemon; reinstall with them enabled or set GHOSTTEAD_BIN.", { cause });
117
+ else {
118
+ manifest = resolveInstalledManifest(packageName, options.resolutionBase ?? import.meta.url);
53
119
  }
54
120
  const binary = join(dirname(manifest), "bin", platform === "win32" ? "ghosttead.exe" : "ghosttead");
55
121
  if (!existsSync(binary)) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,sGAAsG;AACtG,MAAM,iBAAiB,GAAqC,MAAM,CAAC,MAAM,CAAC;IACxE,cAAc,EAAE,kCAAkC;IAClD,WAAW,EAAE,+BAA+B;CAC7C,CAAC,CAAC;AAEH,4CAA4C;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAsB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAazG,MAAM,qBAAqB,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAE/G;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,OAAO,GAA4B,EAAE;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,qBAAqB,CAAC;IAEvE,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC;IACnC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAG,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;IACrC,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,wCAAwC,MAAM,yBAAyB,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;YACxG,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IAED,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,cAAc,CAAC,GAAG,WAAW,eAAe,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,wFAAwF;YACpG,8GAA8G,EAChH,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACpG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,iBAAiB,MAAM,+DAA+D;YAClG,8GAA8G,CACjH,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,sGAAsG;AACtG,MAAM,iBAAiB,GAAqC,MAAM,CAAC,MAAM,CAAC;IACxE,cAAc,EAAE,kCAAkC;IAClD,WAAW,EAAE,+BAA+B;CAC7C,CAAC,CAAC;AAEH,4CAA4C;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAsB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAezG,SAAS,YAAY,CAAC,WAAmB,EAAE,KAAc;IACvD,OAAO,IAAI,KAAK,CACd,GAAG,WAAW,wFAAwF;QACpG,8GAA8G,EAChH,EAAE,KAAK,EAAE,CACV,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,WAAmB,EAAE,KAAc;IAC3D,OAAO,IAAI,KAAK,CACd,GAAG,WAAW,2FAA2F;QACvG,uGAAuG;QACvG,wGAAwG,EAC1G,EAAE,KAAK,EAAE,CACV,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAS,wBAAwB,CAAC,WAAmB,EAAE,IAAkB;IACvE,IAAI,eAAiD,CAAC;IACtD,IAAI,CAAC;QACH,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,+DAA+D;QAC/D,MAAM,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,aAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,OAAO,CAAC,GAAG,WAAW,eAAe,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,aAAa,GAAG,KAAK,CAAC;IACxB,CAAC;IACD,IAAI,YAAgC,CAAC;IACrC,KAAK,MAAM,SAAS,IAAI,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC;QACnF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QAC5E,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,oEAAoE;YACpE,iEAAiE;YACjE,YAAY,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM;QACR,CAAC;IACH,CAAC;IACD,IAAI,CAAC,YAAY;QAAE,MAAM,gBAAgB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,OAAO,aAAa,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,GAAG,WAAW,eAAe,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,OAAO,GAA4B,EAAE;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAEvC,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC;IACnC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAG,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;IACrC,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,wCAAwC,MAAM,yBAAyB,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;YACxG,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IAED,IAAI,QAAgB,CAAC;IACrB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,WAAW,eAAe,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,wBAAwB,CAAC,WAAW,EAAE,OAAO,CAAC,cAAc,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACpG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,iBAAiB,MAAM,+DAA+D;YAClG,8GAA8G,CACjH,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecook/ghosttead",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Prebuilt Ghosttea terminal daemon, resolved to the binary for the current platform.",
5
5
  "license": "MIT",
6
6
  "author": "James Yong",
@@ -11,7 +11,8 @@
11
11
  "exports": {
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
- "import": "./dist/index.js"
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.js"
15
16
  }
16
17
  },
17
18
  "files": [
@@ -47,8 +48,8 @@
47
48
  "prepublishOnly": "npm run build"
48
49
  },
49
50
  "optionalDependencies": {
50
- "@vibecook/ghosttead-darwin-arm64": "0.5.1",
51
- "@vibecook/ghosttead-win32-x64": "0.5.1"
51
+ "@vibecook/ghosttead-darwin-arm64": "0.6.0",
52
+ "@vibecook/ghosttead-win32-x64": "0.6.0"
52
53
  },
53
54
  "devDependencies": {
54
55
  "@types/node": "26.1.1",