aicp-tracker 1.0.3 → 1.0.5

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.
@@ -1,20 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- const [,, cmd, ...args] = process.argv;
4
+ const [,, cmd] = process.argv;
5
+
6
+ async function ensureConfigured() {
7
+ const config = require('../src/config');
8
+ const existing = (() => { try { return config.load(); } catch { return null; } })();
9
+ if (existing?.apiKey && existing?.vcsUrl) return;
10
+ // No config — run the wizard first, then continue
11
+ await require('./setup').main();
12
+ }
5
13
 
6
14
  switch (cmd) {
7
- case 'start': require('../src/daemon').start(); break;
15
+ case 'start':
16
+ ensureConfigured().then(() => require('../src/daemon').start()).catch(e => {
17
+ console.error('[aicp-tracker] Setup failed:', e.message);
18
+ process.exit(1);
19
+ });
20
+ break;
8
21
  case 'stop': require('../src/daemon').stop(); break;
9
22
  case 'status': require('../src/daemon').status(); break;
10
- case 'setup': require('./setup'); break;
23
+ case 'setup': require('./setup').main().catch(e => console.error('[aicp-tracker] Setup failed:', e.message)); break;
11
24
  case 'flush': require('../src/wal').flush(); break;
12
25
  default:
13
26
  console.log(`
14
27
  aicp-tracker <command>
15
28
 
16
29
  Commands:
17
- start Start the background tracker (sends usage every 5 min)
30
+ start Start the background tracker (runs setup wizard on first use)
18
31
  stop Stop the background tracker
19
32
  status Show tracker status and WAL queue depth
20
33
  setup Re-run the configuration wizard
package/bin/setup.js CHANGED
@@ -4,23 +4,57 @@
4
4
  // Runs on `npm install` (postinstall). Skipped in CI environments.
5
5
  if (process.env.CI || process.env.npm_config_yes) process.exit(0);
6
6
 
7
- // Skip interactive setup on upgrade if already fully configured.
8
- // The user can always re-run manually: aicp-tracker setup
7
+ const path = require('path');
8
+
9
+ // Skip if already fully configured (upgrade path — no prompts needed)
9
10
  const isPostinstall = process.env.npm_lifecycle_event === 'postinstall';
10
11
  if (isPostinstall) {
11
12
  let existing = null;
12
13
  try { existing = require('../src/config').load(); } catch {}
13
- if (existing?.apiKey && existing?.vcsUrl) {
14
- console.log('\n [aicp-tracker] Already configured — skipping setup. Run `aicp-tracker setup` to reconfigure.\n');
15
- process.exit(0);
14
+ if (existing?.apiKey && existing?.vcsUrl) process.exit(0);
15
+
16
+ // Spawn a new terminal window with the wizard — gives a guaranteed TTY
17
+ // regardless of how npm pipes its own stdout during postinstall.
18
+ const { spawn } = require('child_process');
19
+ const wizardPath = path.resolve(__dirname, 'aicp-tracker.js');
20
+ const nodePath = process.execPath;
21
+
22
+ try {
23
+ if (process.platform === 'win32') {
24
+ // cmd /k keeps the window open after the wizard finishes so the user can read output
25
+ spawn('cmd.exe', ['/c', 'start', 'cmd', '/k', `"${nodePath}" "${wizardPath}" setup`], { stdio: 'ignore', detached: true }).unref();
26
+ } else if (process.platform === 'darwin') {
27
+ spawn('osascript', ['-e', `tell app "Terminal" to do script "${nodePath} '${wizardPath}' setup"`], { stdio: 'ignore', detached: true }).unref();
28
+ } else {
29
+ // Try common Linux terminal emulators in order
30
+ const terms = ['x-terminal-emulator', 'gnome-terminal', 'xterm', 'konsole'];
31
+ let launched = false;
32
+ for (const term of terms) {
33
+ try {
34
+ spawn(term, ['-e', `${nodePath} "${wizardPath}" setup`], { stdio: 'ignore', detached: true }).unref();
35
+ launched = true;
36
+ break;
37
+ } catch {}
38
+ }
39
+ if (!launched) {
40
+ console.log('\n\x1b[1m AI Code Pulse Tracker installed.\x1b[0m');
41
+ console.log(' Run \x1b[1maicp-tracker setup\x1b[0m to activate tracking.\n');
42
+ }
43
+ }
44
+ } catch {
45
+ console.log('\n\x1b[1m AI Code Pulse Tracker installed.\x1b[0m');
46
+ console.log(' Run \x1b[1maicp-tracker setup\x1b[0m to activate tracking.\n');
16
47
  }
48
+
49
+ process.exit(0);
17
50
  }
18
51
 
52
+ // ── When called directly (aicp-tracker setup) ─────────────────────────────────
53
+
19
54
  const { prompt } = require('enquirer');
20
55
  const { execSync } = require('child_process');
21
56
  const fs = require('fs');
22
57
  const os = require('os');
23
- const path = require('path');
24
58
  const config = require('../src/config');
25
59
  const daemon = require('../src/daemon');
26
60
 
@@ -44,14 +78,11 @@ function installAutoStart() {
44
78
 
45
79
  try {
46
80
  if (process.platform === 'win32') {
47
- // Windows Task Scheduler: run at every login, current user only
48
81
  execSync(
49
82
  `schtasks /create /tn "${TASK_NAME}" /tr "\\"${nodePath}\\" \\"${scriptPath}\\" start" /sc ONLOGON /f`,
50
83
  { stdio: 'ignore' }
51
84
  );
52
-
53
85
  } else if (process.platform === 'darwin') {
54
- // macOS launchd: load on login
55
86
  const plistDir = path.join(os.homedir(), 'Library', 'LaunchAgents');
56
87
  const plistPath = path.join(plistDir, 'com.aicp-tracker.plist');
57
88
  fs.mkdirSync(plistDir, { recursive: true });
@@ -71,9 +102,7 @@ function installAutoStart() {
71
102
  </dict>
72
103
  </plist>`);
73
104
  execSync(`launchctl load "${plistPath}"`, { stdio: 'ignore' });
74
-
75
105
  } else {
76
- // Linux: systemd user service
77
106
  const unitDir = path.join(os.homedir(), '.config', 'systemd', 'user');
78
107
  const unitPath = path.join(unitDir, 'aicp-tracker.service');
79
108
  fs.mkdirSync(unitDir, { recursive: true });
@@ -90,7 +119,6 @@ WantedBy=default.target
90
119
  `);
91
120
  execSync('systemctl --user daemon-reload && systemctl --user enable --now aicp-tracker', { stdio: 'ignore' });
92
121
  }
93
-
94
122
  return true;
95
123
  } catch {
96
124
  return false;
@@ -115,12 +143,12 @@ async function register(email) {
115
143
  // ── Main ──────────────────────────────────────────────────────────────────────
116
144
 
117
145
  async function main() {
118
- console.log('\n\x1b[1m AI Code Pulse Tracker — first-time setup\x1b[0m\n');
146
+ console.log('\n\x1b[1m AI Code Pulse Tracker — setup\x1b[0m\n');
119
147
 
120
148
  let existing = null;
121
149
  try { existing = config.load(); } catch {}
122
150
  if (existing?.vcsUrl) {
123
- console.log(` Already configured (${existing.vcsUrl}). Re-running setup will overwrite it.\n`);
151
+ console.log(` Already configured (${existing.vcsUrl}). Answers below will overwrite it.\n`);
124
152
  }
125
153
 
126
154
  const answers = await prompt([
@@ -174,6 +202,11 @@ async function main() {
174
202
  console.log(' \x1b[32m✔\x1b[0m Tracker running. Usage will be sent every 5 minutes.\n');
175
203
  }
176
204
 
177
- main().catch(e => {
178
- console.warn('\n [aicp-tracker] Setup skipped:', e.message, '\n Run `aicp-tracker setup` to configure later.\n');
179
- });
205
+ module.exports = { main };
206
+
207
+ // Auto-run when invoked directly (aicp-tracker setup) or required without await
208
+ if (require.main === module || process.env.npm_lifecycle_event === 'postinstall') {
209
+ main().catch(e => {
210
+ console.warn('\n [aicp-tracker] Setup error:', e.message, '\n Run `aicp-tracker setup` to try again.\n');
211
+ });
212
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aicp-tracker",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "AI Code Pulse — Claude Code usage tracker for JIRA cost attribution",
5
5
  "main": "src/daemon.js",
6
6
  "bin": {
@@ -15,6 +15,6 @@
15
15
  "engines": {
16
16
  "node": ">=18"
17
17
  },
18
- "license": "UNLICENSED",
18
+ "license": "MIT",
19
19
  "private": false
20
20
  }
package/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2026 Alexey Pavlenko
2
-
3
- All rights reserved.
4
-
5
- This software is proprietary and confidential.
6
-
7
- Permission is granted to install and use this software solely for the purpose
8
- of interacting with the AICP Tracker service, and only with a valid and active subscription.
9
-
10
- You may NOT:
11
- - copy, modify, merge, publish, distribute, sublicense, or sell the software
12
- - use the software in any competing product or service
13
- - reverse engineer, decompile, or attempt to extract source code or algorithms
14
- - remove or alter any proprietary notices
15
-
16
- The software is provided "as is", without warranty of any kind.
17
-
18
- Access to the source code (if provided) is for review purposes only and does
19
- not grant any rights beyond what is explicitly stated in this license.