@vibgrate/cli 2026.618.2 → 2026.623.2
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/DOCS.md +55 -4
- package/README.md +2 -0
- package/dist/baseline-2B6YIW6Z.js +1 -0
- package/dist/chunk-BHWXSLTQ.js +2 -0
- package/dist/chunk-EK7ODJWE.js +1 -0
- package/dist/chunk-I65B3ZRL.js +78 -0
- package/dist/chunk-MKDRULJ6.js +1 -0
- package/dist/chunk-XTHPCEME.js +2 -0
- package/dist/chunk-YF3NML7I.js +323 -0
- package/dist/cli.js +165 -5018
- package/dist/dist-AP3RH35M.js +1 -0
- package/dist/fs-PXXYZATK-ZP2RBR47.js +1 -0
- package/dist/hcs-wasm/package.json +3 -0
- package/dist/hcs-wasm/vibgrate_hcs_wasm.js +450 -0
- package/dist/hcs-wasm/vibgrate_hcs_wasm_bg.wasm +0 -0
- package/dist/hcs-worker.js +567 -283
- package/dist/index.js +1 -19
- package/dist/semver-TPPMM2NV.js +1 -0
- package/package.json +7 -7
- package/HCS-EXTRACT.md +0 -442
- package/dist/baseline-6CJI5Z45.js +0 -12
- package/dist/chunk-34KD4UJ3.js +0 -103
- package/dist/chunk-5IXVOEZN.js +0 -1999
- package/dist/chunk-C7LU6YIL.js +0 -813
- package/dist/chunk-JSBRDJBE.js +0 -30
- package/dist/chunk-XKZBEQYY.js +0 -18964
- package/dist/fs-PXXYZATK-EW5LCUA7.js +0 -37
- package/dist/semver-2FJFIYVN.js +0 -5
package/dist/index.js
CHANGED
|
@@ -1,19 +1 @@
|
|
|
1
|
-
|
|
2
|
-
computeDriftScore,
|
|
3
|
-
formatMarkdown,
|
|
4
|
-
formatSarif,
|
|
5
|
-
formatText,
|
|
6
|
-
generateFindings,
|
|
7
|
-
runScan
|
|
8
|
-
} from "./chunk-XKZBEQYY.js";
|
|
9
|
-
import "./chunk-5IXVOEZN.js";
|
|
10
|
-
import "./chunk-C7LU6YIL.js";
|
|
11
|
-
import "./chunk-JSBRDJBE.js";
|
|
12
|
-
export {
|
|
13
|
-
computeDriftScore,
|
|
14
|
-
formatMarkdown,
|
|
15
|
-
formatSarif,
|
|
16
|
-
formatText,
|
|
17
|
-
generateFindings,
|
|
18
|
-
runScan
|
|
19
|
-
};
|
|
1
|
+
export{Z as runScan}from'./chunk-YF3NML7I.js';export{i as computeDriftScore,v as formatMarkdown,u as formatSarif,t as formatText,j as generateFindings}from'./chunk-I65B3ZRL.js';import'./chunk-MKDRULJ6.js';import'./chunk-XTHPCEME.js';import'./chunk-EK7ODJWE.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {a}from'./chunk-MKDRULJ6.js';import'./chunk-EK7ODJWE.js';var semverTPPMM2NV = a();export{semverTPPMM2NV as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibgrate/cli",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.623.2",
|
|
4
4
|
"description": "CLI for measuring upgrade drift across Node, .NET, Python & Java projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"dist",
|
|
19
19
|
"DOCS.md",
|
|
20
|
-
"HCS-
|
|
21
|
-
"
|
|
20
|
+
"HCS-RUNTIME-SETUP.md",
|
|
21
|
+
"LICENSE.md"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "pnpm run build:hcs && tsup && pnpm run bundle:hcs && pnpm test:solutions",
|
|
25
25
|
"build:only": "pnpm run build:hcs && tsup && pnpm run bundle:hcs",
|
|
26
26
|
"build:hcs": "pnpm --filter @vibgrate/hcs-node-worker build",
|
|
27
|
-
"bundle:hcs": "cp ../vibgrate-hcs/node/dist/main.js dist/hcs-worker.js",
|
|
27
|
+
"bundle:hcs": "cp ../vibgrate-hcs/node/dist/main.js dist/hcs-worker.js && node scripts/bundle-hcs-wasm.mjs",
|
|
28
28
|
"dev": "tsx src/cli.ts",
|
|
29
29
|
"lint": "eslint src",
|
|
30
30
|
"typecheck": "tsc --noEmit",
|
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
"license": "SEE LICENSE IN LICENSE",
|
|
48
48
|
"homepage": "https://vibgrate.com",
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@types/node": "^
|
|
50
|
+
"@types/node": "^26.0.0",
|
|
51
51
|
"@types/semver": "^7.5.0",
|
|
52
52
|
"eslint": "^10.5.0",
|
|
53
|
-
"fast-xml-parser": "^5.9.
|
|
54
|
-
"semver": "^7.8.
|
|
53
|
+
"fast-xml-parser": "^5.9.3",
|
|
54
|
+
"semver": "^7.8.5",
|
|
55
55
|
"tsup": "^8.0.0",
|
|
56
56
|
"tsx": "^4.22.4",
|
|
57
57
|
"vitest": "^2.0.0"
|
package/HCS-EXTRACT.md
DELETED
|
@@ -1,442 +0,0 @@
|
|
|
1
|
-
# HCS Extract — Architecture & Interface Guide
|
|
2
|
-
|
|
3
|
-
How `vibgrate extract` discovers source code, spawns HCS workers, validates
|
|
4
|
-
facts, and renders progress.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Command synopsis
|
|
9
|
-
|
|
10
|
-
```
|
|
11
|
-
vibgrate extract [path] [options]
|
|
12
|
-
|
|
13
|
-
Options:
|
|
14
|
-
-o, --out <file> Write NDJSON to file (default: stdout)
|
|
15
|
-
--language <langs> Comma-separated languages (default: auto-detect)
|
|
16
|
-
--include-tests Include test files in analysis
|
|
17
|
-
--push Stream validated facts to dashboard API
|
|
18
|
-
--dsn <dsn> DSN token for push (or VIBGRATE_DSN env)
|
|
19
|
-
--concurrency <n> Parallel file workers (default: CPU count)
|
|
20
|
-
--timeout-mins <mins> Total timeout in minutes (default: 60)
|
|
21
|
-
--feedback <file> Load NDJSON diff artifact for refinement
|
|
22
|
-
--verbose Print worker stderr and summary statistics
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## High-level architecture
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
31
|
-
│ vibgrate CLI (ESM) │
|
|
32
|
-
│ packages/vibgrate-cli │
|
|
33
|
-
├─────────────────────────────────────────────────────────────┤
|
|
34
|
-
│ cli.ts │
|
|
35
|
-
│ └── extractCommand (src/commands/extract.ts) │
|
|
36
|
-
│ └── diffCommand (src/commands/diff.ts) │
|
|
37
|
-
│ │
|
|
38
|
-
│ Extract orchestration: │
|
|
39
|
-
│ 1. Validate args & options │
|
|
40
|
-
│ 2. Detect languages (walk filesystem for extensions) │
|
|
41
|
-
│ 3. Spawn HCS worker process per language │
|
|
42
|
-
│ 4. Parse stdout (NDJSON facts) + stderr (progress/logs) │
|
|
43
|
-
│ 5. Validate FactEnvelope schema for every line │
|
|
44
|
-
│ 6. Write to stdout or --out file │
|
|
45
|
-
│ 7. Optionally --push to dashboard API │
|
|
46
|
-
└───────────────┬─────────────────────────────────────────────┘
|
|
47
|
-
│ spawns: node --enable-source-maps <worker> --project <dir>
|
|
48
|
-
▼
|
|
49
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
50
|
-
│ HCS Node Worker (ESM, tsup bundle) │
|
|
51
|
-
│ packages/vibgrate-hcs/node │
|
|
52
|
-
├─────────────────────────────────────────────────────────────┤
|
|
53
|
-
│ dist/main.js (~4.8 MB, bundles antlr4ts + vb6-antlr4) │
|
|
54
|
-
│ │
|
|
55
|
-
│ AST extractors (ts-morph): │
|
|
56
|
-
│ typescript, javascript │
|
|
57
|
-
│ │
|
|
58
|
-
│ Text/regex extractors: │
|
|
59
|
-
│ swift, rust, ruby, php, dart, scala, vb6, cobol │
|
|
60
|
-
│ │
|
|
61
|
-
│ STDOUT ─▶ NDJSON FactEnvelope lines │
|
|
62
|
-
│ STDERR ─▶ [info], [warn], [error], [progress] lines │
|
|
63
|
-
└─────────────────────────────────────────────────────────────┘
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Package dependency chain
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
@vibgrate/cli
|
|
72
|
-
└── @vibgrate/hcs-node-worker (workspace:*)
|
|
73
|
-
├── ts-morph (external — resolved from node_modules at runtime)
|
|
74
|
-
├── commander (external)
|
|
75
|
-
├── antlr4ts (bundled into dist/main.js by tsup)
|
|
76
|
-
└── vb6-antlr4 (bundled into dist/main.js by tsup)
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Build order
|
|
80
|
-
|
|
81
|
-
The CLI's `build` and `build:only` scripts automatically build the HCS worker
|
|
82
|
-
first via `pnpm run build:hcs`:
|
|
83
|
-
|
|
84
|
-
```json
|
|
85
|
-
{
|
|
86
|
-
"build": "pnpm run build:hcs && tsup ... && pnpm test:solutions",
|
|
87
|
-
"build:only": "pnpm run build:hcs && tsup ...",
|
|
88
|
-
"build:hcs": "pnpm --filter @vibgrate/hcs-node-worker build"
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
The root-level `pnpm -r build` also resolves the correct order because pnpm
|
|
93
|
-
sees the `workspace:*` dependency and topologically sorts accordingly.
|
|
94
|
-
|
|
95
|
-
### Publishing
|
|
96
|
-
|
|
97
|
-
| Package | `files` field | Notes |
|
|
98
|
-
|---------|---------------|-------|
|
|
99
|
-
| `@vibgrate/cli` | `["dist", "DOCS.md"]` | Built CLI + library |
|
|
100
|
-
| `@vibgrate/hcs-node-worker` | `["dist"]` | Single-file worker bundle |
|
|
101
|
-
|
|
102
|
-
When `@vibgrate/cli` is installed via npm, `@vibgrate/hcs-node-worker` is
|
|
103
|
-
pulled in as a normal dependency. Its `dist/main.js` self-contains the ANTLR
|
|
104
|
-
parsers; only `ts-morph` and `commander` are resolved transitively from
|
|
105
|
-
node_modules.
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Worker resolution
|
|
110
|
-
|
|
111
|
-
`extract.ts` → `resolveHcsWorkerBin()` locates the worker binary at runtime:
|
|
112
|
-
|
|
113
|
-
| Priority | Method | When |
|
|
114
|
-
|----------|--------|------|
|
|
115
|
-
| 1 | `import.meta.resolve('@vibgrate/hcs-node-worker')` | Installed package or pnpm workspace link |
|
|
116
|
-
| 2 | Monorepo sibling path: `../../vibgrate-hcs/node/dist/main.js` | Dev fallback |
|
|
117
|
-
| 3 | Source path: `../../vibgrate-hcs/node/src/main.ts` | `tsx` dev mode |
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## Language detection
|
|
122
|
-
|
|
123
|
-
When `--language` is omitted, `extract.ts` walks the target directory and
|
|
124
|
-
counts files by extension:
|
|
125
|
-
|
|
126
|
-
| Language | Extensions |
|
|
127
|
-
|----------|-----------|
|
|
128
|
-
| typescript | `.ts`, `.tsx`, `.mts`, `.cts` |
|
|
129
|
-
| javascript | `.js`, `.jsx`, `.mjs`, `.cjs` |
|
|
130
|
-
| swift | `.swift` |
|
|
131
|
-
| rust | `.rs` |
|
|
132
|
-
| ruby | `.rb`, `.rake`, `.gemspec` |
|
|
133
|
-
| php | `.php` |
|
|
134
|
-
| dart | `.dart` |
|
|
135
|
-
| scala | `.scala`, `.sc` |
|
|
136
|
-
| cobol | `.cbl`, `.cob`, `.cpy`, `.cob85`, `.cobol` |
|
|
137
|
-
| vb6 | `.vbp`, `.bas`, `.cls`, `.frm`, `.ctl`, `.dsr` |
|
|
138
|
-
| go | `.go` |
|
|
139
|
-
| python | `.py` |
|
|
140
|
-
| java | `.java` |
|
|
141
|
-
| csharp | `.cs` |
|
|
142
|
-
| cplusplus | `.vcxproj`, `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hh`, `.hxx`, `.h`, `.ixx` |
|
|
143
|
-
| vbnet | `.vb` |
|
|
144
|
-
|
|
145
|
-
Directories in `SKIP_DIRS` (`node_modules`, `.git`, `dist`, `build`, `target`,
|
|
146
|
-
`vendor`, etc.) are skipped. Test files are excluded unless `--include-tests`
|
|
147
|
-
is set.
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Worker dispatch
|
|
152
|
-
|
|
153
|
-
Each detected language spawns a separate worker process:
|
|
154
|
-
|
|
155
|
-
```
|
|
156
|
-
node --enable-source-maps <worker> --project <dir> # TS/JS
|
|
157
|
-
node --enable-source-maps <worker> --project <dir> --swift-project <dir> # text langs
|
|
158
|
-
node --enable-source-maps <worker> --project <dir> --cobol-project <dir> \
|
|
159
|
-
--cobol-copybook-paths <paths> # COBOL
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
The `--concurrency` flag controls how many workers run in parallel (default:
|
|
163
|
-
CPU count), managed by a `Semaphore` utility.
|
|
164
|
-
|
|
165
|
-
For native workers (Go/Python/Java/.NET), if no bundled worker is available, the CLI falls back to local toolchains and emits installation hints when commands are missing. See [HCS-RUNTIME-SETUP.md](./HCS-RUNTIME-SETUP.md).
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Fact Envelope schema (ABI v0.2)
|
|
170
|
-
|
|
171
|
-
Every NDJSON line emitted on stdout must conform to:
|
|
172
|
-
|
|
173
|
-
```typescript
|
|
174
|
-
interface FactEnvelope {
|
|
175
|
-
factId: string; // "hcs:<FactType>:<sha256-16>"
|
|
176
|
-
factType: string; // e.g. "SymbolDeclared", "CallObserved"
|
|
177
|
-
language: string; // e.g. "typescript", "cobol"
|
|
178
|
-
scanner: string; // "ts-morph"
|
|
179
|
-
scannerVersion: string; // "0.2.0"
|
|
180
|
-
emittedAt: string; // ISO 8601 timestamp
|
|
181
|
-
payload: unknown; // Fact-type-specific payload object
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
The CLI validates every line against this schema. Invalid lines cause exit
|
|
186
|
-
code `1` (schema failure).
|
|
187
|
-
|
|
188
|
-
### Fact types emitted per language
|
|
189
|
-
|
|
190
|
-
| Language | Fact types |
|
|
191
|
-
|----------|-----------|
|
|
192
|
-
| typescript | CallObserved, DataAccessOperation, EndpointMetadata, FileIndexed, ImportObserved, RouteDeclared, SqlStatementObserved, SqlUsage, SymbolDeclared |
|
|
193
|
-
| javascript | ApiClientCall, CallObserved, DataAccessOperation, EndpointMetadata, ExternalServiceCall, FileIndexed, ImportObserved, RouteDeclared, SqlStatementObserved, SqlUsage, SymbolDeclared |
|
|
194
|
-
| swift | ApiClientCall, ConfigAccess, PageRouteDeclared |
|
|
195
|
-
| cplusplus | FileIndexed, ImportObserved, RouteDeclared, SqlUsage, SymbolDeclared, TestCaseDeclared |
|
|
196
|
-
| rust | AnnotationFound, ExternalServiceCall, FileIndexed, ImportObserved, RouteDeclared, SymbolDeclared, TestCaseDeclared |
|
|
197
|
-
| ruby | ConfigAccess, ExternalServiceCall, FileIndexed, ImportObserved, RouteDeclared, SqlUsage, SymbolDeclared |
|
|
198
|
-
| php | ConfigAccess, ExternalServiceCall, FileIndexed, ImportObserved, SqlUsage, SymbolDeclared |
|
|
199
|
-
| dart | ExternalServiceCall, FileIndexed, ImportObserved, RouteDeclared, SymbolDeclared |
|
|
200
|
-
| scala | ConfigAccess, FileIndexed, ImportObserved, SymbolDeclared |
|
|
201
|
-
| vb6 | AnnotationFound, CallObserved, ConfigAccess, FieldDeclared, SqlUsage, SymbolDeclared |
|
|
202
|
-
| cobol | CallObserved, CobolConfidenceReport, CobolProgramDeclared, ExecBlockObserved, FileResourceDeclared, RecordLayoutDeclared, SqlStatementObserved, SqlUsage, SymbolDeclared |
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
## AST extractors (TypeScript / JavaScript)
|
|
207
|
-
|
|
208
|
-
These use [ts-morph](https://ts-morph.com) to build a full TypeScript AST and
|
|
209
|
-
run extractors in dependency order:
|
|
210
|
-
|
|
211
|
-
| # | Extractor | Emits |
|
|
212
|
-
|---|-----------|-------|
|
|
213
|
-
| 1 | `FileIndexedExtractor` | `FileIndexed` |
|
|
214
|
-
| 2 | `SymbolAndCallGraphExtractor` | `SymbolDeclared`, `CallObserved` |
|
|
215
|
-
| 3 | `ImportObservedExtractor` | `ImportObserved` |
|
|
216
|
-
| 4 | `RouteExtractor` | `RouteDeclared`, `EndpointMetadata` |
|
|
217
|
-
| 5 | `EntityExtractor` | `EntityDeclared`, `FieldDeclared` |
|
|
218
|
-
| 6 | `AuthExtractor` | `AuthBoundaryDeclared`, `RoleRequirement` |
|
|
219
|
-
| 7 | `SqlUsageExtractor` | `SqlUsage` |
|
|
220
|
-
| 8 | `DataAccessOperationExtractor` | `DataAccessOperation` |
|
|
221
|
-
| 9 | `ConfigExtractor` | `ConfigAccess` |
|
|
222
|
-
| 10 | `TestCaseDeclaredExtractor` | `TestCaseDeclared` |
|
|
223
|
-
| 11 | `MigrationDeclaredExtractor` | `MigrationDeclared` |
|
|
224
|
-
| 12 | `EventEmittedExtractor` | `EventEmitted` |
|
|
225
|
-
| 13 | `EventConsumedExtractor` | `EventConsumed` |
|
|
226
|
-
| 14 | `ExternalServiceCallExtractor` | `ExternalServiceCall`, `ApiClientCall` |
|
|
227
|
-
| 15 | `SqlObjectDeclaredExtractor` | `SqlObjectDeclared` |
|
|
228
|
-
| 16 | `ComponentExtractor` | `ComponentDeclared` |
|
|
229
|
-
| 17 | `ClientRouteExtractor` | `PageRouteDeclared` |
|
|
230
|
-
| 18 | `StateExtractor` | `StateStoreDeclared` |
|
|
231
|
-
|
|
232
|
-
### Text extractors (regex-based, no AST)
|
|
233
|
-
|
|
234
|
-
| Language | Extractor classes |
|
|
235
|
-
|----------|------------------|
|
|
236
|
-
| Swift | `SwiftApiCallExtractor`, `SwiftConfigExtractor`, `SwiftNavigationExtractor` |
|
|
237
|
-
| VB6 | `VB6ProjectExtractor`, `VB6SymbolExtractor`, `VB6SqlExtractor`, `VB6ConfigExtractor`, `VB6FormsExtractor` |
|
|
238
|
-
| Rust | `RustExtractor` |
|
|
239
|
-
| Ruby | `RubyExtractor` |
|
|
240
|
-
| PHP | `PhpExtractor` |
|
|
241
|
-
| Dart | `DartExtractor` |
|
|
242
|
-
| Scala | `ScalaExtractor` |
|
|
243
|
-
| C++ | `CppExtractor` |
|
|
244
|
-
| COBOL | `CobolAdapter` (wraps ANTLR parser + preprocessor + SQL/data/procedure extractors) |
|
|
245
|
-
|
|
246
|
-
---
|
|
247
|
-
|
|
248
|
-
## Progress reporting protocol
|
|
249
|
-
|
|
250
|
-
The HCS worker emits structured progress events on **stderr** using the
|
|
251
|
-
`[progress]` prefix. The CLI parses these for live terminal display.
|
|
252
|
-
|
|
253
|
-
### Worker → CLI protocol
|
|
254
|
-
|
|
255
|
-
```
|
|
256
|
-
[progress] {"phase":"discovering","language":"typescript"}
|
|
257
|
-
[progress] {"phase":"scanning","language":"rust","fileCount":142,"fileIndex":0}
|
|
258
|
-
[progress] {"phase":"scanning","language":"rust","file":"src/main.rs","fileIndex":1,"fileCount":142}
|
|
259
|
-
[progress] {"phase":"extracting","extractor":"SymbolAndCallGraphExtractor","fileIndex":2,"fileCount":18}
|
|
260
|
-
[progress] {"phase":"done","language":"rust","fileCount":142}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Progress event schema
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
interface ProgressEvent {
|
|
267
|
-
phase: "discovering" | "scanning" | "extracting" | "done";
|
|
268
|
-
language?: string;
|
|
269
|
-
file?: string; // Absolute path of file being processed
|
|
270
|
-
fileIndex?: number; // 1-based current file/extractor index
|
|
271
|
-
fileCount?: number; // Total files or extractors
|
|
272
|
-
extractor?: string; // Extractor class name (AST extractors)
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### CLI progress rendering
|
|
277
|
-
|
|
278
|
-
The `ProgressTracker` class in `extract.ts` renders a single-line progress
|
|
279
|
-
bar on stderr:
|
|
280
|
-
|
|
281
|
-
```
|
|
282
|
-
typescript 12/42 29% rust ✓ ruby extracting 23 facts
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
| Behaviour | TTY (interactive) | Pipe / CI |
|
|
286
|
-
|-----------|-------------------|-----------|
|
|
287
|
-
| Display | `\r`-overwriting single line, 12 fps throttle | No progress line (clean logs) |
|
|
288
|
-
| Facts | Live counter | `--verbose` summary only |
|
|
289
|
-
| Completion | Line cleared, summary printed | Summary only |
|
|
290
|
-
|
|
291
|
-
stderr is used exclusively so that stdout remains pure NDJSON.
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
## I/O channel separation
|
|
296
|
-
|
|
297
|
-
```
|
|
298
|
-
┌──────────────┐ stdout (NDJSON) ┌──────────────┐
|
|
299
|
-
│ HCS Worker │ ─────────────────────▶ │ CLI │ ──▶ stdout / --out file
|
|
300
|
-
│ │ stderr │ │
|
|
301
|
-
│ │ ─────────────────────▶ │ (progress │ ──▶ stderr (progress/logs)
|
|
302
|
-
│ │ [info] [progress] etc │ tracker) │
|
|
303
|
-
└──────────────┘ └──────────────┘
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
- **stdout**: Only NDJSON `FactEnvelope` lines. One JSON object per line.
|
|
307
|
-
The CLI validates each line, collects valid facts, sorts them, and writes
|
|
308
|
-
to stdout (or `--out` file).
|
|
309
|
-
- **stderr**: Human-readable logs (`[info]`, `[warn]`, `[error]`) and
|
|
310
|
-
machine-readable `[progress]` JSON lines. Shown in `--verbose` mode
|
|
311
|
-
(except progress, which is always parsed).
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## Exit codes
|
|
316
|
-
|
|
317
|
-
| Code | Meaning |
|
|
318
|
-
|------|---------|
|
|
319
|
-
| 0 | Success |
|
|
320
|
-
| 1 | Schema validation failure (invalid fact envelope) |
|
|
321
|
-
| 2 | Worker parse failure |
|
|
322
|
-
| 3 | Timeout exceeded |
|
|
323
|
-
| 4 | Push to dashboard API failed |
|
|
324
|
-
| 5 | Usage error (bad args) |
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## ESM bundling details
|
|
329
|
-
|
|
330
|
-
The HCS worker is built with [tsup](https://tsup.egoist.dev) using
|
|
331
|
-
`packages/vibgrate-hcs/node/tsup.config.ts`:
|
|
332
|
-
|
|
333
|
-
```typescript
|
|
334
|
-
export default defineConfig({
|
|
335
|
-
entry: ["src/main.ts"],
|
|
336
|
-
format: ["esm"],
|
|
337
|
-
target: "es2022",
|
|
338
|
-
platform: "node",
|
|
339
|
-
noExternal: ["antlr4ts", "vb6-antlr4"], // Bundle ANTLR parsers
|
|
340
|
-
esbuildOptions(options) {
|
|
341
|
-
options.banner = {
|
|
342
|
-
js: [
|
|
343
|
-
'#!/usr/bin/env node',
|
|
344
|
-
'import { createRequire as __cjsRequire } from "node:module";',
|
|
345
|
-
'const require = __cjsRequire(import.meta.url);',
|
|
346
|
-
].join('\n'),
|
|
347
|
-
};
|
|
348
|
-
},
|
|
349
|
-
});
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
Key decisions:
|
|
353
|
-
- `antlr4ts` and `vb6-antlr4` are **bundled** because their generated ANTLR
|
|
354
|
-
files use extensionless imports that fail under Node ESM strict resolution.
|
|
355
|
-
- A `createRequire` banner shim is injected **before** esbuild's `__require`
|
|
356
|
-
IIFE so that bundled CJS code (antlr4ts internals) can call `require()`
|
|
357
|
-
without throwing `ERR_REQUIRE_ESM`.
|
|
358
|
-
- `ts-morph` and `commander` remain external — resolved normally from
|
|
359
|
-
node_modules at runtime.
|
|
360
|
-
|
|
361
|
-
---
|
|
362
|
-
|
|
363
|
-
## Integration tests
|
|
364
|
-
|
|
365
|
-
```
|
|
366
|
-
pnpm test:hcs # from packages/vibgrate-cli
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
Runs `test-hcs/test-runner.ts` which exercises all 10 languages against the
|
|
370
|
-
**built** CLI binary. Each language has fixture files under
|
|
371
|
-
`test-hcs/fixtures/<language>/`.
|
|
372
|
-
|
|
373
|
-
| Check | Description |
|
|
374
|
-
|-------|-------------|
|
|
375
|
-
| Exit code | Must be 0 |
|
|
376
|
-
| NDJSON validity | Every stdout line must parse as valid JSON |
|
|
377
|
-
| FactEnvelope schema | All required fields present and typed |
|
|
378
|
-
| Min fact count | Language-specific minimum (3–5) |
|
|
379
|
-
| Required fact types | Language-specific fact types must appear |
|
|
380
|
-
| Language field | Must match the expected language |
|
|
381
|
-
| factId uniqueness | All factIds should be unique (warning if not) |
|
|
382
|
-
|
|
383
|
-
### Running tests
|
|
384
|
-
|
|
385
|
-
```bash
|
|
386
|
-
# Full build + test
|
|
387
|
-
pnpm build:only && pnpm test:hcs
|
|
388
|
-
|
|
389
|
-
# Just tests (assumes built)
|
|
390
|
-
pnpm test:hcs
|
|
391
|
-
|
|
392
|
-
# Verbose output
|
|
393
|
-
pnpm test:hcs -- --verbose
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
## Directories
|
|
399
|
-
|
|
400
|
-
```
|
|
401
|
-
packages/vibgrate-cli/
|
|
402
|
-
src/commands/extract.ts # CLI extract orchestration + progress tracker
|
|
403
|
-
src/commands/diff.ts # CLI diff command (NDJSON delta comparison)
|
|
404
|
-
test-hcs/
|
|
405
|
-
test-runner.ts # Integration test runner (10 languages)
|
|
406
|
-
fixtures/ # Per-language fixture projects
|
|
407
|
-
typescript/ # Express + Prisma app
|
|
408
|
-
javascript/ # Express + SQL + axios app
|
|
409
|
-
swift/ # SwiftUI + URLSession app
|
|
410
|
-
rust/ # actix-web + sqlx + reqwest app
|
|
411
|
-
ruby/ # Sinatra + ActiveRecord app
|
|
412
|
-
php/ # Laravel controller
|
|
413
|
-
dart/ # Flutter + http app
|
|
414
|
-
scala/ # Akka HTTP + Slick app
|
|
415
|
-
vb6/ # VB6 module (Type, Sub, Function, SQL)
|
|
416
|
-
cobol/ # COBOL with EXEC SQL + file I/O
|
|
417
|
-
|
|
418
|
-
packages/vibgrate-hcs/node/
|
|
419
|
-
src/main.ts # Worker entry — commander, dispatch, progress
|
|
420
|
-
src/facts/
|
|
421
|
-
fact-emitter.ts # NdjsonFactEmitter (FactEnvelope, emit helpers)
|
|
422
|
-
fact-types.ts # TypeScript interfaces for all payload types
|
|
423
|
-
src/extractors/
|
|
424
|
-
extractor.ts # Extractor interface (AST-based)
|
|
425
|
-
text-extractor.ts # TextExtractor interface (regex-based)
|
|
426
|
-
file-indexed.ts # FileIndexedExtractor
|
|
427
|
-
symbol-call-graph.ts # SymbolAndCallGraphExtractor
|
|
428
|
-
import-observed.ts # ImportObservedExtractor
|
|
429
|
-
routes.ts # RouteExtractor
|
|
430
|
-
... # 18 AST extractors total
|
|
431
|
-
rust-extractor.ts # RustExtractor
|
|
432
|
-
ruby-extractor.ts # RubyExtractor
|
|
433
|
-
php-extractor.ts # PhpExtractor
|
|
434
|
-
dart-extractor.ts # DartExtractor
|
|
435
|
-
scala-extractor.ts # ScalaExtractor
|
|
436
|
-
swift-*.ts # 3 Swift extractors
|
|
437
|
-
vb6-*.ts # 5 VB6 extractors
|
|
438
|
-
cobol-adapter.ts # CobolAdapter (wraps ANTLR pipeline)
|
|
439
|
-
cobol-*.ts # COBOL parser + 5 sub-extractors
|
|
440
|
-
tsup.config.ts # Build config (bundle ANTLR, createRequire shim)
|
|
441
|
-
dist/main.js # Built worker (~4.8 MB)
|
|
442
|
-
```
|
package/dist/chunk-34KD4UJ3.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
runScan
|
|
3
|
-
} from "./chunk-XKZBEQYY.js";
|
|
4
|
-
|
|
5
|
-
// src/commands/baseline.ts
|
|
6
|
-
import * as path3 from "path";
|
|
7
|
-
import { Command } from "commander";
|
|
8
|
-
import chalk from "chalk";
|
|
9
|
-
|
|
10
|
-
// src/utils/fs.ts
|
|
11
|
-
import { execFile } from "child_process";
|
|
12
|
-
import * as fs from "fs/promises";
|
|
13
|
-
import * as os from "os";
|
|
14
|
-
import * as path2 from "path";
|
|
15
|
-
import { promisify } from "util";
|
|
16
|
-
|
|
17
|
-
// src/utils/semaphore.ts
|
|
18
|
-
var Semaphore = class {
|
|
19
|
-
available;
|
|
20
|
-
queue = [];
|
|
21
|
-
constructor(max) {
|
|
22
|
-
this.available = max;
|
|
23
|
-
}
|
|
24
|
-
async run(fn) {
|
|
25
|
-
await this.acquire();
|
|
26
|
-
try {
|
|
27
|
-
return await fn();
|
|
28
|
-
} finally {
|
|
29
|
-
this.release();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
acquire() {
|
|
33
|
-
if (this.available > 0) {
|
|
34
|
-
this.available--;
|
|
35
|
-
return Promise.resolve();
|
|
36
|
-
}
|
|
37
|
-
return new Promise((resolve3) => this.queue.push(resolve3));
|
|
38
|
-
}
|
|
39
|
-
release() {
|
|
40
|
-
const next = this.queue.shift();
|
|
41
|
-
if (next) next();
|
|
42
|
-
else this.available++;
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// src/utils/glob.ts
|
|
47
|
-
import * as path from "path";
|
|
48
|
-
|
|
49
|
-
// src/utils/fs.ts
|
|
50
|
-
var execFileAsync = promisify(execFile);
|
|
51
|
-
function stripBom(text) {
|
|
52
|
-
return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
|
|
53
|
-
}
|
|
54
|
-
async function readJsonFile(filePath) {
|
|
55
|
-
const txt = await fs.readFile(filePath, "utf8");
|
|
56
|
-
return JSON.parse(stripBom(txt));
|
|
57
|
-
}
|
|
58
|
-
async function pathExists(p) {
|
|
59
|
-
try {
|
|
60
|
-
await fs.access(p);
|
|
61
|
-
return true;
|
|
62
|
-
} catch {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
async function ensureDir(dir) {
|
|
67
|
-
await fs.mkdir(dir, { recursive: true });
|
|
68
|
-
}
|
|
69
|
-
async function writeJsonFile(filePath, data) {
|
|
70
|
-
await ensureDir(path2.dirname(filePath));
|
|
71
|
-
await fs.writeFile(filePath, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
72
|
-
}
|
|
73
|
-
async function writeTextFile(filePath, content) {
|
|
74
|
-
await ensureDir(path2.dirname(filePath));
|
|
75
|
-
await fs.writeFile(filePath, content, "utf8");
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// src/commands/baseline.ts
|
|
79
|
-
async function runBaseline(rootDir) {
|
|
80
|
-
console.log(chalk.dim("Creating baseline..."));
|
|
81
|
-
const artifact = await runScan(rootDir, {
|
|
82
|
-
format: "text",
|
|
83
|
-
concurrency: 8
|
|
84
|
-
});
|
|
85
|
-
const baselinePath = path3.join(rootDir, ".vibgrate", "baseline.json");
|
|
86
|
-
await writeJsonFile(baselinePath, artifact);
|
|
87
|
-
console.log(chalk.green("\u2714") + ` Baseline saved to ${chalk.bold(".vibgrate/baseline.json")}`);
|
|
88
|
-
console.log(chalk.dim(` Baseline score: ${artifact.drift.score}/100`));
|
|
89
|
-
}
|
|
90
|
-
var baselineCommand = new Command("baseline").description("Create a drift baseline snapshot").argument("[path]", "Path to baseline", ".").action(async (targetPath) => {
|
|
91
|
-
const rootDir = path3.resolve(targetPath);
|
|
92
|
-
await runBaseline(rootDir);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
export {
|
|
96
|
-
Semaphore,
|
|
97
|
-
readJsonFile,
|
|
98
|
-
pathExists,
|
|
99
|
-
ensureDir,
|
|
100
|
-
writeTextFile,
|
|
101
|
-
runBaseline,
|
|
102
|
-
baselineCommand
|
|
103
|
-
};
|