@alumbwe/anvil 1.0.38 → 1.0.41

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/bin/anvil.js ADDED
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Anvil CLI launcher — the npm `bin` entry for `anvil`.
4
+ *
5
+ * Runs on plain Node.js (Bun is NOT required upfront) and works from cmd,
6
+ * PowerShell and POSIX shells: npm generates a shim for each shell that all
7
+ * execute this file with `node`.
8
+ *
9
+ * Strategy:
10
+ * 1. Already running under Bun (e.g. `bunx anvil`) → import the TS entry directly.
11
+ * 2. Else locate a Bun executable: local node_modules/.bin, global
12
+ * node_modules/.bin, ~/.bun/bin, /usr/local/bin, Homebrew, then PATH.
13
+ * 3. Else install Bun once via `npm i -g bun`, then retry.
14
+ * 4. Spawn `bun src/entry.ts <args>` with inherited stdio and forward the
15
+ * exit code, so the TUI behaves exactly as when run directly.
16
+ */
17
+
18
+ import { spawnSync } from 'child_process'
19
+ import fs from 'fs'
20
+ import os from 'os'
21
+ import path from 'path'
22
+ import { fileURLToPath, pathToFileURL } from 'url'
23
+
24
+ const HERE = path.dirname(fileURLToPath(import.meta.url))
25
+ const PKG_ROOT = path.resolve(HERE, '..')
26
+ const ENTRY = path.join(PKG_ROOT, 'src', 'entry.ts')
27
+ const IS_WIN = process.platform === 'win32'
28
+ const BUN_EXE = IS_WIN ? 'bun.exe' : 'bun'
29
+
30
+ /** Check that a candidate command is a working bun executable. */
31
+ function isBun(cmd) {
32
+ try {
33
+ const r = spawnSync(cmd, ['--version'], {
34
+ encoding: 'utf8',
35
+ timeout: 15000,
36
+ windowsHide: true,
37
+ })
38
+ return !r.error && r.status === 0
39
+ } catch {
40
+ return false
41
+ }
42
+ }
43
+
44
+ /** Locate a usable bun executable without assuming anything about the machine. */
45
+ function findBun() {
46
+ // Already running under Bun itself
47
+ if (process.versions.bun) return process.execPath
48
+
49
+ const candidates = [
50
+ // Local install: <pkg>/node_modules/.bin/bun
51
+ path.join(PKG_ROOT, 'node_modules', '.bin', BUN_EXE),
52
+ // Hoisted install: <prefix>/node_modules/.bin/bun
53
+ // global: <prefix>/node_modules/@alumbwe/anvil → ../../.bin
54
+ // project: <project>/node_modules/@alumbwe/anvil → ../../.bin
55
+ path.join(PKG_ROOT, '..', '..', '.bin', BUN_EXE),
56
+ // Official bun installer location
57
+ path.join(os.homedir(), '.bun', 'bin', BUN_EXE),
58
+ ]
59
+ if (!IS_WIN) {
60
+ candidates.push('/usr/local/bin/bun', '/opt/homebrew/bin/bun')
61
+ }
62
+
63
+ for (const candidate of candidates) {
64
+ if (fs.existsSync(candidate) && isBun(candidate)) return candidate
65
+ }
66
+
67
+ // Last resort: let the OS resolve `bun` from PATH.
68
+ if (isBun(BUN_EXE)) return BUN_EXE
69
+ return null
70
+ }
71
+
72
+ /** One-time automatic install of Bun through npm (same prefix as this CLI). */
73
+ function installBun() {
74
+ console.error('')
75
+ console.error('Anvil runs on the Bun runtime, which was not found on this machine.')
76
+ console.error('Installing Bun via npm (one-time, this may take a minute)...')
77
+ console.error('')
78
+ const r = spawnSync('npm', ['install', '-g', 'bun'], {
79
+ stdio: 'inherit',
80
+ shell: IS_WIN,
81
+ windowsHide: true,
82
+ })
83
+ return r.status === 0
84
+ }
85
+
86
+ function printManualInstructions() {
87
+ console.error('')
88
+ console.error('Could not install Bun automatically. Install it manually, then re-run anvil:')
89
+ if (IS_WIN) {
90
+ console.error(' powershell -c "irm bun.sh/install.ps1 | iex"')
91
+ } else {
92
+ console.error(' curl -fsSL https://bun.sh/install | bash')
93
+ }
94
+ console.error(' (or) npm i -g bun')
95
+ console.error('')
96
+ }
97
+
98
+ // Under Bun: run the TypeScript entry in-process.
99
+ if (process.versions.bun) {
100
+ await import(pathToFileURL(ENTRY).href)
101
+ } else {
102
+ let bun = findBun()
103
+ if (!bun && installBun()) bun = findBun()
104
+ if (!bun) {
105
+ printManualInstructions()
106
+ process.exit(1)
107
+ }
108
+
109
+ const result = spawnSync(bun, [ENTRY, ...process.argv.slice(2)], {
110
+ stdio: 'inherit',
111
+ env: process.env,
112
+ windowsHide: true,
113
+ })
114
+
115
+ if (result.error) {
116
+ console.error(`Failed to start Anvil via Bun (${bun}):`, result.error.message)
117
+ process.exit(1)
118
+ }
119
+ process.exit(result.status ?? (result.signal ? 1 : 0))
120
+ }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@alumbwe/anvil",
3
- "version": "1.0.38",
3
+ "version": "1.0.41",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
7
- "anvil": "./bin/anvil"
7
+ "anvil": "./bin/anvil.js"
8
8
  },
9
9
  "files": [
10
- "bin/anvil",
10
+ "bin/anvil.js",
11
11
  "bin/tree-sitter.wasm",
12
12
  "src/",
13
13
  "vendor/",