{"record":{"id":"fe73f06f5e53260b","repo":"garrytan/gstack","slug":"out-dir-requires-a-directory-path","errorCode":null,"errorMessage":"--out-dir requires a directory path","messagePattern":"--out-dir requires a directory path","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/gen-skill-docs.ts","lineNumber":162,"sourceCode":"  }\n  return val;\n})();\n\n// ─── Out-dir (dev workspace render isolation) ───────────────\n// --out-dir <abs-dir> redirects Claude SKILL.md + section output to a separate\n// (untracked) directory instead of writing in place, AND rewrites the literal\n// section-base path (`~/.claude/skills/gstack/<skill>/sections/`) inside the\n// generated content to point at the out-dir, so section Reads resolve to the\n// rendered copy rather than the global install. Used by bin/dev-setup to render\n// the gbrain `:user` variant for a Conductor workspace without dirtying tracked\n// source. Default (unset) = in-place, behavior unchanged. Claude host only.\nconst OUT_DIR_ARG = process.argv.find(a => a.startsWith('--out-dir'));\nconst OUT_DIR: string | null = (() => {\n  if (!OUT_DIR_ARG) return null;\n  const val = OUT_DIR_ARG.includes('=')\n    ? OUT_DIR_ARG.split('=')[1]\n    : process.argv[process.argv.indexOf(OUT_DIR_ARG) + 1];\n  if (!val) throw new Error('--out-dir requires a directory path');\n  return path.resolve(val);\n})();\n\n/**\n * When rendering to an out-dir, repoint the literal section-base path at the\n * out-dir so section Reads resolve to the rendered copy, not the global install.\n * Surgical: ONLY paths containing `/sections/` are rewritten — bin/, browse/,\n * docs/ references keep pointing at `~/.claude/skills/gstack` (the global\n * install, which still works). No-op when --out-dir is unset.\n */\nfunction rewriteSectionBase(content: string): string {\n  if (!OUT_DIR) return content;\n  return content.replace(\n    /~\\/\\.claude\\/skills\\/gstack\\/([^\\s)`\"'*]+\\/sections\\/)/g,\n    `${OUT_DIR}/$1`,\n  );\n}\n","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/scripts/gen-skill-docs.ts#L144-L180","documentation":"Thrown by the OUT_DIR IIFE in scripts/gen-skill-docs.ts:162 when --out-dir is present but no value follows (it is the last token, or the = form yields empty). --out-dir redirects Claude SKILL.md + section output to a separate untracked directory and rewrites the section-base path so section Reads resolve to the rendered copy.","triggerScenarios":"`bun run gen:skill-docs -- --host claude --out-dir` with nothing after. `--out-dir=` with empty value. Shell variable expansion producing an empty path.","commonSituations":"Conditionally appending --out-dir $DIR in a script where DIR is unset. Trailing flag at end of an argv array. Quoting bug dropping the path.","solutions":["Append a path: `--out-dir /tmp/render`","Use the equals form: `--out-dir=/tmp/render`","Ensure the env var feeding the path is set and non-empty before invoking"],"exampleFix":"// before\nbun run gen:skill-docs -- --host claude --out-dir\n// after\nbun run gen:skill-docs -- --host claude --out-dir /tmp/gbrain-render","handlingStrategy":"validation","validationCode":"const i = process.argv.indexOf('--out-dir');\nif (i !== -1) {\n  const eq = process.argv[i].includes('=');\n  const next = eq ? process.argv[i].split('=')[1] : process.argv[i + 1];\n  if (!next) {\n    console.error('--out-dir requires a directory path');\n    process.exit(2);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer the --flag=value form to avoid the missing-next-arg trap","Quote paths in shell scripts to survive spaces and empty expansions","Use `set -u` in bash so unset variables error before reaching the CLI"],"tags":["cli","argument-validation","build","out-dir"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}