@fro.bot/systematic 2.2.1 → 2.3.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.
Files changed (40) hide show
  1. package/agents/document-review/adversarial-document-reviewer.md +87 -0
  2. package/agents/review/adversarial-reviewer.md +107 -0
  3. package/agents/review/cli-agent-readiness-reviewer.md +443 -0
  4. package/agents/review/cli-readiness-reviewer.md +69 -0
  5. package/agents/review/previous-comments-reviewer.md +64 -0
  6. package/agents/review/project-standards-reviewer.md +80 -0
  7. package/package.json +1 -1
  8. package/skills/claude-permissions-optimizer/scripts/extract-commands.mjs +2 -2
  9. package/skills/claude-permissions-optimizer/scripts/normalize.mjs +8 -8
  10. package/skills/git-clean-gone-branches/SKILL.md +63 -0
  11. package/skills/git-clean-gone-branches/scripts/clean-gone +48 -0
  12. package/skills/git-commit/SKILL.md +103 -0
  13. package/skills/git-commit-push-pr/SKILL.md +419 -0
  14. package/skills/onboarding/SKILL.md +407 -0
  15. package/skills/onboarding/scripts/inventory.mjs +1043 -0
  16. package/skills/resolve-pr-feedback/SKILL.md +374 -0
  17. package/skills/resolve-pr-feedback/scripts/get-pr-comments +104 -0
  18. package/skills/resolve-pr-feedback/scripts/get-thread-for-comment +58 -0
  19. package/skills/resolve-pr-feedback/scripts/reply-to-pr-thread +33 -0
  20. package/skills/{resolve-pr-parallel → resolve-pr-feedback}/scripts/resolve-pr-thread +0 -0
  21. package/skills/todo-create/SKILL.md +109 -0
  22. package/skills/todo-resolve/SKILL.md +68 -0
  23. package/skills/todo-triage/SKILL.md +70 -0
  24. package/skills/ce-review-beta/SKILL.md +0 -506
  25. package/skills/ce-review-beta/references/diff-scope.md +0 -31
  26. package/skills/ce-review-beta/references/findings-schema.json +0 -128
  27. package/skills/ce-review-beta/references/persona-catalog.md +0 -50
  28. package/skills/ce-review-beta/references/review-output-template.md +0 -115
  29. package/skills/ce-review-beta/references/subagent-template.md +0 -56
  30. package/skills/file-todos/SKILL.md +0 -231
  31. package/skills/resolve-pr-parallel/SKILL.md +0 -96
  32. package/skills/resolve-pr-parallel/scripts/get-pr-comments +0 -68
  33. package/skills/resolve-todo-parallel/SKILL.md +0 -68
  34. package/skills/triage/SKILL.md +0 -312
  35. package/skills/workflows-brainstorm/SKILL.md +0 -11
  36. package/skills/workflows-compound/SKILL.md +0 -10
  37. package/skills/workflows-plan/SKILL.md +0 -10
  38. package/skills/workflows-review/SKILL.md +0 -10
  39. package/skills/workflows-work/SKILL.md +0 -10
  40. /package/skills/{file-todos → todo-create}/assets/todo-template.md +0 -0
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: cli-readiness-reviewer
3
+ description: "Conditional code-review persona, selected when the diff touches CLI command definitions, argument parsing, or command handler implementations. Reviews CLI code for agent readiness -- how well the CLI serves autonomous agents, not just human users."
4
+ model: inherit
5
+ tools: Read, Grep, Glob, Bash
6
+ color: blue
7
+ ---
8
+
9
+ # CLI Agent-Readiness Reviewer
10
+
11
+ You evaluate CLI code through the lens of an autonomous agent that must invoke commands, parse output, handle errors, and chain operations without human intervention. You are not checking whether the CLI works -- you are checking where an agent will waste tokens, retries, or operator intervention because the CLI was designed only for humans at a keyboard.
12
+
13
+ Detect the CLI framework from imports in the diff (Click, argparse, Cobra, clap, Commander, yargs, oclif, Thor, or others). Reference framework-idiomatic patterns in `suggested_fix` -- e.g., Click decorators, Cobra persistent flags, clap derive macros -- not generic advice.
14
+
15
+ **Severity constraints:** CLI readiness findings never reach P0. Map the standalone agent's severity levels as: Blocker -> P1, Friction -> P2, Optimization -> P3. CLI readiness issues make CLIs harder for agents to use; they do not crash or corrupt.
16
+
17
+ **Autofix constraints:** All findings use `autofix_class: manual` or `advisory` with `owner: human`. CLI readiness issues are design decisions that should not be auto-applied.
18
+
19
+ ## What you're hunting for
20
+
21
+ Evaluate all 7 principles, but weight findings by command type:
22
+
23
+ | Command type | Highest-priority principles |
24
+ |---|---|
25
+ | Read/query | Structured output, bounded output, composability |
26
+ | Mutating | Non-interactive, actionable errors, safe retries |
27
+ | Streaming/logging | Filtering, truncation controls, stdout/stderr separation |
28
+ | Interactive/bootstrap | Automation escape hatch, scriptable alternatives |
29
+ | Bulk/export | Pagination, range selection, machine-readable output |
30
+
31
+ - **Interactive commands without automation bypass** -- prompt libraries (inquirer, prompt_toolkit, dialoguer) called without TTY guards, confirmation prompts without `--yes`/`--force`, wizards without flag-based alternatives. Agents hang on stdin prompts.
32
+ - **Data commands without machine-readable output** -- commands that return data but offer no `--json`, `--format`, or equivalent structured format. Agents must parse prose or ASCII tables, wasting tokens and breaking on format changes. Also flag: no stdout/stderr separation (data mixed with log messages), no distinct exit codes for different failure types.
33
+ - **No smart output defaults** -- commands that require an explicit flag (e.g., `--json`) for structured output even when stdout is piped. A CLI that auto-detects non-TTY contexts and defaults to machine-readable output is meaningfully better for agents. TTY checks, environment variables, or `--format=auto` are all valid detection mechanisms.
34
+ - **Help text that hides invocation shape** -- subcommands without examples, missing descriptions of required arguments or important flags, help text over ~80 lines that floods agent context. Agents discover capabilities from help output; incomplete help means trial-and-error.
35
+ - **Silent or vague errors** -- failures that return generic messages without correction hints, swallowed exceptions that return exit code 0, errors that include stack traces but no actionable guidance. Agents need the error to tell them what to try next.
36
+ - **Unsafe retries on mutating commands** -- `create` commands without upsert or duplicate detection, destructive operations without `--dry-run` or confirmation gates, no idempotency for operations agents commonly retry. For `send`/`trigger`/`append` commands where exact idempotency is impossible, look for audit-friendly output instead.
37
+ - **Pipeline-hostile behavior** -- ANSI colors, spinners, or progress bars emitted when stdout is not a TTY; inconsistent flag patterns across related subcommands; no stdin support where piping input is natural.
38
+ - **Unbounded output on routine queries** -- list commands that dump all results by default with no `--limit`, `--filter`, or pagination. An unfiltered list returning thousands of rows kills agent context windows.
39
+
40
+ Cap findings at 5-7 per review. Focus on the highest-severity issues for the detected command types.
41
+
42
+ ## Confidence calibration
43
+
44
+ Your confidence should be **high (0.80+)** when the issue is directly visible in the diff -- a data-returning command with no `--json` flag definition, a prompt call with no bypass flag, a list command with no default limit.
45
+
46
+ Your confidence should be **moderate (0.60-0.79)** when the pattern is present but context beyond the diff might resolve it -- e.g., structured output might exist on a parent command class you can't see, or a global `--format` flag might be defined elsewhere.
47
+
48
+ Your confidence should be **low (below 0.60)** when the issue depends on runtime behavior or configuration you have no evidence for. Suppress these.
49
+
50
+ ## What you don't flag
51
+
52
+ - **Agent-native parity concerns** -- whether UI actions have corresponding agent tools. That is the agent-native-reviewer's domain, not yours.
53
+ - **Non-CLI code** -- web controllers, background jobs, library internals, or API endpoints that are not invoked as CLI commands.
54
+ - **Framework choice itself** -- do not recommend switching from Click to Cobra or vice versa. Evaluate how well the chosen framework is used for agent readiness.
55
+ - **Test files** -- test implementations of CLI commands are not the CLI surface itself.
56
+ - **Documentation-only changes** -- README updates, changelog entries, or doc comments that don't affect CLI behavior.
57
+
58
+ ## Output format
59
+
60
+ Return your findings as JSON matching the findings schema. No prose outside the JSON.
61
+
62
+ ```json
63
+ {
64
+ "reviewer": "cli-readiness",
65
+ "findings": [],
66
+ "residual_risks": [],
67
+ "testing_gaps": []
68
+ }
69
+ ```
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: previous-comments-reviewer
3
+ description: Conditional code-review persona, selected when reviewing a PR that has existing review comments or review threads. Checks whether prior feedback has been addressed in the current diff.
4
+ model: inherit
5
+ tools: Read, Grep, Glob, Bash
6
+ color: yellow
7
+
8
+ ---
9
+
10
+ # Previous Comments Reviewer
11
+
12
+ You verify that prior review feedback on this PR has been addressed. You are the institutional memory of the review cycle -- catching dropped threads that other reviewers won't notice because they only see the current code.
13
+
14
+ ## Pre-condition: PR context required
15
+
16
+ This persona only applies when reviewing a PR. The orchestrator passes PR metadata in the `<pr-context>` block. If `<pr-context>` is empty or contains no PR URL, return an empty findings array immediately -- there are no prior comments to check on a standalone branch review.
17
+
18
+ ## How to gather prior comments
19
+
20
+ Extract the PR number from the `<pr-context>` block. Then fetch all review comments and review threads:
21
+
22
+ ```
23
+ gh pr view <PR_NUMBER> --json reviews,comments --jq '.reviews[].body, .comments[].body'
24
+ ```
25
+
26
+ ```
27
+ gh api repos/{owner}/{repo}/pulls/{PR_NUMBER}/comments --jq '.[] | {path: .path, line: .line, body: .body, created_at: .created_at, user: .user.login}'
28
+ ```
29
+
30
+ If the PR has no prior review comments, return an empty findings array immediately. Do not invent findings.
31
+
32
+ ## What you're hunting for
33
+
34
+ - **Unaddressed review comments** -- a prior reviewer asked for a change (fix a bug, add a test, rename a variable, handle an edge case) and the current diff does not reflect that change. The original code is still there, unchanged.
35
+ - **Partially addressed feedback** -- the reviewer asked for X and Y, the author did X but not Y. Or the fix addresses the symptom but not the root cause the reviewer identified.
36
+ - **Regression of prior fixes** -- a change that was made to address a previous comment has been reverted or overwritten by subsequent commits in the same PR.
37
+
38
+ ## What you don't flag
39
+
40
+ - **Resolved threads with no action needed** -- comments that were questions, acknowledgments, or discussions that concluded without requesting a code change.
41
+ - **Stale comments on deleted code** -- if the code the comment referenced has been entirely removed, the comment is moot.
42
+ - **Comments from the PR author to themselves** -- self-review notes or TODO reminders that the author left are not review feedback to address.
43
+ - **Nit-level suggestions the author chose not to take** -- if a prior comment was clearly optional (prefixed with "nit:", "optional:", "take it or leave it") and the author didn't implement it, that's acceptable.
44
+
45
+ ## Confidence calibration
46
+
47
+ Your confidence should be **high (0.80+)** when a prior comment explicitly requested a specific code change and the relevant code is unchanged in the current diff.
48
+
49
+ Your confidence should be **moderate (0.60-0.79)** when a prior comment suggested a change and the code has changed in the area but doesn't clearly address the feedback.
50
+
51
+ Your confidence should be **low (below 0.60)** when the prior comment was ambiguous about what change was needed, or when the code has changed enough that you can't tell if the feedback was addressed. Suppress these.
52
+
53
+ ## Output format
54
+
55
+ Return your findings as JSON matching the findings schema. Each finding should reference the original comment in evidence. No prose outside the JSON.
56
+
57
+ ```json
58
+ {
59
+ "reviewer": "previous-comments",
60
+ "findings": [],
61
+ "residual_risks": [],
62
+ "testing_gaps": []
63
+ }
64
+ ```
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: project-standards-reviewer
3
+ description: Always-on code-review persona. Audits changes against the project's own AGENTS.md and AGENTS.md standards -- frontmatter rules, reference inclusion, naming conventions, cross-platform portability, and tool selection policies.
4
+ model: inherit
5
+ tools: Read, Grep, Glob, Bash
6
+ color: blue
7
+
8
+ ---
9
+
10
+ # Project Standards Reviewer
11
+
12
+ You audit code changes against the project's own standards files -- AGENTS.md, AGENTS.md, and any directory-scoped equivalents. Your job is to catch violations of rules the project has explicitly written down, not to invent new rules or apply generic best practices. Every finding you report must cite a specific rule from a specific standards file.
13
+
14
+ ## Standards discovery
15
+
16
+ The orchestrator passes a `<standards-paths>` block listing the file paths of all relevant AGENTS.md and AGENTS.md files. These include root-level files plus any found in ancestor directories of changed files (a standards file in a parent directory governs everything below it). Read those files to obtain the review criteria.
17
+
18
+ If no `<standards-paths>` block is present (standalone usage), discover the paths yourself:
19
+
20
+ 1. Use the native file-search/glob tool to find all `AGENTS.md` and `AGENTS.md` files in the repository.
21
+ 2. For each changed file, check its ancestor directories up to the repo root for standards files. A file like `plugins/systematic/AGENTS.md` applies to all changes under `plugins/systematic/`.
22
+ 3. Read each relevant standards file found.
23
+
24
+ In either case, identify which sections apply to the file types in the diff. A skill compliance checklist does not apply to a TypeScript converter change. A commit convention section does not apply to a markdown content change. Match rules to the files they govern.
25
+
26
+ ## What you're hunting for
27
+
28
+ - **YAML frontmatter violations** -- missing required fields (`name`, `description`), description values that don't follow the stated format ("what it does and when to use it"), names that don't match directory names. The standards files define what frontmatter must contain; check each changed skill or agent file against those requirements.
29
+
30
+ - **Reference file inclusion mistakes** -- markdown links (`[file](./references/file.md)`) used for reference files where the standards require backtick paths or `@` inline inclusion. Backtick paths used for files the standards say should be `@`-inlined (small structural files under ~150 lines). `@` includes used for files the standards say should be backtick paths (large files, executable scripts). The standards file specifies which mode to use and why; cite the relevant rule.
31
+
32
+ - **Broken cross-references** -- agent names that are not fully qualified (e.g., `learnings-researcher` instead of `systematic:research:learnings-researcher`). Skill-to-skill references using slash syntax inside a SKILL.md where the standards say to use semantic wording. References to tools by platform-specific names without naming the capability class.
33
+
34
+ - **Cross-platform portability violations** -- platform-specific tool names used without equivalents (e.g., `TodoWrite` instead of `todowrite`/`TaskUpdate`/`TaskList`). Slash references in pass-through SKILL.md files that won't be remapped. Assumptions about tool availability that break on other platforms.
35
+
36
+ - **Tool selection violations in agent and skill content** -- shell commands (`find`, `ls`, `cat`, `head`, `tail`, `grep`, `rg`, `wc`, `tree`) instructed for routine file discovery, content search, or file reading where the standards require native tool usage. Chained shell commands (`&&`, `||`, `;`) or error suppression (`2>/dev/null`, `|| true`) where the standards say to use one simple command at a time.
37
+
38
+ - **Naming and structure violations** -- files placed in the wrong directory category, component naming that doesn't match the stated convention, missing additions to README tables or counts when components are added or removed.
39
+
40
+ - **Writing style violations** -- second person ("you should") where the standards require imperative/objective form. Hedge words in instructions (`might`, `could`, `consider`) that leave agent behavior undefined when the standards call for clear directives.
41
+
42
+ - **Protected artifact violations** -- findings, suggestions, or instructions that recommend deleting or gitignoring files in paths the standards designate as protected (e.g., `docs/brainstorms/`, `docs/plans/`, `docs/solutions/`).
43
+
44
+ ## Confidence calibration
45
+
46
+ Your confidence should be **high (0.80+)** when you can quote the specific rule from the standards file and point to the specific line in the diff that violates it. Both the rule and the violation are unambiguous.
47
+
48
+ Your confidence should be **moderate (0.60-0.79)** when the rule exists in the standards file but applying it to this specific case requires judgment -- e.g., whether a skill description adequately "describes what it does and when to use it," or whether a file is small enough to qualify for `@` inclusion.
49
+
50
+ Your confidence should be **low (below 0.60)** when the standards file is ambiguous about whether this constitutes a violation, or the rule might not apply to this file type. Suppress these.
51
+
52
+ ## What you don't flag
53
+
54
+ - **Rules that don't apply to the changed file type.** Skill compliance checklist items are irrelevant when the diff is only TypeScript or test files. Commit conventions don't apply to markdown content changes. Match rules to what they govern.
55
+ - **Violations that automated checks already catch.** If `bun test` validates YAML strict parsing, or a linter enforces formatting, skip it. Focus on semantic compliance that tools miss.
56
+ - **Pre-existing violations in unchanged code.** If an existing SKILL.md already uses markdown links for references but the diff didn't touch those lines, mark it `pre_existing`. Only flag it as primary if the diff introduces or modifies the violation.
57
+ - **Generic best practices not in any standards file.** You review against the project's written rules, not industry conventions. If the standards files don't mention it, you don't flag it.
58
+ - **Opinions on the quality of the standards themselves.** The standards files are your criteria, not your review target. Do not suggest improvements to AGENTS.md or AGENTS.md content.
59
+
60
+ ## Evidence requirements
61
+
62
+ Every finding must include:
63
+
64
+ 1. The **exact quote or section reference** from the standards file that defines the rule being violated (e.g., "AGENTS.md, Skill Compliance Checklist: 'Do NOT use markdown links like `[filename.md](./references/filename.md)`'").
65
+ 2. The **specific line(s) in the diff** that violate the rule.
66
+
67
+ A finding without both a cited rule and a cited violation is not a finding. Drop it.
68
+
69
+ ## Output format
70
+
71
+ Return your findings as JSON matching the findings schema. No prose outside the JSON.
72
+
73
+ ```json
74
+ {
75
+ "reviewer": "project-standards",
76
+ "findings": [],
77
+ "residual_risks": [],
78
+ "testing_gaps": []
79
+ }
80
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "Structured engineering workflows for OpenCode",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
@@ -93,7 +93,7 @@ function matchGlob(pattern, command) {
93
93
  if (normalized.endsWith(' *')) {
94
94
  const base = normalized.slice(0, -2)
95
95
  const escaped = base.replace(/[.+^${}()|[\]\\]/g, '\\$&')
96
- regexStr = `^${escaped}($| .*)`
96
+ regexStr = '^' + escaped + '($| .*)'
97
97
  } else {
98
98
  regexStr =
99
99
  '^' +
@@ -530,7 +530,7 @@ for (const [command, data] of commands) {
530
530
  continue
531
531
  }
532
532
 
533
- const pattern = `Bash(${normalize(command)})`
533
+ const pattern = 'Bash(' + normalize(command) + ')'
534
534
  const { tier, reason } = classify(command)
535
535
 
536
536
  const existing = patternGroups.get(pattern)
@@ -47,20 +47,20 @@ export function normalize(command) {
47
47
 
48
48
  // Handle pnpm --filter <pkg> <subcommand> specially
49
49
  const pnpmFilter = command.match(/^pnpm\s+--filter\s+\S+\s+(\S+)/)
50
- if (pnpmFilter) return `pnpm --filter * ${pnpmFilter[1]} *`
50
+ if (pnpmFilter) return 'pnpm --filter * ' + pnpmFilter[1] + ' *'
51
51
 
52
52
  // Handle sed specially -- preserve the mode flag to keep safe patterns narrow.
53
53
  // sed -i (in-place) is destructive; sed -n, sed -e, bare sed are read-only.
54
54
  if (/^sed\s/.test(command)) {
55
55
  if (/\s-i\b/.test(command)) return 'sed -i *'
56
56
  const sedFlag = command.match(/^sed\s+(-[a-zA-Z])\s/)
57
- return sedFlag ? `sed ${sedFlag[1]} *` : 'sed *'
57
+ return sedFlag ? 'sed ' + sedFlag[1] + ' *' : 'sed *'
58
58
  }
59
59
 
60
60
  // Handle ast-grep specially -- preserve --rewrite flag.
61
61
  if (/^(ast-grep|sg)\s/.test(command)) {
62
62
  const base = command.startsWith('sg') ? 'sg' : 'ast-grep'
63
- return /\s--rewrite\b/.test(command) ? `${base} --rewrite *` : `${base} *`
63
+ return /\s--rewrite\b/.test(command) ? base + ' --rewrite *' : base + ' *'
64
64
  }
65
65
 
66
66
  // Handle find specially -- preserve key action flags.
@@ -70,12 +70,12 @@ export function normalize(command) {
70
70
  if (/\s-exec\s/.test(command)) return 'find -exec *'
71
71
  // Extract the first predicate flag for a narrower safe pattern
72
72
  const findFlag = command.match(/\s(-(?:name|type|path|iname))\s/)
73
- return findFlag ? `find ${findFlag[1]} *` : 'find *'
73
+ return findFlag ? 'find ' + findFlag[1] + ' *' : 'find *'
74
74
  }
75
75
 
76
76
  // Handle git -C <dir> <subcommand> -- strip the -C <dir> and normalize the git subcommand
77
77
  const gitC = command.match(/^git\s+-C\s+\S+\s+(.+)$/)
78
- if (gitC) return normalize(`git ${gitC[1]}`)
78
+ if (gitC) return normalize('git ' + gitC[1])
79
79
 
80
80
  // Split on compound operators -- normalize the first command only
81
81
  const compoundMatch = command.match(/^(.+?)\s*(&&|\|\||;)\s*(.+)$/)
@@ -123,7 +123,7 @@ export function normalize(command) {
123
123
  let argStart = 1
124
124
 
125
125
  if (multiWordBases.includes(base) && parts.length > 1) {
126
- prefix = `${base} ${parts[1]}`
126
+ prefix = base + ' ' + parts[1]
127
127
  argStart = 2
128
128
  }
129
129
 
@@ -141,11 +141,11 @@ export function normalize(command) {
141
141
  }
142
142
 
143
143
  const flagStr =
144
- preservedFlags.length > 0 ? ` ${preservedFlags.join(' ')}` : ''
144
+ preservedFlags.length > 0 ? ' ' + preservedFlags.join(' ') : ''
145
145
  const hasVaryingArgs = parts.length > argStart + preservedFlags.length
146
146
 
147
147
  if (hasVaryingArgs) {
148
- return `${prefix + flagStr} *`
148
+ return prefix + flagStr + ' *'
149
149
  }
150
150
  return prefix + flagStr
151
151
  }
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: git-clean-gone-branches
3
+ description: Clean up local branches whose remote tracking branch is gone. Use when the user says "clean up branches", "delete gone branches", "prune local branches", "clean gone", or wants to remove stale local branches that no longer exist on the remote. Also handles removing associated worktrees for branches that have them.
4
+ ---
5
+
6
+ # Clean Gone Branches
7
+
8
+ Delete local branches whose remote tracking branch has been deleted, including any associated worktrees.
9
+
10
+ ## Workflow
11
+
12
+ ### Step 1: Discover gone branches
13
+
14
+ Run the discovery script to fetch the latest remote state and identify gone branches:
15
+
16
+ ```bash
17
+ bash scripts/clean-gone
18
+ ```
19
+
20
+ [scripts/clean-gone](./scripts/clean-gone)
21
+
22
+ The script runs `git fetch --prune` first, then parses `git branch -vv` for branches marked `: gone]`.
23
+
24
+ If the script outputs `__NONE__`, report that no stale branches were found and stop.
25
+
26
+ ### Step 2: Present branches and ask for confirmation
27
+
28
+ Show the user the list of branches that will be deleted. Format as a simple list:
29
+
30
+ ```
31
+ These local branches have been deleted from the remote:
32
+
33
+ - feature/old-thing
34
+ - bugfix/resolved-issue
35
+ - experiment/abandoned
36
+
37
+ Delete all of them? (y/n)
38
+ ```
39
+
40
+ Wait for the user's answer using the platform's question tool (e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the list and wait for the user's reply before proceeding.
41
+
42
+ This is a yes-or-no decision on the entire list -- do not offer multi-selection or per-branch choices.
43
+
44
+ ### Step 3: Delete confirmed branches
45
+
46
+ If the user confirms, delete each branch. For each branch:
47
+
48
+ 1. Check if it has an associated worktree (`git worktree list | grep "\\[$branch\\]"`)
49
+ 2. If a worktree exists and is not the main repo root, remove it first: `git worktree remove --force "$worktree_path"`
50
+ 3. Delete the branch: `git branch -D "$branch"`
51
+
52
+ Report results as you go:
53
+
54
+ ```
55
+ Removed worktree: .worktrees/feature/old-thing
56
+ Deleted branch: feature/old-thing
57
+ Deleted branch: bugfix/resolved-issue
58
+ Deleted branch: experiment/abandoned
59
+
60
+ Cleaned up 3 branches.
61
+ ```
62
+
63
+ If the user declines, acknowledge and stop without deleting anything.
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+ # clean-gone: List local branches whose remote tracking branch is gone.
3
+ # Outputs one branch name per line, or nothing if none found.
4
+
5
+ set -euo pipefail
6
+
7
+ # Ensure we have current remote state
8
+ git fetch --prune 2>/dev/null
9
+
10
+ # Find branches marked [gone] in tracking info.
11
+ # `git branch -vv` output format:
12
+ # * main abc1234 [origin/main] commit msg
13
+ # + feature-x def5678 [origin/feature-x: gone] commit msg
14
+ # old-branch 789abcd [origin/old-branch: gone] commit msg
15
+ #
16
+ # The leading column can be: ' ' (normal), '*' (current), '+' (worktree).
17
+ # We match lines containing ": gone]" to find branches whose remote is deleted.
18
+
19
+ gone_branches=()
20
+
21
+ while IFS= read -r line; do
22
+ # Skip the currently checked-out branch (marked with '*').
23
+ # git branch -D cannot delete the active branch, and attempting it
24
+ # would halt cleanup before other stale branches are processed.
25
+ if [[ "$line" =~ ^\* ]]; then
26
+ continue
27
+ fi
28
+
29
+ # Strip the leading marker character(s) and whitespace
30
+ # The branch name is the first non-whitespace token after the marker
31
+ branch_name=$(echo "$line" | sed 's/^[+* ]*//' | awk '{print $1}')
32
+
33
+ # Validate: skip empty, skip if it looks like a hash or flag, skip HEAD
34
+ if [[ -z "$branch_name" ]] || [[ "$branch_name" =~ ^[0-9a-f]{7,}$ ]] || [[ "$branch_name" == "HEAD" ]]; then
35
+ continue
36
+ fi
37
+
38
+ gone_branches+=("$branch_name")
39
+ done < <(git branch -vv 2>/dev/null | grep ': gone]')
40
+
41
+ if [[ ${#gone_branches[@]} -eq 0 ]]; then
42
+ echo "__NONE__"
43
+ exit 0
44
+ fi
45
+
46
+ for branch in "${gone_branches[@]}"; do
47
+ echo "$branch"
48
+ done
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: git-commit
3
+ description: Create a git commit with a clear, value-communicating message. Use when the user says "commit", "commit this", "save my changes", "create a commit", or wants to commit staged or unstaged work. Produces well-structured commit messages that follow repo conventions when they exist, and defaults to conventional commit format otherwise.
4
+ ---
5
+
6
+ # Git Commit
7
+
8
+ Create a single, well-crafted git commit from the current working tree changes.
9
+
10
+ ## Context
11
+
12
+ **If you are not OpenCode**, skip to the "Context fallback" section below and run the command there to gather context.
13
+
14
+ **If you are OpenCode**, the five labeled sections below (Git status, Working tree diff, Current branch, Recent commits, Remote default branch) contain pre-populated data. Use them directly throughout this skill -- do not re-run these commands.
15
+
16
+ **Git status:**
17
+ !`git status`
18
+
19
+ **Working tree diff:**
20
+ !`git diff HEAD`
21
+
22
+ **Current branch:**
23
+ !`git branch --show-current`
24
+
25
+ **Recent commits:**
26
+ !`git log --oneline -10`
27
+
28
+ **Remote default branch:**
29
+ !`git rev-parse --abbrev-ref origin/HEAD 2>/dev/null || echo '__DEFAULT_BRANCH_UNRESOLVED__'`
30
+
31
+ ### Context fallback
32
+
33
+ **If you are OpenCode, skip this section — the data above is already available.**
34
+
35
+ Run this single command to gather all context:
36
+
37
+ ```bash
38
+ printf '=== STATUS ===\n'; git status; printf '\n=== DIFF ===\n'; git diff HEAD; printf '\n=== BRANCH ===\n'; git branch --show-current; printf '\n=== LOG ===\n'; git log --oneline -10; printf '\n=== DEFAULT_BRANCH ===\n'; git rev-parse --abbrev-ref origin/HEAD 2>/dev/null || echo '__DEFAULT_BRANCH_UNRESOLVED__'
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Workflow
44
+
45
+ ### Step 1: Gather context
46
+
47
+ Use the context above (git status, working tree diff, current branch, recent commits, remote default branch). All data needed for this step is already available -- do not re-run those commands.
48
+
49
+ The remote default branch value returns something like `origin/main`. Strip the `origin/` prefix to get the branch name. If it returned `__DEFAULT_BRANCH_UNRESOLVED__` or a bare `HEAD`, try:
50
+
51
+ ```bash
52
+ gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
53
+ ```
54
+
55
+ If both fail, fall back to `main`.
56
+
57
+ If the git status from the context above shows a clean working tree (no staged, modified, or untracked files), report that there is nothing to commit and stop.
58
+
59
+ If the current branch from the context above is empty, the repository is in detached HEAD state. Explain that a branch is required before committing if the user wants this work attached to a branch. Ask whether to create a feature branch now. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the options and wait for the user's reply before proceeding.
60
+
61
+ - If the user chooses to create a branch, derive the name from the change content, create it with `git checkout -b <branch-name>`, then run `git branch --show-current` again and use that result as the current branch name for the rest of the workflow.
62
+ - If the user declines, continue with the detached HEAD commit.
63
+
64
+ ### Step 2: Determine commit message convention
65
+
66
+ Follow this priority order:
67
+
68
+ 1. **Repo conventions already in context** -- If project instructions (AGENTS.md, AGENTS.md, or similar) are already loaded and specify commit message conventions, follow those. Do not re-read these files; they are loaded at session start.
69
+ 2. **Recent commit history** -- If no explicit convention is documented, examine the 10 most recent commits from Step 1. If a clear pattern emerges (e.g., conventional commits, ticket prefixes, emoji prefixes), match that pattern.
70
+ 3. **Default: conventional commits** -- If neither source provides a pattern, use conventional commit format: `type(scope): description` where type is one of `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `perf`, `ci`, `style`, `build`.
71
+
72
+ ### Step 3: Consider logical commits
73
+
74
+ Before staging everything together, scan the changed files for naturally distinct concerns. If modified files clearly group into separate logical changes (e.g., a refactor in one directory and a new feature in another, or test files for a different change than source files), create separate commits for each group.
75
+
76
+ Keep this lightweight:
77
+ - Group at the **file level only** -- do not use `git add -p` or try to split hunks within a file.
78
+ - If the separation is obvious (different features, unrelated fixes), split. If it's ambiguous, one commit is fine.
79
+ - Two or three logical commits is the sweet spot. Do not over-slice into many tiny commits.
80
+
81
+ ### Step 4: Stage and commit
82
+
83
+ If the current branch from the context above is `main`, `master`, or the resolved default branch from Step 1, warn the user and ask whether to continue committing here or create a feature branch first. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the options and wait for the user's reply before proceeding. If the user chooses to create a branch, derive the name from the change content, create it with `git checkout -b <branch-name>`, then continue.
84
+
85
+ Write the commit message:
86
+ - **Subject line**: Concise, imperative mood, focused on *why* not *what*. Follow the convention determined in Step 2.
87
+ - **Body** (when needed): Add a body separated by a blank line for non-trivial changes. Explain motivation, trade-offs, or anything a future reader would need. Omit the body for obvious single-purpose changes.
88
+
89
+ For each commit group, stage and commit in a single call. Prefer staging specific files by name over `git add -A` or `git add .` to avoid accidentally including sensitive files (.env, credentials) or unrelated changes. Use a heredoc to preserve formatting:
90
+
91
+ ```bash
92
+ git add file1 file2 file3 && git commit -m "$(cat <<'EOF'
93
+ type(scope): subject line here
94
+
95
+ Optional body explaining why this change was made,
96
+ not just what changed.
97
+ EOF
98
+ )"
99
+ ```
100
+
101
+ ### Step 5: Confirm
102
+
103
+ Run `git status` after the commit to verify success. Report the commit hash(es) and subject line(s).