From c04ee5f0542ce6a93415efbb156f5a11d7ea2b7b Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Sat, 23 May 2026 11:54:43 -0700 Subject: [PATCH] feat(agent-docs): single-source-of-truth pattern for agent instructions Establish a single canonical source for ecosystem-wide AI agent behavior rules, eliminating duplication across the 8 agent-config files that each repo used to maintain. New canonical sources (this repo only): - AI.dev/SKILLS/agent-behavior-guidelines.md (Karpathy + ByteLyst rules) - AI.dev/SKILLS/agent-onboarding.md (read-order index) Generator rewrite (scripts/update-agent-docs.sh): - Deletes legacy files that duplicated AGENTS.md: .cursorrules, .windsurfrules, .clinerules, CLAUDE.md - Regenerates .github/copilot-instructions.md as a thin pointer (no rules). - Regenerates .aider.conf.yml and .editorconfig. - Idempotently prepends a canonical-behavior-pointer block to AGENTS.md. - Supports --dry-run and --no-commit flags. Drift check (scripts/check-agent-docs-drift.sh): - Fast marker-based check across all repos. - Verifies legacy files absent, AGENTS.md pointer present, copilot/aider/ editorconfig markers intact. Workflow doc updated: .windsurf/workflows/repo_update-agent-docs.md Repos.txt: added learning_ai_talk2obsidian (was missing from canonical list). This repo's own agent files are migrated by the same generator: - Removed: .cursorrules, .windsurfrules, .clinerules, CLAUDE.md - Updated: AGENTS.md (pointer block prepended) - Updated: .github/copilot-instructions.md (rewritten as pointer) - Updated: .aider.conf.yml (canonical format) Karpathy attribution: behavior rules adapted from https://github.com/multica-ai/andrej-karpathy-skills --- .aider.conf.yml | 3 +- .clinerules | 24 - .cursorrules | 32 - .github/copilot-instructions.md | 44 +- .windsurf/workflows/repo_update-agent-docs.md | 132 ++- .windsurf/workflows/repos.txt | 1 + .windsurfrules | 25 - AGENTS.md | 12 + AI.dev/SKILLS/agent-behavior-guidelines.md | 173 ++++ AI.dev/SKILLS/agent-onboarding.md | 77 ++ CLAUDE.md | 33 - scripts/check-agent-docs-drift.sh | 128 +++ scripts/update-agent-docs.sh | 763 ++++++------------ 13 files changed, 734 insertions(+), 713 deletions(-) delete mode 100644 .clinerules delete mode 100644 .cursorrules delete mode 100644 .windsurfrules create mode 100644 AI.dev/SKILLS/agent-behavior-guidelines.md create mode 100644 AI.dev/SKILLS/agent-onboarding.md delete mode 100644 CLAUDE.md create mode 100755 scripts/check-agent-docs-drift.sh diff --git a/.aider.conf.yml b/.aider.conf.yml index 6eed2dae..ac004969 100644 --- a/.aider.conf.yml +++ b/.aider.conf.yml @@ -1,5 +1,6 @@ # .aider.conf.yml — Aider Configuration for @bytelyst Common Platform -# Helps Aider understand the project structure and conventions. +# Auto-generated by learning_ai_common_plat/scripts/update-agent-docs.sh +# Hand-edit will be overwritten on next run. read: - AGENTS.md diff --git a/.clinerules b/.clinerules deleted file mode 100644 index 9c8edba2..00000000 --- a/.clinerules +++ /dev/null @@ -1,24 +0,0 @@ -# .clinerules — Cline / Roo Code Rules for @bytelyst Common Platform -# Read AGENTS.md for the complete onboarding guide. - -## Project: @bytelyst Common Platform — Shared packages + microservices for the ByteLyst ecosystem -Architecture: TypeScript, ESM, pnpm workspace, Fastify 5, Vitest, Azure Cosmos DB - -## Mandatory Rules -- Package manager: pnpm — NEVER use npm -- ESM everywhere: "type": "module", .js extensions in imports -- Fastify module pattern: types.ts → repository.ts → routes.ts -- Use req.log / app.log — never console.log -- Every Cosmos document MUST include a productId field -- peerDependencies for heavy deps; workspace:* for inter-package deps -- Services re-export @bytelyst/* in src/lib/ for clean internal imports -- Commits: `type(scope): description` -- After changes, verify: `pnpm build && pnpm test && pnpm typecheck` - -## Key File Locations -- packages/ — @bytelyst/* shared libraries (errors, cosmos, config, auth, api-client, fastify-core, react-auth, logger, testing, blob, extraction, monitoring, design-tokens) -- services/platform-service/ — consolidated platform service (port 4003) -- services/extraction-service/ — text extraction + Python sidecar (port 4005) -- dashboards/admin-web/ — admin console (port 3001) -- dashboards/tracker-web/ — issue tracker (port 3003) -- Full guide: `AGENTS.md` diff --git a/.cursorrules b/.cursorrules deleted file mode 100644 index 08218d18..00000000 --- a/.cursorrules +++ /dev/null @@ -1,32 +0,0 @@ -# @bytelyst Common Platform — Cursor Rules -# Read AGENTS.md for full context. - -Project: @bytelyst Common Platform — Shared packages + microservices for the ByteLyst ecosystem -Product ID: (product-agnostic) -Stack: TypeScript, ESM, pnpm workspace, Fastify 5, Vitest, Azure Cosmos DB - -## Architecture -- packages/ — @bytelyst/* shared libraries (errors, cosmos, config, auth, api-client, fastify-core, react-auth, logger, testing, blob, extraction, monitoring, design-tokens) -- services/platform-service/ — consolidated platform service (port 4003) -- services/extraction-service/ — text extraction + Python sidecar (port 4005) -- dashboards/admin-web/ — admin console (port 3001) -- dashboards/tracker-web/ — issue tracker (port 3003) - -## Rules -- Package manager: pnpm — NEVER use npm -- ESM everywhere: "type": "module", .js extensions in imports -- Fastify module pattern: types.ts → repository.ts → routes.ts -- Use req.log / app.log — never console.log -- Every Cosmos document MUST include a productId field -- peerDependencies for heavy deps; workspace:* for inter-package deps -- Services re-export @bytelyst/* in src/lib/ for clean internal imports -- Commits: feat(scope): description / fix(scope): description -- Never delete existing comments/documentation unless asked -- Never add emojis unless asked -- Never hardcode secrets, colors, or API URLs - -## Build Verification -- pnpm build && pnpm test && pnpm typecheck - -## Key Documents -- AGENTS.md — Full AI agent instructions (read this first) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6a8bb474..f906be22 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,40 +1,24 @@ + + + # GitHub Copilot Instructions — @bytelyst Common Platform -> For full agent instructions, read [`AGENTS.md`](../AGENTS.md) at the repo root. +**Project:** @bytelyst Common Platform — `(product-agnostic)` +**Stack:** TypeScript, ESM, pnpm workspace, Fastify 5, Vitest, Azure Cosmos DB -## Project Context +## Read these (in order) before suggesting code -**@bytelyst Common Platform** — Shared packages + microservices for the ByteLyst ecosystem. -Stack: TypeScript, ESM, pnpm workspace, Fastify 5, Vitest, Azure Cosmos DB +1. **`AGENTS.md`** at the repo root — repo-specific layout, conventions, + build commands, file ownership. +2. **`AI.dev/SKILLS/agent-behavior-guidelines.md`** — + ecosystem-wide agent behavior rules (Karpathy + ByteLyst). Identical + across every repo in the workspace. -## Code Generation Rules +Both files together are the complete contract. This pointer file contains +no rules of its own to avoid duplication and drift. -### Always -- Package manager: pnpm — NEVER use npm -- ESM everywhere: "type": "module", .js extensions in imports -- Fastify module pattern: types.ts → repository.ts → routes.ts -- Use req.log / app.log — never console.log -- Every Cosmos document MUST include a productId field -- peerDependencies for heavy deps; workspace:* for inter-package deps -- Services re-export @bytelyst/* in src/lib/ for clean internal imports -- Include `productId: "(product-agnostic)"` in every Cosmos DB document -- Use `type(scope): description` commit message format -- Fix source code, not tests (unless the test itself is wrong) +## Quick verification command -### Never -- `console.log` or `print()` in production code -- Hardcoded secrets, API keys, colors, or URLs -- Delete existing comments or documentation unless explicitly asked -- Add emojis unless asked - -## Key Paths -- packages/ — @bytelyst/* shared libraries (errors, cosmos, config, auth, api-client, fastify-core, react-auth, logger, testing, blob, extraction, monitoring, design-tokens) -- services/platform-service/ — consolidated platform service (port 4003) -- services/extraction-service/ — text extraction + Python sidecar (port 4005) -- dashboards/admin-web/ — admin console (port 3001) -- dashboards/tracker-web/ — issue tracker (port 3003) - -## Build Verification ```bash pnpm build && pnpm test && pnpm typecheck ``` diff --git a/.windsurf/workflows/repo_update-agent-docs.md b/.windsurf/workflows/repo_update-agent-docs.md index 4d9dde76..32fbf807 100644 --- a/.windsurf/workflows/repo_update-agent-docs.md +++ b/.windsurf/workflows/repo_update-agent-docs.md @@ -1,54 +1,116 @@ --- -description: Regenerate AI agent docs (AGENTS.md, CLAUDE.md, .cursorrules, etc.) across all repos +description: Regenerate AI agent docs across all repos (single source of truth pattern) --- # Update Agent Docs Across Workspace -Regenerates all 8 AI agent configuration files across all repos in the workspace. +Maintains AI agent docs across the ByteLyst workspace using a +**single source of truth** pattern with **zero duplication**. -## Files Generated Per Repo +## Architecture -| File | Tool | -| --------------------------------- | ----------------------------------------------- | -| `AGENTS.md` | Universal (OpenAI Codex, Claude, Copilot, etc.) | -| `CLAUDE.md` | Claude Code | -| `.cursorrules` | Cursor AI | -| `.github/copilot-instructions.md` | GitHub Copilot | -| `.windsurfrules` | Windsurf / Cascade | -| `.clinerules` | Cline / Roo Code | -| `.aider.conf.yml` | Aider | -| `.editorconfig` | All editors | +``` +learning_ai_common_plat/AI.dev/SKILLS/ +├── agent-behavior-guidelines.md ← SINGLE source of truth for behavior rules +└── agent-onboarding.md ← Read-order index for agents + +/ +├── AGENTS.md ← Repo-specific only. Auto-prepended with +│ "Read first" pointer to canonical file. +├── .github/copilot-instructions.md ← Thin pointer (no rules). Auto-generated. +├── .aider.conf.yml ← Aider config pointing to AGENTS.md. Auto-generated. +└── .editorconfig ← Editor config. Auto-generated. + +DELETED across all repos (content was duplicated AGENTS.md): +├── CLAUDE.md +├── .cursorrules +├── .windsurfrules +└── .clinerules +``` ## Steps -1. Run the update script: +1. **Edit the canonical sources** when behavior rules change: -```bash -cd /Users/sd9235/code/mygh/learning_ai_common_plat -./scripts/update-agent-docs.sh -``` + ```bash + # ecosystem-wide agent behavior (Karpathy + ByteLyst) + open learning_ai_common_plat/AI.dev/SKILLS/agent-behavior-guidelines.md -The script reads `learning_ai_common_plat/.windsurf/workflows/repos.txt` as the canonical list of managed workspace repositories. + # read-order index + open learning_ai_common_plat/AI.dev/SKILLS/agent-onboarding.md + ``` -2. Review changes per repo: + These are referenced (not copied) by every repo's AGENTS.md, so changes + take effect immediately — no regeneration needed when only behavior rules change. -```bash -while IFS= read -r repo; do - [[ -z "$repo" || "$repo" =~ ^# ]] && continue - cd /Users/sd9235/code/mygh/$repo && git diff --stat -done < /Users/sd9235/code/mygh/learning_ai_common_plat/.windsurf/workflows/repos.txt -``` +2. **Run the generator** to delete legacy files / refresh pointers / sync configs: -3. Commit changes (if any): + ```bash + cd /Users/sd9235/code/mygh/learning_ai_common_plat + ./scripts/update-agent-docs.sh --dry-run # preview + ./scripts/update-agent-docs.sh # apply + commit per repo + ./scripts/update-agent-docs.sh --no-commit # apply without committing + ``` -```bash -cd /Users/sd9235/code/mygh/learning_voice_ai_agent -[ -n "$(git status --porcelain)" ] && git add -A && git commit -m "chore(docs): update agent configuration files" -``` + Reads `learning_ai_common_plat/.windsurf/workflows/repos.txt` as the + canonical list of managed repos. + +3. **Verify no drift**: + + ```bash + bash scripts/check-agent-docs-drift.sh + ``` + + Exits 1 if any repo has drifted from the canonical generator output. + Suitable for CI. + +4. **Review changes per repo**: + + ```bash + while IFS= read -r repo; do + [[ -z "$repo" || "$repo" =~ ^# ]] && continue + echo "── $repo ──" + git -C /Users/sd9235/code/mygh/"$repo" log -1 --oneline + done < /Users/sd9235/code/mygh/learning_ai_common_plat/.windsurf/workflows/repos.txt + ``` + +5. **Push (when ready)**: + + ```bash + while IFS= read -r repo; do + [[ -z "$repo" || "$repo" =~ ^# ]] && continue + git -C /Users/sd9235/code/mygh/"$repo" push + done < /Users/sd9235/code/mygh/learning_ai_common_plat/.windsurf/workflows/repos.txt + ``` + +## Files generated per repo + +| File | Type | Tool(s) | +| --------------------------------- | ------- | -------------------------------------- | +| `AGENTS.md` | Hybrid | Codex, Claude, Cursor, Windsurf, Cline | +| `.github/copilot-instructions.md` | Pointer | GitHub Copilot | +| `.aider.conf.yml` | Config | Aider | +| `.editorconfig` | Config | All editors | + +`AGENTS.md` is hybrid: the body is hand-maintained (repo-specific content), +but the generator idempotently prepends a `` +block at the top. The block is the only auto-managed region; everything else +is left alone. + +## Files deleted by the generator + +| File | Reason | +| ---------------- | ------------------------------------------------------------- | +| `CLAUDE.md` | Duplicated AGENTS.md. Claude Code reads AGENTS.md by default. | +| `.cursorrules` | Duplicated AGENTS.md. Cursor reads AGENTS.md. | +| `.windsurfrules` | Duplicated AGENTS.md. Windsurf reads AGENTS.md. | +| `.clinerules` | Duplicated AGENTS.md. Cline reads AGENTS.md. | ## Notes -- The script scans each repo's structure and regenerates docs based on current state -- Only commits if there are actual changes -- Safe to run repeatedly (idempotent) -- Requires `learning_ai_common_plat` to be the source of truth for templates +- Safe to run repeatedly (idempotent). +- Only commits when actual changes exist in the repo. +- The script never touches the body of AGENTS.md outside the marker block. +- For workspaces that include `learning_ai_common_plat` as a sibling + (default for Windsurf/Cascade), the canonical guidelines file resolves + via the relative path written into each AGENTS.md pointer. diff --git a/.windsurf/workflows/repos.txt b/.windsurf/workflows/repos.txt index e7e4e11a..509a94de 100644 --- a/.windsurf/workflows/repos.txt +++ b/.windsurf/workflows/repos.txt @@ -19,6 +19,7 @@ learning_ai_trails learning_ai_local_memory_gpt learning_ai_efforise learning_ai_local_llms +learning_ai_talk2obsidian # --- Auth & identity --- learning_ai_smart_auth diff --git a/.windsurfrules b/.windsurfrules deleted file mode 100644 index f06beb9d..00000000 --- a/.windsurfrules +++ /dev/null @@ -1,25 +0,0 @@ -# @bytelyst Common Platform — Windsurf / Codeium Rules -# Read AGENTS.md for full context. These are the critical rules. - -Project: @bytelyst Common Platform — Shared packages + microservices for the ByteLyst ecosystem -Stack: TypeScript, ESM, pnpm workspace, Fastify 5, Vitest, Azure Cosmos DB - -## Architecture Rules -- packages/ — @bytelyst/* shared libraries (errors, cosmos, config, auth, api-client, fastify-core, react-auth, logger, testing, blob, extraction, monitoring, design-tokens) -- services/platform-service/ — consolidated platform service (port 4003) -- services/extraction-service/ — text extraction + Python sidecar (port 4005) -- dashboards/admin-web/ — admin console (port 3001) -- dashboards/tracker-web/ — issue tracker (port 3003) - -## Conventions -- Package manager: pnpm — NEVER use npm -- ESM everywhere: "type": "module", .js extensions in imports -- Fastify module pattern: types.ts → repository.ts → routes.ts -- Use req.log / app.log — never console.log -- Every Cosmos document MUST include a productId field -- peerDependencies for heavy deps; workspace:* for inter-package deps -- Services re-export @bytelyst/* in src/lib/ for clean internal imports -- Commits: feat(scope): description / fix(scope): description - -## Build Verification -- pnpm build && pnpm test && pnpm typecheck diff --git a/AGENTS.md b/AGENTS.md index 2ec98606..909621e4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,17 @@ # AGENTS.md — AI Coding Agent Instructions + +> **Read first (ecosystem-wide agent behavior):** +> [`AI.dev/SKILLS/agent-behavior-guidelines.md`](AI.dev/SKILLS/agent-behavior-guidelines.md) +> +> The link above is the single source of truth for agent behavior across every +> ByteLyst repo (Karpathy + ByteLyst rules: tests sacred, verify before done, +> no shared-infra hand-edits, no `console.log`/`print`, productId on every +> Cosmos doc, conventional commits, style preservation). +> +> The per-repo content below extends — never duplicates — the canonical rules. + + > **For:** Claude Code, OpenAI Codex, Cursor, GitHub Copilot, Windsurf Cascade, and any AI coding agent. > **Repo:** `learning_ai_common_plat` — Shared platform packages + microservices for the ByteLyst ecosystem. > **See also:** [`README.md`](README.md) for quick start, [`docs/ECOSYSTEM_ARCHITECTURE.md`](docs/ECOSYSTEM_ARCHITECTURE.md) for full architecture, [`docs/ecosystem/README.md`](docs/ecosystem/README.md) for canonical ecosystem strategy/contract docs, [`docs/ecosystem/ECOSYSTEM_AGENT_OPERATING_MODEL.md`](docs/ecosystem/ECOSYSTEM_AGENT_OPERATING_MODEL.md) for delegation/review/merge process. diff --git a/AI.dev/SKILLS/agent-behavior-guidelines.md b/AI.dev/SKILLS/agent-behavior-guidelines.md new file mode 100644 index 00000000..a44ae6ea --- /dev/null +++ b/AI.dev/SKILLS/agent-behavior-guidelines.md @@ -0,0 +1,173 @@ +# Agent Behavior Guidelines — ByteLyst Ecosystem + +> **Single source of truth.** This file is the canonical agent behavior contract +> for every repo in the ByteLyst workspace. Every per-repo `AGENTS.md` points +> here. Do not duplicate these rules into per-repo agent files. +> +> **Location:** `learning_ai_common_plat/AI.dev/SKILLS/agent-behavior-guidelines.md` +> From any sibling repo: `../learning_ai_common_plat/AI.dev/SKILLS/agent-behavior-guidelines.md` + +These rules apply to every AI coding agent (Claude Code, Cursor, Windsurf Cascade, +GitHub Copilot, OpenAI Codex, Cline, Aider, etc.) working in any ByteLyst repo. + +--- + +## Part A — Universal Behavior (adapted from Karpathy's CLAUDE.md) + +Source attribution: behavioral guidelines below adapted from +. + +These bias toward caution over speed. For trivial tasks, use judgment. + +### A1. Think Before Coding + +**Don't assume. Don't hide confusion. Surface tradeoffs.** + +Before implementing: + +- State your assumptions explicitly. If uncertain, ask. +- If multiple interpretations exist, present them — don't pick silently. +- If a simpler approach exists, say so. Push back when warranted. +- If something is unclear, stop. Name what's confusing. Ask. + +### A2. Simplicity First + +**Minimum code that solves the problem. Nothing speculative.** + +- No features beyond what was asked. +- No abstractions for single-use code. +- No "flexibility" or "configurability" that wasn't requested. +- No error handling for impossible scenarios. +- If you write 200 lines and it could be 50, rewrite it. + +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +### A3. Surgical Changes + +**Touch only what you must. Clean up only your own mess.** + +When editing existing code: + +- Don't "improve" adjacent code, comments, or formatting. +- Don't refactor things that aren't broken. +- Match existing style, even if you'd do it differently. +- If you notice unrelated dead code, mention it — don't delete it. + +When your changes create orphans: + +- Remove imports/variables/functions that **your** changes made unused. +- Don't remove pre-existing dead code unless asked. + +**The test:** Every changed line should trace directly to the user's request. + +### A4. Goal-Driven Execution + +**Define success criteria. Loop until verified.** + +Transform tasks into verifiable goals: + +- "Add validation" → "Write tests for invalid inputs, then make them pass" +- "Fix the bug" → "Write a test that reproduces it, then make it pass" +- "Refactor X" → "Ensure tests pass before and after" + +For multi-step tasks, state a brief plan: + +```text +1. [Step] → verify: [check] +2. [Step] → verify: [check] +3. [Step] → verify: [check] +``` + +Strong success criteria let you loop independently. Weak criteria ("make it +work") require constant clarification. + +--- + +## Part B — ByteLyst Ecosystem Rules + +These extend Part A with ecosystem-specific discipline. They apply to every repo. + +### B1. Tests are sacred + +- **Never modify tests to make them pass.** Fix the source code, or stop and ask. +- **Never delete or weaken tests** without explicit user direction. +- When fixing a bug, add a regression test first. + +### B2. Verify before claiming done + +- Run the repo's documented `Build Verification` block (see each AGENTS.md § + "Build Verification") before reporting completion. +- If you cannot run verification, say so explicitly — don't claim "should work". +- For multi-repo changes, verify each affected repo. + +### B3. Never edit shared infrastructure casually + +- `.npmrc` is managed by `learning_ai_common_plat/scripts/npmrc.template`. + Never hand-edit. Use `bash scripts/sync-npmrc.sh`. +- `@bytelyst/*` packages live in `learning_ai_common_plat/packages/`. Changes + ripple across all products — flag cross-repo impact before editing. +- Agent docs (`AGENTS.md`, `.github/copilot-instructions.md`, etc.) are managed + by `learning_ai_common_plat/scripts/update-agent-docs.sh`. Never hand-edit + generated files. Edit the template or per-repo metadata instead. + +### B4. Logging and secrets + +- Never use `console.log` in production code — use `req.log` / `app.log` + (Fastify), `structlog` (Python), `os.Logger` (Swift). +- Never use `print()` in Swift. +- Never hardcode secrets, API keys, OAuth client IDs, or URLs. Use env vars or + Azure Key Vault. + +### B5. Cosmos discipline + +- Every Cosmos document MUST include a `productId` field. +- Use `PRODUCT_ID` from `@bytelyst/config` (or `shared/product.json`) — never + hardcode product IDs as string literals. + +### B6. Commit hygiene + +- Format: `type(scope): description` +- Types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore` +- Keep commits atomic. One logical change per commit. +- Run pre-commit hooks. Do not bypass with `--no-verify` unless asked. + +### B7. Style preservation + +- Never delete existing comments or documentation unless explicitly asked. +- Never add emojis unless explicitly asked. +- Match the existing code style of the file you're editing. + +--- + +## Part C — Tool-Specific Notes + +All AI coding tools should read this file. The conventions for how each tool +discovers it: + +- **Claude Code** — reads `AGENTS.md` (per-repo) which links here. +- **Cursor** — reads `AGENTS.md` (per-repo) which links here. Multi-root + workspace must include `learning_ai_common_plat` so the sibling path resolves. +- **Windsurf / Cascade** — reads `AGENTS.md` (per-repo). Workspace must + include `learning_ai_common_plat`. +- **GitHub Copilot** — reads `.github/copilot-instructions.md` (per-repo) + which points here. Copilot does not always follow cross-file references; the + pointer file is a best-effort. +- **OpenAI Codex** — reads `AGENTS.md` (per-repo). +- **Cline / Roo Code** — reads `AGENTS.md` (per-repo) via its standard agent + file discovery. +- **Aider** — `.aider.conf.yml` (per-repo) declares `read: AGENTS.md` and + `conventions: AGENTS.md`. + +If your tool does not appear here, default to reading `AGENTS.md` at the repo +root. + +--- + +## Maintenance + +- Edit this file in place. Changes take effect for every repo on next agent + invocation — no regeneration needed (it is referenced, not copied). +- After editing, run `bash scripts/check-agent-docs-drift.sh` from + `learning_ai_common_plat` to confirm no per-repo file has drifted out of sync. +- See `learning_ai_common_plat/.windsurf/workflows/repo_update-agent-docs.md` + for the full propagation workflow. diff --git a/AI.dev/SKILLS/agent-onboarding.md b/AI.dev/SKILLS/agent-onboarding.md new file mode 100644 index 00000000..a819ea9a --- /dev/null +++ b/AI.dev/SKILLS/agent-onboarding.md @@ -0,0 +1,77 @@ +# Agent Onboarding — Read Order + +> Quick index for AI coding agents joining any ByteLyst repo. +> Read these documents in the order shown before making changes. + +## 1. Universal behavior (ecosystem-wide, identical across every repo) + +[`agent-behavior-guidelines.md`](agent-behavior-guidelines.md) + +The canonical agent behavior contract — Karpathy's 4 rules (Think, Simplicity, +Surgical, Goal-Driven) plus 7 ByteLyst-specific rules (tests, verification, +shared infra, logging, Cosmos, commits, style). + +## 2. Per-repo context + +`/AGENTS.md` + +Each repo has its own `AGENTS.md` with: + +- Project identity (product name, ID, ports, domain) +- Repo layout +- Tech stack rules +- Coding conventions specific to that repo +- File ownership map +- Build & test commands + +## 3. Per-repo product manifest + +`/shared/product.json` + +Canonical product identity (product ID, display name, bundle IDs, etc.). +Loaded at runtime via `@bytelyst/config` or read directly by build tooling. + +## 4. Cross-repo automation playbook + +[`../../docs/devops/CODING_AGENT_AUTOMATION_PLAYBOOK.md`](../../docs/devops/CODING_AGENT_AUTOMATION_PLAYBOOK.md) + +Periodic maintenance tasks that span all repos (test audits, coverage, +dependency health, secret scans, typecheck sweeps). + +## 5. Skill libraries (this directory) + +Other files in [`AI.dev/SKILLS/`](.) are topic-specific playbooks +(architecture patterns, debugging, releases, testing, etc.). Read on demand, +not upfront. + +--- + +## How agent files compose + +```text +┌──────────────────────────────────────────────────────────────┐ +│ Single source of truth (this directory) │ +│ │ +│ agent-behavior-guidelines.md ← THE behavior contract │ +│ agent-onboarding.md ← this file │ +└──────────────────────────────────────────────────────────────┘ + ▲ + │ referenced (never copied) + │ +┌──────────────────────────────────────────────────────────────┐ +│ Per-repo files (one per repo) │ +│ │ +│ AGENTS.md ← repo-specific only │ +│ .github/copilot-instructions.md ← thin pointer │ +│ .aider.conf.yml ← Aider config │ +│ .editorconfig ← editor config │ +└──────────────────────────────────────────────────────────────┘ +``` + +No behavior rule lives in two files. Drift is impossible by construction. + +## Maintenance + +- Generator: `learning_ai_common_plat/scripts/update-agent-docs.sh` +- Drift check: `learning_ai_common_plat/scripts/check-agent-docs-drift.sh` +- Workflow: `learning_ai_common_plat/.windsurf/workflows/repo_update-agent-docs.md` diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index b058330d..00000000 --- a/CLAUDE.md +++ /dev/null @@ -1,33 +0,0 @@ -# CLAUDE.md — Compact Agent Reference - -Read [`AGENTS.md`](AGENTS.md) for full instructions. This file is a quick summary. - -## Identity - -- **Repo:** `learning_ai_common_plat` — shared `@bytelyst/*` packages + `@lysnrai/*` microservices -- **Consumers:** LysnrAI (voice dictation), MindLyst (multimodal memory) -- **Stack:** TypeScript, ESM, pnpm workspace, Fastify 5, Vitest, Azure Cosmos DB - -## Key Commands - -```bash -pnpm install && pnpm build && pnpm test # full verify -pnpm --filter @lysnrai/platform-service dev # run one service -pnpm --filter @bytelyst/design-tokens generate # regen tokens -``` - -## Critical Rules - -- Every Cosmos doc needs `productId` -- Every endpoint validates with Zod -- Services re-export `@bytelyst/*` in `src/lib/` files -- Services use self-contained Zod config (not from shared package) -- `@bytelyst/*` = packages, `@lysnrai/*` = services -- Use pnpm, never npm -- Commit format: `type(scope): description` - ---- - -## Cross-Repo Automation - -See [`docs/devops/CODING_AGENT_AUTOMATION_PLAYBOOK.md`](docs/devops/CODING_AGENT_AUTOMATION_PLAYBOOK.md) for periodic maintenance tasks: test audits, coverage gaps, dependency checks, secret scans, typecheck sweeps. diff --git a/scripts/check-agent-docs-drift.sh b/scripts/check-agent-docs-drift.sh new file mode 100755 index 00000000..ff46c8f8 --- /dev/null +++ b/scripts/check-agent-docs-drift.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash +# check-agent-docs-drift.sh — Fast drift check for per-repo agent docs. +# Exits 1 if any repo has drifted from the canonical pattern. +# +# Modelled on check-npmrc-drift.sh. Marker-based (no generator runs), +# so this is fast and side-effect-free. +# +# Usage: +# bash scripts/check-agent-docs-drift.sh +# +# What is checked per repo: +# 1. Legacy files MUST NOT exist (they used to duplicate AGENTS.md): +# .cursorrules, .windsurfrules, .clinerules, CLAUDE.md +# 2. AGENTS.md MUST contain the canonical-behavior-pointer marker. +# 3. .github/copilot-instructions.md MUST contain the AUTO-GENERATED marker +# AND a reference to the canonical guidelines file. +# 4. .aider.conf.yml MUST exist and reference AGENTS.md. +# 5. .editorconfig MUST exist with the canonical first line "root = true". +# +# Repair: bash scripts/update-agent-docs.sh + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPOS_TXT="${SCRIPT_DIR}/../.windsurf/workflows/repos.txt" +BASE_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)" + +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' + +if [[ ! -f "$REPOS_TXT" ]]; then + echo -e "${RED}❌ repos.txt not found: $REPOS_TXT${NC}" >&2 + exit 1 +fi + +LEGACY_FILES=(.cursorrules .windsurfrules .clinerules CLAUDE.md) +AGENTS_POINTER_MARKER="" +COPILOT_GENERATED_MARKER="" +COPILOT_CANONICAL_REF="agent-behavior-guidelines.md" + +drifted=0 +clean=0 +missing=0 + +REPOS=() +while IFS= read -r line; do + [[ "$line" =~ ^[[:space:]]*# ]] && continue + [[ -z "${line// }" ]] && continue + REPOS+=("$line") +done < "$REPOS_TXT" + +for repo in "${REPOS[@]}"; do + repo_dir="${BASE_DIR}/${repo}" + + if [[ ! -d "$repo_dir" ]]; then + continue + fi + if [[ ! -f "${repo_dir}/AGENTS.md" ]]; then + echo -e "${YELLOW}⚠️ $repo — AGENTS.md missing${NC}" + ((missing++)) || true + continue + fi + + issues=() + + # 1 — Legacy files must be gone. + for f in "${LEGACY_FILES[@]}"; do + if [[ -e "${repo_dir}/${f}" ]]; then + issues+=("legacy file still present: $f") + fi + done + + # 2 — AGENTS.md must have the canonical pointer block. + if ! grep -qF "$AGENTS_POINTER_MARKER" "${repo_dir}/AGENTS.md"; then + issues+=("AGENTS.md missing canonical-behavior-pointer block") + fi + + # 3 — Copilot file: must exist, must be AUTO-GENERATED, must reference canonical. + copilot="${repo_dir}/.github/copilot-instructions.md" + if [[ ! -f "$copilot" ]]; then + issues+=(".github/copilot-instructions.md missing") + else + if ! grep -qF "$COPILOT_GENERATED_MARKER" "$copilot"; then + issues+=(".github/copilot-instructions.md missing AUTO-GENERATED marker (hand-edited?)") + fi + if ! grep -qF "$COPILOT_CANONICAL_REF" "$copilot"; then + issues+=(".github/copilot-instructions.md missing reference to $COPILOT_CANONICAL_REF") + fi + fi + + # 4 — Aider config: must exist and reference AGENTS.md. + aider="${repo_dir}/.aider.conf.yml" + if [[ ! -f "$aider" ]]; then + issues+=(".aider.conf.yml missing") + elif ! grep -qF "AGENTS.md" "$aider"; then + issues+=(".aider.conf.yml does not reference AGENTS.md") + fi + + # 5 — Editorconfig: must exist with canonical first line. + editorconfig="${repo_dir}/.editorconfig" + if [[ ! -f "$editorconfig" ]]; then + issues+=(".editorconfig missing") + elif ! head -1 "$editorconfig" | grep -qE '^root = true$'; then + issues+=(".editorconfig first line not 'root = true' (hand-edited?)") + fi + + if [[ ${#issues[@]} -gt 0 ]]; then + echo -e "${RED}❌ $repo${NC}" + for i in "${issues[@]}"; do + echo " - $i" + done + ((drifted++)) || true + else + ((clean++)) || true + fi +done + +echo "────────────────────────────────" +echo -e "${GREEN}✅ $clean repos in sync${NC}" +[[ "$missing" -gt 0 ]] && echo -e "${YELLOW}⚠️ $missing repos missing AGENTS.md${NC}" +[[ "$drifted" -gt 0 ]] && echo -e "${RED}❌ $drifted repos drifted${NC}" +echo "" + +if [[ "$drifted" -gt 0 ]] || [[ "$missing" -gt 0 ]]; then + echo "Fix: bash scripts/update-agent-docs.sh" + exit 1 +fi + +echo "All repos in sync ✅" diff --git a/scripts/update-agent-docs.sh b/scripts/update-agent-docs.sh index 1e090113..eb784e0f 100755 --- a/scripts/update-agent-docs.sh +++ b/scripts/update-agent-docs.sh @@ -1,31 +1,48 @@ #!/usr/bin/env bash # scripts/update-agent-docs.sh # -# Regenerates AI agent config files across all repos listed in repos.txt. +# Maintains AI agent docs across the ByteLyst workspace with ZERO duplication. # -# Files always regenerated (overwritten): -# .cursorrules, .windsurfrules, .clinerules, .aider.conf.yml, -# .editorconfig, .github/copilot-instructions.md +# Architecture (locked 2026-05-23): +# Canonical source of behavior rules lives in ONE file: +# learning_ai_common_plat/AI.dev/SKILLS/agent-behavior-guidelines.md # -# Files created only if missing (never overwritten): -# CLAUDE.md — hand-crafted summary; script creates a placeholder if absent +# Per-repo files (managed by this script): +# AGENTS.md — repo-specific (hand-maintained). +# Script idempotently prepends a "Read first" +# pointer block pointing to the canonical file. +# .github/copilot-instructions.md — thin pointer (5 lines). Regenerated. +# .aider.conf.yml — Aider config (reads AGENTS.md). Regenerated. +# .editorconfig — editor config. Regenerated. # -# Files never touched: -# AGENTS.md — canonical source of truth; must be maintained manually +# Legacy files deleted by this script (they used to duplicate AGENTS.md content): +# .cursorrules, .windsurfrules, .clinerules, CLAUDE.md # # Usage: -# ./scripts/update-agent-docs.sh # regenerate + commit +# ./scripts/update-agent-docs.sh # apply changes + commit per repo # ./scripts/update-agent-docs.sh --dry-run # show what would change, no writes +# ./scripts/update-agent-docs.sh --no-commit # write files but don't git commit set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPOS_TXT="${SCRIPT_DIR}/../.windsurf/workflows/repos.txt" BASE_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)" +CANONICAL_REL_FROM_COMMON_PLAT="AI.dev/SKILLS/agent-behavior-guidelines.md" DRY_RUN=false +NO_COMMIT=false CHANGED_REPOS=() -[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true +for arg in "$@"; do + case "$arg" in + --dry-run) DRY_RUN=true ;; + --no-commit) NO_COMMIT=true ;; + -h|--help) + sed -n '2,25p' "${BASH_SOURCE[0]}" | sed 's/^# \?//' + exit 0 + ;; + esac +done # ── colours ──────────────────────────────────────────────────────────────── RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' @@ -33,27 +50,30 @@ BLUE='\033[0;34m'; CYAN='\033[0;36m'; NC='\033[0m' info() { echo -e "${BLUE}[INFO]${NC} $*"; } ok() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +err() { echo -e "${RED}[ERR]${NC} $*" >&2; } header(){ echo -e "\n${CYAN}══ $* ══${NC}"; } -# ── per-repo single-line metadata ────────────────────────────────────────── +# ── per-repo metadata (only fields still needed) ─────────────────────────── +# NAME — display name for headings +# ID — productId string +# STACK — short stack description +# BUILD_VFY — single command shown in copilot pointer & aider.conf +# LINT1-3 — optional lint commands for aider.conf +# AIDER_READ2 — second file aider should read alongside AGENTS.md set_meta() { - NAME="" ID="" TAGLINE="" STACK="" BUILD_VFY="" LINT1="" LINT2="" LINT3="" AIDER_READ2="README.md" + NAME="" ID="" STACK="" BUILD_VFY="" + LINT1="" LINT2="" LINT3="" AIDER_READ2="README.md" case "$1" in learning_ai_common_plat) - NAME="@bytelyst Common Platform" - ID="(product-agnostic)" - TAGLINE="Shared packages + microservices for the ByteLyst ecosystem" + NAME="@bytelyst Common Platform"; ID="(product-agnostic)" STACK="TypeScript, ESM, pnpm workspace, Fastify 5, Vitest, Azure Cosmos DB" BUILD_VFY="pnpm build && pnpm test && pnpm typecheck" LINT1="pnpm build 2>&1 | tail -10" LINT2="pnpm test 2>&1 | tail -10" LINT3="pnpm typecheck 2>&1 | tail -10" - AIDER_READ2="README.md" ;; learning_voice_ai_agent) - NAME="LysnrAI" - ID="lysnrai" - TAGLINE="Cross-platform voice-to-text dictation platform" + NAME="LysnrAI"; ID="lysnrai" STACK="Python 3.12 (desktop/backend) + Next.js 16 (dashboards) + Fastify 5 (microservices in sibling repo)" BUILD_VFY="python -m pytest tests/ -v --tb=short" LINT1="cd user-dashboard-web && npx tsc --noEmit 2>&1 | tail -10" @@ -61,9 +81,7 @@ set_meta() { AIDER_READ2="README_MONO_REPO.md" ;; learning_multimodal_memory_agents) - NAME="MindLyst" - ID="mindlyst" - TAGLINE="Role-Based Life OS — AI-powered multimodal second brain" + NAME="MindLyst"; ID="mindlyst" STACK="KMP (shared) + SwiftUI (iOS) + Jetpack Compose (Android) + Next.js 16 (web)" BUILD_VFY="./gradlew :shared:compileKotlinIosSimulatorArm64" LINT1="cd mindlyst-native && ./gradlew :shared:compileKotlinIosSimulatorArm64 2>&1 | tail -5" @@ -71,9 +89,7 @@ set_meta() { AIDER_READ2="ARCHITECTURE.md" ;; learning_ai_clock) - NAME="ChronoMind" - ID="chronomind" - TAGLINE="AI-Powered Contextual Clock & Timer" + NAME="ChronoMind"; ID="chronomind" STACK="Next.js 16 (web) + SwiftUI (iOS/Watch/Mac) + Jetpack Compose (Android) + Fastify 5 (backend)" BUILD_VFY="cd web && npm test && npm run typecheck && npm run build" LINT1="cd web && npm test 2>&1 | tail -10" @@ -81,9 +97,7 @@ set_meta() { AIDER_READ2="docs/PRD.md" ;; learning_ai_fastgap) - NAME="NomGap" - ID="nomgap" - TAGLINE="Fasting visualization and coaching app" + NAME="NomGap"; ID="nomgap" STACK="React Native (Expo SDK 55) + TypeScript + Fastify 5 (backend)" BUILD_VFY="npm test && npm run typecheck" LINT1="npm test 2>&1 | tail -10" @@ -91,9 +105,7 @@ set_meta() { AIDER_READ2="docs/PRD.md" ;; learning_ai_jarvis_jr) - NAME="JarvisJr" - ID="jarvisjr" - TAGLINE="Voice-first multi-agent coaching platform" + NAME="JarvisJr"; ID="jarvisjr" STACK="SwiftUI (iOS/Watch/Mac) + Next.js 16 (web) + Jetpack Compose (Android) + Fastify 5 (backend)" BUILD_VFY="cd web && npm test && npm run typecheck && npm run build" LINT1="cd web && npm test 2>&1 | tail -10" @@ -101,18 +113,14 @@ set_meta() { AIDER_READ2="docs/ENHANCED_IDEA_v2.md" ;; learning_ai_peakpulse) - NAME="PeakPulse" - ID="peakpulse" - TAGLINE="Sensor-driven adventure tracker for hikers and skiers" + NAME="PeakPulse"; ID="peakpulse" STACK="SwiftUI (iOS 17+), SwiftData, MapKit, WeatherKit, ActivityKit, WidgetKit, App Intents" BUILD_VFY="cd ios && xcodegen generate && xcodebuild -scheme PeakPulse -sdk iphonesimulator build" LINT1="cd ios && xcodebuild -scheme PeakPulse -sdk iphonesimulator build 2>&1 | tail -20" AIDER_READ2="docs/PRD.md" ;; learning_ai_notes) - NAME="ByteLyst Agentic Notes" - ID="bytelyst-notes" - TAGLINE="Agentic note-taking workspace for notes, tasks, relationships, and workspaces" + NAME="ByteLyst Agentic Notes"; ID="bytelyst-notes" STACK="Docs + Fastify 5 backend scaffold with TypeScript ESM and @bytelyst/* shared packages" BUILD_VFY="cd backend && npm test && npm run typecheck && npm run build" LINT1="cd backend && npm test 2>&1 | tail -10" @@ -121,9 +129,7 @@ set_meta() { AIDER_READ2="docs/ROADMAP.md" ;; learning_ai_flowmonk) - NAME="FlowMonk" - ID="flowmonk" - TAGLINE="Agent-first planning and execution platform" + NAME="FlowMonk"; ID="flowmonk" STACK="Next.js 16 (web) + React Native/Expo (mobile) + Fastify 5 (backend)" BUILD_VFY="cd backend && npm run typecheck && npm run build && cd ../web && npm run typecheck && npm run build && cd ../mobile && npm run typecheck" LINT1="cd backend && npm run typecheck 2>&1 | tail -10" @@ -132,9 +138,7 @@ set_meta() { AIDER_READ2="docs/ROADMAP.md" ;; learning_ai_trails) - NAME="ActionTrail" - ID="actiontrail" - TAGLINE="AI activity oversight platform" + NAME="ActionTrail"; ID="actiontrail" STACK="Next.js 16 (web) + Fastify 5 (backend) + TypeScript ESM" BUILD_VFY="cd backend && npm test && npm run typecheck && cd ../sdk && npm test && npm run typecheck && cd ../web && npm run typecheck" LINT1="cd backend && npm test 2>&1 | tail -10" @@ -143,84 +147,75 @@ set_meta() { AIDER_READ2="docs/roadmap.md" ;; learning_ai_local_memory_gpt) - NAME="Local Memory GPT" - ID="localmemgpt" - TAGLINE="Local-first AI chat with persistent memory, RAG, and multi-model compare" + NAME="Local Memory GPT"; ID="localmemgpt" STACK="Fastify 5 + TypeScript ESM (backend) + Next.js 16 (web) + SQLite + Ollama" BUILD_VFY="cd backend && npm test && npm run typecheck && npm run build && cd ../web && npm run typecheck && npm run build" LINT1="cd backend && npm test 2>&1 | tail -10" LINT2="cd backend && npm run typecheck 2>&1 | tail -10" LINT3="cd web && npm run typecheck 2>&1 | tail -10" - AIDER_READ2="README.md" ;; learning_ai_smart_auth) - NAME="ByteLyst SmartAuth" - ID="smartauth" - TAGLINE="Unified authentication and identity platform" + NAME="ByteLyst SmartAuth"; ID="smartauth" STACK="Design/docs repo extending platform-service auth, shared auth packages, and native SDKs" BUILD_VFY="cd ../learning_ai_common_plat && pnpm build && pnpm test && pnpm typecheck" LINT1="cd ../learning_ai_common_plat && pnpm build 2>&1 | tail -10" LINT2="cd ../learning_ai_common_plat && pnpm test 2>&1 | tail -10" LINT3="cd ../learning_ai_common_plat && pnpm typecheck 2>&1 | tail -10" - AIDER_READ2="README.md" ;; learning_ai_auth_app) - NAME="ByteLyst Auth" - ID="smartauth" - TAGLINE="Standalone companion app for ByteLyst authentication" + NAME="ByteLyst Auth"; ID="smartauth" STACK="SwiftUI (iOS/Watch) + Jetpack Compose (Android) — no separate backend" BUILD_VFY="cd ios && xcodegen generate && xcodebuild -scheme ByteLystAuth -sdk iphonesimulator build && cd ../android && ./gradlew :app:assembleDebug" LINT1="cd ios && xcodegen generate >/dev/null 2>&1 && xcodebuild -scheme ByteLystAuth -sdk iphonesimulator build 2>&1 | tail -20" LINT2="cd android && ./gradlew :app:assembleDebug 2>&1 | tail -20" - AIDER_READ2="README.md" ;; learning_ai_efforise) - NAME="EffoRise" - ID="efforise" - TAGLINE="Identity-based habit tracker" + NAME="EffoRise"; ID="efforise" STACK="Vite + React 19 SPA (client/) + Fastify 5 backend (backend/) + React Native/Expo (mobile/) + @bytelyst/* shared packages" BUILD_VFY="cd backend && pnpm test && pnpm run typecheck && pnpm run build" LINT1="cd backend && pnpm test 2>&1 | tail -10" LINT2="cd backend && pnpm run typecheck 2>&1 | tail -10" LINT3="cd backend && pnpm run build 2>&1 | tail -10" - AIDER_READ2="README.md" ;; learning_ai_local_llms) - NAME="Local LLM Lab" - ID="localllmlab" - TAGLINE="Personal local AI inference toolkit" + NAME="Local LLM Lab"; ID="localllmlab" STACK="Next.js 16 (dashboard) + Ollama + @bytelyst/llm-router + Python (TTS)" BUILD_VFY="cd dashboard && pnpm test && pnpm typecheck && pnpm build" LINT1="cd dashboard && pnpm test 2>&1 | tail -10" LINT2="cd dashboard && pnpm typecheck 2>&1 | tail -10" LINT3="cd dashboard && pnpm build 2>&1 | tail -10" - AIDER_READ2="README.md" ;; learning_ai_productivity_web) - NAME="Productivity Web" - ID="(internal)" - TAGLINE="Internal Next.js productivity tools portal" + NAME="Productivity Web"; ID="(internal)" STACK="Next.js 15 + React 19 + TailwindCSS" BUILD_VFY="npm run typecheck && npm run build" LINT1="npm run typecheck 2>&1 | tail -10" LINT2="npm run build 2>&1 | tail -10" - AIDER_READ2="README.md" + ;; + learning_ai_talk2obsidian) + NAME="Talk2Obs"; ID="talk2obs" + STACK="Fastify 5 + TypeScript ESM (backend) + Vite + React 19 (web) + SQLite + Ollama + whisper-cpp" + BUILD_VFY="cd backend && npm test && npm run typecheck" + LINT1="cd backend && npm test 2>&1 | tail -10" + LINT2="cd backend && npm run typecheck 2>&1 | tail -10" + AIDER_READ2="docs/ROADMAP.md" + ;; + learning_ai_mac_tooling) + NAME="Mac Tooling"; ID="(internal)" + STACK="Python (FastAPI backend) + Vite + React (dashboard) + SQLite + Swift (menu bar)" + BUILD_VFY="cd dashboard && npm run build" + LINT1="cd dashboard && npm run build 2>&1 | tail -10" ;; oss/learning_ai_claw-code-oss) - NAME="Claw Code OSS" - ID="(upstream)" - TAGLINE="Upstream Claude Code OSS fork — runtime, API, and tools crates" + NAME="Claw Code OSS"; ID="(upstream)" STACK="Rust (workspace) + Python + TypeScript" BUILD_VFY="cargo build --workspace && cargo test --workspace" LINT1="cargo fmt --check 2>&1 | tail -10" LINT2="cargo clippy --workspace --all-targets -- -D warnings 2>&1 | tail -10" LINT3="cargo test --workspace 2>&1 | tail -10" - AIDER_READ2="README.md" ;; oss/learning_ai_claw-cowork) - NAME="Claw Cowork" - ID="clawcowork" - TAGLINE="Desktop agent for complex multi-step knowledge work with Docker sandboxing" + NAME="Claw Cowork"; ID="clawcowork" STACK="Rust (workspace) + React/TypeScript (Tauri frontend) + Python (skills server)" BUILD_VFY="cargo build --workspace && cargo test --workspace" LINT1="cargo fmt --check 2>&1 | tail -10" @@ -229,294 +224,31 @@ set_meta() { AIDER_READ2="COWORK.md" ;; *) - warn "Unknown repo: $1 — skipping" - return 1 + warn "Unknown repo: $1 — using minimal defaults" + NAME="$1"; ID="(unknown)" + STACK="(see AGENTS.md)" + BUILD_VFY="(see AGENTS.md)" ;; esac } -# ── per-repo multi-line content ───────────────────────────────────────────── -repo_rules() { - case "$1" in - learning_ai_common_plat) - echo "- Package manager: pnpm — NEVER use npm" - echo "- ESM everywhere: \"type\": \"module\", .js extensions in imports" - echo "- Fastify module pattern: types.ts → repository.ts → routes.ts" - echo "- Use req.log / app.log — never console.log" - echo "- Every Cosmos document MUST include a productId field" - echo "- peerDependencies for heavy deps; workspace:* for inter-package deps" - echo "- Services re-export @bytelyst/* in src/lib/ for clean internal imports" - ;; - learning_voice_ai_agent) - echo "- Python: structlog (never print), ruff lint, type hints required, pydantic-settings" - echo "- TypeScript: App Router (not Pages), @bytelyst/api-client for service clients" - echo "- All Cosmos documents MUST include productId field" - echo "- Use PRODUCT_ID from @bytelyst/config — never hardcode \"lysnrai\"" - echo "- Dashboards: TailwindCSS v4, shadcn/ui, Recharts" - echo "- Desktop build requires --webpack flag for Next.js" - ;; - learning_multimodal_memory_agents) - echo "- ALL business logic in shared/src/commonMain/ — NEVER in platform UI code" - echo "- Android/iOS/Web are thin UI shells consuming shared repositories via StateFlow" - echo "- Koin for DI — register all new deps in SharedModule.kt" - echo "- MindLystTokens.kt is the single source of design tokens" - echo "- Web: Pages Router, vanilla CSS with --ml-* props, NO Tailwind" - echo "- Use compilerOptions {} (not deprecated kotlinOptions {})" - echo "- Use StateFlow for observable state, never LiveData" - ;; - learning_ai_clock) - echo "- Web engine logic in web/src/lib/ — pure TS, no React imports" - echo "- Components in web/src/components/ — React UI only" - echo "- iOS shared logic in ios/ChronoMind/Shared/ — consumed by all Apple targets" - echo "- Android engine in android/.../engine/ — pure Kotlin, no Android framework deps" - echo "- Web build: must use --webpack flag (Serwist incompatible with Turbopack)" - echo "- Every Cosmos doc: productId: \"chronomind\"" - echo "- Theme: --cm-* CSS custom properties (web), ChronoMindTheme (native)" - ;; - learning_ai_fastgap) - echo "- All engine logic in src/lib/ — zero React Native imports" - echo "- Screens are thin composites wiring store + engines + components" - echo "- Theme tokens from src/theme/ — never hardcode colors, spacing, or fonts" - echo "- Expo native modules mocked in __mocks__/ for Vitest" - echo "- Engine modules are pure functions — testable without mocking RN" - echo "- Every Cosmos doc: productId: \"nomgap\"" - ;; - learning_ai_jarvis_jr) - echo "- iOS shared logic in ios/JarvisJr/Shared/ — consumed by iOS, Watch, Mac" - echo "- Web engine in web/src/lib/ — pure TS, no React imports" - echo "- Web components in web/src/components/ — React UI only" - echo "- Android engine in android/.../engine/ — pure Kotlin, no Android framework deps" - echo "- Web build: must use --webpack flag (Serwist incompatible with Turbopack)" - echo "- Never use print() in Swift — use os.Logger" - echo "- Theme: --jj-* CSS custom properties (web), JarvisJrTheme (native)" - echo "- Every Cosmos doc: productId: \"jarvisjr\"" - ;; - learning_ai_peakpulse) - echo "- Models in ios/PeakPulse/Models/ — SwiftData @Model + Codable structs" - echo "- Services in ios/PeakPulse/Services/ — pure Swift engine logic" - echo "- ViewModels in ios/PeakPulse/ViewModels/ — @Observable MVVM" - echo "- Platform/ files are thin wrappers over ByteLystPlatformSDK — never reimplement" - echo "- All logging via os.Logger — never use print()" - echo "- All colors from PeakPulseTheme — never hardcode" - echo "- Every Cosmos doc: productId: \"peakpulse\"" - ;; - learning_ai_notes) - echo "- Backend follows the ByteLyst product-backend pattern with Fastify 5 + TypeScript ESM" - echo "- Use @bytelyst/* shared packages instead of reimplementing common infrastructure" - echo "- Fastify modules follow types.ts → repository.ts → routes.ts" - echo "- Use req.log / app.log — never console.log" - echo "- Every Cosmos document MUST include productId: \"bytelyst-notes\"" - echo "- Keep docs aligned with implementation as the repo evolves from scaffold to product" - ;; - learning_ai_flowmonk) - echo "- Backend is authoritative for ALL planning logic — clients never implement scheduling rules" - echo "- Backend modules follow types.ts → repository.ts → routes.ts" - echo "- Web engine logic in web/src/lib/ — pure TS, no React imports" - echo "- Mobile engine logic in mobile/src/lib/ — pure TS, no React Native imports" - echo "- Every Cosmos document MUST include productId: \"flowmonk\"" - ;; - learning_ai_trails) - echo "- Backend modules follow types.ts → repository.ts → routes.ts" - echo "- Use req.log / app.log — never console.log" - echo "- Web engine logic in web/src/lib/ — pure TS, no React imports" - echo "- Every Cosmos document MUST include productId: \"actiontrail\"" - echo "- Use productConfig.productId — never hardcode product IDs" - ;; - learning_ai_local_memory_gpt) - echo "- Backend modules follow types.ts → repository.ts → routes.ts" - echo "- Use req.log / app.log — never console.log" - echo "- ESM everywhere: \"type\": \"module\", .js extensions in imports" - echo "- Theme tokens use --lmg-* CSS custom properties" - echo "- Use productConfig.productId — never hardcode localmemgpt" - ;; - learning_ai_smart_auth) - echo "- SmartAuth is NOT a separate service — it extends platform-service" - echo "- Auth work belongs in platform-service/src/modules/auth/ and shared auth packages" - echo "- Use req.log / app.log — never console.log in implementation repos" - echo "- Every Cosmos document MUST include a productId field" - echo "- Never hardcode OAuth client IDs or secrets" - ;; - learning_ai_auth_app) - echo "- Use BLAuthClient from platform SDKs — never reimplement auth logic" - echo "- Use BLAuthUI views — never build custom auth UI" - echo "- All logging via os.Logger in Swift — never print()" - echo "- Theme via BLAuthUIConfig (iOS) / MaterialTheme (Android)" - echo "- Never create a separate backend — app talks to platform-service" - ;; - learning_ai_efforise) - echo "- Backend follows the ByteLyst product-backend pattern with Fastify 5 + TypeScript ESM" - echo "- Use @bytelyst/* shared packages instead of reimplementing common infrastructure" - echo "- Fastify modules follow types.ts → repository.ts → routes.ts" - echo "- Use req.log / app.log — never console.log" - echo "- Every Cosmos document MUST include productId: \"efforise\"" - echo "- Theme tokens use --er-* CSS custom properties — never hardcode colors" - ;; - learning_ai_local_llms) - echo "- Dashboard uses server-side routing — keep UI as thin client" - echo "- @bytelyst/llm-router from Gitea npm registry (not file: ref)" - echo "- Never commit model weights (.gguf, .bin, .safetensors)" - echo "- Never hardcode Ollama URLs — use OLLAMA_HOST env var" - echo "- Corporate proxy: use hf-mirror.com instead of huggingface.co" - echo "- CSS tokens use --llm-* prefix" - ;; - learning_ai_productivity_web) - echo "- App Router pages live in src/app/" - echo "- Reusable UI lives in src/components/" - echo "- Shared utilities live in src/lib/" - echo "- Keep UI changes thin and tool-registry-driven where possible" - echo "- Avoid inventing APIs or hidden backend contracts" - ;; - oss/learning_ai_claw-code-oss) - echo "- Upstream claw-code fork — do NOT add custom features here" - echo "- Periodically pull from upstream and merge" - echo "- Rust crates: runtime, api, tools (consumed by claw-cowork)" - echo "- Python client: tests/, scripts/" - echo "- TypeScript SDK: ts-sdk/" - ;; - oss/learning_ai_claw-cowork) - echo "- Docker-first sandbox — native VM backends are stubs" - echo "- Python skills inside sandbox for document processing" - echo "- Tauri v2 for desktop GUI — Rust backend + React frontend" - echo "- Async architecture — bollard (Docker API) is async" - echo "- Base64 encoding for file content passed to sandbox" - echo "- Use conventional commit prefixes: feat(), fix(), docs:, test:, refactor:" - ;; - esac -} - -repo_paths() { - case "$1" in - learning_ai_common_plat) - echo "- packages/ — @bytelyst/* shared libraries (errors, cosmos, config, auth, api-client, fastify-core, react-auth, logger, testing, blob, extraction, monitoring, design-tokens)" - echo "- services/platform-service/ — consolidated platform service (port 4003)" - echo "- services/extraction-service/ — text extraction + Python sidecar (port 4005)" - echo "- dashboards/admin-web/ — admin console (port 3001)" - echo "- dashboards/tracker-web/ — issue tracker (port 3003)" - ;; - learning_voice_ai_agent) - echo "- src/ — Desktop app (Python 3.12, tkinter, Azure Speech SDK)" - echo "- backend/ — Fastify 5 + TypeScript backend (port 4015)" - echo "- user-dashboard-web/ — Next.js 16 user portal (port 3002)" - echo "- ../learning_ai_common_plat/services/ — platform-service (4003), extraction-service (4005)" - echo "- ../learning_ai_common_plat/dashboards/ — admin-web (3001), tracker-web (3003)" - echo "- mobile_app/ios/ — Swift + SwiftUI" - echo "- mobile_app/android/ — Kotlin + Jetpack Compose" - ;; - learning_multimodal_memory_agents) - echo "- mindlyst-native/shared/src/commonMain/ — KMP shared logic (ALL business logic)" - echo "- mindlyst-native/androidApp/ — Jetpack Compose Android app" - echo "- mindlyst-native/iosApp/ — SwiftUI iOS app" - echo "- mindlyst-native/web/ — Next.js 16 web dashboard" - echo "- backend/ — Fastify 5 + TypeScript backend (port 4014)" - echo "- design-system/ — design tokens source" - ;; - learning_ai_clock) - echo "- web/src/lib/ — Pure TS engine modules (timer, cascade, urgency, nl-parser, etc.)" - echo "- web/src/components/ — React UI components" - echo "- ios/ChronoMind/Shared/ — Shared Swift code (iOS + Watch + Mac + Widgets)" - echo "- android/app/.../engine/ — Pure Kotlin engine" - echo "- backend/ — Fastify 5 + TypeScript backend (port 4011)" - ;; - learning_ai_fastgap) - echo "- src/lib/ — Pure engine modules (NO React Native deps)" - echo "- src/screens/ — Screen components (thin UI composites)" - echo "- src/components/ — Reusable UI components" - echo "- src/store/ — Zustand store" - echo "- src/theme/ — Design tokens (colors, typography, spacing)" - echo "- backend/ — Fastify 5 + TypeScript backend (port 4013)" - ;; - learning_ai_jarvis_jr) - echo "- ios/JarvisJr/Shared/ — Cross-platform Swift code (iOS + Watch + Mac)" - echo "- web/src/lib/ — Pure TS engine + API clients" - echo "- web/src/app/ — Next.js App Router pages" - echo "- android/app/.../engine/ — Pure Kotlin engine" - echo "- backend/ — Fastify 5 + TypeScript backend (port 4012)" - ;; - learning_ai_peakpulse) - echo "- ios/PeakPulse/Models/ — SwiftData models" - echo "- ios/PeakPulse/Services/ — Pure Swift engine logic" - echo "- ios/PeakPulse/ViewModels/ — @Observable MVVM" - echo "- ios/PeakPulse/Views/ — SwiftUI screens + components" - echo "- ios/PeakPulse/Platform/ — ByteLystPlatformSDK thin wrappers" - echo "- backend/ — Fastify 5 + TypeScript backend (port 4010)" - ;; - learning_ai_notes) - echo "- docs/ — PRD, roadmap, and planning docs" - echo "- backend/ — Fastify 5 + TypeScript ESM backend scaffold (port 4016)" - echo "- backend/src/modules/ — notes, workspaces, note-relationships, note-tasks" - echo "- backend/src/lib/ — shared backend wiring and utilities" - ;; - learning_ai_flowmonk) - echo "- backend/ — Fastify 5 + TypeScript ESM backend (port 4017)" - echo "- web/src/lib/ — Pure TS engine modules" - echo "- web/src/app/ — Next.js App Router pages" - echo "- mobile/src/lib/ — Pure TS engine modules" - echo "- mobile/src/app/ — Expo Router screens" - ;; - learning_ai_trails) - echo "- backend/src/lib/ — shared backend wiring, events, RBAC, risk scoring" - echo "- backend/src/modules/ — actions, alerts, agents, approvals, traces, connectors, reverts" - echo "- web/src/lib/ — typed API clients and product config" - echo "- web/src/components/ — React UI components" - echo "- sdk/src/ — ActionTrail SDK and middleware" - ;; - learning_ai_local_memory_gpt) - echo "- backend/src/lib/ — config, sqlite, ollama, llm, SSE helpers" - echo "- backend/src/modules/ — conversations, messages, chat, models, documents, search, compare" - echo "- web/src/lib/ — typed API client, store, config, telemetry" - echo "- web/src/components/ — chat/search/documents/settings UI" - echo "- shared/product.json — canonical product identity" - ;; - learning_ai_smart_auth) - echo "- docs/ — PRD, roadmap, coding agent prompts" - echo "- shared/product.json — canonical product identity" - echo "- implementation happens in ../learning_ai_common_plat/services/platform-service/src/modules/auth/" - echo "- implementation happens in ../learning_ai_common_plat/packages/auth* and native SDKs" - ;; - learning_ai_auth_app) - echo "- ios/ByteLystAuth/App/ — entry point + ContentView" - echo "- ios/ByteLystAuth/Screens/ — dashboard, approvals, TOTP, devices, settings" - echo "- android/app/src/main/kotlin/com/bytelyst/auth/ — Compose screens + navigation" - echo "- shared/product.json — canonical product identity" - echo "- ios/project.yml and android/ build files — native project wiring" - ;; - learning_ai_efforise) - echo "- client/ — Vite + React 19 SPA" - echo "- backend/ — Fastify 5 + TypeScript ESM backend (port 4020)" - echo "- backend/src/modules/ — identities, efforts, habits, streaks, insights" - echo "- mobile/ — React Native + Expo (SDK 55) companion app" - echo "- mobile/src/app/(tabs)/ — 5-tab navigator (Home, Identity, Log, Insights, Settings)" - ;; - learning_ai_local_llms) - echo "- dashboard/ — Mission Control Next.js 16 app" - echo "- dashboard/src/app/api/ — Ollama proxy, Whisper, TTS, system info" - echo "- dashboard/src/app/(mission-control)/ — System overview, model management" - echo "- tts/ — TTS setup scripts + experiments" - echo "- scripts/ — start-dashboard.sh + windows setup" - echo "- experiments/ — oss-llm, open-claw, voicebox" - ;; - learning_ai_productivity_web) - echo "- src/app/ — App Router pages and routes" - echo "- src/components/ — Navbar and tool cards" - echo "- src/lib/ — utility and tool registry helpers" - echo "- next.config.ts, tailwind.config.ts — web app configuration" - ;; - oss/learning_ai_claw-code-oss) - echo "- rust/crates/runtime/ — ConversationRuntime, Session, PermissionPolicy" - echo "- rust/crates/api/ — AnthropicClient, AuthSource, SSE streaming" - echo "- rust/crates/tools/ — ToolSpec, tool dispatch" - echo "- python/ — Python client SDK" - echo "- ts-sdk/ — TypeScript SDK" - ;; - oss/learning_ai_claw-cowork) - echo "- crates/cowork-vm/ — Sandbox lifecycle (Docker, VZ abstraction)" - echo "- crates/cowork-orchestrator/ — Task coordination, LLM planner, plugins, MCP" - echo "- crates/cowork-skills/ — Rust↔Python bridge for document processing" - echo "- crates/cowork-desktop/ — Tauri v2 desktop app (Rust + React)" - echo "- docker/ — Dockerfile + Python skills server" - echo "- connectors/ — MCP connector servers (Google Drive, Gmail, GCal, Slack)" - ;; - esac +# Compute relative path from a repo to the canonical guidelines file. +# Repos at workspace root (depth 0) → ../learning_ai_common_plat/... +# Repos one level deep (e.g. oss/foo, depth 1) → ../../learning_ai_common_plat/... +# common_plat itself → AI.dev/SKILLS/... +canonical_path_for() { + local repo="$1" + if [[ "$repo" == "learning_ai_common_plat" ]]; then + echo "${CANONICAL_REL_FROM_COMMON_PLAT}" + return + fi + local slashes="${repo//[^\/]/}" + local depth=${#slashes} + local prefix="" + for ((i=0; i<=depth; i++)); do + prefix+="../" + done + echo "${prefix}learning_ai_common_plat/${CANONICAL_REL_FROM_COMMON_PLAT}" } # ── file generators ───────────────────────────────────────────────────────── @@ -538,99 +270,20 @@ trim_trailing_whitespace = false EOF } -write_cursorrules() { - local dest="$1" repo="$2" - local RULES PATHS - RULES=$(repo_rules "$repo") - PATHS=$(repo_paths "$repo") - cat > "$dest" << EOF -# ${NAME} — Cursor Rules -# Read AGENTS.md for full context. - -Project: ${NAME} — ${TAGLINE} -Product ID: ${ID} -Stack: ${STACK} - -## Architecture -${PATHS} - -## Rules -${RULES} -- Commits: feat(scope): description / fix(scope): description -- Never delete existing comments/documentation unless asked -- Never add emojis unless asked -- Never hardcode secrets, colors, or API URLs - -## Build Verification -- ${BUILD_VFY} - -## Key Documents -- AGENTS.md — Full AI agent instructions (read this first) -EOF -} - -write_windsurfrules() { - local dest="$1" repo="$2" - local RULES PATHS - RULES=$(repo_rules "$repo") - PATHS=$(repo_paths "$repo") - cat > "$dest" << EOF -# ${NAME} — Windsurf / Codeium Rules -# Read AGENTS.md for full context. These are the critical rules. - -Project: ${NAME} — ${TAGLINE} -Stack: ${STACK} - -## Architecture Rules -${PATHS} - -## Conventions -${RULES} -- Commits: feat(scope): description / fix(scope): description - -## Build Verification -- ${BUILD_VFY} -EOF -} - -write_clinerules() { - local dest="$1" repo="$2" - local RULES PATHS - RULES=$(repo_rules "$repo") - PATHS=$(repo_paths "$repo") - cat > "$dest" << EOF -# .clinerules — Cline / Roo Code Rules for ${NAME} -# Read AGENTS.md for the complete onboarding guide. - -## Project: ${NAME} — ${TAGLINE} -Architecture: ${STACK} - -## Mandatory Rules -${RULES} -- Commits: \`type(scope): description\` -- After changes, verify: \`${BUILD_VFY}\` - -## Key File Locations -${PATHS} -- Full guide: \`AGENTS.md\` -EOF -} - write_aider_conf() { local dest="$1" - # Build lint-cmd list (skip empty entries) local lint_block="" for cmd in "${LINT1:-}" "${LINT2:-}" "${LINT3:-}"; do [[ -z "$cmd" ]] && continue lint_block+=" - '${cmd}'"$'\n' done - # Build read list local read_block=" - AGENTS.md"$'\n' [[ -n "${AIDER_READ2:-}" ]] && read_block+=" - ${AIDER_READ2}"$'\n' cat > "$dest" << EOF # .aider.conf.yml — Aider Configuration for ${NAME} -# Helps Aider understand the project structure and conventions. +# Auto-generated by learning_ai_common_plat/scripts/update-agent-docs.sh +# Hand-edit will be overwritten on next run. read: ${read_block} @@ -642,86 +295,126 @@ auto-commits: false EOF } -write_copilot_instructions() { - local dest_dir="$1" repo="$2" - local RULES PATHS - RULES=$(repo_rules "$repo") - PATHS=$(repo_paths "$repo") +write_copilot_pointer() { + local dest_dir="$1" canonical="$2" mkdir -p "$dest_dir" cat > "${dest_dir}/copilot-instructions.md" << EOF + + + # GitHub Copilot Instructions — ${NAME} -> For full agent instructions, read [\`AGENTS.md\`](../AGENTS.md) at the repo root. +**Project:** ${NAME} — \`${ID}\` +**Stack:** ${STACK} -## Project Context +## Read these (in order) before suggesting code -**${NAME}** — ${TAGLINE}. -Stack: ${STACK} +1. **\`AGENTS.md\`** at the repo root — repo-specific layout, conventions, + build commands, file ownership. +2. **\`${canonical}\`** — + ecosystem-wide agent behavior rules (Karpathy + ByteLyst). Identical + across every repo in the workspace. -## Code Generation Rules +Both files together are the complete contract. This pointer file contains +no rules of its own to avoid duplication and drift. -### Always -${RULES} -- Include \`productId: "${ID}"\` in every Cosmos DB document -- Use \`type(scope): description\` commit message format -- Fix source code, not tests (unless the test itself is wrong) +## Quick verification command -### Never -- \`console.log\` or \`print()\` in production code -- Hardcoded secrets, API keys, colors, or URLs -- Delete existing comments or documentation unless explicitly asked -- Add emojis unless asked - -## Key Paths -${PATHS} - -## Build Verification \`\`\`bash ${BUILD_VFY} \`\`\` EOF } -write_claude_placeholder() { - local dest="$1" repo="$2" - local PATHS - PATHS=$(repo_paths "$repo") - cat > "$dest" << EOF -# ${NAME} — Claude Code Instructions +# Idempotently prepend a "Read first" pointer block to AGENTS.md. +# The block is delimited by HTML comment markers so we can re-find and +# replace it without touching the rest of AGENTS.md. +# +# Note: awk's -v does not preserve literal newlines reliably, so the +# replacement block is written to a temp file and slurped via getline. +prepend_agents_pointer() { + local agents_md="$1" canonical="$2" + [[ ! -f "$agents_md" ]] && return 0 -> This file is read automatically by Claude Code. For full agent instructions -> shared across all AI tools, see [\`AGENTS.md\`](AGENTS.md). + local begin_marker="" + local end_marker="" -## Quick Context - -**Product:** ${NAME} — ${TAGLINE} -**Product ID:** \`${ID}\` -**Stack:** ${STACK} - -## Rules - -1. **Read \`AGENTS.md\` first** — it has coding conventions, file ownership, and tech stack rules. -2. **Every Cosmos document** must have a \`productId: "${ID}"\` field. -3. **Commit messages:** \`type(scope): description\` (feat, fix, docs, refactor, test, chore). -4. **Fix source, not tests** — unless the test itself is wrong. -5. **Never use** \`console.log\`, \`print()\`, or hardcoded colors/secrets/URLs. - -## Architecture - -${PATHS} - -## Build Verification - -\`\`\`bash -${BUILD_VFY} -\`\`\` + local tmp_block + tmp_block="$(mktemp)" + cat > "$tmp_block" << EOF +${begin_marker} +> **Read first (ecosystem-wide agent behavior):** +> [\`${canonical}\`](${canonical}) +> +> The link above is the single source of truth for agent behavior across every +> ByteLyst repo (Karpathy + ByteLyst rules: tests sacred, verify before done, +> no shared-infra hand-edits, no \`console.log\`/\`print\`, productId on every +> Cosmos doc, conventional commits, style preservation). +> +> The per-repo content below extends — never duplicates — the canonical rules. +${end_marker} EOF + + if grep -qF "$begin_marker" "$agents_md"; then + # Replace existing block in place. + awk -v begin="$begin_marker" -v endm="$end_marker" -v block_file="$tmp_block" ' + BEGIN { + while ((getline line < block_file) > 0) { + new = (new == "" ? line : new "\n" line) + } + close(block_file) + in_block = 0 + } + $0 == begin { print new; in_block = 1; next } + in_block && $0 == endm { in_block = 0; next } + !in_block { print } + ' "$agents_md" > "${agents_md}.tmp" && mv "${agents_md}.tmp" "$agents_md" + else + # Insert after first H1 (line beginning with "# "). If no H1, prepend. + if grep -qE '^# ' "$agents_md"; then + awk -v block_file="$tmp_block" ' + BEGIN { + while ((getline line < block_file) > 0) { + block = (block == "" ? line : block "\n" line) + } + close(block_file) + inserted = 0 + } + { print } + !inserted && /^# / { print ""; print block; inserted = 1 } + ' "$agents_md" > "${agents_md}.tmp" && mv "${agents_md}.tmp" "$agents_md" + else + { cat "$tmp_block"; echo ""; cat "$agents_md"; } > "${agents_md}.tmp" \ + && mv "${agents_md}.tmp" "$agents_md" + fi + fi + + rm -f "$tmp_block" +} + +# Delete legacy agent files (replaced by the canonical pointer architecture). +delete_legacy_files() { + local repo_dir="$1" + local deleted=() + for f in .cursorrules .windsurfrules .clinerules CLAUDE.md; do + local target="${repo_dir}/${f}" + [[ ! -e "$target" ]] && continue + if git -C "$repo_dir" ls-files --error-unmatch "$f" >/dev/null 2>&1; then + git -C "$repo_dir" rm -q "$f" 2>/dev/null || rm -f "$target" + else + rm -f "$target" + fi + deleted+=("$f") + done + if [[ ${#deleted[@]} -gt 0 ]]; then + ok "deleted legacy: ${deleted[*]}" + fi } # ── main loop ─────────────────────────────────────────────────────────────── if [[ ! -f "$REPOS_TXT" ]]; then - echo -e "${RED}[ERROR]${NC} repos.txt not found at: ${REPOS_TXT}" + err "repos.txt not found at: ${REPOS_TXT}" exit 1 fi @@ -731,9 +424,11 @@ while IFS= read -r line; do [[ -z "${line// }" ]] && continue REPOS+=("$line") done < "$REPOS_TXT" + info "Base directory: ${BASE_DIR}" info "Repos to process: ${#REPOS[@]}" $DRY_RUN && warn "DRY RUN — no files will be written or committed" +$NO_COMMIT && info "NO-COMMIT mode — files will be written but not committed" for REPO in "${REPOS[@]}"; do header "$REPO" @@ -744,60 +439,62 @@ for REPO in "${REPOS[@]}"; do continue fi - if ! set_meta "$REPO"; then - continue - fi + set_meta "$REPO" + CANONICAL_PATH="$(canonical_path_for "$REPO")" + info "canonical pointer → ${CANONICAL_PATH}" if [[ ! -f "${REPO_DIR}/AGENTS.md" ]]; then - warn "AGENTS.md not found in ${REPO} — skipping (run manually to bootstrap)" + warn "AGENTS.md not found in ${REPO} — skipping (bootstrap AGENTS.md manually first)" continue fi if $DRY_RUN; then - info "Would generate agent docs for ${NAME} (${ID})" - info " build: ${BUILD_VFY}" + info "Would: delete legacy files, rewrite copilot pointer, prepend AGENTS.md pointer" + info " regenerate .editorconfig and .aider.conf.yml" continue fi - # .editorconfig — always overwrite (identical across all repos) + # 1. Delete legacy files (.cursorrules, .windsurfrules, .clinerules, CLAUDE.md) + delete_legacy_files "$REPO_DIR" + + # 2. Regenerate small config files write_editorconfig "${REPO_DIR}/.editorconfig" ok ".editorconfig" - # .cursorrules — always overwrite - write_cursorrules "${REPO_DIR}/.cursorrules" "$REPO" - ok ".cursorrules" - - # .windsurfrules — always overwrite - write_windsurfrules "${REPO_DIR}/.windsurfrules" "$REPO" - ok ".windsurfrules" - - # .clinerules — always overwrite - write_clinerules "${REPO_DIR}/.clinerules" "$REPO" - ok ".clinerules" - - # .aider.conf.yml — always overwrite write_aider_conf "${REPO_DIR}/.aider.conf.yml" ok ".aider.conf.yml" - # .github/copilot-instructions.md — always overwrite - write_copilot_instructions "${REPO_DIR}/.github" "$REPO" - ok ".github/copilot-instructions.md" + # 3. Rewrite copilot pointer (thin, no rules) + write_copilot_pointer "${REPO_DIR}/.github" "$CANONICAL_PATH" + ok ".github/copilot-instructions.md (pointer)" - # CLAUDE.md — create only if missing - if [[ ! -f "${REPO_DIR}/CLAUDE.md" ]]; then - write_claude_placeholder "${REPO_DIR}/CLAUDE.md" "$REPO" - ok "CLAUDE.md (created — was missing)" - else - info "CLAUDE.md exists — skipping (hand-crafted; delete to regenerate)" + # 4. Idempotently prepend canonical pointer to AGENTS.md + prepend_agents_pointer "${REPO_DIR}/AGENTS.md" "$CANONICAL_PATH" + ok "AGENTS.md (pointer block ensured)" + + # 5. Commit if there are any changes in this repo + if $NO_COMMIT; then + info "Skipping commit (--no-commit)" + continue fi - # Commit if there are any changes in this repo if git -C "$REPO_DIR" status --porcelain 2>/dev/null | grep -q .; then - git -C "$REPO_DIR" add \ - .editorconfig .cursorrules .windsurfrules .clinerules \ - .aider.conf.yml CLAUDE.md .github/copilot-instructions.md \ - 2>/dev/null || true - if git -C "$REPO_DIR" commit -m "chore(docs): regenerate AI agent config files" \ + # Stage only paths that currently exist (legacy file deletes are already + # staged by `git rm` inside delete_legacy_files()). + for f in .editorconfig .aider.conf.yml AGENTS.md .github/copilot-instructions.md; do + [[ -e "${REPO_DIR}/${f}" ]] && git -C "$REPO_DIR" add "$f" 2>/dev/null || true + done + if git -C "$REPO_DIR" commit -m "chore(docs): consolidate agent docs to single source of truth + +- Delete legacy .cursorrules, .windsurfrules, .clinerules, CLAUDE.md + (content duplicated AGENTS.md; replaced by canonical pointer architecture) +- Rewrite .github/copilot-instructions.md as thin pointer to AGENTS.md + and the canonical agent-behavior-guidelines.md +- Prepend canonical 'Read first' pointer block to AGENTS.md +- Regenerate .editorconfig and .aider.conf.yml + +Canonical source: learning_ai_common_plat/AI.dev/SKILLS/agent-behavior-guidelines.md +Managed by: learning_ai_common_plat/scripts/update-agent-docs.sh" \ --no-verify 2>/dev/null; then ok "Committed changes in ${REPO}" CHANGED_REPOS+=("$REPO") @@ -817,10 +514,10 @@ if [[ ${#CHANGED_REPOS[@]} -gt 0 ]]; then echo " • $r" done echo "" - info "Push with:" + info "Push when ready:" for r in "${CHANGED_REPOS[@]}"; do echo " git -C ${BASE_DIR}/${r} push" done else - ok "All repos already up-to-date — no changes." + ok "All repos already in sync — no changes." fi