aiblueprint-cli 1.4.59 → 1.4.61

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 (184) hide show
  1. package/README.md +16 -36
  2. package/agents-config/agents/action.md +1 -1
  3. package/agents-config/agents/explore-codebase.md +53 -53
  4. package/agents-config/agents/explore-docs.md +50 -69
  5. package/agents-config/agents/websearch.md +36 -40
  6. package/agents-config/claude-config/scripts/.claude/skills/fix-on-my-computer/SKILL.md +81 -0
  7. package/agents-config/claude-config/scripts/CLAUDE.md +10 -4
  8. package/agents-config/claude-config/scripts/bun.lockb +0 -0
  9. package/agents-config/claude-config/scripts/package.json +22 -30
  10. package/agents-config/claude-config/scripts/statusline/CLAUDE.md +37 -155
  11. package/agents-config/claude-config/scripts/statusline/README.md +18 -94
  12. package/agents-config/claude-config/scripts/statusline/defaults.json +13 -10
  13. package/agents-config/claude-config/scripts/statusline/fixtures/mock-transcript.jsonl +4 -4
  14. package/agents-config/claude-config/scripts/statusline/fixtures/test-input.json +4 -4
  15. package/agents-config/claude-config/scripts/statusline/src/commands/interactive-config.ts +403 -0
  16. package/agents-config/claude-config/scripts/statusline/src/index.ts +33 -82
  17. package/agents-config/claude-config/scripts/statusline/src/lib/config-types.ts +7 -1
  18. package/agents-config/claude-config/scripts/statusline/src/lib/formatters.ts +40 -0
  19. package/agents-config/claude-config/scripts/statusline/src/lib/presets.ts +13 -13
  20. package/agents-config/claude-config/scripts/statusline/src/lib/render-pure.ts +24 -5
  21. package/agents-config/claude-config/scripts/statusline/statusline.config.free.json +79 -0
  22. package/agents-config/claude-config/scripts/statusline/statusline.config.json +77 -77
  23. package/agents-config/codex-config/config.toml +9 -0
  24. package/agents-config/codex-config/hooks/command-deny-list.ts +203 -0
  25. package/agents-config/commands/prompts/create-vitejs-app.md +272 -0
  26. package/agents-config/commands/prompts/nextjs-add-prisma-db.md +136 -0
  27. package/agents-config/commands/prompts/nextjs-setup-better-auth.md +173 -0
  28. package/agents-config/commands/prompts/nextjs-setup-project.md +200 -0
  29. package/agents-config/commands/prompts/prompt.md +55 -0
  30. package/agents-config/commands/prompts/saas-challenge-idea.md +135 -0
  31. package/agents-config/commands/prompts/saas-create-architecture.md +242 -0
  32. package/agents-config/commands/prompts/saas-create-headline.md +132 -0
  33. package/agents-config/commands/prompts/saas-create-landing-copywritting.md +267 -0
  34. package/agents-config/commands/prompts/saas-create-legals-docs.md +176 -0
  35. package/agents-config/commands/prompts/saas-create-logos.md +240 -0
  36. package/agents-config/commands/prompts/saas-create-prd.md +195 -0
  37. package/agents-config/commands/prompts/saas-create-tasks.md +240 -0
  38. package/agents-config/commands/prompts/saas-define-pricing.md +293 -0
  39. package/agents-config/commands/prompts/saas-find-domain-name.md +190 -0
  40. package/agents-config/commands/prompts/saas-implement-landing-page.md +257 -0
  41. package/agents-config/commands/prompts/setup-tmux.md +160 -0
  42. package/agents-config/commands/prompts/tools.md +148 -0
  43. package/agents-config/scripts/.claude/skills/fix-on-my-computer/SKILL.md +81 -0
  44. package/agents-config/scripts/CLAUDE.md +37 -0
  45. package/agents-config/scripts/biome.json +37 -0
  46. package/agents-config/scripts/bun.lockb +0 -0
  47. package/agents-config/scripts/package.json +24 -0
  48. package/agents-config/scripts/statusline/CLAUDE.md +87 -0
  49. package/agents-config/scripts/statusline/README.md +117 -0
  50. package/agents-config/scripts/statusline/__tests__/context.test.ts +229 -0
  51. package/agents-config/scripts/statusline/__tests__/formatters.test.ts +108 -0
  52. package/agents-config/scripts/statusline/__tests__/statusline.test.ts +309 -0
  53. package/agents-config/scripts/statusline/defaults.json +82 -0
  54. package/agents-config/scripts/statusline/fixtures/mock-transcript.jsonl +4 -0
  55. package/agents-config/scripts/statusline/fixtures/test-input.json +35 -0
  56. package/agents-config/scripts/statusline/src/commands/interactive-config.ts +403 -0
  57. package/agents-config/scripts/statusline/src/index.ts +141 -0
  58. package/agents-config/scripts/statusline/src/lib/config-types.ts +110 -0
  59. package/agents-config/scripts/statusline/src/lib/config.ts +21 -0
  60. package/agents-config/scripts/statusline/src/lib/context.ts +103 -0
  61. package/agents-config/scripts/statusline/src/lib/formatters.ts +426 -0
  62. package/agents-config/scripts/statusline/src/lib/git.ts +100 -0
  63. package/agents-config/scripts/statusline/src/lib/menu-factories.ts +224 -0
  64. package/agents-config/scripts/statusline/src/lib/presets.ts +177 -0
  65. package/agents-config/scripts/statusline/src/lib/render-pure.ts +516 -0
  66. package/agents-config/scripts/statusline/src/lib/types.ts +36 -0
  67. package/agents-config/scripts/statusline/src/lib/utils.ts +15 -0
  68. package/agents-config/scripts/statusline/statusline.config.free.json +79 -0
  69. package/agents-config/scripts/statusline/statusline.config.json +79 -0
  70. package/agents-config/scripts/statusline/test-with-fixtures.ts +37 -0
  71. package/agents-config/scripts/statusline/test.ts +20 -0
  72. package/agents-config/scripts/statusline/tsconfig.json +27 -0
  73. package/agents-config/scripts/tsconfig.json +27 -0
  74. package/agents-config/skills/{subagent-creator → agents-managers}/SKILL.md +47 -47
  75. package/agents-config/skills/{subagent-creator/references/subagents.md → agents-managers/references/agents.md} +45 -45
  76. package/agents-config/skills/{subagent-creator → agents-managers}/references/context-management.md +20 -20
  77. package/agents-config/skills/{subagent-creator → agents-managers}/references/debugging-agents.md +27 -27
  78. package/agents-config/skills/{subagent-creator → agents-managers}/references/error-handling-and-recovery.md +19 -19
  79. package/agents-config/skills/{subagent-creator → agents-managers}/references/evaluation-and-testing.md +29 -29
  80. package/agents-config/skills/{subagent-creator → agents-managers}/references/orchestration-patterns.md +5 -5
  81. package/agents-config/skills/{subagent-creator/references/writing-subagent-prompts.md → agents-managers/references/writing-agent-prompts.md} +23 -23
  82. package/agents-config/skills/codex-environment/SKILL.md +2 -0
  83. package/agents-config/skills/commit/SKILL.md +2 -0
  84. package/agents-config/skills/create-pr/SKILL.md +2 -0
  85. package/agents-config/skills/environments-manager/SKILL.md +271 -0
  86. package/agents-config/skills/environments-manager/examples/claude/.worktreeinclude +3 -0
  87. package/agents-config/skills/environments-manager/examples/claude/commands/dev.md +5 -0
  88. package/agents-config/skills/environments-manager/examples/claude/commands/lint.md +5 -0
  89. package/agents-config/skills/environments-manager/examples/claude/commands/test.md +5 -0
  90. package/agents-config/skills/environments-manager/examples/claude/commands/typecheck.md +5 -0
  91. package/agents-config/skills/environments-manager/examples/claude/settings.json +24 -0
  92. package/agents-config/skills/environments-manager/examples/codex/environments/environment.toml +29 -0
  93. package/agents-config/skills/environments-manager/examples/cursor/worktrees.json +3 -0
  94. package/agents-config/skills/environments-manager/examples/scripts/claude-worktree-create.sh +96 -0
  95. package/agents-config/skills/environments-manager/examples/scripts/claude-worktree-remove.sh +66 -0
  96. package/agents-config/skills/environments-manager/examples/scripts/dev.sh +15 -0
  97. package/agents-config/skills/environments-manager/examples/scripts/worktree-down.sh +22 -0
  98. package/agents-config/skills/environments-manager/examples/scripts/worktree-up.sh +50 -0
  99. package/agents-config/skills/environments-manager/references/claude.md +156 -0
  100. package/agents-config/skills/environments-manager/references/codex.md +97 -0
  101. package/agents-config/skills/environments-manager/references/cursor.md +88 -0
  102. package/agents-config/skills/fix-pr-comments/SKILL.md +2 -0
  103. package/agents-config/skills/grill-me/SKILL.md +10 -0
  104. package/agents-config/skills/merge/SKILL.md +2 -0
  105. package/agents-config/skills/rules-manager/SKILL.md +191 -0
  106. package/agents-config/skills/rules-manager/references/agents-vs-claude.md +66 -0
  107. package/agents-config/skills/rules-manager/references/examples.md +117 -0
  108. package/agents-config/skills/skill-manager/SKILL.md +101 -0
  109. package/agents-config/skills/skill-manager/references/claude-code.md +81 -0
  110. package/agents-config/skills/skill-manager/references/codex.md +288 -0
  111. package/agents-config/skills/skill-manager/references/cursor.md +125 -0
  112. package/agents-config/skills/skill-manager/references/description-recommandation.md +97 -0
  113. package/agents-config/skills/skill-manager/scripts/inspect-description.ts +743 -0
  114. package/agents-config/skills/ultrathink/SKILL.md +2 -0
  115. package/dist/cli.js +581 -299
  116. package/package.json +1 -1
  117. package/agents-config/claude-config/scripts/statusline/data/.gitignore +0 -8
  118. package/agents-config/claude-config/scripts/statusline/data/.gitkeep +0 -0
  119. package/agents-config/claude-config/scripts/statusline/docs/ARCHITECTURE.md +0 -166
  120. package/agents-config/claude-config/scripts/statusline/src/tests/spend-v2.test.ts +0 -306
  121. package/agents-config/skills/apex/SKILL.md +0 -261
  122. package/agents-config/skills/apex/scripts/setup-templates.sh +0 -100
  123. package/agents-config/skills/apex/scripts/update-progress.sh +0 -80
  124. package/agents-config/skills/apex/steps/step-00-init.md +0 -267
  125. package/agents-config/skills/apex/steps/step-00b-branch.md +0 -126
  126. package/agents-config/skills/apex/steps/step-00b-economy.md +0 -244
  127. package/agents-config/skills/apex/steps/step-00b-interactive.md +0 -153
  128. package/agents-config/skills/apex/steps/step-01-analyze.md +0 -361
  129. package/agents-config/skills/apex/steps/step-02-plan.md +0 -264
  130. package/agents-config/skills/apex/steps/step-03-execute.md +0 -239
  131. package/agents-config/skills/apex/steps/step-04-validate.md +0 -251
  132. package/agents-config/skills/apex/templates/00-context.md +0 -43
  133. package/agents-config/skills/apex/templates/01-analyze.md +0 -10
  134. package/agents-config/skills/apex/templates/02-plan.md +0 -10
  135. package/agents-config/skills/apex/templates/03-execute.md +0 -10
  136. package/agents-config/skills/apex/templates/04-validate.md +0 -10
  137. package/agents-config/skills/apex/templates/README.md +0 -176
  138. package/agents-config/skills/apex/templates/step-complete.md +0 -7
  139. package/agents-config/skills/claude-memory/SKILL.md +0 -293
  140. package/agents-config/skills/claude-memory/references/comprehensive-example.md +0 -175
  141. package/agents-config/skills/claude-memory/references/optimize-guide.md +0 -300
  142. package/agents-config/skills/claude-memory/references/project-patterns.md +0 -334
  143. package/agents-config/skills/claude-memory/references/prompting-techniques.md +0 -411
  144. package/agents-config/skills/claude-memory/references/rules-directory-guide.md +0 -298
  145. package/agents-config/skills/claude-memory/references/section-templates.md +0 -347
  146. package/agents-config/skills/fix-errors/SKILL.md +0 -61
  147. package/agents-config/skills/fix-grammar/SKILL.md +0 -59
  148. package/agents-config/skills/ralph-loop/SKILL.md +0 -117
  149. package/agents-config/skills/ralph-loop/scripts/setup.sh +0 -278
  150. package/agents-config/skills/ralph-loop/steps/step-00-init.md +0 -215
  151. package/agents-config/skills/ralph-loop/steps/step-01-interactive-prd.md +0 -366
  152. package/agents-config/skills/ralph-loop/steps/step-02-create-stories.md +0 -273
  153. package/agents-config/skills/ralph-loop/steps/step-03-finish.md +0 -245
  154. package/agents-config/skills/skill-creator/LICENSE.txt +0 -202
  155. package/agents-config/skills/skill-creator/SKILL.md +0 -421
  156. package/agents-config/skills/skill-creator/package.json +0 -5
  157. package/agents-config/skills/skill-creator/references/output-patterns.md +0 -82
  158. package/agents-config/skills/skill-creator/references/progressive-disclosure-patterns.md +0 -374
  159. package/agents-config/skills/skill-creator/references/prompting-integration.md +0 -363
  160. package/agents-config/skills/skill-creator/references/real-world-examples.md +0 -513
  161. package/agents-config/skills/skill-creator/references/script-patterns.md +0 -385
  162. package/agents-config/skills/skill-creator/references/workflows.md +0 -28
  163. package/agents-config/skills/skill-creator/references/xml-tag-guide.md +0 -606
  164. package/agents-config/skills/skill-creator/scripts/init-skill.ts +0 -214
  165. package/agents-config/skills/skill-creator/scripts/package-skill.ts +0 -146
  166. package/agents-config/skills/skill-creator/scripts/validate.ts +0 -138
  167. package/agents-config/skills/workflow-apex-free/SKILL.md +0 -261
  168. package/agents-config/skills/workflow-apex-free/scripts/setup-templates.sh +0 -100
  169. package/agents-config/skills/workflow-apex-free/scripts/update-progress.sh +0 -80
  170. package/agents-config/skills/workflow-apex-free/steps/step-00-init.md +0 -267
  171. package/agents-config/skills/workflow-apex-free/steps/step-00b-branch.md +0 -126
  172. package/agents-config/skills/workflow-apex-free/steps/step-00b-economy.md +0 -244
  173. package/agents-config/skills/workflow-apex-free/steps/step-00b-interactive.md +0 -153
  174. package/agents-config/skills/workflow-apex-free/steps/step-01-analyze.md +0 -361
  175. package/agents-config/skills/workflow-apex-free/steps/step-02-plan.md +0 -264
  176. package/agents-config/skills/workflow-apex-free/steps/step-03-execute.md +0 -239
  177. package/agents-config/skills/workflow-apex-free/steps/step-04-validate.md +0 -251
  178. package/agents-config/skills/workflow-apex-free/templates/00-context.md +0 -43
  179. package/agents-config/skills/workflow-apex-free/templates/01-analyze.md +0 -10
  180. package/agents-config/skills/workflow-apex-free/templates/02-plan.md +0 -10
  181. package/agents-config/skills/workflow-apex-free/templates/03-execute.md +0 -10
  182. package/agents-config/skills/workflow-apex-free/templates/04-validate.md +0 -10
  183. package/agents-config/skills/workflow-apex-free/templates/README.md +0 -176
  184. package/agents-config/skills/workflow-apex-free/templates/step-complete.md +0 -7
@@ -21,7 +21,7 @@ const minimalConfig: StatuslineConfig = {
21
21
  },
22
22
  session: {
23
23
  infoSeparator: null,
24
- cost: { enabled: true, format: "decimal1" },
24
+ cost: { enabled: false, format: "decimal1" },
25
25
  duration: { enabled: false },
26
26
  tokens: { enabled: false, showMax: false, showDecimals: false },
27
27
  percentage: {
@@ -37,7 +37,7 @@ const minimalConfig: StatuslineConfig = {
37
37
  },
38
38
  },
39
39
  limits: {
40
- enabled: true,
40
+ enabled: false,
41
41
  showTimeLeft: false,
42
42
  showPacingDelta: false,
43
43
  cost: { enabled: false, format: "decimal1" },
@@ -93,7 +93,7 @@ const fullConfig: StatuslineConfig = {
93
93
  },
94
94
  session: {
95
95
  infoSeparator: null,
96
- cost: { enabled: true, format: "decimal2" },
96
+ cost: { enabled: false, format: "decimal2" },
97
97
  duration: { enabled: true },
98
98
  tokens: { enabled: true, showMax: true, showDecimals: true },
99
99
  percentage: {
@@ -109,10 +109,10 @@ const fullConfig: StatuslineConfig = {
109
109
  },
110
110
  },
111
111
  limits: {
112
- enabled: true,
113
- showTimeLeft: true,
114
- showPacingDelta: true,
115
- cost: { enabled: true, format: "decimal1" },
112
+ enabled: false,
113
+ showTimeLeft: false,
114
+ showPacingDelta: false,
115
+ cost: { enabled: false, format: "decimal1" },
116
116
  percentage: {
117
117
  enabled: true,
118
118
  showValue: true,
@@ -126,10 +126,10 @@ const fullConfig: StatuslineConfig = {
126
126
  },
127
127
  },
128
128
  weeklyUsage: {
129
- enabled: true,
130
- showTimeLeft: true,
131
- showPacingDelta: true,
132
- cost: { enabled: true, format: "decimal1" },
129
+ enabled: false,
130
+ showTimeLeft: false,
131
+ showPacingDelta: false,
132
+ cost: { enabled: false, format: "decimal1" },
133
133
  percentage: {
134
134
  enabled: true,
135
135
  showValue: true,
@@ -143,7 +143,7 @@ const fullConfig: StatuslineConfig = {
143
143
  },
144
144
  },
145
145
  dailySpend: {
146
- cost: { enabled: true, format: "decimal1" },
146
+ cost: { enabled: false, format: "decimal1" },
147
147
  },
148
148
  context: {
149
149
  ...defaultConfig.context,
@@ -153,7 +153,7 @@ const fullConfig: StatuslineConfig = {
153
153
  export const PRESETS: Preset[] = [
154
154
  {
155
155
  name: "Minimal",
156
- description: "Essential info only: cost, percentage, branch",
156
+ description: "Essential info only: percentage and branch",
157
157
  config: minimalConfig,
158
158
  },
159
159
  {
@@ -55,6 +55,7 @@ export interface RawStatuslineData {
55
55
  };
56
56
  periodCost?: number;
57
57
  todayCost?: number;
58
+ thinkingEnabled?: boolean;
58
59
  }
59
60
 
60
61
  // Legacy interface for backwards compatibility
@@ -72,6 +73,7 @@ export interface StatuslineData {
72
73
  };
73
74
  periodCost?: number;
74
75
  todayCost?: number;
76
+ thinkingEnabled?: boolean;
75
77
  }
76
78
 
77
79
  // ─────────────────────────────────────────────────────────────
@@ -275,12 +277,13 @@ function calculateWeeklyDelta(
275
277
  }
276
278
 
277
279
  function formatPacingDelta(delta: number): string {
278
- const sign = delta >= 0 ? "+" : "";
279
- const value = `${sign}${delta.toFixed(1)}%`;
280
+ const inverted = -delta;
281
+ const sign = inverted >= 0 ? "+" : "";
282
+ const value = `${sign}${inverted.toFixed(1)}%`;
280
283
 
281
- if (delta > 5) return colors.green(value);
282
- if (delta > 0) return colors.lightGray(value);
283
- if (delta > -10) return colors.yellow(value);
284
+ if (inverted > 5) return colors.green(value);
285
+ if (inverted > 0) return colors.lightGray(value);
286
+ if (inverted > -10) return colors.yellow(value);
284
287
  return colors.red(value);
285
288
  }
286
289
 
@@ -361,6 +364,14 @@ function formatDailyPart(
361
364
  return `${colors.gray("D:")} ${colors.gray("$")}${colors.dimWhite(formatCost(todayCost, config.cost.format))}`;
362
365
  }
363
366
 
367
+ function formatThinkingPart(
368
+ thinkingEnabled: boolean,
369
+ config: StatuslineConfig["thinking"],
370
+ ): string {
371
+ if (!config.showDisabledWarning || thinkingEnabled) return "";
372
+ return colors.red("Thinking: OFF");
373
+ }
374
+
364
375
  // ─────────────────────────────────────────────────────────────
365
376
  // MAIN RENDER FUNCTION - Raw data + config = output
366
377
  // ─────────────────────────────────────────────────────────────
@@ -420,6 +431,13 @@ export function renderStatuslineRaw(
420
431
  const dailyPart = formatDailyPart(data.todayCost ?? 0, config.dailySpend);
421
432
  if (dailyPart) sections.push(dailyPart);
422
433
 
434
+ // Thinking warning (last position)
435
+ const thinkingPart = formatThinkingPart(
436
+ data.thinkingEnabled ?? true,
437
+ config.thinking,
438
+ );
439
+ if (thinkingPart) sections.push(thinkingPart);
440
+
423
441
  const output = sections.join(` ${sep} `);
424
442
 
425
443
  if (config.oneLine) return output;
@@ -451,6 +469,7 @@ export function renderStatusline(
451
469
  usageLimits: data.usageLimits,
452
470
  periodCost: data.periodCost,
453
471
  todayCost: data.todayCost,
472
+ thinkingEnabled: data.thinkingEnabled,
454
473
  };
455
474
 
456
475
  return renderStatuslineRaw(rawData, config);
@@ -0,0 +1,79 @@
1
+ {
2
+ "features": {
3
+ "usageLimits": false,
4
+ "spendTracking": false
5
+ },
6
+ "oneLine": true,
7
+ "showSonnetModel": false,
8
+ "pathDisplayMode": "truncated",
9
+ "git": {
10
+ "enabled": true,
11
+ "showBranch": true,
12
+ "showDirtyIndicator": true,
13
+ "showChanges": false,
14
+ "showStaged": true,
15
+ "showUnstaged": true
16
+ },
17
+ "separator": "•",
18
+ "session": {
19
+ "infoSeparator": null,
20
+ "cost": { "enabled": false, "format": "decimal1" },
21
+ "duration": { "enabled": true },
22
+ "tokens": { "enabled": true, "showMax": false, "showDecimals": false },
23
+ "percentage": {
24
+ "enabled": true,
25
+ "showValue": true,
26
+ "progressBar": {
27
+ "enabled": true,
28
+ "length": 10,
29
+ "style": "braille",
30
+ "color": "progressive",
31
+ "background": "none"
32
+ }
33
+ }
34
+ },
35
+ "context": {
36
+ "usePayloadContextWindow": true,
37
+ "maxContextTokens": 200000,
38
+ "autocompactBufferTokens": 45000,
39
+ "useUsableContextOnly": true,
40
+ "overheadTokens": 0
41
+ },
42
+ "limits": {
43
+ "enabled": false,
44
+ "showTimeLeft": false,
45
+ "showPacingDelta": false,
46
+ "cost": { "enabled": false, "format": "decimal1" },
47
+ "percentage": {
48
+ "enabled": false,
49
+ "showValue": false,
50
+ "progressBar": {
51
+ "enabled": false,
52
+ "length": 10,
53
+ "style": "braille",
54
+ "color": "progressive",
55
+ "background": "none"
56
+ }
57
+ }
58
+ },
59
+ "weeklyUsage": {
60
+ "enabled": false,
61
+ "showTimeLeft": false,
62
+ "showPacingDelta": false,
63
+ "cost": { "enabled": false, "format": "decimal1" },
64
+ "percentage": {
65
+ "enabled": false,
66
+ "showValue": false,
67
+ "progressBar": {
68
+ "enabled": false,
69
+ "length": 10,
70
+ "style": "braille",
71
+ "color": "progressive",
72
+ "background": "none"
73
+ }
74
+ }
75
+ },
76
+ "dailySpend": {
77
+ "cost": { "enabled": false, "format": "decimal1" }
78
+ }
79
+ }
@@ -1,79 +1,79 @@
1
1
  {
2
- "features": {
3
- "usageLimits": false,
4
- "spendTracking": false
5
- },
6
- "oneLine": true,
7
- "showSonnetModel": false,
8
- "pathDisplayMode": "truncated",
9
- "git": {
10
- "enabled": true,
11
- "showBranch": true,
12
- "showDirtyIndicator": true,
13
- "showChanges": false,
14
- "showStaged": true,
15
- "showUnstaged": true
16
- },
17
- "separator": "•",
18
- "session": {
19
- "infoSeparator": null,
20
- "cost": { "enabled": true, "format": "decimal1" },
21
- "duration": { "enabled": true },
22
- "tokens": { "enabled": true, "showMax": false, "showDecimals": false },
23
- "percentage": {
24
- "enabled": true,
25
- "showValue": true,
26
- "progressBar": {
27
- "enabled": true,
28
- "length": 10,
29
- "style": "braille",
30
- "color": "progressive",
31
- "background": "none"
32
- }
33
- }
34
- },
35
- "context": {
36
- "usePayloadContextWindow": true,
37
- "maxContextTokens": 200000,
38
- "autocompactBufferTokens": 45000,
39
- "useUsableContextOnly": true,
40
- "overheadTokens": 0
41
- },
42
- "limits": {
43
- "enabled": false,
44
- "showTimeLeft": false,
45
- "showPacingDelta": false,
46
- "cost": { "enabled": false, "format": "decimal1" },
47
- "percentage": {
48
- "enabled": false,
49
- "showValue": false,
50
- "progressBar": {
51
- "enabled": false,
52
- "length": 10,
53
- "style": "braille",
54
- "color": "progressive",
55
- "background": "none"
56
- }
57
- }
58
- },
59
- "weeklyUsage": {
60
- "enabled": false,
61
- "showTimeLeft": false,
62
- "showPacingDelta": false,
63
- "cost": { "enabled": false, "format": "decimal1" },
64
- "percentage": {
65
- "enabled": false,
66
- "showValue": false,
67
- "progressBar": {
68
- "enabled": false,
69
- "length": 10,
70
- "style": "braille",
71
- "color": "progressive",
72
- "background": "none"
73
- }
74
- }
75
- },
76
- "dailySpend": {
77
- "cost": { "enabled": false, "format": "decimal1" }
78
- }
2
+ "features": {
3
+ "usageLimits": false,
4
+ "spendTracking": false
5
+ },
6
+ "oneLine": true,
7
+ "showSonnetModel": false,
8
+ "pathDisplayMode": "truncated",
9
+ "git": {
10
+ "enabled": true,
11
+ "showBranch": true,
12
+ "showDirtyIndicator": true,
13
+ "showChanges": false,
14
+ "showStaged": true,
15
+ "showUnstaged": true
16
+ },
17
+ "separator": "•",
18
+ "session": {
19
+ "infoSeparator": null,
20
+ "cost": { "enabled": false, "format": "decimal1" },
21
+ "duration": { "enabled": true },
22
+ "tokens": { "enabled": true, "showMax": false, "showDecimals": false },
23
+ "percentage": {
24
+ "enabled": true,
25
+ "showValue": true,
26
+ "progressBar": {
27
+ "enabled": true,
28
+ "length": 10,
29
+ "style": "braille",
30
+ "color": "progressive",
31
+ "background": "none"
32
+ }
33
+ }
34
+ },
35
+ "context": {
36
+ "usePayloadContextWindow": true,
37
+ "maxContextTokens": 200000,
38
+ "autocompactBufferTokens": 45000,
39
+ "useUsableContextOnly": true,
40
+ "overheadTokens": 0
41
+ },
42
+ "limits": {
43
+ "enabled": false,
44
+ "showTimeLeft": false,
45
+ "showPacingDelta": false,
46
+ "cost": { "enabled": false, "format": "decimal1" },
47
+ "percentage": {
48
+ "enabled": false,
49
+ "showValue": false,
50
+ "progressBar": {
51
+ "enabled": false,
52
+ "length": 10,
53
+ "style": "braille",
54
+ "color": "progressive",
55
+ "background": "none"
56
+ }
57
+ }
58
+ },
59
+ "weeklyUsage": {
60
+ "enabled": false,
61
+ "showTimeLeft": false,
62
+ "showPacingDelta": false,
63
+ "cost": { "enabled": false, "format": "decimal1" },
64
+ "percentage": {
65
+ "enabled": false,
66
+ "showValue": false,
67
+ "progressBar": {
68
+ "enabled": false,
69
+ "length": 10,
70
+ "style": "braille",
71
+ "color": "progressive",
72
+ "background": "none"
73
+ }
74
+ }
75
+ },
76
+ "dailySpend": {
77
+ "cost": { "enabled": false, "format": "decimal1" }
78
+ }
79
79
  }
@@ -5,6 +5,15 @@
5
5
  approval_policy = "never"
6
6
  sandbox_mode = "danger-full-access"
7
7
 
8
+ [[hooks.PreToolUse]]
9
+ matcher = "^Bash$"
10
+
11
+ [[hooks.PreToolUse.hooks]]
12
+ type = "command"
13
+ command = "/usr/bin/env node \"$HOME/.codex/hooks/command-deny-list.ts\""
14
+ timeout = 5
15
+ statusMessage = "Checking command safety"
16
+
8
17
  [tui]
9
18
  status_line = [
10
19
  "model-with-reasoning",
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+
7
+ type HookPayload = {
8
+ tool_input?: {
9
+ command?: unknown;
10
+ };
11
+ };
12
+
13
+ type ClaudeSettings = {
14
+ permissions?: {
15
+ deny?: unknown;
16
+ };
17
+ };
18
+
19
+ const CLAUDE_SETTINGS_PATH = join(homedir(), ".claude", "settings.json");
20
+ const FALLBACK_DENY_PATTERNS = [
21
+ "Bash(rm -rf *)",
22
+ "Bash(sudo *)",
23
+ "Bash(mkfs *)",
24
+ "Bash(dd *)",
25
+ "Bash(git push --force *)",
26
+ "Bash(git reset --hard *)",
27
+ "Bash(*prisma reset*)",
28
+ "Bash(curl * | bash)",
29
+ "Bash(wget * | bash)",
30
+ ];
31
+
32
+ const BLOCK_REASON =
33
+ "Blocked by Codex command safety rules. Use a safer alternative or ask the user.";
34
+ const TOKEN_BOUNDARY = String.raw`(?:^|[\s"'([{<])`;
35
+ const GH_COMMAND_PREFIX = String.raw`(?:(?:command|builtin|env)\s+(?:[A-Za-z_][A-Za-z0-9_]*=(?:\S+)\s+)*)?`;
36
+ const EXECUTABLE_PATH_PREFIX = String.raw`(?:\S*/)?`;
37
+
38
+ function getCommand(payload: HookPayload): string {
39
+ const command = payload.tool_input?.command;
40
+ return typeof command === "string" ? command : "";
41
+ }
42
+
43
+ function readClaudeDenyPatterns(): string[] {
44
+ try {
45
+ const settings = JSON.parse(
46
+ readFileSync(CLAUDE_SETTINGS_PATH, "utf8"),
47
+ ) as ClaudeSettings;
48
+ const deny = settings.permissions?.deny;
49
+
50
+ if (Array.isArray(deny)) {
51
+ return deny.filter((pattern): pattern is string => typeof pattern === "string");
52
+ }
53
+ } catch {
54
+ return FALLBACK_DENY_PATTERNS;
55
+ }
56
+
57
+ return FALLBACK_DENY_PATTERNS;
58
+ }
59
+
60
+ function extractBashPattern(pattern: string): string | null {
61
+ const match = pattern.match(/^Bash\((.*)\)$/);
62
+ return match?.[1] ?? null;
63
+ }
64
+
65
+ function escapeRegExp(value: string): string {
66
+ return value.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
67
+ }
68
+
69
+ function globPatternToRegExp(pattern: string): RegExp {
70
+ const normalized = normalizeWhitespace(pattern);
71
+ const regex = normalized
72
+ .split("*")
73
+ .map(escapeRegExp)
74
+ .join(".*")
75
+ .replaceAll(" ", "\\s+");
76
+
77
+ return new RegExp(`^${regex}$`, "i");
78
+ }
79
+
80
+ function normalizeWhitespace(value: string): string {
81
+ return value.replace(/\\\n/g, " ").replace(/\s+/g, " ").trim();
82
+ }
83
+
84
+ function commandCandidates(command: string): string[] {
85
+ const normalized = normalizeWhitespace(command);
86
+ const segments = normalized
87
+ .split(/\s*(?:&&|\|\||;)\s*/g)
88
+ .map((segment) => segment.trim())
89
+ .filter(Boolean);
90
+
91
+ return [...new Set([normalized, ...segments])];
92
+ }
93
+
94
+ function containsForcedRecursiveRm(command: string): boolean {
95
+ const rmInvocations = normalizeWhitespace(command).matchAll(
96
+ /\brm\b(?<args>[^\n;&|()]*)/gi,
97
+ );
98
+
99
+ for (const match of rmInvocations) {
100
+ const args = match.groups?.args ?? "";
101
+ const shortOptions = [...args.matchAll(/(?<!\S)-([A-Za-z]+)\b/g)].map(
102
+ (optionMatch) => optionMatch[1] ?? "",
103
+ );
104
+
105
+ let hasRecursive = shortOptions.some((option) =>
106
+ option.toLowerCase().includes("r"),
107
+ );
108
+ let hasForce = shortOptions.some((option) =>
109
+ option.toLowerCase().includes("f"),
110
+ );
111
+
112
+ const longOptions = new Set(
113
+ [...args.matchAll(/--([A-Za-z-]+)\b/g)].map(
114
+ (optionMatch) => optionMatch[1] ?? "",
115
+ ),
116
+ );
117
+
118
+ hasRecursive ||= longOptions.has("recursive") || longOptions.has("dir");
119
+ hasForce ||= longOptions.has("force");
120
+
121
+ if (hasRecursive && hasForce) {
122
+ return true;
123
+ }
124
+ }
125
+
126
+ return false;
127
+ }
128
+
129
+ function containsPullRequestMergeCommand(command: string): boolean {
130
+ const matcher = new RegExp(
131
+ `${TOKEN_BOUNDARY}${GH_COMMAND_PREFIX}${EXECUTABLE_PATH_PREFIX}gh\\s+pr\\s+merge(?:\\s|$)`,
132
+ "i",
133
+ );
134
+
135
+ return commandCandidates(command).some((candidate) => matcher.test(candidate));
136
+ }
137
+
138
+ function matchesImportedDenyPattern(command: string, patterns: string[]): boolean {
139
+ const candidates = commandCandidates(command);
140
+
141
+ for (const pattern of patterns) {
142
+ const bashPattern = extractBashPattern(pattern);
143
+ if (!bashPattern) {
144
+ continue;
145
+ }
146
+
147
+ const matcher = globPatternToRegExp(bashPattern);
148
+ if (candidates.some((candidate) => matcher.test(candidate))) {
149
+ return true;
150
+ }
151
+ }
152
+
153
+ return false;
154
+ }
155
+
156
+ function deny(): void {
157
+ process.stdout.write(
158
+ JSON.stringify({
159
+ hookSpecificOutput: {
160
+ hookEventName: "PreToolUse",
161
+ permissionDecision: "deny",
162
+ permissionDecisionReason: BLOCK_REASON,
163
+ },
164
+ decision: "block",
165
+ reason: BLOCK_REASON,
166
+ }),
167
+ );
168
+ }
169
+
170
+ async function readStdin(): Promise<string> {
171
+ const chunks: Buffer[] = [];
172
+
173
+ for await (const chunk of process.stdin) {
174
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
175
+ }
176
+
177
+ return Buffer.concat(chunks).toString("utf8");
178
+ }
179
+
180
+ async function main(): Promise<void> {
181
+ const input = await readStdin();
182
+ if (!input.trim()) {
183
+ return;
184
+ }
185
+
186
+ let payload: HookPayload;
187
+ try {
188
+ payload = JSON.parse(input) as HookPayload;
189
+ } catch {
190
+ return;
191
+ }
192
+
193
+ const command = getCommand(payload);
194
+ if (
195
+ containsForcedRecursiveRm(command) ||
196
+ containsPullRequestMergeCommand(command) ||
197
+ matchesImportedDenyPattern(command, readClaudeDenyPatterns())
198
+ ) {
199
+ deny();
200
+ }
201
+ }
202
+
203
+ await main();