carrick 0.3.56 → 0.3.58

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/README.md CHANGED
@@ -57,6 +57,29 @@ for the machine-readable shape, pinned in
57
57
  - **Anything else**: `carrick check <file>` on demand, and the pull request
58
58
  check in CI.
59
59
 
60
+ ## In your editor
61
+
62
+ Go to definition on a call to another service jumps to the handler that serves
63
+ it, in the other repo. On a route it lists the call sites that reach it, and
64
+ the editor shows the picker. Carrick answers only inside a row the index holds,
65
+ and only when the file on the other side is on this disk, so every other jump
66
+ falls through to TypeScript exactly as it did before.
67
+
68
+ ## Settings
69
+
70
+ One switch per surface. In VS Code they are settings; any other LSP client
71
+ sends the same keys, with the `carrick.` prefix stripped, as
72
+ `initializationOptions`.
73
+
74
+ | Setting | Default | What it turns off |
75
+ |---|---|---|
76
+ | `carrick.binary` | the `carrick` on PATH | — the path to the CLI, not a surface |
77
+ | `carrick.diagnostics` | on | The verdicts in the Problems panel |
78
+ | `carrick.definition` | on | Cross-repo go to definition. Off means Carrick answers nothing and your other definition providers are untouched |
79
+ | `carrick.boundary` | on | The boundary: the status bar item, or the file-level row in a client without one |
80
+
81
+ `CARRICK_CHANNEL=off` in the environment turns off delivery altogether.
82
+
60
83
  ## What a local index holds
61
84
 
62
85
  Deterministic rows: file-based and descriptor routes, class-controller routes,
@@ -0,0 +1,33 @@
1
+ import { type CheckItem, type CheckResult } from "./contract.ts";
2
+ import { type Range } from "./diagnostics.ts";
3
+ /** An LSP `Location`. `Location[]` is the answer shape; `[]` is "no answer". */
4
+ export type Location = {
5
+ uri: string;
6
+ range: Range;
7
+ };
8
+ export type DefinitionOptions = {
9
+ /** Injectable for tests; the real one hits the disk. */
10
+ exists?: (target: string) => boolean;
11
+ };
12
+ /** LSP positions are 0-based; the payload's line and column are 1-based. */
13
+ export type Position = {
14
+ line: number;
15
+ character: number;
16
+ };
17
+ /**
18
+ * True when the position sits in the row's span: on its line, at or right of
19
+ * its anchor column. A row with no line covers nothing, because a row that
20
+ * cannot say where it is cannot claim a position.
21
+ */
22
+ export declare function coversPosition(item: CheckItem, position: Position): boolean;
23
+ /**
24
+ * Every counterpart of every row covering `position`, deduplicated, facts
25
+ * first.
26
+ *
27
+ * Both directions fall out of one rule: a row's counterparts are its other
28
+ * side, so a call jumps to the producer and a route jumps to its consumers,
29
+ * and several locations is a valid answer the editor renders as a picker.
30
+ */
31
+ export declare function definitionsAt(result: CheckResult, position: Position, options?: DefinitionOptions): Location[];
32
+ /** The position out of a `textDocument/definition` request, or null. */
33
+ export declare function positionOf(params: Record<string, unknown> | undefined): Position | null;
@@ -0,0 +1,107 @@
1
+ // Cross-repo go to definition: from a call site to the producer handler in
2
+ // another repo, and from a route to the consumers that call it (carrick#881).
3
+ //
4
+ // This is the one jump nothing else in the editor can make, and the whole risk
5
+ // is answering a question that was not about Carrick. Four rules hold it down,
6
+ // and every one of them is a test in test/definition.test.ts.
7
+ //
8
+ // **Fall through, never hijack.** A position outside every row's span returns
9
+ // nothing at all, so the client's other definition providers answer as they did
10
+ // before Carrick was installed. A row states an anchor, `line` plus `col`, and
11
+ // no end: the span used here therefore runs from the anchor to the end of that
12
+ // line. The anchor column is a fact, so a position left of it is not the row;
13
+ // end of line is the honest upper bound, and taking the whole line instead
14
+ // would claim the `const user =` in front of a call.
15
+ //
16
+ // `col` is a 1-based column the index recorded. Where it counts bytes and the
17
+ // line holds multi-byte text, this span starts a little right of the anchor and
18
+ // the answer is empty rather than wrong, which is the direction to fail in.
19
+ //
20
+ // **Never a guessed path.** A counterpart is `repo` plus `file`, stated
21
+ // absolutely by the payload, and it is offered only when that path exists on
22
+ // this machine. Nothing here searches for a repo by service name or tries the
23
+ // workspace root: a counterpart this machine cannot point at yields no
24
+ // location, not a best-effort one. `resolveCounterpart` in diagnostics.ts is
25
+ // the one place that rule lives.
26
+ //
27
+ // The switch is `carrick.definition`, in surfaces.ts with the other off
28
+ // switches; off means an empty answer here rather than a withdrawn capability.
29
+ //
30
+ // **A candidate may answer, but never alone beside a fact.** A jump was asked
31
+ // for and a wrong one costs a keystroke back, so the model's reading may answer
32
+ // where nothing else does. Where a fact row matches the same position, the
33
+ // fact's locations come first and the candidate's follow.
34
+ //
35
+ // Known deviation from the design record, which says the peek title labels a
36
+ // candidate: LSP's `Location` and `LocationLink` carry no title, and the peek
37
+ // renders the target file and line only. There is nowhere to put the label, so
38
+ // ordering is what is enforced. (Local mode indexes no candidate rows at all
39
+ // today, so this governs future rows rather than current behaviour.)
40
+ import { isCandidate } from "./contract.js";
41
+ import { resolveCounterpart } from "./diagnostics.js";
42
+ import { pathToFileURL } from "node:url";
43
+ /**
44
+ * True when the position sits in the row's span: on its line, at or right of
45
+ * its anchor column. A row with no line covers nothing, because a row that
46
+ * cannot say where it is cannot claim a position.
47
+ */
48
+ export function coversPosition(item, position) {
49
+ if (typeof item.line !== "number")
50
+ return false;
51
+ if (position.line !== item.line - 1)
52
+ return false;
53
+ const startCharacter = Math.max(0, (item.col ?? 1) - 1);
54
+ return position.character >= startCharacter;
55
+ }
56
+ function locationsFor(item, exists) {
57
+ const locations = [];
58
+ for (const counterpart of item.counterparts ?? []) {
59
+ const resolved = resolveCounterpart(counterpart, exists);
60
+ if (!resolved)
61
+ continue;
62
+ const line = Math.max(0, (counterpart.line ?? 1) - 1);
63
+ locations.push({
64
+ uri: pathToFileURL(resolved).toString(),
65
+ // A counterpart states a line and no column, so the range is the start of
66
+ // that line: an editor reveals the line, and a guessed column would only
67
+ // put the cursor in the wrong place.
68
+ range: { start: { line, character: 0 }, end: { line, character: 0 } },
69
+ });
70
+ }
71
+ return locations;
72
+ }
73
+ /**
74
+ * Every counterpart of every row covering `position`, deduplicated, facts
75
+ * first.
76
+ *
77
+ * Both directions fall out of one rule: a row's counterparts are its other
78
+ * side, so a call jumps to the producer and a route jumps to its consumers,
79
+ * and several locations is a valid answer the editor renders as a picker.
80
+ */
81
+ export function definitionsAt(result, position, options = {}) {
82
+ if (result.error)
83
+ return [];
84
+ const covering = (result.items ?? []).filter((item) => coversPosition(item, position));
85
+ const facts = covering.filter((item) => !isCandidate(item));
86
+ const candidates = covering.filter((item) => isCandidate(item));
87
+ const seen = new Set();
88
+ const locations = [];
89
+ for (const item of [...facts, ...candidates]) {
90
+ for (const location of locationsFor(item, options.exists)) {
91
+ const key = `${location.uri}:${location.range.start.line}`;
92
+ if (seen.has(key))
93
+ continue;
94
+ seen.add(key);
95
+ locations.push(location);
96
+ }
97
+ }
98
+ return locations;
99
+ }
100
+ /** The position out of a `textDocument/definition` request, or null. */
101
+ export function positionOf(params) {
102
+ const position = params?.["position"];
103
+ if (typeof position?.line !== "number" || typeof position?.character !== "number")
104
+ return null;
105
+ return { line: position.line, character: position.character };
106
+ }
107
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type CheckItem, type CheckResult, type Counterpart } from "./contract.ts";
2
+ import { type Surfaces } from "./surfaces.ts";
2
3
  export declare const SOURCE = "carrick";
3
4
  export declare const SEVERITY: {
4
5
  readonly error: 1;
@@ -6,6 +7,18 @@ export declare const SEVERITY: {
6
7
  readonly information: 3;
7
8
  readonly hint: 4;
8
9
  };
10
+ /**
11
+ * Findings one file publishes before it says how many are left.
12
+ *
13
+ * The hook's `MAX_ITEM_LINES` is the same idea on the other channel and the two
14
+ * messages are written to read alike. The boundary fallback rides outside this
15
+ * cap: it is a statement about the workspace and not a finding, so a file with
16
+ * ten findings and a boundary publishes eleven rows and only one of them is the
17
+ * overflow row's business.
18
+ */
19
+ export declare const MAX_PER_FILE = 10;
20
+ /** Findings one check publishes across every file it touches. */
21
+ export declare const MAX_PER_CHECK = 30;
9
22
  export type Position = {
10
23
  line: number;
11
24
  character: number;
@@ -28,8 +41,18 @@ export type Diagnostic = {
28
41
  message: string;
29
42
  }>;
30
43
  };
31
- /** An error only for a finding on a fact row that claims something (R1c). */
32
- export declare function severityOf(item: CheckItem): number;
44
+ /** A one-character range at a 1-based line and column, or at 1:1 without them. */
45
+ export declare function rangeAt(line: number | undefined, col: number | undefined): Range;
46
+ /**
47
+ * The severity policy, in one place.
48
+ *
49
+ * Error only for a finding on a fact row that claims something (R1c) and whose
50
+ * claim a reader can go and check. `resolvable` is whether any counterpart of
51
+ * this row is on this disk: a routing finding is entirely a statement about the
52
+ * other side, so when the other side cannot be opened it is a warning. Nothing
53
+ * here ever returns Hint.
54
+ */
55
+ export declare function severityOf(item: CheckItem, resolvable?: boolean): number;
33
56
  export declare function messageOf(item: CheckItem): string;
34
57
  /**
35
58
  * Where a counterpart lands on this disk, or null when it cannot be pointed at.
@@ -38,11 +61,23 @@ export declare function messageOf(item: CheckItem): string;
38
61
  * a reader that also tried the workspace root or a directory named after the
39
62
  * service would be guessing at paths the producer already knows.
40
63
  */
41
- export declare function resolveCounterpart(counterpart: Counterpart, exists?: (target: string) => boolean): string | null;
64
+ export declare function resolveCounterpart(counterpart: Counterpart, exists?: ((target: string) => boolean) | undefined): string | null;
42
65
  export type DiagnosticOptions = {
43
66
  /** Injectable for tests. */
44
67
  exists?: (target: string) => boolean;
68
+ /** The switches the client stated. Every surface is on when it stated none. */
69
+ surfaces?: Surfaces;
45
70
  };
71
+ /**
72
+ * The cap, applied to a whole check.
73
+ *
74
+ * Ten findings per file with an eleventh row naming the remainder, thirty rows
75
+ * across the check with one more naming what the check as a whole did not show,
76
+ * and a file the budget drops publishes an empty list so its previous rows are
77
+ * cleared rather than left standing. The boundary fallback rides outside both
78
+ * counts: it states something about the workspace and is not a finding.
79
+ */
80
+ export declare function capDiagnostics(byFile: Map<string, Diagnostic[]>, checkedAbs: string, checkedFile: string): Map<string, Diagnostic[]>;
46
81
  /**
47
82
  * Diagnostics for one check payload, keyed by the absolute file they belong to.
48
83
  *
@@ -1,6 +1,9 @@
1
- // Check verdicts as LSP diagnostics.
1
+ // Check verdicts as LSP diagnostics, inside a noise budget.
2
2
  //
3
- // Four rules decide what a diagnostic looks like here.
3
+ // The budget is carrick#879 and the design record of 2026-09-09 ("The noise
4
+ // budget for the whole surface"). A finding a user turns off is worth less than
5
+ // no finding at all, because turning it off takes every later finding with it,
6
+ // so what this file publishes is bounded before it is interesting.
4
7
  //
5
8
  // R1: a finding on a fact row is an error; the same finding on a candidate row
6
9
  // is a warning that says it is the model's reading. `verdict.state` is the type
@@ -10,15 +13,30 @@
10
13
  // every routing finding. A state of `unresolved` is the exception: nothing was
11
14
  // claimed there, so nothing is asserted here either.
12
15
  //
16
+ // SEVERITY POLICY, stated once and only here (severityOf). Error is for a fact
17
+ // row whose verdict claims something and is not compatible. Warning is for
18
+ // candidates, for `unresolved`, and for a routing finding with no counterpart
19
+ // this machine can open: an error nobody can navigate to asserts more than the
20
+ // payload supports. Information is not used per file at all, except as the
21
+ // boundary fallback below. Hint is never used anywhere: it renders as a faint
22
+ // underline to a human and as nothing at all to an agent, which buys presence
23
+ // without buying attention.
24
+ //
13
25
  // E18: Claude Code drops `relatedInformation` from the attachment it gives the
14
26
  // model, and editors render it as clickable locations. So every counterpart
15
27
  // site goes in BOTH: in the message text for the agent, and in
16
28
  // `relatedInformation` for the human.
17
29
  //
18
- // The boundary is never dropped. The local index holds no bare-receiver route
19
- // and no `fetch` call, because both need a model, so a file with no findings is
20
- // not a file with no contracts. One information diagnostic carries the boundary
21
- // on every checked file that has one.
30
+ // THE BOUNDARY IS NEVER DROPPED, and after carrick#879 it is not always in the
31
+ // Problems list. The local index holds no bare-receiver route and no `fetch`
32
+ // call, because both need a model, so a file with no findings is not a file
33
+ // with no contracts. It belongs to the workspace rather than to a file, so a
34
+ // client that has somewhere workspace-shaped to put it says so with
35
+ // `boundarySurface` (the VS Code status bar item does) and gets no per-file
36
+ // row; a client that says nothing keeps the file-level Information diagnostic,
37
+ // which `carrick.boundary` turns off. The hook channel and `carrick check` are
38
+ // untouched by any of this: render.ts states the boundary there whatever a
39
+ // client said, which is what the agent reads.
22
40
  //
23
41
  // A counterpart's `file` is relative to its OWN repo, and the payload names
24
42
  // that repo absolutely, so `repo` + `file` is the path and nothing is guessed.
@@ -30,9 +48,23 @@ import path from "node:path";
30
48
  import { pathToFileURL } from "node:url";
31
49
  import { isCandidate, problemItems, } from "./contract.js";
32
50
  import { boundaryFor, stateWord } from "./render.js";
51
+ import { DEFAULT_SURFACES } from "./surfaces.js";
33
52
  export const SOURCE = "carrick";
34
53
  export const SEVERITY = { error: 1, warning: 2, information: 3, hint: 4 };
35
- function rangeAt(line, col) {
54
+ /**
55
+ * Findings one file publishes before it says how many are left.
56
+ *
57
+ * The hook's `MAX_ITEM_LINES` is the same idea on the other channel and the two
58
+ * messages are written to read alike. The boundary fallback rides outside this
59
+ * cap: it is a statement about the workspace and not a finding, so a file with
60
+ * ten findings and a boundary publishes eleven rows and only one of them is the
61
+ * overflow row's business.
62
+ */
63
+ export const MAX_PER_FILE = 10;
64
+ /** Findings one check publishes across every file it touches. */
65
+ export const MAX_PER_CHECK = 30;
66
+ /** A one-character range at a 1-based line and column, or at 1:1 without them. */
67
+ export function rangeAt(line, col) {
36
68
  const zeroLine = Math.max(0, (line ?? 1) - 1);
37
69
  const zeroCol = Math.max(0, (col ?? 1) - 1);
38
70
  return {
@@ -40,14 +72,35 @@ function rangeAt(line, col) {
40
72
  end: { line: zeroLine, character: zeroCol + 1 },
41
73
  };
42
74
  }
43
- /** An error only for a finding on a fact row that claims something (R1c). */
44
- export function severityOf(item) {
75
+ /**
76
+ * A routing finding: a result with no type verdict behind it.
77
+ *
78
+ * `method_mismatch` and `producer_removed` are read off two deterministic rows
79
+ * and carry `not_checked` because no type verdict bears on them. They are the
80
+ * findings whose whole claim is about the other side of a call.
81
+ */
82
+ function isRoutingFinding(item) {
83
+ const verdict = item.verdict;
84
+ return Boolean(verdict && verdict.result != null && verdict.state === "not_checked");
85
+ }
86
+ /**
87
+ * The severity policy, in one place.
88
+ *
89
+ * Error only for a finding on a fact row that claims something (R1c) and whose
90
+ * claim a reader can go and check. `resolvable` is whether any counterpart of
91
+ * this row is on this disk: a routing finding is entirely a statement about the
92
+ * other side, so when the other side cannot be opened it is a warning. Nothing
93
+ * here ever returns Hint.
94
+ */
95
+ export function severityOf(item, resolvable = true) {
45
96
  if (isCandidate(item))
46
97
  return SEVERITY.warning;
47
98
  if (item.source !== "fact")
48
99
  return SEVERITY.warning;
49
100
  if (item.verdict?.state === "unresolved")
50
101
  return SEVERITY.warning;
102
+ if (isRoutingFinding(item) && !resolvable)
103
+ return SEVERITY.warning;
51
104
  return SEVERITY.error;
52
105
  }
53
106
  /** `consumer in admin-ui`, and for a peer the role word is left out. */
@@ -102,6 +155,8 @@ function defaultExists(target) {
102
155
  * service would be guessing at paths the producer already knows.
103
156
  */
104
157
  export function resolveCounterpart(counterpart, exists = defaultExists) {
158
+ if (!exists)
159
+ exists = defaultExists;
105
160
  if (!counterpart.file)
106
161
  return null;
107
162
  if (path.isAbsolute(counterpart.file))
@@ -111,6 +166,113 @@ export function resolveCounterpart(counterpart, exists = defaultExists) {
111
166
  const target = path.resolve(counterpart.repo, counterpart.file);
112
167
  return exists(target) ? target : null;
113
168
  }
169
+ /**
170
+ * A finding's counterparts grouped by the file they land in.
171
+ *
172
+ * Two call sites in one consumer file are one finding in one file, so they are
173
+ * one mirrored row naming both lines rather than two rows saying the same
174
+ * sentence. Order follows the payload, so the row lands on the first site.
175
+ */
176
+ function groupCounterparts(counterparts, exists) {
177
+ const groups = [];
178
+ const byTarget = new Map();
179
+ for (const counterpart of counterparts) {
180
+ const target = resolveCounterpart(counterpart, exists);
181
+ if (!target)
182
+ continue;
183
+ const existing = byTarget.get(target);
184
+ if (existing) {
185
+ existing.sites.push(counterpart);
186
+ continue;
187
+ }
188
+ const group = { target, sites: [counterpart] };
189
+ byTarget.set(target, group);
190
+ groups.push(group);
191
+ }
192
+ return groups;
193
+ }
194
+ /** The eleventh row: what was not shown, and the command that shows it. */
195
+ function overflowRow(hidden, where, checkedFile) {
196
+ return {
197
+ range: rangeAt(1, 1),
198
+ severity: SEVERITY.warning,
199
+ code: "capped",
200
+ source: SOURCE,
201
+ message: `and ${hidden} more finding(s) ${where}, from \`carrick check ${checkedFile}\`.`,
202
+ };
203
+ }
204
+ const isBoundaryRow = (diagnostic) => diagnostic.code === "boundary";
205
+ /**
206
+ * Findings first and then by line, which is the order the cap keeps.
207
+ *
208
+ * "Problems first" is severity order: when ten of forty rows survive, the ten
209
+ * that survive are the ones that claim the most.
210
+ */
211
+ function orderRows(rows) {
212
+ return [...rows].sort((a, b) => a.severity - b.severity || a.range.start.line - b.range.start.line);
213
+ }
214
+ /**
215
+ * The cap, applied to a whole check.
216
+ *
217
+ * Ten findings per file with an eleventh row naming the remainder, thirty rows
218
+ * across the check with one more naming what the check as a whole did not show,
219
+ * and a file the budget drops publishes an empty list so its previous rows are
220
+ * cleared rather than left standing. The boundary fallback rides outside both
221
+ * counts: it states something about the workspace and is not a finding.
222
+ */
223
+ export function capDiagnostics(byFile, checkedAbs, checkedFile) {
224
+ const order = [
225
+ ...(byFile.has(checkedAbs) ? [checkedAbs] : []),
226
+ ...[...byFile.keys()].filter((file) => file !== checkedAbs).sort(),
227
+ ];
228
+ const staged = order.map((file) => {
229
+ const rows = byFile.get(file) ?? [];
230
+ const findings = orderRows(rows.filter((row) => !isBoundaryRow(row)));
231
+ return {
232
+ file,
233
+ shown: findings.slice(0, MAX_PER_FILE),
234
+ hidden: Math.max(0, findings.length - MAX_PER_FILE),
235
+ boundary: rows.filter(isBoundaryRow),
236
+ };
237
+ });
238
+ // Whether the check as a whole overflows is decided before the walk, so the
239
+ // row that says so has a slot reserved and the thirty is never exceeded.
240
+ const wanted = staged.reduce((total, file) => total + file.shown.length + (file.hidden ? 1 : 0), 0);
241
+ const overflows = wanted > MAX_PER_CHECK;
242
+ let budget = overflows ? MAX_PER_CHECK - 1 : MAX_PER_CHECK;
243
+ const capped = new Map();
244
+ let unstated = 0;
245
+ for (const file of staged) {
246
+ const take = Math.max(0, Math.min(file.shown.length, budget));
247
+ const rows = file.shown.slice(0, take);
248
+ budget -= take;
249
+ unstated += file.shown.length - take;
250
+ if (file.hidden > 0) {
251
+ if (budget > 0 && take === file.shown.length) {
252
+ rows.push(overflowRow(file.hidden, "in this file", checkedFile));
253
+ budget -= 1;
254
+ }
255
+ else {
256
+ unstated += file.hidden;
257
+ }
258
+ }
259
+ capped.set(file.file, rows);
260
+ }
261
+ if (unstated > 0) {
262
+ const rows = capped.get(checkedAbs) ?? [];
263
+ rows.push(overflowRow(unstated, "elsewhere in this check", checkedFile));
264
+ capped.set(checkedAbs, rows);
265
+ }
266
+ // The boundary is appended last, after every overflow row, because it is the
267
+ // line that makes a short answer readable and the hook renders it last for
268
+ // the same reason. Both channels read alike.
269
+ for (const file of staged) {
270
+ if (!file.boundary.length)
271
+ continue;
272
+ capped.get(file.file)?.push(...file.boundary);
273
+ }
274
+ return capped;
275
+ }
114
276
  /**
115
277
  * Diagnostics for one check payload, keyed by the absolute file they belong to.
116
278
  *
@@ -121,6 +283,7 @@ export function resolveCounterpart(counterpart, exists = defaultExists) {
121
283
  */
122
284
  export function toDiagnostics(result, root, checkedFile, options = {}) {
123
285
  const exists = options.exists ?? defaultExists;
286
+ const surfaces = options.surfaces ?? DEFAULT_SURFACES;
124
287
  const byFile = new Map();
125
288
  if (result.error)
126
289
  return byFile;
@@ -136,56 +299,72 @@ export function toDiagnostics(result, root, checkedFile, options = {}) {
136
299
  else
137
300
  byFile.set(file, [diagnostic]);
138
301
  };
139
- for (const item of problemItems(result)) {
140
- const counterparts = item.counterparts ?? [];
141
- const related = counterparts
142
- .map((counterpart) => ({ counterpart, resolved: resolveCounterpart(counterpart, exists) }))
143
- .filter((entry) => entry.resolved !== null)
144
- .map((entry) => ({
145
- location: {
146
- uri: pathToFileURL(entry.resolved).toString(),
147
- range: rangeAt(entry.counterpart.line, 1),
148
- },
149
- message: counterpartPhrase(entry.counterpart),
150
- }));
151
- const diagnostic = {
152
- range: rangeAt(item.line, item.col),
153
- severity: severityOf(item),
154
- source: SOURCE,
155
- message: messageOf(item),
156
- };
157
- if (item.verdict?.result)
158
- diagnostic.code = item.verdict.result;
159
- if (related.length)
160
- diagnostic.relatedInformation = related;
161
- put(checkedAbs, diagnostic);
162
- for (const counterpart of counterparts) {
163
- const resolved = resolveCounterpart(counterpart, exists);
164
- if (!resolved)
165
- continue;
166
- const mirrored = {
167
- range: rangeAt(counterpart.line, 1),
168
- severity: severityOf(item),
302
+ if (surfaces.diagnostics) {
303
+ for (const item of problemItems(result)) {
304
+ const groups = groupCounterparts(item.counterparts ?? [], exists);
305
+ // A routing finding whose other side is not on this disk cannot be gone
306
+ // and looked at, so it is stated as a warning rather than asserted.
307
+ const severity = severityOf(item, groups.length > 0);
308
+ const related = groups.flatMap((group) => group.sites.map((counterpart) => ({
309
+ location: {
310
+ uri: pathToFileURL(group.target).toString(),
311
+ range: rangeAt(counterpart.line, 1),
312
+ },
313
+ message: counterpartPhrase(counterpart),
314
+ })));
315
+ const diagnostic = {
316
+ range: rangeAt(item.line, item.col),
317
+ severity,
169
318
  source: SOURCE,
170
- message: `${counterpartPhrase(counterpart)} of ${result.file ?? checkedFile}. ${messageOf(item)}`,
319
+ message: messageOf(item),
171
320
  };
172
321
  if (item.verdict?.result)
173
- mirrored.code = item.verdict.result;
174
- put(resolved, mirrored);
322
+ diagnostic.code = item.verdict.result;
323
+ if (related.length)
324
+ diagnostic.relatedInformation = related;
325
+ put(checkedAbs, diagnostic);
326
+ // 0b: a finding is mirrored onto each counterpart FILE, once, and never
327
+ // below Warning, because a row a reader did not ask for has to be worth
328
+ // the interruption in the file it lands in.
329
+ if (severity > SEVERITY.warning)
330
+ continue;
331
+ for (const group of groups) {
332
+ const [first, ...rest] = group.sites;
333
+ if (!first)
334
+ continue;
335
+ const alsoAt = rest
336
+ .map((counterpart) => counterpart.line)
337
+ .filter((line) => typeof line === "number");
338
+ const also = alsoAt.length ? ` Also at line ${alsoAt.join(", ")} in this file.` : "";
339
+ const mirrored = {
340
+ range: rangeAt(first.line, 1),
341
+ severity,
342
+ source: SOURCE,
343
+ message: `${counterpartPhrase(first)} of ${result.file ?? checkedFile}.${also} ${messageOf(item)}`,
344
+ };
345
+ if (item.verdict?.result)
346
+ mirrored.code = item.verdict.result;
347
+ put(group.target, mirrored);
348
+ }
349
+ }
350
+ if (result.deleted) {
351
+ const consumers = (result.items ?? []).reduce((total, item) => total + (item.counterparts ?? []).length, 0);
352
+ put(checkedAbs, {
353
+ range: rangeAt(1, 1),
354
+ severity: SEVERITY.warning,
355
+ code: "producer_removed",
356
+ source: SOURCE,
357
+ message: `producer_removed: the index holds ${(result.items ?? []).length} row(s) for this file and it is no longer on disk. ${consumers} counterpart(s) still name it.`,
358
+ });
175
359
  }
176
360
  }
177
- if (result.deleted) {
178
- const consumers = (result.items ?? []).reduce((total, item) => total + (item.counterparts ?? []).length, 0);
179
- put(checkedAbs, {
180
- range: rangeAt(1, 1),
181
- severity: SEVERITY.warning,
182
- code: "producer_removed",
183
- source: SOURCE,
184
- message: `producer_removed: the index holds ${(result.items ?? []).length} row(s) for this file and it is no longer on disk. ${consumers} counterpart(s) still name it.`,
185
- });
186
- }
361
+ // The fallback, and only the fallback: a client that told us it has a
362
+ // workspace surface for the boundary (the VS Code status bar) is not sent a
363
+ // per-file row for it. Nothing here decides whether the boundary is stated,
364
+ // only whether it is stated HERE; render.ts states it on the agent channel
365
+ // either way.
187
366
  const boundary = boundaryFor(result);
188
- if (boundary.length) {
367
+ if (boundary.length && surfaces.boundary && !surfaces.boundarySurface) {
189
368
  put(checkedAbs, {
190
369
  range: rangeAt(1, 1),
191
370
  severity: SEVERITY.information,
@@ -194,6 +373,6 @@ export function toDiagnostics(result, root, checkedFile, options = {}) {
194
373
  message: `What this service's scan could not classify:\n${boundary.join("\n")}`,
195
374
  });
196
375
  }
197
- return byFile;
376
+ return capDiagnostics(byFile, checkedAbs, checkedFile);
198
377
  }
199
378
  //# sourceMappingURL=diagnostics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,4EAA4E;AAC5E,gFAAgF;AAChF,+EAA+E;AAC/E,mEAAmE;AACnE,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,sEAAsE;AACtE,+EAA+E;AAC/E,6EAA6E;AAC7E,+EAA+E;AAC/E,qDAAqD;AACrD,EAAE;AACF,+EAA+E;AAC/E,2EAA2E;AAC3E,8EAA8E;AAC9E,+EAA+E;AAC/E,2EAA2E;AAC3E,8EAA8E;AAC9E,8EAA8E;AAC9E,4BAA4B;AAC5B,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,+DAA+D;AAC/D,sCAAsC;AACtC,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,oEAAoE;AACpE,4EAA4E;AAC5E,+EAA+E;AAC/E,+EAA+E;AAC/E,2EAA2E;AAC3E,8CAA8C;AAC9C,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,6EAA6E;AAC7E,gFAAgF;AAChF,sEAAsE;AAEtE,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,WAAW,EACX,YAAY,GAIb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAiB,MAAM,eAAe,CAAC;AAEhE,MAAM,CAAC,MAAM,MAAM,GAAG,SAAS,CAAC;AAEhC,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAEnF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAC/B,iEAAiE;AACjE,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAiBhC,kFAAkF;AAClF,MAAM,UAAU,OAAO,CAAC,IAAwB,EAAE,GAAuB;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,OAAO;QACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE;QAC7C,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,GAAG,CAAC,EAAE;KAChD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,IAAe;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7B,OAAO,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC;AACvF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,IAAe,EAAE,UAAU,GAAG,IAAI;IAC3D,IAAI,WAAW,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC,OAAO,CAAC;IAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,QAAQ,CAAC,OAAO,CAAC;IACpD,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,KAAK,YAAY;QAAE,OAAO,QAAQ,CAAC,OAAO,CAAC;IAClE,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU;QAAE,OAAO,QAAQ,CAAC,OAAO,CAAC;IACnE,OAAO,QAAQ,CAAC,KAAK,CAAC;AACxB,CAAC;AAED,wEAAwE;AACxE,SAAS,iBAAiB,CAAC,WAAwB;IACjD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,IAAI,oBAAoB,CAAC;IAC5D,OAAO,WAAW,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,IAAI,OAAO,OAAO,EAAE,CAAC;AAC/G,CAAC;AAED,SAAS,gBAAgB,CAAC,WAAwB;IAChD,OAAO,GAAG,WAAW,CAAC,IAAI,IAAI,iBAAiB,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAe;IACvC,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7B,2EAA2E;IAC3E,mEAAmE;IACnE,MAAM,YAAY,GAAG,OAAO;QAC1B,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI;YACtB,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;YAC1B,CAAC,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU;gBAC5B,CAAC,CAAC,OAAO,CAAC,MAAM;gBAChB,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG;QACvD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,KAAK,GAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAChF,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,6DAA6D,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;IAC7C,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CACR,iBAAiB,YAAY;aAC1B,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,GAAG,iBAAiB,CAAC,WAAW,CAAC,KAAK,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;aAC3F,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,aAAa,CAAC,MAAc;IACnC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAAwB,EACxB,SAAoD,aAAa;IAEjE,IAAI,CAAC,MAAM;QAAE,MAAM,GAAG,aAAa,CAAC;IACpC,IAAI,CAAC,WAAW,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACjG,IAAI,CAAC,WAAW,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAiBD;;;;;;GAMG;AACH,SAAS,iBAAiB,CACxB,YAA2B,EAC3B,MAAmC;IAEnC,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;IACrD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAqB,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;QACjE,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,2EAA2E;AAC3E,SAAS,WAAW,CAAC,MAAc,EAAE,KAAa,EAAE,WAAmB;IACrE,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;QACpB,QAAQ,EAAE,QAAQ,CAAC,OAAO;QAC1B,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,OAAO,MAAM,oBAAoB,KAAK,0BAA0B,WAAW,KAAK;KAC1F,CAAC;AACJ,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,UAAsB,EAAW,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC;AAE1F;;;;;GAKG;AACH,SAAS,SAAS,CAAC,IAAkB;IACnC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACtG,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAiC,EACjC,UAAkB,EAClB,WAAmB;IAEnB,MAAM,KAAK,GAAG;QACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,IAAI,EAAE;KACnE,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtE,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC;YACtC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC;YACnD,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;SACrC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,yEAAyE;IACzE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpG,MAAM,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;IACzC,IAAI,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IAE3D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAiB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACrD,MAAM,IAAI,IAAI,CAAC;QACf,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACrC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,MAAM,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC7C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC;gBACjE,MAAM,IAAI,CAAC,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC;YAC1B,CAAC;QACH,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,yBAAyB,EAAE,WAAW,CAAC,CAAC,CAAC;QACzE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IACD,6EAA6E;IAC7E,2EAA2E;IAC3E,6CAA6C;IAC7C,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,SAAS;QACpC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAmB,EACnB,IAAY,EACZ,WAAmB,EACnB,UAA6B,EAAE;IAE/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,gBAAgB,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAEhC,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,6DAA6D;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,UAAsB,EAAQ,EAAE;QACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,QAAQ;YAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;;YACnC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC;IAEF,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;YAClE,wEAAwE;YACxE,oEAAoE;YACpE,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACvC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;gBAChC,QAAQ,EAAE;oBACR,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;oBAC3C,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;iBACpC;gBACD,OAAO,EAAE,iBAAiB,CAAC,WAAW,CAAC;aACxC,CAAC,CAAC,CACJ,CAAC;YACF,MAAM,UAAU,GAAe;gBAC7B,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;gBACnC,QAAQ;gBACR,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC;aACzB,CAAC;YACF,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM;gBAAE,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAChE,IAAI,OAAO,CAAC,MAAM;gBAAE,UAAU,CAAC,kBAAkB,GAAG,OAAO,CAAC;YAC5D,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAE5B,wEAAwE;YACxE,wEAAwE;YACxE,4CAA4C;YAC5C,IAAI,QAAQ,GAAG,QAAQ,CAAC,OAAO;gBAAE,SAAS;YAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;gBACrC,IAAI,CAAC,KAAK;oBAAE,SAAS;gBACrB,MAAM,MAAM,GAAG,IAAI;qBAChB,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;qBACtC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;gBAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrF,MAAM,QAAQ,GAAe;oBAC3B,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC7B,QAAQ;oBACR,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,IAAI,IAAI,WAAW,IAAI,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE;iBACnG,CAAC;gBACF,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM;oBAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC9D,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAC3C,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,MAAM,EACzD,CAAC,CACF,CAAC;YACF,GAAG,CAAC,UAAU,EAAE;gBACd,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;gBACpB,QAAQ,EAAE,QAAQ,CAAC,OAAO;gBAC1B,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,qCAAqC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,sDAAsD,SAAS,gCAAgC;aACzK,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,cAAc;IACd,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;QACtE,GAAG,CAAC,UAAU,EAAE;YACd,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;YACpB,QAAQ,EAAE,QAAQ,CAAC,WAAW;YAC9B,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,iDAAiD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAChF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AACzD,CAAC"}
package/dist/lens.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ import { type CheckResult } from "./contract.ts";
2
+ import { rangeAt } from "./diagnostics.ts";
3
+ import { type Surfaces } from "./surfaces.ts";
4
+ /** The command a client invokes when a lens is clicked. */
5
+ export declare const SHOW_COUNTERPARTS = "carrick.showCounterparts";
6
+ export type LensCommand = {
7
+ title: string;
8
+ command: string;
9
+ arguments?: unknown[];
10
+ };
11
+ export type CodeLens = {
12
+ range: ReturnType<typeof rangeAt>;
13
+ command?: LensCommand;
14
+ };
15
+ /** What the command is handed: enough to list the other side and open it. */
16
+ export type CounterpartList = {
17
+ /** The row's own operation, e.g. `GET /api/users/:id`. */
18
+ operation: string;
19
+ /** Absolute paths, already checked to exist, one per site. */
20
+ sites: Array<{
21
+ role: string;
22
+ service: string | null;
23
+ /** Absolute; null when the counterpart is not on this disk. */
24
+ path: string | null;
25
+ line: number | null;
26
+ }>;
27
+ /** The service's boundary lines, so an empty list reads correctly. */
28
+ boundary: string[];
29
+ };
30
+ export type LensOptions = {
31
+ /** Injectable for tests. */
32
+ exists?: (target: string) => boolean;
33
+ surfaces?: Surfaces;
34
+ };
35
+ /**
36
+ * One lens per row that the index knows something actionable about.
37
+ *
38
+ * Never one per line of a handler, never one for a row whose line the payload
39
+ * did not state, and never one that would have to say zero.
40
+ */
41
+ export declare function toCodeLenses(result: CheckResult, options?: LensOptions): CodeLens[];
package/dist/lens.js ADDED
@@ -0,0 +1,116 @@
1
+ // Code lenses: the one place a person sees what Carrick knows without asking.
2
+ //
3
+ // carrick#880, and the design record of 2026-09-09, candidate 1. Humans only:
4
+ // an agent cannot invoke a lens, so nothing here reaches the agent channel and
5
+ // the whole of it is judged as an editor surface.
6
+ //
7
+ // ZERO SUPPRESSION is the rule the rest of this file exists to keep. A laptop
8
+ // index holds facts only, so a route with no indexed consumer is the ordinary
9
+ // state and not a finding: a lens reading "0 consumers" would say "nobody calls
10
+ // this" where it means "not indexed here". So a lens is rendered only where the
11
+ // index holds at least one counterpart or one non-compatible verdict for that
12
+ // row, and the boundary answers the question of why the others are bare. The
13
+ // general form of the rule, from the same record: nothing states a number it
14
+ // cannot attribute.
15
+ //
16
+ // A candidate row produces no lens at all. Candidates are the model's reading
17
+ // and cannot reach a laptop index today; when they can, they are counted in a
18
+ // clause of their own and never inside the mismatch count, because the mismatch
19
+ // count is the number a person acts on.
20
+ //
21
+ // The lens command carries the boundary in its arguments rather than in a
22
+ // tooltip: `vscode-languageclient`'s `asCommand` copies title, command and
23
+ // arguments and drops everything else, so a tooltip set here would never reach
24
+ // a VS Code user. The extension shows those lines when the lens is clicked, and
25
+ // the status bar item from carrick#879 is where the boundary lives for a person
26
+ // the rest of the time.
27
+ import { isCandidate, } from "./contract.js";
28
+ import { boundaryFor } from "./render.js";
29
+ import { rangeAt, resolveCounterpart } from "./diagnostics.js";
30
+ import { DEFAULT_SURFACES } from "./surfaces.js";
31
+ /** The command a client invokes when a lens is clicked. */
32
+ export const SHOW_COUNTERPARTS = "carrick.showCounterparts";
33
+ /** A verdict that states a result other than `compatible`, on this one row. */
34
+ function isMismatch(item) {
35
+ const verdict = item.verdict;
36
+ return Boolean(verdict && verdict.result != null && verdict.result !== "compatible");
37
+ }
38
+ /**
39
+ * How many of the other side there are, in the word for what they are.
40
+ *
41
+ * One role gets its own noun; a mixed row gets the neutral one. Nothing here
42
+ * can render a zero: the caller has already decided there is something to say.
43
+ */
44
+ function counterpartClause(counterparts) {
45
+ const roles = new Set(counterparts.map((counterpart) => counterpart.role));
46
+ const count = counterparts.length;
47
+ const plural = count === 1 ? "" : "s";
48
+ if (roles.size === 1 && roles.has("consumer"))
49
+ return `${count} consumer${plural}`;
50
+ if (roles.size === 1 && roles.has("producer"))
51
+ return `${count} producer${plural}`;
52
+ if (roles.size === 1 && roles.has("peer"))
53
+ return `${count} service${plural} on the same contract`;
54
+ return `${count} counterpart${plural}`;
55
+ }
56
+ function operationOf(item) {
57
+ return [item.method, item.path].filter(Boolean).join(" ") || item.kind;
58
+ }
59
+ /**
60
+ * One lens per row that the index knows something actionable about.
61
+ *
62
+ * Never one per line of a handler, never one for a row whose line the payload
63
+ * did not state, and never one that would have to say zero.
64
+ */
65
+ export function toCodeLenses(result, options = {}) {
66
+ const surfaces = options.surfaces ?? DEFAULT_SURFACES;
67
+ if (!surfaces.codeLens)
68
+ return [];
69
+ if (result.error)
70
+ return [];
71
+ const exists = options.exists;
72
+ // `carrick.boundary` off takes the boundary off this surface too, or the
73
+ // switch would only half work.
74
+ const boundary = surfaces.boundary ? boundaryFor(result) : [];
75
+ const lenses = [];
76
+ for (const item of result.items ?? []) {
77
+ // A row the model alone states informs a pull surface and asserts nothing
78
+ // on a pushed one. A lens is rendered without being asked for, so no.
79
+ if (isCandidate(item))
80
+ continue;
81
+ if (typeof item.line !== "number")
82
+ continue;
83
+ const counterparts = item.counterparts ?? [];
84
+ const mismatch = isMismatch(item);
85
+ if (counterparts.length === 0 && !mismatch)
86
+ continue;
87
+ const clauses = [];
88
+ if (counterparts.length > 0)
89
+ clauses.push(counterpartClause(counterparts));
90
+ // One row carries one verdict, so the count is one or none. It is stated as
91
+ // a count anyway, because it is the number a person acts on and the clause
92
+ // has to stay countable when candidates gain one of their own.
93
+ if (mismatch)
94
+ clauses.push("1 mismatch");
95
+ const payload = {
96
+ operation: operationOf(item),
97
+ sites: counterparts.map((counterpart) => ({
98
+ role: counterpart.role,
99
+ service: counterpart.service ?? null,
100
+ path: resolveCounterpart(counterpart, exists),
101
+ line: counterpart.line ?? null,
102
+ })),
103
+ boundary,
104
+ };
105
+ lenses.push({
106
+ range: rangeAt(item.line, item.col),
107
+ command: {
108
+ title: clauses.join(", "),
109
+ command: SHOW_COUNTERPARTS,
110
+ arguments: [payload],
111
+ },
112
+ });
113
+ }
114
+ return lenses;
115
+ }
116
+ //# sourceMappingURL=lens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lens.js","sourceRoot":"","sources":["../src/lens.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -27,13 +27,19 @@ import path from "node:path";
27
27
  import { fileURLToPath, pathToFileURL } from "node:url";
28
28
  import { check } from "./cli.js";
29
29
  import { resolveChannel } from "./channel.js";
30
+ import { definitionsAt, positionOf } from "./definition.js";
30
31
  import { toDiagnostics } from "./diagnostics.js";
32
+ import { toCodeLenses } from "./lens.js";
31
33
  import { createLogger } from "./log.js";
32
34
  import { resolveRoot, rootNote } from "./root.js";
35
+ import { boundaryFor } from "./render.js";
36
+ import { DEFAULT_SURFACES, readSurfaces } from "./surfaces.js";
33
37
  const NAME = "carrick";
34
38
  const VERSION = "0.0.1";
35
39
  /** Editors fire `didChange` on every keystroke; one check per pause is enough. */
36
40
  const DEBOUNCE_MS = 400;
41
+ /** How many files' check answers are kept. Enough for the ones in front of you. */
42
+ const CACHE_FILES = 64;
37
43
  const log = createLogger("carrick-lsp");
38
44
  function send(message) {
39
45
  const body = Buffer.from(JSON.stringify({ jsonrpc: "2.0", ...message }), "utf8");
@@ -45,9 +51,21 @@ let root = process.cwd();
45
51
  let rootChoice = null;
46
52
  let channel = resolveChannel({ hooksInstalled: false });
47
53
  let clientName = "an unnamed client";
54
+ /** Whether the client will re-request lenses when asked to (LSP 3.16). */
55
+ let clientRefreshesLenses = false;
56
+ /** One off switch per surface (carrick#879), as the client stated them. */
57
+ let surfaces = DEFAULT_SURFACES;
48
58
  /** What each checked file last published to, so a clear is scoped to it. */
49
59
  const publishedBy = new Map();
50
60
  const debounces = new Map();
61
+ /** Ids for the requests this server makes of the client. */
62
+ let nextServerId = 1;
63
+ /**
64
+ * The last check answer per absolute file, so a pull surface answers from what
65
+ * the push path already ran rather than running the CLI again. Dropped on every
66
+ * edit, because the payload's line numbers are about the text that was checked.
67
+ */
68
+ const lastCheck = new Map();
51
69
  /** One check at a time: a burst of edits must not interleave two runs. */
52
70
  let queue = Promise.resolve();
53
71
  function enqueue(work) {
@@ -63,19 +81,52 @@ function publish(uriPath, diagnostics) {
63
81
  params: { uri: pathToFileURL(uriPath).toString(), diagnostics },
64
82
  });
65
83
  }
84
+ /**
85
+ * The check answer for a file: the cached one, or one run now and cached.
86
+ *
87
+ * Every surface reads the file's answer through here, so a hover, a jump and a
88
+ * diagnostic on the same unchanged file cost one CLI call between them. A
89
+ * `check` reads `.carrick/` and never scans, but it does spawn a process, and
90
+ * an on-demand request is expected back in a fraction of a second.
91
+ */
92
+ async function resultFor(absFile) {
93
+ const key = path.resolve(absFile);
94
+ const cached = lastCheck.get(key);
95
+ if (cached)
96
+ return cached;
97
+ const outcome = await check(relative(absFile), { cwd: root });
98
+ if (!outcome.result) {
99
+ log("no answer for", relative(absFile), outcome.failure ?? "");
100
+ return null;
101
+ }
102
+ // A "no" is never cached. `not_indexed` is the answer that changes under the
103
+ // user's feet: they run `carrick index` in a terminal and the next request
104
+ // has to ask again rather than repeat what was true before they did.
105
+ if (outcome.result.error)
106
+ return outcome.result;
107
+ // An editor session opens files all day and this server runs as long as it
108
+ // does, so the oldest entry goes when the cache is full. A Map iterates in
109
+ // insertion order, which makes the first key the oldest.
110
+ if (lastCheck.size >= CACHE_FILES) {
111
+ const oldest = lastCheck.keys().next();
112
+ if (!oldest.done)
113
+ lastCheck.delete(oldest.value);
114
+ }
115
+ lastCheck.set(key, outcome.result);
116
+ return outcome.result;
117
+ }
66
118
  async function checkAndPublish(absFile) {
67
119
  const relFile = relative(absFile);
68
- const outcome = await check(relFile, { cwd: root });
69
- if (!outcome.result) {
70
- log("no answer for", relFile, outcome.failure ?? "");
120
+ const started = Date.now();
121
+ const result = await resultFor(absFile);
122
+ if (!result)
71
123
  return;
72
- }
73
- if (outcome.result.error) {
74
- log("check", relFile, "->", outcome.result.error);
124
+ if (result.error) {
125
+ log("check", relFile, "->", result.error);
75
126
  return;
76
127
  }
77
- const byFile = toDiagnostics(outcome.result, root, relFile);
78
- log(`check ${relFile} -> ${[...byFile.values()].reduce((n, list) => n + list.length, 0)} diagnostic(s) across ${byFile.size} file(s) in ${outcome.ms}ms`);
128
+ const byFile = toDiagnostics(result, root, relFile, { surfaces });
129
+ log(`check ${relFile} -> ${[...byFile.values()].reduce((n, list) => n + list.length, 0)} diagnostic(s) across ${byFile.size} file(s) in ${Date.now() - started}ms`);
79
130
  // Clear only what THIS file's previous check flagged and no longer does: a
80
131
  // check of another file legitimately returns nothing while its findings stand.
81
132
  const previous = publishedBy.get(relFile) ?? new Set();
@@ -85,6 +136,32 @@ async function checkAndPublish(absFile) {
85
136
  publishedBy.set(relFile, new Set([...byFile.keys()].filter((file) => (byFile.get(file) ?? []).length > 0)));
86
137
  for (const [file, diagnostics] of byFile)
87
138
  publish(file, diagnostics);
139
+ publishBoundary(result);
140
+ }
141
+ /**
142
+ * The boundary, for a client that has somewhere workspace-shaped to put it.
143
+ *
144
+ * carrick#879 moved it off the per-file Problems list for those clients, and
145
+ * this is where it moved TO: one notification per check carrying the same lines
146
+ * the diagnostic used to, which the VS Code extension renders as a status bar
147
+ * item and its tooltip. A client that declared no such surface gets the
148
+ * Information diagnostic instead and this notification as well, which costs it
149
+ * nothing: an unknown notification is ignored by definition.
150
+ */
151
+ function publishBoundary(result) {
152
+ if (!surfaces.boundary)
153
+ return;
154
+ const lines = boundaryFor(result);
155
+ if (!lines.length)
156
+ return;
157
+ send({
158
+ method: "carrick/boundary",
159
+ params: {
160
+ service: result.service ?? null,
161
+ indexCommit: result.index_commit ?? null,
162
+ lines,
163
+ },
164
+ });
88
165
  }
89
166
  function scheduleCheck(absFile, debounceMs) {
90
167
  const existing = debounces.get(absFile);
@@ -129,6 +206,9 @@ function onInitialize(id, params) {
129
206
  const info = params["clientInfo"];
130
207
  if (info?.name)
131
208
  clientName = info.name;
209
+ const capabilities = params["capabilities"];
210
+ clientRefreshesLenses = capabilities?.workspace?.codeLens?.refreshSupport === true;
211
+ surfaces = readSurfaces(params["initializationOptions"]);
132
212
  rootChoice = resolveRoot({
133
213
  clientRoot,
134
214
  projectDir: process.env["CLAUDE_PROJECT_DIR"] ?? null,
@@ -158,6 +238,14 @@ function onInitialize(id, params) {
158
238
  interFileDependencies: true,
159
239
  workspaceDiagnostics: false,
160
240
  },
241
+ // Declared whatever `carrick.codeLens` says, so a client that cached
242
+ // the capability still gets an answer when the switch is flipped: the
243
+ // answer is an empty list.
244
+ codeLensProvider: { resolveProvider: true },
245
+ // Declared whatever `carrick.definition` says, for the same reason:
246
+ // off means an empty answer, which is the fall-through every position
247
+ // outside a row already gets, and never a method the server refuses.
248
+ definitionProvider: true,
161
249
  },
162
250
  serverInfo: { name: NAME, version: VERSION },
163
251
  },
@@ -182,14 +270,71 @@ function handle(message) {
182
270
  case "textDocument/didOpen":
183
271
  case "textDocument/didSave":
184
272
  case "textDocument/didChange": {
185
- if (channel.channel !== "lsp")
186
- return;
187
273
  const file = pathOf(params);
188
274
  if (!file)
189
275
  return;
276
+ // The text moved, so the lines in the cached answer are about text that
277
+ // is gone. Dropped on every channel: in the hook channel nothing
278
+ // re-checks the file, and a jump off a stale line is the worst answer
279
+ // this surface can give.
280
+ lastCheck.delete(path.resolve(file));
281
+ if (channel.channel !== "lsp")
282
+ return;
190
283
  scheduleCheck(file, method === "textDocument/didChange" ? DEBOUNCE_MS : 0);
191
284
  return;
192
285
  }
286
+ case "workspace/didChangeConfiguration": {
287
+ // A switch turned off takes its rows away on the next publish, not at the
288
+ // next restart, so every file this server has flagged is re-checked here.
289
+ surfaces = readSurfaces(params, surfaces);
290
+ log(`surfaces: ${JSON.stringify(surfaces)}`);
291
+ for (const relFile of publishedBy.keys())
292
+ scheduleCheck(path.resolve(root, relFile), 0);
293
+ // A lens is pulled, not pushed, so `carrick.codeLens` off only clears the
294
+ // screen once the client asks again. It is asked to.
295
+ if (clientRefreshesLenses)
296
+ send({ id: `carrick-refresh-${nextServerId++}`, method: "workspace/codeLens/refresh", params: {} });
297
+ return;
298
+ }
299
+ case "textDocument/codeLens": {
300
+ // A REQUEST, not a push: it is answered in an install where the hook owns
301
+ // delivery, because the channel decides who speaks unasked and a lens is
302
+ // only ever rendered because a client asked for it.
303
+ const file = pathOf(params);
304
+ if (!file) {
305
+ send({ id, result: [] });
306
+ return;
307
+ }
308
+ void enqueue(async () => {
309
+ // The same cached answer every other surface reads (carrick#910): a
310
+ // lens and a jump on one unchanged file cost one CLI call between them.
311
+ const result = await resultFor(file);
312
+ send({ id, result: result ? toCodeLenses(result, { surfaces }) : [] });
313
+ });
314
+ return;
315
+ }
316
+ case "codeLens/resolve":
317
+ // Everything a lens carries comes from the one check the list was built
318
+ // from, so there is nothing left to fill in.
319
+ send({ id, result: params ?? null });
320
+ return;
321
+ case "textDocument/definition": {
322
+ // Not gated on which channel owns delivery: an install where the hook
323
+ // owns it publishes nothing, and a person in that editor still asks for
324
+ // a jump. `off` is the exception, because it is the blunt instrument
325
+ // that means Carrick says nothing at all.
326
+ const file = pathOf(params);
327
+ const position = positionOf(params);
328
+ if (!file || !position || !surfaces.definition || channel.channel === "off") {
329
+ send({ id, result: [] });
330
+ return;
331
+ }
332
+ void enqueue(async () => {
333
+ const result = await resultFor(file);
334
+ send({ id, result: result ? definitionsAt(result, position) : [] });
335
+ });
336
+ return;
337
+ }
193
338
  case "textDocument/diagnostic": {
194
339
  // A pull-only client still gets an answer, and the same one.
195
340
  const file = pathOf(params);
@@ -198,9 +343,10 @@ function handle(message) {
198
343
  return;
199
344
  }
200
345
  void enqueue(async () => {
201
- const outcome = await check(relative(file), { cwd: root });
202
- const items = outcome.result
203
- ? (toDiagnostics(outcome.result, root, relative(file)).get(path.resolve(file)) ?? [])
346
+ const result = await resultFor(file);
347
+ const items = result
348
+ ? (toDiagnostics(result, root, relative(file), { surfaces }).get(path.resolve(file)) ??
349
+ [])
204
350
  : [];
205
351
  send({ id, result: { kind: "full", items } });
206
352
  });
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA,kEAAkE;AAClE,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,qEAAqE;AACrE,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,qEAAqE;AACrE,EAAE;AACF,4EAA4E;AAC5E,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAChF,gFAAgF;AAChF,4EAA4E;AAC5E,0EAA0E;AAC1E,0EAA0E;AAC1E,+EAA+E;AAC/E,iDAAiD;AACjD,2EAA2E;AAC3E,kDAAkD;AAClD,EAAE;AACF,0DAA0D;AAE1D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,cAAc,EAAsB,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAmB,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAmB,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;AAE9E,MAAM,IAAI,GAAG,SAAS,CAAC;AACvB,MAAM,OAAO,GAAG,OAAO,CAAC;AACxB,kFAAkF;AAClF,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,mFAAmF;AACnF,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AASxC,SAAS,IAAI,CAAC,OAAgC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC;IAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,2EAA2E;AAE3E,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AACzB,IAAI,UAAU,GAAsB,IAAI,CAAC;AACzC,IAAI,OAAO,GAAkB,cAAc,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;AACvE,IAAI,UAAU,GAAG,mBAAmB,CAAC;AACrC,0EAA0E;AAC1E,IAAI,qBAAqB,GAAG,KAAK,CAAC;AAClC,2EAA2E;AAC3E,IAAI,QAAQ,GAAa,gBAAgB,CAAC;AAE1C,4EAA4E;AAC5E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;AACnD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA0B,CAAC;AACpD,4DAA4D;AAC5D,IAAI,YAAY,GAAG,CAAC,CAAC;AACrB;;;;GAIG;AACH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAC;AACjD,0EAA0E;AAC1E,IAAI,KAAK,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;AAE7C,SAAS,OAAO,CAAC,IAAyB;IACxC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAED,SAAS,OAAO,CAAC,OAAe,EAAE,WAAyB;IACzD,IAAI,CAAC;QACH,MAAM,EAAE,iCAAiC;QACzC,MAAM,EAAE,EAAE,GAAG,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE;KAChE,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,SAAS,CAAC,OAAe;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,6EAA6E;IAC7E,2EAA2E;IAC3E,qEAAqE;IACrE,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC;IAChD,2EAA2E;IAC3E,2EAA2E;IAC3E,yDAAyD;IACzD,IAAI,SAAS,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;IACD,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,OAAe;IAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClE,GAAG,CACD,SAAS,OAAO,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,yBAAyB,MAAM,CAAC,IAAI,eAAe,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,IAAI,CAC/J,CAAC;IAEF,2EAA2E;IAC3E,+EAA+E;IAC/E,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;IAC/D,KAAK,MAAM,KAAK,IAAI,QAAQ;QAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5E,WAAW,CAAC,GAAG,CACb,OAAO,EACP,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAClF,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,MAAM;QAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACrE,eAAe,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,eAAe,CAAC,MAAmB;IAC1C,IAAI,CAAC,QAAQ,CAAC,QAAQ;QAAE,OAAO;IAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO;IAC1B,IAAI,CAAC;QACH,MAAM,EAAE,kBAAkB;QAC1B,MAAM,EAAE;YACN,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;YAC/B,WAAW,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI;YACxC,KAAK;SACN;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,OAAe,EAAE,UAAkB;IACxD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,QAAQ;QAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IACD,SAAS,CAAC,GAAG,CACX,OAAO,EACP,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1B,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC,EAAE,UAAU,CAAC,CACf,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,MAA2C;IACzD,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,cAAc,CAAiC,CAAC;IAC1E,IAAI,CAAC,QAAQ,EAAE,GAAG;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAE9E,SAAS,YAAY,CAAC,EAA+B,EAAE,MAA+B;IACpF,MAAM,OAAO,GAAG,MAAM,CAAC,kBAAkB,CAAwC,CAAC;IAClF,MAAM,SAAS,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAK,MAAM,CAAC,SAAS,CAAwB,CAAC;IACjF,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC;YACH,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IACD,IAAI,CAAC,UAAU,IAAI,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1D,UAAU,GAAG,MAAM,CAAC,UAAU,CAAW,CAAC;IAC5C,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAkC,CAAC;IACnE,IAAI,IAAI,EAAE,IAAI;QAAE,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;IACvC,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc,CAE7B,CAAC;IACd,qBAAqB,GAAG,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IACnF,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAEzD,UAAU,GAAG,WAAW,CAAC;QACvB,UAAU;QACV,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,IAAI;QACrD,QAAQ,EAAE,UAAU;KACrB,CAAC,CAAC;IACH,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;IACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAClC,IAAI,IAAI;QAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAEpB,OAAO,GAAG,cAAc,CAAC;QACvB,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC;KAC3D,CAAC,CAAC;IACH,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,GAAG,CAAC,mBAAmB,OAAO,CAAC,YAAY,4BAA4B,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAC9B,GAAG,CACD,OAAO,OAAO,CAAC,OAAO,2CAA2C,OAAO,CAAC,MAAM,qCAAqC,CACrH,CAAC;IACJ,CAAC;IACD,GAAG,CAAC,kBAAkB,UAAU,UAAU,IAAI,KAAK,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IAEzE,IAAI,CAAC;QACH,EAAE;QACF,MAAM,EAAE;YACN,YAAY,EAAE;gBACZ,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE;gBAC9E,kBAAkB,EAAE;oBAClB,UAAU,EAAE,IAAI;oBAChB,qBAAqB,EAAE,IAAI;oBAC3B,oBAAoB,EAAE,KAAK;iBAC5B;gBACD,qEAAqE;gBACrE,sEAAsE;gBACtE,2BAA2B;gBAC3B,gBAAgB,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;gBAC3C,oEAAoE;gBACpE,sEAAsE;gBACtE,qEAAqE;gBACrE,kBAAkB,EAAE,IAAI;aACzB;YACD,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;SAC7C;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,MAAM,CAAC,OAAgB;IAC9B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,YAAY;YACf,YAAY,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;YAC/B,OAAO;QACT,KAAK,aAAa;YAChB,OAAO;QACT,KAAK,UAAU;YACb,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3B,OAAO;QACT,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO;QACT,KAAK,sBAAsB,CAAC;QAC5B,KAAK,sBAAsB,CAAC;QAC5B,KAAK,wBAAwB,CAAC,CAAC,CAAC;YAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,wEAAwE;YACxE,iEAAiE;YACjE,sEAAsE;YACtE,yBAAyB;YACzB,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACrC,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK;gBAAE,OAAO;YACtC,aAAa,CAAC,IAAI,EAAE,MAAM,KAAK,wBAAwB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3E,OAAO;QACT,CAAC;QACD,KAAK,kCAAkC,CAAC,CAAC,CAAC;YACxC,0EAA0E;YAC1E,0EAA0E;YAC1E,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC1C,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC7C,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE;gBAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;YACxF,0EAA0E;YAC1E,qDAAqD;YACrD,IAAI,qBAAqB;gBAAE,IAAI,CAAC,EAAE,EAAE,EAAE,mBAAmB,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YAC/H,OAAO;QACT,CAAC;QACD,KAAK,uBAAuB,CAAC,CAAC,CAAC;YAC7B,0EAA0E;YAC1E,yEAAyE;YACzE,oDAAoD;YACpD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBACzB,OAAO;YACT,CAAC;YACD,KAAK,OAAO,CAAC,KAAK,IAAI,EAAE;gBACtB,oEAAoE;gBACpE,wEAAwE;gBACxE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzE,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,KAAK,kBAAkB;YACrB,wEAAwE;YACxE,6CAA6C;YAC7C,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;YACrC,OAAO;QACT,KAAK,yBAAyB,CAAC,CAAC,CAAC;YAC/B,sEAAsE;YACtE,wEAAwE;YACxE,qEAAqE;YACrE,0CAA0C;YAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5B,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;gBAC5E,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBACzB,OAAO;YACT,CAAC;YACD,KAAK,OAAO,CAAC,KAAK,IAAI,EAAE;gBACtB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,KAAK,yBAAyB,CAAC,CAAC,CAAC;YAC/B,6DAA6D;YAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;gBACvC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gBAClD,OAAO;YACT,CAAC;YACD,KAAK,OAAO,CAAC,KAAK,IAAI,EAAE;gBACtB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;gBACrC,MAAM,KAAK,GAAG,MAAM;oBAClB,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;wBAClF,EAAE,CAAC;oBACL,CAAC,CAAC,EAAE,CAAC;gBACP,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD;YACE,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;gBACrB,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,uBAAuB,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YAClF,CAAC;YACD,OAAO;IACX,CAAC;AACH,CAAC;AAED,6EAA6E;AAE7E,IAAI,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAE7B,MAAM,UAAU,IAAI,CAAC,KAAa;IAChC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACxC,SAAS,CAAC;QACR,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,SAAS,KAAK,CAAC,CAAC;YAAE,OAAO;QAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YACxC,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,MAAM,GAAG,SAAS,GAAG,CAAC,GAAG,MAAM;YAAE,OAAO;QACnD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACrF,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;QACjD,IAAI,OAAgB,CAAC;QACrB,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;AACH,CAAC;AAED,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACzD,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3E,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvF,GAAG,CAAC,aAAa,OAAO,CAAC,GAAG,SAAS,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ export type Surfaces = {
2
+ /** Publish verdict diagnostics at all. */
3
+ diagnostics: boolean;
4
+ /**
5
+ * Answer `textDocument/definition` (carrick#881). Off means an empty answer
6
+ * rather than a withdrawn capability, so a client that cached the capability
7
+ * at initialize still behaves.
8
+ */
9
+ definition: boolean;
10
+ /** State the boundary. Where it lands depends on `boundarySurface`. */
11
+ boundary: boolean;
12
+ /** Render code lenses on the rows the index knows something about. */
13
+ codeLens: boolean;
14
+ /**
15
+ * The client shows the boundary somewhere that is not the Problems list, so
16
+ * the per-file Information diagnostic is not published to it. False for a
17
+ * client that says nothing, which keeps the fallback.
18
+ */
19
+ boundarySurface: boolean;
20
+ };
21
+ export declare const DEFAULT_SURFACES: Surfaces;
22
+ /**
23
+ * Read the switches a client states, over the ones already in force.
24
+ *
25
+ * A key the client omits keeps its current value: a notification that carries
26
+ * one setting must not silently reset the rest to their defaults.
27
+ */
28
+ export declare function readSurfaces(params: unknown, current?: Surfaces): Surfaces;
@@ -0,0 +1,70 @@
1
+ // One off switch per surface, in one place.
2
+ //
3
+ // Every surface this server offers can be turned off on its own, defaulting on,
4
+ // and turning one off leaves the others exactly as they were (design record
5
+ // 2026-09-09, "Off switches, one per thing"). `CARRICK_CHANNEL=off` stays the
6
+ // blunt instrument that silences delivery entirely.
7
+ //
8
+ // A client states them twice over: once in `initializationOptions` at startup,
9
+ // and again in `workspace/didChangeConfiguration` when a person changes a
10
+ // setting mid-session, which is why one parser reads both shapes. VS Code sends
11
+ // `{ settings: { carrick: { ... } } }` for the notification; a generic client
12
+ // that only has `initializationOptions` sends the flat object. Either is
13
+ // accepted, and anything that is not a boolean leaves the default alone rather
14
+ // than reading as false.
15
+ //
16
+ // `boundarySurface` is not an off switch and not a preference: it is the client
17
+ // saying it has somewhere else to put the boundary, which the VS Code extension
18
+ // does because it owns a status bar item. It decides placement, never whether
19
+ // the boundary is stated at all. See diagnostics.ts for what it changes.
20
+ export const DEFAULT_SURFACES = {
21
+ diagnostics: true,
22
+ definition: true,
23
+ boundary: true,
24
+ codeLens: true,
25
+ boundarySurface: false,
26
+ };
27
+ function isRecord(value) {
28
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29
+ }
30
+ /**
31
+ * The `carrick` block of whatever a client sent, flat or nested.
32
+ *
33
+ * `initializationOptions` is already the block. A
34
+ * `workspace/didChangeConfiguration` payload wraps it in `settings.carrick`,
35
+ * and some clients send `settings` alone with the section stripped.
36
+ */
37
+ function block(params) {
38
+ if (!isRecord(params))
39
+ return {};
40
+ const settings = params["settings"];
41
+ if (isRecord(settings)) {
42
+ const scoped = settings["carrick"];
43
+ return isRecord(scoped) ? scoped : settings;
44
+ }
45
+ const scoped = params["carrick"];
46
+ if (isRecord(scoped))
47
+ return scoped;
48
+ return params;
49
+ }
50
+ /**
51
+ * Read the switches a client states, over the ones already in force.
52
+ *
53
+ * A key the client omits keeps its current value: a notification that carries
54
+ * one setting must not silently reset the rest to their defaults.
55
+ */
56
+ export function readSurfaces(params, current = DEFAULT_SURFACES) {
57
+ const stated = block(params);
58
+ const read = (key) => {
59
+ const value = stated[key];
60
+ return typeof value === "boolean" ? value : current[key];
61
+ };
62
+ return {
63
+ diagnostics: read("diagnostics"),
64
+ definition: read("definition"),
65
+ boundary: read("boundary"),
66
+ codeLens: read("codeLens"),
67
+ boundarySurface: read("boundarySurface"),
68
+ };
69
+ }
70
+ //# sourceMappingURL=surfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surfaces.js","sourceRoot":"","sources":["../src/surfaces.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,8EAA8E;AAC9E,oDAAoD;AACpD,EAAE;AACF,+EAA+E;AAC/E,0EAA0E;AAC1E,gFAAgF;AAChF,8EAA8E;AAC9E,yEAAyE;AACzE,+EAA+E;AAC/E,yBAAyB;AACzB,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,8EAA8E;AAC9E,yEAAyE;AAuBzE,MAAM,CAAC,MAAM,gBAAgB,GAAa;IACxC,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,eAAe,EAAE,KAAK;CACvB,CAAC;AAEF,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,SAAS,KAAK,CAAC,MAAe;IAC5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QACnC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC9C,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAe,EAAE,UAAoB,gBAAgB;IAChF,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,GAAmB,EAAW,EAAE;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC,CAAC;IACF,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC;QAChC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC;QAC9B,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC;QAC1B,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC;QAC1B,eAAe,EAAE,IAAI,CAAC,iBAAiB,CAAC;KACzC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carrick",
3
- "version": "0.3.56",
3
+ "version": "0.3.58",
4
4
  "description": "The API contract index for a TypeScript workspace: what the other services do with the routes and calls in the file you are editing, in your editor and in your agent's context",
5
5
  "keywords": [
6
6
  "typescript",
@@ -55,11 +55,11 @@
55
55
  "zod": "^3.23.0"
56
56
  },
57
57
  "optionalDependencies": {
58
- "@carrick-tools/cli-darwin-arm64": "0.3.56",
59
- "@carrick-tools/cli-darwin-x64": "0.3.56",
60
- "@carrick-tools/cli-linux-arm64": "0.3.56",
61
- "@carrick-tools/cli-linux-x64": "0.3.56",
62
- "@carrick-tools/cli-win32-x64": "0.3.56"
58
+ "@carrick-tools/cli-darwin-arm64": "0.3.58",
59
+ "@carrick-tools/cli-darwin-x64": "0.3.58",
60
+ "@carrick-tools/cli-linux-arm64": "0.3.58",
61
+ "@carrick-tools/cli-linux-x64": "0.3.58",
62
+ "@carrick-tools/cli-win32-x64": "0.3.58"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@types/node": "^24.13.3",