@erode-app/core 0.6.0-beta.0 → 0.7.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/README.md +19 -0
- package/dist/adapters/architecture-adapter.d.ts +2 -6
- package/dist/adapters/architecture-adapter.d.ts.map +1 -1
- package/dist/adapters/architecture-types.d.ts +12 -0
- package/dist/adapters/architecture-types.d.ts.map +1 -1
- package/dist/adapters/base-patcher.d.ts +2 -9
- package/dist/adapters/base-patcher.d.ts.map +1 -1
- package/dist/adapters/base-patcher.js +0 -7
- package/dist/adapters/base-patcher.js.map +1 -1
- package/dist/adapters/likec4/adapter.d.ts +2 -6
- package/dist/adapters/likec4/adapter.d.ts.map +1 -1
- package/dist/adapters/likec4/adapter.js.map +1 -1
- package/dist/adapters/model-patcher.d.ts +22 -21
- package/dist/adapters/model-patcher.d.ts.map +1 -1
- package/dist/adapters/model-patcher.js.map +1 -1
- package/dist/adapters/structurizr/adapter.d.ts +2 -6
- package/dist/adapters/structurizr/adapter.d.ts.map +1 -1
- package/dist/adapters/structurizr/adapter.js +0 -10
- package/dist/adapters/structurizr/adapter.js.map +1 -1
- package/dist/adapters/structurizr/patcher.d.ts.map +1 -1
- package/dist/adapters/structurizr/patcher.js +0 -3
- package/dist/adapters/structurizr/patcher.js.map +1 -1
- package/dist/analysis/analysis-types.d.ts +32 -53
- package/dist/analysis/analysis-types.d.ts.map +1 -1
- package/dist/analysis/prompt-builder.js +1 -1
- package/dist/analysis/prompt-builder.js.map +1 -1
- package/dist/analysis/prompt-variables.d.ts +4 -8
- package/dist/analysis/prompt-variables.d.ts.map +1 -1
- package/dist/analysis/section-formatters.d.ts +5 -17
- package/dist/analysis/section-formatters.d.ts.map +1 -1
- package/dist/analysis/section-formatters.js.map +1 -1
- package/dist/ci-entry.js +2 -2
- package/dist/ci-entry.js.map +1 -1
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/output/structured-output.d.ts +4 -11
- package/dist/output/structured-output.d.ts.map +1 -1
- package/dist/output.d.ts +9 -33
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js.map +1 -1
- package/dist/pipelines/analyze.d.ts.map +1 -1
- package/dist/pipelines/analyze.js +29 -112
- package/dist/pipelines/analyze.js.map +1 -1
- package/dist/pipelines/check.d.ts +7 -9
- package/dist/pipelines/check.d.ts.map +1 -1
- package/dist/pipelines/check.js +122 -175
- package/dist/pipelines/check.js.map +1 -1
- package/dist/pipelines/connections.d.ts +6 -14
- package/dist/pipelines/connections.d.ts.map +1 -1
- package/dist/pipelines/connections.js.map +1 -1
- package/dist/pipelines/pipeline-shared.d.ts +57 -0
- package/dist/pipelines/pipeline-shared.d.ts.map +1 -0
- package/dist/pipelines/pipeline-shared.js +117 -0
- package/dist/pipelines/pipeline-shared.js.map +1 -0
- package/dist/pipelines/publish.d.ts +4 -12
- package/dist/pipelines/publish.d.ts.map +1 -1
- package/dist/pipelines/publish.js.map +1 -1
- package/dist/platforms/bitbucket/writer.d.ts.map +1 -1
- package/dist/platforms/bitbucket/writer.js +0 -5
- package/dist/platforms/bitbucket/writer.js.map +1 -1
- package/dist/platforms/source-platform.d.ts +11 -12
- package/dist/platforms/source-platform.d.ts.map +1 -1
- package/dist/providers/anthropic/provider.d.ts +2 -6
- package/dist/providers/anthropic/provider.d.ts.map +1 -1
- package/dist/providers/anthropic/provider.js +0 -1
- package/dist/providers/anthropic/provider.js.map +1 -1
- package/dist/providers/base-provider.d.ts +5 -0
- package/dist/providers/base-provider.d.ts.map +1 -1
- package/dist/providers/base-provider.js.map +1 -1
- package/dist/providers/gemini/models.d.ts +1 -1
- package/dist/providers/gemini/models.js +1 -1
- package/dist/providers/gemini/models.js.map +1 -1
- package/dist/providers/gemini/provider.d.ts +2 -6
- package/dist/providers/gemini/provider.d.ts.map +1 -1
- package/dist/providers/gemini/provider.js.map +1 -1
- package/dist/providers/openai/provider.d.ts +2 -6
- package/dist/providers/openai/provider.d.ts.map +1 -1
- package/dist/providers/openai/provider.js.map +1 -1
- package/dist/utils/config.d.ts +5 -2
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +21 -8
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/git-diff.d.ts +28 -13
- package/dist/utils/git-diff.d.ts.map +1 -1
- package/dist/utils/git-diff.js +97 -13
- package/dist/utils/git-diff.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +0 -1
- package/dist/utils/validation.js.map +1 -1
- package/package.json +6 -4
package/dist/pipelines/check.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { SilentProgress } from './progress.js';
|
|
2
3
|
import { createAdapter } from '../adapters/adapter-factory.js';
|
|
3
4
|
import { createAIProvider } from '../providers/provider-factory.js';
|
|
4
|
-
import { validatePath } from '../utils/validation.js';
|
|
5
5
|
import { loadSkipPatterns, applySkipPatterns } from '../utils/skip-patterns.js';
|
|
6
6
|
import { ErodeError, ErrorCode } from '../errors.js';
|
|
7
7
|
import { CONFIG } from '../utils/config.js';
|
|
8
8
|
import { buildStructuredOutput } from '../output.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
9
|
+
import { parseFilesFromDiff, filterDiffByFiles } from '../utils/git-diff.js';
|
|
10
|
+
import { loadArchitectureModel, buildArchitecturalContext, runDriftStage, selectComponentWithAI, resolveAndCloneModel, findComponentsForRepo, } from './pipeline-shared.js';
|
|
11
|
+
const CheckOptionsInputSchema = z.object({
|
|
12
|
+
modelPath: z.string().min(1),
|
|
13
|
+
diff: z.string(),
|
|
14
|
+
repo: z.string().min(1),
|
|
15
|
+
repoOwner: z.string().min(1),
|
|
16
|
+
repoName: z.string().min(1),
|
|
17
|
+
modelFormat: z.string().optional(),
|
|
18
|
+
componentId: z.string().optional(),
|
|
19
|
+
format: z.enum(['console', 'json']).optional(),
|
|
20
|
+
files: z.array(z.object({ filename: z.string(), status: z.string() })).optional(),
|
|
21
|
+
stats: z
|
|
22
|
+
.object({
|
|
23
|
+
additions: z.number(),
|
|
24
|
+
deletions: z.number(),
|
|
25
|
+
filesChanged: z.number(),
|
|
26
|
+
})
|
|
27
|
+
.optional(),
|
|
28
|
+
skipFileFiltering: z.boolean().optional(),
|
|
29
|
+
modelRepo: z.string().optional(),
|
|
30
|
+
modelRef: z.string().optional(),
|
|
31
|
+
});
|
|
32
32
|
/**
|
|
33
33
|
* Run a local architecture drift check against a git diff.
|
|
34
34
|
*
|
|
@@ -37,169 +37,116 @@ function parseFilesFromDiff(diff) {
|
|
|
37
37
|
* a raw diff string instead of fetching PR data from a platform API.
|
|
38
38
|
*/
|
|
39
39
|
export async function runCheck(options, progress) {
|
|
40
|
+
CheckOptionsInputSchema.parse(options);
|
|
40
41
|
const p = progress ?? new SilentProgress();
|
|
41
42
|
const adapter = createAdapter(options.modelFormat);
|
|
42
|
-
// ──
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
p.
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
// ── Resolve model source (clone if remote) ───────────────────────────
|
|
44
|
+
const resolvedSource = await resolveAndCloneModel(options.modelPath, options.modelRepo, { ref: options.modelRef }, p);
|
|
45
|
+
const effectiveModelPath = resolvedSource.localPath;
|
|
46
|
+
try {
|
|
47
|
+
// ── Load architecture model ──────────────────────────────────────────
|
|
48
|
+
const architectureModel = await loadArchitectureModel(adapter, effectiveModelPath, p);
|
|
49
|
+
// ── Find components for this repository ──────────────────────────────
|
|
50
|
+
const lookup = findComponentsForRepo(adapter, options.repo, buildLocalMetadata(options), p);
|
|
51
|
+
if (!('found' in lookup))
|
|
52
|
+
return lookup;
|
|
53
|
+
const { components, defaultComponent } = lookup;
|
|
54
|
+
// ── Initialise AI provider ───────────────────────────────────────────
|
|
55
|
+
p.start('Setting up AI provider');
|
|
56
|
+
const provider = createAIProvider();
|
|
57
|
+
p.succeed('AI provider initialized');
|
|
58
|
+
// ── Resolve files from diff ──────────────────────────────────────────
|
|
59
|
+
let files = options.files ?? parseFilesFromDiff(options.diff);
|
|
60
|
+
// ── File filtering ───────────────────────────────────────────────────
|
|
61
|
+
if (!options.skipFileFiltering) {
|
|
62
|
+
const patterns = loadSkipPatterns();
|
|
63
|
+
const asChangeRequestFiles = files.map((f) => ({
|
|
64
|
+
filename: f.filename,
|
|
65
|
+
status: f.status,
|
|
66
|
+
additions: 0,
|
|
67
|
+
deletions: 0,
|
|
68
|
+
changes: 0,
|
|
69
|
+
}));
|
|
70
|
+
const { included, excluded } = applySkipPatterns(asChangeRequestFiles, patterns);
|
|
71
|
+
if (excluded > 0) {
|
|
72
|
+
files = included.map((f) => ({ filename: f.filename, status: f.status }));
|
|
73
|
+
p.info(`Excluded ${String(excluded)} file(s) matching skip patterns`);
|
|
74
|
+
}
|
|
59
75
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
p.succeed(`Located ${String(components.length)} component(s) for repository`);
|
|
74
|
-
const defaultComponent = components[0];
|
|
75
|
-
if (!defaultComponent) {
|
|
76
|
-
throw new ErodeError('Unexpected: components array was non-empty but first element was undefined', ErrorCode.INTERNAL_UNKNOWN, 'Internal pipeline error');
|
|
77
|
-
}
|
|
78
|
-
// ── Resolve files from diff ──────────────────────────────────────────
|
|
79
|
-
let files = options.files ?? parseFilesFromDiff(options.diff);
|
|
80
|
-
// ── File filtering ───────────────────────────────────────────────────
|
|
81
|
-
if (!options.skipFileFiltering) {
|
|
82
|
-
const patterns = loadSkipPatterns();
|
|
83
|
-
const asChangeRequestFiles = files.map((f) => ({
|
|
84
|
-
filename: f.filename,
|
|
85
|
-
status: f.status,
|
|
86
|
-
additions: 0,
|
|
87
|
-
deletions: 0,
|
|
88
|
-
changes: 0,
|
|
89
|
-
}));
|
|
90
|
-
const { included, excluded } = applySkipPatterns(asChangeRequestFiles, patterns);
|
|
91
|
-
if (excluded > 0) {
|
|
92
|
-
files = included.map((f) => ({ filename: f.filename, status: f.status }));
|
|
93
|
-
p.info(`Excluded ${String(excluded)} file(s) matching skip patterns`);
|
|
76
|
+
// ── Filter diff to match included files ────────────────────────────
|
|
77
|
+
const effectiveDiff = !options.skipFileFiltering && files.length > 0
|
|
78
|
+
? filterDiffByFiles(options.diff, files)
|
|
79
|
+
: options.diff;
|
|
80
|
+
// ── Stage 1: Component selection ─────────────────────────────────────
|
|
81
|
+
let selectedComponent = defaultComponent;
|
|
82
|
+
let candidateComponents;
|
|
83
|
+
if (options.componentId) {
|
|
84
|
+
const found = adapter.findComponentById(options.componentId);
|
|
85
|
+
if (!found) {
|
|
86
|
+
throw new ErodeError(`Component not found: ${options.componentId}`, ErrorCode.MODEL_COMPONENT_MISSING, `No component with ID "${options.componentId}" exists in the architecture model.`);
|
|
87
|
+
}
|
|
88
|
+
selectedComponent = found;
|
|
94
89
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
let candidateComponents;
|
|
100
|
-
if (options.componentId) {
|
|
101
|
-
const found = adapter.findComponentById(options.componentId);
|
|
102
|
-
if (!found) {
|
|
103
|
-
throw new ErodeError(`Component not found: ${options.componentId}`, ErrorCode.MODEL_COMPONENT_MISSING, `No component with ID "${options.componentId}" exists in the architecture model.`);
|
|
90
|
+
else if (components.length > 1) {
|
|
91
|
+
candidateComponents = components.map((c) => ({ id: c.id, name: c.name, type: c.type }));
|
|
92
|
+
p.section('Stage 1: Component Selection');
|
|
93
|
+
selectedComponent = await selectComponentWithAI(provider, components, files.map((f) => ({ filename: f.filename })), defaultComponent, p);
|
|
104
94
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
95
|
+
const selectedComponentId = selectedComponent.id;
|
|
96
|
+
// ── Stage 2: Dependency extraction ───────────────────────────────────
|
|
97
|
+
p.section('Stage 2: Extract Dependencies');
|
|
98
|
+
p.start('Scanning diff for dependencies');
|
|
99
|
+
const extractedDeps = await provider.extractDependencies({
|
|
100
|
+
diff: effectiveDiff,
|
|
101
|
+
commit: {
|
|
102
|
+
sha: 'local',
|
|
103
|
+
message: 'Local changes',
|
|
104
|
+
author: 'local',
|
|
105
|
+
},
|
|
106
|
+
repository: {
|
|
107
|
+
owner: options.repoOwner,
|
|
108
|
+
repo: options.repoName,
|
|
109
|
+
url: options.repo,
|
|
110
|
+
},
|
|
111
|
+
components: [selectedComponent],
|
|
112
|
+
});
|
|
113
|
+
p.succeed(`Found ${String(extractedDeps.dependencies.length)} dependency change(s)`);
|
|
114
|
+
if (CONFIG.debug.verbose) {
|
|
115
|
+
console.error('[Stage 2] Extracted dependencies:', JSON.stringify(extractedDeps));
|
|
117
116
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
// ── Stage 2: Dependency extraction ───────────────────────────────────
|
|
134
|
-
p.section('Stage 2: Extract Dependencies');
|
|
135
|
-
p.start('Scanning diff for dependencies');
|
|
136
|
-
const extractedDeps = await provider.extractDependencies({
|
|
137
|
-
diff: options.diff,
|
|
138
|
-
commit: {
|
|
139
|
-
sha: 'local',
|
|
140
|
-
message: 'Local changes',
|
|
141
|
-
author: 'local',
|
|
142
|
-
},
|
|
143
|
-
repository: {
|
|
144
|
-
owner: options.repoOwner,
|
|
145
|
-
repo: options.repoName,
|
|
146
|
-
url: options.repo,
|
|
147
|
-
},
|
|
148
|
-
components: [selectedComponent],
|
|
149
|
-
});
|
|
150
|
-
p.succeed(`Found ${String(extractedDeps.dependencies.length)} dependency change(s)`);
|
|
151
|
-
if (CONFIG.debug.verbose) {
|
|
152
|
-
console.error('[Stage 2] Extracted dependencies:', JSON.stringify(extractedDeps));
|
|
153
|
-
}
|
|
154
|
-
// ── Build prompt data for drift analysis ─────────────────────────────
|
|
155
|
-
const dependencies = adapter.getComponentDependencies(selectedComponent.id);
|
|
156
|
-
const dependents = adapter.getComponentDependents(selectedComponent.id);
|
|
157
|
-
const relationships = adapter.getComponentRelationships(selectedComponent.id);
|
|
158
|
-
const promptData = {
|
|
159
|
-
changeRequest: buildLocalMetadata(options),
|
|
160
|
-
component: selectedComponent,
|
|
161
|
-
dependencies: extractedDeps,
|
|
162
|
-
files,
|
|
163
|
-
architectural: {
|
|
164
|
-
dependencies: dependencies.map((d) => ({ ...d, repository: d.repository })),
|
|
165
|
-
dependents: dependents.map((d) => ({ ...d, repository: d.repository })),
|
|
166
|
-
relationships: relationships.map((r) => ({
|
|
167
|
-
target: { id: r.target.id, name: r.target.name },
|
|
168
|
-
kind: r.kind,
|
|
169
|
-
title: r.title,
|
|
170
|
-
})),
|
|
171
|
-
},
|
|
172
|
-
allComponentIds: Array.from(architectureModel.componentIndex.byId.keys()),
|
|
173
|
-
allRelationships: adapter.getAllRelationships(),
|
|
174
|
-
};
|
|
175
|
-
// ── Stage 3: Drift analysis ──────────────────────────────────────────
|
|
176
|
-
p.section('Stage 3: Drift Analysis');
|
|
177
|
-
p.start('Evaluating changes for architectural drift');
|
|
178
|
-
const analysisResult = await provider.analyzeDrift(promptData);
|
|
179
|
-
p.succeed('Drift analysis finished');
|
|
180
|
-
if (CONFIG.debug.verbose) {
|
|
181
|
-
console.error('[Stage 3] Drift analysis:', JSON.stringify({
|
|
182
|
-
violations: analysisResult.violations.length,
|
|
183
|
-
hasModelUpdates: !!analysisResult.modelUpdates?.relationships?.length,
|
|
184
|
-
}));
|
|
185
|
-
}
|
|
186
|
-
// ── Build structured output ──────────────────────────────────────────
|
|
187
|
-
const needsStructured = options.format === 'json';
|
|
188
|
-
const structured = needsStructured
|
|
189
|
-
? buildStructuredOutput(analysisResult, adapter.metadata.displayName, {
|
|
117
|
+
// ── Build prompt data for drift analysis ─────────────────────────────
|
|
118
|
+
const architectural = buildArchitecturalContext(adapter, selectedComponent.id);
|
|
119
|
+
const promptData = {
|
|
120
|
+
changeRequest: buildLocalMetadata(options),
|
|
121
|
+
component: selectedComponent,
|
|
122
|
+
dependencies: extractedDeps,
|
|
123
|
+
files,
|
|
124
|
+
architectural,
|
|
125
|
+
allComponentIds: Array.from(architectureModel.componentIndex.byId.keys()),
|
|
126
|
+
allRelationships: adapter.getAllRelationships(),
|
|
127
|
+
};
|
|
128
|
+
// ── Stage 3: Drift Analysis ──────────────────────────────────────────
|
|
129
|
+
const analysisResult = await runDriftStage(provider, promptData, p);
|
|
130
|
+
// ── Build structured output ──────────────────────────────────────────
|
|
131
|
+
const structured = buildStructuredOutput(analysisResult, adapter.metadata.displayName, {
|
|
190
132
|
selectedComponentId,
|
|
191
133
|
candidateComponents,
|
|
192
|
-
})
|
|
193
|
-
:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
134
|
+
});
|
|
135
|
+
// Stage 4 (model patching) and publishing are intentionally omitted: check is a read-only local operation.
|
|
136
|
+
return {
|
|
137
|
+
analysisResult,
|
|
138
|
+
structured,
|
|
139
|
+
hasViolations: analysisResult.hasViolations,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
await resolvedSource.cleanup();
|
|
144
|
+
}
|
|
199
145
|
}
|
|
200
146
|
function buildLocalMetadata(options) {
|
|
201
147
|
return {
|
|
202
148
|
number: 0,
|
|
149
|
+
source: 'local',
|
|
203
150
|
title: 'Local changes',
|
|
204
151
|
description: null,
|
|
205
152
|
repository: `${options.repoOwner}/${options.repoName}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/pipelines/check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/pipelines/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,28 +1,20 @@
|
|
|
1
1
|
import type { ProgressReporter } from './progress.js';
|
|
2
|
+
import type { ComponentSummary } from '../adapters/architecture-types.js';
|
|
2
3
|
export interface ConnectionsOptions {
|
|
3
4
|
modelPath: string;
|
|
4
5
|
modelFormat?: string;
|
|
5
6
|
repo: string;
|
|
6
7
|
}
|
|
7
8
|
export interface ComponentConnections {
|
|
8
|
-
component: {
|
|
9
|
-
id: string;
|
|
10
|
-
name: string;
|
|
11
|
-
type: string;
|
|
9
|
+
component: ComponentSummary & {
|
|
12
10
|
repository?: string;
|
|
13
11
|
};
|
|
14
|
-
dependencies: {
|
|
15
|
-
id: string;
|
|
16
|
-
name: string;
|
|
17
|
-
type: string;
|
|
12
|
+
dependencies: (ComponentSummary & {
|
|
18
13
|
repository?: string;
|
|
19
|
-
}[];
|
|
20
|
-
dependents: {
|
|
21
|
-
id: string;
|
|
22
|
-
name: string;
|
|
23
|
-
type: string;
|
|
14
|
+
})[];
|
|
15
|
+
dependents: (ComponentSummary & {
|
|
24
16
|
repository?: string;
|
|
25
|
-
}[];
|
|
17
|
+
})[];
|
|
26
18
|
relationships: {
|
|
27
19
|
targetId: string;
|
|
28
20
|
targetName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../src/pipelines/connections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../src/pipelines/connections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAG1E,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,gBAAgB,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,YAAY,EAAE,CAAC,gBAAgB,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAC7D,UAAU,EAAE,CAAC,gBAAgB,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAC3D,aAAa,EAAE;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,EAAE,CAAC;CACL;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAqDjC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../../src/pipelines/connections.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../../src/pipelines/connections.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ArchitectureModelAdapter } from '../adapters/architecture-adapter.js';
|
|
2
|
+
import type { ArchitecturalComponent, ArchitectureModel } from '../adapters/architecture-types.js';
|
|
3
|
+
import type { ComponentRelationshipRef } from '../analysis/analysis-types.js';
|
|
4
|
+
import type { AIProvider } from '../providers/ai-provider.js';
|
|
5
|
+
import type { DriftAnalysisPromptData, DriftAnalysisResult, ChangeRequestMetadata } from '../analysis/analysis-types.js';
|
|
6
|
+
import type { StructuredAnalysisOutput } from '../output/structured-output.js';
|
|
7
|
+
import type { ProgressReporter } from './progress.js';
|
|
8
|
+
import { type ResolvedModelSource } from '../utils/model-source.js';
|
|
9
|
+
/** Load and validate an architecture model, emitting progress. */
|
|
10
|
+
export declare function loadArchitectureModel(adapter: ArchitectureModelAdapter, modelPath: string, progress: ProgressReporter): Promise<ArchitectureModel>;
|
|
11
|
+
export interface ArchitecturalContext {
|
|
12
|
+
dependencies: (ArchitecturalComponent & {
|
|
13
|
+
repository?: string;
|
|
14
|
+
})[];
|
|
15
|
+
dependents: (ArchitecturalComponent & {
|
|
16
|
+
repository?: string;
|
|
17
|
+
})[];
|
|
18
|
+
relationships: ComponentRelationshipRef[];
|
|
19
|
+
}
|
|
20
|
+
/** Build architectural context (dependencies, dependents, relationships) for a component. */
|
|
21
|
+
export declare function buildArchitecturalContext(adapter: ArchitectureModelAdapter, componentId: string): ArchitecturalContext;
|
|
22
|
+
export interface EmptyResultOptions {
|
|
23
|
+
metadata: ChangeRequestMetadata;
|
|
24
|
+
repoUrl: string;
|
|
25
|
+
adapterDisplayName: string;
|
|
26
|
+
includeStructured?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface EmptyCheckResult {
|
|
29
|
+
analysisResult: DriftAnalysisResult;
|
|
30
|
+
structured?: StructuredAnalysisOutput;
|
|
31
|
+
hasViolations: false;
|
|
32
|
+
}
|
|
33
|
+
/** Build an empty "no components matched" result. */
|
|
34
|
+
export declare function buildEmptyResult(options: EmptyResultOptions): EmptyCheckResult;
|
|
35
|
+
/** Run Stage 3: Drift analysis with progress and verbose logging. */
|
|
36
|
+
export declare function runDriftStage(provider: AIProvider, promptData: DriftAnalysisPromptData, progress: ProgressReporter): Promise<DriftAnalysisResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Use AI to select the best-matching component when multiple candidates exist.
|
|
39
|
+
* Returns the selected component, falling back to `defaultComponent` if the
|
|
40
|
+
* provider lacks the capability or the model returns no result.
|
|
41
|
+
*/
|
|
42
|
+
export declare function selectComponentWithAI(provider: AIProvider, components: ArchitecturalComponent[], files: {
|
|
43
|
+
filename: string;
|
|
44
|
+
}[], defaultComponent: ArchitecturalComponent, progress: ProgressReporter): Promise<ArchitecturalComponent>;
|
|
45
|
+
/** Resolve model source, cloning if remote, with progress messages. */
|
|
46
|
+
export declare function resolveAndCloneModel(modelPath: string, modelRepo: string | undefined, options: {
|
|
47
|
+
ref?: string;
|
|
48
|
+
}, progress: ProgressReporter): Promise<ResolvedModelSource>;
|
|
49
|
+
/** Look up components for a repository, returning an empty result if none match. */
|
|
50
|
+
export declare function findComponentsForRepo(adapter: ArchitectureModelAdapter, repoUrl: string, metadata: ChangeRequestMetadata, progress: ProgressReporter): ComponentLookupResult;
|
|
51
|
+
type ComponentLookupResult = {
|
|
52
|
+
found: true;
|
|
53
|
+
components: ArchitecturalComponent[];
|
|
54
|
+
defaultComponent: ArchitecturalComponent;
|
|
55
|
+
} | EmptyCheckResult;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=pipeline-shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-shared.d.ts","sourceRoot":"","sources":["../../src/pipelines/pipeline-shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { validatePath } from '../utils/validation.js';
|
|
2
|
+
import { buildStructuredOutput } from '../output.js';
|
|
3
|
+
import { CONFIG } from '../utils/config.js';
|
|
4
|
+
import { ErodeError, ErrorCode } from '../errors.js';
|
|
5
|
+
import { resolveModelSource } from '../utils/model-source.js';
|
|
6
|
+
/** Load and validate an architecture model, emitting progress. */
|
|
7
|
+
export async function loadArchitectureModel(adapter, modelPath, progress) {
|
|
8
|
+
progress.section(`Preparing ${adapter.metadata.displayName} Architecture Model`);
|
|
9
|
+
validatePath(modelPath, 'directory');
|
|
10
|
+
progress.start('Reading architecture model');
|
|
11
|
+
const model = await adapter.loadFromPath(modelPath);
|
|
12
|
+
progress.succeed('Architecture model ready');
|
|
13
|
+
return model;
|
|
14
|
+
}
|
|
15
|
+
/** Build architectural context (dependencies, dependents, relationships) for a component. */
|
|
16
|
+
export function buildArchitecturalContext(adapter, componentId) {
|
|
17
|
+
const dependencies = adapter.getComponentDependencies(componentId);
|
|
18
|
+
const dependents = adapter.getComponentDependents(componentId);
|
|
19
|
+
const relationships = adapter.getComponentRelationships(componentId);
|
|
20
|
+
return {
|
|
21
|
+
dependencies: dependencies.map((d) => ({ ...d, repository: d.repository })),
|
|
22
|
+
dependents: dependents.map((d) => ({ ...d, repository: d.repository })),
|
|
23
|
+
relationships: relationships.map((r) => ({
|
|
24
|
+
target: { id: r.target.id, name: r.target.name },
|
|
25
|
+
kind: r.kind,
|
|
26
|
+
title: r.title,
|
|
27
|
+
})),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Build an empty "no components matched" result. */
|
|
31
|
+
export function buildEmptyResult(options) {
|
|
32
|
+
const emptyResult = {
|
|
33
|
+
hasViolations: false,
|
|
34
|
+
violations: [],
|
|
35
|
+
summary: `No components found matching repository: ${options.repoUrl}`,
|
|
36
|
+
metadata: options.metadata,
|
|
37
|
+
component: { id: '', name: '', tags: [], type: '' },
|
|
38
|
+
dependencyChanges: { dependencies: [], summary: '' },
|
|
39
|
+
};
|
|
40
|
+
const structured = options.includeStructured
|
|
41
|
+
? buildStructuredOutput(emptyResult, options.adapterDisplayName)
|
|
42
|
+
: undefined;
|
|
43
|
+
return { analysisResult: emptyResult, structured, hasViolations: false };
|
|
44
|
+
}
|
|
45
|
+
/** Run Stage 3: Drift analysis with progress and verbose logging. */
|
|
46
|
+
export async function runDriftStage(provider, promptData, progress) {
|
|
47
|
+
progress.section('Stage 3: Drift Analysis');
|
|
48
|
+
progress.start('Evaluating changes for architectural drift');
|
|
49
|
+
const analysisResult = await provider.analyzeDrift(promptData);
|
|
50
|
+
progress.succeed('Drift analysis finished');
|
|
51
|
+
if (CONFIG.debug.verbose) {
|
|
52
|
+
console.error('[Stage 3] Drift analysis:', JSON.stringify({
|
|
53
|
+
violations: analysisResult.violations.length,
|
|
54
|
+
hasModelUpdates: !!analysisResult.modelUpdates?.relationships?.length,
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
return analysisResult;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Use AI to select the best-matching component when multiple candidates exist.
|
|
61
|
+
* Returns the selected component, falling back to `defaultComponent` if the
|
|
62
|
+
* provider lacks the capability or the model returns no result.
|
|
63
|
+
*/
|
|
64
|
+
export async function selectComponentWithAI(provider, components, files, defaultComponent, progress) {
|
|
65
|
+
progress.start('Asking the model to pick the best-matching component');
|
|
66
|
+
if (!provider.selectComponent) {
|
|
67
|
+
progress.warn(`Provider lacks component selection, defaulting to: ${defaultComponent.name}`);
|
|
68
|
+
return defaultComponent;
|
|
69
|
+
}
|
|
70
|
+
const componentId = await provider.selectComponent({ components, files });
|
|
71
|
+
if (componentId) {
|
|
72
|
+
const found = components.find((c) => c.id === componentId) ?? defaultComponent;
|
|
73
|
+
progress.succeed(`Chosen component: ${found.name} (${componentId})`);
|
|
74
|
+
return found;
|
|
75
|
+
}
|
|
76
|
+
progress.warn(`AI was unable to pick a component, defaulting to: ${defaultComponent.name}`);
|
|
77
|
+
return defaultComponent;
|
|
78
|
+
}
|
|
79
|
+
/** Resolve model source, cloning if remote, with progress messages. */
|
|
80
|
+
export async function resolveAndCloneModel(modelPath, modelRepo, options, progress) {
|
|
81
|
+
if (modelRepo) {
|
|
82
|
+
progress.start('Cloning model repository');
|
|
83
|
+
}
|
|
84
|
+
const resolvedSource = await resolveModelSource(modelPath, modelRepo, options);
|
|
85
|
+
if (modelRepo) {
|
|
86
|
+
progress.succeed(`Model repository cloned (${resolvedSource.repoSlug ?? modelRepo})`);
|
|
87
|
+
}
|
|
88
|
+
return resolvedSource;
|
|
89
|
+
}
|
|
90
|
+
/** TS strict guard: extract the first element of a non-empty components array. */
|
|
91
|
+
function firstComponentOrThrow(components) {
|
|
92
|
+
const first = components[0];
|
|
93
|
+
if (!first) {
|
|
94
|
+
throw new ErodeError('Unexpected: components array was non-empty but first element was undefined', ErrorCode.INTERNAL_UNKNOWN, 'Internal pipeline error');
|
|
95
|
+
}
|
|
96
|
+
return first;
|
|
97
|
+
}
|
|
98
|
+
/** Look up components for a repository, returning an empty result if none match. */
|
|
99
|
+
export function findComponentsForRepo(adapter, repoUrl, metadata, progress) {
|
|
100
|
+
progress.start('Locating components for repository');
|
|
101
|
+
const components = adapter.findAllComponentsByRepository(repoUrl);
|
|
102
|
+
if (components.length === 0) {
|
|
103
|
+
progress.warn(`No components matched repository: ${repoUrl}`);
|
|
104
|
+
for (const line of adapter.metadata.noComponentHelpLines) {
|
|
105
|
+
progress.info(line.replace('{{repoUrl}}', repoUrl));
|
|
106
|
+
}
|
|
107
|
+
return buildEmptyResult({
|
|
108
|
+
metadata,
|
|
109
|
+
repoUrl,
|
|
110
|
+
adapterDisplayName: adapter.metadata.displayName,
|
|
111
|
+
includeStructured: true,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
progress.succeed(`Located ${String(components.length)} component(s) for repository`);
|
|
115
|
+
return { found: true, components, defaultComponent: firstComponentOrThrow(components) };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=pipeline-shared.js.map
|