@groupby/ai-dev 0.5.8 → 0.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/package.json +1 -1
  2. package/teams/agentic-checkout/prompts/AGENTS.md +103 -0
  3. package/teams/agentic-checkout/prompts/create-plan.md +103 -0
  4. package/teams/agentic-checkout/prompts/create-pull-request.md +157 -0
  5. package/teams/agentic-checkout/prompts/fix-pr-comments.md +170 -0
  6. package/teams/agentic-checkout/prompts/fix-review-findings.md +1 -12
  7. package/teams/agentic-checkout/prompts/implement-task.md +62 -0
  8. package/teams/agentic-checkout/prompts/new-workspace.md +12 -0
  9. package/teams/agentic-checkout/prompts/orchestrate-component-change.md +25 -0
  10. package/teams/agentic-checkout/prompts/review-change.md +8 -2
  11. package/teams/agentic-checkout/scripts/check-secrets +51 -0
  12. package/teams/agentic-checkout/scripts/install-git-hooks +15 -0
  13. package/teams/agentic-checkout/scripts/local-fast-report +5 -0
  14. package/teams/agentic-checkout/scripts/local-report +205 -0
  15. package/teams/agentic-checkout/scripts/local-summarize +47 -0
  16. package/teams/agentic-checkout/scripts/logs-deps +9 -0
  17. package/teams/agentic-checkout/scripts/setup-local-fast-model +20 -0
  18. package/teams/agentic-checkout/scripts/start-deps +15 -0
  19. package/teams/agentic-checkout/scripts/status-deps +9 -0
  20. package/teams/agentic-checkout/scripts/stop-deps +9 -0
  21. package/teams/agentic-checkout/scripts/sync-components +110 -0
  22. package/teams/agentic-checkout/skills/approval-gated-task-execution/SKILL.md +57 -0
  23. package/teams/agentic-checkout/skills/component-verification/SKILL.md +34 -0
  24. package/teams/agentic-checkout/skills/grill-me/SKILL.md +23 -0
  25. package/teams/agentic-checkout/skills/karpathy-guidelines/SKILL.md +67 -0
  26. package/teams/agentic-checkout/skills/secret-safety/SKILL.md +41 -0
  27. package/teams/agentic-checkout/skills/sync-components/SKILL.md +23 -60
  28. package/teams/agentic-checkout/skills/tdd/SKILL.md +48 -0
  29. package/teams/rangers/resources/project-doc-contract.md +41 -0
  30. package/teams/rangers/skills/team-code-review/SKILL.md +66 -0
  31. package/teams/rangers/skills/team-development/SKILL.md +43 -0
  32. package/teams/rangers/skills/team-docs-snapshot/SKILL.md +58 -0
  33. package/teams/rangers/skills/team-docs-snapshot/scripts/collect_project_docs.py +166 -0
  34. package/teams/rangers/skills/team-phase-planning/SKILL.md +63 -0
  35. package/teams/rangers/skills/team-project-orientation/SKILL.md +46 -0
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: karpathy-guidelines
3
+ description: Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.
4
+ license: MIT
5
+ ---
6
+
7
+ # Karpathy Guidelines
8
+
9
+ Behavioral guidelines to reduce common LLM coding mistakes, derived from [Andrej Karpathy's observations](https://x.com/karpathy/status/2015883857489522876) on LLM coding pitfalls.
10
+
11
+ **Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
12
+
13
+ ## 1. Think Before Coding
14
+
15
+ **Don't assume. Don't hide confusion. Surface tradeoffs.**
16
+
17
+ Before implementing:
18
+ - State your assumptions explicitly. If uncertain, ask.
19
+ - If multiple interpretations exist, present them - don't pick silently.
20
+ - If a simpler approach exists, say so. Push back when warranted.
21
+ - If something is unclear, stop. Name what's confusing. Ask.
22
+
23
+ ## 2. Simplicity First
24
+
25
+ **Minimum code that solves the problem. Nothing speculative.**
26
+
27
+ - No features beyond what was asked.
28
+ - No abstractions for single-use code.
29
+ - No "flexibility" or "configurability" that wasn't requested.
30
+ - No error handling for impossible scenarios.
31
+ - If you write 200 lines and it could be 50, rewrite it.
32
+
33
+ Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
34
+
35
+ ## 3. Surgical Changes
36
+
37
+ **Touch only what you must. Clean up only your own mess.**
38
+
39
+ When editing existing code:
40
+ - Don't "improve" adjacent code, comments, or formatting.
41
+ - Don't refactor things that aren't broken.
42
+ - Match existing style, even if you'd do it differently.
43
+ - If you notice unrelated dead code, mention it - don't delete it.
44
+
45
+ When your changes create orphans:
46
+ - Remove imports/variables/functions that YOUR changes made unused.
47
+ - Don't remove pre-existing dead code unless asked.
48
+
49
+ The test: Every changed line should trace directly to the user's request.
50
+
51
+ ## 4. Goal-Driven Execution
52
+
53
+ **Define success criteria. Loop until verified.**
54
+
55
+ Transform tasks into verifiable goals:
56
+ - "Add validation" → "Write tests for invalid inputs, then make them pass"
57
+ - "Fix the bug" → "Write a test that reproduces it, then make it pass"
58
+ - "Refactor X" → "Ensure tests pass before and after"
59
+
60
+ For multi-step tasks, state a brief plan:
61
+ ```
62
+ 1. [Step] → verify: [check]
63
+ 2. [Step] → verify: [check]
64
+ 3. [Step] → verify: [check]
65
+ ```
66
+
67
+ Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: secret-safety
3
+ description: Prevent credentials and sensitive tokens from being committed, logged, or pushed. Use before commits, pushes, PRs, and when editing config or examples.
4
+ license: MIT
5
+ ---
6
+
7
+ # Secret Safety
8
+
9
+ Use this skill before committing, pushing, creating PRs, or editing configuration, examples, logs, credentials, or local
10
+ environment files.
11
+
12
+ ## Rules
13
+
14
+ - Never commit real credentials, API keys, private keys, tokens, session cookies, certificates, keystores, or populated `.env` files.
15
+ - Keep secrets in environment variables, local untracked files, Vault, Azure Key Vault, GitHub Actions secrets, or another approved secret store.
16
+ - Only commit placeholder examples such as `.env.example`, `.env.sample`, or documentation values that are clearly non-secret.
17
+ - Do not paste secrets into prompts, PR descriptions, logs, commit messages, plans, or generated documentation.
18
+ - If a secret appears in a tracked file, stop and remove it before committing or pushing.
19
+ - If a real secret was committed or pushed, treat it as compromised: rotate/revoke it and remove it from git history using an approved process.
20
+
21
+ ## Checks
22
+
23
+ Run the harness secret scanner before commit or push:
24
+
25
+ ```bash
26
+ scripts/check-secrets .
27
+ ```
28
+
29
+ When checking a component repository from the harness root, pass the component path:
30
+
31
+ ```bash
32
+ scripts/check-secrets components/<component>
33
+ ```
34
+
35
+ Install the harness pre-push hook for the harness checkout:
36
+
37
+ ```bash
38
+ scripts/install-git-hooks
39
+ ```
40
+
41
+ The scanner is a guardrail, not a guarantee. Also inspect diffs manually for sensitive values.
@@ -1,76 +1,39 @@
1
1
  ---
2
2
  name: sync-components
3
- description: Sync a multi-repository component workspace by cloning repositories listed in components.txt with minimal inspection. Use when asked to sync up, clone, or refresh project components.
3
+ description: Sync component repositories from components.txt using the deterministic harness script.
4
4
  license: MIT
5
5
  ---
6
6
 
7
7
  # Sync Components
8
8
 
9
- Use this skill when the user asks to sync up a project's component repositories.
10
-
11
- ## Goal
12
-
13
- Populate `components/` from the entries in `components.txt` using `git clone`, and leave each synced component on the `main` branch.
14
-
15
- Keep this workflow lightweight. Do not inspect component source trees, run builds, run tests, scan every repository, or perform broad Git status checks unless the user explicitly asks.
16
-
17
- Do not create a shell script, temporary script, generated helper, Makefile target, or wrapper command for this workflow. Running generated scripts often triggers extra approval prompts. Use direct shell commands only.
18
-
19
- ## Source Of Truth
20
-
21
- Read `components.txt` from the framework or workspace checkout.
22
-
23
- Each non-empty, non-comment line is either:
24
-
25
- - A full Git remote URL, used as-is.
26
- - A repository name. If the file uses bare repository names, infer the Git remote from the project instructions or ask the user for the organization/remote prefix before cloning.
27
-
28
- The local checkout path for each entry is:
29
-
30
- ```text
31
- components/<repo-name>
32
- ```
33
-
34
- Derive `<repo-name>` from the entry basename and remove a trailing `.git`.
9
+ Use when the user asks to sync, clone, refresh, or update component repositories.
35
10
 
36
11
  ## Workflow
37
12
 
38
- 1. Confirm the current directory is the framework checkout.
39
- 2. Create `components/` if it does not exist.
40
- 3. Read `components.txt`.
41
- 4. For each component entry:
42
- - If `components/<repo-name>` does not exist, run:
43
-
44
- ```bash
45
- git clone <remote> components/<repo-name>
46
- ```
47
-
48
- - If the directory already exists, keep it and report `exists`.
49
- - After clone or exists, run:
50
-
51
- ```bash
52
- git -C components/<repo-name> checkout main
53
- ```
13
+ 1. Ask for the user's command approval through the normal Copilot CLI approval flow; do not enable `/allow-all`.
14
+ 2. Run exactly one of these commands after approval:
54
15
 
55
- - If `main` is not available locally, fetch only the main branch and try again:
16
+ ```bash
17
+ scripts/sync-components
18
+ ```
56
19
 
57
- ```bash
58
- git -C components/<repo-name> fetch origin main
59
- git -C components/<repo-name> checkout main
60
- ```
20
+ or, when a local fast model summary is useful:
61
21
 
62
- 5. Report only cloned, existing, checked-out-main, skipped, and failed component names.
22
+ ```bash
23
+ scripts/local-fast-report sync
24
+ ```
63
25
 
64
- Prefer issuing the `git clone` commands directly from the terminal. It is acceptable to run them one at a time. Do not generate a loop script or ask the user to run a script.
26
+ 3. Label `scripts/local-fast-report sync` runs as using the local fast model in any shell command title/description.
27
+ 4. Do not run both commands; `scripts/local-fast-report sync` already runs `scripts/sync-components`.
28
+ 5. Report cloned, existing, checked-out-main, rebased-main, skipped-dirty, and failed components.
29
+ 6. If any component is `skipped-dirty`, stop and ask before destructive cleanup or retry.
65
30
 
66
- ## Constraints
31
+ ## Rules
67
32
 
68
- - Use direct `git clone` commands for this workflow.
69
- - Do not create, modify, chmod, or execute any sync script.
70
- - Do not use heredocs, shell redirection, or generated files to automate cloning.
71
- - Do not delete, reset, clean, or force checkout any component repository.
72
- - Do not pull existing repositories unless the user asks to update already-cloned components.
73
- - Do not fetch existing repositories except `git fetch origin main` when needed to make `main` available for checkout.
74
- - Do not open or validate component-local instruction files during this sync workflow.
75
- - Do not run dependency installation, tests, formatters, linters, or builds.
76
- - Keep all cloned repositories directly under `components/`.
33
+ - Do not reimplement sync with model-driven `git clone`/`fetch`/`checkout`/`rebase` sequences unless the script fails and
34
+ the user approves manual recovery.
35
+ - Do not bypass the user's normal command approval prompts.
36
+ - Never delete, reset, clean, force-checkout, or discard existing component work without explicit approval for that
37
+ component.
38
+ - Do not inspect component source, install dependencies, run tests/builds/formatters/linters, or read component-local
39
+ instructions during sync.
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: tdd
3
+ description: Use a test-driven workflow for implementation tasks. Write or update a failing test first, implement the smallest change to pass, then verify and refactor.
4
+ license: MIT
5
+ ---
6
+
7
+ # TDD
8
+
9
+ Use this skill when the user asks for TDD, test-first development, bug fixes with regression tests, or implementation
10
+ where behavior should be proven by tests.
11
+
12
+ ## Workflow
13
+
14
+ 1. Identify the smallest observable behavior change.
15
+ 2. Find the closest existing test file, fixture style, and assertion pattern.
16
+ 3. Write or update a focused test before changing production code.
17
+ 4. Run the narrowest relevant test command and confirm the test fails for the expected reason.
18
+ 5. Implement the smallest production change needed to pass.
19
+ 6. Re-run the focused test.
20
+ 7. Run the nearest broader relevant test set when the change touches shared behavior, contracts, event payloads, or
21
+ public APIs.
22
+ 8. Refactor only after tests pass, then re-run the focused test.
23
+
24
+ ## Component Commands
25
+
26
+ Prefer component-local instructions when present. Otherwise use the verification matrix in `AGENTS.md` as the canonical source for install/test/build/lint commands.
27
+
28
+ For focused tests, use the component's existing test runner syntax for a single file, module, class, or test case.
29
+
30
+ ## Constraints
31
+
32
+ - Do not make broad refactors before the red/green loop is complete.
33
+ - Do not add new test frameworks or dependencies unless the component already uses them and the change requires it.
34
+ - Do not add large test scaffolding when an existing test style can cover the behavior.
35
+ - Do not skip the failing-test step unless tests cannot run locally or the change is documentation/configuration only.
36
+ - If the failing-test step is skipped, explain why before editing production code.
37
+ - Keep tests focused on observable behavior, not private implementation details.
38
+ - For bug fixes, the first test should fail on the original bug.
39
+ - For new behavior, the first test should encode the expected contract or user-visible behavior.
40
+
41
+ ## Reporting
42
+
43
+ In the final response, include:
44
+
45
+ - The test added or changed.
46
+ - The initial failing command and failure summary, if run.
47
+ - The passing verification command.
48
+ - Any broader tests that were skipped and why.
@@ -0,0 +1,41 @@
1
+ # Rangers Project Documentation Contract
2
+
3
+ Rangers skills expect project-specific truth to live in each project repo, not in shared skills.
4
+
5
+ ## Preferred Entrypoints
6
+
7
+ - `docs/ai/index.md` - primary AI context routing table
8
+ - `docs/ai/working-agreement.md` - non-negotiable team and workflow rules
9
+ - `docs/project/ai-context.md` - project-specific routing, priorities, and domain language
10
+ - `.github/copilot-instructions.md` - compatibility shim for GitHub Copilot
11
+
12
+ ## Common Supporting Docs
13
+
14
+ - `docs/project/architecture.md`
15
+ - `docs/project/decision-log.md`
16
+ - `docs/project/phase-plan.md`
17
+ - `docs/ai/workflow.md`
18
+ - `docs/ai/code-review-checklist.md`
19
+ - `docs/ai/component-patterns.md`
20
+ - `docs/ai/styling.md`
21
+ - `docs/ai/state-management.md`
22
+ - API or contract docs under `docs/project/` or `docs/ai/`
23
+
24
+ ## Operating Rules
25
+
26
+ - Load the router first, then follow its task-specific map.
27
+ - Load the smallest useful context set.
28
+ - Treat project docs as the intended target state unless the user says otherwise.
29
+ - Keep review artifacts, snapshots, and scratch planning notes in gitignored project scratch space such as `tmp/`.
30
+ - Update project docs when implementation changes durable architecture, workflow, API contracts, or conventions.
31
+
32
+ ## Skill-First Scaffolding Expectations
33
+
34
+ Generated project scaffolding should install Rangers skills alongside the project docs, then expose them to the LLM clients the team actually uses.
35
+
36
+ - Copy full skills to `docs/ai/skills/<skill-name>/`.
37
+ - Create lightweight skill stubs in `.github/skills/<skill-name>/SKILL.md` for Copilot when `.github/` is present.
38
+ - Create lightweight skill stubs in `.claude/skills/<skill-name>/SKILL.md` for Claude Code when `.claude/` is present.
39
+ - Preserve each skill's `name` and `description` frontmatter in client stubs so plain-text requests such as "run a code review" can trigger the right skill.
40
+ - Keep `docs/ai/index.md` as the project routing table, but have it route task types to skills first and local docs second.
41
+ - Do not require Codex-specific metadata such as `agents/openai.yaml` unless a project explicitly supports Codex users.
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: team-code-review
3
+ description: >-
4
+ Review current changes against the repository's AI routing docs, working agreement, architecture, code-review checklist, and changed files. Use for phase reviews, final branch reviews, PR readiness checks, or focused reviews where findings should be prioritized before summary.
5
+ ---
6
+
7
+ # Team Code Review
8
+
9
+ ## Purpose
10
+
11
+ Use this skill for read-first review work. The project docs define the review standard; the changed files define the review surface.
12
+
13
+ ## Review Setup
14
+
15
+ 1. Determine the diff under review:
16
+ - prefer `git diff origin/main...HEAD` for branch review
17
+ - fall back to `git diff HEAD` for unstaged or local-only changes
18
+ - use a user-specified base if provided
19
+ 2. Load the project router:
20
+ - `docs/ai/index.md`
21
+ - `.github/copilot-instructions.md`
22
+ - `docs/project/ai-context.md`
23
+ - `docs/ai/resources/project-doc-contract.md`, if no project router exists
24
+ 3. Load review-specific docs:
25
+ - working agreement
26
+ - workflow
27
+ - code review checklist
28
+ - architecture or task-specific docs named by the router
29
+ 4. Inspect changed files and nearby code before writing findings.
30
+
31
+ ## Review Standards
32
+
33
+ Prioritize defects and regressions over style. Check:
34
+
35
+ - correctness and user-visible behavior
36
+ - architecture and documented conventions
37
+ - security, permissions, and sensitive data handling
38
+ - error handling and failure states
39
+ - performance and lifecycle cleanup
40
+ - accessibility for UI work
41
+ - test coverage and validation gaps
42
+ - docs drift caused by the change
43
+
44
+ If the code contradicts project docs, treat that as a finding unless the change deliberately updates the documented target state.
45
+
46
+ ## Output
47
+
48
+ Lead with findings ordered by severity. Include tight file and line references when possible.
49
+
50
+ Use this shape:
51
+
52
+ ```markdown
53
+ ## Findings
54
+ - [P1/P2/P3] file:line - Issue and impact.
55
+
56
+ ## Open Questions
57
+ - [Question]
58
+
59
+ ## Summary
60
+ [Brief assessment]
61
+
62
+ ## Validation Gaps
63
+ - [Gap]
64
+ ```
65
+
66
+ If the project workflow requires a review artifact, write it to the documented scratch location, commonly `tmp/review-phase-XX.md` or `tmp/review-final.md`.
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: team-development
3
+ description: >-
4
+ Guide normal implementation work by loading a project's AI router, working agreement, architecture docs, and task-specific docs before editing. Use for feature work, bug fixes, refactors, UI changes, API integration, and documentation updates in repos that expose project-owned AI context.
5
+ ---
6
+
7
+ # Team Development
8
+
9
+ ## Purpose
10
+
11
+ Use this skill as the default implementation workflow for Rangers projects. It keeps shared process in the skill and project truth in the project docs.
12
+
13
+ ## Context Loading
14
+
15
+ 1. Read the project router first:
16
+ - prefer `docs/ai/index.md`
17
+ - also check `.github/copilot-instructions.md`
18
+ - use `docs/project/ai-context.md` for project-specific priorities
19
+ - use `docs/ai/resources/project-doc-contract.md` as a fallback contract if no project router exists
20
+ 2. Always load the working agreement if present.
21
+ 3. Load only task-relevant docs from the router. Common routes:
22
+ - UI/components: component patterns, styling, frontend scope
23
+ - API/data/state: API contract, state management, architecture
24
+ - architecture decisions: architecture docs and decision log
25
+ - phase work: workflow, phase plan, review checklist
26
+ 4. If the task requires comparing or migrating many docs, use `team-docs-snapshot`.
27
+
28
+ ## Implementation Flow
29
+
30
+ 1. Check git status and current branch.
31
+ 2. Inspect the relevant files before editing.
32
+ 3. Make a short working plan when the change spans multiple files or behaviors.
33
+ 4. Edit narrowly and follow established local patterns.
34
+ 5. Update project docs when the implementation changes architecture, workflow, API contracts, or durable conventions.
35
+ 6. Run the smallest meaningful validation for the changed surface.
36
+ 7. Summarize changed files, validation, and any remaining risks.
37
+
38
+ ## Rules
39
+
40
+ - Let project docs define the target state. If code and docs disagree, flag the mismatch or update docs as part of the work.
41
+ - Do not load every doc by default.
42
+ - Do not turn project-specific facts into shared skill instructions.
43
+ - Keep scratch notes and reviews in the location the project workflow specifies, commonly `tmp/`.
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: team-docs-snapshot
3
+ description: >-
4
+ Collect AI/project documentation from a repository into a temporary review folder. Use when documentation needs to be pulled together for orientation, planning, review, migration, or skill-authoring analysis without loading every source file into the active context.
5
+ ---
6
+
7
+ # Team Docs Snapshot
8
+
9
+ ## Purpose
10
+
11
+ Use this skill to gather a project's AI-facing documentation into a disposable snapshot. Prefer it when the task is about understanding or migrating docs, comparing routing systems, reviewing documentation drift, or preparing a compact handoff for another session.
12
+
13
+ ## Workflow
14
+
15
+ 1. Identify the target repository root.
16
+ 2. Check for a project routing contract before collecting files:
17
+ - `docs/ai/index.md`
18
+ - `docs/project/ai-context.md`
19
+ - `.github/copilot-instructions.md`
20
+ - `AGENTS.md`
21
+ 3. Run the bundled collector from the project root or pass `--root` explicitly:
22
+
23
+ ```sh
24
+ python3 docs/ai/skills/team-docs-snapshot/scripts/collect_project_docs.py --root .
25
+ ```
26
+
27
+ If the skill is being used from the shared repo source instead of an installed project copy, run the script from this skill folder:
28
+
29
+ ```sh
30
+ python3 teams/rangers/skills/team-docs-snapshot/scripts/collect_project_docs.py --root /path/to/project
31
+ ```
32
+
33
+ 4. Read the generated `MANIFEST.md` first. Use it to decide which copied docs to load next.
34
+ 5. Treat the snapshot as scratch material. Do not commit it unless the user explicitly asks.
35
+
36
+ ## Collector Options
37
+
38
+ - `--out <dir>` writes to a specific snapshot directory.
39
+ - `--include <glob>` adds extra files. Repeat it for multiple patterns.
40
+ - `--exclude <glob>` removes files from the default or included matches.
41
+ - `--combined` also writes `COMBINED.md` for tools that need one linear document.
42
+
43
+ Default collection includes common project guidance docs:
44
+
45
+ - `docs/ai/**/*.md`
46
+ - `docs/project/**/*.md`
47
+ - `.github/copilot-instructions.md`
48
+ - `AGENTS.md`
49
+ - `README.md`
50
+
51
+ ## Output Expectations
52
+
53
+ When reporting back, include only:
54
+
55
+ - snapshot directory
56
+ - number of files collected
57
+ - notable missing entrypoints
58
+ - recommended docs to read next
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env python3
2
+ """Collect project AI/documentation files into a temporary snapshot directory."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import fnmatch
8
+ import shutil
9
+ from datetime import datetime
10
+ from pathlib import Path
11
+
12
+
13
+ DEFAULT_PATTERNS = [
14
+ "docs/ai/**/*.md",
15
+ "docs/project/**/*.md",
16
+ ".github/copilot-instructions.md",
17
+ "AGENTS.md",
18
+ "README.md",
19
+ ]
20
+
21
+ DEFAULT_EXCLUDES = [
22
+ ".git/**",
23
+ "node_modules/**",
24
+ "tmp/**",
25
+ "dist/**",
26
+ "build/**",
27
+ ]
28
+
29
+
30
+ def parse_args() -> argparse.Namespace:
31
+ parser = argparse.ArgumentParser(
32
+ description="Copy project AI-facing docs into a temporary review snapshot.",
33
+ )
34
+ parser.add_argument(
35
+ "--root",
36
+ default=".",
37
+ help="Project root to scan. Defaults to the current directory.",
38
+ )
39
+ parser.add_argument(
40
+ "--out",
41
+ help="Snapshot output directory. Defaults to <root>/tmp/ai-docs-snapshot-<timestamp>.",
42
+ )
43
+ parser.add_argument(
44
+ "--include",
45
+ action="append",
46
+ default=[],
47
+ help="Additional glob to include. Can be repeated.",
48
+ )
49
+ parser.add_argument(
50
+ "--exclude",
51
+ action="append",
52
+ default=[],
53
+ help="Glob to exclude from copied results. Can be repeated.",
54
+ )
55
+ parser.add_argument(
56
+ "--combined",
57
+ action="store_true",
58
+ help="Also write COMBINED.md with all copied docs in one file.",
59
+ )
60
+ return parser.parse_args()
61
+
62
+
63
+ def is_excluded(relative_path: str, patterns: list[str]) -> bool:
64
+ return any(fnmatch.fnmatch(relative_path, pattern) for pattern in patterns)
65
+
66
+
67
+ def collect_matches(root: Path, includes: list[str], excludes: list[str]) -> list[Path]:
68
+ matches: set[Path] = set()
69
+ for pattern in includes:
70
+ for match in root.glob(pattern):
71
+ if match.is_file():
72
+ matches.add(match.resolve())
73
+
74
+ root_resolved = root.resolve()
75
+ filtered: list[Path] = []
76
+ for match in matches:
77
+ try:
78
+ relative = match.relative_to(root_resolved).as_posix()
79
+ except ValueError:
80
+ continue
81
+ if not is_excluded(relative, excludes):
82
+ filtered.append(match)
83
+
84
+ return sorted(filtered, key=lambda path: path.relative_to(root_resolved).as_posix())
85
+
86
+
87
+ def write_manifest(root: Path, out_dir: Path, files: list[Path], missing: list[str]) -> None:
88
+ lines = [
89
+ "# Project Docs Snapshot",
90
+ "",
91
+ f"Source root: `{root}`",
92
+ f"Generated: `{datetime.now().isoformat(timespec='seconds')}`",
93
+ f"Files collected: {len(files)}",
94
+ "",
95
+ "## Files",
96
+ "",
97
+ ]
98
+ for file_path in files:
99
+ relative = file_path.relative_to(root).as_posix()
100
+ lines.append(f"- `{relative}`")
101
+
102
+ if missing:
103
+ lines.extend(["", "## Missing Common Entrypoints", ""])
104
+ for pattern in missing:
105
+ lines.append(f"- `{pattern}`")
106
+
107
+ out_dir.joinpath("MANIFEST.md").write_text("\n".join(lines) + "\n", encoding="utf-8")
108
+
109
+
110
+ def write_combined(root: Path, out_dir: Path, files: list[Path]) -> None:
111
+ sections: list[str] = ["# Combined Project Docs", ""]
112
+ for file_path in files:
113
+ relative = file_path.relative_to(root).as_posix()
114
+ sections.extend([f"## {relative}", ""])
115
+ try:
116
+ sections.append(file_path.read_text(encoding="utf-8"))
117
+ except UnicodeDecodeError:
118
+ sections.append("[Skipped: file is not UTF-8 text]")
119
+ sections.append("")
120
+ out_dir.joinpath("COMBINED.md").write_text("\n".join(sections), encoding="utf-8")
121
+
122
+
123
+ def main() -> int:
124
+ args = parse_args()
125
+ root = Path(args.root).expanduser().resolve()
126
+ if not root.is_dir():
127
+ raise SystemExit(f"Project root does not exist or is not a directory: {root}")
128
+
129
+ timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
130
+ out_dir = (
131
+ Path(args.out).expanduser().resolve()
132
+ if args.out
133
+ else root / "tmp" / f"ai-docs-snapshot-{timestamp}"
134
+ )
135
+ out_dir.mkdir(parents=True, exist_ok=False)
136
+
137
+ includes = DEFAULT_PATTERNS + args.include
138
+ excludes = DEFAULT_EXCLUDES + args.exclude
139
+ files = collect_matches(root, includes, excludes)
140
+
141
+ missing = []
142
+ for pattern in DEFAULT_PATTERNS:
143
+ if not any(root.glob(pattern)):
144
+ missing.append(pattern)
145
+
146
+ for file_path in files:
147
+ relative = file_path.relative_to(root)
148
+ destination = out_dir / relative
149
+ destination.parent.mkdir(parents=True, exist_ok=True)
150
+ shutil.copy2(file_path, destination)
151
+
152
+ write_manifest(root, out_dir, files, missing)
153
+ if args.combined:
154
+ write_combined(root, out_dir, files)
155
+
156
+ print(f"Snapshot: {out_dir}")
157
+ print(f"Files collected: {len(files)}")
158
+ if missing:
159
+ print("Missing common entrypoints:")
160
+ for pattern in missing:
161
+ print(f"- {pattern}")
162
+ return 0
163
+
164
+
165
+ if __name__ == "__main__":
166
+ raise SystemExit(main())