devflow-kit 1.7.0 → 1.8.1

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 (197) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +31 -1
  3. package/dist/cli.js +3 -1
  4. package/dist/commands/hud.d.ts +22 -0
  5. package/dist/commands/hud.js +180 -0
  6. package/dist/commands/init.d.ts +2 -12
  7. package/dist/commands/init.js +362 -181
  8. package/dist/commands/list.js +1 -0
  9. package/dist/commands/uninstall.js +9 -16
  10. package/dist/hud/cache.d.ts +14 -0
  11. package/dist/hud/cache.js +54 -0
  12. package/dist/hud/colors.d.ts +23 -0
  13. package/dist/hud/colors.js +62 -0
  14. package/dist/hud/components/config-counts.d.ts +8 -0
  15. package/dist/hud/components/config-counts.js +91 -0
  16. package/dist/hud/components/context-usage.d.ts +8 -0
  17. package/dist/hud/components/context-usage.js +49 -0
  18. package/dist/hud/components/diff-stats.d.ts +3 -0
  19. package/dist/hud/components/diff-stats.js +36 -0
  20. package/dist/hud/components/directory.d.ts +3 -0
  21. package/dist/hud/components/directory.js +10 -0
  22. package/dist/hud/components/git-ahead-behind.d.ts +3 -0
  23. package/dist/hud/components/git-ahead-behind.js +16 -0
  24. package/dist/hud/components/git-branch.d.ts +3 -0
  25. package/dist/hud/components/git-branch.js +14 -0
  26. package/dist/hud/components/model.d.ts +3 -0
  27. package/dist/hud/components/model.js +21 -0
  28. package/dist/hud/components/release-info.d.ts +3 -0
  29. package/dist/hud/components/release-info.js +9 -0
  30. package/dist/hud/components/session-cost.d.ts +3 -0
  31. package/dist/hud/components/session-cost.js +9 -0
  32. package/dist/hud/components/session-duration.d.ts +3 -0
  33. package/dist/hud/components/session-duration.js +18 -0
  34. package/dist/hud/components/todo-progress.d.ts +3 -0
  35. package/dist/hud/components/todo-progress.js +11 -0
  36. package/dist/hud/components/usage-quota.d.ts +3 -0
  37. package/dist/hud/components/usage-quota.js +45 -0
  38. package/dist/hud/components/version-badge.d.ts +3 -0
  39. package/dist/hud/components/version-badge.js +80 -0
  40. package/dist/hud/components/worktree-count.d.ts +3 -0
  41. package/dist/hud/components/worktree-count.js +8 -0
  42. package/dist/hud/config.d.ts +10 -0
  43. package/dist/hud/config.js +55 -0
  44. package/dist/hud/credentials.d.ts +17 -0
  45. package/dist/hud/credentials.js +99 -0
  46. package/dist/hud/git.d.ts +7 -0
  47. package/dist/hud/git.js +153 -0
  48. package/dist/hud/index.d.ts +2 -0
  49. package/dist/hud/index.js +81 -0
  50. package/dist/hud/render.d.ts +7 -0
  51. package/dist/hud/render.js +111 -0
  52. package/dist/hud/stdin.d.ts +6 -0
  53. package/dist/hud/stdin.js +25 -0
  54. package/dist/hud/transcript.d.ts +7 -0
  55. package/dist/hud/transcript.js +130 -0
  56. package/dist/hud/types.d.ts +116 -0
  57. package/dist/hud/types.js +2 -0
  58. package/dist/hud/usage-api.d.ts +7 -0
  59. package/dist/hud/usage-api.js +84 -0
  60. package/dist/utils/manifest.d.ts +1 -0
  61. package/dist/utils/post-install.d.ts +8 -1
  62. package/dist/utils/post-install.js +41 -0
  63. package/package.json +5 -2
  64. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +1 -1
  65. package/plugins/devflow-ambient/.claude-plugin/plugin.json +1 -1
  66. package/plugins/devflow-ambient/agents/scrutinizer.md +6 -4
  67. package/plugins/devflow-ambient/agents/shepherd.md +26 -12
  68. package/plugins/devflow-ambient/agents/simplifier.md +24 -15
  69. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  70. package/plugins/devflow-code-review/.claude-plugin/plugin.json +1 -1
  71. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +1 -1
  72. package/plugins/devflow-debug/.claude-plugin/plugin.json +1 -1
  73. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +1 -1
  74. package/plugins/devflow-go/.claude-plugin/plugin.json +1 -1
  75. package/plugins/devflow-implement/.claude-plugin/plugin.json +1 -1
  76. package/plugins/devflow-implement/agents/scrutinizer.md +6 -4
  77. package/plugins/devflow-implement/agents/shepherd.md +26 -12
  78. package/plugins/devflow-implement/agents/simplifier.md +24 -15
  79. package/plugins/devflow-implement/skills/self-review/references/stub-detection.md +135 -0
  80. package/plugins/devflow-java/.claude-plugin/plugin.json +1 -1
  81. package/plugins/devflow-python/.claude-plugin/plugin.json +1 -1
  82. package/plugins/devflow-react/.claude-plugin/plugin.json +1 -1
  83. package/plugins/devflow-resolve/.claude-plugin/plugin.json +1 -1
  84. package/plugins/devflow-resolve/agents/simplifier.md +24 -15
  85. package/plugins/devflow-rust/.claude-plugin/plugin.json +1 -1
  86. package/plugins/devflow-self-review/.claude-plugin/plugin.json +1 -1
  87. package/plugins/devflow-self-review/agents/scrutinizer.md +6 -4
  88. package/plugins/devflow-self-review/agents/simplifier.md +24 -15
  89. package/plugins/devflow-self-review/skills/self-review/references/stub-detection.md +135 -0
  90. package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
  91. package/plugins/devflow-typescript/.claude-plugin/plugin.json +1 -1
  92. package/scripts/hud/cache.d.ts +14 -0
  93. package/scripts/hud/cache.d.ts.map +1 -0
  94. package/scripts/hud/cache.js +54 -0
  95. package/scripts/hud/cache.js.map +1 -0
  96. package/scripts/hud/colors.d.ts +23 -0
  97. package/scripts/hud/colors.d.ts.map +1 -0
  98. package/scripts/hud/colors.js +62 -0
  99. package/scripts/hud/colors.js.map +1 -0
  100. package/scripts/hud/components/config-counts.d.ts +8 -0
  101. package/scripts/hud/components/config-counts.d.ts.map +1 -0
  102. package/scripts/hud/components/config-counts.js +91 -0
  103. package/scripts/hud/components/config-counts.js.map +1 -0
  104. package/scripts/hud/components/context-usage.d.ts +8 -0
  105. package/scripts/hud/components/context-usage.d.ts.map +1 -0
  106. package/scripts/hud/components/context-usage.js +49 -0
  107. package/scripts/hud/components/context-usage.js.map +1 -0
  108. package/scripts/hud/components/diff-stats.d.ts +3 -0
  109. package/scripts/hud/components/diff-stats.d.ts.map +1 -0
  110. package/scripts/hud/components/diff-stats.js +36 -0
  111. package/scripts/hud/components/diff-stats.js.map +1 -0
  112. package/scripts/hud/components/directory.d.ts +3 -0
  113. package/scripts/hud/components/directory.d.ts.map +1 -0
  114. package/scripts/hud/components/directory.js +10 -0
  115. package/scripts/hud/components/directory.js.map +1 -0
  116. package/scripts/hud/components/git-ahead-behind.d.ts +3 -0
  117. package/scripts/hud/components/git-ahead-behind.d.ts.map +1 -0
  118. package/scripts/hud/components/git-ahead-behind.js +16 -0
  119. package/scripts/hud/components/git-ahead-behind.js.map +1 -0
  120. package/scripts/hud/components/git-branch.d.ts +3 -0
  121. package/scripts/hud/components/git-branch.d.ts.map +1 -0
  122. package/scripts/hud/components/git-branch.js +14 -0
  123. package/scripts/hud/components/git-branch.js.map +1 -0
  124. package/scripts/hud/components/model.d.ts +3 -0
  125. package/scripts/hud/components/model.d.ts.map +1 -0
  126. package/scripts/hud/components/model.js +21 -0
  127. package/scripts/hud/components/model.js.map +1 -0
  128. package/scripts/hud/components/release-info.d.ts +3 -0
  129. package/scripts/hud/components/release-info.d.ts.map +1 -0
  130. package/scripts/hud/components/release-info.js +9 -0
  131. package/scripts/hud/components/release-info.js.map +1 -0
  132. package/scripts/hud/components/session-cost.d.ts +3 -0
  133. package/scripts/hud/components/session-cost.d.ts.map +1 -0
  134. package/scripts/hud/components/session-cost.js +9 -0
  135. package/scripts/hud/components/session-cost.js.map +1 -0
  136. package/scripts/hud/components/session-duration.d.ts +3 -0
  137. package/scripts/hud/components/session-duration.d.ts.map +1 -0
  138. package/scripts/hud/components/session-duration.js +18 -0
  139. package/scripts/hud/components/session-duration.js.map +1 -0
  140. package/scripts/hud/components/todo-progress.d.ts +3 -0
  141. package/scripts/hud/components/todo-progress.d.ts.map +1 -0
  142. package/scripts/hud/components/todo-progress.js +11 -0
  143. package/scripts/hud/components/todo-progress.js.map +1 -0
  144. package/scripts/hud/components/usage-quota.d.ts +3 -0
  145. package/scripts/hud/components/usage-quota.d.ts.map +1 -0
  146. package/scripts/hud/components/usage-quota.js +45 -0
  147. package/scripts/hud/components/usage-quota.js.map +1 -0
  148. package/scripts/hud/components/version-badge.d.ts +3 -0
  149. package/scripts/hud/components/version-badge.d.ts.map +1 -0
  150. package/scripts/hud/components/version-badge.js +80 -0
  151. package/scripts/hud/components/version-badge.js.map +1 -0
  152. package/scripts/hud/components/worktree-count.d.ts +3 -0
  153. package/scripts/hud/components/worktree-count.d.ts.map +1 -0
  154. package/scripts/hud/components/worktree-count.js +8 -0
  155. package/scripts/hud/components/worktree-count.js.map +1 -0
  156. package/scripts/hud/config.d.ts +10 -0
  157. package/scripts/hud/config.d.ts.map +1 -0
  158. package/scripts/hud/config.js +55 -0
  159. package/scripts/hud/config.js.map +1 -0
  160. package/scripts/hud/credentials.d.ts +17 -0
  161. package/scripts/hud/credentials.d.ts.map +1 -0
  162. package/scripts/hud/credentials.js +99 -0
  163. package/scripts/hud/credentials.js.map +1 -0
  164. package/scripts/hud/git.d.ts +7 -0
  165. package/scripts/hud/git.d.ts.map +1 -0
  166. package/scripts/hud/git.js +153 -0
  167. package/scripts/hud/git.js.map +1 -0
  168. package/scripts/hud/index.d.ts +2 -0
  169. package/scripts/hud/index.d.ts.map +1 -0
  170. package/scripts/hud/index.js +81 -0
  171. package/scripts/hud/index.js.map +1 -0
  172. package/scripts/hud/render.d.ts +7 -0
  173. package/scripts/hud/render.d.ts.map +1 -0
  174. package/scripts/hud/render.js +111 -0
  175. package/scripts/hud/render.js.map +1 -0
  176. package/scripts/hud/stdin.d.ts +6 -0
  177. package/scripts/hud/stdin.d.ts.map +1 -0
  178. package/scripts/hud/stdin.js +25 -0
  179. package/scripts/hud/stdin.js.map +1 -0
  180. package/scripts/hud/transcript.d.ts +7 -0
  181. package/scripts/hud/transcript.d.ts.map +1 -0
  182. package/scripts/hud/transcript.js +130 -0
  183. package/scripts/hud/transcript.js.map +1 -0
  184. package/scripts/hud/types.d.ts +116 -0
  185. package/scripts/hud/types.d.ts.map +1 -0
  186. package/scripts/hud/types.js +2 -0
  187. package/scripts/hud/types.js.map +1 -0
  188. package/scripts/hud/usage-api.d.ts +7 -0
  189. package/scripts/hud/usage-api.d.ts.map +1 -0
  190. package/scripts/hud/usage-api.js +84 -0
  191. package/scripts/hud/usage-api.js.map +1 -0
  192. package/scripts/hud.sh +5 -0
  193. package/shared/agents/scrutinizer.md +6 -4
  194. package/shared/agents/shepherd.md +26 -12
  195. package/shared/agents/simplifier.md +24 -15
  196. package/shared/skills/self-review/references/stub-detection.md +135 -0
  197. package/src/templates/settings.json +1 -1
@@ -0,0 +1,153 @@
1
+ import { execFile } from 'node:child_process';
2
+ const GIT_TIMEOUT = 1000; // 1s per command
3
+ function shellExec(cmd, args, cwd) {
4
+ return new Promise((resolve) => {
5
+ execFile(cmd, args, { cwd, timeout: GIT_TIMEOUT }, (err, stdout) => {
6
+ resolve(err ? '' : stdout.trim());
7
+ });
8
+ });
9
+ }
10
+ function gitExec(args, cwd) {
11
+ return shellExec('git', args, cwd);
12
+ }
13
+ /**
14
+ * Gather git status for the given working directory.
15
+ * Returns null if not in a git repo or on error.
16
+ */
17
+ export async function gatherGitStatus(cwd) {
18
+ // Check if in a git repo
19
+ const topLevel = await gitExec(['rev-parse', '--show-toplevel'], cwd);
20
+ if (!topLevel)
21
+ return null;
22
+ // Branch name
23
+ const branch = await gitExec(['rev-parse', '--abbrev-ref', 'HEAD'], cwd);
24
+ if (!branch)
25
+ return null;
26
+ // Dirty check
27
+ const statusOutput = await gitExec(['status', '--porcelain', '--no-optional-locks'], cwd);
28
+ let dirty = false;
29
+ let staged = false;
30
+ for (const line of statusOutput.split('\n')) {
31
+ if (line.length < 2)
32
+ continue;
33
+ const index = line[0];
34
+ const worktree = line[1];
35
+ // Index column: staged change (A/M/D/R/C)
36
+ if (index !== ' ' && index !== '?')
37
+ staged = true;
38
+ // Worktree column: unstaged change (M/D), or untracked (??)
39
+ if (worktree !== ' ' || index === '?')
40
+ dirty = true;
41
+ }
42
+ // Ahead/behind — detect base branch with layered fallback (ported from statusline.sh)
43
+ const baseBranch = await detectBaseBranch(branch, cwd);
44
+ let ahead = 0;
45
+ let behind = 0;
46
+ if (baseBranch) {
47
+ const revList = await gitExec(['rev-list', '--left-right', '--count', `${baseBranch}...HEAD`], cwd);
48
+ const parts = revList.split(/\s+/);
49
+ if (parts.length === 2) {
50
+ behind = parseInt(parts[0], 10) || 0;
51
+ ahead = parseInt(parts[1], 10) || 0;
52
+ }
53
+ }
54
+ // Diff stats against base
55
+ let filesChanged = 0;
56
+ let additions = 0;
57
+ let deletions = 0;
58
+ if (baseBranch) {
59
+ const diffStat = await gitExec(['diff', '--shortstat', baseBranch], cwd);
60
+ const filesMatch = diffStat.match(/(\d+)\s+file/);
61
+ const addMatch = diffStat.match(/(\d+)\s+insertion/);
62
+ const delMatch = diffStat.match(/(\d+)\s+deletion/);
63
+ filesChanged = filesMatch ? parseInt(filesMatch[1], 10) : 0;
64
+ additions = addMatch ? parseInt(addMatch[1], 10) : 0;
65
+ deletions = delMatch ? parseInt(delMatch[1], 10) : 0;
66
+ }
67
+ // Tag and worktree info (parallel)
68
+ const [tagOutput, worktreeOutput] = await Promise.all([
69
+ gitExec(['describe', '--tags', '--abbrev=0'], cwd),
70
+ gitExec(['worktree', 'list'], cwd),
71
+ ]);
72
+ const lastTag = tagOutput || null;
73
+ let commitsSinceTag = 0;
74
+ if (lastTag) {
75
+ const countOutput = await gitExec(['rev-list', `${lastTag}..HEAD`, '--count'], cwd);
76
+ commitsSinceTag = parseInt(countOutput, 10) || 0;
77
+ }
78
+ const worktreeCount = worktreeOutput
79
+ ? worktreeOutput.split('\n').filter(l => l.trim().length > 0).length
80
+ : 1;
81
+ return {
82
+ branch,
83
+ dirty,
84
+ staged,
85
+ ahead,
86
+ behind,
87
+ filesChanged,
88
+ additions,
89
+ deletions,
90
+ lastTag,
91
+ commitsSinceTag,
92
+ worktreeCount,
93
+ };
94
+ }
95
+ /**
96
+ * Detect the base branch for ahead/behind calculations.
97
+ * Uses a 4-layer fallback (ported from statusline.sh):
98
+ * 1. Branch reflog ("Created from")
99
+ * 2. HEAD reflog ("checkout: moving from X to branch")
100
+ * 3. GitHub PR base branch (gh pr view, cached)
101
+ * 4. main/master fallback
102
+ */
103
+ async function detectBaseBranch(branch, cwd) {
104
+ // Layer 1: branch reflog — look for "branch: Created from"
105
+ const branchLog = await gitExec(['reflog', 'show', branch, '--format=%gs', '-n', '1'], cwd);
106
+ const createdMatch = branchLog.match(/branch: Created from (.+)/);
107
+ if (createdMatch) {
108
+ const candidate = createdMatch[1];
109
+ if (candidate !== 'HEAD' && !candidate.includes('~')) {
110
+ const exists = await gitExec(['rev-parse', '--verify', candidate], cwd);
111
+ if (exists)
112
+ return candidate;
113
+ }
114
+ }
115
+ // Layer 2: HEAD reflog — look for "checkout: moving from X to branch"
116
+ const headLog = await gitExec(['reflog', 'show', 'HEAD', '--format=%gs'], cwd);
117
+ const escapedBranch = branch.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
118
+ const checkoutPattern = new RegExp(`checkout: moving from (\\S+) to ${escapedBranch}`);
119
+ for (const line of headLog.split('\n')) {
120
+ const match = line.match(checkoutPattern);
121
+ if (match) {
122
+ const candidate = match[1];
123
+ // Skip raw commit hashes and the current branch
124
+ if (candidate === branch || /^[0-9a-f]{7,}$/.test(candidate))
125
+ continue;
126
+ const exists = await gitExec(['rev-parse', '--verify', candidate], cwd);
127
+ if (exists)
128
+ return candidate;
129
+ }
130
+ }
131
+ // Layer 3: GitHub PR base branch via gh CLI
132
+ const prBase = await shellExec('gh', ['pr', 'view', '--json', 'baseRefName', '-q', '.baseRefName'], cwd);
133
+ if (prBase) {
134
+ const exists = await gitExec(['rev-parse', '--verify', prBase], cwd);
135
+ if (exists)
136
+ return prBase;
137
+ }
138
+ // Layer 4: main/master fallback (skip if already on that branch — use remote tracking instead)
139
+ for (const candidate of ['main', 'master']) {
140
+ if (candidate === branch) {
141
+ // On main/master itself — compare against remote tracking branch
142
+ const remote = await gitExec(['rev-parse', '--verify', `origin/${candidate}`], cwd);
143
+ if (remote)
144
+ return `origin/${candidate}`;
145
+ continue;
146
+ }
147
+ const exists = await gitExec(['rev-parse', '--verify', candidate], cwd);
148
+ if (exists)
149
+ return candidate;
150
+ }
151
+ return null;
152
+ }
153
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/cli/hud/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/hud/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { readStdin } from './stdin.js';
5
+ import { loadConfig, resolveComponents } from './config.js';
6
+ import { gatherGitStatus } from './git.js';
7
+ import { parseTranscript } from './transcript.js';
8
+ import { fetchUsageData } from './usage-api.js';
9
+ import { gatherConfigCounts } from './components/config-counts.js';
10
+ import { render } from './render.js';
11
+ const OVERALL_TIMEOUT = 2000; // 2 second overall timeout
12
+ async function main() {
13
+ const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), OVERALL_TIMEOUT));
14
+ try {
15
+ const result = await Promise.race([run(), timeoutPromise]);
16
+ process.stdout.write(result);
17
+ }
18
+ catch {
19
+ // Timeout or error — output nothing (graceful degradation)
20
+ }
21
+ }
22
+ async function run() {
23
+ const stdin = await readStdin();
24
+ // Debug: dump raw stdin to file when DEVFLOW_HUD_DEBUG is set
25
+ if (process.env.DEVFLOW_HUD_DEBUG) {
26
+ fs.writeFileSync(process.env.DEVFLOW_HUD_DEBUG, JSON.stringify(stdin, null, 2));
27
+ }
28
+ const config = loadConfig();
29
+ const resolved = resolveComponents(config);
30
+ const components = new Set(resolved);
31
+ const cwd = stdin.cwd || process.cwd();
32
+ const devflowDir = process.env.DEVFLOW_DIR ||
33
+ path.join(process.env.HOME || homedir(), '.devflow');
34
+ // Determine what data to gather based on enabled components
35
+ const needsGit = components.has('gitBranch') ||
36
+ components.has('gitAheadBehind') ||
37
+ components.has('diffStats') ||
38
+ components.has('releaseInfo') ||
39
+ components.has('worktreeCount');
40
+ const needsTranscript = components.has('todoProgress') ||
41
+ components.has('configCounts');
42
+ const needsUsage = components.has('usageQuota');
43
+ const needsConfigCounts = components.has('configCounts');
44
+ // Parallel data gathering — only fetch what's needed
45
+ const [git, transcript, usage] = await Promise.all([
46
+ needsGit ? gatherGitStatus(cwd) : Promise.resolve(null),
47
+ needsTranscript && stdin.transcript_path
48
+ ? parseTranscript(stdin.transcript_path)
49
+ : Promise.resolve(null),
50
+ needsUsage ? fetchUsageData() : Promise.resolve(null),
51
+ ]);
52
+ // Session start time from transcript file creation time
53
+ let sessionStartTime = null;
54
+ if (stdin.transcript_path) {
55
+ try {
56
+ const stat = fs.statSync(stdin.transcript_path);
57
+ sessionStartTime = stat.birthtime.getTime();
58
+ }
59
+ catch { /* file may not exist yet */ }
60
+ }
61
+ // Config counts (fast, synchronous filesystem reads)
62
+ const configCountsData = needsConfigCounts
63
+ ? gatherConfigCounts(cwd)
64
+ : null;
65
+ // Terminal width via stderr (stdout is piped to Claude Code)
66
+ const terminalWidth = process.stderr.columns || 120;
67
+ const ctx = {
68
+ stdin,
69
+ git,
70
+ transcript,
71
+ usage,
72
+ configCounts: configCountsData,
73
+ config: { ...config, components: resolved },
74
+ devflowDir,
75
+ sessionStartTime,
76
+ terminalWidth,
77
+ };
78
+ return render(ctx);
79
+ }
80
+ main();
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/hud/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { GatherContext } from './types.js';
2
+ /**
3
+ * Render all enabled components into a multi-line HUD string.
4
+ * Components that return null are excluded. Empty lines are skipped.
5
+ */
6
+ export declare function render(ctx: GatherContext): Promise<string>;
7
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/cli/hud/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,aAAa,EAEd,MAAM,YAAY,CAAC;AAsDpB;;;GAGG;AACH,wBAAsB,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA+DhE"}
@@ -0,0 +1,111 @@
1
+ import { dim } from './colors.js';
2
+ import directory from './components/directory.js';
3
+ import gitBranch from './components/git-branch.js';
4
+ import gitAheadBehind from './components/git-ahead-behind.js';
5
+ import diffStats from './components/diff-stats.js';
6
+ import model from './components/model.js';
7
+ import contextUsage from './components/context-usage.js';
8
+ import versionBadge from './components/version-badge.js';
9
+ import sessionDuration from './components/session-duration.js';
10
+ import usageQuota from './components/usage-quota.js';
11
+ import todoProgress from './components/todo-progress.js';
12
+ import configCounts from './components/config-counts.js';
13
+ import sessionCost from './components/session-cost.js';
14
+ import releaseInfo from './components/release-info.js';
15
+ import worktreeCount from './components/worktree-count.js';
16
+ const COMPONENT_MAP = {
17
+ directory,
18
+ gitBranch,
19
+ gitAheadBehind,
20
+ diffStats,
21
+ model,
22
+ contextUsage,
23
+ versionBadge,
24
+ sessionDuration,
25
+ usageQuota,
26
+ todoProgress,
27
+ configCounts,
28
+ sessionCost,
29
+ releaseInfo,
30
+ worktreeCount,
31
+ };
32
+ /**
33
+ * Line groupings for smart layout.
34
+ * Components are assigned to lines and only rendered if enabled.
35
+ * null entries denote section breaks (blank line between sections).
36
+ */
37
+ const LINE_GROUPS = [
38
+ // Section 1: Info (3 lines)
39
+ ['directory', 'gitBranch', 'gitAheadBehind', 'releaseInfo', 'worktreeCount', 'diffStats'],
40
+ ['contextUsage', 'usageQuota'],
41
+ ['model', 'sessionDuration', 'sessionCost', 'configCounts'],
42
+ // --- section break ---
43
+ null,
44
+ // Section 2: Activity
45
+ ['todoProgress'],
46
+ ['versionBadge'],
47
+ ];
48
+ const SEPARATOR = dim(' \u00B7 ');
49
+ /**
50
+ * Render all enabled components into a multi-line HUD string.
51
+ * Components that return null are excluded. Empty lines are skipped.
52
+ */
53
+ export async function render(ctx) {
54
+ const enabled = new Set(ctx.config.components);
55
+ // Render all enabled components in parallel
56
+ const results = new Map();
57
+ const promises = [];
58
+ for (const id of enabled) {
59
+ const fn = COMPONENT_MAP[id];
60
+ if (!fn)
61
+ continue;
62
+ promises.push(fn(ctx)
63
+ .then((result) => {
64
+ if (result)
65
+ results.set(id, result);
66
+ })
67
+ .catch(() => {
68
+ /* Component failure is non-fatal */
69
+ }));
70
+ }
71
+ await Promise.all(promises);
72
+ // Assemble lines using smart layout with section breaks
73
+ const lines = [];
74
+ let pendingBreak = false;
75
+ for (const entry of LINE_GROUPS) {
76
+ if (entry === null) {
77
+ if (lines.length > 0)
78
+ pendingBreak = true;
79
+ continue;
80
+ }
81
+ const lineResults = entry
82
+ .filter((id) => enabled.has(id) && results.has(id))
83
+ .map((id) => results.get(id));
84
+ if (lineResults.length > 0) {
85
+ if (pendingBreak) {
86
+ lines.push('');
87
+ pendingBreak = false;
88
+ }
89
+ // Separate multi-line results (containing newlines) from single-line
90
+ const singleLine = [];
91
+ for (const r of lineResults) {
92
+ if (r.text.includes('\n')) {
93
+ // Flush any accumulated single-line parts first
94
+ if (singleLine.length > 0) {
95
+ lines.push(singleLine.join(SEPARATOR));
96
+ singleLine.length = 0;
97
+ }
98
+ lines.push(r.text);
99
+ }
100
+ else {
101
+ singleLine.push(r.text);
102
+ }
103
+ }
104
+ if (singleLine.length > 0) {
105
+ lines.push(singleLine.join(SEPARATOR));
106
+ }
107
+ }
108
+ }
109
+ return lines.join('\n');
110
+ }
111
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/cli/hud/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { StdinData } from './types.js';
2
+ /**
3
+ * Read and parse JSON from stdin. Returns empty object on parse failure.
4
+ */
5
+ export declare function readStdin(): Promise<StdinData>;
6
+ //# sourceMappingURL=stdin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin.d.ts","sourceRoot":"","sources":["../../src/cli/hud/stdin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,CAmB9C"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Read and parse JSON from stdin. Returns empty object on parse failure.
3
+ */
4
+ export function readStdin() {
5
+ return new Promise((resolve) => {
6
+ let data = '';
7
+ process.stdin.setEncoding('utf-8');
8
+ process.stdin.on('data', (chunk) => {
9
+ data += chunk;
10
+ });
11
+ process.stdin.on('end', () => {
12
+ try {
13
+ resolve(JSON.parse(data));
14
+ }
15
+ catch {
16
+ resolve({});
17
+ }
18
+ });
19
+ process.stdin.on('error', () => {
20
+ resolve({});
21
+ });
22
+ process.stdin.resume();
23
+ });
24
+ }
25
+ //# sourceMappingURL=stdin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin.js","sourceRoot":"","sources":["../../src/cli/hud/stdin.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,IAAI,IAAI,KAAK,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YAC3B,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAc,CAAC,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,EAAE,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAC7B,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { TranscriptData } from './types.js';
2
+ /**
3
+ * Parse a Claude Code session transcript (JSONL) to extract tool/agent activity and todo progress.
4
+ * Returns null if the file doesn't exist or can't be parsed.
5
+ */
6
+ export declare function parseTranscript(transcriptPath: string): Promise<TranscriptData | null>;
7
+ //# sourceMappingURL=transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/cli/hud/transcript.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAsDhC"}
@@ -0,0 +1,130 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as readline from 'node:readline';
4
+ // Precompiled patterns
5
+ const TODO_WRITE_NAME = /^TodoWrite$/i;
6
+ /**
7
+ * Parse a Claude Code session transcript (JSONL) to extract tool/agent activity and todo progress.
8
+ * Returns null if the file doesn't exist or can't be parsed.
9
+ */
10
+ export async function parseTranscript(transcriptPath) {
11
+ try {
12
+ if (!fs.existsSync(transcriptPath))
13
+ return null;
14
+ const tools = new Map();
15
+ const agents = new Map();
16
+ const skills = new Set();
17
+ let todosCompleted = 0;
18
+ let todosTotal = 0;
19
+ const stream = fs.createReadStream(transcriptPath, { encoding: 'utf-8' });
20
+ const rl = readline.createInterface({
21
+ input: stream,
22
+ crlfDelay: Infinity,
23
+ });
24
+ for await (const line of rl) {
25
+ if (!line.trim())
26
+ continue;
27
+ try {
28
+ const entry = JSON.parse(line);
29
+ // Turn boundary: clear tools and agents on each human message
30
+ // so only the current turn's activity shows in the HUD
31
+ if (entry.type === 'human') {
32
+ tools.clear();
33
+ agents.clear();
34
+ continue;
35
+ }
36
+ const todoResult = processEntry(entry, tools, agents, skills);
37
+ if (todoResult) {
38
+ todosCompleted = todoResult.completed;
39
+ todosTotal = todoResult.total;
40
+ }
41
+ }
42
+ catch {
43
+ // Skip malformed lines
44
+ }
45
+ }
46
+ return {
47
+ tools: Array.from(tools.values()),
48
+ agents: Array.from(agents.values()),
49
+ todos: { completed: todosCompleted, total: todosTotal },
50
+ skills: Array.from(skills),
51
+ };
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ }
57
+ function processEntry(entry, tools, agents, skills) {
58
+ if (entry.type !== 'assistant' || !entry.message)
59
+ return null;
60
+ const message = entry.message;
61
+ if (!Array.isArray(message.content))
62
+ return null;
63
+ let todoResult = null;
64
+ for (const block of message.content) {
65
+ const blockType = block.type;
66
+ if (blockType === 'tool_use') {
67
+ const name = block.name;
68
+ const id = block.id;
69
+ if (name === 'Agent' || name === 'Task') {
70
+ // Agent spawn
71
+ const input = block.input;
72
+ const agentType = input?.subagent_type || 'Agent';
73
+ const agentDesc = typeof input?.description === 'string' ? input.description : undefined;
74
+ agents.set(id, {
75
+ name: agentType,
76
+ model: input?.model,
77
+ status: 'running',
78
+ description: agentDesc,
79
+ });
80
+ }
81
+ else if (name === 'Skill') {
82
+ // Track loaded skills
83
+ const input = block.input;
84
+ if (input?.skill && typeof input.skill === 'string') {
85
+ skills.add(input.skill);
86
+ }
87
+ }
88
+ else if (TODO_WRITE_NAME.test(name)) {
89
+ // Track todos
90
+ const input = block.input;
91
+ const todos = input?.todos;
92
+ if (Array.isArray(todos)) {
93
+ const total = todos.length;
94
+ const completed = todos.filter((t) => t.status === 'completed').length;
95
+ todoResult = { completed, total };
96
+ }
97
+ }
98
+ else {
99
+ // Regular tool — extract file target for Read/Edit/Write
100
+ const input = block.input;
101
+ let target;
102
+ if (input?.file_path && typeof input.file_path === 'string') {
103
+ target = path.basename(input.file_path);
104
+ }
105
+ // Extract description: prefer input.description, fallback to first 4 words of command (Bash)
106
+ let description;
107
+ if (typeof input?.description === 'string') {
108
+ description = input.description;
109
+ }
110
+ else if (name === 'Bash' && typeof input?.command === 'string') {
111
+ description = input.command.split(/\s+/).slice(0, 4).join(' ');
112
+ }
113
+ tools.set(id, { name, status: 'running', target, description });
114
+ }
115
+ }
116
+ else if (blockType === 'tool_result') {
117
+ const toolUseId = block.tool_use_id;
118
+ const toolEntry = tools.get(toolUseId);
119
+ if (toolEntry) {
120
+ toolEntry.status = 'completed';
121
+ }
122
+ const agentEntry = agents.get(toolUseId);
123
+ if (agentEntry) {
124
+ agentEntry.status = 'completed';
125
+ }
126
+ }
127
+ }
128
+ return todoResult;
129
+ }
130
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/cli/hud/transcript.ts"],"names":[],"mappings":"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"}