carrick 0.3.57 → 0.3.59

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.
Files changed (65) hide show
  1. package/README.md +117 -26
  2. package/bin/carrick.mjs +13 -2
  3. package/dist/auth/credentials.d.ts +14 -0
  4. package/dist/auth/credentials.js +86 -0
  5. package/dist/auth/credentials.js.map +1 -0
  6. package/dist/auth/oauth.d.ts +11 -0
  7. package/dist/auth/oauth.js +119 -0
  8. package/dist/auth/oauth.js.map +1 -0
  9. package/dist/auth/read.d.ts +139 -0
  10. package/dist/auth/read.js +44 -0
  11. package/dist/auth/read.js.map +1 -0
  12. package/dist/auth/run.d.ts +12 -0
  13. package/dist/auth/run.js +68 -0
  14. package/dist/auth/run.js.map +1 -0
  15. package/dist/contract.d.ts +10 -0
  16. package/dist/contract.js +3 -0
  17. package/dist/contract.js.map +1 -1
  18. package/dist/definition.d.ts +33 -0
  19. package/dist/definition.js +107 -0
  20. package/dist/definition.js.map +1 -0
  21. package/dist/diagnostics.d.ts +72 -3
  22. package/dist/diagnostics.js +275 -55
  23. package/dist/diagnostics.js.map +1 -1
  24. package/dist/hook/refresh.d.ts +32 -0
  25. package/dist/hook/refresh.js +138 -0
  26. package/dist/hook/refresh.js.map +1 -0
  27. package/dist/hook/session-start.js +13 -0
  28. package/dist/hook/session-start.js.map +1 -1
  29. package/dist/init/connect.d.ts +17 -0
  30. package/dist/init/connect.js +120 -0
  31. package/dist/init/connect.js.map +1 -0
  32. package/dist/init/mcp.d.ts +50 -0
  33. package/dist/init/mcp.js +235 -0
  34. package/dist/init/mcp.js.map +1 -0
  35. package/dist/init/projects.d.ts +46 -0
  36. package/dist/init/projects.js +137 -0
  37. package/dist/init/projects.js.map +1 -0
  38. package/dist/init/repos.d.ts +113 -19
  39. package/dist/init/repos.js +60 -39
  40. package/dist/init/repos.js.map +1 -1
  41. package/dist/init/run.d.ts +16 -0
  42. package/dist/init/run.js +243 -61
  43. package/dist/init/run.js.map +1 -1
  44. package/dist/init/settings.d.ts +1 -1
  45. package/dist/init/settings.js +1 -1
  46. package/dist/init/settings.js.map +1 -1
  47. package/dist/lens.d.ts +41 -0
  48. package/dist/lens.js +116 -0
  49. package/dist/lens.js.map +1 -0
  50. package/dist/server.js +327 -24
  51. package/dist/server.js.map +1 -1
  52. package/dist/surfaces.d.ts +28 -0
  53. package/dist/surfaces.js +70 -0
  54. package/dist/surfaces.js.map +1 -0
  55. package/package.json +6 -6
  56. package/sidecar/dist/src/capture/deno-project.d.ts +41 -0
  57. package/sidecar/dist/src/capture/deno-project.js +513 -0
  58. package/sidecar/dist/src/capture/index.d.ts +1 -0
  59. package/sidecar/dist/src/capture/index.js +60 -19
  60. package/sidecar/dist/src/capture/self-check.d.ts +2 -0
  61. package/sidecar/dist/src/capture/self-check.js +3 -2
  62. package/sidecar/dist/src/project-loader.js +22 -1
  63. package/dist/init/identity.d.ts +0 -20
  64. package/dist/init/identity.js +0 -60
  65. package/dist/init/identity.js.map +0 -1
@@ -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,73 @@ 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
+ * What a diagnostic underlines on its line: first non-whitespace to last
77
+ * (carrick#922).
78
+ *
79
+ * The index stores line-only locators, so there is no column span to publish
80
+ * and a one-character range marks the indent rather than the code. The line's
81
+ * own text is the span: an editor underlines the statement, and a reader who
82
+ * cannot see the Problems list still knows which line is meant.
83
+ *
84
+ * `col` is deliberately not used to start the span. The locators the index
85
+ * holds are line-only and the column, when a payload carries one, is where a
86
+ * pass happened to anchor rather than where the statement begins. Without the
87
+ * line's text there is nothing to widen to and the one-character range stands.
88
+ *
89
+ * Characters are UTF-16 code units, which is what LSP means by `character` at
90
+ * the default position encoding and what a JavaScript string index already is.
91
+ * A line with a multi-byte character before the code is therefore right by
92
+ * construction here, which is not true of the byte offsets the scanner sends
93
+ * the sidecar (carrick#805).
94
+ */
95
+ export function lineSpan(file, line, col, lineText) {
96
+ const fallback = rangeAt(line, col);
97
+ if (!lineText)
98
+ return fallback;
99
+ const text = lineText(file, line ?? 1);
100
+ if (text == null)
101
+ return fallback;
102
+ const end = text.trimEnd().length;
103
+ // A blank line has nothing to underline, and a zero-width range renders as
104
+ // nothing at all, so the one-character range stands there too.
105
+ if (end === 0)
106
+ return fallback;
107
+ const start = text.length - text.trimStart().length;
108
+ return {
109
+ start: { line: fallback.start.line, character: start },
110
+ end: { line: fallback.start.line, character: end },
111
+ };
112
+ }
113
+ /**
114
+ * A routing finding: a result with no type verdict behind it.
115
+ *
116
+ * `method_mismatch` and `producer_removed` are read off two deterministic rows
117
+ * and carry `not_checked` because no type verdict bears on them. They are the
118
+ * findings whose whole claim is about the other side of a call.
119
+ */
120
+ function isRoutingFinding(item) {
121
+ const verdict = item.verdict;
122
+ return Boolean(verdict && verdict.result != null && verdict.state === "not_checked");
123
+ }
124
+ /**
125
+ * The severity policy, in one place.
126
+ *
127
+ * Error only for a finding on a fact row that claims something (R1c) and whose
128
+ * claim a reader can go and check. `resolvable` is whether any counterpart of
129
+ * this row is on this disk: a routing finding is entirely a statement about the
130
+ * other side, so when the other side cannot be opened it is a warning. Nothing
131
+ * here ever returns Hint.
132
+ */
133
+ export function severityOf(item, resolvable = true) {
45
134
  if (isCandidate(item))
46
135
  return SEVERITY.warning;
47
136
  if (item.source !== "fact")
48
137
  return SEVERITY.warning;
49
138
  if (item.verdict?.state === "unresolved")
50
139
  return SEVERITY.warning;
140
+ if (isRoutingFinding(item) && !resolvable)
141
+ return SEVERITY.warning;
51
142
  return SEVERITY.error;
52
143
  }
53
144
  /** `consumer in admin-ui`, and for a peer the role word is left out. */
@@ -102,6 +193,10 @@ function defaultExists(target) {
102
193
  * service would be guessing at paths the producer already knows.
103
194
  */
104
195
  export function resolveCounterpart(counterpart, exists = defaultExists) {
196
+ if (!exists)
197
+ exists = defaultExists;
198
+ if (counterpart.remote)
199
+ return null;
105
200
  if (!counterpart.file)
106
201
  return null;
107
202
  if (path.isAbsolute(counterpart.file))
@@ -111,6 +206,113 @@ export function resolveCounterpart(counterpart, exists = defaultExists) {
111
206
  const target = path.resolve(counterpart.repo, counterpart.file);
112
207
  return exists(target) ? target : null;
113
208
  }
209
+ /**
210
+ * A finding's counterparts grouped by the file they land in.
211
+ *
212
+ * Two call sites in one consumer file are one finding in one file, so they are
213
+ * one mirrored row naming both lines rather than two rows saying the same
214
+ * sentence. Order follows the payload, so the row lands on the first site.
215
+ */
216
+ function groupCounterparts(counterparts, exists) {
217
+ const groups = [];
218
+ const byTarget = new Map();
219
+ for (const counterpart of counterparts) {
220
+ const target = resolveCounterpart(counterpart, exists);
221
+ if (!target)
222
+ continue;
223
+ const existing = byTarget.get(target);
224
+ if (existing) {
225
+ existing.sites.push(counterpart);
226
+ continue;
227
+ }
228
+ const group = { target, sites: [counterpart] };
229
+ byTarget.set(target, group);
230
+ groups.push(group);
231
+ }
232
+ return groups;
233
+ }
234
+ /** The eleventh row: what was not shown, and the command that shows it. */
235
+ function overflowRow(hidden, where, checkedFile, range) {
236
+ return {
237
+ range,
238
+ severity: SEVERITY.warning,
239
+ code: "capped",
240
+ source: SOURCE,
241
+ message: `and ${hidden} more finding(s) ${where}, from \`carrick check ${checkedFile}\`.`,
242
+ };
243
+ }
244
+ const isBoundaryRow = (diagnostic) => diagnostic.code === "boundary";
245
+ /**
246
+ * Findings first and then by line, which is the order the cap keeps.
247
+ *
248
+ * "Problems first" is severity order: when ten of forty rows survive, the ten
249
+ * that survive are the ones that claim the most.
250
+ */
251
+ function orderRows(rows) {
252
+ return [...rows].sort((a, b) => a.severity - b.severity || a.range.start.line - b.range.start.line);
253
+ }
254
+ /**
255
+ * The cap, applied to a whole check.
256
+ *
257
+ * Ten findings per file with an eleventh row naming the remainder, thirty rows
258
+ * across the check with one more naming what the check as a whole did not show,
259
+ * and a file the budget drops publishes an empty list so its previous rows are
260
+ * cleared rather than left standing. The boundary fallback rides outside both
261
+ * counts: it states something about the workspace and is not a finding.
262
+ */
263
+ export function capDiagnostics(byFile, checkedAbs, checkedFile, lineText) {
264
+ const order = [
265
+ ...(byFile.has(checkedAbs) ? [checkedAbs] : []),
266
+ ...[...byFile.keys()].filter((file) => file !== checkedAbs).sort(),
267
+ ];
268
+ const staged = order.map((file) => {
269
+ const rows = byFile.get(file) ?? [];
270
+ const findings = orderRows(rows.filter((row) => !isBoundaryRow(row)));
271
+ return {
272
+ file,
273
+ shown: findings.slice(0, MAX_PER_FILE),
274
+ hidden: Math.max(0, findings.length - MAX_PER_FILE),
275
+ boundary: rows.filter(isBoundaryRow),
276
+ };
277
+ });
278
+ // Whether the check as a whole overflows is decided before the walk, so the
279
+ // row that says so has a slot reserved and the thirty is never exceeded.
280
+ const wanted = staged.reduce((total, file) => total + file.shown.length + (file.hidden ? 1 : 0), 0);
281
+ const overflows = wanted > MAX_PER_CHECK;
282
+ let budget = overflows ? MAX_PER_CHECK - 1 : MAX_PER_CHECK;
283
+ const capped = new Map();
284
+ let unstated = 0;
285
+ for (const file of staged) {
286
+ const take = Math.max(0, Math.min(file.shown.length, budget));
287
+ const rows = file.shown.slice(0, take);
288
+ budget -= take;
289
+ unstated += file.shown.length - take;
290
+ if (file.hidden > 0) {
291
+ if (budget > 0 && take === file.shown.length) {
292
+ rows.push(overflowRow(file.hidden, "in this file", checkedFile, lineSpan(file.file, 1, 1, lineText)));
293
+ budget -= 1;
294
+ }
295
+ else {
296
+ unstated += file.hidden;
297
+ }
298
+ }
299
+ capped.set(file.file, rows);
300
+ }
301
+ if (unstated > 0) {
302
+ const rows = capped.get(checkedAbs) ?? [];
303
+ rows.push(overflowRow(unstated, "elsewhere in this check", checkedFile, lineSpan(checkedAbs, 1, 1, lineText)));
304
+ capped.set(checkedAbs, rows);
305
+ }
306
+ // The boundary is appended last, after every overflow row, because it is the
307
+ // line that makes a short answer readable and the hook renders it last for
308
+ // the same reason. Both channels read alike.
309
+ for (const file of staged) {
310
+ if (!file.boundary.length)
311
+ continue;
312
+ capped.get(file.file)?.push(...file.boundary);
313
+ }
314
+ return capped;
315
+ }
114
316
  /**
115
317
  * Diagnostics for one check payload, keyed by the absolute file they belong to.
116
318
  *
@@ -121,6 +323,8 @@ export function resolveCounterpart(counterpart, exists = defaultExists) {
121
323
  */
122
324
  export function toDiagnostics(result, root, checkedFile, options = {}) {
123
325
  const exists = options.exists ?? defaultExists;
326
+ const surfaces = options.surfaces ?? DEFAULT_SURFACES;
327
+ const lineText = options.lineText;
124
328
  const byFile = new Map();
125
329
  if (result.error)
126
330
  return byFile;
@@ -136,64 +340,80 @@ export function toDiagnostics(result, root, checkedFile, options = {}) {
136
340
  else
137
341
  byFile.set(file, [diagnostic]);
138
342
  };
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),
343
+ if (surfaces.diagnostics) {
344
+ for (const item of problemItems(result)) {
345
+ const groups = groupCounterparts(item.counterparts ?? [], exists);
346
+ // A routing finding whose other side is not on this disk cannot be gone
347
+ // and looked at, so it is stated as a warning rather than asserted.
348
+ const severity = severityOf(item, groups.length > 0);
349
+ const related = groups.flatMap((group) => group.sites.map((counterpart) => ({
350
+ location: {
351
+ uri: pathToFileURL(group.target).toString(),
352
+ range: lineSpan(group.target, counterpart.line, 1, lineText),
353
+ },
354
+ message: counterpartPhrase(counterpart),
355
+ })));
356
+ const diagnostic = {
357
+ range: lineSpan(checkedAbs, item.line, item.col, lineText),
358
+ severity,
169
359
  source: SOURCE,
170
- message: `${counterpartPhrase(counterpart)} of ${result.file ?? checkedFile}. ${messageOf(item)}`,
360
+ message: messageOf(item),
171
361
  };
172
362
  if (item.verdict?.result)
173
- mirrored.code = item.verdict.result;
174
- put(resolved, mirrored);
363
+ diagnostic.code = item.verdict.result;
364
+ if (related.length)
365
+ diagnostic.relatedInformation = related;
366
+ put(checkedAbs, diagnostic);
367
+ // 0b: a finding is mirrored onto each counterpart FILE, once, and never
368
+ // below Warning, because a row a reader did not ask for has to be worth
369
+ // the interruption in the file it lands in.
370
+ if (severity > SEVERITY.warning)
371
+ continue;
372
+ for (const group of groups) {
373
+ const [first, ...rest] = group.sites;
374
+ if (!first)
375
+ continue;
376
+ const alsoAt = rest
377
+ .map((counterpart) => counterpart.line)
378
+ .filter((line) => typeof line === "number");
379
+ const also = alsoAt.length ? ` Also at line ${alsoAt.join(", ")} in this file.` : "";
380
+ const mirrored = {
381
+ range: lineSpan(group.target, first.line, 1, lineText),
382
+ severity,
383
+ source: SOURCE,
384
+ message: `${counterpartPhrase(first)} of ${result.file ?? checkedFile}.${also} ${messageOf(item)}`,
385
+ };
386
+ if (item.verdict?.result)
387
+ mirrored.code = item.verdict.result;
388
+ put(group.target, mirrored);
389
+ }
390
+ }
391
+ if (result.deleted) {
392
+ const consumers = (result.items ?? []).reduce((total, item) => total + (item.counterparts ?? []).length, 0);
393
+ put(checkedAbs, {
394
+ range: lineSpan(checkedAbs, 1, 1, lineText),
395
+ severity: SEVERITY.warning,
396
+ code: "producer_removed",
397
+ source: SOURCE,
398
+ 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.`,
399
+ });
175
400
  }
176
401
  }
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
- }
402
+ // The fallback, and only the fallback: a client that told us it has a
403
+ // workspace surface for the boundary (the VS Code status bar) is not sent a
404
+ // per-file row for it. Nothing here decides whether the boundary is stated,
405
+ // only whether it is stated HERE; render.ts states it on the agent channel
406
+ // either way.
187
407
  const boundary = boundaryFor(result);
188
- if (boundary.length) {
408
+ if (boundary.length && surfaces.boundary && !surfaces.boundarySurface) {
189
409
  put(checkedAbs, {
190
- range: rangeAt(1, 1),
410
+ range: lineSpan(checkedAbs, 1, 1, lineText),
191
411
  severity: SEVERITY.information,
192
412
  code: "boundary",
193
413
  source: SOURCE,
194
414
  message: `What this service's scan could not classify:\n${boundary.join("\n")}`,
195
415
  });
196
416
  }
197
- return byFile;
417
+ return capDiagnostics(byFile, checkedAbs, checkedFile, lineText);
198
418
  }
199
419
  //# 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":"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"}
@@ -0,0 +1,32 @@
1
+ import type { StatusResult } from "../contract.ts";
2
+ /** Default gap between unattended refreshes of one workspace. */
3
+ export declare const REFRESH_COOLDOWN_MS: number;
4
+ /** The claim file, inside the ignored directory the index already owns. */
5
+ export declare function markerPath(root: string): string;
6
+ export declare function cooldownMs(env?: NodeJS.ProcessEnv): number;
7
+ /** Whether this workspace is waiting for a hosted index that may now exist. */
8
+ export declare function awaitingHostedIndex(status: StatusResult): boolean;
9
+ /** The last time anything read the hosted side, from the marker or the index. */
10
+ export declare function lastHostedRead(status: StatusResult, marker: string): number;
11
+ /**
12
+ * Take the right to refresh this workspace, or decline it.
13
+ *
14
+ * The claim is a hard link onto the marker path, which is the one file
15
+ * operation two processes cannot both win: whoever links first holds it, and
16
+ * the loser sees EEXIST. A marker older than the cooldown is replaced, and
17
+ * replacing it is where the race is — so the timestamp it held is re-read
18
+ * before it is removed, and a marker that changed under us belongs to the
19
+ * session that changed it.
20
+ */
21
+ export declare function claimRefresh(marker: string, now: number, cooldown: number): boolean;
22
+ export type RefreshOptions = {
23
+ env?: NodeJS.ProcessEnv;
24
+ now?: number;
25
+ /** Injected in tests; the real one detaches a child and forgets it. */
26
+ start?: (command: string, args: string[], env: NodeJS.ProcessEnv) => void;
27
+ };
28
+ /**
29
+ * Start a background `carrick refresh` when this workspace is waiting for a
30
+ * hosted index and has not asked recently. Returns the line to print, or null.
31
+ */
32
+ export declare function refreshInBackground(root: string, status: StatusResult, options?: RefreshOptions): string | null;
@@ -0,0 +1,138 @@
1
+ // Picking up a hosted index without being asked to (carrick#955).
2
+ //
3
+ // The first CI scan on a repo's default branch is what writes that repo's
4
+ // hosted index, and until a local `carrick refresh` reads it, a workspace
5
+ // indexed before that scan holds only what this machine could see on its own.
6
+ // Nothing tells the developer the moment it lands, so the step that connects
7
+ // the two was a command they had to remember.
8
+ //
9
+ // The session-start hook is where that can happen for free, with two
10
+ // constraints it must not break:
11
+ //
12
+ // - **A hook may not take time.** `carrick refresh` re-scans every repo in the
13
+ // workspace and drives a type sidecar per repo; it is minutes, not
14
+ // milliseconds. So it is started detached and not waited for. The session
15
+ // gets its orientation line immediately, and the refreshed index is there
16
+ // for the next one.
17
+ // - **A hook may not thrash.** The refresh is asked for only while some
18
+ // service still reports `no_index_yet` — a repo connected to the workspace
19
+ // whose hosted index has not appeared yet — and at most once per cooldown.
20
+ // Once the hosted index is read, the state becomes `enriched` and this stops
21
+ // on its own. `not_connected` and `not_signed_in` never trigger it: there is
22
+ // nothing to wait for in either.
23
+ //
24
+ // Two sessions opening in one workspace would otherwise both see the same
25
+ // stale marker and both start a re-index over the same `.carrick` directory,
26
+ // so the marker is claimed by a link that only one of them can win.
27
+ import fs from "node:fs";
28
+ import path from "node:path";
29
+ import { spawn } from "node:child_process";
30
+ import { binary } from "../cli.js";
31
+ /** Default gap between unattended refreshes of one workspace. */
32
+ export const REFRESH_COOLDOWN_MS = 60 * 60_000;
33
+ /** The claim file, inside the ignored directory the index already owns. */
34
+ export function markerPath(root) {
35
+ return path.join(root, ".carrick", "last-hook-refresh");
36
+ }
37
+ export function cooldownMs(env = process.env) {
38
+ const raw = env["CARRICK_REFRESH_COOLDOWN_MS"];
39
+ const parsed = raw ? Number.parseInt(raw, 10) : Number.NaN;
40
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : REFRESH_COOLDOWN_MS;
41
+ }
42
+ /** Whether this workspace is waiting for a hosted index that may now exist. */
43
+ export function awaitingHostedIndex(status) {
44
+ return status.services.some((service) => service.hosted_state === "no_index_yet");
45
+ }
46
+ /** When the marker last recorded a claim, or null when there is none. */
47
+ function claimedAt(marker) {
48
+ try {
49
+ const stamp = Date.parse(fs.readFileSync(marker, "utf8").trim());
50
+ return Number.isFinite(stamp) ? stamp : null;
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ /** The last time anything read the hosted side, from the marker or the index. */
57
+ export function lastHostedRead(status, marker) {
58
+ const checked = status.hosted_checked_at ? Date.parse(status.hosted_checked_at) : Number.NaN;
59
+ return Math.max(claimedAt(marker) ?? 0, Number.isFinite(checked) ? checked : 0);
60
+ }
61
+ /**
62
+ * Take the right to refresh this workspace, or decline it.
63
+ *
64
+ * The claim is a hard link onto the marker path, which is the one file
65
+ * operation two processes cannot both win: whoever links first holds it, and
66
+ * the loser sees EEXIST. A marker older than the cooldown is replaced, and
67
+ * replacing it is where the race is — so the timestamp it held is re-read
68
+ * before it is removed, and a marker that changed under us belongs to the
69
+ * session that changed it.
70
+ */
71
+ export function claimRefresh(marker, now, cooldown) {
72
+ const held = claimedAt(marker);
73
+ if (held !== null && now - held < cooldown)
74
+ return false;
75
+ const temporary = `${marker}.${process.pid}`;
76
+ try {
77
+ fs.mkdirSync(path.dirname(marker), { recursive: true });
78
+ fs.writeFileSync(temporary, `${new Date(now).toISOString()}\n`, { flag: "wx" });
79
+ }
80
+ catch {
81
+ return false;
82
+ }
83
+ try {
84
+ for (let attempt = 0; attempt < 2; attempt += 1) {
85
+ try {
86
+ fs.linkSync(temporary, marker);
87
+ return true;
88
+ }
89
+ catch (error) {
90
+ if (error.code !== "EEXIST")
91
+ return false;
92
+ }
93
+ const current = claimedAt(marker);
94
+ if (current === null || current !== held)
95
+ return false;
96
+ if (now - current < cooldown)
97
+ return false;
98
+ try {
99
+ fs.unlinkSync(marker);
100
+ }
101
+ catch {
102
+ // Another session removed it first; the retry decides between us.
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+ finally {
108
+ try {
109
+ fs.unlinkSync(temporary);
110
+ }
111
+ catch {
112
+ // Already gone, which is not ours to report.
113
+ }
114
+ }
115
+ }
116
+ function startDetached(command, args, env) {
117
+ const child = spawn(command, args, { detached: true, stdio: "ignore", env });
118
+ child.unref();
119
+ }
120
+ /**
121
+ * Start a background `carrick refresh` when this workspace is waiting for a
122
+ * hosted index and has not asked recently. Returns the line to print, or null.
123
+ */
124
+ export function refreshInBackground(root, status, options = {}) {
125
+ const env = options.env ?? process.env;
126
+ const now = options.now ?? Date.now();
127
+ if (!awaitingHostedIndex(status))
128
+ return null;
129
+ const marker = markerPath(root);
130
+ const cooldown = cooldownMs(env);
131
+ if (now - lastHostedRead(status, marker) < cooldown)
132
+ return null;
133
+ if (!claimRefresh(marker, now, cooldown))
134
+ return null;
135
+ (options.start ?? startDetached)(binary(env), ["refresh", "--workspace", root], env);
136
+ return "Carrick: a repo here is connected with no hosted index yet, so a refresh is running in the background. Its rows arrive in the next session.";
137
+ }
138
+ //# sourceMappingURL=refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/hook/refresh.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,0EAA0E;AAC1E,0EAA0E;AAC1E,8EAA8E;AAC9E,6EAA6E;AAC7E,8CAA8C;AAC9C,EAAE;AACF,qEAAqE;AACrE,iCAAiC;AACjC,EAAE;AACF,+EAA+E;AAC/E,qEAAqE;AACrE,4EAA4E;AAC5E,4EAA4E;AAC5E,sBAAsB;AACtB,wEAAwE;AACxE,6EAA6E;AAC7E,6EAA6E;AAC7E,+EAA+E;AAC/E,+EAA+E;AAC/E,mCAAmC;AACnC,EAAE;AACF,0EAA0E;AAC1E,6EAA6E;AAC7E,oEAAoE;AAEpE,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,iEAAiE;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,GAAG,MAAM,CAAC;AAE/C,2EAA2E;AAC3E,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,mBAAmB,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,GAAG,GAAG,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IAC3D,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC;AAC/E,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,mBAAmB,CAAC,MAAoB;IACtD,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,KAAK,cAAc,CAAC,CAAC;AACpF,CAAC;AAED,yEAAyE;AACzE,SAAS,SAAS,CAAC,MAAc;IAC/B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACjE,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,MAAoB,EAAE,MAAc;IACjE,MAAM,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IAC7F,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,GAAW,EAAE,QAAgB;IACxE,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IACzD,MAAM,SAAS,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7C,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC;gBACH,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBAC/B,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;oBAAE,OAAO,KAAK,CAAC;YACvE,CAAC;YACD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YACvD,IAAI,GAAG,GAAG,OAAO,GAAG,QAAQ;gBAAE,OAAO,KAAK,CAAC;YAC3C,IAAI,CAAC;gBACH,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,kEAAkE;YACpE,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,6CAA6C;QAC/C,CAAC;IACH,CAAC;AACH,CAAC;AASD,SAAS,aAAa,CAAC,OAAe,EAAE,IAAc,EAAE,GAAsB;IAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7E,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,MAAoB,EACpB,UAA0B,EAAE;IAE5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACtC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,CAAC,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACrF,OAAO,6IAA6I,CAAC;AACvJ,CAAC"}