ai-lens 0.8.109 → 0.8.110
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/init.js +13 -0
- package/cli/logger.js +16 -7
- package/cli/status.js +32 -5
- package/package.json +1 -1
package/.commithash
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
a16390a
|
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.110 — 2026-06-23
|
|
6
|
+
- feat: `init` now sends a status report to the server right after it finishes, so the server has your current config (including which `projects` are tracked) and confirmation that hooks fire — no need to run `ai-lens status` by hand. The diagnostic runs quietly: just one summary line on screen.
|
|
7
|
+
|
|
5
8
|
## 0.8.109 — 2026-06-22
|
|
6
9
|
- fix: `init --yes` no longer captures every project or silently imports your local Claude history. It now scopes capture to the git root of the current folder (still `--projects all` for everything), and imports past history only when you pass `--import`.
|
|
7
10
|
|
package/cli/init.js
CHANGED
|
@@ -1436,6 +1436,19 @@ export default async function init() {
|
|
|
1436
1436
|
// so the dashboard isn't empty on first open.
|
|
1437
1437
|
await maybeOfferImportHistory(flags);
|
|
1438
1438
|
|
|
1439
|
+
// Push a full status snapshot to the server right after every init — so it always has
|
|
1440
|
+
// this machine's FRESH config (crucially the `projects` filter, which the ingest path
|
|
1441
|
+
// never carries) plus post-install health (hooks actually fire). Runs quietly: the full
|
|
1442
|
+
// diagnostic is muted on screen (only one summary line) but still POSTed and written to
|
|
1443
|
+
// init.log. Best-effort: a token is required (the report needs auth), and any failure is
|
|
1444
|
+
// swallowed so it can never block or fail init.
|
|
1445
|
+
if (finalConfig.authToken && finalConfig.serverUrl) {
|
|
1446
|
+
try {
|
|
1447
|
+
const { default: status } = await import('./status.js');
|
|
1448
|
+
await status({ report: true, quiet: true });
|
|
1449
|
+
} catch { /* best-effort — never break init on a status/report failure */ }
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1439
1452
|
detail(`Log: ${getLogPath()}`);
|
|
1440
1453
|
}
|
|
1441
1454
|
|
package/cli/logger.js
CHANGED
|
@@ -7,6 +7,14 @@ const LOG_FILE = join(DATA_DIR, 'init.log');
|
|
|
7
7
|
|
|
8
8
|
let logFile = null;
|
|
9
9
|
|
|
10
|
+
// Screen-quiet mode: suppress stdout (console.log) while STILL writing to init.log.
|
|
11
|
+
// Used by init's end-of-run auto status report — the full diagnostic snapshot is sent
|
|
12
|
+
// to the server and logged to ~/.ai-lens/init.log, but the screen shows only the single
|
|
13
|
+
// summary line the caller prints (after flipping this back off). Toggled in a finally so
|
|
14
|
+
// a throw never leaves the terminal muted.
|
|
15
|
+
let screenQuiet = false;
|
|
16
|
+
export function setScreenQuiet(v) { screenQuiet = Boolean(v); }
|
|
17
|
+
|
|
10
18
|
export function initLogger(versionStr) {
|
|
11
19
|
mkdirSync(DATA_DIR, { recursive: true });
|
|
12
20
|
logFile = LOG_FILE;
|
|
@@ -53,6 +61,7 @@ let progressLastPaint = 0;
|
|
|
53
61
|
|
|
54
62
|
/** Show/update a transient one-line progress indicator (TTY only, throttled). */
|
|
55
63
|
export function progress(text) {
|
|
64
|
+
if (screenQuiet) return;
|
|
56
65
|
if (!useColor) return; // useColor === stdout.isTTY
|
|
57
66
|
const now = Date.now();
|
|
58
67
|
if (progressActive && now - progressLastPaint < PROGRESS_MIN_REPAINT_MS) return;
|
|
@@ -71,43 +80,43 @@ export function progressDone() {
|
|
|
71
80
|
|
|
72
81
|
export function info(msg) {
|
|
73
82
|
progressDone();
|
|
74
|
-
console.log(msg);
|
|
83
|
+
if (!screenQuiet) console.log(msg);
|
|
75
84
|
write('INFO', msg);
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
export function success(msg) {
|
|
79
88
|
progressDone();
|
|
80
|
-
console.log(`${GREEN}${msg}${RESET}`);
|
|
89
|
+
if (!screenQuiet) console.log(`${GREEN}${msg}${RESET}`);
|
|
81
90
|
write('INFO', msg);
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
export function warn(msg) {
|
|
85
94
|
progressDone();
|
|
86
|
-
console.log(`${YELLOW}${msg}${RESET}`);
|
|
95
|
+
if (!screenQuiet) console.log(`${YELLOW}${msg}${RESET}`);
|
|
87
96
|
write('WARN', msg);
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
export function error(msg) {
|
|
91
100
|
progressDone();
|
|
92
|
-
console.log(`${RED}${msg}${RESET}`);
|
|
101
|
+
if (!screenQuiet) console.log(`${RED}${msg}${RESET}`);
|
|
93
102
|
write('ERROR', msg);
|
|
94
103
|
}
|
|
95
104
|
|
|
96
105
|
export function heading(msg) {
|
|
97
106
|
progressDone();
|
|
98
|
-
console.log(`\n${BOLD}${CYAN}${msg}${RESET}`);
|
|
107
|
+
if (!screenQuiet) console.log(`\n${BOLD}${CYAN}${msg}${RESET}`);
|
|
99
108
|
write('INFO', msg);
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
export function detail(msg) {
|
|
103
112
|
progressDone();
|
|
104
|
-
console.log(`${DIM} ${msg}${RESET}`);
|
|
113
|
+
if (!screenQuiet) console.log(`${DIM} ${msg}${RESET}`);
|
|
105
114
|
write('INFO', msg);
|
|
106
115
|
}
|
|
107
116
|
|
|
108
117
|
export function blank() {
|
|
109
118
|
progressDone();
|
|
110
|
-
console.log();
|
|
119
|
+
if (!screenQuiet) console.log();
|
|
111
120
|
}
|
|
112
121
|
|
|
113
122
|
export function getLogPath() {
|
package/cli/status.js
CHANGED
|
@@ -10,7 +10,7 @@ import { TLS_TRUST_CODES, tlsCodeOf, tlsVerdictSummary, issuerName } from '../cl
|
|
|
10
10
|
import { getVersionInfo, readLensConfig, detectInstalledTools, getCursorToolConfig, getClaudeCodeToolConfig, getCodexToolConfig, analyzeToolHooks, checkHooksDisabled, verifyCodexHookTrust, CAPTURE_PATH, TOOL_CONFIGS, isClaudeProjectDirCommand, analyzeClaudeLocalOverlay, extractProjectDirRelPath, globalClaudeHooksActive, CONHOST_HEADLESS_PREFIX_RE } from './hooks.js';
|
|
11
11
|
import { DATA_DIR, PENDING_DIR, SENDING_DIR, SESSION_PATHS_DIR, LOG_PATH, CAPTURE_LOG_PATH, LAST_STATUS_REPORT_PATH, getGitIdentity, getMonitoredProjects } from '../client/config.js';
|
|
12
12
|
import { isLockStale } from '../client/sender.js';
|
|
13
|
-
import { initLogger, info, success, warn, error, heading, blank } from './logger.js';
|
|
13
|
+
import { initLogger, info, success, warn, error, heading, blank, detail, setScreenQuiet } from './logger.js';
|
|
14
14
|
import { scanNestedProjects, summarizeNestedProjects } from './scan.js';
|
|
15
15
|
|
|
16
16
|
const INIT_LOG_PATH = join(DATA_DIR, 'init.log');
|
|
@@ -1414,7 +1414,7 @@ function collectHookConfigs(allTools) {
|
|
|
1414
1414
|
}
|
|
1415
1415
|
|
|
1416
1416
|
async function sendStatusReport(results, warnings, clientVersion, clientCommit, serverUrl, authToken, allTools = TOOL_CONFIGS) {
|
|
1417
|
-
if (!serverUrl || !authToken) return;
|
|
1417
|
+
if (!serverUrl || !authToken) return { ok: false, reason: 'no-auth' };
|
|
1418
1418
|
|
|
1419
1419
|
const payload = {
|
|
1420
1420
|
timestamp: new Date().toISOString(),
|
|
@@ -1446,8 +1446,10 @@ async function sendStatusReport(results, warnings, clientVersion, clientCommit,
|
|
|
1446
1446
|
if (res.ok) {
|
|
1447
1447
|
try { writeFileSync(LAST_STATUS_REPORT_PATH, new Date().toISOString()); } catch {}
|
|
1448
1448
|
}
|
|
1449
|
-
|
|
1449
|
+
return { ok: res.ok, status: res.status };
|
|
1450
|
+
} catch (err) {
|
|
1450
1451
|
// Silent — report is best-effort
|
|
1452
|
+
return { ok: false, reason: err.message };
|
|
1451
1453
|
}
|
|
1452
1454
|
}
|
|
1453
1455
|
|
|
@@ -1455,7 +1457,15 @@ async function sendStatusReport(results, warnings, clientVersion, clientCommit,
|
|
|
1455
1457
|
// Main
|
|
1456
1458
|
// ---------------------------------------------------------------------------
|
|
1457
1459
|
|
|
1458
|
-
export default async function status({ report = false } = {}) {
|
|
1460
|
+
export default async function status({ report = false, quiet = false } = {}) {
|
|
1461
|
+
// quiet: run the full diagnostic + report, but suppress the on-screen dump — the
|
|
1462
|
+
// caller (init) prints a single summary line. The full snapshot still ships to the
|
|
1463
|
+
// server and is written to ~/.ai-lens/init.log. setScreenQuiet is flipped back in a
|
|
1464
|
+
// finally so a throw never leaves the terminal muted.
|
|
1465
|
+
if (quiet) setScreenQuiet(true);
|
|
1466
|
+
let reportOutcome = null;
|
|
1467
|
+
let failedChecks = 0;
|
|
1468
|
+
try {
|
|
1459
1469
|
const versionResult = checkVersion();
|
|
1460
1470
|
// Print to screen in both modes. --report additionally POSTs to the server
|
|
1461
1471
|
// (and skips the local text-file write + "Full report → path" line at the end).
|
|
@@ -1672,7 +1682,7 @@ export default async function status({ report = false } = {}) {
|
|
|
1672
1682
|
if (report) {
|
|
1673
1683
|
// --report mode: same on-screen output as normal status, but POST the
|
|
1674
1684
|
// structured JSON to the server instead of writing the local text file.
|
|
1675
|
-
await sendStatusReport(results, warnings, version, commit, serverUrl, authToken, allToolsForReport);
|
|
1685
|
+
reportOutcome = await sendStatusReport(results, warnings, version, commit, serverUrl, authToken, allToolsForReport);
|
|
1676
1686
|
blank();
|
|
1677
1687
|
} else {
|
|
1678
1688
|
// Normal mode: write text report file
|
|
@@ -1688,4 +1698,21 @@ export default async function status({ report = false } = {}) {
|
|
|
1688
1698
|
}
|
|
1689
1699
|
blank();
|
|
1690
1700
|
}
|
|
1701
|
+
failedChecks = results.filter(r => r && r.ok === false).length;
|
|
1702
|
+
} finally {
|
|
1703
|
+
if (quiet) setScreenQuiet(false);
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
// Quiet mode (init's end-of-run auto report): the full diagnostic above was muted —
|
|
1707
|
+
// print exactly one summary line now that the screen is un-muted.
|
|
1708
|
+
if (quiet) {
|
|
1709
|
+
if (reportOutcome?.ok) {
|
|
1710
|
+
const tail = failedChecks > 0
|
|
1711
|
+
? ` (${failedChecks} проверок с замечаниями — запусти ai-lens status)`
|
|
1712
|
+
: '';
|
|
1713
|
+
success(` 📡 Диагностика и конфиг отправлены на сервер${tail}`);
|
|
1714
|
+
} else {
|
|
1715
|
+
detail('📡 Не удалось отправить диагностику на сервер (не критично)');
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1691
1718
|
}
|