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 the postinstall build chain that triggers workspace builds. This is the central entry point for all pnpm commands.

  • pnpm-workspace.yaml – Lists all workspace packages and templates, enabling the workspace:* 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 preventing drizzle-kit push commands or unscoped credentials. These run automatically via pnpm 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, and guards jobs in .github/workflows/ci.yml protect 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 using workspace:* specifiers. This prevents installation failures caught by the scaffold-e2e job (lines 28-52 in ci.yml).

  • Guard first – Codify new invariants in scripts/guard-*.mjs files. 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 and pnpm changeset version to apply them.

  • Never embed secrets – Hard-coded keys violate the security policy in AGENTS.md. Use environment variables and the secrets system documented in DEVELOPMENT.md.

Step-by-Step Workflow for Editing Root Files

Use this checklist workflow to ensure compliance when modifying root configuration:

  1. Review AGENTS.md – Verify your change complies with "always-on" rules (e.g., no Co-Authored-By lines in commits).

  2. Install dependencies – Run pnpm install --frozen-lockfile to ensure lockfile consistency before making changes.

  3. Implement the change – Edit the target file (e.g., add a script to package.json or a workspace folder to pnpm-workspace.yaml).

  4. Add guard coverage – If introducing a new invariant, create a matching scripts/guard-*.mjs script following the pattern in guard-no-drizzle-push.mjs.

  5. Validate locally – Execute pnpm run prep to run the full verification suite: formatting, linting, type-checking, testing, and guard execution.

  6. Commit correctly – Write a clear commit message; do not use Co-Authored-By metadata per repository rules.

  7. Open PR and verify CI – Push changes and confirm all GitHub Actions jobs (lint, typecheck, test, guards) pass successfully.

  8. Document changes – If the modification is user-facing, run pnpm changeset add to 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 prep locally before every PR to verify formatting, linting, type-checking, and guard compliance.

  • Encode policies in guard scripts – Create scripts/guard-*.mjs files to automate enforcement of new invariants rather than relying on documentation alone.

  • Use workspace protocols – Always reference internal packages with workspace:* in package.json dependencies to prevent resolution failures.

  • Automate versioning – Use pnpm changeset add for 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →