Files
gstack/package.json
T
Garry Tanandcapy-ai[bot] 6c3cf1baac v1.91.242.0 fix(context-bill): bill installed skills whose SKILL.md is a symlink (GSTA-97) (#3423)
* fix(context-bill): follow symlinked SKILL.md files and skill dirs so a real install is billed (GSTA-97)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): walk both links to one directory so the walk never depends on readdir order

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(changelog): describe the loop guard as shipped

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): a root named '..x' no longer lets a parent link climb out

encloses() tested rel.startsWith('..'), which also matches a first
segment such as '..skills', so a link to the parent of a root under such
a name was followed out of the root. Compare the '..' segment exactly.
Adds that case plus a loop to a directory below the walk root, which only
the ancestor guard stops (found by /ship pre-landing review).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): a .md-named link counts only when its target is markdown

walkMd checked only the link's own name, so a link such as notes.md ->
a non-markdown file was walked and, under --exact, its content was sent
to count_tokens. Require the resolved target to end in .md as well.
Adds tests for --exact on the installed layout (every billed file is
measured; nothing behind gstack/ or a .md-named link to another file is
sent) and for a symlinked foreign-host file (found by /ship review).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): walk each real directory once so link fan-out cannot explode

walkMd guarded only the current path, and walked every link to the same
directory, so links that fan out into each other grew the walk
exponentially; under --exact every duplicate path was another
count_tokens POST on the user's key. Expand each real directory and
return each real file once per walk, under the first lexical path
reached with entries sorted. Refuse a walk past 200,000 entries with an
error instead of truncating. --exact sends each real file once and
prices every lexical key that resolves to it from that measurement.
Found by the /ship Step 11 adversarial reviews (Claude and GPT).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): fence walks at the billed root, measure every walked frontmatter, count outside files in the --exact notice

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): a container skill keeps files a nested skill links to

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact names a missing tree before any request

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact sends only files the bill prices

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact refuses every missing tree before sending, and the notice counts what is sent

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): exactSendFiles does not swallow a realpath error

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact walks only what the bill walks, sends nothing for a skill-less tree, and measures only priced frontmatter

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact says when a tree with skills had nothing to send; doc and alias-test fixes

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* test(context-bill): a skill-less tree prints no estimate line under --exact

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): a container skips only nested dirs whose SKILL.md is a file, as discovery does

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): skill discovery refuses a tree past the entry cap too

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): walk directories through their realpaths so a deep link chain cannot drop files

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact reads only the file each walk approved

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact sends only the skills root and the linked gstack checkout; anything else is named and estimated

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (context-bill run-4 cycle 1)

Checkout detection needs a gstack checkout outside the tree; identity taken during the walk and re-checked by realpath; discovery and calibration read through realpaths; refused-dir collapse is linear; all-refused wording; stale comments; tests for each.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (context-bill run-4 cycle 2)

The gstack checkout is recognised by .git, VERSION, setup and a SKILL.md named gstack, so the bin/dev-setup layout counts and other repos do not; walk contract documented on walkMdFiles; tests for the same-file parent move, a gstack-shaped folder without .git, another project repo, and dev-setup.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): a root container skips a nested skill reached through a directory link at any depth

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact refuses a walked file swapped for a FIFO instead of blocking on open

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact resolves a billed path one link at a time, so a shared deep chain keeps its measurements

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): --exact reuses a measurement only for the same realpath, size and mtime it measured

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(context-bill): a bill with any estimated item under --exact is labelled mixed and keeps its error band, in --json and text

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* feat(context-bill): --exact also sends files inside gstack's render folder ($GSTACK_STATE_ROOT/render), judged by realpath

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(changelog): the repo bill keeps its skills, bytes and rounded tokens; raw token floats differ in the last digit

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(context-bill): CHANGELOG and README for the render folder, mixed labels, measurement identity, FIFO refusal and container fixes

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (context-bill run-5 cycle 1)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (context-bill run-5 cycle 2)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (context-bill run-5 cycle 3)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* v1.91.242.0 stamp

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 10:57:52 +00:00

119 lines
5.7 KiB
JSON

{
"name": "gstack",
"version": "1.91.242",
"description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
"license": "MIT",
"type": "module",
"bin": {
"browse": "./browse/dist/browse",
"make-pdf": "./make-pdf/dist/pdf"
},
"scripts": {
"build": "bash scripts/build.sh",
"build:cso": "bash scripts/build-cso.sh",
"format:cso": "prettier --write 'lib/cso/*.ts'",
"format:cso:check": "prettier --check 'lib/cso/*.ts'",
"typecheck": "tsc -p tsconfig.json",
"typecheck:test": "bun run scripts/typecheck-test.ts",
"test:cso:docker": "bun test --max-concurrency 1 test/cso-docker-integration.test.ts test/cso-node-lifecycle-integration.test.ts test/cso-stack-cold-integration.test.ts",
"test:cso:macos": "bun test test/cso-macos-launcher.test.ts test/cso-registry-socket.test.ts",
"test:cso:windows": "bun test test/cso-windows-launcher.test.ts",
"vendor:xterm": "mkdir -p extension/lib && cp node_modules/xterm/lib/xterm.js extension/lib/xterm.js && cp node_modules/xterm/css/xterm.css extension/lib/xterm.css && cp node_modules/xterm-addon-fit/lib/xterm-addon-fit.js extension/lib/xterm-addon-fit.js",
"dev:make-pdf": "bun run make-pdf/src/cli.ts",
"dev:design": "bun run design/src/cli.ts",
"build:diagram-render": "cd lib/diagram-render && bun install && bun run scripts/build.ts",
"build:gates": "bun build --compile make-pdf/src/cli.ts --outfile make-pdf/dist/pdf --no-compile-autoload-dotenv --no-compile-autoload-bunfig && bun build --compile browse/src/cli.ts --outfile browse/dist/browse --no-compile-autoload-dotenv --no-compile-autoload-bunfig && bun run build:diagram-render",
"gen:skill-docs": "bun run scripts/gen-skill-docs.ts",
"gen:skill-docs:user": "bun run scripts/gen-skill-docs.ts --respect-detection",
"audit:manifest": "bun run scripts/prompt-audit-manifest.ts",
"dev": "bun run browse/src/cli.ts",
"server": "bun run browse/src/server.ts",
"test": "bun run scripts/test-free-shards.ts",
"test:free": "bun run scripts/test-free-shards.ts",
"test:windows": "bun run scripts/test-free-shards.ts --windows-only",
"test:ubicloud": "bash scripts/ubicloud/test-free.sh",
"test:evals": "bun run scripts/retired-command.ts test:evals",
"test:evals:all": "bun run scripts/retired-command.ts test:evals:all",
"test:e2e": "bun run scripts/retired-command.ts test:e2e",
"test:e2e:all": "bun run scripts/retired-command.ts test:e2e:all",
"test:gate": "bun run scripts/retired-command.ts test:gate",
"test:periodic": "bun run scripts/retired-command.ts test:periodic",
"test:gate:sharded": "bun run scripts/test-paid-shards.ts --tier gate",
"test:periodic:sharded": "EVALS_ALL=1 bun run scripts/test-paid-shards.ts --tier periodic",
"test:codex": "bun run scripts/retired-command.ts test:codex",
"test:codex:all": "bun run scripts/retired-command.ts test:codex:all",
"skill:check": "bun run scripts/skill-check.ts",
"dev:skill": "bun run scripts/dev-skill.ts",
"start": "bun run browse/src/server.ts",
"eval:bg": "bun run scripts/retired-command.ts eval:bg",
"eval:bg:all": "bun run scripts/retired-command.ts eval:bg:all",
"eval:bg:gate": "bun run scripts/eval-bg.ts gate",
"eval:bg:periodic": "bun run scripts/eval-bg.ts periodic",
"test:health": "bun run scripts/test-health-report.ts",
"test:exercised-map": "bun run scripts/exercised-map.ts",
"eval:list": "bun run scripts/eval-list.ts",
"eval:compare": "bun run scripts/eval-compare.ts",
"eval:summary": "bun run scripts/eval-summary.ts",
"eval:flake-rank": "bun run scripts/retired-command.ts eval:flake-rank",
"eval:pass-rates": "bun run scripts/eval-flake-rank.ts",
"eval:watch": "bun run scripts/retired-command.ts eval:watch",
"eval:select": "bun run scripts/eval-select.ts",
"analytics": "bun run scripts/analytics.ts",
"test:audit": "bun run scripts/retired-command.ts test:audit",
"slop": "npx slop-scan scan . 2>/dev/null || echo 'slop-scan not available (install with: npm i -g slop-scan)'",
"slop:diff": "bun run scripts/slop-diff.ts",
"test:quick": "bun run scripts/test-free-shards.ts --quick",
"test:pr": "EVALS_JOBS=${EVALS_JOBS:-2} bun run scripts/test-paid-shards.ts --tier gate --profile pr",
"test:release": "EVALS_ALL=1 EVALS_FRESH=1 EVALS_CACHE_PURPOSE=release bun run scripts/test-paid-shards.ts --tier gate --profile full && EVALS_ALL=1 EVALS_FRESH=1 EVALS_CACHE_PURPOSE=release bun run scripts/test-paid-shards.ts --tier periodic --profile full",
"eval:bg:pr": "bun run scripts/eval-bg.ts pr",
"eval:bg:release": "bun run scripts/eval-bg.ts release"
},
"dependencies": {
"@anthropic-ai/sdk": "^0.78.0",
"@huggingface/transformers": "^4.3.1",
"@ngrok/ngrok": "^1.7.0",
"cross-spawn": "^7.0.6",
"diff": "^9.0.0",
"html-to-docx": "1.8.0",
"html-to-vdom": "0.7.0",
"marked": "^18.1.1",
"playwright": "^1.62.1",
"sharp": "^0.35.4",
"socks": "^2.8.10",
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
},
"engines": {
"bun": ">=1.4.2"
},
"keywords": [
"browser",
"automation",
"playwright",
"headless",
"cli",
"claude",
"ai-agent",
"devtools"
],
"devDependencies": {
"@anthropic-ai/claude-agent-sdk": "0.2.141",
"@types/bun": "1.4.3",
"prettier": "3.9.10",
"typescript": "7.0.2"
},
"overrides": {
"@modelcontextprotocol/sdk": "1.32.0",
"adm-zip": "^0.6.1",
"fast-uri": "3.1.9",
"hono": "4.13.13",
"image-size": "2.0.4",
"ip-address": "10.7.4",
"proxy-addr": "2.0.8",
"sharp": "0.35.5"
},
"patchedDependencies": {
"playwright-core@1.62.1": "patches/playwright-core@1.62.1.patch"
}
}