@nudojs/service 0.2.0 → 0.3.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +27 -0
  3. package/dist/index.d.ts +638 -5
  4. package/dist/index.js +4439 -208
  5. package/package.json +17 -4
  6. package/src/__tests__/abs-bindings.test.ts +53 -0
  7. package/src/__tests__/abs-call-records.test.ts +33 -0
  8. package/src/__tests__/abs-calls.test.ts +59 -0
  9. package/src/__tests__/abs-module-cache.test.ts +121 -0
  10. package/src/__tests__/abs-modules-graph.test.ts +100 -0
  11. package/src/__tests__/abs-typevalue-diff.test.ts +111 -0
  12. package/src/__tests__/analyzer.test.ts +745 -2
  13. package/src/__tests__/as-replace.test.ts +165 -0
  14. package/src/__tests__/bpath-arg-provenance.test.ts +104 -0
  15. package/src/__tests__/bpath-as.test.ts +54 -0
  16. package/src/__tests__/bpath-cache-key.test.ts +33 -0
  17. package/src/__tests__/bpath-calls.test.ts +55 -0
  18. package/src/__tests__/bpath-diagnostics.test.ts +78 -0
  19. package/src/__tests__/bpath-env-modules.test.ts +30 -0
  20. package/src/__tests__/bpath-env.test.ts +80 -0
  21. package/src/__tests__/bpath-hosted-skip.test.ts +71 -0
  22. package/src/__tests__/bpath-import-default-ns.test.ts +106 -0
  23. package/src/__tests__/bpath-method-dedupe.test.ts +65 -0
  24. package/src/__tests__/bpath-method-diag.test.ts +45 -0
  25. package/src/__tests__/bpath-module-diags.test.ts +101 -0
  26. package/src/__tests__/bpath-path-env.test.ts +46 -0
  27. package/src/__tests__/bpath-reexport.test.ts +131 -0
  28. package/src/__tests__/bpath-replace.test.ts +52 -0
  29. package/src/__tests__/bpath-require.test.ts +66 -0
  30. package/src/__tests__/bpath-run.test.ts +109 -0
  31. package/src/__tests__/case-emitter.test.ts +636 -0
  32. package/src/__tests__/cjs-require.test.ts +54 -0
  33. package/src/__tests__/diagnostics.test.ts +60 -0
  34. package/src/__tests__/dts-generator.test.ts +290 -6
  35. package/src/__tests__/fn-cache-evict.test.ts +56 -0
  36. package/src/__tests__/fn-sig-impl.test.ts +247 -0
  37. package/src/__tests__/guard-generator.test.ts +29 -0
  38. package/src/__tests__/harvest-auto.test.ts +43 -0
  39. package/src/__tests__/harvest-node.test.ts +24 -0
  40. package/src/__tests__/harvest-package.test.ts +38 -0
  41. package/src/__tests__/harvest-to-abs.test.ts +46 -0
  42. package/src/__tests__/hover-intension.test.ts +39 -0
  43. package/src/__tests__/infer-json.test.ts +35 -0
  44. package/src/__tests__/integration.test.ts +421 -0
  45. package/src/__tests__/m3-intension.test.ts +28 -0
  46. package/src/__tests__/mock-seed-fingerprint.test.ts +64 -0
  47. package/src/__tests__/schema-generator.test.ts +38 -0
  48. package/src/__tests__/session-cache-evict.test.ts +90 -0
  49. package/src/__tests__/static-imports.test.ts +44 -0
  50. package/src/abs-modules-graph.ts +387 -0
  51. package/src/analysis-file-cache.ts +51 -0
  52. package/src/analyzer.ts +2569 -94
  53. package/src/bpath-diagnostics.ts +283 -0
  54. package/src/bpath-run.ts +409 -0
  55. package/src/case-emitter.ts +477 -0
  56. package/src/dts-generator.ts +220 -24
  57. package/src/env-to-abs.ts +57 -0
  58. package/src/fn-analysis-cache.ts +119 -0
  59. package/src/guard-generator.ts +57 -0
  60. package/src/harvest-auto.ts +86 -0
  61. package/src/harvest-node.ts +48 -0
  62. package/src/harvest-package.ts +204 -0
  63. package/src/harvest-to-abs.ts +129 -0
  64. package/src/index.ts +128 -0
  65. package/src/infer-json.ts +137 -0
  66. package/src/load-module.ts +34 -0
  67. package/src/mock-abs.ts +275 -0
  68. package/src/schema-generator.ts +43 -0
  69. package/src/semantic-tokens.ts +216 -0
  70. package/src/session-cache.ts +50 -0
  71. package/src/static-imports.ts +241 -0
  72. package/src/target-path.ts +17 -0
package/dist/index.d.ts CHANGED
@@ -1,5 +1,22 @@
1
- import { Node } from '@babel/types';
2
- import { TypeValue } from '@nudojs/core';
1
+ import { Node, File } from '@babel/types';
2
+ import { TypeValue, Abs, PolyFn, AbsModuleExports, AstEnv, Phi, BMemberDiag, BCallRecord, TranspiledCallResult } from '@nudojs/core';
3
+ export { AbsInlay, BMemberDiag, collectAbsInlays } from '@nudojs/core';
4
+ import { CallRecord } from '@nudojs/cli/evaluator';
5
+ export { CallRecord } from '@nudojs/cli/evaluator';
6
+ import { HarvestedEnv } from '@nudojs/harvester';
7
+ import { FunctionWithDirectives } from '@nudojs/parser';
8
+
9
+ /**
10
+ * Per-function FunctionAnalysis cache (body-edit: recompute only dirty fns).
11
+ * Cleared together with B-path / whole-file analysis caches.
12
+ */
13
+
14
+ declare function clearFnAnalysisCache(): void;
15
+ /**
16
+ * Dependency content changed: drop every per-fn entry for these entry files.
17
+ * Keys are `filePath\0...`, so a prefix scan is sound and cheap at LRU size.
18
+ */
19
+ declare function evictFnAnalysisCacheForFiles(files: string[]): number;
3
20
 
4
21
  type SourceLocation = {
5
22
  start: {
@@ -18,6 +35,14 @@ type Diagnostic = {
18
35
  severity: DiagnosticSeverity;
19
36
  message: string;
20
37
  tags?: DiagnosticTag[];
38
+ code?: string;
39
+ suggestions?: string[];
40
+ data?: unknown;
41
+ /** provenance of the receiver value (callsite argument that flowed into the error) */
42
+ origin?: {
43
+ line: number;
44
+ column: number;
45
+ };
21
46
  };
22
47
  type CaseResult = {
23
48
  name: string;
@@ -25,13 +50,45 @@ type CaseResult = {
25
50
  result: TypeValue;
26
51
  throws: TypeValue;
27
52
  throwLoc?: SourceLocation;
53
+ source?: "directive" | "callsite";
54
+ /** `@nudo:case "name" (…) => expected` — presence means the case is a test assertion */
55
+ expected?: TypeValue;
56
+ /** number of additional call sites folded into a symbolic case */
57
+ aggregatedFrom?: number;
58
+ /**
59
+ * 内涵摘要(代数 generalize):无损 Abs + term/pred/conf。
60
+ * 仅在 entry@ / call@(Abs 路径)填充;外延 TypeValue 不变。
61
+ */
62
+ intension?: {
63
+ display?: string;
64
+ term?: string;
65
+ pred?: string;
66
+ conf?: string;
67
+ /** 无损 Abs 单行(formatAbs) */
68
+ abs?: string;
69
+ /** 无损 Abs 多行(formatAbsMultiline) */
70
+ absMultiline?: string;
71
+ };
72
+ /** 无损 Abs(denote/守卫用);仅 Abs 路径 case 填充 */
73
+ abs?: Abs;
28
74
  };
29
75
  type FunctionAnalysis = {
30
76
  name: string;
31
77
  loc: SourceLocation;
78
+ paramNames: string[];
32
79
  cases: CaseResult[];
33
80
  combined?: TypeValue;
34
- assertionErrors?: string[];
81
+ entryOnly?: boolean;
82
+ skipped?: boolean;
83
+ /**
84
+ * True for functions collected from CJS-style bindings/assignments
85
+ * (`exports.X = fn`, `module.exports = fn`, `const f = fn`): their name has
86
+ * no declaration-level stability, so .d.ts generation skips them while
87
+ * infer/JSON output still reports them.
88
+ */
89
+ noDeclaration?: boolean;
90
+ /** absolute path of the module this function is imported from (externalFunctions only) */
91
+ fromModule?: string;
35
92
  };
36
93
  type BindingInfo = {
37
94
  type: TypeValue;
@@ -46,15 +103,80 @@ type AnalysisResult = {
46
103
  functions: FunctionAnalysis[];
47
104
  diagnostics: Diagnostic[];
48
105
  bindings: Map<string, BindingInfo>;
106
+ /**
107
+ * Node identity is from the analysis-time parse. A later re-parse of the
108
+ * same source returns a *different* File (new Nodes) if the AST LRU evicted
109
+ * the original — lookups must use the File that produced this result, not a
110
+ * freshly parsed one. getTypeAtPosition rebuilds its own map and is unaffected.
111
+ */
49
112
  nodeTypeMap: Map<Node, TypeValue>;
50
113
  caseHints: CaseHint[];
114
+ /** functions imported from other modules, synthesized from cross-file call sites observed while analyzing this file */
115
+ externalFunctions?: FunctionAnalysis[];
51
116
  };
52
117
  type CompletionItem = {
53
118
  label: string;
54
119
  kind: "property" | "method" | "variable";
55
120
  detail?: string;
56
121
  };
57
- declare function analyzeFile(filePath: string, source: string, activeCases?: Map<string, number>): AnalysisResult;
122
+ type SymbolInfo = {
123
+ name: string;
124
+ kind: "function" | "variable" | "class" | "parameter";
125
+ loc: SourceLocation;
126
+ uri?: string;
127
+ };
128
+ type ReferenceInfo = {
129
+ name: string;
130
+ loc: SourceLocation;
131
+ uri?: string;
132
+ };
133
+ type SymbolTable = {
134
+ definitions: Map<string, SymbolInfo>;
135
+ references: ReferenceInfo[];
136
+ };
137
+ /** mtime 边缓存:key 为文件路径,edges 为已抽取的相对 import 边(与 buildModuleGraph 返回语义一致)。 */
138
+ type ModuleGraphCache = Map<string, {
139
+ mtimeMs: number;
140
+ size: number;
141
+ edges: string[];
142
+ }>;
143
+ /** Statically extract each file's relative import edges (extension resolution identical to CLI resolveModule: ''/'.js'/'.ts'/'.mjs'; bare npm specifiers skipped). */
144
+ declare function buildModuleGraph(files: string[], cache?: ModuleGraphCache): {
145
+ imports: Map<string, Set<string>>;
146
+ dependents: Map<string, Set<string>>;
147
+ };
148
+ /** changed plus its transitive dependents (reverse-edge BFS); cycle-safe via visited. */
149
+ declare function computeDirtySet(dependents: Map<string, Set<string>>, changedFile: string): string[];
150
+ /** Topological order with dependencies before dependents (only imports edges internal to dirty; cycles tolerated — remaining files appended in arbitrary order). */
151
+ declare function topoSortDirty(imports: Map<string, Set<string>>, dirty: string[]): string[];
152
+ /**
153
+ * Async entry to analyzeFile: preloads path-based env files
154
+ * (`/// @nudo:env ./nudo-harvest-node.ts`) via dynamic import — impossible
155
+ * synchronously in ESM — then runs the sync analysis, which picks the
156
+ * preloaded factories up from the env-loader cache. The sync analyzeFile
157
+ * signature is unchanged for existing consumers (LSP, MCP, vite-plugin).
158
+ */
159
+ declare function analyzeFileAsync(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: CallRecord[]): Promise<AnalysisResult>;
160
+ /**
161
+ * 调用点发现(阶段一):在"使用现场"文件(测试 / 上层应用)中求值
162
+ * 顶层代码,收集它对(外部模块导出的)函数的调用记录。每条记录带
163
+ * 真实的实参类型与结果类型——后续 analyzeFile 将其注入合成 case,
164
+ * 使被使用方从 entry-only(参数全 unknown)升级为真实调用形态。
165
+ *
166
+ * 只做求值与记录,不产出诊断;求值异常不抛出(使用现场文件可能
167
+ * 依赖未 mock 的全局,收集不到就收集不到,不能拖垮主分析)。
168
+ */
169
+ declare function collectCallRecords(filePath: string, source: string): CallRecord[];
170
+ /**
171
+ * 整文件分析。同 (path, source, cases, external) 命中 memo → O(1)。
172
+ * 不再每次 clearBPathCache:B 路径按本文件 source 键控。
173
+ *
174
+ * 宿主契约:入口 source 未变但依赖模块内容变了时,必须调用
175
+ * `evictBPathCacheForFiles` / `evictAnalysisFileCacheForFiles` /
176
+ * `evictFnAnalysisCacheForFiles`(LSP 已接好)。非 LSP 宿主
177
+ * (CLI watch / vite-plugin)在 dep 变更时应 `clearBPathCache()` 或上述逐出。
178
+ */
179
+ declare function analyzeFile(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: CallRecord[]): AnalysisResult;
58
180
  type CaseInfo = {
59
181
  functionName: string;
60
182
  caseName: string;
@@ -68,10 +190,521 @@ declare function getCasesForFile(filePath: string, source: string): {
68
190
  }[];
69
191
  loc: SourceLocation;
70
192
  }[];
193
+ /** Async entry to getTypeAtPosition with path-env preloading (see analyzeFileAsync). */
194
+ declare function getTypeAtPositionAsync(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): Promise<TypeValue | null>;
71
195
  declare function getTypeAtPosition(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): TypeValue | null;
196
+ type HoverInfo = {
197
+ /** 外延 TypeValue 展示(bridge 有损,仅兜底) */
198
+ typeText: string;
199
+ /** 内涵签名(代数 generalize) */
200
+ intension?: string;
201
+ /** 无损 Abs 单行展示(shape / term / pred / conf) */
202
+ abs?: string;
203
+ /** 无损 Abs 多行展示 */
204
+ absMultiline?: string;
205
+ };
206
+ /**
207
+ * LSP hover:优先无损 Abs(类型即计算本体),TypeValue 仅作外延对照。
208
+ * 节点表也是 Abs(collectAbsNodeTypes),不经 bridge。
209
+ */
210
+ declare function getHoverAtPosition(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): HoverInfo | null;
72
211
  declare function getCompletionsAtPosition(filePath: string, source: string, line: number, column: number): CompletionItem[];
73
212
 
213
+ /**
214
+ * `nudo infer --json` 稳定契约 v1(CI / Agent)。
215
+ *
216
+ * 字段只增不改语义:
217
+ * - ext_*:TypeValue 投影字符串(有损,兼容)
218
+ * - intension.abs*:无损 Abs 展示(主线)
219
+ */
220
+
221
+ type InferJsonCase = {
222
+ name: string;
223
+ /** TypeValue 投影(有损外延) */
224
+ args: string[];
225
+ result: string;
226
+ throws: string | null;
227
+ source: string | null;
228
+ aggregatedFrom?: number;
229
+ /** 无损内涵(Abs);无则省略 */
230
+ intension?: {
231
+ display?: string;
232
+ abs?: string;
233
+ absMultiline?: string;
234
+ term?: string;
235
+ pred?: string;
236
+ conf?: string;
237
+ };
238
+ };
239
+ type InferJsonFunction = {
240
+ name: string;
241
+ loc: SourceLocation;
242
+ entryOnly: boolean;
243
+ noDeclaration?: boolean;
244
+ cases: InferJsonCase[];
245
+ combined?: string;
246
+ };
247
+ type InferJson = {
248
+ version: 1;
249
+ file: string;
250
+ summary: {
251
+ functions: number;
252
+ externalFunctions: number;
253
+ cases: number;
254
+ diagnostics: number;
255
+ };
256
+ functions: InferJsonFunction[];
257
+ externalFunctions?: Array<{
258
+ name: string;
259
+ fromModule?: string;
260
+ cases: InferJsonCase[];
261
+ }>;
262
+ diagnostics: Array<{
263
+ range: SourceLocation;
264
+ severity: string;
265
+ message: string;
266
+ code?: string;
267
+ suggestions?: string[];
268
+ tags?: string[];
269
+ origin?: {
270
+ line: number;
271
+ column: number;
272
+ };
273
+ }>;
274
+ };
275
+ declare function serializeInferJson(result: AnalysisResult, file: string): InferJson;
276
+
277
+ /**
278
+ * nudo 推断目标文件判定(纯扩展名规则,路径无需存在)。
279
+ *
280
+ * 规则:.js / .mjs / .ts 可作为推断目标;其余扩展(.cjs/.tsx/.jsx/.mts/.d.ts…)
281
+ * 一律 false。两类显式排除:
282
+ * - .d.ts —— 类型声明文件(harvester 的输入),不是可求值的实现源码;
283
+ * - .tsx / .jsx —— JSX 构造的求值超出 nudo 推断器范围。
284
+ *
285
+ * 消费方:CLI 的 collectNudoFiles/watch 过滤/doctor 目录展开(.ts 放开后统一
286
+ * 走本函数,避免各处手写 endsWith 漂移),以及 LSP 的 isNudoFile(接线由
287
+ * LSP 侧负责)。
288
+ */
289
+ declare function isNudoTargetPath(path: string): boolean;
290
+
291
+ /**
292
+ * 相对/绝对 specifier → 模块源码。
293
+ * CLI / LSP / vite / check 共用同一扩展名表,避免门禁结果分叉。
294
+ */
295
+ type LoadModule = (spec: string, fromFile: string) => string | undefined;
296
+ /** 默认 loadModule:支持 .js/.mjs/.ts 与 index 入口 */
297
+ declare function defaultLoadModule(spec: string, fromFile: string): string | undefined;
298
+
299
+ /**
300
+ * Host 侧多文件解析(非代数层)。
301
+ *
302
+ * 分层:
303
+ * algebra = 纯抽象解释:吃 AST / source string,不碰 fs/path
304
+ * host = 读文件、解析相对 import/require、把 source 喂给代数
305
+ * Node/打包器 = 真正的模块加载与执行
306
+ *
307
+ * 引擎不做 bundler;这里只为「跨文件类型事实」做最薄的静态扫描。
308
+ */
309
+
310
+ type ModuleExports = {
311
+ path: string;
312
+ named: Map<string, string>;
313
+ defaultExport?: string;
314
+ source: string;
315
+ poly: Map<string, PolyFn>;
316
+ };
317
+ /** 从 AST 收集静态相对依赖(ESM import + CJS require) */
318
+ declare function collectDependencySpecs(ast: File): string[];
319
+ /** 分析单文件导出 + 内涵签名(source 由 host 提供) */
320
+ declare function analyzeExportsFromSource(filePath: string, source: string): ModuleExports;
321
+ /**
322
+ * 从入口文件沿静态相对 import/require 收集(仅类型事实,不是运行时加载器)。
323
+ * bare specifier(npm 包)跳过——交给 harvest / env。
324
+ */
325
+ declare function collectStaticImports(entryFile: string, maxDepth?: number): Map<string, ModuleExports>;
326
+
327
+ /**
328
+ * Host:从 npm 包 / @types 收集 .d.ts → harvestDts。
329
+ * 代数不碰 fs;这里只做「找到 dts 路径」这一层宿主职责。
330
+ */
331
+
332
+ /** 在 node_modules 中解析包根(含 @types/*) */
333
+ declare function resolvePackageRoot(pkg: string, fromDir?: string): string | undefined;
334
+ type PackageHarvest = {
335
+ pkg: string;
336
+ root: string;
337
+ dtsFiles: string[];
338
+ env: HarvestedEnv;
339
+ };
340
+ /**
341
+ * 从入口 .d.ts 沿 reference path / 相对 import 做 BFS 收集。
342
+ * 适合 @types 包(三斜线引用图);比整树 walk 更贴声明入口。
343
+ */
344
+ declare function collectDtsFromEntry(entry: string, maxFiles?: number): string[];
345
+ /** harvest 一个 npm 包(或 @types 包) */
346
+ declare function harvestPackage(pkg: string, fromDir?: string, maxFiles?: number): PackageHarvest | {
347
+ error: string;
348
+ };
349
+ /** harvest 结果 → 人类可读导出表 */
350
+ declare function formatHarvestSummary(h: PackageHarvest): string;
351
+ /** 取某个导出的 TypeValue 字符串 */
352
+ declare function lookupHarvested(h: PackageHarvest, moduleName: string, exportName: string): string | undefined;
353
+
354
+ /**
355
+ * harvest 自动化:源码裸 import → @types/package → env modules。
356
+ * 手动 `nudo harvest` 仍保留;这里是分析路径上的按需注入。
357
+ */
358
+
359
+ /** 裸说明符 → 包名(含 scope);相对/绝对/node: 内建返回 undefined */
360
+ declare function barePackageName(spec: string): string | undefined;
361
+ declare function collectBarePackages(source: string): string[];
362
+ declare function harvestPackageCached(pkg: string, fromDir: string): PackageHarvest | null;
363
+ declare function clearHarvestCache(): void;
364
+ /**
365
+ * 自动 harvest 源码中全部裸包(有 @types 或包内 dts 时)。
366
+ * 返回可注入 setEnvModules 的 modules 表;无包可 harvest 时为空对象。
367
+ */
368
+ declare function autoHarvestModules(source: string, fromDir: string): Record<string, Record<string, TypeValue>>;
369
+
370
+ /**
371
+ * Host:import 图(相对 + 裸包 harvest)→ Abs 导出表 → 注入入口。
372
+ * 读 fs / 解析路径 / harvest 在这里;core 只收 modules 表。
373
+ */
374
+
375
+ type AbsLoadModule = (spec: string, fromFile: string) => string | undefined;
376
+ /** 相对说明符 → 源码 */
377
+ declare function defaultAbsLoadModule(spec: string, fromFile: string): string | undefined;
378
+ /** 模块加载守卫:与 TypeValue loadModuleEnv 口径对齐,供 analyzer 映射诊断 */
379
+ type AbsModuleLoadIssue = {
380
+ kind: "cycle" | "depth" | "missing";
381
+ /** 诊断定位用标签(文件 basename 或 require/import 说明符) */
382
+ label: string;
383
+ reason: string;
384
+ };
385
+ type AbsModuleGraphResult = {
386
+ /** 入口 import 说明符 → 依赖导出表 */
387
+ modules: Record<string, AbsModuleExports>;
388
+ /** 绝对路径 → 导出表(含依赖;循环时占位为空) */
389
+ byPath: Map<string, AbsModuleExports>;
390
+ /** cycle / depth / missing(B 路径权威,避免 TypeValue 叠报) */
391
+ issues: AbsModuleLoadIssue[];
392
+ };
393
+ type AbsGraphOptions = {
394
+ loadModule?: AbsLoadModule;
395
+ seedVars?: Record<string, Abs>;
396
+ seedFns?: Record<string, {
397
+ params: string[];
398
+ body: Node;
399
+ async?: boolean;
400
+ }>;
401
+ maxDepth?: number;
402
+ };
403
+ /** 会话级依赖模块缓存条目:stat 指纹 + 导出 + 子树装载 issue。 */
404
+ type AbsModuleCacheEntry = {
405
+ mtimeMs: number;
406
+ size: number;
407
+ exports: AbsModuleExports;
408
+ /** 该模块子树首次求值时记录的 cycle/depth/missing;命中时重放。 */
409
+ issues: AbsModuleLoadIssue[];
410
+ };
411
+ declare function clearAbsModuleCache(): void;
412
+ declare function evictAbsModuleCacheFiles(paths: string[]): void;
413
+ /**
414
+ * 递归求值相对依赖 + 裸包 harvest,产出入口可用的 modules 表。
415
+ * 循环依赖:先放空表再回填(与 TypeValue 路径 partial 口径一致),
416
+ * 并记录 cycle/depth/missing 供诊断。
417
+ */
418
+ declare function evalAbsModuleGraph(entrySource: string, entryFile: string, opts?: AbsGraphOptions): AbsModuleGraphResult;
419
+ /** 便捷:入口求值 + 依赖 Abs 注入 */
420
+ declare function evalProgramAbsWithModules(source: string, entryFile: string, opts?: AbsGraphOptions & {
421
+ file?: unknown;
422
+ }): {
423
+ env: AstEnv;
424
+ last: Abs;
425
+ phi: Phi;
426
+ };
427
+ /**
428
+ * 收集顶层绑定名 → Abs(含相对 import / 裸包 harvest 注入)。
429
+ * 供 bindings / hover 从 Abs 投影,不必走 TypeValue evaluator。
430
+ */
431
+ declare function collectAbsBindingsFromGraph(source: string, filePath: string, opts?: AbsGraphOptions): Map<string, Abs>;
432
+
433
+ /**
434
+ * Harvest TypeValue 导出 → AbsModuleExports(供 Abs 模块图注入)。
435
+ * fnSig → absFunction + apply 直接返回声明返回类型(conf=mock)。
436
+ */
437
+
438
+ /** 单个 TypeValue 导出 → Abs(可调用) */
439
+ declare function harvestedValueToAbs(tv: TypeValue): Abs;
440
+ /**
441
+ * 把 harvest 的 modules/globals 合成 AbsModuleExports。
442
+ * 键同时登记:原始模块路径、包名、basename(path / @types/path)。
443
+ */
444
+ declare function harvestToAbsModules(pkg: string, fromDir: string): Record<string, AbsModuleExports>;
445
+ declare function packageHarvestToAbsModules(pkg: string, h: PackageHarvest): Record<string, AbsModuleExports>;
446
+ /** 裸说明符 → Abs 导出表(走 harvest 缓存) */
447
+ declare function bareSpecToAbsModules(spec: string, fromFile: string): AbsModuleExports | undefined;
448
+
449
+ /** @nudo:env → Abs 全局表(保留 fnSig impl) */
450
+ declare function collectEnvGlobals(envNames: string[]): Record<string, Abs>;
451
+ /** @nudo:env modules(path / node:path / fs…)→ AbsModuleExports */
452
+ declare function collectEnvModules(envNames: string[]): Record<string, AbsModuleExports>;
453
+ /** 收集 @nudo:replace + @nudo:as → transpile 注入表 */
454
+ declare function collectBPathReplacements(source: string): {
455
+ targets: Array<{
456
+ target: string;
457
+ varName: string;
458
+ stmtStart?: number;
459
+ stmtEnd?: number;
460
+ }>;
461
+ values: Record<string, Abs>;
462
+ asTargets: Array<{
463
+ varName: string;
464
+ stmtStart: number;
465
+ stmtEnd: number;
466
+ }>;
467
+ asValues: Record<string, Abs>;
468
+ };
469
+ /** 可走 transpile+exec:env 经 loadEnvs(内置 + 已 preload 的路径型) */
470
+ declare function isBPathCapable(source: string, envNames?: string[]): boolean;
471
+ type BPathRunResult = {
472
+ exports: Record<string, unknown>;
473
+ modules: Record<string, AbsModuleExports>;
474
+ /** 顶层执行期 method-missing */
475
+ memberDiags?: BMemberDiag[];
476
+ /** 模块图 cycle/depth/missing(B 权威) */
477
+ moduleIssues?: AbsModuleLoadIssue[];
478
+ /** Abs 求值递归截断的函数标签 */
479
+ truncatedFns?: string[];
480
+ /** 顶层 $callNamed 调用点(call@ 合成;不经 TypeValue collector) */
481
+ calls?: BCallRecord[];
482
+ };
483
+ declare function clearBPathCache(): void;
484
+ /** 依赖文件变更后:逐出以这些文件为入口的 B-path 缓存 */
485
+ declare function evictBPathCacheForFiles(files: string[]): number;
486
+ /** 模块图 + runTranspiled(默认 analyze 模式) */
487
+ declare function tryRunBPath(source: string, filePath: string, opts?: {
488
+ maxLoopIters?: number;
489
+ mode?: "exec" | "analyze";
490
+ envNames?: string[];
491
+ /** @nudo:mock → Abs,注入为全局绑定(防止顶层调用真 fetch 等) */
492
+ mocks?: Record<string, Abs>;
493
+ }): BPathRunResult | undefined;
494
+ /** B 路径求值具名导出(结果 + throws);opts.collectCalls 时附带调用点记录 */
495
+ declare function tryBPathCallFull(source: string, filePath: string, fnName: string, args: Abs[], opts?: {
496
+ collectCalls?: boolean;
497
+ collectMemberDiags?: boolean;
498
+ envNames?: string[];
499
+ mocks?: Record<string, Abs>;
500
+ }): (TranspiledCallResult & {
501
+ calls?: BCallRecord[];
502
+ memberDiags?: BMemberDiag[];
503
+ moduleIssues?: AbsModuleLoadIssue[];
504
+ truncatedFns?: string[];
505
+ }) | undefined;
506
+ /** B 路径求值具名导出(仅成功结果) */
507
+ declare function tryBPathCall(source: string, filePath: string, fnName: string, args: Abs[], opts?: {
508
+ envNames?: string[];
509
+ mocks?: Record<string, Abs>;
510
+ }): Abs | undefined;
511
+
512
+ declare function clearAnalysisFileCache(): void;
513
+ declare function getAnalysisFileCacheSize(): number;
514
+ /** 依赖变更后:按入口文件逐出 */
515
+ declare function evictAnalysisFileCacheForFiles(files: string[]): number;
516
+
517
+ /**
518
+ * 依赖内容变更后:按入口文件定向逐出 service 层缓存。
519
+ * 调用方应传「以这些文件为入口」的路径(脏集里的 dependents),
520
+ * 而不是变更的 dep 文件本身——dep 自己 source 变了会自然 miss。
521
+ */
522
+ declare function evictAnalysisCachesForFiles(files: string[]): void;
523
+ /**
524
+ * 清空全部会话级分析缓存(service + core)。
525
+ * 适用于:CLI watch 增量批前、vite buildStart / watchChange、测试隔离。
526
+ * 比定向逐出重,但保证无陈旧命中;单次 analyze 内部的 per-fn / generalize
527
+ * memo 不受影响(它们在同一轮里先写后读)。
528
+ */
529
+ declare function clearAnalysisSessionCaches(): void;
530
+ /** 比 clearAnalysisSessionCaches 更彻底:再丢 AST LRU(测试 / 进程复用场景) */
531
+ declare function resetAllAnalysisCaches(): void;
532
+
533
+ /**
534
+ * env TypeValue → Abs:保留 fnSig impl,使 Promise.resolve / URL 等
535
+ * 在 B 路径也能产出精确字面量。
536
+ */
537
+
538
+ declare function envValueToAbs(tv: TypeValue): Abs;
539
+
540
+ /**
541
+ * B 路径静态诊断(AST,不执行):
542
+ * - unreachable:同块 return/throw 之后的语句
543
+ * - builtin-unknown:未声明的全局调用(非 import / 局部 / $runtime)
544
+ */
545
+ type BPathLoc = {
546
+ start: {
547
+ line: number;
548
+ column: number;
549
+ };
550
+ end: {
551
+ line: number;
552
+ column: number;
553
+ };
554
+ };
555
+ type BPathUnreachable = {
556
+ range: BPathLoc;
557
+ };
558
+ type BPathBuiltinUnknown = {
559
+ name: string;
560
+ range: BPathLoc;
561
+ };
562
+ type BPathDiagnostics = {
563
+ unreachable: BPathUnreachable[];
564
+ builtinUnknown: BPathBuiltinUnknown[];
565
+ };
566
+ /**
567
+ * 静态收集 B 路径诊断。
568
+ * extraKnown:@nudo:mock / @nudo:env 已覆盖的全局名(B 注入后不再是裸原生
569
+ * 调用,不得误报 builtin-unknown——收集器只吃 AST,看不到指令)。
570
+ */
571
+ declare function collectBPathDiagnostics(source: string, extraKnown?: Iterable<string>): BPathDiagnostics;
572
+
573
+ /**
574
+ * 预置 Node API env:从 @types/node 的 .d.ts harvest。
575
+ * 与 packages/env 的手写 env 并行;此路径自动、可刷新。
576
+ */
577
+
578
+ type NodeEnvResult = {
579
+ ok: true;
580
+ env: HarvestedEnv;
581
+ root: string;
582
+ files: number;
583
+ } | {
584
+ ok: false;
585
+ error: string;
586
+ };
587
+ /** harvest @types/node(限制文件数 + 时间预算,避免拖垮启动) */
588
+ declare function harvestNodeTypes(fromDir?: string, maxFiles?: number, maxMs?: number): NodeEnvResult;
589
+ /** 把 harvest 结果压成「模块名 → 导出名列表」摘要,便于日志/测试 */
590
+ declare function summarizeNodeEnv(env: HarvestedEnv): {
591
+ modules: string[];
592
+ globals: string[];
593
+ symbolCount: number;
594
+ };
595
+
596
+ /**
597
+ * Semantic tokens 图例(tokenTypes 下标即 LSP 编码里的 tokenType 值)。
598
+ * 与 LSP server capabilities 里声明的 legend 必须逐字对齐——server.ts 直接
599
+ * 导入本常量注册,保证「提取端索引」与「客户端图例」单一来源。
600
+ * 顺序沿用 lsp 包原 legend(function/variable/parameter/property 在前),
601
+ * 末尾追加 method(对象字面量方法键),只追加不重排,客户端索引稳定。
602
+ */
603
+ declare const SEMANTIC_TOKEN_TYPES: readonly ["function", "variable", "parameter", "property", "type", "keyword", "string", "number", "comment", "decorator", "method"];
604
+ declare const SEMANTIC_TOKEN_MODIFIERS: readonly ["declaration", "readonly", "deprecated", "unreachable"];
605
+ type SemanticToken = {
606
+ line: number;
607
+ char: number;
608
+ length: number;
609
+ typeIndex: number;
610
+ modifierBitmask: number;
611
+ };
612
+ /** LSP 标准相对五元组编码:deltaLine/deltaStartChar/length/tokenType/tokenModifiers。 */
613
+ declare function encodeSemanticTokens(tokens: SemanticToken[]): number[];
614
+ /**
615
+ * 从源码提取 semantic tokens 并按 LSP 相对编码返回扁平 number[]。
616
+ *
617
+ * 上色范围(声明位优先,未解析的 token 一律不上色):
618
+ * - 顶层 const/let/var 声明的绑定名:推断为函数绑定 → function,否则 variable
619
+ * (函数体内部的声明不做 env 反查——外层同名绑定会串味,统一 variable);
620
+ * - 函数声明/函数表达式的名字 → function;所有函数的参数 → parameter;
621
+ * - 对象字面量的键:值为函数 → method,否则 property。
622
+ *
623
+ * 推断复用 evaluateProgram 的绑定分析(与补全/诊断同一求值链),不另建
624
+ * 符号体系;解析失败返回 [],求值中断则按已绑定的部分结果继续上色。
625
+ */
626
+ declare function buildSemanticTokens(filePath: string, source: string): number[];
627
+
74
628
  declare function typeValueToTSType(tv: TypeValue): string;
629
+ /**
630
+ * 为单个函数生成 .d.ts 声明行(JSDoc + 单一 widen 主签名)。
631
+ * service 的 generateDts 与 CLI `--dts`(infer/watch)共用本函数,
632
+ * 两条路径输出保持一致。
633
+ */
634
+ declare function generateFunctionDtsLines(fn: FunctionAnalysis): string[];
75
635
  declare function generateDts(result: AnalysisResult): string;
76
636
 
77
- export { type AnalysisResult, type BindingInfo, type CaseHint, type CaseInfo, type CaseResult, type CompletionItem, type Diagnostic, type DiagnosticSeverity, type DiagnosticTag, type FunctionAnalysis, type SourceLocation, analyzeFile, generateDts, getCasesForFile, getCompletionsAtPosition, getTypeAtPosition, typeValueToTSType };
637
+ declare function typeValueToZodSchema(tv: TypeValue): string;
638
+
639
+ declare function generateGuardFunction(name: string, tv: TypeValue): string;
640
+ /** Abs 指称守卫(设计 §2.7):比 TypeValue 投影多保留 pred */
641
+ declare function generateGuardFunctionFromAbs(name: string, abs: Abs): string;
642
+
643
+ /** 单个 TypeValue → parseTypeValueExpr 可解析回去的表达式文本;不可表达返回 null */
644
+ declare function serializeCaseArg(tv: TypeValue): string | null;
645
+ /**
646
+ * 组装单行 ` * @nudo:case "name" (a, b)` 指令文本(无尾换行)。
647
+ * 任一实参不可序列化、或名字含双引号/换行(名字正则 `"([^"]+)"` 承载不了)→ 整体 null。
648
+ */
649
+ declare function buildCaseDirective(name: string, args: TypeValue[]): string | null;
650
+ /**
651
+ * 从源码剥离所有本模块生成的 @nudo:case 指令(名字以 call@ 开头,整行删除)。
652
+ * 若所属 JSDoc 块因此只剩空 ` *` 行(无其他 @nudo:* 指令、无文字内容),
653
+ * 连块首 `/**` 行与块尾行整块删除。绝不碰非 case 指令与普通注释。
654
+ * 注意:手写但以 call@ 命名的 case 同样会被删——call@ 前缀保留为生成物标记。
655
+ * removed 返回被删指令名列表(按出现顺序)。
656
+ */
657
+ declare function stripGeneratedCaseDirectives(source: string): {
658
+ source: string;
659
+ removed: string[];
660
+ };
661
+ type EmitSkipReason = "hand-written" | "already-generated" | "entry-only" | "no-serializable-cases" | "no-declaration" | "skipped";
662
+ type EmitResult = {
663
+ source: string;
664
+ changed: boolean;
665
+ written: Array<{
666
+ fn: string;
667
+ cases: string[];
668
+ }>;
669
+ skipped: Array<{
670
+ fn: string;
671
+ reason: EmitSkipReason;
672
+ detail?: string;
673
+ }>;
674
+ };
675
+ /**
676
+ * 把 analysis 中的合成 case(source === "callsite")固化为源码指令:
677
+ *
678
+ * 1. 源码已有任何非 call@ 命名的 case → skip "hand-written";
679
+ * 已有 call@ case → skip "already-generated"。
680
+ * 2. fn.skipped / fn.noDeclaration / fn.entryOnly → 对应 skip。
681
+ * 3. 逐 case 序列化;个别不可序列化的丢弃并在 skipped 记
682
+ * no-serializable-cases(函数整体仍写可序列化子集,全不可序列化才整函数跳过)。
683
+ * 4. 写入位置:函数声明行正上方——已有 JSDoc 块则插到 `/**` 行后,
684
+ * 无块则新建三行块。缩进取声明行的 loc.start.column(babel 0 基列)。
685
+ * 多函数编辑按行号从下往上应用,避免行号漂移。
686
+ */
687
+ declare function insertGeneratedCaseDirectives(source: string, analysis: AnalysisResult): EmitResult;
688
+ /** 行级 unified diff:`--- a/path` 头 + `@@` hunk + 上下文 3 行;相同返回 "" */
689
+ declare function unifiedDiff(a: string, b: string, path: string): string;
690
+
691
+ /**
692
+ * @nudo:mock / sinon 指令 → Abs seed(供 evalProgramAbs)。
693
+ * host 层:依赖 parser 指令形态;core 只吃 seedVars/seedFns。
694
+ */
695
+
696
+ type AbsMockSeeds = {
697
+ seedVars: Record<string, Abs>;
698
+ seedFns: Record<string, {
699
+ params: string[];
700
+ body: Node;
701
+ async?: boolean;
702
+ fingerprint?: string;
703
+ }>;
704
+ };
705
+ /** 从函数上的 @nudo:mock 指令收集 Abs seed */
706
+ declare function mockDirectivesToAbsSeeds(functions: Array<{
707
+ directives: FunctionWithDirectives["directives"];
708
+ }>): AbsMockSeeds;
709
+
710
+ export { type AbsGraphOptions, type AbsMockSeeds, type AbsModuleCacheEntry, type AbsModuleGraphResult, type AbsModuleLoadIssue, type AnalysisResult, type BPathBuiltinUnknown, type BPathDiagnostics, type BPathRunResult, type BPathUnreachable, type BindingInfo, type CaseHint, type CaseInfo, type CaseResult, type CompletionItem, type Diagnostic, type DiagnosticSeverity, type DiagnosticTag, type EmitResult, type EmitSkipReason, type FunctionAnalysis, type HoverInfo, type InferJson, type InferJsonCase, type InferJsonFunction, type LoadModule, type ModuleExports, type ModuleGraphCache, type NodeEnvResult, type PackageHarvest, type ReferenceInfo, SEMANTIC_TOKEN_MODIFIERS, SEMANTIC_TOKEN_TYPES, type SemanticToken, type SourceLocation, type SymbolInfo, type SymbolTable, analyzeExportsFromSource, analyzeFile, analyzeFileAsync, autoHarvestModules, barePackageName, bareSpecToAbsModules, buildCaseDirective, buildModuleGraph, buildSemanticTokens, clearAbsModuleCache, clearAnalysisFileCache, clearAnalysisSessionCaches, clearBPathCache, clearFnAnalysisCache, clearHarvestCache, collectAbsBindingsFromGraph, collectBPathDiagnostics, collectBPathReplacements, collectBarePackages, collectCallRecords, collectDependencySpecs, collectDtsFromEntry, collectEnvGlobals, collectEnvModules, collectStaticImports, computeDirtySet, defaultAbsLoadModule, defaultLoadModule, encodeSemanticTokens, envValueToAbs, evalAbsModuleGraph, evalProgramAbsWithModules, evictAbsModuleCacheFiles, evictAnalysisCachesForFiles, evictAnalysisFileCacheForFiles, evictBPathCacheForFiles, evictFnAnalysisCacheForFiles, formatHarvestSummary, generateDts, generateFunctionDtsLines, generateGuardFunction, generateGuardFunctionFromAbs, getAnalysisFileCacheSize, getCasesForFile, getCompletionsAtPosition, getHoverAtPosition, getTypeAtPosition, getTypeAtPositionAsync, harvestNodeTypes, harvestPackage, harvestPackageCached, harvestToAbsModules, harvestedValueToAbs, insertGeneratedCaseDirectives, isBPathCapable, isNudoTargetPath, lookupHarvested, mockDirectivesToAbsSeeds, packageHarvestToAbsModules, resetAllAnalysisCaches, resolvePackageRoot, serializeCaseArg, serializeInferJson, stripGeneratedCaseDirectives, summarizeNodeEnv, topoSortDirty, tryBPathCall, tryBPathCallFull, tryRunBPath, typeValueToTSType, typeValueToZodSchema, unifiedDiff };