@pasajero_0/agent-stack 0.1.0
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/LICENSE +21 -0
- package/README.md +116 -0
- package/bin/cli.mjs +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +683 -0
- package/dist/index.js.map +1 -0
- package/mcp/catalog.json +42 -0
- package/package.json +61 -0
- package/templates/claude/_TOKENS.md +28 -0
- package/templates/claude/_normative.md +24 -0
- package/templates/claude/agents/code-reviewer.md +78 -0
- package/templates/claude/agents/pattern-scout.md +111 -0
- package/templates/claude/agents/task-analyzer.md +77 -0
- package/templates/claude/agents/test-writer.md +50 -0
- package/templates/claude/commands/reflect.md +25 -0
- package/templates/claude/commands/review.md +25 -0
- package/templates/claude/hooks/guard-bash.sh +19 -0
- package/templates/claude/hooks/guard-file.sh +37 -0
- package/templates/claude/hooks/post-edit-lint.sh +55 -0
- package/templates/claude/hooks/post-edit-verify.sh +71 -0
- package/templates/claude/hooks/session-start-context.sh +57 -0
- package/templates/claude/hooks/stop-flag-reflect.sh +24 -0
- package/templates/claude/rules/README.md +33 -0
- package/templates/claude/skills/ci-testing-patterns.md +22 -0
- package/templates/claude/skills/migration/SKILL.md +35 -0
- package/templates/claude/skills/mr-description/SKILL.md +56 -0
- package/templates/claude/skills/repo-structure.md +22 -0
- package/templates/claude/skills/team-conventions.md +31 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse(Bash) guard — enforces hard prohibitions.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
cmd=$(jq -r '.tool_input.command // empty')
|
|
6
|
+
[ -z "$cmd" ] && exit 0
|
|
7
|
+
|
|
8
|
+
if printf '%s' "$cmd" | grep -Eq '(^|[&|;]|&&)[[:space:]]*git[[:space:]]+push\b'; then
|
|
9
|
+
echo "Blocked: 'git push' is manual-only — the team pushes by hand." >&2
|
|
10
|
+
exit 2
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
# Package-manager guard. This repo is {{PM}}-only.
|
|
14
|
+
if printf '%s' "$cmd" | grep -Eq '(^|[&|;]|&&)[[:space:]]*({{FORBIDDEN_PM}})[[:space:]]'; then
|
|
15
|
+
echo "Blocked: this repo uses {{PM}} only." >&2
|
|
16
|
+
exit 2
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
exit 0
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse(Edit|Write|MultiEdit) guard — protects generated + secret files.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
path=$(jq -r '.tool_input.file_path // empty')
|
|
6
|
+
[ -z "$path" ] && exit 0
|
|
7
|
+
|
|
8
|
+
# Auto-generated build outputs — never hand-edit.
|
|
9
|
+
case "$path" in
|
|
10
|
+
{{GEN_GLOBS}})
|
|
11
|
+
echo "Blocked: this file is auto-generated (build output) — never edit it by hand." >&2
|
|
12
|
+
exit 2
|
|
13
|
+
;;
|
|
14
|
+
esac
|
|
15
|
+
|
|
16
|
+
# Lockfile — regenerate via the package manager, never hand-edit.
|
|
17
|
+
case "$path" in
|
|
18
|
+
*{{LOCKFILE}})
|
|
19
|
+
echo "Blocked: {{LOCKFILE}} is generated by {{PM}} — never edit it by hand." >&2
|
|
20
|
+
exit 2
|
|
21
|
+
;;
|
|
22
|
+
esac
|
|
23
|
+
|
|
24
|
+
case "$path" in
|
|
25
|
+
*.env|*.env.*)
|
|
26
|
+
jq -n '{
|
|
27
|
+
hookSpecificOutput: {
|
|
28
|
+
hookEventName: "PreToolUse",
|
|
29
|
+
permissionDecision: "ask",
|
|
30
|
+
permissionDecisionReason: "Editing an env file — it may contain secrets. Confirm before writing."
|
|
31
|
+
}
|
|
32
|
+
}'
|
|
33
|
+
exit 0
|
|
34
|
+
;;
|
|
35
|
+
esac
|
|
36
|
+
|
|
37
|
+
exit 0
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse(Edit|Write|MultiEdit) — lint edited source files, surface issues as additionalContext.
|
|
3
|
+
# Does NOT modify the file (no --fix) — keeps Claude's file-state tracking consistent.
|
|
4
|
+
# NOTE: this repo currently has no linter installed, so this hook self-disables
|
|
5
|
+
# (the `[ -x "$LINTER" ] || exit 0` guard). Install a linter or point LINTER at it to enable.
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
input=$(cat)
|
|
9
|
+
path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
|
|
10
|
+
[ -z "$path" ] && exit 0
|
|
11
|
+
|
|
12
|
+
case "$path" in
|
|
13
|
+
*.ts|*.tsx|*.js|*.jsx|*.mts|*.cts) ;;
|
|
14
|
+
*) exit 0 ;;
|
|
15
|
+
esac
|
|
16
|
+
|
|
17
|
+
case "$path" in
|
|
18
|
+
*.gen.*|*/node_modules/*|*/dist/*|*/build/*|*/storybook-static/*|*/coverage/*) exit 0 ;;
|
|
19
|
+
esac
|
|
20
|
+
|
|
21
|
+
LINTER="${CLAUDE_PROJECT_DIR:-$(pwd)}/node_modules/.bin/eslint"
|
|
22
|
+
[ -x "$LINTER" ] || LINTER="$(command -v eslint || true)"
|
|
23
|
+
[ -x "$LINTER" ] || exit 0
|
|
24
|
+
|
|
25
|
+
CACHE_DIR=/tmp/claude-eslint-cache
|
|
26
|
+
mkdir -p "$CACHE_DIR"
|
|
27
|
+
|
|
28
|
+
output=$(timeout 20 "$LINTER" \
|
|
29
|
+
--cache \
|
|
30
|
+
--cache-location "$CACHE_DIR/" \
|
|
31
|
+
--cache-strategy content \
|
|
32
|
+
--format=json \
|
|
33
|
+
--no-warn-ignored \
|
|
34
|
+
"$path" 2>/dev/null) || true
|
|
35
|
+
|
|
36
|
+
# Parse only if output is valid JSON (eslint may bail on config errors)
|
|
37
|
+
echo "$output" | jq empty 2>/dev/null || exit 0
|
|
38
|
+
|
|
39
|
+
filtered=$(echo "$output" | jq -r '
|
|
40
|
+
.[].messages[]?
|
|
41
|
+
| select(.severity >= 1)
|
|
42
|
+
| " \(if .severity==2 then "✘" else "⚠" end) line \(.line):\(.column) \(.message) (\(.ruleId // "—"))"
|
|
43
|
+
' 2>/dev/null)
|
|
44
|
+
|
|
45
|
+
if [ -n "$filtered" ]; then
|
|
46
|
+
jq -nc --arg ctx "Linter issues in $(basename "$path"):
|
|
47
|
+
$filtered" '{
|
|
48
|
+
hookSpecificOutput: {
|
|
49
|
+
hookEventName: "PostToolUse",
|
|
50
|
+
additionalContext: $ctx
|
|
51
|
+
}
|
|
52
|
+
}'
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
exit 0
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse(Edit|Write|MultiEdit) — D12 post-apply verify.
|
|
3
|
+
# Active ONLY when at least one migration plan exists in .claude/tmp/.
|
|
4
|
+
# Outside active migrations: zero noise, near-zero latency.
|
|
5
|
+
#
|
|
6
|
+
# Caveat: diff is git working-tree vs HEAD, so it shows ALL uncommitted
|
|
7
|
+
# changes to the file, not only the change from the just-completed tool call.
|
|
8
|
+
# That caveat is surfaced in the additionalContext so Claude does not
|
|
9
|
+
# over-interpret unrelated edits.
|
|
10
|
+
#
|
|
11
|
+
# `set -e` and `pipefail` deliberately omitted: `git diff | head -200`
|
|
12
|
+
# triggers SIGPIPE on diffs >200 lines, which would crash the hook under
|
|
13
|
+
# pipefail. Defensive philosophy: always exit 0.
|
|
14
|
+
#
|
|
15
|
+
# JSON build: python3 (stdin + UTF-8 "replace" decode) preferred — survives
|
|
16
|
+
# non-UTF-8 bytes from arbitrary diff content. Fallback: `jq --rawfile` via
|
|
17
|
+
# temp file if python3 is absent.
|
|
18
|
+
#
|
|
19
|
+
# Historical note: do NOT use `echo "$out" | jq .` to post-process — the hook
|
|
20
|
+
# runner may exec `zsh -c`, and zsh's `echo` interprets `\n` escapes, turning
|
|
21
|
+
# valid escaped JSON back into raw LF before parsing. Use `printf '%s'`.
|
|
22
|
+
set -u
|
|
23
|
+
|
|
24
|
+
# (1) Early-exit if no active migration plan.
|
|
25
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
26
|
+
PLAN_DIR="$PROJECT_DIR/.claude/tmp"
|
|
27
|
+
ls "$PLAN_DIR"/*-plan.md >/dev/null 2>&1 || exit 0
|
|
28
|
+
|
|
29
|
+
# (2) Parse file path from tool_input.
|
|
30
|
+
input=$(cat)
|
|
31
|
+
path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
|
|
32
|
+
[ -z "$path" ] && exit 0
|
|
33
|
+
|
|
34
|
+
# (3) Normalize to absolute path so case-glob matches reliably for relative paths.
|
|
35
|
+
case "$path" in
|
|
36
|
+
/*) abs_path="$path" ;;
|
|
37
|
+
*) abs_path="$PROJECT_DIR/$path" ;;
|
|
38
|
+
esac
|
|
39
|
+
|
|
40
|
+
# (4) Skip noise paths (same filter spirit as post-edit-lint.sh).
|
|
41
|
+
case "$abs_path" in
|
|
42
|
+
*.gen.*|*/node_modules/*|*/dist/*|*/build/*|*/storybook-static/*|*/coverage/*) exit 0 ;;
|
|
43
|
+
esac
|
|
44
|
+
|
|
45
|
+
# (5) Build diff: tracked → git diff -U2 (truncated 200 lines); untracked → head -50.
|
|
46
|
+
cd "$PROJECT_DIR" 2>/dev/null || exit 0
|
|
47
|
+
if git ls-files --error-unmatch -- "$abs_path" >/dev/null 2>&1; then
|
|
48
|
+
diff_output=$(timeout 10 git diff -U2 -- "$abs_path" 2>/dev/null | head -200)
|
|
49
|
+
else
|
|
50
|
+
diff_output=$(head -50 "$abs_path" 2>/dev/null)
|
|
51
|
+
fi
|
|
52
|
+
[ -z "$diff_output" ] && exit 0
|
|
53
|
+
|
|
54
|
+
# (6) Build ctx then emit JSON.
|
|
55
|
+
ctx="POST-APPLY VERIFY (D12) $abs_path:
|
|
56
|
+
$diff_output
|
|
57
|
+
|
|
58
|
+
(diff may include earlier uncommitted changes to this file)
|
|
59
|
+
|
|
60
|
+
Compare against the approved preview table. Report any mismatch before marking the step done."
|
|
61
|
+
|
|
62
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
63
|
+
printf '%s' "$ctx" | python3 -c 'import json,sys; print(json.dumps({"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":sys.stdin.buffer.read().decode("utf-8","replace")}}))'
|
|
64
|
+
else
|
|
65
|
+
tmpf=$(mktemp)
|
|
66
|
+
printf '%s' "$ctx" > "$tmpf"
|
|
67
|
+
jq -nc --rawfile ctx "$tmpf" '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:$ctx}}'
|
|
68
|
+
rm -f "$tmpf"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
exit 0
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SessionStart — write start-marker for Stop hook + inject git context (only on fresh starts).
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
input=$(cat)
|
|
6
|
+
session_id=$(echo "$input" | jq -r '.session_id // "unknown"')
|
|
7
|
+
cwd=$(echo "$input" | jq -r '.cwd // "."')
|
|
8
|
+
src=$(echo "$input" | jq -r '.source // "startup"')
|
|
9
|
+
|
|
10
|
+
mkdir -p /tmp/claude-sessions
|
|
11
|
+
# Sweep stale markers (>24h) so /tmp doesn't grow forever
|
|
12
|
+
find /tmp/claude-sessions -maxdepth 1 -type f -name '*.start' -mtime +1 -delete 2>/dev/null || true
|
|
13
|
+
|
|
14
|
+
# Always write a fresh marker for this session — Stop hook compares memory mtimes against it
|
|
15
|
+
touch "/tmp/claude-sessions/$session_id.start"
|
|
16
|
+
|
|
17
|
+
# Heavy git context: only on a truly new context window
|
|
18
|
+
case "$src" in
|
|
19
|
+
startup|clear)
|
|
20
|
+
if git -C "$cwd" rev-parse 2>/dev/null >/dev/null; then
|
|
21
|
+
branch=$(git -C "$cwd" rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)
|
|
22
|
+
last=$(git -C "$cwd" log -1 --pretty='%h %s' 2>/dev/null || echo none)
|
|
23
|
+
changed=$(git -C "$cwd" status --short 2>/dev/null | head -20)
|
|
24
|
+
echo "## Session context"
|
|
25
|
+
echo
|
|
26
|
+
echo "- Branch: \`$branch\`"
|
|
27
|
+
echo "- Last commit: $last"
|
|
28
|
+
if [ -n "$changed" ]; then
|
|
29
|
+
echo "- Working tree (first 20 entries):"
|
|
30
|
+
echo '```'
|
|
31
|
+
echo "$changed"
|
|
32
|
+
echo '```'
|
|
33
|
+
else
|
|
34
|
+
echo "- Working tree: clean"
|
|
35
|
+
fi
|
|
36
|
+
echo
|
|
37
|
+
fi
|
|
38
|
+
;;
|
|
39
|
+
esac
|
|
40
|
+
|
|
41
|
+
# Active migration plan(s) — fire on every source. Cheap (3 lines); most valuable
|
|
42
|
+
# on `compact` where prior nuances were summarized away.
|
|
43
|
+
if ls "${CLAUDE_PROJECT_DIR:-$cwd}"/.claude/tmp/*-plan.md >/dev/null 2>&1; then
|
|
44
|
+
echo "⚠️ Active migration plan(s):"
|
|
45
|
+
ls "${CLAUDE_PROJECT_DIR:-$cwd}"/.claude/tmp/*-plan.md
|
|
46
|
+
echo "Re-read before acting; use /migration to continue."
|
|
47
|
+
echo
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Pending /reflect notice — always (cheap), regardless of source
|
|
51
|
+
if [ -f /tmp/.claude-reflect-pending ]; then
|
|
52
|
+
echo "💡 Memory was modified in the previous session — consider running \`/reflect\` to consolidate."
|
|
53
|
+
echo
|
|
54
|
+
rm -f /tmp/.claude-reflect-pending
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
exit 0
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Stop — fires every assistant turn. Keep work tiny.
|
|
3
|
+
# If any memory file changed since session start, raise the /reflect-pending flag.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
input=$(cat)
|
|
7
|
+
session_id=$(echo "$input" | jq -r '.session_id // "unknown"')
|
|
8
|
+
marker="/tmp/claude-sessions/$session_id.start"
|
|
9
|
+
[ -f "$marker" ] || exit 0
|
|
10
|
+
|
|
11
|
+
# Self-derive the auto-memory dir slug from the session cwd (every "/" → "-").
|
|
12
|
+
cwd=$(echo "$input" | jq -r '.cwd // empty')
|
|
13
|
+
[ -z "$cwd" ] && exit 0
|
|
14
|
+
slug="${cwd//\//-}"
|
|
15
|
+
MEM="$HOME/.claude/projects/${slug}/memory"
|
|
16
|
+
[ -d "$MEM" ] || exit 0
|
|
17
|
+
|
|
18
|
+
# -quit stops at first match → ~few ms even if memory has many files
|
|
19
|
+
if find "$MEM" -maxdepth 1 -name '*.md' -newer "$marker" -print -quit 2>/dev/null | grep -q .; then
|
|
20
|
+
touch /tmp/.claude-reflect-pending
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Do NOT remove the marker — Stop fires on every turn within the same session.
|
|
24
|
+
exit 0
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Path-scoped rules
|
|
2
|
+
|
|
3
|
+
This directory holds **path-scoped rules** — narrow, machine-checkable conventions that activate
|
|
4
|
+
only when a matching file is touched (frontmatter `paths:` glob).
|
|
5
|
+
|
|
6
|
+
**Rules are NOT shipped or copied — they are generated per-repo.** `agent-stack` deliberately leaves
|
|
7
|
+
this directory empty at deploy time, because rules must reflect *this* codebase's real conventions,
|
|
8
|
+
not another project's.
|
|
9
|
+
|
|
10
|
+
To generate them: open `claude` in this repo and run the **pattern-scout** subagent against your
|
|
11
|
+
code and architecture docs. It drafts rules marked `[DRAFT]`; review them, keep what fits, delete
|
|
12
|
+
the rest.
|
|
13
|
+
|
|
14
|
+
Each rule file looks like:
|
|
15
|
+
|
|
16
|
+
```markdown
|
|
17
|
+
---
|
|
18
|
+
description: <one line — what this rule enforces and when it fires>
|
|
19
|
+
paths:
|
|
20
|
+
- "<glob, e.g. src/**/*.ts>"
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# <Rule name>
|
|
24
|
+
|
|
25
|
+
## Do
|
|
26
|
+
- <convention> — detect: `<grep regex>` — severity: critical/warning/suggestion
|
|
27
|
+
|
|
28
|
+
## Don't
|
|
29
|
+
- <banned pattern> — detect: `<grep regex>` — severity: ...
|
|
30
|
+
|
|
31
|
+
## Why
|
|
32
|
+
<the failure mode this rule prevents>
|
|
33
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# CI / Testing Patterns
|
|
2
|
+
|
|
3
|
+
Validated knowledge from this project's test + CI setup. Replace with **your project's** runner and
|
|
4
|
+
CI provider as you learn them.
|
|
5
|
+
|
|
6
|
+
## Test runner
|
|
7
|
+
|
|
8
|
+
- Config: `<test config file>`; run focused with `<runner> <substring>`.
|
|
9
|
+
- Test the logic-heavy modules; mock external processes/IO, not internal modules.
|
|
10
|
+
|
|
11
|
+
## CI
|
|
12
|
+
|
|
13
|
+
A minimal pipeline on PR:
|
|
14
|
+
- install dependencies (frozen lockfile)
|
|
15
|
+
- typecheck
|
|
16
|
+
- test
|
|
17
|
+
- lint commit messages (if the repo enforces a commit convention)
|
|
18
|
+
|
|
19
|
+
## Gotchas
|
|
20
|
+
|
|
21
|
+
Keep a running list of tool issues that bit CI (version quirks, cache keys, runtime drift), one
|
|
22
|
+
line each, so the next debugging session starts from known causes.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Drive a multi-step migration or refactor against a plan file in `.claude/tmp/<task>-plan.md`. Loads the active plan into context, walks the next pending step under the plan's invariants, marks completed steps. Trigger when the user says "start migration", "continue migration", "next migration step", or similar.
|
|
3
|
+
disable-model-invocation: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Active plan(s)
|
|
7
|
+
|
|
8
|
+
<!-- Path resolution: `${CLAUDE_SKILL_DIR%/skills/*}/tmp` strips `/skills/<name>` from this skill's directory to get `<repo>/.claude/`, then appends `/tmp`. Requires this SKILL.md to live at `<repo>/.claude/skills/migration/SKILL.md` — moving the directory breaks the resolver. -->
|
|
9
|
+
|
|
10
|
+
!`d="${CLAUDE_SKILL_DIR%/skills/*}/tmp"; if ls "$d"/*-plan.md >/dev/null 2>&1; then for f in "$d"/*-plan.md; do printf '\n=== %s ===\n' "$f"; cat "$f"; done; else echo "(no active plan in $d — create one first)"; fi`
|
|
11
|
+
|
|
12
|
+
## How to drive a migration
|
|
13
|
+
|
|
14
|
+
1. **If no plan is loaded above** — draft one from the decisions in the current conversation.
|
|
15
|
+
Capture every committed invariant (numbered `Dn` style: scope, format, deviation policy,
|
|
16
|
+
completion gate), plus a top-level `## Open questions` section recording every unresolved
|
|
17
|
+
question raised by the user; it stays open until that question is explicitly closed. Save to
|
|
18
|
+
`.claude/tmp/<task>-plan.md`, show it to the user, and wait for explicit approval. Re-read the
|
|
19
|
+
saved plan from disk before proposing the first step.
|
|
20
|
+
|
|
21
|
+
2. **If a plan is loaded above** — identify the next pending step from the checklist at the bottom
|
|
22
|
+
of the plan. Re-read the affected source files (do NOT cite from memory). Open the diff preview
|
|
23
|
+
with a compliance header that names which invariants are honoured — for example:
|
|
24
|
+
`Plan check: D1, D4 — ok; D3 — n/a`. Each invariant touched must be either honoured or flagged
|
|
25
|
+
as a **deviation** (`ОТКЛОНЕНИЕ ОТ ПЛАНА`) with rationale, awaiting explicit approval before the
|
|
26
|
+
diff appears.
|
|
27
|
+
|
|
28
|
+
3. **After applying a step** — verify the actual diff against the approved preview (call this the
|
|
29
|
+
D12 verify: run `git diff` or re-read the changed lines; a divergence in either direction must
|
|
30
|
+
be surfaced and explicitly accepted before the step is marked done). Then mark its checklist
|
|
31
|
+
entry as `[x]` in the plan file with a one-line note about what landed. Run any gate the plan
|
|
32
|
+
specifies (e.g. a `grep` clean of old paths) before declaring the step done.
|
|
33
|
+
|
|
34
|
+
4. **When every step is checked off** — propose deleting the plan file, after confirming with the
|
|
35
|
+
user that the migration is fully landed and verified.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Draft a GitHub pull request description for the current branch following a compact template (what / scenarios / verification). Use when the user asks to write, draft, or generate a PR description for the current branch.
|
|
3
|
+
allowed-tools: Bash(git rev-parse:*), Bash(git log:*), Bash(git diff:*)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Current branch state
|
|
7
|
+
|
|
8
|
+
- Branch: !`git rev-parse --abbrev-ref HEAD`
|
|
9
|
+
- Commits ahead of {{MAIN_BRANCH}} (origin first, local fallback):
|
|
10
|
+
|
|
11
|
+
!`git log origin/{{MAIN_BRANCH}}..HEAD --oneline 2>/dev/null | head -30 || git log {{MAIN_BRANCH}}..HEAD --oneline 2>/dev/null | head -30 || echo "(no upstream or local {{MAIN_BRANCH}} branch found)"`
|
|
12
|
+
|
|
13
|
+
- Files changed (top 20):
|
|
14
|
+
|
|
15
|
+
!`git diff origin/{{MAIN_BRANCH}}...HEAD --stat --stat-count=20 2>/dev/null || git diff {{MAIN_BRANCH}}...HEAD --stat --stat-count=20 2>/dev/null || echo "(diff unavailable)"`
|
|
16
|
+
|
|
17
|
+
## Style rules
|
|
18
|
+
|
|
19
|
+
- "What" block ≤ 2 sentences. State user-visible behaviour / CLI surface change; no implementation
|
|
20
|
+
detail. If you need more than 2 sentences, the scope is too wide — split.
|
|
21
|
+
- "Scenarios" use imperative + arrow notation: `<command> → <expected>`. Not full sentences.
|
|
22
|
+
- For a CLI, scenarios are commands the reviewer runs (e.g. `agent-stack detect → lists Claude
|
|
23
|
+
Code`); state which directory / fixture to run them in if it matters.
|
|
24
|
+
- Link the GitHub issue narratively or with `Closes #NN` — this repo has no Jira.
|
|
25
|
+
|
|
26
|
+
## Delivery format
|
|
27
|
+
|
|
28
|
+
Wrap the entire PR body in a **single fenced code block** (use four backticks if the body itself
|
|
29
|
+
contains code fences). The user copies the block once; GitHub renders markdown on paste. Do NOT
|
|
30
|
+
render markdown inline in the reply — bold/lists/headers won't survive the clipboard hop.
|
|
31
|
+
|
|
32
|
+
## Template
|
|
33
|
+
|
|
34
|
+
````markdown
|
|
35
|
+
**What this PR does / why we need it:**
|
|
36
|
+
|
|
37
|
+
<One- or two-sentence summary of the user-visible / CLI behaviour change.>
|
|
38
|
+
|
|
39
|
+
**Scenarios**
|
|
40
|
+
|
|
41
|
+
1. **<Scenario name>** — `<command>` → <expected outcome>.
|
|
42
|
+
2. **<Scenario name>** — `<command>` → <expected outcome>.
|
|
43
|
+
|
|
44
|
+
**Verification**
|
|
45
|
+
|
|
46
|
+
- `{{PM}} typecheck && {{PM}} test` — green.
|
|
47
|
+
|
|
48
|
+
Closes #<issue>
|
|
49
|
+
````
|
|
50
|
+
|
|
51
|
+
## When to deviate
|
|
52
|
+
|
|
53
|
+
- **Bug-fix PR:** add a "**Reproduction**" line above "Scenarios" with exact repro steps, then
|
|
54
|
+
scenarios verify the fix.
|
|
55
|
+
- **Pure refactor / chore:** drop "Scenarios"; replace with "No behaviour change — verified by
|
|
56
|
+
`{{PM}} test`".
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Repository Structure
|
|
2
|
+
|
|
3
|
+
Template for documenting this repo's layout so agents can locate code and respect boundaries. Fill
|
|
4
|
+
the tables with **this project's** actual structure.
|
|
5
|
+
|
|
6
|
+
## Layout
|
|
7
|
+
|
|
8
|
+
| Path | Purpose |
|
|
9
|
+
| -------- | ---------------- |
|
|
10
|
+
| `<path>` | <what lives here> |
|
|
11
|
+
|
|
12
|
+
## Tooling
|
|
13
|
+
|
|
14
|
+
- **Package manager**: {{PM}} only.
|
|
15
|
+
- **Build**: `<build command>` → `<output dir>`.
|
|
16
|
+
- **Typecheck / static gate**: `<typecheck command>`.
|
|
17
|
+
- **Test**: `<test command>`.
|
|
18
|
+
|
|
19
|
+
## Where new files go
|
|
20
|
+
|
|
21
|
+
- New <unit> → `<path>` (+ register in `<entry>`).
|
|
22
|
+
- New test → mirror the source path under the test dir.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Team Conventions
|
|
2
|
+
|
|
3
|
+
Fill each section with **this project's** actual rules. The structure below is the transferable
|
|
4
|
+
part; the values are placeholders the deploying agent (or you) should replace.
|
|
5
|
+
|
|
6
|
+
## Commits
|
|
7
|
+
|
|
8
|
+
Format: `type(scope): message` (Conventional Commits if the repo runs commitlint).
|
|
9
|
+
|
|
10
|
+
**Types**: feat, fix, chore, refactor, test, docs, style, perf, ci, build, revert
|
|
11
|
+
**Scopes**: enumerate the areas the project uses as scopes.
|
|
12
|
+
**Issue reference**: how this repo links work (e.g. `Closes #NN`).
|
|
13
|
+
|
|
14
|
+
## Branches
|
|
15
|
+
|
|
16
|
+
Main branch: `{{MAIN_BRANCH}}`. `git push` is manual-only (the guard-bash hook blocks the agent).
|
|
17
|
+
|
|
18
|
+
## Git hooks
|
|
19
|
+
|
|
20
|
+
- `pre-commit`: <linter/typecheck on staged files, or empty>.
|
|
21
|
+
- `commit-msg`: <commit-message linting, if any>.
|
|
22
|
+
|
|
23
|
+
## Code style
|
|
24
|
+
|
|
25
|
+
Capture the load-bearing rules: typing strictness, import conventions, formatter settings, naming.
|
|
26
|
+
|
|
27
|
+
## Hard prohibitions
|
|
28
|
+
|
|
29
|
+
- **{{PM}} only** — other package managers are blocked by the guard-bash hook.
|
|
30
|
+
- **Never `git push`** from the agent — manual-only.
|
|
31
|
+
- **Never hand-edit generated files** ({{GEN_GLOBS}}, {{LOCKFILE}}).
|