@vibescore/tracker 0.2.3 → 0.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibescore/tracker",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Codex CLI token usage tracker (macOS-first, notify-driven).",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -132,19 +132,26 @@ async function cmdInit(argv) {
132
132
  await fs.chmod(notifyPath, 0o755).catch(() => {});
133
133
 
134
134
  // Configure Codex notify hook.
135
- const codexConfigPath = path.join(home, '.codex', 'config.toml');
135
+ const codexHome = process.env.CODEX_HOME || path.join(home, '.codex');
136
+ const codexConfigPath = path.join(codexHome, 'config.toml');
136
137
  const codeHome = process.env.CODE_HOME || path.join(home, '.code');
137
138
  const codeConfigPath = path.join(codeHome, 'config.toml');
138
139
  const notifyCmd = ['/usr/bin/env', 'node', notifyPath];
139
- const result = await upsertCodexNotify({
140
- codexConfigPath,
141
- notifyCmd,
142
- notifyOriginalPath
143
- });
144
-
145
- const chained = await loadCodexNotifyOriginal(notifyOriginalPath);
140
+ const codexProbe = await probeFile(codexConfigPath);
141
+ const codexConfigExists = codexProbe.exists;
142
+ let result = null;
143
+ let chained = null;
144
+ if (codexConfigExists) {
145
+ result = await upsertCodexNotify({
146
+ codexConfigPath,
147
+ notifyCmd,
148
+ notifyOriginalPath
149
+ });
150
+ chained = await loadCodexNotifyOriginal(notifyOriginalPath);
151
+ }
146
152
  const codeNotifyOriginalPath = path.join(trackerDir, 'code_notify_original.json');
147
- const codeConfigExists = await isFile(codeConfigPath);
153
+ const codeProbe = await probeFile(codeConfigPath);
154
+ const codeConfigExists = codeProbe.exists;
148
155
  let codeResult = null;
149
156
  let codeChained = null;
150
157
  if (codeConfigExists) {
@@ -192,10 +199,18 @@ async function cmdInit(argv) {
192
199
  'Installed:',
193
200
  `- Tracker config: ${configPath}`,
194
201
  `- Notify handler: ${notifyPath}`,
195
- `- Codex config: ${codexConfigPath}`,
196
- result.changed ? '- Codex notify: updated' : '- Codex notify: already set',
197
- chained ? '- Codex notify: chained (original preserved)' : '- Codex notify: no original',
198
- codeConfigExists ? `- Every Code config: ${codeConfigPath}` : '- Every Code notify: skipped (config.toml not found)',
202
+ codexConfigExists
203
+ ? `- Codex config: ${codexConfigPath}`
204
+ : `- Codex notify: skipped (${renderProbeSkip(codexConfigPath, codexProbe)})`,
205
+ codexConfigExists
206
+ ? result?.changed
207
+ ? '- Codex notify: updated'
208
+ : '- Codex notify: already set'
209
+ : null,
210
+ codexConfigExists ? (chained ? '- Codex notify: chained (original preserved)' : '- Codex notify: no original') : null,
211
+ codeConfigExists
212
+ ? `- Every Code config: ${codeConfigPath}`
213
+ : `- Every Code notify: skipped (${renderProbeSkip(codeConfigPath, codeProbe)})`,
199
214
  codeConfigExists && codeResult
200
215
  ? codeResult.changed
201
216
  ? '- Every Code notify: updated'
@@ -429,6 +444,26 @@ async function isFile(p) {
429
444
  }
430
445
  }
431
446
 
447
+ async function probeFile(p) {
448
+ try {
449
+ const st = await fs.stat(p);
450
+ if (st.isFile()) return { exists: true, reason: null };
451
+ return { exists: false, reason: 'not-file' };
452
+ } catch (e) {
453
+ if (e?.code === 'ENOENT' || e?.code === 'ENOTDIR') return { exists: false, reason: 'missing' };
454
+ if (e?.code === 'EACCES' || e?.code === 'EPERM') return { exists: false, reason: 'permission-denied' };
455
+ return { exists: false, reason: 'error', code: e?.code || 'unknown' };
456
+ }
457
+ }
458
+
459
+ function renderProbeSkip(pathname, probe) {
460
+ if (!probe || probe.reason === 'missing') return `${pathname} not found`;
461
+ if (probe.reason === 'not-file') return `${pathname} is not a file`;
462
+ if (probe.reason === 'permission-denied') return `permission denied: ${pathname}`;
463
+ const code = probe.code ? ` (${probe.code})` : '';
464
+ return `unavailable: ${pathname}${code}`;
465
+ }
466
+
432
467
  async function isDir(p) {
433
468
  try {
434
469
  const st = await fs.stat(p);
@@ -17,7 +17,8 @@ async function cmdUninstall(argv) {
17
17
  const home = os.homedir();
18
18
  const trackerDir = path.join(home, '.vibescore', 'tracker');
19
19
  const binDir = path.join(home, '.vibescore', 'bin');
20
- const codexConfigPath = path.join(home, '.codex', 'config.toml');
20
+ const codexHome = process.env.CODEX_HOME || path.join(home, '.codex');
21
+ const codexConfigPath = path.join(codexHome, 'config.toml');
21
22
  const codeHome = process.env.CODE_HOME || path.join(home, '.code');
22
23
  const codeConfigPath = path.join(codeHome, 'config.toml');
23
24
  const claudeSettingsPath = path.join(home, '.claude', 'settings.json');