oh-my-claude-sisyphus 3.7.0 → 3.7.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 (66) hide show
  1. package/README.md +24 -1
  2. package/commands/hud.md +37 -5
  3. package/commands/omc-setup.md +105 -0
  4. package/dist/__tests__/hud/analytics-display.test.js +137 -1
  5. package/dist/__tests__/hud/analytics-display.test.js.map +1 -1
  6. package/dist/__tests__/hud-windows.test.d.ts +2 -0
  7. package/dist/__tests__/hud-windows.test.d.ts.map +1 -0
  8. package/dist/__tests__/hud-windows.test.js +91 -0
  9. package/dist/__tests__/hud-windows.test.js.map +1 -0
  10. package/dist/features/rate-limit-wait/daemon.d.ts.map +1 -1
  11. package/dist/features/rate-limit-wait/daemon.js +41 -1
  12. package/dist/features/rate-limit-wait/daemon.js.map +1 -1
  13. package/dist/features/state-manager/index.d.ts.map +1 -1
  14. package/dist/features/state-manager/index.js +4 -1
  15. package/dist/features/state-manager/index.js.map +1 -1
  16. package/dist/hooks/permission-handler/__tests__/index.test.js +47 -0
  17. package/dist/hooks/permission-handler/__tests__/index.test.js.map +1 -1
  18. package/dist/hooks/permission-handler/index.d.ts +1 -1
  19. package/dist/hooks/permission-handler/index.d.ts.map +1 -1
  20. package/dist/hooks/permission-handler/index.js +11 -15
  21. package/dist/hooks/permission-handler/index.js.map +1 -1
  22. package/dist/hooks/plugin-patterns/index.d.ts +5 -0
  23. package/dist/hooks/plugin-patterns/index.d.ts.map +1 -1
  24. package/dist/hooks/plugin-patterns/index.js +26 -1
  25. package/dist/hooks/plugin-patterns/index.js.map +1 -1
  26. package/dist/hooks/session-end/index.d.ts +0 -8
  27. package/dist/hooks/session-end/index.d.ts.map +1 -1
  28. package/dist/hooks/session-end/index.js +5 -12
  29. package/dist/hooks/session-end/index.js.map +1 -1
  30. package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
  31. package/dist/hooks/subagent-tracker/index.js +32 -17
  32. package/dist/hooks/subagent-tracker/index.js.map +1 -1
  33. package/dist/hud/analytics-display.d.ts +16 -0
  34. package/dist/hud/analytics-display.d.ts.map +1 -1
  35. package/dist/hud/analytics-display.js +35 -9
  36. package/dist/hud/analytics-display.js.map +1 -1
  37. package/dist/hud/render.d.ts.map +1 -1
  38. package/dist/hud/render.js +49 -18
  39. package/dist/hud/render.js.map +1 -1
  40. package/dist/hud/types.d.ts +2 -0
  41. package/dist/hud/types.d.ts.map +1 -1
  42. package/dist/hud/types.js +14 -0
  43. package/dist/hud/types.js.map +1 -1
  44. package/dist/installer/index.d.ts.map +1 -1
  45. package/dist/installer/index.js +3 -2
  46. package/dist/installer/index.js.map +1 -1
  47. package/hooks/keyword-detector.sh +4 -4
  48. package/hooks/persistent-mode.sh +10 -10
  49. package/hooks/session-start.sh +4 -4
  50. package/package.json +1 -1
  51. package/scripts/keyword-detector.mjs +4 -4
  52. package/scripts/persistent-mode.mjs +6 -6
  53. package/scripts/persistent-mode.sh +10 -10
  54. package/scripts/session-start.mjs +4 -4
  55. package/skills/hud/SKILL.md +37 -5
  56. package/skills/omc-setup/SKILL.md +162 -4
  57. package/skills/writer-memory/SKILL.md +443 -0
  58. package/skills/writer-memory/lib/character-tracker.ts +338 -0
  59. package/skills/writer-memory/lib/memory-manager.ts +804 -0
  60. package/skills/writer-memory/lib/relationship-graph.ts +400 -0
  61. package/skills/writer-memory/lib/scene-organizer.ts +544 -0
  62. package/skills/writer-memory/lib/synopsis-builder.ts +339 -0
  63. package/skills/writer-memory/templates/synopsis-template.md +46 -0
  64. package/templates/hooks/keyword-detector.sh +4 -4
  65. package/templates/hooks/persistent-mode.sh +10 -10
  66. package/templates/hooks/session-start.sh +4 -4
package/README.md CHANGED
@@ -1,4 +1,8 @@
1
- <div align="center">
1
+ # Oh-My-ClaudeCode
2
+
3
+ [![npm version](https://img.shields.io/npm/v/oh-my-claude-sisyphus.svg)](https://www.npmjs.com/package/oh-my-claude-sisyphus)
4
+ [![Sponsor](https://img.shields.io/badge/Sponsor-❤️-red?style=flat&logo=github)](https://github.com/sponsors/Yeachan-Heo)
5
+
2
6
 
3
7
  ![oh-my-claudecode](https://raw.githubusercontent.com/Yeachan-Heo/oh-my-claudecode-website/main/social-preview.png)
4
8
 
@@ -146,3 +150,22 @@ MIT
146
150
  ## Star History
147
151
 
148
152
  [![Star History Chart](https://api.star-history.com/svg?repos=Yeachan-Heo/oh-my-claudecode&type=date&legend=top-left)](https://www.star-history.com/#Yeachan-Heo/oh-my-claudecode&type=date&legend=top-left)
153
+
154
+ ## 💖 Support This Project
155
+
156
+ If Oh-My-ClaudeCode helps your workflow, consider sponsoring:
157
+
158
+ [![Sponsor on GitHub](https://img.shields.io/badge/Sponsor-❤️-red?style=for-the-badge&logo=github)](https://github.com/sponsors/Yeachan-Heo)
159
+
160
+ **Why sponsor?**
161
+ - Keep development active
162
+ - Priority support for sponsors
163
+ - Influence roadmap & features
164
+ - Help maintain free & open source
165
+
166
+ **Other ways to help:**
167
+ - ⭐ Star the repo
168
+ - 🐛 Report bugs
169
+ - 💡 Suggest features
170
+ - 📝 Contribute code
171
+
package/commands/hud.md CHANGED
@@ -78,6 +78,19 @@ Then, use the Write tool to create `~/.claude/hud/omc-hud.mjs` with this exact c
78
78
  import { existsSync, readdirSync } from "node:fs";
79
79
  import { homedir } from "node:os";
80
80
  import { join } from "node:path";
81
+ import { pathToFileURL } from "node:url";
82
+
83
+ // Semantic version comparison: returns negative if a < b, positive if a > b, 0 if equal
84
+ function semverCompare(a, b) {
85
+ const pa = a.replace(/^v/, "").split(".").map(Number);
86
+ const pb = b.replace(/^v/, "").split(".").map(Number);
87
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
88
+ const na = pa[i] || 0;
89
+ const nb = pb[i] || 0;
90
+ if (na !== nb) return na - nb;
91
+ }
92
+ return 0;
93
+ }
81
94
 
82
95
  async function main() {
83
96
  const home = homedir();
@@ -89,11 +102,11 @@ async function main() {
89
102
  try {
90
103
  const versions = readdirSync(pluginCacheBase);
91
104
  if (versions.length > 0) {
92
- const latestVersion = versions.sort().reverse()[0];
105
+ const latestVersion = versions.sort(semverCompare).reverse()[0];
93
106
  pluginCacheDir = join(pluginCacheBase, latestVersion);
94
107
  const pluginPath = join(pluginCacheDir, "dist/hud/index.js");
95
108
  if (existsSync(pluginPath)) {
96
- await import(pluginPath);
109
+ await import(pathToFileURL(pluginPath).href);
97
110
  return;
98
111
  }
99
112
  }
@@ -111,7 +124,7 @@ async function main() {
111
124
  for (const devPath of devPaths) {
112
125
  if (existsSync(devPath)) {
113
126
  try {
114
- await import(devPath);
127
+ await import(pathToFileURL(devPath).href);
115
128
  return;
116
129
  } catch { /* continue */ }
117
130
  }
@@ -135,12 +148,31 @@ chmod +x ~/.claude/hud/omc-hud.mjs
135
148
 
136
149
  **Step 4:** Update settings.json to use the HUD:
137
150
 
138
- Read `~/.claude/settings.json`, then update/add the `statusLine` field:
151
+ Read `~/.claude/settings.json`, then update/add the `statusLine` field.
152
+
153
+ **IMPORTANT:** The command must use an absolute path, not `~`, because Windows does not expand `~` in shell commands.
154
+
155
+ First, determine the correct path:
156
+ ```bash
157
+ node -e "const p=require('path').join(require('os').homedir(),'.claude','hud','omc-hud.mjs');console.log(JSON.stringify(p))"
158
+ ```
159
+
160
+ Then set the `statusLine` field using the resolved path. On Unix it will look like:
161
+ ```json
162
+ {
163
+ "statusLine": {
164
+ "type": "command",
165
+ "command": "node /home/username/.claude/hud/omc-hud.mjs"
166
+ }
167
+ }
168
+ ```
169
+
170
+ On Windows it will look like:
139
171
  ```json
140
172
  {
141
173
  "statusLine": {
142
174
  "type": "command",
143
- "command": "node ~/.claude/hud/omc-hud.mjs"
175
+ "command": "node C:\\Users\\username\\.claude\\hud\\omc-hud.mjs"
144
176
  }
145
177
  }
146
178
  ```
@@ -6,6 +6,73 @@ description: One-time setup for oh-my-claudecode (the ONLY command you need to l
6
6
 
7
7
  This is the **only command you need to learn**. After running this, everything else is automatic.
8
8
 
9
+ ## Graceful Interrupt Handling
10
+
11
+ **IMPORTANT**: This setup process saves progress after each step. If interrupted (Ctrl+C or connection loss), the setup can resume from where it left off.
12
+
13
+ ### Resume Detection (Step 0)
14
+
15
+ Before starting any step, check for existing state:
16
+
17
+ ```bash
18
+ # Check for existing setup state
19
+ STATE_FILE=".omc/state/setup-state.json"
20
+
21
+ # Cross-platform ISO date to epoch conversion
22
+ iso_to_epoch() {
23
+ local iso_date="$1"
24
+ local epoch=""
25
+ # Try GNU date first (Linux)
26
+ epoch=$(date -d "$iso_date" +%s 2>/dev/null)
27
+ if [ $? -eq 0 ] && [ -n "$epoch" ]; then
28
+ echo "$epoch"
29
+ return 0
30
+ fi
31
+ # Try BSD/macOS date
32
+ local clean_date=$(echo "$iso_date" | sed 's/[+-][0-9][0-9]:[0-9][0-9]$//' | sed 's/Z$//' | sed 's/T/ /')
33
+ epoch=$(date -j -f "%Y-%m-%d %H:%M:%S" "$clean_date" +%s 2>/dev/null)
34
+ if [ $? -eq 0 ] && [ -n "$epoch" ]; then
35
+ echo "$epoch"
36
+ return 0
37
+ fi
38
+ echo "0"
39
+ }
40
+
41
+ if [ -f "$STATE_FILE" ]; then
42
+ # Check if state is stale (older than 24 hours)
43
+ TIMESTAMP_RAW=$(jq -r '.timestamp // empty' "$STATE_FILE" 2>/dev/null)
44
+ if [ -n "$TIMESTAMP_RAW" ]; then
45
+ TIMESTAMP_EPOCH=$(iso_to_epoch "$TIMESTAMP_RAW")
46
+ NOW_EPOCH=$(date +%s)
47
+ STATE_AGE=$((NOW_EPOCH - TIMESTAMP_EPOCH))
48
+ else
49
+ STATE_AGE=999999 # Force fresh start if no timestamp
50
+ fi
51
+ if [ "$STATE_AGE" -gt 86400 ]; then
52
+ echo "Previous setup state is more than 24 hours old. Starting fresh."
53
+ rm -f "$STATE_FILE"
54
+ else
55
+ LAST_STEP=$(jq -r ".lastCompletedStep // 0" "$STATE_FILE" 2>/dev/null || echo "0")
56
+ TIMESTAMP=$(jq -r .timestamp "$STATE_FILE" 2>/dev/null || echo "unknown")
57
+ echo "Found previous setup session (Step $LAST_STEP completed at $TIMESTAMP)"
58
+ fi
59
+ fi
60
+ ```
61
+
62
+ If state exists, use AskUserQuestion to prompt:
63
+
64
+ **Question:** "Found a previous setup session. Would you like to resume or start fresh?"
65
+
66
+ **Options:**
67
+ 1. **Resume from step $LAST_STEP** - Continue where you left off
68
+ 2. **Start fresh** - Begin from the beginning (clears saved state)
69
+
70
+ If user chooses "Start fresh":
71
+ ```bash
72
+ rm -f ".omc/state/setup-state.json"
73
+ echo "Previous state cleared. Starting fresh setup."
74
+ ```
75
+
9
76
  ## Step 1: Ask User Preference
10
77
 
11
78
  Use the AskUserQuestion tool to prompt the user:
@@ -227,6 +294,44 @@ CLI ANALYTICS (if installed):
227
294
  Your workflow won't break - it just got easier!
228
295
  ```
229
296
 
297
+ ## Step 8: Ask About Starring Repository
298
+
299
+ First, check if `gh` CLI is available and authenticated:
300
+
301
+ ```bash
302
+ gh auth status &>/dev/null
303
+ ```
304
+
305
+ ### If gh is available and authenticated:
306
+
307
+ Use the AskUserQuestion tool to prompt the user:
308
+
309
+ **Question:** "If you're enjoying oh-my-claudecode, would you like to support the project by starring it on GitHub?"
310
+
311
+ **Options:**
312
+ 1. **Yes, star it!** - Star the repository
313
+ 2. **No thanks** - Skip without further prompts
314
+ 3. **Maybe later** - Skip without further prompts
315
+
316
+ If user chooses "Yes, star it!":
317
+
318
+ ```bash
319
+ gh api -X PUT /user/starred/Yeachan-Heo/oh-my-claudecode 2>/dev/null && echo "Thanks for starring! ⭐" || echo "Could not star - you can star manually at https://github.com/Yeachan-Heo/oh-my-claudecode"
320
+ ```
321
+
322
+ **Note:** Fail gracefully if the API call doesn't work - never block setup completion.
323
+
324
+ ### If gh is NOT available or not authenticated:
325
+
326
+ Skip the AskUserQuestion and just display:
327
+
328
+ ```bash
329
+ echo ""
330
+ echo "If you enjoy oh-my-claudecode, consider starring the repo:"
331
+ echo " https://github.com/Yeachan-Heo/oh-my-claudecode"
332
+ echo ""
333
+ ```
334
+
230
335
  ## Fallback
231
336
 
232
337
  If curl fails, tell user to manually download from:
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { renderSessionHealthAnalytics } from '../../hud/analytics-display.js';
2
+ import { renderSessionHealthAnalytics, renderAnalyticsLineWithConfig, getSessionHealthAnalyticsData, } from '../../hud/analytics-display.js';
3
3
  describe('renderSessionHealthAnalytics', () => {
4
4
  const baseHealth = {
5
5
  durationMinutes: 5,
@@ -98,4 +98,140 @@ describe('renderSessionHealthAnalytics', () => {
98
98
  expect(result).toContain('2.50M');
99
99
  });
100
100
  });
101
+ describe('renderAnalyticsLineWithConfig', () => {
102
+ const baseAnalytics = {
103
+ sessionCost: '$1.2345',
104
+ sessionTokens: '50.0k',
105
+ topAgents: 'executor:$0.80 architect:$0.30',
106
+ cacheEfficiency: '45.6%',
107
+ costColor: 'green',
108
+ };
109
+ describe('showCost=true, showCache=true (default)', () => {
110
+ it('renders all elements', () => {
111
+ const result = renderAnalyticsLineWithConfig(baseAnalytics, true, true);
112
+ expect(result).toContain('Cost: $1.2345');
113
+ expect(result).toContain('Tokens: 50.0k');
114
+ expect(result).toContain('Cache: 45.6%');
115
+ expect(result).toContain('Top: executor:$0.80 architect:$0.30');
116
+ });
117
+ it('shows green indicator for green costColor', () => {
118
+ const result = renderAnalyticsLineWithConfig({ ...baseAnalytics, costColor: 'green' }, true, true);
119
+ expect(result).toContain('🟢');
120
+ });
121
+ it('shows yellow indicator for yellow costColor', () => {
122
+ const result = renderAnalyticsLineWithConfig({ ...baseAnalytics, costColor: 'yellow' }, true, true);
123
+ expect(result).toContain('🟡');
124
+ });
125
+ it('shows red indicator for red costColor', () => {
126
+ const result = renderAnalyticsLineWithConfig({ ...baseAnalytics, costColor: 'red' }, true, true);
127
+ expect(result).toContain('🔴');
128
+ });
129
+ });
130
+ describe('showCost=false, showCache=true', () => {
131
+ it('hides cost but shows cache', () => {
132
+ const result = renderAnalyticsLineWithConfig(baseAnalytics, false, true);
133
+ expect(result).not.toContain('Cost:');
134
+ expect(result).toContain('Tokens: 50.0k');
135
+ expect(result).toContain('Cache: 45.6%');
136
+ expect(result).toContain('Top:');
137
+ });
138
+ });
139
+ describe('showCost=true, showCache=false', () => {
140
+ it('shows cost but hides cache', () => {
141
+ const result = renderAnalyticsLineWithConfig(baseAnalytics, true, false);
142
+ expect(result).toContain('Cost: $1.2345');
143
+ expect(result).toContain('Tokens: 50.0k');
144
+ expect(result).not.toContain('Cache:');
145
+ expect(result).toContain('Top:');
146
+ });
147
+ });
148
+ describe('showCost=false, showCache=false (minimal)', () => {
149
+ it('shows only tokens and top agents', () => {
150
+ const result = renderAnalyticsLineWithConfig(baseAnalytics, false, false);
151
+ expect(result).not.toContain('Cost:');
152
+ expect(result).not.toContain('Cache:');
153
+ expect(result).toContain('Tokens: 50.0k');
154
+ expect(result).toContain('Top:');
155
+ });
156
+ it('formats with pipe separators', () => {
157
+ const result = renderAnalyticsLineWithConfig(baseAnalytics, false, false);
158
+ const parts = result.split(' | ');
159
+ expect(parts).toHaveLength(2);
160
+ });
161
+ });
162
+ });
163
+ describe('getSessionHealthAnalyticsData', () => {
164
+ const baseHealth = {
165
+ durationMinutes: 5,
166
+ messageCount: 0,
167
+ health: 'healthy',
168
+ sessionCost: 0,
169
+ totalTokens: 0,
170
+ cacheHitRate: 0,
171
+ costPerHour: 0,
172
+ isEstimated: false,
173
+ };
174
+ describe('cost indicator', () => {
175
+ it('returns green for healthy', () => {
176
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, health: 'healthy' });
177
+ expect(data.costIndicator).toBe('🟢');
178
+ });
179
+ it('returns yellow for warning', () => {
180
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, health: 'warning' });
181
+ expect(data.costIndicator).toBe('🟡');
182
+ });
183
+ it('returns red for critical', () => {
184
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, health: 'critical' });
185
+ expect(data.costIndicator).toBe('🔴');
186
+ });
187
+ });
188
+ describe('cost formatting', () => {
189
+ it('formats with 4 decimal places', () => {
190
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, sessionCost: 1.2345 });
191
+ expect(data.cost).toBe('$1.2345');
192
+ });
193
+ it('adds estimated prefix when isEstimated', () => {
194
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, sessionCost: 0.5, isEstimated: true });
195
+ expect(data.cost).toBe('~$0.5000');
196
+ });
197
+ it('handles undefined as 0', () => {
198
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, sessionCost: undefined });
199
+ expect(data.cost).toBe('$0.0000');
200
+ });
201
+ });
202
+ describe('token formatting', () => {
203
+ it('formats small counts without suffix', () => {
204
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, totalTokens: 999 });
205
+ expect(data.tokens).toBe('999');
206
+ });
207
+ it('formats thousands with k suffix', () => {
208
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, totalTokens: 50000 });
209
+ expect(data.tokens).toBe('50.0k');
210
+ });
211
+ it('formats millions with M suffix', () => {
212
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, totalTokens: 2500000 });
213
+ expect(data.tokens).toBe('2.50M');
214
+ });
215
+ });
216
+ describe('cache formatting', () => {
217
+ it('formats with 1 decimal and percent', () => {
218
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, cacheHitRate: 45.67 });
219
+ expect(data.cache).toBe('45.7%');
220
+ });
221
+ it('handles undefined as 0', () => {
222
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, cacheHitRate: undefined });
223
+ expect(data.cache).toBe('0.0%');
224
+ });
225
+ });
226
+ describe('cost per hour', () => {
227
+ it('formats with dollar and /h suffix', () => {
228
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, costPerHour: 2.5 });
229
+ expect(data.costHour).toBe('$2.50/h');
230
+ });
231
+ it('returns empty when undefined', () => {
232
+ const data = getSessionHealthAnalyticsData({ ...baseHealth, costPerHour: undefined });
233
+ expect(data.costHour).toBe('');
234
+ });
235
+ });
236
+ });
101
237
  //# sourceMappingURL=analytics-display.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-display.test.js","sourceRoot":"","sources":["../../../src/__tests__/hud/analytics-display.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAG9E,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,MAAM,UAAU,GAAkB;QAChC,eAAe,EAAE,CAAC;QAClB,YAAY,EAAE,CAAC;QACf,MAAM,EAAE,SAAS;QACjB,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,CAAC;QACd,YAAY,EAAE,CAAC;QACf,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,KAAK;KACnB,CAAC;IAEF,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAG,4BAA4B,CAAC,EAAE,GAAG,UAAU,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,WAAW,EAAE,MAAM;YACnB,WAAW,EAAE,KAAK;YAClB,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,WAAW,EAAE,GAAG;YAChB,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,MAAM,EAAE,SAAS;YACjB,WAAW,EAAE,GAAG;SACjB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,MAAM,EAAE,SAAS;YACjB,WAAW,EAAE,GAAG;SACjB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,MAAM,EAAE,UAAU;YAClB,WAAW,EAAE,GAAG;SACjB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,WAAW,EAAE,GAAG;YAChB,WAAW,EAAE,SAAgB;SAC9B,CAAC,CAAC;QACH,uDAAuD;QACvD,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,WAAW,EAAE,GAAG;YAChB,YAAY,EAAE,SAAgB;SAC/B,CAAC,CAAC;QACH,uDAAuD;QACvD,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,WAAW,EAAE,GAAG;YAChB,WAAW,EAAE,MAAM;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC1C,GAAG,UAAU;YACb,WAAW,EAAE,GAAG;YAChB,WAAW,EAAE,OAAO;SACrB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"analytics-display.test.js","sourceRoot":"","sources":["../../../src/__tests__/hud/analytics-display.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hud-windows.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hud-windows.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/hud-windows.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { readFileSync, existsSync } from 'fs';
3
+ import { join, dirname } from 'path';
4
+ import { fileURLToPath, pathToFileURL } from 'url';
5
+ /**
6
+ * HUD Windows Compatibility Tests
7
+ *
8
+ * These tests verify Windows compatibility fixes for HUD:
9
+ * - File naming (omc-hud.mjs)
10
+ * - Windows dynamic import() requires file:// URLs (pathToFileURL)
11
+ * - Version sorting (numeric vs lexicographic)
12
+ *
13
+ * Related: GitHub Issue #138, PR #139, PR #140
14
+ */
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ const packageRoot = join(__dirname, '..', '..');
18
+ describe('HUD Windows Compatibility', () => {
19
+ describe('File Naming', () => {
20
+ it('session-start.mjs should reference omc-hud.mjs', () => {
21
+ const sessionStartPath = join(packageRoot, 'scripts', 'session-start.mjs');
22
+ expect(existsSync(sessionStartPath)).toBe(true);
23
+ const content = readFileSync(sessionStartPath, 'utf-8');
24
+ expect(content).toContain('omc-hud.mjs');
25
+ expect(content).not.toContain('sisyphus-hud.mjs');
26
+ });
27
+ it('installer should create omc-hud.mjs', () => {
28
+ const installerPath = join(packageRoot, 'src', 'installer', 'index.ts');
29
+ expect(existsSync(installerPath)).toBe(true);
30
+ const content = readFileSync(installerPath, 'utf-8');
31
+ expect(content).toContain('omc-hud.mjs');
32
+ expect(content).not.toContain('sisyphus-hud.mjs');
33
+ });
34
+ });
35
+ describe('pathToFileURL for Dynamic Import', () => {
36
+ it('installer HUD script should import pathToFileURL', () => {
37
+ const installerPath = join(packageRoot, 'src', 'installer', 'index.ts');
38
+ const content = readFileSync(installerPath, 'utf-8');
39
+ // Should have pathToFileURL import in the generated script
40
+ expect(content).toContain('import { pathToFileURL } from "node:url"');
41
+ });
42
+ it('installer HUD script should use pathToFileURL for dev path import', () => {
43
+ const installerPath = join(packageRoot, 'src', 'installer', 'index.ts');
44
+ const content = readFileSync(installerPath, 'utf-8');
45
+ // Should use pathToFileURL for devPath
46
+ expect(content).toContain('pathToFileURL(devPath).href');
47
+ });
48
+ it('installer HUD script should use pathToFileURL for plugin path import', () => {
49
+ const installerPath = join(packageRoot, 'src', 'installer', 'index.ts');
50
+ const content = readFileSync(installerPath, 'utf-8');
51
+ // Should use pathToFileURL for pluginPath
52
+ expect(content).toContain('pathToFileURL(pluginPath).href');
53
+ });
54
+ it('pathToFileURL should correctly convert Unix paths', () => {
55
+ const unixPath = '/home/user/test.js';
56
+ expect(pathToFileURL(unixPath).href).toBe('file:///home/user/test.js');
57
+ });
58
+ it('pathToFileURL should encode spaces in paths', () => {
59
+ const spacePath = '/path/with spaces/file.js';
60
+ expect(pathToFileURL(spacePath).href).toBe('file:///path/with%20spaces/file.js');
61
+ });
62
+ });
63
+ describe('Numeric Version Sorting', () => {
64
+ it('installer HUD script should use numeric version sorting', () => {
65
+ const installerPath = join(packageRoot, 'src', 'installer', 'index.ts');
66
+ const content = readFileSync(installerPath, 'utf-8');
67
+ // Should use localeCompare with numeric option
68
+ expect(content).toContain('localeCompare(b, undefined, { numeric: true })');
69
+ });
70
+ it('numeric sort should correctly order versions', () => {
71
+ const versions = ['3.5.0', '3.10.0', '3.9.0'];
72
+ // Incorrect lexicographic sort
73
+ const lexSorted = [...versions].sort().reverse();
74
+ expect(lexSorted[0]).toBe('3.9.0'); // Wrong! 9 > 1 lexicographically
75
+ // Correct numeric sort
76
+ const numSorted = [...versions].sort((a, b) => a.localeCompare(b, undefined, { numeric: true })).reverse();
77
+ expect(numSorted[0]).toBe('3.10.0'); // Correct! 10 > 9 > 5 numerically
78
+ });
79
+ it('should handle single-digit and double-digit versions', () => {
80
+ const versions = ['1.0.0', '10.0.0', '2.0.0', '9.0.0'];
81
+ const sorted = [...versions].sort((a, b) => a.localeCompare(b, undefined, { numeric: true })).reverse();
82
+ expect(sorted).toEqual(['10.0.0', '9.0.0', '2.0.0', '1.0.0']);
83
+ });
84
+ it('should handle patch version comparison', () => {
85
+ const versions = ['1.0.1', '1.0.10', '1.0.9', '1.0.2'];
86
+ const sorted = [...versions].sort((a, b) => a.localeCompare(b, undefined, { numeric: true })).reverse();
87
+ expect(sorted).toEqual(['1.0.10', '1.0.9', '1.0.2', '1.0.1']);
88
+ });
89
+ });
90
+ });
91
+ //# sourceMappingURL=hud-windows.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hud-windows.test.js","sourceRoot":"","sources":["../../src/__tests__/hud-windows.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/features/rate-limit-wait/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAaH,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EAEZ,cAAc,EACf,MAAM,YAAY,CAAC;AAuEpB;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,WAAW,GAAG,IAAI,CAmCzE;AAwDD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAe9D;AA8CD;;GAEG;AACH,iBAAe,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA4FrE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CAgEjE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC9E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CA2ChE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CAyBrE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CA6BvF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAgD5D;AAGD,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/features/rate-limit-wait/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAaH,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EAEZ,cAAc,EACf,MAAM,YAAY,CAAC;AAgHpB;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,WAAW,GAAG,IAAI,CAmCzE;AAwDD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAe9D;AA8CD;;GAEG;AACH,iBAAe,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA4FrE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CAiEjE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC9E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CA2ChE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CAyBrE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CA6BvF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAgD5D;AAGD,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -30,6 +30,45 @@ const DEFAULT_CONFIG = {
30
30
  const MAX_LOG_SIZE_BYTES = 1 * 1024 * 1024;
31
31
  /** Restrictive file permissions (owner read/write only) */
32
32
  const SECURE_FILE_MODE = 0o600;
33
+ /**
34
+ * Allowlist of environment variables safe to pass to daemon child process.
35
+ * This prevents leaking sensitive variables like ANTHROPIC_API_KEY, GITHUB_TOKEN, etc.
36
+ */
37
+ const DAEMON_ENV_ALLOWLIST = [
38
+ // Core system paths
39
+ 'PATH', 'HOME', 'USERPROFILE',
40
+ // User identification
41
+ 'USER', 'USERNAME', 'LOGNAME',
42
+ // Locale settings
43
+ 'LANG', 'LC_ALL', 'LC_CTYPE',
44
+ // Terminal/tmux (required for tmux integration)
45
+ 'TERM', 'TMUX', 'TMUX_PANE',
46
+ // Temp directories
47
+ 'TMPDIR', 'TMP', 'TEMP',
48
+ // XDG directories (Linux)
49
+ 'XDG_RUNTIME_DIR', 'XDG_DATA_HOME', 'XDG_CONFIG_HOME',
50
+ // Shell
51
+ 'SHELL',
52
+ // Node.js
53
+ 'NODE_ENV',
54
+ // Proxy settings
55
+ 'HTTP_PROXY', 'HTTPS_PROXY', 'http_proxy', 'https_proxy', 'NO_PROXY', 'no_proxy',
56
+ // Windows system
57
+ 'SystemRoot', 'SYSTEMROOT', 'windir', 'COMSPEC',
58
+ ];
59
+ /**
60
+ * Create a minimal environment for daemon child processes.
61
+ * Only includes allowlisted variables to prevent credential leakage.
62
+ */
63
+ function createMinimalDaemonEnv() {
64
+ const env = {};
65
+ for (const key of DAEMON_ENV_ALLOWLIST) {
66
+ if (process.env[key] !== undefined) {
67
+ env[key] = process.env[key];
68
+ }
69
+ }
70
+ return env;
71
+ }
33
72
  /**
34
73
  * Get effective configuration by merging with defaults
35
74
  */
@@ -331,11 +370,12 @@ export function startDaemon(config) {
331
370
  `;
332
371
  try {
333
372
  // Use node to run the daemon in background
373
+ // Note: Using minimal env to prevent leaking sensitive credentials
334
374
  const child = spawn('node', ['-e', daemonScript], {
335
375
  detached: true,
336
376
  stdio: 'ignore',
337
377
  cwd: process.cwd(),
338
- env: process.env,
378
+ env: createMinimalDaemonEnv(),
339
379
  });
340
380
  child.unref();
341
381
  const pid = child.pid;