Problem
npx @tanstack/intent setup-github-actions generates CI workflow files with incorrect template variable substitution when run in a monorepo. There is no documented way to correctly generate workflows for a monorepo, and every approach we tried produced broken output that required manual patching.
Expected behavior
Running setup-github-actions in a monorepo should either:
- Detect the monorepo and produce workflows that loop over all packages (like
validate-skills.yml already does internally), or
- Clearly document the intended workflow for monorepos, or
- Accept a
--packages flag or similar to specify which packages to cover
What we found
Issue 1: setup-github-actions reads process.cwd()/package.json for template variables
The detectVars() function in setup.mjs reads package.json from process.cwd() to populate {{PACKAGE_NAME}}, {{SRC_PATH}}, etc. In a monorepo:
- Running from repo root: The root
package.json typically has no name (or a private workspace name like root), so all template vars resolve to nonsense: npm install root, packages/root/src/**, "package": "root".
- Running from a package directory (e.g.
cd packages/react-router && npx @tanstack/intent setup-github-actions): Template vars resolve correctly for that one package (@tanstack/react-router, src/**), but the workflows land in packages/react-router/.github/workflows/ instead of the repo root's .github/workflows/. And they only cover one package.
Issue 2: Workflows are generated per-package but GitHub Actions are per-repo
The three generated workflows have different monorepo-readiness:
| Workflow |
Monorepo-ready? |
Notes |
validate-skills.yml |
Yes |
Has hardcoded packages/*/skills loop — works out of the box |
check-skills.yml |
No |
npm install {{PACKAGE_NAME}} only installs one package; npx @tanstack/intent stale only checks cwd |
notify-playbooks.yml |
No |
paths: '{{SRC_PATH}}' only watches one package's src; client-payload.package is a single package name |
Issue 3: validate command has the same cwd confusion
npx @tanstack/intent validate uses args[0] ?? "skills" as the target dir, but collectPackagingWarnings() always reads process.cwd()/package.json. So:
npx @tanstack/intent validate packages/react-router/skills — skills validate fine, but packaging warnings fire because it checks the root package.json (which has no @tanstack/intent devDep, no bin.intent, etc.)
cd packages/react-router && npx @tanstack/intent validate skills — everything works correctly
This is confusing in a monorepo where you naturally run commands from the repo root.
Issue 4: stale command doesn't find packages from repo root
Running npx @tanstack/intent stale from the repo root outputs No intent-enabled packages found. You have to cd into each package directory individually.
Steps to reproduce
# 1. Clone a monorepo with intent skills in multiple packages
git clone https://github.com/TanStack/router.git
cd router
pnpm install
# 2. Try setup-github-actions from repo root
npx @tanstack/intent@latest setup-github-actions
# Output: Template variables applied: Package: root, Src: packages/root/src/**
# Generated workflows have "npm install root" and "packages/root/src/**"
# 3. Try from a package directory
cd packages/react-router
npx @tanstack/intent@latest setup-github-actions
# Output: Correct vars, but workflows land in packages/react-router/.github/workflows/
# 4. Try validate from repo root
cd ../..
npx @tanstack/intent@latest validate packages/react-router/skills
# Skills pass, but packaging warnings fire against root package.json
# 5. Try stale from repo root
npx @tanstack/intent@latest stale
# "No intent-enabled packages found."
# 6. Try stale from package dir — works
cd packages/react-router
npx @tanstack/intent@latest stale
# Correctly reports version drift
What we did to work around it
- Ran
setup-github-actions from packages/react-router, then manually moved the generated files from packages/react-router/.github/workflows/ to .github/workflows/
validate-skills.yml — left as-is (already monorepo-aware)
check-skills.yml — replaced npm install @tanstack/react-router with npm install -g @tanstack/intent, added a shell loop over packages/*/skills directories to run stale per-package, changed the prompt text from package-specific to repo-wide
notify-playbooks.yml — changed src/** to packages/*/src/**, changed "package" from @tanstack/react-router to @tanstack/router
Suggested improvements
setup-github-actions: Add monorepo detection (check for workspaces in root package.json or packages/ directory). When detected, generate check-skills.yml and notify-playbooks.yml with loops over all packages, similar to how validate-skills.yml already works.
validate: Make collectPackagingWarnings() resolve the package.json relative to the skills directory being validated, not always process.cwd().
stale: Add monorepo support — when run from a workspace root, discover and check all packages that have skills/ directories.
- Docs: Add a "Monorepo setup" section to the README covering the intended workflow.
Environment
@tanstack/intent version: 0.0.14
- Node: v22
- Monorepo: pnpm workspaces, 10+ packages with skills
Problem
npx @tanstack/intent setup-github-actionsgenerates CI workflow files with incorrect template variable substitution when run in a monorepo. There is no documented way to correctly generate workflows for a monorepo, and every approach we tried produced broken output that required manual patching.Expected behavior
Running
setup-github-actionsin a monorepo should either:validate-skills.ymlalready does internally), or--packagesflag or similar to specify which packages to coverWhat we found
Issue 1:
setup-github-actionsreadsprocess.cwd()/package.jsonfor template variablesThe
detectVars()function insetup.mjsreadspackage.jsonfromprocess.cwd()to populate{{PACKAGE_NAME}},{{SRC_PATH}}, etc. In a monorepo:package.jsontypically has noname(or a private workspace name likeroot), so all template vars resolve to nonsense:npm install root,packages/root/src/**,"package": "root".cd packages/react-router && npx @tanstack/intent setup-github-actions): Template vars resolve correctly for that one package (@tanstack/react-router,src/**), but the workflows land inpackages/react-router/.github/workflows/instead of the repo root's.github/workflows/. And they only cover one package.Issue 2: Workflows are generated per-package but GitHub Actions are per-repo
The three generated workflows have different monorepo-readiness:
validate-skills.ymlpackages/*/skillsloop — works out of the boxcheck-skills.ymlnpm install {{PACKAGE_NAME}}only installs one package;npx @tanstack/intent staleonly checks cwdnotify-playbooks.ymlpaths: '{{SRC_PATH}}'only watches one package's src;client-payload.packageis a single package nameIssue 3:
validatecommand has the same cwd confusionnpx @tanstack/intent validateusesargs[0] ?? "skills"as the target dir, butcollectPackagingWarnings()always readsprocess.cwd()/package.json. So:npx @tanstack/intent validate packages/react-router/skills— skills validate fine, but packaging warnings fire because it checks the rootpackage.json(which has no@tanstack/intentdevDep, nobin.intent, etc.)cd packages/react-router && npx @tanstack/intent validate skills— everything works correctlyThis is confusing in a monorepo where you naturally run commands from the repo root.
Issue 4:
stalecommand doesn't find packages from repo rootRunning
npx @tanstack/intent stalefrom the repo root outputsNo intent-enabled packages found.You have tocdinto each package directory individually.Steps to reproduce
What we did to work around it
setup-github-actionsfrompackages/react-router, then manually moved the generated files frompackages/react-router/.github/workflows/to.github/workflows/validate-skills.yml— left as-is (already monorepo-aware)check-skills.yml— replacednpm install @tanstack/react-routerwithnpm install -g @tanstack/intent, added a shell loop overpackages/*/skillsdirectories to runstaleper-package, changed the prompt text from package-specific to repo-widenotify-playbooks.yml— changedsrc/**topackages/*/src/**, changed"package"from@tanstack/react-routerto@tanstack/routerSuggested improvements
setup-github-actions: Add monorepo detection (check forworkspacesin rootpackage.jsonorpackages/directory). When detected, generatecheck-skills.ymlandnotify-playbooks.ymlwith loops over all packages, similar to howvalidate-skills.ymlalready works.validate: MakecollectPackagingWarnings()resolve the package.json relative to the skills directory being validated, not alwaysprocess.cwd().stale: Add monorepo support — when run from a workspace root, discover and check all packages that haveskills/directories.Environment
@tanstack/intentversion: 0.0.14