getaimeter 0.7.2 → 0.7.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 +1 -1
- package/service.js +29 -22
- package/watcher.js +35 -15
package/package.json
CHANGED
package/service.js
CHANGED
|
@@ -98,37 +98,44 @@ WshShell.Run """${nodePath}"" ""${script}"" watch", 0, False
|
|
|
98
98
|
* These are proper Windows shortcuts with icon and description.
|
|
99
99
|
*/
|
|
100
100
|
function createWindowsShortcuts(nodePath, script) {
|
|
101
|
-
const
|
|
101
|
+
const { execSync } = require('child_process');
|
|
102
|
+
const iconPath = path.join(__dirname, 'icon.ico');
|
|
103
|
+
|
|
102
104
|
const locations = [
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
path.join(os.homedir(), 'Desktop', 'AIMeter.lnk'),
|
|
106
|
+
path.join(os.homedir(), 'AppData', 'Roaming', 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'AIMeter.lnk'),
|
|
105
107
|
];
|
|
106
108
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
$
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
$
|
|
121
|
-
|
|
109
|
+
// Write a temporary PS1 file to avoid all escaping issues
|
|
110
|
+
const ps1Path = path.join(os.tmpdir(), 'aimeter-shortcut.ps1');
|
|
111
|
+
|
|
112
|
+
for (const lnkPath of locations) {
|
|
113
|
+
// Use single quotes in PS1 with doubled single-quote escaping
|
|
114
|
+
const ps1Content = [
|
|
115
|
+
'$ws = New-Object -ComObject WScript.Shell',
|
|
116
|
+
`$s = $ws.CreateShortcut('${lnkPath.replace(/'/g, "''")}')`,
|
|
117
|
+
`$s.TargetPath = '${nodePath.replace(/\\\\/g, '\\').replace(/'/g, "''")}'`,
|
|
118
|
+
`$s.Arguments = [char]34 + '${script.replace(/\\\\/g, '\\').replace(/'/g, "''")}' + [char]34 + ' start'`,
|
|
119
|
+
`$s.WorkingDirectory = '${os.homedir().replace(/'/g, "''")}'`,
|
|
120
|
+
`$s.Description = 'AIMeter - AI coding cost optimizer'`,
|
|
121
|
+
`$s.WindowStyle = 7`,
|
|
122
|
+
`$icon = '${iconPath.replace(/'/g, "''")}'`,
|
|
123
|
+
`if (Test-Path $icon) { $s.IconLocation = $icon }`,
|
|
124
|
+
`$s.Save()`,
|
|
125
|
+
].join('\n');
|
|
122
126
|
|
|
123
127
|
try {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
fs.writeFileSync(ps1Path, ps1Content, 'utf8');
|
|
129
|
+
execSync(`powershell -NoProfile -ExecutionPolicy Bypass -File "${ps1Path}"`, {
|
|
130
|
+
stdio: 'ignore',
|
|
131
|
+
timeout: 10000,
|
|
132
|
+
});
|
|
128
133
|
} catch {
|
|
129
134
|
// Non-critical — shortcuts are convenience, not required
|
|
130
135
|
}
|
|
131
136
|
}
|
|
137
|
+
|
|
138
|
+
try { fs.unlinkSync(ps1Path); } catch {}
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
function uninstallWindows() {
|
package/watcher.js
CHANGED
|
@@ -159,31 +159,51 @@ function extractNewUsage(filePath) {
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
if (!msg) {
|
|
162
|
-
// ── Codex CLI format
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
if (obj.type === 'event' && obj.payload?.type === 'token_count') {
|
|
166
|
-
|
|
162
|
+
// ── Codex CLI format (old: type="event", new: type="event_msg") ──
|
|
163
|
+
// Old format: { type: "event", payload: { type: "token_count", input_tokens, ... } }
|
|
164
|
+
// New format: { type: "event_msg", payload: { type: "token_count", info: { total_token_usage: { input_tokens, ... } } } }
|
|
165
|
+
if ((obj.type === 'event' || obj.type === 'event_msg') && obj.payload?.type === 'token_count') {
|
|
166
|
+
// Extract token counts — handle both old (flat) and new (nested) format
|
|
167
|
+
let inputTokens, outputTokens, reasoningTokens, cachedTokens;
|
|
168
|
+
|
|
169
|
+
if (obj.payload.info?.total_token_usage) {
|
|
170
|
+
// New format (2026+): cumulative totals in info.total_token_usage
|
|
171
|
+
const t = obj.payload.info.total_token_usage;
|
|
172
|
+
inputTokens = t.input_tokens || 0;
|
|
173
|
+
outputTokens = t.output_tokens || 0;
|
|
174
|
+
reasoningTokens = t.reasoning_output_tokens || t.reasoning_tokens || 0;
|
|
175
|
+
cachedTokens = t.cached_input_tokens || 0;
|
|
176
|
+
} else {
|
|
177
|
+
// Old format: flat fields on payload
|
|
178
|
+
inputTokens = obj.payload.input_tokens || 0;
|
|
179
|
+
outputTokens = obj.payload.output_tokens || 0;
|
|
180
|
+
reasoningTokens = obj.payload.reasoning_tokens || 0;
|
|
181
|
+
cachedTokens = obj.payload.cached_input_tokens || 0;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Skip events with no token info (e.g. rate limit only events)
|
|
185
|
+
if (inputTokens === 0 && outputTokens === 0) continue;
|
|
186
|
+
|
|
167
187
|
const codexModel = obj.turn_context?.model || 'codex';
|
|
188
|
+
|
|
168
189
|
// Token counts are cumulative per session; we store deltas
|
|
169
|
-
// Use a per-file tracker for the previous cumulative values
|
|
170
190
|
const prevKey = filePath;
|
|
171
191
|
const prev = _codexCumulative[prevKey] || { input: 0, output: 0, reasoning: 0, cached: 0 };
|
|
172
|
-
const deltaInput =
|
|
173
|
-
const deltaOutput =
|
|
174
|
-
const deltaReasoning =
|
|
192
|
+
const deltaInput = inputTokens - prev.input;
|
|
193
|
+
const deltaOutput = outputTokens - prev.output;
|
|
194
|
+
const deltaReasoning = reasoningTokens - prev.reasoning;
|
|
175
195
|
|
|
176
196
|
_codexCumulative[prevKey] = {
|
|
177
|
-
input:
|
|
178
|
-
output:
|
|
179
|
-
reasoning:
|
|
180
|
-
cached:
|
|
197
|
+
input: inputTokens,
|
|
198
|
+
output: outputTokens,
|
|
199
|
+
reasoning: reasoningTokens,
|
|
200
|
+
cached: cachedTokens,
|
|
181
201
|
};
|
|
182
202
|
|
|
183
203
|
// Skip if no new tokens (duplicate or first read)
|
|
184
204
|
if (deltaInput <= 0 && deltaOutput <= 0) continue;
|
|
185
205
|
|
|
186
|
-
const hashKey = `${filePath}:${lineOffset}:codex:${
|
|
206
|
+
const hashKey = `${filePath}:${lineOffset}:codex:${inputTokens}:${outputTokens}`;
|
|
187
207
|
const hash = crypto.createHash('md5').update(hashKey).digest('hex');
|
|
188
208
|
if (isDuplicate(hash)) continue;
|
|
189
209
|
|
|
@@ -194,7 +214,7 @@ function extractNewUsage(filePath) {
|
|
|
194
214
|
inputTokens: deltaInput,
|
|
195
215
|
outputTokens: deltaOutput,
|
|
196
216
|
thinkingTokens: deltaReasoning,
|
|
197
|
-
cacheReadTokens:
|
|
217
|
+
cacheReadTokens: cachedTokens,
|
|
198
218
|
cacheWriteTokens: 0,
|
|
199
219
|
});
|
|
200
220
|
continue;
|