waypoint-codex 0.18.0 → 0.18.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/README.md +9 -0
- package/dist/src/core.js +1 -0
- package/dist/src/templates.js +2 -0
- package/package.json +1 -1
- package/templates/.agents/skills/planning/SKILL.md +8 -3
- package/templates/.waypoint/agent-operating-manual.md +6 -1
- package/templates/.waypoint/scripts/prepare-context.mjs +146 -33
- package/templates/managed-agents-block.md +6 -3
package/README.md
CHANGED
|
@@ -189,6 +189,15 @@ The continuity story matters:
|
|
|
189
189
|
- `.waypoint/context/RECENT_THREAD.md` helps the agent retain the important
|
|
190
190
|
parts of the previous conversation
|
|
191
191
|
|
|
192
|
+
Waypoint defaults to Codex transcript discovery.
|
|
193
|
+
If you use Pi instead, set this in `.waypoint/config.toml`:
|
|
194
|
+
|
|
195
|
+
```toml
|
|
196
|
+
coding_agent = "pi"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Supported values are `"codex"` and `"pi"`.
|
|
200
|
+
|
|
192
201
|
## Best fit
|
|
193
202
|
|
|
194
203
|
Waypoint is most useful when you want:
|
package/dist/src/core.js
CHANGED
|
@@ -143,6 +143,7 @@ function buildWaypointConfig(projectRoot, existingConfig, options) {
|
|
|
143
143
|
return {
|
|
144
144
|
version: existingConfig?.version ?? defaults.version,
|
|
145
145
|
profile: options.profile,
|
|
146
|
+
coding_agent: existingConfig?.coding_agent ?? defaults.coding_agent,
|
|
146
147
|
workspace_file: existingConfig?.workspace_file ?? defaults.workspace_file,
|
|
147
148
|
docs_dirs: configuredRootDirs(projectRoot, existingConfig?.docs_dirs, existingConfig?.docs_dir, DEFAULT_DOCS_DIR).map((dir) => path.relative(projectRoot, dir).split(path.sep).join("/")),
|
|
148
149
|
plans_dirs: configuredRootDirs(projectRoot, existingConfig?.plans_dirs, existingConfig?.plans_dir, DEFAULT_PLANS_DIR).map((dir) => path.relative(projectRoot, dir).split(path.sep).join("/")),
|
package/dist/src/templates.js
CHANGED
|
@@ -30,6 +30,7 @@ export function defaultWaypointConfig(options) {
|
|
|
30
30
|
return {
|
|
31
31
|
version: 1,
|
|
32
32
|
profile: options.profile,
|
|
33
|
+
coding_agent: "codex",
|
|
33
34
|
workspace_file: ".waypoint/WORKSPACE.md",
|
|
34
35
|
docs_dirs: [".waypoint/docs"],
|
|
35
36
|
plans_dirs: [".waypoint/plans"],
|
|
@@ -44,6 +45,7 @@ export function renderWaypointConfig(config) {
|
|
|
44
45
|
const renderedConfig = {
|
|
45
46
|
version: config.version,
|
|
46
47
|
profile: config.profile,
|
|
48
|
+
coding_agent: config.coding_agent,
|
|
47
49
|
workspace_file: config.workspace_file,
|
|
48
50
|
docs_dirs: config.docs_dirs,
|
|
49
51
|
plans_dirs: config.plans_dirs,
|
package/package.json
CHANGED
|
@@ -102,6 +102,7 @@ Plans document your understanding. Include what matters for this task:
|
|
|
102
102
|
- **Current State**: What exists today — relevant files, data flows, constraints, existing patterns
|
|
103
103
|
- **Changes**: Every file to create/modify/delete, how changes connect
|
|
104
104
|
- **Decisions**: Why this approach, tradeoffs, assumptions
|
|
105
|
+
- **Scope checklist**: Concrete implementation items that can be marked done or not done
|
|
105
106
|
- **Acceptance criteria**: What must be true when each step is "done"
|
|
106
107
|
- **Test cases**: For behavioral changes, include input -> expected output examples
|
|
107
108
|
- **Non-Goals**: Explicitly out of scope to prevent implementation drift
|
|
@@ -125,6 +126,8 @@ Before presenting the plan, verify against real code:
|
|
|
125
126
|
- No "we'll figure it out during implementation"
|
|
126
127
|
- No literal code unless the user explicitly wants it
|
|
127
128
|
- No pretending you verified something you didn't
|
|
129
|
+
- Approved scope must be explicit enough to act as an execution contract after user approval
|
|
130
|
+
- If the user approves the plan, do not silently defer or drop checklist items later; discuss any proposed scope change first
|
|
128
131
|
|
|
129
132
|
If the change touches durable project behavior, include docs/workspace updates in the plan.
|
|
130
133
|
Write or update the durable plan doc under `.waypoint/plans/` as part of the skill, not as an optional follow-up.
|
|
@@ -140,9 +143,10 @@ A good durable plan doc usually includes:
|
|
|
140
143
|
1. Current state
|
|
141
144
|
2. Proposed changes
|
|
142
145
|
3. Decisions and tradeoffs
|
|
143
|
-
4.
|
|
144
|
-
5.
|
|
145
|
-
6.
|
|
146
|
+
4. Scope checklist
|
|
147
|
+
5. Acceptance criteria
|
|
148
|
+
6. Verification
|
|
149
|
+
7. TL;DR
|
|
146
150
|
|
|
147
151
|
## Final Response
|
|
148
152
|
|
|
@@ -152,6 +156,7 @@ When the plan doc is written:
|
|
|
152
156
|
- include the doc path
|
|
153
157
|
- call out any unresolved decisions that still need the user's input
|
|
154
158
|
- if there are no unresolved decisions and the user approves the plan, treat that approval as authorization to execute the plan end to end rather than asking again at each obvious next step
|
|
159
|
+
- once approved, use the plan's checklist and acceptance criteria to decide whether the work is actually done; if anything approved is skipped, report that as partial work or ask to change scope instead of calling it complete
|
|
155
160
|
|
|
156
161
|
## Quality Bar
|
|
157
162
|
|
|
@@ -49,10 +49,13 @@ If something important lives only in your head or in the chat transcript, the re
|
|
|
49
49
|
- Read code before editing it.
|
|
50
50
|
- Follow the repo's documented patterns when they are healthy.
|
|
51
51
|
- If the user approves a plan or explicitly tells you to proceed, treat that as authorization to finish the approved work end to end.
|
|
52
|
-
-
|
|
52
|
+
- Once a plan is approved, treat its scope and acceptance criteria as the execution contract. Do not silently narrow, defer, or drop approved work because the system feels good enough, the remaining work looks less valuable, or you would prefer a smaller PR. If the scope should change, discuss that with the user first unless a real blocker, hidden-risk decision, or explicit user redirect forces the change.
|
|
53
|
+
- When the user shows a bug, screenshot, or broken behavior, investigate first. Lead with what is happening, why it is likely happening, the important options or tradeoffs if they matter, what you checked, and what you are doing next.
|
|
54
|
+
- After investigation, explain the diagnosis before jumping into implementation whenever the cause, tradeoffs, or solution shape are not already obvious.
|
|
53
55
|
- Fix underlying causes instead of papering over symptoms. If the real fix requires changing a shaky abstraction, deleting stale compatibility logic, or cleaning up debt that is directly causing the bug, do that work instead of shipping a hot patch around it.
|
|
54
56
|
- Do not stop at the first local patch that makes the symptom disappear if the root cause is still obviously in place.
|
|
55
57
|
- Do not lead with readiness disclaimers such as "I can't call this done yet" unless the user explicitly asked whether the work is ready, shippable, or complete.
|
|
58
|
+
- Keep communication concise by default. Lead with the answer, diagnosis, decision, or next step, and include only the most important supporting detail unless the user asks for more.
|
|
56
59
|
- Honesty means accurate diagnosis, explicit uncertainty, and clear verification limits. It does not mean substituting process language for investigation.
|
|
57
60
|
- Before making meaningful frontend or backend decisions, inspect the available user-scoped and project-scoped `AGENTS.md` guidance. If the task depends on frontend or backend context that is missing from the project-scoped guidance and routed docs, use the corresponding `*-context-interview` skill to fill that gap instead of guessing.
|
|
58
61
|
- Update the user-scoped `AGENTS.md` when you learn a durable preference, workflow rule, or default that should apply across projects and your environment allows you to edit it.
|
|
@@ -96,6 +99,7 @@ Pause only when:
|
|
|
96
99
|
|
|
97
100
|
- a real blocker prevents forward progress
|
|
98
101
|
- a hidden-risk or non-obvious decision would materially change scope, behavior, cost, or data safety
|
|
102
|
+
- you want to change approved scope or defer approved work
|
|
99
103
|
- the user explicitly redirects, pauses, or narrows the work
|
|
100
104
|
|
|
101
105
|
If none of those are true, keep going.
|
|
@@ -143,6 +147,7 @@ Deliberate closeout review is available when you want a second pass for ship-rea
|
|
|
143
147
|
- No silent assumptions
|
|
144
148
|
- No fake verification
|
|
145
149
|
- No hiding behind process language when a useful diagnosis is possible
|
|
150
|
+
- No silent scope reduction after plan approval
|
|
146
151
|
- No skipping docs or workspace updates when they matter
|
|
147
152
|
- No broad scope creep under the banner of "while I'm here"
|
|
148
153
|
|
|
@@ -116,7 +116,7 @@ function renderPullRequestBlock(result, emptyMessage) {
|
|
|
116
116
|
return result.stdout || emptyMessage;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
const
|
|
119
|
+
const CODEX_SESSION_DIR_NAMES = ["sessions", "archived_sessions"];
|
|
120
120
|
const SECRET_PATTERNS = [
|
|
121
121
|
/npm_[A-Za-z0-9]+/g,
|
|
122
122
|
/github_pat_[A-Za-z0-9_]+/g,
|
|
@@ -132,6 +132,29 @@ function codexHome() {
|
|
|
132
132
|
return process.env.CODEX_HOME || path.join(os.homedir(), ".codex");
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
function piAgentHome() {
|
|
136
|
+
return process.env.PI_AGENT_HOME || path.join(os.homedir(), ".pi", "agent");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function loadCodingAgent(projectRoot) {
|
|
140
|
+
const configPath = path.join(projectRoot, ".waypoint", "config.toml");
|
|
141
|
+
if (!existsSync(configPath)) {
|
|
142
|
+
return "codex";
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const configText = readFileSync(configPath, "utf8");
|
|
146
|
+
const match = configText.match(/^\s*coding_agent\s*=\s*"(codex|pi)"\s*$/m);
|
|
147
|
+
return match?.[1] || "codex";
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function codingAgentLabel(codingAgent) {
|
|
151
|
+
return codingAgent === "pi" ? "Pi" : "Codex";
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function codingAgentHome(codingAgent) {
|
|
155
|
+
return codingAgent === "pi" ? piAgentHome() : codexHome();
|
|
156
|
+
}
|
|
157
|
+
|
|
135
158
|
function redactSecrets(text) {
|
|
136
159
|
return SECRET_PATTERNS.reduce((current, pattern) => current.replace(pattern, "[REDACTED]"), text);
|
|
137
160
|
}
|
|
@@ -181,7 +204,7 @@ function collectSessionFiles(rootDir) {
|
|
|
181
204
|
return files;
|
|
182
205
|
}
|
|
183
206
|
|
|
184
|
-
function
|
|
207
|
+
function extractCodexMessageText(content) {
|
|
185
208
|
if (!Array.isArray(content)) {
|
|
186
209
|
return "";
|
|
187
210
|
}
|
|
@@ -192,6 +215,17 @@ function extractMessageText(content) {
|
|
|
192
215
|
.trim();
|
|
193
216
|
}
|
|
194
217
|
|
|
218
|
+
function extractPiMessageText(content) {
|
|
219
|
+
if (!Array.isArray(content)) {
|
|
220
|
+
return "";
|
|
221
|
+
}
|
|
222
|
+
return content
|
|
223
|
+
.filter((block) => block?.type === "text")
|
|
224
|
+
.map((block) => (typeof block?.text === "string" ? block.text : ""))
|
|
225
|
+
.join("")
|
|
226
|
+
.trim();
|
|
227
|
+
}
|
|
228
|
+
|
|
195
229
|
function isBootstrapNoise(role, text) {
|
|
196
230
|
return role === "user" && text.startsWith("# AGENTS.md instructions for ");
|
|
197
231
|
}
|
|
@@ -213,11 +247,33 @@ function mergeConsecutiveTurns(turns) {
|
|
|
213
247
|
return merged;
|
|
214
248
|
}
|
|
215
249
|
|
|
216
|
-
function
|
|
250
|
+
function finalizeParsedSession(sessionFile, projectRoot, sessionId, sessionCwd, sessionStartedAt, rawTurns, compactionBoundaries) {
|
|
251
|
+
if (!sessionCwd || !isWithinPath(sessionCwd, projectRoot)) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const selectedFromPreCompaction = compactionBoundaries.length > 0;
|
|
256
|
+
const relevantTurns = selectedFromPreCompaction ? rawTurns.slice(0, compactionBoundaries.at(-1)) : rawTurns;
|
|
257
|
+
const turns = mergeConsecutiveTurns(relevantTurns);
|
|
258
|
+
if (turns.length === 0) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return {
|
|
263
|
+
path: sessionFile,
|
|
264
|
+
sessionId,
|
|
265
|
+
sessionCwd,
|
|
266
|
+
turns,
|
|
267
|
+
compactionCount: compactionBoundaries.length,
|
|
268
|
+
selectedFromPreCompaction,
|
|
269
|
+
sessionStartedAt,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function parseCodexSession(sessionFile, projectRoot) {
|
|
217
274
|
let sessionId = null;
|
|
218
275
|
let sessionCwd = null;
|
|
219
276
|
let sessionStartedAt = null;
|
|
220
|
-
let compactionCount = 0;
|
|
221
277
|
const rawTurns = [];
|
|
222
278
|
const compactionBoundaries = [];
|
|
223
279
|
|
|
@@ -250,7 +306,6 @@ function parseSession(sessionFile, projectRoot) {
|
|
|
250
306
|
}
|
|
251
307
|
|
|
252
308
|
if (parsed.type === "compacted") {
|
|
253
|
-
compactionCount += 1;
|
|
254
309
|
compactionBoundaries.push(rawTurns.length);
|
|
255
310
|
continue;
|
|
256
311
|
}
|
|
@@ -264,7 +319,7 @@ function parseSession(sessionFile, projectRoot) {
|
|
|
264
319
|
continue;
|
|
265
320
|
}
|
|
266
321
|
|
|
267
|
-
const text = redactSecrets(
|
|
322
|
+
const text = redactSecrets(extractCodexMessageText(parsed.payload?.content));
|
|
268
323
|
if (!text || isBootstrapNoise(role, text)) {
|
|
269
324
|
continue;
|
|
270
325
|
}
|
|
@@ -277,37 +332,90 @@ function parseSession(sessionFile, projectRoot) {
|
|
|
277
332
|
});
|
|
278
333
|
}
|
|
279
334
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
335
|
+
return finalizeParsedSession(sessionFile, projectRoot, sessionId, sessionCwd, sessionStartedAt, rawTurns, compactionBoundaries);
|
|
336
|
+
}
|
|
283
337
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
338
|
+
function parsePiSession(sessionFile, projectRoot) {
|
|
339
|
+
let sessionId = null;
|
|
340
|
+
let sessionCwd = null;
|
|
341
|
+
let sessionStartedAt = null;
|
|
342
|
+
const rawTurns = [];
|
|
343
|
+
const compactionBoundaries = [];
|
|
344
|
+
|
|
345
|
+
for (const line of readFileSync(sessionFile, "utf8").split("\n")) {
|
|
346
|
+
if (!line.trim()) {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
let parsed;
|
|
351
|
+
try {
|
|
352
|
+
parsed = JSON.parse(line);
|
|
353
|
+
} catch {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (parsed.type === "session") {
|
|
358
|
+
if (typeof parsed.id === "string") {
|
|
359
|
+
sessionId = parsed.id;
|
|
360
|
+
}
|
|
361
|
+
if (typeof parsed.cwd === "string") {
|
|
362
|
+
sessionCwd = parsed.cwd;
|
|
363
|
+
}
|
|
364
|
+
if (typeof parsed.timestamp === "string") {
|
|
365
|
+
sessionStartedAt = parsed.timestamp;
|
|
366
|
+
}
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (parsed.type === "compaction") {
|
|
371
|
+
compactionBoundaries.push(rawTurns.length);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (parsed.type !== "message") {
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const role = parsed.message?.role;
|
|
380
|
+
if (role !== "user" && role !== "assistant") {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const text = redactSecrets(extractPiMessageText(parsed.message?.content));
|
|
385
|
+
if (!text || isBootstrapNoise(role, text)) {
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
rawTurns.push({
|
|
390
|
+
role,
|
|
391
|
+
text,
|
|
392
|
+
timestamp: parsed.timestamp || parsed.message?.timestamp || null,
|
|
393
|
+
messageCount: 1,
|
|
394
|
+
});
|
|
289
395
|
}
|
|
290
396
|
|
|
291
|
-
return
|
|
292
|
-
path: sessionFile,
|
|
293
|
-
sessionId,
|
|
294
|
-
sessionCwd,
|
|
295
|
-
turns,
|
|
296
|
-
compactionCount,
|
|
297
|
-
selectedFromPreCompaction,
|
|
298
|
-
sessionStartedAt,
|
|
299
|
-
};
|
|
397
|
+
return finalizeParsedSession(sessionFile, projectRoot, sessionId, sessionCwd, sessionStartedAt, rawTurns, compactionBoundaries);
|
|
300
398
|
}
|
|
301
399
|
|
|
302
|
-
function latestMatchingSession(projectRoot, threadIdOverride = null) {
|
|
400
|
+
function latestMatchingSession(projectRoot, codingAgent, threadIdOverride = null) {
|
|
303
401
|
const matches = [];
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
402
|
+
|
|
403
|
+
if (codingAgent === "pi") {
|
|
404
|
+
for (const sessionFile of collectSessionFiles(path.join(piAgentHome(), "sessions"))) {
|
|
405
|
+
const parsed = parsePiSession(sessionFile, projectRoot);
|
|
307
406
|
if (parsed) {
|
|
308
407
|
matches.push(parsed);
|
|
309
408
|
}
|
|
310
409
|
}
|
|
410
|
+
} else {
|
|
411
|
+
for (const dirName of CODEX_SESSION_DIR_NAMES) {
|
|
412
|
+
for (const sessionFile of collectSessionFiles(path.join(codexHome(), dirName))) {
|
|
413
|
+
const parsed = parseCodexSession(sessionFile, projectRoot);
|
|
414
|
+
if (parsed) {
|
|
415
|
+
matches.push(parsed);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
311
419
|
}
|
|
312
420
|
|
|
313
421
|
const requestedThreadId = threadIdOverride || process.env.CODEX_THREAD_ID || null;
|
|
@@ -331,7 +439,10 @@ function latestMatchingSession(projectRoot, threadIdOverride = null) {
|
|
|
331
439
|
|
|
332
440
|
function writeRecentThread(contextDir, projectRoot, threadIdOverride = null) {
|
|
333
441
|
const filePath = path.join(contextDir, "RECENT_THREAD.md");
|
|
334
|
-
const
|
|
442
|
+
const codingAgent = loadCodingAgent(projectRoot);
|
|
443
|
+
const agentLabel = codingAgentLabel(codingAgent);
|
|
444
|
+
const agentHome = codingAgentHome(codingAgent);
|
|
445
|
+
const snapshot = latestMatchingSession(projectRoot, codingAgent, threadIdOverride);
|
|
335
446
|
const generatedAt = new Date().toString();
|
|
336
447
|
|
|
337
448
|
if (!snapshot) {
|
|
@@ -342,7 +453,7 @@ function writeRecentThread(contextDir, projectRoot, threadIdOverride = null) {
|
|
|
342
453
|
"",
|
|
343
454
|
`Generated by \`${path.relative(projectRoot, fileURLToPath(import.meta.url))}\` on ${generatedAt}.`,
|
|
344
455
|
"",
|
|
345
|
-
|
|
456
|
+
`No matching local ${agentLabel} session was found for this repo yet.`,
|
|
346
457
|
"",
|
|
347
458
|
].join("\n"),
|
|
348
459
|
"utf8"
|
|
@@ -358,10 +469,10 @@ function writeRecentThread(contextDir, projectRoot, threadIdOverride = null) {
|
|
|
358
469
|
"",
|
|
359
470
|
`Generated by \`${path.relative(projectRoot, fileURLToPath(import.meta.url))}\` on ${generatedAt}.`,
|
|
360
471
|
"",
|
|
361
|
-
`- Source session: \`${path.relative(
|
|
472
|
+
`- Source session: \`${path.relative(agentHome, snapshot.path)}\``,
|
|
362
473
|
`- Session cwd: \`${snapshot.sessionCwd}\``,
|
|
363
474
|
`- Compactions in source session: ${snapshot.compactionCount}`,
|
|
364
|
-
|
|
475
|
+
`- No compaction was found in the latest matching local ${agentLabel} session, so there is nothing to restore into startup context yet.`,
|
|
365
476
|
"",
|
|
366
477
|
].join("\n"),
|
|
367
478
|
"utf8"
|
|
@@ -370,7 +481,7 @@ function writeRecentThread(contextDir, projectRoot, threadIdOverride = null) {
|
|
|
370
481
|
}
|
|
371
482
|
|
|
372
483
|
const selectedTurns = snapshot.turns.slice(-MAX_RECENT_TURNS);
|
|
373
|
-
const relSessionPath = path.relative(
|
|
484
|
+
const relSessionPath = path.relative(agentHome, snapshot.path);
|
|
374
485
|
const lines = [
|
|
375
486
|
"# Recent Thread",
|
|
376
487
|
"",
|
|
@@ -435,6 +546,8 @@ function main() {
|
|
|
435
546
|
|
|
436
547
|
const docsIndexPath = writeDocsIndex(projectRoot);
|
|
437
548
|
const { outputPath: tracksIndexPath, activeTracks } = writeTracksIndex(projectRoot);
|
|
549
|
+
const codingAgent = loadCodingAgent(projectRoot);
|
|
550
|
+
const codingAgentLabelText = codingAgentLabel(codingAgent);
|
|
438
551
|
|
|
439
552
|
const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
440
553
|
const currentLocalDatetime = new Date().toString();
|
|
@@ -577,7 +690,7 @@ function main() {
|
|
|
577
690
|
`- \`${path.relative(projectRoot, uncommittedChangesPath)}\` — uncommitted change summary`,
|
|
578
691
|
`- \`${path.relative(projectRoot, recentCommitsPath)}\` — recent commits`,
|
|
579
692
|
`- \`${path.relative(projectRoot, prsPath)}\` — open and recently merged pull requests`,
|
|
580
|
-
`- \`${path.relative(projectRoot, recentThreadPath)}\` — latest meaningful turns from the local
|
|
693
|
+
`- \`${path.relative(projectRoot, recentThreadPath)}\` — latest meaningful turns from the local ${codingAgentLabelText} session for this repo`,
|
|
581
694
|
`- \`${path.relative(projectRoot, docsIndexPath)}\` — current docs index`,
|
|
582
695
|
`- \`${path.relative(projectRoot, tracksIndexPath)}\` — current tracker index`,
|
|
583
696
|
`- \`${path.relative(projectRoot, activeTrackersPath)}\` — active tracker summary`,
|
|
@@ -69,18 +69,20 @@ If some uncertainty still remains after checking persisted context and interview
|
|
|
69
69
|
|
|
70
70
|
Prefer existing persisted context over re-interviewing the user.
|
|
71
71
|
|
|
72
|
-
If the user approves a plan or explicitly tells you to proceed, treat that as authorization to execute the work end to end.
|
|
72
|
+
If the user approves a plan or explicitly tells you to proceed, treat that as authorization to execute the work end to end. An approved plan is the active execution contract: do not silently narrow, defer, or drop planned work because the system feels good enough, the remaining work feels less important, or you would prefer a smaller PR. If you believe the approved scope should change, pause and discuss that change with the user before proceeding. Only change approved scope without that discussion when a real blocker, hidden-risk decision, or explicit user redirect requires it.
|
|
73
73
|
When work is in flight elsewhere — reviewer agents, subagents, CI, automated review, external jobs, or other waiting periods — wait as long as required. There is no fixed waiting limit, and slowness alone is not a reason to interrupt or abandon the work.
|
|
74
74
|
When you use a browser, app, or other interactive UI to inspect, reproduce, or verify something, send the user screenshots of the relevant states so they can see what you saw. If screenshots are not possible in the current environment, say so explicitly.
|
|
75
75
|
When an explanation is clearer visually, use Mermaid diagrams directly in chat for flows, architecture, state, and plans.
|
|
76
76
|
|
|
77
77
|
Delivery expectations:
|
|
78
|
-
-
|
|
78
|
+
- Keep communication concise by default. Lead with the answer, diagnosis, decision, or next step, and include only the most important supporting detail unless the user asks for more.
|
|
79
|
+
- For planned work, define done from the approved scope and acceptance criteria, not from your own sense that the system is already good enough.
|
|
79
80
|
- When you report back to the user, explain the result in plain, direct language. Say what you changed, what happened, and anything the user actually needs to know, but do not lean on jargon, low-level implementation detail, or code-heavy narration unless the user asks for it.
|
|
80
81
|
- Write for a smart person who is not looking at the code. The goal is clarity, not technical performance.
|
|
81
82
|
- This communication rule applies to how you explain the work, not to how you do it. Your actual reasoning, coding, debugging, and verification should stay technical, precise, and rigorous.
|
|
82
83
|
- When the user shows a bug, broken behavior, or a screenshot of something wrong, investigate before discussing readiness.
|
|
83
|
-
-
|
|
84
|
+
- After investigation, explain the problem to the user before jumping into implementation whenever the diagnosis, tradeoffs, or solution shape are not already obvious.
|
|
85
|
+
- Lead with the useful truth: what is happening, the likely cause, the important options or tradeoffs if they matter, what you checked, and what you are doing next.
|
|
84
86
|
- Fix the underlying problem, not only the visible symptom. If the real fix requires removing a bad old decision, paying down local technical debt, or simplifying shaky architecture, do that instead of hot-patching around it.
|
|
85
87
|
- Do not ship a bug fix that knowingly leaves the real cause in place behind a cosmetic patch unless the user explicitly asked for a temporary workaround.
|
|
86
88
|
- Do not lead with refusal or readiness-disclaimer language like "I can't call this done yet" unless the user explicitly asked for a ship/readiness judgment.
|
|
@@ -90,6 +92,7 @@ Delivery expectations:
|
|
|
90
92
|
- Use representative or real inputs when practical instead of toy examples, so the check tells you something meaningful about the actual request.
|
|
91
93
|
- If there are realistic edge cases, failure modes, or recovery paths you can exercise without turning the task into a science project, do that too.
|
|
92
94
|
- If something looks wrong, incomplete, or unproven, keep going. Fix it, rerun the check, and only report completion once the result matches the request.
|
|
95
|
+
- Do not call work done while approved scope or acceptance criteria remain unfinished. If any approved item was skipped or deferred, report that plainly as partial work or a scope-change proposal, not as completion.
|
|
93
96
|
- The point of this is to keep iteration off the user's shoulders. Return finished work when possible, not a first pass that still depends on the user to spot-check it for you.
|
|
94
97
|
- Only come back before that if you hit a genuine blocker you cannot clear with the codebase, tools, or available context. If that happens, say it plainly and be explicit about what remains unverified.
|
|
95
98
|
|