gitwise-cli 0.24.2__py3-none-any.whl

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 (125) hide show
  1. gitwise/__init__.py +11 -0
  2. gitwise/__main__.py +113 -0
  3. gitwise/_cli_completions.py +88 -0
  4. gitwise/_cli_dispatch.py +469 -0
  5. gitwise/_cli_introspection.py +275 -0
  6. gitwise/_cli_parser.py +345 -0
  7. gitwise/_cli_setup_agents.py +439 -0
  8. gitwise/_i18n_data.json +1934 -0
  9. gitwise/_paths.py +22 -0
  10. gitwise/_runtime_config.py +246 -0
  11. gitwise/audit.py +338 -0
  12. gitwise/branches.py +183 -0
  13. gitwise/clean.py +197 -0
  14. gitwise/commit.py +142 -0
  15. gitwise/conflicts.py +112 -0
  16. gitwise/context.py +163 -0
  17. gitwise/design.py +383 -0
  18. gitwise/diff.py +309 -0
  19. gitwise/doctor.py +116 -0
  20. gitwise/git.py +254 -0
  21. gitwise/health.py +345 -0
  22. gitwise/i18n.py +99 -0
  23. gitwise/log.py +329 -0
  24. gitwise/merge.py +193 -0
  25. gitwise/optimize.py +212 -0
  26. gitwise/output.py +652 -0
  27. gitwise/pick.py +102 -0
  28. gitwise/pr.py +543 -0
  29. gitwise/py.typed +0 -0
  30. gitwise/schema.py +49 -0
  31. gitwise/setup.py +551 -0
  32. gitwise/setup_agents/__init__.py +36 -0
  33. gitwise/setup_agents/adapters/__init__.py +17 -0
  34. gitwise/setup_agents/adapters/aider.py +5 -0
  35. gitwise/setup_agents/adapters/base.py +5 -0
  36. gitwise/setup_agents/adapters/codex.py +5 -0
  37. gitwise/setup_agents/adapters/continue_adapter.py +5 -0
  38. gitwise/setup_agents/adapters/cursor.py +5 -0
  39. gitwise/setup_agents/adapters/opencode.py +5 -0
  40. gitwise/setup_agents/adapters/pi.py +5 -0
  41. gitwise/setup_agents/exec.py +449 -0
  42. gitwise/setup_agents/format.py +164 -0
  43. gitwise/setup_agents/plan.py +254 -0
  44. gitwise/setup_agents/plan_gitfiles.py +167 -0
  45. gitwise/setup_agents/plan_skills.py +256 -0
  46. gitwise/setup_agents/providers/__init__.py +96 -0
  47. gitwise/setup_agents/providers/aider.py +11 -0
  48. gitwise/setup_agents/providers/base.py +79 -0
  49. gitwise/setup_agents/providers/claude.py +408 -0
  50. gitwise/setup_agents/providers/codex.py +11 -0
  51. gitwise/setup_agents/providers/continue_adapter.py +11 -0
  52. gitwise/setup_agents/providers/cursor.py +11 -0
  53. gitwise/setup_agents/providers/opencode.py +11 -0
  54. gitwise/setup_agents/providers/pi.py +11 -0
  55. gitwise/setup_agents/state.py +141 -0
  56. gitwise/setup_agents/types.py +48 -0
  57. gitwise/share/agents/skills/git-audit/SKILL.md +25 -0
  58. gitwise/share/agents/skills/git-clean/SKILL.md +22 -0
  59. gitwise/share/agents/skills/git-optimize/SKILL.md +21 -0
  60. gitwise/share/aider/CONVENTIONS.md.template +8 -0
  61. gitwise/share/aider/aider.conf.yml.template +4 -0
  62. gitwise/share/claude/CLAUDE.md.template +9 -0
  63. gitwise/share/claude/rules/gitwise.md +16 -0
  64. gitwise/share/claude/settings.json.template +47 -0
  65. gitwise/share/claude/skills/git-audit/SKILL.md +25 -0
  66. gitwise/share/claude/skills/git-clean/SKILL.md +22 -0
  67. gitwise/share/claude/skills/git-optimize/SKILL.md +21 -0
  68. gitwise/share/codex/agents/gitwise.toml.template +18 -0
  69. gitwise/share/continue/rules/gitwise.md.template +14 -0
  70. gitwise/share/cursor/rules/gitwise.mdc.template +16 -0
  71. gitwise/share/git-config-modern.txt +48 -0
  72. gitwise/share/hooks/commit-msg +22 -0
  73. gitwise/share/hooks/pre-commit +19 -0
  74. gitwise/share/opencode/agents/gitwise.md.template +14 -0
  75. gitwise/share/pi/skills/gitwise.md.template +14 -0
  76. gitwise/share/schemas/v1/input/audit.json +40 -0
  77. gitwise/share/schemas/v1/input/branches.json +51 -0
  78. gitwise/share/schemas/v1/input/clean.json +52 -0
  79. gitwise/share/schemas/v1/input/commands.json +36 -0
  80. gitwise/share/schemas/v1/input/commit.json +63 -0
  81. gitwise/share/schemas/v1/input/completions.json +51 -0
  82. gitwise/share/schemas/v1/input/conflicts.json +46 -0
  83. gitwise/share/schemas/v1/input/context.json +36 -0
  84. gitwise/share/schemas/v1/input/diff.json +56 -0
  85. gitwise/share/schemas/v1/input/doctor.json +36 -0
  86. gitwise/share/schemas/v1/input/health.json +36 -0
  87. gitwise/share/schemas/v1/input/log.json +71 -0
  88. gitwise/share/schemas/v1/input/merge.json +63 -0
  89. gitwise/share/schemas/v1/input/optimize.json +44 -0
  90. gitwise/share/schemas/v1/input/pick.json +63 -0
  91. gitwise/share/schemas/v1/input/pr.json +51 -0
  92. gitwise/share/schemas/v1/input/schema.json +48 -0
  93. gitwise/share/schemas/v1/input/setup-agents.json +108 -0
  94. gitwise/share/schemas/v1/input/setup.json +55 -0
  95. gitwise/share/schemas/v1/input/show.json +46 -0
  96. gitwise/share/schemas/v1/input/snapshot.json +36 -0
  97. gitwise/share/schemas/v1/input/stash.json +68 -0
  98. gitwise/share/schemas/v1/input/status.json +36 -0
  99. gitwise/share/schemas/v1/input/suggest.json +36 -0
  100. gitwise/share/schemas/v1/input/summarize.json +44 -0
  101. gitwise/share/schemas/v1/input/sync.json +55 -0
  102. gitwise/share/schemas/v1/input/tag.json +73 -0
  103. gitwise/share/schemas/v1/input/undo.json +60 -0
  104. gitwise/share/schemas/v1/input/update.json +40 -0
  105. gitwise/share/schemas/v1/input/worktree.json +50 -0
  106. gitwise/show.py +118 -0
  107. gitwise/snapshot.py +110 -0
  108. gitwise/stash.py +188 -0
  109. gitwise/status.py +93 -0
  110. gitwise/suggest.py +148 -0
  111. gitwise/summarize.py +202 -0
  112. gitwise/sync.py +257 -0
  113. gitwise/tag.py +252 -0
  114. gitwise/undo.py +145 -0
  115. gitwise/update.py +42 -0
  116. gitwise/utils/__init__.py +1 -0
  117. gitwise/utils/git_output.py +51 -0
  118. gitwise/utils/json_envelope.py +58 -0
  119. gitwise/utils/parsing.py +34 -0
  120. gitwise/worktree.py +182 -0
  121. gitwise_cli-0.24.2.dist-info/METADATA +151 -0
  122. gitwise_cli-0.24.2.dist-info/RECORD +125 -0
  123. gitwise_cli-0.24.2.dist-info/WHEEL +4 -0
  124. gitwise_cli-0.24.2.dist-info/entry_points.txt +2 -0
  125. gitwise_cli-0.24.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,141 @@
1
+ """State detection for setup-agents: path classification, symlink support, GPG readiness."""
2
+
3
+ import os
4
+ import platform
5
+ import re
6
+ from pathlib import Path
7
+
8
+ from gitwise.git import config as git_config
9
+ from gitwise.i18n import t
10
+ from gitwise.setup_agents.types import PathState, StateDict
11
+
12
+ _AGENTS_MD = "AGENTS.md"
13
+ _CLAUDE_MD = "CLAUDE.md"
14
+ _MARKER_RE = re.compile(
15
+ r"^##\s+(Convenciones git para este proyecto|Git conventions for this project)\b",
16
+ re.MULTILINE,
17
+ )
18
+
19
+ _supports_symlinks_cache: dict[Path, bool] = {}
20
+
21
+
22
+ def _gpg_ready(root: Path) -> bool:
23
+ import shutil
24
+
25
+ if not (shutil.which("gpg") or shutil.which("gpg2")):
26
+ return False
27
+ return git_config("commit.gpgsign", cwd=root) == "true" and bool(
28
+ git_config("user.signingkey", cwd=root)
29
+ )
30
+
31
+
32
+ def _classify_path(p: Path) -> PathState:
33
+ if p.is_symlink():
34
+ return "symlink_valid" if p.exists() else "symlink_broken"
35
+ if p.exists():
36
+ return "regular"
37
+ return "absent"
38
+
39
+
40
+ def _supports_symlinks(root: Path) -> bool:
41
+ if platform.system() == "Windows":
42
+ return False
43
+ if root in _supports_symlinks_cache:
44
+ return _supports_symlinks_cache[root]
45
+ try:
46
+ import tempfile
47
+
48
+ with tempfile.TemporaryDirectory(dir=root) as td:
49
+ link = Path(td) / "_test_link"
50
+ link.symlink_to("_nonexistent")
51
+ link.unlink()
52
+ _supports_symlinks_cache[root] = True
53
+ except (OSError, NotImplementedError):
54
+ _supports_symlinks_cache[root] = False
55
+ return _supports_symlinks_cache[root]
56
+
57
+
58
+ def _has_marker(p: Path) -> bool:
59
+ try:
60
+ text = p.read_text(encoding="utf-8")
61
+ return bool(_MARKER_RE.search(text))
62
+ except OSError:
63
+ return False
64
+
65
+
66
+ def _files_equal(a: Path, b: Path) -> bool:
67
+ try:
68
+ return a.read_text(encoding="utf-8") == b.read_text(encoding="utf-8")
69
+ except OSError:
70
+ return False
71
+
72
+
73
+ def _detect_rules(root: Path) -> list[str]:
74
+ """Validates .claude/rules/*.md for required globs: frontmatter field."""
75
+ rules_dir = root / ".claude" / "rules"
76
+ warnings: list[str] = []
77
+ if not rules_dir.is_dir():
78
+ return warnings
79
+ root_real = Path(os.path.realpath(str(root)))
80
+ for f in sorted(rules_dir.glob("*.md")):
81
+ f_real = Path(os.path.realpath(str(f)))
82
+ if not f_real.is_relative_to(root_real):
83
+ warnings.append(t("symlink_outside_repo", name=f.name))
84
+ continue
85
+ try:
86
+ if f.stat().st_size > 64_000:
87
+ warnings.append(t("file_too_large", name=f.name))
88
+ continue
89
+ except OSError:
90
+ continue
91
+ try:
92
+ text = f.read_text(encoding="utf-8-sig")
93
+ except OSError:
94
+ continue
95
+ has_frontmatter = text.startswith("---\n")
96
+ fm_end = text.find("\n---\n", 4) if has_frontmatter else -1
97
+ has_globs = "globs:" in text[4:fm_end] if fm_end > 0 else False
98
+ if not (has_frontmatter and has_globs):
99
+ warnings.append(t("missing_globs_frontmatter", name=f.name))
100
+ return warnings
101
+
102
+
103
+ def reset_caches() -> None:
104
+ _supports_symlinks_cache.clear()
105
+
106
+
107
+ def _detect_state(root: Path) -> StateDict:
108
+ agents_md = root / _AGENTS_MD
109
+ claude_md = root / _CLAUDE_MD
110
+ agents_dir = root / ".agents"
111
+ skills_dir = root / ".claude" / "skills"
112
+
113
+ a_state = _classify_path(agents_md)
114
+ c_state = _classify_path(claude_md)
115
+ errors: list[str] = []
116
+
117
+ if a_state == "symlink_broken":
118
+ errors.append(t("symlink_conflict_broken", file=_AGENTS_MD))
119
+ if c_state == "symlink_broken":
120
+ errors.append(t("symlink_conflict_broken", file=_CLAUDE_MD))
121
+
122
+ skills_state = _classify_path(skills_dir)
123
+ skills_target: str | None = None
124
+ if skills_state == "symlink_valid":
125
+ try:
126
+ skills_target = os.readlink(skills_dir)
127
+ except OSError as e:
128
+ errors.append(t("symlink_read_failed", file=".claude/skills", error=str(e)))
129
+ elif skills_state == "symlink_broken":
130
+ errors.append(t("symlink_conflict_broken", file=".claude/skills"))
131
+
132
+ return {
133
+ "a_state": a_state,
134
+ "c_state": c_state,
135
+ "agents_dir": agents_dir.is_dir() and not agents_dir.is_symlink(),
136
+ "skills_state": skills_state,
137
+ "skills_target": skills_target,
138
+ "supports_symlinks": _supports_symlinks(root),
139
+ "errors": errors,
140
+ "rules_warnings": _detect_rules(root),
141
+ }
@@ -0,0 +1,48 @@
1
+ """Typed structures for the setup-agents pipeline (actions, state, plan results)."""
2
+
3
+ from typing import Any, Literal, TypedDict
4
+
5
+ ActionDict = dict[str, Any]
6
+
7
+
8
+ PathState = Literal["absent", "regular", "symlink_valid", "symlink_broken"]
9
+
10
+
11
+ class StateDict(TypedDict):
12
+ a_state: PathState
13
+ c_state: PathState
14
+ agents_dir: bool
15
+ skills_state: PathState
16
+ skills_target: str | None
17
+ supports_symlinks: bool
18
+ errors: list[str]
19
+ rules_warnings: list[str]
20
+
21
+
22
+ class ActionSummary(TypedDict):
23
+ created: int
24
+ appended: int
25
+ symlinked: int
26
+ skipped: int
27
+ errored: int
28
+
29
+
30
+ def build_action_summary(actions: list[ActionDict]) -> ActionSummary:
31
+ summary: ActionSummary = {
32
+ "created": 0,
33
+ "appended": 0,
34
+ "symlinked": 0,
35
+ "skipped": 0,
36
+ "errored": 0,
37
+ }
38
+ for a in actions:
39
+ match a.get("action"):
40
+ case "create" | "managed-block-create" | "adapter-create":
41
+ summary["created"] += 1
42
+ case "append" | "merge":
43
+ summary["appended"] += 1
44
+ case "symlink-create":
45
+ summary["symlinked"] += 1
46
+ case "skip" | "symlink-skip" | "managed-block-skip":
47
+ summary["skipped"] += 1
48
+ return summary
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: git-audit
3
+ description: Diagnostica el repositorio git (ramas stale, commit-graph, fsmonitor, blobs grandes, stashes viejos) y reporta hallazgos priorizados con fixes recomendados. Usa cuando el usuario pida auditar, revisar salud o diagnosticar el repo.
4
+ argument-hint: "[--quick]"
5
+ allowed-tools: Bash(gitwise audit*)
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # git-audit
10
+
11
+ ## Contexto
12
+
13
+ Resultado de `gitwise audit --json`:
14
+
15
+ !`gitwise audit --json`
16
+
17
+ ## Tarea
18
+
19
+ Eres un asistente experto en git. Analiza el JSON anterior y produce un reporte breve y accionable:
20
+
21
+ 1. **Resumen ejecutivo** (1 línea): estado general del repo.
22
+ 2. **Hallazgos priorizados**: lista cada `finding` ordenado por `severity` (critical > high > medium > low > info). Para cada uno indica: `message`, `fix` sugerido, `cost_of_ignore`.
23
+ 3. **Acción recomendada**: el comando exacto a ejecutar primero (típicamente el `fix` del finding más severo). NO lo ejecutes — solo recomiéndalo.
24
+
25
+ Si `findings` está vacío, responde "Repo en buen estado" y termina. No inventes hallazgos no presentes en el JSON.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: git-clean
3
+ description: Lista en dry-run las ramas locales cuyo upstream fue eliminado ([gone]) y reporta cuáles son seguras de borrar. Usa cuando el usuario pida limpiar ramas stale, huérfanas o merged.
4
+ argument-hint: "(sin argumentos)"
5
+ allowed-tools: Bash(gitwise clean --branches --dry-run --json)
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # git-clean
10
+
11
+ ## Contexto
12
+
13
+ Resultado de `gitwise clean --branches --dry-run --json`:
14
+
15
+ !`gitwise clean --branches --dry-run --json`
16
+
17
+ ## Tarea
18
+
19
+ 1. Reporta el conteo y nombres de ramas en `deletable` y `skipped` (con su `reason`).
20
+ 2. Si `deletable` está vacío, responde "No hay ramas stale eliminables" y termina.
21
+ 3. Si hay ramas eliminables, sugiere al usuario el comando para borrarlas tras revisión: `gitwise clean --branches --yes`.
22
+ 4. NUNCA ejecutes el borrado tú mismo. La versión `--yes` NO está en `allowed-tools` por diseño — requiere confirmación humana explícita.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: git-optimize
3
+ description: Muestra qué optimizaciones aplicaría gitwise (commit-graph, repack -A -d, prune) en modo dry-run. Usa cuando el usuario pida optimizar git, acelerar log/status, o cuando audit reporte commit-graph ausente.
4
+ argument-hint: "(sin argumentos)"
5
+ allowed-tools: Bash(gitwise optimize --dry-run --json)
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # git-optimize
10
+
11
+ ## Contexto
12
+
13
+ Plan de optimización (dry-run):
14
+
15
+ !`gitwise optimize --dry-run --json`
16
+
17
+ ## Tarea
18
+
19
+ 1. Lista los `steps` que se ejecutarían (`name`, `desc`).
20
+ 2. Estima impacto: commit-graph acelera `git log` 2-10x; repack reduce tamaño y crea bitmap-index; prune libera objetos no referenciados.
21
+ 3. Recomienda al usuario ejecutar `gitwise optimize --yes` para aplicarlas. NO ejecutes la versión `--yes` tú mismo: `disable-model-invocation: true` + `allowed-tools` restrictivo lo previenen por diseño.
@@ -0,0 +1,8 @@
1
+ ## Git conventions
2
+
3
+ - Diff: `gitwise diff` (= `git diff --name-status HEAD`). Never raw `git diff`.
4
+ - Log: `git --no-pager log --oneline -n 20`. Never without a limit.
5
+ - Commits: conventional format `feat/fix/refactor/docs/chore: description`.
6
+ - Commits: always GPG-signed. Never `--no-gpg-sign`.
7
+ - Branch switch: `gitwise worktree new <branch>`. Never `git stash + checkout`.
8
+ - Before large commits: `gitwise audit --quick`.
@@ -0,0 +1,4 @@
1
+ # .aider.conf.yml — generated by gitwise setup-agents
2
+ read:
3
+ - AGENTS.md
4
+ - CONVENTIONS.md
@@ -0,0 +1,9 @@
1
+ ## Git conventions for this project
2
+
3
+ - Diff: `git diff --stat` or `gitwise summarize`. Never raw `git diff`.
4
+ - Log: `git --no-pager log --oneline -n 20`. Never without a limit.
5
+ - Commits: conventional format `feat/fix/refactor/docs/chore: description`.
6
+ - Commits: always GPG-signed. Never `--no-gpg-sign`.
7
+ - Branch switch: `gitwise worktree new <branch>`. Never `git stash + checkout`.
8
+ - Changed files: `gitwise diff` (= `git diff --name-status HEAD`). Never raw `git diff`.
9
+ - Before large commits: `gitwise audit --quick`.
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: gitwise
3
+ description: Use gitwise CLI for git operations — gitwise diff, summarize, worktree
4
+ globs: "**/*"
5
+ ---
6
+
7
+ ## Use gitwise commands in tool calls
8
+
9
+ - Changed files: `gitwise diff` — never raw `git diff`
10
+ - Status + log: `gitwise summarize` — never raw `git status` or `git log`
11
+ - Branch switch: `gitwise worktree new <branch>` — never `git stash + checkout`
12
+ - Snapshot: `gitwise snapshot` — regenerates `.claude/git-snapshot.md`
13
+
14
+ ## Shell note
15
+
16
+ `gw` is a terminal alias only — use `gitwise` or `python -m gitwise` in Bash tool calls.
@@ -0,0 +1,47 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(gitwise *)",
5
+ "Bash(python -m gitwise *)",
6
+ "Bash(git status*)",
7
+ "Bash(git --no-pager log*)",
8
+ "Bash(git --no-pager diff --stat*)",
9
+ "Bash(git --no-pager diff --name-status*)",
10
+ "Bash(git --no-pager diff --shortstat*)",
11
+ "Bash(git diff --staged*)",
12
+ "Bash(git show*)",
13
+ "Bash(git blame*)",
14
+ "Bash(git for-each-ref*)",
15
+ "Bash(git rev-parse*)",
16
+ "Bash(git ls-files*)",
17
+ "Bash(git branch*)",
18
+ "Bash(git worktree*)",
19
+ "Bash(git add*)",
20
+ "Bash(git commit -S*)",
21
+ "Bash(git commit -m*)"
22
+ ],
23
+ "ask": [
24
+ "Bash(git push*)",
25
+ "Bash(git rebase*)",
26
+ "Bash(git reset*)",
27
+ "Bash(git commit --amend*)"
28
+ ],
29
+ "deny": [
30
+ "Bash(git push --force*)",
31
+ "Bash(git filter-branch*)",
32
+ "Bash(git clean -fdx*)",
33
+ "Bash(git commit --no-gpg-sign*)",
34
+ "Bash(git commit --no-verify*)",
35
+ "Bash(git commit --allow-empty*)",
36
+ "Bash(git -c commit.gpgsign=false*)",
37
+ "Bash(git -c gpg.format=*)",
38
+ "Bash(git -c core.hooksPath*)",
39
+ "Read(./.env*)",
40
+ "Read(./secrets/**)",
41
+ "Read(**/*.key)",
42
+ "Read(**/*.pem)",
43
+ "Read(**/*.p12)",
44
+ "Read(**/*.pfx)"
45
+ ]
46
+ }
47
+ }
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: git-audit
3
+ description: Diagnostica el repositorio git (ramas stale, commit-graph, fsmonitor, blobs grandes, stashes viejos) y reporta hallazgos priorizados con fixes recomendados. Usa cuando el usuario pida auditar, revisar salud o diagnosticar el repo.
4
+ argument-hint: "[--quick]"
5
+ allowed-tools: Bash(gitwise audit*)
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # git-audit
10
+
11
+ ## Contexto
12
+
13
+ Resultado de `gitwise audit --json`:
14
+
15
+ !`gitwise audit --json`
16
+
17
+ ## Tarea
18
+
19
+ Eres un asistente experto en git. Analiza el JSON anterior y produce un reporte breve y accionable:
20
+
21
+ 1. **Resumen ejecutivo** (1 línea): estado general del repo.
22
+ 2. **Hallazgos priorizados**: lista cada `finding` ordenado por `severity` (critical > high > medium > low > info). Para cada uno indica: `message`, `fix` sugerido, `cost_of_ignore`.
23
+ 3. **Acción recomendada**: el comando exacto a ejecutar primero (típicamente el `fix` del finding más severo). NO lo ejecutes — solo recomiéndalo.
24
+
25
+ Si `findings` está vacío, responde "Repo en buen estado" y termina. No inventes hallazgos no presentes en el JSON.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: git-clean
3
+ description: Lista en dry-run las ramas locales cuyo upstream fue eliminado ([gone]) y reporta cuáles son seguras de borrar. Usa cuando el usuario pida limpiar ramas stale, huérfanas o merged.
4
+ argument-hint: "(sin argumentos)"
5
+ allowed-tools: Bash(gitwise clean --branches --dry-run --json)
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # git-clean
10
+
11
+ ## Contexto
12
+
13
+ Resultado de `gitwise clean --branches --dry-run --json`:
14
+
15
+ !`gitwise clean --branches --dry-run --json`
16
+
17
+ ## Tarea
18
+
19
+ 1. Reporta el conteo y nombres de ramas en `deletable` y `skipped` (con su `reason`).
20
+ 2. Si `deletable` está vacío, responde "No hay ramas stale eliminables" y termina.
21
+ 3. Si hay ramas eliminables, sugiere al usuario el comando para borrarlas tras revisión: `gitwise clean --branches --yes`.
22
+ 4. NUNCA ejecutes el borrado tú mismo. La versión `--yes` NO está en `allowed-tools` por diseño — requiere confirmación humana explícita.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: git-optimize
3
+ description: Muestra qué optimizaciones aplicaría gitwise (commit-graph, repack -A -d, prune) en modo dry-run. Usa cuando el usuario pida optimizar git, acelerar log/status, o cuando audit reporte commit-graph ausente.
4
+ argument-hint: "(sin argumentos)"
5
+ allowed-tools: Bash(gitwise optimize --dry-run --json)
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # git-optimize
10
+
11
+ ## Contexto
12
+
13
+ Plan de optimización (dry-run):
14
+
15
+ !`gitwise optimize --dry-run --json`
16
+
17
+ ## Tarea
18
+
19
+ 1. Lista los `steps` que se ejecutarían (`name`, `desc`).
20
+ 2. Estima impacto: commit-graph acelera `git log` 2-10x; repack reduce tamaño y crea bitmap-index; prune libera objetos no referenciados.
21
+ 3. Recomienda al usuario ejecutar `gitwise optimize --yes` para aplicarlas. NO ejecutes la versión `--yes` tú mismo: `disable-model-invocation: true` + `allowed-tools` restrictivo lo previenen por diseño.
@@ -0,0 +1,18 @@
1
+ name = "gitwise"
2
+ description = "Git workflow conventions — use gitwise CLI for git operations"
3
+ model = "inherit"
4
+ model_reasoning_effort = "inherit"
5
+ sandbox_mode = "inherit"
6
+
7
+ developer_instructions = """
8
+ ## Use gitwise commands in tool calls
9
+
10
+ - Changed files: `gitwise diff` — never raw `git diff`
11
+ - Status + log: `gitwise summarize` — never raw `git status` or `git log`
12
+ - Branch switch: `gitwise worktree new <branch>` — never `git stash + checkout`
13
+ - Snapshot: `gitwise snapshot` — regenerates `.claude/git-snapshot.md`
14
+
15
+ ## Shell note
16
+
17
+ `gw` is a terminal alias only — use `gitwise` or `python -m gitwise` in Bash tool calls.
18
+ """
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: gitwise
3
+ description: Use gitwise CLI for git operations — gitwise diff, summarize, worktree
4
+ ---
5
+
6
+ ## Use gitwise commands in tool calls
7
+
8
+ - Changed files: `gitwise diff` — never raw `git diff`
9
+ - Status + log: `gitwise summarize` — never raw `git status` or `git log`
10
+ - Branch switch: `gitwise worktree new <branch>` — never `git stash + checkout`
11
+ - Snapshot: `gitwise snapshot` — regenerates `.claude/git-snapshot.md`
12
+ - Audit: `gitwise audit --quick` — before large commits
13
+ - Clean: `gitwise clean --branches` — remove stale branches
14
+ - Optimize: `gitwise optimize` — gc, pack-refs, commit-graph
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Use gitwise CLI for git operations — gitwise diff, summarize, worktree
3
+ globs:
4
+ - "**/*"
5
+ alwaysApply: true
6
+ ---
7
+
8
+ ## Use gitwise commands in tool calls
9
+
10
+ - Changed files: `gitwise diff` — never raw `git diff`
11
+ - Status + log: `gitwise summarize` — never raw `git status` or `git log`
12
+ - Branch switch: `gitwise worktree new <branch>` — never `git stash + checkout`
13
+ - Snapshot: `gitwise snapshot` — regenerates `.claude/git-snapshot.md`
14
+ - Audit: `gitwise audit --quick` — before large commits
15
+ - Clean: `gitwise clean --branches` — remove stale branches
16
+ - Optimize: `gitwise optimize` — gc, pack-refs, commit-graph
@@ -0,0 +1,48 @@
1
+ # Subset of GitButler "How Core Git Devs Configure Git" (Chacon, feb 2025)
2
+ # Applied by: gitwise setup
3
+ # Reference: https://blog.gitbutler.com/how-git-core-devs-configure-git/
4
+
5
+ [core]
6
+ # macOS/Windows only — gitwise setup detects platform before applying
7
+ # fsmonitor = true
8
+ untrackedCache = true
9
+ preloadindex = true
10
+
11
+ [fetch]
12
+ prune = true
13
+ prunetags = true
14
+ all = true
15
+
16
+ [merge]
17
+ conflictstyle = zdiff3
18
+
19
+ [diff]
20
+ algorithm = histogram
21
+ colorMoved = default
22
+
23
+ [rerere]
24
+ enabled = true
25
+ autoupdate = true
26
+
27
+ [branch]
28
+ sort = -committerdate
29
+
30
+ [tag]
31
+ sort = -version:refname
32
+
33
+ [push]
34
+ default = current
35
+ autoSetupRemote = true
36
+
37
+ [commit]
38
+ verbose = true
39
+
40
+ [maintenance]
41
+ auto = false
42
+ strategy = incremental
43
+
44
+ # Excluded (matter of taste per GitButler):
45
+ # pull.rebase = true
46
+
47
+ # Gated on git >= 2.40:
48
+ # feature.manyFiles = true
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ # gitwise commit-msg hook: verifies conventional commit format
3
+ # Installed by: gitwise setup (legacy core.hooksPath or native Git config hooks)
4
+ set -euo pipefail
5
+
6
+ # Skip format check for git-generated merge/revert/squash/cherry-pick commits
7
+ GIT_DIR="$(git rev-parse --git-dir 2>/dev/null || true)"
8
+ [ -f "${GIT_DIR}/MERGE_HEAD" ] && exit 0
9
+ [ -f "${GIT_DIR}/REBASE_HEAD" ] && exit 0
10
+ [ -f "${GIT_DIR}/CHERRY_PICK_HEAD" ] && exit 0
11
+ [ -f "${GIT_DIR}/SQUASH_MSG" ] && exit 0
12
+
13
+ MSG="$(cat "$1")"
14
+ PATTERN="^(feat|fix|refactor|docs|chore|test|style|perf|ci|build|revert)(\(.+\))?: .{1,72}"
15
+
16
+ if ! printf '%s\n' "$MSG" | grep -qE "$PATTERN"; then
17
+ printf 'gitwise: el mensaje no sigue el formato de conventional commits\n' >&2
18
+ printf ' Esperado: feat: desc | fix(scope): desc | docs: corrección\n' >&2
19
+ printf ' Ejemplos: docs: corrige typo en README | fix: maneja nil en parse\n' >&2
20
+ printf ' Recibido: %s\n' "$MSG" >&2
21
+ exit 1
22
+ fi
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ # gitwise pre-commit hook: verifies GPG signing configuration
3
+ # Installed by: gitwise setup (legacy core.hooksPath or native Git config hooks)
4
+ set -euo pipefail
5
+
6
+ gpgsign_val=$(git config --get commit.gpgsign 2>/dev/null || true)
7
+ if [ "$gpgsign_val" = "true" ]; then
8
+ if ! git config --get user.signingkey > /dev/null 2>&1; then
9
+ printf 'gitwise: GPG signing activo pero sin user.signingkey configurado\n' >&2
10
+ printf ' Ejecuta: git config user.signingkey <tu-key-id>\n' >&2
11
+ exit 1
12
+ fi
13
+ signing_key="$(git config user.signingkey)"
14
+ if ! gpg --list-secret-keys "$signing_key" > /dev/null 2>&1; then
15
+ printf 'gitwise: GPG key no encontrada en el keyring: %s\n' "$signing_key" >&2
16
+ printf ' Verifica con: gpg --list-secret-keys\n' >&2
17
+ exit 1
18
+ fi
19
+ fi
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: gitwise
3
+ description: Use gitwise CLI for git operations — gitwise diff, summarize, worktree
4
+ ---
5
+
6
+ ## Use gitwise commands in tool calls
7
+
8
+ - Changed files: `gitwise diff` — never raw `git diff`
9
+ - Status + log: `gitwise summarize` — never raw `git status` or `git log`
10
+ - Branch switch: `gitwise worktree new <branch>` — never `git stash + checkout`
11
+ - Snapshot: `gitwise snapshot` — regenerates `.claude/git-snapshot.md`
12
+ - Audit: `gitwise audit --quick` — before large commits
13
+ - Clean: `gitwise clean --branches` — remove stale branches
14
+ - Optimize: `gitwise optimize` — gc, pack-refs, commit-graph
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: gitwise
3
+ description: Use gitwise CLI for git operations — gitwise diff, summarize, worktree
4
+ ---
5
+
6
+ ## Use gitwise commands in tool calls
7
+
8
+ - Changed files: `gitwise diff` — never raw `git diff`
9
+ - Status + log: `gitwise summarize` — never raw `git status` or `git log`
10
+ - Branch switch: `gitwise worktree new <branch>` — never `git stash + checkout`
11
+ - Snapshot: `gitwise snapshot` — regenerates `.claude/git-snapshot.md`
12
+ - Audit: `gitwise audit --quick` — before large commits
13
+ - Clean: `gitwise clean --branches` — remove stale branches
14
+ - Optimize: `gitwise optimize` — gc, pack-refs, commit-graph
@@ -0,0 +1,40 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://gitwise.dev/schemas/v1/input/audit.json",
4
+ "title": "gitwise audit cli input",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "lang": {
9
+ "type": "string",
10
+ "enum": [
11
+ "es",
12
+ "en"
13
+ ],
14
+ "description": "output language (default: auto-detect from locale)"
15
+ },
16
+ "theme": {
17
+ "type": "string",
18
+ "enum": [
19
+ "dark",
20
+ "light",
21
+ "auto"
22
+ ],
23
+ "description": "color theme: dark, light, or auto-detect (default: auto)"
24
+ },
25
+ "json": {
26
+ "type": "boolean",
27
+ "description": "output JSON",
28
+ "default": false
29
+ },
30
+ "json_pretty": {
31
+ "type": "boolean",
32
+ "description": "pretty-print JSON output",
33
+ "default": false
34
+ },
35
+ "quick": {
36
+ "type": "boolean",
37
+ "default": false
38
+ }
39
+ }
40
+ }