opencroc 0.1.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 opencroc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,282 @@
1
+ <p align="center">
2
+ <img src="docs/assets/logo-placeholder.png" alt="OpenCroc" width="200" />
3
+ </p>
4
+
5
+ <h1 align="center">OpenCroc</h1>
6
+
7
+ <p align="center">
8
+ <strong>AI-native E2E testing framework that reads your source code, generates tests, and self-heals failures.</strong>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/opencroc"><img src="https://img.shields.io/npm/v/opencroc?color=green" alt="npm version" /></a>
13
+ <a href="https://github.com/opencroc/opencroc/blob/main/LICENSE"><img src="https://img.shields.io/github/license/opencroc/opencroc" alt="MIT License" /></a>
14
+ <a href="https://opencroc.com"><img src="https://img.shields.io/badge/docs-opencroc.com-blue" alt="Documentation" /></a>
15
+ </p>
16
+
17
+ ---
18
+
19
+ ## What is OpenCroc?
20
+
21
+ OpenCroc is an **AI-native end-to-end testing framework** built on top of [Playwright](https://playwright.dev). Instead of writing test scripts by hand, OpenCroc **reads your backend source code** (models, controllers, DTOs) and automatically generates complete E2E test suites — including API chains, seed data, request bodies, and assertions.
22
+
23
+ When tests fail, OpenCroc doesn't just report errors — it **traces the root cause** through the full request chain, **generates fix patches**, and **re-runs tests to verify the fix** — all autonomously.
24
+
25
+ ### Key Capabilities
26
+
27
+ | Capability | Description |
28
+ |---|---|
29
+ | **Source-Aware Test Generation** | Parses Sequelize/TypeORM models, Express/NestJS controllers, and DTO decorators via [ts-morph](https://ts-morph.com) to understand your API surface |
30
+ | **AI-Driven Configuration** | LLM generates request body templates, seed data, parameter mappings — validated by 3-layer verification (schema → semantic → dry-run) |
31
+ | **Intelligent Chain Planning** | Builds API dependency DAGs, performs topological sorting, and plans test chains with greedy coverage optimization |
32
+ | **Log-Driven Completion Detection** | Goes beyond `networkidle` — verifies request completion by matching backend execution logs (`api_exec end`) |
33
+ | **Failure Chain Attribution** | Traces failures through the full call chain: network errors → slow APIs → backend logs → root cause |
34
+ | **Controlled Self-Healing** | `backup → AI patch → dry-run → apply → re-run → verify → rollback` — with safety gates at every step |
35
+ | **Impact Analysis** | BFS traversal of foreign key relations to map blast radius, auto-generates Mermaid diagrams |
36
+
37
+ ## Quick Start
38
+
39
+ ### Prerequisites
40
+
41
+ - Node.js >= 18
42
+ - A backend project with Express/NestJS + Sequelize/TypeORM
43
+
44
+ ### Installation
45
+
46
+ ```bash
47
+ npm install opencroc --save-dev
48
+ ```
49
+
50
+ ### Initialize
51
+
52
+ ```bash
53
+ npx opencroc init
54
+ ```
55
+
56
+ This will:
57
+ 1. Scan your project structure
58
+ 2. Detect your ORM and framework
59
+ 3. Create `opencroc.config.ts` with sensible defaults
60
+ 4. Generate a sample test suite
61
+
62
+ ### Generate Tests
63
+
64
+ ```bash
65
+ # Generate tests for a single module
66
+ npx opencroc generate --module=knowledge-base
67
+
68
+ # Generate tests for all detected modules
69
+ npx opencroc generate --all
70
+
71
+ # Dry-run (preview without writing files)
72
+ npx opencroc generate --all --dry-run
73
+ ```
74
+
75
+ ### Run Tests
76
+
77
+ ```bash
78
+ # Run all generated tests
79
+ npx opencroc test
80
+
81
+ # Run specific module
82
+ npx opencroc test --module=knowledge-base
83
+
84
+ # Run with self-healing enabled
85
+ npx opencroc test --self-heal
86
+ ```
87
+
88
+ ### Validate AI Configs
89
+
90
+ ```bash
91
+ # Validate generated configurations
92
+ npx opencroc validate --all
93
+
94
+ # Compare AI-generated vs baseline results
95
+ npx opencroc compare --baseline=report-a.json --current=report-b.json
96
+ ```
97
+
98
+ ## Architecture
99
+
100
+ ```
101
+ ┌─────────────────────────────────────────────────────────────┐
102
+ │ CLI / Orchestrator │
103
+ ├──────────┬──────────┬──────────┬──────────┬─────────────────┤
104
+ │ Source │ Chain │ Test │ Execution│ Self-Healing │
105
+ │ Parser │ Planner │Generator │ Engine │ Engine │
106
+ │ │ │ │ │ │
107
+ │ ts-morph │ DAG + │ Template │Playwright│ AI Attribution │
108
+ │ Model │ Topo │ + AI │ + Log │ + Controlled │
109
+ │ Controller│ Sort + │ Config │ Driven │ Fix + Verify │
110
+ │ DTO │ Greedy │ Merge │ Assert │ + Rollback │
111
+ ├──────────┴──────────┴──────────┴──────────┴─────────────────┤
112
+ │ Observation Bus (Network + Backend Logs) │
113
+ ├──────────────────────────────────────────────────────────────┤
114
+ │ Report Engine (HTML / JSON / Markdown) │
115
+ └──────────────────────────────────────────────────────────────┘
116
+ ```
117
+
118
+ ### 6-Stage Pipeline
119
+
120
+ ```
121
+ Source Scan → ER Diagram → API Analysis → Chain Planning → Test Generation → Failure Analysis
122
+ │ │ │ │ │ │
123
+ ts-morph Mermaid Dependency Topological Playwright + Root Cause +
124
+ parsing erDiagram DAG builder + greedy AI body/seed Impact map
125
+ ```
126
+
127
+ ## How It Works
128
+
129
+ ### 1. Source Parsing
130
+
131
+ OpenCroc uses [ts-morph](https://ts-morph.com) to statically analyze your backend:
132
+
133
+ - **Models**: Extracts table names, column types, indexes, and foreign keys from Sequelize `Model.init()` / TypeORM `@Entity()`
134
+ - **Controllers**: Extracts routes, HTTP methods, path parameters from Express `router.get/post/put/delete`
135
+ - **DTOs**: Extracts validation rules from `@IsString()`, `@IsNumber()`, `@IsOptional()` decorators
136
+
137
+ ### 2. AI Configuration Generation
138
+
139
+ For each module, OpenCroc calls an LLM (OpenAI / ZhiPu / any OpenAI-compatible API) to generate:
140
+
141
+ - **Request body templates** — field-accurate POST/PUT payloads
142
+ - **Seed data** — `beforeAll` setup steps with correct API sequences
143
+ - **Parameter mappings** — path parameter aliases (`/:id` → `categoryId`)
144
+ - **ID aliases** — preventing ID conflicts across multi-resource chains
145
+
146
+ Each config is validated through **3 layers**:
147
+ 1. **Schema validation** — JSON structure completeness
148
+ 2. **Semantic validation** — field values match source code metadata
149
+ 3. **Dry-run validation** — TypeScript compilation check
150
+
151
+ Failed configs are **automatically fixed** (up to 3 rounds) before being written.
152
+
153
+ ### 3. Log-Driven Completion
154
+
155
+ Instead of relying on fragile `networkidle` signals:
156
+
157
+ ```
158
+ Frontend Request → Backend api_exec start log → Backend processing → api_exec end log
159
+
160
+ OpenCroc polls end logs to confirm completion
161
+ ```
162
+
163
+ This catches cases where the frontend appears idle but the backend is still processing.
164
+
165
+ ### 4. Self-Healing Loop
166
+
167
+ ```
168
+ Test Failure
169
+ → AI Attribution (LLM + heuristic fallback)
170
+ → Generate Fix Patch
171
+ → Dry-Run Validation
172
+ → Apply Patch (with backup)
173
+ → Re-run Failed Tests
174
+ → Verify Fix
175
+ → Commit or Rollback
176
+ ```
177
+
178
+ ## Configuration
179
+
180
+ ```typescript
181
+ // opencroc.config.ts
182
+ import { defineConfig } from 'opencroc';
183
+
184
+ export default defineConfig({
185
+ // Backend source paths
186
+ backend: {
187
+ modelsDir: 'src/models',
188
+ controllersDir: 'src/controllers',
189
+ servicesDir: 'src/services',
190
+ },
191
+
192
+ // Target application
193
+ baseUrl: 'http://localhost:3000',
194
+ apiBaseUrl: 'http://localhost:3000/api',
195
+
196
+ // AI configuration
197
+ ai: {
198
+ provider: 'openai', // 'openai' | 'zhipu' | 'custom'
199
+ apiKey: process.env.AI_API_KEY,
200
+ model: 'gpt-4o-mini',
201
+ },
202
+
203
+ // Test execution
204
+ execution: {
205
+ workers: 4,
206
+ timeout: 30_000,
207
+ retries: 1,
208
+ },
209
+
210
+ // Log-driven completion (requires backend instrumentation)
211
+ logCompletion: {
212
+ enabled: true,
213
+ endpoint: '/internal/test-logs',
214
+ pollIntervalMs: 500,
215
+ timeoutMs: 10_000,
216
+ },
217
+
218
+ // Self-healing
219
+ selfHealing: {
220
+ enabled: false,
221
+ fixScope: 'config-only', // 'config-only' | 'config-and-source'
222
+ maxFixRounds: 3,
223
+ dryRunFirst: true,
224
+ },
225
+ });
226
+ ```
227
+
228
+ ## Supported Tech Stacks
229
+
230
+ | Layer | Supported | Planned |
231
+ |---|---|---|
232
+ | **ORM** | Sequelize | TypeORM, Prisma, Drizzle |
233
+ | **Framework** | Express | NestJS, Fastify, Koa |
234
+ | **Test Runner** | Playwright | — |
235
+ | **LLM** | OpenAI, ZhiPu (GLM) | Anthropic, Ollama (local) |
236
+ | **Database** | MySQL, PostgreSQL | SQLite, MongoDB |
237
+
238
+ ## Comparison
239
+
240
+ | Feature | OpenCroc | Playwright | Metersphere | auto-playwright |
241
+ |---|---|---|---|---|
242
+ | Source-aware generation | ✅ | ❌ | ❌ | ❌ |
243
+ | AI config generation + validation | ✅ | ❌ | ❌ | ❌ |
244
+ | Log-driven completion | ✅ | ❌ | ❌ | ❌ |
245
+ | Failure chain attribution | ✅ | ❌ | Partial | ❌ |
246
+ | Self-healing with rollback | ✅ | ❌ | ❌ | ❌ |
247
+ | API dependency DAG | ✅ | ❌ | ❌ | ❌ |
248
+ | Zero-config test generation | ✅ | Codegen only | Manual | NL→action |
249
+ | Impact blast radius analysis | ✅ | ❌ | ❌ | ❌ |
250
+
251
+ ## Roadmap
252
+
253
+ - [x] 6-stage source-to-test pipeline
254
+ - [x] AI configuration generation with 3-layer validation
255
+ - [x] Controlled self-healing loop
256
+ - [x] Log-driven completion detection
257
+ - [x] Failure chain attribution + impact analysis
258
+ - [ ] TypeORM / Prisma adapter
259
+ - [ ] NestJS controller parser
260
+ - [ ] Visual dashboard (opencroc.com)
261
+ - [ ] GitHub Actions integration
262
+ - [ ] VS Code extension
263
+ - [ ] Ollama local LLM support
264
+
265
+ ## Documentation
266
+
267
+ Visit **[opencroc.com](https://opencroc.com)** for full documentation, or browse:
268
+
269
+ - [Architecture Guide](docs/architecture.md)
270
+ - [Configuration Reference](docs/configuration.md)
271
+ - [Backend Instrumentation Guide](docs/backend-instrumentation.md)
272
+ - [AI Provider Setup](docs/ai-providers.md)
273
+ - [Self-Healing Guide](docs/self-healing.md)
274
+ - [Troubleshooting](docs/troubleshooting.md)
275
+
276
+ ## Contributing
277
+
278
+ We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
279
+
280
+ ## License
281
+
282
+ [MIT](LICENSE) © 2026 OpenCroc Contributors
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // node_modules/tsup/assets/esm_shims.js
13
+ import path from "path";
14
+ import { fileURLToPath } from "url";
15
+ var init_esm_shims = __esm({
16
+ "node_modules/tsup/assets/esm_shims.js"() {
17
+ "use strict";
18
+ }
19
+ });
20
+
21
+ // src/cli/commands/init.ts
22
+ var init_exports = {};
23
+ __export(init_exports, {
24
+ initProject: () => initProject
25
+ });
26
+ import chalk from "chalk";
27
+ import { writeFileSync, mkdirSync, existsSync } from "fs";
28
+ import { join } from "path";
29
+ async function initProject() {
30
+ const cwd = process.cwd();
31
+ const configPath = join(cwd, "opencroc.config.ts");
32
+ if (existsSync(configPath)) {
33
+ console.log(chalk.yellow("opencroc.config.ts already exists. Skipping."));
34
+ return;
35
+ }
36
+ writeFileSync(configPath, CONFIG_TEMPLATE, "utf-8");
37
+ console.log(chalk.green("\u2713 Created opencroc.config.ts"));
38
+ const outDir = join(cwd, "opencroc-output");
39
+ if (!existsSync(outDir)) {
40
+ mkdirSync(outDir, { recursive: true });
41
+ console.log(chalk.green("\u2713 Created opencroc-output/"));
42
+ }
43
+ console.log("");
44
+ console.log(chalk.cyan("Next steps:"));
45
+ console.log(" 1. Edit opencroc.config.ts with your project settings");
46
+ console.log(" 2. Run: npx opencroc generate --all");
47
+ console.log(" 3. Run: npx opencroc test");
48
+ }
49
+ var CONFIG_TEMPLATE;
50
+ var init_init = __esm({
51
+ "src/cli/commands/init.ts"() {
52
+ "use strict";
53
+ init_esm_shims();
54
+ CONFIG_TEMPLATE = `import { defineConfig } from 'opencroc';
55
+
56
+ export default defineConfig({
57
+ backendRoot: './backend',
58
+ adapter: 'sequelize',
59
+ llm: {
60
+ provider: 'openai',
61
+ model: 'gpt-4o-mini',
62
+ },
63
+ selfHealing: {
64
+ enabled: true,
65
+ maxIterations: 3,
66
+ },
67
+ });
68
+ `;
69
+ }
70
+ });
71
+
72
+ // src/cli/commands/generate.ts
73
+ var generate_exports = {};
74
+ __export(generate_exports, {
75
+ generate: () => generate
76
+ });
77
+ import chalk2 from "chalk";
78
+ async function generate(opts) {
79
+ console.log(chalk2.cyan("\u{1F40A} OpenCroc \u2014 Generating E2E tests...\n"));
80
+ console.log(chalk2.yellow("Generation pipeline is under development."));
81
+ console.log("Options:", opts);
82
+ }
83
+ var init_generate = __esm({
84
+ "src/cli/commands/generate.ts"() {
85
+ "use strict";
86
+ init_esm_shims();
87
+ }
88
+ });
89
+
90
+ // src/cli/commands/test.ts
91
+ var test_exports = {};
92
+ __export(test_exports, {
93
+ runTests: () => runTests
94
+ });
95
+ import chalk3 from "chalk";
96
+ async function runTests(opts) {
97
+ console.log(chalk3.cyan("\u{1F40A} OpenCroc \u2014 Running E2E tests...\n"));
98
+ console.log(chalk3.yellow("Test runner is under development."));
99
+ console.log("Options:", opts);
100
+ }
101
+ var init_test = __esm({
102
+ "src/cli/commands/test.ts"() {
103
+ "use strict";
104
+ init_esm_shims();
105
+ }
106
+ });
107
+
108
+ // src/cli/commands/validate.ts
109
+ var validate_exports = {};
110
+ __export(validate_exports, {
111
+ validate: () => validate
112
+ });
113
+ import chalk4 from "chalk";
114
+ async function validate(opts) {
115
+ console.log(chalk4.cyan("\u{1F40A} OpenCroc \u2014 Validating configurations...\n"));
116
+ console.log(chalk4.yellow("Validation pipeline is under development."));
117
+ console.log("Options:", opts);
118
+ }
119
+ var init_validate = __esm({
120
+ "src/cli/commands/validate.ts"() {
121
+ "use strict";
122
+ init_esm_shims();
123
+ }
124
+ });
125
+
126
+ // src/cli/commands/heal.ts
127
+ var heal_exports = {};
128
+ __export(heal_exports, {
129
+ heal: () => heal
130
+ });
131
+ import chalk5 from "chalk";
132
+ async function heal(opts) {
133
+ console.log(chalk5.cyan("\u{1F40A} OpenCroc \u2014 Running self-healing loop...\n"));
134
+ console.log(chalk5.yellow("Self-healing loop is under development."));
135
+ console.log("Options:", opts);
136
+ }
137
+ var init_heal = __esm({
138
+ "src/cli/commands/heal.ts"() {
139
+ "use strict";
140
+ init_esm_shims();
141
+ }
142
+ });
143
+
144
+ // src/cli/index.ts
145
+ init_esm_shims();
146
+ import { Command } from "commander";
147
+ var program = new Command();
148
+ program.name("opencroc").description("AI-native E2E testing framework").version("0.1.0");
149
+ program.command("init").description("Initialize OpenCroc in the current project").action(async () => {
150
+ const { initProject: initProject2 } = await Promise.resolve().then(() => (init_init(), init_exports));
151
+ await initProject2();
152
+ });
153
+ program.command("generate").description("Generate E2E test cases from source code").option("-m, --module <name>", "Generate for a specific module").option("-a, --all", "Generate for all discovered modules").option("--steps <steps>", "Run specific pipeline steps (comma-separated)").option("--dry-run", "Preview without writing files").action(async (opts) => {
154
+ const { generate: generate2 } = await Promise.resolve().then(() => (init_generate(), generate_exports));
155
+ await generate2(opts);
156
+ });
157
+ program.command("test").description("Run generated E2E tests").option("-m, --module <name>", "Run tests for a specific module").option("--headed", "Run in headed browser mode").action(async (opts) => {
158
+ const { runTests: runTests2 } = await Promise.resolve().then(() => (init_test(), test_exports));
159
+ await runTests2(opts);
160
+ });
161
+ program.command("validate").description("Validate module configurations and generated tests").option("-m, --module <name>", "Validate a specific module").action(async (opts) => {
162
+ const { validate: validate2 } = await Promise.resolve().then(() => (init_validate(), validate_exports));
163
+ await validate2(opts);
164
+ });
165
+ program.command("heal").description("Run self-healing loop on failed tests").option("-m, --module <name>", "Heal a specific module").option("--max-iterations <n>", "Maximum healing iterations", "3").action(async (opts) => {
166
+ const { heal: heal2 } = await Promise.resolve().then(() => (init_heal(), heal_exports));
167
+ await heal2(opts);
168
+ });
169
+ program.parse();
170
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/cli/commands/init.ts","../../src/cli/commands/generate.ts","../../src/cli/commands/test.ts","../../src/cli/commands/validate.ts","../../src/cli/commands/heal.ts","../../src/cli/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import chalk from 'chalk';\nimport { writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst CONFIG_TEMPLATE = `import { defineConfig } from 'opencroc';\n\nexport default defineConfig({\n backendRoot: './backend',\n adapter: 'sequelize',\n llm: {\n provider: 'openai',\n model: 'gpt-4o-mini',\n },\n selfHealing: {\n enabled: true,\n maxIterations: 3,\n },\n});\n`;\n\nexport async function initProject(): Promise<void> {\n const cwd = process.cwd();\n const configPath = join(cwd, 'opencroc.config.ts');\n\n if (existsSync(configPath)) {\n console.log(chalk.yellow('opencroc.config.ts already exists. Skipping.'));\n return;\n }\n\n writeFileSync(configPath, CONFIG_TEMPLATE, 'utf-8');\n console.log(chalk.green('✓ Created opencroc.config.ts'));\n\n const outDir = join(cwd, 'opencroc-output');\n if (!existsSync(outDir)) {\n mkdirSync(outDir, { recursive: true });\n console.log(chalk.green('✓ Created opencroc-output/'));\n }\n\n console.log('');\n console.log(chalk.cyan('Next steps:'));\n console.log(' 1. Edit opencroc.config.ts with your project settings');\n console.log(' 2. Run: npx opencroc generate --all');\n console.log(' 3. Run: npx opencroc test');\n}\n","import chalk from 'chalk';\n\ninterface GenerateOptions {\n module?: string;\n all?: boolean;\n steps?: string;\n dryRun?: boolean;\n}\n\nexport async function generate(opts: GenerateOptions): Promise<void> {\n console.log(chalk.cyan('🐊 OpenCroc — Generating E2E tests...\\n'));\n\n // TODO: Load config, create pipeline, and run generation\n console.log(chalk.yellow('Generation pipeline is under development.'));\n console.log('Options:', opts);\n}\n","import chalk from 'chalk';\n\ninterface TestOptions {\n module?: string;\n headed?: boolean;\n}\n\nexport async function runTests(opts: TestOptions): Promise<void> {\n console.log(chalk.cyan('🐊 OpenCroc — Running E2E tests...\\n'));\n\n // TODO: Load config, discover generated tests, and run with Playwright\n console.log(chalk.yellow('Test runner is under development.'));\n console.log('Options:', opts);\n}\n","import chalk from 'chalk';\n\ninterface ValidateOptions {\n module?: string;\n}\n\nexport async function validate(opts: ValidateOptions): Promise<void> {\n console.log(chalk.cyan('🐊 OpenCroc — Validating configurations...\\n'));\n\n // TODO: Load config, validate module configs, and report results\n console.log(chalk.yellow('Validation pipeline is under development.'));\n console.log('Options:', opts);\n}\n","import chalk from 'chalk';\n\ninterface HealOptions {\n module?: string;\n maxIterations?: string;\n}\n\nexport async function heal(opts: HealOptions): Promise<void> {\n console.log(chalk.cyan('🐊 OpenCroc — Running self-healing loop...\\n'));\n\n // TODO: Load config, detect failures, and run controlled fix loop\n console.log(chalk.yellow('Self-healing loop is under development.'));\n console.log('Options:', opts);\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\n\nconst program = new Command();\n\nprogram\n .name('opencroc')\n .description('AI-native E2E testing framework')\n .version('0.1.0');\n\nprogram\n .command('init')\n .description('Initialize OpenCroc in the current project')\n .action(async () => {\n const { initProject } = await import('./commands/init.js');\n await initProject();\n });\n\nprogram\n .command('generate')\n .description('Generate E2E test cases from source code')\n .option('-m, --module <name>', 'Generate for a specific module')\n .option('-a, --all', 'Generate for all discovered modules')\n .option('--steps <steps>', 'Run specific pipeline steps (comma-separated)')\n .option('--dry-run', 'Preview without writing files')\n .action(async (opts) => {\n const { generate } = await import('./commands/generate.js');\n await generate(opts);\n });\n\nprogram\n .command('test')\n .description('Run generated E2E tests')\n .option('-m, --module <name>', 'Run tests for a specific module')\n .option('--headed', 'Run in headed browser mode')\n .action(async (opts) => {\n const { runTests } = await import('./commands/test.js');\n await runTests(opts);\n });\n\nprogram\n .command('validate')\n .description('Validate module configurations and generated tests')\n .option('-m, --module <name>', 'Validate a specific module')\n .action(async (opts) => {\n const { validate } = await import('./commands/validate.js');\n await validate(opts);\n });\n\nprogram\n .command('heal')\n .description('Run self-healing loop on failed tests')\n .option('-m, --module <name>', 'Heal a specific module')\n .option('--max-iterations <n>', 'Maximum healing iterations', '3')\n .action(async (opts) => {\n const { heal } = await import('./commands/heal.js');\n await heal(opts);\n });\n\nprogram.parse();\n"],"mappings":"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","names":["chalk","chalk","chalk","chalk","initProject","generate","runTests","validate","heal"]}
@@ -0,0 +1,253 @@
1
+ interface OpenCrocConfig {
2
+ /** Path to the backend source code root */
3
+ backendRoot: string;
4
+ /** Test output directory (default: ./opencroc-output) */
5
+ outDir?: string;
6
+ /** Backend adapter: 'sequelize' | 'typeorm' | 'prisma' | custom BackendAdapter */
7
+ adapter?: string | BackendAdapter;
8
+ /** LLM provider configuration */
9
+ llm?: LlmConfig;
10
+ /** Playwright configuration overrides */
11
+ playwright?: PlaywrightOverrides;
12
+ /** Module filter — only process these modules */
13
+ modules?: string[];
14
+ /** Pipeline step selection */
15
+ steps?: PipelineStep[];
16
+ /** Self-healing configuration */
17
+ selfHealing?: SelfHealingConfig;
18
+ /** Report configuration */
19
+ report?: ReportConfig;
20
+ }
21
+ interface ResolvedConfig extends Required<OpenCrocConfig> {
22
+ _resolved: true;
23
+ }
24
+ interface LlmConfig {
25
+ provider: 'openai' | 'zhipu' | 'ollama' | 'custom';
26
+ apiKey?: string;
27
+ baseUrl?: string;
28
+ model?: string;
29
+ maxTokens?: number;
30
+ temperature?: number;
31
+ }
32
+ interface PlaywrightOverrides {
33
+ baseURL?: string;
34
+ headless?: boolean;
35
+ timeout?: number;
36
+ }
37
+ interface SelfHealingConfig {
38
+ enabled?: boolean;
39
+ maxIterations?: number;
40
+ mode?: 'config-only' | 'config-and-source';
41
+ }
42
+ interface ReportConfig {
43
+ format?: ('html' | 'json' | 'markdown')[];
44
+ outputDir?: string;
45
+ }
46
+ type PipelineStep = 'scan' | 'er-diagram' | 'api-chain' | 'plan' | 'codegen' | 'validate';
47
+ interface ModuleDefinition {
48
+ name: string;
49
+ label?: string;
50
+ modelDir: string;
51
+ controllerDir: string;
52
+ associationFile?: string;
53
+ }
54
+ interface RouteEntry {
55
+ method: string;
56
+ path: string;
57
+ handler: string;
58
+ controllerClass: string;
59
+ }
60
+ interface FieldSchema {
61
+ name: string;
62
+ type: string;
63
+ allowNull?: boolean;
64
+ defaultValue?: unknown;
65
+ primaryKey?: boolean;
66
+ unique?: boolean;
67
+ comment?: string;
68
+ }
69
+ interface TableSchema {
70
+ tableName: string;
71
+ className: string;
72
+ fields: FieldSchema[];
73
+ indexes?: IndexSchema[];
74
+ }
75
+ interface IndexSchema {
76
+ name?: string;
77
+ unique?: boolean;
78
+ fields: string[];
79
+ }
80
+ interface ForeignKeyRelation {
81
+ sourceTable: string;
82
+ targetTable: string;
83
+ sourceColumn: string;
84
+ targetColumn: string;
85
+ type: 'belongsTo' | 'hasMany' | 'hasOne' | 'belongsToMany';
86
+ }
87
+ interface ApiEndpoint {
88
+ method: string;
89
+ path: string;
90
+ handler: string;
91
+ module: string;
92
+ params?: string[];
93
+ bodyFields?: string[];
94
+ }
95
+ interface ApiDependency {
96
+ from: ApiEndpoint;
97
+ to: ApiEndpoint;
98
+ reason: string;
99
+ }
100
+ interface ERDiagramResult {
101
+ tables: TableSchema[];
102
+ relations: ForeignKeyRelation[];
103
+ mermaidText: string;
104
+ }
105
+ interface TestStep {
106
+ order: number;
107
+ action: string;
108
+ endpoint: ApiEndpoint;
109
+ description: string;
110
+ assertions: string[];
111
+ }
112
+ interface TestChain {
113
+ name: string;
114
+ module: string;
115
+ steps: TestStep[];
116
+ }
117
+ interface ChainPlanResult {
118
+ chains: TestChain[];
119
+ totalSteps: number;
120
+ }
121
+ interface GeneratedTestFile {
122
+ filePath: string;
123
+ content: string;
124
+ module: string;
125
+ chain: string;
126
+ }
127
+ interface PipelineRunResult {
128
+ modules: string[];
129
+ erDiagrams: Map<string, ERDiagramResult>;
130
+ chainPlans: Map<string, ChainPlanResult>;
131
+ generatedFiles: GeneratedTestFile[];
132
+ validationErrors: ValidationError[];
133
+ duration: number;
134
+ }
135
+ interface ChainFailureResult {
136
+ chain: string;
137
+ failedStep: number;
138
+ error: string;
139
+ rootCause?: string;
140
+ impactedChains: string[];
141
+ }
142
+ interface ImpactReport {
143
+ affectedModules: string[];
144
+ affectedChains: string[];
145
+ affectedEndpoints: ApiEndpoint[];
146
+ mermaidText: string;
147
+ }
148
+ interface ValidationError {
149
+ module: string;
150
+ field: string;
151
+ message: string;
152
+ severity: 'error' | 'warning';
153
+ }
154
+ interface BackendAdapter {
155
+ name: string;
156
+ parseModels(dir: string): Promise<TableSchema[]>;
157
+ parseAssociations(file: string): Promise<ForeignKeyRelation[]>;
158
+ parseControllers(dir: string): Promise<RouteEntry[]>;
159
+ }
160
+ interface LlmProvider {
161
+ name: string;
162
+ chat(messages: Array<{
163
+ role: string;
164
+ content: string;
165
+ }>): Promise<string>;
166
+ estimateTokens(text: string): number;
167
+ }
168
+
169
+ /**
170
+ * Define an OpenCroc configuration with type checking.
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * // opencroc.config.ts
175
+ * import { defineConfig } from 'opencroc';
176
+ *
177
+ * export default defineConfig({
178
+ * backendRoot: './backend',
179
+ * adapter: 'sequelize',
180
+ * llm: {
181
+ * provider: 'openai',
182
+ * model: 'gpt-4o-mini',
183
+ * },
184
+ * });
185
+ * ```
186
+ */
187
+ declare function defineConfig(config: OpenCrocConfig): OpenCrocConfig;
188
+
189
+ interface Pipeline {
190
+ run(steps?: PipelineStep[]): Promise<PipelineRunResult>;
191
+ }
192
+ declare function createPipeline(_config: OpenCrocConfig): Pipeline;
193
+
194
+ interface ModelParser {
195
+ parseFile(filePath: string): Promise<TableSchema>;
196
+ parseDirectory(dirPath: string): Promise<TableSchema[]>;
197
+ }
198
+ declare function createModelParser(): ModelParser;
199
+
200
+ interface ControllerParser {
201
+ parseFile(filePath: string): Promise<RouteEntry[]>;
202
+ parseDirectory(dirPath: string): Promise<RouteEntry[]>;
203
+ }
204
+ declare function createControllerParser(): ControllerParser;
205
+
206
+ interface AssociationParser {
207
+ parseFile(filePath: string): Promise<ForeignKeyRelation[]>;
208
+ }
209
+ declare function createAssociationParser(): AssociationParser;
210
+
211
+ interface TestCodeGenerator {
212
+ generate(chains: TestChain[]): GeneratedTestFile[];
213
+ }
214
+ declare function createTestCodeGenerator(): TestCodeGenerator;
215
+
216
+ interface MockDataGenerator {
217
+ generateForTable(schema: TableSchema): Record<string, unknown>;
218
+ generateForTables(schemas: TableSchema[]): Map<string, Record<string, unknown>[]>;
219
+ }
220
+ declare function createMockDataGenerator(): MockDataGenerator;
221
+
222
+ interface ERDiagramGenerator {
223
+ generate(tables: TableSchema[], relations: ForeignKeyRelation[]): ERDiagramResult;
224
+ }
225
+ declare function createERDiagramGenerator(): ERDiagramGenerator;
226
+
227
+ interface ApiChainAnalyzer {
228
+ analyze(endpoints: ApiEndpoint[]): {
229
+ dependencies: ApiDependency[];
230
+ topologicalOrder: ApiEndpoint[];
231
+ };
232
+ }
233
+ declare function createApiChainAnalyzer(): ApiChainAnalyzer;
234
+
235
+ interface ImpactReporter {
236
+ analyze(failedEndpoints: string[]): Promise<ImpactReport>;
237
+ }
238
+ declare function createImpactReporter(): ImpactReporter;
239
+
240
+ declare function validateConfig(_config: Record<string, unknown>): ValidationError[];
241
+
242
+ interface SelfHealingLoop {
243
+ run(testResultsDir: string): Promise<SelfHealingResult>;
244
+ }
245
+ interface SelfHealingResult {
246
+ iterations: number;
247
+ fixed: string[];
248
+ remaining: string[];
249
+ totalTokensUsed: number;
250
+ }
251
+ declare function createSelfHealingLoop(_config: SelfHealingConfig): SelfHealingLoop;
252
+
253
+ export { type ApiDependency, type ApiEndpoint, type BackendAdapter, type ChainFailureResult, type ChainPlanResult, type ERDiagramResult, type FieldSchema, type ForeignKeyRelation, type GeneratedTestFile, type ImpactReport, type LlmProvider, type ModuleDefinition, type OpenCrocConfig, type PipelineRunResult, type ResolvedConfig, type RouteEntry, type TableSchema, type TestChain, type TestStep, createApiChainAnalyzer, createAssociationParser, createControllerParser, createERDiagramGenerator, createImpactReporter, createMockDataGenerator, createModelParser, createPipeline, createSelfHealingLoop, createTestCodeGenerator, defineConfig, validateConfig };
package/dist/index.js ADDED
@@ -0,0 +1,123 @@
1
+ // src/config.ts
2
+ function defineConfig(config) {
3
+ return config;
4
+ }
5
+
6
+ // src/pipeline/index.ts
7
+ function createPipeline(_config) {
8
+ return {
9
+ async run(_steps) {
10
+ throw new Error("Pipeline not yet implemented");
11
+ }
12
+ };
13
+ }
14
+
15
+ // src/parsers/model-parser.ts
16
+ function createModelParser() {
17
+ return {
18
+ async parseFile(_filePath) {
19
+ throw new Error("Model parser not yet implemented");
20
+ },
21
+ async parseDirectory(_dirPath) {
22
+ throw new Error("Model parser not yet implemented");
23
+ }
24
+ };
25
+ }
26
+
27
+ // src/parsers/controller-parser.ts
28
+ function createControllerParser() {
29
+ return {
30
+ async parseFile(_filePath) {
31
+ throw new Error("Controller parser not yet implemented");
32
+ },
33
+ async parseDirectory(_dirPath) {
34
+ throw new Error("Controller parser not yet implemented");
35
+ }
36
+ };
37
+ }
38
+
39
+ // src/parsers/association-parser.ts
40
+ function createAssociationParser() {
41
+ return {
42
+ async parseFile(_filePath) {
43
+ throw new Error("Association parser not yet implemented");
44
+ }
45
+ };
46
+ }
47
+
48
+ // src/generators/test-code-generator.ts
49
+ function createTestCodeGenerator() {
50
+ return {
51
+ generate(_chains) {
52
+ throw new Error("Test code generator not yet implemented");
53
+ }
54
+ };
55
+ }
56
+
57
+ // src/generators/mock-data-generator.ts
58
+ function createMockDataGenerator() {
59
+ return {
60
+ generateForTable(_schema) {
61
+ throw new Error("Mock data generator not yet implemented");
62
+ },
63
+ generateForTables(_schemas) {
64
+ throw new Error("Mock data generator not yet implemented");
65
+ }
66
+ };
67
+ }
68
+
69
+ // src/generators/er-diagram-generator.ts
70
+ function createERDiagramGenerator() {
71
+ return {
72
+ generate(_tables, _relations) {
73
+ throw new Error("ER diagram generator not yet implemented");
74
+ }
75
+ };
76
+ }
77
+
78
+ // src/analyzers/api-chain-analyzer.ts
79
+ function createApiChainAnalyzer() {
80
+ return {
81
+ analyze(_endpoints) {
82
+ throw new Error("API chain analyzer not yet implemented");
83
+ }
84
+ };
85
+ }
86
+
87
+ // src/analyzers/impact-reporter.ts
88
+ function createImpactReporter() {
89
+ return {
90
+ async analyze(_failedEndpoints) {
91
+ throw new Error("Impact reporter not yet implemented");
92
+ }
93
+ };
94
+ }
95
+
96
+ // src/validators/config-validator.ts
97
+ function validateConfig(_config) {
98
+ return [];
99
+ }
100
+
101
+ // src/self-healing/index.ts
102
+ function createSelfHealingLoop(_config) {
103
+ return {
104
+ async run(_testResultsDir) {
105
+ throw new Error("Self-healing loop not yet implemented");
106
+ }
107
+ };
108
+ }
109
+ export {
110
+ createApiChainAnalyzer,
111
+ createAssociationParser,
112
+ createControllerParser,
113
+ createERDiagramGenerator,
114
+ createImpactReporter,
115
+ createMockDataGenerator,
116
+ createModelParser,
117
+ createPipeline,
118
+ createSelfHealingLoop,
119
+ createTestCodeGenerator,
120
+ defineConfig,
121
+ validateConfig
122
+ };
123
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts","../src/pipeline/index.ts","../src/parsers/model-parser.ts","../src/parsers/controller-parser.ts","../src/parsers/association-parser.ts","../src/generators/test-code-generator.ts","../src/generators/mock-data-generator.ts","../src/generators/er-diagram-generator.ts","../src/analyzers/api-chain-analyzer.ts","../src/analyzers/impact-reporter.ts","../src/validators/config-validator.ts","../src/self-healing/index.ts"],"sourcesContent":["import type { OpenCrocConfig } from './types.js';\n\n/**\n * Define an OpenCroc configuration with type checking.\n *\n * @example\n * ```ts\n * // opencroc.config.ts\n * import { defineConfig } from 'opencroc';\n *\n * export default defineConfig({\n * backendRoot: './backend',\n * adapter: 'sequelize',\n * llm: {\n * provider: 'openai',\n * model: 'gpt-4o-mini',\n * },\n * });\n * ```\n */\nexport function defineConfig(config: OpenCrocConfig): OpenCrocConfig {\n return config;\n}\n","import type {\n OpenCrocConfig,\n PipelineRunResult,\n PipelineStep,\n} from '../types.js';\n\nexport interface Pipeline {\n run(steps?: PipelineStep[]): Promise<PipelineRunResult>;\n}\n\nexport function createPipeline(_config: OpenCrocConfig): Pipeline {\n return {\n async run(_steps) {\n // TODO: Implement 6-stage pipeline\n // 1. Scan — discover modules via adapter\n // 2. ER Diagram — parse models and generate relationship graphs\n // 3. API Chain — analyze controller routes and build dependency DAG\n // 4. Plan — generate test chains with topological ordering\n // 5. Codegen — emit Playwright test files from chain plans\n // 6. Validate — run multi-layer validation on generated configs\n throw new Error('Pipeline not yet implemented');\n },\n };\n}\n","import type { TableSchema } from '../types.js';\n\nexport interface ModelParser {\n parseFile(filePath: string): Promise<TableSchema>;\n parseDirectory(dirPath: string): Promise<TableSchema[]>;\n}\n\nexport function createModelParser(): ModelParser {\n return {\n async parseFile(_filePath) {\n // TODO: Use ts-morph to parse Sequelize/TypeORM/Prisma model files\n throw new Error('Model parser not yet implemented');\n },\n async parseDirectory(_dirPath) {\n throw new Error('Model parser not yet implemented');\n },\n };\n}\n","import type { RouteEntry } from '../types.js';\n\nexport interface ControllerParser {\n parseFile(filePath: string): Promise<RouteEntry[]>;\n parseDirectory(dirPath: string): Promise<RouteEntry[]>;\n}\n\nexport function createControllerParser(): ControllerParser {\n return {\n async parseFile(_filePath) {\n // TODO: Use ts-morph to extract route definitions from controllers\n throw new Error('Controller parser not yet implemented');\n },\n async parseDirectory(_dirPath) {\n throw new Error('Controller parser not yet implemented');\n },\n };\n}\n","import type { ForeignKeyRelation } from '../types.js';\n\nexport interface AssociationParser {\n parseFile(filePath: string): Promise<ForeignKeyRelation[]>;\n}\n\nexport function createAssociationParser(): AssociationParser {\n return {\n async parseFile(_filePath) {\n // TODO: Use ts-morph to extract association definitions\n throw new Error('Association parser not yet implemented');\n },\n };\n}\n","import type { GeneratedTestFile, TestChain } from '../types.js';\n\nexport interface TestCodeGenerator {\n generate(chains: TestChain[]): GeneratedTestFile[];\n}\n\nexport function createTestCodeGenerator(): TestCodeGenerator {\n return {\n generate(_chains) {\n // TODO: Generate Playwright test files from chain plans\n throw new Error('Test code generator not yet implemented');\n },\n };\n}\n","import type { TableSchema } from '../types.js';\n\nexport interface MockDataGenerator {\n generateForTable(schema: TableSchema): Record<string, unknown>;\n generateForTables(schemas: TableSchema[]): Map<string, Record<string, unknown>[]>;\n}\n\nexport function createMockDataGenerator(): MockDataGenerator {\n return {\n generateForTable(_schema) {\n // TODO: Generate realistic mock data based on field types and constraints\n throw new Error('Mock data generator not yet implemented');\n },\n generateForTables(_schemas) {\n throw new Error('Mock data generator not yet implemented');\n },\n };\n}\n","import type { ERDiagramResult, TableSchema, ForeignKeyRelation } from '../types.js';\n\nexport interface ERDiagramGenerator {\n generate(tables: TableSchema[], relations: ForeignKeyRelation[]): ERDiagramResult;\n}\n\nexport function createERDiagramGenerator(): ERDiagramGenerator {\n return {\n generate(_tables, _relations) {\n // TODO: Generate Mermaid ER diagram from parsed schemas\n throw new Error('ER diagram generator not yet implemented');\n },\n };\n}\n","import type { ApiEndpoint, ApiDependency } from '../types.js';\n\nexport interface ApiChainAnalyzer {\n analyze(endpoints: ApiEndpoint[]): {\n dependencies: ApiDependency[];\n topologicalOrder: ApiEndpoint[];\n };\n}\n\nexport function createApiChainAnalyzer(): ApiChainAnalyzer {\n return {\n analyze(_endpoints) {\n // TODO: Build DAG of API dependencies and compute topological sort\n throw new Error('API chain analyzer not yet implemented');\n },\n };\n}\n","import type { ImpactReport } from '../types.js';\n\nexport interface ImpactReporter {\n analyze(failedEndpoints: string[]): Promise<ImpactReport>;\n}\n\nexport function createImpactReporter(): ImpactReporter {\n return {\n async analyze(_failedEndpoints) {\n // TODO: Trace failure impact through dependency chains\n throw new Error('Impact reporter not yet implemented');\n },\n };\n}\n","import type { ValidationError } from '../types.js';\n\nexport function validateConfig(_config: Record<string, unknown>): ValidationError[] {\n // TODO: Implement 3-layer validation (schema → semantic → dry-run)\n return [];\n}\n","import type { SelfHealingConfig } from '../types.js';\n\nexport interface SelfHealingLoop {\n run(testResultsDir: string): Promise<SelfHealingResult>;\n}\n\nexport interface SelfHealingResult {\n iterations: number;\n fixed: string[];\n remaining: string[];\n totalTokensUsed: number;\n}\n\nexport function createSelfHealingLoop(_config: SelfHealingConfig): SelfHealingLoop {\n return {\n async run(_testResultsDir) {\n // TODO: Implement the dialog loop:\n // 1. Parse test failures\n // 2. Attribute root cause via LLM\n // 3. Generate controlled fix (config-only or config-and-source)\n // 4. Re-run tests\n // 5. Repeat until success or max iterations\n throw new Error('Self-healing loop not yet implemented');\n },\n };\n}\n"],"mappings":";AAoBO,SAAS,aAAa,QAAwC;AACnE,SAAO;AACT;;;ACZO,SAAS,eAAe,SAAmC;AAChE,SAAO;AAAA,IACL,MAAM,IAAI,QAAQ;AAQhB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAAA,EACF;AACF;;;AChBO,SAAS,oBAAiC;AAC/C,SAAO;AAAA,IACL,MAAM,UAAU,WAAW;AAEzB,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAAA,IACA,MAAM,eAAe,UAAU;AAC7B,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAAA,EACF;AACF;;;ACVO,SAAS,yBAA2C;AACzD,SAAO;AAAA,IACL,MAAM,UAAU,WAAW;AAEzB,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAAA,IACA,MAAM,eAAe,UAAU;AAC7B,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAAA,EACF;AACF;;;ACXO,SAAS,0BAA6C;AAC3D,SAAO;AAAA,IACL,MAAM,UAAU,WAAW;AAEzB,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAAA,EACF;AACF;;;ACPO,SAAS,0BAA6C;AAC3D,SAAO;AAAA,IACL,SAAS,SAAS;AAEhB,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAAA,EACF;AACF;;;ACNO,SAAS,0BAA6C;AAC3D,SAAO;AAAA,IACL,iBAAiB,SAAS;AAExB,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAAA,IACA,kBAAkB,UAAU;AAC1B,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAAA,EACF;AACF;;;ACXO,SAAS,2BAA+C;AAC7D,SAAO;AAAA,IACL,SAAS,SAAS,YAAY;AAE5B,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AAAA,EACF;AACF;;;ACJO,SAAS,yBAA2C;AACzD,SAAO;AAAA,IACL,QAAQ,YAAY;AAElB,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAAA,EACF;AACF;;;ACVO,SAAS,uBAAuC;AACrD,SAAO;AAAA,IACL,MAAM,QAAQ,kBAAkB;AAE9B,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAAA,EACF;AACF;;;ACXO,SAAS,eAAe,SAAqD;AAElF,SAAO,CAAC;AACV;;;ACQO,SAAS,sBAAsB,SAA6C;AACjF,SAAO;AAAA,IACL,MAAM,IAAI,iBAAiB;AAOzB,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAAA,EACF;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "opencroc",
3
+ "version": "0.1.6",
4
+ "description": "AI-native E2E testing framework — source-aware test generation, intelligent validation, and self-healing",
5
+ "keywords": [
6
+ "e2e",
7
+ "testing",
8
+ "ai",
9
+ "playwright",
10
+ "test-generation",
11
+ "self-healing",
12
+ "source-aware"
13
+ ],
14
+ "homepage": "https://opencroc.com",
15
+ "bugs": {
16
+ "url": "https://github.com/opencroc/opencroc/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/opencroc/opencroc.git"
21
+ },
22
+ "license": "MIT",
23
+ "author": "OpenCroc Contributors",
24
+ "type": "module",
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "bin": {
28
+ "opencroc": "./dist/cli/index.js"
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "scripts": {
36
+ "build": "tsup",
37
+ "dev": "tsup --watch",
38
+ "lint": "eslint src/",
39
+ "lint:fix": "eslint src/ --fix",
40
+ "test": "vitest run",
41
+ "test:watch": "vitest",
42
+ "test:coverage": "vitest run --coverage",
43
+ "typecheck": "tsc --noEmit",
44
+ "prepublishOnly": "npm run build"
45
+ },
46
+ "dependencies": {
47
+ "chalk": "^5.3.0",
48
+ "commander": "^12.1.0",
49
+ "cosmiconfig": "^9.0.0",
50
+ "glob": "^10.3.10",
51
+ "ts-morph": "^22.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^20.11.0",
55
+ "eslint": "^9.0.0",
56
+ "tsup": "^8.0.0",
57
+ "typescript": "^5.4.0",
58
+ "vitest": "^1.6.0"
59
+ },
60
+ "peerDependencies": {
61
+ "@playwright/test": ">=1.40.0"
62
+ },
63
+ "peerDependenciesMeta": {
64
+ "@playwright/test": {
65
+ "optional": false
66
+ }
67
+ },
68
+ "engines": {
69
+ "node": ">=18.0.0"
70
+ }
71
+ }