@fairfox/polly 0.1.3 → 0.1.4
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/{cli/polly.ts → dist/cli/polly.js} +100 -206
- package/dist/cli/polly.js.map +10 -0
- package/dist/scripts/build-extension.js +137 -0
- package/dist/scripts/build-extension.js.map +10 -0
- package/dist/vendor/verify/src/cli.js +2089 -0
- package/dist/vendor/verify/src/cli.js.map +16 -0
- package/dist/vendor/visualize/src/cli.js +2204 -0
- package/dist/vendor/visualize/src/cli.js.map +19 -0
- package/package.json +12 -12
- package/vendor/analysis/src/extract/adr.ts +0 -212
- package/vendor/analysis/src/extract/architecture.ts +0 -160
- package/vendor/analysis/src/extract/contexts.ts +0 -298
- package/vendor/analysis/src/extract/flows.ts +0 -309
- package/vendor/analysis/src/extract/handlers.ts +0 -321
- package/vendor/analysis/src/extract/index.ts +0 -9
- package/vendor/analysis/src/extract/integrations.ts +0 -329
- package/vendor/analysis/src/extract/manifest.ts +0 -298
- package/vendor/analysis/src/extract/types.ts +0 -389
- package/vendor/analysis/src/index.ts +0 -7
- package/vendor/analysis/src/types/adr.ts +0 -53
- package/vendor/analysis/src/types/architecture.ts +0 -245
- package/vendor/analysis/src/types/core.ts +0 -210
- package/vendor/analysis/src/types/index.ts +0 -18
- package/vendor/verify/src/adapters/base.ts +0 -164
- package/vendor/verify/src/adapters/detection.ts +0 -281
- package/vendor/verify/src/adapters/event-bus/index.ts +0 -480
- package/vendor/verify/src/adapters/web-extension/index.ts +0 -508
- package/vendor/verify/src/adapters/websocket/index.ts +0 -486
- package/vendor/verify/src/cli.ts +0 -430
- package/vendor/verify/src/codegen/config.ts +0 -354
- package/vendor/verify/src/codegen/tla.ts +0 -719
- package/vendor/verify/src/config/parser.ts +0 -303
- package/vendor/verify/src/config/types.ts +0 -113
- package/vendor/verify/src/core/model.ts +0 -267
- package/vendor/verify/src/core/primitives.ts +0 -106
- package/vendor/verify/src/extract/handlers.ts +0 -2
- package/vendor/verify/src/extract/types.ts +0 -2
- package/vendor/verify/src/index.ts +0 -150
- package/vendor/verify/src/primitives/index.ts +0 -102
- package/vendor/verify/src/runner/docker.ts +0 -283
- package/vendor/verify/src/types.ts +0 -51
- package/vendor/visualize/src/cli.ts +0 -365
- package/vendor/visualize/src/codegen/structurizr.ts +0 -770
- package/vendor/visualize/src/index.ts +0 -13
- package/vendor/visualize/src/runner/export.ts +0 -235
- package/vendor/visualize/src/viewer/server.ts +0 -485
- /package/dist/{background → src/background}/index.js +0 -0
- /package/dist/{background → src/background}/index.js.map +0 -0
- /package/dist/{background → src/background}/message-router.js +0 -0
- /package/dist/{background → src/background}/message-router.js.map +0 -0
- /package/dist/{index.js → src/index.js} +0 -0
- /package/dist/{index.js.map → src/index.js.map} +0 -0
- /package/dist/{shared → src/shared}/adapters/index.js +0 -0
- /package/dist/{shared → src/shared}/adapters/index.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/context-helpers.js +0 -0
- /package/dist/{shared → src/shared}/lib/context-helpers.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/errors.js +0 -0
- /package/dist/{shared → src/shared}/lib/errors.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/message-bus.js +0 -0
- /package/dist/{shared → src/shared}/lib/message-bus.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/state.js +0 -0
- /package/dist/{shared → src/shared}/lib/state.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/test-helpers.js +0 -0
- /package/dist/{shared → src/shared}/lib/test-helpers.js.map +0 -0
- /package/dist/{shared → src/shared}/state/app-state.js +0 -0
- /package/dist/{shared → src/shared}/state/app-state.js.map +0 -0
- /package/dist/{shared → src/shared}/types/messages.js +0 -0
- /package/dist/{shared → src/shared}/types/messages.js.map +0 -0
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
// Type extraction from TypeScript using ts-morph
|
|
2
|
-
|
|
3
|
-
import { Project, SourceFile, Type, TypeFormatFlags } from "ts-morph";
|
|
4
|
-
import type { TypeInfo, TypeKind, FieldAnalysis, Confidence, CodebaseAnalysis } from "../types";
|
|
5
|
-
import { HandlerExtractor } from "./handlers";
|
|
6
|
-
|
|
7
|
-
export class TypeExtractor {
|
|
8
|
-
private project: Project;
|
|
9
|
-
|
|
10
|
-
constructor(tsConfigPath: string) {
|
|
11
|
-
this.project = new Project({
|
|
12
|
-
tsConfigFilePath: tsConfigPath,
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Analyze the codebase and extract state types and message types
|
|
18
|
-
*/
|
|
19
|
-
async analyzeCodebase(stateFilePath?: string): Promise<CodebaseAnalysis> {
|
|
20
|
-
// Find state type
|
|
21
|
-
const stateType = stateFilePath ? this.extractStateType(stateFilePath) : this.findStateType();
|
|
22
|
-
|
|
23
|
-
// Find message types
|
|
24
|
-
const messageTypes = this.findMessageTypes();
|
|
25
|
-
|
|
26
|
-
// Analyze fields
|
|
27
|
-
const fields = stateType ? this.analyzeFields(stateType) : [];
|
|
28
|
-
|
|
29
|
-
// Extract message handlers
|
|
30
|
-
const configFilePath = this.project.getCompilerOptions().configFilePath;
|
|
31
|
-
const tsConfigPath = typeof configFilePath === "string" ? configFilePath : "tsconfig.json";
|
|
32
|
-
const handlerExtractor = new HandlerExtractor(tsConfigPath);
|
|
33
|
-
const handlerAnalysis = handlerExtractor.extractHandlers();
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
stateType,
|
|
37
|
-
messageTypes: Array.from(new Set([...messageTypes, ...handlerAnalysis.messageTypes])),
|
|
38
|
-
fields,
|
|
39
|
-
handlers: handlerAnalysis.handlers,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Extract state type from a specific file
|
|
45
|
-
*/
|
|
46
|
-
private extractStateType(filePath: string): TypeInfo | null {
|
|
47
|
-
const sourceFile = this.project.getSourceFile(filePath);
|
|
48
|
-
if (!sourceFile) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Look for type alias named "AppState" or similar
|
|
53
|
-
const typeAlias =
|
|
54
|
-
sourceFile.getTypeAlias("AppState") ||
|
|
55
|
-
sourceFile.getTypeAlias("State") ||
|
|
56
|
-
sourceFile.getTypeAliases()[0];
|
|
57
|
-
|
|
58
|
-
if (!typeAlias) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const type = typeAlias.getType();
|
|
63
|
-
return this.convertType(type, typeAlias.getName());
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Find state type by searching common patterns
|
|
68
|
-
*/
|
|
69
|
-
private findStateType(): TypeInfo | null {
|
|
70
|
-
// Search for files with "state" in the name
|
|
71
|
-
const stateFiles = this.project.getSourceFiles("**/state*.ts");
|
|
72
|
-
|
|
73
|
-
for (const file of stateFiles) {
|
|
74
|
-
const typeAlias = file.getTypeAlias("AppState") || file.getTypeAlias("State");
|
|
75
|
-
|
|
76
|
-
if (typeAlias) {
|
|
77
|
-
const type = typeAlias.getType();
|
|
78
|
-
return this.convertType(type, typeAlias.getName());
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Find message types by searching for type unions
|
|
87
|
-
*/
|
|
88
|
-
private findMessageTypes(): string[] {
|
|
89
|
-
const messageTypes: string[] = [];
|
|
90
|
-
|
|
91
|
-
// Search for files with "message" in the name
|
|
92
|
-
const messageFiles = this.project.getSourceFiles("**/message*.ts");
|
|
93
|
-
|
|
94
|
-
for (const file of messageFiles) {
|
|
95
|
-
// Look for type aliases that are unions
|
|
96
|
-
for (const typeAlias of file.getTypeAliases()) {
|
|
97
|
-
const type = typeAlias.getType();
|
|
98
|
-
if (type.isUnion()) {
|
|
99
|
-
// Extract message type literals
|
|
100
|
-
for (const unionType of type.getUnionTypes()) {
|
|
101
|
-
if (unionType.isObject()) {
|
|
102
|
-
const typeProperty = unionType.getProperty("type");
|
|
103
|
-
if (typeProperty) {
|
|
104
|
-
const typeType = typeProperty.getTypeAtLocation(file);
|
|
105
|
-
if (typeType.isStringLiteral()) {
|
|
106
|
-
messageTypes.push(typeType.getLiteralValue() as string);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return [...new Set(messageTypes)]; // Dedupe
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Convert ts-morph Type to our TypeInfo
|
|
120
|
-
*/
|
|
121
|
-
private convertType(type: Type, name: string): TypeInfo {
|
|
122
|
-
// Check for null/undefined
|
|
123
|
-
const nullable = type.isNullable();
|
|
124
|
-
|
|
125
|
-
// Boolean
|
|
126
|
-
if (type.isBoolean() || type.isBooleanLiteral()) {
|
|
127
|
-
return { name, kind: "boolean", nullable };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Union types
|
|
131
|
-
if (type.isUnion()) {
|
|
132
|
-
const unionTypes = type.getUnionTypes();
|
|
133
|
-
|
|
134
|
-
// Check for string literal union (enum)
|
|
135
|
-
const allStringLiterals = unionTypes.every((t) => t.isStringLiteral());
|
|
136
|
-
if (allStringLiterals) {
|
|
137
|
-
const enumValues = unionTypes.map((t) => t.getLiteralValue() as string);
|
|
138
|
-
return {
|
|
139
|
-
name,
|
|
140
|
-
kind: "enum",
|
|
141
|
-
nullable,
|
|
142
|
-
enumValues,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Check for nullable type (T | null | undefined)
|
|
147
|
-
const nonNullTypes = unionTypes.filter((t) => !t.isNull() && !t.isUndefined());
|
|
148
|
-
|
|
149
|
-
if (nonNullTypes.length === 1) {
|
|
150
|
-
// This is a nullable type: T | null or T | undefined
|
|
151
|
-
const baseType = this.convertType(nonNullTypes[0], name);
|
|
152
|
-
return {
|
|
153
|
-
...baseType,
|
|
154
|
-
nullable: true,
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Generic union - keep as-is
|
|
159
|
-
return {
|
|
160
|
-
name,
|
|
161
|
-
kind: "union",
|
|
162
|
-
nullable,
|
|
163
|
-
unionTypes: unionTypes.map((t, i) => this.convertType(t, `${name}_${i}`)),
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// String
|
|
168
|
-
if (type.isString() || type.isStringLiteral()) {
|
|
169
|
-
return { name, kind: "string", nullable };
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Number
|
|
173
|
-
if (type.isNumber() || type.isNumberLiteral()) {
|
|
174
|
-
return { name, kind: "number", nullable };
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Array
|
|
178
|
-
if (type.isArray()) {
|
|
179
|
-
const elementType = type.getArrayElementType();
|
|
180
|
-
return {
|
|
181
|
-
name,
|
|
182
|
-
kind: "array",
|
|
183
|
-
nullable,
|
|
184
|
-
elementType: elementType
|
|
185
|
-
? this.convertType(elementType, `${name}_element`)
|
|
186
|
-
: { name: "unknown", kind: "unknown", nullable: false },
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Map/Set detection - must come before generic object handling
|
|
191
|
-
const symbol = type.getSymbol();
|
|
192
|
-
if (symbol) {
|
|
193
|
-
const symbolName = symbol.getName();
|
|
194
|
-
|
|
195
|
-
// Map<K, V>
|
|
196
|
-
if (symbolName === "Map") {
|
|
197
|
-
const typeArgs = type.getTypeArguments();
|
|
198
|
-
return {
|
|
199
|
-
name,
|
|
200
|
-
kind: "map",
|
|
201
|
-
nullable,
|
|
202
|
-
// Extract value type from Map<K, V>
|
|
203
|
-
valueType:
|
|
204
|
-
typeArgs && typeArgs[1] ? this.convertType(typeArgs[1], `${name}_value`) : undefined,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Set<T>
|
|
209
|
-
if (symbolName === "Set") {
|
|
210
|
-
const typeArgs = type.getTypeArguments();
|
|
211
|
-
return {
|
|
212
|
-
name,
|
|
213
|
-
kind: "set",
|
|
214
|
-
nullable,
|
|
215
|
-
elementType:
|
|
216
|
-
typeArgs && typeArgs[0] ? this.convertType(typeArgs[0], `${name}_element`) : undefined,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Object
|
|
222
|
-
if (type.isObject()) {
|
|
223
|
-
const properties: Record<string, TypeInfo> = {};
|
|
224
|
-
|
|
225
|
-
for (const prop of type.getProperties()) {
|
|
226
|
-
const propName = prop.getName();
|
|
227
|
-
const propType = prop.getTypeAtLocation(this.project.getSourceFiles()[0]);
|
|
228
|
-
properties[propName] = this.convertType(propType, propName);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return {
|
|
232
|
-
name,
|
|
233
|
-
kind: "object",
|
|
234
|
-
nullable,
|
|
235
|
-
properties,
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Null
|
|
240
|
-
if (type.isNull()) {
|
|
241
|
-
return { name, kind: "null", nullable: true };
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Unknown/Any
|
|
245
|
-
return { name, kind: "unknown", nullable };
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Analyze fields and determine confidence/bounds
|
|
250
|
-
*/
|
|
251
|
-
private analyzeFields(stateType: TypeInfo, prefix = ""): FieldAnalysis[] {
|
|
252
|
-
const fields: FieldAnalysis[] = [];
|
|
253
|
-
|
|
254
|
-
if (stateType.kind === "object" && stateType.properties) {
|
|
255
|
-
for (const [key, propType] of Object.entries(stateType.properties)) {
|
|
256
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
257
|
-
|
|
258
|
-
// Recursively analyze nested objects (but not Map/Set - they're leaf nodes)
|
|
259
|
-
if (propType.kind === "object") {
|
|
260
|
-
// Don't add intermediate objects as fields, just recurse into them
|
|
261
|
-
fields.push(...this.analyzeFields(propType, path));
|
|
262
|
-
} else {
|
|
263
|
-
// This is a leaf field (or Map/Set), add it for configuration
|
|
264
|
-
const analysis = this.analyzeField(path, propType);
|
|
265
|
-
fields.push(analysis);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return fields;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Analyze a single field and determine configuration needs
|
|
275
|
-
*/
|
|
276
|
-
private analyzeField(path: string, type: TypeInfo): FieldAnalysis {
|
|
277
|
-
const analysis: FieldAnalysis = {
|
|
278
|
-
path,
|
|
279
|
-
type,
|
|
280
|
-
confidence: "low",
|
|
281
|
-
evidence: [],
|
|
282
|
-
suggestions: [],
|
|
283
|
-
bounds: {},
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
// Boolean - high confidence, no config needed
|
|
287
|
-
if (type.kind === "boolean") {
|
|
288
|
-
analysis.confidence = "high";
|
|
289
|
-
analysis.evidence.push("Boolean type - auto-configured");
|
|
290
|
-
return analysis;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Enum - high confidence
|
|
294
|
-
if (type.kind === "enum" && type.enumValues) {
|
|
295
|
-
analysis.confidence = "high";
|
|
296
|
-
analysis.evidence.push(`Enum with ${type.enumValues.length} values`);
|
|
297
|
-
analysis.bounds!.values = type.enumValues;
|
|
298
|
-
return analysis;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// Array - needs manual configuration
|
|
302
|
-
if (type.kind === "array") {
|
|
303
|
-
analysis.confidence = "low";
|
|
304
|
-
analysis.suggestions.push("Choose maxLength: 5 (fast), 10 (balanced), or 20 (thorough)");
|
|
305
|
-
analysis.bounds!.maxLength = undefined;
|
|
306
|
-
|
|
307
|
-
// Try to find bounds in code
|
|
308
|
-
const foundBound = this.findArrayBound(path);
|
|
309
|
-
if (foundBound) {
|
|
310
|
-
analysis.confidence = "medium";
|
|
311
|
-
analysis.evidence.push(`Found array check: ${foundBound.evidence}`);
|
|
312
|
-
analysis.bounds!.maxLength = foundBound.value;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return analysis;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Number - needs manual configuration
|
|
319
|
-
if (type.kind === "number") {
|
|
320
|
-
analysis.confidence = "low";
|
|
321
|
-
analysis.suggestions.push("Provide min and max values based on your application logic");
|
|
322
|
-
analysis.bounds!.min = undefined;
|
|
323
|
-
analysis.bounds!.max = undefined;
|
|
324
|
-
|
|
325
|
-
// Try to find bounds in code
|
|
326
|
-
const foundBound = this.findNumberBound(path);
|
|
327
|
-
if (foundBound) {
|
|
328
|
-
analysis.confidence = "high";
|
|
329
|
-
analysis.evidence.push(`Found comparison: ${foundBound.evidence}`);
|
|
330
|
-
analysis.bounds = { ...analysis.bounds!, ...foundBound.bounds };
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return analysis;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// String - needs manual configuration
|
|
337
|
-
if (type.kind === "string") {
|
|
338
|
-
analysis.confidence = "low";
|
|
339
|
-
analysis.suggestions.push(
|
|
340
|
-
'Provide 2-3 example values: ["value1", "value2", "value3"]',
|
|
341
|
-
"Or use { abstract: true } for symbolic verification"
|
|
342
|
-
);
|
|
343
|
-
analysis.bounds!.values = undefined;
|
|
344
|
-
return analysis;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// Map/Set - needs manual configuration
|
|
348
|
-
if (type.kind === "map" || type.kind === "set") {
|
|
349
|
-
analysis.confidence = "low";
|
|
350
|
-
analysis.suggestions.push("Provide maxSize (recommended: 3-5)");
|
|
351
|
-
analysis.bounds!.maxSize = undefined;
|
|
352
|
-
return analysis;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
return analysis;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Try to find array bounds by searching for length checks
|
|
360
|
-
*/
|
|
361
|
-
private findArrayBound(path: string): { value: number; evidence: string } | null {
|
|
362
|
-
// TODO: Search source code for patterns like:
|
|
363
|
-
// - if (array.length < N)
|
|
364
|
-
// - array.slice(0, N)
|
|
365
|
-
// This would require analyzing the actual usage in code
|
|
366
|
-
return null;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Try to find number bounds by searching for comparisons
|
|
371
|
-
*/
|
|
372
|
-
private findNumberBound(
|
|
373
|
-
path: string
|
|
374
|
-
): { bounds: { min?: number; max?: number }; evidence: string } | null {
|
|
375
|
-
// TODO: Search source code for patterns like:
|
|
376
|
-
// - if (counter < 100)
|
|
377
|
-
// - if (value >= 0 && value <= 100)
|
|
378
|
-
// This would require analyzing the actual usage in code
|
|
379
|
-
return null;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
export async function analyzeCodebase(options: {
|
|
384
|
-
tsConfigPath: string;
|
|
385
|
-
stateFilePath?: string;
|
|
386
|
-
}): Promise<CodebaseAnalysis> {
|
|
387
|
-
const extractor = new TypeExtractor(options.tsConfigPath);
|
|
388
|
-
return extractor.analyzeCodebase(options.stateFilePath);
|
|
389
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
// Architecture Decision Record types
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Architecture Decision Record
|
|
5
|
-
* Based on Michael Nygard's ADR format
|
|
6
|
-
*/
|
|
7
|
-
export type ADR = {
|
|
8
|
-
/** ADR number/ID */
|
|
9
|
-
id: string;
|
|
10
|
-
|
|
11
|
-
/** Decision title */
|
|
12
|
-
title: string;
|
|
13
|
-
|
|
14
|
-
/** Status: proposed, accepted, deprecated, superseded */
|
|
15
|
-
status: ADRStatus;
|
|
16
|
-
|
|
17
|
-
/** Date of decision */
|
|
18
|
-
date: string;
|
|
19
|
-
|
|
20
|
-
/** Context - what is the issue motivating this decision */
|
|
21
|
-
context: string;
|
|
22
|
-
|
|
23
|
-
/** Decision - what is the change we're proposing */
|
|
24
|
-
decision: string;
|
|
25
|
-
|
|
26
|
-
/** Consequences - what becomes easier or more difficult */
|
|
27
|
-
consequences: string;
|
|
28
|
-
|
|
29
|
-
/** Optional: Alternatives considered */
|
|
30
|
-
alternatives?: string[];
|
|
31
|
-
|
|
32
|
-
/** Optional: Links to superseding/superseded ADRs */
|
|
33
|
-
links?: ADRLink[];
|
|
34
|
-
|
|
35
|
-
/** Source file path */
|
|
36
|
-
source: string;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export type ADRStatus = "proposed" | "accepted" | "deprecated" | "superseded";
|
|
40
|
-
|
|
41
|
-
export type ADRLink = {
|
|
42
|
-
type: "supersedes" | "superseded-by" | "related-to";
|
|
43
|
-
adrId: string;
|
|
44
|
-
title?: string;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Collection of ADRs
|
|
49
|
-
*/
|
|
50
|
-
export type ADRCollection = {
|
|
51
|
-
adrs: ADR[];
|
|
52
|
-
directory: string;
|
|
53
|
-
};
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
// Types for architecture analysis (used by visualize)
|
|
2
|
-
|
|
3
|
-
import type { MessageHandler } from "./core";
|
|
4
|
-
|
|
5
|
-
// ─────────────────────────────────────────────────────────────────
|
|
6
|
-
// Context Information
|
|
7
|
-
// ─────────────────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Information about an execution context (background, content, popup, etc.)
|
|
11
|
-
*/
|
|
12
|
-
export type ContextInfo = {
|
|
13
|
-
/** Type of context */
|
|
14
|
-
type: string;
|
|
15
|
-
|
|
16
|
-
/** Entry point file path */
|
|
17
|
-
entryPoint: string;
|
|
18
|
-
|
|
19
|
-
/** Message handlers defined in this context */
|
|
20
|
-
handlers: MessageHandler[];
|
|
21
|
-
|
|
22
|
-
/** Chrome APIs used in this context */
|
|
23
|
-
chromeAPIs: string[];
|
|
24
|
-
|
|
25
|
-
/** External APIs called from this context */
|
|
26
|
-
externalAPIs: ExternalAPICall[];
|
|
27
|
-
|
|
28
|
-
/** UI components rendered (for popup/options/devtools) */
|
|
29
|
-
components?: ComponentInfo[];
|
|
30
|
-
|
|
31
|
-
/** Dependencies/imports */
|
|
32
|
-
dependencies: string[];
|
|
33
|
-
|
|
34
|
-
/** JSDoc description if available */
|
|
35
|
-
description?: string;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Component information (for UI contexts)
|
|
40
|
-
*/
|
|
41
|
-
export type ComponentInfo = {
|
|
42
|
-
name: string;
|
|
43
|
-
type: "function" | "class";
|
|
44
|
-
filePath: string;
|
|
45
|
-
line: number;
|
|
46
|
-
props?: string[];
|
|
47
|
-
description?: string;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// ─────────────────────────────────────────────────────────────────
|
|
51
|
-
// Message Flow Analysis
|
|
52
|
-
// ─────────────────────────────────────────────────────────────────
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Represents a message flow between contexts
|
|
56
|
-
*/
|
|
57
|
-
export type MessageFlow = {
|
|
58
|
-
/** Message type identifier */
|
|
59
|
-
messageType: string;
|
|
60
|
-
|
|
61
|
-
/** Source context */
|
|
62
|
-
from: string;
|
|
63
|
-
|
|
64
|
-
/** Destination context(s) */
|
|
65
|
-
to: string[];
|
|
66
|
-
|
|
67
|
-
/** What triggers this flow (user action, event, etc.) */
|
|
68
|
-
trigger?: string;
|
|
69
|
-
|
|
70
|
-
/** Sequence of steps in this flow */
|
|
71
|
-
sequence: MessageStep[];
|
|
72
|
-
|
|
73
|
-
/** Flow name (from @flow annotation or inferred) */
|
|
74
|
-
flowName?: string;
|
|
75
|
-
|
|
76
|
-
/** Description (from JSDoc) */
|
|
77
|
-
description?: string;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* A step in a message flow sequence
|
|
82
|
-
*/
|
|
83
|
-
export type MessageStep = {
|
|
84
|
-
/** Step number in sequence */
|
|
85
|
-
step: number;
|
|
86
|
-
|
|
87
|
-
/** Action description */
|
|
88
|
-
action: string;
|
|
89
|
-
|
|
90
|
-
/** Context where this step occurs */
|
|
91
|
-
context: string;
|
|
92
|
-
|
|
93
|
-
/** Source location */
|
|
94
|
-
location?: {
|
|
95
|
-
file: string;
|
|
96
|
-
line: number;
|
|
97
|
-
};
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// ─────────────────────────────────────────────────────────────────
|
|
101
|
-
// External Integrations
|
|
102
|
-
// ─────────────────────────────────────────────────────────────────
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* External system integration
|
|
106
|
-
*/
|
|
107
|
-
export type ExternalIntegration = {
|
|
108
|
-
/** Type of integration */
|
|
109
|
-
type: "api" | "storage" | "browser-api" | "external-script" | "websocket";
|
|
110
|
-
|
|
111
|
-
/** Name/identifier */
|
|
112
|
-
name: string;
|
|
113
|
-
|
|
114
|
-
/** Technology/protocol */
|
|
115
|
-
technology?: string;
|
|
116
|
-
|
|
117
|
-
/** Base URL or endpoint */
|
|
118
|
-
url?: string;
|
|
119
|
-
|
|
120
|
-
/** Where it's used (file paths) */
|
|
121
|
-
usedIn: string[];
|
|
122
|
-
|
|
123
|
-
/** Description (from JSDoc or inferred) */
|
|
124
|
-
description?: string;
|
|
125
|
-
|
|
126
|
-
/** Specific API calls made */
|
|
127
|
-
calls?: ExternalAPICall[];
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* A specific API call
|
|
132
|
-
*/
|
|
133
|
-
export type ExternalAPICall = {
|
|
134
|
-
/** HTTP method or API method name */
|
|
135
|
-
method: string;
|
|
136
|
-
|
|
137
|
-
/** Endpoint or resource */
|
|
138
|
-
endpoint: string;
|
|
139
|
-
|
|
140
|
-
/** Where this call is made */
|
|
141
|
-
location: {
|
|
142
|
-
file: string;
|
|
143
|
-
line: number;
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
/** Description */
|
|
147
|
-
description?: string;
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
// ─────────────────────────────────────────────────────────────────
|
|
151
|
-
// Manifest Analysis
|
|
152
|
-
// ─────────────────────────────────────────────────────────────────
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Parsed manifest.json information
|
|
156
|
-
*/
|
|
157
|
-
export type ManifestInfo = {
|
|
158
|
-
/** Extension name */
|
|
159
|
-
name: string;
|
|
160
|
-
|
|
161
|
-
/** Version */
|
|
162
|
-
version: string;
|
|
163
|
-
|
|
164
|
-
/** Description */
|
|
165
|
-
description?: string;
|
|
166
|
-
|
|
167
|
-
/** Manifest version (2 or 3) */
|
|
168
|
-
manifestVersion: number;
|
|
169
|
-
|
|
170
|
-
/** Background script/service worker */
|
|
171
|
-
background?: {
|
|
172
|
-
type: "script" | "service_worker";
|
|
173
|
-
files: string[];
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
/** Content scripts */
|
|
177
|
-
contentScripts?: Array<{
|
|
178
|
-
matches: string[];
|
|
179
|
-
js: string[];
|
|
180
|
-
css?: string[];
|
|
181
|
-
}>;
|
|
182
|
-
|
|
183
|
-
/** Popup */
|
|
184
|
-
popup?: {
|
|
185
|
-
html: string;
|
|
186
|
-
default?: boolean;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
/** Options page */
|
|
190
|
-
options?: {
|
|
191
|
-
page: string;
|
|
192
|
-
openInTab?: boolean;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
/** DevTools page */
|
|
196
|
-
devtools?: {
|
|
197
|
-
page: string;
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
/** Permissions */
|
|
201
|
-
permissions?: string[];
|
|
202
|
-
|
|
203
|
-
/** Host permissions */
|
|
204
|
-
hostPermissions?: string[];
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
// ─────────────────────────────────────────────────────────────────
|
|
208
|
-
// Complete Architecture Analysis
|
|
209
|
-
// ─────────────────────────────────────────────────────────────────
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Complete architecture analysis result
|
|
213
|
-
*/
|
|
214
|
-
export type ArchitectureAnalysis = {
|
|
215
|
-
/** Basic system information */
|
|
216
|
-
system: {
|
|
217
|
-
name: string;
|
|
218
|
-
version: string;
|
|
219
|
-
description?: string;
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
/** Manifest information */
|
|
223
|
-
manifest?: ManifestInfo;
|
|
224
|
-
|
|
225
|
-
/** All contexts found in the system */
|
|
226
|
-
contexts: Record<string, ContextInfo>;
|
|
227
|
-
|
|
228
|
-
/** Message flows between contexts */
|
|
229
|
-
messageFlows: MessageFlow[];
|
|
230
|
-
|
|
231
|
-
/** External integrations */
|
|
232
|
-
integrations: ExternalIntegration[];
|
|
233
|
-
|
|
234
|
-
/** Architecture Decision Records */
|
|
235
|
-
adrs?: ADRCollection;
|
|
236
|
-
|
|
237
|
-
/** Repository information */
|
|
238
|
-
repository?: {
|
|
239
|
-
url: string;
|
|
240
|
-
type: string;
|
|
241
|
-
};
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
// Import ADR types
|
|
245
|
-
import type { ADRCollection } from "./adr";
|