litclaude-ai 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/LICENSE +21 -0
  3. package/README.md +369 -0
  4. package/README_ko-KR.md +374 -0
  5. package/RELEASE_CHECKLIST.md +165 -0
  6. package/bin/litclaude-ai.js +643 -0
  7. package/cover.png +0 -0
  8. package/docs/agents.md +67 -0
  9. package/docs/hooks.md +134 -0
  10. package/docs/lsp.md +40 -0
  11. package/docs/migration.md +209 -0
  12. package/docs/workflow-compatibility-audit.md +119 -0
  13. package/generate_cover.py +123 -0
  14. package/package.json +48 -0
  15. package/plugins/litclaude/.claude-plugin/plugin.json +25 -0
  16. package/plugins/litclaude/.lsp.json +13 -0
  17. package/plugins/litclaude/.mcp.json +9 -0
  18. package/plugins/litclaude/agents/boulder-executor.md +12 -0
  19. package/plugins/litclaude/agents/librarian-researcher.md +15 -0
  20. package/plugins/litclaude/agents/oracle-verifier.md +16 -0
  21. package/plugins/litclaude/agents/prometheus-planner.md +13 -0
  22. package/plugins/litclaude/agents/qa-runner.md +16 -0
  23. package/plugins/litclaude/agents/quality-reviewer.md +17 -0
  24. package/plugins/litclaude/bin/litclaude-hook.js +110 -0
  25. package/plugins/litclaude/bin/litclaude-hud.js +271 -0
  26. package/plugins/litclaude/bin/litclaude-lsp-doctor.js +15 -0
  27. package/plugins/litclaude/bin/litclaude-mcp.js +70 -0
  28. package/plugins/litclaude/commands/deep-interview.md +21 -0
  29. package/plugins/litclaude/commands/dynamic-workflow.md +36 -0
  30. package/plugins/litclaude/commands/lit-loop.md +40 -0
  31. package/plugins/litclaude/commands/lit-plan.md +35 -0
  32. package/plugins/litclaude/commands/litgoal.md +30 -0
  33. package/plugins/litclaude/commands/review-work.md +35 -0
  34. package/plugins/litclaude/commands/start-work.md +36 -0
  35. package/plugins/litclaude/hooks/hooks.json +54 -0
  36. package/plugins/litclaude/lib/context-pressure.mjs +25 -0
  37. package/plugins/litclaude/lib/hud-accent-palette.mjs +58 -0
  38. package/plugins/litclaude/lib/litgoal/cli.mjs +266 -0
  39. package/plugins/litclaude/lib/litgoal/ledger.mjs +16 -0
  40. package/plugins/litclaude/lib/litgoal/paths.mjs +7 -0
  41. package/plugins/litclaude/lib/litgoal/state.mjs +67 -0
  42. package/plugins/litclaude/lib/mutated-file-paths.mjs +63 -0
  43. package/plugins/litclaude/lib/start-work-continuation.mjs +99 -0
  44. package/plugins/litclaude/lib/workflow-check.mjs +83 -0
  45. package/plugins/litclaude/skills/ai-slop-remover/SKILL.md +142 -0
  46. package/plugins/litclaude/skills/comment-checker/SKILL.md +55 -0
  47. package/plugins/litclaude/skills/debugging/SKILL.md +70 -0
  48. package/plugins/litclaude/skills/debugging/references/methodology/00-setup.md +108 -0
  49. package/plugins/litclaude/skills/debugging/references/methodology/02-investigate.md +126 -0
  50. package/plugins/litclaude/skills/debugging/references/methodology/04-oracle-triple.md +106 -0
  51. package/plugins/litclaude/skills/debugging/references/methodology/05-escalate.md +69 -0
  52. package/plugins/litclaude/skills/debugging/references/methodology/06-fix.md +116 -0
  53. package/plugins/litclaude/skills/debugging/references/methodology/08-qa.md +94 -0
  54. package/plugins/litclaude/skills/debugging/references/methodology/09-cleanup.md +164 -0
  55. package/plugins/litclaude/skills/debugging/references/methodology/partial-runtime-evidence.md +228 -0
  56. package/plugins/litclaude/skills/debugging/references/runtimes/bundled-js-binary.md +415 -0
  57. package/plugins/litclaude/skills/debugging/references/runtimes/go.md +252 -0
  58. package/plugins/litclaude/skills/debugging/references/runtimes/native-binary.md +484 -0
  59. package/plugins/litclaude/skills/debugging/references/runtimes/node.md +260 -0
  60. package/plugins/litclaude/skills/debugging/references/runtimes/python.md +248 -0
  61. package/plugins/litclaude/skills/debugging/references/runtimes/rust.md +234 -0
  62. package/plugins/litclaude/skills/debugging/references/tools/ghidra.md +212 -0
  63. package/plugins/litclaude/skills/debugging/references/tools/playwright-cli.md +194 -0
  64. package/plugins/litclaude/skills/debugging/references/tools/pwndbg.md +263 -0
  65. package/plugins/litclaude/skills/debugging/references/tools/pwntools.md +265 -0
  66. package/plugins/litclaude/skills/deep-interview/SKILL.md +323 -0
  67. package/plugins/litclaude/skills/deep-interview/scripts/render_progress.py +193 -0
  68. package/plugins/litclaude/skills/frontend-ui-ux/SKILL.md +62 -0
  69. package/plugins/litclaude/skills/lit-loop/SKILL.md +144 -0
  70. package/plugins/litclaude/skills/lit-plan/SKILL.md +125 -0
  71. package/plugins/litclaude/skills/litgoal/SKILL.md +219 -0
  72. package/plugins/litclaude/skills/lsp/SKILL.md +63 -0
  73. package/plugins/litclaude/skills/programming/SKILL.md +106 -0
  74. package/plugins/litclaude/skills/programming/references/go/README.md +90 -0
  75. package/plugins/litclaude/skills/programming/references/go/backend-stack.md +641 -0
  76. package/plugins/litclaude/skills/programming/references/go/bootstrap.md +328 -0
  77. package/plugins/litclaude/skills/programming/references/go/bubbletea-v2.md +360 -0
  78. package/plugins/litclaude/skills/programming/references/go/cobra-stack.md +468 -0
  79. package/plugins/litclaude/skills/programming/references/go/concurrency.md +362 -0
  80. package/plugins/litclaude/skills/programming/references/go/data-modeling.md +329 -0
  81. package/plugins/litclaude/skills/programming/references/go/error-handling.md +359 -0
  82. package/plugins/litclaude/skills/programming/references/go/golangci-strict.md +236 -0
  83. package/plugins/litclaude/skills/programming/references/go/grpc-connect.md +375 -0
  84. package/plugins/litclaude/skills/programming/references/go/libraries.md +337 -0
  85. package/plugins/litclaude/skills/programming/references/go/one-liners.md +202 -0
  86. package/plugins/litclaude/skills/programming/references/go/sqlc-pgx.md +471 -0
  87. package/plugins/litclaude/skills/programming/references/go/testing.md +467 -0
  88. package/plugins/litclaude/skills/programming/references/go/type-patterns.md +298 -0
  89. package/plugins/litclaude/skills/programming/references/python/README.md +314 -0
  90. package/plugins/litclaude/skills/programming/references/python/async-anyio.md +442 -0
  91. package/plugins/litclaude/skills/programming/references/python/data-modeling.md +233 -0
  92. package/plugins/litclaude/skills/programming/references/python/data-processing.md +133 -0
  93. package/plugins/litclaude/skills/programming/references/python/error-handling.md +218 -0
  94. package/plugins/litclaude/skills/programming/references/python/fastapi-stack.md +316 -0
  95. package/plugins/litclaude/skills/programming/references/python/httpx2-optimization.md +360 -0
  96. package/plugins/litclaude/skills/programming/references/python/libraries.md +307 -0
  97. package/plugins/litclaude/skills/programming/references/python/one-liners.md +268 -0
  98. package/plugins/litclaude/skills/programming/references/python/orjson-stack.md +378 -0
  99. package/plugins/litclaude/skills/programming/references/python/pydantic-ai.md +285 -0
  100. package/plugins/litclaude/skills/programming/references/python/pyproject-strict.md +232 -0
  101. package/plugins/litclaude/skills/programming/references/python/textual-tui.md +201 -0
  102. package/plugins/litclaude/skills/programming/references/python/type-patterns.md +176 -0
  103. package/plugins/litclaude/skills/programming/references/rust/README.md +317 -0
  104. package/plugins/litclaude/skills/programming/references/rust/async-tokio.md +299 -0
  105. package/plugins/litclaude/skills/programming/references/rust/axum-stack.md +467 -0
  106. package/plugins/litclaude/skills/programming/references/rust/cargo-strict.md +317 -0
  107. package/plugins/litclaude/skills/programming/references/rust/clap-stack.md +409 -0
  108. package/plugins/litclaude/skills/programming/references/rust/concurrency.md +375 -0
  109. package/plugins/litclaude/skills/programming/references/rust/libraries.md +439 -0
  110. package/plugins/litclaude/skills/programming/references/rust/one-liners.md +291 -0
  111. package/plugins/litclaude/skills/programming/references/rust/proptest-insta.md +429 -0
  112. package/plugins/litclaude/skills/programming/references/rust/type-state.md +354 -0
  113. package/plugins/litclaude/skills/programming/references/rust/unsafe-discipline.md +250 -0
  114. package/plugins/litclaude/skills/programming/references/rust/zero-cost-safety.md +527 -0
  115. package/plugins/litclaude/skills/programming/references/rust-ub/README.md +289 -0
  116. package/plugins/litclaude/skills/programming/references/rust-ub/miri-sanitizers-loom.md +411 -0
  117. package/plugins/litclaude/skills/programming/references/rust-ub/ub-taxonomy.md +269 -0
  118. package/plugins/litclaude/skills/programming/references/typescript/README.md +195 -0
  119. package/plugins/litclaude/skills/programming/references/typescript/backend-hono.md +672 -0
  120. package/plugins/litclaude/skills/programming/references/typescript/bootstrap.md +199 -0
  121. package/plugins/litclaude/skills/programming/references/typescript/data-modeling.md +202 -0
  122. package/plugins/litclaude/skills/programming/references/typescript/error-handling.md +169 -0
  123. package/plugins/litclaude/skills/programming/references/typescript/tsconfig-strict.md +152 -0
  124. package/plugins/litclaude/skills/programming/references/typescript/type-patterns.md +196 -0
  125. package/plugins/litclaude/skills/programming/scripts/go/check-no-excuse-rules.sh +173 -0
  126. package/plugins/litclaude/skills/programming/scripts/go/new-project.py +138 -0
  127. package/plugins/litclaude/skills/programming/scripts/go/templates/.editorconfig +13 -0
  128. package/plugins/litclaude/skills/programming/scripts/go/templates/.golangci.yml +95 -0
  129. package/plugins/litclaude/skills/programming/scripts/go/templates/AGENTS.md.tmpl +24 -0
  130. package/plugins/litclaude/skills/programming/scripts/go/templates/README.md.tmpl +12 -0
  131. package/plugins/litclaude/skills/programming/scripts/go/templates/Taskfile.yml +40 -0
  132. package/plugins/litclaude/skills/programming/scripts/go/templates/ci.yml +37 -0
  133. package/plugins/litclaude/skills/programming/scripts/go/templates/config.go +24 -0
  134. package/plugins/litclaude/skills/programming/scripts/go/templates/gitignore +15 -0
  135. package/plugins/litclaude/skills/programming/scripts/go/templates/main.go.tmpl +22 -0
  136. package/plugins/litclaude/skills/programming/scripts/go/templates/run.go +15 -0
  137. package/plugins/litclaude/skills/programming/scripts/python/check-no-excuse-rules.py +687 -0
  138. package/plugins/litclaude/skills/programming/scripts/python/new-project.py +172 -0
  139. package/plugins/litclaude/skills/programming/scripts/python/new-script.py +116 -0
  140. package/plugins/litclaude/skills/programming/scripts/rust/check-no-excuse-rules.py +296 -0
  141. package/plugins/litclaude/skills/programming/scripts/rust/check-no-excuse-rules.sh +158 -0
  142. package/plugins/litclaude/skills/programming/scripts/rust/new-project.py +175 -0
  143. package/plugins/litclaude/skills/programming/scripts/typescript/check-no-excuse-rules.ts +282 -0
  144. package/plugins/litclaude/skills/programming/scripts/typescript/new-project.ts +177 -0
  145. package/plugins/litclaude/skills/refactor/SKILL.md +73 -0
  146. package/plugins/litclaude/skills/remove-ai-slops/SKILL.md +52 -0
  147. package/plugins/litclaude/skills/review-work/SKILL.md +331 -0
  148. package/plugins/litclaude/skills/rules/SKILL.md +66 -0
  149. package/plugins/litclaude/skills/start-work/SKILL.md +132 -0
  150. package/scripts/audit-plan-checkboxes.mjs +37 -0
  151. package/scripts/doctor.mjs +41 -0
  152. package/scripts/inspect-agent-tools.mjs +27 -0
  153. package/scripts/postinstall.mjs +50 -0
  154. package/scripts/qa-claude-plugin-smoke.sh +60 -0
  155. package/scripts/qa-portable-install.sh +136 -0
  156. package/scripts/validate-plugin.mjs +72 -0
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFileSync } from "node:child_process";
4
+ import { existsSync, readFileSync } from "node:fs";
5
+ import { dirname, join } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { accentCodeForName, litBrandPrefix, supportsTruecolor } from "../lib/hud-accent-palette.mjs";
8
+
9
+ const pluginRoot = dirname(dirname(fileURLToPath(import.meta.url)));
10
+ const pluginManifestPath = join(pluginRoot, ".claude-plugin", "plugin.json");
11
+ const noColor = process.env.NO_COLOR || process.env.LITCLAUDE_HUD_NO_COLOR === "1";
12
+ const sep = process.env.LITCLAUDE_HUD_SEP || "│";
13
+ const configuredAccent = String(process.env.LITCLAUDE_HUD_ACCENT || "cyan").toLowerCase();
14
+ const accentCode = accentCodeForName(configuredAccent);
15
+
16
+ const colors = noColor
17
+ ? { reset: "", bold: "", dim: "", accent: "", empty: "", green: "", yellow: "", red: "" }
18
+ : {
19
+ reset: "\x1b[0m",
20
+ bold: "\x1b[1m",
21
+ dim: "\x1b[38;5;245m",
22
+ accent: `\x1b[38;5;${accentCode}m`,
23
+ empty: "\x1b[38;5;238m",
24
+ green: "\x1b[38;5;71m",
25
+ yellow: "\x1b[38;5;178m",
26
+ red: "\x1b[38;5;167m",
27
+ };
28
+
29
+ const accent = (text) => `${colors.accent}${text}${colors.reset}`;
30
+
31
+ const readStdin = async () => {
32
+ let input = "";
33
+ for await (const chunk of process.stdin) input += chunk;
34
+ return input;
35
+ };
36
+
37
+ const readVersion = () => {
38
+ if (process.env.LITCLAUDE_VERSION) return process.env.LITCLAUDE_VERSION;
39
+ try {
40
+ return JSON.parse(readFileSync(pluginManifestPath, "utf8")).version ?? "?";
41
+ } catch {
42
+ return "?";
43
+ }
44
+ };
45
+
46
+ const shortModel = (raw) => {
47
+ const compact = String(raw || "?")
48
+ .replace(/\([^)]*\)/gu, "")
49
+ .replace(/\[[^\]]*\]/gu, "")
50
+ .replace(/\s+/gu, " ")
51
+ .trim();
52
+ const number = compact.match(/[0-9]+(?:\.[0-9]+)?/u)?.[0] ?? "";
53
+ if (/opus/iu.test(compact)) return `O${number}`;
54
+ if (/sonnet/iu.test(compact)) return `S${number}`;
55
+ if (/haiku/iu.test(compact)) return `H${number}`;
56
+ return compact.slice(0, 10) || "?";
57
+ };
58
+
59
+ const clamp = (value, min = 0, max = 100) => Math.max(min, Math.min(max, Number.isFinite(value) ? value : min));
60
+
61
+ const displayPercent = (value) => Math.round(clamp(value));
62
+
63
+ const barColor = (value) => {
64
+ if (value >= 90) return colors.red;
65
+ if (value >= 70) return colors.yellow;
66
+ return colors.green;
67
+ };
68
+
69
+ const makeBlockBar = (value, width = 3, color = null) => {
70
+ const pct = clamp(Math.round(value));
71
+ const exact = (pct * width) / 100;
72
+ const filled = Math.floor(exact);
73
+ const partial = exact - filled;
74
+ const partialBlocks = ["", "▏", "▎", "▍", "▌", "▋", "▊", "▉"];
75
+ const partialIndex = filled < width && partial > 0 ? Math.max(1, Math.min(7, Math.round(partial * 8))) : 0;
76
+ const empty = width - filled - (partialIndex > 0 ? 1 : 0);
77
+ return `${color ?? barColor(pct)}${"█".repeat(filled)}${partialBlocks[partialIndex]}${colors.empty}${"░".repeat(empty)}${colors.reset}`;
78
+ };
79
+
80
+ const makeContextBar = (value, width = 3) => {
81
+ const pct = clamp(Math.round(value));
82
+ return makeBlockBar(pct, width, colors.accent);
83
+ };
84
+
85
+ const latestUsageTokens = (transcriptPath) => {
86
+ if (!transcriptPath || !existsSync(transcriptPath)) return 0;
87
+ const lines = readFileSync(transcriptPath, "utf8").split(/\r?\n/u).filter(Boolean);
88
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
89
+ try {
90
+ const event = JSON.parse(lines[index]);
91
+ const usage = event?.message?.usage;
92
+ if (!usage || event.isSidechain === true || event.isApiErrorMessage === true) continue;
93
+ return (
94
+ Number(usage.input_tokens ?? 0) +
95
+ Number(usage.cache_read_input_tokens ?? 0) +
96
+ Number(usage.cache_creation_input_tokens ?? 0)
97
+ );
98
+ } catch {
99
+ }
100
+ }
101
+ return 0;
102
+ };
103
+
104
+ const latestUserMessage = (transcriptPath) => {
105
+ if (!transcriptPath || !existsSync(transcriptPath)) return "";
106
+ const lines = readFileSync(transcriptPath, "utf8").split(/\r?\n/u).filter(Boolean);
107
+ const ignoredPrefixes = ["[Request interrupted", "[Request cancelled", "<local-command-stdout>", "<local-command-stderr>"];
108
+ const hasCommandXml = (text) => /<(?:command-name|command-message|command-args)\b[^>]*>/u.test(text);
109
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
110
+ try {
111
+ const event = JSON.parse(lines[index]);
112
+ if (event.type !== "user") continue;
113
+ const content = event?.message?.content;
114
+ const text = Array.isArray(content)
115
+ ? content.filter((part) => part?.type === "text").map((part) => part.text).join(" ")
116
+ : content;
117
+ const normalized = String(text || "").replace(/\s+/gu, " ").trim();
118
+ if (normalized && !ignoredPrefixes.some((prefix) => normalized.startsWith(prefix)) && !hasCommandXml(normalized)) {
119
+ return normalized;
120
+ }
121
+ } catch {
122
+ }
123
+ }
124
+ return "";
125
+ };
126
+
127
+ const gitStatus = (cwd) => {
128
+ if (!cwd || !existsSync(cwd)) return "";
129
+ try {
130
+ const branch = execFileSync("git", ["-C", cwd, "branch", "--show-current"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
131
+ if (!branch) return "";
132
+ const status = execFileSync("git", ["-C", cwd, "--no-optional-locks", "status", "--porcelain", "-uall"], {
133
+ encoding: "utf8",
134
+ stdio: ["ignore", "pipe", "ignore"],
135
+ }).trim();
136
+ const count = status ? status.split(/\r?\n/u).length : 0;
137
+ let sync = "✓";
138
+ try {
139
+ execFileSync("git", ["-C", cwd, "rev-parse", "--abbrev-ref", "@{upstream}"], { stdio: "ignore" });
140
+ const [ahead, behind] = execFileSync("git", ["-C", cwd, "rev-list", "--left-right", "--count", "HEAD...@{upstream}"], {
141
+ encoding: "utf8",
142
+ stdio: ["ignore", "pipe", "ignore"],
143
+ }).trim().split(/\s+/u).map(Number);
144
+ sync = `${ahead > 0 ? `↑${ahead}` : ""}${behind > 0 ? `↓${behind}` : ""}` || "✓";
145
+ } catch {
146
+ sync = "✓";
147
+ }
148
+ return `${branch}${count > 0 ? ` +${count}` : ""} ${sync}`;
149
+ } catch {
150
+ return "";
151
+ }
152
+ };
153
+
154
+ const firstNumber = (...values) => {
155
+ for (const value of values) {
156
+ const number = Number(value);
157
+ if (Number.isFinite(number)) return number;
158
+ }
159
+ return null;
160
+ };
161
+
162
+ const firstString = (...values) => {
163
+ for (const value of values) {
164
+ if (typeof value === "string" && value.trim()) return value.trim();
165
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
166
+ }
167
+ return "";
168
+ };
169
+
170
+ const parseUsage = (status) => {
171
+ const raw = process.env.LITCLAUDE_HUD_TEST_USAGE || process.env.CLAUDE_HUD_TEST_USAGE || "";
172
+ const values = {};
173
+ for (const part of raw.split(",")) {
174
+ const [key, value] = part.split("=");
175
+ if (!key || value === undefined) continue;
176
+ values[key.trim()] = value.trim();
177
+ }
178
+ const fiveHour = status.rate_limits?.five_hour ?? status.rate_limits?.["5_hour"] ?? {};
179
+ const sevenDay = status.rate_limits?.seven_day ?? status.rate_limits?.["7_day"] ?? status.rate_limits?.weekly ?? {};
180
+ const fiveHourPct = firstNumber(values["5h"], values.five_hour, fiveHour.used_percentage, fiveHour.percentage, fiveHour.usedPercent);
181
+ const weeklyPct = firstNumber(values["1w"], values.wk, values.seven_day, sevenDay.used_percentage, sevenDay.percentage, sevenDay.usedPercent);
182
+ return {
183
+ fiveHour: fiveHourPct === null ? null : clamp(fiveHourPct),
184
+ fiveHourReset: firstString(
185
+ values.reset5,
186
+ values.reset5h,
187
+ fiveHour.resets_at,
188
+ fiveHour.reset_at,
189
+ fiveHour.reset_time,
190
+ fiveHour.resetAt,
191
+ fiveHour.resetTime,
192
+ fiveHour.next_reset,
193
+ fiveHour.nextReset,
194
+ ),
195
+ weekly: weeklyPct === null ? null : clamp(weeklyPct),
196
+ weeklyReset: firstString(
197
+ values.reset1,
198
+ values.resetw,
199
+ values.reset7,
200
+ values.reset7d,
201
+ sevenDay.resets_at,
202
+ sevenDay.reset_at,
203
+ sevenDay.reset_time,
204
+ sevenDay.resetAt,
205
+ sevenDay.resetTime,
206
+ sevenDay.next_reset,
207
+ sevenDay.nextReset,
208
+ ),
209
+ };
210
+ };
211
+
212
+ const parseResetTarget = (value) => {
213
+ if (!value) return NaN;
214
+ const raw = String(value).trim();
215
+ if (/^\d+(?:\.\d+)?$/u.test(raw)) {
216
+ const epoch = Number(raw);
217
+ return epoch < 100000000000 ? epoch * 1000 : epoch;
218
+ }
219
+ return Date.parse(raw);
220
+ };
221
+
222
+ const formatReset = (value) => {
223
+ const target = parseResetTarget(value);
224
+ if (!Number.isFinite(target)) return "";
225
+ const minutes = Math.max(0, Math.floor((target - Date.now()) / 60000));
226
+ const hours = Math.floor(minutes / 60);
227
+ const days = Math.floor(hours / 24);
228
+ if (days > 0) return `↻${days}d${hours % 24}h`;
229
+ if (hours > 0) return `↻${hours}h${minutes % 60}m`;
230
+ return `↻${minutes}m`;
231
+ };
232
+
233
+ const formatUsageSegment = (label, value, reset) => {
234
+ const labelText = accent(label);
235
+ if (value === null) return `${labelText} ${accent("[")}${colors.accent}░░${colors.reset}${accent("]")} ${accent("--%")}`;
236
+ const pct = displayPercent(value);
237
+ const resetText = formatReset(reset);
238
+ return `${labelText} ${accent("[")}${makeBlockBar(pct, 2)}${accent("]")} ${barColor(pct)}${pct}%${colors.reset}${resetText ? ` ${accent(resetText)}` : ""}`;
239
+ };
240
+
241
+ const main = async () => {
242
+ const input = await readStdin();
243
+ const status = input.trim() ? JSON.parse(input) : {};
244
+ const version = readVersion();
245
+ const model = shortModel(status.model?.display_name ?? status.model?.id);
246
+ const maxContext = Number(status.context_window?.context_window_size ?? 200000);
247
+ const maxK = Math.max(1, Math.round(maxContext / 1000));
248
+ const tokens = latestUsageTokens(status.transcript_path);
249
+ const estimatedTokens = tokens > 0 ? tokens : 20000;
250
+ const statusContextPct = firstNumber(status.context_window?.used_percentage, status.context_window?.usage_percentage);
251
+ const rawContextPct = statusContextPct === null ? Math.floor((estimatedTokens * 100) / maxContext) : statusContextPct;
252
+ const contextPct = displayPercent(rawContextPct);
253
+ const usage = parseUsage(status);
254
+ const usageText = ` ${accent(sep)} ${formatUsageSegment("5h", usage.fiveHour, usage.fiveHourReset)} ${accent(sep)} ${formatUsageSegment("1w", usage.weekly, usage.weeklyReset)}`;
255
+ const git = gitStatus(status.cwd);
256
+ const prefix = litBrandPrefix(version, { noColor, truecolor: supportsTruecolor() });
257
+ const contextText = `${accent("ctx")} ${accent("[")}${makeContextBar(contextPct)}${accent("]")} ${accent(`${contextPct}%/${maxK}k`)}`;
258
+ const line = `${prefix} ${accent("|")} ${accent(model)} ${accent(sep)} ${contextText}${usageText}${git ? ` ${accent(sep)} ${accent("git")} ${accent(git)}` : ""}`;
259
+ process.stdout.write(`${line}\n`);
260
+
261
+ const lastMessage = latestUserMessage(status.transcript_path);
262
+ if (lastMessage) {
263
+ const trimmed = lastMessage.length > 120 ? `${lastMessage.slice(0, 117)}...` : lastMessage;
264
+ process.stdout.write(`└─ ${trimmed}\n`);
265
+ }
266
+ };
267
+
268
+ main().catch((error) => {
269
+ process.stdout.write(`[🔥LITCLAUDE v${readVersion()}] | HUD unavailable: ${error.message}\n`);
270
+ process.exit(0);
271
+ });
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from "node:child_process";
4
+
5
+ const result = spawnSync("typescript-language-server", ["--version"], {
6
+ encoding: "utf8",
7
+ });
8
+
9
+ if (result.error) {
10
+ console.log("typescript-language-server is not available.");
11
+ console.log("Install with: npm install -g typescript-language-server typescript");
12
+ process.exit(0);
13
+ }
14
+
15
+ console.log(`typescript-language-server available: ${(result.stdout || result.stderr).trim()}`);
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+
3
+ const protocolVersion = "2024-11-05";
4
+
5
+ const write = (message) => {
6
+ process.stdout.write(`${JSON.stringify(message)}\n`);
7
+ };
8
+
9
+ const result = (id, value) => write({ jsonrpc: "2.0", id, result: value });
10
+
11
+ const error = (id, code, message) => write({ jsonrpc: "2.0", id, error: { code, message } });
12
+
13
+ const handleMessage = (message) => {
14
+ if (!message || typeof message !== "object" || !("id" in message)) {
15
+ return;
16
+ }
17
+
18
+ switch (message.method) {
19
+ case "initialize":
20
+ result(message.id, {
21
+ protocolVersion,
22
+ capabilities: { tools: {} },
23
+ serverInfo: { name: "litclaude", version: "0.1.0" },
24
+ });
25
+ break;
26
+ case "ping":
27
+ result(message.id, {});
28
+ break;
29
+ case "tools/list":
30
+ result(message.id, { tools: [] });
31
+ break;
32
+ case "tools/call":
33
+ error(message.id, -32601, "LitClaude MCP exposes no callable tools in this MVP.");
34
+ break;
35
+ default:
36
+ error(message.id, -32601, `Unknown method: ${message.method}`);
37
+ break;
38
+ }
39
+ };
40
+
41
+ let buffer = "";
42
+
43
+ process.stdin.setEncoding("utf8");
44
+ process.stdin.on("data", (chunk) => {
45
+ buffer += chunk;
46
+ let newlineIndex = buffer.indexOf("\n");
47
+ while (newlineIndex !== -1) {
48
+ const line = buffer.slice(0, newlineIndex).trim();
49
+ buffer = buffer.slice(newlineIndex + 1);
50
+ if (line) {
51
+ try {
52
+ handleMessage(JSON.parse(line));
53
+ } catch {
54
+ error(null, -32700, "Parse error");
55
+ }
56
+ }
57
+ newlineIndex = buffer.indexOf("\n");
58
+ }
59
+ });
60
+
61
+ process.stdin.on("end", () => {
62
+ const line = buffer.trim();
63
+ if (line) {
64
+ try {
65
+ handleMessage(JSON.parse(line));
66
+ } catch {
67
+ error(null, -32700, "Parse error");
68
+ }
69
+ }
70
+ });
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Clarify broad or underspecified work before planning or implementation.
3
+ argument-hint: '[--quick|--standard|--deep] <idea or vague description>'
4
+ ---
5
+
6
+ Use the `deep-interview` skill for the user's current brief or command
7
+ arguments.
8
+
9
+ Run it as a requirements mode, not an implementation mode:
10
+
11
+ - Ask one question per round.
12
+ - Gather read-only codebase facts before asking the user for facts Claude can
13
+ discover directly.
14
+ - Track ambiguity, non-goals, decision boundaries, and a pressure pass.
15
+ - Persist state under `deep-interview/` so interrupted interviews can resume.
16
+ - Crystallize a spec before handing off to `/litclaude:lit-plan`,
17
+ `/litclaude:lit-loop`, or `/litclaude:start-work`.
18
+
19
+ If the user has already supplied concrete files, acceptance criteria, and
20
+ non-goals, state that the interview can be skipped and hand the brief to the
21
+ appropriate planning or execution command.
@@ -0,0 +1,36 @@
1
+ ---
2
+ description: Verify and run LitClaude Dynamic workflow delegation.
3
+ argument-hint: '<objective>'
4
+ ---
5
+
6
+ Use the `lit-loop` skill for the user's current objective, with this
7
+ Dynamic-workflow bootstrap first.
8
+
9
+ 1. Inspect native goal state when model-facing tools are exposed: call
10
+ `get_goal`, call `create_goal` only when no matching active goal exists, and
11
+ reserve `update_goal` for verified completion or a genuine blocker. If only
12
+ the user-visible goal surface is available, ask for one exact
13
+ `/goal <completion condition>` instead of claiming LitClaude set it.
14
+ 2. Run `litclaude-ai workflow-check --json` when the package CLI is available.
15
+ Treat a failing check as BLOCKED until the missing route, command, or
16
+ subagent delegation surface is fixed.
17
+ 3. For broad, risky, parallel, or long-running work, call the `Workflow` tool
18
+ when Claude Code exposes it. Bind each lane to success criteria, evidence
19
+ artifacts, and cleanup receipts.
20
+ 4. Use subagent delegation where available:
21
+ - `prometheus-planner` for read-only planning and dependency ordering.
22
+ - `boulder-executor` for implementation against a checked plan.
23
+ - `oracle-verifier` for evidence and acceptance verification.
24
+ - `qa-runner` for tmux/manual-QA scenarios and cleanup receipts.
25
+ - `quality-reviewer` for code-quality and security findings.
26
+ - `librarian-researcher` for local-first context mining.
27
+ Each child assignment starts with `TASK:` and includes `DELIVERABLE`,
28
+ `SCOPE`, and `VERIFY`. Use short wait cycles; treat timeouts as no-update
29
+ signals, and fallback only after a missing deliverable, acknowledgement-only
30
+ reply, or `BLOCKED:` report.
31
+ 5. For isolated edit lanes, use `EnterWorktree` when exposed. If only the CLI
32
+ surface exists, use or recommend `claude --worktree <short-name> --tmux`.
33
+
34
+ Do not auto-type `/goal`, do not echo or execute prompt text, and do not mutate
35
+ remote state. Continue through the normal LitClaude evidence loop:
36
+ `PIN -> RED -> GREEN -> VERIFY -> SURFACE -> REVIEW -> CLEAN -> RECORD`.
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: Run LitClaude lit-loop discipline with goal and Dynamic workflow bootstrap.
3
+ argument-hint: '<objective>'
4
+ ---
5
+
6
+ Use the `lit-loop` skill for the user's current objective or command arguments.
7
+
8
+ Before implementation, bootstrap Claude Code-native workflow state:
9
+
10
+ 1. If model-facing goal tools are available in this session, inspect `get_goal`,
11
+ call `create_goal` only when no matching goal exists, and reserve
12
+ `update_goal` for verified completion or a genuine blocker.
13
+ 2. If goal tools are unavailable, state that plainly and ask the user to bind
14
+ the native Claude Code goal with this exact surface before long execution:
15
+ `/goal <completion condition for the current objective>`.
16
+ 3. For broad, risky, parallel, or long-running work, call the `Workflow` tool
17
+ when Claude Code exposes it. Bind every lane to explicit criteria, evidence
18
+ artifacts, and cleanup receipts.
19
+ 4. When isolated edits are needed, use `EnterWorktree` when Claude Code exposes
20
+ it. If only the CLI surface is available, tell the user the concrete launch
21
+ form: `claude --worktree <short-name> --tmux`.
22
+
23
+ Then continue with evidence-bound success criteria, tests, manual QA artifacts,
24
+ cleanup receipts, and explicit release approval boundaries.
25
+
26
+ Run the objective through `PIN -> RED -> GREEN -> VERIFY -> SURFACE -> REVIEW
27
+ -> CLEAN -> RECORD`:
28
+
29
+ - PIN the objective, non-goals, stale state to reread, dirty worktree files,
30
+ commit/push approval, publish approval, and resume checkpoint.
31
+ - RED before implementation when behavior changes, then GREEN with targeted
32
+ evidence and broader verification.
33
+ - SURFACE with a real Manual-QA channel and artifact.
34
+ - REVIEW when the change is broad, risky, shared, security-sensitive, or
35
+ release-facing.
36
+ - CLEAN with a bounded cleanup receipt for tmux sessions, servers, ports,
37
+ browser contexts, temp directories, and child processes.
38
+
39
+ Stop rules: stop before unapproved commit/push or publish, stop on malformed or
40
+ contradictory requirements, and reread live repo state on resume before acting.
@@ -0,0 +1,35 @@
1
+ ---
2
+ description: Plan LitClaude work with explicit goal, Dynamic workflow, and QA criteria.
3
+ argument-hint: '<planning brief>'
4
+ ---
5
+
6
+ Use the `lit-plan` skill for the user's current planning brief or command
7
+ arguments.
8
+
9
+ The plan must include Claude Code-native bootstrap steps:
10
+
11
+ - If model-facing goal tools are exposed, use `get_goal`, `create_goal`, and
12
+ delayed `update_goal` exactly as native goal state, not as slash-command text.
13
+ - If goal tools are unavailable, include the exact user-visible `/goal`
14
+ completion condition to bind before execution.
15
+ - For independent, risky, parallel, or long-running work, include when Claude
16
+ should call the `Workflow` tool and how each lane proves its evidence.
17
+ - For isolated edit lanes, include when to use `EnterWorktree`; if only the CLI
18
+ surface is available, include `claude --worktree <short-name> --tmux`, plus
19
+ evidence paths and cleanup.
20
+
21
+ Write the plan under `plans/` and keep it executable: concrete files, tests,
22
+ manual QA, cleanup, and publish/remote-mutation guardrails.
23
+
24
+ The plan must include a strict execution section:
25
+
26
+ - Bootstrap and PIN: objective, non-goals, stale state, dirty worktree
27
+ constraints, resume ledger, commit/push boundary, and publish boundary.
28
+ - TDD loop: `PIN -> RED -> GREEN -> VERIFY -> SURFACE -> REVIEW -> CLEAN ->
29
+ RECORD`.
30
+ - Manual-QA: exact channel, command or steps, PASS/FAIL observable, artifact
31
+ path, and cleanup receipt.
32
+ - Reviewer gate: when to run it and what artifact proves it passed or was not
33
+ required.
34
+ - Stop rules: stop on malformed plan input, contradictory live state,
35
+ unapproved remote mutation, missing artifacts, or repeated identical failure.
@@ -0,0 +1,30 @@
1
+ ---
2
+ description: Manage LitClaude litgoal ledger and durable goal state.
3
+ argument-hint: '<goal operation>'
4
+ ---
5
+
6
+ Use the `litgoal` skill for the user's current goal operation or command
7
+ arguments.
8
+
9
+ Prefer the package CLI for durable local state:
10
+ `litclaude-ai litgoal create-goals`, `status`, `criteria`,
11
+ `record-evidence`, `checkpoint`, `steer`, and `record-review-blockers`.
12
+ The installed alias may also be invoked as:
13
+
14
+ ```bash
15
+ litclaude litgoal create-goals --brief "<brief>" --json
16
+ litclaude litgoal record-evidence --criterion <id> --status pass --json '{"artifact":"...","cleanup":"..."}'
17
+ litclaude litgoal checkpoint --status active --note "<progress>" --json
18
+ litclaude litgoal steer --kind scope --note "<what changed and why>" --json
19
+ ```
20
+
21
+ The ledger lives under `.litclaude/litgoal/` unless test environment variables
22
+ override it. Bind work to native goal tools when they are available; when goal
23
+ tools are unavailable, record clear criteria and evidence in the local ledger.
24
+ For broad goal execution, use Dynamic workflow when Claude Code exposes it, and
25
+ use `claude --worktree <short-name> --tmux` only when isolated worktree
26
+ execution is needed.
27
+ Manual-QA channels and cleanup receipt artifacts should be recorded with
28
+ `record-evidence`. Malformed JSON, unknown criteria, corrupt state, and invalid
29
+ steering kinds must fail as controlled errors. Use current docs/test reads
30
+ before trusting stale local state.
@@ -0,0 +1,35 @@
1
+ ---
2
+ description: Run LitClaude 5-lane review discipline.
3
+ argument-hint: '<scope>'
4
+ ---
5
+
6
+ Use the `review-work` skill for the user's current scope or command arguments.
7
+
8
+ Run the 5-lane review contract: goal and constraint verification
9
+ (goal/constraint), hands-on QA execution, code quality review, security review,
10
+ and local-first context mining.
11
+ Aggregate findings into a PASS, FAIL, or NEEDS-CONTEXT verdict, and cite the
12
+ evidence used for every lane.
13
+ Manual-QA channels must leave artifacts, cleanup receipt paths, and bounded
14
+ session teardown proof. Respect the publish boundary: reviewing release
15
+ readiness is allowed, but npm publish, remote marketplace registration, and
16
+ other remote mutation still need explicit user approval.
17
+
18
+ Lane routing:
19
+
20
+ - goal and constraint verification: use `oracle-verifier` with `review-work`
21
+ and `rules`.
22
+ - hands-on QA execution: use `qa-runner` with `start-work` and `review-work`.
23
+ - code quality review: use `quality-reviewer` with `review-work` and
24
+ `programming`.
25
+ - security review: use `quality-reviewer` with `review-work` and
26
+ `programming`.
27
+ - local-first context mining: use `librarian-researcher` with `rules`.
28
+
29
+ Before launching broad review work, check whether native goal tools are
30
+ available and bind the review to the active goal. If goal tools are unavailable,
31
+ keep the local evidence ledger authoritative. For large independent lanes, use
32
+ Dynamic workflow when Claude Code exposes it, and use `claude --worktree` only
33
+ when isolated review edits or reproduction steps need a separate checkout.
34
+ Use current docs/test reads before trusting stale local state or continuation
35
+ notes.
@@ -0,0 +1,36 @@
1
+ ---
2
+ description: Execute a checked plan with LitClaude start-work discipline.
3
+ argument-hint: '<plan-file>'
4
+ ---
5
+
6
+ Use the `start-work` skill for the user's current plan file or command
7
+ arguments.
8
+
9
+ Before the first checkbox, bootstrap Claude Code-native workflow state:
10
+
11
+ - Use `get_goal` and `create_goal` only if model-facing goal tools are exposed.
12
+ - If goal tools are unavailable, ask the user to set a native `/goal` completion
13
+ condition for the plan before multi-turn execution.
14
+ - For broad, risky, parallel, or long-running checkbox waves, call the
15
+ `Workflow` tool when Claude Code exposes it.
16
+ - For isolated edit lanes, use `EnterWorktree` when exposed; otherwise launch
17
+ or recommend `claude --worktree <short-name> --tmux`.
18
+
19
+ Then execute the first unchecked top-level checkbox with failing-test-first
20
+ implementation, automated verification, manual QA evidence, cleanup receipts,
21
+ and ledger updates.
22
+
23
+ For that checkbox, enforce `PIN -> RED -> GREEN -> VERIFY -> SURFACE -> REVIEW
24
+ -> CLEAN -> RECORD`:
25
+
26
+ - PIN the plan objective, selected checkbox, stale state, dirty worktree
27
+ boundaries, resume checkpoint, commit/push approval, and publish approval.
28
+ - RED first for behavior changes, then GREEN with targeted and plan-level tests.
29
+ - SURFACE through the plan's Manual-QA channel with an artifact path.
30
+ - REVIEW broad, risky, shared, security-sensitive, or release-facing changes.
31
+ - CLEAN with bounded cleanup receipt for tmux sessions, servers, ports, browser
32
+ contexts, temp directories, and child processes.
33
+
34
+ Stop rules: stop on malformed plan structure, missing acceptance criteria,
35
+ missing Manual-QA or cleanup requirements, contradictory live state, or
36
+ unapproved commit/push or publish.
@@ -0,0 +1,54 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/bin/litclaude-hook.js\" session-start",
9
+ "timeout": 10,
10
+ "statusMessage": "loading LitClaude rules"
11
+ }
12
+ ]
13
+ }
14
+ ],
15
+ "UserPromptSubmit": [
16
+ {
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/bin/litclaude-hook.js\" user-prompt-submit",
21
+ "timeout": 5,
22
+ "statusMessage": "checking LitClaude workflow trigger"
23
+ }
24
+ ]
25
+ }
26
+ ],
27
+ "PostToolUse": [
28
+ {
29
+ "matcher": "^(Write|Edit|MultiEdit|NotebookEdit)$",
30
+ "hooks": [
31
+ {
32
+ "type": "command",
33
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/bin/litclaude-hook.js\" post-tool-use",
34
+ "timeout": 30,
35
+ "statusMessage": "running LitClaude post-edit checks"
36
+ }
37
+ ]
38
+ }
39
+ ],
40
+ "PostCompact": [
41
+ {
42
+ "matcher": "manual|auto",
43
+ "hooks": [
44
+ {
45
+ "type": "command",
46
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/bin/litclaude-hook.js\" post-compact",
47
+ "timeout": 10,
48
+ "statusMessage": "resetting LitClaude rule cache"
49
+ }
50
+ ]
51
+ }
52
+ ]
53
+ }
54
+ }
@@ -0,0 +1,25 @@
1
+ import { readFileSync } from "node:fs";
2
+
3
+ const contextPressureMarkers = [
4
+ "context compacted",
5
+ "context_length_exceeded",
6
+ "context_too_large",
7
+ "context window",
8
+ "skill descriptions were shortened",
9
+ "input exceeds the context",
10
+ ];
11
+
12
+ export const hasContextPressure = (text) => {
13
+ if (typeof text !== "string") return false;
14
+ const normalized = text.toLowerCase();
15
+ return contextPressureMarkers.some((marker) => normalized.includes(marker));
16
+ };
17
+
18
+ export const transcriptHasContextPressure = (transcriptPath) => {
19
+ if (typeof transcriptPath !== "string" || transcriptPath.length === 0) return false;
20
+ try {
21
+ return hasContextPressure(readFileSync(transcriptPath, "utf8"));
22
+ } catch {
23
+ return false;
24
+ }
25
+ };