@phuc1403/musketeer 0.9.0 → 0.10.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 (163) hide show
  1. package/INSTALLATION.md +52 -52
  2. package/bin/musketeer.js +168 -168
  3. package/package.json +48 -48
  4. package/src/dotnet-scaffold-copier.js +79 -79
  5. package/src/provisioner/detect.js +93 -93
  6. package/src/self-update.js +77 -77
  7. package/template/.claude/agents/git-manager.md +18 -18
  8. package/template/.claude/agents/hallmark-auditor.md +78 -78
  9. package/template/.claude/agents/researcher.md +33 -33
  10. package/template/.claude/hooks/block-unsafe-adr-title.cjs +85 -85
  11. package/template/.claude/hooks/init-adr-dir.cjs +173 -173
  12. package/template/.claude/hooks/inject-adr-flags.cjs +94 -94
  13. package/template/.claude/hooks/lib/adr/command-scan.cjs +115 -115
  14. package/template/.claude/hooks/lib/characteristics/checker.cjs +357 -357
  15. package/template/.claude/hooks/lib/git-info-cache.cjs +191 -191
  16. package/template/.claude/hooks/sync-adr-toc.cjs +146 -146
  17. package/template/.claude/hooks/usage-quota-cache-refresh.cjs +166 -166
  18. package/template/.claude/hooks/validate-characteristics-hook.cjs +66 -66
  19. package/template/.claude/hooks/validate-cml-hook.js +145 -145
  20. package/template/.claude/skills/adr-writer/SKILL.md +48 -48
  21. package/template/.claude/skills/adr-writer/references/adr-example.md +35 -35
  22. package/template/.claude/skills/architecture-characteristic-writer/SKILL.md +215 -215
  23. package/template/.claude/skills/architecture-characteristic-writer/assets/worksheet-template.md +29 -29
  24. package/template/.claude/skills/architecture-characteristic-writer/references/characteristics-catalog.md +40 -40
  25. package/template/.claude/skills/architecture-characteristic-writer/scripts/ranking-table.cjs +171 -171
  26. package/template/.claude/skills/context-map/SKILL.md +80 -80
  27. package/template/.claude/skills/context-map/example.cml +106 -106
  28. package/template/.claude/skills/context-map/reference/Bounded Context/Bounded Context.md +40 -40
  29. package/template/.claude/skills/context-map/reference/Bounded Context/businessModel.md +5 -5
  30. package/template/.claude/skills/context-map/reference/Bounded Context/domainVisionStatement.md +2 -2
  31. package/template/.claude/skills/context-map/reference/Bounded Context/evolution.md +5 -5
  32. package/template/.claude/skills/context-map/reference/Bounded Context/implementationTechnology.md +1 -1
  33. package/template/.claude/skills/context-map/reference/Bounded Context/implements.md +1 -1
  34. package/template/.claude/skills/context-map/reference/Bounded Context/knowledgeLevel.md +4 -4
  35. package/template/.claude/skills/context-map/reference/Bounded Context/realizes.md +9 -9
  36. package/template/.claude/skills/context-map/reference/Bounded Context/refines.md +10 -10
  37. package/template/.claude/skills/context-map/reference/Bounded Context/responsibilities.md +26 -26
  38. package/template/.claude/skills/context-map/reference/Bounded Context/type.md +23 -23
  39. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Anticorruption Layer.md +5 -5
  40. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Bounded Context Relationship.md +12 -12
  41. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Conformist.md +5 -5
  42. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Customer-Supplier (C-S).md +22 -22
  43. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Open Host Service.md +4 -4
  44. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Partnership (P).md +13 -13
  45. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Published Language.md +4 -4
  46. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Shared Kernel (SK).md +12 -12
  47. package/template/.claude/skills/context-map/reference/Context Map.md +62 -62
  48. package/template/.claude/skills/context-map/reference/Domain/Domain.md +30 -30
  49. package/template/.claude/skills/context-map/reference/Domain/supports.md +33 -33
  50. package/template/.claude/skills/context-map/reference/Domain/type.md +3 -3
  51. package/template/.claude/skills/context-map/reference/Semantic Rules.md +32 -32
  52. package/template/.claude/skills/hallmark/SKILL.md +552 -552
  53. package/template/.claude/skills/hallmark/references/anti-patterns.md +412 -412
  54. package/template/.claude/skills/hallmark/references/assets.md +406 -406
  55. package/template/.claude/skills/hallmark/references/color.md +95 -95
  56. package/template/.claude/skills/hallmark/references/component-cookbook.md +256 -256
  57. package/template/.claude/skills/hallmark/references/components/c1-outlined-chip.md +12 -12
  58. package/template/.claude/skills/hallmark/references/components/c2-inline-form-as-cta.md +16 -16
  59. package/template/.claude/skills/hallmark/references/components/c3-typographic-link.md +8 -8
  60. package/template/.claude/skills/hallmark/references/components/c4-sticky-bottom-bar.md +16 -16
  61. package/template/.claude/skills/hallmark/references/components/f1-bento-grid.md +20 -20
  62. package/template/.claude/skills/hallmark/references/components/f2-sticky-scroll-stack.md +20 -20
  63. package/template/.claude/skills/hallmark/references/components/f3-tabular-spec-sheet.md +11 -11
  64. package/template/.claude/skills/hallmark/references/components/f4-step-sequence.md +11 -11
  65. package/template/.claude/skills/hallmark/references/components/f5-annotated-screenshot.md +11 -11
  66. package/template/.claude/skills/hallmark/references/components/f6-product-card-grid.md +41 -41
  67. package/template/.claude/skills/hallmark/references/components/ft1-mast-headed.md +13 -13
  68. package/template/.claude/skills/hallmark/references/components/ft2-inline-rule-single-line.md +10 -10
  69. package/template/.claude/skills/hallmark/references/components/ft3-index-style-category-list.md +12 -12
  70. package/template/.claude/skills/hallmark/references/components/ft4-dense-typographic.md +10 -10
  71. package/template/.claude/skills/hallmark/references/components/ft5-statement.md +21 -21
  72. package/template/.claude/skills/hallmark/references/components/ft6-letter-close.md +19 -19
  73. package/template/.claude/skills/hallmark/references/components/ft7-newsletter-first.md +27 -27
  74. package/template/.claude/skills/hallmark/references/components/ft8-marquee-scroll.md +25 -25
  75. package/template/.claude/skills/hallmark/references/components/h1-marquee.md +15 -15
  76. package/template/.claude/skills/hallmark/references/components/h2-split-diptych.md +15 -15
  77. package/template/.claude/skills/hallmark/references/components/h3-quote-led.md +11 -11
  78. package/template/.claude/skills/hallmark/references/components/h4-stat-led.md +14 -14
  79. package/template/.claude/skills/hallmark/references/components/h5-letter-hero.md +11 -11
  80. package/template/.claude/skills/hallmark/references/components/h6-photographic-fold.md +16 -16
  81. package/template/.claude/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +27 -27
  82. package/template/.claude/skills/hallmark/references/components/h8-mockup-split-browser-framed.md +23 -23
  83. package/template/.claude/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +27 -27
  84. package/template/.claude/skills/hallmark/references/components/n1-wordmark-2-links.md +12 -12
  85. package/template/.claude/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +19 -19
  86. package/template/.claude/skills/hallmark/references/components/n2-floating-chip.md +14 -14
  87. package/template/.claude/skills/hallmark/references/components/n3-side-rail.md +14 -14
  88. package/template/.claude/skills/hallmark/references/components/n4-hidden-behind-k.md +9 -9
  89. package/template/.claude/skills/hallmark/references/components/n5-floating-pill.md +28 -28
  90. package/template/.claude/skills/hallmark/references/components/n6-newspaper-masthead.md +24 -24
  91. package/template/.claude/skills/hallmark/references/components/n7-brutal-slab.md +22 -22
  92. package/template/.claude/skills/hallmark/references/components/n8-terminal-command.md +21 -21
  93. package/template/.claude/skills/hallmark/references/components/n9-edge-aligned-minimal.md +17 -17
  94. package/template/.claude/skills/hallmark/references/components/s1-left-margin-numbered.md +15 -15
  95. package/template/.claude/skills/hallmark/references/components/s2-hanging.md +13 -13
  96. package/template/.claude/skills/hallmark/references/components/s3-sticky-pinned.md +19 -19
  97. package/template/.claude/skills/hallmark/references/components/s4-inline-no-break.md +11 -11
  98. package/template/.claude/skills/hallmark/references/components/s5-bottom-anchored.md +13 -13
  99. package/template/.claude/skills/hallmark/references/components/t1-pull-quote-with-marginalia.md +12 -12
  100. package/template/.claude/skills/hallmark/references/components/t2-logo-wall-hairline.md +19 -19
  101. package/template/.claude/skills/hallmark/references/components/t3-single-huge-quote.md +11 -11
  102. package/template/.claude/skills/hallmark/references/components/t4-numbered-stat-strip.md +14 -14
  103. package/template/.claude/skills/hallmark/references/contract.md +24 -24
  104. package/template/.claude/skills/hallmark/references/copy.md +182 -182
  105. package/template/.claude/skills/hallmark/references/custom-craft.md +626 -626
  106. package/template/.claude/skills/hallmark/references/custom-theme.md +329 -329
  107. package/template/.claude/skills/hallmark/references/design-md.md +116 -116
  108. package/template/.claude/skills/hallmark/references/export-formats.md +328 -328
  109. package/template/.claude/skills/hallmark/references/floating-nav.md +89 -89
  110. package/template/.claude/skills/hallmark/references/genres/atmospheric.md +65 -65
  111. package/template/.claude/skills/hallmark/references/genres/editorial.md +70 -70
  112. package/template/.claude/skills/hallmark/references/genres/modern-minimal.md +67 -67
  113. package/template/.claude/skills/hallmark/references/genres/playful.md +65 -65
  114. package/template/.claude/skills/hallmark/references/hero-enrichment.md +474 -474
  115. package/template/.claude/skills/hallmark/references/imagery-kit.md +170 -170
  116. package/template/.claude/skills/hallmark/references/interaction-and-states.md +207 -207
  117. package/template/.claude/skills/hallmark/references/layout-and-space.md +111 -111
  118. package/template/.claude/skills/hallmark/references/macrostructures/01-bento-grid.md +35 -35
  119. package/template/.claude/skills/hallmark/references/macrostructures/02-long-document.md +34 -34
  120. package/template/.claude/skills/hallmark/references/macrostructures/03-marquee-hero.md +31 -31
  121. package/template/.claude/skills/hallmark/references/macrostructures/04-stat-led.md +32 -32
  122. package/template/.claude/skills/hallmark/references/macrostructures/05-workbench.md +32 -32
  123. package/template/.claude/skills/hallmark/references/macrostructures/06-conversational-faq.md +33 -33
  124. package/template/.claude/skills/hallmark/references/macrostructures/07-manifesto.md +32 -32
  125. package/template/.claude/skills/hallmark/references/macrostructures/08-photographic.md +34 -34
  126. package/template/.claude/skills/hallmark/references/macrostructures/09-quote-led.md +32 -32
  127. package/template/.claude/skills/hallmark/references/macrostructures/10-specimen.md +32 -32
  128. package/template/.claude/skills/hallmark/references/macrostructures/11-catalogue.md +23 -23
  129. package/template/.claude/skills/hallmark/references/macrostructures/12-letter.md +23 -23
  130. package/template/.claude/skills/hallmark/references/macrostructures/13-index-first.md +23 -23
  131. package/template/.claude/skills/hallmark/references/macrostructures/14-narrative-workflow.md +23 -23
  132. package/template/.claude/skills/hallmark/references/macrostructures/15-split-studio.md +23 -23
  133. package/template/.claude/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -23
  134. package/template/.claude/skills/hallmark/references/macrostructures/17-type-specimen.md +23 -23
  135. package/template/.claude/skills/hallmark/references/macrostructures/18-portfolio-grid.md +23 -23
  136. package/template/.claude/skills/hallmark/references/macrostructures/19-map-diagram.md +23 -23
  137. package/template/.claude/skills/hallmark/references/macrostructures/20-ecosystem-index.md +23 -23
  138. package/template/.claude/skills/hallmark/references/macrostructures/21-component-playground.md +23 -23
  139. package/template/.claude/skills/hallmark/references/macrostructures.md +89 -89
  140. package/template/.claude/skills/hallmark/references/microinteractions.md +260 -260
  141. package/template/.claude/skills/hallmark/references/motion.md +109 -109
  142. package/template/.claude/skills/hallmark/references/preview-examples.md +49 -49
  143. package/template/.claude/skills/hallmark/references/responsive.md +138 -138
  144. package/template/.claude/skills/hallmark/references/slop-test.md +205 -205
  145. package/template/.claude/skills/hallmark/references/structure.md +164 -164
  146. package/template/.claude/skills/hallmark/references/study.md +511 -511
  147. package/template/.claude/skills/hallmark/references/typography.md +243 -243
  148. package/template/.claude/skills/hallmark/references/verbs/audit.md +25 -25
  149. package/template/.claude/skills/hallmark/references/verbs/redesign.md +269 -269
  150. package/template/.claude/skills/hallmark-loop/SKILL.md +105 -105
  151. package/template/.claude/skills/hallmark-loop/references/auditor-call.md +60 -60
  152. package/template/.claude/skills/hallmark-loop/references/capture.md +78 -78
  153. package/template/.claude/skills/hallmark-loop/references/loop-control.md +79 -79
  154. package/template/.claude/skills/handoff/SKILL.md +15 -15
  155. package/template/.claude/skills/knowledge-crunching/SKILL.md +94 -94
  156. package/template/.claude/skills/research/SKILL.md +69 -69
  157. package/template/.claude/skills/tdd/SKILL.md +142 -142
  158. package/template/.claude/skills/tdd/deep-modules.md +15 -15
  159. package/template/.claude/skills/tdd/interface-design.md +31 -31
  160. package/template/.claude/skills/tdd/mocking.md +59 -59
  161. package/template/.claude/skills/tdd/refactoring.md +10 -10
  162. package/template/.claude/skills/tdd/tests.md +61 -61
  163. package/template/.claude/statusline.cjs +100 -37
@@ -1,166 +1,166 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Usage Cache Writer - UserPromptSubmit & PostToolUse Hook
4
- *
5
- * Fetches Claude Code usage limits from Anthropic OAuth API and writes to cache.
6
- * The cache is read by statusline.cjs to show the 5-hour rate-limit budget.
7
- *
8
- * Self-contained port (no .ck.json / hook-logger deps). Fails open: any error
9
- * just emits {continue:true} so it can never block a prompt or tool call.
10
- *
11
- * Features:
12
- * - Cross-platform credential retrieval (macOS Keychain, file-based)
13
- * - API response caching (60s TTL)
14
- * - Throttled API calls (1 min for prompts, 5 mins for tool use)
15
- */
16
-
17
- try {
18
- const fs = require("fs");
19
- const path = require("path");
20
- const os = require("os");
21
- const { execSync } = require("child_process");
22
-
23
- // Cache configuration
24
- const USAGE_CACHE_FILE = path.join(os.tmpdir(), "ck-usage-limits-cache.json");
25
- const FETCH_INTERVAL_MS = 300000; // 5 minutes for PostToolUse
26
- const FETCH_INTERVAL_PROMPT_MS = 60000; // 1 minute for UserPromptSubmit
27
-
28
- /**
29
- * Get Claude OAuth credentials (cross-platform)
30
- */
31
- function getClaudeCredentials() {
32
- // macOS: Try Keychain first
33
- if (os.platform() === "darwin") {
34
- try {
35
- const result = execSync('security find-generic-password -s "Claude Code-credentials" -w', {
36
- timeout: 5000,
37
- encoding: "utf-8",
38
- stdio: ["pipe", "pipe", "ignore"],
39
- }).trim();
40
- const parsed = JSON.parse(result);
41
- if (parsed.claudeAiOauth?.accessToken) {
42
- return parsed.claudeAiOauth.accessToken;
43
- }
44
- } catch {
45
- // Fallback to file-based
46
- }
47
- }
48
-
49
- // File-based credentials (Linux/Windows, or macOS fallback)
50
- const credPath = path.join(os.homedir(), ".claude", ".credentials.json");
51
- try {
52
- const content = fs.readFileSync(credPath, "utf-8");
53
- const parsed = JSON.parse(content);
54
- return parsed.claudeAiOauth?.accessToken || null;
55
- } catch {
56
- return null;
57
- }
58
- }
59
-
60
- /**
61
- * Check if we should fetch (throttled)
62
- */
63
- function shouldFetch(isUserPrompt = false) {
64
- const interval = isUserPrompt ? FETCH_INTERVAL_PROMPT_MS : FETCH_INTERVAL_MS;
65
-
66
- try {
67
- if (fs.existsSync(USAGE_CACHE_FILE)) {
68
- const cache = JSON.parse(fs.readFileSync(USAGE_CACHE_FILE, "utf-8"));
69
- if (Date.now() - cache.timestamp < interval) {
70
- return false;
71
- }
72
- }
73
- } catch {}
74
- return true;
75
- }
76
-
77
- /**
78
- * Write cache atomically (temp+rename prevents partial reads by statusline)
79
- */
80
- function writeCache(status, data = null) {
81
- const tmpFile = `${USAGE_CACHE_FILE}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
82
- try {
83
- fs.writeFileSync(
84
- tmpFile,
85
- JSON.stringify({
86
- timestamp: Date.now(),
87
- status,
88
- data,
89
- })
90
- );
91
- fs.renameSync(tmpFile, USAGE_CACHE_FILE);
92
- } catch {
93
- try { fs.unlinkSync(tmpFile); } catch {}
94
- }
95
- }
96
-
97
- /**
98
- * Fetch usage limits from Anthropic OAuth API and write to cache
99
- * Always writes status to cache (available or unavailable) for statusline fallback
100
- */
101
- async function fetchAndCacheUsageLimits() {
102
- const token = getClaudeCredentials();
103
- if (!token) {
104
- writeCache("unavailable");
105
- return;
106
- }
107
-
108
- try {
109
- const response = await fetch("https://api.anthropic.com/api/oauth/usage", {
110
- method: "GET",
111
- headers: {
112
- Accept: "application/json",
113
- "Content-Type": "application/json",
114
- Authorization: `Bearer ${token}`,
115
- "anthropic-beta": "oauth-2025-04-20",
116
- "User-Agent": "claudekit-engineer/1.0",
117
- },
118
- });
119
-
120
- if (!response.ok) {
121
- writeCache("unavailable");
122
- return;
123
- }
124
-
125
- const data = await response.json();
126
- writeCache("available", data);
127
- } catch {
128
- writeCache("unavailable");
129
- }
130
- }
131
-
132
- /**
133
- * Main hook execution - just fetch and cache, no injection
134
- */
135
- async function main() {
136
- const result = { continue: true };
137
-
138
- try {
139
- // Read hook input
140
- let inputStr = "";
141
- try {
142
- inputStr = fs.readFileSync(0, "utf-8");
143
- } catch {}
144
-
145
- const input = JSON.parse(inputStr || "{}");
146
-
147
- // Detect hook type (UserPromptSubmit vs PostToolUse) for throttle interval
148
- const isUserPrompt = typeof input.prompt === "string";
149
-
150
- // Check if we should fetch (throttled)
151
- if (shouldFetch(isUserPrompt)) {
152
- await fetchAndCacheUsageLimits();
153
- }
154
- } catch {}
155
-
156
- // Output result (no injection, just continue)
157
- console.log(JSON.stringify(result));
158
- }
159
-
160
- main().catch(() => {
161
- console.log(JSON.stringify({ continue: true }));
162
- process.exit(0);
163
- });
164
- } catch (e) {
165
- process.exit(0); // fail-open
166
- }
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Usage Cache Writer - UserPromptSubmit & PostToolUse Hook
4
+ *
5
+ * Fetches Claude Code usage limits from Anthropic OAuth API and writes to cache.
6
+ * The cache is read by statusline.cjs to show the 5-hour rate-limit budget.
7
+ *
8
+ * Self-contained port (no .ck.json / hook-logger deps). Fails open: any error
9
+ * just emits {continue:true} so it can never block a prompt or tool call.
10
+ *
11
+ * Features:
12
+ * - Cross-platform credential retrieval (macOS Keychain, file-based)
13
+ * - API response caching (60s TTL)
14
+ * - Throttled API calls (1 min for prompts, 5 mins for tool use)
15
+ */
16
+
17
+ try {
18
+ const fs = require("fs");
19
+ const path = require("path");
20
+ const os = require("os");
21
+ const { execSync } = require("child_process");
22
+
23
+ // Cache configuration
24
+ const USAGE_CACHE_FILE = path.join(os.tmpdir(), "ck-usage-limits-cache.json");
25
+ const FETCH_INTERVAL_MS = 300000; // 5 minutes for PostToolUse
26
+ const FETCH_INTERVAL_PROMPT_MS = 60000; // 1 minute for UserPromptSubmit
27
+
28
+ /**
29
+ * Get Claude OAuth credentials (cross-platform)
30
+ */
31
+ function getClaudeCredentials() {
32
+ // macOS: Try Keychain first
33
+ if (os.platform() === "darwin") {
34
+ try {
35
+ const result = execSync('security find-generic-password -s "Claude Code-credentials" -w', {
36
+ timeout: 5000,
37
+ encoding: "utf-8",
38
+ stdio: ["pipe", "pipe", "ignore"],
39
+ }).trim();
40
+ const parsed = JSON.parse(result);
41
+ if (parsed.claudeAiOauth?.accessToken) {
42
+ return parsed.claudeAiOauth.accessToken;
43
+ }
44
+ } catch {
45
+ // Fallback to file-based
46
+ }
47
+ }
48
+
49
+ // File-based credentials (Linux/Windows, or macOS fallback)
50
+ const credPath = path.join(os.homedir(), ".claude", ".credentials.json");
51
+ try {
52
+ const content = fs.readFileSync(credPath, "utf-8");
53
+ const parsed = JSON.parse(content);
54
+ return parsed.claudeAiOauth?.accessToken || null;
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Check if we should fetch (throttled)
62
+ */
63
+ function shouldFetch(isUserPrompt = false) {
64
+ const interval = isUserPrompt ? FETCH_INTERVAL_PROMPT_MS : FETCH_INTERVAL_MS;
65
+
66
+ try {
67
+ if (fs.existsSync(USAGE_CACHE_FILE)) {
68
+ const cache = JSON.parse(fs.readFileSync(USAGE_CACHE_FILE, "utf-8"));
69
+ if (Date.now() - cache.timestamp < interval) {
70
+ return false;
71
+ }
72
+ }
73
+ } catch {}
74
+ return true;
75
+ }
76
+
77
+ /**
78
+ * Write cache atomically (temp+rename prevents partial reads by statusline)
79
+ */
80
+ function writeCache(status, data = null) {
81
+ const tmpFile = `${USAGE_CACHE_FILE}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
82
+ try {
83
+ fs.writeFileSync(
84
+ tmpFile,
85
+ JSON.stringify({
86
+ timestamp: Date.now(),
87
+ status,
88
+ data,
89
+ })
90
+ );
91
+ fs.renameSync(tmpFile, USAGE_CACHE_FILE);
92
+ } catch {
93
+ try { fs.unlinkSync(tmpFile); } catch {}
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Fetch usage limits from Anthropic OAuth API and write to cache
99
+ * Always writes status to cache (available or unavailable) for statusline fallback
100
+ */
101
+ async function fetchAndCacheUsageLimits() {
102
+ const token = getClaudeCredentials();
103
+ if (!token) {
104
+ writeCache("unavailable");
105
+ return;
106
+ }
107
+
108
+ try {
109
+ const response = await fetch("https://api.anthropic.com/api/oauth/usage", {
110
+ method: "GET",
111
+ headers: {
112
+ Accept: "application/json",
113
+ "Content-Type": "application/json",
114
+ Authorization: `Bearer ${token}`,
115
+ "anthropic-beta": "oauth-2025-04-20",
116
+ "User-Agent": "claudekit-engineer/1.0",
117
+ },
118
+ });
119
+
120
+ if (!response.ok) {
121
+ writeCache("unavailable");
122
+ return;
123
+ }
124
+
125
+ const data = await response.json();
126
+ writeCache("available", data);
127
+ } catch {
128
+ writeCache("unavailable");
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Main hook execution - just fetch and cache, no injection
134
+ */
135
+ async function main() {
136
+ const result = { continue: true };
137
+
138
+ try {
139
+ // Read hook input
140
+ let inputStr = "";
141
+ try {
142
+ inputStr = fs.readFileSync(0, "utf-8");
143
+ } catch {}
144
+
145
+ const input = JSON.parse(inputStr || "{}");
146
+
147
+ // Detect hook type (UserPromptSubmit vs PostToolUse) for throttle interval
148
+ const isUserPrompt = typeof input.prompt === "string";
149
+
150
+ // Check if we should fetch (throttled)
151
+ if (shouldFetch(isUserPrompt)) {
152
+ await fetchAndCacheUsageLimits();
153
+ }
154
+ } catch {}
155
+
156
+ // Output result (no injection, just continue)
157
+ console.log(JSON.stringify(result));
158
+ }
159
+
160
+ main().catch(() => {
161
+ console.log(JSON.stringify({ continue: true }));
162
+ process.exit(0);
163
+ });
164
+ } catch (e) {
165
+ process.exit(0); // fail-open
166
+ }
@@ -1,66 +1,66 @@
1
- #!/usr/bin/env node
2
- // PostToolUse validation hook for the two architecture-characteristic documents.
3
- //
4
- // .claude/settings.json calls this after every Write/Edit/MultiEdit. If the
5
- // edited file is the ranking or the worksheet, both are checked together — the
6
- // worksheet is a derivation of the ranking, so neither can be judged alone.
7
- //
8
- // Hook exit-code contract:
9
- // exit 0 -> ok (stdout shown in transcript)
10
- // exit 2 -> blocking error (stderr fed back to Claude to fix)
11
- // An unrelated edit, a missing file, or an unparseable payload all exit 0.
12
- //
13
- // Only structure is checked. The ranking ORDER is the architect's call and is
14
- // never second-guessed here.
15
-
16
- const fs = require('fs');
17
- const path = require('path');
18
-
19
- const RANKING = 'docs/architecture-characteristics-ranking.md';
20
- const WORKSHEET = 'docs/architecture-characteristics.md';
21
-
22
- function read(root, rel) {
23
- try {
24
- return fs.readFileSync(path.join(root, rel), 'utf8');
25
- } catch {
26
- return null;
27
- }
28
- }
29
-
30
- try {
31
- const root = process.env.CLAUDE_PROJECT_DIR || process.cwd();
32
- const payload = JSON.parse(fs.readFileSync(0, 'utf8'));
33
- const edited = payload?.tool_input?.file_path;
34
-
35
- if (!edited) process.exit(0);
36
-
37
- // Windows resolves paths case-insensitively, so the same document can arrive
38
- // spelled several ways. Comparing case-sensitively there would let an edit
39
- // slip past the gate unchecked, which is worse than checking one file twice.
40
- const fold = (p) => (process.platform === 'win32' ? p.toLowerCase() : p);
41
- const rel = path.relative(root, path.resolve(root, edited)).split(path.sep).join('/');
42
- if (fold(rel) !== fold(RANKING) && fold(rel) !== fold(WORKSHEET)) process.exit(0);
43
-
44
- const { check } = require('./lib/characteristics/checker.cjs');
45
- const ranking = read(root, RANKING);
46
-
47
- // Editing the ranking alone, before any worksheet exists, is the normal path
48
- // through Phase A: `read` returns null and the worksheet rules stay quiet.
49
- const worksheet = read(root, WORKSHEET);
50
-
51
- const errors = check({ ranking, worksheet });
52
-
53
- if (errors.length) {
54
- process.stderr.write(
55
- `Architecture characteristics: ${errors.length} structural problem(s) in ${rel}\n\n` +
56
- errors.map((e) => ` - ${e}`).join('\n') +
57
- '\n\nFix the file. These are mechanical rules, not judgement calls: the ranking must ' +
58
- 'cover the catalog exactly once each, every Reason must name the row directly below it, ' +
59
- 'and the worksheet must derive from the top 7.\n'
60
- );
61
- process.exit(2);
62
- }
63
- } catch {
64
- /* fail open — a structure checker must never be the thing that breaks a session */
65
- }
66
- process.exit(0);
1
+ #!/usr/bin/env node
2
+ // PostToolUse validation hook for the two architecture-characteristic documents.
3
+ //
4
+ // .claude/settings.json calls this after every Write/Edit/MultiEdit. If the
5
+ // edited file is the ranking or the worksheet, both are checked together — the
6
+ // worksheet is a derivation of the ranking, so neither can be judged alone.
7
+ //
8
+ // Hook exit-code contract:
9
+ // exit 0 -> ok (stdout shown in transcript)
10
+ // exit 2 -> blocking error (stderr fed back to Claude to fix)
11
+ // An unrelated edit, a missing file, or an unparseable payload all exit 0.
12
+ //
13
+ // Only structure is checked. The ranking ORDER is the architect's call and is
14
+ // never second-guessed here.
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ const RANKING = 'docs/architecture-characteristics-ranking.md';
20
+ const WORKSHEET = 'docs/architecture-characteristics.md';
21
+
22
+ function read(root, rel) {
23
+ try {
24
+ return fs.readFileSync(path.join(root, rel), 'utf8');
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
29
+
30
+ try {
31
+ const root = process.env.CLAUDE_PROJECT_DIR || process.cwd();
32
+ const payload = JSON.parse(fs.readFileSync(0, 'utf8'));
33
+ const edited = payload?.tool_input?.file_path;
34
+
35
+ if (!edited) process.exit(0);
36
+
37
+ // Windows resolves paths case-insensitively, so the same document can arrive
38
+ // spelled several ways. Comparing case-sensitively there would let an edit
39
+ // slip past the gate unchecked, which is worse than checking one file twice.
40
+ const fold = (p) => (process.platform === 'win32' ? p.toLowerCase() : p);
41
+ const rel = path.relative(root, path.resolve(root, edited)).split(path.sep).join('/');
42
+ if (fold(rel) !== fold(RANKING) && fold(rel) !== fold(WORKSHEET)) process.exit(0);
43
+
44
+ const { check } = require('./lib/characteristics/checker.cjs');
45
+ const ranking = read(root, RANKING);
46
+
47
+ // Editing the ranking alone, before any worksheet exists, is the normal path
48
+ // through Phase A: `read` returns null and the worksheet rules stay quiet.
49
+ const worksheet = read(root, WORKSHEET);
50
+
51
+ const errors = check({ ranking, worksheet });
52
+
53
+ if (errors.length) {
54
+ process.stderr.write(
55
+ `Architecture characteristics: ${errors.length} structural problem(s) in ${rel}\n\n` +
56
+ errors.map((e) => ` - ${e}`).join('\n') +
57
+ '\n\nFix the file. These are mechanical rules, not judgement calls: the ranking must ' +
58
+ 'cover the catalog exactly once each, every Reason must name the row directly below it, ' +
59
+ 'and the worksheet must derive from the top 7.\n'
60
+ );
61
+ process.exit(2);
62
+ }
63
+ } catch {
64
+ /* fail open — a structure checker must never be the thing that breaks a session */
65
+ }
66
+ process.exit(0);