@haposoft/cafekit 0.16.7 → 0.18.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.
Files changed (193) hide show
  1. package/README.md +14 -22
  2. package/bin/__tests__/codex-hooks-ownership.test.js +2 -2
  3. package/bin/__tests__/codex-hooks.test.js +0 -36
  4. package/bin/__tests__/codex-native.test.js +46 -88
  5. package/bin/__tests__/develop-contract.test.js +26 -57
  6. package/bin/__tests__/docs-sync-on-demand.test.js +93 -0
  7. package/bin/__tests__/grok-envelope.test.js +0 -56
  8. package/bin/__tests__/hook-payload.test.js +4 -6
  9. package/bin/__tests__/legacy-authority-decoupled.test.js +159 -0
  10. package/bin/__tests__/legacy-hooks-retired.test.js +221 -0
  11. package/bin/__tests__/omp-bridge.test.js +20 -17
  12. package/bin/__tests__/omp-hooks.test.js +0 -19
  13. package/bin/__tests__/optional-skill-inventory.test.js +112 -4
  14. package/bin/__tests__/orca-session.test.js +0 -2
  15. package/bin/__tests__/package-inventory.test.js +100 -541
  16. package/bin/__tests__/runtime-dir.test.js +0 -3
  17. package/bin/__tests__/runtime-schema.test.js +3 -2
  18. package/bin/__tests__/skill-routing-source.test.js +27 -15
  19. package/bin/__tests__/spec-narrowing.test.js +0 -27
  20. package/bin/__tests__/specs-v2-execution-closeout.test.js +4 -69
  21. package/bin/__tests__/ui-ux-skill.test.js +101 -0
  22. package/bin/__tests__/usage-hook-retired.test.js +114 -0
  23. package/bin/__tests__/validator-grounding.test.js +9 -28
  24. package/bin/phases/codex-runtime.js +24 -0
  25. package/bin/phases/omp-runtime.js +22 -0
  26. package/package.json +1 -1
  27. package/src/claude/CLAUDE.md +3 -10
  28. package/src/claude/agents/brainstormer.md +7 -3
  29. package/src/claude/agents/code-auditor.md +35 -50
  30. package/src/claude/agents/debugger.md +5 -79
  31. package/src/claude/agents/deployer.md +3 -5
  32. package/src/claude/agents/docs-keeper.md +2 -7
  33. package/src/claude/agents/implementer.md +6 -9
  34. package/src/claude/agents/inspector.md +2 -3
  35. package/src/claude/agents/project-manager.md +7 -15
  36. package/src/claude/agents/researcher.md +9 -3
  37. package/src/claude/agents/spec-maker.md +11 -11
  38. package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -1
  39. package/src/claude/hooks/__tests__/spec-gate.test.js +74 -3
  40. package/src/claude/hooks/__tests__/spec-state-touched.test.js +134 -0
  41. package/src/claude/hooks/__tests__/state.test.js +68 -0
  42. package/src/claude/hooks/__tests__/statusline.test.js +140 -11
  43. package/src/claude/hooks/agent.cjs +2 -1
  44. package/src/claude/hooks/lib/context.cjs +0 -89
  45. package/src/claude/hooks/lib/hook-payload.cjs +2 -2
  46. package/src/claude/hooks/rules.cjs +2 -1
  47. package/src/claude/hooks/session.cjs +0 -1
  48. package/src/claude/hooks/spec-gate.cjs +17 -28
  49. package/src/claude/hooks/spec-state.cjs +95 -1
  50. package/src/claude/hooks/state.cjs +21 -2
  51. package/src/claude/migration-manifest.json +30 -15
  52. package/src/claude/rules/ai-dev-rules.md +1 -1
  53. package/src/claude/rules/hook-protocols.md +8 -15
  54. package/src/claude/rules/manage-docs.md +9 -23
  55. package/src/claude/rules/orchestrator.md +3 -4
  56. package/src/claude/rules/review-audit-self-decision.md +3 -3
  57. package/src/claude/rules/skill-domain-routing.md +1 -3
  58. package/src/claude/rules/skill-workflow-routing.md +4 -5
  59. package/src/claude/rules/state-sync.md +3 -12
  60. package/src/claude/rules/workflow.md +10 -18
  61. package/src/claude/runtime.schema.json +5 -3
  62. package/src/claude/scripts/generate-skill-catalog.cjs +7 -6
  63. package/src/claude/scripts/provenance.cjs +23 -5
  64. package/src/claude/scripts/spec-receipt.cjs +24 -7
  65. package/src/claude/scripts/spec-resolver.cjs +1 -2
  66. package/src/claude/scripts/validate-spec-output.cjs +5 -32
  67. package/src/claude/settings/settings.json +1 -32
  68. package/src/claude/skills/{question → ask}/SKILL.md +9 -75
  69. package/src/claude/skills/brainstorm/SKILL.md +43 -131
  70. package/src/claude/skills/code-review/SKILL.md +48 -17
  71. package/src/claude/skills/code-review/references/spec-compliance-review.md +2 -3
  72. package/src/claude/skills/code-review/references/verification-gate.md +22 -27
  73. package/src/claude/skills/debug/SKILL.md +29 -149
  74. package/src/claude/skills/develop/SKILL.md +27 -36
  75. package/src/claude/skills/develop/references/parallel-waves.md +0 -8
  76. package/src/claude/skills/develop/references/quality-gate.md +15 -13
  77. package/src/claude/skills/docs/SKILL.md +2 -2
  78. package/src/claude/skills/docs/references/update-workflow.md +1 -1
  79. package/src/claude/skills/fix/SKILL.md +153 -0
  80. package/src/claude/skills/{hotfix → fix}/references/diagnosis-protocol.md +2 -2
  81. package/src/claude/skills/{hotfix → fix}/references/parallel-patterns.md +2 -2
  82. package/src/claude/skills/{hotfix → fix}/references/prevention-gate.md +3 -3
  83. package/src/claude/skills/{hotfix → fix}/references/review-cycle.md +1 -1
  84. package/src/claude/skills/git/SKILL.md +48 -9
  85. package/src/claude/skills/git/references/commit-protocols.md +35 -16
  86. package/src/claude/skills/git/references/worktree-blueprint.md +42 -6
  87. package/src/claude/skills/orca/SKILL.md +9 -8
  88. package/src/claude/skills/research/SKILL.md +2 -0
  89. package/src/claude/skills/scout/SKILL.md +61 -0
  90. package/src/claude/skills/{inspect → scout}/references/internal-inspection.md +26 -10
  91. package/src/claude/skills/specs/SKILL.md +22 -29
  92. package/src/claude/skills/specs/references/review.md +8 -6
  93. package/src/claude/skills/specs/references/templates.md +34 -41
  94. package/src/claude/skills/sync/SKILL.md +8 -15
  95. package/src/claude/skills/sync/references/rebind-and-audit.md +59 -0
  96. package/src/claude/skills/sync/references/sync-protocols.md +4 -13
  97. package/src/claude/skills/test/SKILL.md +22 -3
  98. package/src/claude/skills/test/references/execution-strategy.md +83 -0
  99. package/src/claude/skills/test/references/failure-triage.md +1 -1
  100. package/src/claude/skills/ui-ux/LICENSE +21 -0
  101. package/src/claude/skills/ui-ux/SKILL.md +497 -0
  102. package/src/claude/skills/ui-ux/references/brand-tokens.md +90 -0
  103. package/src/claude/skills/ui-ux/references/budgets.md +113 -0
  104. package/src/claude/skills/ui-ux/references/checklist.md +271 -0
  105. package/src/claude/skills/ui-ux/references/components/accordion.md +246 -0
  106. package/src/claude/skills/ui-ux/references/components/avatar.md +153 -0
  107. package/src/claude/skills/ui-ux/references/components/banner.md +43 -0
  108. package/src/claude/skills/ui-ux/references/components/breadcrumb.md +201 -0
  109. package/src/claude/skills/ui-ux/references/components/button.md +142 -0
  110. package/src/claude/skills/ui-ux/references/components/card.md +113 -0
  111. package/src/claude/skills/ui-ux/references/components/charts.md +376 -0
  112. package/src/claude/skills/ui-ux/references/components/chat.md +132 -0
  113. package/src/claude/skills/ui-ux/references/components/choice-controls.md +369 -0
  114. package/src/claude/skills/ui-ux/references/components/comment-thread.md +17 -0
  115. package/src/claude/skills/ui-ux/references/components/description-list.md +116 -0
  116. package/src/claude/skills/ui-ux/references/components/empty-state.md +98 -0
  117. package/src/claude/skills/ui-ux/references/components/file-upload.md +107 -0
  118. package/src/claude/skills/ui-ux/references/components/inline-edit.md +128 -0
  119. package/src/claude/skills/ui-ux/references/components/input.md +161 -0
  120. package/src/claude/skills/ui-ux/references/components/list-row.md +56 -0
  121. package/src/claude/skills/ui-ux/references/components/loading.md +198 -0
  122. package/src/claude/skills/ui-ux/references/components/logo.md +147 -0
  123. package/src/claude/skills/ui-ux/references/components/otp-input.md +43 -0
  124. package/src/claude/skills/ui-ux/references/components/quantity-input.md +100 -0
  125. package/src/claude/skills/ui-ux/references/components/range-slider.md +16 -0
  126. package/src/claude/skills/ui-ux/references/components/small-controls.md +340 -0
  127. package/src/claude/skills/ui-ux/references/components/sortable-header.md +86 -0
  128. package/src/claude/skills/ui-ux/references/components/tag-input.md +14 -0
  129. package/src/claude/skills/ui-ux/references/components/timeline.md +38 -0
  130. package/src/claude/skills/ui-ux/references/components/tree.md +30 -0
  131. package/src/claude/skills/ui-ux/references/design-process.md +650 -0
  132. package/src/claude/skills/ui-ux/references/layouts/app-kanban.html +303 -0
  133. package/src/claude/skills/ui-ux/references/layouts/app.md +1369 -0
  134. package/src/claude/skills/ui-ux/references/layouts/form.md +430 -0
  135. package/src/claude/skills/ui-ux/references/layouts/overlay.md +552 -0
  136. package/src/claude/skills/ui-ux/references/layouts/pricing.md +204 -0
  137. package/src/claude/skills/ui-ux/references/locked-rules.md +35 -0
  138. package/src/claude/skills/ui-ux/references/principles.md +408 -0
  139. package/src/claude/skills/ui-ux/references/refactor.md +245 -0
  140. package/src/claude/skills/ui-ux/references/responsive.md +195 -0
  141. package/src/claude/skills/ui-ux/references/review.md +528 -0
  142. package/src/claude/skills/ui-ux/references/rules-color.md +623 -0
  143. package/src/claude/skills/ui-ux/references/rules-form.md +235 -0
  144. package/src/claude/skills/ui-ux/references/rules-state.md +680 -0
  145. package/src/claude/skills/ui-ux/references/rules-type.md +369 -0
  146. package/src/claude/skills/ui-ux/references/styles.md +311 -0
  147. package/src/claude/skills/ui-ux/references/system.md +219 -0
  148. package/src/claude/skills/ui-ux/references/tailwind-v4-traps.md +237 -0
  149. package/src/claude/skills/ui-ux/references/tokens.css +362 -0
  150. package/src/claude/skills/ui-ux/scripts/lint-skill.mjs +216 -0
  151. package/src/claude/skills/ui-ux/scripts/package.json +9 -0
  152. package/src/claude/skills/ui-ux/scripts/probe.mjs +4447 -0
  153. package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
  154. package/src/claude/status.cjs +149 -144
  155. package/src/codex/AGENTS.md +8 -13
  156. package/src/codex/hooks/agent.cjs +2 -1
  157. package/src/codex/hooks/lib/spec-receipt.cjs +2 -2
  158. package/src/codex/hooks/lib/spec-utils.cjs +0 -7
  159. package/src/codex/hooks/rules.cjs +2 -1
  160. package/src/codex/hooks/session.cjs +0 -2
  161. package/src/codex/hooks/spec-gate.cjs +7 -18
  162. package/src/codex/hooks.json +0 -20
  163. package/src/codex/rules/state-sync.md +3 -12
  164. package/src/common/AGENTS.md +2 -2
  165. package/src/omp/extensions/cafekit-bridge.mjs +6 -6
  166. package/src/claude/hooks/__tests__/completion-authority.test.js +0 -990
  167. package/src/claude/hooks/__tests__/semantic-review-authority.test.js +0 -259
  168. package/src/claude/hooks/completion-authority-check.cjs +0 -56
  169. package/src/claude/hooks/completion-authority-state.cjs +0 -527
  170. package/src/claude/hooks/completion-authority.cjs +0 -163
  171. package/src/claude/hooks/semantic-review-authority.cjs +0 -154
  172. package/src/claude/hooks/task-scaffold-guard.cjs +0 -114
  173. package/src/claude/hooks/usage.cjs +0 -197
  174. package/src/claude/skills/delegate/SKILL.md +0 -124
  175. package/src/claude/skills/delegate/references/codex-delegation.md +0 -71
  176. package/src/claude/skills/delegate/references/grok-delegation.md +0 -84
  177. package/src/claude/skills/hotfix/SKILL.md +0 -289
  178. package/src/claude/skills/inspect/SKILL.md +0 -142
  179. package/src/claude/skills/loop/SKILL.md +0 -114
  180. package/src/claude/skills/loop/references/bounded-loop-protocol.md +0 -104
  181. package/src/claude/skills/loop/references/metric-and-guard-contract.md +0 -76
  182. package/src/claude/skills/route/SKILL.md +0 -94
  183. package/src/claude/skills/route/references/agent-timing.md +0 -46
  184. package/src/claude/skills/route/references/chaining-patterns.md +0 -53
  185. package/src/claude/skills/route/references/task-taxonomy.md +0 -48
  186. package/src/codex/hooks/completion-authority-check.cjs +0 -67
  187. package/src/codex/hooks/completion-authority-state.cjs +0 -527
  188. package/src/codex/hooks/completion-authority.cjs +0 -109
  189. package/src/codex/hooks/semantic-review-authority.cjs +0 -130
  190. package/src/codex/hooks/task-scaffold-guard.cjs +0 -63
  191. /package/src/claude/skills/{question → ask}/templates/question.md +0 -0
  192. /package/src/claude/skills/{hotfix → fix}/references/escalation-tactics.md +0 -0
  193. /package/src/claude/skills/{hotfix → fix}/references/workflow-specialized.md +0 -0
@@ -2,7 +2,7 @@
2
2
  name: cf:ui-ux-pro-max
3
3
  description: "UI/UX design intelligence for web and mobile. Includes 50+ styles, 161 color palettes, 57 font pairings, 161 product types, 99 UX guidelines, and 25 chart types across 10 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui, and HTML/CSS). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, and check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, and mobile app. Elements: button, modal, navbar, sidebar, card, table, form, and chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, and flat design. Topics: color systems, accessibility, animation, layout, typography, font pairing, spacing, interaction states, shadow, and gradient. Integrations: shadcn/ui MCP for component search and examples."
4
4
  user-invocable: true
5
- when_to_use: "Invoke to choose colors, fonts, layout, and design systems."
5
+ when_to_use: "Invoke to look up color palettes, font pairings, product-type styles, or UX guidelines; to build or review a screen use cf:ui-ux."
6
6
  category: frontend
7
7
  keywords: [ui, ux, design-system, layout]
8
8
  metadata:
@@ -2,7 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  /**
5
- * Custom Claude Code statusline for Node.js - Multi-line Edition
5
+ * Custom Claude Code statusline for Node.js - one-line default
6
6
  * Cross-platform support: Windows, macOS, Linux
7
7
  * Features: ANSI colors, tool/agent/todo tracking, context window, session timer
8
8
  * No external dependencies - uses only Node.js built-in modules
@@ -26,10 +26,6 @@ const { getGitInfo } = require('./hooks/lib/git.cjs');
26
26
  // ratio so 1M-context models are not treated as if they were 200k.
27
27
  const AUTOCOMPACT_BUFFER_RATIO = 0.225;
28
28
 
29
- // Usage cache freshness gate: a cache older than this hides the quota area
30
- // instead of rendering stale numbers.
31
- const USAGE_CACHE_TTL_MS = 300000;
32
-
33
29
  /**
34
30
  * Expand home directory to ~
35
31
  */
@@ -104,7 +100,7 @@ async function readStdin() {
104
100
  * @returns {string|null} Formatted usage string or null if unavailable
105
101
  */
106
102
  function buildUsageString(ctx) {
107
- if (!ctx.sessionText || ctx.sessionText === 'N/A') return null;
103
+ if (!ctx.sessionText) return null;
108
104
  let str = ctx.sessionText.replace(' until reset', ' left');
109
105
  if (ctx.usagePercent != null) str += ` (${Math.round(ctx.usagePercent)}%)`;
110
106
  return str;
@@ -130,77 +126,115 @@ function buildBranchPart(ctx) {
130
126
  return branchPart;
131
127
  }
132
128
 
133
- function renderSessionLines(ctx) {
134
- const lines = [];
135
- const termWidth = getTerminalWidth();
136
- const threshold = Math.floor(termWidth * 0.85);
129
+ // Default session line: one row of single-width symbols, each value labelled by
130
+ // its glyph so the line stays short and every number says what it measures.
131
+ // ◆ model (effort) ϟfast ✱thinking ◔ context% ⧗ 5h-quota% reset ◷ weekly% ⎇ branch ●changed ↑ahead ↓behind ± +added/-removed ⏱ session ↻ cache-hit%
132
+
133
+ /** Quarter-circle glyph that fills with the percentage. */
134
+ function fillGlyph(percent) {
135
+ if (percent >= 88) return '●';
136
+ if (percent >= 63) return '◕';
137
+ if (percent >= 38) return '◑';
138
+ if (percent >= 13) return '◔';
139
+ return '○';
140
+ }
137
141
 
138
- // Build all atomic parts for flexible composition (no colors on static text)
139
- const dirPart = `📁 ${ctx.currentDir}`;
140
- const branchPart = buildBranchPart(ctx);
142
+ /** Same thresholds as the context bar; plain text when colours are off. */
143
+ function tintPercent(percent, text) {
144
+ if (percent >= 85) return red(text);
145
+ if (percent >= 70) return yellow(text);
146
+ return green(text);
147
+ }
141
148
 
142
- // Active plan indicator (disabled for now - code preserved)
143
- // const planPart = ctx.activePlan ? `📋 ${ctx.activePlan}` : '';
144
- const planPart = '';
149
+ /** "2h 48m until reset" → "2h48m"; anything else → null. */
150
+ function shortReset(sessionText) {
151
+ const match = /^(\d+)h (\d+)m/.exec(sessionText || '');
152
+ return match ? `${match[1]}h${match[2]}m` : null;
153
+ }
145
154
 
146
- // Combined location (dir + branch + plan)
147
- let locationPart = branchPart ? `${dirPart} ${branchPart}` : dirPart;
148
- if (planPart) locationPart += ` ${planPart}`;
155
+ /** 28147114 → "7h49m"; under an hour → "12m". */
156
+ function formatDuration(ms) {
157
+ const minutes = Math.floor(ms / 60000);
158
+ const hours = Math.floor(minutes / 60);
159
+ return hours > 0 ? `${hours}h${String(minutes % 60).padStart(2, '0')}m` : `${minutes}m`;
160
+ }
161
+
162
+ /** "#80✓" approved, "#80✗" changes requested, "#80" pending, dim "#80" draft; "!80" for a GitLab MR. */
163
+ function formatPr(pr) {
164
+ const label = `${pr.kind === 'mr' ? '!' : '#'}${pr.number}`;
165
+ if (pr.review_state === 'approved') return `${label}${green('✓')}`;
166
+ if (pr.review_state === 'changes_requested') return `${label}${red('✗')}`;
167
+ if (pr.review_state === 'draft') return dim(label);
168
+ return label;
169
+ }
170
+
171
+ /**
172
+ * Parts of the default line in display order. `drop` ranks what goes first
173
+ * when the terminal is too narrow (higher drops earlier); 0 never drops.
174
+ */
175
+ function buildLineParts(ctx, { minimal = false } = {}) {
176
+ let model = `◆ ${ctx.modelName}`;
177
+ if (ctx.effortLevel) model += ` ${dim(`(${ctx.effortLevel})`)}`;
178
+ const flags = `${ctx.fastMode ? 'ϟ' : ''}${ctx.thinking ? '✱' : ''}`;
179
+ if (flags) model += ` ${flags}`;
180
+ const parts = [{ text: model, drop: 0 }];
149
181
 
150
- // Build session part: 🤖 model contextBar% ⌛ time left (usage%)
151
- let sessionPart = `🤖 ${ctx.modelName}`;
152
182
  if (ctx.contextPercent > 0) {
153
- sessionPart += ` ${coloredBar(ctx.contextPercent, 12)} ${ctx.contextPercent}%`;
183
+ parts.push({ text: tintPercent(ctx.contextPercent, `${fillGlyph(ctx.contextPercent)} ${ctx.contextPercent}%`), drop: 0 });
154
184
  }
155
- // Add usage/reset info to session part (stays on line 1 with model - Claude Code only reads line 1)
156
- const usageStr = buildUsageString(ctx);
157
- if (usageStr) {
158
- sessionPart += ` ⌛ ${usageStr.replace(/\)$/, ' used)')}`;
159
- if (ctx.weeklyText) sessionPart += ` ${ctx.weeklyText}`;
185
+
186
+ if (!minimal && ctx.usagePercent != null) {
187
+ const pct = Math.round(ctx.usagePercent);
188
+ const reset = shortReset(ctx.sessionText);
189
+ parts.push({ text: `⧗ ${tintPercent(pct, `${pct}%`)}${reset ? ` ${dim(reset)}` : ''}`, drop: 2 });
160
190
  }
161
191
 
162
- // Build stats part (only lines changed now)
163
- const statsItems = [];
164
- // if (ctx.costText) statsItems.push(`💵 ${ctx.costText.replace(/(\.\d{2})\d+/, '$1')}`);
165
- if (ctx.linesAdded > 0 || ctx.linesRemoved > 0) {
166
- statsItems.push(`📝 ${green(`+${ctx.linesAdded}`)} ${red(`-${ctx.linesRemoved}`)}`);
192
+ if (!minimal && ctx.weeklyPercent != null) {
193
+ parts.push({ text: `◷ ${tintPercent(ctx.weeklyPercent, `${ctx.weeklyPercent}%`)}`, drop: 3 });
167
194
  }
168
- const statsPart = statsItems.join(' ');
169
-
170
- // Calculate lengths for layout decisions
171
- const locationLen = visibleLength(locationPart);
172
- const sessionLen = visibleLength(sessionPart);
173
- const statsLen = visibleLength(statsPart);
174
-
175
- // Layout priority: SESSION FIRST (Claude Code only reads line 1)
176
- // Line 1: model + context + usage (most important for Claude Code)
177
- // Line 2+: location, git, stats
178
- const allOneLine = `${sessionPart} ${locationPart} ${statsPart}`;
179
- const sessionLocation = `${sessionPart} ${locationPart}`;
180
- const sessionStats = `${sessionPart} ${statsPart}`;
181
-
182
- if (visibleLength(allOneLine) <= threshold && statsLen > 0) {
183
- // Ultra-wide: everything on one line (session first)
184
- lines.push(allOneLine);
185
- } else if (visibleLength(sessionLocation) <= threshold) {
186
- // Wide: session+location on line 1 | stats on line 2
187
- lines.push(sessionLocation);
188
- if (statsLen > 0) lines.push(statsPart);
189
- } else if (sessionLen <= threshold) {
190
- // Medium: session on line 1 | location on line 2 | stats on line 3
191
- lines.push(sessionPart);
192
- lines.push(locationPart);
193
- if (statsLen > 0) lines.push(statsPart);
194
- } else {
195
- // Narrow: session | dir | branch | stats (each on own line)
196
- lines.push(sessionPart);
197
- lines.push(dirPart);
198
- if (branchPart) lines.push(branchPart);
199
- if (planPart) lines.push(planPart);
200
- if (statsLen > 0) lines.push(statsPart);
195
+
196
+ if (ctx.gitBranch) {
197
+ let git = `⎇ ${ctx.gitBranch}`;
198
+ if (!minimal) {
199
+ const changed = ctx.gitUnstaged + ctx.gitStaged;
200
+ if (changed > 0) git += ` ${yellow(`●${changed}`)}`;
201
+ if (ctx.gitAhead > 0) git += ` ↑${ctx.gitAhead}`;
202
+ if (ctx.gitBehind > 0) git += ` ↓${ctx.gitBehind}`;
203
+ if (ctx.pr) git += ` ${formatPr(ctx.pr)}`;
204
+ if (ctx.inWorktree) git += ' ⊟';
205
+ }
206
+ parts.push({ text: git, drop: 1 });
201
207
  }
202
208
 
203
- return lines;
209
+ if (!minimal && (ctx.linesAdded > 0 || ctx.linesRemoved > 0)) {
210
+ parts.push({ text: `± ${green(`+${ctx.linesAdded}`)}/${red(`-${ctx.linesRemoved}`)}`, drop: 4 });
211
+ }
212
+
213
+ if (!minimal && ctx.durationMs >= 60000) {
214
+ parts.push({ text: `⏱ ${formatDuration(ctx.durationMs)}`, drop: 5 });
215
+ }
216
+
217
+ if (!minimal && ctx.cacheHitRatio != null) {
218
+ const pct = Math.round(ctx.cacheHitRatio * 100);
219
+ const tinted = pct < 50 ? red(`${pct}%`) : pct < 80 ? yellow(`${pct}%`) : green(`${pct}%`);
220
+ parts.push({ text: `↻ ${tinted}`, drop: 6 });
221
+ }
222
+
223
+ return parts;
224
+ }
225
+
226
+ /** Join parts, dropping the highest-ranked ones until the line fits the terminal. */
227
+ function fitLine(parts) {
228
+ const width = getTerminalWidth() - 2;
229
+ const kept = [...parts];
230
+ const join = () => kept.map((part) => part.text).join(' ');
231
+ while (visibleLength(join()) > width) {
232
+ const candidates = kept.filter((part) => part.drop > 0);
233
+ if (candidates.length === 0) break;
234
+ const victim = candidates.reduce((a, b) => (b.drop > a.drop ? b : a));
235
+ kept.splice(kept.indexOf(victim), 1);
236
+ }
237
+ return join();
204
238
  }
205
239
 
206
240
  /**
@@ -309,52 +343,21 @@ function renderTodosLine(transcript) {
309
343
  return `${yellow('▸')} ${display} ${dim(`(${completedCount} done, ${pendingCount} pending)`)}`;
310
344
  }
311
345
 
312
- /**
313
- * Render minimal mode - single line with emojis, no progress bar
314
- * Format: "🤖 opus 4.5 🔋 50% ⏰ 2h 16m (38%) 🌿 branch 📁 ~/path"
315
- */
346
+ /** minimal mode: model, context and branch only. */
316
347
  function renderMinimal(ctx) {
317
- const parts = [`🤖 ${ctx.modelName}`];
318
- if (ctx.contextPercent > 0) {
319
- const batteryIcon = ctx.contextPercent > 70 ? red('🔋') : '🔋';
320
- parts.push(`${batteryIcon} ${ctx.contextPercent}%`);
321
- }
322
- const usageStr = buildUsageString(ctx);
323
- if (usageStr) parts.push(`⏰ ${usageStr}${ctx.weeklyText ? ` ${ctx.weeklyText}` : ''}`);
324
- if (ctx.gitBranch) parts.push(`🌿 ${ctx.gitBranch}`);
325
- parts.push(`📁 ${ctx.currentDir}`);
326
- console.log(parts.join(' '));
348
+ writeStyledLines([fitLine(buildLineParts(ctx, { minimal: true }))]);
327
349
  }
328
350
 
329
- /**
330
- * Render compact mode - 2 lines: session info + location (branch + dir)
331
- */
351
+ /** compact mode: the default line without the agent and todo lines. */
332
352
  function renderCompact(ctx) {
333
- // Line 1: Session info (model + context + usage)
334
- let line1 = `🤖 ${ctx.modelName}`;
335
- if (ctx.contextPercent > 0) {
336
- line1 += ` ${coloredBar(ctx.contextPercent, 12)} ${ctx.contextPercent}%`;
337
- }
338
- const usageStr = buildUsageString(ctx);
339
- if (usageStr) line1 += ` ⌛ ${usageStr}${ctx.weeklyText ? ` ${ctx.weeklyText}` : ''}`;
340
- console.log(line1.replace(/ /g, '\u00A0'));
341
-
342
- // Line 2: Location (branch + directory)
343
- let line2 = `📁 ${ctx.currentDir}`;
344
- if (ctx.gitBranch) line2 += ` 🌿 ${ctx.gitBranch}`;
345
- console.log(line2.replace(/ /g, '\u00A0'));
353
+ render(ctx, true);
346
354
  }
347
355
 
348
356
  /**
349
- * Main render function - outputs all lines
350
- * Falls back to single line if multi-line fails
357
+ * full mode: the default line, then agent and todo lines only while they exist.
351
358
  */
352
359
  function render(ctx, singleLineMode = false) {
353
- const lines = [];
354
-
355
- // Session lines (cleaner multi-line layout)
356
- const sessionLines = renderSessionLines(ctx);
357
- lines.push(...sessionLines);
360
+ const lines = [fitLine(buildLineParts(ctx))];
358
361
 
359
362
  if (!singleLineMode) {
360
363
  // Agents lines (one per agent for clarity)
@@ -463,6 +466,8 @@ async function main() {
463
466
  currentDir = expandHome(currentDir);
464
467
 
465
468
  const modelName = data.model?.display_name || 'Claude';
469
+ // Live /effort value; absent when the model has no effort parameter.
470
+ const effortLevel = typeof data.effort?.level === 'string' ? data.effort.level : '';
466
471
 
467
472
  // Git detection using batched cache
468
473
  const rawDir = data.workspace?.current_dir || data.cwd || process.cwd();
@@ -522,55 +527,39 @@ async function main() {
522
527
  } catch {}
523
528
  }
524
529
 
525
- // Session timer - read actual reset time from usage limits cache
530
+ // Quota text, filled from the payload's rate_limits below
526
531
  let sessionText = '';
527
532
  let weeklyText = '';
533
+ let weeklyPercent = null;
528
534
  const transcriptPath = data.transcript_path;
529
535
 
530
536
  // Parse transcript for tools/agents/todos
531
537
  const transcript = transcriptPath ? await parseTranscript(transcriptPath) : { tools: [], agents: [], todos: [], sessionStart: null };
532
538
 
533
- // Read actual reset time and utilization from usage limits cache (written by usage-context-awareness hook)
539
+ // Quota windows come only from Claude Code's own rate_limits, sent for Pro/Max after
540
+ // the session's first API response; without it the quota segments stay hidden.
534
541
  let usagePercent = null;
535
- try {
536
- const usageCachePath = path.join(os.tmpdir(), 'ck-usage-limits-cache.json');
537
- if (fs.existsSync(usageCachePath)) {
538
- const cache = JSON.parse(fs.readFileSync(usageCachePath, 'utf8'));
539
-
540
- // Check status flag for fallback (non-OAuth scenarios)
541
- const fresh = typeof cache.timestamp === 'number'
542
- && Date.now() - cache.timestamp < USAGE_CACHE_TTL_MS;
543
- if (cache.status === 'unavailable') {
544
- sessionText = 'N/A';
545
- } else if (cache.status === 'available' && fresh) {
546
- const fiveHour = cache.data?.five_hour;
547
- usagePercent = fiveHour?.utilization ?? null;
548
- const resetAt = fiveHour?.resets_at;
549
- if (resetAt) {
550
- const resetTime = new Date(resetAt);
551
- const remaining = Math.floor(resetTime.getTime() / 1000) - Math.floor(Date.now() / 1000);
552
- if (remaining > 0 && remaining < 18000) {
553
- const rh = Math.floor(remaining / 3600);
554
- const rm = Math.floor((remaining % 3600) / 60);
555
- sessionText = `${rh}h ${rm}m until reset`;
556
- }
557
- }
558
- const sevenDay = cache.data?.seven_day;
559
- if (sevenDay?.utilization != null) {
560
- weeklyText = `wk ${Math.round(sevenDay.utilization)}%`;
561
- const wkResetAt = sevenDay.resets_at;
562
- if (wkResetAt) {
563
- const wkRemaining = Math.floor(new Date(wkResetAt).getTime() / 1000) - Math.floor(Date.now() / 1000);
564
- if (wkRemaining > 0) {
565
- const wd = Math.floor(wkRemaining / 86400);
566
- const wh = Math.floor((wkRemaining % 86400) / 3600);
567
- weeklyText += ` (${wd}d ${wh}h)`;
568
- }
569
- }
570
- }
542
+ const applyWindows = (fiveHour, sevenDay) => {
543
+ if (fiveHour?.percent != null) {
544
+ usagePercent = fiveHour.percent;
545
+ const remaining = Math.floor(fiveHour.resetsAtMs / 1000) - Math.floor(Date.now() / 1000);
546
+ if (remaining > 0 && remaining < 18000) {
547
+ sessionText = `${Math.floor(remaining / 3600)}h ${Math.floor((remaining % 3600) / 60)}m until reset`;
571
548
  }
572
549
  }
573
- } catch {}
550
+ if (sevenDay?.percent != null) {
551
+ weeklyPercent = Math.round(sevenDay.percent);
552
+ weeklyText = `wk ${weeklyPercent}%`;
553
+ const wkRemaining = Math.floor(sevenDay.resetsAtMs / 1000) - Math.floor(Date.now() / 1000);
554
+ if (wkRemaining > 0) {
555
+ weeklyText += ` (${Math.floor(wkRemaining / 86400)}d ${Math.floor((wkRemaining % 86400) / 3600)}h)`;
556
+ }
557
+ }
558
+ };
559
+ const fromPayload = (window) => (window && typeof window.used_percentage === 'number'
560
+ ? { percent: window.used_percentage, resetsAtMs: Number(window.resets_at) * 1000 }
561
+ : null);
562
+ applyWindows(fromPayload(data.rate_limits?.five_hour), fromPayload(data.rate_limits?.seven_day));
574
563
 
575
564
  // Cost and lines changed
576
565
  const billingMode = env.CLAUDE_BILLING_MODE || 'api';
@@ -580,6 +569,14 @@ async function main() {
580
569
  : null;
581
570
  const linesAdded = data.cost?.total_lines_added || 0;
582
571
  const linesRemoved = data.cost?.total_lines_removed || 0;
572
+ const durationMs = Number(data.cost?.total_duration_ms) || 0;
573
+ const cacheHitRatio = data.prompt_cache?.requests > 0 && typeof data.prompt_cache.hit_ratio === 'number'
574
+ ? data.prompt_cache.hit_ratio
575
+ : null;
576
+ const fastMode = data.fast_mode === true;
577
+ const thinking = data.thinking?.enabled === true;
578
+ const pr = typeof data.pr?.number === 'number' ? data.pr : null;
579
+ const inWorktree = Boolean(data.worktree?.name || data.workspace?.git_worktree);
583
580
 
584
581
  // Config counts
585
582
  const configs = countConfigs(rawDir);
@@ -587,6 +584,7 @@ async function main() {
587
584
  // Build render context
588
585
  const ctx = {
589
586
  modelName,
587
+ effortLevel,
590
588
  currentDir,
591
589
  gitBranch,
592
590
  gitUnstaged,
@@ -597,10 +595,17 @@ async function main() {
597
595
  contextPercent,
598
596
  sessionText,
599
597
  weeklyText,
598
+ weeklyPercent,
600
599
  usagePercent,
601
600
  costText,
602
601
  linesAdded,
603
602
  linesRemoved,
603
+ durationMs,
604
+ cacheHitRatio,
605
+ fastMode,
606
+ thinking,
607
+ pr,
608
+ inWorktree,
604
609
  configs,
605
610
  transcript
606
611
  };
@@ -636,11 +641,11 @@ async function main() {
636
641
 
637
642
  } catch (err) {
638
643
  // Fallback: output minimal single line on any error
639
- console.log('📁 ' + (process.cwd() || 'unknown'));
644
+ console.log(`◆ ${expandHome(process.cwd() || 'unknown')}`);
640
645
  }
641
646
  }
642
647
 
643
648
  main().catch(() => {
644
- console.log('📁 error');
649
+ console.log('◆ statusline error');
645
650
  process.exit(1);
646
651
  });
@@ -10,17 +10,19 @@
10
10
  - For skill selection, read `.codex/rules/skill-workflow-routing.md` and
11
11
  `.codex/rules/skill-domain-routing.md`. When capability presence is uncertain,
12
12
  run `node .codex/scripts/generate-skill-catalog.cjs --skills`; its Codex-bound
13
- root is `.agents/skills`. Use `$cf-route` only for ambiguous, multi-step,
14
- multi-domain, or risk-elevated work; explicit, obvious, and factual intents
15
- stay direct.
13
+ root is `.agents/skills`. Explicit, obvious, and factual intents stay
14
+ direct; compose a short chain only for ambiguous, multi-step, multi-domain, or
15
+ risk-elevated work.
16
16
  - Consult `.codex/rules/review-audit-self-decision.md` before applying audit
17
17
  feedback, reversing a verified or user decision, or cutting scope, and
18
18
  `.codex/rules/process-management.md` whenever a task starts, reuses, or ends
19
19
  long-running processes.
20
+ - Read `.codex/rules/state-sync.md` before changing a task `Status:` or Receipt,
21
+ and `.codex/rules/hook-protocols.md` when a hook blocks or asks.
20
22
  - Project hooks live in `.codex/hooks.json`; review trusted hooks with `/hooks`.
21
- - New Specs work uses the process-first flow. `$cf-specs` opens C1, writes
23
+ - New Specs work uses the process-first flow. `$cf-specs` opens GATE-SCOPE, writes
22
24
  `specs/<feature>/plan.md` with flat `task-NN-*.md` files beside it, then opens
23
- C2 after adversarial review. It never starts implementation.
25
+ GATE-REVIEW after adversarial review. It never starts implementation.
24
26
  - Start implementation only through a new explicit `$cf-develop` invocation.
25
27
  Execute one unblocked task at a time; each task has exactly one `Status:`
26
28
  field and the controller is its sole state-and-proof writer.
@@ -28,16 +30,9 @@
28
30
  requires a canonical final inline `## Receipt` with the exact command,
29
31
  `Exit: 0`, `Verification: PASS`, runtime-derived Base and Head values, and
30
32
  non-empty fenced current output.
31
- - At C3, show current receipts and unresolved limitations. The user decides
33
+ - At GATE-DONE, show current receipts and unresolved limitations. The user decides
32
34
  completion; no command, review, or host state may invent approval or proof.
33
35
 
34
- ### Legacy Specs compatibility
35
-
36
- Existing packets containing `spec.json`, nested tasks, or legacy kernel
37
- artifacts keep their installed adapter, `task_registry`, `semantic_model`,
38
- `planning_depth`, lane, `execution_tier`, machine authority, separate receipts,
39
- and closeout contract. Do not migrate them during unrelated process-first work.
40
-
41
36
  ## Codex caveats
42
37
 
43
38
  - Custom agents use snake_case names and `fork_turns: "none"` for explicit delegation.
@@ -26,6 +26,7 @@ try {
26
26
  const thinkLang = runtime.locale?.thinkingLanguage || (respondLang ? 'en' : '');
27
27
  const plansPath = resolveProjectPath(projectRoot, runtime.paths?.plans, 'plans');
28
28
  const docsPath = resolveProjectPath(projectRoot, runtime.paths?.docs, 'docs');
29
+ const specsPath = resolveProjectPath(projectRoot, runtime.paths?.specs, 'specs');
29
30
  const venv = resolveVenv(projectRoot);
30
31
  const lines = [
31
32
  `## Subagent: ${payload.agent_type || 'unknown'}`,
@@ -44,7 +45,7 @@ try {
44
45
 
45
46
  lines.push(
46
47
  '## Rules',
47
- `- Plans → ${plansPath}/ | Docs → ${docsPath}/`,
48
+ `- Specs → ${specsPath}/ | Plans → ${plansPath}/ | Docs → ${docsPath}/`,
48
49
  '- YAGNI · KISS · DRY',
49
50
  '- Be concise. List unresolved questions at end.'
50
51
  );
@@ -99,9 +99,9 @@ function checkFeatureReceipt(featureDir, runtimeContext) {
99
99
  if (!policy) return { failures: ['shared_validator'], status: 'missing' };
100
100
  return receiptHelper().checkFeatureReceipt(featureDir, runtimeContext, policy);
101
101
  }
102
- function receiptFixHint(failures) {
102
+ function receiptFixHint(failures, body) {
103
103
  const helper = receiptHelper();
104
- return typeof helper.receiptFixHint === 'function' ? helper.receiptFixHint(failures) : null;
104
+ return typeof helper.receiptFixHint === 'function' ? helper.receiptFixHint(failures, body) : null;
105
105
  }
106
106
  function readTaskProof(featureDir, taskPath) {
107
107
  return receiptHelper().readTaskProof(featureDir, taskPath, getSharedPolicy() || {});
@@ -152,17 +152,10 @@ function readActiveFeatureTarget(options) {
152
152
  return resolver.readActiveFeatureTarget(options);
153
153
  }
154
154
 
155
- function resolvePersistedSpec(options) {
156
- const resolver = sharedResolver();
157
- if (typeof resolver.resolvePersistedSpec !== 'function') return null;
158
- return resolver.resolvePersistedSpec(options);
159
- }
160
-
161
155
  module.exports = {
162
156
  findActiveSpec,
163
157
  extractExplicitTarget,
164
158
  readActiveFeatureTarget,
165
- resolvePersistedSpec,
166
159
  findAllActiveSpecs,
167
160
  findAllSpecCandidates,
168
161
  resolveActiveSpec,
@@ -79,6 +79,7 @@ try {
79
79
  const thinkLang = runtime.locale?.thinkingLanguage || (respondLang ? 'en' : '');
80
80
  const plansPath = resolveProjectPath(projectRoot, runtime.paths?.plans, 'plans');
81
81
  const docsPath = resolveProjectPath(projectRoot, runtime.paths?.docs, 'docs');
82
+ const specsPath = resolveProjectPath(projectRoot, runtime.paths?.specs, 'specs');
82
83
  const lines = [];
83
84
 
84
85
  if ((thinkLang && thinkLang !== respondLang) || respondLang) {
@@ -92,7 +93,7 @@ try {
92
93
 
93
94
  lines.push(
94
95
  '## Rules',
95
- `- Markdown: Plans → "${plansPath}/" | Docs → "${docsPath}/"`,
96
+ `- Markdown: Specs → "${specsPath}/" | Plans → "${plansPath}/" | Docs → "${docsPath}/"`,
96
97
  '- Do not create markdown outside those directories unless explicitly asked.',
97
98
  `- docs.maxLoc: ${runtime.docs?.maxLoc || 800} lines per doc file`
98
99
  );
@@ -10,7 +10,6 @@ const {
10
10
  readPayload
11
11
  } = require('./lib/hook-context.cjs');
12
12
  const { clearState } = require('./lib/privacy-state.cjs');
13
- const { clearState: clearCompletionState } = require('./completion-authority-state.cjs');
14
13
 
15
14
  function readPackage(projectRoot) {
16
15
  try {
@@ -89,7 +88,6 @@ try {
89
88
 
90
89
  // Approval tokens never survive a session boundary or compaction.
91
90
  clearState(projectRoot);
92
- clearCompletionState(projectRoot, payload.session_id);
93
91
 
94
92
  // Orca (onorca.dev) sets ORCA_PANE_KEY in every pane; it is a presence marker, not a
95
93
  // secret. ORCA_AGENT_HOOK_TOKEN and ORCA_AGENT_LAUNCH_TOKEN live in the same
@@ -19,7 +19,6 @@ const {
19
19
  receiptFixHint,
20
20
  } = require('./lib/spec-receipt.cjs');
21
21
  const { taskStatusMap } = require('./lib/spec-utils.cjs');
22
- const FINAL_STATE = require('./completion-authority-check.cjs');
23
22
 
24
23
  function emitBlock(reason) {
25
24
  process.stdout.write(`${JSON.stringify({ decision: 'block', reason })}\n`);
@@ -54,9 +53,7 @@ try {
54
53
  // the payload leaves, which is what made the block unescapable on this runtime too.
55
54
  const target = resolver.extractExplicitTarget(payload)
56
55
  || resolver.readActiveFeatureTarget({ projectRoot, runtime });
57
- let resolved = typeof resolver.resolveWorkflowCandidate === 'function'
58
- ? resolver.resolveWorkflowCandidate({ projectRoot, runtime, target, includeCompleted: true })
59
- : FINAL_STATE.resolveCandidate({ resolver, projectRoot, runtime, payload });
56
+ let resolved = resolver.resolveWorkflowCandidate({ projectRoot, runtime, target, includeCompleted: true });
60
57
  if (typeof resolver.refineWorkflowGateResolution === 'function') {
61
58
  resolved = resolver.refineWorkflowGateResolution(resolved);
62
59
  }
@@ -76,7 +73,7 @@ try {
76
73
  const lines = [`Completion gate: ${checked.failures.length} done task(s) lack a verification receipt.`];
77
74
  for (const failure of checked.failures) {
78
75
  lines.push(`- \`${failure.featureName}/${failure.taskPath}\`: failed check(s) ${failure.failures.join(', ')}`);
79
- lines.push(` In \`specs/${failure.featureName}/${failure.taskPath}\`: ${receiptFixHint(failure.failures) || 'write a runtime-bound `## Receipt` with the planned command'}.`);
76
+ lines.push(` In \`specs/${failure.featureName}/${failure.taskPath}\`: ${receiptFixHint(failure.failures, failure.body) || 'write a runtime-bound `## Receipt` with the planned command'}.`);
80
77
  }
81
78
  emitBlock(lines.slice(0, 8).join('\n'));
82
79
  process.exit(0);
@@ -109,18 +106,10 @@ try {
109
106
  const lifecyclePhase = activeSpec.current_phase || activeSpec.phase;
110
107
  const explicitCloseout = ['done', 'completed', 'complete'].includes(activeSpec.status)
111
108
  || ['closeout', 'completion', 'completed', 'complete'].includes(lifecyclePhase);
112
- if (!processWorkflow && activeSpec.schema_version === '2.1') {
113
- const finalState = FINAL_STATE.evaluateCloseout({
114
- policy: POLICY,
115
- projectRoot,
116
- runtime,
117
- payload: { ...payload, session_id: sessionIdentity(payload) },
118
- });
119
- if (!finalState.ok) {
120
- emitBlock(`Completion gate: ${finalState.reason}`);
121
- process.exit(0);
122
- }
123
- if (finalState.active) process.exit(0);
109
+ // Legacy 2.1 closeout is retired; a 2.1 packet mid-execution keeps the ordinary receipt checks.
110
+ if (!processWorkflow && activeSpec.schema_version === '2.1' && explicitCloseout) {
111
+ emitBlock('Completion gate: Legacy spec.json closeout is no longer supported; move the packet to plan.md with flat task files');
112
+ process.exit(0);
124
113
  }
125
114
  const runtimeContext = POLICY.deriveRuntimeContext({
126
115
  projectRoot,
@@ -229,7 +218,7 @@ try {
229
218
  lines.push(result.taskPath === 'feature-receipt.md'
230
219
  ? ` Run final integration proof, then write \`specs/${active.featureName}/feature-receipt.md\`.`
231
220
  : processWorkflow
232
- ? ` In \`specs/${active.featureName}/${path.posix.basename(result.taskPath)}\`: ${receiptFixHint(result.failures) || 'write a runtime-bound `## Receipt` with command output'}.`
221
+ ? ` In \`specs/${active.featureName}/${path.posix.basename(result.taskPath)}\`: ${receiptFixHint(result.failures, result.body) || 'write a runtime-bound `## Receipt` with command output'}.`
233
222
  : ` Write canonical proof to \`specs/${active.featureName}/receipts/${path.posix.basename(result.taskPath)}\`; legacy \`## Evidence\` remains read-compatible.`);
234
223
  }
235
224
  if (completionBlocked) {
@@ -48,11 +48,6 @@
48
48
  "command": "node \".codex/hooks/privacy-approval.cjs\"",
49
49
  "commandWindows": "node \".codex/hooks/privacy-approval.cjs\""
50
50
  },
51
- {
52
- "type": "command",
53
- "command": "node \".codex/hooks/completion-authority.cjs\"",
54
- "commandWindows": "node \".codex/hooks/completion-authority.cjs\""
55
- },
56
51
  {
57
52
  "type": "command",
58
53
  "command": "node \".codex/hooks/rules.cjs\"",
@@ -79,11 +74,6 @@
79
74
  "type": "command",
80
75
  "command": "node \".codex/hooks/inspect-block.cjs\"",
81
76
  "commandWindows": "node \".codex/hooks/inspect-block.cjs\""
82
- },
83
- {
84
- "type": "command",
85
- "command": "node \".codex/hooks/task-scaffold-guard.cjs\"",
86
- "commandWindows": "node \".codex/hooks/task-scaffold-guard.cjs\""
87
77
  }
88
78
  ]
89
79
  }
@@ -108,11 +98,6 @@
108
98
  "command": "node \".codex/hooks/spec-gate.cjs\"",
109
99
  "commandWindows": "node \".codex/hooks/spec-gate.cjs\""
110
100
  },
111
- {
112
- "type": "command",
113
- "command": "node \".codex/hooks/completion-authority.cjs\"",
114
- "commandWindows": "node \".codex/hooks/completion-authority.cjs\""
115
- },
116
101
  {
117
102
  "type": "command",
118
103
  "command": "node \".codex/hooks/state.cjs\"",
@@ -125,11 +110,6 @@
125
110
  {
126
111
  "matcher": "*",
127
112
  "hooks": [
128
- {
129
- "type": "command",
130
- "command": "node \".codex/hooks/semantic-review-authority.cjs\"",
131
- "commandWindows": "node \".codex/hooks/semantic-review-authority.cjs\""
132
- },
133
113
  {
134
114
  "type": "command",
135
115
  "command": "node \".codex/hooks/state.cjs\"",