@suss/adapter-typescript 0.21.0 → 0.22.0

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/dist/index.d.ts CHANGED
@@ -1,209 +1,11 @@
1
1
  import { SourceFile, Node, FunctionDeclaration, FunctionExpression, ArrowFunction, MethodDeclaration, CallExpression, PropertyAccessExpression, TaggedTemplateExpression, Project, ImportDeclaration, Symbol, Expression, NewExpression, Identifier } from 'ts-morph';
2
- import { PackDeclarations, TransparentWrapper, RawCondition, DiscoveryPattern, TerminalPattern, InputMappingPattern, EffectArg, CallOps, LanguageAdapter, PatternPack, ExtractorOptions, InvocationRecognizer, AccessRecognizer, RawCodeStructure, RawTerminal, RawBranch, configuredCallOption, RawDeclaredContract, ContractPattern, AstCapableOps, ResponsePropertyMapping } from '@suss/extractor';
3
- import { BehavioralSummary, MessageBusSemantics, DeployableUnit, BoundaryBinding, Predicate, TypeShape, ValueRef } from '@suss/behavioral-ir';
2
+ import { TransparentWrapper, RawCondition, DiscoveryPattern, TerminalPattern, InputMappingPattern, EffectArg, CallOps, LanguageAdapter, PatternPack, ExtractorOptions, TimingReport, CacheDiagnostic, ExtractionReport, InvocationRecognizer, AccessRecognizer, RawCodeStructure, RawTerminal, RawBranch, configuredCallOption, RawDeclaredContract, ContractPattern, AstCapableOps, ResponsePropertyMapping } from '@suss/extractor';
3
+ export { EmptyStage, ExtractionReport, PackFunnel, Timer, TimingReport, computeContentHash } from '@suss/extractor';
4
+ import { MessageBusSemantics, DeployableUnit, UnfollowedCall, BehavioralSummary, BoundaryBinding, Predicate, TypeShape, ValueRef } from '@suss/behavioral-ir';
4
5
  import { z } from 'zod';
6
+ import { ExplainStats, WhyExplained, ValueLocation } from '@suss/resolution';
7
+ export { ExplainStats, ValueLocation, WhyExplained } from '@suss/resolution';
5
8
  import { Proof, Atom } from '@suss/datalog';
6
- import { ResolutionExplanation } from '@suss/resolution';
7
-
8
- /**
9
- * cache.ts: the on-disk extraction cache.
10
- *
11
- * A run reuses the previous one's summaries whole when nothing
12
- * changed, and per file when some files did. The entry directory is
13
- * named after everything that has to agree before any reuse is sound:
14
- * schema version, adapter version and code hash, pack versions, the
15
- * extraction config stamp and the tsconfig path. Inside it, the
16
- * manifest records a stamp and content hash per file, each summary's
17
- * owning files, and per owning file the other files its walk read, so
18
- * a change to any of those re-extracts the owner instead of serving a
19
- * stale answer. The full design, including what per-file reuse can
20
- * and cannot promise, is in this package's README.
21
- */
22
-
23
- /** Reported by `lookup`: what the cache decided, and why. */
24
- interface CacheDiagnostic {
25
- kind: "hit" | "miss" | "partial";
26
- /**
27
- * Reason the lookup missed (only set when kind === "miss").
28
- * `key-changed` means the cache directory contains entries, but none
29
- * under this run's schema, adapter, packs and tsconfig path.
30
- * `files-changed` means the include set is not the one the entry
31
- * was written from.
32
- */
33
- missReason?: "no-manifest" | "key-changed" | "tsconfig-changed" | "files-changed";
34
- /** Set when kind === "partial". */
35
- partial?: {
36
- filesChanged: number;
37
- filesRemoved: number;
38
- rootsReused: number;
39
- rootsReextracted: number;
40
- rootsDeclined: number;
41
- summariesReused: number;
42
- };
43
- }
44
- /**
45
- * Result of a cache lookup. A hit gives back the whole summary set; a miss
46
- * says why, so a caller can render the reason.
47
- */
48
- type CacheLookup = {
49
- kind: "hit";
50
- summaries: BehavioralSummary[];
51
- diagnostic: CacheDiagnostic;
52
- } | {
53
- kind: "miss";
54
- diagnostic: CacheDiagnostic;
55
- };
56
-
57
- /** One pack's path through the funnel. */
58
- interface PackFunnel {
59
- pack: string;
60
- /**
61
- * What the pack calls this build of itself, or null when it declares
62
- * nothing. The cache keys on it, so a pack that never changes its
63
- * stamp can serve a later run with an earlier build's results.
64
- */
65
- version: string | null;
66
- /**
67
- * Whether the pack looks for units of its own at all. A pack made only
68
- * of recognisers contributes effects to units other packs found, so it
69
- * always discovers nothing, and that tells you nothing about whether
70
- * it is working.
71
- */
72
- discovers: boolean;
73
- /**
74
- * Whether the pack has any recognisers. Those fire inside units other
75
- * packs discovered, so a pack made only of them contributes effects
76
- * and never a summary.
77
- */
78
- recognizes: boolean;
79
- /**
80
- * Import specifiers that make a file relevant to this pack. Empty
81
- * for an ungated pack, which walks every file.
82
- */
83
- gates: string[];
84
- /**
85
- * Gate specifiers that do not resolve from the tsconfig. Non-empty
86
- * here usually means the target project's dependencies are not
87
- * installed, which stops symbol-resolution packs while leaving
88
- * textual-gate packs working, so the run half-succeeds in a way
89
- * nothing else surfaces.
90
- */
91
- unresolvedGates: string[];
92
- /** Files the pre-filter selected for this pack. */
93
- candidateFiles: number;
94
- /** Units discovered across those files. */
95
- unitsDiscovered: number;
96
- /**
97
- * Unit bodies any pack walked in the files this pack's gate selected.
98
- *
99
- * This is what a recogniser pack had the chance to fire on. Its own
100
- * discovery count tells you nothing, since it discovers nothing by
101
- * design, and neither does its candidate-file count, because a
102
- * recogniser only runs where some pack found a unit to walk.
103
- */
104
- unitsInGatedFiles: number;
105
- /** Effects this pack's recognisers returned. */
106
- effectsRecognized: number;
107
- /**
108
- * Units this pack kept. A unit an earlier pack already claimed is
109
- * dropped here, so a pack can discover plenty and keep none when it
110
- * comes after a pack that recognises the same code.
111
- */
112
- unitsClaimed: number;
113
- /**
114
- * Units this pack discovered twice over. Cross-pack dedup is the
115
- * point of the claim set, but a pack colliding with itself means its
116
- * own discovery patterns overlap and one of the two is being thrown
117
- * away without anybody deciding which.
118
- */
119
- selfCollisions: number;
120
- /** Summaries built from those units. */
121
- summariesProduced: number;
122
- /** Summaries in the finished run that credit this pack for finding them. */
123
- summariesBound: number;
124
- /**
125
- * Bound summaries on the provider side of their boundary.
126
- *
127
- * Kept apart from the count below because a provider that produced
128
- * no transitions is a different problem from a client that produced
129
- * none.
130
- */
131
- providerSummaries: number;
132
- /**
133
- * Summaries with at least one transition, of any role. A provider's
134
- * transitions say what it does with a request and a client's say what
135
- * it expects back, so a pack whose summaries have none has bound
136
- * something and described nothing either way.
137
- */
138
- summariesWithBehavior: number;
139
- /**
140
- * Where one of this pack's hooks threw. Every count above is a floor
141
- * while this is non-empty.
142
- */
143
- failures: PackFailure[];
144
- /**
145
- * Registration helpers this pack's config asked for that no call in
146
- * the run matched. The helper belongs to the project, so a spelling
147
- * that matches nothing is a config mistake with no other symptom: the
148
- * routes go missing and every count reads the same as a project
149
- * without them.
150
- */
151
- helpersUnmatched: string[];
152
- /**
153
- * What the pack wrote as data rather than as code, or null for a pack
154
- * written as a hand-rolled walk. This is the one thing in the funnel
155
- * that no run produces: it is the pack's own shape, and it is here so
156
- * the migration onto the declared surface can be measured.
157
- */
158
- declarations: PackDeclarations | null;
159
- }
160
- interface ExtractionReport {
161
- /** Files in the tsconfig include set, or null when the caller supplied a Project. */
162
- filesInProject: number | null;
163
- /** Files the bootstrap loaded and the extract walked. */
164
- filesWalked: number;
165
- packs: PackFunnel[];
166
- summaries: number;
167
- /**
168
- * Files whose exports the checker could not follow, so the run read
169
- * them as exporting nothing.
170
- *
171
- * Without this the artifact cannot tell the two apart: a module whose
172
- * barrel chain outran the call stack and a module that really does
173
- * export nothing both produce no summaries and exit 0.
174
- * Anything reachable only through these files is missing, and every
175
- * count below is a floor while this is non-empty.
176
- */
177
- filesWithUnreadableExports: string[];
178
- /**
179
- * The first stage whose count was zero, when the run produced
180
- * nothing. Null when the run produced summaries.
181
- */
182
- emptyStage: EmptyStage | null;
183
- /**
184
- * Reassigned names the run stated nothing for, because control flow
185
- * decides which write a reader sees. Each is a value resolution the
186
- * facts decline; the count across a large corpus says whether scoped
187
- * reaching definitions is worth writing.
188
- */
189
- reassignedNamesUnstated: number;
190
- }
191
- type EmptyStage = "tsconfig" | "gateResolution" | "candidateFiles" | "discovery" | "assembly";
192
- /**
193
- * A pack's hook throwing on one file.
194
- *
195
- * The run continues with the other files, so every count for that pack
196
- * afterwards is a floor rather than a total. Somebody reading those
197
- * counts has to be told, or a pack that broke looks the same as a pack
198
- * that looked and found nothing.
199
- */
200
- interface PackFailure {
201
- /** The hook that threw, called what a pack author would call it. */
202
- hook: string;
203
- /** The file the pack was reading. */
204
- file: string;
205
- message: string;
206
- }
207
9
 
208
10
  /** One question: do these files reach any of these packages. */
209
11
  interface FileSetQuery {
@@ -222,8 +24,8 @@ interface FileSetQuery {
222
24
  * files reach any of a set of packages, which a per-file import check
223
25
  * misses whenever a local barrel re-exports the SDK.
224
26
  *
225
- * Facts are extracted per file on demand and only along the module
226
- * edges a query follows, so cost tracks how indirect the code is.
27
+ * A query extracts the modules the rules ask for while answering it,
28
+ * so the files a question reads do not depend on what was asked before.
227
29
  */
228
30
 
229
31
  interface ExplainCallableOptions {
@@ -232,14 +34,6 @@ interface ExplainCallableOptions {
232
34
  /** How many derived nodes deep the proof walk goes; see `proofOf`. */
233
35
  maxDepth?: number;
234
36
  }
235
- /** What one witness re-evaluation cost, said rather than hidden. */
236
- interface ExplainStats {
237
- /** Facts the demand walk had extracted, which the proof pass reran. */
238
- baseFacts: number;
239
- /** Facts the exhaustive pass derived on top of those. */
240
- derivedFacts: number;
241
- evaluateMs: number;
242
- }
243
37
  interface ExplainedResolution {
244
38
  /** The node the value comes down to. */
245
39
  target: Node;
@@ -263,7 +57,7 @@ declare class ResolutionStore {
263
57
  * extraction elsewhere cannot change an entry.
264
58
  */
265
59
  private readonly exportTables;
266
- /** Files the most recent wave walk entered, for the memo to keep. */
60
+ /** Files the most recent query read, for the memo to keep. */
267
61
  private lastQueryWalked;
268
62
  private readonly declarations;
269
63
  private readonly graph;
@@ -286,10 +80,10 @@ declare class ResolutionStore {
286
80
  resolveCallableSources(value: Node, alsoFrom?: SourceFile): Node[];
287
81
  /**
288
82
  * The witness proof behind `resolveCallable`'s answer. Resolves the
289
- * value first, which walks files and extracts facts in the usual
290
- * waves, then re-evaluates the rules over those base facts under the
291
- * witness algebra and rebuilds the proof of the answer. Null when
292
- * the value does not resolve at all.
83
+ * value first, which extracts the files the question demands, then
84
+ * re-evaluates the rules over those base facts under the witness
85
+ * algebra and rebuilds the proof of the answer. Null when the value
86
+ * does not resolve at all.
293
87
  */
294
88
  explainCallable(value: Node, options?: ExplainCallableOptions): ExplainedResolution | null;
295
89
  resolveObject(value: Node): Node | null;
@@ -313,10 +107,8 @@ declare class ResolutionStore {
313
107
  */
314
108
  subjectCandidateCountOf(value: Node, importModule: string, importName: string): number;
315
109
  /**
316
- * The single-answer policy over the written-value walk, then the
317
- * origin check on the one candidate. A candidate failing the check
318
- * is settled refusal rather than a reason to widen: its own file's
319
- * import facts are already in, and more files only add candidates.
110
+ * The single-answer policy over the written-value chain, then the
111
+ * origin check on the one candidate.
320
112
  */
321
113
  private lookupSubjectConstruction;
322
114
  /**
@@ -348,8 +140,8 @@ declare class ResolutionStore {
348
140
  path: string[];
349
141
  }>;
350
142
  /**
351
- * The batched form: one demand set, one derivation, one widening
352
- * walk shared by every value. A discovery pass asks about every
143
+ * The batched form: one demand set, one derivation, one round of
144
+ * extraction shared by every value. A discovery pass asks about every
353
145
  * callee in a file, and per-value queries would re-pay demand
354
146
  * clearing and re-derivation once per call site.
355
147
  */
@@ -365,14 +157,22 @@ declare class ResolutionStore {
365
157
  */
366
158
  private sharedDeclarationFor;
367
159
  private lookupImportOrigins;
160
+ private lookupImportedNames;
161
+ private askAbout;
368
162
  /**
369
- * Null tells the walk to keep widening. A value that landed in a
370
- * package returns empty instead, because a library's own body is not
371
- * here to read and widening would never find anything.
163
+ * Extract the seed files, then every module the rules ask for, until
164
+ * they ask for nothing new. The files a question reads are then fixed
165
+ * by the question alone, so its answer does not depend on what an
166
+ * earlier question left in the store.
372
167
  */
373
- private lookupImportedNames;
374
- private resolveByWaves;
375
- private walkForAnswer;
168
+ private extractDemanded;
169
+ /**
170
+ * Module keys the rules are waiting on. Demand facts are cleared
171
+ * between queries, so the demand relations contain this query's
172
+ * alone; the unrestricted program has none, and follows the imports
173
+ * of the files read this round instead.
174
+ */
175
+ private demandedModules;
376
176
  /**
377
177
  * The question and the chain that settled it are dropped. The files
378
178
  * the query extracted stay, since the next query reads the same facts.
@@ -380,6 +180,13 @@ declare class ResolutionStore {
380
180
  */
381
181
  private forgetQuery;
382
182
  private wantValue;
183
+ private wantExportsOf;
184
+ /**
185
+ * Discovery walks the table in order, and the rounds derive it in
186
+ * the order files arrived. Deriving it again from the demand alone,
187
+ * over the loaded closure, orders it by the file's own statements.
188
+ */
189
+ private rederiveExportsOf;
383
190
  /**
384
191
  * File extraction only reaches values hanging off exports, and a query
385
192
  * can be rooted anywhere, so the queried value gets its own facts.
@@ -398,10 +205,10 @@ declare class ResolutionStore {
398
205
  /**
399
206
  * Read these files' facts now, before anything asks a question.
400
207
  *
401
- * A query widens along the imports of the file it starts in, which
402
- * is where a value's definition is. What a caller passed is the other
208
+ * A query follows the imports of the file it starts in, which is
209
+ * where a value's definition is. What a caller passed is the other
403
210
  * direction, so a question about a parameter is answered only by
404
- * files the walk never reaches on its own.
211
+ * files the query never reaches on its own.
405
212
  */
406
213
  extractFiles(sourceFiles: Iterable<SourceFile>): void;
407
214
  /**
@@ -411,28 +218,23 @@ declare class ResolutionStore {
411
218
  */
412
219
  filesImportingTransitively(fileSets: ReadonlyArray<FileSetQuery>): ReadonlyArray<ReadonlySet<SourceFile>>;
413
220
  /**
414
- * The calls behind a receiver that `matches` accepts, walked out in
415
- * waves the way every question is. The wave ends as soon as one file
416
- * yields a match, and the caller applies the single-answer policy to
417
- * the set; the resolution README's anchor section says why the rules
418
- * cannot rank a nearer call above a farther one.
221
+ * The calls behind a receiver that `matches` accepts. The caller
222
+ * applies the single-answer policy to the set; the resolution
223
+ * README's anchor section says why the rules cannot rank a nearer
224
+ * call above a farther one.
419
225
  */
420
226
  anchorCallsOf(value: Node, matches: (call: Node) => boolean): Node[];
421
227
  /**
422
228
  * Every name a module exports and the values behind each, with
423
- * re-export chains flattened by the rules. The frontier follows
229
+ * re-export chains flattened by the rules. The demand follows
424
230
  * re-export targets only, so a barrel of barrels extracts its own
425
231
  * chain and nothing beside it, to any depth.
426
232
  */
427
233
  exportsOf(sourceFile: SourceFile): Map<string, Node[]>;
428
234
  private collectExports;
429
- /** Module keys this file re-exports from, read off its own facts. */
430
- private reExportTargetsOf;
431
235
  /**
432
- * Null keeps the wave walk widening; any candidate at all ends it,
433
- * since more files can only add candidates, never take one away. The
434
- * single-answer policy stays with the callers: picking one of two
435
- * would make the result depend on the order the facts came in.
236
+ * The single-answer policy stays with the callers: a value with two
237
+ * sources is something to say at the site, not something to pick from.
436
238
  */
437
239
  private lookupSources;
438
240
  private derive;
@@ -454,44 +256,6 @@ type FunctionRoot = FunctionDeclaration | FunctionExpression | ArrowFunction | M
454
256
  */
455
257
  declare function collectAncestorBranches(terminalNode: Node, functionRoot: FunctionRoot): RawCondition[];
456
258
 
457
- /**
458
- * unfollowedCall.ts: naming the calls the reachable closure stops at.
459
- *
460
- * The closure follows a call by resolving its callee to a function with a
461
- * body. When that fails the edge is dropped, and a unit whose body is full
462
- * of dropped edges produces the same empty summary as a unit that does
463
- * nothing. This module says which kind of stop a call site is, and which
464
- * kinds are worth leaving a gap for.
465
- *
466
- * The README beside this file explains where that line is drawn, and why
467
- * a call into a dependency stays on the other side of it.
468
- */
469
-
470
- /**
471
- * Why the walk stopped.
472
- *
473
- * `noBody` states a shape and nothing else: a method on an interface, an
474
- * abstract method, an ambient declaration. `unsettledValue` is declared
475
- * as something other than a function, with something in it that could
476
- * not be read. `multipleSources` reaches two different functions, so no
477
- * single body can be followed. `outsideRun` is a declaration in a
478
- * dependency, whose source this run never read. `noDeclaration` is a
479
- * callee nothing declares, which is what a call on an untyped value
480
- * comes to. `callerSupplied` is a parameter of the function being
481
- * scanned, so the call runs whatever its caller handed in.
482
- * `multipleReceivers` is a registration whose receiver comes down to
483
- * more than one thing, so nothing says which one it registers on.
484
- */
485
- type UnfollowedReason = "noBody" | "unsettledValue" | "multipleSources" | "outsideRun" | "noDeclaration" | "callerSupplied" | "multipleReceivers";
486
- /** One call the walk met and could not follow. */
487
- interface UnfollowedCall {
488
- /** The callee as the source writes it, `this.dao.getEditions` say. */
489
- readonly callee: string;
490
- readonly reason: UnfollowedReason;
491
- /** How many things the walk reached where it needed one. */
492
- readonly candidates?: number;
493
- }
494
-
495
259
  interface ClientCallSite {
496
260
  callExpression: CallExpression;
497
261
  /** Method name on the client object (e.g. "getUser"), null for bare calls like fetch() */
@@ -717,23 +481,6 @@ interface ExpandedRegistrations {
717
481
  */
718
482
  declare function discoverUnits(sourceFile: SourceFile, patterns: DiscoveryPattern[], resolution?: ResolutionStore, mountPrefixes?: MountPrefixIndex, expandedElsewhere?: ExpandedRegistrations): DiscoveredUnit[];
719
483
 
720
- interface TimingReport {
721
- totalMs: number;
722
- phases: Array<{
723
- label: string;
724
- durationMs: number;
725
- calls: number;
726
- }>;
727
- }
728
- interface Timer {
729
- /** Run `fn`, accumulate wall time under `label`, return its result. */
730
- time<T>(label: string, fn: () => T): T;
731
- /** Async variant: same accumulation rule. */
732
- timeAsync<T>(label: string, fn: () => Promise<T>): Promise<T>;
733
- /** Snapshot of all accumulated phases, ordered by total time descending. */
734
- report(): TimingReport;
735
- }
736
-
737
484
  /**
738
485
  * Nested function nodes a pack claimed as sub-units. The unit-body
739
486
  * walkers stop at these so the sub-unit's behavior isn't double-counted
@@ -741,6 +488,21 @@ interface Timer {
741
488
  */
742
489
  type DescentBarriers = ReadonlySet<Node>;
743
490
 
491
+ /**
492
+ * invocationEffects.ts: capture every call in a unit's body as an
493
+ * `invocation` RawEffect, wherever the call is written: a statement of
494
+ * its own, an argument, an element of a literal, an arm of a ternary,
495
+ * the receiver of a method chain. Which calls a summary keeps is
496
+ * decided in assembly by node identity, so no position needs a rule of
497
+ * its own here.
498
+ *
499
+ * The walk descends into nested arrows and function expressions, since
500
+ * their calls are behavior of the enclosing unit, and stops at named
501
+ * nested declarations, pack-declared sub-unit boundaries and
502
+ * decorators. The README beside this file says how the effects are
503
+ * ordered and what `async` means.
504
+ */
505
+
744
506
  /**
745
507
  * Context handed to TypeScript-adapter access recognizers: sister
746
508
  * to TsInvocationRecognizerContext but for property-access nodes.
@@ -1193,23 +955,7 @@ interface WhySessionOptions {
1193
955
  /** The project root, which paths in every answer come out relative to. */
1194
956
  dir: string;
1195
957
  }
1196
- /** A value or function said the way an answer prints it. */
1197
- interface ValueLocation {
1198
- name: string;
1199
- /** Relative to the session root when under it, absolute otherwise. */
1200
- file: string;
1201
- line: number;
1202
- }
1203
- interface WhyExplained {
1204
- explanation: ResolutionExplanation;
1205
- /** The chain's atoms, each said in source terms. */
1206
- chain: string[];
1207
- /** The chain and its reasons as printable lines. */
1208
- lines: string[];
1209
- target: ValueLocation;
1210
- stats: ExplainStats;
1211
- }
1212
- declare class WhySession {
958
+ declare class TypeScriptWhySession {
1213
959
  private readonly project;
1214
960
  private readonly store;
1215
961
  private readonly root;
@@ -1254,87 +1000,6 @@ declare function exportedDeclarationsOf(sourceFile: SourceFile, resolution: Reso
1254
1000
  */
1255
1001
  declare function resolveAliasedSymbol(symbol: Symbol): Symbol | undefined;
1256
1002
 
1257
- /**
1258
- * Checks that tell you a pack is probably not working.
1259
- *
1260
- * The funnel shows where a run's counts dropped to zero. These checks
1261
- * ask something narrower of each pack on its own: did this pack lose
1262
- * everything at some stage, when the stage before it had something?
1263
- *
1264
- * A pack that finds nothing in a codebase that does not use its library
1265
- * is working correctly, so a count of zero on its own is never the
1266
- * signal. What makes zero a signal is the count before it. A pack whose
1267
- * import gate picked forty files and whose discovery then found no unit
1268
- * in any of them said "look here" and failed to look. Every later stage
1269
- * works the same way, which is why these checks are one comparison run
1270
- * over a list of pairs rather than one check written per stage.
1271
- */
1272
-
1273
- /** One thing that looks wrong, reported the way the dogfood invariants are. */
1274
- interface HealthViolation {
1275
- label: string;
1276
- detail: string;
1277
- }
1278
- interface HealthCheck {
1279
- /** The property being checked, as something either true or false. */
1280
- name: string;
1281
- /**
1282
- * The short word this check reports under, kebab-case.
1283
- *
1284
- * It is the first column of every line the check prints, so a reader
1285
- * works out what it means once and recognises it after that. `name`
1286
- * is written as an assertion and would read backwards over a list of
1287
- * things failing it.
1288
- */
1289
- code: string;
1290
- /**
1291
- * Who the finding is addressed to.
1292
- *
1293
- * A `run` check found something about the code in front of it, and
1294
- * the person who started the run can do something about it: drop a
1295
- * pack, install a dependency, open an issue with the file that broke.
1296
- * A `pack` check found something about how a pack was built, which
1297
- * only whoever ships that pack can fix. Printing the second kind on
1298
- * every run would teach people to skim past the first.
1299
- */
1300
- audience: "run" | "pack";
1301
- violations: HealthViolation[];
1302
- }
1303
- /**
1304
- * What one pack paid for what it matches.
1305
- *
1306
- * Expressiveness is bought link by link, and #542 asks for the price to
1307
- * be printed. A pack with every link written as data runs on any
1308
- * adapter with the executor ops. A link written as a function runs only
1309
- * where its own language does, and one that reads the syntax tree is
1310
- * the floor. All three are allowed, and this says which is which.
1311
- */
1312
- interface PackGradient {
1313
- pack: string;
1314
- /** Links written as data, across every declaration. */
1315
- dataLinks: number;
1316
- /** Links written as a function, as "declaration.question". */
1317
- functionLinks: string[];
1318
- /** Links whose function reads the adapter's own syntax tree. */
1319
- astLinks: string[];
1320
- /** Declarations shipped without a line of code to run against them. */
1321
- withoutExample: string[];
1322
- }
1323
- /**
1324
- * Run every health check over one extraction report and return what
1325
- * fired, grouped by which check caught it.
1326
- */
1327
- declare function evaluatePackHealth(report: ExtractionReport): HealthCheck[];
1328
- /**
1329
- * The health checks that fired, as lines for a terminal.
1330
- *
1331
- * `audiences` is who the caller is printing for. It is required because
1332
- * no single choice suits every caller: a CLI run prints what the person
1333
- * who started it can act on, while a run a pack author is reading wants
1334
- * both kinds.
1335
- */
1336
- declare function formatPackHealth(checks: ReadonlyArray<HealthCheck>, audiences: ReadonlyArray<HealthCheck["audience"]>): string;
1337
-
1338
1003
  /**
1339
1004
  * Parse a ts-morph Expression into a structured Predicate.
1340
1005
  * Returns null when the expression can't be decomposed cleanly.
@@ -1580,35 +1245,30 @@ declare function createTsSubUnitContext(): TsSubUnitContext;
1580
1245
  */
1581
1246
  declare function workspaceRootFor(anchor: string): string;
1582
1247
 
1583
- declare const ADAPTER_VERSION = "0.2.1";
1584
1248
  /**
1585
- * Content hash of the given files, in the order they arrive. Empty when
1586
- * the list is empty or a file cannot be read, so a caller that could not
1587
- * locate a file gets the same "no stamp" result as a run from source
1588
- * rather than a hash of a shorter list.
1249
+ * version.ts: this adapter's own half of the cache key.
1589
1250
  *
1590
- * The caller resolves the paths, because where a specifier resolves to
1591
- * depends on which package is asking.
1251
+ * `ADAPTER_VERSION` is the hand-bumped semver. Bump it on any change
1252
+ * that affects extraction output: IR shape, discovery semantics,
1253
+ * terminal classification, anything that would invalidate previously
1254
+ * cached summaries. `createAdapterStamp` (from `@suss/extractor`) folds
1255
+ * it together with a hash of this adapter's own loaded code, so a
1256
+ * rebuilt dev build invalidates the cache even when nobody remembered
1257
+ * to bump the constant. See that package's README for the full design.
1592
1258
  */
1593
- declare function computeContentHash(paths: readonly string[]): string;
1259
+
1260
+ declare const ADAPTER_VERSION = "0.2.1";
1594
1261
  /**
1595
1262
  * Compute a cache-friendly identity for an adapter+packs combination.
1596
- * Stable across processes given the same inputs; bumps when any pack
1597
- * arrives with a new version stamp, the adapter version changes, or the
1598
- * loaded adapter dist file changes (dev-mode rebuild auto-invalidation).
1599
1263
  *
1600
1264
  * A pack's stamp is whatever the caller that loaded the pack put there.
1601
1265
  * The adapter takes packs as plain objects and cannot tell where one
1602
1266
  * came from, so folding the config and the code into the stamp is the
1603
1267
  * loader's job.
1604
- *
1605
- * A source run says as much in the digest rather than leaving the
1606
- * adapter out of it. Nothing writes under that digest today, and a key
1607
- * that says "source" cannot be mistaken for one built from the code.
1608
1268
  */
1609
1269
  declare function computeAdapterPacksDigest(packVersions: ReadonlyArray<{
1610
1270
  name: string;
1611
1271
  version?: string;
1612
1272
  }>): string;
1613
1273
 
1614
- export { ADAPTER_VERSION, type Accessed, type CacheDiagnostic, type CacheLookup, type ClientCallSite, type ConfiguredCallContext, type ConfiguredCallRead, type ConfiguredCallSpec, type ContractReadResult, type DiscoveredUnit, type EmptyStage, type ExplainCallableOptions, type ExplainStats, type ExplainedResolution, type ExtractionReport, type FoundTerminal, type FunctionRoot, type HealthCheck, type HealthViolation, type ImportScanOptions, type ObservedStubCall, type PackFunnel, type PackGradient, type ReadNameOptions, ResolutionStore, type StubCallEvidence, type StubEvidenceOptions, type Timer, type TimingReport, type TsDiscoveryContext, type TsInvocationRecognizerContext, type TsJsxAttributeLocation, type TsSubUnitContext, type TypeScriptAdapter, type TypeScriptAdapterConfig, type ValueLocation, type WhyExplained, WhySession, type WhySessionOptions, accessContextFor, buildProjectHelperIndex, callOpsFor, collectAncestorBranches, collectClientFieldAccesses, computeAdapterPacksDigest, computeContentHash, createProjectWithoutTsconfig, createTsDiscoveryContext, createTsSubUnitContext, createTypeScriptAdapter, discoverUnits, evaluatePackHealth, exportedDeclarationsOf, extractCodeStructure, extractRawBranches, findNearestTsconfig, findTerminals, formatPackHealth, functionTargetOf, importDeclarationsOf, importedNamesOf, importedRootsOf, invocationContextFor, isImportedFrom, methodDeclaredIn, namedImportsOf, parseConditionExpression, readConfiguredCall, readContract, readContractForClientCall, readName, resolveAliasedSymbol, resolveSubject, rootIdentifier, stubEvidence, stubEvidenceIn, workspaceRootFor };
1274
+ export { ADAPTER_VERSION, type Accessed, type ClientCallSite, type ConfiguredCallContext, type ConfiguredCallRead, type ConfiguredCallSpec, type ContractReadResult, type DiscoveredUnit, type ExplainCallableOptions, type ExplainedResolution, type FoundTerminal, type FunctionRoot, type ImportScanOptions, type ObservedStubCall, type ReadNameOptions, ResolutionStore, type StubCallEvidence, type StubEvidenceOptions, type TsDiscoveryContext, type TsInvocationRecognizerContext, type TsJsxAttributeLocation, type TsSubUnitContext, type TypeScriptAdapter, type TypeScriptAdapterConfig, TypeScriptWhySession, type WhySessionOptions, accessContextFor, buildProjectHelperIndex, callOpsFor, collectAncestorBranches, collectClientFieldAccesses, computeAdapterPacksDigest, createProjectWithoutTsconfig, createTsDiscoveryContext, createTsSubUnitContext, createTypeScriptAdapter, discoverUnits, exportedDeclarationsOf, extractCodeStructure, extractRawBranches, findNearestTsconfig, findTerminals, functionTargetOf, importDeclarationsOf, importedNamesOf, importedRootsOf, invocationContextFor, isImportedFrom, methodDeclaredIn, namedImportsOf, parseConditionExpression, readConfiguredCall, readContract, readContractForClientCall, readName, resolveAliasedSymbol, resolveSubject, rootIdentifier, stubEvidence, stubEvidenceIn, workspaceRootFor };