@opensip-cli/graph-adapter-common 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 +202 -0
- package/NOTICE +8 -0
- package/README.md +31 -0
- package/dist/__tests__/discover-config.test.d.ts +16 -0
- package/dist/__tests__/discover-config.test.d.ts.map +1 -0
- package/dist/__tests__/discover-config.test.js +67 -0
- package/dist/__tests__/discover-config.test.js.map +1 -0
- package/dist/__tests__/helpers.test.d.ts +2 -0
- package/dist/__tests__/helpers.test.d.ts.map +1 -0
- package/dist/__tests__/helpers.test.js +258 -0
- package/dist/__tests__/helpers.test.js.map +1 -0
- package/dist/__tests__/parse-from-adapter.test.d.ts +14 -0
- package/dist/__tests__/parse-from-adapter.test.d.ts.map +1 -0
- package/dist/__tests__/parse-from-adapter.test.js +93 -0
- package/dist/__tests__/parse-from-adapter.test.js.map +1 -0
- package/dist/__tests__/run-walk.test.d.ts +12 -0
- package/dist/__tests__/run-walk.test.d.ts.map +1 -0
- package/dist/__tests__/run-walk.test.js +183 -0
- package/dist/__tests__/run-walk.test.js.map +1 -0
- package/dist/body-digest.d.ts +25 -0
- package/dist/body-digest.d.ts.map +1 -0
- package/dist/body-digest.js +39 -0
- package/dist/body-digest.js.map +1 -0
- package/dist/cache-key.d.ts +34 -0
- package/dist/cache-key.d.ts.map +1 -0
- package/dist/cache-key.js +54 -0
- package/dist/cache-key.js.map +1 -0
- package/dist/discover.d.ts +35 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +114 -0
- package/dist/discover.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/parse-from-adapter.d.ts +24 -0
- package/dist/parse-from-adapter.d.ts.map +1 -0
- package/dist/parse-from-adapter.js +81 -0
- package/dist/parse-from-adapter.js.map +1 -0
- package/dist/parse.d.ts +24 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +14 -0
- package/dist/parse.js.map +1 -0
- package/dist/return-discarded.d.ts +22 -0
- package/dist/return-discarded.d.ts.map +1 -0
- package/dist/return-discarded.js +31 -0
- package/dist/return-discarded.js.map +1 -0
- package/dist/walk.d.ts +108 -0
- package/dist/walk.d.ts.map +1 -0
- package/dist/walk.js +141 -0
- package/dist/walk.js.map +1 -0
- package/package.json +49 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @opensip-cli/graph-adapter-common — shared scaffolding for the
|
|
3
|
+
* tree-sitter graph language adapters (graph-go, graph-java,
|
|
4
|
+
* graph-python, graph-rust).
|
|
5
|
+
*
|
|
6
|
+
* This is a *helper layer for implementing* the engine's
|
|
7
|
+
* `GraphLanguageAdapter` contract, not a change to it. It sits downstream
|
|
8
|
+
* of `@opensip-cli/graph` (the engine) and upstream of the four
|
|
9
|
+
* tree-sitter adapters:
|
|
10
|
+
*
|
|
11
|
+
* core → … → graph (engine) → graph-adapter-common → graph-{go,java,python,rust}
|
|
12
|
+
*
|
|
13
|
+
* It exports `createX` factories that return values; the adapter composes
|
|
14
|
+
* them. It exports NO `adapter` / `metadata` — it is a library, not a
|
|
15
|
+
* discoverable graph adapter (its package.json deliberately omits
|
|
16
|
+
* `opensipTools.kind`). `graph-typescript` (TS-compiler-backed, not
|
|
17
|
+
* tree-sitter) shares none of this and must not depend on it.
|
|
18
|
+
*/
|
|
19
|
+
export { createDiscover, type TreeSitterDiscoverConfig } from './discover.js';
|
|
20
|
+
export { type TreeSitterParsedFile, type TreeSitterParsedProject } from './parse.js';
|
|
21
|
+
export { createParseProjectFromAdapter } from './parse-from-adapter.js';
|
|
22
|
+
export { hashConfig, makeConfigCacheKey } from './cache-key.js';
|
|
23
|
+
export { skipToEndOfLine, skipBlockComment } from './body-digest.js';
|
|
24
|
+
export { isReturnValueDiscarded } from './return-discarded.js';
|
|
25
|
+
export { record, makeFileClassifier, type FileClassifier, type FileClassifierConfig, runWalk, type RunWalkParams, type WalkSinks, synthesizeModuleInit, type SynthesizeModuleInitParams, buildNameIndex, nameOf, childrenOf, namedChildrenOf, } from './walk.js';
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9E,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAErF,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAExE,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,OAAO,EACP,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,oBAAoB,EACpB,KAAK,0BAA0B,EAC/B,cAAc,EACd,MAAM,EACN,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @opensip-cli/graph-adapter-common — shared scaffolding for the
|
|
3
|
+
* tree-sitter graph language adapters (graph-go, graph-java,
|
|
4
|
+
* graph-python, graph-rust).
|
|
5
|
+
*
|
|
6
|
+
* This is a *helper layer for implementing* the engine's
|
|
7
|
+
* `GraphLanguageAdapter` contract, not a change to it. It sits downstream
|
|
8
|
+
* of `@opensip-cli/graph` (the engine) and upstream of the four
|
|
9
|
+
* tree-sitter adapters:
|
|
10
|
+
*
|
|
11
|
+
* core → … → graph (engine) → graph-adapter-common → graph-{go,java,python,rust}
|
|
12
|
+
*
|
|
13
|
+
* It exports `createX` factories that return values; the adapter composes
|
|
14
|
+
* them. It exports NO `adapter` / `metadata` — it is a library, not a
|
|
15
|
+
* discoverable graph adapter (its package.json deliberately omits
|
|
16
|
+
* `opensipTools.kind`). `graph-typescript` (TS-compiler-backed, not
|
|
17
|
+
* tree-sitter) shares none of this and must not depend on it.
|
|
18
|
+
*/
|
|
19
|
+
export { createDiscover } from './discover.js';
|
|
20
|
+
export { createParseProjectFromAdapter } from './parse-from-adapter.js';
|
|
21
|
+
export { hashConfig, makeConfigCacheKey } from './cache-key.js';
|
|
22
|
+
export { skipToEndOfLine, skipBlockComment } from './body-digest.js';
|
|
23
|
+
export { isReturnValueDiscarded } from './return-discarded.js';
|
|
24
|
+
export { record, makeFileClassifier, runWalk, synthesizeModuleInit, buildNameIndex, nameOf, childrenOf, namedChildrenOf, } from './walk.js';
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,cAAc,EAAiC,MAAM,eAAe,CAAC;AAI9E,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAExE,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EACL,MAAM,EACN,kBAAkB,EAGlB,OAAO,EAGP,oBAAoB,EAEpB,cAAc,EACd,MAAM,EACN,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `parseProject` driver that sources each file's parse from a
|
|
3
|
+
* `LanguageAdapter` (ADR-0010) instead of an inline grammar-bound parser.
|
|
4
|
+
* It is byte-for-byte equivalent to `createTreeSitterParseProject`'s loop —
|
|
5
|
+
* same read, same `ParseError` messages, same `hasError` "record but keep the
|
|
6
|
+
* partial tree" behavior, same completion log — but the per-file parse is
|
|
7
|
+
* `adapter.parse(source, path)`. This is what lets the graph Python adapter
|
|
8
|
+
* consume `@opensip-cli/lang-python` so there is one parser per language.
|
|
9
|
+
*
|
|
10
|
+
* Total over `input.files` per invariant I-7: every file either parses or
|
|
11
|
+
* surfaces in `parseErrors`. The adapter's `parse` is synchronous (its grammar
|
|
12
|
+
* loads at module top level), so `parseProject` stays synchronous.
|
|
13
|
+
*/
|
|
14
|
+
import type { TreeSitterParsedProject } from './parse.js';
|
|
15
|
+
import type { LanguageAdapter } from '@opensip-cli/core';
|
|
16
|
+
import type { ParseInput, ParseOutput } from '@opensip-cli/graph';
|
|
17
|
+
import type { ParsedFile } from '@opensip-cli/tree-sitter';
|
|
18
|
+
/**
|
|
19
|
+
* Build a graph `parseProject` from a tree-sitter-backed `LanguageAdapter`
|
|
20
|
+
* (one whose `parse` returns the `{ tree, source }` `ParsedFile` shape). The
|
|
21
|
+
* adapter's `id` is the `graph:parse:<id>` log-tag suffix.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createParseProjectFromAdapter(adapter: LanguageAdapter<ParsedFile>): (input: ParseInput) => ParseOutput<TreeSitterParsedProject>;
|
|
24
|
+
//# sourceMappingURL=parse-from-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-from-adapter.d.ts","sourceRoot":"","sources":["../src/parse-from-adapter.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EAAwB,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAc,MAAM,oBAAoB,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,GACnC,CAAC,KAAK,EAAE,UAAU,KAAK,WAAW,CAAC,uBAAuB,CAAC,CA2D7D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// @fitness-ignore-file unbounded-memory -- reads source files one at a time; per-file memory bounded by source size (tree-sitter constraint)
|
|
2
|
+
/**
|
|
3
|
+
* `parseProject` driver that sources each file's parse from a
|
|
4
|
+
* `LanguageAdapter` (ADR-0010) instead of an inline grammar-bound parser.
|
|
5
|
+
* It is byte-for-byte equivalent to `createTreeSitterParseProject`'s loop —
|
|
6
|
+
* same read, same `ParseError` messages, same `hasError` "record but keep the
|
|
7
|
+
* partial tree" behavior, same completion log — but the per-file parse is
|
|
8
|
+
* `adapter.parse(source, path)`. This is what lets the graph Python adapter
|
|
9
|
+
* consume `@opensip-cli/lang-python` so there is one parser per language.
|
|
10
|
+
*
|
|
11
|
+
* Total over `input.files` per invariant I-7: every file either parses or
|
|
12
|
+
* surfaces in `parseErrors`. The adapter's `parse` is synchronous (its grammar
|
|
13
|
+
* loads at module top level), so `parseProject` stays synchronous.
|
|
14
|
+
*/
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
import { relative } from 'node:path';
|
|
17
|
+
import { logger } from '@opensip-cli/core';
|
|
18
|
+
/**
|
|
19
|
+
* Build a graph `parseProject` from a tree-sitter-backed `LanguageAdapter`
|
|
20
|
+
* (one whose `parse` returns the `{ tree, source }` `ParsedFile` shape). The
|
|
21
|
+
* adapter's `id` is the `graph:parse:<id>` log-tag suffix.
|
|
22
|
+
*/
|
|
23
|
+
export function createParseProjectFromAdapter(adapter) {
|
|
24
|
+
const module = `graph:parse:${adapter.id}`;
|
|
25
|
+
return function parseProject(input) {
|
|
26
|
+
const files = new Map();
|
|
27
|
+
const parseErrors = [];
|
|
28
|
+
for (const path of input.files) {
|
|
29
|
+
let source;
|
|
30
|
+
/* v8 ignore start */
|
|
31
|
+
try {
|
|
32
|
+
source = readFileSync(path, 'utf8');
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
parseErrors.push({
|
|
36
|
+
filePath: relative(input.projectDirAbs, path),
|
|
37
|
+
message: `read failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
38
|
+
});
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
/* v8 ignore stop */
|
|
42
|
+
let parsed;
|
|
43
|
+
/* v8 ignore start */
|
|
44
|
+
try {
|
|
45
|
+
parsed = adapter.parse(source, path);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
parseErrors.push({
|
|
49
|
+
filePath: relative(input.projectDirAbs, path),
|
|
50
|
+
message: error instanceof Error ? error.message : String(error),
|
|
51
|
+
});
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
/* v8 ignore stop */
|
|
55
|
+
/* v8 ignore start */
|
|
56
|
+
if (parsed === null) {
|
|
57
|
+
parseErrors.push({
|
|
58
|
+
filePath: relative(input.projectDirAbs, path),
|
|
59
|
+
message: 'tree-sitter returned no tree',
|
|
60
|
+
});
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
/* v8 ignore stop */
|
|
64
|
+
if (parsed.tree.rootNode.hasError) {
|
|
65
|
+
parseErrors.push({
|
|
66
|
+
filePath: relative(input.projectDirAbs, path),
|
|
67
|
+
message: 'tree-sitter reported syntax errors; partial tree retained',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
files.set(path, parsed);
|
|
71
|
+
}
|
|
72
|
+
logger.info({
|
|
73
|
+
evt: 'graph.parse.complete',
|
|
74
|
+
module,
|
|
75
|
+
files: files.size,
|
|
76
|
+
parseErrors: parseErrors.length,
|
|
77
|
+
});
|
|
78
|
+
return { project: { files }, parseErrors };
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=parse-from-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-from-adapter.js","sourceRoot":"","sources":["../src/parse-from-adapter.ts"],"names":[],"mappings":"AAAA,6IAA6I;AAC7I;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAO3C;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAC3C,OAAoC;IAEpC,MAAM,MAAM,GAAG,eAAe,OAAO,CAAC,EAAE,EAAE,CAAC;IAE3C,OAAO,SAAS,YAAY,CAAC,KAAiB;QAC5C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgC,CAAC;QACtD,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,MAAc,CAAC;YACnB,qBAAqB;YACrB,IAAI,CAAC;gBACH,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC;oBAC7C,OAAO,EAAE,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;iBAClF,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,oBAAoB;YACpB,IAAI,MAAyB,CAAC;YAC9B,qBAAqB;YACrB,IAAI,CAAC;gBACH,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACvC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC;oBAC7C,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,oBAAoB;YACpB,qBAAqB;YACrB,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC;oBAC7C,OAAO,EAAE,8BAA8B;iBACxC,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,oBAAoB;YACpB,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBAClC,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC;oBAC7C,OAAO,EAAE,2DAA2D;iBACrE,CAAC,CAAC;YACL,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;YACV,GAAG,EAAE,sBAAsB;YAC3B,MAAM;YACN,KAAK,EAAE,KAAK,CAAC,IAAI;YACjB,WAAW,EAAE,WAAW,CAAC,MAAM;SAChC,CAAC,CAAC;QAEH,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,CAAC;IAC7C,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/parse.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsed-project type surface for the tree-sitter graph adapters.
|
|
3
|
+
*
|
|
4
|
+
* ADR-0010 (rollout complete): all four tree-sitter adapters (python, rust, go,
|
|
5
|
+
* java) now parse via their `@opensip-cli/lang-*` package through
|
|
6
|
+
* `createParseProjectFromAdapter` (see ./parse-from-adapter.ts). The former
|
|
7
|
+
* grammar-bound `createTreeSitterParseProject` driver — and its `Parser.init()`
|
|
8
|
+
* seam — have been removed; this module is reduced to the two nominal types the
|
|
9
|
+
* adapters and the walk/resolve scaffolding still share. The parsed-file shape
|
|
10
|
+
* is sourced from the canonical substrate so graph-adapter-common no longer
|
|
11
|
+
* depends on `web-tree-sitter`.
|
|
12
|
+
*/
|
|
13
|
+
import type { ParsedFile } from '@opensip-cli/tree-sitter';
|
|
14
|
+
/**
|
|
15
|
+
* The parsed-file shape every tree-sitter adapter uses: the parse tree plus the
|
|
16
|
+
* original source text (held so body slices can be extracted for hashing
|
|
17
|
+
* without re-parsing). Identical to the substrate's `ParsedFile`.
|
|
18
|
+
*/
|
|
19
|
+
export type TreeSitterParsedFile = ParsedFile;
|
|
20
|
+
/** A parsed tree-sitter project: map of absolute file path → parsed file. */
|
|
21
|
+
export interface TreeSitterParsedProject<F extends TreeSitterParsedFile = TreeSitterParsedFile> {
|
|
22
|
+
readonly files: ReadonlyMap<string, F>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAE9C,6EAA6E;AAC7E,MAAM,WAAW,uBAAuB,CAAC,CAAC,SAAS,oBAAoB,GAAG,oBAAoB;IAC5F,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CACxC"}
|
package/dist/parse.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsed-project type surface for the tree-sitter graph adapters.
|
|
3
|
+
*
|
|
4
|
+
* ADR-0010 (rollout complete): all four tree-sitter adapters (python, rust, go,
|
|
5
|
+
* java) now parse via their `@opensip-cli/lang-*` package through
|
|
6
|
+
* `createParseProjectFromAdapter` (see ./parse-from-adapter.ts). The former
|
|
7
|
+
* grammar-bound `createTreeSitterParseProject` driver — and its `Parser.init()`
|
|
8
|
+
* seam — have been removed; this module is reduced to the two nominal types the
|
|
9
|
+
* adapters and the walk/resolve scaffolding still share. The parsed-file shape
|
|
10
|
+
* is sourced from the canonical substrate so graph-adapter-common no longer
|
|
11
|
+
* depends on `web-tree-sitter`.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared "is the return value discarded?" predicate for the tree-sitter
|
|
3
|
+
* adapters.
|
|
4
|
+
*
|
|
5
|
+
* The base shape is byte-identical across the adapters whose call sites
|
|
6
|
+
* only ever discard via a bare `expression_statement` (Java, Rust): a
|
|
7
|
+
* call expression's return value is discarded when the call is the entire
|
|
8
|
+
* expression of an enclosing `expression_statement`. Parenthesized
|
|
9
|
+
* wrappers are transparent and walked through.
|
|
10
|
+
*
|
|
11
|
+
* Adapters with extra discard shapes (Go's `go`/`defer` statements,
|
|
12
|
+
* Python's `await` wrapper) keep their own variant — only the common
|
|
13
|
+
* Java/Rust form lives here.
|
|
14
|
+
*/
|
|
15
|
+
import type { Node } from '@opensip-cli/tree-sitter';
|
|
16
|
+
/**
|
|
17
|
+
* The call's return value is discarded when the call expression is the
|
|
18
|
+
* entire expression of an enclosing `expression_statement`.
|
|
19
|
+
* `parenthesized_expression` wrappers are transparent.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isReturnValueDiscarded(node: Node): boolean;
|
|
22
|
+
//# sourceMappingURL=return-discarded.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"return-discarded.d.ts","sourceRoot":"","sources":["../src/return-discarded.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAU1D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared "is the return value discarded?" predicate for the tree-sitter
|
|
3
|
+
* adapters.
|
|
4
|
+
*
|
|
5
|
+
* The base shape is byte-identical across the adapters whose call sites
|
|
6
|
+
* only ever discard via a bare `expression_statement` (Java, Rust): a
|
|
7
|
+
* call expression's return value is discarded when the call is the entire
|
|
8
|
+
* expression of an enclosing `expression_statement`. Parenthesized
|
|
9
|
+
* wrappers are transparent and walked through.
|
|
10
|
+
*
|
|
11
|
+
* Adapters with extra discard shapes (Go's `go`/`defer` statements,
|
|
12
|
+
* Python's `await` wrapper) keep their own variant — only the common
|
|
13
|
+
* Java/Rust form lives here.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* The call's return value is discarded when the call expression is the
|
|
17
|
+
* entire expression of an enclosing `expression_statement`.
|
|
18
|
+
* `parenthesized_expression` wrappers are transparent.
|
|
19
|
+
*/
|
|
20
|
+
export function isReturnValueDiscarded(node) {
|
|
21
|
+
let parent = node.parent;
|
|
22
|
+
while (parent) {
|
|
23
|
+
if (parent.type === 'parenthesized_expression') {
|
|
24
|
+
parent = parent.parent;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
return parent.type === 'expression_statement';
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=return-discarded.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"return-discarded.js","sourceRoot":"","sources":["../src/return-discarded.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAU;IAC/C,IAAI,MAAM,GAAgB,IAAI,CAAC,MAAM,CAAC;IACtC,OAAO,MAAM,EAAE,CAAC;QACd,IAAI,MAAM,CAAC,IAAI,KAAK,0BAA0B,EAAE,CAAC;YAC/C,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YACvB,SAAS;QACX,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,KAAK,sBAAsB,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/walk.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared walk scaffolding for the tree-sitter adapters.
|
|
3
|
+
*
|
|
4
|
+
* The actual node traversal (`visit` / `walkFile`) is language-specific
|
|
5
|
+
* and stays in each adapter. What is duplicated — and moves here — is:
|
|
6
|
+
*
|
|
7
|
+
* - `record(out, occ)` — the occurrence-sink append.
|
|
8
|
+
* - `makeFileClassifier(...)` — the regex-parameterized
|
|
9
|
+
* `isTestFile` / `isGeneratedFile`
|
|
10
|
+
* predicates.
|
|
11
|
+
* - `runWalk({ input, walkFile })`— the `walkProject` driver skeleton:
|
|
12
|
+
* allocate the output sinks, filter +
|
|
13
|
+
* sort `input.files`, per-file
|
|
14
|
+
* try/catch → `ParseError`.
|
|
15
|
+
* - `synthesizeModuleInit(...)` — the module-init `FunctionOccurrence`
|
|
16
|
+
* skeleton (top-level-text join →
|
|
17
|
+
* `digestSyntheticBody` → occurrence).
|
|
18
|
+
* The `qualifiedName` shape differs per
|
|
19
|
+
* language and is passed in.
|
|
20
|
+
*/
|
|
21
|
+
import { nameOf, childrenOf, namedChildrenOf } from '@opensip-cli/tree-sitter';
|
|
22
|
+
import type { TreeSitterParsedFile, TreeSitterParsedProject } from './parse.js';
|
|
23
|
+
import type { BodyDigest, CallSiteRecord, DependencySiteRecord, FunctionOccurrence, WalkInput, WalkOutput } from '@opensip-cli/graph';
|
|
24
|
+
/** Append an occurrence into the by-simple-name occurrence sink. */
|
|
25
|
+
export declare function record(out: Record<string, FunctionOccurrence[]>, occ: FunctionOccurrence): void;
|
|
26
|
+
/** Regex inputs for the shared file classifier. */
|
|
27
|
+
export interface FileClassifierConfig {
|
|
28
|
+
/** Matches a test file by name (e.g. `*_test.go`, `*Test.java`). */
|
|
29
|
+
readonly testRe: RegExp;
|
|
30
|
+
/** Matches a generated / build-output path. */
|
|
31
|
+
readonly generatedRe: RegExp;
|
|
32
|
+
/**
|
|
33
|
+
* Optional path-based test matcher (e.g. `src/test/`, `tests/`). When
|
|
34
|
+
* present, a file is a test file if EITHER `testPathRe` or `testRe`
|
|
35
|
+
* matches. Go omits this (the `_test.go` name convention is exact);
|
|
36
|
+
* java/python/rust supply it.
|
|
37
|
+
*/
|
|
38
|
+
readonly testPathRe?: RegExp;
|
|
39
|
+
}
|
|
40
|
+
/** The bound file-classification predicates. */
|
|
41
|
+
export interface FileClassifier {
|
|
42
|
+
readonly isTestFile: (rel: string) => boolean;
|
|
43
|
+
readonly isGeneratedFile: (rel: string) => boolean;
|
|
44
|
+
}
|
|
45
|
+
/** Builds `isTestFile` / `isGeneratedFile` bound to the given regexes. */
|
|
46
|
+
export declare function makeFileClassifier(config: FileClassifierConfig): FileClassifier;
|
|
47
|
+
/**
|
|
48
|
+
* The three output accumulators a per-file walk appends into. Grouping
|
|
49
|
+
* them keeps `walkFile` (and the adapter `visit` helpers that thread
|
|
50
|
+
* them) under the wide-function parameter budget, and names the cohesive
|
|
51
|
+
* "walk output" concept the driver allocates once per project.
|
|
52
|
+
*/
|
|
53
|
+
export interface WalkSinks {
|
|
54
|
+
/** By-simple-name occurrence sink (the engine's `out` map). */
|
|
55
|
+
readonly occurrences: Record<string, FunctionOccurrence[]>;
|
|
56
|
+
/** Flat list of call sites discovered across the file. */
|
|
57
|
+
readonly callSites: CallSiteRecord[];
|
|
58
|
+
/** Flat list of dependency (import) sites discovered across the file. */
|
|
59
|
+
readonly dependencySites: DependencySiteRecord[];
|
|
60
|
+
}
|
|
61
|
+
/** Inputs to the shared `walkProject` driver. */
|
|
62
|
+
export interface RunWalkParams<P extends TreeSitterParsedProject> {
|
|
63
|
+
readonly input: WalkInput<P>;
|
|
64
|
+
/**
|
|
65
|
+
* The adapter's per-file walk: visits one file's AST and pushes
|
|
66
|
+
* occurrences / call sites / dependency sites into the supplied sinks.
|
|
67
|
+
*/
|
|
68
|
+
readonly walkFile: (absPath: string, file: P['files'] extends ReadonlyMap<string, infer F> ? F : never, projectDirAbs: string, sinks: WalkSinks) => void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Drives `walkProject`: allocate the output sinks, iterate
|
|
72
|
+
* `input.files` (filtered to parsed files, sorted for I-1 determinism),
|
|
73
|
+
* and run `walkFile` per file with a try/catch that records a
|
|
74
|
+
* `ParseError` on failure.
|
|
75
|
+
*/
|
|
76
|
+
export declare function runWalk<P extends TreeSitterParsedProject>(params: RunWalkParams<P>): WalkOutput;
|
|
77
|
+
/** Inputs to the shared module-init occurrence builder. */
|
|
78
|
+
export interface SynthesizeModuleInitParams<F extends TreeSitterParsedFile> {
|
|
79
|
+
readonly file: F;
|
|
80
|
+
readonly filePathProjectRel: string;
|
|
81
|
+
readonly inTestFile: boolean;
|
|
82
|
+
readonly definedInGenerated: boolean;
|
|
83
|
+
/** The adapter's synthetic-body digest (same normalization as real bodies). */
|
|
84
|
+
readonly digestSyntheticBody: (text: string) => BodyDigest;
|
|
85
|
+
/**
|
|
86
|
+
* The fully-built `qualifiedName` for the synthetic `<module-init>`
|
|
87
|
+
* occurrence — language-specific (extension strip + separator differ:
|
|
88
|
+
* `pkg/file.<module-init>` for go, `a.b.<module-init>` for python,
|
|
89
|
+
* `a::b::<module-init>` for rust, …). Computed by the adapter.
|
|
90
|
+
*/
|
|
91
|
+
readonly qualifiedName: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Build the synthetic `<module-init>` `FunctionOccurrence`: hash the
|
|
95
|
+
* file's top-level statement-text concatenation and assemble the
|
|
96
|
+
* occurrence with the adapter-supplied `qualifiedName`.
|
|
97
|
+
*/
|
|
98
|
+
export declare function synthesizeModuleInit<F extends TreeSitterParsedFile>(params: SynthesizeModuleInitParams<F>): FunctionOccurrence;
|
|
99
|
+
export { nameOf, childrenOf, namedChildrenOf };
|
|
100
|
+
/**
|
|
101
|
+
* Build a simple-name → bodyHash[] index from the walk's occurrence map.
|
|
102
|
+
* Skips synthetic names (those starting with `<`); only real names are
|
|
103
|
+
* resolution targets. Language-agnostic (operates on the engine's
|
|
104
|
+
* `FunctionOccurrence` record), so it is shared by every resolver that
|
|
105
|
+
* needs it (go / java / python; rust resolves differently).
|
|
106
|
+
*/
|
|
107
|
+
export declare function buildNameIndex(functions: Readonly<Record<string, readonly FunctionOccurrence[]>>): ReadonlyMap<string, readonly string[]>;
|
|
108
|
+
//# sourceMappingURL=walk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../src/walk.ts"],"names":[],"mappings":"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"}
|
package/dist/walk.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared walk scaffolding for the tree-sitter adapters.
|
|
3
|
+
*
|
|
4
|
+
* The actual node traversal (`visit` / `walkFile`) is language-specific
|
|
5
|
+
* and stays in each adapter. What is duplicated — and moves here — is:
|
|
6
|
+
*
|
|
7
|
+
* - `record(out, occ)` — the occurrence-sink append.
|
|
8
|
+
* - `makeFileClassifier(...)` — the regex-parameterized
|
|
9
|
+
* `isTestFile` / `isGeneratedFile`
|
|
10
|
+
* predicates.
|
|
11
|
+
* - `runWalk({ input, walkFile })`— the `walkProject` driver skeleton:
|
|
12
|
+
* allocate the output sinks, filter +
|
|
13
|
+
* sort `input.files`, per-file
|
|
14
|
+
* try/catch → `ParseError`.
|
|
15
|
+
* - `synthesizeModuleInit(...)` — the module-init `FunctionOccurrence`
|
|
16
|
+
* skeleton (top-level-text join →
|
|
17
|
+
* `digestSyntheticBody` → occurrence).
|
|
18
|
+
* The `qualifiedName` shape differs per
|
|
19
|
+
* language and is passed in.
|
|
20
|
+
*/
|
|
21
|
+
import { relative } from 'node:path';
|
|
22
|
+
import { withSpan } from '@opensip-cli/core';
|
|
23
|
+
import { nameOf, childrenOf, namedChildrenOf } from '@opensip-cli/tree-sitter';
|
|
24
|
+
// ── output helpers ────────────────────────────────────────────────
|
|
25
|
+
/** Append an occurrence into the by-simple-name occurrence sink. */
|
|
26
|
+
export function record(out, occ) {
|
|
27
|
+
const list = out[occ.simpleName];
|
|
28
|
+
if (list)
|
|
29
|
+
list.push(occ);
|
|
30
|
+
else
|
|
31
|
+
out[occ.simpleName] = [occ];
|
|
32
|
+
}
|
|
33
|
+
/** Builds `isTestFile` / `isGeneratedFile` bound to the given regexes. */
|
|
34
|
+
export function makeFileClassifier(config) {
|
|
35
|
+
const { testRe, generatedRe, testPathRe } = config;
|
|
36
|
+
return {
|
|
37
|
+
isTestFile: testPathRe === undefined
|
|
38
|
+
? (rel) => testRe.test(rel)
|
|
39
|
+
: (rel) => testPathRe.test(rel) || testRe.test(rel),
|
|
40
|
+
isGeneratedFile: (rel) => generatedRe.test(rel),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Drives `walkProject`: allocate the output sinks, iterate
|
|
45
|
+
* `input.files` (filtered to parsed files, sorted for I-1 determinism),
|
|
46
|
+
* and run `walkFile` per file with a try/catch that records a
|
|
47
|
+
* `ParseError` on failure.
|
|
48
|
+
*/
|
|
49
|
+
export function runWalk(params) {
|
|
50
|
+
const { input, walkFile } = params;
|
|
51
|
+
const occurrences = Object.create(null);
|
|
52
|
+
const callSites = [];
|
|
53
|
+
const dependencySites = [];
|
|
54
|
+
const parseErrors = [];
|
|
55
|
+
const sinks = { occurrences, callSites, dependencySites };
|
|
56
|
+
const sortedPaths = [...input.files].filter((p) => input.project.files.has(p)).sort();
|
|
57
|
+
return withSpan('opensip-cli-graph', 'graph.walk', () => {
|
|
58
|
+
for (const path of sortedPaths) {
|
|
59
|
+
const file = input.project.files.get(path);
|
|
60
|
+
if (!file)
|
|
61
|
+
continue;
|
|
62
|
+
try {
|
|
63
|
+
walkFile(path, file, input.projectDirAbs, sinks);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
parseErrors.push({
|
|
67
|
+
filePath: relative(input.projectDirAbs, path),
|
|
68
|
+
message: error instanceof Error ? error.message : String(error),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { occurrences, callSites, dependencySites, parseErrors };
|
|
73
|
+
}, {
|
|
74
|
+
'graph.walk.file_count': sortedPaths.length,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Build the synthetic `<module-init>` `FunctionOccurrence`: hash the
|
|
79
|
+
* file's top-level statement-text concatenation and assemble the
|
|
80
|
+
* occurrence with the adapter-supplied `qualifiedName`.
|
|
81
|
+
*/
|
|
82
|
+
export function synthesizeModuleInit(params) {
|
|
83
|
+
const { file, filePathProjectRel, inTestFile, definedInGenerated, digestSyntheticBody, qualifiedName, } = params;
|
|
84
|
+
const root = file.tree.rootNode;
|
|
85
|
+
const topLevelText = childrenOf(root)
|
|
86
|
+
.map((c) => file.source.slice(c.startIndex, c.endIndex))
|
|
87
|
+
.join('\n');
|
|
88
|
+
const digest = digestSyntheticBody(`${filePathProjectRel}\n${topLevelText}`);
|
|
89
|
+
return {
|
|
90
|
+
bodyHash: digest.hash,
|
|
91
|
+
bodySize: digest.size,
|
|
92
|
+
simpleName: `<module-init:${filePathProjectRel}>`,
|
|
93
|
+
qualifiedName,
|
|
94
|
+
filePath: filePathProjectRel,
|
|
95
|
+
line: 1,
|
|
96
|
+
column: 0,
|
|
97
|
+
endLine: root.endPosition.row + 1,
|
|
98
|
+
kind: 'module-init',
|
|
99
|
+
params: [],
|
|
100
|
+
returnType: null,
|
|
101
|
+
enclosingClass: null,
|
|
102
|
+
decorators: [],
|
|
103
|
+
visibility: 'module-local',
|
|
104
|
+
inTestFile,
|
|
105
|
+
definedInGenerated,
|
|
106
|
+
calls: [],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// ── node helpers ──────────────────────────────────────────────────
|
|
110
|
+
// `nameOf` / `childrenOf` / `namedChildrenOf` now live in the canonical
|
|
111
|
+
// grammar-agnostic substrate `@opensip-cli/tree-sitter` (ADR-0010). They
|
|
112
|
+
// are re-exported here so the graph adapters' existing imports from
|
|
113
|
+
// `@opensip-cli/graph-adapter-common` are unchanged. (Imported, not just
|
|
114
|
+
// re-exported, because `synthesizeModuleInit` above uses `childrenOf`
|
|
115
|
+
// internally — a plain `export…from` would not bind it in scope.)
|
|
116
|
+
// eslint-disable-next-line unicorn/prefer-export-from -- childrenOf is also used internally; the import binding is required
|
|
117
|
+
export { nameOf, childrenOf, namedChildrenOf };
|
|
118
|
+
// ── resolver helper ───────────────────────────────────────────────
|
|
119
|
+
/**
|
|
120
|
+
* Build a simple-name → bodyHash[] index from the walk's occurrence map.
|
|
121
|
+
* Skips synthetic names (those starting with `<`); only real names are
|
|
122
|
+
* resolution targets. Language-agnostic (operates on the engine's
|
|
123
|
+
* `FunctionOccurrence` record), so it is shared by every resolver that
|
|
124
|
+
* needs it (go / java / python; rust resolves differently).
|
|
125
|
+
*/
|
|
126
|
+
export function buildNameIndex(functions) {
|
|
127
|
+
const out = new Map();
|
|
128
|
+
for (const [name, occs] of Object.entries(functions)) {
|
|
129
|
+
if (!occs)
|
|
130
|
+
continue;
|
|
131
|
+
if (name.startsWith('<'))
|
|
132
|
+
continue;
|
|
133
|
+
const list = out.get(name) ?? [];
|
|
134
|
+
for (const o of occs)
|
|
135
|
+
list.push(o.bodyHash);
|
|
136
|
+
if (list.length > 0)
|
|
137
|
+
out.set(name, list);
|
|
138
|
+
}
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=walk.js.map
|
package/dist/walk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../src/walk.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opensip-cli/graph-adapter-common",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"description": "Shared scaffolding for the tree-sitter graph language adapters (go, java, python, rust)",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"opensip-cli",
|
|
8
|
+
"static-analysis",
|
|
9
|
+
"code-quality",
|
|
10
|
+
"call-graph",
|
|
11
|
+
"tree-sitter"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/opensip-ai/opensip-cli.git",
|
|
16
|
+
"directory": "packages/graph/graph-adapter-common"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/opensip-ai/opensip-cli",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/opensip-ai/opensip-cli/issues"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"NOTICE"
|
|
32
|
+
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"glob": "^13.0.0",
|
|
35
|
+
"@opensip-cli/core": "0.1.0",
|
|
36
|
+
"@opensip-cli/graph": "0.1.0",
|
|
37
|
+
"@opensip-cli/tree-sitter": "0.1.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^24.13.2",
|
|
41
|
+
"vitest": "^4.1.8"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc",
|
|
45
|
+
"test": "vitest run --passWithNoTests",
|
|
46
|
+
"typecheck": "tsc --noEmit",
|
|
47
|
+
"clean": "rm -rf dist"
|
|
48
|
+
}
|
|
49
|
+
}
|