gsd-remix 1.0.0 → 1.0.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.
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/gsd-remix?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/gsd-remix)
12
12
  [![npm downloads](https://img.shields.io/npm/dm/gsd-remix?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/gsd-remix)
13
- [![Tests](https://img.shields.io/github/actions/workflow/status/gsd-build/get-shit-done/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/gsd-build/get-shit-done/actions/workflows/test.yml)
13
+ [![Tests](https://img.shields.io/github/actions/workflow/status/Wynne-cwb/gsd-remix/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/Wynne-cwb/gsd-remix/actions/workflows/test.yml)
14
14
  [![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/mYgfVNfA2r)
15
15
  [![X (Twitter)](https://img.shields.io/badge/X-@gsd__foundation-000000?style=for-the-badge&logo=x&logoColor=white)](https://x.com/gsd_foundation)
16
16
  [![$GSD Token](https://img.shields.io/badge/$GSD-Dexscreener-1C1C1C?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIgZmlsbD0iIzAwRkYwMCIvPjwvc3ZnPg==&logoColor=00FF00)](https://dexscreener.com/solana/dwudwjvan7bzkw9zwlbyv6kspdlvhwzrqy6ebk8xzxkv)
@@ -226,8 +226,8 @@ To confirm that an existing `/gsd-*` command surface is coming from `gsd-remix`
226
226
  Clone the repository, build hooks, and run the installer locally:
227
227
 
228
228
  ```bash
229
- git clone https://github.com/gsd-build/get-shit-done.git
230
- cd get-shit-done
229
+ git clone https://github.com/Wynne-cwb/gsd-remix.git
230
+ cd gsd-remix
231
231
  npm run build:hooks
232
232
  node bin/install.js --claude --local
233
233
  ```
package/README.zh-CN.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/gsd-remix?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/gsd-remix)
12
12
  [![npm downloads](https://img.shields.io/npm/dm/gsd-remix?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/gsd-remix)
13
- [![Tests](https://img.shields.io/github/actions/workflow/status/gsd-build/get-shit-done/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/gsd-build/get-shit-done/actions/workflows/test.yml)
13
+ [![Tests](https://img.shields.io/github/actions/workflow/status/Wynne-cwb/gsd-remix/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/Wynne-cwb/gsd-remix/actions/workflows/test.yml)
14
14
  [![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/mYgfVNfA2r)
15
15
  [![X (Twitter)](https://img.shields.io/badge/X-@gsd__foundation-000000?style=for-the-badge&logo=x&logoColor=white)](https://x.com/gsd_foundation)
16
16
  [![$GSD Token](https://img.shields.io/badge/$GSD-Dexscreener-1C1C1C?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIgZmlsbD0iIzAwRkYwMCIvPjwvc3ZnPg==&logoColor=00FF00)](https://dexscreener.com/solana/dwudwjvan7bzkw9zwlbyv6kspdlvhwzrqy6ebk8xzxkv)
@@ -222,8 +222,8 @@ npx gsd-remix --all --global # 安装到所有目录
222
222
  克隆仓库并在本地运行安装器:
223
223
 
224
224
  ```bash
225
- git clone https://github.com/gsd-build/get-shit-done.git
226
- cd get-shit-done
225
+ git clone https://github.com/Wynne-cwb/gsd-remix.git
226
+ cd gsd-remix
227
227
  node bin/install.js --claude --local
228
228
  ```
229
229
 
@@ -490,7 +490,7 @@ npx -y get-shit-done-cc@latest --claude --global
490
490
 
491
491
  Capture output. If install fails, show error and exit.
492
492
 
493
- Clear the update cache so statusline indicator disappears:
493
+ Clear the update cache so future update checks start fresh:
494
494
 
495
495
  ```bash
496
496
  expand_home() {
@@ -554,7 +554,7 @@ Format completion message (changelog was already shown in confirmation step):
554
554
 
555
555
  ⚠️ Restart your runtime to pick up the new commands.
556
556
 
557
- [View full changelog](https://github.com/gsd-build/get-shit-done/blob/main/CHANGELOG.md)
557
+ [View full changelog](https://github.com/Wynne-cwb/gsd-remix/blob/main/CHANGELOG.md)
558
558
  ```
559
559
  </step>
560
560
 
@@ -30,8 +30,7 @@ function detectConfigDir(baseDir) {
30
30
  const globalConfigDir = detectConfigDir(homeDir);
31
31
  const projectConfigDir = detectConfigDir(cwd);
32
32
  // Use a shared, tool-agnostic cache directory to avoid multi-runtime
33
- // resolution mismatches where check-update writes to one runtime's cache
34
- // but statusline reads from another (#1421).
33
+ // resolution mismatches when different runtimes trigger update checks (#1421).
35
34
  const cacheDir = path.join(homeDir, '.cache', 'gsd');
36
35
  const cacheFile = path.join(cacheDir, 'gsd-update-check.json');
37
36
 
@@ -1,107 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  // gsd-hook-version: {{GSD_VERSION}}
3
3
  // Claude Code Statusline - GSD Edition
4
- // Shows: model | current task (or GSD state) | directory | context usage
4
+ // Shows: model | directory | context usage | rate limits
5
5
 
6
6
  const fs = require('fs');
7
7
  const path = require('path');
8
8
  const os = require('os');
9
9
 
10
- // --- GSD state reader -------------------------------------------------------
11
-
12
- /**
13
- * Walk up from dir looking for .planning/STATE.md.
14
- * Returns parsed state object or null.
15
- */
16
- function readGsdState(dir) {
17
- const home = os.homedir();
18
- let current = dir;
19
- for (let i = 0; i < 10; i++) {
20
- const candidate = path.join(current, '.planning', 'STATE.md');
21
- if (fs.existsSync(candidate)) {
22
- try {
23
- return parseStateMd(fs.readFileSync(candidate, 'utf8'));
24
- } catch (e) {
25
- return null;
26
- }
27
- }
28
- const parent = path.dirname(current);
29
- if (parent === current || current === home) break;
30
- current = parent;
31
- }
32
- return null;
33
- }
34
-
35
- /**
36
- * Parse STATE.md frontmatter + Phase line from body.
37
- * Returns { status, milestone, milestoneName, phaseNum, phaseTotal, phaseName }
38
- */
39
- function parseStateMd(content) {
40
- const state = {};
41
-
42
- // YAML frontmatter between --- markers
43
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
44
- if (fmMatch) {
45
- for (const line of fmMatch[1].split('\n')) {
46
- const m = line.match(/^(\w+):\s*(.+)/);
47
- if (!m) continue;
48
- const [, key, val] = m;
49
- const v = val.trim().replace(/^["']|["']$/g, '');
50
- if (key === 'status') state.status = v === 'null' ? null : v;
51
- if (key === 'milestone') state.milestone = v === 'null' ? null : v;
52
- if (key === 'milestone_name') state.milestoneName = v === 'null' ? null : v;
53
- }
54
- }
55
-
56
- // Phase: N of M (name) or Phase: none active (...)
57
- const phaseMatch = content.match(/^Phase:\s*(\d+)\s+of\s+(\d+)(?:\s+\(([^)]+)\))?/m);
58
- if (phaseMatch) {
59
- state.phaseNum = phaseMatch[1];
60
- state.phaseTotal = phaseMatch[2];
61
- state.phaseName = phaseMatch[3] || null;
62
- }
63
-
64
- // Fallback: parse Status: from body when frontmatter is absent
65
- if (!state.status) {
66
- const bodyStatus = content.match(/^Status:\s*(.+)/m);
67
- if (bodyStatus) {
68
- const raw = bodyStatus[1].trim().toLowerCase();
69
- if (raw.includes('ready to plan') || raw.includes('planning')) state.status = 'planning';
70
- else if (raw.includes('execut')) state.status = 'executing';
71
- else if (raw.includes('complet') || raw.includes('archived')) state.status = 'complete';
72
- }
73
- }
74
-
75
- return state;
76
- }
77
-
78
- /**
79
- * Format GSD state into display string.
80
- * Format: "v1.9 Code Quality · executing · fix-graphiti-deployment (1/5)"
81
- * Gracefully degrades when parts are missing.
82
- */
83
- function formatGsdState(s) {
84
- const parts = [];
85
-
86
- // Milestone: version + name (skip placeholder "milestone")
87
- if (s.milestone || s.milestoneName) {
88
- const ver = s.milestone || '';
89
- const name = (s.milestoneName && s.milestoneName !== 'milestone') ? s.milestoneName : '';
90
- const ms = [ver, name].filter(Boolean).join(' ');
91
- if (ms) parts.push(ms);
92
- }
93
-
94
- // Status
95
- if (s.status) parts.push(s.status);
96
-
97
- // Phase (name intentionally omitted to keep the middle slot compact)
98
- if (s.phaseNum && s.phaseTotal) {
99
- parts.push(`ph ${s.phaseNum}/${s.phaseTotal}`);
100
- }
101
-
102
- return parts.join(' · ');
103
- }
104
-
105
10
  // --- stdin ------------------------------------------------------------------
106
11
 
107
12
  function runStatusline() {
@@ -177,66 +82,6 @@ function runStatusline() {
177
82
  }
178
83
  }
179
84
 
180
- // Current task from todos
181
- let task = '';
182
- const homeDir = os.homedir();
183
- // Respect CLAUDE_CONFIG_DIR for custom config directory setups (#870)
184
- const claudeDir = process.env.CLAUDE_CONFIG_DIR || path.join(homeDir, '.claude');
185
- const todosDir = path.join(claudeDir, 'todos');
186
- if (session && fs.existsSync(todosDir)) {
187
- try {
188
- const files = fs.readdirSync(todosDir)
189
- .filter(f => f.startsWith(session) && f.includes('-agent-') && f.endsWith('.json'))
190
- .map(f => ({ name: f, mtime: fs.statSync(path.join(todosDir, f)).mtime }))
191
- .sort((a, b) => b.mtime - a.mtime);
192
-
193
- if (files.length > 0) {
194
- try {
195
- const todos = JSON.parse(fs.readFileSync(path.join(todosDir, files[0].name), 'utf8'));
196
- const inProgress = todos.find(t => t.status === 'in_progress');
197
- if (inProgress) task = inProgress.activeForm || '';
198
- } catch (e) {}
199
- }
200
- } catch (e) {
201
- // Silently fail on file system errors - don't break statusline
202
- }
203
- }
204
-
205
- // GSD state (milestone · status · phase) — shown when no todo task
206
- const gsdStateStr = task ? '' : formatGsdState(readGsdState(dir) || {});
207
-
208
- // GSD update available?
209
- // Check shared cache first (#1421), fall back to runtime-specific cache for
210
- // backward compatibility with older gsd-check-update.js versions.
211
- let gsdUpdate = '';
212
- const sharedCacheFile = path.join(homeDir, '.cache', 'gsd', 'gsd-update-check.json');
213
- const legacyCacheFile = path.join(claudeDir, 'cache', 'gsd-update-check.json');
214
- const cacheFile = fs.existsSync(sharedCacheFile) ? sharedCacheFile : legacyCacheFile;
215
- if (fs.existsSync(cacheFile)) {
216
- try {
217
- const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
218
- if (cache.update_available) {
219
- gsdUpdate = '\x1b[33m⬆ /gsd-update\x1b[0m │ ';
220
- }
221
- if (cache.stale_hooks && cache.stale_hooks.length > 0) {
222
- // If installed version is ahead of npm latest, this is a dev install.
223
- // Running /gsd-update would downgrade — show a contextual warning instead.
224
- const isDevInstall = (() => {
225
- if (!cache.installed || !cache.latest || cache.latest === 'unknown') return false;
226
- const parseV = v => v.replace(/^v/, '').split('.').map(Number);
227
- const [ai, bi, ci] = parseV(cache.installed);
228
- const [an, bn, cn] = parseV(cache.latest);
229
- return ai > an || (ai === an && bi > bn) || (ai === an && bi === bn && ci > cn);
230
- })();
231
- if (isDevInstall) {
232
- gsdUpdate += '\x1b[33m⚠ dev install — re-run installer to sync hooks\x1b[0m │ ';
233
- } else {
234
- gsdUpdate += '\x1b[31m⚠ stale hooks — run /gsd-update\x1b[0m │ ';
235
- }
236
- }
237
- } catch (e) {}
238
- }
239
-
240
85
  // Rate limits (5h / 7d remaining)
241
86
  function rlColor(remain) {
242
87
  if (remain > 50) return '\x1b[32m';
@@ -270,24 +115,11 @@ function runStatusline() {
270
115
 
271
116
  // Output
272
117
  const dirname = path.basename(dir);
273
- const middle = task
274
- ? `\x1b[1m${task}\x1b[0m`
275
- : gsdStateStr
276
- ? `\x1b[2m${gsdStateStr}\x1b[0m`
277
- : null;
278
-
279
- if (middle) {
280
- process.stdout.write(`${gsdUpdate}\x1b[2m${model}\x1b[0m │ ${middle} │ \x1b[2m${dirname}\x1b[0m${ctx}${rateLimits}`);
281
- } else {
282
- process.stdout.write(`${gsdUpdate}\x1b[2m${model}\x1b[0m │ \x1b[2m${dirname}\x1b[0m${ctx}${rateLimits}`);
283
- }
118
+ process.stdout.write(`\x1b[2m${model}\x1b[0m \x1b[2m${dirname}\x1b[0m${ctx}${rateLimits}`);
284
119
  } catch (e) {
285
120
  // Silent fail - don't break statusline on parse errors
286
121
  }
287
122
  });
288
123
  }
289
124
 
290
- // Export helpers for unit tests. Harmless when run as a script.
291
- module.exports = { readGsdState, parseStateMd, formatGsdState };
292
-
293
125
  if (require.main === module) runStatusline();
@@ -30,8 +30,7 @@ function detectConfigDir(baseDir) {
30
30
  const globalConfigDir = detectConfigDir(homeDir);
31
31
  const projectConfigDir = detectConfigDir(cwd);
32
32
  // Use a shared, tool-agnostic cache directory to avoid multi-runtime
33
- // resolution mismatches where check-update writes to one runtime's cache
34
- // but statusline reads from another (#1421).
33
+ // resolution mismatches when different runtimes trigger update checks (#1421).
35
34
  const cacheDir = path.join(homeDir, '.cache', 'gsd');
36
35
  const cacheFile = path.join(cacheDir, 'gsd-update-check.json');
37
36
 
@@ -1,107 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  // gsd-hook-version: {{GSD_VERSION}}
3
3
  // Claude Code Statusline - GSD Edition
4
- // Shows: model | current task (or GSD state) | directory | context usage
4
+ // Shows: model | directory | context usage | rate limits
5
5
 
6
6
  const fs = require('fs');
7
7
  const path = require('path');
8
8
  const os = require('os');
9
9
 
10
- // --- GSD state reader -------------------------------------------------------
11
-
12
- /**
13
- * Walk up from dir looking for .planning/STATE.md.
14
- * Returns parsed state object or null.
15
- */
16
- function readGsdState(dir) {
17
- const home = os.homedir();
18
- let current = dir;
19
- for (let i = 0; i < 10; i++) {
20
- const candidate = path.join(current, '.planning', 'STATE.md');
21
- if (fs.existsSync(candidate)) {
22
- try {
23
- return parseStateMd(fs.readFileSync(candidate, 'utf8'));
24
- } catch (e) {
25
- return null;
26
- }
27
- }
28
- const parent = path.dirname(current);
29
- if (parent === current || current === home) break;
30
- current = parent;
31
- }
32
- return null;
33
- }
34
-
35
- /**
36
- * Parse STATE.md frontmatter + Phase line from body.
37
- * Returns { status, milestone, milestoneName, phaseNum, phaseTotal, phaseName }
38
- */
39
- function parseStateMd(content) {
40
- const state = {};
41
-
42
- // YAML frontmatter between --- markers
43
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
44
- if (fmMatch) {
45
- for (const line of fmMatch[1].split('\n')) {
46
- const m = line.match(/^(\w+):\s*(.+)/);
47
- if (!m) continue;
48
- const [, key, val] = m;
49
- const v = val.trim().replace(/^["']|["']$/g, '');
50
- if (key === 'status') state.status = v === 'null' ? null : v;
51
- if (key === 'milestone') state.milestone = v === 'null' ? null : v;
52
- if (key === 'milestone_name') state.milestoneName = v === 'null' ? null : v;
53
- }
54
- }
55
-
56
- // Phase: N of M (name) or Phase: none active (...)
57
- const phaseMatch = content.match(/^Phase:\s*(\d+)\s+of\s+(\d+)(?:\s+\(([^)]+)\))?/m);
58
- if (phaseMatch) {
59
- state.phaseNum = phaseMatch[1];
60
- state.phaseTotal = phaseMatch[2];
61
- state.phaseName = phaseMatch[3] || null;
62
- }
63
-
64
- // Fallback: parse Status: from body when frontmatter is absent
65
- if (!state.status) {
66
- const bodyStatus = content.match(/^Status:\s*(.+)/m);
67
- if (bodyStatus) {
68
- const raw = bodyStatus[1].trim().toLowerCase();
69
- if (raw.includes('ready to plan') || raw.includes('planning')) state.status = 'planning';
70
- else if (raw.includes('execut')) state.status = 'executing';
71
- else if (raw.includes('complet') || raw.includes('archived')) state.status = 'complete';
72
- }
73
- }
74
-
75
- return state;
76
- }
77
-
78
- /**
79
- * Format GSD state into display string.
80
- * Format: "v1.9 Code Quality · executing · fix-graphiti-deployment (1/5)"
81
- * Gracefully degrades when parts are missing.
82
- */
83
- function formatGsdState(s) {
84
- const parts = [];
85
-
86
- // Milestone: version + name (skip placeholder "milestone")
87
- if (s.milestone || s.milestoneName) {
88
- const ver = s.milestone || '';
89
- const name = (s.milestoneName && s.milestoneName !== 'milestone') ? s.milestoneName : '';
90
- const ms = [ver, name].filter(Boolean).join(' ');
91
- if (ms) parts.push(ms);
92
- }
93
-
94
- // Status
95
- if (s.status) parts.push(s.status);
96
-
97
- // Phase (name intentionally omitted to keep the middle slot compact)
98
- if (s.phaseNum && s.phaseTotal) {
99
- parts.push(`ph ${s.phaseNum}/${s.phaseTotal}`);
100
- }
101
-
102
- return parts.join(' · ');
103
- }
104
-
105
10
  // --- stdin ------------------------------------------------------------------
106
11
 
107
12
  function runStatusline() {
@@ -177,66 +82,6 @@ function runStatusline() {
177
82
  }
178
83
  }
179
84
 
180
- // Current task from todos
181
- let task = '';
182
- const homeDir = os.homedir();
183
- // Respect CLAUDE_CONFIG_DIR for custom config directory setups (#870)
184
- const claudeDir = process.env.CLAUDE_CONFIG_DIR || path.join(homeDir, '.claude');
185
- const todosDir = path.join(claudeDir, 'todos');
186
- if (session && fs.existsSync(todosDir)) {
187
- try {
188
- const files = fs.readdirSync(todosDir)
189
- .filter(f => f.startsWith(session) && f.includes('-agent-') && f.endsWith('.json'))
190
- .map(f => ({ name: f, mtime: fs.statSync(path.join(todosDir, f)).mtime }))
191
- .sort((a, b) => b.mtime - a.mtime);
192
-
193
- if (files.length > 0) {
194
- try {
195
- const todos = JSON.parse(fs.readFileSync(path.join(todosDir, files[0].name), 'utf8'));
196
- const inProgress = todos.find(t => t.status === 'in_progress');
197
- if (inProgress) task = inProgress.activeForm || '';
198
- } catch (e) {}
199
- }
200
- } catch (e) {
201
- // Silently fail on file system errors - don't break statusline
202
- }
203
- }
204
-
205
- // GSD state (milestone · status · phase) — shown when no todo task
206
- const gsdStateStr = task ? '' : formatGsdState(readGsdState(dir) || {});
207
-
208
- // GSD update available?
209
- // Check shared cache first (#1421), fall back to runtime-specific cache for
210
- // backward compatibility with older gsd-check-update.js versions.
211
- let gsdUpdate = '';
212
- const sharedCacheFile = path.join(homeDir, '.cache', 'gsd', 'gsd-update-check.json');
213
- const legacyCacheFile = path.join(claudeDir, 'cache', 'gsd-update-check.json');
214
- const cacheFile = fs.existsSync(sharedCacheFile) ? sharedCacheFile : legacyCacheFile;
215
- if (fs.existsSync(cacheFile)) {
216
- try {
217
- const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
218
- if (cache.update_available) {
219
- gsdUpdate = '\x1b[33m⬆ /gsd-update\x1b[0m │ ';
220
- }
221
- if (cache.stale_hooks && cache.stale_hooks.length > 0) {
222
- // If installed version is ahead of npm latest, this is a dev install.
223
- // Running /gsd-update would downgrade — show a contextual warning instead.
224
- const isDevInstall = (() => {
225
- if (!cache.installed || !cache.latest || cache.latest === 'unknown') return false;
226
- const parseV = v => v.replace(/^v/, '').split('.').map(Number);
227
- const [ai, bi, ci] = parseV(cache.installed);
228
- const [an, bn, cn] = parseV(cache.latest);
229
- return ai > an || (ai === an && bi > bn) || (ai === an && bi === bn && ci > cn);
230
- })();
231
- if (isDevInstall) {
232
- gsdUpdate += '\x1b[33m⚠ dev install — re-run installer to sync hooks\x1b[0m │ ';
233
- } else {
234
- gsdUpdate += '\x1b[31m⚠ stale hooks — run /gsd-update\x1b[0m │ ';
235
- }
236
- }
237
- } catch (e) {}
238
- }
239
-
240
85
  // Rate limits (5h / 7d remaining)
241
86
  function rlColor(remain) {
242
87
  if (remain > 50) return '\x1b[32m';
@@ -270,24 +115,11 @@ function runStatusline() {
270
115
 
271
116
  // Output
272
117
  const dirname = path.basename(dir);
273
- const middle = task
274
- ? `\x1b[1m${task}\x1b[0m`
275
- : gsdStateStr
276
- ? `\x1b[2m${gsdStateStr}\x1b[0m`
277
- : null;
278
-
279
- if (middle) {
280
- process.stdout.write(`${gsdUpdate}\x1b[2m${model}\x1b[0m │ ${middle} │ \x1b[2m${dirname}\x1b[0m${ctx}${rateLimits}`);
281
- } else {
282
- process.stdout.write(`${gsdUpdate}\x1b[2m${model}\x1b[0m │ \x1b[2m${dirname}\x1b[0m${ctx}${rateLimits}`);
283
- }
118
+ process.stdout.write(`\x1b[2m${model}\x1b[0m \x1b[2m${dirname}\x1b[0m${ctx}${rateLimits}`);
284
119
  } catch (e) {
285
120
  // Silent fail - don't break statusline on parse errors
286
121
  }
287
122
  });
288
123
  }
289
124
 
290
- // Export helpers for unit tests. Harmless when run as a script.
291
- module.exports = { readGsdState, parseStateMd, formatGsdState };
292
-
293
125
  if (require.main === module) runStatusline();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsd-remix",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "An unofficial, opinionated remix of GSD for Claude Code, OpenCode, Gemini and Codex.",
5
5
  "bin": {
6
6
  "gsd-remix": "bin/install.js"
@@ -36,11 +36,11 @@
36
36
  "license": "MIT",
37
37
  "repository": {
38
38
  "type": "git",
39
- "url": "git+https://github.com/gsd-build/get-shit-done.git"
39
+ "url": "git+https://github.com/Wynne-cwb/gsd-remix.git"
40
40
  },
41
- "homepage": "https://github.com/gsd-build/get-shit-done",
41
+ "homepage": "https://github.com/Wynne-cwb/gsd-remix",
42
42
  "bugs": {
43
- "url": "https://github.com/gsd-build/get-shit-done/issues"
43
+ "url": "https://github.com/Wynne-cwb/gsd-remix/issues"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=22.0.0"
package/sdk/package.json CHANGED
@@ -20,12 +20,12 @@
20
20
  ],
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "git+https://github.com/gsd-build/get-shit-done.git",
23
+ "url": "git+https://github.com/Wynne-cwb/gsd-remix.git",
24
24
  "directory": "sdk"
25
25
  },
26
- "homepage": "https://github.com/gsd-build/get-shit-done/tree/main/sdk",
26
+ "homepage": "https://github.com/Wynne-cwb/gsd-remix/tree/main/sdk",
27
27
  "bugs": {
28
- "url": "https://github.com/gsd-build/get-shit-done/issues"
28
+ "url": "https://github.com/Wynne-cwb/gsd-remix/issues"
29
29
  },
30
30
  "author": "TÂCHES",
31
31
  "license": "MIT",