Files
gstack/scripts/resolvers/make-pdf.ts
T
garrytan c050f18371 C1: every env-var host fence resolves its own gstack root
Codex and the other env-var hosts run each block in a fresh shell, so
GSTACK_ROOT/BIN, B and D set by the preamble were empty in later blocks
(/bin/gstack-slug, B=/browse). scripts/resolvers/runtime-root.ts now owns
root resolution: a valid exported GSTACK_ROOT (bin/ and lib/), else the
per-install literal root (no git call), else repo-local, else the global root
(CODEX_HOME on Codex); no root prints the setup fix line and exits. One
post-render pass inserts it (<=400 bytes) into every fence that uses these
variables without assigning them; B/D come from the same helper as BROWSE
and DESIGN SETUP. Claude output is byte-identical.

Migrated pins of the old preamble lines (gen-skill-docs.test.ts) and a
fixture whose exported GSTACK_ROOT lacked lib/ (skill-positional-literals).
2026-10-03 20:59:44 +00:00

53 lines
2.5 KiB
TypeScript

import { type TemplateContext, toShellPath } from './types';
/**
* {{MAKE_PDF_SETUP}} — emits the shell preamble that resolves $P to the
* make-pdf binary. Mirrors generateDesignSetup.
*
* $P = make-pdf/dist/pdf.
*
* Resolution order:
* 1. Local skill root: $_ROOT/{localSkillRoot}/make-pdf/dist/pdf
* 2. Global: ~/{globalRoot}/make-pdf/dist/pdf
* 3. Env override (MAKE_PDF_BIN) — for contributor dev builds
*/
export function generateMakePdfSetup(ctx: TemplateContext): string {
return `## MAKE-PDF SETUP (run this check BEFORE any make-pdf command)
\`\`\`bash
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
P=""
[ -n "$MAKE_PDF_BIN" ] && [ -x "$MAKE_PDF_BIN" ] && P="$MAKE_PDF_BIN"
[ -z "$P" ] && [ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/dist/pdf" ] && P="$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/dist/pdf"
[ -z "$P" ] && P="${toShellPath(ctx.paths.skillRoot)}/make-pdf/dist/pdf"
if [ -x "$P" ]; then
echo "MAKE_PDF_READY: $P"
alias _p_="$P" # shellcheck alias helper (not exported)
export P # available as $P in subsequent blocks within the same skill invocation
else
echo "MAKE_PDF_NOT_AVAILABLE (run './setup' in the gstack repo to build it)"
fi
\`\`\`
If \`MAKE_PDF_NOT_AVAILABLE\` is printed: tell the user the binary is not
built. Have them run \`./setup\` from the gstack repo, then retry.
If \`MAKE_PDF_READY\` is printed: \`$P\` is the binary path for the rest of
the skill. Use \`$P\` (not an explicit path) so the skill body stays portable.
Core commands:
- \`$P generate <input.md> [output.pdf]\` — render markdown to PDF (80% use case)
- \`$P generate --cover --toc essay.md out.pdf\` — full publication layout
- \`$P generate --watermark DRAFT memo.md draft.pdf\` — diagonal DRAFT watermark
- \`$P preview <input.md>\` — render HTML and open in browser (fast iteration)
- \`$P setup\` — verify the browser (Aside, or gstack's own headless fallback) + pdftotext and run a smoke test
- \`$P --help\` — full flag reference
Output contract:
- \`stdout\`: ONLY the output path on success. One line.
- \`stderr\`: progress (\`Rendering HTML... Generating PDF...\`) unless \`--quiet\`.
- Exit 0 success / 1 bad args / 2 render error / 3 TOC page numbers failed / 4 no browser available (open the Aside app, or run \`./setup\` to build gstack's own browser).
PDFs print through Aside when it is running and through gstack's own headless browser otherwise; the stderr progress line says which (\`Rendering PDF through Aside\` / \`through gstack's browser\`).`;
}