@codeledger/cli 0.6.6 → 0.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/architecture-graph/dependency-scanner.d.ts +16 -0
- package/dist/architecture-graph/dependency-scanner.d.ts.map +1 -0
- package/dist/architecture-graph/dependency-scanner.js +96 -0
- package/dist/architecture-graph/dependency-scanner.js.map +1 -0
- package/dist/architecture-graph/graph-builder.d.ts +70 -0
- package/dist/architecture-graph/graph-builder.d.ts.map +1 -0
- package/dist/architecture-graph/graph-builder.js +231 -0
- package/dist/architecture-graph/graph-builder.js.map +1 -0
- package/dist/architecture-graph/index.d.ts +4 -0
- package/dist/architecture-graph/index.d.ts.map +1 -0
- package/dist/architecture-graph/index.js +7 -0
- package/dist/architecture-graph/index.js.map +1 -0
- package/dist/architecture-graph/service-scanner.d.ts +22 -0
- package/dist/architecture-graph/service-scanner.d.ts.map +1 -0
- package/dist/architecture-graph/service-scanner.js +181 -0
- package/dist/architecture-graph/service-scanner.js.map +1 -0
- package/dist/commands/audit-export.d.ts +8 -0
- package/dist/commands/audit-export.d.ts.map +1 -0
- package/dist/commands/audit-export.js +190 -0
- package/dist/commands/audit-export.js.map +1 -0
- package/dist/commands/fix.d.ts +7 -0
- package/dist/commands/fix.d.ts.map +1 -0
- package/dist/commands/fix.js +107 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/graph.d.ts +8 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +29 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/learn.d.ts +8 -0
- package/dist/commands/learn.d.ts.map +1 -0
- package/dist/commands/learn.js +33 -0
- package/dist/commands/learn.js.map +1 -0
- package/dist/commands/pack.d.ts +12 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +75 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/serve.d.ts +13 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +179 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/setup-ci.d.ts +6 -4
- package/dist/commands/setup-ci.d.ts.map +1 -1
- package/dist/commands/setup-ci.js +216 -23
- package/dist/commands/setup-ci.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +82 -3
- package/dist/index.js.map +1 -1
- package/dist/review-intelligence/detectors/cjs-named-import.d.ts +13 -0
- package/dist/review-intelligence/detectors/cjs-named-import.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/cjs-named-import.js +134 -0
- package/dist/review-intelligence/detectors/cjs-named-import.js.map +1 -0
- package/dist/review-intelligence/detectors/exact-count-assertion.d.ts +17 -0
- package/dist/review-intelligence/detectors/exact-count-assertion.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/exact-count-assertion.js +93 -0
- package/dist/review-intelligence/detectors/exact-count-assertion.js.map +1 -0
- package/dist/review-intelligence/detectors/exports-map-missing.d.ts +14 -0
- package/dist/review-intelligence/detectors/exports-map-missing.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/exports-map-missing.js +131 -0
- package/dist/review-intelligence/detectors/exports-map-missing.js.map +1 -0
- package/dist/review-intelligence/detectors/fixture-keyword-drift.d.ts +12 -0
- package/dist/review-intelligence/detectors/fixture-keyword-drift.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/fixture-keyword-drift.js +82 -0
- package/dist/review-intelligence/detectors/fixture-keyword-drift.js.map +1 -0
- package/dist/review-intelligence/detectors/optional-infra-crash.d.ts +12 -0
- package/dist/review-intelligence/detectors/optional-infra-crash.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/optional-infra-crash.js +97 -0
- package/dist/review-intelligence/detectors/optional-infra-crash.js.map +1 -0
- package/dist/review-intelligence/detectors/undeclared-dependency.d.ts +11 -0
- package/dist/review-intelligence/detectors/undeclared-dependency.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/undeclared-dependency.js +100 -0
- package/dist/review-intelligence/detectors/undeclared-dependency.js.map +1 -0
- package/dist/review-intelligence/engine/ast-parser.d.ts +90 -0
- package/dist/review-intelligence/engine/ast-parser.d.ts.map +1 -0
- package/dist/review-intelligence/engine/ast-parser.js +266 -0
- package/dist/review-intelligence/engine/ast-parser.js.map +1 -0
- package/dist/review-intelligence/engine/dataflow.d.ts +34 -0
- package/dist/review-intelligence/engine/dataflow.d.ts.map +1 -0
- package/dist/review-intelligence/engine/dataflow.js +115 -0
- package/dist/review-intelligence/engine/dataflow.js.map +1 -0
- package/dist/review-intelligence/engine/index.d.ts +7 -0
- package/dist/review-intelligence/engine/index.d.ts.map +1 -0
- package/dist/review-intelligence/engine/index.js +7 -0
- package/dist/review-intelligence/engine/index.js.map +1 -0
- package/dist/review-intelligence/engine/symbol-resolver.d.ts +34 -0
- package/dist/review-intelligence/engine/symbol-resolver.d.ts.map +1 -0
- package/dist/review-intelligence/engine/symbol-resolver.js +106 -0
- package/dist/review-intelligence/engine/symbol-resolver.js.map +1 -0
- package/dist/review-intelligence/fixes/index.d.ts +36 -0
- package/dist/review-intelligence/fixes/index.d.ts.map +1 -0
- package/dist/review-intelligence/fixes/index.js +157 -0
- package/dist/review-intelligence/fixes/index.js.map +1 -0
- package/dist/review-intelligence/index.d.ts.map +1 -1
- package/dist/review-intelligence/index.js +2 -0
- package/dist/review-intelligence/index.js.map +1 -1
- package/dist/review-intelligence/invariants.d.ts.map +1 -1
- package/dist/review-intelligence/invariants.js +14 -1
- package/dist/review-intelligence/invariants.js.map +1 -1
- package/dist/review-intelligence/learning/index.d.ts +39 -0
- package/dist/review-intelligence/learning/index.d.ts.map +1 -0
- package/dist/review-intelligence/learning/index.js +265 -0
- package/dist/review-intelligence/learning/index.js.map +1 -0
- package/dist/review-intelligence/packs/index.d.ts +69 -0
- package/dist/review-intelligence/packs/index.d.ts.map +1 -0
- package/dist/review-intelligence/packs/index.js +168 -0
- package/dist/review-intelligence/packs/index.js.map +1 -0
- package/dist/review-intelligence/repair-guidance.d.ts.map +1 -1
- package/dist/review-intelligence/repair-guidance.js +46 -0
- package/dist/review-intelligence/repair-guidance.js.map +1 -1
- package/dist/review-intelligence/types.d.ts +6 -1
- package/dist/review-intelligence/types.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// ─── Service Scanner ────────────────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Detect services in a monorepo by scanning for common patterns:
|
|
4
|
+
// - Directories with package.json + server entry points
|
|
5
|
+
// - Docker-related files (Dockerfile, docker-compose)
|
|
6
|
+
// - Known service directory structures
|
|
7
|
+
import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
/**
|
|
10
|
+
* Scan a monorepo for services.
|
|
11
|
+
*/
|
|
12
|
+
export function scanServices(cwd) {
|
|
13
|
+
const services = [];
|
|
14
|
+
// Scan common service directories
|
|
15
|
+
const serviceDirs = [
|
|
16
|
+
'services',
|
|
17
|
+
'apps',
|
|
18
|
+
'packages',
|
|
19
|
+
'microservices',
|
|
20
|
+
];
|
|
21
|
+
for (const serviceDir of serviceDirs) {
|
|
22
|
+
const fullDir = join(cwd, serviceDir);
|
|
23
|
+
if (!existsSync(fullDir))
|
|
24
|
+
continue;
|
|
25
|
+
try {
|
|
26
|
+
const entries = readdirSync(fullDir);
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
const entryPath = join(fullDir, entry);
|
|
29
|
+
try {
|
|
30
|
+
if (!statSync(entryPath).isDirectory())
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const serviceInfo = analyzeServiceDirectory(cwd, join(serviceDir, entry));
|
|
37
|
+
if (serviceInfo) {
|
|
38
|
+
services.push(serviceInfo);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Skip unreadable directories
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Also check root level for single-service repos
|
|
47
|
+
if (services.length === 0) {
|
|
48
|
+
const rootService = analyzeServiceDirectory(cwd, '.');
|
|
49
|
+
if (rootService) {
|
|
50
|
+
services.push(rootService);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return services;
|
|
54
|
+
}
|
|
55
|
+
function analyzeServiceDirectory(cwd, relPath) {
|
|
56
|
+
const fullPath = join(cwd, relPath);
|
|
57
|
+
const pkgJsonPath = join(fullPath, 'package.json');
|
|
58
|
+
if (!existsSync(pkgJsonPath))
|
|
59
|
+
return undefined;
|
|
60
|
+
let pkg;
|
|
61
|
+
try {
|
|
62
|
+
pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const name = pkg['name'] ?? relPath.split('/').pop() ?? 'unknown';
|
|
68
|
+
const hasDockerfile = existsSync(join(fullPath, 'Dockerfile'));
|
|
69
|
+
const isEntryPoint = hasServerEntryPoint(fullPath, pkg);
|
|
70
|
+
const type = classifyService(fullPath, pkg, hasDockerfile, isEntryPoint);
|
|
71
|
+
// Extract dependencies
|
|
72
|
+
const dependencies = [];
|
|
73
|
+
for (const field of ['dependencies', 'devDependencies']) {
|
|
74
|
+
const section = pkg[field];
|
|
75
|
+
if (section && typeof section === 'object') {
|
|
76
|
+
dependencies.push(...Object.keys(section));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Scan for internal imports
|
|
80
|
+
const internalImports = scanInternalImports(fullPath, cwd);
|
|
81
|
+
return {
|
|
82
|
+
name,
|
|
83
|
+
path: relPath,
|
|
84
|
+
type,
|
|
85
|
+
hasDockerfile,
|
|
86
|
+
dependencies,
|
|
87
|
+
internalImports,
|
|
88
|
+
isEntryPoint,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function hasServerEntryPoint(dir, pkg) {
|
|
92
|
+
// Check scripts for start/serve commands
|
|
93
|
+
const scripts = pkg['scripts'];
|
|
94
|
+
if (scripts && typeof scripts === 'object') {
|
|
95
|
+
const scriptEntries = Object.entries(scripts);
|
|
96
|
+
for (const [key, value] of scriptEntries) {
|
|
97
|
+
if (['start', 'serve', 'dev'].includes(key) && typeof value === 'string') {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Check for common server files
|
|
103
|
+
const serverFiles = ['server.ts', 'server.js', 'app.ts', 'app.js', 'main.ts', 'main.js', 'index.ts', 'index.js'];
|
|
104
|
+
const srcDir = join(dir, 'src');
|
|
105
|
+
for (const file of serverFiles) {
|
|
106
|
+
if (existsSync(join(dir, file)) || existsSync(join(srcDir, file))) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
function classifyService(_dir, pkg, hasDockerfile, isEntryPoint) {
|
|
113
|
+
const name = (pkg['name'] ?? '').toLowerCase();
|
|
114
|
+
const deps = pkg['dependencies'];
|
|
115
|
+
// Gateway patterns
|
|
116
|
+
if (name.includes('gateway') || name.includes('proxy') || name.includes('bff')) {
|
|
117
|
+
return 'gateway';
|
|
118
|
+
}
|
|
119
|
+
// Worker patterns
|
|
120
|
+
if (name.includes('worker') || name.includes('consumer') || name.includes('processor') || name.includes('job')) {
|
|
121
|
+
return 'worker';
|
|
122
|
+
}
|
|
123
|
+
// API patterns
|
|
124
|
+
if (name.includes('api') ||
|
|
125
|
+
name.includes('service') ||
|
|
126
|
+
name.includes('server') ||
|
|
127
|
+
(deps && typeof deps === 'object' && ('fastify' in deps || 'express' in deps))) {
|
|
128
|
+
return 'api';
|
|
129
|
+
}
|
|
130
|
+
// Library patterns (no server, no docker)
|
|
131
|
+
if (!isEntryPoint && !hasDockerfile) {
|
|
132
|
+
return 'library';
|
|
133
|
+
}
|
|
134
|
+
return 'unknown';
|
|
135
|
+
}
|
|
136
|
+
function scanInternalImports(dir, cwd) {
|
|
137
|
+
const imports = new Set();
|
|
138
|
+
const srcDir = join(dir, 'src');
|
|
139
|
+
const scanDir = existsSync(srcDir) ? srcDir : dir;
|
|
140
|
+
try {
|
|
141
|
+
scanDirForImports(scanDir, cwd, imports, 0);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Skip on error
|
|
145
|
+
}
|
|
146
|
+
return [...imports];
|
|
147
|
+
}
|
|
148
|
+
function scanDirForImports(dir, cwd, imports, depth) {
|
|
149
|
+
if (depth > 3)
|
|
150
|
+
return; // Limit recursion
|
|
151
|
+
try {
|
|
152
|
+
const entries = readdirSync(dir);
|
|
153
|
+
for (const entry of entries) {
|
|
154
|
+
if (entry.startsWith('.') || entry === 'node_modules' || entry === 'dist')
|
|
155
|
+
continue;
|
|
156
|
+
const fullPath = join(dir, entry);
|
|
157
|
+
try {
|
|
158
|
+
const stat = statSync(fullPath);
|
|
159
|
+
if (stat.isDirectory()) {
|
|
160
|
+
scanDirForImports(fullPath, cwd, imports, depth + 1);
|
|
161
|
+
}
|
|
162
|
+
else if (/\.(?:ts|tsx|js|jsx)$/.test(entry) && !entry.endsWith('.test.ts') && !entry.endsWith('.spec.ts')) {
|
|
163
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
164
|
+
// Find workspace package imports
|
|
165
|
+
const importPattern = /from\s+['"](@\w+\/[\w-]+)/g;
|
|
166
|
+
let match;
|
|
167
|
+
while ((match = importPattern.exec(content)) !== null) {
|
|
168
|
+
imports.add(match[1]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// Skip inaccessible files
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Skip unreadable directories
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=service-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-scanner.js","sourceRoot":"","sources":["../../src/architecture-graph/service-scanner.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,iEAAiE;AACjE,wDAAwD;AACxD,sDAAsD;AACtD,uCAAuC;AAEvC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAoBjC;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,QAAQ,GAAkB,EAAE,CAAC;IAEnC,kCAAkC;IAClC,MAAM,WAAW,GAAG;QAClB,UAAU;QACV,MAAM;QACN,UAAU;QACV,eAAe;KAChB,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QAEnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;YACrC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBACvC,IAAI,CAAC;oBACH,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;wBAAE,SAAS;gBACnD,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;gBAED,MAAM,WAAW,GAAG,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;gBAC1E,IAAI,WAAW,EAAE,CAAC;oBAChB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,uBAAuB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACtD,IAAI,WAAW,EAAE,CAAC;YAChB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAW,EAAE,OAAe;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAEnD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAE/C,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAA4B,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,IAAI,GAAI,GAAG,CAAC,MAAM,CAAY,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;IAC9E,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;IAEzE,uBAAuB;IACvB,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACxD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC3C,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAkC,CAAC,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,MAAM,eAAe,GAAG,mBAAmB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAE3D,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,OAAO;QACb,IAAI;QACJ,aAAa;QACb,YAAY;QACZ,eAAe;QACf,YAAY;KACb,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAW,EAAE,GAA4B;IACpE,yCAAyC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC3C,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,OAAiC,CAAC,CAAC;QACxE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,aAAa,EAAE,CAAC;YACzC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACzE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,WAAW,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IACjH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEhC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CACtB,IAAY,EACZ,GAA4B,EAC5B,aAAsB,EACtB,YAAqB;IAErB,MAAM,IAAI,GAAG,CAAE,GAAG,CAAC,MAAM,CAAY,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,MAAM,IAAI,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC;IAEjC,mBAAmB;IACnB,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,kBAAkB;IAClB,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/G,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,eAAe;IACf,IACE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACvB,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,SAAS,IAAK,IAAgC,IAAI,SAAS,IAAK,IAAgC,CAAC,CAAC,EACxI,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0CAA0C;IAC1C,IAAI,CAAC,YAAY,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAW,EAAE,GAAW;IACnD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IAElD,IAAI,CAAC;QACH,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW,EAAE,GAAW,EAAE,OAAoB,EAAE,KAAa;IACtF,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,CAAC,kBAAkB;IAEzC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,cAAc,IAAI,KAAK,KAAK,MAAM;gBAAE,SAAS;YAEpF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAChC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBACvB,iBAAiB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACvD,CAAC;qBAAM,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC5G,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,iCAAiC;oBACjC,MAAM,aAAa,GAAG,4BAA4B,CAAC;oBACnD,IAAI,KAA6B,CAAC;oBAClC,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;wBACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,0BAA0B;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codeledger audit-export [--format json|csv|jsonl] [--output <path>] [--table runs|events|bundles|coverage]`
|
|
3
|
+
*
|
|
4
|
+
* Exports the SQLite append-only ledger to compliance-friendly formats.
|
|
5
|
+
* Supports JSON (full export), CSV (tabular), and JSON Lines (SIEM-compatible).
|
|
6
|
+
*/
|
|
7
|
+
export declare function runAuditExport(cwd: string, flags: Record<string, string>): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=audit-export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-export.d.ts","sourceRoot":"","sources":["../../src/commands/audit-export.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAiEf"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* `codeledger audit-export [--format json|csv|jsonl] [--output <path>] [--table runs|events|bundles|coverage]`
|
|
5
|
+
*
|
|
6
|
+
* Exports the SQLite append-only ledger to compliance-friendly formats.
|
|
7
|
+
* Supports JSON (full export), CSV (tabular), and JSON Lines (SIEM-compatible).
|
|
8
|
+
*/
|
|
9
|
+
export async function runAuditExport(cwd, flags) {
|
|
10
|
+
const format = (flags['format'] ?? 'json');
|
|
11
|
+
if (!VALID_FORMATS.includes(format)) {
|
|
12
|
+
console.error(`Invalid --format "${format}". Must be one of: ${VALID_FORMATS.join(', ')}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const table = flags['table'];
|
|
16
|
+
if (table && !VALID_TABLES.includes(table)) {
|
|
17
|
+
console.error(`Invalid --table "${table}". Must be one of: ${VALID_TABLES.join(', ')}`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
const outputPath = flags['output'] ? resolve(cwd, flags['output']) : undefined;
|
|
21
|
+
// Locate the ledger database
|
|
22
|
+
const dbPath = resolveLedgerPath(cwd);
|
|
23
|
+
if (!dbPath) {
|
|
24
|
+
console.error('Ledger database not found.');
|
|
25
|
+
console.error('Expected at: .codeledger/ledger.db');
|
|
26
|
+
console.error('Run `codeledger init` to initialize, or `codeledger run` to create the ledger.');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
// Dynamically import better-sqlite3 (native addon in packages/core)
|
|
30
|
+
let db;
|
|
31
|
+
try {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
33
|
+
const createRequire = (await import('node:module')).createRequire;
|
|
34
|
+
const require = createRequire(import.meta.url);
|
|
35
|
+
const Database = require('better-sqlite3');
|
|
36
|
+
db = Database(dbPath, { readonly: true });
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
console.error('better-sqlite3 is required for audit-export but is not installed.');
|
|
40
|
+
console.error('Run: npm install better-sqlite3');
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const tables = table ? [table] : VALID_TABLES;
|
|
45
|
+
const exportData = {};
|
|
46
|
+
for (const t of tables) {
|
|
47
|
+
const rows = queryTable(db, t);
|
|
48
|
+
exportData[t] = rows;
|
|
49
|
+
}
|
|
50
|
+
const output = formatExport(exportData, format);
|
|
51
|
+
if (outputPath) {
|
|
52
|
+
writeFileSync(outputPath, output);
|
|
53
|
+
console.log(`Exported ${countRows(exportData)} records to ${outputPath}`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
process.stdout.write(output);
|
|
57
|
+
}
|
|
58
|
+
// Summary to stderr (so stdout is clean for piping)
|
|
59
|
+
if (!outputPath) {
|
|
60
|
+
for (const [t, rows] of Object.entries(exportData)) {
|
|
61
|
+
console.error(` ${t}: ${rows.length} records`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
db.close();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const VALID_FORMATS = ['json', 'csv', 'jsonl'];
|
|
70
|
+
const VALID_TABLES = ['runs', 'events', 'bundles', 'coverage'];
|
|
71
|
+
/** Map logical table names to actual SQLite table names */
|
|
72
|
+
const TABLE_MAP = {
|
|
73
|
+
runs: 'runs',
|
|
74
|
+
events: 'events',
|
|
75
|
+
bundles: 'bundles',
|
|
76
|
+
coverage: 'coverage_events',
|
|
77
|
+
};
|
|
78
|
+
// ─── Database ─────────────────────────────────────────────────────────────────
|
|
79
|
+
function resolveLedgerPath(cwd) {
|
|
80
|
+
// Check config for custom path
|
|
81
|
+
const configPath = join(cwd, '.codeledger', 'config.json');
|
|
82
|
+
if (existsSync(configPath)) {
|
|
83
|
+
try {
|
|
84
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
85
|
+
const workspace = config['workspace'];
|
|
86
|
+
if (workspace?.['db_path']) {
|
|
87
|
+
const customPath = resolve(cwd, String(workspace['db_path']));
|
|
88
|
+
if (existsSync(customPath))
|
|
89
|
+
return customPath;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Fall through to default path
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Default path
|
|
97
|
+
const defaultPath = join(cwd, '.codeledger', 'ledger.db');
|
|
98
|
+
if (existsSync(defaultPath))
|
|
99
|
+
return defaultPath;
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
const ALLOWED_SQL_TABLES = new Set(['runs', 'events', 'bundles', 'coverage_events']);
|
|
103
|
+
function queryTable(db, table) {
|
|
104
|
+
const sqlTable = TABLE_MAP[table];
|
|
105
|
+
if (!ALLOWED_SQL_TABLES.has(sqlTable)) {
|
|
106
|
+
throw new Error(`Invalid table name: ${sqlTable}`);
|
|
107
|
+
}
|
|
108
|
+
// Use the database's all() method to get all rows
|
|
109
|
+
const stmt = db
|
|
110
|
+
.prepare(`SELECT * FROM ${sqlTable} ORDER BY created_at DESC, rowid DESC`);
|
|
111
|
+
try {
|
|
112
|
+
return stmt.all();
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Table might not exist yet (e.g., no runs recorded)
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ─── Formatters ───────────────────────────────────────────────────────────────
|
|
120
|
+
function formatExport(data, format) {
|
|
121
|
+
switch (format) {
|
|
122
|
+
case 'json':
|
|
123
|
+
return formatJson(data);
|
|
124
|
+
case 'jsonl':
|
|
125
|
+
return formatJsonLines(data);
|
|
126
|
+
case 'csv':
|
|
127
|
+
return formatCsv(data);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function formatJson(data) {
|
|
131
|
+
const export_ = {
|
|
132
|
+
schema_version: 'codeledger/audit-export/v1',
|
|
133
|
+
exported_at: new Date().toISOString(),
|
|
134
|
+
...data,
|
|
135
|
+
};
|
|
136
|
+
return JSON.stringify(export_, null, 2) + '\n';
|
|
137
|
+
}
|
|
138
|
+
function formatJsonLines(data) {
|
|
139
|
+
const lines = [];
|
|
140
|
+
for (const [table, rows] of Object.entries(data)) {
|
|
141
|
+
for (const row of rows) {
|
|
142
|
+
// CEF-compatible: each line is a self-contained JSON object with table context
|
|
143
|
+
lines.push(JSON.stringify({
|
|
144
|
+
_table: table,
|
|
145
|
+
_exported_at: new Date().toISOString(),
|
|
146
|
+
...row,
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return lines.join('\n') + '\n';
|
|
151
|
+
}
|
|
152
|
+
function formatCsv(data) {
|
|
153
|
+
const sections = [];
|
|
154
|
+
for (const [table, rows] of Object.entries(data)) {
|
|
155
|
+
if (rows.length === 0)
|
|
156
|
+
continue;
|
|
157
|
+
// Header comment
|
|
158
|
+
sections.push(`# Table: ${table}`);
|
|
159
|
+
// Collect all unique column names across all rows for stable output
|
|
160
|
+
const colSet = new Set();
|
|
161
|
+
for (const row of rows) {
|
|
162
|
+
for (const key of Object.keys(row))
|
|
163
|
+
colSet.add(key);
|
|
164
|
+
}
|
|
165
|
+
const columns = Array.from(colSet);
|
|
166
|
+
sections.push(columns.join(','));
|
|
167
|
+
// Data rows
|
|
168
|
+
for (const row of rows) {
|
|
169
|
+
const r = row;
|
|
170
|
+
const values = columns.map(col => csvEscape(r[col]));
|
|
171
|
+
sections.push(values.join(','));
|
|
172
|
+
}
|
|
173
|
+
sections.push(''); // blank line between tables
|
|
174
|
+
}
|
|
175
|
+
return sections.join('\n');
|
|
176
|
+
}
|
|
177
|
+
function csvEscape(value) {
|
|
178
|
+
if (value === null || value === undefined)
|
|
179
|
+
return '';
|
|
180
|
+
const str = String(value);
|
|
181
|
+
// Escape if contains comma, quote, or newline
|
|
182
|
+
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
|
|
183
|
+
return `"${str.replace(/"/g, '""')}"`;
|
|
184
|
+
}
|
|
185
|
+
return str;
|
|
186
|
+
}
|
|
187
|
+
function countRows(data) {
|
|
188
|
+
return Object.values(data).reduce((sum, rows) => sum + rows.length, 0);
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=audit-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-export.js","sourceRoot":"","sources":["../../src/commands/audit-export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,KAA6B;IAE7B,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAiB,CAAC;IAC3D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,CAAC,qBAAqB,MAAM,sBAAsB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAA0B,CAAC;IACtD,IAAI,KAAK,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,oBAAoB,KAAK,sBAAsB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE/E,6BAA6B;IAC7B,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC5C,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;QAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oEAAoE;IACpE,IAAI,EAAW,CAAC;IAChB,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,aAAa,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;QAClE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAA8D,CAAC;QACxG,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACnF,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;QAC9C,MAAM,UAAU,GAA8B,EAAE,CAAC;QAEjD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC/B,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACvB,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAEhD,IAAI,UAAU,EAAE,CAAC;YACf,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,CAAC,UAAU,CAAC,eAAe,UAAU,EAAE,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAED,oDAAoD;QACpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBACnD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACR,EAA4B,CAAC,KAAK,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAOD,MAAM,aAAa,GAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAC/D,MAAM,YAAY,GAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAE5E,2DAA2D;AAC3D,MAAM,SAAS,GAA8B;IAC3C,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,iBAAiB;CAC5B,CAAC;AAEF,iFAAiF;AAEjF,SAAS,iBAAiB,CAAC,GAAW;IACpC,+BAA+B;IAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAA4B,CAAC;YACxF,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAwC,CAAC;YAC7E,IAAI,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC9D,IAAI,UAAU,CAAC,UAAU,CAAC;oBAAE,OAAO,UAAU,CAAC;YAChD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;IAED,eAAe;IACf,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IAC1D,IAAI,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,CAAC;IAEhD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAErF,SAAS,UAAU,CAAC,EAAW,EAAE,KAAgB;IAC/C,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,kDAAkD;IAClD,MAAM,IAAI,GAAI,EAA6E;SACxF,OAAO,CAAC,iBAAiB,QAAQ,uCAAuC,CAAC,CAAC;IAE7E,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;QACrD,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF,SAAS,YAAY,CAAC,IAA+B,EAAE,MAAoB;IACzE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,KAAK,OAAO;YACV,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/B,KAAK,KAAK;YACR,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAA+B;IACjD,MAAM,OAAO,GAAG;QACd,cAAc,EAAE,4BAA4B;QAC5C,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,GAAG,IAAI;KACR,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AACjD,CAAC;AAED,SAAS,eAAe,CAAC,IAA+B;IACtD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,+EAA+E;YAC/E,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;gBACxB,MAAM,EAAE,KAAK;gBACb,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACtC,GAAI,GAA+B;aACpC,CAAC,CAAC,CAAC;QACN,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC;AAED,SAAS,SAAS,CAAC,IAA+B;IAChD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEhC,iBAAiB;QACjB,QAAQ,CAAC,IAAI,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC;QAEnC,oEAAoE;QACpE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAA8B,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjF,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAEjC,YAAY;QACZ,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,GAA8B,CAAC;YACzC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACrD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAClC,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,4BAA4B;IACjD,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,8CAA8C;IAC9C,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjE,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IACxC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAAC,IAA+B;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codeledger fix [--rule <rule-id>] [--dry-run]`
|
|
3
|
+
*
|
|
4
|
+
* Apply auto-fixes for architectural violations detected by Review Intelligence.
|
|
5
|
+
*/
|
|
6
|
+
export declare function runFix(cwd: string, flags: Record<string, string>): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=fix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,wBAAsB,MAAM,CAC1B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAyGf"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
import { runReviewIntelligence, DEFAULT_REVIEW_INTELLIGENCE_POLICY, } from '../review-intelligence/index.js';
|
|
5
|
+
import { applyAllFixes, isFixable, getFixableRuleIds } from '../review-intelligence/fixes/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* `codeledger fix [--rule <rule-id>] [--dry-run]`
|
|
8
|
+
*
|
|
9
|
+
* Apply auto-fixes for architectural violations detected by Review Intelligence.
|
|
10
|
+
*/
|
|
11
|
+
export async function runFix(cwd, flags) {
|
|
12
|
+
const ruleFilter = flags['rule'];
|
|
13
|
+
const dryRun = flags['dry-run'] === 'true';
|
|
14
|
+
// Load config
|
|
15
|
+
const configPath = join(cwd, '.codeledger', 'config.json');
|
|
16
|
+
if (!existsSync(configPath)) {
|
|
17
|
+
console.error('No .codeledger/config.json found. Run "codeledger init" first.');
|
|
18
|
+
process.exit(2);
|
|
19
|
+
}
|
|
20
|
+
// Get changed files from git
|
|
21
|
+
let files;
|
|
22
|
+
try {
|
|
23
|
+
const gitOutput = execSync('git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only --cached 2>/dev/null || git ls-files -m', {
|
|
24
|
+
cwd,
|
|
25
|
+
encoding: 'utf-8',
|
|
26
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
27
|
+
}).trim();
|
|
28
|
+
files = gitOutput.split('\n').filter((f) => f.length > 0);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Fallback: scan all TS/JS files in src
|
|
32
|
+
console.error('Could not determine changed files from git. Scanning all source files.');
|
|
33
|
+
files = [];
|
|
34
|
+
}
|
|
35
|
+
if (files.length === 0) {
|
|
36
|
+
console.log('No changed files detected. Nothing to fix.');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// Run review intelligence to find fixable issues
|
|
40
|
+
const result = runReviewIntelligence({
|
|
41
|
+
cwd,
|
|
42
|
+
files,
|
|
43
|
+
policy: DEFAULT_REVIEW_INTELLIGENCE_POLICY,
|
|
44
|
+
explain: false,
|
|
45
|
+
debug: false,
|
|
46
|
+
});
|
|
47
|
+
// Filter to fixable findings
|
|
48
|
+
let fixableFindings = result.findings.filter(isFixable);
|
|
49
|
+
if (ruleFilter) {
|
|
50
|
+
fixableFindings = fixableFindings.filter((f) => f.rule_id === ruleFilter);
|
|
51
|
+
}
|
|
52
|
+
if (fixableFindings.length === 0) {
|
|
53
|
+
console.log('No auto-fixable findings detected.');
|
|
54
|
+
if (result.findings.length > 0) {
|
|
55
|
+
console.log(`(${result.findings.length} finding(s) require manual fix)`);
|
|
56
|
+
console.log(`Auto-fixable rules: ${getFixableRuleIds().join(', ')}`);
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
console.log(`Found ${fixableFindings.length} auto-fixable finding(s)`);
|
|
61
|
+
if (dryRun) {
|
|
62
|
+
console.log('');
|
|
63
|
+
console.log('Dry run — changes will NOT be applied:');
|
|
64
|
+
for (const f of fixableFindings) {
|
|
65
|
+
console.log(` [${f.severity}] ${f.rule_id} — ${f.file}:${f.line} — ${f.title}`);
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Group findings by file
|
|
70
|
+
const findingsByFile = new Map();
|
|
71
|
+
for (const f of fixableFindings) {
|
|
72
|
+
const existing = findingsByFile.get(f.file);
|
|
73
|
+
if (existing) {
|
|
74
|
+
existing.push(f);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
findingsByFile.set(f.file, [f]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Apply fixes per file
|
|
81
|
+
let totalApplied = 0;
|
|
82
|
+
for (const [filePath, fileFindings] of findingsByFile) {
|
|
83
|
+
const fullPath = join(cwd, filePath);
|
|
84
|
+
let content;
|
|
85
|
+
try {
|
|
86
|
+
content = readFileSync(fullPath, 'utf-8');
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
console.error(` Could not read ${filePath}, skipping.`);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const { newContent, applied } = applyAllFixes(fileFindings, content);
|
|
93
|
+
if (applied.length > 0) {
|
|
94
|
+
writeFileSync(fullPath, newContent);
|
|
95
|
+
for (const fix of applied) {
|
|
96
|
+
console.log(` Fixed: ${fix.rule_id} in ${fix.file} — ${fix.description}`);
|
|
97
|
+
}
|
|
98
|
+
totalApplied += applied.length;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
console.log('');
|
|
102
|
+
console.log(`Applied ${totalApplied} fix(es) across ${findingsByFile.size} file(s).`);
|
|
103
|
+
if (totalApplied > 0) {
|
|
104
|
+
console.log('Review the changes and commit when ready.');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codeledger graph [--json] [--save]`
|
|
3
|
+
*
|
|
4
|
+
* Build and display the architecture graph showing service relationships,
|
|
5
|
+
* package dependencies, circular dependencies, and boundary violations.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runGraph(cwd: string, flags: Record<string, string>): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/commands/graph.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { buildArchitectureGraph, formatGraphOutput, formatGraphJson, } from '../architecture-graph/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* `codeledger graph [--json] [--save]`
|
|
6
|
+
*
|
|
7
|
+
* Build and display the architecture graph showing service relationships,
|
|
8
|
+
* package dependencies, circular dependencies, and boundary violations.
|
|
9
|
+
*/
|
|
10
|
+
export async function runGraph(cwd, flags) {
|
|
11
|
+
const jsonOutput = flags['json'] === 'true';
|
|
12
|
+
const shouldSave = flags['save'] === 'true';
|
|
13
|
+
console.log('Building architecture graph...');
|
|
14
|
+
const graph = buildArchitectureGraph(cwd);
|
|
15
|
+
if (jsonOutput) {
|
|
16
|
+
console.log(formatGraphJson(graph));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.log(formatGraphOutput(graph));
|
|
20
|
+
}
|
|
21
|
+
if (shouldSave) {
|
|
22
|
+
const outputDir = join(cwd, '.codeledger');
|
|
23
|
+
mkdirSync(outputDir, { recursive: true });
|
|
24
|
+
const outputPath = join(outputDir, 'architecture-graph.json');
|
|
25
|
+
writeFileSync(outputPath, formatGraphJson(graph) + '\n');
|
|
26
|
+
console.log(`Graph saved to: ${outputPath}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/commands/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,GAChB,MAAM,gCAAgC,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAW,EACX,KAA6B;IAE7B,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC;IAE5C,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,MAAM,KAAK,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAE1C,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC3C,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAC;QAC9D,aAAa,CAAC,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codeledger learn [--save] [--enable]`
|
|
3
|
+
*
|
|
4
|
+
* Analyze repository usage patterns and discover canonical conventions.
|
|
5
|
+
* Optionally save and enable the generated invariant pack.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runLearn(cwd: string, flags: Record<string, string>): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=learn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learn.d.ts","sourceRoot":"","sources":["../../src/commands/learn.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { learnConventions, formatLearnOutput } from '../review-intelligence/learning/index.js';
|
|
2
|
+
import { addPack, saveGeneratedPack } from '../review-intelligence/packs/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* `codeledger learn [--save] [--enable]`
|
|
5
|
+
*
|
|
6
|
+
* Analyze repository usage patterns and discover canonical conventions.
|
|
7
|
+
* Optionally save and enable the generated invariant pack.
|
|
8
|
+
*/
|
|
9
|
+
export async function runLearn(cwd, flags) {
|
|
10
|
+
const shouldSave = flags['save'] === 'true';
|
|
11
|
+
const shouldEnable = flags['enable'] === 'true';
|
|
12
|
+
const jsonOutput = flags['json'] === 'true';
|
|
13
|
+
console.log('Analyzing repository conventions...');
|
|
14
|
+
const result = learnConventions(cwd);
|
|
15
|
+
if (jsonOutput) {
|
|
16
|
+
console.log(JSON.stringify(result, null, 2));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
console.log(formatLearnOutput(result));
|
|
20
|
+
if (result.suggestedPack && (shouldSave || shouldEnable)) {
|
|
21
|
+
const packPath = saveGeneratedPack(cwd, result.suggestedPack);
|
|
22
|
+
console.log(`Pack saved to: ${packPath}`);
|
|
23
|
+
if (shouldEnable) {
|
|
24
|
+
addPack(cwd, { ...result.suggestedPack, enabled: true });
|
|
25
|
+
console.log('Pack enabled in registry.');
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
addPack(cwd, result.suggestedPack);
|
|
29
|
+
console.log('Pack added to registry (disabled). Run `codeledger pack enable learned-conventions` to activate.');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=learn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learn.js","sourceRoot":"","sources":["../../src/commands/learn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC/F,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAW,EACX,KAA6B;IAE7B,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC;IAC5C,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC;IAChD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC;IAE5C,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAErC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;IAEvC,IAAI,MAAM,CAAC,aAAa,IAAI,CAAC,UAAU,IAAI,YAAY,CAAC,EAAE,CAAC;QACzD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,EAAE,CAAC,CAAC;QAE1C,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,kGAAkG,CAAC,CAAC;QAClH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codeledger pack <subcommand>`
|
|
3
|
+
*
|
|
4
|
+
* Manage invariant packs.
|
|
5
|
+
*
|
|
6
|
+
* Subcommands:
|
|
7
|
+
* list List all available packs and their status
|
|
8
|
+
* enable <name> Enable a pack
|
|
9
|
+
* disable <name> Disable a pack
|
|
10
|
+
*/
|
|
11
|
+
export declare function runPack(cwd: string, flags: Record<string, string>): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/commands/pack.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAmEf"}
|