tokengolf 0.5.3 → 0.5.4

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/dist/cli.js CHANGED
@@ -1798,22 +1798,28 @@ function installHooks() {
1798
1798
  const existingCmd = typeof existing === "string" ? existing : existing?.command ?? null;
1799
1799
  const isTgStatusline = (cmd) => cmd && (cmd.includes("tokengolf/hooks/statusline") || cmd.includes("tokengolf\\hooks\\statusline"));
1800
1800
  const alreadyOurs = isTgStatusline(existingCmd);
1801
- if (alreadyOurs) {
1802
- let userStatusline = null;
1803
- if (existingCmd.includes("statusline-wrapper")) {
1804
- try {
1805
- const wrapperContent = fs4.readFileSync(existingCmd, "utf8");
1806
- const lines = wrapperContent.split("\n").filter((l) => l.includes('echo "$SESSION_JSON"'));
1807
- for (const line of lines) {
1808
- const match = line.match(/echo "\$SESSION_JSON" \| (.+?)( 2>|$)/);
1809
- if (match && !isTgStatusline(match[1])) {
1810
- userStatusline = match[1];
1811
- break;
1812
- }
1801
+ function extractUserStatusline(wrapperPath, visited = /* @__PURE__ */ new Set()) {
1802
+ if (!wrapperPath || visited.has(wrapperPath)) return null;
1803
+ visited.add(wrapperPath);
1804
+ try {
1805
+ const content = fs4.readFileSync(wrapperPath, "utf8");
1806
+ const pipeLines = content.split("\n").filter((l) => l.includes('echo "$SESSION_JSON"'));
1807
+ for (const line of pipeLines) {
1808
+ const match = line.match(/echo "\$SESSION_JSON" \| (.+?)( 2>|$)/);
1809
+ if (!match) continue;
1810
+ const cmd = match[1].replace(/^bash /, "");
1811
+ if (!isTgStatusline(cmd)) return cmd;
1812
+ if (cmd.includes("statusline-wrapper")) {
1813
+ const found = extractUserStatusline(cmd, visited);
1814
+ if (found) return found;
1813
1815
  }
1814
- } catch {
1815
1816
  }
1817
+ } catch {
1816
1818
  }
1819
+ return null;
1820
+ }
1821
+ if (alreadyOurs) {
1822
+ const userStatusline = existingCmd.includes("statusline-wrapper") ? extractUserStatusline(existingCmd) : null;
1817
1823
  if (userStatusline) {
1818
1824
  fs4.writeFileSync(
1819
1825
  WRAPPER_PATH,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokengolf",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Gamify your Claude Code sessions. Flow mode tracks you. Roguelike mode trains you.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -155,23 +155,33 @@ export function installHooks() {
155
155
  (cmd.includes('tokengolf/hooks/statusline') || cmd.includes('tokengolf\\hooks\\statusline'));
156
156
  const alreadyOurs = isTgStatusline(existingCmd);
157
157
 
158
- if (alreadyOurs) {
159
- // Check if existing wrapper has a non-TG statusline we should preserve
160
- let userStatusline = null;
161
- if (existingCmd.includes('statusline-wrapper')) {
162
- try {
163
- const wrapperContent = fs.readFileSync(existingCmd, 'utf8');
164
- const lines = wrapperContent.split('\n').filter((l) => l.includes('echo "$SESSION_JSON"'));
165
- // Find the line that calls a non-tokengolf statusline
166
- for (const line of lines) {
167
- const match = line.match(/echo "\$SESSION_JSON" \| (.+?)( 2>|$)/);
168
- if (match && !isTgStatusline(match[1])) {
169
- userStatusline = match[1];
170
- break;
171
- }
158
+ // Extract user's non-TG statusline command from a wrapper, following chains recursively
159
+ function extractUserStatusline(wrapperPath, visited = new Set()) {
160
+ if (!wrapperPath || visited.has(wrapperPath)) return null;
161
+ visited.add(wrapperPath);
162
+ try {
163
+ const content = fs.readFileSync(wrapperPath, 'utf8');
164
+ const pipeLines = content.split('\n').filter((l) => l.includes('echo "$SESSION_JSON"'));
165
+ for (const line of pipeLines) {
166
+ const match = line.match(/echo "\$SESSION_JSON" \| (.+?)( 2>|$)/);
167
+ if (!match) continue;
168
+ const cmd = match[1].replace(/^bash /, '');
169
+ if (!isTgStatusline(cmd)) return cmd; // found the user's statusline
170
+ // It's another TG wrapper — follow the chain
171
+ if (cmd.includes('statusline-wrapper')) {
172
+ const found = extractUserStatusline(cmd, visited);
173
+ if (found) return found;
172
174
  }
173
- } catch {}
174
- }
175
+ }
176
+ } catch {}
177
+ return null;
178
+ }
179
+
180
+ if (alreadyOurs) {
181
+ // Find user's statusline buried in any depth of wrapper chain
182
+ const userStatusline = existingCmd.includes('statusline-wrapper')
183
+ ? extractUserStatusline(existingCmd)
184
+ : null;
175
185
 
176
186
  if (userStatusline) {
177
187
  // Re-wrap: preserve user's statusline + update tokengolf path