@herbertgao/pi-extensions 2026.9.1 → 2026.9.2
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/node_modules/@narumitw/pi-btw/README.md +57 -141
- package/node_modules/@narumitw/pi-btw/dist/index.ts +466 -41
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +4 -4
- package/node_modules/@narumitw/pi-btw/docs/workflows.md +74 -0
- package/node_modules/@narumitw/pi-btw/package.json +2 -1
- package/node_modules/@narumitw/pi-btw/src/btw.ts +15 -1
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +32 -2
- package/node_modules/@narumitw/pi-btw/src/keybindings.ts +330 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +136 -19
- package/node_modules/@narumitw/pi-btw/src/settings.ts +32 -0
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +57 -5
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +52 -30
- package/node_modules/pi-lens/CHANGELOG.md +84 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +0 -7
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +1 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +0 -7
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +2 -0
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +133 -1
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +0 -6
- package/node_modules/pi-lens/dist/clients/bootstrap.js +4 -4
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +1 -1
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +0 -5
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +1 -9
- package/node_modules/pi-lens/dist/clients/cache-observability.js +1 -6
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +2 -2
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +0 -7
- package/node_modules/pi-lens/dist/clients/child-unref.js +1 -19
- package/node_modules/pi-lens/dist/clients/config-core/index.js +11 -8
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +1 -1
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +2 -9
- package/node_modules/pi-lens/dist/clients/config-core/records.js +1 -1
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +3 -5
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +1 -1
- package/node_modules/pi-lens/dist/clients/config-resolve.js +4 -4
- package/node_modules/pi-lens/dist/clients/config-schema.js +39 -2
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +0 -4
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +1 -1
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -4
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +0 -26
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +18 -1
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -6
- package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -3
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +1 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +6 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +4 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +1 -64
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -21
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +2 -20
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +1 -0
- package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +2 -2
- package/node_modules/pi-lens/dist/clients/disposition-logger.js +0 -7
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +2 -2
- package/node_modules/pi-lens/dist/clients/file-kinds.js +1 -38
- package/node_modules/pi-lens/dist/clients/file-time.js +1 -1
- package/node_modules/pi-lens/dist/clients/file-utils.js +5 -1
- package/node_modules/pi-lens/dist/clients/format-service.js +0 -1
- package/node_modules/pi-lens/dist/clients/formatters.js +110 -3
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +3 -4
- package/node_modules/pi-lens/dist/clients/git-guard.js +5 -0
- package/node_modules/pi-lens/dist/clients/grammar-source.js +3 -3
- package/node_modules/pi-lens/dist/clients/installer/index.js +220 -9
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +84 -18
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +6 -6
- package/node_modules/pi-lens/dist/clients/language-profile.js +0 -9
- package/node_modules/pi-lens/dist/clients/language-registry.js +5 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +5 -7
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +19 -0
- package/node_modules/pi-lens/dist/clients/lens-engine.js +3 -4
- package/node_modules/pi-lens/dist/clients/lens-events.js +1 -1
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +18 -0
- package/node_modules/pi-lens/dist/clients/lens-map.js +1 -1
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +0 -36
- package/node_modules/pi-lens/dist/clients/lsp/client.js +4 -3
- package/node_modules/pi-lens/dist/clients/lsp/config.js +1 -0
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +3 -3
- package/node_modules/pi-lens/dist/clients/lsp/index.js +216 -25
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/language.js +0 -8
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +0 -2
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -1
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +5 -5
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +6 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -1
- package/node_modules/pi-lens/dist/clients/metrics-history.js +28 -107
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +1 -1
- package/node_modules/pi-lens/dist/clients/module-report.js +1 -1
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +3 -3
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +3 -3
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +0 -4
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +9 -9
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +2 -6
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/path-utils.js +23 -2
- package/node_modules/pi-lens/dist/clients/performance-report.js +2 -2
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/pipeline.js +2 -2
- package/node_modules/pi-lens/dist/clients/project-changes.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +46 -1
- package/node_modules/pi-lens/dist/clients/project-scan-policy.js +3 -51
- package/node_modules/pi-lens/dist/clients/python-provenance.js +1 -1
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/read-guard.js +5 -2
- package/node_modules/pi-lens/dist/clients/recent-touches.js +2 -2
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +3 -5
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +1 -1
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +1 -1
- package/node_modules/pi-lens/dist/clients/runtime-session.js +45 -10
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +11 -1
- package/node_modules/pi-lens/dist/clients/sanitize.js +0 -11
- package/node_modules/pi-lens/dist/clients/scan-utils.js +1 -56
- package/node_modules/pi-lens/dist/clients/session-summary.js +0 -24
- package/node_modules/pi-lens/dist/clients/sgconfig.js +1 -5
- package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +2 -2
- package/node_modules/pi-lens/dist/clients/startup-scan.js +2 -10
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +77 -72
- package/node_modules/pi-lens/dist/clients/tool-policy.js +1 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +1 -52
- package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -4
- package/node_modules/pi-lens/dist/clients/user-notify.js +0 -4
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +0 -7
- package/node_modules/pi-lens/dist/clients/word-index-store.js +3 -7
- package/node_modules/pi-lens/dist/clients/word-index.js +9 -16
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +1 -1
- package/node_modules/pi-lens/dist/index.js +1062 -538
- package/node_modules/pi-lens/dist/mcp/build-staleness.js +1 -1
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +1 -1
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +1 -1
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +1 -1
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +37 -6
- package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +3 -3
- package/node_modules/pi-lens/dist/tools/render-compact.js +1 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -2
- package/node_modules/pi-lens/docs/globalconfig.md +20 -0
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +9 -1
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +6 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +12 -1
- package/node_modules/pi-lens/docs/release-qa-baseline.md +12 -4
- package/node_modules/pi-lens/docs/servercapabilities.md +7 -3
- package/node_modules/pi-lens/docs/word-index.md +1 -1
- package/node_modules/pi-lens/package.json +6 -15
- package/node_modules/pi-lens/rules/typos/_typos.toml +4 -2
- package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +1 -1
- package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +1 -1
- package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +4 -2
- package/package.json +3 -3
|
@@ -46,7 +46,7 @@ function runningOnWindows() {
|
|
|
46
46
|
return process.platform === "win32";
|
|
47
47
|
}
|
|
48
48
|
/** Default ceiling for one process listing. */
|
|
49
|
-
|
|
49
|
+
const DEFAULT_SNAPSHOT_TIMEOUT_MS = 4_000;
|
|
50
50
|
/**
|
|
51
51
|
* @typedef {"pid" | "ppid" | "ageMs" | "rssBytes" | "cpuKernel100ns" | "cpuUser100ns" | "startedAt" | "command"} ProcessField
|
|
52
52
|
* @typedef {{ pid: number, ppid: number, command: string, ageMs?: number, rssBytes?: number, cpuKernel100ns?: number, cpuUser100ns?: number, startedAt?: string, cwd?: string }} ProcRow
|
|
@@ -52,7 +52,7 @@ import * as path from "node:path";
|
|
|
52
52
|
* @param {import("node:fs").Dirent} entry
|
|
53
53
|
* @returns {"file" | "dir" | "other"}
|
|
54
54
|
*/
|
|
55
|
-
|
|
55
|
+
function resolvedEntryKind(fullPath, entry) {
|
|
56
56
|
if (entry.isSymbolicLink()) {
|
|
57
57
|
try {
|
|
58
58
|
const stats = fs.statSync(fullPath);
|
|
@@ -1115,7 +1115,7 @@ function tallyLspPrimaryVsAuxiliary(results) {
|
|
|
1115
1115
|
}
|
|
1116
1116
|
return { primary, auxiliary };
|
|
1117
1117
|
}
|
|
1118
|
-
|
|
1118
|
+
function mergeDiagnosticsWithWidgetSummaries(widgetSummaries, lspResults, projectSnapshot, projectDelta,
|
|
1119
1119
|
/**
|
|
1120
1120
|
* #1993: resolved paths covered by a CONFIRMED, fully-covered LSP result
|
|
1121
1121
|
* in `lspResults`. The fresh sweep is AUTHORITATIVE for these files - any
|
|
@@ -245,6 +245,10 @@ onConfirmedNoBlockers) {
|
|
|
245
245
|
// compact-render as a bare "N diagnostics" — that erases the fact some
|
|
246
246
|
// files' clean status was never actually confirmed by the server.
|
|
247
247
|
const unconfirmedFiles = details?.unconfirmedFiles ?? 0;
|
|
248
|
+
const navigationOnlyFiles = details?.navigationOnlyFiles ?? 0;
|
|
249
|
+
if (navigationOnlyFiles > 0) {
|
|
250
|
+
return `lsp_diagnostics${scope} — ${count} ${noun} · ${details?.cleanFiles ?? 0} clean · ${navigationOnlyFiles} navigation-only`;
|
|
251
|
+
}
|
|
248
252
|
if (unconfirmedFiles > 0) {
|
|
249
253
|
const cleanFiles = details?.cleanFiles ?? 0;
|
|
250
254
|
const timedOutFiles = details?.timedOutFiles ?? 0;
|
|
@@ -470,6 +474,7 @@ async function collectDiagnosticsForFile(absPath, lspService, waitMs, serverScop
|
|
|
470
474
|
// field across the socket. An older incumbent omits it → empty → the
|
|
471
475
|
// pre-#1470 handling, unchanged.
|
|
472
476
|
unconfirmedServerIds: attached.response.unconfirmedServerIds ?? [],
|
|
477
|
+
diagnosticsUnsupportedServerIds: [],
|
|
473
478
|
content,
|
|
474
479
|
};
|
|
475
480
|
}
|
|
@@ -528,6 +533,7 @@ async function collectDiagnosticsForFile(absPath, lspService, waitMs, serverScop
|
|
|
528
533
|
// the getDiagnostics fallback never reports one, which is honest — that
|
|
529
534
|
// path claims no confirmation at all.
|
|
530
535
|
unconfirmedServerIds: touchCoverageGap(touched),
|
|
536
|
+
diagnosticsUnsupportedServerIds: touched?.diagnosticsUnsupportedServerIds ?? [],
|
|
531
537
|
content,
|
|
532
538
|
binding,
|
|
533
539
|
};
|
|
@@ -777,7 +783,7 @@ onConfirmedNoBlockers) {
|
|
|
777
783
|
};
|
|
778
784
|
}
|
|
779
785
|
}
|
|
780
|
-
const { diagnostics: rawDiags, timedOut, confirmedByTouch, unconfirmedServerIds, content: collectedContent, binding, skipReason, } = await collectDiagnosticsForFile(file, lspService, waitMs, serverScope);
|
|
786
|
+
const { diagnostics: rawDiags, timedOut, confirmedByTouch, unconfirmedServerIds, diagnosticsUnsupportedServerIds, content: collectedContent, binding, skipReason, } = await collectDiagnosticsForFile(file, lspService, waitMs, serverScope);
|
|
781
787
|
const health = lspService.getDiagnosticsHealth?.(file);
|
|
782
788
|
// #570: a timed-out priming check is never a confirmed "clean" — treat it
|
|
783
789
|
// as unconfirmed without consulting the (unrelated) silent-tier
|
|
@@ -788,7 +794,12 @@ onConfirmedNoBlockers) {
|
|
|
788
794
|
// be merged in rather than discarded.
|
|
789
795
|
let effectiveRawDiags = rawDiags;
|
|
790
796
|
let confirmation;
|
|
791
|
-
if (
|
|
797
|
+
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
798
|
+
// No diagnostic provider and no push evidence is a capability boundary,
|
|
799
|
+
// not a clean result and not a timeout.
|
|
800
|
+
confirmation = undefined;
|
|
801
|
+
}
|
|
802
|
+
else if (skipReason !== undefined) {
|
|
792
803
|
confirmation = "unconfirmed";
|
|
793
804
|
}
|
|
794
805
|
else if (timedOut) {
|
|
@@ -851,6 +862,7 @@ onConfirmedNoBlockers) {
|
|
|
851
862
|
if (cacheCtx &&
|
|
852
863
|
scopeKey !== undefined &&
|
|
853
864
|
confirmation !== "unconfirmed" &&
|
|
865
|
+
diagnosticsUnsupportedServerIds.length === 0 &&
|
|
854
866
|
unconfirmedServerIds.length === 0) {
|
|
855
867
|
cacheCtx.record(file, scopeKey, effectiveRawDiags, stat.mtimeMs, collectedContent !== undefined
|
|
856
868
|
? hashDiagnosticContent(collectedContent)
|
|
@@ -864,6 +876,7 @@ onConfirmedNoBlockers) {
|
|
|
864
876
|
timedOut: confirmation === "unconfirmed" ? timedOut : undefined,
|
|
865
877
|
...(skipReason !== undefined && { skipReason }),
|
|
866
878
|
primaryServerId: primaryServerId(file),
|
|
879
|
+
diagnosticsUnsupported: diagnosticsUnsupportedServerIds.length > 0,
|
|
867
880
|
};
|
|
868
881
|
}
|
|
869
882
|
async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope = "all", cwd = process.cwd(),
|
|
@@ -873,7 +886,7 @@ onConfirmedNoBlockers) {
|
|
|
873
886
|
// Reserve the token before awaiting this file's LSP result. The direct-file
|
|
874
887
|
// path performs its own confirmation/reconciliation below (#1198).
|
|
875
888
|
const writeIndex = nextWriteIndex?.();
|
|
876
|
-
const { diagnostics: rawDiags, timedOut, confirmedByTouch, unconfirmedServerIds, content: collectedContent, binding, skipReason, } = await collectDiagnosticsForFile(absPath, lspService, waitMs, serverScope);
|
|
889
|
+
const { diagnostics: rawDiags, timedOut, confirmedByTouch, unconfirmedServerIds, diagnosticsUnsupportedServerIds, content: collectedContent, binding, skipReason, } = await collectDiagnosticsForFile(absPath, lspService, waitMs, serverScope);
|
|
877
890
|
const lspHealth = lspService.getDiagnosticsHealth?.(absPath);
|
|
878
891
|
const unavailable = lspUnavailableMessage(absPath, lspHealth);
|
|
879
892
|
// #533: an empty result needs a confirmed/unconfirmed verdict — a push-only,
|
|
@@ -887,7 +900,10 @@ onConfirmedNoBlockers) {
|
|
|
887
900
|
// diagnostics it surfaces are merged in, not discarded.
|
|
888
901
|
let effectiveRawDiags = rawDiags;
|
|
889
902
|
let confirmation;
|
|
890
|
-
if (
|
|
903
|
+
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
904
|
+
confirmation = undefined;
|
|
905
|
+
}
|
|
906
|
+
else if (skipReason !== undefined) {
|
|
891
907
|
confirmation = "unconfirmed";
|
|
892
908
|
}
|
|
893
909
|
else if (timedOut) {
|
|
@@ -955,6 +971,9 @@ onConfirmedNoBlockers) {
|
|
|
955
971
|
// auxiliary findings exist — a wall of ast-grep/opengrep noise must never
|
|
956
972
|
// bury whether the actual language server confirmed the file clean.
|
|
957
973
|
const primaryLine = (() => {
|
|
974
|
+
if (diagnosticsUnsupportedServerIds.length > 0) {
|
|
975
|
+
return `Primary LSP${primaryId ? ` (${primaryId})` : ""}: navigation-only — diagnostics unsupported (no pull provider or publish evidence).`;
|
|
976
|
+
}
|
|
958
977
|
if (timedOut) {
|
|
959
978
|
return ("Primary LSP: check timed out — NOT the same as 0 diagnostics; the " +
|
|
960
979
|
"file may still have errors that just hadn't been reported yet. " +
|
|
@@ -1031,6 +1050,7 @@ onConfirmedNoBlockers) {
|
|
|
1031
1050
|
truncated,
|
|
1032
1051
|
unconfirmed,
|
|
1033
1052
|
timedOut: unconfirmed ? timedOut : undefined,
|
|
1053
|
+
navigationOnlyFiles: diagnosticsUnsupportedServerIds.length > 0 ? 1 : undefined,
|
|
1034
1054
|
...(skipReason !== undefined && { skipReason }),
|
|
1035
1055
|
// #1470: which servers this result does NOT speak for. Absent when it
|
|
1036
1056
|
// speaks for all of them.
|
|
@@ -1054,7 +1074,12 @@ function tallyConfirmation(results) {
|
|
|
1054
1074
|
let clean = 0;
|
|
1055
1075
|
let unconfirmed = 0;
|
|
1056
1076
|
let timedOut = 0;
|
|
1077
|
+
let navigationOnly = 0;
|
|
1057
1078
|
for (const result of results) {
|
|
1079
|
+
if (result.diagnosticsUnsupported) {
|
|
1080
|
+
navigationOnly += 1;
|
|
1081
|
+
continue;
|
|
1082
|
+
}
|
|
1058
1083
|
if (result.diagnostics.length > 0)
|
|
1059
1084
|
continue;
|
|
1060
1085
|
if (result.confirmation === "unconfirmed") {
|
|
@@ -1068,11 +1093,13 @@ function tallyConfirmation(results) {
|
|
|
1068
1093
|
clean += 1;
|
|
1069
1094
|
}
|
|
1070
1095
|
}
|
|
1071
|
-
return { clean, unconfirmed, timedOut };
|
|
1096
|
+
return { clean, unconfirmed, timedOut, navigationOnly };
|
|
1072
1097
|
}
|
|
1073
1098
|
function classifyBatchFileOutcome(result) {
|
|
1074
1099
|
if (result.error)
|
|
1075
1100
|
return "failed";
|
|
1101
|
+
if (result.diagnosticsUnsupported)
|
|
1102
|
+
return "unsupported";
|
|
1076
1103
|
// A timed-out/unconfirmed answer may contain partial findings, but it cannot
|
|
1077
1104
|
// honestly be called a complete findings result. Keep the raw findings for
|
|
1078
1105
|
// investigation while making the aggregate incomplete.
|
|
@@ -1228,6 +1255,7 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options)
|
|
|
1228
1255
|
};
|
|
1229
1256
|
}
|
|
1230
1257
|
const { results, fileErrors, lspHealthWarnings, total, truncated, display, primaryDisplay, auxiliaryDisplay, clean, unconfirmed, timedOut, outcomeCounts, incompleteFiles, } = await collectBatchDiagnostics(absPaths, severity, lspService, options);
|
|
1258
|
+
const navigationOnly = results.filter((result) => result.diagnosticsUnsupported).length;
|
|
1231
1259
|
const lines = [
|
|
1232
1260
|
`Files checked: ${results.length}`,
|
|
1233
1261
|
`Total diagnostics: ${total}`,
|
|
@@ -1298,6 +1326,7 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options)
|
|
|
1298
1326
|
truncated,
|
|
1299
1327
|
cleanFiles: clean,
|
|
1300
1328
|
unconfirmedFiles: unconfirmed,
|
|
1329
|
+
navigationOnlyFiles: navigationOnly > 0 ? navigationOnly : undefined,
|
|
1301
1330
|
timedOutFiles: timedOut > 0 ? timedOut : undefined,
|
|
1302
1331
|
outcomes: results.map((result) => ({
|
|
1303
1332
|
file: result.file,
|
|
@@ -1366,7 +1395,8 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
1366
1395
|
}
|
|
1367
1396
|
const wasCapped = collectedFiles.length > MAX_FILES;
|
|
1368
1397
|
const filesToProcess = collectedFiles.slice(0, MAX_FILES);
|
|
1369
|
-
const { fileErrors, lspHealthWarnings, total, truncated, display, primaryDisplay, auxiliaryDisplay, clean, unconfirmed, timedOut, } = await collectBatchDiagnostics(filesToProcess, severity, lspService, options);
|
|
1398
|
+
const { results, fileErrors, lspHealthWarnings, total, truncated, display, primaryDisplay, auxiliaryDisplay, clean, unconfirmed, timedOut, } = await collectBatchDiagnostics(filesToProcess, severity, lspService, options);
|
|
1399
|
+
const navigationOnly = results.filter((result) => result.diagnosticsUnsupported).length;
|
|
1370
1400
|
let text;
|
|
1371
1401
|
if (total === 0) {
|
|
1372
1402
|
// #533/#570: an unconfirmed-containing directory result must never
|
|
@@ -1450,6 +1480,7 @@ async function runDirectoryDiagnostics(absPath, severity, lspService, options) {
|
|
|
1450
1480
|
truncated,
|
|
1451
1481
|
cleanFiles: clean,
|
|
1452
1482
|
unconfirmedFiles: unconfirmed,
|
|
1483
|
+
navigationOnlyFiles: navigationOnly > 0 ? navigationOnly : undefined,
|
|
1453
1484
|
timedOutFiles: timedOut > 0 ? timedOut : undefined,
|
|
1454
1485
|
fileErrors: fileErrors.length > 0 ? fileErrors : undefined,
|
|
1455
1486
|
lspHealthWarnings: lspHealthWarnings.length > 0 ? lspHealthWarnings : undefined,
|
|
@@ -9,7 +9,7 @@ function finiteNumber(value) {
|
|
|
9
9
|
? value
|
|
10
10
|
: undefined;
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
function lspStatusFromFailureKind(failureKind) {
|
|
13
13
|
if (failureKind === "success" || failureKind === "fallback_success") {
|
|
14
14
|
return "success";
|
|
15
15
|
}
|
|
@@ -145,7 +145,7 @@ function collectCallHierarchyLocationSummaries(result, operation) {
|
|
|
145
145
|
}
|
|
146
146
|
return out;
|
|
147
147
|
}
|
|
148
|
-
|
|
148
|
+
function collectLspToolLocationsForOperation(operation, result, filePath) {
|
|
149
149
|
if ([
|
|
150
150
|
"definition",
|
|
151
151
|
"typeDefinition",
|
|
@@ -210,7 +210,7 @@ function parseBalancedJsonPrefix(text) {
|
|
|
210
210
|
}
|
|
211
211
|
return undefined;
|
|
212
212
|
}
|
|
213
|
-
|
|
213
|
+
function parseLspNavigationTextPayload(text) {
|
|
214
214
|
const notes = [];
|
|
215
215
|
const hints = [];
|
|
216
216
|
const errors = [];
|
|
@@ -65,7 +65,7 @@ export function selectCompactText(result, args, expanded, summarize) {
|
|
|
65
65
|
}
|
|
66
66
|
/** Apply a CompactStyle to text. `brand` uses raw blue ANSI; the rest defer to
|
|
67
67
|
* the theme so error-red and normal output stay consistent with the host. */
|
|
68
|
-
|
|
68
|
+
function paintCompact(style, text, theme) {
|
|
69
69
|
if (style === "brand") {
|
|
70
70
|
return `${PI_LENS_BLUE_FG}${text}${RESET_FG}`;
|
|
71
71
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import * as path from "node:path";
|
|
9
9
|
import { Type } from "../clients/deps/typebox.js";
|
|
10
10
|
import { symbolSearch, } from "../clients/lens-engine.js";
|
|
11
|
-
import {
|
|
11
|
+
import { compactRenderResult } from "./render-compact.js";
|
|
12
12
|
/**
|
|
13
13
|
* Machine-actionable follow-up hint (#771) — mirrors ast-grep-search.ts's
|
|
14
14
|
* `suggestedDump` pattern. Cheap enough to attach per hit rather than only the
|
|
@@ -153,4 +153,3 @@ export function createSymbolSearchTool(getProjectRoot) {
|
|
|
153
153
|
}
|
|
154
154
|
// Re-exported so tests importing from this module can reach baseName without
|
|
155
155
|
// a second import path.
|
|
156
|
-
export { baseName };
|
|
@@ -27,6 +27,20 @@ Each runtime toggle is settable from the CLI *and* from `config.json`. The two a
|
|
|
27
27
|
| `--lens-compact-tool-line` | `ui.compactToolLine` | `false` |
|
|
28
28
|
| `--no-lazy-tools` | `tools.lazy` | `true` |
|
|
29
29
|
| `--lens-turn-end-madge` | `turnEnd.madge.enabled` | `false` |
|
|
30
|
+
| `--no-knip` | `knip.enabled` | `true` |
|
|
31
|
+
| `--no-jscpd` | `jscpd.enabled` | `true` |
|
|
32
|
+
| `--no-madge` | `madge.enabled` | `true` |
|
|
33
|
+
| `--no-gitleaks` | `gitleaks.enabled` | `true` |
|
|
34
|
+
| `--no-govulncheck` | `govulncheck.enabled` | `true` |
|
|
35
|
+
| `--no-dead-code` | `deadCode.enabled` | `true` |
|
|
36
|
+
| `--no-complexity` | `complexity.enabled` | `true` |
|
|
37
|
+
|
|
38
|
+
## Startup controls
|
|
39
|
+
|
|
40
|
+
| Configuration key | Default | Accepted values |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| `startup.mode` | `full` | `quick`, `full`, or `minimal`; `PI_LENS_STARTUP_MODE` wins |
|
|
43
|
+
| `startup.scans.enabled` | `true` | `true` or `false` |
|
|
30
44
|
|
|
31
45
|
By default pi-lens registers six situational tools (the `ast_grep_*` family,
|
|
32
46
|
`lsp_navigation`, `lens_diagnostic_mark`) inactive and exposes a small loader,
|
|
@@ -249,6 +263,12 @@ Explicit override for the review graph's own file budget (#775), for monorepos t
|
|
|
249
263
|
|
|
250
264
|
### Schema rules
|
|
251
265
|
|
|
266
|
+
Session-start analyzer keys default to `true` and work in both the global
|
|
267
|
+
config and `.pi-lens.json`. Set one to `false` to skip that analyzer; pi-lens
|
|
268
|
+
records the disabled skip. `startup.mode` accepts `quick`, `full`, or
|
|
269
|
+
`minimal`, and `startup.scans.enabled: false` disables background startup scans
|
|
270
|
+
while leaving diagnostics and LSP active. `PI_LENS_STARTUP_MODE` still wins.
|
|
271
|
+
|
|
252
272
|
- Unknown rule ids are ignored (forward-compat). Unrecognized **top-level** keys are logged once and then ignored — never fatal to the parse. The LSP namespaces a shared file legitimately carries (`servers`, `serverOverrides`, `disabledServers`, `warmFiles`) and `$schema` are tolerated silently; a user-level-only lens key placed here (e.g. `lsp`, `tests`, `delta`) is logged as "not honored at project scope"; anything else is logged as a likely typo. The raw parsed JSON is still exposed for forward-compat consumers regardless.
|
|
253
273
|
- Every toggle key in the table above must be a boolean, and its containing section must be an object. A wrong type is logged once and the key is treated as absent, so the flag falls through to its default rather than the whole file being rejected.
|
|
254
274
|
- A malformed JSON file is logged once and treated as "no config" — your diagnostics never get blocked by a syntax error in your own config.
|
|
@@ -35,11 +35,19 @@ they share a server id but not a verified clean-signal behavior.
|
|
|
35
35
|
| **2 — push, publishes-versioned** | `publishDiagnostics([])` **with version** on every scan, incl. clean→clean | YES, currency-proven via version | ast-grep |
|
|
36
36
|
| **2\* — push, publishes-unversioned** | re-publishes on a clean scan but **version-less** — the wait still early-returns (the client accepts a version-less publish as fresh: it can't be proven stale), but currency is only *temporally correlated*, not proven | YES at runtime, with a staleness-risk caveat (not a latency cost) | opengrep |
|
|
37
37
|
| **3 — push, silent on clean** | server publishes nothing when nothing changed | **NO** — budget-wait floor (safe; a timeout is *not* a false clean). **This tier is #458's learned-deadline target set.** | typescript-language-server |
|
|
38
|
+
| **Navigation-only — custom, no evidence** | custom `lsp.servers.*` entry has no pull provider and has not published in this session | **NO** — diagnostics are unsupported; skip the wait and report navigation-only | Dexter |
|
|
38
39
|
|
|
39
40
|
Detection is **cached** at `initialize` (`detectWorkspaceDiagnosticsSupport` →
|
|
40
41
|
`state.workspaceDiagnosticsSupport.mode`, upgraded on `client/registerCapability`),
|
|
41
42
|
so the tier is free at collection time — no per-edit probe.
|
|
42
43
|
|
|
44
|
+
Custom servers without a pull provider begin with one bounded first-contact
|
|
45
|
+
probe. The probe uses the smaller of the server's push-wait budget and the live
|
|
46
|
+
hook deadline. If the hook cuts it off first, the result remains unconfirmed and
|
|
47
|
+
the next touch probes again. Only silence through the full push budget latches
|
|
48
|
+
that server id as navigation-only for the service session. A publish upgrades it
|
|
49
|
+
to the ordinary push-wait policy.
|
|
50
|
+
|
|
43
51
|
## Matrix (dev box + CI nightly; mode last refreshed 2026-06-17 from run 27713958681, clean-behavior probed on the dev box 2026-07-08 — #460)
|
|
44
52
|
|
|
45
53
|
`mode` from cached capabilities; `clean-behavior` from the phase-aware publish-trace
|
|
@@ -74,7 +82,7 @@ classification standing.
|
|
|
74
82
|
| toml | taplo | push-only | publishes-unversioned | 2* | dev+ci |
|
|
75
83
|
| terraform | terraform-ls | push-only | TBD | 2/3? | dev+ci |
|
|
76
84
|
| prisma | @prisma/language-server | push-only | publishes-unversioned | 2* | dev+ci |
|
|
77
|
-
| php | intelephense | push-only | TBD | 2/3? | dev |
|
|
85
|
+
| php | intelephense | push-only | TBD | 2/3? | dev+ci |
|
|
78
86
|
| zig | zls | push-only | publishes-unversioned | 2* | dev+ci |
|
|
79
87
|
| vue | @vue/language-server | push-only | TBD | 2/3? | dev+ci |
|
|
80
88
|
| dart | dart language-server | push-only | publishes-unversioned | 2* | ci |
|
|
@@ -6,6 +6,12 @@ Assume the implementation's claims are incomplete. Read the issue, full diff,
|
|
|
6
6
|
repository instructions, shared delegated worker contract, PR body, and merge
|
|
7
7
|
state. Keep the review read-only.
|
|
8
8
|
|
|
9
|
+
Diff the change from its merge base (`git diff origin/master...HEAD`, or
|
|
10
|
+
`git diff $(git merge-base origin/master HEAD)..HEAD`), never a two-dot diff
|
|
11
|
+
against `origin/master`: a checkout cut before another lane merged shows that
|
|
12
|
+
merge in reverse as deletions and produces a false HIGH (2026-09-08, #2730
|
|
13
|
+
round 2 and #2747 round 1).
|
|
14
|
+
|
|
9
15
|
Reproduce the build and targeted tests. Verify quoted red-first evidence by
|
|
10
16
|
keeping the tests and removing the source fix. Mutate every new guard and demand
|
|
11
17
|
a red test. Probe inversions, concurrency, input channels, trust boundaries,
|
|
@@ -30,7 +30,18 @@ real store, sink, coordinator, or registry, use it and assert the durable result
|
|
|
30
30
|
Git authority is separate from the role. Commit, push, or open a PR only when
|
|
31
31
|
the delegation explicitly grants that authority after worktree verification.
|
|
32
32
|
Otherwise, edit and test with the assigned worktree as the command working
|
|
33
|
-
directory,
|
|
33
|
+
directory, leave every change uncommitted, and write two handoff files at the
|
|
34
|
+
worktree root: `PR_BODY.md` (the full PR body, transcripts pasted) and
|
|
35
|
+
`COMMIT_MSG.txt` (subject, body, issue ref, trailers). Name any path inside the
|
|
36
|
+
worktree that must not be committed. The orchestrator commits from those files;
|
|
37
|
+
they are never committed themselves. Never merge.
|
|
38
|
+
|
|
39
|
+
A sandboxed worker may find the shared `.git` and the linked `node_modules`
|
|
40
|
+
read-only and the network absent (the codex `workspace-write` sandbox does
|
|
41
|
+
this; see plegma#311). Run Vitest as
|
|
42
|
+
`node_modules/.bin/vitest run <files> --configLoader runner`, and if the
|
|
43
|
+
tree-sitter grammar prefetch hangs offline, verify through direct probes of the
|
|
44
|
+
built code and say so; the orchestrator re-runs the files outside the sandbox.
|
|
34
45
|
|
|
35
46
|
When Git authority is granted, use one logical commit with an imperative,
|
|
36
47
|
conventional-prefix subject of at most 50 characters, a blank line, and a
|
|
@@ -11,10 +11,11 @@ Every child process the runner spawns — `pi`, the MCP server, `node`, `npm`
|
|
|
11
11
|
runs under a pinned environment: `HOME`, `USERPROFILE`, `PI_LENS_HOME`,
|
|
12
12
|
`PILENS_DATA_DIR`, `PI_LENS_INSTALL_LOG` and `npm_config_cache` all inside the
|
|
13
13
|
scratch root. `PI_LENS_INSTALL_LOG` is on that list by hard experience: it is
|
|
14
|
-
what `scripts/warm-loader-cache.mjs` keys its install log on,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
what `scripts/warm-loader-cache.mjs` keys its install log on, with
|
|
15
|
+
`PI_LENS_HOME/install.log` as the fallback when it is unset, and the runner's
|
|
16
|
+
first six runs — which pinned the pi-lens home but passed no environment to
|
|
17
|
+
`npm` at all — put 41 records into the maintainer's real
|
|
18
|
+
`~/.pi-lens/install.log` (#2619 review F1). The pack runs in a
|
|
18
19
|
`git archive HEAD` export, never the live checkout, because `npm pack` fires our
|
|
19
20
|
own `prepack` (rewrites `package.json` + `package-lock.json`) and `prepare`
|
|
20
21
|
(rebuilds `dist/`, downloads grammars, reinstalls git hooks).
|
|
@@ -61,6 +62,13 @@ arithmetic.
|
|
|
61
62
|
| `mcp-stdio` | an MCP client speaking JSON-RPC to `dist/mcp/server.js` |
|
|
62
63
|
| `git-install` | `pi install git:...` against a pushed ref |
|
|
63
64
|
|
|
65
|
+
Static packaging shape under `npm-pack` is NOT a matrix row: CI's
|
|
66
|
+
`ci.yml` `prod-install-build` job already runs `publint` (gating) on every
|
|
67
|
+
PR's packed tarball (#2700, the check #2587 was missing). `attw`
|
|
68
|
+
(arethetypeswrong) is not run there or here — the package ships no
|
|
69
|
+
`.d.ts` at all (`tsconfig.dist.json` sets `"declaration": false`, no
|
|
70
|
+
`types`/`exports` in `package.json`), so there is nothing for it to grade.
|
|
71
|
+
|
|
64
72
|
## The matrix
|
|
65
73
|
|
|
66
74
|
| row id | feature | modality | entry point | pass criterion | witness | reuse | umbrella |
|
|
@@ -6,7 +6,7 @@ server's `initialize` handshake. Generated by `node scripts/server-capabilities.
|
|
|
6
6
|
absent on the generating host are listed under *Unavailable* — run in a
|
|
7
7
|
provisioned environment (the nightly) to capture those rows.
|
|
8
8
|
|
|
9
|
-
_Last generated: 2026-08
|
|
9
|
+
_Last generated: 2026-09-08 on linux; 30 servers captured, 18 unavailable._
|
|
10
10
|
|
|
11
11
|
## Diagnostic mode + navigation/edit operations
|
|
12
12
|
|
|
@@ -60,7 +60,7 @@ Legend: ✓ advertised, · not. **mode** = document diagnostics (`pull` = `textD
|
|
|
60
60
|
- **deno**: callHierarchyProvider, codeActionProvider, codeLensProvider, completionProvider, definitionProvider, diagnosticProvider, documentFormattingProvider, documentHighlightProvider, documentSymbolProvider, executeCommandProvider, experimental, foldingRangeProvider, hoverProvider, implementationProvider, inlayHintProvider, notebookDocumentSync, referencesProvider, renameProvider, selectionRangeProvider, semanticTokensProvider, signatureHelpProvider, textDocumentSync, typeDefinitionProvider, workspace, workspaceSymbolProvider
|
|
61
61
|
- **docker**: codeActionProvider, completionProvider, definitionProvider, documentFormattingProvider, documentHighlightProvider, documentLinkProvider, documentOnTypeFormattingProvider, documentRangeFormattingProvider, documentSymbolProvider, foldingRangeProvider, hoverProvider, renameProvider, signatureHelpProvider, textDocumentSync
|
|
62
62
|
- **expert**: codeActionProvider, codeLensProvider, completionProvider, definitionProvider, documentFormattingProvider, documentSymbolProvider, executeCommandProvider, experimental, hoverProvider, referencesProvider, textDocumentSync, workspace, workspaceSymbolProvider
|
|
63
|
-
- **fsharp**: callHierarchyProvider, codeActionProvider, codeLensProvider, completionProvider, definitionProvider, documentFormattingProvider, documentHighlightProvider, documentRangeFormattingProvider, documentSymbolProvider, foldingRangeProvider, hoverProvider, implementationProvider, inlayHintProvider,
|
|
63
|
+
- **fsharp**: callHierarchyProvider, codeActionProvider, codeLensProvider, completionProvider, definitionProvider, documentFormattingProvider, documentHighlightProvider, documentRangeFormattingProvider, documentSymbolProvider, foldingRangeProvider, hoverProvider, implementationProvider, inlayHintProvider, referencesProvider, renameProvider, selectionRangeProvider, semanticTokensProvider, signatureHelpProvider, textDocumentSync, typeDefinitionProvider, workspaceSymbolProvider
|
|
64
64
|
- **gleam**: codeActionProvider, completionProvider, definitionProvider, documentFormattingProvider, documentHighlightProvider, documentSymbolProvider, foldingRangeProvider, hoverProvider, referencesProvider, renameProvider, signatureHelpProvider, textDocumentSync, typeDefinitionProvider, workspace
|
|
65
65
|
- **go**: callHierarchyProvider, codeActionProvider, codeLensProvider, completionProvider, definitionProvider, documentFormattingProvider, documentHighlightProvider, documentLinkProvider, documentSymbolProvider, executeCommandProvider, experimental, foldingRangeProvider, hoverProvider, implementationProvider, inlayHintProvider, referencesProvider, renameProvider, selectionRangeProvider, semanticTokensProvider, signatureHelpProvider, textDocumentSync, typeDefinitionProvider, typeHierarchyProvider, workspace, workspaceSymbolProvider
|
|
66
66
|
- **html**: colorProvider, definitionProvider, diagnosticProvider, documentFormattingProvider, documentHighlightProvider, documentLinkProvider, documentRangeFormattingProvider, documentSymbolProvider, foldingRangeProvider, hoverProvider, linkedEditingRangeProvider, referencesProvider, renameProvider, selectionRangeProvider, signatureHelpProvider, textDocumentSync
|
|
@@ -109,12 +109,12 @@ Toolchain/binary not installed here, so capabilities weren't captured
|
|
|
109
109
|
(many are the toolchain-gated family tracked in #241):
|
|
110
110
|
|
|
111
111
|
- @prisma/language-server
|
|
112
|
+
- @vue/language-server
|
|
112
113
|
- PowerShell Editor Services (pwsh Start-EditorServices.ps1 -Stdio)
|
|
113
114
|
- clangd
|
|
114
115
|
- cmake-language-server
|
|
115
116
|
- fish-lsp
|
|
116
117
|
- haskell-language-server
|
|
117
|
-
- intelephense
|
|
118
118
|
- jdtls
|
|
119
119
|
- jdtls + lombok javaagent
|
|
120
120
|
- kotlin-language-server
|
|
@@ -122,3 +122,7 @@ Toolchain/binary not installed here, so capabilities weren't captured
|
|
|
122
122
|
- ocamllsp
|
|
123
123
|
- rust-analyzer
|
|
124
124
|
- sourcekit-lsp
|
|
125
|
+
- typescript native (clean file)
|
|
126
|
+
- typescript native (tsc --lsp --stdio, TS7+)
|
|
127
|
+
- typescript-language-server
|
|
128
|
+
- typescript-language-server (clean file)
|
|
@@ -156,7 +156,7 @@ the cwd, falling back to the stateless snapshot read otherwise.
|
|
|
156
156
|
|
|
157
157
|
## Caps and boundaries
|
|
158
158
|
|
|
159
|
-
- **≤6000 files, ≤512KB per file** (
|
|
159
|
+
- **≤6000 files, ≤512KB per file** (the file cap is passed into the walk;
|
|
160
160
|
`WORD_INDEX_MAX_BYTES` in `clients/word-index.ts`) — shared by every
|
|
161
161
|
build path and the per-edit update path alike.
|
|
162
162
|
- **Deletions aren't plumbed at the per-edit seam** — the cascade only ever
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-lens",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo",
|
|
6
6
|
"repository": {
|
|
@@ -21,10 +21,12 @@
|
|
|
21
21
|
"prepack": "node scripts/strip-dev-deps-for-pack.mjs --strip",
|
|
22
22
|
"postpack": "node scripts/strip-dev-deps-for-pack.mjs --restore",
|
|
23
23
|
"lint": "tsc --project tsconfig.json && npm run lint:js",
|
|
24
|
-
"lint:js": "oxlint --deny-warnings --ignore-pattern \"tests/**/*.ts\" --ignore-pattern \"tests/**/*.tsx\" --ignore-pattern \"**/*.d.mts\" --ignore-pattern \"tests/fixtures/autofix-smoke/**\" --ignore-pattern \"tests/fixtures/format-smoke/**\" --ignore-pattern \"tests/fixtures/tool-smoke/**\" --ignore-pattern \"tests/fixtures/call-graph/javascript/**\" --ignore-pattern \"tests/fixtures/function-facts/javascript-parameter.js\" .",
|
|
24
|
+
"lint:js": "oxlint --deny-warnings --import-plugin --promise-plugin -D block-scoped-var -D import/default -D import/namespace -D import/no-absolute-path -D import/no-empty-named-blocks -D import/no-named-as-default -D import/no-self-import -D no-extend-native -D no-extra-bind -D no-implied-eval -D no-new -D no-unexpected-multiline -D no-useless-constructor -D oxc/approx-constant -D oxc/misrefactored-assign-op -D oxc/no-accumulating-spread -D oxc/no-async-endpoint-handlers -D oxc/no-this-in-exported-function -D promise/no-callback-in-promise -D promise/no-multiple-resolved -D promise/no-new-statics -D promise/valid-params -D typescript/no-confusing-non-null-assertion -D typescript/no-extraneous-class -D typescript/no-unnecessary-type-constraint -D typescript/no-unsafe-enum-comparison -D unicorn/no-accessor-recursion -D unicorn/no-array-fill-with-reference-type -D unicorn/no-confusing-array-with -D unicorn/no-instanceof-builtins -D unicorn/prefer-array-flat-map -D unicorn/require-module-specifiers --ignore-pattern \"tests/**/*.ts\" --ignore-pattern \"tests/**/*.tsx\" --ignore-pattern \"**/*.d.mts\" --ignore-pattern \"tests/fixtures/autofix-smoke/**\" --ignore-pattern \"tests/fixtures/format-smoke/**\" --ignore-pattern \"tests/fixtures/tool-smoke/**\" --ignore-pattern \"tests/fixtures/call-graph/javascript/**\" --ignore-pattern \"tests/fixtures/function-facts/javascript-parameter.js\" .",
|
|
25
|
+
"lint:js:advisory": "node scripts/lint-js-advisory.mjs --deny-warnings --format default -D correctness -D suspicious -D perf --import-plugin --promise-plugin --type-aware -A no-underscore-dangle -A no-await-in-loop -A unicorn/no-array-sort -A unicorn/consistent-function-scoping -A promise/no-promise-in-callback -A no-useless-call -A import/no-unassigned-import -A no-unmodified-loop-condition --ignore-pattern \"**/*.d.mts\" --ignore-pattern \"tests/fixtures/autofix-smoke/**\" --ignore-pattern \"tests/fixtures/format-smoke/**\" --ignore-pattern \"tests/fixtures/tool-smoke/**\" --ignore-pattern \"tests/fixtures/call-graph/javascript/**\" --ignore-pattern \"tests/fixtures/function-facts/javascript-parameter.js\" .",
|
|
25
26
|
"depcruise:check": "depcruise --validate --config .dependency-cruiser.cjs --ignore-known .dependency-cruiser-known-violations.json --output-type err index.ts \"clients/**/*.ts\"",
|
|
26
27
|
"fmt": "oxfmt",
|
|
27
28
|
"fmt:check": "oxfmt --check",
|
|
29
|
+
"taplo": "taplo check $(git ls-files '*.toml' ':!tests/fixtures/**') && taplo fmt --check $(git ls-files '*.toml' ':!tests/fixtures/**' ':!config/ruff/core.toml') # taplo 0.7.0 panics on this file's comments; lint it above",
|
|
28
30
|
"watch": "tsc --watch",
|
|
29
31
|
"test": "node scripts/with-test-lock.mjs -- vitest run",
|
|
30
32
|
"test:unit": "node scripts/with-test-lock.mjs -- vitest run",
|
|
@@ -35,6 +37,7 @@
|
|
|
35
37
|
"check": "node scripts/check-extensions.mjs",
|
|
36
38
|
"selftest:install": "node scripts/install-selftest.mjs",
|
|
37
39
|
"check:lockfile": "node scripts/check-lockfile-sync.mjs",
|
|
40
|
+
"knip": "node scripts/run-knip.mjs",
|
|
38
41
|
"check:grammars": "node scripts/check-grammar-provenance.mjs",
|
|
39
42
|
"check:grammar-load": "node scripts/check-grammar-load.mjs",
|
|
40
43
|
"audit:tree-sitter": "node scripts/audit-tree-sitter-rules.mjs",
|
|
@@ -138,20 +141,8 @@
|
|
|
138
141
|
"./skills"
|
|
139
142
|
]
|
|
140
143
|
},
|
|
141
|
-
"knip": {
|
|
142
|
-
"entry": [
|
|
143
|
-
"index.ts"
|
|
144
|
-
],
|
|
145
|
-
"project": [
|
|
146
|
-
"**/*.ts",
|
|
147
|
-
"!**/*.test.ts"
|
|
148
|
-
],
|
|
149
|
-
"ignore": [
|
|
150
|
-
"**/*.test.ts"
|
|
151
|
-
]
|
|
152
|
-
},
|
|
153
144
|
"allowScripts": {
|
|
154
|
-
"@ast-grep/cli@0.45.
|
|
145
|
+
"@ast-grep/cli@0.45.3": true,
|
|
155
146
|
"@google/genai@1.52.0": true,
|
|
156
147
|
"protobufjs@7.6.5": true
|
|
157
148
|
}
|
|
@@ -13,5 +13,7 @@
|
|
|
13
13
|
# dictionary here; every entry must have a provenance comment.
|
|
14
14
|
|
|
15
15
|
[default.extend-identifiers]
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
# #967 — real model/vendor namespace (provider-failover normalization prefix), not a misspelling of "ditto"
|
|
17
|
+
dito = "dito"
|
|
18
|
+
# #967 — valid English spelling ("un-parseable"), not a typo of "unparsable"
|
|
19
|
+
unparseable = "unparseable"
|
|
@@ -54,7 +54,7 @@ import * as path from "node:path";
|
|
|
54
54
|
* @param {import("node:fs").Dirent} entry
|
|
55
55
|
* @returns {"file" | "dir" | "other"}
|
|
56
56
|
*/
|
|
57
|
-
|
|
57
|
+
function resolvedEntryKind(fullPath, entry) {
|
|
58
58
|
if (entry.isSymbolicLink()) {
|
|
59
59
|
try {
|
|
60
60
|
const stats = fs.statSync(fullPath);
|
|
@@ -281,5 +281,5 @@ export function appendBounded(
|
|
|
281
281
|
return lines.slice(Math.max(0, lines.length - max));
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
-
/** Cap for `~/.pi-lens
|
|
284
|
+
/** Cap for the install log under `PI_LENS_HOME` or `~/.pi-lens`. */
|
|
285
285
|
export const INSTALL_LOG_MAX_LINES = 100;
|
|
@@ -44,7 +44,8 @@ function log(message) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* Append one JSONL record to
|
|
47
|
+
* Append one JSONL record to PI_LENS_INSTALL_LOG, or install.log under
|
|
48
|
+
* PI_LENS_HOME (falling back to ~/.pi-lens when neither is set).
|
|
48
49
|
*
|
|
49
50
|
* pi's install output scrolls away, so without this there is no record that the
|
|
50
51
|
* warm ran, was skipped, or failed. One bounded line per install keeps the
|
|
@@ -54,10 +55,11 @@ function log(message) {
|
|
|
54
55
|
function record(entry) {
|
|
55
56
|
try {
|
|
56
57
|
const override = process.env.PI_LENS_INSTALL_LOG;
|
|
58
|
+
const home = process.env.PI_LENS_HOME?.trim();
|
|
57
59
|
const file =
|
|
58
60
|
typeof override === "string" && override.length > 0
|
|
59
61
|
? override
|
|
60
|
-
: path.join(os.homedir(), ".pi-lens", "install.log");
|
|
62
|
+
: path.join(home || path.join(os.homedir(), ".pi-lens"), "install.log");
|
|
61
63
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
62
64
|
const existing = fs.existsSync(file)
|
|
63
65
|
? fs.readFileSync(file, "utf8").split("\n")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herbertgao/pi-extensions",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.2",
|
|
4
4
|
"description": "Aggregate installer for HerbertGao-maintained Pi extensions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"extensions",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
57
57
|
"@mozilla/readability": "^0.6.0",
|
|
58
58
|
"@napi-rs/keyring": "^1.3.0",
|
|
59
|
-
"@narumitw/pi-btw": "0.
|
|
59
|
+
"@narumitw/pi-btw": "0.58.0",
|
|
60
60
|
"@narumitw/pi-caffeinate": "0.49.7",
|
|
61
61
|
"@narumitw/pi-tui-kit": "^0.59.0",
|
|
62
62
|
"@noble/ed25519": "^3.1.0",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"open": "^10.2.0",
|
|
91
91
|
"p-limit": "^6.1.0",
|
|
92
92
|
"pi-footer": "0.5.1",
|
|
93
|
-
"pi-lens": "4.1.
|
|
93
|
+
"pi-lens": "4.1.5",
|
|
94
94
|
"pi-mcp-adapter": "2.32.1",
|
|
95
95
|
"pi-web-access": "0.28.0",
|
|
96
96
|
"pidusage": "^4.0.1",
|