fix(make-pdf): move setup before preamble footer

This commit is contained in:
Jayesh Betala 2026-05-09 19:50:22 +05:30 committed by Garry Tan
parent 9d92f8e9c2
commit a6b32b71af
No known key found for this signature in database
GPG Key ID: C1F69E85C74EFE1D
4 changed files with 59 additions and 39 deletions

View File

@ -102,6 +102,42 @@ echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
```
## 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/.claude/skills/gstack/make-pdf/dist/pdf" ] && P="$_ROOT/.claude/skills/gstack/make-pdf/dist/pdf"
[ -z "$P" ] && P="$HOME/.claude/skills/gstack/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 browse + Chromium + 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 Paged.js timeout / 4 browse unavailable.
## Plan Mode Safe Operations
In plan mode, allowed because they inform the plan: `$B`, `$D`, `codex exec`/`codex review`, writes to `~/.gstack/`, writes to the plan file, and `open` for generated artifacts.
@ -489,42 +525,6 @@ On Linux, install `fonts-liberation` for correct rendering — Helvetica and Ari
aren't present by default, and Liberation Sans is the standard metric-compatible
fallback. CI and Docker builds install it automatically via Dockerfile.ci.
## 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/.claude/skills/gstack/make-pdf/dist/pdf" ] && P="$_ROOT/.claude/skills/gstack/make-pdf/dist/pdf"
[ -z "$P" ] && P="$HOME/.claude/skills/gstack/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 browse + Chromium + 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 Paged.js timeout / 4 browse unavailable.
## Core patterns
### 80% case — memo/letter

View File

@ -41,8 +41,6 @@ On Linux, install `fonts-liberation` for correct rendering — Helvetica and Ari
aren't present by default, and Liberation Sans is the standard metric-compatible
fallback. CI and Docker builds install it automatically via Dockerfile.ci.
{{MAKE_PDF_SETUP}}
## Core patterns
### 80% case — memo/letter

View File

@ -58,6 +58,7 @@ import { generateContextHealth } from './preamble/generate-context-health';
// Tier 3+ repo mode + search
import { generateRepoModeSection } from './preamble/generate-repo-mode-section';
import { generateSearchBeforeBuildingSection } from './preamble/generate-search-before-building';
import { generateMakePdfSetup } from './make-pdf';
// Standalone export used directly by the resolver registry
export { generateTestFailureTriage } from './preamble/generate-test-failure-triage';
@ -81,7 +82,8 @@ export function generatePreamble(ctx: TemplateContext): string {
}
const sections = [
generatePreambleBash(ctx),
// Plan-mode-skill semantics at position 1: after bash (so _SESSION_ID /
...(ctx.skillName === 'make-pdf' ? [generateMakePdfSetup(ctx)] : []),
// Plan-mode-skill semantics stays near the top: after bash (so _SESSION_ID /
// _BRANCH / _TEL env vars are live) and before all onboarding gates so
// models read the authoritative "AskUserQuestion satisfies plan mode's
// end-of-turn" rule before any other instruction. Renders for all skills

View File

@ -1098,6 +1098,26 @@ describe('Plan status footer in preamble', () => {
});
});
// --- make-pdf setup ordering ---
describe('make-pdf setup ordering', () => {
test('MAKE-PDF SETUP appears before generic preamble footer sections', () => {
const content = fs.readFileSync(path.join(ROOT, 'make-pdf', 'SKILL.md'), 'utf-8');
const preambleIdx = content.indexOf('## Preamble (run first)');
const setupIdx = content.indexOf('## MAKE-PDF SETUP');
const planModeIdx = content.indexOf('## Plan Mode Safe Operations');
const telemetryIdx = content.indexOf('## Telemetry (run last)');
const workflowIdx = content.indexOf('# make-pdf: publication-quality PDFs from markdown');
expect(preambleIdx).toBeGreaterThanOrEqual(0);
expect(setupIdx).toBeGreaterThan(preambleIdx);
expect(setupIdx).toBeLessThan(planModeIdx);
expect(setupIdx).toBeLessThan(telemetryIdx);
expect(setupIdx).toBeLessThan(workflowIdx);
expect(content.match(/^## MAKE-PDF SETUP/gm)?.length ?? 0).toBe(1);
});
});
// --- Skill invocation during plan mode in preamble ---
describe('Skill invocation during plan mode in preamble', () => {