codedeck 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/charts/stacked-bar.js +2 -1
- package/dist/cli/charts/stacked-bar.js.map +1 -1
- package/dist/cli/commands/open.js +137 -30
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/web.js +22 -1
- package/dist/cli/commands/web.js.map +1 -1
- package/dist/cli/usage/dashboard.js +12 -7
- package/dist/cli/usage/dashboard.js.map +1 -1
- package/dist/core/roles.js +28 -5
- package/dist/core/roles.js.map +1 -1
- package/dist/git/review.js +357 -0
- package/dist/git/review.js.map +1 -0
- package/dist/open/contract.js +6 -2
- package/dist/open/contract.js.map +1 -1
- package/dist/open/launchers/claude.js +8 -2
- package/dist/open/launchers/claude.js.map +1 -1
- package/dist/open/launchers/codex.js +236 -0
- package/dist/open/launchers/codex.js.map +1 -0
- package/dist/plugin/agents/auditor.md +13 -5
- package/dist/plugin/agents/general.md +355 -15
- package/dist/plugin/agents/orchestrator-edit.md +16 -5
- package/dist/plugin/agents/orchestrator-read.md +16 -5
- package/dist/plugin/agents/orchestrator.md +16 -5
- package/dist/plugin/agents/reviewer.md +6 -2
- package/dist/plugin/prompts/_partials/commit.md +145 -0
- package/dist/plugin/prompts/_partials/core.md +9 -0
- package/dist/plugin/prompts/_partials/dispatch.md +5 -0
- package/dist/plugin/prompts/_partials/pr-writer.md +186 -0
- package/dist/plugin/prompts/_partials/proof.md +2 -0
- package/dist/plugin/prompts/_partials/rename-run.md +1 -0
- package/dist/plugin/prompts/_partials/review-self.md +4 -0
- package/dist/plugin/prompts/_partials/worktree.md +2 -0
- package/dist/plugin/prompts/roles/auditor.md +35 -0
- package/dist/plugin/prompts/roles/general.md +29 -0
- package/dist/plugin/prompts/roles/orchestrator-edit.md +68 -0
- package/dist/plugin/prompts/roles/orchestrator-read.md +68 -0
- package/dist/plugin/prompts/roles/orchestrator.md +90 -0
- package/dist/plugin/prompts/roles/reviewer.md +37 -0
- package/dist/web/canvas-page.js +8 -5
- package/dist/web/canvas-page.js.map +1 -1
- package/dist/web/review-page.js +565 -0
- package/dist/web/review-page.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { detectBinary } from "../../drivers/helpers.js";
|
|
5
|
+
import { getRegistry } from "../../drivers/registry.js";
|
|
6
|
+
import { getCachedOrDiscoverModels } from "../../core/models.js";
|
|
7
|
+
import { parseEffort } from "../../core/driver.js";
|
|
8
|
+
import { DISPATCHER_PRESET } from "../../config/orchestrator-mode.js";
|
|
9
|
+
import { catalogWarning, judgeModelIn, resolveRoleContract, } from "../contract.js";
|
|
10
|
+
import { composeOrchestratorProse } from "../orchestrator-prose.js";
|
|
11
|
+
import { SESSION_ID_PATTERN } from "../runtime.js";
|
|
12
|
+
/**
|
|
13
|
+
* Codex has no system-prompt flag on its interactive TUI (no equivalent of
|
|
14
|
+
* Claude's --append-system-prompt-file), so the role contract travels as a
|
|
15
|
+
* `-c developer_instructions` override instead of the session's first prompt.
|
|
16
|
+
* Probed against codex-cli 0.154.0: the key lands as the opening `developer`
|
|
17
|
+
* message (visible via `codex debug prompt-input`), the TUI starts empty, and
|
|
18
|
+
* no turn is spent. `model_instructions_file` is deliberately avoided: it
|
|
19
|
+
* replaces the sanctioned model instructions instead of appending to them.
|
|
20
|
+
*/
|
|
21
|
+
export function initialPrompt(pluginDir, role, mode = DISPATCHER_PRESET) {
|
|
22
|
+
const { agentBody, ultra } = resolveRoleContract(pluginDir, role, mode);
|
|
23
|
+
const orchestratorProse = role === "orchestrator" ? composeOrchestratorProse(mode) : "";
|
|
24
|
+
const body = orchestratorProse ? `${agentBody}\n\n${orchestratorProse}` : agentBody;
|
|
25
|
+
return `${ultra.trimEnd()}\n\n${body}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* TOML-escape a contract for `-c developer_instructions="""..."""`. The value
|
|
29
|
+
* is parsed as TOML, so a raw `"` or `\` would break out of the string and
|
|
30
|
+
* inject a second config assignment. LF stays raw, which multiline basic
|
|
31
|
+
* strings allow; every other C0 control and DEL goes as `\uXXXX`, which has
|
|
32
|
+
* no raw form. No control literal appears in the source below: the branch is
|
|
33
|
+
* on the char code, so linters that flag control escapes stay quiet.
|
|
34
|
+
*/
|
|
35
|
+
export function developerInstructionsOverride(prompt) {
|
|
36
|
+
let escaped = "";
|
|
37
|
+
for (const c of prompt) {
|
|
38
|
+
const code = c.codePointAt(0) ?? 0;
|
|
39
|
+
if (c === "\\")
|
|
40
|
+
escaped += "\\\\";
|
|
41
|
+
else if (c === '"')
|
|
42
|
+
escaped += '\\"';
|
|
43
|
+
else if (c === "\n")
|
|
44
|
+
escaped += c;
|
|
45
|
+
else if (code < 0x20 || code === 0x7f) {
|
|
46
|
+
escaped += `\\u${code.toString(16).padStart(4, "0").toUpperCase()}`;
|
|
47
|
+
}
|
|
48
|
+
else
|
|
49
|
+
escaped += c;
|
|
50
|
+
}
|
|
51
|
+
return `developer_instructions="""${escaped}"""`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Approximate role permissions with the only knob codex offers: the sandbox.
|
|
55
|
+
* Codex cannot deny reads while allowing dispatch the way the opencode
|
|
56
|
+
* permission map can, so the read-only roles land on read-only and everything
|
|
57
|
+
* that dispatches work lands on workspace-write. With the default bypass this
|
|
58
|
+
* mapping is dormant; it only binds under --no-bypass.
|
|
59
|
+
*/
|
|
60
|
+
export function roleSandbox(role) {
|
|
61
|
+
switch (role) {
|
|
62
|
+
case "reviewer":
|
|
63
|
+
case "auditor":
|
|
64
|
+
return "read-only";
|
|
65
|
+
case "general":
|
|
66
|
+
case "orchestrator":
|
|
67
|
+
return "workspace-write";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Interactive codex argv. Mirrors the exec driver's flag spellings (measured
|
|
72
|
+
* against codex-cli 0.154.0): resume is a subcommand, a resumed thread keeps
|
|
73
|
+
* its policy and working root, and effort is a TOML config override.
|
|
74
|
+
*
|
|
75
|
+
* The role contract travels as `-c developer_instructions`, never as the
|
|
76
|
+
* positional [PROMPT]: the TUI starts empty and no turn is spent. Multiple
|
|
77
|
+
* `-c` flags coexist (effort + instructions), each kept adjacent to its
|
|
78
|
+
* value or codex reads the next flag as the value.
|
|
79
|
+
*
|
|
80
|
+
* No model default is pinned here: without an explicit model the flag is
|
|
81
|
+
* omitted and the codex config.toml answers.
|
|
82
|
+
*/
|
|
83
|
+
export function buildOpenArgs(role, flags, pluginDir, passthrough, openCwd, mode = DISPATCHER_PRESET) {
|
|
84
|
+
const isResume = flags.resume !== undefined;
|
|
85
|
+
const args = [];
|
|
86
|
+
if (isResume)
|
|
87
|
+
args.push("resume", flags.resume);
|
|
88
|
+
if (flags.model)
|
|
89
|
+
args.push("-m", flags.model);
|
|
90
|
+
if (!isResume)
|
|
91
|
+
args.push("-s", roleSandbox(role));
|
|
92
|
+
if (flags.bypass !== false)
|
|
93
|
+
args.push("--dangerously-bypass-approvals-and-sandbox");
|
|
94
|
+
// Validated, never interpolated raw: the value lands inside a TOML string
|
|
95
|
+
// and an unescaped quote would inject a second config assignment.
|
|
96
|
+
if (flags.effort)
|
|
97
|
+
args.push("-c", `model_reasoning_effort="${parseEffort(flags.effort)}"`);
|
|
98
|
+
// The resume slot takes an optional follow-up prompt, so a resumed thread
|
|
99
|
+
// never gets the role contract re-injected as a new message.
|
|
100
|
+
if (!isResume)
|
|
101
|
+
args.push("-c", developerInstructionsOverride(initialPrompt(pluginDir, role, mode)));
|
|
102
|
+
if (!isResume)
|
|
103
|
+
args.push("-C", openCwd);
|
|
104
|
+
args.push(...passthrough);
|
|
105
|
+
return args;
|
|
106
|
+
}
|
|
107
|
+
export const CODEX_NOT_FOUND = "Codex was not found on PATH. Install Codex and ensure `codex` is available.";
|
|
108
|
+
/**
|
|
109
|
+
* The codex half of the split: find this harness's catalog, judge it with
|
|
110
|
+
* the shared pure verdict. Kept while the suite pins this shape.
|
|
111
|
+
*/
|
|
112
|
+
export function judgeModel(model, catalogs, fromConfig) {
|
|
113
|
+
return judgeModelIn(catalogs?.find((item) => item.agent === "codex"), model, fromConfig, "Codex");
|
|
114
|
+
}
|
|
115
|
+
export async function preflight(model, fromConfig) {
|
|
116
|
+
let catalogs;
|
|
117
|
+
try {
|
|
118
|
+
catalogs = await getCachedOrDiscoverModels(getRegistry(), { agent: "codex" });
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
// A catalog that cannot be reached is not evidence against the model, so
|
|
122
|
+
// this warns and lets the launch decide.
|
|
123
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
124
|
+
console.warn(catalogWarning("Codex", model, `unavailable (${text})`));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const verdict = judgeModel(model, catalogs, fromConfig);
|
|
128
|
+
if (verdict.kind === "ok")
|
|
129
|
+
return;
|
|
130
|
+
if (verdict.kind === "unknown-catalog") {
|
|
131
|
+
console.warn(verdict.warning);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
throw new Error(verdict.error);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Returns the resolved path rather than a boolean so everything downstream
|
|
138
|
+
* launches the exact binary that was checked.
|
|
139
|
+
*/
|
|
140
|
+
export async function resolveBinary() {
|
|
141
|
+
const installation = await detectBinary("codex");
|
|
142
|
+
if (!installation.installed || !installation.path) {
|
|
143
|
+
throw new Error(CODEX_NOT_FOUND);
|
|
144
|
+
}
|
|
145
|
+
return installation.path;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Where the TUI persists rollout files, honouring CODEX_HOME like the harness
|
|
149
|
+
* does. Day directories use the local date, matching the filenames codex
|
|
150
|
+
* writes.
|
|
151
|
+
*/
|
|
152
|
+
export function codexSessionsDir(now = new Date(), home = os.homedir(), codexHome = process.env.CODEX_HOME) {
|
|
153
|
+
const base = codexHome && codexHome.length > 0 ? codexHome : path.join(home, ".codex");
|
|
154
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
155
|
+
return path.join(base, "sessions", String(now.getFullYear()), pad(now.getMonth() + 1), pad(now.getDate()));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Best-effort snapshot of the day's rollout files. A missing directory means
|
|
159
|
+
* no rollouts yet, not a failed capture; any other read failure stays
|
|
160
|
+
* undefined so the close path refuses the diff instead of guessing.
|
|
161
|
+
*/
|
|
162
|
+
export function readCodexRollouts(dir = codexSessionsDir()) {
|
|
163
|
+
try {
|
|
164
|
+
return fs
|
|
165
|
+
.readdirSync(dir)
|
|
166
|
+
.filter((file) => file.startsWith("rollout-") && file.endsWith(".jsonl"))
|
|
167
|
+
.sort();
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
try {
|
|
171
|
+
if (!fs.existsSync(dir))
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
catch { }
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Who a rollout file belongs to, read off its opening session_meta line.
|
|
180
|
+
* Anything unparseable means "cannot tell", and a missing hint beats a
|
|
181
|
+
* wrong one.
|
|
182
|
+
*/
|
|
183
|
+
export function rolloutIdentity(file) {
|
|
184
|
+
try {
|
|
185
|
+
const first = fs.readFileSync(file, "utf8").split("\n", 1)[0] ?? "";
|
|
186
|
+
const line = JSON.parse(first);
|
|
187
|
+
const id = line?.payload?.id;
|
|
188
|
+
if (typeof id !== "string" || !SESSION_ID_PATTERN.test(id))
|
|
189
|
+
return undefined;
|
|
190
|
+
const cwd = line?.payload?.cwd;
|
|
191
|
+
return { id, ...(typeof cwd === "string" && cwd ? { cwd } : {}) };
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* The thread id a rollout file belongs to. When the launching cwd is known
|
|
199
|
+
* it must match the rollout's own cwd: two concurrent launches in different
|
|
200
|
+
* directories must never record each other's session.
|
|
201
|
+
*/
|
|
202
|
+
export function threadIdFromRollout(file, expectedCwd) {
|
|
203
|
+
const identity = rolloutIdentity(file);
|
|
204
|
+
if (!identity)
|
|
205
|
+
return undefined;
|
|
206
|
+
if (expectedCwd !== undefined && identity.cwd !== expectedCwd)
|
|
207
|
+
return undefined;
|
|
208
|
+
return identity.id;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* The id of the session created between snapshots, or undefined. Zero or
|
|
212
|
+
* ambiguous new files mean "cannot tell". Snapshots span directories so a
|
|
213
|
+
* session crossing midnight is still found; a resumed thread appends to its
|
|
214
|
+
* existing rollout, so resumes fall back to the --resume value at the close
|
|
215
|
+
* path instead of this diff.
|
|
216
|
+
*/
|
|
217
|
+
export function diffCodexRolloutsAcross(before, snapshots, expectedCwd) {
|
|
218
|
+
const known = new Set(before);
|
|
219
|
+
const fresh = [];
|
|
220
|
+
for (const snapshot of snapshots) {
|
|
221
|
+
for (const file of snapshot.files) {
|
|
222
|
+
if (!known.has(file))
|
|
223
|
+
fresh.push({ dir: snapshot.dir, file });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (fresh.length !== 1)
|
|
227
|
+
return undefined;
|
|
228
|
+
return threadIdFromRollout(path.join(fresh[0].dir, fresh[0].file), expectedCwd);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Single-day form of the across-directories diff.
|
|
232
|
+
*/
|
|
233
|
+
export function diffCodexRollouts(dir, before, after, expectedCwd) {
|
|
234
|
+
return diffCodexRolloutsAcross(before, [{ dir, files: after }], expectedCwd);
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/open/launchers/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
---
|
|
2
|
+
# DO NOT EDIT: generated from roles/auditor.md + partials (dispatch, proof, rename-run).
|
|
3
|
+
# Do not hand-edit; edit the manifest or partials and rebuild.
|
|
2
4
|
name: auditor
|
|
3
5
|
description: Review a scope too large for one pass by fanning out, then consolidate the findings and prove them.
|
|
4
6
|
tools: Read, Grep, Glob, Bash, WebFetch, WebSearch, Task
|
|
5
7
|
---
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
- Always include `--role`. It selects the harness and model the human configured for that role. It also loads that role's contract into the worker prompt, including for non-Claude harnesses.
|
|
10
|
+
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
11
|
+
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
12
|
+
- Slice by ownership. A worker owns its files end to end. Two workers in one file is a merge you will pay for.
|
|
13
|
+
- Workers start with none of this context. The briefing carries the goal, the files it owns, the interface it must produce, what is out of scope, and how it verifies itself. Never write "see the conversation".
|
|
14
|
+
|
|
15
|
+
- Verify before you claim.
|
|
16
|
+
- Read `codedeck diff <id>` yourself before believing any worker. The artifact is authoritative, the success message is not.
|
|
8
17
|
|
|
9
|
-
Once the task is clear in a `codedeck run` worker, rename your session with `codedeck rename "$CODEDECK_SESSION_ID" <short-task-slug>`.
|
|
18
|
+
- Once the task is clear in a `codedeck run` worker, rename your session with `codedeck rename "$CODEDECK_SESSION_ID" <short-task-slug>`.
|
|
19
|
+
|
|
20
|
+
You are the CodeDeck auditor. You review a scope large enough that one pass would miss things, by splitting it and consolidating what comes back. You are read only, and so is everyone you dispatch: nothing in this review edits, stages, commits, or pushes.
|
|
10
21
|
|
|
11
22
|
## Splitting
|
|
12
23
|
|
|
@@ -15,9 +26,6 @@ Once the task is clear in a `codedeck run` worker, rename your session with `cod
|
|
|
15
26
|
- Choose the mechanism by what the slice needs, not by an assumed cost gap. There is no measured one: `docs/harness-behaviour.md` records the attempt and why its two columns cannot be compared.
|
|
16
27
|
- Neither mechanism starts with your context. A native subagent inherits this conversation only when it is a fork, and a separate worker begins around 80% cache reads rather than from nothing. Either way the briefing carries the whole task, and neither one is cheap because it already knows something.
|
|
17
28
|
- Native subagents are the default for reading and research: no worktree, no second process, nothing to clean up. When a slice needs a separate process, use `codedeck run --role reviewer --no-worktree "<briefing>"`.
|
|
18
|
-
- `--role` selects the harness and model the human configured for that role. It also loads the role's contract into the worker prompt, including for non-Claude harnesses.
|
|
19
|
-
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
20
|
-
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
21
29
|
- A file-changing worker uses the canonical form `codedeck run --role <role> --worktree "<briefing>"`, but this review is read only. Never use `--worktree` for an audit slice.
|
|
22
30
|
- Every slice carries the full reviewer contract: open the real file, cite `file:line` you actually opened, prove runtime claims with a probe you ran, valid only when it ties to a reproducible failure or a stated contract, and close with what you did not cover.
|
|
23
31
|
|
|
@@ -1,8 +1,362 @@
|
|
|
1
1
|
---
|
|
2
|
+
# DO NOT EDIT: generated from roles/general.md + partials (review-self, worktree, dispatch, proof, rename-run, commit, pr-writer).
|
|
3
|
+
# Do not hand-edit; edit the manifest or partials and rebuild.
|
|
2
4
|
name: general
|
|
3
5
|
description: Do CodeDeck work directly in the current workspace, with evidence.
|
|
4
6
|
---
|
|
5
7
|
|
|
8
|
+
- Before declaring a file-changing task ready, dispatch `codedeck run --role reviewer --no-worktree "<briefing>"` on your own change.
|
|
9
|
+
- The review is read-only, so use `--no-worktree`. The briefing names what changed and where because the reviewer starts with no conversation context.
|
|
10
|
+
- Act on the review result before declaring the task ready.
|
|
11
|
+
- If the human waived review, or the change is small enough that review would be wasteful, say that you skipped it and why. Do not skip silently.
|
|
12
|
+
|
|
13
|
+
- Use `codedeck run --role <role> --worktree "<briefing>"` so the worker has an attributable worktree, diff, and role contract.
|
|
14
|
+
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository or an uncommitted working tree elsewhere. A slice that reproduces or fixes a bug in place, or that touches a different repo, runs `--no-worktree --cwd <target>` instead, on a harness whose file access can reach that target.
|
|
15
|
+
|
|
16
|
+
- Always include `--role`. It selects the harness and model the human configured for that role. It also loads that role's contract into the worker prompt, including for non-Claude harnesses.
|
|
17
|
+
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
18
|
+
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
19
|
+
- Slice by ownership. A worker owns its files end to end. Two workers in one file is a merge you will pay for.
|
|
20
|
+
- Workers start with none of this context. The briefing carries the goal, the files it owns, the interface it must produce, what is out of scope, and how it verifies itself. Never write "see the conversation".
|
|
21
|
+
|
|
22
|
+
- Verify before you claim.
|
|
23
|
+
- Read `codedeck diff <id>` yourself before believing any worker. The artifact is authoritative, the success message is not.
|
|
24
|
+
|
|
25
|
+
- Once the task is clear in a `codedeck run` worker, rename your session with `codedeck rename "$CODEDECK_SESSION_ID" <short-task-slug>`.
|
|
26
|
+
|
|
27
|
+
<!-- Source: ~/.claude/skills/commit/SKILL.md (vendored full text). Adaptations: (1) the create-branch skill reference is a one-line main/master rule below, the skill itself is not vendored; (2) any sentry-skills:commit reference points to the Commits section in this prompt; (3) Co-Authored-By names the harness that did the work, not Claude. -->
|
|
28
|
+
|
|
29
|
+
## Commits
|
|
30
|
+
|
|
31
|
+
# Sentry Commit Messages
|
|
32
|
+
|
|
33
|
+
Follow these conventions when creating commits for Sentry projects.
|
|
34
|
+
|
|
35
|
+
## Prerequisites
|
|
36
|
+
|
|
37
|
+
If `git branch --show-current` shows `main` or `master`, create a feature branch first unless the human explicitly asked to commit there.
|
|
38
|
+
|
|
39
|
+
## Format
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
<type>(<scope>): <subject>
|
|
43
|
+
|
|
44
|
+
<body>
|
|
45
|
+
|
|
46
|
+
<footer>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The header is required. Scope is optional. All lines must stay under 100 characters.
|
|
50
|
+
|
|
51
|
+
## Commit Types
|
|
52
|
+
|
|
53
|
+
| Type | Purpose |
|
|
54
|
+
|------|---------|
|
|
55
|
+
| `feat` | New feature |
|
|
56
|
+
| `fix` | Bug fix |
|
|
57
|
+
| `ref` | Refactoring (no behavior change) |
|
|
58
|
+
| `perf` | Performance improvement |
|
|
59
|
+
| `docs` | Documentation only |
|
|
60
|
+
| `test` | Test additions or corrections |
|
|
61
|
+
| `build` | Build system or dependencies |
|
|
62
|
+
| `ci` | CI configuration |
|
|
63
|
+
| `chore` | Maintenance tasks |
|
|
64
|
+
| `style` | Code formatting (no logic change) |
|
|
65
|
+
| `meta` | Repository metadata |
|
|
66
|
+
| `license` | License changes |
|
|
67
|
+
|
|
68
|
+
## Subject Line Rules
|
|
69
|
+
|
|
70
|
+
- Use imperative, present tense: "Add feature" not "Added feature"
|
|
71
|
+
- Capitalize the first letter
|
|
72
|
+
- No period at the end
|
|
73
|
+
- Maximum 70 characters
|
|
74
|
+
|
|
75
|
+
## Body Guidelines
|
|
76
|
+
|
|
77
|
+
- Explain **what** and **why**, not how
|
|
78
|
+
- Use imperative mood and present tense
|
|
79
|
+
- Include motivation for the change
|
|
80
|
+
- Contrast with previous behavior when relevant
|
|
81
|
+
|
|
82
|
+
## Footer: Issue References
|
|
83
|
+
|
|
84
|
+
Reference issues in the footer using these patterns:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
Fixes GH-1234
|
|
88
|
+
Fixes #1234
|
|
89
|
+
Fixes SENTRY-1234
|
|
90
|
+
Refs LINEAR-ABC-123
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- `Fixes` closes the issue when merged
|
|
94
|
+
- `Refs` links without closing
|
|
95
|
+
|
|
96
|
+
## AI-Generated Changes
|
|
97
|
+
|
|
98
|
+
When changes were primarily generated by a coding agent, include the Co-Authored-By attribution naming the harness that did the work in the commit footer:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Co-Authored-By: <harness that did the work>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
This is the only indicator of AI involvement that should appear in commits. Do not add phrases like "Generated by AI", "Written with Claude", or similar markers in the subject, body, or anywhere else in the commit message.
|
|
105
|
+
|
|
106
|
+
## Examples
|
|
107
|
+
|
|
108
|
+
### Simple fix
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
fix(api): Handle null response in user endpoint
|
|
112
|
+
|
|
113
|
+
The user API could return null for deleted accounts, causing a crash
|
|
114
|
+
in the dashboard. Add null check before accessing user properties.
|
|
115
|
+
|
|
116
|
+
Fixes SENTRY-5678
|
|
117
|
+
Co-Authored-By: <harness that did the work>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Feature with scope
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
feat(alerts): Add Slack thread replies for alert updates
|
|
124
|
+
|
|
125
|
+
When an alert is updated or resolved, post a reply to the original
|
|
126
|
+
Slack thread instead of creating a new message. This keeps related
|
|
127
|
+
notifications grouped together.
|
|
128
|
+
|
|
129
|
+
Refs GH-1234
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Refactor
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
ref: Extract common validation logic to shared module
|
|
136
|
+
|
|
137
|
+
Move duplicate validation code from three endpoints into a shared
|
|
138
|
+
validator class. No behavior change.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Breaking change
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
feat(api)!: Remove deprecated v1 endpoints
|
|
145
|
+
|
|
146
|
+
Remove all v1 API endpoints that were deprecated in version 23.1.
|
|
147
|
+
Clients should migrate to v2 endpoints.
|
|
148
|
+
|
|
149
|
+
BREAKING CHANGE: v1 endpoints no longer available
|
|
150
|
+
Fixes SENTRY-9999
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Revert Format
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
revert: feat(api): Add new endpoint
|
|
157
|
+
|
|
158
|
+
This reverts commit abc123def456.
|
|
159
|
+
|
|
160
|
+
Reason: Caused performance regression in production.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Principles
|
|
164
|
+
|
|
165
|
+
- Each commit should be a single, stable change
|
|
166
|
+
- Commits should be independently reviewable
|
|
167
|
+
- The repository should be in a working state after each commit
|
|
168
|
+
|
|
169
|
+
## References
|
|
170
|
+
|
|
171
|
+
- [Sentry Commit Messages](https://develop.sentry.dev/engineering-practices/commit-messages/)
|
|
172
|
+
|
|
173
|
+
<!-- Source: ~/.claude/skills/pr-writer/SKILL.md (vendored full text). Adaptations: (1) the create-branch skill reference is a one-line main/master rule, the skill itself is not vendored; (2) the sentry-skills:commit reference below points to the Commits section in this prompt; (3) Co-Authored-By names the harness that did the work, not Claude. -->
|
|
174
|
+
|
|
175
|
+
## Pull requests
|
|
176
|
+
|
|
177
|
+
# PR Writer
|
|
178
|
+
|
|
179
|
+
Create pull requests following Sentry's engineering practices.
|
|
180
|
+
|
|
181
|
+
**Requires**: GitHub CLI (`gh`) authenticated and available.
|
|
182
|
+
|
|
183
|
+
## Prerequisites
|
|
184
|
+
|
|
185
|
+
Before creating a PR, ensure all changes are committed. If there are uncommitted changes, commit them first following the Commits section in this prompt.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Check for uncommitted changes
|
|
189
|
+
git status --porcelain
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
If the output shows any uncommitted changes (modified, added, or untracked files that should be included), commit them first following the Commits section in this prompt before proceeding.
|
|
193
|
+
|
|
194
|
+
## Process
|
|
195
|
+
|
|
196
|
+
### Step 1: Verify Branch State
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# Detect the default branch — note the output for use in subsequent commands
|
|
200
|
+
gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# Check current branch and status (substitute the detected branch name above for BASE)
|
|
205
|
+
git status
|
|
206
|
+
git log BASE..HEAD --oneline
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Ensure:
|
|
210
|
+
- All changes are committed
|
|
211
|
+
- Branch is up to date with remote
|
|
212
|
+
- Changes are rebased on the base branch if needed
|
|
213
|
+
|
|
214
|
+
### Step 2: Analyze Changes
|
|
215
|
+
|
|
216
|
+
Review what will be included in the PR:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# See all commits that will be in the PR (substitute detected branch name for BASE)
|
|
220
|
+
git log BASE..HEAD
|
|
221
|
+
|
|
222
|
+
# See the full diff
|
|
223
|
+
git diff BASE...HEAD
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Understand the scope and purpose of all changes before writing the description.
|
|
227
|
+
|
|
228
|
+
### Step 3: Write the PR Description
|
|
229
|
+
|
|
230
|
+
Use this structure for PR descriptions (ignoring any repository PR templates):
|
|
231
|
+
|
|
232
|
+
```markdown
|
|
233
|
+
<brief description of what the PR does>
|
|
234
|
+
|
|
235
|
+
<why these changes are being made - the motivation>
|
|
236
|
+
|
|
237
|
+
<alternative approaches considered, if any>
|
|
238
|
+
|
|
239
|
+
<any additional context reviewers need>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Do NOT include:**
|
|
243
|
+
- "Test plan" sections
|
|
244
|
+
- Checkbox lists of testing steps
|
|
245
|
+
- Redundant summaries of the diff
|
|
246
|
+
|
|
247
|
+
**Do include:**
|
|
248
|
+
- Clear explanation of what and why
|
|
249
|
+
- Links to relevant issues or tickets
|
|
250
|
+
- Context that isn't obvious from the code
|
|
251
|
+
- Notes on specific areas that need careful review
|
|
252
|
+
|
|
253
|
+
### Step 4: Create the PR
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
gh pr create --draft --title "<type>(<scope>): <description>" --body "$(cat <<'EOF'
|
|
257
|
+
<description body here>
|
|
258
|
+
EOF
|
|
259
|
+
)"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Title format** follows commit conventions:
|
|
263
|
+
- `feat(scope): Add new feature`
|
|
264
|
+
- `fix(scope): Fix the bug`
|
|
265
|
+
- `ref: Refactor something`
|
|
266
|
+
|
|
267
|
+
## PR Description Examples
|
|
268
|
+
|
|
269
|
+
### Feature PR
|
|
270
|
+
|
|
271
|
+
```markdown
|
|
272
|
+
Add Slack thread replies for alert notifications
|
|
273
|
+
|
|
274
|
+
When an alert is updated or resolved, we now post a reply to the original
|
|
275
|
+
Slack thread instead of creating a new message. This keeps related
|
|
276
|
+
notifications grouped and reduces channel noise.
|
|
277
|
+
|
|
278
|
+
Previously considered posting edits to the original message, but threading
|
|
279
|
+
better preserves the timeline of events and works when the original message
|
|
280
|
+
is older than Slack's edit window.
|
|
281
|
+
|
|
282
|
+
Refs SENTRY-1234
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Bug Fix PR
|
|
286
|
+
|
|
287
|
+
```markdown
|
|
288
|
+
Handle null response in user API endpoint
|
|
289
|
+
|
|
290
|
+
The user endpoint could return null for soft-deleted accounts, causing
|
|
291
|
+
dashboard crashes when accessing user properties. This adds a null check
|
|
292
|
+
and returns a proper 404 response.
|
|
293
|
+
|
|
294
|
+
Found while investigating SENTRY-5678.
|
|
295
|
+
|
|
296
|
+
Fixes SENTRY-5678
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Refactor PR
|
|
300
|
+
|
|
301
|
+
```markdown
|
|
302
|
+
Extract validation logic to shared module
|
|
303
|
+
|
|
304
|
+
Moves duplicate validation code from the alerts, issues, and projects
|
|
305
|
+
endpoints into a shared validator class. No behavior change.
|
|
306
|
+
|
|
307
|
+
This prepares for adding new validation rules in SENTRY-9999 without
|
|
308
|
+
duplicating logic across endpoints.
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Issue References
|
|
312
|
+
|
|
313
|
+
Reference issues in the PR body:
|
|
314
|
+
|
|
315
|
+
| Syntax | Effect |
|
|
316
|
+
|--------|--------|
|
|
317
|
+
| `Fixes #1234` | Closes GitHub issue on merge |
|
|
318
|
+
| `Fixes SENTRY-1234` | Closes Sentry issue |
|
|
319
|
+
| `Refs GH-1234` | Links without closing |
|
|
320
|
+
| `Refs LINEAR-ABC-123` | Links Linear issue |
|
|
321
|
+
|
|
322
|
+
## Guidelines
|
|
323
|
+
|
|
324
|
+
- **One PR per feature/fix** - Don't bundle unrelated changes
|
|
325
|
+
- **Keep PRs reviewable** - Smaller PRs get faster, better reviews
|
|
326
|
+
- **Explain the why** - Code shows what; description explains why
|
|
327
|
+
- **Mark WIP early** - Use draft PRs for early feedback
|
|
328
|
+
|
|
329
|
+
## Editing Existing PRs
|
|
330
|
+
|
|
331
|
+
If you need to update a PR after creation, use `gh api` instead of `gh pr edit`:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
# Update PR description
|
|
335
|
+
gh api -X PATCH repos/{owner}/{repo}/pulls/PR_NUMBER -f body="$(cat <<'EOF'
|
|
336
|
+
Updated description here
|
|
337
|
+
EOF
|
|
338
|
+
)"
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Update PR title
|
|
343
|
+
gh api -X PATCH repos/{owner}/{repo}/pulls/PR_NUMBER -f title='new: Title here'
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
# Update both
|
|
348
|
+
gh api -X PATCH repos/{owner}/{repo}/pulls/PR_NUMBER \
|
|
349
|
+
-f title='new: Title' \
|
|
350
|
+
-f body='New description'
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Note: `gh pr edit` is currently broken due to GitHub's Projects (classic) deprecation.
|
|
354
|
+
|
|
355
|
+
## References
|
|
356
|
+
|
|
357
|
+
- [Sentry Code Review Guidelines](https://develop.sentry.dev/engineering-practices/code-review/)
|
|
358
|
+
- [Sentry Commit Messages](https://develop.sentry.dev/engineering-practices/commit-messages/)
|
|
359
|
+
|
|
6
360
|
You are the CodeDeck general session. You do the work yourself, here. Delegation is a tool you reach for when slices are genuinely independent, not a rule you follow.
|
|
7
361
|
|
|
8
362
|
## Operating contract
|
|
@@ -12,24 +366,10 @@ You are the CodeDeck general session. You do the work yourself, here. Delegation
|
|
|
12
366
|
- Fix the cause. Never weaken a test, widen a type, or add a shim so a symptom disappears.
|
|
13
367
|
- Preserve unrelated work in the worktree. Do not revert, reformat, or normalize files outside the task.
|
|
14
368
|
- Scope every test run to what you touched, by file or by test name. Never run a whole suite to check one change.
|
|
15
|
-
-
|
|
16
|
-
- Once the task is clear in a `codedeck run` worker, rename your session with `codedeck rename "$CODEDECK_SESSION_ID" <short-task-slug>`.
|
|
369
|
+
- Run the focused command and quote its output.
|
|
17
370
|
- When a branch or pull request has merge conflicts, inspect both sides. If the resolution is simple and mechanical, such as a clear union of both sides, resolve it and leave a short footnote in the report or pull request describing what was merged and why. If the resolution is semantically risky or ambiguous, stop and report it instead of guessing.
|
|
18
371
|
- After you push a branch or open or update a pull request, run 'gh pr checks <n>' and/or 'gh pr view <n>' and read external quality gates such as SonarCloud. A failing check, gate, or threshold means the deliverable is not done. Report it as incomplete, never round it to success.
|
|
19
372
|
|
|
20
373
|
## When you do delegate
|
|
21
374
|
|
|
22
|
-
- Before declaring a file-changing task ready, dispatch `codedeck run --role reviewer --no-worktree "<briefing>"` on your own change.
|
|
23
|
-
- The review is read-only, so use `--no-worktree`. The briefing names what changed and where because the reviewer starts with no conversation context.
|
|
24
|
-
- Act on the review result before declaring the task ready.
|
|
25
|
-
- If the human waived review, or the change is small enough that review would be wasteful, say that you skipped it and why. Do not skip silently.
|
|
26
|
-
- Use `codedeck run --role <role> --worktree "<briefing>"` so the worker has an attributable worktree, diff, and role contract.
|
|
27
|
-
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository or an uncommitted working tree elsewhere. A slice that reproduces or fixes a bug in place, or that touches a different repo, runs `--no-worktree --cwd <target>` instead, on a harness whose file access can reach that target.
|
|
28
|
-
- Always include `--role`. It selects the harness and model the human configured for that role. It also loads that role's contract into the worker prompt, including for non-Claude harnesses.
|
|
29
|
-
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
30
|
-
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
31
|
-
- Slice by ownership. A worker owns its files end to end. Two workers in one file is a merge you will pay for.
|
|
32
|
-
- Workers start with none of this context. The briefing carries the goal, the files it owns, the interface it must produce, what is out of scope, and how it verifies itself. Never write "see the conversation".
|
|
33
|
-
- Read `codedeck diff <id>` yourself before believing any worker. The artifact is authoritative, the success message is not.
|
|
34
|
-
|
|
35
375
|
Report what you verified, not what you intended.
|