@vibecook/ghosttead 0.5.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 James Yong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # @vibecook/ghosttead
2
+
3
+ The prebuilt Ghosttea terminal daemon. Installing this package pulls the
4
+ binary for the current platform through an `os`/`cpu`-gated optional
5
+ dependency, and `ghostteadPath()` names it:
6
+
7
+ ```ts
8
+ import { spawn } from "node:child_process";
9
+ import { ghostteadPath } from "@vibecook/ghosttead";
10
+
11
+ const daemon = spawn(ghostteadPath(), { env: daemonEnvironment });
12
+ ```
13
+
14
+ The daemon is configured entirely through its environment
15
+ (`GHOSTTEA_CONTROL_SOCKET`, `GHOSTTEA_FRAME_SOCKET`, `GHOSTTEA_AUTH_TOKEN`);
16
+ the one argument it understands is `--version`. The binary's version is the
17
+ package's version — both come from the same release tag.
18
+
19
+ ## Resolution order
20
+
21
+ 1. `GHOSTTEAD_BIN`, when set. This is the same override every consumer of the
22
+ daemon already honors, and pointing it at a locally built
23
+ `target/release/ghosttead` is how development against an unreleased daemon
24
+ works — including on platforms with no prebuild.
25
+ 2. The platform package for `${process.platform}-${process.arch}`:
26
+ `@vibecook/ghosttead-darwin-arm64` or `@vibecook/ghosttead-win32-x64`.
27
+
28
+ Prebuilds exist exactly for the targets Ghosttea's release gate builds and
29
+ validates. On any other platform `ghostteadPath()` throws an error naming the
30
+ supported targets and the `GHOSTTEAD_BIN` way out.
31
+
32
+ ## Bundlers
33
+
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.
@@ -0,0 +1,22 @@
1
+ /** Targets a prebuilt daemon exists for. */
2
+ export declare const SUPPORTED_TARGETS: readonly string[];
3
+ export interface ResolveGhostteadOptions {
4
+ /** Defaults to `process.platform`. */
5
+ platform?: string;
6
+ /** Defaults to `process.arch`. */
7
+ arch?: string;
8
+ /** Defaults to `process.env`; `GHOSTTEAD_BIN` overrides resolution entirely. */
9
+ env?: Readonly<Record<string, string | undefined>>;
10
+ /** Defaults to resolving from this package; injectable so tests reach every failure without a registry. */
11
+ resolvePackage?: (specifier: string) => string;
12
+ }
13
+ /**
14
+ * Absolute path of the daemon for the current platform.
15
+ *
16
+ * `GHOSTTEAD_BIN` wins when set. It is the same override every consumer of
17
+ * the daemon already honors, and pointing it at a locally built
18
+ * `target/release/ghosttead` is how development against an unreleased daemon
19
+ * works — including on platforms with no prebuild at all.
20
+ */
21
+ export declare function ghostteadPath(options?: ResolveGhostteadOptions): string;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
package/dist/index.js ADDED
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Resolution for the prebuilt `ghosttead` daemon binary.
3
+ *
4
+ * The daemon is a Rust executable, not JavaScript, so one package cannot
5
+ * carry it everywhere: each supported target ships in its own npm package,
6
+ * gated by `os`/`cpu`, and installing this package pulls exactly the one
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.
12
+ */
13
+ import { existsSync } from "node:fs";
14
+ import { createRequire } from "node:module";
15
+ import { dirname, join } from "node:path";
16
+ /** Platform packages keyed by `${platform}-${arch}` — the targets release CI builds and validates. */
17
+ const PLATFORM_PACKAGES = Object.freeze({
18
+ "darwin-arm64": "@vibecook/ghosttead-darwin-arm64",
19
+ "win32-x64": "@vibecook/ghosttead-win32-x64",
20
+ });
21
+ /** Targets a prebuilt daemon exists for. */
22
+ export const SUPPORTED_TARGETS = Object.freeze(Object.keys(PLATFORM_PACKAGES).sort());
23
+ const defaultResolvePackage = (specifier) => createRequire(import.meta.url).resolve(specifier);
24
+ /**
25
+ * Absolute path of the daemon for the current platform.
26
+ *
27
+ * `GHOSTTEAD_BIN` wins when set. It is the same override every consumer of
28
+ * the daemon already honors, and pointing it at a locally built
29
+ * `target/release/ghosttead` is how development against an unreleased daemon
30
+ * works — including on platforms with no prebuild at all.
31
+ */
32
+ export function ghostteadPath(options = {}) {
33
+ const platform = options.platform ?? process.platform;
34
+ const arch = options.arch ?? process.arch;
35
+ const env = options.env ?? process.env;
36
+ const resolvePackage = options.resolvePackage ?? defaultResolvePackage;
37
+ const override = env.GHOSTTEAD_BIN;
38
+ if (override)
39
+ return override;
40
+ const target = `${platform}-${arch}`;
41
+ const packageName = PLATFORM_PACKAGES[target];
42
+ if (!packageName) {
43
+ throw new Error(`ghosttead has no prebuilt binary for ${target}; prebuilds exist for ${SUPPORTED_TARGETS.join(" and ")}. ` +
44
+ "Set GHOSTTEAD_BIN to a daemon built from source to run on this platform.");
45
+ }
46
+ let manifest;
47
+ try {
48
+ manifest = resolvePackage(`${packageName}/package.json`);
49
+ }
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 });
53
+ }
54
+ const binary = join(dirname(manifest), "bin", platform === "win32" ? "ghosttead.exe" : "ghosttead");
55
+ if (!existsSync(binary)) {
56
+ throw new Error(`${packageName} resolved but ${binary} does not exist. Published packages always carry the binary; ` +
57
+ "inside the Ghosttea repository nothing is staged outside the release workflow, so a workspace link has none.");
58
+ }
59
+ return binary;
60
+ }
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@vibecook/ghosttead",
3
+ "version": "0.5.0",
4
+ "description": "Prebuilt Ghosttea terminal daemon, resolved to the binary for the current platform.",
5
+ "license": "MIT",
6
+ "author": "James Yong",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/vibecook-dev/ghosttea.git",
25
+ "directory": "packages/ghosttead"
26
+ },
27
+ "homepage": "https://github.com/vibecook-dev/ghosttea#readme",
28
+ "bugs": {
29
+ "url": "https://github.com/vibecook-dev/ghosttea/issues"
30
+ },
31
+ "keywords": [
32
+ "electron",
33
+ "ghostty",
34
+ "terminal",
35
+ "daemon",
36
+ "pty"
37
+ ],
38
+ "publishConfig": {
39
+ "access": "public",
40
+ "provenance": true
41
+ },
42
+ "scripts": {
43
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
44
+ "build": "npm run clean && tsc -p tsconfig.build.json",
45
+ "check": "tsc --noEmit",
46
+ "test": "vitest run",
47
+ "prepublishOnly": "npm run build"
48
+ },
49
+ "optionalDependencies": {
50
+ "@vibecook/ghosttead-darwin-arm64": "0.5.0",
51
+ "@vibecook/ghosttead-win32-x64": "0.5.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "26.1.1",
55
+ "typescript": "7.0.2",
56
+ "vitest": "4.1.10"
57
+ }
58
+ }