mirror of https://github.com/garrytan/gstack.git
Merge 0ceda64562 into a3259400a3
This commit is contained in:
commit
a455a74ad8
|
|
@ -963,9 +963,13 @@ For Paths 1, 2a, 2b, 3, switch — only if `gbrain_on_path=false`:
|
||||||
|
|
||||||
The installer runs D5 detect-first (probes `~/git/gbrain`, `~/gbrain` first),
|
The installer runs D5 detect-first (probes `~/git/gbrain`, `~/gbrain` first),
|
||||||
then D19 PATH-shadow validation (post-link `gbrain --version` must match
|
then D19 PATH-shadow validation (post-link `gbrain --version` must match
|
||||||
install-dir `package.json`). On D19 failure the installer exits 3 with a
|
install-dir `package.json`). On Windows MSYS/Git Bash, the installer uses
|
||||||
clear remediation menu; surface the full output to the user and STOP. Do not
|
`bun install --ignore-scripts` because Bun's Windows shell can fail while
|
||||||
continue the skill — the environment is broken until the user fixes PATH.
|
parsing gbrain's postinstall redirect probe before the graceful fallback runs;
|
||||||
|
`bun link` and the later `gbrain init --pglite` migration step still run. On
|
||||||
|
D19 failure the installer exits 3 with a clear remediation menu; surface the
|
||||||
|
full output to the user and STOP. Do not continue the skill — the environment
|
||||||
|
is broken until the user fixes PATH.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -1295,14 +1299,30 @@ this machine, not just the current workspace. Absolute path avoids PATH
|
||||||
resolution issues when Claude Code spawns `gbrain serve` as a subprocess.
|
resolution issues when Claude Code spawns `gbrain serve` as a subprocess.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
GBRAIN_BIN=$(command -v gbrain)
|
GBRAIN_BIN=$(command -v gbrain || true)
|
||||||
[ -z "$GBRAIN_BIN" ] && GBRAIN_BIN="$HOME/.bun/bin/gbrain"
|
if [ -z "$GBRAIN_BIN" ]; then
|
||||||
|
case "$(uname -s 2>/dev/null || echo unknown)" in
|
||||||
|
MINGW*|MSYS*|CYGWIN*|Windows_NT) GBRAIN_BIN="$HOME/.bun/bin/gbrain.exe" ;;
|
||||||
|
*) GBRAIN_BIN="$HOME/.bun/bin/gbrain" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
claude mcp remove gbrain -s user 2>/dev/null || true
|
claude mcp remove gbrain -s user 2>/dev/null || true
|
||||||
claude mcp remove gbrain 2>/dev/null || true
|
claude mcp remove gbrain 2>/dev/null || true
|
||||||
claude mcp add --scope user gbrain -- "$GBRAIN_BIN" serve
|
claude mcp add --scope user gbrain -- "$GBRAIN_BIN" serve
|
||||||
claude mcp list | grep gbrain # verify: should show "✓ Connected"
|
claude mcp list | grep gbrain # verify: should show "✓ Connected"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On Windows, keep the explicit `.exe` fallback. Claude Code on Windows does
|
||||||
|
not apply PATHEXT when spawning the stored absolute MCP server path, so
|
||||||
|
`C:/Users/<user>/.bun/bin/gbrain` can fail while
|
||||||
|
`C:/Users/<user>/.bun/bin/gbrain.exe` works.
|
||||||
|
|
||||||
|
If `claude mcp list` reports `✗ Failed to connect` for a local PGLite brain
|
||||||
|
while an active Claude Code session can still call `mcp__gbrain__*` tools,
|
||||||
|
treat it as likely single-writer lock contention, not proof registration
|
||||||
|
failed. PGLite allows one writer; `claude mcp list` starts a second probe
|
||||||
|
process that can lose the lock to the already-running MCP server.
|
||||||
|
|
||||||
### Both paths
|
### Both paths
|
||||||
|
|
||||||
If `claude` is not on PATH: emit "MCP registration skipped — this skill is
|
If `claude` is not on PATH: emit "MCP registration skipped — this skill is
|
||||||
|
|
@ -1615,7 +1635,7 @@ Do NOT print the actual token in the curl command — leave the placeholder
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
SLUG="setup-gbrain-smoke-test-$(date +%s)"
|
SLUG="setup-gbrain-smoke-test-$(date +%s)"
|
||||||
echo "Set up on $(date). Smoke test for /setup-gbrain." | gbrain put "$SLUG"
|
gbrain put "$SLUG" --content "Set up on $(date). Smoke test for /setup-gbrain."
|
||||||
gbrain search "smoke test" | grep -i "$SLUG"
|
gbrain search "smoke test" | grep -i "$SLUG"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,9 +209,13 @@ For Paths 1, 2a, 2b, 3, switch — only if `gbrain_on_path=false`:
|
||||||
|
|
||||||
The installer runs D5 detect-first (probes `~/git/gbrain`, `~/gbrain` first),
|
The installer runs D5 detect-first (probes `~/git/gbrain`, `~/gbrain` first),
|
||||||
then D19 PATH-shadow validation (post-link `gbrain --version` must match
|
then D19 PATH-shadow validation (post-link `gbrain --version` must match
|
||||||
install-dir `package.json`). On D19 failure the installer exits 3 with a
|
install-dir `package.json`). On Windows MSYS/Git Bash, the installer uses
|
||||||
clear remediation menu; surface the full output to the user and STOP. Do not
|
`bun install --ignore-scripts` because Bun's Windows shell can fail while
|
||||||
continue the skill — the environment is broken until the user fixes PATH.
|
parsing gbrain's postinstall redirect probe before the graceful fallback runs;
|
||||||
|
`bun link` and the later `gbrain init --pglite` migration step still run. On
|
||||||
|
D19 failure the installer exits 3 with a clear remediation menu; surface the
|
||||||
|
full output to the user and STOP. Do not continue the skill — the environment
|
||||||
|
is broken until the user fixes PATH.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -541,14 +545,30 @@ this machine, not just the current workspace. Absolute path avoids PATH
|
||||||
resolution issues when Claude Code spawns `gbrain serve` as a subprocess.
|
resolution issues when Claude Code spawns `gbrain serve` as a subprocess.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
GBRAIN_BIN=$(command -v gbrain)
|
GBRAIN_BIN=$(command -v gbrain || true)
|
||||||
[ -z "$GBRAIN_BIN" ] && GBRAIN_BIN="$HOME/.bun/bin/gbrain"
|
if [ -z "$GBRAIN_BIN" ]; then
|
||||||
|
case "$(uname -s 2>/dev/null || echo unknown)" in
|
||||||
|
MINGW*|MSYS*|CYGWIN*|Windows_NT) GBRAIN_BIN="$HOME/.bun/bin/gbrain.exe" ;;
|
||||||
|
*) GBRAIN_BIN="$HOME/.bun/bin/gbrain" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
claude mcp remove gbrain -s user 2>/dev/null || true
|
claude mcp remove gbrain -s user 2>/dev/null || true
|
||||||
claude mcp remove gbrain 2>/dev/null || true
|
claude mcp remove gbrain 2>/dev/null || true
|
||||||
claude mcp add --scope user gbrain -- "$GBRAIN_BIN" serve
|
claude mcp add --scope user gbrain -- "$GBRAIN_BIN" serve
|
||||||
claude mcp list | grep gbrain # verify: should show "✓ Connected"
|
claude mcp list | grep gbrain # verify: should show "✓ Connected"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On Windows, keep the explicit `.exe` fallback. Claude Code on Windows does
|
||||||
|
not apply PATHEXT when spawning the stored absolute MCP server path, so
|
||||||
|
`C:/Users/<user>/.bun/bin/gbrain` can fail while
|
||||||
|
`C:/Users/<user>/.bun/bin/gbrain.exe` works.
|
||||||
|
|
||||||
|
If `claude mcp list` reports `✗ Failed to connect` for a local PGLite brain
|
||||||
|
while an active Claude Code session can still call `mcp__gbrain__*` tools,
|
||||||
|
treat it as likely single-writer lock contention, not proof registration
|
||||||
|
failed. PGLite allows one writer; `claude mcp list` starts a second probe
|
||||||
|
process that can lose the lock to the already-running MCP server.
|
||||||
|
|
||||||
### Both paths
|
### Both paths
|
||||||
|
|
||||||
If `claude` is not on PATH: emit "MCP registration skipped — this skill is
|
If `claude` is not on PATH: emit "MCP registration skipped — this skill is
|
||||||
|
|
@ -861,7 +881,7 @@ Do NOT print the actual token in the curl command — leave the placeholder
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
SLUG="setup-gbrain-smoke-test-$(date +%s)"
|
SLUG="setup-gbrain-smoke-test-$(date +%s)"
|
||||||
echo "Set up on $(date). Smoke test for /setup-gbrain." | gbrain put "$SLUG"
|
gbrain put "$SLUG" --content "Set up on $(date). Smoke test for /setup-gbrain."
|
||||||
gbrain search "smoke test" | grep -i "$SLUG"
|
gbrain search "smoke test" | grep -i "$SLUG"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { describe, expect, test } from 'bun:test';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
const ROOT = path.resolve(import.meta.dir, '..');
|
||||||
|
const TMPL = path.join(ROOT, 'setup-gbrain', 'SKILL.md.tmpl');
|
||||||
|
const INSTALL = path.join(ROOT, 'bin', 'gstack-gbrain-install');
|
||||||
|
|
||||||
|
const tmpl = fs.readFileSync(TMPL, 'utf-8');
|
||||||
|
const installer = fs.readFileSync(INSTALL, 'utf-8');
|
||||||
|
|
||||||
|
describe('setup-gbrain Windows MSYS quirks from issue #1271', () => {
|
||||||
|
test('local stdio registration uses gbrain.exe fallback on MSYS/Windows', () => {
|
||||||
|
const localStdio = tmpl.match(/### Paths 1, 2a, 2b, 3 \(Local stdio\)[\s\S]*?### Both paths/)?.[0] ?? '';
|
||||||
|
|
||||||
|
expect(localStdio).toContain('MINGW*|MSYS*|CYGWIN*|Windows_NT');
|
||||||
|
expect(localStdio).toContain('$HOME/.bun/bin/gbrain.exe');
|
||||||
|
expect(localStdio).toContain('GBRAIN_BIN="$HOME/.bun/bin/gbrain.exe"');
|
||||||
|
expect(localStdio).toMatch(/Claude Code on Windows does\s+not apply PATHEXT/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('local stdio registration warns that PGLite lock contention can make claude mcp list look disconnected', () => {
|
||||||
|
const localStdio = tmpl.match(/### Paths 1, 2a, 2b, 3 \(Local stdio\)[\s\S]*?### Both paths/)?.[0] ?? '';
|
||||||
|
|
||||||
|
expect(localStdio).toContain('PGLite');
|
||||||
|
expect(localStdio).toContain('single-writer lock');
|
||||||
|
expect(localStdio).toContain('Failed to connect');
|
||||||
|
expect(localStdio).toContain('mcp__gbrain__');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('local smoke test uses gbrain put --content, never stdin pipe', () => {
|
||||||
|
const smoke = tmpl.match(/### Paths 1, 2a, 2b, 3 \(Local stdio\)[\s\S]*?Confirms the round trip/)?.[0] ?? '';
|
||||||
|
|
||||||
|
expect(smoke).toContain('gbrain put "$SLUG" --content');
|
||||||
|
expect(smoke).not.toContain('| gbrain put "$SLUG"');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('installer documents and preserves the MSYS bun install --ignore-scripts mitigation', () => {
|
||||||
|
expect(installer).toContain('MINGW*|MSYS*|CYGWIN*|Windows_NT');
|
||||||
|
expect(installer).toContain('bun install --silent --ignore-scripts');
|
||||||
|
expect(tmpl).toMatch(/On Windows MSYS\/Git Bash, the installer uses\s+`bun install --ignore-scripts`/);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue