aicp-tracker 1.2.3 → 1.2.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.
package/bin/setup.js CHANGED
@@ -139,16 +139,27 @@ async function main() {
139
139
  name: 'vcsUrl',
140
140
  message: 'VCS organisation URL (e.g. https://bitbucket.org/my-workspace or https://github.com/my-org)',
141
141
  initial: existing?.vcsUrl || '',
142
- validate: v => /^https?:\/\/(bitbucket\.org|github\.com)\/.+/.test(v.trim())
143
- ? true
144
- : 'Must be https://bitbucket.org/<slug> or https://github.com/<slug>',
142
+ validate: v => {
143
+ try {
144
+ const url = new URL(v.trim());
145
+ if (!['bitbucket.org', 'github.com'].includes(url.hostname))
146
+ return 'Must be a bitbucket.org or github.com URL';
147
+ if (url.pathname.replace(/^\/+|\/+$/g, '').length === 0)
148
+ return 'Must include workspace/org slug (e.g. https://bitbucket.org/my-workspace)';
149
+ return true;
150
+ } catch {
151
+ return 'Enter a valid URL (e.g. https://bitbucket.org/my-workspace)';
152
+ }
153
+ },
145
154
  },
146
155
  {
147
156
  type: 'input',
148
157
  name: 'email',
149
158
  message: 'Your email used in Bitbucket / GitHub',
150
159
  initial: existing?.email || '',
151
- validate: v => v.includes('@') ? true : 'Enter a valid email address',
160
+ validate: v => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.trim().replace(/^[/\\]+|[/\\]+$/g, ''))
161
+ ? true
162
+ : 'Enter a valid email address (e.g. you@example.com)',
152
163
  },
153
164
  {
154
165
  type: 'select',
@@ -159,12 +170,14 @@ async function main() {
159
170
  },
160
171
  ]);
161
172
 
173
+ const normalizedEmail = answers.email.trim().replace(/^[/\\]+|[/\\]+$/g, '').toLowerCase();
174
+ const normalizedVcsUrl = answers.vcsUrl.trim().replace(/\/+$/, '');
162
175
  console.log('\n Registering with AI Code Pulse server…');
163
- const apiKey = await register(answers.email.trim());
176
+ const apiKey = await register(normalizedEmail);
164
177
 
165
178
  config.save({
166
- vcsUrl: answers.vcsUrl.trim(),
167
- email: answers.email.trim(),
179
+ vcsUrl: normalizedVcsUrl,
180
+ email: normalizedEmail,
168
181
  plan: answers.plan,
169
182
  apiUrl: API_URL,
170
183
  apiKey,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aicp-tracker",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "AI Code Pulse — Claude Code usage tracker for JIRA cost attribution",
5
5
  "main": "src/daemon.js",
6
6
  "bin": {
package/src/log-parser.js CHANGED
@@ -44,6 +44,7 @@ function sumUsage(entries) {
44
44
  let serviceTier = null, speed = null;
45
45
  const models = new Set();
46
46
 
47
+ const uuids = [];
47
48
  for (const e of entries) {
48
49
  const u = e.message?.usage || {};
49
50
  input += u.input_tokens || 0;
@@ -65,12 +66,13 @@ function sumUsage(entries) {
65
66
  }
66
67
  }
67
68
  if (e.message?.model) models.add(e.message.model);
69
+ if (e.uuid) uuids.push(e.uuid);
68
70
  }
69
- return { input, cc, cr, out, ephUser, ephAsst, ephTool, webSearch, webFetch, serviceTier, speed, models };
71
+ return { input, cc, cr, out, ephUser, ephAsst, ephTool, webSearch, webFetch, serviceTier, speed, models, uuids };
70
72
  }
71
73
 
72
74
  function makeRecord(first, rootUuid, usage, filePaths) {
73
- const { input, cc, cr, out, ephUser, ephAsst, ephTool, webSearch, webFetch, serviceTier, speed, models } = usage;
75
+ const { input, cc, cr, out, ephUser, ephAsst, ephTool, webSearch, webFetch, serviceTier, speed, models, uuids } = usage;
74
76
  return {
75
77
  sessionId: first.sessionId || null,
76
78
  uuid: rootUuid,
@@ -92,6 +94,7 @@ function makeRecord(first, rootUuid, usage, filePaths) {
92
94
  enterprise_usd_per_token: null,
93
95
  service_tier: serviceTier,
94
96
  speed: speed || (cc > 0 ? 'fast' : 'normal'),
97
+ trace_uuids: uuids.join(','),
95
98
  };
96
99
  }
97
100
 
package/src/sender.js CHANGED
@@ -38,6 +38,7 @@ function buildPayload(cfg, records) {
38
38
  timestamp: rec.timestamp || null,
39
39
  gitBranch: rec.gitBranch,
40
40
  task_from_git_branch: rec.task_from_git_branch || [],
41
+ trace_uuids: rec.trace_uuids || '',
41
42
  });
42
43
  }
43
44