@reddb-io/red-skills-dev 2.75.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +30 -0
- package/package.json +32 -0
- package/skills/engineering/README.md +36 -0
- package/skills/engineering/_report-runtime/WRAPPER.md +47 -0
- package/skills/engineering/afk/AGENT-PROMPT.md +295 -0
- package/skills/engineering/afk/SAFETY.md +103 -0
- package/skills/engineering/afk/SKILL.md +160 -0
- package/skills/engineering/afk/TROUBLESHOOTING.md +260 -0
- package/skills/engineering/afk/actions-lane.md +213 -0
- package/skills/engineering/afk/bin/README.md +29 -0
- package/skills/engineering/afk/bin/afk.mjs +51 -0
- package/skills/engineering/afk/defaults/cargo-pre-worktree.sh +37 -0
- package/skills/engineering/afk/defaults/envelope-post-attempt.sh +47 -0
- package/skills/engineering/afk/defaults/gradle-pre-worktree.sh +42 -0
- package/skills/engineering/afk/defaults/heartbeat-post-attempt.sh +43 -0
- package/skills/engineering/afk/defaults/validation-post-merge.sh +77 -0
- package/skills/engineering/afk/detectors/README.md +72 -0
- package/skills/engineering/afk/detectors/cargo.sh +27 -0
- package/skills/engineering/afk/detectors/gradle.sh +35 -0
- package/skills/engineering/afk/docs/BOOT-SWEEPS.md +81 -0
- package/skills/engineering/afk/docs/CONFIG.md +238 -0
- package/skills/engineering/afk/docs/ENVELOPE.md +177 -0
- package/skills/engineering/afk/docs/HANDOFF.md +70 -0
- package/skills/engineering/afk/docs/LIVENESS.md +56 -0
- package/skills/engineering/afk/docs/OPERATIONS.md +409 -0
- package/skills/engineering/afk/examples/only-mine.sh +32 -0
- package/skills/engineering/afk/examples/red-afk-attempt-action.yml +53 -0
- package/skills/engineering/afk/examples/rs-afk-attempt.yml +76 -0
- package/skills/engineering/afk/fleet.md +127 -0
- package/skills/engineering/afk/hooks/red-cargo +44 -0
- package/skills/engineering/afk/hooks/red-envelope +50 -0
- package/skills/engineering/afk/hooks/red-gradle +50 -0
- package/skills/engineering/afk/hooks/red-heartbeat +46 -0
- package/skills/engineering/afk/hooks/red-validation +79 -0
- package/skills/engineering/afk/monitor.md +170 -0
- package/skills/engineering/afk/runner-claude-minimax.md +71 -0
- package/skills/engineering/afk/runner-claude.md +67 -0
- package/skills/engineering/afk/runner-codex.md +138 -0
- package/skills/engineering/afk/runner-hermes.md +40 -0
- package/skills/engineering/afk/runner-opencode.md +142 -0
- package/skills/engineering/ask-red/SKILL.md +137 -0
- package/skills/engineering/audit-skills/SKILL.md +46 -0
- package/skills/engineering/code-review/SKILL.md +106 -0
- package/skills/engineering/context/SKILL.md +142 -0
- package/skills/engineering/curate/SKILL.md +133 -0
- package/skills/engineering/daily-review/SKILL.md +68 -0
- package/skills/engineering/dashboard/SKILL.md +44 -0
- package/skills/engineering/diagnose/SKILL.md +155 -0
- package/skills/engineering/diagnose/scripts/hitl-loop.template.sh +41 -0
- package/skills/engineering/go/SKILL.md +144 -0
- package/skills/engineering/go/TROUBLESHOOTING.md +81 -0
- package/skills/engineering/ground-truth/SKILL.md +84 -0
- package/skills/engineering/hitl/SKILL.md +171 -0
- package/skills/engineering/hitl/TROUBLESHOOTING.md +76 -0
- package/skills/engineering/implement/SKILL.md +69 -0
- package/skills/engineering/improve-codebase-architecture/DEEPENING.md +37 -0
- package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -0
- package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +53 -0
- package/skills/engineering/improve-codebase-architecture/SKILL.md +81 -0
- package/skills/engineering/model-tier-policy/SKILL.md +83 -0
- package/skills/engineering/prototype/LOGIC.md +79 -0
- package/skills/engineering/prototype/SKILL.md +30 -0
- package/skills/engineering/prototype/UI.md +112 -0
- package/skills/engineering/red-doctor/APPLY.md +35 -0
- package/skills/engineering/red-doctor/SKILL.md +172 -0
- package/skills/engineering/red-gains/SKILL.md +49 -0
- package/skills/engineering/red-setup/INTERVIEW.md +266 -0
- package/skills/engineering/red-setup/ISSUE-SWEEP.md +18 -0
- package/skills/engineering/red-setup/REFERENCE.md +35 -0
- package/skills/engineering/red-setup/SKILL.md +58 -0
- package/skills/engineering/red-setup/WORKFLOWS.md +74 -0
- package/skills/engineering/red-setup/WRITE-CONTRACT.md +151 -0
- package/skills/engineering/red-setup/config-template.yaml +174 -0
- package/skills/engineering/red-setup/domain.md +52 -0
- package/skills/engineering/red-setup/issue-tracker-github.md +88 -0
- package/skills/engineering/red-setup/rsp-retirement-runbook.md +35 -0
- package/skills/engineering/red-setup/scripts/install-runtime-shim.sh +189 -0
- package/skills/engineering/red-setup/triage-labels.md +176 -0
- package/skills/engineering/red-setup/workflows/red-issues-needs-triage.yml +36 -0
- package/skills/engineering/red-statusline/HOST-NOTES.md +180 -0
- package/skills/engineering/red-statusline/SKILL.md +58 -0
- package/skills/engineering/report-bug/SKILL.md +155 -0
- package/skills/engineering/resolving-merge-conflicts/SKILL.md +143 -0
- package/skills/engineering/retake/SKILL.md +184 -0
- package/skills/engineering/review-adrs/SKILL.md +125 -0
- package/skills/engineering/start/ADR-FORMAT.md +47 -0
- package/skills/engineering/start/CONTEXT-FORMAT.md +77 -0
- package/skills/engineering/start/DOC-LANDING-FINALIZER.md +9 -0
- package/skills/engineering/start/SKILL.md +179 -0
- package/skills/engineering/tdd/SKILL.md +96 -0
- package/skills/engineering/tdd/deep-modules.md +33 -0
- package/skills/engineering/tdd/interface-design.md +31 -0
- package/skills/engineering/tdd/mocking.md +59 -0
- package/skills/engineering/tdd/tests.md +85 -0
- package/skills/engineering/to-spec/SKILL.md +104 -0
- package/skills/engineering/to-tickets/SKILL.md +158 -0
- package/skills/engineering/triage/AGENT-BRIEF.md +207 -0
- package/skills/engineering/triage/OUT-OF-SCOPE.md +101 -0
- package/skills/engineering/triage/SKILL.md +176 -0
- package/skills/engineering/verify/SKILL.md +136 -0
- package/skills/engineering/wayfinder/SKILL.md +128 -0
- package/skills/engineering/zoom-out/SKILL.md +51 -0
- package/skills/engineering/zoom-out/scripts/graph-mode-plumbing.sh +36 -0
- package/skills/engineering/zoom-out/scripts/tests/contract.test.sh +168 -0
- package/skills/knowledge/README.md +5 -0
- package/skills/knowledge/research/SKILL.md +76 -0
- package/skills/misc/README.md +8 -0
- package/skills/misc/branch-lock/SKILL.md +187 -0
- package/skills/misc/branch-lock/scripts/branch-lock-hook.sh +113 -0
- package/skills/misc/branch-lock/scripts/branch-lock-session-start.sh +81 -0
- package/skills/misc/branch-lock/scripts/branch-lock.sh +68 -0
- package/skills/misc/branch-lock/scripts/lib/dev-config.sh +126 -0
- package/skills/misc/branch-lock/scripts/lib/git-command-classifier.sh +198 -0
- package/skills/misc/branch-lock/scripts/lib/lock-store.sh +67 -0
- package/skills/misc/branch-lock/scripts/lib/scope-resolver.sh +43 -0
- package/skills/misc/branch-lock/scripts/tests/branch-lock-cli.test.sh +114 -0
- package/skills/misc/branch-lock/scripts/tests/claude-plugin-hook.test.sh +117 -0
- package/skills/misc/branch-lock/scripts/tests/codex-hook.test.sh +229 -0
- package/skills/misc/branch-lock/scripts/tests/dev-config.test.sh +99 -0
- package/skills/misc/branch-lock/scripts/tests/git-command-classifier.test.sh +187 -0
- package/skills/misc/branch-lock/scripts/tests/lock-store.test.sh +90 -0
- package/skills/misc/branch-lock/scripts/tests/scope-resolver.test.sh +63 -0
- package/skills/misc/branch-lock/scripts/tests/session-start.test.sh +123 -0
- package/skills/misc/git-guardrails-claude-code/SKILL.md +105 -0
- package/skills/misc/git-guardrails-claude-code/scripts/block-dangerous-git.sh +231 -0
- package/skills/misc/git-guardrails-claude-code/scripts/tests/block-dangerous-git.test.sh +143 -0
- package/skills/misc/migrate-to-shoehorn/SKILL.md +96 -0
- package/skills/misc/setup-pre-commit/SKILL.md +94 -0
- package/skills/productivity/README.md +8 -0
- package/skills/productivity/ff/SKILL.md +116 -0
- package/skills/productivity/handoff/SKILL.md +37 -0
- package/skills/productivity/reflect/SKILL.md +18 -0
- package/skills/productivity/write-a-skill/SKILL.md +190 -0
- package/skills/productivity/write-a-skill/WRITING-STYLE.md +62 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Host Notes
|
|
2
|
+
|
|
3
|
+
Reference material for the host branches in `SKILL.md`. Read only the section for
|
|
4
|
+
the branch you are wiring; these notes preserve the recipes, line-shape rules,
|
|
5
|
+
and rationale outside the hot path.
|
|
6
|
+
|
|
7
|
+
## Shared Architecture And Line Shapes
|
|
8
|
+
|
|
9
|
+
Install or inspect the RedSkills statusline for this repository. The shared producer renders the project name, branch, model/context data when the host provides it, repo counters, and live AFK state. **The two hosts get two shapes (per-runner split, ADR 0003):**
|
|
10
|
+
|
|
11
|
+
- **Claude Code — multi-line.** Claude Code's `statusLine` renders multiple rows, so the themed producer emits a repo-global **header line** — always shown, even with no live workers: project (branch) + version, model·effort + context, open PRs + open issues, local diff vs `origin/main`, and (Pro/Max only, when the payload exposes them) the 5-hour and weekly usage windows `5h=…% 7d=…%` — **then one line per live AFK worker**. The worker line is a **terse, colored `k=v` form** that reads as a visual sibling of the header — every token follows the header's `key=value` colour convention:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
w82UX run=claude opus high iss=1173 tests 00:04:41 loc=+10 -11 tks=34k tls=11 rsn=13 txt=0
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Every `k=v` key on this line is **exactly 3 letters** (house rule). The `wID` is **bold + red**; then `run=<runner> <model> <effort>` (model shortened, e.g. `claude-opus-4-8` → `opus`; the effort word is omitted when unavailable), `iss=<issue-number>` (the bare ISSUE NUMBER from the worker's `current.number`, populated for BOTH `/afk` and `/go` lanes — not a `done/total` counter), the bare `<phase>` word (no `phase:` prefix, no standalone `#<n>` token), the required `HH:MM:SS` elapsed, `loc=+A -R`, `tks=<humanized>` (SI k/M/B token total), and the vitals as INDIVIDUAL 3-letter `k=v` pairs `tls=<t> rsn=<r> txt=<x>` (never a nested `stats=…:…` blob). The `/afk monitor` dashboard uses the same vitals vocabulary (`tls`/`rsn`/`txt`) while keeping its fuller row shape. The truncated issue TITLE, the live `activity`, the `[live]`/`[quiet]` badge, `wait`, and `log` are **dropped** here — that verbosity stays on the fuller `/afk monitor` line. The two surfaces share only the per-worker FIELD DATA (`workerFields`), never a renderer, so the terse statusline form never bleeds into the monitor. Zero live workers → only the header line.
|
|
18
|
+
|
|
19
|
+
The **`/afk monitor` dashboard keeps its fuller per-worker row** (title, `[live]`/`[quiet]`, `wait`, `log`) — it is a full dashboard, not a compact statusline — but its vitals tokens are the same `tls`/`rsn`/`txt` vocabulary as the statusline.
|
|
20
|
+
|
|
21
|
+
For an on-demand decode table, run `red-skills-dev statusline --legend` or `red-skills-dev monitor --legend`. The legend prints `token / name / gloss` rows and exits without rendering the live statusline or monitor surface.
|
|
22
|
+
- **Codex — single line.** The `tui.status_line` footer is single-line only, so the plain producer stays ONE aggregate line (project · model · context · usage · repo counts · the AFK block). The multi-line layout is Claude-Code-only.
|
|
23
|
+
|
|
24
|
+
The AFK rows are quiet when no worker is active. Hosts that cannot run a command-backed statusline still get a useful native footer plus `/afk monitor` for live AFK visibility.
|
|
25
|
+
|
|
26
|
+
**Host capabilities differ; the product architecture should not.** Treat the RedSkills statusline as:
|
|
27
|
+
|
|
28
|
+
1. A shared producer: the dev bundle's `statusline` subcommand.
|
|
29
|
+
2. Host adapters: Claude Code's command-backed `statusLine`; Codex's global `tui.status_line` list and plugin `SessionStart` hook.
|
|
30
|
+
3. Fallback visibility: `/afk monitor`, which works when a host has no command-backed footer.
|
|
31
|
+
|
|
32
|
+
This mirrors how Codex itself organizes customization: skills define reusable workflows, plugins distribute skills plus hooks/MCP/apps, `config.toml` stores host settings, and hooks attach lifecycle behavior next to the active plugin/config layer. Keep RedSkills logic in the bundle and keep host-specific wiring in the host sections below.
|
|
33
|
+
|
|
34
|
+
## Claude Code Adapter Recipe
|
|
35
|
+
|
|
36
|
+
1. Inspect the repo: `.red/config.yaml`, `.claude/settings.json`, and whether `jq` is available.
|
|
37
|
+
|
|
38
|
+
2. **Early exit — opt-out:** if `.red/config.yaml` has top-level `statusline: false` or nested `afk.statusline: false`, stop and tell the user it is disabled. Do not proceed.
|
|
39
|
+
|
|
40
|
+
3. **Early exit — already configured:** if `.claude/settings.json` already has `statusLine`, do not overwrite it unless the user explicitly asked to replace it (then replace only `statusLine`, preserving all other keys).
|
|
41
|
+
|
|
42
|
+
4. Write the RedSkills statusline:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"statusLine": {
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "sh -c 'N=$(command -v node 2>/dev/null || ls -1 /usr/local/bin/node /opt/homebrew/bin/node /usr/bin/node \"$HOME\"/.volta/bin/node \"$HOME\"/.asdf/shims/node \"$HOME\"/.nodenv/shims/node \"$HOME\"/.nvm/versions/node/*/bin/node \"$HOME\"/.local/share/fnm/node-versions/*/installation/bin/node \"$HOME\"/.fnm/node-versions/*/installation/bin/node 2>/dev/null | sort -V | tail -1); b=$(ls -1 \"$HOME\"/.cache/red-skills/bundles/dev-*.bundle.min.mjs 2>/dev/null | sort -V | tail -1); [ -z \"$b\" ] && b=$(ls -1 \"$HOME\"/.claude/plugins/cache/red-skills/dev/*/skills/engineering/afk/bin/afk.mjs 2>/dev/null | sort -V | tail -1); [ -n \"$b\" ] && [ -n \"$N\" ] && exec \"$N\" \"$b\" statusline'",
|
|
49
|
+
"refreshInterval": 60
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Why this shape (cached-bundle-first, not `$CLAUDE_PLUGIN_ROOT`, not `afk.mjs` directly):** the command above is cached-bundle-first by design (ADR 0084) — never alter it to fetch synchronously in the render path.
|
|
55
|
+
|
|
56
|
+
Use a 60s refresh interval because the producer reads cached state: 5s ticks burn CPU and repeat calls without new information at that cadence, while 60s matches the real rate of change of fleet/PR state.
|
|
57
|
+
|
|
58
|
+
Use `jq` to merge when `.claude/settings.json` already exists; create `.claude/`
|
|
59
|
+
and a fresh file when it is missing. Keep unrelated settings intact.
|
|
60
|
+
|
|
61
|
+
5. Verify: confirm `.claude/settings.json` is valid JSON and has `.statusLine.command`. Unlike the old `$CLAUDE_PLUGIN_ROOT` form, you **can** prove this one renders by piping a minimal session JSON into the **same `sh -c '…'` command from step 4** (no need to re-type it):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
printf '{"workspace":{"project_dir":"%s"},"model":{"display_name":"Opus"}}' "$PWD" \
|
|
65
|
+
| <the step-4 statusLine command>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
It should print the themed **header line** (e.g. `» red-skills (main) v… Opus·high …`); when AFK workers are live it prints one additional row per worker below it. Under `NO_COLOR` the same command collapses to the single-line plain form `red-skills (main) · Opus·high · …`.
|
|
69
|
+
|
|
70
|
+
## Claude Code Rationale
|
|
71
|
+
|
|
72
|
+
**Why this shape, not `$CLAUDE_PLUGIN_ROOT`.** Claude Code does **not** export
|
|
73
|
+
`CLAUDE_PLUGIN_ROOT` (nor `CLAUDE_PROJECT_DIR`) to a `statusLine` command — those
|
|
74
|
+
are only set for plugin hooks and MCP/LSP subprocesses. A statusLine that
|
|
75
|
+
references `$CLAUDE_PLUGIN_ROOT` expands it to an empty string and fails with
|
|
76
|
+
`Cannot find module` — the statusline then silently renders blank.
|
|
77
|
+
|
|
78
|
+
**Why resolve `node` explicitly, not bare `exec node`.** Claude Code runs the
|
|
79
|
+
`statusLine` command in a **non-interactive shell** that does not source the
|
|
80
|
+
user's `~/.bashrc`/`~/.zshrc`, so a Node installed through a **version manager**
|
|
81
|
+
(nvm, fnm, volta, asdf, nodenv, …) is not on `PATH` — a bare `exec node …` then
|
|
82
|
+
fails with `node: not found` (exit 127) and the statusline silently renders
|
|
83
|
+
blank. The command resolves the interpreter itself, manager-agnostic:
|
|
84
|
+
**`command -v node` first** — which already covers every host with Node on `PATH`
|
|
85
|
+
(system package, Homebrew, or no version manager at all) — and only when that
|
|
86
|
+
misses does it scan the common install roots (nvm, fnm, volta, asdf, nodenv,
|
|
87
|
+
Homebrew, `/usr/local`, `/usr`), newest wins. So the line renders regardless of
|
|
88
|
+
how Node was installed or how the host shell was launched.
|
|
89
|
+
|
|
90
|
+
**Why the cached bundle, not `afk.mjs` directly.** Since ADR 0038, the installed
|
|
91
|
+
`afk.mjs` is a tiny **launcher that fetches** the real runtime bundle from the
|
|
92
|
+
GitHub release on first use (caching it at
|
|
93
|
+
`~/.cache/red-skills/bundles/dev-<version>.bundle.min.mjs`). Pointing the
|
|
94
|
+
statusLine straight at the launcher means **every plugin update** lands a new
|
|
95
|
+
version whose bundle is not cached yet, so the launcher tries a **synchronous
|
|
96
|
+
network download inside the statusline render** — which blows the render's tight
|
|
97
|
+
timeout (blank statusline), or fails outright if that version's release asset is
|
|
98
|
+
not published yet. The command instead runs the **highest-version
|
|
99
|
+
already-fetched bundle** (`ls -1 …/.cache/red-skills/bundles/dev-*.bundle.min.mjs | sort -V | tail -1`
|
|
100
|
+
— `sort -V` picks the highest semver, NOT `ls -t` which picks newest-by-mtime and
|
|
101
|
+
can resolve an OLD version when an older dir was touched/re-extracted more recently) —
|
|
102
|
+
no network in the hot path, so an update never blanks the line; it keeps showing
|
|
103
|
+
the last good bundle until a normal `afk` run (or a SessionStart pre-fetch)
|
|
104
|
+
caches the new one. It falls back to the launcher only when the cache is empty
|
|
105
|
+
(first-ever install), to bootstrap. The project root is **not** passed as an
|
|
106
|
+
argument: the AFK `statusline` subcommand reads it from `workspace.project_dir`
|
|
107
|
+
in the JSON Claude Code pipes on stdin, which the `sh -c` wrapper forwards
|
|
108
|
+
intact.
|
|
109
|
+
|
|
110
|
+
This respects ADR 0084: the documented command stays cached-bundle-first and
|
|
111
|
+
never fetches synchronously in a render path.
|
|
112
|
+
|
|
113
|
+
## Codex Adapter Recipe
|
|
114
|
+
|
|
115
|
+
Codex configures its footer through the `tui.status_line` key in `config.toml`
|
|
116
|
+
— an ordered list of **built-in** item identifiers (`project`, `git-branch`,
|
|
117
|
+
`model-with-reasoning`, `context-remaining`, `task-progress`, `current-dir`,
|
|
118
|
+
…). When unset, Codex currently uses `["model-with-reasoning",
|
|
119
|
+
"context-remaining", "current-dir"]`; set it to `[]` to hide the footer.
|
|
120
|
+
This skill offers the **global** `~/.codex/config.toml` path because the footer
|
|
121
|
+
is a personal host preference, not repo state. There is no command hook, so the
|
|
122
|
+
shared RedSkills `statusline` producer cannot be injected into the footer yet.
|
|
123
|
+
|
|
124
|
+
Codex has a native `/statusline` command for picking and reordering these
|
|
125
|
+
footer items and persisting them to `config.toml`. The dev bundle also exposes
|
|
126
|
+
an explicit inspector/fixer:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
red-skills-dev codex-statusline
|
|
130
|
+
red-skills-dev codex-statusline --fix
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The inspector reports the active `tui.status_line`, flags a missing
|
|
134
|
+
`task-progress` widget, prints the recommended order, and reminds the operator
|
|
135
|
+
that rich AFK worker state still lives in `/afk monitor`. `--fix` is explicit:
|
|
136
|
+
it appends `task-progress` to an existing visible footer or installs the
|
|
137
|
+
recommended footer when `status_line` is absent. If the user already has a
|
|
138
|
+
custom `tui.status_line`, preserve it unless they explicitly ask for `--fix`;
|
|
139
|
+
that custom value is the operator's host preference, not repo state.
|
|
140
|
+
|
|
141
|
+
Offer to set a useful footer (note: this is **global** Codex config, not
|
|
142
|
+
per-repo like the Claude path):
|
|
143
|
+
|
|
144
|
+
```toml
|
|
145
|
+
[tui]
|
|
146
|
+
status_line = ["project", "git-branch", "model-with-reasoning", "context-remaining", "task-progress"]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Surviving Codex config resets.** A global `tui.status_line` gets dropped when Codex rewrites `~/.codex/config.toml`, but the dev plugin's Codex `SessionStart` hook re-asserts it so a reset self-heals on the next session start — why and how (the additive, atomic, absent-only re-write) is described below.
|
|
150
|
+
|
|
151
|
+
This is intentionally host-global and plugin-gated. Codex stores footer
|
|
152
|
+
preferences in `~/.codex/config.toml`, while RedSkills gates global hook side
|
|
153
|
+
effects on the repo's `.red/config.yaml` `plugins.dev.enabled: true` flag. That
|
|
154
|
+
keeps the installed plugin available everywhere but inert outside opted-in
|
|
155
|
+
repos, matching the rest of the RedSkills hook model.
|
|
156
|
+
|
|
157
|
+
For live AFK visibility under Codex, `/afk monitor` remains the canonical
|
|
158
|
+
dashboard. Normal `/afk run` launches and `/afk fleet` launches also try to
|
|
159
|
+
attach one read-only Codex monitor agent when the host exposes a sub-agent
|
|
160
|
+
primitive; the prompt comes from `afk codex-monitor-agent --mode run|fleet`.
|
|
161
|
+
When the primitive is unavailable, Codex falls back to the monitor dashboard.
|
|
162
|
+
When Codex ships a command-backed statusline (openai/codex#17827 / #20244), this
|
|
163
|
+
skill can add a `{ type = "command", command = … }` entry pointing at the same
|
|
164
|
+
AFK bundle so the line matches Claude Code's.
|
|
165
|
+
|
|
166
|
+
## Codex Rationale
|
|
167
|
+
|
|
168
|
+
That global `tui.status_line` gets dropped whenever Codex rewrites
|
|
169
|
+
`~/.codex/config.toml` (e.g. re-syncing plugin `[hooks.state]` on update),
|
|
170
|
+
blanking the footer "every update". The dev plugin's Codex `SessionStart` hook
|
|
171
|
+
re-asserts it: `hooks/ensure-codex-statusline.mjs` inserts `status_line` **only
|
|
172
|
+
when absent** (never clobbers an operator's own value) via an **atomic** write
|
|
173
|
+
(temp + rename — a race with Codex's writer can lose the update but never corrupt
|
|
174
|
+
the file). So a reset self-heals on the next session start. The hook is additive
|
|
175
|
+
and idempotent; disable it by removing the second `SessionStart` entry in
|
|
176
|
+
`hooks/codex.hooks.json`.
|
|
177
|
+
|
|
178
|
+
## OpenCode Adapter
|
|
179
|
+
|
|
180
|
+
Nothing to install: OpenCode is an AFK API-auth runner lane (`--runner opencode`), not an interactive host UI, so it has no footer/statusline adapter — observe it through `/afk monitor`, `/afk dashboard`, and Actions output like any other runner.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: red-statusline
|
|
3
|
+
description: Install or inspect the RedSkills statusline for the active host. RedSkills has one shared `statusline` producer in the dev bundle; Claude Code wires it through `.claude/settings.json` as a command-backed statusLine, while Codex configures the built-in `tui.status_line` footer and the dev plugin's SessionStart self-heal hook. Preserves existing config unless replacement is explicitly requested.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Statusline
|
|
8
|
+
|
|
9
|
+
**Wire the RedSkills statusline surface for the current host — stop as soon as a gate condition is met.** Keep the host branch hot here; read [HOST-NOTES.md](HOST-NOTES.md) only for the exact adapter recipe, shared line shape, or rationale needed by the selected host.
|
|
10
|
+
|
|
11
|
+
<what-to-do>
|
|
12
|
+
|
|
13
|
+
## 1. Identify The Host
|
|
14
|
+
|
|
15
|
+
**Pick one branch.** Use Claude Code when `.claude/` or Claude plugin state is the active surface, Codex when the active client is Codex CLI, and OpenCode only when the user asks about the OpenCode runner lane.
|
|
16
|
+
|
|
17
|
+
**Respect explicit intent.** Install only when the user asks to install, fix, replace, or configure. Otherwise inspect and report the current state.
|
|
18
|
+
|
|
19
|
+
## 2. Claude Code
|
|
20
|
+
|
|
21
|
+
1. Inspect `.red/config.yaml`, `.claude/settings.json`, and whether `jq` is available.
|
|
22
|
+
2. **Opt-out gate** — if `.red/config.yaml` has top-level `statusline: false` or nested `afk.statusline: false`, stop and tell the user it is disabled.
|
|
23
|
+
3. **Existing-config gate** — if `.claude/settings.json` already has `statusLine`, preserve it unless the user explicitly asked to replace it. Replacement touches only `statusLine`; keep every other key.
|
|
24
|
+
4. **Apply the adapter recipe** — read [HOST-NOTES.md](HOST-NOTES.md#claude-code-adapter-recipe), then write or merge the cached-bundle-first `statusLine` block exactly as documented there.
|
|
25
|
+
5. **Verify the write** — confirm `.claude/settings.json` is valid JSON, contains `.statusLine.command`, and renders by piping minimal session JSON into the same command from the recipe.
|
|
26
|
+
|
|
27
|
+
## 3. Codex
|
|
28
|
+
|
|
29
|
+
1. Inspect the active `~/.codex/config.toml` footer preference with `red-skills-dev codex-statusline`.
|
|
30
|
+
2. **Preserve host preference** — if `tui.status_line` is already custom, leave it alone unless the user explicitly asks to fix or replace it.
|
|
31
|
+
3. **Apply the adapter recipe only on request** — read [HOST-NOTES.md](HOST-NOTES.md#codex-adapter-recipe), then run the explicit fixer or write the recommended global footer. Treat this as host-global config, not repo state.
|
|
32
|
+
4. **Report AFK visibility honestly** — Codex gets native footer widgets plus `/afk monitor`; it cannot inject the shared command-backed producer into the footer yet.
|
|
33
|
+
|
|
34
|
+
## 4. OpenCode
|
|
35
|
+
|
|
36
|
+
**Install nothing.** OpenCode is a runner lane, not an interactive host UI with a footer adapter. Point the user to `/afk monitor`, `/afk dashboard`, and Actions output. The full note is in [HOST-NOTES.md](HOST-NOTES.md#opencode-adapter).
|
|
37
|
+
|
|
38
|
+
## 5. Finish
|
|
39
|
+
|
|
40
|
+
Tell the user which host branch you used, what changed or why nothing changed, and how to observe live AFK state.
|
|
41
|
+
|
|
42
|
+
</what-to-do>
|
|
43
|
+
|
|
44
|
+
<supporting-info>
|
|
45
|
+
|
|
46
|
+
## Reference Map
|
|
47
|
+
|
|
48
|
+
- **Shared architecture and line shapes:** [HOST-NOTES.md](HOST-NOTES.md#shared-architecture-and-line-shapes).
|
|
49
|
+
- **Claude Code command-backed adapter:** [HOST-NOTES.md](HOST-NOTES.md#claude-code-adapter-recipe).
|
|
50
|
+
- **Codex native footer adapter:** [HOST-NOTES.md](HOST-NOTES.md#codex-adapter-recipe).
|
|
51
|
+
- **OpenCode no-install note:** [HOST-NOTES.md](HOST-NOTES.md#opencode-adapter).
|
|
52
|
+
|
|
53
|
+
## Invocation Notes
|
|
54
|
+
|
|
55
|
+
- Invoke as `/red-statusline` (Claude Code) or `$red-statusline` (Codex). Wire the host you are running under; do not imply the statusline feature belongs to only one client.
|
|
56
|
+
- `/red-setup` may offer the Claude Code command-backed adapter during project bootstrap. Under Codex, use this skill to inspect or configure the native footer path.
|
|
57
|
+
|
|
58
|
+
</supporting-info>
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: report-bug
|
|
3
|
+
description: Interview the user about a bug they hit, then file a structured `type:bug needs-triage` issue on the project tracker. Pulls seed material from the conversation context when invoked with no arguments, or from the argument when one is provided. Use when the user says "report a bug", "open a bug", "this is broken — file it", "/report-bug ...", or otherwise wants a bug captured on the tracker without going through full triage themselves.
|
|
4
|
+
argument-hint: "[symptom — leave empty to seed from conversation]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<what-to-do>
|
|
8
|
+
|
|
9
|
+
**You file, /triage routes. Never pre-label or guess priority.**
|
|
10
|
+
|
|
11
|
+
Conduct a short, focused interview that fills in every field of the issue template in `<supporting-info>`, then open the issue on the project tracker.
|
|
12
|
+
|
|
13
|
+
**Boot behavior (turn 1):**
|
|
14
|
+
|
|
15
|
+
The argument is optional.
|
|
16
|
+
|
|
17
|
+
- **Argument present** → treat it as the seed for "What's happening". Emit a single-line receipt confirming the seed (`Seed: <first 80 chars>…`), then jump to the next missing field.
|
|
18
|
+
- **Argument empty** → silently mine the current conversation context for: what the user was doing, error messages, file paths, stack traces, recent commands, anything that smells like the symptom of the bug. Emit a one-line receipt (`Seeded from conversation: <one-sentence summary>.`) and start the interview with whichever field is still least clear.
|
|
19
|
+
- **No useful context AND no argument** → open with `Q01: What's the bug? Describe what you observed.`
|
|
20
|
+
|
|
21
|
+
**The loop:**
|
|
22
|
+
|
|
23
|
+
1. Pick the next unresolved field from the template in `<supporting-info>`.
|
|
24
|
+
2. Ask **one** question using the format below. Include a recommended answer or `[branches]` whenever the field has a finite shape (severity, repro type), otherwise ask open-ended.
|
|
25
|
+
3. Wait for the user's reply. Do not stack questions.
|
|
26
|
+
4. When their answer changes the picture (e.g. severity escalates from "low" to "blocker" because they mention prod), re-evaluate before asking the next question.
|
|
27
|
+
5. Once every field is filled, summarise the issue as it will be filed (title + body), ask `Q##: Open this issue on the tracker? (y/n / edit)`. On `y` or `yes`, proceed. On `edit`, ask which field to revise. On `n`, abort cleanly.
|
|
28
|
+
|
|
29
|
+
**Filing:**
|
|
30
|
+
|
|
31
|
+
1. Build the issue title per **Title rules** in `<supporting-info>` (lowercase, ≤72 chars, imperative/noun phrase derived from "What's happening").
|
|
32
|
+
2. Render the body using the exact template in `<supporting-info>`. Leave no `[…]` placeholders.
|
|
33
|
+
3. `gh issue create --title "<title>" --body "<body>" --label type:bug --label needs-triage`. Pass body via heredoc/tempfile, not inline, to preserve newlines.
|
|
34
|
+
4. Read the URL from the gh output and present it to the user with one of: open URL, run `/triage`, or stop.
|
|
35
|
+
|
|
36
|
+
**Hard rules:**
|
|
37
|
+
|
|
38
|
+
- ❌ Do **not** invent reproduction steps, error text, or file paths. If the user can't supply them, write `no clean repro yet` and `unknown` rather than fabricating.
|
|
39
|
+
- ❌ Do **not** apply any label beyond `type:bug` + `needs-triage` — see **Labels** in `<supporting-info>`; `/triage` owns priority, slice tagging, and agent-readiness.
|
|
40
|
+
- ❌ Do **not** close the issue, comment after creation, or run any AFK action. This skill ends with the URL.
|
|
41
|
+
- ❌ Do **not** open more than one issue per invocation. If the user describes two unrelated bugs, suggest running `/report-bug` again for the second.
|
|
42
|
+
- ✅ **Do** number every question `Q##:` (zero-padded, session-scoped, same convention as `/start`).
|
|
43
|
+
- ✅ **Do** use `gh` (not the GitHub web UI) — the user invoked a CLI skill, they want the issue handle in the terminal.
|
|
44
|
+
- ✅ **Do** sanitise the body before filing: strip ANSI escapes, mask anything that looks like a secret (API keys, tokens) — when in doubt, ask the user to confirm.
|
|
45
|
+
- ✅ **Do** route the user to `/triage` after creating the issue — see **After creation** in `<supporting-info>` for the exact receipt. The reporter's job ends at "captured".
|
|
46
|
+
|
|
47
|
+
**Question format template:**
|
|
48
|
+
|
|
49
|
+
> **Q##:** [the question]
|
|
50
|
+
> **Branches:** _(omit when the field is open-ended free text)_
|
|
51
|
+
> (a) [answer option A]
|
|
52
|
+
> (b) [answer option B]
|
|
53
|
+
> [if more options, add more branches]
|
|
54
|
+
> **Recommend:** (a), because [one-sentence reason].
|
|
55
|
+
> *(answer, redirect, or push back — I'll wait)*
|
|
56
|
+
|
|
57
|
+
</what-to-do>
|
|
58
|
+
|
|
59
|
+
<supporting-info>
|
|
60
|
+
|
|
61
|
+
## Issue body template
|
|
62
|
+
|
|
63
|
+
````markdown
|
|
64
|
+
## What's happening
|
|
65
|
+
|
|
66
|
+
<one to three sentences describing the observed behaviour, verbatim from the user where possible>
|
|
67
|
+
|
|
68
|
+
## What should happen instead
|
|
69
|
+
|
|
70
|
+
<one or two sentences describing the expected behaviour>
|
|
71
|
+
|
|
72
|
+
## Reproduction
|
|
73
|
+
|
|
74
|
+
<numbered steps, or `no clean repro yet — observed in <context>`>
|
|
75
|
+
|
|
76
|
+
## Context
|
|
77
|
+
|
|
78
|
+
- **when:** <date/time the user noticed, ISO format if known>
|
|
79
|
+
- **where:** <file path, route, URL, component name>
|
|
80
|
+
- **what i was doing:** <one sentence>
|
|
81
|
+
- **environment:** <OS, runtime version, branch/commit if relevant; "n/a" otherwise>
|
|
82
|
+
|
|
83
|
+
## Severity
|
|
84
|
+
|
|
85
|
+
<one of: blocker | high | medium | low | unknown>
|
|
86
|
+
|
|
87
|
+
## Source
|
|
88
|
+
|
|
89
|
+
Filed via `/report-bug`. <"Seeded from inline argument." | "Seeded from conversation context." | "No prior context.">
|
|
90
|
+
````
|
|
91
|
+
|
|
92
|
+
Fields that the interview must fill, in order of priority:
|
|
93
|
+
|
|
94
|
+
1. **What's happening** — symptom, observed behaviour.
|
|
95
|
+
2. **What should happen instead** — expected behaviour. If user can't articulate, ask "what made you think this was a bug and not the design?"
|
|
96
|
+
3. **Reproduction** — numbered steps if the user can produce them; otherwise the rough conditions (`no clean repro yet — observed when X`).
|
|
97
|
+
4. **Context** — `when`, `where`, `what i was doing`, `environment`. Pull from conversation if mined; ask only for what's missing.
|
|
98
|
+
5. **Severity** — branches: blocker / high / medium / low / unknown.
|
|
99
|
+
6. **Source** — auto-filled from boot mode.
|
|
100
|
+
|
|
101
|
+
## Severity branches
|
|
102
|
+
|
|
103
|
+
Use these when asking `Q##: Severity?`:
|
|
104
|
+
|
|
105
|
+
- **blocker** — production is down or data is at risk now.
|
|
106
|
+
- **high** — a core flow is broken; workaround is awkward or partial.
|
|
107
|
+
- **medium** — broken in a non-core path or has a clean workaround.
|
|
108
|
+
- **low** — cosmetic, minor, or rare edge.
|
|
109
|
+
- **unknown** — pick this freely; `/triage` will assign properly.
|
|
110
|
+
|
|
111
|
+
## Title rules
|
|
112
|
+
|
|
113
|
+
- Lowercase, ≤72 chars.
|
|
114
|
+
- Imperative or noun phrase: `monitor crashes on empty history.jsonl`, `wiki ingest mangles assets folder`, `afk loses claim when worker_id collides`.
|
|
115
|
+
- Avoid prefixes like `Bug:`, `[BUG]`, `Issue:` — the `type:bug` label already conveys this.
|
|
116
|
+
- Avoid clickbait — `WTF`, `???`, `please fix` waste tokens for the next reader.
|
|
117
|
+
|
|
118
|
+
## Labels
|
|
119
|
+
|
|
120
|
+
Apply exactly two on creation:
|
|
121
|
+
|
|
122
|
+
- `type:bug`
|
|
123
|
+
- `needs-triage`
|
|
124
|
+
|
|
125
|
+
The `/triage` skill is responsible for adding the rest (`priority:*`, `prd:*`, eventually `ready-for-agent`). Pre-emptively labelling here breaks that contract.
|
|
126
|
+
|
|
127
|
+
If `type:bug` or `needs-triage` don't exist in the repo (fresh checkout), stop and tell the user to run `/red-setup` first — same precondition as `/triage`.
|
|
128
|
+
|
|
129
|
+
## Conversation-mining heuristic
|
|
130
|
+
|
|
131
|
+
When invoked with no argument, scan the conversation transcript (most recent ~50 turns) for:
|
|
132
|
+
|
|
133
|
+
- Error messages, stack traces, non-zero exit codes.
|
|
134
|
+
- File paths the user just opened or edited.
|
|
135
|
+
- Recently failing test names.
|
|
136
|
+
- Commands the user ran that produced unexpected output.
|
|
137
|
+
- Explicit phrases: "this is weird", "shouldn't this …", "why is it doing …", "I expected … but got …".
|
|
138
|
+
|
|
139
|
+
Pick the strongest signal as the seed for "What's happening" and surface what's still missing for the rest of the fields.
|
|
140
|
+
|
|
141
|
+
If nothing useful is in the transcript, say so in the receipt (`Seeded from conversation: no clear symptom found, starting open.`) and open with `Q01`.
|
|
142
|
+
|
|
143
|
+
## After creation
|
|
144
|
+
|
|
145
|
+
When the issue is filed, print exactly:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
✓ filed #<N>: <title>
|
|
149
|
+
<url>
|
|
150
|
+
next: /triage to assign priority and route to /afk.
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Then stop. Do not call `/triage` yourself unless the user explicitly asks.
|
|
154
|
+
|
|
155
|
+
</supporting-info>
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: resolving-merge-conflicts
|
|
3
|
+
description: Guided merge-conflict resolution loop. Inspect state → find each side's intent → resolve every hunk preserving both intents → run the project's checks. Never abort. Use when a merge, rebase, or cherry-pick leaves conflict markers in tracked files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Resolving Merge Conflicts
|
|
7
|
+
|
|
8
|
+
**Intent preservation is the only goal — not picking a winner.** Each side touched that line for a reason; your job is to honour both reasons in the resolved output.
|
|
9
|
+
|
|
10
|
+
<what-to-do>
|
|
11
|
+
|
|
12
|
+
### Step 1 — Inspect state
|
|
13
|
+
|
|
14
|
+
Before touching any file, understand what kind of operation produced the conflicts:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
git status # lists every file with conflict markers
|
|
18
|
+
git log --merge # shows the two commits being reconciled
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Identify the operation type — `MERGE_HEAD` means a merge, `REBASE_HEAD` means a rebase, `CHERRY_PICK_HEAD` means a cherry-pick. The semantics differ:
|
|
22
|
+
|
|
23
|
+
- **Merge**: two independent branches are being joined. Both sides' changes are equally valid.
|
|
24
|
+
- **Rebase**: commits are being replayed on top of a new base. The "ours" side is the base, the "theirs" side is the patch being applied.
|
|
25
|
+
- **Cherry-pick**: a single commit is being applied. "Theirs" is the patch; "ours" is the current state.
|
|
26
|
+
|
|
27
|
+
### Step 2 — Find each side's primary source and original intent
|
|
28
|
+
|
|
29
|
+
For each conflicted file, read the full diff for each branch **before** looking at the conflict markers. Use:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git diff ORIG_HEAD...HEAD -- <file> # what "ours" changed vs the merge base
|
|
33
|
+
git diff MERGE_HEAD...HEAD -- <file> # what "theirs" changed vs the merge base (merge)
|
|
34
|
+
git show REBASE_HEAD -- <file> # theirs during rebase
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For each conflict block, answer two questions before resolving it:
|
|
38
|
+
|
|
39
|
+
1. *Why did "ours" change this?* — find the commit message, PR, or issue that explains it.
|
|
40
|
+
2. *Why did "theirs" change this?* — same.
|
|
41
|
+
|
|
42
|
+
**Never resolve a hunk you cannot explain both sides of.** If the intent is unclear, read the surrounding commit history (`git log --oneline -10 -- <file>`) or the linked PR/issue rather than guessing.
|
|
43
|
+
|
|
44
|
+
### Step 3 — Resolve every hunk, preserving both intents
|
|
45
|
+
|
|
46
|
+
For each conflict block (`<<<<<<<` … `=======` … `>>>>>>>`):
|
|
47
|
+
|
|
48
|
+
1. **If both sides changed different things** (different lines, no semantic overlap): include both changes. Edit the block so both modifications appear in the output; order them to maintain the file's logical flow.
|
|
49
|
+
2. **If both sides changed the same lines** (semantic overlap): produce a version that achieves both intentions. Write the merged result explicitly — do not just pick one side.
|
|
50
|
+
3. **If one side deleted what the other modified**: include the modification, not the deletion, unless the deletion's intent makes the modification meaningless. Explain your reasoning in the commit message.
|
|
51
|
+
|
|
52
|
+
Hard rules:
|
|
53
|
+
|
|
54
|
+
- ❌ Do **not** run `git merge --abort`, `git rebase --abort`, or `git cherry-pick --abort`. Aborting discards work; resolve instead.
|
|
55
|
+
- ❌ Do **not** accept "ours" or "theirs" wholesale with `git checkout --ours` / `--theirs` without verifying the other side's intent is preserved.
|
|
56
|
+
- ❌ Do **not** leave conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) in any file when you are done.
|
|
57
|
+
- ✅ **Do** remove the markers and all three sections, replacing them with a single coherent resolution.
|
|
58
|
+
|
|
59
|
+
### Step 4 — Discover and run the project's automated checks
|
|
60
|
+
|
|
61
|
+
After resolving all hunks, find the project's test and lint commands. Look for them in this order:
|
|
62
|
+
|
|
63
|
+
1. `package.json` → `scripts` block (`test`, `lint`, `typecheck`, `build`)
|
|
64
|
+
2. `Makefile` → `make test`, `make lint`
|
|
65
|
+
3. `README.md` → "how to run tests" section
|
|
66
|
+
4. CI config (`.github/workflows/`, `.circleci/config.yml`, etc.) — the commands the pipeline runs
|
|
67
|
+
|
|
68
|
+
Run every check that covers the conflicted files. A resolution that breaks a test is not a resolution.
|
|
69
|
+
|
|
70
|
+
### Step 5 — Complete the operation
|
|
71
|
+
|
|
72
|
+
Once all conflicts are resolved and all checks pass:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
git add -- <each resolved file> # stage by name, never git add -A
|
|
76
|
+
git merge --continue # or git rebase --continue / git cherry-pick --continue
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Write a commit message that names both intents that were reconciled, e.g.:
|
|
80
|
+
|
|
81
|
+
> "Merge: preserve both the cache-invalidation fix (#42) and the retry-backoff refactor (#67)"
|
|
82
|
+
|
|
83
|
+
</what-to-do>
|
|
84
|
+
|
|
85
|
+
<supporting-info>
|
|
86
|
+
|
|
87
|
+
## Reading conflict markers
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
<<<<<<< HEAD (ours)
|
|
91
|
+
const timeout = 5000
|
|
92
|
+
=======
|
|
93
|
+
const timeout = retryConfig.timeoutMs
|
|
94
|
+
>>>>>>> feature/retry-backoff (theirs)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- `HEAD` / `ours` — the branch you were on when you ran `git merge`/`git cherry-pick`, or the new base during a rebase.
|
|
98
|
+
- `theirs` — the branch being merged in, the patch being applied, or the commit being replayed.
|
|
99
|
+
- The merge base (the common ancestor) is visible via `git merge-base HEAD MERGE_HEAD` and can be checked out to a temp file with `git show $(git merge-base HEAD MERGE_HEAD):<file>`.
|
|
100
|
+
|
|
101
|
+
## Diff3 style for three-way context
|
|
102
|
+
|
|
103
|
+
Enable extended conflict markers to see the merge-base version alongside both sides:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
git config merge.conflictstyle diff3
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
With `diff3`, conflict blocks show three sections:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
<<<<<<< HEAD
|
|
113
|
+
const timeout = 5000
|
|
114
|
+
||||||| merged common ancestors
|
|
115
|
+
const timeout = 3000
|
|
116
|
+
=======
|
|
117
|
+
const timeout = retryConfig.timeoutMs
|
|
118
|
+
>>>>>>> feature/retry-backoff
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The middle `|||||||` section is the merge base — it shows what the file looked like before either branch touched it. This makes each side's intent immediately clear.
|
|
122
|
+
|
|
123
|
+
## When a file is marked "both deleted" or "both added"
|
|
124
|
+
|
|
125
|
+
- **Both deleted**: the file is already gone on both sides. Stage with `git rm -- <file>` and move on.
|
|
126
|
+
- **Both added** (same path, different content): treat the whole file as one large conflict block. Follow Step 3 to produce a single merged file.
|
|
127
|
+
|
|
128
|
+
## When a binary file conflicts
|
|
129
|
+
|
|
130
|
+
Git cannot produce text conflict markers for binary files. Inspect the two versions:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
git show HEAD:<file> > /tmp/ours.<ext>
|
|
134
|
+
git show MERGE_HEAD:<file> > /tmp/theirs.<ext>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Choose the correct version or produce a new merged binary through the appropriate tool (image editor, compiled output, etc.), then stage the result.
|
|
138
|
+
|
|
139
|
+
## Handling renames
|
|
140
|
+
|
|
141
|
+
If one side renamed a file while the other modified it, Git may detect this as `both modified` on the **new** path. Confirm with `git status` and check that the resolved file lives at the correct path before staging.
|
|
142
|
+
|
|
143
|
+
</supporting-info>
|