#1111 · Import Universal v1.0.0

merged cross-platform @dev-ananta  ·  27 files changed  ·  +4,539  −101
Net change
+4,438
Lines added
+4,539
Lines removed
−101
Files touched
27

gstack ships as a Claude Code workflow toolkit, currently macOS-only. This PR is the lift to universal support: Windows, macOS, and Linux, addressing three real blockers identified in CROSS_PLATFORM_ANALYSIS.md: (a) Mach-O-only binaries, (b) 100+ hardcoded ~/.gstack paths, (c) a Bash-only setup script.

The fix lands a new lib/paths.ts + lib/binary-locator.ts as the cross-platform shim, a setup.bat alongside the existing setup, and refactors make-pdf/src/pdftotext.ts to discover its dependency on PATH/Program Files/Snap rather than assuming Homebrew.

nice / correct info / context consider blocker
lib/paths.ts
NEW
+216
@@ cross-platform path utilities @@
17
import * as os from 'os';
18
import * as path from 'path';
19
20
export const IS_WINDOWS = process.platform === 'win32';
21
export const IS_MAC = process.platform === 'darwin';
22
export const IS_LINUX = process.platform === 'linux';
23
27
export function getHomeDir(): string {
28
return os.homedir();
29
}
30
35
export function getConfigDir(): string {
36
return path.join(getHomeDir(), '.gstack');
37
}
38
42
export function getTempDir(): string {
43
return os.tmpdir();
44
}
make-pdf/src/pdftotext.ts
+39 · −38
@@ resolution order — comment block @@
14
* Resolution order for the pdftotext binary:
16
* 2. `which pdftotext` on PATH
17
* 3. standard Homebrew paths on macOS
14
* Resolution order for the pdftotext binary (cross-platform):
16
* 2. Automatic discovery via lib/binary-locator
17
* - Searches: Program Files, Homebrew, /usr/bin, Snap, etc.
18
* - Platform-aware for Windows, macOS, Linux
@@ resolvePdftotext — sync → async @@
46
export function resolvePdftotext(): PdftotextInfo {
48
export async function resolvePdftotext(): Promise<PdftotextInfo> {
49
const envOverride = process.env.PDFTOTEXT_BIN;
50
if (envOverride && isExecutable(envOverride)) {
51
return describeBinary(envOverride);
52
}
52
// env override first (sync check); then platform-aware search
54
const located = await findBinary('pdftotext', { searchPaths: getPdfPlatformPaths() });
setup.bat
NEW
+95
@@ Windows setup — entry point @@
1
@echo off
2
REM gstack setup - Windows batch version
3
REM For Windows users who want to set up gstack without WSL/Git Bash
14
17
set "GSTACK_DIR=%~dp0"
18
set "GSTACK_DIR=%GSTACK_DIR:~0,-1%"
19
21
echo Home: %USERPROFILE%
22
echo gstack: %GSTACK_DIR%
package.json
+2 · −1
@@ build scripts @@
14
"build": "bun build --compile browse/src/cli.ts --outfile browse/dist/browse"
14
"build": "bun run scripts/build-binaries.ts",
15
"build:all": "bun run scripts/build-binaries.ts --all-platforms"

Takeaway

Solid, well-scoped lift. The two pieces that matter — lib/paths.ts as the cross-platform path resolver and lib/binary-locator.ts as the cross-platform binary discoverer — are shims in the good sense: they encapsulate platform divergence behind named functions so the rest of the codebase doesn't have to think about it.

One real blocker: resolvePdftotext went sync → async, which is a breaking change every caller has to absorb. The PR catches the local callers but it's worth grepping templates that ship to user-installed locations before merging.