From 9821c6cc0d3f9d376f5f0912d47714f5dd1bb3b7 Mon Sep 17 00:00:00 2001 From: Alan Treadway Date: Tue, 17 Mar 2026 15:32:21 +0000 Subject: [PATCH 1/4] git subrepo pull external/ag-shared subrepo: subdir: "external/ag-shared" merged: "d8153efdf5f" upstream: origin: "https://github.com/ag-grid/ag-shared.git" branch: "latest" commit: "2459687b246" git-subrepo: version: "0.4.9" origin: "https://github.com/Homebrew/brew" commit: "4135badedd" --- external/ag-shared/.gitrepo | 2 +- external/ag-shared/docs/SYNC-LOG.md | 19 ++ .../github/actions/codex-pr-review/action.yml | 95 +++++- .../ag-shared/prompts/skills/jira/SKILL.md | 15 + .../prompts/skills/nx-performance/SKILL.md | 280 ++++++++++++++++++ .../references/build-and-dev.md | 184 ++++++++++++ .../references/caching-strategy.md | 127 ++++++++ .../nx-performance/references/ci-patterns.md | 187 ++++++++++++ .../nx-performance/references/gotchas.md | 206 +++++++++++++ .../prompts/skills/pr-review/_review-core.md | 12 +- .../ag-shared/prompts/skills/reflect/SKILL.md | 219 ++++++++++++++ .../prompts/skills/rulesync/SKILL.md | 2 +- .../prompts/skills/sync-ag-shared/SKILL.md | 24 +- .../prompts/skills/website-astro/SKILL.md | 3 +- 14 files changed, 1363 insertions(+), 12 deletions(-) create mode 100644 external/ag-shared/prompts/skills/nx-performance/SKILL.md create mode 100644 external/ag-shared/prompts/skills/nx-performance/references/build-and-dev.md create mode 100644 external/ag-shared/prompts/skills/nx-performance/references/caching-strategy.md create mode 100644 external/ag-shared/prompts/skills/nx-performance/references/ci-patterns.md create mode 100644 external/ag-shared/prompts/skills/nx-performance/references/gotchas.md create mode 100644 external/ag-shared/prompts/skills/reflect/SKILL.md diff --git a/external/ag-shared/.gitrepo b/external/ag-shared/.gitrepo index b6355b8f527..132d5534e01 100644 --- a/external/ag-shared/.gitrepo +++ b/external/ag-shared/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/ag-grid/ag-shared.git branch = latest - commit = 8ba8e8e436eed4992181a97843b045a0c5249aef + commit = 2459687b24688dc840629ad808471e7ad7945a8f parent = d0d058059e38acc51bd4484e3861c57d6cada8b7 method = rebase cmdver = 0.4.9 diff --git a/external/ag-shared/docs/SYNC-LOG.md b/external/ag-shared/docs/SYNC-LOG.md index 666fc8c9a8d..063471cde48 100644 --- a/external/ag-shared/docs/SYNC-LOG.md +++ b/external/ag-shared/docs/SYNC-LOG.md @@ -6,6 +6,25 @@ Newest entries first. Generated by `/ag-shared-sync-log`. --- +## 2026-03-17 -- Migrate nx-performance skill to ag-shared + +**Branch:** `latest` + +### Changes + +- **[prompts/skills]** Migrated `nx-performance` skill from ag-charts-local to ag-shared — generalized AG Charts-specific language to "AG product monorepos" while preserving concrete examples +- **[prompts/skills]** Skill structure: `SKILL.md` + `references/` subdirectory with `caching-strategy.md`, `build-and-dev.md`, `ci-patterns.md`, `gotchas.md` + +### Migration Actions + +- [ ] ag-charts: Replace `.rulesync/skills/nx-performance/` directory with symlink → `../../external/ag-shared/prompts/skills/nx-performance/` +- [ ] ag-grid: Add `.rulesync/skills/nx-performance` symlink → `../../external/ag-shared/prompts/skills/nx-performance/` +- [ ] ag-studio: Add `.rulesync/skills/nx-performance` symlink → `../../external/ag-shared/prompts/skills/nx-performance/` +- [ ] Run `./external/ag-shared/scripts/setup-prompts/setup-prompts.sh` +- [ ] Run `./external/ag-shared/scripts/setup-prompts/verify-rulesync.sh` + +--- + ## 2026-03-12 -- Context optimisation, plunker multi-product, symlinked repo support **Branch:** `latest` diff --git a/external/ag-shared/github/actions/codex-pr-review/action.yml b/external/ag-shared/github/actions/codex-pr-review/action.yml index de26bef2fde..35f349fa220 100644 --- a/external/ag-shared/github/actions/codex-pr-review/action.yml +++ b/external/ag-shared/github/actions/codex-pr-review/action.yml @@ -288,6 +288,93 @@ runs: echo "prompt_file=${prompt_file}" >> $GITHUB_OUTPUT echo "output_ext=${output_ext}" >> $GITHUB_OUTPUT + - name: Generate PR Diff Context + if: steps.check-auth.outputs.skipped != 'true' + id: diff-context + shell: bash + env: + PR_NUMBER: ${{ inputs.pr-number }} + BASE_REF: ${{ inputs.base-ref }} + HEAD_REF: ${{ inputs.head-ref }} + PR_TITLE: ${{ inputs.pr-title }} + PR_AUTHOR: ${{ inputs.pr-author }} + ARGUMENTS: ${{ inputs.inline-comments == 'true' && format('--json {0}', inputs.pr-number) || inputs.pr-number }} + GH_TOKEN: ${{ inputs.github-token }} + run: | + # Pre-generate the diff and metadata so Codex doesn't need to exec git commands. + # This avoids sandbox (bwrap) issues on GitHub Actions runners. + context_file=".codex-diff-context-${PR_NUMBER}.md" + diff_file=".codex-diff-${PR_NUMBER}.patch" + echo "context_file=${context_file}" >> $GITHUB_OUTPUT + echo "diff_file=${diff_file}" >> $GITHUB_OUTPUT + + PR_REF="origin/pr/${PR_NUMBER}" + DIFF_BASE="origin/${BASE_REF}...${PR_REF}" + HEAD_SHA=$(git rev-parse "${PR_REF}") + PR_URL="https://github.com/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}" + + # Fill in missing metadata (e.g. workflow_dispatch doesn't have PR event context) + if [ -z "${PR_TITLE}" ] || [ -z "${PR_AUTHOR}" ] || [ -z "${HEAD_REF}" ]; then + PR_META=$(gh pr view "${PR_NUMBER}" --json title,author,headRefName 2>/dev/null || echo '{}') + [ -z "${PR_TITLE}" ] && PR_TITLE=$(echo "${PR_META}" | jq -r '.title // empty') + [ -z "${PR_AUTHOR}" ] && PR_AUTHOR=$(echo "${PR_META}" | jq -r '.author.login // empty') + [ -z "${HEAD_REF}" ] && HEAD_REF=$(echo "${PR_META}" | jq -r '.headRefName // empty') + fi + + # Collect diff stats + FILES_CHANGED=$(git diff --name-only "${DIFF_BASE}" | wc -l | tr -d ' ') + DIFF_STAT=$(git diff --stat "${DIFF_BASE}") + LINES_ADDED=$(git diff --numstat "${DIFF_BASE}" | awk '{ s += $1 } END { print s+0 }') + LINES_REMOVED=$(git diff --numstat "${DIFF_BASE}" | awk '{ s += $2 } END { print s+0 }') + + # Write the raw diff to a standalone file (avoids Markdown escaping issues) + git diff "${DIFF_BASE}" > "${diff_file}" + + # Build the context file (metadata only, no embedded diff). + # Uses printf instead of a heredoc to keep content indented within the + # YAML block scalar — unindented heredoc lines break GitHub Actions' YAML parser. + COMMIT_MSGS=$(git log --format="%s" "origin/${BASE_REF}..${PR_REF}") + printf '%s\n' \ + "" \ + "## Pre-generated PR Context" \ + "" \ + "The PR diff and metadata have been pre-generated and are provided below." \ + "**Do NOT run any git, gh, or shell commands.** Analyse the diff below directly." \ + "" \ + "### Arguments" \ + "" \ + "ARGUMENTS: ${ARGUMENTS}" \ + "" \ + "### PR Metadata" \ + "- **PR Number:** ${PR_NUMBER}" \ + "- **PR Title:** ${PR_TITLE}" \ + "- **PR URL:** ${PR_URL}" \ + "- **Author:** ${PR_AUTHOR}" \ + "- **Base Branch:** ${BASE_REF}" \ + "- **Head Branch:** ${HEAD_REF}" \ + "- **Head SHA:** ${HEAD_SHA}" \ + "- **Files Changed:** ${FILES_CHANGED}" \ + "- **Lines Added:** ${LINES_ADDED}" \ + "- **Lines Removed:** ${LINES_REMOVED}" \ + "" \ + "### Diff Stats" \ + '```' \ + "${DIFF_STAT}" \ + '```' \ + "" \ + "### Commit Messages" \ + '```' \ + "${COMMIT_MSGS}" \ + '```' \ + "" \ + "### Full Diff" \ + "" \ + "Everything below this line is the raw unified diff for this PR." \ + "---" \ + > "${context_file}" + + echo "Generated context ($(wc -c < "${context_file}") bytes) + diff ($(wc -c < "${diff_file}") bytes)" + - name: Run Codex Review if: steps.check-auth.outputs.skipped != 'true' id: codex @@ -306,15 +393,17 @@ runs: # Output file paths (unique per PR to avoid conflicts) output_file=".codex-review-${{ inputs.pr-number }}.${{ steps.prompt.outputs.output_ext }}" error_file=".codex-error-${{ inputs.pr-number }}.log" + context_file="${{ steps.diff-context.outputs.context_file }}" + diff_file="${{ steps.diff-context.outputs.diff_file }}" echo "output_file=${output_file}" >> $GITHUB_OUTPUT # Run Codex with ALL output suppressed - # - stdin: Prompt file content piped in + # - stdin: Review instructions + metadata context + raw diff (three files concatenated) # - stdout (>/dev/null): Suppresses reasoning/streaming output # - stderr (2>file): Captured to file for debugging, not logged set +e - cat "${{ steps.prompt.outputs.prompt_file }}" | codex exec \ + cat "${{ steps.prompt.outputs.prompt_file }}" "${context_file}" "${diff_file}" | codex exec \ --output-last-message "${output_file}" \ --sandbox read-only \ 2>"${error_file}" \ @@ -672,4 +761,4 @@ runs: if: always() shell: bash run: | - rm -f ".codex-review-${{ inputs.pr-number }}.md" ".codex-review-${{ inputs.pr-number }}.json" ".codex-error-${{ inputs.pr-number }}.log" + rm -f ".codex-review-${{ inputs.pr-number }}.md" ".codex-review-${{ inputs.pr-number }}.json" ".codex-error-${{ inputs.pr-number }}.log" ".codex-diff-context-${{ inputs.pr-number }}.md" ".codex-diff-${{ inputs.pr-number }}.patch" diff --git a/external/ag-shared/prompts/skills/jira/SKILL.md b/external/ag-shared/prompts/skills/jira/SKILL.md index 06fecf5e3ad..71926d36387 100644 --- a/external/ag-shared/prompts/skills/jira/SKILL.md +++ b/external/ag-shared/prompts/skills/jira/SKILL.md @@ -23,6 +23,21 @@ context: fork Unified skill for creating, estimating, and analysing JIRA tickets across AG products. +## Step 0: Verify Atlassian MCP Connection + +Before doing anything else, verify the Atlassian MCP is available by calling `mcp__atlassian__atlassianUserInfo`. If the tool is not available, returns an error, or the MCP server is not connected: + +**Hard stop.** Output the following and do not proceed: + +``` +Cannot proceed — Atlassian MCP is not connected. + +This skill requires the Atlassian MCP server to interact with JIRA. +Please ensure the MCP connection is configured and active, then retry. +``` + +Do not attempt to work around the missing connection or produce partial results. + ## Product Detection Detect the product from the repository context: diff --git a/external/ag-shared/prompts/skills/nx-performance/SKILL.md b/external/ag-shared/prompts/skills/nx-performance/SKILL.md new file mode 100644 index 00000000000..45add50713f --- /dev/null +++ b/external/ag-shared/prompts/skills/nx-performance/SKILL.md @@ -0,0 +1,280 @@ +--- +name: nx-performance +description: >- + Nx monorepo performance, caching, and build pipeline best practices. Use this + skill whenever planning or making changes to nx.json, project.json, targetDefaults, + namedInputs, or any Nx configuration. Also use when auditing a repo for Nx + optimisations, diagnosing cache misses, investigating slow builds, reviewing CI + pipeline efficiency, or when anyone mentions Nx caching, build performance, + task graph, or build decomposition. If the user is touching Nx config files or + asking "why is my build slow?", this skill applies. +--- + +# Nx Performance & Caching Guide + +This skill encodes battle-tested patterns from AG product Nx monorepos — large-scale Nx 20 workspaces with 100-220+ projects, decomposed build targets, batch executors, and sophisticated CI pipelines. Use it both for making changes and for auditing. + +## When to consult reference files + +| Topic | Reference file | Read when... | +| --------------------------------------------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------- | +| Named inputs, cache config, output declarations | `references/caching-strategy.md` | Modifying `namedInputs`, `targetDefaults`, `cache`, or `outputs` in nx.json or project.json | +| Build decomposition, esbuild, dev server, batch executors | `references/build-and-dev.md` | Changing build targets, adding new targets, modifying the dev server, or working with batch executors | +| CI caching, sharding, artifacts, concurrency | `references/ci-patterns.md` | Modifying GitHub Actions workflows, CI caching strategy, test sharding, or artifact sharing | +| Known bugs and fixes from AG monorepos | `references/gotchas.md` | Debugging unexpected cache behaviour, or auditing a repo that may have inherited older patterns | + +--- + +## The Five Laws of Cacheable Targets + +Every Nx target that has `cache: true` must satisfy all five. Violating any one silently degrades cache hit rates — often to zero. + +### 1. Inputs and outputs must not overlap + +A target's inputs (files Nx hashes for the cache key) and outputs (files the target produces) must be disjoint. When they overlap, the target invalidates its own cache every time it runs. + +**Common violations:** + +- Code generation that writes back to `src/` +- In-place transpilation (`.js` alongside `.ts` in `src/`) +- Auto-formatting (`--fix`) during build, mutating source files + +**Fix:** Write generated/transformed files to `dist/` or `.generated/`, and exclude that directory from inputs: + +```json +"buildOutputExcludes": ["!{projectRoot}/dist/**"] +``` + +### 2. Targets must be idempotent + +Running a target twice with the same inputs must produce byte-identical outputs. Non-idempotent targets create cache entries that never validate on restore. + +**Common breakers:** timestamps in output, non-deterministic ordering (`Object.keys()`, `fs.readdir()`), random values, absolute paths in source maps. + +**How to test:** + +```bash +nx run my-package:build +cp -r packages/my-package/dist /tmp/first-run +nx run my-package:build --skip-nx-cache +diff -r /tmp/first-run packages/my-package/dist +# Any diff = non-idempotent target +``` + +### 3. Upstream outputs must not pollute downstream inputs + +When target A produces output that target B reads, A's outputs must not land in B's input set unintentionally. This is a cross-package variant of Law 1. + +**Fix:** Use `dependentTasksOutputFiles` to read only specific output files (e.g., `*.d.ts`) from dependencies — not their entire `src/`. Exclude all `dist/` from the default input set. + +### 4. Pin your tools — both npm packages and local scripts + +The cache key must invalidate when any tool that transforms the output changes. This means two things: + +**npm tool versions** — declare `externalDependencies` so upgrading TypeScript or esbuild invalidates the cache: + +```json +{ "externalDependencies": ["npm:typescript", "npm:esbuild"] } +``` + +**Local build scripts** — if the target runs a custom script (e.g., `node tools/compile-sass.js`), that script file must be in the target's `inputs`. Otherwise, changes to the script produce stale cached results: + +```json +"inputs": [ + "{projectRoot}/src/**/*.scss", + "{workspaceRoot}/tools/compile-sass.js", + "buildOutputExcludes", + { "externalDependencies": ["npm:sass"] } +] +``` + +A common mistake is to include only source files in inputs while forgetting the scripts and config files that process them. + +### 5. Declare outputs for every cached target + +Missing `outputs` means Nx caches "nothing" — the target runs, produces files, but restoring from cache doesn't restore those files. + +```json +"build:types": { "outputs": ["{options.outputPath}"] } +"lint": { "outputs": [] } +"test": { "outputs": [] } +``` + +Even targets that produce no files (lint, test) should declare `"outputs": []` explicitly. + +--- + +## Key Patterns + +### Named inputs hierarchy + +Define reusable `namedInputs` in `nx.json` so every target references a well-scoped input set. This is the single most impactful optimisation — it prevents over-invalidation (cache misses from irrelevant file changes) and under-invalidation (stale results). + +Essential named inputs: + +- **`production`** — source files minus tests, snapshots, lint configs, and build outputs +- **`buildOutputExcludes`** — `!{projectRoot}/dist/**` (prevents self-invalidation) +- **`sharedGlobals`** — root config files that affect all builds (tsconfig, esbuild config) + +See `references/caching-strategy.md` for the full hierarchy and dependency output inputs (`tsDeclarations`, `jsOutputs`, `allTransitiveOutputs`). + +### Build decomposition + +Split monolithic `build` into sub-targets that maximise parallelism and minimise cache invalidation: + +| Target | Executor | Produces | Key benefit | +| --------------- | ------------- | ----------------------------------- | ---------------------------------------- | +| `build` | `nx:noop` | Nothing (aggregator) | Fan-out point, `inputs: [], outputs: []` | +| `build:types` | `@nx/js:tsc` | `dist/types/*.d.ts` | Parallel with `build:package` | +| `build:package` | `@nx/esbuild` | `dist/package/*.cjs.js + *.esm.mjs` | Only rebuilds on source changes | +| `build:umd` | `@nx/esbuild` | `dist/umd/*.js` | Consumes JS output, not source | +| `build:test` | `tsc` | `dist/test/**` | Depends on types only, not packages | + +See `references/build-and-dev.md` for the full pipeline including dev server and batch executors. + +### Dependency precision + +Be precise about `dependsOn` — targets should depend on exactly what they need: + +```json +// build:umd only needs JS outputs from dependencies, not types +"build:umd": { "dependsOn": ["build:package", "^build:package"] } + +// build:test needs types for compilation, not packages +"build:test": { "dependsOn": ["^build:types", "build:types"] } + +// test needs compiled specs + runtime, but NOT UMD bundles +"test": { "dependsOn": ["build:test"] } +``` + +Over-broad dependencies (everything depending on `build`) serialise the task graph unnecessarily. + +### Noop aggregator targets + +Use `nx:noop` for fan-out targets (like `build` that just triggers sub-targets): + +```json +"build": { + "executor": "nx:noop", + "dependsOn": ["build:types", "build:package", "build:umd"], + "inputs": [], + "outputs": [], + "cache": true +} +``` + +`inputs: []` and `outputs: []` are critical. Without them, cache restoration can delete real build artifacts produced by sub-targets. + +### Cache defaults for `nx:run-commands` + +Set `cache: true` as the default for `nx:run-commands` in `targetDefaults`: + +```json +"targetDefaults": { + "nx:run-commands": { "cache": true } +} +``` + +Without this, every shell command target is uncached by default. + +--- + +## Audit Workflow + +When auditing a repo for Nx optimisations, work through these checks in order. The checklist is prioritised by typical impact. + +### Phase 1: Fundamentals (highest impact) + +1. **Check for input/output overlap** — Do any targets write to `src/` or directories included in their inputs? +2. **Check `dist/` exclusion** — Is `dist/` excluded from input globs? Look for `buildOutputExcludes` or `!{projectRoot}/dist/**` in `namedInputs`. +3. **Check `namedInputs` exist** — Are they defined in `nx.json` and referenced by targets? The biggest miss is targets using the default `{projectRoot}/**/*`, which includes test files, snapshots, and dist output. +4. **Check `production` input** — Does it exclude test files (`!**/*.spec.*`), snapshots (`!**/__image_snapshots__/**`), and build outputs? +5. **Check `outputs` declarations** — Every cached target should declare its outputs. Missing outputs means cache restores are empty. +6. **Test idempotency** — Run a build target twice and diff the outputs. + +### Phase 2: Build pipeline + +7. **Check build decomposition** — Is `build` a monolithic target, or decomposed into types/package/umd? +8. **Check bundler** — Is esbuild used for JS bundling? tsc is 10-100x slower. +9. **Check dependency precision** — Do targets depend on more than they need? (e.g., `test` depending on full `build` including UMD) +10. **Check `externalDependencies`** — Are compiler tools (typescript, esbuild) declared on build targets? +11. **Check `transitive: false`** — Are dependency output inputs using `transitive: false` where only direct deps are needed? + +### Phase 3: Cache configuration + +12. **Check `cache: true` default** — Is `nx:run-commands` cached by default in `targetDefaults`? +13. **Check `useLegacyCache: false`** — Is the newer, more efficient cache format enabled? +14. **Check for accidental `cache: false`** — Search for `"cache": false` in project.json files and verify each is intentional. +15. **Check noop targets** — Do aggregator (noop) targets use `inputs: [], outputs: []`? + +### Phase 4: CI (if applicable) + +16. See `references/ci-patterns.md` for the full CI audit checklist covering GHA caching, sharding, artifacts, and concurrency control. + +### Phase 5: Known gotchas + +17. See `references/gotchas.md` for 13 specific bugs discovered and fixed in AG product monorepos. The most common issues (check these first): + - **Noop aggregator targets with inherited outputs** — can destroy real build artifacts on cache restore. Fix: `inputs: [], outputs: []`. + - **`nx:run-commands` with `parallel: true`** — race conditions when commands must run sequentially. Fix: `parallel: false`. + - **Lint inputs missing config files** — `.dependency-cruiser.js`, `eslint.*` not in lint inputs means stale lint results after config changes. + - **Dev setup/generation cached across branches** — Nx cache is branch-unaware. Fix: `cache: false` on orchestrator targets, or broaden inputs so branch switches invalidate the cache. Workaround: `nx reset` or `--skip-nx-cache`. + - **External (unbundled) packages missing `implicitDependencies`** — Nx can't trace through `external` imports for build ordering. + +--- + +## Verification Commands + +```bash +# Check named inputs are defined +cat nx.json | jq '.namedInputs | keys' + +# Check target defaults +cat nx.json | jq '.targetDefaults | keys' + +# Check which targets have cache: true/false +grep -r '"cache"' packages/*/project.json nx.json + +# Check for targets that write to src/ +grep -r '"command"' packages/*/project.json | grep 'src/' + +# Test idempotency +nx run :build && cp -r packages//dist /tmp/first-run +nx run :build --skip-nx-cache +diff -r /tmp/first-run packages//dist + +# List all projects (including auto-generated) +nx show projects | wc -l + +# Check cache size +du -sh .nx/cache/ + +# Check build decomposition for a package +cat packages//project.json | jq '.targets | keys' + +# Check .nxignore exists +cat .nxignore +``` + +--- + +## Making Configuration Changes + +When modifying Nx configuration, follow these principles: + +1. **Centralise in `nx.json` `targetDefaults`** — Project-level `project.json` should only contain overrides. Define default inputs, outputs, dependsOn, and cache settings in `targetDefaults` keyed by executor name. + +2. **Use tokens, not hardcoded paths** — Always use `{projectRoot}` and `{workspaceRoot}` instead of `packages/my-package/...`. Hardcoded paths break when packages are reorganised. + +3. **Scope inputs as tightly as possible, but don't forget build tools** — Every file included in inputs that doesn't affect the target's output is a potential false cache invalidation. Use specific globs (`{projectRoot}/src/**`) rather than broad ones (`{projectRoot}/**/*`). But be careful not to go too narrow: include every file that affects the output — source files, local build/transform scripts (e.g., `{workspaceRoot}/tools/compile-sass.js`), relevant config files, and tool versions via `externalDependencies`. + +4. **Use `dependentTasksOutputFiles` for cross-package dependencies** — Instead of including all upstream source in inputs, reference specific output file patterns: + + ```json + "tsDeclarations": [{ "dependentTasksOutputFiles": "**/*.d.ts", "transitive": false }] + ``` + + Use `transitive: false` unless you genuinely need the full dependency tree (e.g., `pack`). + +5. **Test cache behaviour after changes** — Run the target, then run it again. The second run should be a cache hit. If not, investigate what changed between runs using `NX_VERBOSE_LOGGING=true`. + +6. **Consider the `.nxignore` file** — Exclude generated files, vendored directories, patch infrastructure, and anything that shouldn't be in the project graph or trigger formatting. diff --git a/external/ag-shared/prompts/skills/nx-performance/references/build-and-dev.md b/external/ag-shared/prompts/skills/nx-performance/references/build-and-dev.md new file mode 100644 index 00000000000..d97d28e259e --- /dev/null +++ b/external/ag-shared/prompts/skills/nx-performance/references/build-and-dev.md @@ -0,0 +1,184 @@ +# Build Pipeline & Dev Server Reference + +## Decomposed build targets + +The recommended pattern splits `build` into four sub-targets that maximise parallelism and minimise cache invalidation: + +``` +build (nx:noop aggregator) +├── build:types (@nx/js:tsc) → dist/types/*.d.ts +├── build:package (@nx/esbuild) → dist/package/*.cjs.js + *.esm.mjs +├── build:umd (@nx/esbuild) → dist/umd/*.js (depends on build:package) +└── build:test (tsc) → dist/test/** (depends on build:types) +``` + +### Why decomposition matters + +- **Parallel execution**: `build:types` and `build:package` run simultaneously — no mutual dependency. +- **Granular caching**: Changing a type signature invalidates `build:types` but not `build:package` (if the JS output is unchanged). Changing implementation invalidates `build:package` but not `build:types`. +- **Minimal downstream invalidation**: `build:umd` uses `jsOutputs` (not `production`), so it only rebuilds when actual JS output changes — not when comments or tests change. + +### What invalidates what + +| Change type | build:types | build:package | build:umd | build:test | +| ------------------- | ----------- | ------------- | ------------------------- | ---------- | +| Source code change | Rebuilds | Rebuilds | Only if JS output changed | Rebuilds | +| Test file change | Cached | Cached | Cached | Rebuilds | +| Comment-only change | Rebuilds | Cached | Cached | Rebuilds | + +### Per-package overrides + +Individual packages can override `targetDefaults`. For example, a community package (e.g., `ag-charts-community`) may override `build:umd` to build from source rather than `dist/` output, because its UMD bundle is a self-contained browser bundle needing a dedicated entry point (`main-umd.ts`). + +```json +"build:umd": { + "dependsOn": [], + "inputs": ["production", "^production"], + "options": { "main": "{projectRoot}/src/main-umd.ts" } +} +``` + +### What to audit + +1. **Is `build` a monolithic target?** If a single target runs tsc + bundle + UMD, every change invalidates everything. +2. **Does `build:umd` depend on `build:package` output (not source)?** The UMD bundle should consume `dist/package/main.cjs.js`, not `src/`. Some packages may legitimately override this. +3. **Are test compilation and library compilation separated?** `build:test` depending on `build:types` (not `build:package`) means tests can compile as soon as types are ready. + +--- + +## esbuild over tsc for bundling + +Use `@nx/esbuild:esbuild` for `build:package` and `build:umd`. esbuild is 10-100x faster than tsc + bundler for producing JS output. `@nx/js:tsc` is only used for `build:types` (declaration emit). + +Custom esbuild plugins (`esbuild.config.cjs`) handle: CSS inlining and minification, HTML minification, post-build `.min.js` generation, UMD wrapper adaptation. + +### What to audit + +- Is tsc being used for JS output when esbuild could do it? +- Are there separate minification steps that could be folded into esbuild plugins? + +--- + +## Batch executors + +For targets that run hundreds of times with identical setup (e.g., ~200 example generation tasks), batch executors avoid spawning a separate Node process per task: + +- Receives all tasks in a single process +- Uses Node.js worker threads for CPU-parallelism (requires Node >= 18.18) +- Falls back to serial execution on older Node versions + +Both `implementation` and `batchImplementation` must be declared in `executors.json`. + +### What to audit + +- Are there targets that run hundreds of times with identical setup? These are candidates for batch executors. +- Are batch executors registered with `batchImplementation` in `executors.json`? + +--- + +## Dev server + +### Startup sequence + +``` +nx dev +├── Phase 1: Dependencies (sequential) +│ ├── ^build:types (all packages) +│ ├── ^build:package (all packages) +│ └── generate (all examples + thumbnails) +└── Phase 2: Concurrent processes + ├── watch.js (file watcher + queue-based rebuilder) + └── -website:dev (Astro dev server) +``` + +**Variants:** + +- `dev:lite` — simple HTTPS file server instead of Astro. Much faster startup for core library work. +- `dev:quick` — only depends on a single thumbnail generation. Fastest startup for gallery-focused work. + +### Watch system design + +The watch script is a queue-based system: + +1. `nx watch --all` detects file changes and emits project names +2. 50ms quiet period batches rapid-fire changes +3. Dependency-aware fan-out — core change → rebuild community, enterprise, then core +4. `build:umd` listed before `build` so browser-reloadable target finishes first +5. Batch limit (50 projects per `nx run-many`) prevents command-line length issues +6. HMR bridge — touching a sentinel file signals Astro/Vite to send full-reload WebSocket message + +**Key environment variables:** + +- `NX_FORCE_REUSE_CACHED_GRAPH=true` — skips re-computing the project graph on every watch-triggered build (~20-40ms savings per invocation) +- `NX_DAEMON=true` — required for the watch process (even if daemon is disabled for one-shot commands) +- `BUILD_FWS` — opt-in to rebuild framework wrappers during watch (excluded by default) + +**Git-aware pausing**: Builds are blocked during `git rebase`, `git merge`, or any operation that creates `.git/index.lock`. + +### What to audit + +1. **Does `dev` depend on build but NOT lint/test?** Dev startup should be minimal. +2. **Is the watch config dependency-aware?** Naive watch that just rebuilds the changed project produces broken intermediate states. +3. **Is UMD prioritised for reload?** Browser loads UMD bundles — listing `build:umd` first means reload fires sooner. +4. **Is `NX_FORCE_REUSE_CACHED_GRAPH` set?** Avoids re-computing the project graph on every watch-triggered build. +5. **Is there a lightweight dev variant?** Not every developer needs the full website. +6. **Are framework wrappers excluded from watch?** Rebuilding them on every change is wasteful. + +--- + +## Task graph optimisation + +### Dependency precision patterns + +```json +// build:umd only needs JS outputs, not types +"build:umd": { + "dependsOn": ["build:package", "^build:package"], + "inputs": ["jsOutputs"] +} + +// build:test needs types (for compilation) but not packages (not bundling) +"build:test": { + "dependsOn": ["^build:types", "build:types"] +} + +// test needs build:test (compiled specs) + build:package (runtime) +"test": { + "inputs": ["default", "buildOutputExcludes", "^production"] +} +``` + +### What to audit + +- **Are targets depending on more than they need?** Common mistake: `test` depending on `build` (which includes UMD). +- **Are `^` (upstream) dependencies used correctly?** `^build:types` means "build types for all dependencies". Without `^`, it means "build types for this project only". + +--- + +## Aggregator project (`all`) + +AG product monorepos use an aggregator project with `nx:noop` targets and `dependsOn: ["^targetName"]` to fan out work. Running `nx run all:build` triggers every package's `build`. + +Convenience targets: `blt` (build-lint-test), `blt:ci` (adds e2e and pack), `clean`, `nuke`. + +### What to audit + +- Does the repo have an aggregator project? Without one, developers use `nx run-many` with hand-maintained project lists that drift. + +--- + +## Dynamic project creation + +AG product monorepos use custom Nx plugins (e.g., `ag-charts-task-autogen`) that scan example directories (e.g., `packages/*/src/**/_examples/*/main.ts`) and create virtual projects at graph-computation time, each with `generate-example`, `generate-thumbnail`, and `typecheck` targets. + +### What to audit + +- Is dynamic project creation used for examples/generated content, or are hundreds of targets hand-maintained in `project.json` files? + +--- + +## Nx references + +- [Batch executors](https://nx.dev/docs/technologies/typescript/guides/enable-tsc-batch-mode) +- [Project graph plugins](https://nx.dev/docs/extending-nx/project-graph-plugins) — `createNodes` API +- [Workspace watching](https://nx.dev/docs/guides/tasks--caching/workspace-watching) diff --git a/external/ag-shared/prompts/skills/nx-performance/references/caching-strategy.md b/external/ag-shared/prompts/skills/nx-performance/references/caching-strategy.md new file mode 100644 index 00000000000..c4cdbc03c62 --- /dev/null +++ b/external/ag-shared/prompts/skills/nx-performance/references/caching-strategy.md @@ -0,0 +1,127 @@ +# Caching Strategy Reference + +## Named Inputs — the foundation of correct caching + +AG product monorepos define reusable `namedInputs` in `nx.json` that every target references. This ensures Nx knows exactly what files affect each target, avoiding both over-invalidation (cache misses) and under-invalidation (stale results). + +### Named input hierarchy + +``` +default = {projectRoot}/**/* + sharedGlobals +├── defaultExcludes = !tests, !snapshots, !eslint, !jest configs +├── buildOutputExcludes = !{projectRoot}/dist/** +└── production = default + defaultExcludes + buildOutputExcludes + +sharedGlobals = esbuild.config*.cjs + tsconfig.*.json (root) + +tsDefaults = src + tsconfigs + tsDeclarations + sharedGlobals + defaultExcludes +``` + +### Named input definitions + +| Named Input | Purpose | Key detail | +| ---------------------- | ------------------------------------------ | ---------------------------------------------------------------- | +| `production` | Source files minus tests/snapshots/configs | Built from `default` + `defaultExcludes` + `buildOutputExcludes` | +| `tsDeclarations` | `.d.ts` from direct dependencies | `transitive: false` — only direct deps | +| `jsOutputs` | `.js` from direct dependencies | Used by `build:umd` which bundles from `dist/` | +| `allTransitiveOutputs` | All outputs, transitively | Used by `pack` (needs the full dependency tree) | +| `tsDefaults` | Standard TS compilation inputs | Available for project-level overrides | +| `sharedGlobals` | Root esbuild/tsconfig files | Changes to these invalidate all builds | +| `buildOutputExcludes` | Excludes `dist/` from project files | Prevents output files from being counted as inputs | + +### Dependency output inputs (`dependentTasksOutputFiles`) + +These control what output files from upstream packages are included in a target's cache key: + +```json +"tsDeclarations": [ + { "dependentTasksOutputFiles": "**/*.d.ts", "transitive": false } +], +"jsOutputs": [ + { "dependentTasksOutputFiles": "**/*.js", "transitive": false } +], +"allTransitiveOutputs": [ + { "dependentTasksOutputFiles": "**/*.*", "transitive": true } +] +``` + +**`transitive: false`** is critical for most targets — it means only direct dependency outputs are hashed, not the entire transitive tree. Setting `transitive: true` when you only need direct deps causes massive over-invalidation. In practice, `transitive: true` is typically only needed for the `pack` target (which genuinely needs the full tree to detect changes in deep dependencies). + +### What to audit + +1. **Are `namedInputs` defined and used consistently?** The most common mistake is targets that use the default `{projectRoot}/**/*`, which includes test files, snapshots, and dist output. +2. **Does `production` exclude test files and build outputs?** Check for patterns like `!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)` and `!{projectRoot}/dist/**`. +3. **Are `externalDependencies` declared?** Pin `npm:typescript` and `npm:esbuild` as inputs to build targets. +4. **Is `transitive: false` used on `dependentTasksOutputFiles`?** Only use `transitive: true` for targets that genuinely need the full dependency tree (e.g., `pack`). + +--- + +## Cache-enabled vs cache-disabled targets + +### Recommended defaults + +**Cached (`cache: true`):** + +- `build` / `build:types` / `build:package` / `build:umd` / `build:test` +- `lint` / `lint:eslint` / `lint:depcruise` / `lint:circular` +- `test` / `e2e` / `pack` +- `generate-example` / `generate-thumbnail` / `typecheck` +- `nx:noop` / `nx:run-commands` / `nx:run-script` (via targetDefaults) + +**Uncached (`cache: false`):** + +- `benchmark` — fresh runs needed for accurate measurements +- `website:build` — Astro has its own cache; double-caching wastes GBs +- `all:generate` — noop orchestrator, no value in caching + +### What to audit + +1. **Is `cache: true` the default for `nx:run-commands`?** Without this, every shell command target is uncached by default. +2. **Are any build/lint/test targets accidentally uncached?** Search `project.json` files for `"cache": false` and verify each is intentional. +3. **Are noop aggregator targets cached?** `nx:noop` with `cache: true` and `inputs: [], outputs: []` is essentially free. +4. **Is the website/SSG build cache disabled?** Frameworks like Astro/Next.js have their own caching. Double-caching wastes disk and the Nx cache often can't correctly track SSG outputs. + +--- + +## Output declarations + +Every cached target must declare its `outputs` so Nx knows what to store and restore. + +### Output declaration patterns + +```json +"build:types": { "outputs": ["{options.outputPath}"] } // → dist/types +"build:package": { "outputs": ["{options.outputPath}"] } // → dist/package +"build:umd": { "outputs": ["{options.outputPath}"] } // → dist/umd +"build:test": { "outputs": ["{projectRoot}/dist/test"] } +"lint": { "outputs": [] } // lint has no outputs +"test": { "outputs": [] } // test has no outputs +``` + +### What to audit + +- **Are `outputs` declared for every cached target?** Missing outputs means Nx caches "nothing" — the target runs, produces files, but restoring from cache doesn't restore those files. +- **Do outputs use `{options.outputPath}` or `{projectRoot}/dist/...`?** The former is more DRY when the executor already defines `outputPath`. + +--- + +## Other cache settings + +### `useLegacyCache: false` + +Ensures the newer, more efficient cache format is used. Peer repos should verify this is set. + +### `.nxignore` + +Controls what Nx includes in its project graph and formatting scope. Without it, Nx may discover spurious projects in vendored directories, treat generated files as inputs, or attempt to format files without Prettier parsers. + +Typical exclusions: diff output directories, generated benchmark files, patch infrastructure, external prompt directories, and shell/patch files. + +--- + +## Nx references + +- [Nx input types reference](https://nx.dev/docs/reference/inputs) — named inputs, `dependentTasksOutputFiles`, external dependencies +- [How caching works](https://nx.dev/docs/concepts/how-caching-works) +- [Cache task results](https://nx.dev/docs/features/cache-task-results) +- [Reduce repetitive configuration](https://nx.dev/docs/guides/tasks--caching/reduce-repetitive-configuration) diff --git a/external/ag-shared/prompts/skills/nx-performance/references/ci-patterns.md b/external/ag-shared/prompts/skills/nx-performance/references/ci-patterns.md new file mode 100644 index 00000000000..3f976c04010 --- /dev/null +++ b/external/ag-shared/prompts/skills/nx-performance/references/ci-patterns.md @@ -0,0 +1,187 @@ +# CI Patterns Reference + +## GHA cache strategy + +AG product monorepos manage three layers of caching in CI via a `setup-nx` composite action: + +### Layer 1: node_modules + +``` +Key: yarn.lock + patches/*.patch + all package.json files +Fallback: prefix restore (any matching yarn.lock) +Release branches: release-{branch}-{hash} +``` + +Using only `yarn.lock` misses changes to workspace `package.json` files (new scripts, resolutions). Include all `package.json` files in the key. + +### Layer 2: Nx task cache + +``` +Key: yarn.lock + package.json hashes + github.sha +Prefix restore: partial cache hits from prior commits +Tidy step: prune stale entries before save +``` + +GHA caches have a 10 GB limit. Pruning stale Nx cache entries before saving prevents eviction of valuable entries. + +### Layer 3: Build artifacts + +``` +init job: uploads dist/ + generated examples +e2e jobs: download artifacts — no rebuild needed +``` + +### Read-only vs read-write modes + +- The `init` job uses read-write — it populates the cache for all downstream jobs. +- All other jobs (`lint`, `build`, `test`, `e2e`) use read-only — they restore but never write, preventing cache corruption from parallel writes. + +### NX_PARALLEL auto-detection + +The action sets `NX_PARALLEL` to the CPU count unless already set. CI jobs needing serial execution (e.g., tests with `NX_PARALLEL: 1`) override this explicitly. + +### NX_BASE calculation (dynamic affected base) + +| Branch type | NX_BASE value | +| ------------------ | --------------------------------------------- | +| `latest` / `next` | `{branch}-success` tag | +| Release (`b*.*.*`) | `{branch}-success` if exists, else `{branch}` | +| PR | `origin/{base_branch}` | + +The `report` job tags successful CI runs with `{branch}-success`. This means `nx affected` compares against the last _successful_ build, not just the previous commit — ensuring a failed CI run doesn't shift the baseline and mask regressions. + +--- + +## Concurrency control and early exit + +### Concurrency groups + +```yaml +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/latest' && github.ref != 'refs/heads/next' }} +``` + +- PR branches: new pushes cancel in-progress runs (avoids wasted compute). +- `latest`/`next`: runs are never cancelled (success tag must be set reliably). + +### Early exit for non-code PRs + +A `detect-changes` job uses `dorny/paths-filter` to check if the PR only touches non-code files. If so, only `lint` runs — all other jobs are skipped. + +Code paths: `packages/**`, `libraries/**`, `plugins/**`, `tests/**`, `tools/**`, `external/ag-shared/**`, `*.json`, `*.ts`, `*.js`, `yarn.lock`, `nx.json`. + +--- + +## `affected` vs `run-many` toggle + +The CI workflow supports switching between `nx affected` (default) and `nx run-many` (full workspace) via `workflow_dispatch` input. Useful for debugging where `affected` may compute the wrong diff, or for validating a full-workspace build before releases. + +--- + +## Selective GHA caching + +The task autogen plugin tags volatile examples with `skip-gha-cache`. CI uses a two-phase strategy: + +1. Build all cacheable examples (exclude `tag:skip-gha-cache`) +2. Build volatile examples separately with `--excludeTaskDependencies --skip-nx-cache` + +This ensures volatile examples are always rebuilt fresh while cacheable ones benefit from Nx caching. + +--- + +## Test sharding strategy + +The CI pipeline dynamically calculates test shard counts based on the number of affected projects. + +### Unit test shards + +- **Shard 0** (always created): non-shardable work — tests tagged `no-sharding`, bundle size validation (`size-limit`), package sanity checks (`pack:verify`). +- **Shards 1-6**: Nx distributes affected test projects using `--shard=N/total`. + +### E2E shards + +- Fixed maximum of 16 shards. +- Playwright distributes test files across shards. + +### Framework package tests + +Only run on `latest`/release branches or when test files are directly modified. + +### Parallelism + +`NX_PARALLEL: 1` for test jobs — tests run sequentially within each shard to avoid resource contention (canvas rendering, GC-sensitive benchmarks). + +--- + +## Artifact-based build output sharing + +The `init` job builds all packages and generates all examples, then uploads outputs as a GHA artifact. E2E test shards download this artifact instead of rebuilding. + +```yaml +# init job: persist build outputs +- uses: actions/upload-artifact@v4 + with: + name: e2e-init-outputs + path: | + dist/ + packages/*/dist/ + external/*/dist/ + packages/-website/e2e/generated/ + +# e2e job: restore build outputs +- uses: actions/download-artifact@v4 + with: + name: e2e-init-outputs +``` + +--- + +## Snapshot branch management + +Visual regression tests generate image snapshots across sharded test runs. A custom snapshot workflow collects them: + +1. `snapshot-prepare` — creates a temporary branch for snapshot updates +2. `snapshot-branch` — each shard commits its snapshot changes +3. `snapshot-notify` — report job checks for updates and notifies via Slack/PR comment + +--- + +## Parallelism control + +**Parallel OK:** `build:types`, `build:package`, `lint:eslint`, `generate-example` +**Serial (parallelism: false):** `benchmark` (GC-sensitive), `test:e2e` (Playwright), `test` (GC-exposed Jest) + +--- + +## CI audit checklist + +- [ ] `NX_DAEMON=false` set for CI (avoids daemon startup overhead in ephemeral environments) +- [ ] `parallelism: false` for CPU-intensive/flaky targets +- [ ] GHA cache tags used to exclude volatile targets +- [ ] node_modules cache keyed on `yarn.lock` + `patches/` + all `package.json` files +- [ ] Nx task cache persisted across CI runs (keyed on `github.sha` with prefix restore) +- [ ] Read-only/read-write cache split (only one job writes) +- [ ] `NX_BASE` set to a success tag for `affected` accuracy +- [ ] Success tagging on green builds +- [ ] Concurrency control: `cancel-in-progress` for PR branches, never for main +- [ ] Early exit for non-code PRs +- [ ] Test sharding with dynamic matrix calculation +- [ ] Shard 0 reserved for non-shardable work +- [ ] Build artifacts shared via upload/download +- [ ] `.nxignore` excludes generated files, patches, and vendored directories +- [ ] `affected` vs `run-many` toggle available +- [ ] Bundle size validation target +- [ ] Pack pipeline includes extraction and verification steps + +--- + +## Nx / GHA references + +- [`nx affected`](https://nx.dev/docs/features/ci-features/affected) +- [GHA dependency caching](https://docs.github.com/en/actions/concepts/workflows-and-actions/dependency-caching) +- [`actions/cache`](https://github.com/actions/cache) +- [`EndBug/latest-tag`](https://github.com/EndBug/latest-tag) — success tagging action +- [GHA composite actions](https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action) +- [GHA matrix strategy](https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow) +- [Playwright test sharding](https://playwright.dev/docs/test-sharding) diff --git a/external/ag-shared/prompts/skills/nx-performance/references/gotchas.md b/external/ag-shared/prompts/skills/nx-performance/references/gotchas.md new file mode 100644 index 00000000000..6dd198defd8 --- /dev/null +++ b/external/ag-shared/prompts/skills/nx-performance/references/gotchas.md @@ -0,0 +1,206 @@ +# Gotchas: Lessons Learned the Hard Way + +These are bugs and misconfigurations discovered in AG product monorepos and fixed. Repos sharing these Nx patterns may have inherited the same issues. Each entry includes the symptom, root cause, and fix. + +--- + +## 1. Noop targets with caching can destroy real outputs + +**Symptom**: After a cache hit on a `build` noop target, downstream consumers find empty `dist/` directories. + +**Root cause**: When `nx:noop` with `cache: true` restores from cache, Nx clears the declared outputs before restoring. If outputs were declared (or inherited from defaults), this deleted the real build artifacts produced by sub-targets. + +**Fix**: Set `inputs: [], outputs: []` on noop aggregator targets. With no outputs declared, cache restoration has nothing to clear. + +```json +"build": { + "executor": "nx:noop", + "dependsOn": ["build:types", "build:package", "build:umd"], + "inputs": [], + "outputs": [], + "cache": true +} +``` + +--- + +## 2. Test targets forcing full upstream production builds + +**Symptom**: Running tests on a single package triggers `build` on every upstream package, taking minutes. + +**Root cause**: `test` had `dependsOn: ["^build"]`, meaning "build everything upstream". Tests only need compiled types and packages, not UMD bundles. + +**Fix**: Changed to `dependsOn: ["build:test"]` (local test compilation only), with test inputs including `^production` for cache invalidation on upstream changes. + +--- + +## 3. Tests using stale cache when upstream code changes + +**Symptom**: Tests pass locally but fail in CI, or vice versa. Tests use outdated upstream implementations. + +**Root cause**: Test inputs only included local files, missing `^production` (upstream source files). Changes to upstream packages didn't invalidate the test cache. + +**Fix**: Added `^production` to test inputs: + +```json +"test": { "inputs": ["default", "buildOutputExcludes", "^production", ...] } +``` + +--- + +## 4. `dist/` inside project root pollutes input hashes + +**Symptom**: Build targets never get cache hits even when source files haven't changed. Cache keys change after every build. + +**Root cause**: Nx's default `{projectRoot}/**/*` input glob includes `dist/` (which lives inside the project root). Every build modifies `dist/`, changing the input hash, invalidating its own cache. + +**Fix**: Introduced `buildOutputExcludes`: + +```json +"buildOutputExcludes": ["!{projectRoot}/dist/**"] +``` + +Included in `production` and `default` named inputs. + +--- + +## 5. Image snapshots pollute build cache keys + +**Symptom**: Updating visual regression snapshots causes all build targets to rebuild. + +**Root cause**: `__image_snapshots__/` directories were included in the default input glob. These binary files are large and change frequently. + +**Fix**: Added exclusion to `defaultExcludes`: + +```json +"!{projectRoot}/**/__image_snapshots__/**" +``` + +--- + +## 6. Pack target misses transitive dependency changes + +**Symptom**: `yarn pack` produces a tarball with stale transitive dependencies. Publishing includes old versions of deep dependencies. + +**Root cause**: `pack` inputs only referenced direct build outputs, not transitive ones. A change in a deep transitive dependency (e.g., a types package two levels up from an enterprise package) wouldn't trigger a re-pack. + +**Fix**: Changed pack inputs to `allTransitiveOutputs`: + +```json +"pack": { "inputs": ["allTransitiveOutputs", "{projectRoot}/.npmignore"] } +``` + +--- + +## 7. Lint config changes not invalidating lint cache + +**Symptom**: Changing `.dependency-cruiser.js` or ESLint config doesn't cause lint to re-run. Stale lint results served from cache. + +**Root cause**: Lint target inputs didn't include the lint tool's configuration files. + +**Fix**: Added config files to lint inputs: + +```json +"lint:depcruise": { "inputs": ["{projectRoot}/src/**", "{projectRoot}/.dependency-cruiser.js"] } +"lint:eslint": { "inputs": [..., "{workspaceRoot}/eslint.*", "{projectRoot}/eslint.*"] } +``` + +--- + +## 8. Noop targets invalidated by unrelated NPM changes + +**Symptom**: Installing any NPM package causes all noop aggregator targets to re-run, triggering cascading rebuilds. + +**Root cause**: Without explicit `externalDependencies`, Nx includes all of `node_modules` in the input hash. Noop targets don't use any NPM packages but still got invalidated. + +**Fix**: Set `inputs: []` on noop targets (which also clears external dependencies). + +--- + +## 9. `nx:run-commands` race conditions with `parallel: true` + +**Symptom**: `pack` target intermittently fails because `yarn pack` runs before `mkdir` creates the output directory. + +**Root cause**: `nx:run-commands` runs commands in parallel by default. When the target has sequential commands (create directory, then pack into it), parallel execution causes race conditions. + +**Fix**: Added `parallel: false` to targets with ordering-dependent commands. + +--- + +## 10. Hardcoded paths break portability + +**Symptom**: Copying a `project.json` to a new package requires manual path updates. Targets break if packages are reorganised. + +**Root cause**: Using hardcoded paths like `packages//...` instead of `{projectRoot}/...`. + +**Fix**: Replaced all hardcoded paths with `{projectRoot}` and `{workspaceRoot}` tokens. + +--- + +## 11. External (unbundled) packages need explicit `implicitDependencies` + +**Symptom**: After unbundling a package (marking it as `external` in esbuild), Nx no longer builds it before downstream consumers. Broken builds. + +**Root cause**: When a package is bundled, Nx detects the dependency through import analysis. When marked as `external`, the import still exists but Nx doesn't trace through it for build ordering. + +**Fix**: Added explicit `implicitDependencies`: + +```json +"implicitDependencies": ["-types", "-core"] +``` + +--- + +## 12. Watch process dies silently when Nx daemon self-disables + +**Symptom**: Dev server stops rebuilding on file changes. No error messages. Requires manual restart. + +**Root cause**: When Nx's parallel `run-commands` executor ran the watch process and Astro server, the Nx daemon could self-disable mid-session (writing to `.nx/workspace-data/d/disabled`), causing `nx watch` to exit silently. + +**Fix**: Replaced Nx's parallel execution with `yarn concurrently --kill-others`: + +```json +"commands": [ + "NX_DAEMON=true yarn concurrently -n \"watch,astro\" --kill-others \"node watch.js charts\" \"nx run website:dev\"" +] +``` + +--- + +## 13. Dev setup cached across branch switches + +**Symptom**: After switching branches, the dev server serves examples from the previous branch. + +**Root cause**: The `dev:setup` target (which generates examples) was cached. Switching branches didn't change the cache key because the inputs were too narrow. Nx's cache is branch-unaware — it uses content hashes, not branch names — so if the input files happen to match (or the inputs are too narrow to capture the change), the old branch's output is served. + +Additionally, orphaned files in `dist/` from targets that only existed on the previous branch persist on disk because no target is responsible for cleaning them up. + +**Fix — two strategies:** + +1. **Set `cache: false` on orchestrator targets**: This forces the orchestrator to always re-evaluate its dependents, even when hashes match. Individual child targets can remain cached for performance. This is the recommended approach: + + ```json + "generate": { "cache": false } + ``` + +2. **Broaden the target's inputs** so that branch switching is more likely to invalidate the cache. For example, include a broader set of source files or add `{workspaceRoot}/package.json` to the inputs so that version bumps or script changes between branches trigger re-generation. This preserves caching benefits at the cost of occasional false invalidations. + +**Immediate workaround**: Run `nx reset` (or `yarn nx clean` if the repo has a clean target) to clear the Nx cache, then restart the dev server. Alternatively, use `--skip-nx-cache` for the specific generation target. + +--- + +## How to use this list + +When auditing a peer repo: + +1. Check the repo's history against when these fixes were applied +2. For each gotcha listed above, check whether the repo's Nx config has the same vulnerability +3. The fixes are listed — apply them as appropriate + +Most common gotchas in peer repos (in order of frequency): + +1. **#4** — `dist/` polluting input hashes (almost universal in repos without `buildOutputExcludes`) +2. **#1** — noop targets with inherited outputs destroying build artifacts +3. **#2** — test targets forcing full upstream builds +4. **#7** — lint config changes not invalidating lint cache +5. **#8** — noop targets invalidated by any NPM change diff --git a/external/ag-shared/prompts/skills/pr-review/_review-core.md b/external/ag-shared/prompts/skills/pr-review/_review-core.md index c9ca03b0dd7..174393ab957 100644 --- a/external/ag-shared/prompts/skills/pr-review/_review-core.md +++ b/external/ag-shared/prompts/skills/pr-review/_review-core.md @@ -53,14 +53,20 @@ Apply any repo-specific rules found (e.g., "Don't log PII", "Verify auth middlew ## 4. Workflow 1. Determine the PR number from `$ARGUMENTS` (required in CI, optional locally). -2. Determine if running in CI (PR refs pre-fetched) or locally (use `gh` CLI). -3. Fetch the PR diff and metadata using the appropriate method (see sections below). +2. Check if a **"Pre-generated PR Context"** section is appended to this prompt. If it is, use the metadata, commit messages, and diff provided directly — **do NOT run any git, gh, or shell commands**. The raw unified diff follows immediately after the context section's `---` separator. +3. Otherwise, determine if running in CI (PR refs pre-fetched) or locally (use `gh` CLI), and fetch the PR diff and metadata using the appropriate method (see sections below). 4. Analyse the changes and identify issues. 5. Output the review in the format specified by the calling prompt. +### Pre-supplied Diff (CI Default) + +In CI, the workflow pre-generates the diff and metadata and appends them to this prompt under a **"Pre-generated PR Context"** heading. The raw unified diff follows immediately after the `---` separator at the end of the context section. When this section is present: +- Use the provided metadata, commit messages, stats, and diff directly. +- **Do NOT execute any commands** — the sandbox does not support it. All required information is included in this prompt. + ### CI Environment (Sandboxed - No Network Access) -In CI, PR refs are pre-fetched by the workflow. Use git commands with these environment variables: +Fallback when diff is not pre-supplied. In CI, PR refs are pre-fetched by the workflow. Use git commands with these environment variables: - `$ARGUMENTS` - PR number - `$BASE_REF` - Target branch (e.g., `latest`, `main`) - `$HEAD_REF` - Source branch name (may be empty) diff --git a/external/ag-shared/prompts/skills/reflect/SKILL.md b/external/ag-shared/prompts/skills/reflect/SKILL.md new file mode 100644 index 00000000000..5a6deaf2463 --- /dev/null +++ b/external/ag-shared/prompts/skills/reflect/SKILL.md @@ -0,0 +1,219 @@ +--- +targets: ['*'] +name: reflect +description: 'Analyse the current conversation to identify where agentic configuration (rules, skills, sub-agents, commands) caused friction, and recommend specific improvements. Use this skill when the user says "reflect", "what went wrong", "what could be better", "improve the prompts", or after a long or friction-heavy session. Also use when the user asks to review how skills or rules performed during the conversation.' +invocable: user-only +context: fork +--- + +# Reflect — Agentic Configuration Improvement + +Analyse the current conversation to find where agentic configuration caused friction, wasted context, or produced wrong results. Output a structured report with actionable recommendations, then optionally apply improvements. + +## Arguments + +Parse optional flags from the invocation: + +- `--focus skills|rules|agents|commands|all` — narrow analysis scope (default: `all`) +- Free text — describe a specific pain point if the conversation doesn't make it obvious + +Examples: `/reflect`, `/reflect --focus skills`, `/reflect the jira skill kept loading when I was just editing code` + +--- + +## Phase 1: Conversation Mining + +Scan the conversation history above this skill invocation. For each friction signal, record the **evidence** (what happened), the **config source** (which rule, skill, or agent was involved), and the **impact** (wasted tokens, wrong output, user correction needed, time lost). + +### What to look for + +#### User Corrections + +The user explicitly corrected the agent's approach or output — "no", "wrong", "don't do that", "use X instead", "I said...". The agent made assumptions a rule should have prevented, or lacked knowledge a rule should have provided. + +**Likely root cause**: Rule gap, rule ambiguity, or rule not loaded for the relevant file pattern. + +#### Skill Misfires + +A skill was invoked but didn't match the user's intent. A skill was invoked multiple times for the same task (retry signal). A skill loaded but its guidance was ignored or contradicted by the agent. The user had to manually name a skill that should have auto-triggered, or a skill auto-triggered when it shouldn't have. + +**Likely root cause**: Skill description too broad or too narrow, missing trigger phrases, wrong `invocable` setting, or skill body missing key guidance. + +#### Rule Gaps + +The agent lacked knowledge that a rule should have provided. The agent violated a convention that exists in a rule but the rule wasn't loaded because the glob pattern didn't match the files being edited. The agent had to ask the user for information that's already documented somewhere. + +**Likely root cause**: Missing rule, wrong glob pattern, rule content incomplete or outdated. + +#### Sub-agent Focus Issues + +A sub-agent produced off-topic or low-quality output. A sub-agent lacked necessary tools or permissions. A sub-agent duplicated work already done by the main agent or another sub-agent. + +**Likely root cause**: Agent description too vague, wrong tool list, insufficient context in the agent prompt. + +#### Context Waste + +Large rules loaded that were irrelevant to the task. Skills auto-triggered when they shouldn't have. Redundant information loaded from overlapping rules. The conversation burned significant tokens on a dead-end approach that better guidance would have prevented. + +**Likely root cause**: Overly broad globs, missing `invocable: user-only`, rule overlap, or missing early-exit guidance. + +#### Permission and Configuration Issues + +Tool calls denied that should have been allowed. MCP servers unavailable when needed. Hooks blocked a legitimate workflow. + +**Likely root cause**: `.claude-settings.json` gaps, MCP config issues, hook logic too strict. + +#### Missing Capabilities + +The user needed a workflow that no skill or command covers. The agent had to improvise a multi-step process that should be codified. A repeatable task with no existing automation. + +**Likely root cause**: Missing skill or command. + +### How to mine + +1. Read through the conversation chronologically +2. Flag every instance where the user redirected, corrected, or expressed frustration +3. Flag every skill invocation and whether it helped or hindered +4. Flag every sub-agent spawn and whether its output was used +5. Note any repeated manual steps that could be automated +6. If the user provided free text describing a pain point, start there + +--- + +## Phase 2: Configuration Audit + +For each friction signal, trace it to the responsible configuration file. + +### Load the inventory + +Read `.rulesync/README.md` to understand what's available. Then, only for signals that need deeper investigation, read the specific config files involved. + +Do not read all config files upfront — only the ones relevant to identified friction. + +### Classify each finding + +For each friction signal, determine: + +| Field | Description | +|-------|-------------| +| **Category** | `skill-misfire`, `rule-gap`, `rule-overload`, `agent-focus`, `context-waste`, `permission-gap`, or `missing-capability` | +| **Severity** | `high` (blocked work or significant rework), `medium` (friction but worked around), `low` (minor annoyance) | +| **Config file** | Exact path to the responsible file, or "N/A — new file needed" | +| **Evidence** | Brief description of what happened in the conversation | +| **Recommendation** | Specific change: text to add/remove/modify, glob to adjust, frontmatter to change, or new file to create | + +--- + +## Phase 3: Report + +Present findings using this structure: + +```markdown +# Reflection Report + +**Conversation focus**: {brief description of what the session was about} +**Analysis scope**: {all | skills | rules | agents | commands} +**Findings**: {N} issue(s) across {M} categories + +--- + +## High Severity + +### H1: {Short title} + +**Category**: {category} +**Evidence**: {what happened} +**Config**: `{file path}` +**Problem**: {why the current config caused this} +**Recommendation**: {specific change — be concrete enough to act on} + +--- + +## Medium Severity + +### M1: {Short title} +{Same structure} + +--- + +## Low Severity + +### L1: {Short title} +{Same structure} + +--- + +## Recommended Changes + +| # | File | Change | Severity | +|---|------|--------|----------| +| 1 | `.rulesync/rules/foo.md` | Add section on X | High | +| 2 | `.rulesync/skills/bar/SKILL.md` | Narrow description trigger | Medium | + +## New Capabilities Needed + +{List any missing skills, commands, or rules that should be created, with a one-paragraph spec for each} +``` + +If no friction was found, say so — a clean conversation is valuable signal too. + +--- + +## Phase 4: Offer Next Steps + +After presenting the report, ask the user what they'd like to do: + +1. **Apply changes** — implement the recommended config changes directly (follow `.rulesync/` conventions from the `/rulesync` skill) +2. **Persist learnings** — feed high-severity findings into `/remember` (Project Memory Path) as rule/skill updates +3. **Create new skills** — if new capabilities were identified and `/skill-creator` is available, use it to draft them +4. **Create tasks** — log findings as tasks for later action +5. **Done** — report only, no further action + +Use AskUserQuestion with these options. Wait for the user's response. + +### Applying changes + +For each approved change: + +1. Read the target file +2. Apply the modification +3. Follow `.rulesync/` conventions: + - Never target `.claude/` directly — it's generated output + - Never modify `CLAUDE.md`, `AGENTS.md`, or `root: true` files + - Cross-repo reusable content → `external/ag-shared/prompts/` + - Product-specific content → `external/prompts/` + - Repo-specific content → `.rulesync/` directly +4. After all changes, regenerate and verify: + ```bash + ./external/ag-shared/scripts/setup-prompts/setup-prompts.sh + ./external/ag-shared/scripts/setup-prompts/verify-rulesync.sh + ``` + +### Creating new skills + +If the report identified missing capabilities and the user chose option 3: + +1. For each new skill spec from the "New Capabilities Needed" section +2. Invoke `/skill-creator` with the spec as context +3. The skill-creator handles drafting, testing, and iteration + +--- + +## Anti-patterns + +- **Do not invent problems** — only report friction that actually occurred in the conversation or that the user described. No hypothetical issues. +- **Do not auto-apply changes** — always present the report first and wait for explicit approval. +- **Do not load all config files upfront** — only read files relevant to identified friction signals. +- **Do not critique prompt writing style** — focus on functional issues (misfires, gaps, waste), not aesthetics or formatting preferences. +- **Do not duplicate `/validate-prompts`** — that skill checks structural path hygiene. This skill checks functional effectiveness. +- **Do not duplicate `/optimise-context`** — that command audits token budget. This skill audits conversation-level friction. + +## Relationship to Other Skills + +| Skill | Boundary | +|-------|----------| +| `/remember` | Reflect identifies *what* to improve; Remember persists the learnings | +| `/validate-prompts` | Validates structural correctness; Reflect validates functional effectiveness | +| `/optimise-context` | Optimises token budget; Reflect optimises guidance quality | +| `/rulesync` | Provides the conventions Reflect follows when applying changes | +| `/skill-creator` | Drafts new skills that Reflect identifies as missing capabilities | diff --git a/external/ag-shared/prompts/skills/rulesync/SKILL.md b/external/ag-shared/prompts/skills/rulesync/SKILL.md index 6218dc54e1a..1ffd5e40d7b 100644 --- a/external/ag-shared/prompts/skills/rulesync/SKILL.md +++ b/external/ag-shared/prompts/skills/rulesync/SKILL.md @@ -1,7 +1,7 @@ --- targets: ['*'] name: rulesync -description: 'Configure AI/agentic tooling using rulesync. Use when asking about .rulesync/, adding or editing commands, rules, skills, or subagents, configuring AI tools like Claude Code or Cursor, understanding where AI config files live, editing prompt files, or asking how to add a new command/rule/skill/agent. Also use when someone references .claude/, .cursor/, .copilot/ or similar tool-specific config directories.' +description: 'Use this skill whenever creating, editing, registering, or troubleshooting skills, commands, rules, subagents, or any AI prompt file. Covers SKILL.md authoring, frontmatter syntax (targets, description, globs, alwaysApply), symlink setup between .rulesync/ and external/ tiers, and regeneration/verification via setup-prompts.sh and verify-rulesync.sh. Also use when referencing .rulesync/, .claude/, .cursor/, .copilot/, or any AI tooling config directory — .rulesync/ is the single source of truth and generated directories must never be edited directly. IMPORTANT: Always load this skill alongside the skill-creator plugin — when creating or improving any skill, this skill provides the correct file locations, registration steps, and content tier decisions that the skill-creator workflow depends on.' --- # Rulesync Configuration Guide diff --git a/external/ag-shared/prompts/skills/sync-ag-shared/SKILL.md b/external/ag-shared/prompts/skills/sync-ag-shared/SKILL.md index 9f408748ca5..205a690e1d4 100644 --- a/external/ag-shared/prompts/skills/sync-ag-shared/SKILL.md +++ b/external/ag-shared/prompts/skills/sync-ag-shared/SKILL.md @@ -24,7 +24,7 @@ If the user provides a command option of `help`: - `git subrepo` must be installed (`git subrepo --version`). - **Use `yarn subrepo` for push and pull** (never raw `git subrepo push`/`pull`). The wrapper handles edge cases like stale parent references. Other subrepo commands (e.g. `git subrepo status`, `git subrepo clean`) use `git subrepo` directly. - **Never edit `external/ag-shared/.gitrepo` manually.** Only subrepo commands should modify this file. -- Must be on a **feature branch** (not `latest`, `main`, or `master`). +- Should be on a **feature branch**. If on `latest`/`main`/`master`, the skill will offer to create one. - Working tree must be **clean** (`git status --porcelain` is empty). - The current repo must have `external/ag-shared/.gitrepo`. @@ -55,11 +55,17 @@ SOURCE_REPO=$(basename "$SOURCE_ROOT") Validate: -- `SOURCE_BRANCH` is not `latest`, `main`, or `master`. - `git status --porcelain` is empty. - `external/ag-shared/.gitrepo` exists. -If any validation fails, report the issue and **STOP**. +**If on `latest`, `main`, or `master`:** offer to create and switch to a `sync-ag-shared` feature branch. If the user confirms: + +```bash +git checkout -b sync-ag-shared +SOURCE_BRANCH="sync-ag-shared" +``` + +If the user declines or any other validation fails, report the issue and **STOP**. ### 1b. Discover Destination Repos @@ -110,6 +116,18 @@ The sub-agent should produce: - Script changes may need `package.json` or CI updates. - Setup-prompts changes need `setup-prompts.sh` re-run in each repo. +### No Changes Detected (Force Sync) + +If `git diff latest...HEAD` shows no changes (i.e., the branch is at the same commit as `latest` or has no ag-shared changes): + +1. Inform the user that no local changes were found relative to `latest`. +2. Use `AskUserQuestion` to ask whether they want to proceed with a **force sync** — this will `yarn subrepo push ag-shared` to push the current `external/ag-shared/` state to the ag-shared remote, then pull it into all destination repos. This is useful when: + - The ag-shared remote is out of sync with the consuming repos. + - A previous sync was incomplete or failed partway through. + - Changes were committed directly to `latest` and need propagating. +3. If the user confirms, continue to Step 3 with an empty change summary. The plan should note this is a **force sync** with no new changes on the branch. +4. If the user declines, **STOP**. + ## STEP 3: Present Plan and Confirm Display to the user: diff --git a/external/ag-shared/prompts/skills/website-astro/SKILL.md b/external/ag-shared/prompts/skills/website-astro/SKILL.md index f2615d88d8b..c3a3b0c4a9a 100644 --- a/external/ag-shared/prompts/skills/website-astro/SKILL.md +++ b/external/ag-shared/prompts/skills/website-astro/SKILL.md @@ -94,7 +94,8 @@ external/ag-website-shared/src/ |------|------------|---------| | Astro pages | kebab-case | `license-pricing.astro` | | Components | PascalCase | `MyComponent.tsx` | -| Style modules | kebab-case | `my-page.module.scss` | +| Component styles | PascalCase | `MyComponent.module.scss` | +| Page styles | kebab-case | `my-page.module.scss` | | CSS classes | camelCase | `.pageContainer` | ## Common Tasks From 3f5712427b1abe3c540ea850c8fd7dd4baed702f Mon Sep 17 00:00:00 2001 From: Alan Treadway Date: Tue, 17 Mar 2026 15:33:47 +0000 Subject: [PATCH 2/4] Add nx-performance and reflect skill symlinks --- .rulesync/skills/nx-performance | 1 + .rulesync/skills/reflect | 1 + 2 files changed, 2 insertions(+) create mode 120000 .rulesync/skills/nx-performance create mode 120000 .rulesync/skills/reflect diff --git a/.rulesync/skills/nx-performance b/.rulesync/skills/nx-performance new file mode 120000 index 00000000000..651fde80d80 --- /dev/null +++ b/.rulesync/skills/nx-performance @@ -0,0 +1 @@ +../../external/ag-shared/prompts/skills/nx-performance/ \ No newline at end of file diff --git a/.rulesync/skills/reflect b/.rulesync/skills/reflect new file mode 120000 index 00000000000..5689df16114 --- /dev/null +++ b/.rulesync/skills/reflect @@ -0,0 +1 @@ +../../external/ag-shared/prompts/skills/reflect/ \ No newline at end of file From a16aae8f271cb36330e049f22c5a5c4ad3d8419d Mon Sep 17 00:00:00 2001 From: Alan Treadway Date: Tue, 17 Mar 2026 15:45:30 +0000 Subject: [PATCH 3/4] Update rulesync README with nx-performance and reflect skills --- .rulesync/README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.rulesync/README.md b/.rulesync/README.md index fa2d2022163..24538ebb544 100644 --- a/.rulesync/README.md +++ b/.rulesync/README.md @@ -55,19 +55,21 @@ Quick-reference for all AI agent commands, skills, sub-agents, and rules availab ## Planning and Analysis -| Type | Name | Invoke | What it does | -| ----- | ------------------------------- | ------------------------------------ | ------------------------------------------------ | -| Skill | 🔵 `plan-review` | `/plan-review` (user) | Review plans for completeness and correctness | -| Skill | 🔵 `plan-implementation-review` | `/plan-implementation-review` (user) | Review plan execution, identify delivery gaps | -| Skill | 🔵 `jira` | `/jira` | Create, estimate, or analyse JIRA tickets | -| Agent | 🔵 `nx-expert` | Auto | Nx monorepo configuration and build optimisation | +| Type | Name | Invoke | What it does | +| ----- | ------------------------------- | ------------------------------------ | ---------------------------------------------------------- | +| Skill | 🔵 `jira` | `/jira` | Create, estimate, or analyse JIRA tickets | +| Skill | 🔵 `nx-performance` | `/nx-performance` | Nx monorepo performance diagnostics and optimization | +| Skill | 🔵 `plan-implementation-review` | `/plan-implementation-review` (user) | Review plan execution, identify delivery gaps | +| Skill | 🔵 `plan-review` | `/plan-review` (user) | Review plans for completeness and correctness | +| Agent | 🔵 `nx-expert` | Auto | Nx monorepo configuration and build optimisation | ## Prompt Hygiene | Type | Name | Invoke | What it does | | ----- | --------------------- | -------------------------- | ------------------------------------------------ | -| Skill | 🔵 `validate-prompts` | `/validate-prompts` (user) | Validate prompt file references for path hygiene | +| Skill | 🔵 `reflect` | `/reflect` (user) | Self-reflection and meta-cognitive analysis | | Skill | 🔵 `rulesync` | `/rulesync` | Configure AI/agentic tooling via `.rulesync/` | +| Skill | 🔵 `validate-prompts` | `/validate-prompts` (user) | Validate prompt file references for path hygiene | ## Memory @@ -144,12 +146,14 @@ Skills load on-demand when invoked. All skills are invoked via `/skill-name`. Al | 🔵 `git-split` | Split large files preserving git history | | 🔵 `git-worktree-clean` | Hard-reset worktree to `origin/latest` | | 🔵 `jira` | Create, estimate, or analyse JIRA tickets | +| 🔵 `nx-performance` | Nx monorepo performance diagnostics and optimization | | 🔵 `plan-implementation-review` | Review plan execution, identify delivery gaps | | 🔵 `plan-review` | Review plans for completeness and correctness | | 🔵 `pr-create` | Commit, push, and open a PR | | 🔵 `pr-review` | Review a PR (Markdown default, JSON with `--json`) | | 🔵 `pr-split` | Split a branch into stacked PRs | | 🔵 `recall` | Load branch context, browse project memories | +| 🔵 `reflect` | Self-reflection and meta-cognitive analysis | | 🔵 `remember` | Save branch context or project learnings as memory | | 🔵 `rulesync` | Configure AI/agentic tooling via `.rulesync/` | | 🔵 `sync-ag-shared` | Sync ag-shared subrepo changes across AG repos | From 9d20f31458b800e0fd5c89d02664def3a9d60084 Mon Sep 17 00:00:00 2001 From: Alan Treadway Date: Tue, 17 Mar 2026 15:55:25 +0000 Subject: [PATCH 4/4] Format rulesync README to fix CI format check --- .rulesync/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.rulesync/README.md b/.rulesync/README.md index 24538ebb544..00f66521897 100644 --- a/.rulesync/README.md +++ b/.rulesync/README.md @@ -55,13 +55,13 @@ Quick-reference for all AI agent commands, skills, sub-agents, and rules availab ## Planning and Analysis -| Type | Name | Invoke | What it does | -| ----- | ------------------------------- | ------------------------------------ | ---------------------------------------------------------- | -| Skill | 🔵 `jira` | `/jira` | Create, estimate, or analyse JIRA tickets | -| Skill | 🔵 `nx-performance` | `/nx-performance` | Nx monorepo performance diagnostics and optimization | -| Skill | 🔵 `plan-implementation-review` | `/plan-implementation-review` (user) | Review plan execution, identify delivery gaps | -| Skill | 🔵 `plan-review` | `/plan-review` (user) | Review plans for completeness and correctness | -| Agent | 🔵 `nx-expert` | Auto | Nx monorepo configuration and build optimisation | +| Type | Name | Invoke | What it does | +| ----- | ------------------------------- | ------------------------------------ | ---------------------------------------------------- | +| Skill | 🔵 `jira` | `/jira` | Create, estimate, or analyse JIRA tickets | +| Skill | 🔵 `nx-performance` | `/nx-performance` | Nx monorepo performance diagnostics and optimization | +| Skill | 🔵 `plan-implementation-review` | `/plan-implementation-review` (user) | Review plan execution, identify delivery gaps | +| Skill | 🔵 `plan-review` | `/plan-review` (user) | Review plans for completeness and correctness | +| Agent | 🔵 `nx-expert` | Auto | Nx monorepo configuration and build optimisation | ## Prompt Hygiene