Best Practices for Modifying BuilderIO/agent-native Root Files: A Complete Guide
Always run pnpm run prep before committing, encode new invariants in scripts/guard-*.mjs, and use Changesets for version management to safely modify root files in the BuilderIO/agent-native monorepo.
The BuilderIO/agent-native repository is a sophisticated monorepo where root-level configuration files govern the entire workspace ecosystem. Modifying these files requires strict adherence to architectural contracts defined in AGENTS.md and validation through the CI pipeline in .github/workflows/ci.yml. This guide provides actionable steps for editing root files without breaking the shared infrastructure across all templates and packages.
Understanding the Root Architecture
The root of the Agent-Native repository contains configuration, scripts, and package definitions that form a four-area contract (UI, actions, skills, state) described in AGENTS.md. These components are tightly coupled and affect every workspace member.
Central Configuration Files
-
package.json– Defines workspace scripts, dev-dependencies, and thepostinstallbuild chain that triggers workspace builds. This is the central entry point for allpnpmcommands. -
pnpm-workspace.yaml– Lists all workspace packages and templates, enabling theworkspace:*version protocol that prevents dangling references. -
AGENTS.md– Contains the canonical "always-on" rules governing branch safety, commit hygiene, and guard philosophy. Any modification must respect these policies. -
.github/workflows/ci.yml– Runs the CI pipeline executing lint, type-checks, tests, and security guards. Changes introducing failures here block all PRs. -
scripts/guard-*.mjs– Runtime scripts enforcing invariants like preventingdrizzle-kit pushcommands or unscoped credentials. These run automatically viapnpm guards.
Core Principles for Safe Root Modifications
Follow these architectural principles when editing files in the repository root:
-
Never break CI – The
lint,typecheck,test, andguardsjobs in.github/workflows/ci.ymlprotect the workspace from regressions. Always verify green status locally before pushing. -
Keep root files declarative – Avoid embedding application logic in root scripts. The root is shared across all templates; template-specific code belongs in
packages/*or package-specific scripts. -
Prefer
workspace:version ranges – Every inter-package dependency must resolve to a workspace member usingworkspace:*specifiers. This prevents installation failures caught by the scaffold-e2e job (lines 28-52 inci.yml). -
Guard first – Codify new invariants in
scripts/guard-*.mjsfiles. Guards automate the detection of real-world incidents like credential leaks and run automatically on every PR. -
Version-control via changesets – Never bump versions manually in
package.json. Use the Changeset workflow (pnpm changeset add) to generate changelog entries andpnpm changeset versionto apply them. -
Never embed secrets – Hard-coded keys violate the security policy in
AGENTS.md. Use environment variables and the secrets system documented inDEVELOPMENT.md.
Step-by-Step Workflow for Editing Root Files
Use this checklist workflow to ensure compliance when modifying root configuration:
-
Review
AGENTS.md– Verify your change complies with "always-on" rules (e.g., noCo-Authored-Bylines in commits). -
Install dependencies – Run
pnpm install --frozen-lockfileto ensure lockfile consistency before making changes. -
Implement the change – Edit the target file (e.g., add a script to
package.jsonor a workspace folder topnpm-workspace.yaml). -
Add guard coverage – If introducing a new invariant, create a matching
scripts/guard-*.mjsscript following the pattern inguard-no-drizzle-push.mjs. -
Validate locally – Execute
pnpm run prepto run the full verification suite: formatting, linting, type-checking, testing, and guard execution. -
Commit correctly – Write a clear commit message; do not use
Co-Authored-Bymetadata per repository rules. -
Open PR and verify CI – Push changes and confirm all GitHub Actions jobs (
lint,typecheck,test,guards) pass successfully. -
Document changes – If the modification is user-facing, run
pnpm changeset addto create a changeset entry describing the impact.
Practical Implementation Examples
Adding a New Root Script in package.json
When adding utility scripts to the root, keep them declarative and avoid business logic:
{
"scripts": {
"my:clean": "rimraf ./tmp && pnpm install --frozen-lockfile"
}
}
This script is safe because it performs cleanup without affecting build order. While no guard is required for simple utilities, always run pnpm fmt:check to maintain formatting standards.
Creating a New Guard Script
Encode policy enforcement by creating scripts/guard-no-legacy-deps.mjs:
#!/usr/bin/env node
import { readFileSync } from "fs";
import path from "path";
const pkgPath = path.resolve(process.cwd(), "package.json");
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
let violations = [];
function checkDeps(deps, type) {
for (const [name, version] of Object.entries(deps || {})) {
if (typeof version === "string" && version.startsWith("npm:")) {
violations.push(`${type}.${name}=${version}`);
}
}
}
checkDeps(pkg.dependencies, "dependencies");
checkDeps(pkg.devDependencies, "devDependencies");
if (violations.length) {
console.error("🚨 Legacy npm: protocol dependencies detected:");
violations.forEach(v => console.error(" -", v));
process.exit(1);
}
Add this guard to the validation suite by ensuring it follows the guard-*.mjs naming convention, which pnpm guards automatically discovers and executes.
Extending the Workspace Configuration
To add a new workspace folder in pnpm-workspace.yaml:
packages:
- "packages/*"
- "templates/*"
- "tools/*" # New folder for shared CLI utilities
After modifying workspace definitions, run pnpm install and verify the new package appears in pnpm list output. The scaffold-e2e job in .github/workflows/ci.yml validates that these references resolve correctly.
Managing Releases with Changesets
For user-facing root modifications that require version bumps:
pnpm changeset add
Follow the interactive prompts to select the change type (e.g., "added") and provide a summary: "Add my:clean helper script for CI pipelines". This creates a markdown file under .changeset/ that the release pipeline consumes when pnpm changeset version runs on merge.
Summary
-
Root files require strict validation – Run
pnpm run preplocally before every PR to verify formatting, linting, type-checking, and guard compliance. -
Encode policies in guard scripts – Create
scripts/guard-*.mjsfiles to automate enforcement of new invariants rather than relying on documentation alone. -
Use workspace protocols – Always reference internal packages with
workspace:*inpackage.jsondependencies to prevent resolution failures. -
Automate versioning – Use
pnpm changeset addfor all user-facing changes; manual version bumps bypass the release pipeline and break the Changeset workflow. -
Respect the four-area contract – Ensure modifications to root configuration support the UI, actions, skills, and state architecture defined in
AGENTS.md.
Frequently Asked Questions
What happens if I modify root files without running pnpm run prep?
CI will fail. The .github/workflows/ci.yml pipeline runs the same checks as pnpm run prep (lint, typecheck, tests, and guards). Local execution catches errors before they block your PR and prevents breaking the shared workspace configuration.
How do I add a new invariant check to the repository?
Create a scripts/guard-*.mjs file. Copy the pattern from scripts/guard-no-drizzle-push.mjs, implement your validation logic using Node.js APIs, and exit with code 1 on failure. The pnpm guards command automatically discovers and executes all files matching the guard-*.mjs pattern in the scripts directory.
When should I use workspace:* versus standard version ranges?
Always use workspace:* for internal dependencies. In package.json, reference other monorepo packages with the workspace:* protocol to ensure they resolve to local source rather than npm registry versions. This prevents "dangling workspace refs" that cause pnpm install failures and are caught by the scaffold-e2e CI job.
Why does CI fail after I edit pnpm-workspace.yaml?
You likely broke workspace resolution. Adding folders to pnpm-workspace.yaml requires that those directories contain valid package.json files and that cross-references use workspace:* specifiers. The scaffold-e2e job (lines 28-52 in ci.yml) validates that all workspace dependencies resolve correctly. Verify locally with pnpm install and pnpm list before pushing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →