codex-coach 0.1.0 → 0.1.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.
@@ -67,6 +67,8 @@ def render_markdown_report(
67
67
  else:
68
68
  lines.append("No project capsules available.")
69
69
 
70
+ lines.extend(_instruction_playbook_lines(facts.get("instruction_audit", {}), expert=expert))
71
+
70
72
  lines.extend(["", "## Prompt Quality", ""])
71
73
  categories = prompt_quality.get("categories", {})
72
74
  if categories:
@@ -202,6 +204,19 @@ def build_suggestions(facts: dict[str, Any]) -> list[dict[str, str]]:
202
204
  }
203
205
  )
204
206
 
207
+ instruction_audit = facts.get("instruction_audit", {})
208
+ instruction_findings = instruction_audit.get("findings", []) if isinstance(instruction_audit, dict) else []
209
+ if instruction_findings:
210
+ high = any(item.get("severity") == "high" for item in instruction_findings if isinstance(item, dict))
211
+ suggestions.append(
212
+ {
213
+ "id": "review-instruction-playbook",
214
+ "title": "Review instruction playbook",
215
+ "confidence": "high" if high else "medium",
216
+ "body": "Instruction files have review findings. Check for stale mode locks, project-specific global rules, missing AGENTS.md coverage, or secrets before changing user instructions.",
217
+ }
218
+ )
219
+
205
220
  if not suggestions:
206
221
  suggestions.append(
207
222
  {
@@ -242,13 +257,91 @@ def write_suggestion_files(facts: dict[str, Any], suggestions_dir: Path) -> list
242
257
  text = _render_suggestion_patch(suggestion)
243
258
  path.write_text(text, encoding="utf-8")
244
259
  written.append(path)
260
+ written.extend(write_instruction_suggestion_files(facts.get("instruction_audit", {}), suggestions_dir))
245
261
  return written
246
262
 
247
263
 
264
+ def write_instruction_suggestion_files(instruction_audit: dict[str, Any], suggestions_dir: Path) -> list[Path]:
265
+ suggestions_dir.mkdir(parents=True, exist_ok=True)
266
+ written: list[Path] = []
267
+ if not isinstance(instruction_audit, dict):
268
+ return written
269
+ for suggestion in instruction_audit.get("suggestions", []):
270
+ if not isinstance(suggestion, dict):
271
+ continue
272
+ suggestion_id = str(suggestion.get("id") or "instruction-suggestion")
273
+ path = suggestions_dir / f"instruction-{suggestion_id}.patch.md"
274
+ path.write_text(_render_instruction_suggestion_patch(suggestion), encoding="utf-8")
275
+ written.append(path)
276
+ return written
277
+
278
+
279
+ def render_instruction_report(instruction_audit: dict[str, Any], *, generated_at: datetime | None = None) -> str:
280
+ generated_at = generated_at or datetime.now(UTC)
281
+ lines = [
282
+ "# Codex Coach Instruction Playbook Report",
283
+ "",
284
+ f"Generated: {generated_at.isoformat(timespec='seconds')}",
285
+ f"Window: {instruction_audit.get('since') or 'all available local logs'}",
286
+ ]
287
+ lines.extend(_instruction_playbook_lines(instruction_audit, expert=True))
288
+ lines.extend(
289
+ [
290
+ "",
291
+ "## Privacy",
292
+ "",
293
+ "Instruction files are analyzed locally. Reports use file hashes, project labels, and review categories instead of raw instruction text.",
294
+ "",
295
+ ]
296
+ )
297
+ return "\n".join(lines)
298
+
299
+
248
300
  def _coaching_notes(suggestions: list[dict[str, str]], *, limit: int) -> list[str]:
249
301
  return [f"- [{item['confidence']}] {item['title']}: {item['body']}" for item in suggestions[:limit]]
250
302
 
251
303
 
304
+ def _instruction_playbook_lines(instruction_audit: dict[str, Any], *, expert: bool) -> list[str]:
305
+ lines = ["", "## Instruction Playbook", ""]
306
+ if not isinstance(instruction_audit, dict) or not instruction_audit:
307
+ lines.append("No instruction audit was generated.")
308
+ return lines
309
+
310
+ lines.append(f"- Status: {instruction_audit.get('status', 'unknown')}")
311
+ lines.append(f"- Files reviewed: {instruction_audit.get('files_reviewed', 0)}")
312
+ lines.append(f"- Findings: {len(instruction_audit.get('findings', []))}")
313
+ lines.append(f"- Reviewable suggestions: {len(instruction_audit.get('suggestions', []))}")
314
+
315
+ findings = [item for item in instruction_audit.get("findings", []) if isinstance(item, dict)]
316
+ if findings:
317
+ lines.extend(["", "Top playbook findings:"])
318
+ for item in findings[: 8 if expert else 4]:
319
+ lines.append(
320
+ f"- [{item.get('severity', 'info')}] {item.get('title')}: "
321
+ f"{item.get('body')} Target: `{item.get('target', 'unknown')}`"
322
+ )
323
+ else:
324
+ lines.extend(["", "No instruction playbook issues stood out."])
325
+
326
+ suggestions = [item for item in instruction_audit.get("suggestions", []) if isinstance(item, dict)]
327
+ if suggestions:
328
+ lines.extend(["", "Suggested playbook changes:"])
329
+ for item in suggestions[: 8 if expert else 4]:
330
+ lines.append(f"- [{item.get('confidence', 'medium')}] {item.get('title')}: {item.get('body')}")
331
+
332
+ if expert:
333
+ files = [item for item in instruction_audit.get("files", []) if isinstance(item, dict)]
334
+ if files:
335
+ lines.extend(["", "Reviewed files:"])
336
+ for item in files[:10]:
337
+ projects = ", ".join(item.get("project_labels", [])) or "global"
338
+ lines.append(
339
+ f"- `{item.get('file')}` scope={item.get('scope')} hash={item.get('file_hash')} "
340
+ f"lines={item.get('lines', 0)} projects={projects}"
341
+ )
342
+ return lines
343
+
344
+
252
345
  def _render_suggestion_patch(suggestion: dict[str, str]) -> str:
253
346
  return "\n".join(
254
347
  [
@@ -276,6 +369,38 @@ def _render_suggestion_patch(suggestion: dict[str, str]) -> str:
276
369
  )
277
370
 
278
371
 
372
+ def _render_instruction_suggestion_patch(suggestion: dict[str, Any]) -> str:
373
+ suggested_text = str(suggestion.get("suggested_text") or suggestion.get("body") or "")
374
+ return "\n".join(
375
+ [
376
+ f"# Instruction Playbook Suggestion: {suggestion.get('title', 'Review instruction')}",
377
+ "",
378
+ "Review this suggestion before applying it. Codex Coach never edits custom instructions or AGENTS.md automatically.",
379
+ "",
380
+ "## Target",
381
+ "",
382
+ f"- Scope: {suggestion.get('scope', 'unknown')}",
383
+ f"- Target: {suggestion.get('target', 'unknown')}",
384
+ f"- Confidence: {suggestion.get('confidence', 'medium')}",
385
+ "",
386
+ "## Why",
387
+ "",
388
+ str(suggestion.get("body") or ""),
389
+ "",
390
+ "## Suggested Text",
391
+ "",
392
+ "```md",
393
+ suggested_text,
394
+ "```",
395
+ "",
396
+ "## Rollback",
397
+ "",
398
+ str(suggestion.get("rollback") or "Remove the added instruction if it does not improve the workflow."),
399
+ "",
400
+ ]
401
+ )
402
+
403
+
279
404
  def _confidence(value: float, *, high: float, medium: float) -> str:
280
405
  if value >= high:
281
406
  return "high"
@@ -1,49 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-labelledby="title desc">
2
- <title id="title">Codex Coach icon</title>
3
- <desc id="desc">A loud neon square logo with a terminal prompt, target ring, and lightning bolt.</desc>
4
- <defs>
5
- <linearGradient id="bg" x1="80" y1="80" x2="944" y2="944" gradientUnits="userSpaceOnUse">
6
- <stop offset="0" stop-color="#09090b"/>
7
- <stop offset="0.44" stop-color="#111827"/>
8
- <stop offset="1" stop-color="#020617"/>
9
- </linearGradient>
10
- <linearGradient id="hot" x1="116" y1="122" x2="914" y2="900" gradientUnits="userSpaceOnUse">
11
- <stop offset="0" stop-color="#f97316"/>
12
- <stop offset="0.38" stop-color="#facc15"/>
13
- <stop offset="0.65" stop-color="#22c55e"/>
14
- <stop offset="1" stop-color="#ec4899"/>
15
- </linearGradient>
16
- <linearGradient id="bolt" x1="453" y1="196" x2="679" y2="769" gradientUnits="userSpaceOnUse">
17
- <stop offset="0" stop-color="#facc15"/>
18
- <stop offset="0.48" stop-color="#22c55e"/>
19
- <stop offset="1" stop-color="#06b6d4"/>
20
- </linearGradient>
21
- <filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
22
- <feGaussianBlur stdDeviation="18" result="blur"/>
23
- <feColorMatrix in="blur" type="matrix" values="0 0 0 0 0.15 0 0 0 0 1 0 0 0 0 0.48 0 0 0 0.8 0" result="greenGlow"/>
24
- <feMerge>
25
- <feMergeNode in="greenGlow"/>
26
- <feMergeNode in="SourceGraphic"/>
27
- </feMerge>
28
- </filter>
29
- <pattern id="grid" width="44" height="44" patternUnits="userSpaceOnUse">
30
- <path d="M44 0H0V44" fill="none" stroke="#334155" stroke-width="2" opacity="0.28"/>
31
- </pattern>
32
- <pattern id="stripes" width="48" height="48" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
33
- <rect width="16" height="48" fill="#f97316" opacity="0.9"/>
34
- <rect x="16" width="32" height="48" fill="#020617" opacity="0.65"/>
35
- </pattern>
36
- </defs>
37
- <rect width="1024" height="1024" rx="108" fill="url(#bg)"/>
38
- <rect x="36" y="36" width="952" height="952" rx="88" fill="none" stroke="url(#hot)" stroke-width="24"/>
39
- <rect x="70" y="70" width="884" height="884" rx="64" fill="url(#grid)" opacity="0.95"/>
40
- <path d="M92 186H932L887 270H137Z" fill="url(#stripes)" opacity="0.9"/>
41
- <path d="M114 802H910" stroke="#ec4899" stroke-width="20" stroke-linecap="round" opacity="0.85"/>
42
- <circle cx="512" cy="512" r="315" fill="#020617" stroke="#22c55e" stroke-width="16" opacity="0.94"/>
43
- <circle cx="512" cy="512" r="226" fill="none" stroke="#facc15" stroke-width="10" stroke-dasharray="24 18" opacity="0.95"/>
44
- <circle cx="512" cy="512" r="126" fill="none" stroke="#ec4899" stroke-width="10" opacity="0.9"/>
45
- <path d="M442 198L334 559H488L430 828L706 430H548L604 198Z" fill="url(#bolt)" filter="url(#glow)"/>
46
- <path d="M247 386L342 478L247 570" fill="none" stroke="#f8fafc" stroke-width="52" stroke-linecap="round" stroke-linejoin="round"/>
47
- <path d="M647 621H817" stroke="#f8fafc" stroke-width="52" stroke-linecap="round"/>
48
- <text x="512" y="936" text-anchor="middle" font-family="Arial Black, Impact, sans-serif" font-size="72" font-weight="900" fill="#f8fafc" letter-spacing="6">COACH</text>
49
- </svg>
@@ -1,62 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630" role="img" aria-labelledby="title desc">
2
- <title id="title">Codex Coach wide logo</title>
3
- <desc id="desc">A bold neon brand banner for Codex Coach with a terminal icon and coaching workflow tagline.</desc>
4
- <defs>
5
- <linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
6
- <stop offset="0" stop-color="#030712"/>
7
- <stop offset="0.48" stop-color="#111827"/>
8
- <stop offset="1" stop-color="#020617"/>
9
- </linearGradient>
10
- <linearGradient id="blast" x1="92" y1="70" x2="1120" y2="562" gradientUnits="userSpaceOnUse">
11
- <stop offset="0" stop-color="#f97316"/>
12
- <stop offset="0.24" stop-color="#facc15"/>
13
- <stop offset="0.52" stop-color="#22c55e"/>
14
- <stop offset="0.78" stop-color="#06b6d4"/>
15
- <stop offset="1" stop-color="#ec4899"/>
16
- </linearGradient>
17
- <linearGradient id="textHot" x1="462" y1="147" x2="1120" y2="366" gradientUnits="userSpaceOnUse">
18
- <stop offset="0" stop-color="#f8fafc"/>
19
- <stop offset="0.55" stop-color="#bbf7d0"/>
20
- <stop offset="1" stop-color="#f9a8d4"/>
21
- </linearGradient>
22
- <filter id="glow" x="-20%" y="-40%" width="140%" height="180%">
23
- <feGaussianBlur stdDeviation="12" result="blur"/>
24
- <feMerge>
25
- <feMergeNode in="blur"/>
26
- <feMergeNode in="SourceGraphic"/>
27
- </feMerge>
28
- </filter>
29
- <pattern id="grid" width="38" height="38" patternUnits="userSpaceOnUse">
30
- <path d="M38 0H0V38" fill="none" stroke="#475569" stroke-width="1.4" opacity="0.28"/>
31
- </pattern>
32
- <pattern id="stripes" width="42" height="42" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
33
- <rect width="14" height="42" fill="#f97316" opacity="0.9"/>
34
- <rect x="14" width="28" height="42" fill="#020617" opacity="0.55"/>
35
- </pattern>
36
- </defs>
37
- <rect width="1200" height="630" rx="0" fill="url(#bg)"/>
38
- <rect width="1200" height="630" fill="url(#grid)"/>
39
- <path d="M0 0H1200V104H0Z" fill="url(#stripes)" opacity="0.82"/>
40
- <path d="M0 526H1200V630H0Z" fill="url(#stripes)" opacity="0.5"/>
41
- <rect x="42" y="44" width="1116" height="542" rx="30" fill="none" stroke="url(#blast)" stroke-width="8"/>
42
- <circle cx="245" cy="314" r="184" fill="#020617" stroke="#22c55e" stroke-width="12"/>
43
- <circle cx="245" cy="314" r="126" fill="none" stroke="#facc15" stroke-width="7" stroke-dasharray="20 14"/>
44
- <path d="M209 136L142 350H241L203 501L382 255H282L318 136Z" fill="#facc15" filter="url(#glow)"/>
45
- <path d="M104 268L174 332L104 396" fill="none" stroke="#f8fafc" stroke-width="37" stroke-linecap="round" stroke-linejoin="round"/>
46
- <path d="M279 402H405" stroke="#f8fafc" stroke-width="37" stroke-linecap="round"/>
47
- <text x="480" y="252" font-family="Arial Black, Impact, sans-serif" font-size="110" font-weight="900" fill="url(#textHot)" letter-spacing="2">CODEX</text>
48
- <text x="480" y="358" font-family="Arial Black, Impact, sans-serif" font-size="110" font-weight="900" fill="#22c55e" letter-spacing="3" filter="url(#glow)">COACH</text>
49
- <text x="485" y="422" font-family="Arial, Helvetica, sans-serif" font-size="28" font-weight="800" fill="#f8fafc" letter-spacing="5">LOCAL-FIRST USAGE COACH</text>
50
- <g font-family="Arial Black, Impact, sans-serif" font-size="24" font-weight="900">
51
- <rect x="482" y="462" width="154" height="50" rx="8" fill="#22c55e"/>
52
- <text x="559" y="496" text-anchor="middle" fill="#020617">SCAN</text>
53
- <path d="M650 487H718" stroke="#facc15" stroke-width="8" stroke-linecap="round"/>
54
- <path d="M718 487L697 469V505Z" fill="#facc15"/>
55
- <rect x="737" y="462" width="174" height="50" rx="8" fill="#facc15"/>
56
- <text x="824" y="496" text-anchor="middle" fill="#020617">REPORT</text>
57
- <path d="M925 487H993" stroke="#ec4899" stroke-width="8" stroke-linecap="round"/>
58
- <path d="M993 487L972 469V505Z" fill="#ec4899"/>
59
- <rect x="1011" y="462" width="104" height="50" rx="8" fill="#ec4899"/>
60
- <text x="1063" y="496" text-anchor="middle" fill="#fff">LEVEL UP</text>
61
- </g>
62
- </svg>
Binary file
@@ -1,71 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1400" height="760" viewBox="0 0 1400 760" role="img" aria-labelledby="title desc">
2
- <title id="title">How Codex Coach works</title>
3
- <desc id="desc">A four-step workflow showing local Codex logs becoming a redacted report and reviewable suggestions.</desc>
4
- <defs>
5
- <linearGradient id="bg" x1="0" y1="0" x2="1400" y2="760" gradientUnits="userSpaceOnUse">
6
- <stop offset="0" stop-color="#020617"/>
7
- <stop offset="1" stop-color="#111827"/>
8
- </linearGradient>
9
- <linearGradient id="hot" x1="110" y1="110" x2="1288" y2="640" gradientUnits="userSpaceOnUse">
10
- <stop offset="0" stop-color="#f97316"/>
11
- <stop offset="0.38" stop-color="#22c55e"/>
12
- <stop offset="0.72" stop-color="#06b6d4"/>
13
- <stop offset="1" stop-color="#ec4899"/>
14
- </linearGradient>
15
- <filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
16
- <feGaussianBlur stdDeviation="10" result="blur"/>
17
- <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
18
- </filter>
19
- <style>
20
- .title{font:900 52px Arial Black,Impact,sans-serif;fill:#f8fafc;letter-spacing:1px}
21
- .label{font:900 30px Arial Black,Impact,sans-serif;fill:#f8fafc}
22
- .body{font:700 23px Arial,Helvetica,sans-serif;fill:#cbd5e1}
23
- .mono{font:700 22px ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;fill:#bbf7d0}
24
- .card{fill:#030712;stroke:#334155;stroke-width:3}
25
- </style>
26
- </defs>
27
- <rect width="1400" height="760" fill="url(#bg)"/>
28
- <rect x="32" y="32" width="1336" height="696" rx="26" fill="none" stroke="url(#hot)" stroke-width="7"/>
29
- <text x="76" y="104" class="title">RAW LOGS -&gt; BETTER CODEX SESSIONS</text>
30
- <g transform="translate(82 176)">
31
- <rect class="card" width="260" height="368" rx="12"/>
32
- <rect x="0" y="0" width="260" height="10" fill="#f97316"/>
33
- <text x="28" y="62" class="label">1. LOCAL LOGS</text>
34
- <text x="28" y="112" class="mono">~/.codex/sessions</text>
35
- <text x="28" y="150" class="mono">archived_sessions</text>
36
- <path d="M34 210H226M34 250H180M34 290H216" stroke="#64748b" stroke-width="10" stroke-linecap="round"/>
37
- <text x="28" y="340" class="body">No cloud account.</text>
38
- </g>
39
- <path d="M372 360H472" stroke="#facc15" stroke-width="11" stroke-linecap="round" filter="url(#glow)"/>
40
- <path d="M472 360L441 334V386Z" fill="#facc15"/>
41
- <g transform="translate(502 176)">
42
- <rect class="card" width="260" height="368" rx="12"/>
43
- <rect x="0" y="0" width="260" height="10" fill="#22c55e"/>
44
- <text x="28" y="62" class="label">2. SCAN</text>
45
- <text x="28" y="112" class="mono">codex-coach</text>
46
- <text x="28" y="150" class="mono">report --since 7d</text>
47
- <circle cx="130" cy="248" r="72" fill="none" stroke="#22c55e" stroke-width="12"/>
48
- <path d="M101 248L126 273L171 219" fill="none" stroke="#f8fafc" stroke-width="14" stroke-linecap="round" stroke-linejoin="round"/>
49
- <text x="28" y="340" class="body">Deterministic parser.</text>
50
- </g>
51
- <path d="M792 360H892" stroke="#06b6d4" stroke-width="11" stroke-linecap="round" filter="url(#glow)"/>
52
- <path d="M892 360L861 334V386Z" fill="#06b6d4"/>
53
- <g transform="translate(922 176)">
54
- <rect class="card" width="260" height="368" rx="12"/>
55
- <rect x="0" y="0" width="260" height="10" fill="#06b6d4"/>
56
- <text x="28" y="62" class="label">3. REPORT</text>
57
- <text x="28" y="112" class="body">Prompt quality</text>
58
- <text x="28" y="150" class="body">Verification habits</text>
59
- <text x="28" y="188" class="body">Project capsules</text>
60
- <rect x="30" y="228" width="200" height="24" fill="#22c55e"/>
61
- <rect x="30" y="270" width="150" height="24" fill="#facc15"/>
62
- <rect x="30" y="312" width="96" height="24" fill="#ec4899"/>
63
- </g>
64
- <path d="M1212 360H1290" stroke="#ec4899" stroke-width="11" stroke-linecap="round" filter="url(#glow)"/>
65
- <path d="M1290 360L1259 334V386Z" fill="#ec4899"/>
66
- <g transform="translate(1090 594)">
67
- <rect x="-16" y="-16" width="244" height="82" rx="10" fill="#ec4899"/>
68
- <text x="106" y="34" text-anchor="middle" font-family="Arial Black,Impact,sans-serif" font-size="28" fill="#fff">LEVEL UP</text>
69
- </g>
70
- <text x="82" y="662" font-family="Arial,Helvetica,sans-serif" font-size="30" font-weight="900" fill="#f8fafc">Output: redacted facts, weekly report, and review-only config suggestions.</text>
71
- </svg>
@@ -1,59 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1400" height="760" viewBox="0 0 1400 760" role="img" aria-labelledby="title desc">
2
- <title id="title">Project capsules example</title>
3
- <desc id="desc">A dashboard-style illustration of Codex Coach project capsules and suggested local instructions.</desc>
4
- <defs>
5
- <linearGradient id="bg" x1="0" y1="0" x2="1400" y2="760" gradientUnits="userSpaceOnUse">
6
- <stop offset="0" stop-color="#020617"/>
7
- <stop offset="0.55" stop-color="#0f172a"/>
8
- <stop offset="1" stop-color="#111827"/>
9
- </linearGradient>
10
- <linearGradient id="hot" x1="70" y1="80" x2="1320" y2="690" gradientUnits="userSpaceOnUse">
11
- <stop offset="0" stop-color="#22c55e"/>
12
- <stop offset="0.5" stop-color="#06b6d4"/>
13
- <stop offset="1" stop-color="#ec4899"/>
14
- </linearGradient>
15
- <style>
16
- .title{font:900 56px Arial Black,Impact,sans-serif;fill:#f8fafc}
17
- .label{font:900 30px Arial Black,Impact,sans-serif;fill:#f8fafc}
18
- .body{font:800 24px Arial,Helvetica,sans-serif;fill:#cbd5e1}
19
- .mono{font:800 23px ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;fill:#bbf7d0}
20
- </style>
21
- </defs>
22
- <rect width="1400" height="760" fill="url(#bg)"/>
23
- <rect x="36" y="36" width="1328" height="688" rx="24" fill="none" stroke="url(#hot)" stroke-width="7"/>
24
- <text x="74" y="108" class="title">PROJECT CAPSULES: MEMORY AT A GLANCE</text>
25
- <g transform="translate(74 176)">
26
- <rect width="382" height="420" rx="12" fill="#030712" stroke="#22c55e" stroke-width="4"/>
27
- <rect x="0" y="0" width="382" height="12" fill="#22c55e"/>
28
- <text x="28" y="62" class="label">referiate [hash]</text>
29
- <text x="28" y="114" class="body">Workflow</text>
30
- <text x="28" y="152" class="mono">terminal diagnosis</text>
31
- <text x="28" y="218" class="body">Habit found</text>
32
- <text x="28" y="256" class="mono">verify live endpoint</text>
33
- <text x="28" y="322" class="body">Suggested instruction</text>
34
- <path d="M28 356H332M28 388H282" stroke="#22c55e" stroke-width="10" stroke-linecap="round"/>
35
- </g>
36
- <g transform="translate(510 176)">
37
- <rect width="382" height="420" rx="12" fill="#030712" stroke="#06b6d4" stroke-width="4"/>
38
- <rect x="0" y="0" width="382" height="12" fill="#06b6d4"/>
39
- <text x="28" y="62" class="label">app-ui [hash]</text>
40
- <text x="28" y="114" class="body">Workflow</text>
41
- <text x="28" y="152" class="mono">browser verification</text>
42
- <text x="28" y="218" class="body">Habit found</text>
43
- <text x="28" y="256" class="mono">screenshots help</text>
44
- <text x="28" y="322" class="body">Suggested instruction</text>
45
- <path d="M28 356H320M28 388H240" stroke="#06b6d4" stroke-width="10" stroke-linecap="round"/>
46
- </g>
47
- <g transform="translate(946 176)">
48
- <rect width="382" height="420" rx="12" fill="#030712" stroke="#ec4899" stroke-width="4"/>
49
- <rect x="0" y="0" width="382" height="12" fill="#ec4899"/>
50
- <text x="28" y="62" class="label">long-run [hash]</text>
51
- <text x="28" y="114" class="body">Workflow</text>
52
- <text x="28" y="152" class="mono">multi-step assets</text>
53
- <text x="28" y="218" class="body">Habit found</text>
54
- <text x="28" y="256" class="mono">checkpoint often</text>
55
- <text x="28" y="322" class="body">Skill opportunity</text>
56
- <path d="M28 356H328M28 388H262" stroke="#ec4899" stroke-width="10" stroke-linecap="round"/>
57
- </g>
58
- <text x="74" y="666" font-family="Arial,Helvetica,sans-serif" font-size="30" font-weight="900" fill="#f8fafc">Review snippets first. Codex Coach never auto-edits AGENTS.md.</text>
59
- </svg>
Binary file
@@ -1,54 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1400" height="760" viewBox="0 0 1400 760" role="img" aria-labelledby="title desc">
2
- <title id="title">Prompt lint example</title>
3
- <desc id="desc">A before and after example showing a vague Codex prompt being rewritten into a clearer prompt.</desc>
4
- <defs>
5
- <linearGradient id="bg" x1="0" y1="0" x2="1400" y2="760" gradientUnits="userSpaceOnUse">
6
- <stop offset="0" stop-color="#09090b"/>
7
- <stop offset="1" stop-color="#020617"/>
8
- </linearGradient>
9
- <filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
10
- <feGaussianBlur stdDeviation="9" result="blur"/>
11
- <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
12
- </filter>
13
- <style>
14
- .title{font:900 58px Arial Black,Impact,sans-serif;fill:#f8fafc}
15
- .label{font:900 34px Arial Black,Impact,sans-serif;fill:#f8fafc}
16
- .mono{font:800 29px ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
17
- .body{font:800 28px Arial,Helvetica,sans-serif;fill:#e2e8f0}
18
- .small{font:800 22px Arial,Helvetica,sans-serif;fill:#94a3b8}
19
- </style>
20
- </defs>
21
- <rect width="1400" height="760" fill="url(#bg)"/>
22
- <rect x="36" y="36" width="1328" height="688" rx="24" fill="none" stroke="#22c55e" stroke-width="7"/>
23
- <text x="74" y="112" class="title">PROMPT LINT: MAKE THE ASK UNMISSABLE</text>
24
- <g transform="translate(74 186)">
25
- <rect width="346" height="368" rx="14" fill="#18080b" stroke="#ef4444" stroke-width="5"/>
26
- <rect x="24" y="24" width="116" height="42" rx="6" fill="#ef4444"/>
27
- <text x="82" y="55" text-anchor="middle" font-family="Arial Black,Impact,sans-serif" font-size="24" fill="#fff">BEFORE</text>
28
- <text x="34" y="138" class="mono" fill="#fecaca">fix</text>
29
- <path d="M34 208H300M34 254H246M34 300H278" stroke="#7f1d1d" stroke-width="12" stroke-linecap="round"/>
30
- <text x="34" y="342" class="small">Missing target and success state</text>
31
- </g>
32
- <path d="M454 370H574" stroke="#facc15" stroke-width="13" stroke-linecap="round" filter="url(#glow)"/>
33
- <path d="M574 370L535 338V402Z" fill="#facc15"/>
34
- <g transform="translate(610 186)">
35
- <rect width="238" height="368" rx="14" fill="#141006" stroke="#facc15" stroke-width="5"/>
36
- <circle cx="119" cy="144" r="76" fill="none" stroke="#facc15" stroke-width="12"/>
37
- <path d="M86 144H152M119 111V177" stroke="#facc15" stroke-width="11" stroke-linecap="round"/>
38
- <text x="119" y="270" text-anchor="middle" class="label">LINT</text>
39
- <text x="119" y="316" text-anchor="middle" class="small">score + rewrite</text>
40
- </g>
41
- <path d="M882 370H1002" stroke="#22c55e" stroke-width="13" stroke-linecap="round" filter="url(#glow)"/>
42
- <path d="M1002 370L963 338V402Z" fill="#22c55e"/>
43
- <g transform="translate(1038 186)">
44
- <rect width="286" height="368" rx="14" fill="#03150b" stroke="#22c55e" stroke-width="5"/>
45
- <rect x="24" y="24" width="98" height="42" rx="6" fill="#22c55e"/>
46
- <text x="73" y="55" text-anchor="middle" font-family="Arial Black,Impact,sans-serif" font-size="24" fill="#020617">AFTER</text>
47
- <text x="30" y="124" class="mono" fill="#bbf7d0">Fix login in</text>
48
- <text x="30" y="164" class="mono" fill="#bbf7d0">auth.py because</text>
49
- <text x="30" y="204" class="mono" fill="#bbf7d0">401 appears.</text>
50
- <text x="30" y="264" class="mono" fill="#bbf7d0">Success means</text>
51
- <text x="30" y="304" class="mono" fill="#bbf7d0">pytest passes.</text>
52
- </g>
53
- <text x="74" y="646" class="body">Command: codex-coach lint-prompt "fix"</text>
54
- </svg>