@phuc1403/musketeer 0.2.2 → 0.2.4

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/README.md CHANGED
@@ -12,15 +12,19 @@ npm i -g @phuc1403/musketeer
12
12
  ## Use
13
13
 
14
14
  ```bash
15
- musketeer muster # open the muster — pick your company (multi-select) → reconcile
15
+ musketeer muster # self-update pick company (multi-select) → refresh all selected skills to latest
16
16
  musketeer promote # update the musketeer CLI itself to the latest published version
17
17
  musketeer # show usage
18
18
  musketeer --help # show usage
19
19
  ```
20
20
 
21
- `musketeer muster` is **idempotent**: the picker pre-checks your current company (from `.musketeer.json`),
22
- and confirming applies the diff install newly-checked, remove newly-unchecked, regenerate
23
- `settings.json`, and auto-install any missing prerequisites.
21
+ `musketeer muster` **self-updates first**: it pulls the latest published version (re-execing when behind),
22
+ so the refresh always applies the newest template. Set `MUSKETEER_NO_SELF_UPDATE=1` to skip (offline / pinned).
23
+
24
+ It is also **idempotent** and **force-updating**: the picker pre-checks your current company (from
25
+ `.musketeer.json`); on confirm it **re-writes every selected musketeer's files to the latest template**
26
+ (overwriting any local edits), removes newly-unchecked ones, regenerates `settings.json`, and auto-installs
27
+ any missing prerequisites.
24
28
 
25
29
  `musketeer promote` upgrades the **CLI tool** itself (not your project's company): it checks the npm
26
30
  registry, and if a newer version exists, runs `npm i -g @phuc1403/musketeer@latest`. _muster = which
@@ -30,7 +34,7 @@ musketeers are in this project; promote = upgrade the binary._
30
34
 
31
35
  | Musketeer | Default in muster | What it adds |
32
36
  |-----------|-------------------|--------------|
33
- | **core** | always on (locked, hidden) | research, handoff, skill-creator · statusline, usage-context, format-json hooks |
37
+ | **core** | always on (locked, hidden) | research, handoff, skill-creator, git (+ git-manager agent) · statusline, usage-context, format-json hooks |
34
38
  | **architecture** | off | adr-writer, architecture-characteristic-writer, context-map · CML validation hook |
35
39
  | **hallmark** | off | hallmark, hallmark-explore, hallmark-loop · auditor/explorer agents |
36
40
  | **code-review** | off | code-review skill + code-reviewer agent |
package/bin/musketeer.js CHANGED
@@ -6,16 +6,17 @@ const { parseArgs } = require('node:util');
6
6
  const USAGE = `musketeer — scaffold a curated company of Claude Code musketeers into ./.claude
7
7
 
8
8
  Usage:
9
- musketeer muster Open the muster pick your company (multi-select), then reconcile
9
+ musketeer muster Self-update to latest, then pick your company and refresh all selected skills
10
10
  musketeer promote Update the musketeer CLI itself to the latest published version
11
11
  musketeer Show this help
12
12
  musketeer --help Show this help
13
13
 
14
14
  Notes:
15
15
  * "muster" changes which musketeers are in THIS project; "promote" upgrades the CLI itself.
16
+ * On confirm, muster REFRESHES every selected musketeer's files to the latest template (overwrites local edits).
17
+ * muster auto-updates the CLI to the latest published version first (set MUSKETEER_NO_SELF_UPDATE=1 to skip).
16
18
  * "core" is always installed and locked — it cannot be removed.
17
19
  * The muster is multi-select: check every musketeer you want, then confirm.
18
- * Re-running is idempotent: the picker pre-checks your current company; confirm applies the diff.
19
20
  * settings.json is GENERATED per-selection; missing prereqs are auto-installed (announced).`;
20
21
 
21
22
  function parse(argv) {
@@ -48,6 +49,14 @@ async function main(argv = process.argv.slice(2)) {
48
49
  }
49
50
 
50
51
  if (command === 'muster') {
52
+ // Pull the latest published version first, so the picker refreshes installed
53
+ // skills to the newest template (not a stale package's). Re-execs when behind.
54
+ const { ensureLatest } = require('../src/self-update');
55
+ const reexecCode = ensureLatest();
56
+ if (reexecCode !== null) {
57
+ process.exitCode = reexecCode;
58
+ return;
59
+ }
51
60
  // Lazy-require so help never pays the cost of loading the engine/manifest.
52
61
  const reconcile = require('../src/reconcile');
53
62
  await reconcile.run({ desiredIds: null, interactive: true });
package/manifest.json CHANGED
@@ -3,16 +3,18 @@
3
3
  "musketeers": {
4
4
  "core": {
5
5
  "label": "core",
6
- "description": "Always-on foundation: research, handoff, skill-creator + statusline, usage-context & format-json hooks.",
6
+ "description": "Always-on foundation: research, handoff, skill-creator, git (+ git-manager) + statusline, usage-context & format-json hooks.",
7
7
  "locked": true,
8
8
  "deps": [],
9
9
  "files": [
10
10
  "skills/research/**",
11
11
  "skills/handoff/**",
12
12
  "skills/skill-creator/**",
13
+ "skills/git/**",
13
14
  "skills/install.ps1",
14
15
  "skills/install.sh",
15
16
  "agents/researcher.md",
17
+ "agents/git-manager.md",
16
18
  "statusline.cjs",
17
19
  "hooks/usage-context-awareness.cjs",
18
20
  "hooks/lib/**",
@@ -43,7 +45,7 @@
43
45
  "order": 2
44
46
  }
45
47
  ],
46
- "prereqs": ["node", "git", "python", "venv-anthropic", "claude-cli"]
48
+ "prereqs": ["node", "git", "gh", "python", "venv-anthropic", "claude-cli"]
47
49
  },
48
50
  "architecture": {
49
51
  "label": "architecture",
@@ -95,13 +97,14 @@
95
97
  },
96
98
  "dotnet": {
97
99
  "label": "dotnet",
98
- "description": ".NET extras: tdd, knowledge-crunching + EF migration-guard hook.",
100
+ "description": ".NET extras: tdd, knowledge-crunching + EF migration-guard & CONTEXT auto-load hooks.",
99
101
  "locked": false,
100
102
  "deps": [],
101
103
  "files": [
102
104
  "skills/tdd/**",
103
105
  "skills/knowledge-crunching/**",
104
- "hooks/block-migration-edits.cjs"
106
+ "hooks/block-migration-edits.cjs",
107
+ "hooks/inject-context.cjs"
105
108
  ],
106
109
  "settings": [
107
110
  {
@@ -110,6 +113,13 @@
110
113
  "command": "node \"${CLAUDE_PROJECT_DIR}/.claude/hooks/block-migration-edits.cjs\"",
111
114
  "order": 1,
112
115
  "statusMessage": "Checking for EF migration edits"
116
+ },
117
+ {
118
+ "event": "SessionStart",
119
+ "matcher": "startup|resume|clear|compact",
120
+ "command": "node \"${CLAUDE_PROJECT_DIR}/.claude/hooks/inject-context.cjs\"",
121
+ "order": 1,
122
+ "statusMessage": "Loading domain CONTEXT"
113
123
  }
114
124
  ],
115
125
  "prereqs": []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phuc1403/musketeer",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Distributable custom Claude Code harness — one declarative command scaffolds a curated company of musketeers (skills/agents/hooks) into any project's .claude/.",
5
5
  "type": "commonjs",
6
6
  "bin": {
package/src/promote.js CHANGED
@@ -23,6 +23,19 @@ function defaultRun(cmd) {
23
23
  };
24
24
  }
25
25
 
26
+ /**
27
+ * Look up a package's published `latest` version from the registry.
28
+ * @param {(cmd:string)=>{code:number,stdout:string,stderr:string}} exec
29
+ * @param {string} name
30
+ * @returns {?string} the version, or null if unreachable / unparseable
31
+ */
32
+ function fetchLatest(exec, name) {
33
+ const view = exec(`npm view ${name} version`);
34
+ const latest = (view.stdout || '').trim();
35
+ if (view.code !== 0 || !/^\d+\.\d+\.\d+/.test(latest)) return null;
36
+ return latest;
37
+ }
38
+
26
39
  /** Compare dotted numeric versions: 1 if a>b, -1 if a<b, 0 if equal. */
27
40
  function compareVersions(a, b) {
28
41
  const pa = String(a).split('.').map(Number);
@@ -50,10 +63,9 @@ async function run(overrides = {}) {
50
63
  const current = overrides.current || pkg.version;
51
64
 
52
65
  log(`Checking rank… installed ${current} (${name})`);
53
- const view = exec(`npm view ${name} version`);
54
- const latest = (view.stdout || '').trim();
66
+ const latest = fetchLatest(exec, name);
55
67
 
56
- if (view.code !== 0 || !/^\d+\.\d+\.\d+/.test(latest)) {
68
+ if (!latest) {
57
69
  log('Could not reach the npm registry to check for a newer version.');
58
70
  log(`Try manually: npm i -g ${name}@latest`);
59
71
  return { status: 'unknown', from: current, to: null };
@@ -78,4 +90,4 @@ async function run(overrides = {}) {
78
90
  return { status: 'promoted', from: current, to: latest };
79
91
  }
80
92
 
81
- module.exports = { run, compareVersions, defaultRun };
93
+ module.exports = { run, fetchLatest, compareVersions, defaultRun };
package/src/reconcile.js CHANGED
@@ -50,7 +50,7 @@ async function run(opts, overrides = {}) {
50
50
  const plan = copier.planFiles(prev.files, desired.files);
51
51
 
52
52
  d.log(`Company: ${desired.ids.join(', ')}`);
53
- d.log(`Files: ${plan.copy.length} managed, ${plan.remove.length} to remove.`);
53
+ d.log(`Files: ${plan.copy.length} refreshed to latest, ${plan.remove.length} removed.`);
54
54
 
55
55
  copier.apply(plan, d.templateDir, projectDir);
56
56
  d.settingsMerger.generate(desired, projectDir);
@@ -0,0 +1,73 @@
1
+ 'use strict';
2
+
3
+ // Self-update gate for `musketeer muster`. Before the picker applies the bundled
4
+ // template, make sure the CLI is at the latest PUBLISHED version — otherwise
5
+ // "muster" would refresh installed skills to a stale package's template.
6
+ //
7
+ // When behind: promote (npm i -g @latest), then re-exec `musketeer muster` so the
8
+ // picker runs under the freshly-installed template. A running Node process can't
9
+ // reliably hot-swap its own package files mid-run, so re-exec is the safe path.
10
+ //
11
+ // Guards:
12
+ // MUSKETEER_REEXEC=1 set on the child so it never re-checks (no loop)
13
+ // MUSKETEER_NO_SELF_UPDATE=1 user opt-out (offline / pinned version)
14
+
15
+ const { spawnSync } = require('child_process');
16
+ const { fetchLatest, compareVersions, defaultRun } = require('./promote');
17
+ const pkg = require('../package.json');
18
+
19
+ /**
20
+ * Decide whether muster should self-update first. Pure — injectable exec/env.
21
+ * @param {{exec?:Function, current?:string, name?:string, env?:object}} [o]
22
+ * @returns {{action:'proceed'|'update', latest:?string}}
23
+ */
24
+ function decide(o = {}) {
25
+ const exec = o.exec || defaultRun;
26
+ const current = o.current || pkg.version;
27
+ const name = o.name || pkg.name;
28
+ const env = o.env || process.env;
29
+
30
+ if (env.MUSKETEER_REEXEC === '1' || env.MUSKETEER_NO_SELF_UPDATE === '1') {
31
+ return { action: 'proceed', latest: null };
32
+ }
33
+ const latest = fetchLatest(exec, name);
34
+ if (!latest) return { action: 'proceed', latest: null }; // offline / unknown — proceed as-is
35
+ if (compareVersions(latest, current) <= 0) return { action: 'proceed', latest }; // already latest
36
+ return { action: 'update', latest };
37
+ }
38
+
39
+ /**
40
+ * Ensure the CLI is latest before muster applies the template.
41
+ * @param {object} [io] injectable { log, exec, spawn, env, name, current } for tests
42
+ * @returns {?number} an exit code if it re-exec'd a fresh muster (caller should
43
+ * exit with it); null to mean "proceed in-process".
44
+ */
45
+ function ensureLatest(io = {}) {
46
+ const log = io.log || ((m) => process.stdout.write(m + '\n'));
47
+ const exec = io.exec || defaultRun;
48
+ const spawn = io.spawn || spawnSync;
49
+ const env = io.env || process.env;
50
+ const name = io.name || pkg.name;
51
+ const current = io.current || pkg.version;
52
+
53
+ const d = decide({ exec, current, name, env });
54
+ if (d.action === 'proceed') return null;
55
+
56
+ log(`Updating musketeer ${current} → ${d.latest} before muster…`);
57
+ const ins = exec(`npm i -g ${name}@latest`);
58
+ if (ins.code !== 0) {
59
+ log('Self-update failed — continuing with the current version.');
60
+ if (ins.stderr) log(ins.stderr.trim());
61
+ return null;
62
+ }
63
+
64
+ // Re-exec the now-latest binary's muster, inheriting the TTY for the picker.
65
+ const r = spawn('musketeer', ['muster'], {
66
+ stdio: 'inherit',
67
+ shell: true,
68
+ env: { ...env, MUSKETEER_REEXEC: '1' },
69
+ });
70
+ return typeof r.status === 'number' ? r.status : 0;
71
+ }
72
+
73
+ module.exports = { decide, ensureLatest };
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: git-manager
3
+ description: Stage, commit, and push code changes with conventional commits. Use when user says "commit", "push", or finishes a feature/fix.
4
+ model: haiku
5
+ tools: Glob, Grep, Read, Bash, TaskCreate, TaskGet, TaskUpdate, TaskList, SendMessage
6
+ ---
7
+ You are a Git Operations Specialist. Execute workflow in EXACTLY 2-4 tool calls. No exploration phase.
8
+ Activate `git` skill.
9
+ **IMPORTANT**: Ensure token efficiency while maintaining high quality.
10
+
11
+ ## Team Mode (when spawned as teammate)
12
+
13
+ When operating as a team member:
14
+ 1. On start: check `TaskList` then claim your assigned or next unblocked task via `TaskUpdate`
15
+ 2. Read full task description via `TaskGet` before starting work
16
+ 3. Only perform git operations explicitly requested in task — no unsolicited pushes or force operations
17
+ 4. When done: `TaskUpdate(status: "completed")` then `SendMessage` git operation summary to lead
18
+ 5. When receiving `shutdown_request`: approve via `SendMessage(type: "shutdown_response")` unless mid-critical-operation
19
+ 6. Communicate with peers via `SendMessage(type: "message")` when coordination needed
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ // SessionStart hook (dotnet company): auto-load the repo-root `CONTEXT.md` — the
3
+ // bounded-context model produced by the knowledge-crunching skill — into every
4
+ // session, so the domain's ubiquitous language and invariants "lead the code".
5
+ //
6
+ // If the root CONTEXT.md is missing, ALERT the user (systemMessage) so they
7
+ // create one. Any other error fails open (emits nothing, exit 0) so it can never
8
+ // block a session.
9
+ const fs = require("fs");
10
+ const path = require("path");
11
+
12
+ const root = process.env.CLAUDE_PROJECT_DIR || process.cwd();
13
+ const file = path.join(root, "CONTEXT.md");
14
+
15
+ try {
16
+ let content;
17
+ try {
18
+ content = fs.readFileSync(file, "utf-8");
19
+ } catch {
20
+ // Not found — surface a visible warning to the user, inject nothing.
21
+ process.stdout.write(
22
+ JSON.stringify({
23
+ systemMessage:
24
+ "musketeer: no CONTEXT.md at the repo root — the bounded-context model is missing. " +
25
+ "Run the knowledge-crunching skill (/knowledge-crunching) to create one.",
26
+ })
27
+ );
28
+ process.exit(0);
29
+ }
30
+
31
+ const additionalContext =
32
+ "Bounded-context model (root CONTEXT.md) — injected every session. It is the " +
33
+ "ubiquitous language and model rules of this bounded context, kept vendor- and " +
34
+ "decision-neutral. Treat it as canonical for domain naming, concepts, and invariants: " +
35
+ "name new code after it, and when a concept is renamed update CONTEXT.md and the code in " +
36
+ "the same turn. It bounds what the DOMAIN model sees, not what infrastructure may do " +
37
+ "(an ACL can legitimately key on more).\n\n" +
38
+ "===== CONTEXT.md =====\n" +
39
+ content.trimEnd();
40
+
41
+ process.stdout.write(
42
+ JSON.stringify({
43
+ hookSpecificOutput: {
44
+ hookEventName: "SessionStart",
45
+ additionalContext,
46
+ },
47
+ })
48
+ );
49
+ process.exit(0);
50
+ } catch {
51
+ process.exit(0); // fail open
52
+ }
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: ck:git
3
+ description: "Git operations with conventional commits. Use for staging, committing, pushing, PRs, merges. Auto-splits commits by type/scope. Security scans for secrets."
4
+ argument-hint: "cm|cp|pr|merge [args]"
5
+ metadata:
6
+ author: claudekit
7
+ version: "1.0.0"
8
+ ---
9
+
10
+ # Git Operations
11
+
12
+ ## Default (No Arguments)
13
+
14
+ If invoked without arguments, use `AskUserQuestion` to present available git operations:
15
+
16
+ | Operation | Description |
17
+ |-----------|-------------|
18
+ | `cm` | Stage files & create commits |
19
+ | `cp` | Stage files, create commits and push |
20
+ | `pr` | Create Pull Request |
21
+ | `merge` | Merge branches |
22
+
23
+ Present as options via `AskUserQuestion` with header "Git Operation", question "What would you like to do?".
24
+
25
+ Execute git workflows via `git-manager` subagent to isolate verbose output.
26
+
27
+ **IMPORTANT:**
28
+ - Sacrifice grammar for the sake of concision.
29
+ - Ensure token efficiency while maintaining high quality.
30
+ - Pass these rules to subagents.
31
+
32
+ ## Arguments
33
+ - `cm`: Stage files & create commits
34
+ - `cp`: Stage files, create commits and push
35
+ - `pr`: Create Pull Request [to-branch] [from-branch]
36
+ - `to-branch`: Target branch (default: main)
37
+ - `from-branch`: Source branch (default: current branch)
38
+ - `merge`: Merge [to-branch] [from-branch]
39
+ - `to-branch`: Target branch (default: main)
40
+ - `from-branch`: Source branch (default: current branch)
41
+
42
+ ## Quick Reference
43
+
44
+ | Task | Reference |
45
+ |------|-----------|
46
+ | Commit | `references/workflow-commit.md` |
47
+ | Push | `references/workflow-push.md` |
48
+ | Pull Request | `references/workflow-pr.md` |
49
+ | Merge | `references/workflow-merge.md` |
50
+ | Standards | `references/commit-standards.md` |
51
+ | Safety | `references/safety-protocols.md` |
52
+ | Branches | `references/branch-management.md` |
53
+ | GitHub CLI | `references/gh-cli-guide.md` |
54
+
55
+ ## Core Workflow
56
+
57
+ ### Step 1: Stage + Analyze
58
+ ```bash
59
+ git add -A && git diff --cached --stat && git diff --cached --name-only
60
+ ```
61
+
62
+ ### Step 2: Security Check
63
+ Scan for secrets before commit:
64
+ ```bash
65
+ git diff --cached | grep -iE "(api[_-]?key|token|password|secret|credential)"
66
+ ```
67
+ **If secrets found:** STOP, warn user, suggest `.gitignore`.
68
+
69
+ ### Step 3: Split Decision
70
+
71
+ **NOTE:**
72
+ - Search for related issues on GitHub and add to body.
73
+ - Only use `feat`, `fix`, or `perf` prefixes for files in `.claude` directory (do not use `docs`).
74
+
75
+ **Split commits if:**
76
+ - Different types mixed (feat + fix, code + docs)
77
+ - Multiple scopes (auth + payments)
78
+ - Config/deps + code mixed
79
+ - FILES > 10 unrelated
80
+
81
+ **Single commit if:**
82
+ - Same type/scope, FILES ≤ 3, LINES ≤ 50
83
+
84
+ ### Step 4: Commit
85
+ ```bash
86
+ git commit -m "type(scope): description"
87
+ ```
88
+
89
+ ## Output Format
90
+ ```
91
+ ✓ staged: N files (+X/-Y lines)
92
+ ✓ security: passed
93
+ ✓ commit: HASH type(scope): description
94
+ ✓ pushed: yes/no
95
+ ```
96
+
97
+ ## Error Handling
98
+
99
+ | Error | Action |
100
+ |-------|--------|
101
+ | Secrets detected | Block commit, show files |
102
+ | No changes | Exit cleanly |
103
+ | Push rejected | Suggest `git pull --rebase` |
104
+ | Merge conflicts | Suggest manual resolution |
105
+
106
+ ## References
107
+
108
+ - `references/workflow-commit.md` - Commit workflow with split logic
109
+ - `references/workflow-push.md` - Push workflow with error handling
110
+ - `references/workflow-pr.md` - PR creation with remote diff analysis
111
+ - `references/workflow-merge.md` - Branch merge workflow
112
+ - `references/commit-standards.md` - Conventional commit format rules
113
+ - `references/safety-protocols.md` - Secret detection, branch protection
114
+ - `references/branch-management.md` - Naming, lifecycle, strategies
115
+ - `references/gh-cli-guide.md` - GitHub CLI commands reference
@@ -0,0 +1,88 @@
1
+ # Branch Management
2
+
3
+ ## Naming Convention
4
+
5
+ **Format:** `<type>/<descriptive-name>`
6
+
7
+ | Type | Purpose | Example |
8
+ |------|---------|---------|
9
+ | `feature/` | New features | `feature/oauth-login` |
10
+ | `fix/` | Bug fixes | `fix/db-timeout` |
11
+ | `refactor/` | Code restructure | `refactor/api-cleanup` |
12
+ | `docs/` | Documentation | `docs/api-reference` |
13
+ | `test/` | Test improvements | `test/integration-suite` |
14
+ | `chore/` | Maintenance | `chore/deps-update` |
15
+ | `hotfix/` | Production fixes | `hotfix/payment-crash` |
16
+
17
+ ## Branch Lifecycle
18
+
19
+ ### Create
20
+ ```bash
21
+ git checkout main
22
+ git pull origin main
23
+ git checkout -b feature/new-feature
24
+ ```
25
+
26
+ ### During Development
27
+ ```bash
28
+ # Regular commits
29
+ git add <files> && git commit -m "feat(scope): description"
30
+
31
+ # Stay current with main
32
+ git fetch origin
33
+ git rebase origin/main
34
+ ```
35
+
36
+ ### Before Merge
37
+ ```bash
38
+ # Push final state
39
+ git push origin feature/new-feature
40
+
41
+ # Or after rebase (feature branches only)
42
+ git push -f origin feature/new-feature
43
+ ```
44
+
45
+ ### After Merge
46
+ ```bash
47
+ # Delete local
48
+ git branch -d feature/new-feature
49
+
50
+ # Delete remote
51
+ git push origin --delete feature/new-feature
52
+ ```
53
+
54
+ ## Branch Strategies
55
+
56
+ ### Simple (small teams)
57
+ ```
58
+ main (production)
59
+ └─ feature/* (development)
60
+ ```
61
+
62
+ ### Git Flow (releases)
63
+ ```
64
+ main (production)
65
+ develop (staging)
66
+ ├─ feature/*
67
+ ├─ bugfix/*
68
+ ├─ hotfix/*
69
+ └─ release/*
70
+ ```
71
+
72
+ ### Trunk-Based (CI/CD)
73
+ ```
74
+ main (always deployable)
75
+ └─ short-lived feature branches
76
+ ```
77
+
78
+ ## Quick Commands
79
+
80
+ | Task | Command |
81
+ |------|---------|
82
+ | List branches | `git branch -a` |
83
+ | Current branch | `git rev-parse --abbrev-ref HEAD` |
84
+ | Switch branch | `git checkout <branch>` |
85
+ | Create + switch | `git checkout -b <branch>` |
86
+ | Delete local | `git branch -d <branch>` |
87
+ | Delete remote | `git push origin --delete <branch>` |
88
+ | Rename | `git branch -m <old> <new>` |
@@ -0,0 +1,46 @@
1
+ # Commit Message Standards
2
+
3
+ ## Format
4
+ ```
5
+ type(scope): description
6
+ ```
7
+
8
+ ## Types (priority order)
9
+ - `feat`: New feature
10
+ - `fix`: Bug fix
11
+ - `docs`: Documentation only
12
+ - `style`: Formatting (no logic change)
13
+ - `refactor`: Restructure without behavior change
14
+ - `test`: Tests
15
+ - `chore`: Maintenance, deps, config
16
+ - `perf`: Performance
17
+ - `build`: Build system
18
+ - `ci`: CI/CD
19
+
20
+ ## Rules
21
+ - **<72 characters**
22
+ - **Present tense, imperative** ("add" not "added")
23
+ - **No period at end**
24
+ - **Scope optional but recommended**
25
+ - **Focus on WHAT, not HOW**
26
+ - Only use `feat`, `fix`, or `perf` prefixes for files in `.claude` directory (do not use `docs`).
27
+
28
+ ## NEVER Include AI Attribution
29
+ - ❌ "Generated with Claude"
30
+ - ❌ "Co-Authored-By: Claude"
31
+ - ❌ Any AI reference
32
+
33
+ ## Good Examples
34
+ - `feat(auth): add login validation`
35
+ - `fix(api): resolve query timeout`
36
+ - `docs(readme): update install guide`
37
+ - `refactor(utils): simplify date logic`
38
+
39
+ ## Bad Examples
40
+ - ❌ `Updated files` (not descriptive)
41
+ - ❌ `feat(auth): added login using bcrypt with salt` (too long, describes HOW)
42
+ - ❌ `Fix bug` (not specific)
43
+
44
+ ## Special Cases
45
+ - `.claude/` skill updates: `perf(skill): improve token efficiency`
46
+ - `.claude/` new skills: `feat(skill): add database-optimizer`
@@ -0,0 +1,109 @@
1
+ # GitHub CLI Guide
2
+
3
+ ## Authentication
4
+ ```bash
5
+ gh auth login # Interactive login
6
+ gh auth status # Check auth state
7
+ gh auth logout # Logout
8
+ ```
9
+
10
+ ## Pull Requests
11
+
12
+ ### Create PR
13
+ ```bash
14
+ # Basic
15
+ gh pr create --base main --head feature-branch --title "feat: add login" --body "Summary"
16
+
17
+ # With HEREDOC body
18
+ gh pr create --base main --title "feat(auth): add OAuth" --body "$(cat <<'EOF'
19
+ ## Summary
20
+ - Added OAuth2 provider support
21
+ - Implemented token refresh
22
+
23
+ ## Test plan
24
+ - [ ] Unit tests pass
25
+ - [ ] Manual login test
26
+ EOF
27
+ )"
28
+
29
+ # Draft mode
30
+ gh pr create --draft --title "WIP: new feature"
31
+
32
+ # Assign reviewers
33
+ gh pr create --reviewer @user1,@user2
34
+
35
+ # Add labels
36
+ gh pr create --label "bug,priority:high"
37
+ ```
38
+
39
+ ### View/Review PR
40
+ ```bash
41
+ gh pr list # List PRs
42
+ gh pr view 123 # View PR details
43
+ gh pr view 123 --web # Open in browser
44
+ gh pr checkout 123 # Checkout PR locally
45
+ gh pr diff 123 # View PR diff
46
+ gh pr status # Your PRs + reviews
47
+ ```
48
+
49
+ ### Merge PR
50
+ ```bash
51
+ gh pr merge 123 # Default merge commit
52
+ gh pr merge 123 --squash # Squash commits
53
+ gh pr merge 123 --rebase # Rebase merge
54
+ gh pr merge 123 --auto # Auto-merge when checks pass
55
+ gh pr merge 123 --delete-branch # Delete branch after
56
+ ```
57
+
58
+ ### PR Comments
59
+ ```bash
60
+ gh pr comment 123 --body "LGTM!"
61
+ gh api repos/{owner}/{repo}/pulls/123/comments # View all
62
+ ```
63
+
64
+ ## Issues
65
+
66
+ ```bash
67
+ gh issue list # List issues
68
+ gh issue view 42 # View issue
69
+ gh issue create --title "Bug" --body "Description"
70
+ gh issue develop 42 -c # Create branch from issue
71
+ ```
72
+
73
+ ## Repository
74
+
75
+ ```bash
76
+ gh repo view # Current repo info
77
+ gh repo clone owner/repo # Clone
78
+ gh browse # Open repo in browser
79
+ gh browse path/to/file:42 # Open file at line
80
+ ```
81
+
82
+ ## Workflow Runs
83
+
84
+ ```bash
85
+ gh run list # List workflow runs
86
+ gh run view <run-id> # View run details
87
+ gh run watch # Watch running workflow
88
+ gh run rerun <run-id> # Rerun failed workflow
89
+ ```
90
+
91
+ ## JSON Output (scripting)
92
+
93
+ ```bash
94
+ gh pr list --json number,title,author
95
+ gh pr view 123 --json commits,reviews
96
+ gh issue list --json number,title --jq '.[].title'
97
+ ```
98
+
99
+ ## Common Patterns
100
+
101
+ ### Create PR with auto-merge
102
+ ```bash
103
+ gh pr create --fill && gh pr merge --auto --squash
104
+ ```
105
+
106
+ ### Close stale PRs
107
+ ```bash
108
+ gh pr list --state open --json number -q '.[].number' | xargs -I {} gh pr close {}
109
+ ```
@@ -0,0 +1,69 @@
1
+ # Git Safety Protocols
2
+
3
+ ## Secret Detection Patterns
4
+
5
+ ### Scan Command
6
+ ```bash
7
+ git diff --cached | grep -iE "(AKIA|api[_-]?key|token|password|secret|credential|private[_-]?key|mongodb://|postgres://|mysql://|redis://|-----BEGIN)"
8
+ ```
9
+
10
+ ### Patterns to Detect
11
+
12
+ | Category | Pattern | Example |
13
+ |----------|---------|---------|
14
+ | API Keys | `api[_-]?key`, `apiKey` | `API_KEY=abc123` |
15
+ | AWS | `AKIA[0-9A-Z]{16}` | `AKIAIOSFODNN7EXAMPLE` |
16
+ | Tokens | `token`, `auth_token`, `jwt` | `AUTH_TOKEN=xyz` |
17
+ | Passwords | `password`, `passwd`, `pwd` | `DB_PASSWORD=secret` |
18
+ | Private Keys | `-----BEGIN PRIVATE KEY-----` | PEM files |
19
+ | DB URLs | `mongodb://`, `postgres://`, `mysql://` | Connection strings |
20
+ | OAuth | `client_secret`, `oauth_token` | `CLIENT_SECRET=abc` |
21
+
22
+ ### Files to Warn About
23
+ - `.env`, `.env.*` (except `.env.example`)
24
+ - `*.key`, `*.pem`, `*.p12`
25
+ - `credentials.json`, `secrets.json`
26
+ - `config/private.*`
27
+
28
+ ### Action on Detection
29
+ 1. **BLOCK commit immediately**
30
+ 2. Show matching lines: `git diff --cached | grep -B2 -A2 <pattern>`
31
+ 3. Suggest: "Add to .gitignore or use environment variables"
32
+ 4. Offer to unstage: `git reset HEAD <file>`
33
+
34
+ ## Branch Protection
35
+
36
+ ### Never Force Push To
37
+ - `main`, `master`, `production`, `prod`, `release/*`
38
+
39
+ ### Pre-Merge Checks
40
+ ```bash
41
+ # Check for conflicts before merge
42
+ git merge --no-commit --no-ff origin/{branch} && git merge --abort
43
+ ```
44
+
45
+ ### Remote-First Operations
46
+ Always use `origin/{branch}` for comparisons:
47
+ - ✅ `git diff origin/main...origin/feature`
48
+ - ❌ `git diff main...HEAD` (includes local uncommitted)
49
+
50
+ ## Error Recovery
51
+
52
+ ### Undo Last Commit (unpushed)
53
+ ```bash
54
+ git reset --soft HEAD~1 # Keep changes staged
55
+ git reset HEAD~1 # Keep changes unstaged
56
+ ```
57
+
58
+ ### Abort Merge
59
+ ```bash
60
+ git merge --abort
61
+ ```
62
+
63
+ ### Discard Local Changes
64
+ ```bash
65
+ git checkout -- <file> # Single file
66
+ git reset --hard HEAD # All files (DANGER)
67
+ ```
68
+
69
+ **Always confirm with user before destructive operations.**
@@ -0,0 +1,58 @@
1
+ # Commit Workflow
2
+
3
+ Execute via `git-manager` subagent.
4
+
5
+ ## Tool 1: Stage + Analyze
6
+ ```bash
7
+ git add -A && \
8
+ echo "=== STAGED ===" && git diff --cached --stat && \
9
+ echo "=== SECURITY ===" && \
10
+ git diff --cached | grep -c -iE "(api[_-]?key|token|password|secret|credential)" | awk '{print "SECRETS:"$1}' && \
11
+ echo "=== GROUPS ===" && \
12
+ git diff --cached --name-only | awk -F'/' '{
13
+ if ($0 ~ /\.(md|txt)$/) print "docs:"$0
14
+ else if ($0 ~ /test|spec/) print "test:"$0
15
+ else if ($0 ~ /\.claude/) print "config:"$0
16
+ else if ($0 ~ /package\.json|lock/) print "deps:"$0
17
+ else print "code:"$0
18
+ }'
19
+ ```
20
+
21
+ **If SECRETS > 0:** STOP, show matches, block commit.
22
+
23
+ ## Tool 2: Split Decision
24
+
25
+ NOTE:
26
+ - Search for related issues on GitHub and add to body.
27
+ - Only use `feat`, `fix`, or `perf` prefixes for files in `.claude` directory (do not use `docs`).
28
+
29
+ **From groups, decide:**
30
+
31
+ **A) Single commit:** Same type/scope, FILES ≤ 3, LINES ≤ 50
32
+
33
+ **B) Multi commit:** Mixed types/scopes, group by:
34
+ - Group 1: `config:` → `chore(config): ...`
35
+ - Group 2: `deps:` → `chore(deps): ...`
36
+ - Group 3: `test:` → `test: ...`
37
+ - Group 4: `code:` → `feat|fix: ...`
38
+ - Group 5: `docs:` → `docs: ...`
39
+
40
+ ## Tool 3: Commit
41
+
42
+ **Single:**
43
+ ```bash
44
+ git commit -m "type(scope): description"
45
+ ```
46
+
47
+ **Multi (sequential):**
48
+ ```bash
49
+ git reset && git add file1 file2 && git commit -m "type(scope): desc"
50
+ ```
51
+ Repeat for each group.
52
+
53
+ ## Tool 4: Push (if requested)
54
+ ```bash
55
+ git push && echo "✓ pushed: yes" || echo "✓ pushed: no"
56
+ ```
57
+
58
+ **Only push if user explicitly requested** ("push", "commit and push").
@@ -0,0 +1,48 @@
1
+ # Merge Workflow
2
+
3
+ Execute via `git-manager` subagent.
4
+
5
+ ## Variables
6
+ - TO_BRANCH: target (defaults to `main`)
7
+ - FROM_BRANCH: source (defaults to current branch)
8
+
9
+ ## Step 1: Sync with Remote
10
+
11
+ **IMPORTANT: Always merge `main` (or any default branch) to current branch first.**
12
+
13
+ ```bash
14
+ git fetch origin
15
+ git checkout {TO_BRANCH}
16
+ git pull origin {TO_BRANCH}
17
+ ```
18
+
19
+ ## Step 2: Merge from REMOTE
20
+ ```bash
21
+ git merge origin/{FROM_BRANCH} --no-ff -m "merge: {FROM_BRANCH} into {TO_BRANCH}"
22
+ ```
23
+
24
+ **Why `origin/{FROM_BRANCH}`:** Ensures merging only committed+pushed changes, not local WIP.
25
+
26
+ ## Step 3: Resolve Conflicts
27
+ If conflicts:
28
+ 1. Resolve manually
29
+ 2. `git add . && git commit`
30
+ 3. If clarifications needed, report to main agent
31
+
32
+ ## Step 4: Push
33
+ ```bash
34
+ git push origin {TO_BRANCH}
35
+ ```
36
+
37
+ ## Pre-Merge Checklist
38
+ - Fetch latest: `git fetch origin`
39
+ - Ensure FROM_BRANCH pushed to remote
40
+ - Check for conflicts: `git merge --no-commit --no-ff origin/{FROM_BRANCH}` then abort
41
+
42
+ ## Error Handling
43
+
44
+ | Error | Action |
45
+ |-------|--------|
46
+ | Merge conflicts | Resolve manually, then commit |
47
+ | Branch not found | Verify branch name, ensure pushed |
48
+ | Push rejected | `git pull --rebase`, retry |
@@ -0,0 +1,58 @@
1
+ # Pull Request Workflow
2
+
3
+ Execute via `git-manager` subagent.
4
+
5
+ ## Variables
6
+ - TO_BRANCH: target (defaults to `main`)
7
+ - FROM_BRANCH: source (defaults to current branch)
8
+
9
+ ## CRITICAL: Use REMOTE diff
10
+ PRs based on remote branches. Local diff includes unpushed changes.
11
+
12
+ ## Tool 1: Sync + Analyze
13
+
14
+ **IMPORTANT: Always merge `main` (or any default branch) to current branch first.**
15
+
16
+ ```bash
17
+ git fetch origin && \
18
+ git push -u origin HEAD 2>/dev/null || true && \
19
+ BASE=${BASE_BRANCH:-main} && \
20
+ HEAD=$(git rev-parse --abbrev-ref HEAD) && \
21
+ echo "=== PR: $HEAD → $BASE ===" && \
22
+ echo "=== COMMITS ===" && \
23
+ git log origin/$BASE...origin/$HEAD --oneline && \
24
+ echo "=== FILES ===" && \
25
+ git diff origin/$BASE...origin/$HEAD --stat
26
+ ```
27
+
28
+ **If "Branch not on remote":** Push first, retry.
29
+
30
+ ## Tool 2: Generate Content
31
+ **Title:** Conventional commit format, <72 chars, NO version numbers
32
+ **Body:** Summary bullets + Test plan checklist
33
+
34
+ ## Tool 3: Create PR
35
+ ```bash
36
+ gh pr create --base $BASE --head $HEAD --title "..." --body "$(cat <<'EOF'
37
+ ## Summary
38
+ - Bullet points
39
+
40
+ ## Test plan
41
+ - [ ] Test item
42
+ EOF
43
+ )"
44
+ ```
45
+
46
+ ## DO NOT use (local comparison)
47
+ - ❌ `git diff main...HEAD`
48
+ - ❌ `git diff --cached`
49
+ - ❌ `git status`
50
+
51
+ ## Error Handling
52
+
53
+ | Error | Action |
54
+ |-------|--------|
55
+ | Branch not on remote | `git push -u origin HEAD`, retry |
56
+ | Empty diff | Warn: "No changes for PR" |
57
+ | Push rejected | `git pull --rebase`, resolve, push |
58
+ | No upstream | `git push -u origin HEAD` |
@@ -0,0 +1,52 @@
1
+ # Push Workflow
2
+
3
+ Execute via `git-manager` subagent.
4
+
5
+ ## Pre-Push Checklist
6
+ 1. All changes committed
7
+ 2. Secrets scanned (see `safety-protocols.md`)
8
+ 3. Branch pushed to remote
9
+
10
+ ## Tool 1: Verify State
11
+ ```bash
12
+ git status && \
13
+ git log origin/$(git rev-parse --abbrev-ref HEAD)..HEAD --oneline 2>/dev/null || echo "NO_UPSTREAM"
14
+ ```
15
+
16
+ **If uncommitted changes:** Warn user, suggest commit first.
17
+ **If NO_UPSTREAM:** Use `git push -u origin HEAD`.
18
+
19
+ ## Tool 2: Push
20
+ ```bash
21
+ git push origin HEAD
22
+ ```
23
+
24
+ **On success:** Report commit hashes pushed.
25
+
26
+ ## Error Handling
27
+
28
+ | Error | Cause | Solution |
29
+ |-------|-------|----------|
30
+ | `rejected - non-fast-forward` | Remote has newer commits | `git pull --rebase`, resolve conflicts, push again |
31
+ | `no upstream branch` | Branch not tracked | `git push -u origin HEAD` |
32
+ | `Authentication failed` | Invalid credentials | Check `gh auth status` or SSH keys |
33
+ | `Repository not found` | Wrong remote URL | Verify `git remote -v` |
34
+ | `Permission denied` | No write access | Check repository permissions |
35
+
36
+ ## Force Push (DANGER)
37
+
38
+ **NEVER force push to main/master/production branches.**
39
+
40
+ If user explicitly requests force push on feature branch:
41
+ ```bash
42
+ git push -f origin HEAD
43
+ ```
44
+
45
+ **Warn user:** "Force push rewrites history. Collaborators may lose work."
46
+
47
+ ## Output Format
48
+ ```
49
+ ✓ pushed: N commits to origin/{branch}
50
+ - abc123 feat(auth): add login
51
+ - def456 fix(api): resolve timeout
52
+ ```