jorgex-stack 1.0.1 → 1.0.3
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.
- package/PRD.md +310 -297
- package/README.md +68 -56
- package/dist/cli.js +37 -3
- package/package.json +1 -1
- package/stack/agents/code-simplifier.md +21 -10
- package/stack/agents/implementer.md +1 -0
- package/stack/agents/orchestrator.md +194 -192
- package/stack/agents/security-auditor.md +7 -0
- package/stack/agents/silent-failure-hunter.md +7 -0
- package/stack/agents/test-analyzer.md +7 -0
- package/stack/agents/tester.md +71 -71
- package/stack/agents/type-design-analyzer.md +1 -1
- package/stack/commands/lean-audit.md +59 -0
- package/stack/commands/xreview.md +82 -80
- package/stack/hooks/hooks.json +18 -18
- package/stack/scripts/post-pr-review.cjs +159 -156
- package/stack/skills/diagnose/SKILL.md +117 -117
- package/stack/skills/diagnose/scripts/hitl-loop.template.sh +41 -41
- package/stack/skills/find-skills/SKILL.md +133 -133
- package/stack/skills/lean-code/SKILL.md +69 -0
- package/stack/skills/mcp-builder/LICENSE.txt +201 -201
- package/stack/skills/mcp-builder/SKILL.md +236 -236
- package/stack/skills/mcp-builder/reference/evaluation.md +601 -601
- package/stack/skills/mcp-builder/reference/mcp_best_practices.md +249 -249
- package/stack/skills/mcp-builder/reference/node_mcp_server.md +969 -969
- package/stack/skills/mcp-builder/reference/python_mcp_server.md +718 -718
- package/stack/skills/mcp-builder/scripts/connections.py +151 -151
- package/stack/skills/mcp-builder/scripts/evaluation.py +373 -373
- package/stack/skills/mcp-builder/scripts/example_evaluation.xml +22 -22
- package/stack/skills/mcp-builder/scripts/requirements.txt +2 -2
- package/stack/skills/obsidian-cli/SKILL.md +106 -106
- package/stack/skills/obsidian-markdown/SKILL.md +196 -196
- package/stack/skills/obsidian-markdown/references/CALLOUTS.md +58 -58
- package/stack/skills/obsidian-markdown/references/EMBEDS.md +63 -63
- package/stack/skills/obsidian-markdown/references/PROPERTIES.md +61 -61
- package/stack/skills/react-doctor/SKILL.md +19 -19
- package/stack/skills/skill-creator/LICENSE.txt +201 -201
- package/stack/skills/skill-creator/agents/analyzer.md +274 -274
- package/stack/skills/skill-creator/agents/comparator.md +202 -202
- package/stack/skills/skill-creator/agents/grader.md +223 -223
- package/stack/skills/skill-creator/assets/eval_review.html +146 -146
- package/stack/skills/skill-creator/eval-viewer/generate_review.py +471 -471
- package/stack/skills/skill-creator/eval-viewer/viewer.html +1325 -1325
- package/stack/skills/skill-creator/references/schemas.md +430 -430
- package/stack/skills/skill-creator/scripts/aggregate_benchmark.py +401 -401
- package/stack/skills/skill-creator/scripts/generate_report.py +326 -326
- package/stack/skills/skill-creator/scripts/improve_description.py +248 -248
- package/stack/skills/skill-creator/scripts/package_skill.py +136 -136
- package/stack/skills/skill-creator/scripts/quick_validate.py +102 -102
- package/stack/skills/skill-creator/scripts/run_eval.py +310 -310
- package/stack/skills/skill-creator/scripts/run_loop.py +332 -332
- package/stack/skills/skill-creator/scripts/utils.py +47 -47
- package/stack/skills/supabase/SKILL.md +135 -135
- package/stack/skills/supabase/assets/feedback-issue-template.md +17 -17
- package/stack/skills/supabase/references/skill-feedback.md +17 -17
- package/stack/skills/supabase-postgres-best-practices/SKILL.md +64 -64
- package/stack/skills/supabase-postgres-best-practices/references/_contributing.md +170 -170
- package/stack/skills/supabase-postgres-best-practices/references/_sections.md +39 -39
- package/stack/skills/supabase-postgres-best-practices/references/_template.md +34 -34
- package/stack/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -55
- package/stack/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -49
- package/stack/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -46
- package/stack/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -44
- package/stack/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -41
- package/stack/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -46
- package/stack/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -54
- package/stack/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -53
- package/stack/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -50
- package/stack/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -50
- package/stack/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -56
- package/stack/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -68
- package/stack/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -50
- package/stack/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -54
- package/stack/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -45
- package/stack/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -55
- package/stack/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -55
- package/stack/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -44
- package/stack/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -40
- package/stack/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -48
- package/stack/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -43
- package/stack/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -45
- package/stack/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -80
- package/stack/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -46
- package/stack/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -59
- package/stack/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -55
- package/stack/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -55
- package/stack/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -61
- package/stack/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -54
- package/stack/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -50
- package/stack/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -63
- package/stack/skills/tdd/SKILL.md +109 -109
- package/stack/skills/tdd/deep-modules.md +33 -33
- package/stack/skills/tdd/interface-design.md +31 -31
- package/stack/skills/tdd/mocking.md +59 -59
- package/stack/skills/tdd/refactoring.md +10 -10
- package/stack/skills/tdd/tests.md +61 -61
- package/stack/skills/to-issues/SKILL.md +83 -83
- package/stack/skills/to-prd/SKILL.md +72 -72
- package/upstreams.json +96 -96
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Manual read-only lean audit — resolves repo/path scope, runs a cheap scope/routing scan, launches code-simplifier always and the relevant analysts conditionally, then reports ranked lean findings.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run a manual lean audit. Your job as the main agent: determine WHAT to audit, resolve the exact repo/path scope, decide which subagents apply, and launch them in parallel.
|
|
6
|
+
|
|
7
|
+
## 0. Determine the audit target
|
|
8
|
+
|
|
9
|
+
User input (may be empty): {{input}}
|
|
10
|
+
|
|
11
|
+
- If the input names a repo or a path → audit that repo/subtree.
|
|
12
|
+
- If the input is empty or ambiguous: do a quick, cheap situation scan first — current repo root (`git rev-parse --show-toplevel`), current branch (`git rev-parse --abbrev-ref HEAD`), and the most likely changed area from the user's prompt — then ASK the user what to audit before launching anything, offering only the options that actually apply.
|
|
13
|
+
- If the input points to a PR or a diff → stop: `/lean-audit` is not a PR review command; use `/xreview` for diffs and PRs.
|
|
14
|
+
|
|
15
|
+
## 1. Resolve scope
|
|
16
|
+
|
|
17
|
+
- Print the chosen repo/path scope and why it was selected.
|
|
18
|
+
- If the input is a path, audit that subtree.
|
|
19
|
+
- If the input is a repo root, audit the repo from that root downward.
|
|
20
|
+
- If you are inside a worktree, use that worktree as the scope unless the user named a different path.
|
|
21
|
+
|
|
22
|
+
## 2. Cheap scope/routing scan
|
|
23
|
+
|
|
24
|
+
Before launching subagents, do a quick scan for obvious routing signals in the scope:
|
|
25
|
+
|
|
26
|
+
- changed file names and top-level directories
|
|
27
|
+
- obvious code/test/docs boundaries
|
|
28
|
+
- areas that likely need code-simplifier vs analyst passes
|
|
29
|
+
- anything that changes which subagents should run
|
|
30
|
+
|
|
31
|
+
Use the scan to route work, not to judge bloat or rewrite anything. Code-simplifier owns the lean/anti-bloat findings.
|
|
32
|
+
|
|
33
|
+
## 3. Launch the remaining subagents in PARALLEL
|
|
34
|
+
|
|
35
|
+
All subagents are CONDITIONAL and read-only. Launch one only when the scope indicates it applies. Pass every one EXACTLY:
|
|
36
|
+
|
|
37
|
+
- the audit scope: repo root / path root, verbatim
|
|
38
|
+
- the instruction: audit only that scope — never broaden it, and never apply fixes
|
|
39
|
+
|
|
40
|
+
Subagents and their triggers:
|
|
41
|
+
|
|
42
|
+
1. Task(subagent_type='code-simplifier') — always; this is the lean/anti-bloat pass
|
|
43
|
+
2. Task(subagent_type='backend-analyst') — if the scope includes backend, DB, APIs, server logic, or data flows
|
|
44
|
+
3. Task(subagent_type='frontend-analyst') — if the scope includes UI, hooks, state, rendering, or client-side flows
|
|
45
|
+
4. Task(subagent_type='type-design-analyzer') — if the scope changes types, interfaces, schemas, or contracts
|
|
46
|
+
|
|
47
|
+
If none of a subagent's triggers are present, skip it and note that it was skipped. Always state which subagents ran and which were skipped and why.
|
|
48
|
+
|
|
49
|
+
## 4. Synthesize
|
|
50
|
+
|
|
51
|
+
After the relevant subagents complete, synthesize their findings into a unified report:
|
|
52
|
+
|
|
53
|
+
- Scope used and how it was chosen
|
|
54
|
+
- Subagents run vs skipped (with reason)
|
|
55
|
+
- Ranked findings: delete, stdlib, native/platform, reuse, yagni, shrink
|
|
56
|
+
- What should be deferred because it is out of scope or too risky for this audit
|
|
57
|
+
- Positive findings
|
|
58
|
+
|
|
59
|
+
Do not apply fixes. This command only audits and reports.
|
|
@@ -1,80 +1,82 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Conditional multi-agent code review — determines what to review (asking if unclear), resolves the exact diff, and launches only the relevant subagents in parallel
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Run a comprehensive multi-agent review. Your job as the main agent: determine WHAT to review, resolve the exact diff, decide which subagents apply, and launch them in parallel.
|
|
6
|
-
|
|
7
|
-
## 0. Determine the review target
|
|
8
|
-
|
|
9
|
-
User input (may be empty): {{input}}
|
|
10
|
-
|
|
11
|
-
- If the input names a branch → review `git diff <that-branch>...HEAD`.
|
|
12
|
-
- If the input references a PR (number or URL) → use that PR's base branch as BASE.
|
|
13
|
-
- If the input names files/paths/areas → review the changes touching those paths.
|
|
14
|
-
- If the input is empty or ambiguous: do a quick, cheap situation scan first — uncommitted changes (`git status --short`), current branch, open PR for it (`gh pr view --json baseRefName --jq .baseRefName`) — and ASK the user what to review before launching anything, offering only the options that actually apply:
|
|
15
|
-
1. Uncommitted work (`git diff` + `git diff --staged`)
|
|
16
|
-
2. The current branch against its base (say which base you detected and how)
|
|
17
|
-
3. Against a specific branch they name
|
|
18
|
-
4. An existing PR
|
|
19
|
-
5. Specific files or areas
|
|
20
|
-
|
|
21
|
-
Do NOT guess silently: a review against the wrong target wastes every subagent and buries the user in irrelevant findings.
|
|
22
|
-
|
|
23
|
-
## 1. Resolve BASE and HEAD (branch/PR reviews)
|
|
24
|
-
|
|
25
|
-
HEAD is the current branch / worktree being worked on (`git rev-parse --abbrev-ref HEAD`).
|
|
26
|
-
|
|
27
|
-
BASE is the branch the work will merge into. Do NOT default to `main` — work is often done in sub-branches whose PR targets another branch. Resolve BASE in this order:
|
|
28
|
-
|
|
29
|
-
1. The branch the user chose in step 0, if any.
|
|
30
|
-
2. If the current branch has an open GitHub PR, its base branch (`gh pr view --json baseRefName --jq .baseRefName`).
|
|
31
|
-
3. Otherwise, inspect local and `origin/*` branches and choose the branch directly underneath the current branch: the candidate whose merge-base with HEAD is newest/closest to HEAD, excluding the current branch itself and its remote tracking ref.
|
|
32
|
-
4. If still unsure, ask the user — never silently fall back to `main`.
|
|
33
|
-
|
|
34
|
-
Print the chosen BASE and HEAD and why BASE was selected. (For working-tree reviews there is no BASE: the scope is `git diff` + `git diff --staged`.)
|
|
35
|
-
|
|
36
|
-
## 2. Decide routing (lightweight)
|
|
37
|
-
|
|
38
|
-
List only the changed file NAMES to decide routing — do NOT load the full diff into your own context:
|
|
39
|
-
`git diff <BASE>...HEAD --name-only` (or `git diff --name-only` + `git diff --staged --name-only` for working-tree reviews).
|
|
40
|
-
|
|
41
|
-
Sanity check: if that list is far larger than the work being reviewed (hundreds of files, unrelated areas), BASE is almost certainly wrong — STOP, re-resolve it (step 1), and only continue when the diff matches the actual work. Reviewing against the wrong BASE makes every finding worthless.
|
|
42
|
-
|
|
43
|
-
## 3. Comment pass FIRST (conditional)
|
|
44
|
-
|
|
45
|
-
If the diff adds or changes comments/docstrings, run `comment-fixer` ALONE before the analysts — it edits comments in place (comments only, never code), so the analysts then review a diff already clean of comment noise instead of re-reporting it or mistaking its edits for contamination.
|
|
46
|
-
|
|
47
|
-
- Pass it the same scope (BASE/HEAD or working diff) as everyone else.
|
|
48
|
-
- If it changed anything and the scope is a committed diff (branch/PR): comment-fixer itself never commits — YOU commit its fixes to the reviewed branch before launching the analysts, staging ONLY the files it touched (never `-a`/`-A`: don't sweep unrelated working-tree changes into the commit). If the commit can't be made (branch checked out elsewhere, hook rejection), leave the edits uncommitted and say so in the report.
|
|
49
|
-
- For working-tree reviews: leave its edits uncommitted (they join the user's pending work) and say so in the report.
|
|
50
|
-
- If the diff touches no comments, skip it and move on.
|
|
51
|
-
|
|
52
|
-
## 4. Launch the remaining subagents in PARALLEL
|
|
53
|
-
|
|
54
|
-
All subagents are CONDITIONAL: launch one only when the changed files indicate it applies. Run them in PARALLEL via the Task tool. Each subagent fetches its OWN diff; all are read-only. Pass every one EXACTLY:
|
|
55
|
-
|
|
56
|
-
- the review scope: BASE and HEAD branches (verbatim), or "working diff" for uncommitted work
|
|
57
|
-
- the instruction: review only that scope — never assume `main`, use the scope given
|
|
58
|
-
|
|
59
|
-
Subagents and their triggers:
|
|
60
|
-
|
|
61
|
-
1. Task(subagent_type='test-analyzer') — only if the diff touches tests or code that should be tested
|
|
62
|
-
2. Task(subagent_type='silent-failure-hunter') — only if the diff includes error handling, try/catch, fallbacks, or async flows
|
|
63
|
-
3. Task(subagent_type='type-design-analyzer') — only if the diff changes types, interfaces, schemas, or public contracts
|
|
64
|
-
4. Task(subagent_type='code-reviewer') — for general code quality whenever non-trivial source code changed
|
|
65
|
-
5. Task(subagent_type='code-simplifier') — only if the diff introduces complexity worth simplifying
|
|
66
|
-
6. Task(subagent_type='security-auditor') — only if the diff touches auth, authorization, permissions, secrets/credentials, sensitive data, input validation, webhooks, or other security-critical flows
|
|
67
|
-
|
|
68
|
-
If none of a subagent's triggers are present, skip it and note that it was skipped. Always state which subagents ran and which were skipped and why.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
1
|
+
---
|
|
2
|
+
description: Conditional multi-agent code review — determines what to review (asking if unclear), resolves the exact diff, and launches only the relevant subagents in parallel
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run a comprehensive multi-agent review. Your job as the main agent: determine WHAT to review, resolve the exact diff, decide which subagents apply, and launch them in parallel.
|
|
6
|
+
|
|
7
|
+
## 0. Determine the review target
|
|
8
|
+
|
|
9
|
+
User input (may be empty): {{input}}
|
|
10
|
+
|
|
11
|
+
- If the input names a branch → review `git diff <that-branch>...HEAD`.
|
|
12
|
+
- If the input references a PR (number or URL) → use that PR's base branch as BASE.
|
|
13
|
+
- If the input names files/paths/areas → review the changes touching those paths.
|
|
14
|
+
- If the input is empty or ambiguous: do a quick, cheap situation scan first — uncommitted changes (`git status --short`), current branch, open PR for it (`gh pr view --json baseRefName --jq .baseRefName`) — and ASK the user what to review before launching anything, offering only the options that actually apply:
|
|
15
|
+
1. Uncommitted work (`git diff` + `git diff --staged`)
|
|
16
|
+
2. The current branch against its base (say which base you detected and how)
|
|
17
|
+
3. Against a specific branch they name
|
|
18
|
+
4. An existing PR
|
|
19
|
+
5. Specific files or areas
|
|
20
|
+
|
|
21
|
+
Do NOT guess silently: a review against the wrong target wastes every subagent and buries the user in irrelevant findings.
|
|
22
|
+
|
|
23
|
+
## 1. Resolve BASE and HEAD (branch/PR reviews)
|
|
24
|
+
|
|
25
|
+
HEAD is the current branch / worktree being worked on (`git rev-parse --abbrev-ref HEAD`).
|
|
26
|
+
|
|
27
|
+
BASE is the branch the work will merge into. Do NOT default to `main` — work is often done in sub-branches whose PR targets another branch. Resolve BASE in this order:
|
|
28
|
+
|
|
29
|
+
1. The branch the user chose in step 0, if any.
|
|
30
|
+
2. If the current branch has an open GitHub PR, its base branch (`gh pr view --json baseRefName --jq .baseRefName`).
|
|
31
|
+
3. Otherwise, inspect local and `origin/*` branches and choose the branch directly underneath the current branch: the candidate whose merge-base with HEAD is newest/closest to HEAD, excluding the current branch itself and its remote tracking ref.
|
|
32
|
+
4. If still unsure, ask the user — never silently fall back to `main`.
|
|
33
|
+
|
|
34
|
+
Print the chosen BASE and HEAD and why BASE was selected. (For working-tree reviews there is no BASE: the scope is `git diff` + `git diff --staged`.)
|
|
35
|
+
|
|
36
|
+
## 2. Decide routing (lightweight)
|
|
37
|
+
|
|
38
|
+
List only the changed file NAMES to decide routing — do NOT load the full diff into your own context:
|
|
39
|
+
`git diff <BASE>...HEAD --name-only` (or `git diff --name-only` + `git diff --staged --name-only` for working-tree reviews).
|
|
40
|
+
|
|
41
|
+
Sanity check: if that list is far larger than the work being reviewed (hundreds of files, unrelated areas), BASE is almost certainly wrong — STOP, re-resolve it (step 1), and only continue when the diff matches the actual work. Reviewing against the wrong BASE makes every finding worthless.
|
|
42
|
+
|
|
43
|
+
## 3. Comment pass FIRST (conditional)
|
|
44
|
+
|
|
45
|
+
If the diff adds or changes comments/docstrings, run `comment-fixer` ALONE before the analysts — it edits comments in place (comments only, never code), so the analysts then review a diff already clean of comment noise instead of re-reporting it or mistaking its edits for contamination.
|
|
46
|
+
|
|
47
|
+
- Pass it the same scope (BASE/HEAD or working diff) as everyone else.
|
|
48
|
+
- If it changed anything and the scope is a committed diff (branch/PR): comment-fixer itself never commits — YOU commit its fixes to the reviewed branch before launching the analysts, staging ONLY the files it touched (never `-a`/`-A`: don't sweep unrelated working-tree changes into the commit). If the commit can't be made (branch checked out elsewhere, hook rejection), leave the edits uncommitted and say so in the report.
|
|
49
|
+
- For working-tree reviews: leave its edits uncommitted (they join the user's pending work) and say so in the report.
|
|
50
|
+
- If the diff touches no comments, skip it and move on.
|
|
51
|
+
|
|
52
|
+
## 4. Launch the remaining subagents in PARALLEL
|
|
53
|
+
|
|
54
|
+
All subagents are CONDITIONAL: launch one only when the changed files indicate it applies. Run them in PARALLEL via the Task tool. Each subagent fetches its OWN diff; all are read-only. Pass every one EXACTLY:
|
|
55
|
+
|
|
56
|
+
- the review scope: BASE and HEAD branches (verbatim), or "working diff" for uncommitted work
|
|
57
|
+
- the instruction: review only that scope — never assume `main`, use the scope given
|
|
58
|
+
|
|
59
|
+
Subagents and their triggers:
|
|
60
|
+
|
|
61
|
+
1. Task(subagent_type='test-analyzer') — only if the diff touches tests or code that should be tested
|
|
62
|
+
2. Task(subagent_type='silent-failure-hunter') — only if the diff includes error handling, try/catch, fallbacks, or async flows
|
|
63
|
+
3. Task(subagent_type='type-design-analyzer') — only if the diff changes types, interfaces, schemas, or public contracts
|
|
64
|
+
4. Task(subagent_type='code-reviewer') — for general code quality whenever non-trivial source code changed
|
|
65
|
+
5. Task(subagent_type='code-simplifier') — only if the diff introduces complexity worth simplifying; this is the lean/anti-bloat pass for diffs and PRs
|
|
66
|
+
6. Task(subagent_type='security-auditor') — only if the diff touches auth, authorization, permissions, secrets/credentials, sensitive data, input validation, webhooks, or other security-critical flows
|
|
67
|
+
|
|
68
|
+
If none of a subagent's triggers are present, skip it and note that it was skipped. Always state which subagents ran and which were skipped and why.
|
|
69
|
+
|
|
70
|
+
`/lean-audit` is a separate manual repo/path command, not post-PR automation. Do not route it from here.
|
|
71
|
+
|
|
72
|
+
## 5. Synthesize
|
|
73
|
+
|
|
74
|
+
After the relevant subagents complete, synthesize their findings into a unified report. Use 4R internally (Reliability / Resilience / Readability / Risk) as a checklist while synthesizing; do not add a separate 4R section or taxonomy to the final report.
|
|
75
|
+
|
|
76
|
+
- Review scope used (BASE/HEAD or working diff) and how it was chosen
|
|
77
|
+
- Subagents run vs skipped (with reason)
|
|
78
|
+
- Critical Issues (must fix)
|
|
79
|
+
- Important Improvements (should fix)
|
|
80
|
+
- Suggestions (nice to have)
|
|
81
|
+
- Changes already applied (comment fixes: committed to the branch, or left uncommitted for working-tree reviews)
|
|
82
|
+
- Positive Findings
|
package/stack/hooks/hooks.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$comment": "Hooks canónicos del stack. Formato base = Claude Code (code.claude.com/docs/en/hooks). Traducción por adapter en install: Claude Code → merge en ~/.claude/settings.json (clave hooks) · Codex → ~/.codex/hooks.json (el usuario debe aprobarlos después con /hooks) · OpenCode → plugin puente stack/plugins/opencode/hooks.ts con su propio hooks.json. Extensión propia 'x-command-includes': filtro por substring del comando bash que el puente de OpenCode aplica antes de ejecutar el script; en Claude Code y Codex el filtro lo aplica el propio script (sale con exit 0 si el comando no aplica). El placeholder {{SCRIPTS_DIR}} lo resuelve el instalador a la ruta real donde queden instalados los scripts del stack.",
|
|
3
|
-
"hooks": {
|
|
4
|
-
"PostToolUse": [
|
|
5
|
-
{
|
|
6
|
-
"matcher": "Bash|PowerShell",
|
|
7
|
-
"x-command-includes": "gh pr create",
|
|
8
|
-
"hooks": [
|
|
9
|
-
{
|
|
10
|
-
"type": "command",
|
|
11
|
-
"command": "node \"{{SCRIPTS_DIR}}/post-pr-review.cjs\"",
|
|
12
|
-
"timeout": 30
|
|
13
|
-
}
|
|
14
|
-
]
|
|
15
|
-
}
|
|
16
|
-
]
|
|
17
|
-
}
|
|
18
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Hooks canónicos del stack. Formato base = Claude Code (code.claude.com/docs/en/hooks). Traducción por adapter en install: Claude Code → merge en ~/.claude/settings.json (clave hooks) · Codex → ~/.codex/hooks.json (el usuario debe aprobarlos después con /hooks) · OpenCode → plugin puente stack/plugins/opencode/hooks.ts con su propio hooks.json. Extensión propia 'x-command-includes': filtro por substring del comando bash que el puente de OpenCode aplica antes de ejecutar el script; en Claude Code y Codex el filtro lo aplica el propio script (sale con exit 0 si el comando no aplica). El placeholder {{SCRIPTS_DIR}} lo resuelve el instalador a la ruta real donde queden instalados los scripts del stack.",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PostToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "Bash|PowerShell",
|
|
7
|
+
"x-command-includes": "gh pr create",
|
|
8
|
+
"hooks": [
|
|
9
|
+
{
|
|
10
|
+
"type": "command",
|
|
11
|
+
"command": "node \"{{SCRIPTS_DIR}}/post-pr-review.cjs\"",
|
|
12
|
+
"timeout": 30
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,156 +1,159 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Global PostToolUse hook: gh pr create
|
|
4
|
-
*
|
|
5
|
-
* Injects a conditional multi-agent review request after a PR is created.
|
|
6
|
-
* Generic and project-agnostic: no version bump, no React Doctor, no project paths.
|
|
7
|
-
*
|
|
8
|
-
* The review subagents are CONDITIONAL — only the ones relevant to the diff run.
|
|
9
|
-
* Mirrors the `/xreview` command logic so both stay aligned: comment-fixer first
|
|
10
|
-
* (committed before the analysts), then the read-only analysts in parallel.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
process.stdin.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
process.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Global PostToolUse hook: gh pr create
|
|
4
|
+
*
|
|
5
|
+
* Injects a conditional multi-agent review request after a PR is created.
|
|
6
|
+
* Generic and project-agnostic: no version bump, no React Doctor, no project paths.
|
|
7
|
+
*
|
|
8
|
+
* The review subagents are CONDITIONAL — only the ones relevant to the diff run.
|
|
9
|
+
* Mirrors the `/xreview` command logic so both stay aligned: comment-fixer first
|
|
10
|
+
* (committed before the analysts), then the read-only analysts in parallel. 4R
|
|
11
|
+
* stays internal (Reliability / Resilience / Readability / Risk), not a separate
|
|
12
|
+
* report section, taxonomy, or extra agents.
|
|
13
|
+
*
|
|
14
|
+
* Payload compatibility (stdin JSON), so the same script works on every runtime:
|
|
15
|
+
* - Claude Code hooks: { tool_name: "Bash", tool_input: { command: "..." }, cwd }
|
|
16
|
+
* - Codex hooks: { tool_name: "shell", tool_input: { command: [...] }, cwd }
|
|
17
|
+
* - OpenCode bridge: { tool: "bash", args: { command: "..." }, directory }
|
|
18
|
+
*
|
|
19
|
+
* Output (single channel per runtime, so the bridge never duplicates it):
|
|
20
|
+
* - OpenCode bridge payload → plain message on stderr.
|
|
21
|
+
* - Claude Code / Codex payload → JSON additionalContext on stdout.
|
|
22
|
+
* Exit 0 always.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const { execSync } = require('child_process');
|
|
26
|
+
const path = require('path');
|
|
27
|
+
|
|
28
|
+
const DEFAULT_BASE_BRANCH = 'main';
|
|
29
|
+
const BASE_BRANCH_SOURCE = Object.freeze({
|
|
30
|
+
GH: 'gh',
|
|
31
|
+
ORIGIN_HEAD: 'origin-head',
|
|
32
|
+
DEFAULT: 'default',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
function writeWarning(message) {
|
|
36
|
+
process.stderr.write(`post-pr-review: warning: ${message}\n`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function formatGitRef(value) {
|
|
40
|
+
const ref = String(value);
|
|
41
|
+
return /^[A-Za-z0-9._/-]+$/.test(ref) ? ref : `'${ref.replace(/'/g, "'\\''")}'`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function resolveBaseBranch(cwd) {
|
|
45
|
+
try {
|
|
46
|
+
const base = execSync('gh pr view --json baseRefName --jq .baseRefName', {
|
|
47
|
+
cwd,
|
|
48
|
+
encoding: 'utf8',
|
|
49
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
50
|
+
timeout: 8_000,
|
|
51
|
+
}).trim();
|
|
52
|
+
if (base) return { branch: base, source: BASE_BRANCH_SOURCE.GH };
|
|
53
|
+
} catch {
|
|
54
|
+
// PR not yet discoverable; fall back below.
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const originHead = execSync('git symbolic-ref refs/remotes/origin/HEAD', {
|
|
59
|
+
cwd,
|
|
60
|
+
encoding: 'utf8',
|
|
61
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
62
|
+
timeout: 10_000,
|
|
63
|
+
}).trim();
|
|
64
|
+
if (originHead) {
|
|
65
|
+
return {
|
|
66
|
+
branch: originHead.replace(/^refs\/remotes\/origin\//, ''),
|
|
67
|
+
source: BASE_BRANCH_SOURCE.ORIGIN_HEAD,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
// ignore
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return { branch: DEFAULT_BASE_BRANCH, source: BASE_BRANCH_SOURCE.DEFAULT };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let raw = '';
|
|
78
|
+
process.stdin.setEncoding('utf8');
|
|
79
|
+
process.stdin.on('data', (chunk) => (raw += chunk));
|
|
80
|
+
process.stdin.on('end', () => {
|
|
81
|
+
let data = {};
|
|
82
|
+
try {
|
|
83
|
+
data = JSON.parse(raw || '{}');
|
|
84
|
+
} catch {
|
|
85
|
+
writeWarning('invalid JSON payload; skipping review hook.');
|
|
86
|
+
process.exit(0);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const toolName = String(data.tool_name || data.tool || '').toLowerCase();
|
|
90
|
+
const SHELL_TOOLS = ['bash', 'shell', 'local_shell', 'powershell'];
|
|
91
|
+
const commandValue = data?.tool_input?.command ?? data?.args?.command ?? '';
|
|
92
|
+
// Codex passes the shell command as an argv array; the rest as a string.
|
|
93
|
+
const rawToolCommand = Array.isArray(commandValue) ? commandValue.join(' ') : String(commandValue);
|
|
94
|
+
const toolCommand = rawToolCommand.toLowerCase();
|
|
95
|
+
|
|
96
|
+
if (!SHELL_TOOLS.includes(toolName) || !toolCommand.includes('gh pr create')) {
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const scriptDir = __dirname;
|
|
101
|
+
const projectDir = data.cwd || data.directory || path.resolve(scriptDir, '..');
|
|
102
|
+
const resolution = resolveBaseBranch(projectDir);
|
|
103
|
+
const baseBranch = resolution.branch;
|
|
104
|
+
const baseRef = formatGitRef(baseBranch);
|
|
105
|
+
const diffScope = `git diff ${baseRef}...HEAD`;
|
|
106
|
+
const isConfirmed = resolution.source === BASE_BRANCH_SOURCE.GH;
|
|
107
|
+
const baseSummary = isConfirmed
|
|
108
|
+
? `BASE (PR target, confirmed via gh pr view): ${baseBranch}`
|
|
109
|
+
: `BASE (PR target, NOT confirmed — fallback guess): ${baseBranch}. Before anything else, re-resolve it yourself: run \`gh pr view --json baseRefName --jq .baseRefName\` (the PR exists now; this hook may have raced its creation) and use THAT as BASE. Keep ${baseBranch} only if it still fails. Work is often done in sub-branches whose PR does NOT target the default branch — reviewing against the wrong BASE produces a huge, useless diff.`;
|
|
110
|
+
|
|
111
|
+
const message = `<post-pr-review-required>
|
|
112
|
+
A PR was just created. Run a conditional multi-agent review BEFORE reporting back to the user.
|
|
113
|
+
|
|
114
|
+
${baseSummary}
|
|
115
|
+
HEAD: the current branch / worktree (resolve with \`git rev-parse --abbrev-ref HEAD\`).
|
|
116
|
+
|
|
117
|
+
1. Routing only (lightweight): list changed file NAMES with \`${diffScope} --name-only\` to decide which subagents apply. Do NOT load the full diff into your own context.
|
|
118
|
+
|
|
119
|
+
Sanity check: if that list is far larger than the work just done (hundreds of files, unrelated areas), BASE is almost certainly wrong — STOP, re-resolve the PR base with \`gh pr view\`, and only continue when the diff matches the actual work.
|
|
120
|
+
|
|
121
|
+
2. Comment pass FIRST (conditional): if the diff adds or changes comments/docstrings, run comment-fixer ALONE before the analysts — it edits comments in place (comments only, never code). If it changed anything, comment-fixer itself never commits — YOU commit its fixes to the PR branch BEFORE launching the analysts, staging ONLY the files it touched (never -a/-A: don't sweep unrelated working-tree changes), so the diff they fetch is already clean of comment noise; push them together with whatever the review produces, or on their own if nothing else needs fixing. If the commit can't be made, leave the edits uncommitted and say so in the report. If the diff touches no comments, skip it.
|
|
122
|
+
|
|
123
|
+
3. The remaining subagents are CONDITIONAL, read-only, and each fetches its OWN diff. Launch in PARALLEL (with your runtime's delegation mechanism) ONLY the relevant ones, passing each EXACTLY the BASE and HEAD branches and the instruction: review only \`${diffScope}\` — never assume \`main\`, use the BASE/HEAD given.
|
|
124
|
+
- test-analyzer — only if the diff touches tests or code that should be tested
|
|
125
|
+
- silent-failure-hunter — only if the diff includes error handling, try/catch, fallbacks, or async flows
|
|
126
|
+
- type-design-analyzer — only if the diff changes types, interfaces, schemas, or public contracts
|
|
127
|
+
- code-reviewer — for general code quality whenever non-trivial source code changed
|
|
128
|
+
- code-simplifier — only if the diff introduces complexity worth simplifying; this is the lean/anti-bloat pass for diffs and PRs
|
|
129
|
+
- security-auditor — only if the diff touches auth, authorization, permissions, secrets/credentials, sensitive data, input validation, webhooks, or other security-critical flows
|
|
130
|
+
|
|
131
|
+
If none of a subagent's triggers are present, skip it. Always state which subagents ran and which were skipped and why.
|
|
132
|
+
|
|
133
|
+
4. After the relevant subagents complete, synthesize a unified report:
|
|
134
|
+
Use 4R internally (Reliability / Resilience / Readability / Risk) as a checklist while synthesizing; do not add a separate 4R section or taxonomy to the final report.
|
|
135
|
+
- BASE and HEAD used
|
|
136
|
+
- Subagents run vs skipped (with reason)
|
|
137
|
+
- Critical Issues (must fix)
|
|
138
|
+
- Important Improvements (should fix)
|
|
139
|
+
- Suggestions (nice to have)
|
|
140
|
+
- Changes already applied (comment fixes: committed to the PR branch, or left uncommitted for working-tree reviews)
|
|
141
|
+
- Positive Findings
|
|
142
|
+
</post-pr-review-required>`;
|
|
143
|
+
|
|
144
|
+
// Un solo canal por runtime: el bridge de OpenCode recoge stdout Y stderr,
|
|
145
|
+
// así que emitir por ambos duplicaría el mensaje.
|
|
146
|
+
const isOpenCodeBridge = data.tool !== undefined && data.tool_name === undefined;
|
|
147
|
+
if (isOpenCodeBridge) {
|
|
148
|
+
process.stderr.write(message + '\n');
|
|
149
|
+
} else {
|
|
150
|
+
// Claude Code / Codex PostToolUse leen additionalContext del stdout JSON.
|
|
151
|
+
process.stdout.write(
|
|
152
|
+
JSON.stringify({
|
|
153
|
+
additionalContext: message,
|
|
154
|
+
hookSpecificOutput: { hookEventName: 'PostToolUse', additionalContext: message },
|
|
155
|
+
}) + '\n',
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
process.exit(0);
|
|
159
|
+
});
|