# Extension points — garrytan/gstack

> Canonical page: https://codevetter.com/unpack/gstack/extension-points

# Extension points — garrytan/gstack

Scanned commit 35dd014c580037d1c009776d8b0584587c1bd42c (2026-09-21). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The repo is built around registries and discovery conventions. New skills are a directory + SKILL.md.tmpl picked up automatically by discoverTemplates; new hosts are a defineHost() config + one line in hosts/index.ts; new template placeholders are a RESOLVERS entry; new browse commands are additions to the READ/WRITE/META sets + COMMAND_DESCRIPTIONS + a dispatch handler; new CDP methods are allowlist entries with justification; new models are an overlay file + ALL_MODEL_NAMES entry; browser-skills and domain-skills are runtime-extensible stores; sections/*.md.tmpl let a big skill lazy-carve content.
- Add a skill: create <name>/SKILL.md.tmpl at repo root — discoverTemplates() scans root + one subdir level automatically; the generator, validator (test/helpers/skill-parser.ts), skill-check dashboard, and catalog budget all pick it up with zero wiring. — [scripts/discover-skills.ts#L9-27](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/scripts/discover-skills.ts#L9-L27) [test/helpers/skill-parser.ts](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/test/helpers/skill-parser.ts) [scripts/skill-check.ts](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/scripts/skill-check.ts)
- Add a host: write hosts/<name>.ts calling defineHost() (defaults derive paths, frontmatter allowlist, resolver suppressions, runtimeRoot symlinks from the name), register it in hosts/index.ts ALL_HOST_CONFIGS + re-exports, gitignore the hostSubdir; parameterized smoke tests cover it automatically — documented step-by-step in docs/ADDING_A_HOST.md. — [docs/ADDING_A_HOST.md#L39-147](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/docs/ADDING_A_HOST.md#L39-L147) [hosts/define-host.ts#L83-160](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/hosts/define-host.ts#L83-L160) [hosts/index.ts#L20-29](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/hosts/index.ts#L20-L29)
- Add a template placeholder: implement a resolver function taking TemplateContext and register it in the RESOLVERS record (scripts/resolvers/index.ts); optional gated entries ({resolve, appliesTo}) restrict a placeholder to named skills as a structural guardrail. — [scripts/resolvers/index.ts#L1-15](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/scripts/resolvers/index.ts#L1-L15) [scripts/resolvers/types.ts](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/scripts/resolvers/types.ts)
- Add a browse command: add the name to READ_COMMANDS/WRITE_COMMANDS/META_COMMANDS plus a COMMAND_DESCRIPTIONS entry in browse/src/commands.ts (load-time validation throws on mismatch), then handle it in read-commands.ts / write-commands.ts / meta-commands.ts; aliases go in COMMAND_ALIASES resolved by canonicalizeCommand(). — [browse/src/commands.ts#L13-51](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/browse/src/commands.ts#L13-L51) [browse/src/commands.ts#L190-218](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/browse/src/commands.ts#L190-L218) [CLAUDE.md](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/CLAUDE.md)
- Add a snapshot flag: extend the SNAPSHOT_FLAGS metadata array in browse/src/snapshot.ts — the {{SNAPSHOT_FLAGS}} resolver renders it into docs from the same source. — [CLAUDE.md](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/CLAUDE.md) [browse/src/snapshot.ts](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/browse/src/snapshot.ts) [ARCHITECTURE.md#L327](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/ARCHITECTURE.md#L327)
- Extend CDP reachability: add a CdpAllowEntry {domain, method, scope, output, justification} to CDP_ALLOWLIST — deny-default means anything not listed 403s, and cdp-allowlist.test.ts lints that every entry has all four fields. — [browse/src/cdp-allowlist.ts#L1-30](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/browse/src/cdp-allowlist.ts#L1-L30)
- Add a model family: drop model-overlays/<family>.md and add the name to ALL_MODEL_NAMES in scripts/models.ts; resolveModel() already maps family variants (gpt-5.4-* → gpt-5.4, claude-* → claude). — [scripts/models.ts#L18-60](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/scripts/models.ts#L18-L60) [model-overlays/gpt-5.6-sol.md](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/model-overlays/gpt-5.6-sol.md)
- Lazy-carve a big skill: put on-demand sections in <skill>/sections/*.md.tmpl with a manifest.json; discoverSectionTemplates renders them with the parent skill's TemplateContext. — [scripts/discover-skills.ts#L29-55](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/scripts/discover-skills.ts#L29-L55) [ship/sections](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/ship/sections) [autoplan/sections/manifest.json](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/autoplan/sections/manifest.json)
- Browser-skills are a runtime plugin store: drop a directory with SKILL.md frontmatter (name/host/triggers/args/trusted) + script.ts into <project>/.gstack/browser-skills/, ~/.gstack/browser-skills/, or the bundled tier — no index file, discovery walks dirs; /skillify generates one from a successful /scrape. — [browse/src/browser-skills.ts#L1-57](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/browse/src/browser-skills.ts#L1-L57)
- Domain-skills let agents persist per-site playbooks through `$B domain-skill save|promote-to-global|...` with a quarantine→active→global trust lifecycle tied to the injection classifier. — [browse/src/commands.ts#L183](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/browse/src/commands.ts#L183) [browse/src/domain-skills.ts](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/browse/src/domain-skills.ts)
- Host lifecycle hooks live under hosts/<host>/hooks/ (e.g. hosts/claude/hooks/: AUQ capture, spawned-session directive, timeline stop, Memorable recall bridge) — the pattern for host-specific behavior that isn't skill content. — [hosts/claude/hooks](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/hosts/claude/hooks) [docs/PROJECT_STRUCTURE.md#L18](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/docs/PROJECT_STRUCTURE.md#L18)
- The Chrome extension is a fixed-surface extension point: new sidebar panes or content scripts plug into extension/ (sidepanel.js, inspector.js, background.js service worker) but must respect the WS auth + token bootstrap contract pinned by BROWSER_INTERNALS. — [extension/manifest.json](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/extension/manifest.json) [extension/sidepanel.js](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/extension/sidepanel.js) [docs/BROWSER_INTERNALS.md#L40-62](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/docs/BROWSER_INTERNALS.md#L40-L62)
- contrib/add-host is a contributor-only skill (/gstack-contrib-add-host) that scaffolds new hosts — an extension point that itself is never installed for users. — [contrib/add-host](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/contrib/add-host) [docs/PROJECT_STRUCTURE.md#L92-93](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/docs/PROJECT_STRUCTURE.md#L92-L93)
- Resolver suppression is a per-host extension dial: hosts opt out of resolver output via suppressedResolvers (CROSS_MODEL_RESOLVERS for outside-provider reviews, GBRAIN_RESOLVERS for brain features), and gen-skill-docs --respect-detection can un-suppress GBRAIN_* when a local gbrain is detected. — [hosts/define-host.ts#L27-43](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/hosts/define-host.ts#L27-L43) [scripts/gen-skill-docs.ts#L27-76](https://github.com/garrytan/gstack/blob/35dd014c580037d1c009776d8b0584587c1bd42c/scripts/gen-skill-docs.ts#L27-L76)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
