Skip to content

Commit f4f7ea2

Browse files
committed
feat(install): install and upgrade from GitHub Releases without npm
- Bundles ship a codegraph-vba launcher next to codegraph, and install.sh links both, so agent MCP configs and Dysflow resolve it without npm. - codegraph-vba install runs the GitHub installer script instead of npm. - The release workflow publishes to npm only when NPM_TOKEN is set, and an npm failure no longer fails the release. - README and CLI hints lead with the GitHub installer. Closes #326
1 parent 719492b commit f4f7ea2

10 files changed

Lines changed: 218 additions & 35 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ name: Release
1010
# native compilation, so cross-packaging is fine),
1111
# 4. creates the GitHub Release (tag v<version>) with all archives, using the
1212
# release notes from CHANGELOG.md,
13-
# 5. publishes the npm thin-installer (shim + per-platform packages).
13+
# 5. publishes the npm thin-installer (shim + per-platform packages) — OPTIONAL.
1414
#
1515
# Before triggering: bump package.json on the default branch, and dispatch this
1616
# workflow from that branch — a guard step rejects anything else, because step 2
1717
# pushes its commit to whichever branch triggered the run. CHANGELOG.md entries
1818
# can live under `## [Unreleased]`; step 2 moves them. Never pre-create a
19-
# `## [<version>]` block. Set the NPM_TOKEN secret.
19+
# `## [<version>]` block.
20+
#
21+
# GitHub Releases is the required channel: install.sh / install.ps1 and
22+
# `codegraph-vba upgrade` only need the release assets. Step 5 runs only when the
23+
# NPM_TOKEN secret is set, and an npm failure never fails the release (#326).
2024
on:
2125
workflow_dispatch: {}
2226

@@ -154,7 +158,25 @@ jobs:
154158
gh release create "$TAG" release/codegraph-vba-* release/SHA256SUMS --title "$TITLE" --notes-file notes.md
155159
fi
156160
161+
- name: Check npm credentials
162+
# Secrets can't be read in `if:`, so expose only whether one is set.
163+
id: npm
164+
env:
165+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
166+
run: |
167+
if [ -n "$NPM_TOKEN" ]; then
168+
echo "enabled=true" >> "$GITHUB_OUTPUT"
169+
else
170+
echo "enabled=false" >> "$GITHUB_OUTPUT"
171+
echo "::warning::NPM_TOKEN is not set — skipping npm publish. The GitHub Release is complete."
172+
fi
173+
157174
- name: Publish to npm
175+
# Optional channel (#326): a dead or revoked token must not turn a
176+
# release red after its GitHub Release already shipped.
177+
id: publish
178+
if: steps.npm.outputs.enabled == 'true'
179+
continue-on-error: true
158180
env:
159181
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
160182
run: |
@@ -178,6 +200,8 @@ jobs:
178200
done < <(find release/npm -name 'package.json' -not -path '*/node_modules/*' -not -path '*/lib/*' -not -path '*/bin/*' -exec dirname {} \; | sort -u)
179201
180202
- name: Verify every package is actually on the registry
203+
if: steps.publish.outcome == 'success'
204+
continue-on-error: true
181205
env:
182206
# Per-package patience. Each per-platform package bundles a Node
183207
# runtime and unpacks to ~200 MB over ~1,000 files, and npm's
@@ -211,6 +235,7 @@ jobs:
211235
done < <(find release/npm -name 'package.json' -not -path '*/node_modules/*' -not -path '*/lib/*' -not -path '*/bin/*' -exec dirname {} \; | sort -u)
212236
213237
- name: Sync packages to npmmirror
238+
if: steps.publish.outcome == 'success'
214239
# npmmirror/cnpm mirror lazily and frequently never pull the per-platform
215240
# optionalDependencies on their own, so `npm i` there fails with
216241
# "no prebuilt bundle" (issue #303). Nudge a sync now so mirror users get

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

1010
## [Unreleased]
1111

12+
### New Features
13+
14+
- CodeGraph-VBA now installs and upgrades entirely from GitHub Releases, with no npm needed: the one-line installers put both `codegraph` and `codegraph-vba` on your PATH, and `codegraph-vba install` sets up the CLI the same way. (#326)
15+
1216

1317
## [2.0.0] - 2026-09-19
1418

‎README.md‎

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ See [fork capabilities and lineage](docs/fork-capabilities.md) for the delivered
5757

5858
**Why fork?** To add VBA / Access language support that does not exist upstream, so agents can navigate Microsoft Access projects managed by Dysflow the same way they navigate TypeScript or Python today. See the [VBA / Access + Dysflow integration](#vba--access--dysflow-integration) section below for the feature spec, the pattern table, and the hard invariants.
5959

60-
**The fork is published to npm as `@aroman22/codegraph-vba`.** The upstream package `@colbymchenry/codegraph` does **not** have VBA / Access support — install `@aroman22/codegraph-vba` to get it:
60+
**The fork ships through [GitHub Releases](https://github.com/ardelperal/codegraph-vba/releases).** The upstream package `@colbymchenry/codegraph` does **not** have VBA / Access support — install this fork to get it:
6161

6262
```bash
63-
# Option A — install from npm (easiest; gets you the codegraph-vba CLI on PATH):
64-
npm i -g @aroman22/codegraph-vba
65-
# or with pnpm:
66-
pnpm add -g codegraph-vba
67-
# or the one-line OS installer (no Node required) — see Get Started below.
63+
# Option A — one-line installer from GitHub Releases (no Node, no npm):
64+
# macOS / Linux
65+
curl -fsSL https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.sh | sh
66+
# Windows (PowerShell)
67+
irm https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.ps1 | iex
6868
```
6969

7070
```bash
@@ -98,17 +98,15 @@ curl -fsSL https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/insta
9898
irm https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.ps1 | iex
9999
```
100100

101-
<details>
102-
<summary><b>Already have Node? Use npm instead (works on any version)</b></summary>
103-
104-
```bash
105-
npm i -g @aroman22/codegraph-vba
106-
```
107-
108101
<sub>CodeGraph bundles its own runtime — nothing to compile, no native build, works the same everywhere. The installer puts `codegraph-vba` on your PATH but **doesn't change your current shell** — open a new terminal before the next step so the command resolves.</sub>
109102

110103
<sub>**Upgrade any time** with `codegraph-vba upgrade` — it detects how you installed (bundle, npm, or npx) and updates in place. Add `--check` to see if an update is available, or `codegraph-vba upgrade <version>` to pin one.</sub>
111104

105+
<details>
106+
<summary><b>npm (legacy)</b></summary>
107+
108+
The npm package `@aroman22/codegraph-vba` is published only on a best-effort basis and can lag behind GitHub Releases. Prefer the installer above; if you already installed through npm, re-run the installer to switch.
109+
112110
</details>
113111

114112
### 2. Wire up your agent(s)
@@ -119,7 +117,7 @@ In a **new terminal**, run the installer to connect CodeGraph to the agents you
119117
codegraph-vba install
120118
```
121119

122-
<sub>Detects and auto-configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, and Kiro — wiring the CodeGraph MCP server into each. **This is the step that connects CodeGraph to your agent;** installing the CLI in step 1 does not do it on its own. It only wires up your agent — it does **not** index any code; building each project's graph is the separate `codegraph-vba init` in step 3. (Shortcut: `npx codegraph-vba` downloads and runs this in one go.)</sub>
120+
<sub>Detects and auto-configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, and Kiro — wiring the CodeGraph MCP server into each. **This is the step that connects CodeGraph to your agent;** installing the CLI in step 1 does not do it on its own. It only wires up your agent — it does **not** index any code; building each project's graph is the separate `codegraph-vba init` in step 3.</sub>
123121

124122
### 3. Initialize each project
125123

@@ -552,8 +550,10 @@ payload as JSON.
552550

553551
### 1. Run the Installer
554552

553+
Install the CLI (see [Get Started](#get-started)), then run:
554+
555555
```bash
556-
npx codegraph-vba
556+
codegraph-vba install
557557
```
558558

559559
The installer will:
@@ -600,9 +600,10 @@ That's it — your agent will use CodeGraph tools automatically when a `.codegra
600600
<details>
601601
<summary><strong>Manual Setup (Alternative)</strong></summary>
602602

603-
**Install globally:**
603+
**Install the CLI:**
604604
```bash
605-
npm i -g @aroman22/codegraph-vba
605+
curl -fsSL https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.sh | sh # macOS / Linux
606+
irm https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.ps1 | iex # Windows
606607
```
607608

608609
**Add to `~/.claude.json`:**
@@ -883,9 +884,9 @@ compile) for all three desktop OSes, on both Intel/AMD (x64) and ARM (arm64):
883884

884885
| Platform | Architectures | Install |
885886
|----------|---------------|---------|
886-
| Windows | x64, arm64 | PowerShell installer or npm |
887-
| macOS | x64, arm64 | shell installer or npm |
888-
| Linux | x64, arm64 | shell installer or npm |
887+
| Windows | x64, arm64 | PowerShell installer |
888+
| macOS | x64, arm64 | shell installer |
889+
| Linux | x64, arm64 | shell installer |
889890

890891
See [Get Started](#get-started) for the one-line install commands.
891892

@@ -972,7 +973,7 @@ Framework routing is validated the same way, on a canonical app per framework: E
972973

973974
**MCP hits `database is locked`** — current builds shouldn't: CodeGraph bundles its own Node runtime and uses Node's built-in `node:sqlite` in WAL mode, where concurrent reads never block on a writer. If you still see it:
974975

975-
- **You're on an old (pre-0.9) install.** Reinstall to get the bundled runtime — `curl -fsSL https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.sh | sh` (macOS/Linux), `irm https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.ps1 | iex` (Windows), or `npm i -g @aroman22/codegraph-vba@latest`.
976+
- **You're on an old (pre-0.9) install.** Reinstall to get the bundled runtime — `curl -fsSL https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.sh | sh` (macOS/Linux), `irm https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.ps1 | iex` (Windows).
976977
- **`codegraph-vba status` shows `Journal:` other than `wal`** — WAL couldn't be enabled on this filesystem (common on network shares and WSL2 `/mnt`), so reads can block on writes. Move the project (with its `.codegraph/` folder) onto a local disk.
977978

978979
**MCP server not connecting** — Your agent starts the server itself, so you don't launch it by hand. Make sure the project is initialized and indexed (`codegraph-vba status`) and that the path in your MCP config is correct. If it still won't connect, re-run `codegraph-vba install` to rewrite the config.

‎__tests__/bundle-launchers.test.ts‎

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* Bundle launcher names (issue #326).
3+
*
4+
* Agent MCP configs and Dysflow launch `codegraph-vba`, so a GitHub-only
5+
* install (no npm) must put that name on PATH next to `codegraph`. These tests
6+
* extract the REAL launcher block from `scripts/build-bundle.sh` and the REAL
7+
* link block from `install.sh` (between their marker comments) and run them
8+
* against temp fixtures — no build, no download.
9+
*
10+
* POSIX only: both blocks are shell, and the install.sh block uses symlinks.
11+
*/
12+
13+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
14+
import { spawnSync } from 'child_process';
15+
import * as fs from 'fs';
16+
import * as os from 'os';
17+
import * as path from 'path';
18+
19+
const ROOT = path.join(__dirname, '..');
20+
21+
function extractBlock(file: string, marker: string): string {
22+
const lines = fs.readFileSync(path.join(ROOT, file), 'utf8').replace(/\r\n/g, '\n').split('\n');
23+
const i = lines.findIndex((l) => l.trim() === `# >>> ${marker}`);
24+
const j = lines.findIndex((l) => l.trim() === `# <<< ${marker}`);
25+
if (i < 0 || j < 0 || j <= i) throw new Error(`${marker} markers not found in ${file}`);
26+
return lines.slice(i + 1, j).join('\n');
27+
}
28+
29+
function shq(s: string): string {
30+
return `'${s.replace(/'/g, `'\\''`)}'`;
31+
}
32+
33+
function run(shell: string, script: string): { code: number; stdout: string; stderr: string } {
34+
const r = spawnSync(shell, ['-c', script], { encoding: 'utf8' });
35+
return { code: r.status ?? -1, stdout: r.stdout ?? '', stderr: r.stderr ?? '' };
36+
}
37+
38+
describe.skipIf(process.platform === 'win32')('bundle launchers (#326)', () => {
39+
let tmp: string;
40+
41+
beforeEach(() => {
42+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'cg-launchers-'));
43+
});
44+
afterEach(() => {
45+
fs.rmSync(tmp, { recursive: true, force: true });
46+
});
47+
48+
function stageBundle(osfam: string): string {
49+
const stage = path.join(tmp, 'stage');
50+
fs.mkdirSync(path.join(stage, 'bin'), { recursive: true });
51+
// Stand-in for the vendored Node: prints the args it was exec'd with.
52+
const fakeNode = path.join(tmp, 'fake-node');
53+
fs.writeFileSync(fakeNode, '#!/bin/sh\necho "node $*"\n', { mode: 0o755 });
54+
const script =
55+
`set -eu\nOSFAM=${shq(osfam)}\nSTAGE=${shq(stage)}\nNODE_BIN=${shq(fakeNode)}\n` +
56+
extractBlock('scripts/build-bundle.sh', 'CODEGRAPH_LAUNCHERS');
57+
const r = run('bash', script);
58+
expect(r.code, r.stderr).toBe(0);
59+
return stage;
60+
}
61+
62+
it('POSIX bundles ship an executable codegraph-vba launcher that runs the CLI', () => {
63+
const stage = stageBundle('linux');
64+
const launcher = path.join(stage, 'bin', 'codegraph-vba');
65+
expect(fs.statSync(launcher).mode & 0o111).not.toBe(0);
66+
67+
const r = spawnSync(launcher, ['--version'], { encoding: 'utf8' });
68+
expect(r.status).toBe(0);
69+
expect(r.stdout).toContain(`${path.join(stage, 'lib/dist/bin/codegraph.js')} --version`);
70+
});
71+
72+
it('Windows bundles ship codegraph-vba.cmd identical to codegraph.cmd', () => {
73+
const stage = stageBundle('win32');
74+
const cmd = fs.readFileSync(path.join(stage, 'bin', 'codegraph.cmd'), 'utf8');
75+
expect(fs.readFileSync(path.join(stage, 'bin', 'codegraph-vba.cmd'), 'utf8')).toBe(cmd);
76+
});
77+
78+
function linkLaunchers(dest: string): { binDir: string; stdout: string } {
79+
const binDir = path.join(tmp, 'bin');
80+
const script =
81+
`set -eu\nBIN_DIR=${shq(binDir)}\ndest=${shq(dest)}\n` +
82+
extractBlock('install.sh', 'CODEGRAPH_LINK_LAUNCHERS');
83+
const r = run('sh', script);
84+
expect(r.code, r.stderr).toBe(0);
85+
return { binDir, stdout: r.stdout };
86+
}
87+
88+
it('install.sh links both launchers onto PATH', () => {
89+
const dest = stageBundle('linux');
90+
const { binDir } = linkLaunchers(dest);
91+
expect(fs.readlinkSync(path.join(binDir, 'codegraph'))).toBe(path.join(dest, 'bin', 'codegraph'));
92+
expect(fs.readlinkSync(path.join(binDir, 'codegraph-vba'))).toBe(path.join(dest, 'bin', 'codegraph-vba'));
93+
});
94+
95+
it('install.sh leaves no dangling codegraph-vba link for an older bundle that lacks it', () => {
96+
const dest = path.join(tmp, 'old-bundle');
97+
fs.mkdirSync(path.join(dest, 'bin'), { recursive: true });
98+
fs.writeFileSync(path.join(dest, 'bin', 'codegraph'), '#!/bin/sh\n', { mode: 0o755 });
99+
const { binDir } = linkLaunchers(dest);
100+
expect(fs.existsSync(path.join(binDir, 'codegraph'))).toBe(true);
101+
expect(fs.existsSync(path.join(binDir, 'codegraph-vba'))).toBe(false);
102+
});
103+
});

‎__tests__/upgrade.test.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import {
2121
readInstalledPackageVersion,
2222
resolveNpmGlobalRoot,
2323
NPM_PACKAGE,
24+
cliInstallCommand,
25+
INSTALL_SH_URL,
26+
INSTALL_PS1_URL,
2427
type InstallMethod,
2528
type UpgradeDeps,
2629
} from '../src/upgrade';
@@ -154,6 +157,18 @@ describe('detectInstallMethod', () => {
154157
});
155158
});
156159

160+
describe('cliInstallCommand (#326)', () => {
161+
it('installs from this repo\'s GitHub installer script, never npm', () => {
162+
expect(cliInstallCommand('win32')).toContain(`irm ${INSTALL_PS1_URL} | iex`);
163+
expect(cliInstallCommand('linux')).toBe(`curl -fsSL ${INSTALL_SH_URL} | sh`);
164+
expect(cliInstallCommand('darwin')).toBe(`curl -fsSL ${INSTALL_SH_URL} | sh`);
165+
for (const platform of ['win32', 'linux', 'darwin'] as const) {
166+
expect(cliInstallCommand(platform)).not.toMatch(/\bnpm\b/);
167+
}
168+
expect(INSTALL_PS1_URL).toBe('https://raw.githubusercontent.com/ardelperal/codegraph-vba/main/install.ps1');
169+
});
170+
});
171+
157172
describe('deriveInstallDir', () => {
158173
it('unix: returns the dir above versions/', () => {
159174
expect(deriveInstallDir('/a/b/.codegraph/versions/v1.2.3', 'unix', () => true)).toBe('/a/b/.codegraph');
@@ -403,6 +418,8 @@ describe('runUpgrade', () => {
403418
const code = await runUpgrade({}, deps);
404419
expect(code).toBe(1);
405420
expect(calls.errors.join('\n')).toMatch(/npm exited/i);
421+
// The way out of a broken npm install is the npm-free installer (#326).
422+
expect(calls.logs.join('\n')).toContain(cliInstallCommand('linux'));
406423
});
407424

408425
it('npx: nothing to upgrade', async () => {

‎install.sh‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ INSTALL_DIR="${CODEGRAPH_INSTALL_DIR:-$HOME/.codegraph}"
2222
BIN_DIR="${CODEGRAPH_BIN_DIR:-$HOME/.local/bin}"
2323

2424
if [ "${1:-}" = "--uninstall" ]; then
25-
rm -f "$BIN_DIR/codegraph"
25+
rm -f "$BIN_DIR/codegraph" "$BIN_DIR/codegraph-vba"
2626
rm -rf "$INSTALL_DIR"
27-
echo "CodeGraph uninstalled (removed $INSTALL_DIR and $BIN_DIR/codegraph)."
27+
echo "CodeGraph uninstalled (removed $INSTALL_DIR, $BIN_DIR/codegraph and $BIN_DIR/codegraph-vba)."
2828
exit 0
2929
fi
3030

@@ -76,13 +76,21 @@ mkdir -p "$dest"
7676
# Archives contain a top-level codegraph-<target>/ dir; strip it.
7777
tar -xzf "$tmp/cg.tar.gz" -C "$dest" --strip-components=1
7878

79-
# 4. Symlink the launcher onto PATH and mark the current version.
79+
# 4. Symlink the launchers onto PATH and mark the current version.
80+
# >>> CODEGRAPH_LINK_LAUNCHERS
8081
mkdir -p "$BIN_DIR"
8182
ln -sf "$dest/bin/codegraph" "$BIN_DIR/codegraph"
83+
echo "Linked $BIN_DIR/codegraph"
84+
# Agent MCP configs and Dysflow launch `codegraph-vba` (issue #326). Bundles
85+
# older than the release that added it only ship `codegraph`.
86+
if [ -f "$dest/bin/codegraph-vba" ]; then
87+
ln -sf "$dest/bin/codegraph-vba" "$BIN_DIR/codegraph-vba"
88+
echo "Linked $BIN_DIR/codegraph-vba"
89+
fi
90+
# <<< CODEGRAPH_LINK_LAUNCHERS
8291
ln -sfn "$dest" "$INSTALL_DIR/current"
8392

8493
echo "Installed to $dest"
85-
echo "Linked $BIN_DIR/codegraph"
8694

8795
# 5. Prune older bundles so they don't pile up across upgrades (issue #1074).
8896
# Each release lives in its own versions/<v> dir (~50 MB with the vendored Node

‎scripts/build-bundle.sh‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,16 @@ rm -f "$STAGE/lib/package-lock.json" "$STAGE/lib/pnpm-lock.yaml"
101101
# it. See issues #293/#298 and src/extraction/wasm-runtime-flags.ts. (The CLI
102102
# also self-relaunches with this flag when launched without it, so non-bundled
103103
# runs are covered too; passing it here avoids that extra spawn.)
104+
#
105+
# Two launcher names, same program: `codegraph` and `codegraph-vba`. Agent MCP
106+
# configs and Dysflow launch `codegraph-vba`, so a GitHub-only install must put
107+
# that name on PATH too (issue #326).
108+
# >>> CODEGRAPH_LAUNCHERS
104109
if [ "$OSFAM" = "win32" ]; then
105110
cp "$NODE_BIN" "$STAGE/node.exe"
106111
printf '@"%%~dp0..\\node.exe" --liftoff-only "%%~dp0..\\lib\\dist\\bin\\codegraph.js" %%*\r\n' \
107112
> "$STAGE/bin/codegraph.cmd"
113+
cp "$STAGE/bin/codegraph.cmd" "$STAGE/bin/codegraph-vba.cmd"
108114
else
109115
cp "$NODE_BIN" "$STAGE/node"
110116
cat > "$STAGE/bin/codegraph" <<'LAUNCH'
@@ -129,7 +135,10 @@ export CODEGRAPH_HOST_PPID
129135
exec "$DIR/node" --liftoff-only "$DIR/lib/dist/bin/codegraph.js" "$@"
130136
LAUNCH
131137
chmod +x "$STAGE/bin/codegraph"
138+
cp "$STAGE/bin/codegraph" "$STAGE/bin/codegraph-vba"
139+
chmod +x "$STAGE/bin/codegraph-vba"
132140
fi
141+
# <<< CODEGRAPH_LAUNCHERS
133142

134143
# 5. Archive (.zip for Windows, .tar.gz otherwise).
135144
mkdir -p "$OUT"

‎src/bin/codegraph.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ async function loadCodeGraph(): Promise<typeof import('../index')> {
5454
console.error(`\x1b[31m${getGlyphs().err}\x1b[0m Failed to load CodeGraph modules.`);
5555
console.error(`\n Node: ${process.version} Platform: ${process.platform} ${process.arch}`);
5656
console.error(`\n Error: ${msg}`);
57-
console.error('\n Try reinstalling with: npm install -g @colbymchenry/codegraph\n');
57+
const { cliInstallCommand } = await import('../upgrade');
58+
console.error(`\n Try reinstalling with: ${cliInstallCommand(process.platform)}\n`);
5859
process.exit(1);
5960
}
6061
}

0 commit comments

Comments
 (0)