@fairfox/polly 0.1.2 → 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.
Files changed (68) hide show
  1. package/{cli/polly.ts → dist/cli/polly.js} +100 -206
  2. package/dist/cli/polly.js.map +10 -0
  3. package/dist/scripts/build-extension.js +137 -0
  4. package/dist/scripts/build-extension.js.map +10 -0
  5. package/dist/vendor/verify/src/cli.js +2089 -0
  6. package/dist/vendor/verify/src/cli.js.map +16 -0
  7. package/dist/vendor/visualize/src/cli.js +2204 -0
  8. package/dist/vendor/visualize/src/cli.js.map +19 -0
  9. package/package.json +12 -12
  10. package/vendor/analysis/src/extract/adr.ts +0 -212
  11. package/vendor/analysis/src/extract/architecture.ts +0 -160
  12. package/vendor/analysis/src/extract/contexts.ts +0 -298
  13. package/vendor/analysis/src/extract/flows.ts +0 -309
  14. package/vendor/analysis/src/extract/handlers.ts +0 -321
  15. package/vendor/analysis/src/extract/index.ts +0 -9
  16. package/vendor/analysis/src/extract/integrations.ts +0 -329
  17. package/vendor/analysis/src/extract/manifest.ts +0 -298
  18. package/vendor/analysis/src/extract/types.ts +0 -389
  19. package/vendor/analysis/src/index.ts +0 -7
  20. package/vendor/analysis/src/types/adr.ts +0 -53
  21. package/vendor/analysis/src/types/architecture.ts +0 -245
  22. package/vendor/analysis/src/types/core.ts +0 -210
  23. package/vendor/analysis/src/types/index.ts +0 -18
  24. package/vendor/verify/src/adapters/base.ts +0 -164
  25. package/vendor/verify/src/adapters/detection.ts +0 -281
  26. package/vendor/verify/src/adapters/event-bus/index.ts +0 -480
  27. package/vendor/verify/src/adapters/web-extension/index.ts +0 -508
  28. package/vendor/verify/src/adapters/websocket/index.ts +0 -486
  29. package/vendor/verify/src/cli.ts +0 -430
  30. package/vendor/verify/src/codegen/config.ts +0 -354
  31. package/vendor/verify/src/codegen/tla.ts +0 -719
  32. package/vendor/verify/src/config/parser.ts +0 -303
  33. package/vendor/verify/src/config/types.ts +0 -113
  34. package/vendor/verify/src/core/model.ts +0 -267
  35. package/vendor/verify/src/core/primitives.ts +0 -106
  36. package/vendor/verify/src/extract/handlers.ts +0 -2
  37. package/vendor/verify/src/extract/types.ts +0 -2
  38. package/vendor/verify/src/index.ts +0 -150
  39. package/vendor/verify/src/primitives/index.ts +0 -102
  40. package/vendor/verify/src/runner/docker.ts +0 -283
  41. package/vendor/verify/src/types.ts +0 -51
  42. package/vendor/visualize/src/cli.ts +0 -365
  43. package/vendor/visualize/src/codegen/structurizr.ts +0 -770
  44. package/vendor/visualize/src/index.ts +0 -13
  45. package/vendor/visualize/src/runner/export.ts +0 -235
  46. package/vendor/visualize/src/viewer/server.ts +0 -485
  47. /package/dist/{background → src/background}/index.js +0 -0
  48. /package/dist/{background → src/background}/index.js.map +0 -0
  49. /package/dist/{background → src/background}/message-router.js +0 -0
  50. /package/dist/{background → src/background}/message-router.js.map +0 -0
  51. /package/dist/{index.js → src/index.js} +0 -0
  52. /package/dist/{index.js.map → src/index.js.map} +0 -0
  53. /package/dist/{shared → src/shared}/adapters/index.js +0 -0
  54. /package/dist/{shared → src/shared}/adapters/index.js.map +0 -0
  55. /package/dist/{shared → src/shared}/lib/context-helpers.js +0 -0
  56. /package/dist/{shared → src/shared}/lib/context-helpers.js.map +0 -0
  57. /package/dist/{shared → src/shared}/lib/errors.js +0 -0
  58. /package/dist/{shared → src/shared}/lib/errors.js.map +0 -0
  59. /package/dist/{shared → src/shared}/lib/message-bus.js +0 -0
  60. /package/dist/{shared → src/shared}/lib/message-bus.js.map +0 -0
  61. /package/dist/{shared → src/shared}/lib/state.js +0 -0
  62. /package/dist/{shared → src/shared}/lib/state.js.map +0 -0
  63. /package/dist/{shared → src/shared}/lib/test-helpers.js +0 -0
  64. /package/dist/{shared → src/shared}/lib/test-helpers.js.map +0 -0
  65. /package/dist/{shared → src/shared}/state/app-state.js +0 -0
  66. /package/dist/{shared → src/shared}/state/app-state.js.map +0 -0
  67. /package/dist/{shared → src/shared}/types/messages.js +0 -0
  68. /package/dist/{shared → src/shared}/types/messages.js.map +0 -0
@@ -1,430 +0,0 @@
1
- #!/usr/bin/env bun
2
- // CLI for verification system
3
-
4
- import * as fs from "node:fs";
5
- import * as path from "node:path";
6
- import { analyzeCodebase } from "./extract/types";
7
- import { generateConfig } from "./codegen/config";
8
- import { validateConfig } from "./config/parser";
9
-
10
- const COLORS = {
11
- reset: "\x1b[0m",
12
- red: "\x1b[31m",
13
- green: "\x1b[32m",
14
- yellow: "\x1b[33m",
15
- blue: "\x1b[34m",
16
- gray: "\x1b[90m",
17
- };
18
-
19
- function color(text: string, colorCode: string): string {
20
- return `${colorCode}${text}${COLORS.reset}`;
21
- }
22
-
23
- async function main() {
24
- const args = process.argv.slice(2);
25
- const command = args[0];
26
-
27
- switch (command) {
28
- case "--setup":
29
- case "setup":
30
- await setupCommand();
31
- break;
32
-
33
- case "--validate":
34
- case "validate":
35
- await validateCommand();
36
- break;
37
-
38
- case "--help":
39
- case "help":
40
- showHelp();
41
- break;
42
-
43
- default:
44
- await verifyCommand();
45
- }
46
- }
47
-
48
- async function setupCommand() {
49
- console.log(color("\n🔍 Analyzing codebase...\n", COLORS.blue));
50
-
51
- try {
52
- // Find tsconfig
53
- const tsConfigPath = findTsConfig();
54
- if (!tsConfigPath) {
55
- console.error(color("❌ Could not find tsconfig.json", COLORS.red));
56
- console.error(" Run this command from your project root");
57
- process.exit(1);
58
- }
59
-
60
- console.log(color(` Using: ${tsConfigPath}`, COLORS.gray));
61
-
62
- // Analyze codebase
63
- const analysis = await analyzeCodebase({
64
- tsConfigPath,
65
- stateFilePath: findStateFile(),
66
- });
67
-
68
- if (!analysis.stateType) {
69
- console.log(color("\n⚠️ Could not find state type definition", COLORS.yellow));
70
- console.log(" Expected to find a type named 'AppState' or 'State'");
71
- console.log(" in a file matching **/state*.ts");
72
- console.log();
73
- console.log(" You can still generate a config template:");
74
- console.log(" It will be empty and you'll need to fill it in manually.");
75
- console.log();
76
- } else {
77
- console.log(
78
- color(`✓ Found state type with ${analysis.fields.length} field(s)`, COLORS.green)
79
- );
80
- }
81
-
82
- console.log(color(`✓ Found ${analysis.messageTypes.length} message type(s)`, COLORS.green));
83
-
84
- // Show analysis summary
85
- if (analysis.fields.length > 0) {
86
- console.log(color("\n📊 Configuration Summary:\n", COLORS.blue));
87
-
88
- const table = [
89
- ["Field", "Type", "Status"],
90
- ["─".repeat(30), "─".repeat(20), "─".repeat(20)],
91
- ];
92
-
93
- for (const field of analysis.fields) {
94
- const status =
95
- field.confidence === "high"
96
- ? color("✓ Auto-configured", COLORS.green)
97
- : field.confidence === "medium"
98
- ? color("⚠ Review needed", COLORS.yellow)
99
- : color("⚠ Manual config", COLORS.red);
100
-
101
- table.push([field.path, field.type.kind, status]);
102
- }
103
-
104
- for (const row of table) {
105
- console.log(` ${row[0].padEnd(32)} ${row[1].padEnd(22)} ${row[2]}`);
106
- }
107
- }
108
-
109
- // Generate config
110
- const configContent = generateConfig(analysis);
111
- const configPath = path.join(process.cwd(), "specs", "verification.config.ts");
112
-
113
- // Ensure directory exists
114
- const configDir = path.dirname(configPath);
115
- if (!fs.existsSync(configDir)) {
116
- fs.mkdirSync(configDir, { recursive: true });
117
- }
118
-
119
- // Write config
120
- fs.writeFileSync(configPath, configContent, "utf-8");
121
-
122
- console.log(color("\n✅ Configuration generated!\n", COLORS.green));
123
- console.log(` File: ${color(configPath, COLORS.blue)}`);
124
- console.log();
125
- console.log(color("📝 Next steps:", COLORS.blue));
126
- console.log();
127
- console.log(" 1. Review the generated configuration file");
128
- console.log(" 2. Fill in values marked with /* CONFIGURE */");
129
- console.log(" 3. Run 'bun verify' to check your configuration");
130
- console.log();
131
- console.log(color("💡 Tip:", COLORS.gray));
132
- console.log(color(" Look for comments explaining what each field needs.", COLORS.gray));
133
- console.log();
134
- } catch (error) {
135
- console.error(color("\n❌ Setup failed:", COLORS.red));
136
- console.error(` ${error instanceof Error ? error.message : String(error)}`);
137
- process.exit(1);
138
- }
139
- }
140
-
141
- async function validateCommand() {
142
- const configPath = path.join(process.cwd(), "specs", "verification.config.ts");
143
-
144
- console.log(color("\n🔍 Validating configuration...\n", COLORS.blue));
145
-
146
- const result = validateConfig(configPath);
147
-
148
- if (result.valid) {
149
- console.log(color("✅ Configuration is complete and valid!\n", COLORS.green));
150
- console.log(" You can now run 'bun verify' to start verification.");
151
- console.log();
152
- return;
153
- }
154
-
155
- // Show errors
156
- const errors = result.issues.filter((i) => i.severity === "error");
157
- const warnings = result.issues.filter((i) => i.severity === "warning");
158
-
159
- if (errors.length > 0) {
160
- console.log(color(`❌ Found ${errors.length} error(s):\n`, COLORS.red));
161
-
162
- for (const error of errors) {
163
- console.log(color(` • ${error.message}`, COLORS.red));
164
- if (error.field) {
165
- console.log(color(` Field: ${error.field}`, COLORS.gray));
166
- }
167
- if (error.location) {
168
- console.log(color(` Location: line ${error.location.line}`, COLORS.gray));
169
- }
170
- console.log(color(` → ${error.suggestion}`, COLORS.yellow));
171
- console.log();
172
- }
173
- }
174
-
175
- if (warnings.length > 0) {
176
- console.log(color(`⚠️ Found ${warnings.length} warning(s):\n`, COLORS.yellow));
177
-
178
- for (const warning of warnings) {
179
- console.log(color(` • ${warning.message}`, COLORS.yellow));
180
- if (warning.field) {
181
- console.log(color(` Field: ${warning.field}`, COLORS.gray));
182
- }
183
- console.log(color(` → ${warning.suggestion}`, COLORS.gray));
184
- console.log();
185
- }
186
- }
187
-
188
- console.log(color("Configuration incomplete. Please fix the errors above.\n", COLORS.red));
189
- process.exit(1);
190
- }
191
-
192
- async function verifyCommand() {
193
- const configPath = path.join(process.cwd(), "specs", "verification.config.ts");
194
-
195
- console.log(color("\n🔍 Running verification...\n", COLORS.blue));
196
-
197
- // First validate config
198
- const validation = validateConfig(configPath);
199
-
200
- if (!validation.valid) {
201
- const errors = validation.issues.filter((i) => i.severity === "error");
202
- console.log(color(`❌ Configuration incomplete (${errors.length} error(s))\n`, COLORS.red));
203
-
204
- for (const error of errors.slice(0, 3)) {
205
- console.log(color(` • ${error.message}`, COLORS.red));
206
- if (error.field) {
207
- console.log(color(` Field: ${error.field}`, COLORS.gray));
208
- }
209
- console.log();
210
- }
211
-
212
- if (errors.length > 3) {
213
- console.log(color(` ... and ${errors.length - 3} more error(s)`, COLORS.gray));
214
- console.log();
215
- }
216
-
217
- console.log(" Run 'bun verify --validate' to see all issues");
218
- console.log(" Run 'bun verify --setup' to regenerate configuration");
219
- console.log();
220
- process.exit(1);
221
- }
222
-
223
- console.log(color("✓ Configuration valid", COLORS.green));
224
- console.log();
225
-
226
- // Run full verification
227
- try {
228
- await runFullVerification(configPath);
229
- } catch (error) {
230
- console.error(color("\n❌ Verification failed:", COLORS.red));
231
- console.error(` ${error instanceof Error ? error.message : String(error)}`);
232
- process.exit(1);
233
- }
234
- }
235
-
236
- async function runFullVerification(configPath: string) {
237
- const { generateTLA } = await import("./codegen/tla");
238
- const { DockerRunner } = await import("./runner/docker");
239
-
240
- // Load config
241
- delete require.cache[require.resolve(path.resolve(configPath))];
242
- const configModule = require(path.resolve(configPath));
243
- const config = configModule.default || configModule;
244
-
245
- // Analyze codebase
246
- console.log(color("📊 Analyzing codebase...", COLORS.blue));
247
- const tsConfigPath = findTsConfig();
248
- if (!tsConfigPath) {
249
- throw new Error("Could not find tsconfig.json");
250
- }
251
-
252
- const analysis = await analyzeCodebase({
253
- tsConfigPath,
254
- stateFilePath: findStateFile(),
255
- });
256
-
257
- console.log(color("✓ Analysis complete", COLORS.green));
258
- console.log();
259
-
260
- // Generate TLA+ specs
261
- console.log(color("📝 Generating TLA+ specification...", COLORS.blue));
262
- const { spec, cfg } = generateTLA(config, analysis);
263
-
264
- // Write specs to temp directory
265
- const specDir = path.join(process.cwd(), "specs", "tla", "generated");
266
- if (!fs.existsSync(specDir)) {
267
- fs.mkdirSync(specDir, { recursive: true });
268
- }
269
-
270
- const specPath = path.join(specDir, "UserApp.tla");
271
- const cfgPath = path.join(specDir, "UserApp.cfg");
272
-
273
- fs.writeFileSync(specPath, spec);
274
- fs.writeFileSync(cfgPath, cfg);
275
-
276
- // Copy base MessageRouter spec to generated directory so TLC can find it
277
- const baseSpecPath = path.join(process.cwd(), "specs", "tla", "MessageRouter.tla");
278
- if (fs.existsSync(baseSpecPath)) {
279
- const destSpecPath = path.join(specDir, "MessageRouter.tla");
280
- fs.copyFileSync(baseSpecPath, destSpecPath);
281
- } else {
282
- console.log(
283
- color("⚠️ Warning: MessageRouter.tla not found, verification may fail", COLORS.yellow)
284
- );
285
- }
286
-
287
- console.log(color("✓ Specification generated", COLORS.green));
288
- console.log(color(` ${specPath}`, COLORS.gray));
289
- console.log();
290
-
291
- // Check Docker
292
- console.log(color("🐳 Checking Docker...", COLORS.blue));
293
- const docker = new DockerRunner();
294
-
295
- if (!(await docker.isDockerAvailable())) {
296
- throw new Error("Docker is not available. Please install Docker and try again.");
297
- }
298
-
299
- if (!(await docker.hasImage())) {
300
- console.log(color(" Pulling TLA+ image (this may take a moment)...", COLORS.gray));
301
- await docker.pullImage((line) => {
302
- console.log(color(` ${line}`, COLORS.gray));
303
- });
304
- }
305
-
306
- console.log(color("✓ Docker ready", COLORS.green));
307
- console.log();
308
-
309
- // Run TLC
310
- console.log(color("⚙️ Running TLC model checker...", COLORS.blue));
311
- console.log(color(" This may take a minute...", COLORS.gray));
312
- console.log();
313
-
314
- const result = await docker.runTLC(specPath, {
315
- workers: 2,
316
- timeout: 120000, // 2 minutes
317
- });
318
-
319
- // Display results
320
- if (result.success) {
321
- console.log(color("✅ Verification passed!\n", COLORS.green));
322
- console.log(color("Statistics:", COLORS.blue));
323
- console.log(color(` States explored: ${result.stats?.statesGenerated || 0}`, COLORS.gray));
324
- console.log(color(` Distinct states: ${result.stats?.distinctStates || 0}`, COLORS.gray));
325
- console.log();
326
- } else {
327
- console.log(color("❌ Verification failed!\n", COLORS.red));
328
-
329
- if (result.violation) {
330
- console.log(color(`Invariant violated: ${result.violation.name}\n`, COLORS.red));
331
- console.log(color("Trace to violation:", COLORS.yellow));
332
- for (const line of result.violation.trace.slice(0, 20)) {
333
- console.log(color(` ${line}`, COLORS.gray));
334
- }
335
- if (result.violation.trace.length > 20) {
336
- console.log(color(` ... (${result.violation.trace.length - 20} more lines)`, COLORS.gray));
337
- }
338
- } else if (result.error) {
339
- console.log(color(`Error: ${result.error}`, COLORS.red));
340
- }
341
-
342
- console.log();
343
- console.log(color("Full output saved to:", COLORS.gray));
344
- console.log(color(` ${path.join(specDir, "tlc-output.log")}`, COLORS.gray));
345
- fs.writeFileSync(path.join(specDir, "tlc-output.log"), result.output);
346
-
347
- process.exit(1);
348
- }
349
- }
350
-
351
- function showHelp() {
352
- console.log(`
353
- ${color("bun verify", COLORS.blue)} - Formal verification for web extensions
354
-
355
- ${color("Commands:", COLORS.blue)}
356
-
357
- ${color("bun verify", COLORS.green)}
358
- Run verification (validates config, generates specs, runs TLC)
359
-
360
- ${color("bun verify --setup", COLORS.green)}
361
- Analyze codebase and generate configuration file
362
-
363
- ${color("bun verify --validate", COLORS.green)}
364
- Validate existing configuration without running verification
365
-
366
- ${color("bun verify --help", COLORS.green)}
367
- Show this help message
368
-
369
- ${color("Getting Started:", COLORS.blue)}
370
-
371
- 1. Run ${color("bun verify --setup", COLORS.green)} to generate configuration
372
- 2. Review ${color("specs/verification.config.ts", COLORS.blue)} and fill in marked fields
373
- 3. Run ${color("bun verify --validate", COLORS.green)} to check your configuration
374
- 4. Run ${color("bun verify", COLORS.green)} to start verification
375
-
376
- ${color("Configuration Help:", COLORS.blue)}
377
-
378
- The generated config file uses special markers:
379
-
380
- ${color("/* CONFIGURE */", COLORS.yellow)} - Replace with your value
381
- ${color("/* REVIEW */", COLORS.yellow)} - Check auto-generated value
382
- ${color("null", COLORS.yellow)} - Must be replaced with concrete value
383
-
384
- ${color("Learn More:", COLORS.blue)}
385
-
386
- Documentation: https://github.com/fairfox/web-ext
387
- TLA+ Resources: https://learntla.com
388
- `);
389
- }
390
-
391
- function findTsConfig(): string | null {
392
- const locations = [
393
- path.join(process.cwd(), "tsconfig.json"),
394
- path.join(process.cwd(), "packages", "web-ext", "tsconfig.json"),
395
- ];
396
-
397
- for (const loc of locations) {
398
- if (fs.existsSync(loc)) {
399
- return loc;
400
- }
401
- }
402
-
403
- return null;
404
- }
405
-
406
- function findStateFile(): string | undefined {
407
- const locations = [
408
- path.join(process.cwd(), "types", "state.ts"),
409
- path.join(process.cwd(), "src", "types", "state.ts"),
410
- path.join(process.cwd(), "packages", "web-ext", "src", "shared", "state", "app-state.ts"),
411
- ];
412
-
413
- for (const loc of locations) {
414
- if (fs.existsSync(loc)) {
415
- return loc;
416
- }
417
- }
418
-
419
- return undefined;
420
- }
421
-
422
- main().catch((error) => {
423
- console.error(color("\n❌ Fatal error:", COLORS.red));
424
- console.error(` ${error instanceof Error ? error.message : String(error)}`);
425
- if (error instanceof Error && error.stack) {
426
- console.error(color("\nStack trace:", COLORS.gray));
427
- console.error(color(error.stack, COLORS.gray));
428
- }
429
- process.exit(1);
430
- });