@nudojs/service 1.0.0 → 2.0.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/chunk-ADFCZP72.js +556 -0
- package/dist/config-Cqj8zeZH.d.ts +117 -0
- package/dist/evaluator/evaluator-api.d.ts +10 -21
- package/dist/evaluator/evaluator-api.js +11 -53
- package/dist/index.d.ts +539 -52
- package/dist/index.js +3780 -1490
- package/package.json +5 -5
- package/dist/chunk-FSIHAE7I.js +0 -5871
- package/dist/config-UlReSTfh.d.ts +0 -152
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Node, File } from '@babel/types';
|
|
2
|
-
import {
|
|
2
|
+
import { FormalParam, Abs, InterfaceSource, InterfaceTierOpts, PolyFn, AbsModuleExports, AstEnv, Phi, BMemberDiag, BCallRecord, TranspiledCallResult, NudoConstraint } from '@nudojs/core';
|
|
3
3
|
export { AbsInlay, BMemberDiag, collectAbsInlays } from '@nudojs/core';
|
|
4
|
-
import { C as CallRecord } from './config-
|
|
5
|
-
export { I as InterfaceConfig, N as NudoConfig, f as findProjectConfig, i as interfaceConfig } from './config-
|
|
4
|
+
import { C as CallRecord, D as DiagnosticsLevel, A as AnalysisConfig } from './config-Cqj8zeZH.js';
|
|
5
|
+
export { a as AnalysisMode, b as DEFAULT_ANALYSIS_MODE, I as InterfaceConfig, N as NudoConfig, c as analysisConfig, d as clearPathEnvCaches, e as diskCacheRoot, f as findProjectConfig, i as interfaceConfig, m as matchesEmitAllowlist } from './config-Cqj8zeZH.js';
|
|
6
6
|
import { HarvestedEnv } from '@nudojs/harvester';
|
|
7
7
|
import { FunctionWithDirectives } from '@nudojs/parser';
|
|
8
8
|
|
|
@@ -46,18 +46,20 @@ type Diagnostic = {
|
|
|
46
46
|
};
|
|
47
47
|
type CaseResult = {
|
|
48
48
|
name: string;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
/** 无损参数 Abs */
|
|
50
|
+
argAbs: Abs[];
|
|
51
|
+
/** 无损结果 Abs */
|
|
52
|
+
abs: Abs;
|
|
53
|
+
/** 无损抛出 Abs(未抛为 never) */
|
|
54
|
+
throwsAbs: Abs;
|
|
52
55
|
throwLoc?: SourceLocation;
|
|
53
56
|
source?: "directive" | "callsite";
|
|
54
57
|
/** `@nudo:case "name" (…) => expected` — presence means the case is a test assertion */
|
|
55
|
-
expected?:
|
|
58
|
+
expected?: Abs;
|
|
56
59
|
/** number of additional call sites folded into a symbolic case */
|
|
57
60
|
aggregatedFrom?: number;
|
|
58
61
|
/**
|
|
59
62
|
* 内涵摘要(代数 generalize):无损 Abs + term/pred/conf。
|
|
60
|
-
* 仅在 entry@ / call@(Abs 路径)填充;外延 TypeValue 不变。
|
|
61
63
|
*/
|
|
62
64
|
intension?: {
|
|
63
65
|
display?: string;
|
|
@@ -69,15 +71,16 @@ type CaseResult = {
|
|
|
69
71
|
/** 无损 Abs 多行(formatAbsMultiline) */
|
|
70
72
|
absMultiline?: string;
|
|
71
73
|
};
|
|
72
|
-
/** 无损 Abs(denote/守卫用);仅 Abs 路径 case 填充 */
|
|
73
|
-
abs?: Abs;
|
|
74
74
|
};
|
|
75
75
|
type FunctionAnalysis = {
|
|
76
76
|
name: string;
|
|
77
77
|
loc: SourceLocation;
|
|
78
78
|
paramNames: string[];
|
|
79
|
+
/** C4.1 形参表面:draft/契约对齐(解构 placeholder + bound 名) */
|
|
80
|
+
formals?: FormalParam[];
|
|
79
81
|
cases: CaseResult[];
|
|
80
|
-
|
|
82
|
+
/** cases 结果 Abs 的 join;dts 返回位源 */
|
|
83
|
+
combinedAbs?: Abs;
|
|
81
84
|
entryOnly?: boolean;
|
|
82
85
|
skipped?: boolean;
|
|
83
86
|
/**
|
|
@@ -89,9 +92,28 @@ type FunctionAnalysis = {
|
|
|
89
92
|
noDeclaration?: boolean;
|
|
90
93
|
/** absolute path of the module this function is imported from (externalFunctions only) */
|
|
91
94
|
fromModule?: string;
|
|
95
|
+
/**
|
|
96
|
+
* HOF / entry shape 关系快照(generalizeFromAst),供 dts 泛型投影(C3.3)。
|
|
97
|
+
* 只存投影所需的 Abs,不挂 PolyFn 本体(缓存可克隆)。
|
|
98
|
+
*/
|
|
99
|
+
hof?: {
|
|
100
|
+
/** 函数形参:外延关系 Abs(fn 形状,paramTypes/returnType) */
|
|
101
|
+
fnRels?: Array<{
|
|
102
|
+
param: string;
|
|
103
|
+
abs: Abs;
|
|
104
|
+
}>;
|
|
105
|
+
/** 值形参提升快照(如 items → arr(A1)) */
|
|
106
|
+
entryShapes?: Array<{
|
|
107
|
+
param: string;
|
|
108
|
+
abs: Abs;
|
|
109
|
+
}>;
|
|
110
|
+
/** 符号返回 Abs(含自由 α / B:param) */
|
|
111
|
+
symbolic?: Abs;
|
|
112
|
+
};
|
|
92
113
|
};
|
|
93
114
|
type BindingInfo = {
|
|
94
|
-
|
|
115
|
+
/** 无损 Abs */
|
|
116
|
+
abs: Abs;
|
|
95
117
|
loc?: SourceLocation;
|
|
96
118
|
};
|
|
97
119
|
type CaseHint = {
|
|
@@ -109,7 +131,8 @@ type AnalysisResult = {
|
|
|
109
131
|
* the original — lookups must use the File that produced this result, not a
|
|
110
132
|
* freshly parsed one. getTypeAtPosition rebuilds its own map and is unaffected.
|
|
111
133
|
*/
|
|
112
|
-
|
|
134
|
+
/** 无损节点 Abs */
|
|
135
|
+
nodeAbsMap: Map<Node, Abs>;
|
|
113
136
|
caseHints: CaseHint[];
|
|
114
137
|
/** functions imported from other modules, synthesized from cross-file call sites observed while analyzing this file */
|
|
115
138
|
externalFunctions?: FunctionAnalysis[];
|
|
@@ -149,34 +172,55 @@ declare function buildModuleGraph(files: string[], cache?: ModuleGraphCache): {
|
|
|
149
172
|
declare function computeDirtySet(dependents: Map<string, Set<string>>, changedFile: string): string[];
|
|
150
173
|
/** Topological order with dependencies before dependents (only imports edges internal to dirty; cycles tolerated — remaining files appended in arbitrary order). */
|
|
151
174
|
declare function topoSortDirty(imports: Map<string, Set<string>>, dirty: string[]): string[];
|
|
175
|
+
/** Optional module loader for analysis (sidecar / relative imports). */
|
|
176
|
+
type AnalyzeLoadModule = (spec: string, fromFile: string) => string | undefined;
|
|
152
177
|
/**
|
|
153
178
|
* Async entry to analyzeFile: preloads path-based env files
|
|
154
179
|
* (`/// @nudo:env ./nudo-harvest-node.ts`) via dynamic import — impossible
|
|
155
180
|
* synchronously in ESM — then runs the sync analysis, which picks the
|
|
156
|
-
* preloaded factories up from the env-loader cache.
|
|
157
|
-
*
|
|
181
|
+
* preloaded factories up from the env-loader cache.
|
|
182
|
+
* `loadModule` is optional; when provided it is used for relative imports /
|
|
183
|
+
* sidecar ambient bindings (LSP buffer-aware path). Default remains
|
|
184
|
+
* `defaultLoadModule` (disk).
|
|
158
185
|
*/
|
|
159
|
-
declare function analyzeFileAsync(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: CallRecord[]): Promise<AnalysisResult>;
|
|
186
|
+
declare function analyzeFileAsync(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: CallRecord[], loadModule?: AnalyzeLoadModule): Promise<AnalysisResult>;
|
|
160
187
|
/**
|
|
161
188
|
* 调用点发现(阶段一):在"使用现场"文件(测试 / 上层应用)中求值
|
|
162
189
|
* 顶层代码,收集它对(外部模块导出的)函数的调用记录。每条记录带
|
|
163
190
|
* 真实的实参类型与结果类型——后续 analyzeFile 将其注入合成 case,
|
|
164
191
|
* 使被使用方从 entry-only(参数全 unknown)升级为真实调用形态。
|
|
165
192
|
*
|
|
193
|
+
* Abs 路径(TypeValue evaluateProgram 已删):evalProgramAbs + AbsCallRecord。
|
|
166
194
|
* 只做求值与记录,不产出诊断;求值异常不抛出(使用现场文件可能
|
|
167
195
|
* 依赖未 mock 的全局,收集不到就收集不到,不能拖垮主分析)。
|
|
168
196
|
*/
|
|
169
197
|
declare function collectCallRecords(filePath: string, source: string): CallRecord[];
|
|
198
|
+
declare function analysisFileCacheKey(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: CallRecord[], analysisCfg?: {
|
|
199
|
+
mode: string;
|
|
200
|
+
evalMissingSlot: string;
|
|
201
|
+
callSiteBudget: number;
|
|
202
|
+
diagnostics: string;
|
|
203
|
+
}, loadModule?: AnalyzeLoadModule, projectEnvNames?: string[],
|
|
204
|
+
/** ambient 侧车绑定:变更必须 miss(dep 指纹故意不编码 autoBind) */
|
|
205
|
+
autoBind?: boolean): {
|
|
206
|
+
filePath: string;
|
|
207
|
+
source: string;
|
|
208
|
+
auxKey: string;
|
|
209
|
+
noCache?: boolean;
|
|
210
|
+
};
|
|
170
211
|
/**
|
|
171
212
|
* 整文件分析。同 (path, source, cases, external) 命中 memo → O(1)。
|
|
172
213
|
* 不再每次 clearBPathCache:B 路径按本文件 source 键控。
|
|
173
214
|
*
|
|
215
|
+
* `loadModule`:可选;提供时用于相对 import / 侧车 ambient(LSP
|
|
216
|
+
* buffer-aware)。未提供时走 defaultLoadModule(磁盘)。
|
|
217
|
+
*
|
|
174
218
|
* 宿主契约:入口 source 未变但依赖模块内容变了时,必须调用
|
|
175
219
|
* `evictBPathCacheForFiles` / `evictAnalysisFileCacheForFiles` /
|
|
176
220
|
* `evictFnAnalysisCacheForFiles`(LSP 已接好)。非 LSP 宿主
|
|
177
221
|
* (CLI watch / vite-plugin)在 dep 变更时应 `clearBPathCache()` 或上述逐出。
|
|
178
222
|
*/
|
|
179
|
-
declare function analyzeFile(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: CallRecord[]): AnalysisResult;
|
|
223
|
+
declare function analyzeFile(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: CallRecord[], loadModule?: AnalyzeLoadModule): AnalysisResult;
|
|
180
224
|
|
|
181
225
|
type CaseInfo = {
|
|
182
226
|
functionName: string;
|
|
@@ -192,10 +236,17 @@ declare function getCasesForFile(filePath: string, source: string): {
|
|
|
192
236
|
loc: SourceLocation;
|
|
193
237
|
}[];
|
|
194
238
|
/** Async entry to getTypeAtPosition with path-env preloading (see analyzeFileAsync). */
|
|
195
|
-
declare function getTypeAtPositionAsync(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): Promise<
|
|
196
|
-
|
|
239
|
+
declare function getTypeAtPositionAsync(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): Promise<Abs | null>;
|
|
240
|
+
/** Async entry to getAbsAtPosition(与 getTypeAtPositionAsync 同预加载口径) */
|
|
241
|
+
declare function getAbsAtPositionAsync(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): Promise<Abs | null>;
|
|
242
|
+
/**
|
|
243
|
+
* 光标处无损 Abs。B-path 节点表优先;用例函数体走 Abs 重放。
|
|
244
|
+
*/
|
|
245
|
+
declare function getAbsAtPosition(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): Abs | null;
|
|
246
|
+
/** 光标处类型(Abs)。B-path 节点表优先;用例函数体走 Abs 重放。 */
|
|
247
|
+
declare function getTypeAtPosition(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): Abs | null;
|
|
197
248
|
type HoverInfo = {
|
|
198
|
-
/**
|
|
249
|
+
/** 外延展示(formatShape / formatAbs) */
|
|
199
250
|
typeText: string;
|
|
200
251
|
/** 内涵签名(代数 generalize) */
|
|
201
252
|
intension?: string;
|
|
@@ -203,25 +254,36 @@ type HoverInfo = {
|
|
|
203
254
|
abs?: string;
|
|
204
255
|
/** 无损 Abs 多行展示 */
|
|
205
256
|
absMultiline?: string;
|
|
257
|
+
/** CodeLens `● interface` 同源档位(A7);仅本地 named export */
|
|
258
|
+
interfaceSource?: InterfaceSource;
|
|
259
|
+
/** 有效契约展示(handwritten/generated);implicit 为 undefined */
|
|
260
|
+
interfaceDisplay?: string;
|
|
206
261
|
};
|
|
262
|
+
/** A7:hover/inlay 与 CodeLens interface 档同源(design-refine-derivation §8) */
|
|
263
|
+
type HoverInterfaceOpts = InterfaceTierOpts;
|
|
207
264
|
/**
|
|
208
|
-
* LSP hover:优先无损 Abs
|
|
265
|
+
* LSP hover:优先无损 Abs(类型即计算本体)。
|
|
209
266
|
* 节点表也是 Abs(collectAbsNodeTypes),不经 bridge。
|
|
210
267
|
*
|
|
211
268
|
* 函数名/调用 callee 位置(design-hof-relations §7):
|
|
212
269
|
* intension 一律走 generalize/formatPoly(HOF fnRels 在这里);
|
|
213
|
-
* typeText 仍落 B-path
|
|
270
|
+
* typeText 仍落 B-path Abs(调用点显示结果类型,不是函数签名)。
|
|
214
271
|
* 禁止用 B-path 的 arity-only fn Abs 冒充权威关系源。
|
|
272
|
+
*
|
|
273
|
+
* A7 default 档:函数名 hover 附带 interfaceTierOf 来源 + 契约展示,
|
|
274
|
+
* 与 CodeLens `● interface / <source>` 同源;选 case 时 body 仍走
|
|
275
|
+
* activeCases 重放,interface 档标注不变。
|
|
215
276
|
*/
|
|
216
|
-
declare function getHoverAtPosition(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number
|
|
277
|
+
declare function getHoverAtPosition(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>, opts?: HoverInterfaceOpts): HoverInfo | null;
|
|
217
278
|
declare function getCompletionsAtPosition(filePath: string, source: string, line: number, column: number): CompletionItem[];
|
|
218
279
|
|
|
219
280
|
/**
|
|
220
281
|
* `nudo infer --json` 稳定契约 v1(CI / Agent)。
|
|
221
282
|
*
|
|
222
283
|
* 字段只增不改语义:
|
|
223
|
-
* -
|
|
284
|
+
* - args / result / throws / combined:formatShape 外延投影(有损,兼容)
|
|
224
285
|
* - intension.abs*:无损 Abs 展示(主线)
|
|
286
|
+
* - argsAbs / resultAbs:CaseResult 上的无损 Abs(formatAbs);有则补齐
|
|
225
287
|
*/
|
|
226
288
|
|
|
227
289
|
type InferJsonCase = {
|
|
@@ -232,6 +294,10 @@ type InferJsonCase = {
|
|
|
232
294
|
throws: string | null;
|
|
233
295
|
source: string | null;
|
|
234
296
|
aggregatedFrom?: number;
|
|
297
|
+
/** 无损参数 Abs 展示(与 args 对齐;缺失位省略) */
|
|
298
|
+
argsAbs?: string[];
|
|
299
|
+
/** 无损结果 Abs 展示 */
|
|
300
|
+
resultAbs?: string;
|
|
235
301
|
/** 无损内涵(Abs);无则省略 */
|
|
236
302
|
intension?: {
|
|
237
303
|
display?: string;
|
|
@@ -249,6 +315,8 @@ type InferJsonFunction = {
|
|
|
249
315
|
noDeclaration?: boolean;
|
|
250
316
|
cases: InferJsonCase[];
|
|
251
317
|
combined?: string;
|
|
318
|
+
/** 无损 combined Abs 展示 */
|
|
319
|
+
combinedAbs?: string;
|
|
252
320
|
};
|
|
253
321
|
type InferJson = {
|
|
254
322
|
version: 1;
|
|
@@ -287,8 +355,10 @@ declare function serializeInferJson(result: AnalysisResult, file: string): Infer
|
|
|
287
355
|
* 一律 false。显式排除:
|
|
288
356
|
* - .d.ts —— 类型声明文件(harvester 的输入),不是可求值的实现源码;
|
|
289
357
|
* - .tsx / .jsx —— JSX 构造的求值超出 nudo 推断器范围;
|
|
290
|
-
* - *.nudo.js / *.nudo.ts —— 侧车契约模块(interface
|
|
291
|
-
*
|
|
358
|
+
* - *.nudo.js / *.nudo.mjs / *.nudo.ts —— 侧车契约模块(interface 绑定源),
|
|
359
|
+
* 不是源码推断目标;目录级 check/infer/doctor 展开不得把它们当实现分析;
|
|
360
|
+
* - *.nudo.draft.js / *.nudo.draft.mjs / *.nudo.draft.ts —— draft 产物,
|
|
361
|
+
* 明确不被 ambient 绑定,也不得当实现源码分析。
|
|
292
362
|
*
|
|
293
363
|
* 消费方:CLI 的 collectNudoFiles/watch 过滤/doctor 目录展开(.ts 放开后统一
|
|
294
364
|
* 走本函数,避免各处手写 endsWith 漂移),以及 LSP 的 isNudoFile(接线由
|
|
@@ -296,6 +366,51 @@ declare function serializeInferJson(result: AnalysisResult, file: string): Infer
|
|
|
296
366
|
*/
|
|
297
367
|
declare function isNudoTargetPath(path: string): boolean;
|
|
298
368
|
|
|
369
|
+
/** Formal sidecar contracts only — drafts never ambient-bind and need not reanalyze */
|
|
370
|
+
declare function isSidecarPath(path: string): boolean;
|
|
371
|
+
declare function isProjectConfigPath(path: string): boolean;
|
|
372
|
+
/** Watch accept gate: analysis targets + sidecar/config/env-template invalidators */
|
|
373
|
+
declare function isWatchRelevantPath(path: string): boolean;
|
|
374
|
+
/** `lib.nudo.js|ts` → candidate ambient sources next to it */
|
|
375
|
+
declare function ambientSourcesOfSidecar(sidecarPath: string): string[];
|
|
376
|
+
|
|
377
|
+
/** 源码里的 path-based load specs 解析为绝对路径后登记反向边 */
|
|
378
|
+
declare function noteEnvPathDeps(sourcePath: string, source: string): void;
|
|
379
|
+
/** 依赖该 env 模板的源文件列表 */
|
|
380
|
+
declare function envPathDependents(envPath: string): string[];
|
|
381
|
+
declare function clearEnvPathDeps(): void;
|
|
382
|
+
/** watch 门禁:env 模板变更必须可被接收(即便扩展名不进 isNudoTargetPath) */
|
|
383
|
+
declare function isEnvTemplatePath(path: string): boolean;
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* 分析范围判定(A1/A2,design-analysis-scope.md)。
|
|
387
|
+
* CLI 显式路径不受 mode 限制;本模块供 LSP/watch 自动验证使用。
|
|
388
|
+
*/
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* 按 analysis.diagnostics 档过滤 evaluator/check **显示路径**诊断。
|
|
392
|
+
* - off:显示层全静音(与 errors 档区分)。check 门禁(CLI `nudo check` /
|
|
393
|
+
* checkSource)独立于本过滤,不受 off 影响。
|
|
394
|
+
* - errors:只发 severity=error
|
|
395
|
+
* - default:error + warning(静音 NOISY_WARNING_CODES)
|
|
396
|
+
* - verbose:全量
|
|
397
|
+
*/
|
|
398
|
+
declare function filterDiagnosticsByLevel<T extends {
|
|
399
|
+
severity: string;
|
|
400
|
+
code?: string;
|
|
401
|
+
}>(diags: T[], level: DiagnosticsLevel): T[];
|
|
402
|
+
declare function diagnosticsLevelForFile(filePath: string): DiagnosticsLevel;
|
|
403
|
+
declare function hasNudoDirectives(source: string): boolean;
|
|
404
|
+
/**
|
|
405
|
+
* 是否应对该文件跑分析(自动路径,如 LSP validate)。
|
|
406
|
+
* - 非 target 路径 → false
|
|
407
|
+
* - exclude 命中 / include 未命中 → false
|
|
408
|
+
* - mode=directives → 仅有指令
|
|
409
|
+
* - mode=exports → 指令 | export | 同名侧车
|
|
410
|
+
* - mode=all → true
|
|
411
|
+
*/
|
|
412
|
+
declare function shouldAnalyzeFile(filePath: string, source: string | undefined, config?: AnalysisConfig): boolean;
|
|
413
|
+
|
|
299
414
|
/**
|
|
300
415
|
* 相对/绝对 specifier → 模块源码。
|
|
301
416
|
* CLI / LSP / vite / check 共用同一扩展名表,避免门禁结果分叉。
|
|
@@ -356,7 +471,7 @@ declare function harvestPackage(pkg: string, fromDir?: string, maxFiles?: number
|
|
|
356
471
|
};
|
|
357
472
|
/** harvest 结果 → 人类可读导出表 */
|
|
358
473
|
declare function formatHarvestSummary(h: PackageHarvest): string;
|
|
359
|
-
/**
|
|
474
|
+
/** 取某个导出的展示串(formatShape) */
|
|
360
475
|
declare function lookupHarvested(h: PackageHarvest, moduleName: string, exportName: string): string | undefined;
|
|
361
476
|
|
|
362
477
|
/**
|
|
@@ -373,7 +488,7 @@ declare function clearHarvestCache(): void;
|
|
|
373
488
|
* 自动 harvest 源码中全部裸包(有 @types 或包内 dts 时)。
|
|
374
489
|
* 返回可注入 setEnvModules 的 modules 表;无包可 harvest 时为空对象。
|
|
375
490
|
*/
|
|
376
|
-
declare function autoHarvestModules(source: string, fromDir: string): Record<string, Record<string,
|
|
491
|
+
declare function autoHarvestModules(source: string, fromDir: string): Record<string, Record<string, Abs>>;
|
|
377
492
|
|
|
378
493
|
/**
|
|
379
494
|
* Host:import 图(相对 + 裸包 harvest)→ Abs 导出表 → 注入入口。
|
|
@@ -439,12 +554,12 @@ declare function evalProgramAbsWithModules(source: string, entryFile: string, op
|
|
|
439
554
|
declare function collectAbsBindingsFromGraph(source: string, filePath: string, opts?: AbsGraphOptions): Map<string, Abs>;
|
|
440
555
|
|
|
441
556
|
/**
|
|
442
|
-
* Harvest
|
|
443
|
-
*
|
|
557
|
+
* Harvest Abs 导出 → AbsModuleExports(供 Abs 模块图注入)。
|
|
558
|
+
* harvest 产物已是 Abs;fn 槽 apply 直接返回声明返回类型(conf=mock)。
|
|
444
559
|
*/
|
|
445
560
|
|
|
446
|
-
/** 单个
|
|
447
|
-
declare function harvestedValueToAbs(
|
|
561
|
+
/** 单个 Abs 导出 → 可调用 mock(fn 槽 apply 返回声明返回类型) */
|
|
562
|
+
declare function harvestedValueToAbs(a: Abs): Abs;
|
|
448
563
|
/**
|
|
449
564
|
* 把 harvest 的 modules/globals 合成 AbsModuleExports。
|
|
450
565
|
* 键同时登记:原始模块路径、包名、basename(path / @types/path)。
|
|
@@ -454,7 +569,7 @@ declare function packageHarvestToAbsModules(pkg: string, h: PackageHarvest): Rec
|
|
|
454
569
|
/** 裸说明符 → Abs 导出表(走 harvest 缓存) */
|
|
455
570
|
declare function bareSpecToAbsModules(spec: string, fromFile: string): AbsModuleExports | undefined;
|
|
456
571
|
|
|
457
|
-
/** @nudo:env → Abs
|
|
572
|
+
/** @nudo:env → Abs 全局表(env 模块 Abs 原生) */
|
|
458
573
|
declare function collectEnvGlobals(envNames: string[]): Record<string, Abs>;
|
|
459
574
|
/** @nudo:env modules(path / node:path / fs…)→ AbsModuleExports */
|
|
460
575
|
declare function collectEnvModules(envNames: string[]): Record<string, AbsModuleExports>;
|
|
@@ -548,12 +663,127 @@ declare function clearAnalysisSessionCaches(): void;
|
|
|
548
663
|
declare function resetAllAnalysisCaches(): void;
|
|
549
664
|
|
|
550
665
|
/**
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
* -
|
|
666
|
+
* B5:workspace 级 AnalysisSession——LSP 与 CLI(同进程)共享的分析 memo 面。
|
|
667
|
+
*
|
|
668
|
+
* core/service 的 analyzeFile / B-path / generalize / checkSource 都是
|
|
669
|
+
* 进程级模块缓存;本模块把「清空 / 定向逐出 / 依赖变更」收成一个显式
|
|
670
|
+
* session 对象,避免宿主各接一套失效逻辑,也便于测试隔离。
|
|
671
|
+
*
|
|
672
|
+
* 宿主契约:
|
|
673
|
+
* - 依赖内容变更 → `session.evictForDependents(files)`
|
|
674
|
+
* - 全量重置(watch 批前 / vite buildStart)→ `session.clear()`
|
|
675
|
+
* - LSP validate 与 agent check/hover/interface 在同一进程共用默认 session
|
|
554
676
|
*/
|
|
555
677
|
|
|
556
|
-
|
|
678
|
+
type AnalysisSession = {
|
|
679
|
+
/** 依赖变更:按「以这些文件为入口」的路径定向逐出 */
|
|
680
|
+
evictForDependents(files: string[]): void;
|
|
681
|
+
/** 清空 service+core 会话 memo(不含 AST LRU) */
|
|
682
|
+
clear(): void;
|
|
683
|
+
/** 彻底重置(含 AST LRU) */
|
|
684
|
+
reset(): void;
|
|
685
|
+
/**
|
|
686
|
+
* 与 analyzeFile 同源,但强制走本 session 的 memo(进程内默认即共享)。
|
|
687
|
+
* LSP / CLI / agent 工具都应调用这里,而不是旁路第二套缓存。
|
|
688
|
+
*/
|
|
689
|
+
analyze(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: unknown): AnalysisResult;
|
|
690
|
+
};
|
|
691
|
+
/** 进程内默认 AnalysisSession(LSP server / CLI watch / agent tools 共用) */
|
|
692
|
+
declare function getAnalysisSession(): AnalysisSession;
|
|
693
|
+
/** 测试:替换默认 session(返回旧值以便恢复) */
|
|
694
|
+
declare function setAnalysisSession(session: AnalysisSession | undefined): AnalysisSession | undefined;
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* 磁盘内容寻址缓存(B3,design-persistent-cache.md L1 骨架)。
|
|
698
|
+
* - 键:sha256(analysisAbi + relative paths + content hashes + import deps)
|
|
699
|
+
* - fail-open:读写失败/版本不符 → miss,绝不 throw
|
|
700
|
+
* - 不存 Abs;只存可 JSON 再执行投影(如 CheckJson)
|
|
701
|
+
* - 缓存根解析见 `evaluator/config.ts` 的 `diskCacheRoot`(唯一入口)
|
|
702
|
+
*/
|
|
703
|
+
/**
|
|
704
|
+
* 带包版本:升级 @nudojs/* 后旧 CheckJson 不得继续命中。
|
|
705
|
+
* 语义大改仍可手工再抬 major(`nudo-check-cache-v3`)。
|
|
706
|
+
*/
|
|
707
|
+
declare const ANALYSIS_ABI: string;
|
|
708
|
+
type DiskCacheOptions = {
|
|
709
|
+
/** 缓存根目录;undefined = 禁用 */
|
|
710
|
+
root?: string | undefined;
|
|
711
|
+
/** 命名空间子目录(check / interface …) */
|
|
712
|
+
namespace: string;
|
|
713
|
+
};
|
|
714
|
+
declare function sha256Hex(data: string | Buffer): string;
|
|
715
|
+
/** 相对化路径,避免绝对路径进磁盘键;树外路径用稳定内容 hash */
|
|
716
|
+
declare function relativizePath(p: string, root?: string): string;
|
|
717
|
+
declare class DiskCache {
|
|
718
|
+
private readonly root;
|
|
719
|
+
private readonly ns;
|
|
720
|
+
enabled: boolean;
|
|
721
|
+
constructor(opts: DiskCacheOptions);
|
|
722
|
+
private pathFor;
|
|
723
|
+
get<T>(key: string): T | undefined;
|
|
724
|
+
set(key: string, value: unknown): void;
|
|
725
|
+
clearNamespace(): void;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* check 报告键:abi + 相对路径 + 源码 sha + autoBind + **侧车 sha** +
|
|
729
|
+
* **@nudo:import / 传递契约依赖内容 sha**(依赖变更必须 miss)。
|
|
730
|
+
* dep 路径同样相对化(`relativizePath`):绝对路径进键会让同内容在不同
|
|
731
|
+
* 机器/checkout 上键不同,缓存无法跨环境复用。
|
|
732
|
+
*/
|
|
733
|
+
declare function checkCacheKey(filePath: string, source: string, opts: {
|
|
734
|
+
autoBind: boolean;
|
|
735
|
+
projectDir?: string;
|
|
736
|
+
sidecarContent?: string | null;
|
|
737
|
+
depContents?: Array<{
|
|
738
|
+
path: string;
|
|
739
|
+
content: string | null;
|
|
740
|
+
}>;
|
|
741
|
+
/** package.json#nudo.env 等项目维(named env 不在 path-dep 指纹里) */
|
|
742
|
+
projectEnvNames?: string[];
|
|
743
|
+
/** analysis knobs that can change check surface */
|
|
744
|
+
analysisCfg?: {
|
|
745
|
+
mode?: string;
|
|
746
|
+
evalMissingSlot?: string;
|
|
747
|
+
callSiteBudget?: number;
|
|
748
|
+
};
|
|
749
|
+
}): string;
|
|
750
|
+
/**
|
|
751
|
+
* effectiveInterface 表键(L1 Phase B,design-persistent-cache)。
|
|
752
|
+
* 维度:相对路径 + 源码 sha256 + autoBind + 侧车内容 sha256 + import 依赖
|
|
753
|
+
* (dep 路径相对化,与 checkCacheKey 同口径)。
|
|
754
|
+
* **不含** emit allowlist(白名单不影响契约读取)。
|
|
755
|
+
*/
|
|
756
|
+
declare function ifaceCacheKey(filePath: string, source: string, opts: {
|
|
757
|
+
autoBind: boolean;
|
|
758
|
+
projectDir?: string;
|
|
759
|
+
/** 侧车源码(已读入);undefined = 无侧车或 autoBind 关 */
|
|
760
|
+
sidecarSource?: string | undefined;
|
|
761
|
+
depContents?: Array<{
|
|
762
|
+
path: string;
|
|
763
|
+
content: string | null;
|
|
764
|
+
}>;
|
|
765
|
+
projectEnvNames?: string[];
|
|
766
|
+
}): string;
|
|
767
|
+
/** 从源码提取 `@nudo:import` / `@nudo:import * as` 的 specifier */
|
|
768
|
+
declare function extractNudoImportSpecs(source: string): string[];
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* check/iface 磁盘缓存键的依赖内容采集。
|
|
772
|
+
* 走 core `loadModuleDepsFingerprint`:覆盖 ESM from / require / dynamic import /
|
|
773
|
+
* `@nudo:import` / ambient 侧车闭包——不只 `@nudo:import` 注释。
|
|
774
|
+
*
|
|
775
|
+
* 内容必须优先取 loadModule 解析结果(fingerprint.contents),不得回读磁盘:
|
|
776
|
+
* LSP buffer-aware loadModule 与自定义 loader 的内容可能与磁盘不一致,
|
|
777
|
+
* 回读会让缓存键分叉(buffer 编辑后仍命中磁盘旧内容)。
|
|
778
|
+
*/
|
|
779
|
+
type DepContent = {
|
|
780
|
+
path: string;
|
|
781
|
+
content: string | null;
|
|
782
|
+
};
|
|
783
|
+
declare function collectLoadDepContents(filePath: string, source: string, loadModule: (spec: string, fromFile: string) => string | undefined): {
|
|
784
|
+
depContents: DepContent[];
|
|
785
|
+
truncated: boolean;
|
|
786
|
+
};
|
|
557
787
|
|
|
558
788
|
/**
|
|
559
789
|
* B 路径静态诊断(AST,不执行):
|
|
@@ -616,10 +846,11 @@ declare function summarizeNodeEnv(env: HarvestedEnv): {
|
|
|
616
846
|
* 与 LSP server capabilities 里声明的 legend 必须逐字对齐——server.ts 直接
|
|
617
847
|
* 导入本常量注册,保证「提取端索引」与「客户端图例」单一来源。
|
|
618
848
|
* 顺序沿用 lsp 包原 legend(function/variable/parameter/property 在前),
|
|
619
|
-
* 末尾追加 method
|
|
849
|
+
* 末尾追加 method(对象字面量方法键)与 interface 档 modifier(A7),
|
|
850
|
+
* 只追加不重排,客户端索引稳定。
|
|
620
851
|
*/
|
|
621
852
|
declare const SEMANTIC_TOKEN_TYPES: readonly ["function", "variable", "parameter", "property", "type", "keyword", "string", "number", "comment", "decorator", "method"];
|
|
622
|
-
declare const SEMANTIC_TOKEN_MODIFIERS: readonly ["declaration", "readonly", "deprecated", "unreachable"];
|
|
853
|
+
declare const SEMANTIC_TOKEN_MODIFIERS: readonly ["declaration", "readonly", "deprecated", "unreachable", "contract", "generated", "derived"];
|
|
623
854
|
type SemanticToken = {
|
|
624
855
|
line: number;
|
|
625
856
|
char: number;
|
|
@@ -629,6 +860,11 @@ type SemanticToken = {
|
|
|
629
860
|
};
|
|
630
861
|
/** LSP 标准相对五元组编码:deltaLine/deltaStartChar/length/tokenType/tokenModifiers。 */
|
|
631
862
|
declare function encodeSemanticTokens(tokens: SemanticToken[]): number[];
|
|
863
|
+
/** A7:interface 档 → semantic token modifier(与 CodeLens 同源) */
|
|
864
|
+
declare function interfaceTierModifierBit(src: InterfaceSource): number;
|
|
865
|
+
type BuildSemanticTokensOpts = InterfaceTierOpts & {
|
|
866
|
+
loadModule?: (spec: string, fromFile: string) => string | undefined;
|
|
867
|
+
};
|
|
632
868
|
/**
|
|
633
869
|
* 从源码提取 semantic tokens 并按 LSP 相对编码返回扁平 number[]。
|
|
634
870
|
*
|
|
@@ -638,33 +874,45 @@ declare function encodeSemanticTokens(tokens: SemanticToken[]): number[];
|
|
|
638
874
|
* - 函数声明/函数表达式的名字 → function;所有函数的参数 → parameter;
|
|
639
875
|
* - 对象字面量的键:值为函数 → method,否则 property。
|
|
640
876
|
*
|
|
641
|
-
*
|
|
642
|
-
*
|
|
877
|
+
* A7:本地 named export 的函数绑定额外带 interface 档 modifier
|
|
878
|
+
* (contract / generated / derived),与 CodeLens `● interface` 同源。
|
|
879
|
+
* 非导出绑定只带 declaration,不假装进档。
|
|
880
|
+
*
|
|
881
|
+
* 推断优先 Abs 模块图绑定(TypeValue 退出主路径);失败时复用
|
|
882
|
+
* evaluateProgram。解析失败返回 []。
|
|
643
883
|
*/
|
|
644
|
-
declare function buildSemanticTokens(filePath: string, source: string): number[];
|
|
884
|
+
declare function buildSemanticTokens(filePath: string, source: string, opts?: BuildSemanticTokensOpts): number[];
|
|
645
885
|
|
|
646
|
-
|
|
886
|
+
/**
|
|
887
|
+
* Abs → TS 类型串。有损:pred / 非 lit term 落到 shape 基类型。
|
|
888
|
+
* `typeVars`:term var id → TS 类型参数名(HOF 泛型投影时传入;
|
|
889
|
+
* `any`+var 在此映射下渲染为该参数名,否则 `unknown`)。
|
|
890
|
+
*/
|
|
891
|
+
declare function absToTSType(a: Abs, typeVars?: Map<string, string>): string;
|
|
647
892
|
/**
|
|
648
893
|
* 为单个函数生成 .d.ts 声明行(JSDoc + 单一 widen 主签名)。
|
|
894
|
+
* 有 hof 关系时优先泛型投影(C3.3);否则 case-widen。
|
|
649
895
|
* service 的 generateDts 与 CLI `--dts`(infer/watch)共用本函数,
|
|
650
896
|
* 两条路径输出保持一致。
|
|
651
897
|
*/
|
|
652
898
|
declare function generateFunctionDtsLines(fn: FunctionAnalysis): string[];
|
|
653
899
|
declare function generateDts(result: AnalysisResult): string;
|
|
654
900
|
|
|
655
|
-
|
|
901
|
+
/** Abs → zod schema 源码。有损:pred / 非 lit term 落到 shape 基类型。 */
|
|
902
|
+
declare function absToZodSchema(a: Abs): string;
|
|
656
903
|
|
|
657
|
-
|
|
658
|
-
/** Abs 指称守卫(设计 §2.7):比 TypeValue 投影多保留 pred */
|
|
904
|
+
/** Abs 指称守卫(设计 §2.7):保留 pred */
|
|
659
905
|
declare function generateGuardFunctionFromAbs(name: string, abs: Abs): string;
|
|
906
|
+
/** 兼容别名:Abs 路径唯一 */
|
|
907
|
+
declare function generateGuardFunction(name: string, abs: Abs): string;
|
|
660
908
|
|
|
661
|
-
/** 单个
|
|
662
|
-
declare function serializeCaseArg(
|
|
909
|
+
/** 单个 Abs → parseCaseArgExpr 可解析回去的表达式文本;不可表达返回 null */
|
|
910
|
+
declare function serializeCaseArg(a: Abs): string | null;
|
|
663
911
|
/**
|
|
664
912
|
* 组装单行 ` * @nudo:case "name" (a, b)` 指令文本(无尾换行)。
|
|
665
913
|
* 任一实参不可序列化、或名字含双引号/换行(名字正则 `"([^"]+)"` 承载不了)→ 整体 null。
|
|
666
914
|
*/
|
|
667
|
-
declare function buildCaseDirective(name: string,
|
|
915
|
+
declare function buildCaseDirective(name: string, argsAbs: Abs[]): string | null;
|
|
668
916
|
/**
|
|
669
917
|
* 从源码剥离所有本模块生成的 @nudo:case 指令(名字以 call@ 开头,整行删除)。
|
|
670
918
|
* 若所属 JSDoc 块因此只剩空 ` *` 行(无其他 @nudo:* 指令、无文字内容),
|
|
@@ -729,12 +977,16 @@ declare function mockDirectivesToAbsSeeds(functions: Array<{
|
|
|
729
977
|
* `nudo interface` 的打印数据源(design-refine-derivation §11 第 0 步):
|
|
730
978
|
* 逐顶层函数展示有效契约分层——effectiveInterface 命中(手写契约 / 侧车
|
|
731
979
|
* 生成段)时 params/returns 用 formatConstraint 组合式显示;未命中走
|
|
732
|
-
* implicit
|
|
733
|
-
*
|
|
980
|
+
* implicit:优先 CaseResult.argAbs / FunctionAnalysis.combinedAbs(无损
|
|
981
|
+
* Abs 源),展示用 formatShape(外延口径,不强求约束式、不带 conf)。
|
|
734
982
|
*
|
|
735
983
|
* autoBind 沿 package.json#nudo.interface(findProjectConfig → interfaceConfig)
|
|
736
984
|
* 下传,可用 opts 覆盖(测试 / CLI 显式开关);读盘用 defaultLoadModule
|
|
737
985
|
* (与 check 的 refine 解析同一扩展名表)。
|
|
986
|
+
*
|
|
987
|
+
* B3 Phase B:`nudo.cache` / NUDO_CACHE_DIR 打开时,整文件 effectiveInterface
|
|
988
|
+
* 表(含 implicit 负缓存 null)落盘;二次冷启动跳过侧车 exec / 契约合并。
|
|
989
|
+
* 缓存只服务打印/表面,不加速 B-path 分析(design-persistent-cache §0)。
|
|
738
990
|
*/
|
|
739
991
|
|
|
740
992
|
type InterfaceSurfaceEntry = {
|
|
@@ -755,6 +1007,8 @@ type InterfaceSurfaceOpts = {
|
|
|
755
1007
|
loadModule?: LoadModule;
|
|
756
1008
|
/** 跨文件调用记录(--callsites 采集):implicit 展示的实参域原料 */
|
|
757
1009
|
records?: CallRecord[];
|
|
1010
|
+
/** 打开 buffer 覆盖磁盘源码(E5:agent/LSP 与 hover 同口径) */
|
|
1011
|
+
source?: string;
|
|
758
1012
|
};
|
|
759
1013
|
/** 单条 interface 打印行(CLI runInterface 与 LSP agent 面共用) */
|
|
760
1014
|
declare function formatInterfaceSurfaceLine(e: InterfaceSurfaceEntry): string;
|
|
@@ -785,6 +1039,8 @@ declare function interfaceSurface(filePath: string, opts?: InterfaceSurfaceOpts)
|
|
|
785
1039
|
*/
|
|
786
1040
|
|
|
787
1041
|
type EmitInterfaceSkipReason = "name-clash" | "not-projectable" | "not-an-export" | "no-change"
|
|
1042
|
+
/** package.json#nudo.interface.emit 白名单拒绝 */
|
|
1043
|
+
| "emit-denied"
|
|
788
1044
|
/** 手工合并的多声明符 @generated 段:按段原子保留,不拆不重写 */
|
|
789
1045
|
| "multi-declarator";
|
|
790
1046
|
type EmitInterfaceOpts = {
|
|
@@ -801,6 +1057,10 @@ type EmitInterfaceOpts = {
|
|
|
801
1057
|
* 外部使用现场记录)的投影原料;缺省时仅用本文件调用点证据。
|
|
802
1058
|
*/
|
|
803
1059
|
records?: CallRecord[];
|
|
1060
|
+
/** 缓冲源(E5:agent/LSP 与 validate 同源);缺省读盘 */
|
|
1061
|
+
source?: string;
|
|
1062
|
+
/** 模块装载器(buffer-aware 侧车可见);缺省 defaultLoadModule */
|
|
1063
|
+
loadModule?: (spec: string, fromFile: string) => string | undefined;
|
|
804
1064
|
};
|
|
805
1065
|
type EmitInterfaceResult = {
|
|
806
1066
|
written: string[];
|
|
@@ -834,4 +1094,231 @@ declare function emitInterface(filePath: string, opts: EmitInterfaceOpts): Promi
|
|
|
834
1094
|
*/
|
|
835
1095
|
declare function formatEmitSummary(sourcePath: string, sidecarRel: string, result: EmitInterfaceResult): string[];
|
|
836
1096
|
|
|
837
|
-
|
|
1097
|
+
/**
|
|
1098
|
+
* `nudo interface --draft`:从已有 JS **逻辑** 生成 interface 草稿。
|
|
1099
|
+
*
|
|
1100
|
+
* 产品位(代码优先 / 迁移):先写实现,再反推可审阅的 `fn({…}, …)` 草稿;
|
|
1101
|
+
* 人审后迁入 `*.nudo.js` 才成为契约。
|
|
1102
|
+
*
|
|
1103
|
+
* 证据分层(与 C0 一致:草稿 ≠ ambient 义务):
|
|
1104
|
+
* - callsite / directive case → joinThenProject 值域(迁移最可信)
|
|
1105
|
+
* - body 触达(**仅草稿展示**)→ 参数上被读到的字段名建议;不进 check
|
|
1106
|
+
* - generalize symbolic → 返回位兜底
|
|
1107
|
+
* - 无证据 → 参数槽省略 + 注释 TODO(不发明义务)
|
|
1108
|
+
* - 已有 handwritten 契约 → **跳过**(手写优先,不覆盖)
|
|
1109
|
+
*
|
|
1110
|
+
* 写盘:默认只打印;`--write` 写入 `<file>.nudo.draft.js`——**不会**被
|
|
1111
|
+
* sidecar 自动绑定(loadModule 只认 `*.nudo.js`)。审阅后复制进正式侧车。
|
|
1112
|
+
*/
|
|
1113
|
+
|
|
1114
|
+
/**
|
|
1115
|
+
* DraftEvidence `body` = 仅来自函数体对形参的成员读取(草稿建议,非义务)。
|
|
1116
|
+
* check / effectiveInterface **永不**消费该档。
|
|
1117
|
+
*/
|
|
1118
|
+
type DraftEvidence = "callsite" | "directive" | "symbolic" | "body" | "none";
|
|
1119
|
+
type InterfaceDraftEntry = {
|
|
1120
|
+
fn: string;
|
|
1121
|
+
/** 全部形参(含无证据槽,便于人读) */
|
|
1122
|
+
params: Array<{
|
|
1123
|
+
name: string;
|
|
1124
|
+
constraint?: NudoConstraint;
|
|
1125
|
+
display: string;
|
|
1126
|
+
/** false = 无证据,DSL 对象里省略该槽 */
|
|
1127
|
+
projected: boolean;
|
|
1128
|
+
/** 函数体读到的字段名(草稿建议;与 projected 无关) */
|
|
1129
|
+
bodyAccesses?: string[];
|
|
1130
|
+
}>;
|
|
1131
|
+
returns?: {
|
|
1132
|
+
constraint?: NudoConstraint;
|
|
1133
|
+
display: string;
|
|
1134
|
+
projected: boolean;
|
|
1135
|
+
};
|
|
1136
|
+
paramEvidence: DraftEvidence;
|
|
1137
|
+
returnEvidence: DraftEvidence;
|
|
1138
|
+
skipped?: "handwritten" | "not-an-export";
|
|
1139
|
+
/** 草稿 DSL:`fn({ … }, …)`;handwritten / 非导出时 undefined */
|
|
1140
|
+
dsl?: string;
|
|
1141
|
+
};
|
|
1142
|
+
type InterfaceDraftOpts = {
|
|
1143
|
+
fnNames?: string[];
|
|
1144
|
+
records?: CallRecord[];
|
|
1145
|
+
loadModule?: LoadModule;
|
|
1146
|
+
/**
|
|
1147
|
+
* Accepted for API compatibility; **ignored**. The handwritten-contract probe
|
|
1148
|
+
* always uses `effectiveInterface(..., { autoBind: true })` so draft skips
|
|
1149
|
+
* disk sidecars even when ambient autoBind is off (product: draft asks
|
|
1150
|
+
* "does a contract already exist?", not "is ambient binding on?").
|
|
1151
|
+
*/
|
|
1152
|
+
autoBind?: boolean;
|
|
1153
|
+
/** 默认 true:收集 body 成员读取作草稿建议(永不进 check) */
|
|
1154
|
+
bodyAccesses?: boolean;
|
|
1155
|
+
/** 打开 buffer 源(E5:与 hover/interface 同口径) */
|
|
1156
|
+
source?: string;
|
|
1157
|
+
};
|
|
1158
|
+
type InterfaceDraftResult = {
|
|
1159
|
+
file: string;
|
|
1160
|
+
entries: InterfaceDraftEntry[];
|
|
1161
|
+
draftSource: string;
|
|
1162
|
+
sidecarPath: string;
|
|
1163
|
+
};
|
|
1164
|
+
/**
|
|
1165
|
+
* Draft-only:收集每个顶层函数形参上的成员读取键(`user.name` → name)。
|
|
1166
|
+
* **不是** C0 禁止的 body→义务通道——只进草稿注释/建议,check 不读此表。
|
|
1167
|
+
*/
|
|
1168
|
+
declare function collectParamBodyAccesses(source: string): Map<string, Map<string, Set<string>>>;
|
|
1169
|
+
/**
|
|
1170
|
+
* 为单文件顶层导出生成 interface 草稿(不写盘)。
|
|
1171
|
+
* handwritten 跳过;已有 @generated 仍出草稿(便于对照)。
|
|
1172
|
+
*/
|
|
1173
|
+
declare function draftInterface(filePath: string, opts?: InterfaceDraftOpts): Promise<InterfaceDraftResult>;
|
|
1174
|
+
/** 草稿模块文本(人读 + 可复制到 *.nudo.js / *.nudo.ts) */
|
|
1175
|
+
declare function formatDraftModule(filePath: string, entries: InterfaceDraftEntry[], sidecarPath?: string): string;
|
|
1176
|
+
/** `lib.js|ts` → `lib.nudo.draft.js|ts`(不进 ambient sidecar 表) */
|
|
1177
|
+
declare function sidecarDraftPath(filePath: string): string;
|
|
1178
|
+
type WriteDraftResult = {
|
|
1179
|
+
draftPath: string;
|
|
1180
|
+
written: boolean;
|
|
1181
|
+
changed: boolean;
|
|
1182
|
+
draftable: boolean;
|
|
1183
|
+
draftSource: string;
|
|
1184
|
+
};
|
|
1185
|
+
/** Parse-layer draftable: at least one entry has generated DSL and was not skipped */
|
|
1186
|
+
declare function isDraftableEntry(entries: ReadonlyArray<Pick<InterfaceDraftEntry, "dsl" | "skipped">>): boolean;
|
|
1187
|
+
/**
|
|
1188
|
+
* 写入 `*.nudo.draft.js`(覆盖草稿文件本身;不碰正式 `*.nudo.js`)。
|
|
1189
|
+
* 基础路径防护:拒绝 node_modules;拒绝 draft 路径与正式侧车重合;
|
|
1190
|
+
* 拒绝 draft 路径落在源文件目录之外的穿越。
|
|
1191
|
+
*
|
|
1192
|
+
* `opts.entries` / `opts.draftable`:解析层判定(优先)。缺省时用 Unicode
|
|
1193
|
+
* 感知 export 正则兜底——`\w` 会静默丢掉 `计算` 这类标识符。
|
|
1194
|
+
*/
|
|
1195
|
+
declare function writeInterfaceDraft(filePath: string, draftSource: string, opts?: {
|
|
1196
|
+
dryRun?: boolean;
|
|
1197
|
+
projectDir?: string;
|
|
1198
|
+
entries?: ReadonlyArray<Pick<InterfaceDraftEntry, "dsl" | "skipped">>;
|
|
1199
|
+
draftable?: boolean;
|
|
1200
|
+
}): WriteDraftResult;
|
|
1201
|
+
declare function formatDraftSummary(sourceRel: string, draftRel: string, result: InterfaceDraftResult, write?: WriteDraftResult): string[];
|
|
1202
|
+
|
|
1203
|
+
/**
|
|
1204
|
+
* Root 驱动的契约下行(design-refine-derivation §4.2 / §11 Phase 2)。
|
|
1205
|
+
*
|
|
1206
|
+
* 对含手写契约根的文件(lib.nudo.js 绑定 add4):
|
|
1207
|
+
* 1. 从侧车 AST 抽出参数约束的源表达式(`positive` ← `./std.nudo.js`);
|
|
1208
|
+
* 2. constraintToEntryAbs + tagDerivationRoot;
|
|
1209
|
+
* 3. analyzeFn 求值 body(模块图注入下游),收集调用记录 + 推导打点;
|
|
1210
|
+
* 4. 闭包内下游导出投影为组合式 DSL,禁止事后从 Abs 反编译链。
|
|
1211
|
+
*
|
|
1212
|
+
* check 分轨:每条 root 链独立;join 只用于工件聚合(多调用者)。
|
|
1213
|
+
*/
|
|
1214
|
+
|
|
1215
|
+
type ConstraintSourceExpr = {
|
|
1216
|
+
expr: string;
|
|
1217
|
+
importFrom?: string;
|
|
1218
|
+
importName?: string;
|
|
1219
|
+
};
|
|
1220
|
+
type DerivedParam = {
|
|
1221
|
+
name: string;
|
|
1222
|
+
constraint: NudoConstraint;
|
|
1223
|
+
dsl: string;
|
|
1224
|
+
prelude: string[];
|
|
1225
|
+
imports: Array<{
|
|
1226
|
+
name: string;
|
|
1227
|
+
from: string;
|
|
1228
|
+
}>;
|
|
1229
|
+
/** 单链组合式投影时的推导图 root 节点 id(返回位相对锚定用) */
|
|
1230
|
+
rootNodeId?: number;
|
|
1231
|
+
/** 该参数位自 root 起消耗的 shift 步数(与 prelude 行数无关,读图) */
|
|
1232
|
+
shiftCount?: number;
|
|
1233
|
+
};
|
|
1234
|
+
type DerivedExport = {
|
|
1235
|
+
file: string;
|
|
1236
|
+
fn: string;
|
|
1237
|
+
paramNames: string[];
|
|
1238
|
+
params: DerivedParam[];
|
|
1239
|
+
returns?: {
|
|
1240
|
+
constraint: NudoConstraint;
|
|
1241
|
+
dsl: string;
|
|
1242
|
+
prelude: string[];
|
|
1243
|
+
imports: Array<{
|
|
1244
|
+
name: string;
|
|
1245
|
+
from: string;
|
|
1246
|
+
}>;
|
|
1247
|
+
};
|
|
1248
|
+
/** `lib.js:add4` */
|
|
1249
|
+
derivedFrom: string;
|
|
1250
|
+
compositional: boolean;
|
|
1251
|
+
underivable?: boolean;
|
|
1252
|
+
};
|
|
1253
|
+
type RootDeriveOpts = {
|
|
1254
|
+
loadModule?: LoadModule;
|
|
1255
|
+
autoBind?: boolean;
|
|
1256
|
+
fnNames?: string[];
|
|
1257
|
+
/**
|
|
1258
|
+
* true:只刷新目标侧车里**已存在**的 @generated 段(CLI 无 --fn/--all 时
|
|
1259
|
+
* 的默认行为——不发明新下游契约)。false/省略:闭包内全部可推导导出。
|
|
1260
|
+
*/
|
|
1261
|
+
refreshExistingOnly?: boolean;
|
|
1262
|
+
};
|
|
1263
|
+
type RootDeriveResult = {
|
|
1264
|
+
roots: string[];
|
|
1265
|
+
derived: DerivedExport[];
|
|
1266
|
+
hasRoot: boolean;
|
|
1267
|
+
};
|
|
1268
|
+
/** 从侧车源码抽出 `export const f = fn({ x: positive }, ret)` 的约束源表达式 */
|
|
1269
|
+
declare function extractFnConstraintSources(sidecarSrc: string, fnName: string): {
|
|
1270
|
+
params: Record<string, ConstraintSourceExpr>;
|
|
1271
|
+
returns?: ConstraintSourceExpr;
|
|
1272
|
+
};
|
|
1273
|
+
/**
|
|
1274
|
+
* 入口:对 filePath 做 root 驱动下行推导。
|
|
1275
|
+
*/
|
|
1276
|
+
declare function deriveFromRoot(filePath: string, opts?: RootDeriveOpts): RootDeriveResult;
|
|
1277
|
+
/**
|
|
1278
|
+
* 组装生成段(组合式 + import + prelude)。
|
|
1279
|
+
* importFrom 相对 root 侧车解析,再相对 target 侧车写出。
|
|
1280
|
+
*
|
|
1281
|
+
* `takenNames`:侧车顶层已占用标识符(手写 / 既有生成段 / 本批先前段)。
|
|
1282
|
+
* 同文件多导出时对 import local 与 prelude local 做避让改写,
|
|
1283
|
+
* 保证拼出的侧车在模块作用域内无重复声明。
|
|
1284
|
+
*/
|
|
1285
|
+
declare function formatDerivedSection(row: DerivedExport, opts: {
|
|
1286
|
+
rootSidecarDir: string;
|
|
1287
|
+
targetSidecarDir: string;
|
|
1288
|
+
takenNames?: Iterable<string>;
|
|
1289
|
+
}): {
|
|
1290
|
+
text: string;
|
|
1291
|
+
usedNames: string[];
|
|
1292
|
+
} | undefined;
|
|
1293
|
+
type EmitDerivedResult = {
|
|
1294
|
+
/** 被写/将写的下游侧车(绝对路径) */
|
|
1295
|
+
sidecars: Array<{
|
|
1296
|
+
file: string;
|
|
1297
|
+
sidecarPath: string;
|
|
1298
|
+
fn: string;
|
|
1299
|
+
written: boolean;
|
|
1300
|
+
changed: boolean;
|
|
1301
|
+
skipped?: "name-clash" | "not-projectable" | "underivable" | "no-change";
|
|
1302
|
+
diff?: string;
|
|
1303
|
+
issues: Array<{
|
|
1304
|
+
code: string;
|
|
1305
|
+
severity: "error" | "warning" | "info";
|
|
1306
|
+
message: string;
|
|
1307
|
+
}>;
|
|
1308
|
+
}>;
|
|
1309
|
+
hasRoot: boolean;
|
|
1310
|
+
roots: string[];
|
|
1311
|
+
/** 根在别处 / 无契约根且无已存在生成段 → info */
|
|
1312
|
+
entryOnly?: boolean;
|
|
1313
|
+
};
|
|
1314
|
+
declare function emitDerivedFromRoot(rootFile: string, opts: {
|
|
1315
|
+
fnNames?: string[];
|
|
1316
|
+
mode: "add" | "update";
|
|
1317
|
+
dryRun?: boolean;
|
|
1318
|
+
loadModule?: LoadModule;
|
|
1319
|
+
autoBind?: boolean;
|
|
1320
|
+
/** 只刷新目标侧车里已存在的 @generated 段(不发明新下游契约) */
|
|
1321
|
+
refreshExistingOnly?: boolean;
|
|
1322
|
+
}): EmitDerivedResult;
|
|
1323
|
+
|
|
1324
|
+
export { ANALYSIS_ABI, type AbsGraphOptions, type AbsMockSeeds, type AbsModuleCacheEntry, type AbsModuleGraphResult, type AbsModuleLoadIssue, AnalysisConfig, type AnalysisResult, type AnalysisSession, type BPathBuiltinUnknown, type BPathDiagnostics, type BPathRunResult, type BPathUnreachable, type BindingInfo, type BuildSemanticTokensOpts, CallRecord, type CaseHint, type CaseInfo, type CaseResult, type CompletionItem, type ConstraintSourceExpr, type DepContent, type DerivedExport, type DerivedParam, type Diagnostic, type DiagnosticSeverity, type DiagnosticTag, DiagnosticsLevel, DiskCache, type DiskCacheOptions, type DraftEvidence, type EmitDerivedResult, type EmitInterfaceOpts, type EmitInterfaceResult, type EmitInterfaceSkipReason, type EmitResult, type EmitSkipReason, type FunctionAnalysis, type HoverInfo, type InferJson, type InferJsonCase, type InferJsonFunction, type InterfaceDraftEntry, type InterfaceDraftOpts, type InterfaceDraftResult, type InterfaceSurfaceEntry, type InterfaceSurfaceOpts, type LoadModule, type ModuleExports, type ModuleGraphCache, type NodeEnvResult, type PackageHarvest, type ReferenceInfo, type RootDeriveOpts, type RootDeriveResult, SEMANTIC_TOKEN_MODIFIERS, SEMANTIC_TOKEN_TYPES, type SemanticToken, type SourceLocation, type SymbolInfo, type SymbolTable, type WriteDraftResult, absToTSType, absToZodSchema, ambientSourcesOfSidecar, analysisFileCacheKey, analyzeExportsFromSource, analyzeFile, analyzeFileAsync, autoHarvestModules, barePackageName, bareSpecToAbsModules, buildCaseDirective, buildModuleGraph, buildSemanticTokens, checkCacheKey, clearAbsModuleCache, clearAnalysisFileCache, clearAnalysisSessionCaches, clearBPathCache, clearEnvPathDeps, clearFnAnalysisCache, clearHarvestCache, collectAbsBindingsFromGraph, collectBPathDiagnostics, collectBPathReplacements, collectBarePackages, collectCallRecords, collectDependencySpecs, collectDtsFromEntry, collectEnvGlobals, collectEnvModules, collectLoadDepContents, collectParamBodyAccesses, collectStaticImports, computeDirtySet, defaultAbsLoadModule, defaultLoadModule, deriveFromRoot, diagnosticsLevelForFile, draftInterface, emitDerivedFromRoot, emitInterface, encodeSemanticTokens, envPathDependents, evalAbsModuleGraph, evalProgramAbsWithModules, evictAbsModuleCacheFiles, evictAnalysisCachesForFiles, evictAnalysisFileCacheForFiles, evictBPathCacheForFiles, evictFnAnalysisCacheForFiles, extractFnConstraintSources, extractNudoImportSpecs, filterDiagnosticsByLevel, formatDerivedSection, formatDraftModule, formatDraftSummary, formatEmitSummary, formatHarvestSummary, formatInterfaceSurfaceLine, generateDts, generateFunctionDtsLines, generateGuardFunction, generateGuardFunctionFromAbs, getAbsAtPosition, getAbsAtPositionAsync, getAnalysisFileCacheSize, getAnalysisSession, getCasesForFile, getCompletionsAtPosition, getHoverAtPosition, getTypeAtPosition, getTypeAtPositionAsync, harvestNodeTypes, harvestPackage, harvestPackageCached, harvestToAbsModules, harvestedValueToAbs, ifaceCacheKey, insertGeneratedCaseDirectives, interfaceSurface, interfaceTierModifierBit, isBPathCapable, isDraftableEntry, isEnvTemplatePath, isNudoTargetPath, isProjectConfigPath, isSidecarPath, isWatchRelevantPath, lookupHarvested, mockDirectivesToAbsSeeds, noteEnvPathDeps, packageHarvestToAbsModules, relativizePath, resetAllAnalysisCaches, resolvePackageRoot, serializeCaseArg, serializeInferJson, setAnalysisSession, sha256Hex, shouldAnalyzeFile, sidecarDraftPath, hasNudoDirectives as sourceHasNudoDirectives, stripGeneratedCaseDirectives, summarizeNodeEnv, topoSortDirty, tryBPathCall, tryBPathCallFull, tryRunBPath, unifiedDiff, writeInterfaceDraft };
|