opencode-starterkit 1.0.5 → 1.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-starterkit",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Global baseline + thin project overlay installer for OpenCode.",
@@ -1,5 +1,6 @@
1
1
  import fs from 'node:fs'
2
2
  import path from 'node:path'
3
+ import os from 'node:os'
3
4
  import { spawnSync } from 'node:child_process'
4
5
  import readline from 'node:readline'
5
6
  import {
@@ -75,32 +76,51 @@ function mergeGlobalOpencodeJson() {
75
76
  return { merged: true, globalPath }
76
77
  }
77
78
 
79
+ function runCommandCapture(cmd) {
80
+ return spawnSync('bash', ['-lc', cmd], { encoding: 'utf8' })
81
+ }
82
+
78
83
  function checkBeadsCli() {
79
- const whichResult = spawnSync('bash', ['-lc', 'command -v br'], { encoding: 'utf8' })
80
- const found = whichResult.status === 0 && whichResult.stdout.trim().length > 0
81
- if (!found) {
82
- return { ok: false, path: null, version: null }
84
+ const candidates = [
85
+ 'command -v br',
86
+ `${os.homedir()}/.local/bin/br`,
87
+ `${os.homedir()}/.cargo/bin/br`,
88
+ ]
89
+
90
+ for (const candidate of candidates) {
91
+ const whichResult = candidate.startsWith('command -v')
92
+ ? runCommandCapture(candidate)
93
+ : { status: fs.existsSync(candidate) ? 0 : 1, stdout: candidate }
94
+
95
+ const found = whichResult.status === 0 && String(whichResult.stdout || '').trim().length > 0
96
+ if (!found) continue
97
+
98
+ const resolvedPath = String(whichResult.stdout || '').trim()
99
+ const versionResult = runCommandCapture(`"${resolvedPath}" --version || "${resolvedPath}" version`)
100
+ const version = `${versionResult.stdout || ''}${versionResult.stderr || ''}`.trim() || null
101
+ return { ok: true, path: resolvedPath, version }
83
102
  }
84
- const versionResult = spawnSync('bash', ['-lc', 'br --version || br version'], { encoding: 'utf8' })
85
- const version = `${versionResult.stdout || ''}${versionResult.stderr || ''}`.trim() || null
86
- return { ok: true, path: whichResult.stdout.trim(), version }
103
+
104
+ return { ok: false, path: null, version: null }
87
105
  }
88
106
 
89
- function getSuggestedBeadsInstall() {
107
+ function detectPlatformArch() {
90
108
  const platform = process.platform
91
- const primary = 'curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/beads_rust/main/install.sh | bash'
92
- const fallback = 'cargo install beads-rs'
109
+ const arch = process.arch
110
+
111
+ if (platform === 'darwin' && arch === 'arm64') return { osLabel: 'macOS Apple Silicon', platform, arch }
112
+ if (platform === 'darwin' && (arch === 'x64' || arch === 'amd64')) return { osLabel: 'macOS Intel', platform, arch }
113
+ if (platform === 'linux' && (arch === 'x64' || arch === 'amd64')) return { osLabel: 'Linux x64', platform, arch }
114
+ if (platform === 'linux' && arch === 'arm64') return { osLabel: 'Linux arm64', platform, arch }
115
+ if (platform === 'win32') return { osLabel: `Windows ${arch}`, platform, arch }
116
+ return { osLabel: `${platform} ${arch}`, platform, arch }
117
+ }
93
118
 
94
- if (platform === 'darwin') {
95
- return { osLabel: 'macOS', primary, fallback }
96
- }
97
- if (platform === 'linux') {
98
- return { osLabel: 'Linux', primary, fallback }
99
- }
100
- if (platform === 'win32') {
101
- return { osLabel: 'Windows', primary: 'Use WSL and run: ' + primary, fallback: 'Use a supported Rust/cargo install path inside WSL' }
102
- }
103
- return { osLabel: platform, primary, fallback }
119
+ function getInstallPlan() {
120
+ const detected = detectPlatformArch()
121
+ const primary = 'curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/beads_rust/main/install.sh | bash'
122
+ const fallback = 'curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/beads_rust/main/install.sh | bash -s -- --from-source'
123
+ return { ...detected, primary, fallback }
104
124
  }
105
125
 
106
126
  async function askYesNo(question) {
@@ -118,6 +138,13 @@ function runShellCommand(command) {
118
138
  return spawnSync('bash', ['-lc', command], { stdio: 'inherit', encoding: 'utf8' })
119
139
  }
120
140
 
141
+ function ensureBrOnPathHints(brPath) {
142
+ const dir = path.dirname(brPath)
143
+ if (process.env.PATH && process.env.PATH.split(':').includes(dir)) return
144
+ process.env.PATH = `${dir}:${process.env.PATH || ''}`
145
+ console.warn(`[opencode-starterkit] Added ${dir} to current process PATH for verification.`)
146
+ }
147
+
121
148
  async function ensureBeadsCliInteractive() {
122
149
  const check = checkBeadsCli()
123
150
  if (check.ok) {
@@ -126,14 +153,14 @@ async function ensureBeadsCliInteractive() {
126
153
  return
127
154
  }
128
155
 
129
- const install = getSuggestedBeadsInstall()
156
+ const install = getInstallPlan()
130
157
  console.warn('[opencode-starterkit] beads CLI (br) is required by the baseline but was not found.')
131
- console.warn(`[opencode-starterkit] Detected OS: ${install.osLabel}`)
132
- console.warn(`[opencode-starterkit] Recommended install command:\n ${install.primary}`)
133
- console.warn(`[opencode-starterkit] Fallback command:\n ${install.fallback}`)
158
+ console.warn(`[opencode-starterkit] Detected platform: ${install.osLabel}`)
159
+ console.warn(`[opencode-starterkit] Primary install command:\n ${install.primary}`)
160
+ console.warn(`[opencode-starterkit] Fallback install command:\n ${install.fallback}`)
134
161
 
135
162
  if (!process.stdin.isTTY) {
136
- throw new Error('Missing beads CLI (br). Non-interactive mode cannot auto-install; run the suggested install command and retry.')
163
+ throw new Error(`Missing beads CLI (br). Non-interactive mode cannot auto-install. Try: ${install.primary}`)
137
164
  }
138
165
 
139
166
  const approved = await askYesNo('Install beads CLI now? [y/N] ')
@@ -141,18 +168,29 @@ async function ensureBeadsCliInteractive() {
141
168
  throw new Error('User declined beads CLI installation. Beads-based workflows will not function until br is installed.')
142
169
  }
143
170
 
144
- const result = runShellCommand(install.primary)
145
- if (result.status !== 0) {
146
- throw new Error(`Automatic beads install failed. Try manually: ${install.primary}`)
171
+ console.log('[opencode-starterkit] Running primary beads install...')
172
+ let result = runShellCommand(install.primary)
173
+ let verify = checkBeadsCli()
174
+ if (!verify.ok) {
175
+ console.warn(`[opencode-starterkit] Primary install did not yield br. Exit code=${result.status}. Trying fallback...`)
176
+ result = runShellCommand(install.fallback)
177
+ verify = checkBeadsCli()
147
178
  }
148
179
 
149
- const verify = checkBeadsCli()
150
180
  if (!verify.ok) {
151
- throw new Error('beads install command completed but br is still not available on PATH.')
181
+ throw new Error(
182
+ `Automatic beads install failed. Tried:\n1) ${install.primary}\n2) ${install.fallback}\nPlease install br manually and retry.`
183
+ )
184
+ }
185
+
186
+ ensureBrOnPathHints(verify.path)
187
+ const finalCheck = checkBeadsCli()
188
+ if (!finalCheck.ok) {
189
+ throw new Error(`beads install appears to have succeeded, but br is still not executable from PATH candidates. Found path=${verify.path}`)
152
190
  }
153
191
 
154
- console.log(`[opencode-starterkit] beads CLI installed: ${verify.path}`)
155
- if (verify.version) console.log(`[opencode-starterkit] beads CLI version: ${verify.version}`)
192
+ console.log(`[opencode-starterkit] beads CLI installed: ${finalCheck.path}`)
193
+ if (finalCheck.version) console.log(`[opencode-starterkit] beads CLI version: ${finalCheck.version}`)
156
194
  }
157
195
 
158
196
  export async function installGlobal({ cwd }) {