ai-lens 0.8.69 → 0.8.70
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/.commithash +1 -1
- package/CHANGELOG.md +3 -0
- package/cli/status.js +22 -3
- package/client/capture.js +3 -3
- package/package.json +1 -1
package/.commithash
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
0912a07
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
History of changes to the `ai-lens` CLI package on npm. New entries go on top. Format: `## X.Y.Z — YYYY-MM-DD`, followed by user-facing bullets.
|
|
4
4
|
|
|
5
|
+
## 0.8.70 — 2026-05-28
|
|
6
|
+
- diag: `sender-spawn-failed`, `codex-watcher-spawn-failed` and `queue-write-failed` entries in the capture log now record the OS `error.code` (e.g. EMFILE, EACCES). `ai-lens status` surfaces a per-category code breakdown so these failures can be diagnosed centrally instead of guessing from a bare count. The raw error message (which may contain local paths) stays on your machine — only the short code travels in the status report.
|
|
7
|
+
|
|
5
8
|
## 0.8.69 — 2026-05-27
|
|
6
9
|
- feat: per-machine launcher (`~/.ai-lens/client/run.sh` / `run.cmd`) now also accepts an optional script path as its first argument. With no args it still execs the sibling `capture.js` (default install), but `~/.ai-lens/client/run.sh path/to/some/capture.js` execs that script with the launcher's resolved node — letting bootstrap-style workflows (e.g. meta-cursor) route through the launcher for proper node resolution while keeping `capture.js` under git in the workspace repo.
|
|
7
10
|
- feat: new `--install-launcher` flag for `init`. Forces launcher installation even when `--no-hooks` is set, so the meta-cursor setup skill can wire up `~/.ai-lens/client/run.sh` without touching the static hook templates in the workspace repo.
|
package/cli/status.js
CHANGED
|
@@ -725,8 +725,13 @@ function checkCaptureLog() {
|
|
|
725
725
|
return { ok: false, summary: `error reading log: ${err.message}`, detail: `Error: ${err.message}` };
|
|
726
726
|
}
|
|
727
727
|
|
|
728
|
-
// Count entries by category (reason for drops, msg for errors)
|
|
728
|
+
// Count entries by category (reason for drops, msg for errors). For error
|
|
729
|
+
// entries that carry an `error.code` (spawn/queue failures), also tally the
|
|
730
|
+
// code distribution per category so it reaches the server via client_reports
|
|
731
|
+
// — the count alone can't tell EMFILE from EACCES from ENOENT. The raw
|
|
732
|
+
// error.message strings stay local (may contain paths); only the code travels.
|
|
729
733
|
const counts = {};
|
|
734
|
+
const codesByCategory = {};
|
|
730
735
|
let lastTs = null;
|
|
731
736
|
let hasErrors = false;
|
|
732
737
|
for (const line of lines) {
|
|
@@ -734,24 +739,38 @@ function checkCaptureLog() {
|
|
|
734
739
|
const entry = JSON.parse(line);
|
|
735
740
|
const category = entry.reason || entry.msg || 'unknown';
|
|
736
741
|
counts[category] = (counts[category] || 0) + 1;
|
|
742
|
+
if (entry.code) {
|
|
743
|
+
(codesByCategory[category] ??= {});
|
|
744
|
+
codesByCategory[category][entry.code] = (codesByCategory[category][entry.code] || 0) + 1;
|
|
745
|
+
}
|
|
737
746
|
lastTs = entry.ts;
|
|
738
747
|
if (entry.msg) hasErrors = true;
|
|
739
748
|
} catch { /* non-JSON line */ }
|
|
740
749
|
}
|
|
741
750
|
|
|
742
751
|
const total = lines.length;
|
|
743
|
-
const breakdown = Object.entries(counts).map(([r, n]) =>
|
|
752
|
+
const breakdown = Object.entries(counts).map(([r, n]) => {
|
|
753
|
+
const codes = codesByCategory[r];
|
|
754
|
+
if (!codes) return `${r}: ${n}`;
|
|
755
|
+
const codeStr = Object.entries(codes).map(([c, cn]) => `${c}: ${cn}`).join(', ');
|
|
756
|
+
return `${r}: ${n} [${codeStr}]`;
|
|
757
|
+
}).join(', ');
|
|
744
758
|
|
|
745
759
|
let summary = `${total} entries`;
|
|
746
760
|
if (breakdown) summary += ` (${breakdown})`;
|
|
747
761
|
if (lastTs) summary += `, last ${relativeTime(lastTs)}`;
|
|
748
762
|
|
|
763
|
+
// Include a compact code-distribution block in detail too — survives even if
|
|
764
|
+
// the "last 10 entries" happen to be benign project_filter lines.
|
|
765
|
+
const codeLines = Object.entries(codesByCategory)
|
|
766
|
+
.map(([cat, codes]) => ` ${cat}: ${Object.entries(codes).map(([c, n]) => `${c}=${n}`).join(', ')}`);
|
|
767
|
+
const codeBlock = codeLines.length ? `\n\nError codes by category:\n${codeLines.join('\n')}` : '';
|
|
749
768
|
const last10 = lines.slice(-10);
|
|
750
769
|
|
|
751
770
|
return {
|
|
752
771
|
ok: !hasErrors,
|
|
753
772
|
summary,
|
|
754
|
-
detail: `Log: ${CAPTURE_LOG_PATH}\nTotal: ${total}\n\nLast 10 entries:\n${last10.join('\n')}`,
|
|
773
|
+
detail: `Log: ${CAPTURE_LOG_PATH}\nTotal: ${total}${codeBlock}\n\nLast 10 entries:\n${last10.join('\n')}`,
|
|
755
774
|
};
|
|
756
775
|
}
|
|
757
776
|
|
package/client/capture.js
CHANGED
|
@@ -1263,7 +1263,7 @@ async function main() {
|
|
|
1263
1263
|
writeToSpool(ev);
|
|
1264
1264
|
if (ev === primary) primaryWritten = true;
|
|
1265
1265
|
} catch (err) {
|
|
1266
|
-
captureLog({ msg: 'queue-write-failed', error: err.message, type: ev.type, session_id: ev.session_id });
|
|
1266
|
+
captureLog({ msg: 'queue-write-failed', error: err.message, code: err.code, type: ev.type, session_id: ev.session_id });
|
|
1267
1267
|
// If the primary failed, propagate the failure so the hook exits non-zero
|
|
1268
1268
|
// (and dedup is NOT committed). If a per-call event failed, log and keep
|
|
1269
1269
|
// going — losing one TokenUsage row is better than dropping the whole
|
|
@@ -1312,14 +1312,14 @@ async function main() {
|
|
|
1312
1312
|
try {
|
|
1313
1313
|
trySpawnSender();
|
|
1314
1314
|
} catch (err) {
|
|
1315
|
-
captureLog({ msg: 'sender-spawn-failed', error: err.message });
|
|
1315
|
+
captureLog({ msg: 'sender-spawn-failed', error: err.message, code: err.code });
|
|
1316
1316
|
// event is queued — sender will be spawned on next capture
|
|
1317
1317
|
}
|
|
1318
1318
|
|
|
1319
1319
|
try {
|
|
1320
1320
|
trySpawnCodexWatcher({ replayExisting: shouldReplayCodexHistory(primary) });
|
|
1321
1321
|
} catch (err) {
|
|
1322
|
-
captureLog({ msg: 'codex-watcher-spawn-failed', error: err.message });
|
|
1322
|
+
captureLog({ msg: 'codex-watcher-spawn-failed', error: err.message, code: err.code });
|
|
1323
1323
|
}
|
|
1324
1324
|
}
|
|
1325
1325
|
|