@c4a/extract 0.5.29-beta.18

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/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # @c4a/extract
2
+
3
+ Code extraction framework: plugin protocol, registry, digest generation, and shared parsing infrastructure.
4
+
5
+ ## Role in the monorepo
6
+
7
+ Defines the standard extraction protocol (`ExtractionPlugin` interface) and provides:
8
+ - Plugin registry for language-specific extraction plugins
9
+ - ExtractionResult v2 schema (SymbolInfo + RelationInfo)
10
+ - Digest generation (exported/internal symbol partitioning) and symbol diff
11
+ - Shared Tree-sitter parsing and file scanning utilities
12
+
13
+ **Depends on:** `core`
14
+ **Depended on by:** `extract-ts`, `daemon`, `api`, `e2e`
15
+
16
+ ## Key exports
17
+
18
+ ### Plugin protocol
19
+
20
+ - `ExtractionPlugin` — interface that language plugins implement
21
+ - `ExtractionPluginRegistry` — register/resolve plugins by source manifest
22
+ - `FileSystem` — abstraction for file access (plugins don't touch disk directly)
23
+ - `SourceInfo` / `ManifestInfo` — source metadata passed to `canHandle`/`detectEntries`
24
+ - `EntryDetectionResult` — package info + entry files (supports monorepo recursion via `subPackages`)
25
+ - `PatternDetectionResult` — framework pattern detection (endpoints, implicit deps)
26
+
27
+ ### Types (ExtractionResult v2)
28
+
29
+ - `ExtractionResult` — standard output format: `{ version: "2", meta, package, files, symbols, relations, stats }`
30
+ - `SymbolInfo` — extracted symbol: name, kind, visibility, file, line, members, params, returnType, etc.
31
+ - `RelationInfo` — extracted relation: type, from, to, grounding, confidence, source
32
+
33
+ ### Digest & diff
34
+
35
+ - `generateDigest(result)` — ExtractionResult -> DigestData (exported/internal symbol partitioning)
36
+ - `generateSymbolDiff(current, previous)` — compare two digests, output `{ added, removed }`
37
+ - `DigestData` / `SymbolDiff` types
38
+
39
+ ### Shared utilities
40
+
41
+ - `initParser()` / `parseFile()` — Tree-sitter parser initialization and per-file AST parsing
42
+ - `scanSourceFiles()` / `detectModules()` / `detectModuleAt()` — file system scanning and module detection
43
+ - `getGitCommitHash()` — reads the current git commit hash
44
+ - `detectTechStack()` — identifies languages and frameworks in a repository
45
+
46
+ ## Writing a language plugin
47
+
48
+ To add support for a new language (e.g., Python), create a new package `@c4a/extract-python` that implements `ExtractionPlugin`:
49
+
50
+ ```typescript
51
+ import type {
52
+ ExtractionPlugin,
53
+ ExtractionResult,
54
+ EntryDetectionResult,
55
+ FileSystem,
56
+ ManifestInfo,
57
+ SourceInfo,
58
+ EntryFile,
59
+ } from "@c4a/extract";
60
+
61
+ export class PythonPlugin implements ExtractionPlugin {
62
+ readonly id = "c4a-extract-python";
63
+ readonly languages = ["python"];
64
+ readonly packageManagers = ["pip"];
65
+
66
+ canHandle(source: SourceInfo): boolean {
67
+ // Return true if this source has a pyproject.toml or setup.py
68
+ return source.manifests.some(
69
+ (m) => m.type === "pyproject.toml",
70
+ );
71
+ }
72
+
73
+ async detectEntries(
74
+ manifest: ManifestInfo,
75
+ fs: FileSystem,
76
+ ): Promise<EntryDetectionResult> {
77
+ // Parse pyproject.toml to find package name, kind, entry points
78
+ // Return: { package: { name, kind, language }, entries: [...] }
79
+ }
80
+
81
+ async extractSymbols(
82
+ entries: EntryFile[],
83
+ fs: FileSystem,
84
+ ): Promise<ExtractionResult> {
85
+ // Use Tree-sitter with Python grammar to parse AST
86
+ // Extract SymbolInfo[] (functions, classes, etc.)
87
+ // Extract RelationInfo[] (imports, inheritance, etc.)
88
+ // Return ExtractionResult v2
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### Plugin interface
94
+
95
+ | Method | When called | Returns |
96
+ |--------|------------|---------|
97
+ | `canHandle(source)` | Registry resolves which plugin handles a source | `boolean` |
98
+ | `detectEntries(manifest, fs)` | Layer 0: identify package info + entry files | `EntryDetectionResult` |
99
+ | `extractSymbols(entries, fs)` | Layer 1: AST parsing + symbol extraction | `ExtractionResult` |
100
+ | `detectPatterns?(fs)` | Layer 2 (optional): framework-specific patterns | `PatternDetectionResult` |
101
+
102
+ ### Registration
103
+
104
+ Plugins are currently registered statically in the daemon:
105
+
106
+ ```typescript
107
+ import { ExtractionPluginRegistry } from "@c4a/extract";
108
+ import { TypeScriptPlugin } from "@c4a/extract-ts";
109
+
110
+ const registry = new ExtractionPluginRegistry();
111
+ registry.register(new TypeScriptPlugin());
112
+
113
+ const plugin = registry.resolve(sourceInfo);
114
+ if (plugin) {
115
+ const entries = await plugin.detectEntries(manifest, fs);
116
+ const result = await plugin.extractSymbols(entries.entries, fs);
117
+ }
118
+ ```
119
+
120
+ ### FileSystem abstraction
121
+
122
+ Plugins access files through the `FileSystem` interface, not directly via `node:fs`. This enables future API-based file loading without changing plugin code.
123
+
124
+ ```typescript
125
+ interface FileSystem {
126
+ readFile(path: string): Promise<string>;
127
+ readdir(path: string): Promise<string[]>;
128
+ exists(path: string): Promise<boolean>;
129
+ readJson<T = unknown>(path: string): Promise<T>;
130
+ }
131
+ ```
132
+
133
+ ### ExtractionResult v2 format
134
+
135
+ ```typescript
136
+ {
137
+ version: "2",
138
+ meta: { extractedAt, pluginId, commitHash, language },
139
+ package: { name, kind, language },
140
+ files: [{ path, language, lines }],
141
+ symbols: SymbolInfo[], // exported + internal
142
+ relations: RelationInfo[], // imports, calls, type refs, etc.
143
+ stats: { files, lines, exportedSymbols, internalSymbols, relations },
144
+ }
145
+ ```
146
+
147
+ ## Development
148
+
149
+ ```bash
150
+ bun run --filter @c4a/extract build
151
+ bun run --filter @c4a/extract typecheck
152
+ bun run --filter @c4a/extract test
153
+ bun run --filter @c4a/extract lint
154
+ ```