@mka-rainmaker/ama 0.1.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/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/analyzers/baseline/analyzer.d.ts +47 -0
- package/dist/analyzers/baseline/analyzer.d.ts.map +1 -0
- package/dist/analyzers/baseline/analyzer.js +84 -0
- package/dist/analyzers/baseline/analyzer.js.map +1 -0
- package/dist/analyzers/baseline/c.d.ts +12 -0
- package/dist/analyzers/baseline/c.d.ts.map +1 -0
- package/dist/analyzers/baseline/c.js +56 -0
- package/dist/analyzers/baseline/c.js.map +1 -0
- package/dist/analyzers/baseline/config.d.ts +21 -0
- package/dist/analyzers/baseline/config.d.ts.map +1 -0
- package/dist/analyzers/baseline/config.js +32 -0
- package/dist/analyzers/baseline/config.js.map +1 -0
- package/dist/analyzers/baseline/csharp.d.ts +9 -0
- package/dist/analyzers/baseline/csharp.d.ts.map +1 -0
- package/dist/analyzers/baseline/csharp.js +107 -0
- package/dist/analyzers/baseline/csharp.js.map +1 -0
- package/dist/analyzers/baseline/go.d.ts +11 -0
- package/dist/analyzers/baseline/go.d.ts.map +1 -0
- package/dist/analyzers/baseline/go.js +66 -0
- package/dist/analyzers/baseline/go.js.map +1 -0
- package/dist/analyzers/baseline/java.d.ts +9 -0
- package/dist/analyzers/baseline/java.d.ts.map +1 -0
- package/dist/analyzers/baseline/java.js +50 -0
- package/dist/analyzers/baseline/java.js.map +1 -0
- package/dist/analyzers/baseline/javascript.d.ts +10 -0
- package/dist/analyzers/baseline/javascript.d.ts.map +1 -0
- package/dist/analyzers/baseline/javascript.js +55 -0
- package/dist/analyzers/baseline/javascript.js.map +1 -0
- package/dist/analyzers/baseline/kotlin.d.ts +11 -0
- package/dist/analyzers/baseline/kotlin.d.ts.map +1 -0
- package/dist/analyzers/baseline/kotlin.js +67 -0
- package/dist/analyzers/baseline/kotlin.js.map +1 -0
- package/dist/analyzers/baseline/paths.d.ts +6 -0
- package/dist/analyzers/baseline/paths.d.ts.map +1 -0
- package/dist/analyzers/baseline/paths.js +17 -0
- package/dist/analyzers/baseline/paths.js.map +1 -0
- package/dist/analyzers/baseline/php.d.ts +11 -0
- package/dist/analyzers/baseline/php.d.ts.map +1 -0
- package/dist/analyzers/baseline/php.js +76 -0
- package/dist/analyzers/baseline/php.js.map +1 -0
- package/dist/analyzers/baseline/python.d.ts +10 -0
- package/dist/analyzers/baseline/python.d.ts.map +1 -0
- package/dist/analyzers/baseline/python.js +63 -0
- package/dist/analyzers/baseline/python.js.map +1 -0
- package/dist/analyzers/baseline/rust.d.ts +10 -0
- package/dist/analyzers/baseline/rust.d.ts.map +1 -0
- package/dist/analyzers/baseline/rust.js +45 -0
- package/dist/analyzers/baseline/rust.js.map +1 -0
- package/dist/analyzers/baseline/swift.d.ts +11 -0
- package/dist/analyzers/baseline/swift.d.ts.map +1 -0
- package/dist/analyzers/baseline/swift.js +19 -0
- package/dist/analyzers/baseline/swift.js.map +1 -0
- package/dist/analyzers/baseline/treesitter.d.ts +11 -0
- package/dist/analyzers/baseline/treesitter.d.ts.map +1 -0
- package/dist/analyzers/baseline/treesitter.js +87 -0
- package/dist/analyzers/baseline/treesitter.js.map +1 -0
- package/dist/analyzers/baseline/walk.d.ts +26 -0
- package/dist/analyzers/baseline/walk.d.ts.map +1 -0
- package/dist/analyzers/baseline/walk.js +76 -0
- package/dist/analyzers/baseline/walk.js.map +1 -0
- package/dist/analyzers/registry.d.ts +19 -0
- package/dist/analyzers/registry.d.ts.map +1 -0
- package/dist/analyzers/registry.js +43 -0
- package/dist/analyzers/registry.js.map +1 -0
- package/dist/analyzers/sfc/analyzer.d.ts +17 -0
- package/dist/analyzers/sfc/analyzer.d.ts.map +1 -0
- package/dist/analyzers/sfc/analyzer.js +141 -0
- package/dist/analyzers/sfc/analyzer.js.map +1 -0
- package/dist/analyzers/sidecar/analyzer.d.ts +29 -0
- package/dist/analyzers/sidecar/analyzer.d.ts.map +1 -0
- package/dist/analyzers/sidecar/analyzer.js +114 -0
- package/dist/analyzers/sidecar/analyzer.js.map +1 -0
- package/dist/analyzers/sidecar/protocol.d.ts +508 -0
- package/dist/analyzers/sidecar/protocol.d.ts.map +1 -0
- package/dist/analyzers/sidecar/protocol.js +102 -0
- package/dist/analyzers/sidecar/protocol.js.map +1 -0
- package/dist/analyzers/types.d.ts +46 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +2 -0
- package/dist/analyzers/types.js.map +1 -0
- package/dist/analyzers/typescript/analyzer.d.ts +126 -0
- package/dist/analyzers/typescript/analyzer.d.ts.map +1 -0
- package/dist/analyzers/typescript/analyzer.js +1600 -0
- package/dist/analyzers/typescript/analyzer.js.map +1 -0
- package/dist/cli/commands/cycles.d.ts +6 -0
- package/dist/cli/commands/cycles.d.ts.map +1 -0
- package/dist/cli/commands/cycles.js +27 -0
- package/dist/cli/commands/cycles.js.map +1 -0
- package/dist/cli/commands/files.d.ts +6 -0
- package/dist/cli/commands/files.d.ts.map +1 -0
- package/dist/cli/commands/files.js +33 -0
- package/dist/cli/commands/files.js.map +1 -0
- package/dist/cli/commands/impact.d.ts +18 -0
- package/dist/cli/commands/impact.d.ts.map +1 -0
- package/dist/cli/commands/impact.js +113 -0
- package/dist/cli/commands/impact.js.map +1 -0
- package/dist/cli/commands/lifecycle.d.ts +5 -0
- package/dist/cli/commands/lifecycle.d.ts.map +1 -0
- package/dist/cli/commands/lifecycle.js +83 -0
- package/dist/cli/commands/lifecycle.js.map +1 -0
- package/dist/cli/commands/query.d.ts +31 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +187 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/search.d.ts +21 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +160 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/status.d.ts +6 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +63 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +6 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +57 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/emit.d.ts +9 -0
- package/dist/cli/emit.d.ts.map +1 -0
- package/dist/cli/emit.js +10 -0
- package/dist/cli/emit.js.map +1 -0
- package/dist/cli/index.d.ts +37 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +128 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/paths.d.ts +7 -0
- package/dist/cli/paths.d.ts.map +1 -0
- package/dist/cli/paths.js +10 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/query-runner.d.ts +13 -0
- package/dist/cli/query-runner.d.ts.map +1 -0
- package/dist/cli/query-runner.js +33 -0
- package/dist/cli/query-runner.js.map +1 -0
- package/dist/graph/dispatch.d.ts +17 -0
- package/dist/graph/dispatch.d.ts.map +1 -0
- package/dist/graph/dispatch.js +82 -0
- package/dist/graph/dispatch.js.map +1 -0
- package/dist/graph/id.d.ts +19 -0
- package/dist/graph/id.d.ts.map +1 -0
- package/dist/graph/id.js +17 -0
- package/dist/graph/id.js.map +1 -0
- package/dist/graph/index.d.ts +6 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +4 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/types.d.ts +71 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +52 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/indexer/debouncer.d.ts +32 -0
- package/dist/indexer/debouncer.d.ts.map +1 -0
- package/dist/indexer/debouncer.js +81 -0
- package/dist/indexer/debouncer.js.map +1 -0
- package/dist/indexer/ignore.d.ts +55 -0
- package/dist/indexer/ignore.d.ts.map +1 -0
- package/dist/indexer/ignore.js +170 -0
- package/dist/indexer/ignore.js.map +1 -0
- package/dist/indexer/indexer.d.ts +112 -0
- package/dist/indexer/indexer.d.ts.map +1 -0
- package/dist/indexer/indexer.js +392 -0
- package/dist/indexer/indexer.js.map +1 -0
- package/dist/indexer/watcher.d.ts +50 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +86 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/mcp/build-info.d.ts +16 -0
- package/dist/mcp/build-info.d.ts.map +1 -0
- package/dist/mcp/build-info.js +54 -0
- package/dist/mcp/build-info.js.map +1 -0
- package/dist/mcp/http.d.ts +18 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +145 -0
- package/dist/mcp/http.js.map +1 -0
- package/dist/mcp/server.d.ts +22 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +401 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +155 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +319 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/query/service.d.ts +329 -0
- package/dist/query/service.d.ts.map +1 -0
- package/dist/query/service.js +959 -0
- package/dist/query/service.js.map +1 -0
- package/dist/runtime/entrypoint.d.ts +11 -0
- package/dist/runtime/entrypoint.d.ts.map +1 -0
- package/dist/runtime/entrypoint.js +22 -0
- package/dist/runtime/entrypoint.js.map +1 -0
- package/dist/runtime/quiet-sqlite-warning.d.ts +14 -0
- package/dist/runtime/quiet-sqlite-warning.d.ts.map +1 -0
- package/dist/runtime/quiet-sqlite-warning.js +26 -0
- package/dist/runtime/quiet-sqlite-warning.js.map +1 -0
- package/dist/runtime/wasm-tier.d.ts +2 -0
- package/dist/runtime/wasm-tier.d.ts.map +1 -0
- package/dist/runtime/wasm-tier.js +54 -0
- package/dist/runtime/wasm-tier.js.map +1 -0
- package/dist/store/memory.d.ts +54 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +210 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/sqlite.d.ts +38 -0
- package/dist/store/sqlite.d.ts.map +1 -0
- package/dist/store/sqlite.js +298 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/types.d.ts +76 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +2 -0
- package/dist/store/types.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { EDGE_KINDS, NODE_KINDS } from "../../graph/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Wire protocol for out-of-process deep analyzers ("sidecars"). (ama-3bb.1)
|
|
5
|
+
*
|
|
6
|
+
* A sidecar is a subprocess that does semantic analysis for a language Ama can't
|
|
7
|
+
* analyze deeply in-process (.NET via Roslyn, Java via native tooling) and speaks this
|
|
8
|
+
* protocol back. The contract here is language-agnostic; each sidecar implements its own
|
|
9
|
+
* end in its own runtime.
|
|
10
|
+
*
|
|
11
|
+
* **Transport.** Newline-delimited JSON (NDJSON): one JSON object per line. Ama writes
|
|
12
|
+
* requests to the sidecar's **stdin** and reads messages from its **stdout**. The
|
|
13
|
+
* sidecar's **stderr** is for its own logs only — never protocol — exactly the
|
|
14
|
+
* "stdout is JSON-only" rule Ama's own MCP server follows.
|
|
15
|
+
*
|
|
16
|
+
* **Lifecycle.** On startup a sidecar SHOULD emit a `ready` message announcing the
|
|
17
|
+
* language it serves (so the indexer can route and report it). Ama then sends `analyze`
|
|
18
|
+
* requests; the sidecar replies with a `result` (correlated by the request `id`) or an
|
|
19
|
+
* `error`. Ama closes the sidecar's stdin to request shutdown.
|
|
20
|
+
*
|
|
21
|
+
* **Tier.** Everything a sidecar produces is tier `deep` — that is the whole point of
|
|
22
|
+
* running one instead of the baseline syntactic analyzer.
|
|
23
|
+
*/
|
|
24
|
+
const tierSchema = z.enum(["deep", "baseline"]);
|
|
25
|
+
const provenanceSchema = z.enum(["resolved", "heuristic", "dispatch"]);
|
|
26
|
+
const sourceRangeSchema = z.object({ startLine: z.number(), endLine: z.number() });
|
|
27
|
+
const siteSchema = z.object({ line: z.number(), column: z.number() });
|
|
28
|
+
/** A {@link GraphNode} on the wire. Kept in lockstep with the graph model; the node/edge
|
|
29
|
+
* round-trip test fails if a required field drifts. */
|
|
30
|
+
export const graphNodeSchema = z.object({
|
|
31
|
+
id: z.string(),
|
|
32
|
+
kind: z.enum(NODE_KINDS),
|
|
33
|
+
name: z.string(),
|
|
34
|
+
file: z.string(),
|
|
35
|
+
qualifiedName: z.string(),
|
|
36
|
+
range: sourceRangeSchema.optional(),
|
|
37
|
+
tier: tierSchema,
|
|
38
|
+
});
|
|
39
|
+
/** A {@link GraphEdge} on the wire. */
|
|
40
|
+
export const graphEdgeSchema = z.object({
|
|
41
|
+
from: z.string(),
|
|
42
|
+
to: z.string(),
|
|
43
|
+
kind: z.enum(EDGE_KINDS),
|
|
44
|
+
provenance: provenanceSchema.optional(),
|
|
45
|
+
at: siteSchema.optional(),
|
|
46
|
+
sites: z.array(siteSchema).optional(),
|
|
47
|
+
});
|
|
48
|
+
const resolutionStatsSchema = z.object({
|
|
49
|
+
callsTotal: z.number(),
|
|
50
|
+
callsResolved: z.number(),
|
|
51
|
+
unresolved: z.record(z.string(), z.number()),
|
|
52
|
+
});
|
|
53
|
+
/** Ama → sidecar: analyze these repo-relative `files` rooted at the absolute `root`.
|
|
54
|
+
* `id` correlates the matching `result`/`error`. */
|
|
55
|
+
export const analyzeRequestSchema = z.object({
|
|
56
|
+
type: z.literal("analyze"),
|
|
57
|
+
id: z.number(),
|
|
58
|
+
root: z.string(),
|
|
59
|
+
files: z.array(z.string()),
|
|
60
|
+
});
|
|
61
|
+
/** Sidecar → Ama: a startup handshake announcing the language served. */
|
|
62
|
+
const readySchema = z.object({
|
|
63
|
+
type: z.literal("ready"),
|
|
64
|
+
language: z.string(),
|
|
65
|
+
version: z.string().optional(),
|
|
66
|
+
});
|
|
67
|
+
/** Sidecar → Ama: the analysis of one request's files. */
|
|
68
|
+
const resultSchema = z.object({
|
|
69
|
+
type: z.literal("result"),
|
|
70
|
+
id: z.number(),
|
|
71
|
+
nodes: z.array(graphNodeSchema),
|
|
72
|
+
edges: z.array(graphEdgeSchema),
|
|
73
|
+
resolution: resolutionStatsSchema.optional(),
|
|
74
|
+
});
|
|
75
|
+
/** Sidecar → Ama: a failure, optionally tied to a request `id`. */
|
|
76
|
+
const errorSchema = z.object({
|
|
77
|
+
type: z.literal("error"),
|
|
78
|
+
id: z.number().optional(),
|
|
79
|
+
message: z.string(),
|
|
80
|
+
});
|
|
81
|
+
/** Any message a sidecar sends to Ama. */
|
|
82
|
+
export const sidecarMessageSchema = z.discriminatedUnion("type", [
|
|
83
|
+
readySchema,
|
|
84
|
+
resultSchema,
|
|
85
|
+
errorSchema,
|
|
86
|
+
]);
|
|
87
|
+
/** Encode a protocol message as one NDJSON line (its JSON, plus the framing newline).
|
|
88
|
+
* Used by both ends; a message must contain no raw newline of its own (JSON escapes them). */
|
|
89
|
+
export function frame(message) {
|
|
90
|
+
return `${JSON.stringify(message)}\n`;
|
|
91
|
+
}
|
|
92
|
+
/** Parse one inbound line as an `analyze` request (the sidecar's side). Throws (ZodError
|
|
93
|
+
* or SyntaxError) on a malformed or invalid line. */
|
|
94
|
+
export function parseRequest(line) {
|
|
95
|
+
return analyzeRequestSchema.parse(JSON.parse(line));
|
|
96
|
+
}
|
|
97
|
+
/** Parse one inbound line as a sidecar message (Ama's side). Throws on a malformed or
|
|
98
|
+
* invalid line, so a buggy sidecar can't inject an ill-formed node/edge into the graph. */
|
|
99
|
+
export function parseMessage(line) {
|
|
100
|
+
return sidecarMessageSchema.parse(JSON.parse(line));
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/analyzers/sidecar/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { GraphEdge, GraphNode, Tier } from "../graph/index.js";
|
|
2
|
+
/** How many references an analyzer tried to resolve vs actually resolved — the
|
|
3
|
+
* basis for an honest "resolution coverage" metric. (ama-m8k.12) */
|
|
4
|
+
export interface ResolutionStats {
|
|
5
|
+
/** Call/construction sites inside a function (those that can become an edge). */
|
|
6
|
+
callsTotal: number;
|
|
7
|
+
/** Of those, how many resolved to a known target node (the rest are external
|
|
8
|
+
* or dynamic — library calls, computed dispatch). */
|
|
9
|
+
callsResolved: number;
|
|
10
|
+
/** The unresolved calls, counted by callee root name (e.g. `ts`, `console`,
|
|
11
|
+
* `path`) — what the code calls that Ama can't see. (ama-qbn) */
|
|
12
|
+
unresolved: Record<string, number>;
|
|
13
|
+
}
|
|
14
|
+
/** Nodes and edges produced by analyzing a set of files. */
|
|
15
|
+
export interface AnalysisResult {
|
|
16
|
+
nodes: GraphNode[];
|
|
17
|
+
edges: GraphEdge[];
|
|
18
|
+
/** Resolution coverage, when the analyzer measures it. Deep analyzers report
|
|
19
|
+
* it; a baseline (syntactic) analyzer resolves nothing, so it omits this. */
|
|
20
|
+
resolution?: ResolutionStats;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A per-language analyzer. Each declares its capability {@link Tier} so every
|
|
24
|
+
* result can be attributed honestly: a `baseline` (syntactic) analyzer must
|
|
25
|
+
* never be mistaken for `deep` (semantic) coverage.
|
|
26
|
+
*/
|
|
27
|
+
export interface Analyzer {
|
|
28
|
+
/** Human-readable language name, e.g. "typescript". */
|
|
29
|
+
readonly language: string;
|
|
30
|
+
/** Capability tier this analyzer reports. */
|
|
31
|
+
readonly tier: Tier;
|
|
32
|
+
/** File extensions this analyzer handles, including the dot, e.g. [".ts"]. */
|
|
33
|
+
readonly extensions: readonly string[];
|
|
34
|
+
/**
|
|
35
|
+
* Analyze `files` (repo-relative paths) rooted at the absolute `root`,
|
|
36
|
+
* returning the nodes and edges they define.
|
|
37
|
+
*/
|
|
38
|
+
analyze(root: string, files: string[]): AnalysisResult | Promise<AnalysisResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Whether this analyzer can actually run right now. In-process analyzers omit it
|
|
41
|
+
* (always available); an out-of-process sidecar probes its subprocess so routing can
|
|
42
|
+
* prefer it only when present, falling back to baseline otherwise. (ama-3bb.4)
|
|
43
|
+
*/
|
|
44
|
+
isAvailable?(): boolean | Promise<boolean>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEpE;qEACqE;AACrE,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IACnB;0DACsD;IACtD,aAAa,EAAE,MAAM,CAAC;IACtB;sEACkE;IAClE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB;kFAC8E;IAC9E,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEjF;;;;OAIG;IACH,WAAW,CAAC,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { AnalysisResult, Analyzer } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Deep TypeScript analyzer built on the TypeScript Compiler API.
|
|
4
|
+
*
|
|
5
|
+
* Two passes over each source file:
|
|
6
|
+
* 1. Structural — emit nodes (File, Function, Class, Interface, Enum, TypeAlias,
|
|
7
|
+
* Method, Property — see `describe` for the full set) and `Defines` edges,
|
|
8
|
+
* recording each declaration's AST node so later references link back to ids.
|
|
9
|
+
* 2. Resolution — through the type checker, emit `Calls` edges (enclosing
|
|
10
|
+
* function/method → callee), `Inherits`/`Implements` edges (class → base
|
|
11
|
+
* class / interface), `UsesType` edges (enclosing symbol → each named type
|
|
12
|
+
* used in a parameter, return, or property annotation), and `Imports` edges
|
|
13
|
+
* (file → each symbol it imports or re-exports). References to symbols
|
|
14
|
+
* outside the analyzed set (library code) resolve to no node and are
|
|
15
|
+
* skipped, so the graph only asserts edges it can actually back.
|
|
16
|
+
*/
|
|
17
|
+
export declare class TypeScriptAnalyzer implements Analyzer {
|
|
18
|
+
readonly language = "typescript";
|
|
19
|
+
readonly tier: "deep";
|
|
20
|
+
readonly extensions: readonly [".ts", ".tsx", ".mts", ".cts"];
|
|
21
|
+
analyze(root: string, files: string[]): AnalysisResult;
|
|
22
|
+
private walkFile;
|
|
23
|
+
private visit;
|
|
24
|
+
/** Walk a subtree, attributing each call to the nearest enclosing symbol — or,
|
|
25
|
+
* for a call at true module scope, to the File node so module-level wiring is
|
|
26
|
+
* queryable. `atFileScope` is true until the walk enters any function body.
|
|
27
|
+
* (ama-53q) */
|
|
28
|
+
private collectCalls;
|
|
29
|
+
/**
|
|
30
|
+
* Emit a `References` edge from the enclosing symbol to a module-level Variable
|
|
31
|
+
* node (ama-hft.12) each time its value is read — so `find_callers("MAX_RETRIES")`
|
|
32
|
+
* answers "who reads this constant". Mirrors `collectCalls`' enclosing-tracking.
|
|
33
|
+
*
|
|
34
|
+
* `resolveModuleVarRef` restricts targets to top-level const/let/var
|
|
35
|
+
* declarations (by *decl kind*, not a batch-local id set), so reads of
|
|
36
|
+
* functions/classes don't become References — and a cross-file const still
|
|
37
|
+
* resolves in a single-file reindex, where the batch holds no other file's
|
|
38
|
+
* Variable nodes (ama-l6k). Most false positives filter themselves out: a
|
|
39
|
+
* property-access member name and an import specifier resolve away, and a
|
|
40
|
+
* declaration's own name is caught by the `to !== enclosingId` guard. (ama-6k0)
|
|
41
|
+
*/
|
|
42
|
+
private collectVarReferences;
|
|
43
|
+
/** Walk a subtree emitting an `Implements` edge for each `class … implements I`. */
|
|
44
|
+
private collectHeritage;
|
|
45
|
+
/**
|
|
46
|
+
* Emit an `Imports` edge from a file to each symbol it imports, and from a
|
|
47
|
+
* re-exporting file (`export { x } from "./m.js"`) to the re-exported symbol.
|
|
48
|
+
* Import/re-export bindings are aliases, so the edge target is the symbol's
|
|
49
|
+
* original declaration — even through a chain of barrels.
|
|
50
|
+
*/
|
|
51
|
+
private collectImports;
|
|
52
|
+
/**
|
|
53
|
+
* Emit a `UsesType` edge for each named type referenced in a parameter, a
|
|
54
|
+
* function/method return type, a property type, or a generic instantiation's
|
|
55
|
+
* type arguments (`f<Widget>()`, `new Box<Widget>()`, `extends Base<Widget>`),
|
|
56
|
+
* attributed to the nearest enclosing emitted symbol. Composite annotations are
|
|
57
|
+
* walked, so `Widget[]` or `Map<K, Widget>` still link to `Widget`. Types
|
|
58
|
+
* outside the analyzed set (`number`, library types) resolve to no node and are
|
|
59
|
+
* skipped.
|
|
60
|
+
*/
|
|
61
|
+
private collectTypeUsages;
|
|
62
|
+
/**
|
|
63
|
+
* Detect framework routes (Express/NestJS-style call APIs: `app.get("/x", h)`,
|
|
64
|
+
* `router.post(...)`) and emit a Route node per route, plus a References edge to
|
|
65
|
+
* each named handler. Deliberately scoped to avoid false positives: an HTTP-verb
|
|
66
|
+
* method call whose first arg is a "/"-prefixed string literal and which has at
|
|
67
|
+
* least one handler arg (so `map.get("k")` / `headers.get("x")` don't match).
|
|
68
|
+
* Inline arrow/function handlers get a Route node but no edge yet — naming an
|
|
69
|
+
* anonymous handler is the arg-position-handler follow-up (ama-y9q).
|
|
70
|
+
*/
|
|
71
|
+
private collectRoutes;
|
|
72
|
+
/**
|
|
73
|
+
* Wire a route to its handler argument(s): an inline arrow/function becomes a
|
|
74
|
+
* synthesized handler Function node (named by the route, registered so its body
|
|
75
|
+
* attributes to it), while a named handler reference resolves to its node. Each
|
|
76
|
+
* gets a heuristic References edge from the route. Shared by every route style.
|
|
77
|
+
* (ama-rme.1, ama-rme.10)
|
|
78
|
+
*/
|
|
79
|
+
private emitRouteHandlers;
|
|
80
|
+
/**
|
|
81
|
+
* Synthesize a Function node for an inline arrow/function-expression passed as an
|
|
82
|
+
* argument to a *string-named* call whose result is itself consumed —
|
|
83
|
+
* `register("work", wrap("work", () => …))`. The leading string literal names the
|
|
84
|
+
* node (`"work handler"`); registering the arrow in `declToId` before
|
|
85
|
+
* `collectCalls` makes the callback body's calls attribute to it instead of
|
|
86
|
+
* leaking to the enclosing function (so per-handler blast radius is precise).
|
|
87
|
+
*
|
|
88
|
+
* Runs after `collectRoutes`, so a route's inline handler — already registered —
|
|
89
|
+
* is skipped. The "result is consumed" gate (the call is not a bare expression
|
|
90
|
+
* statement) is what separates a handler-producing wrapper like `tap(name, fn)`
|
|
91
|
+
* from a fire-and-forget test block like `it(name, fn)` / `describe(name, fn)`:
|
|
92
|
+
* only the former becomes a node, so the graph isn't flooded with one node per
|
|
93
|
+
* test case. (ama-y9q)
|
|
94
|
+
*
|
|
95
|
+
* The handler need not be a *direct* argument: it may be nested inside a second
|
|
96
|
+
* wrapper whose own first argument is not a string — `tap("search",
|
|
97
|
+
* queryTool(session, () => …))`. `collectHandlerArrows` digs through such
|
|
98
|
+
* wrapper-call arguments (stopping at the first function, so a handler's body is
|
|
99
|
+
* never mistaken for another handler), keying every one by the outer name. (ama-63x)
|
|
100
|
+
*/
|
|
101
|
+
private collectCallbackHandlers;
|
|
102
|
+
/**
|
|
103
|
+
* File-based routing: a route file at a framework convention path exports HTTP
|
|
104
|
+
* method handlers and the URL comes from the *path* (not a call). Next.js App
|
|
105
|
+
* Router (`app/**/route.ts`) and SvelteKit (`src/routes/**/+server.ts`) — each
|
|
106
|
+
* exported `GET`/`POST`/… function becomes a `<METHOD> <path>` Route referencing
|
|
107
|
+
* it. Heuristic: the route is inferred from filesystem convention. (ama-rme.7)
|
|
108
|
+
*/
|
|
109
|
+
private collectFileRoutes;
|
|
110
|
+
/**
|
|
111
|
+
* Synthesize call edges for the EventEmitter pattern: an `emitter.emit("ch")`
|
|
112
|
+
* invokes every handler registered with `.on("ch", h)` (or once/addListener)
|
|
113
|
+
* for the same channel string. Heuristic — matched by channel name, not proven
|
|
114
|
+
* dispatch — so the synthesized edges carry `provenance: "heuristic"`. Runs
|
|
115
|
+
* after collectCallbackHandlers so inline `.on("ch", () => …)` arrows (already
|
|
116
|
+
* synthesized into handler nodes there) are connectable too. (ama-hft.14)
|
|
117
|
+
*/
|
|
118
|
+
private collectEvents;
|
|
119
|
+
/**
|
|
120
|
+
* Find Express mounts — `app.use("/prefix", router, …)` — and map each mounted
|
|
121
|
+
* argument's declaration to the prefix. Runs over every file before route
|
|
122
|
+
* detection so a router defined in one file and mounted in another composes.
|
|
123
|
+
*/
|
|
124
|
+
private collectMounts;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/typescript/analyzer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAmB,MAAM,aAAa,CAAC;AAkB7E;;;;;;;;;;;;;;GAcG;AACH,qBAAa,kBAAmB,YAAW,QAAQ;IACjD,QAAQ,CAAC,QAAQ,gBAAgB;IACjC,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAU;IAChC,QAAQ,CAAC,UAAU,2CAA4C;IAE/D,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc;IA+FtD,OAAO,CAAC,QAAQ;IAyBhB,OAAO,CAAC,KAAK;IAqHb;;;oBAGgB;IAChB,OAAO,CAAC,YAAY;IAoGpB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,oBAAoB;IA6D5B,oFAAoF;IACpF,OAAO,CAAC,eAAe;IAqBvB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAkDtB;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;IAkEzB;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAoOrB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAsCzB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,uBAAuB;IA6D/B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IA8FzB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IA0ErB;;;;OAIG;IACH,OAAO,CAAC,aAAa;CA0BtB"}
|