@mknrt/autotests-overkill 1.1.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 +117 -0
- package/assets/overkill-logo.svg +8 -0
- package/assets/overkill-small.svg +8 -0
- package/dist/connectors/index.d.ts +4 -0
- package/dist/connectors/index.js +4 -0
- package/dist/indexer/index.d.ts +4 -0
- package/dist/indexer/index.js +4 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +2 -0
- package/dist/src/appContext.d.ts +21 -0
- package/dist/src/appContext.js +40 -0
- package/dist/src/cli/indexKnowledge.d.ts +1 -0
- package/dist/src/cli/indexKnowledge.js +11 -0
- package/dist/src/cli/main.d.ts +19 -0
- package/dist/src/cli/main.js +59 -0
- package/dist/src/cli/runAcceptance.d.ts +21 -0
- package/dist/src/cli/runAcceptance.js +131 -0
- package/dist/src/cli/runMcpServer.d.ts +1 -0
- package/dist/src/cli/runMcpServer.js +10 -0
- package/dist/src/cli/shared.d.ts +1 -0
- package/dist/src/cli/shared.js +7 -0
- package/dist/src/config/consumerConfig.d.ts +126 -0
- package/dist/src/config/consumerConfig.js +63 -0
- package/dist/src/connectors/autotests2Connector.d.ts +41 -0
- package/dist/src/connectors/autotests2Connector.js +94 -0
- package/dist/src/connectors/caseplatformConnector.d.ts +35 -0
- package/dist/src/connectors/caseplatformConnector.js +251 -0
- package/dist/src/connectors/ciArtifactsConnector.d.ts +23 -0
- package/dist/src/connectors/ciArtifactsConnector.js +14 -0
- package/dist/src/connectors/diffConnector.d.ts +1 -0
- package/dist/src/connectors/diffConnector.js +4 -0
- package/dist/src/connectors/filesystemConnector.d.ts +4 -0
- package/dist/src/connectors/filesystemConnector.js +15 -0
- package/dist/src/connectors/gitlabConnector.d.ts +14 -0
- package/dist/src/connectors/gitlabConnector.js +64 -0
- package/dist/src/connectors/reportPortalConnector.d.ts +14 -0
- package/dist/src/connectors/reportPortalConnector.js +84 -0
- package/dist/src/contracts/confidence.d.ts +8 -0
- package/dist/src/contracts/confidence.js +33 -0
- package/dist/src/contracts/errors.d.ts +6 -0
- package/dist/src/contracts/errors.js +18 -0
- package/dist/src/contracts/toolOutput.d.ts +113 -0
- package/dist/src/contracts/toolOutput.js +35 -0
- package/dist/src/domain/analyzeDiffImpact.d.ts +22 -0
- package/dist/src/domain/analyzeDiffImpact.js +52 -0
- package/dist/src/domain/analyzeTestGaps.d.ts +22 -0
- package/dist/src/domain/analyzeTestGaps.js +41 -0
- package/dist/src/domain/buildRerunScope.d.ts +23 -0
- package/dist/src/domain/buildRerunScope.js +17 -0
- package/dist/src/domain/buildSetupTeardownPlan.d.ts +23 -0
- package/dist/src/domain/buildSetupTeardownPlan.js +13 -0
- package/dist/src/domain/findExistingTestAssets.d.ts +22 -0
- package/dist/src/domain/findExistingTestAssets.js +50 -0
- package/dist/src/domain/findFrontendContract.d.ts +22 -0
- package/dist/src/domain/findFrontendContract.js +13 -0
- package/dist/src/domain/findFrontendRuntimeLogic.d.ts +22 -0
- package/dist/src/domain/findFrontendRuntimeLogic.js +28 -0
- package/dist/src/domain/findTestAreaContext.d.ts +23 -0
- package/dist/src/domain/findTestAreaContext.js +30 -0
- package/dist/src/domain/generateSpecBlueprint.d.ts +23 -0
- package/dist/src/domain/generateSpecBlueprint.js +213 -0
- package/dist/src/domain/mapFeatureToExistingCoverage.d.ts +22 -0
- package/dist/src/domain/mapFeatureToExistingCoverage.js +56 -0
- package/dist/src/domain/recommendSelectorStrategy.d.ts +22 -0
- package/dist/src/domain/recommendSelectorStrategy.js +13 -0
- package/dist/src/domain/shared.d.ts +5 -0
- package/dist/src/domain/shared.js +36 -0
- package/dist/src/domain/summarizeCiContext.d.ts +22 -0
- package/dist/src/domain/summarizeCiContext.js +35 -0
- package/dist/src/domain/triageFailedRun.d.ts +25 -0
- package/dist/src/domain/triageFailedRun.js +46 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +4 -0
- package/dist/src/indexer/extractors/frontendContractExtractor.d.ts +17 -0
- package/dist/src/indexer/extractors/frontendContractExtractor.js +109 -0
- package/dist/src/indexer/extractors/frontendRuntimeExtractor.d.ts +14 -0
- package/dist/src/indexer/extractors/frontendRuntimeExtractor.js +110 -0
- package/dist/src/indexer/extractors/testAssetExtractor.d.ts +13 -0
- package/dist/src/indexer/extractors/testAssetExtractor.js +17 -0
- package/dist/src/indexer/refreshPipeline.d.ts +12 -0
- package/dist/src/indexer/refreshPipeline.js +156 -0
- package/dist/src/indexer/snapshotStore.d.ts +10 -0
- package/dist/src/indexer/snapshotStore.js +45 -0
- package/dist/src/knowledge/database.d.ts +3 -0
- package/dist/src/knowledge/database.js +8 -0
- package/dist/src/knowledge/migrations.d.ts +1 -0
- package/dist/src/knowledge/migrations.js +28 -0
- package/dist/src/knowledge/repositories.d.ts +28 -0
- package/dist/src/knowledge/repositories.js +78 -0
- package/dist/src/mcp/registerTools.d.ts +11 -0
- package/dist/src/mcp/registerTools.js +118 -0
- package/dist/src/mcp/server.d.ts +4 -0
- package/dist/src/mcp/server.js +29 -0
- package/dist/src/utils/fileUtils.d.ts +4 -0
- package/dist/src/utils/fileUtils.js +16 -0
- package/dist/src/utils/pathUtils.d.ts +7 -0
- package/dist/src/utils/pathUtils.js +59 -0
- package/dist/src/utils/textUtils.d.ts +3 -0
- package/dist/src/utils/textUtils.js +26 -0
- package/docs/architecture/overview.md +31 -0
- package/docs/consumer-integration.md +64 -0
- package/docs/operator-cookbook.md +39 -0
- package/docs/plugin-packaging.md +33 -0
- package/docs/superpowers/plans/2026-04-19-autotests-overkill-v1.md +600 -0
- package/docs/tool-catalog.md +34 -0
- package/overkill.config.example.json +16 -0
- package/package.json +73 -0
- package/skills/overkill-debug-failure/SKILL.md +13 -0
- package/skills/overkill-find-gaps/SKILL.md +13 -0
- package/skills/overkill-generate-setup/SKILL.md +12 -0
- package/skills/overkill-generate-test/SKILL.md +15 -0
- package/skills/overkill-impact-analysis/SKILL.md +12 -0
- package/skills/overkill-onboard/SKILL.md +16 -0
- package/skills/overkill-prompt-builder/SKILL.md +13 -0
- package/skills/overkill-reuse-project-patterns/SKILL.md +13 -0
- package/skills/overkill-review-test-draft/SKILL.md +10 -0
- package/templates/prompts/debug-failure.md +3 -0
- package/templates/prompts/find-gaps.md +3 -0
- package/templates/prompts/generate-test.md +3 -0
- package/templates/prompts/impact-analysis.md +3 -0
- package/templates/spec-blueprints/default.md +39 -0
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
# Autotests Ultimate Testing Overkill v1 Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Build a production-ready standalone Node.js platform that indexes `autotests2`, `caseplatform-web`, and CI artifacts, exposes normalized MCP tools for testing intelligence, and ships Codex-oriented skills/templates without mutating consumer repositories by default.
|
|
6
|
+
|
|
7
|
+
**Architecture:** The repository will be a TypeScript Node.js workspace with a thin MCP server over focused domain services. Data flows through configurable connectors into a SQLite + FTS knowledge store plus JSON snapshots; each MCP tool is a small orchestration layer over reusable analyzers, not a monolithic “smart tool”. Skills and prompt templates sit on top of tool contracts, while integration docs and sample consumer config keep `autotests2` as a consumer, not a host.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Node.js, TypeScript, `@modelcontextprotocol/server`, `zod`, `better-sqlite3`, SQLite FTS5, `fast-glob`, `typescript`, `tsx`, `vitest`
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## File Structure
|
|
14
|
+
|
|
15
|
+
- `package.json`: scripts, dependency graph, local dev workflow
|
|
16
|
+
- `tsconfig.json`: compiler settings for strict TypeScript output
|
|
17
|
+
- `vitest.config.ts`: unit/integration test runner configuration
|
|
18
|
+
- `src/config/`: consumer config schema, defaults, loader, path helpers
|
|
19
|
+
- `src/contracts/`: normalized MCP output schema, tool input schemas, confidence/error model
|
|
20
|
+
- `src/connectors/`: adapters for repo files, CI artifacts, ReportPortal metadata sources
|
|
21
|
+
- `src/indexer/`: repo scanners, extractors, SQLite persistence, snapshot refresh pipeline
|
|
22
|
+
- `src/knowledge/`: schema migrations, FTS queries, repositories, search primitives
|
|
23
|
+
- `src/domain/`: bounded services for contracts, coverage, failures, diff impact, spec generation
|
|
24
|
+
- `src/mcp/`: MCP server bootstrap and per-tool registration modules
|
|
25
|
+
- `src/templates/`: blueprint builders, prompt stubs, skill-facing templates
|
|
26
|
+
- `skills/`: Codex skill bundle for end-to-end workflows
|
|
27
|
+
- `templates/`: human-readable prompt workflows and example requests
|
|
28
|
+
- `docs/`: architecture, onboarding, operator cookbook, consumer integration guide
|
|
29
|
+
- `tests/`: unit tests, fixture-backed integration tests, acceptance tests against real adjacent repos
|
|
30
|
+
- `fixtures/`: captured test data and minimal snapshots for deterministic tests
|
|
31
|
+
|
|
32
|
+
## Discovery Facts Locked In
|
|
33
|
+
|
|
34
|
+
- `C:\gitrep\autotests-overkill` is not yet a git repository and currently contains only `PLAN.md`.
|
|
35
|
+
- `C:\gitrep\autotests2` contains real Cypress specs, support commands, selectors, fixtures, `.codex/context.md`, `.codex/testing.md`, GitLab CI config, ReportPortal config, and local run artifacts under `cypress/reports`, `cypress/screenshots`, `cypress/videos`, and `cypress/logs`.
|
|
36
|
+
- `C:\gitrep\caseplatform-web` contains real FormRunner and VCM widget sources. Example evidence target: `vcm/jqVCM/widget/caption/CaptionControl.ts`, `CaptionSingleton.ts`, and `CaptionHandlers.ts`.
|
|
37
|
+
- Real coverage target exists in `autotests2`: `cypress/e2e/tests/formRunner/vcm/captions/caption.cy.js` and `captionInContainers.cy.js`.
|
|
38
|
+
- Real CI summary input exists in `autotests2/cypress/reports/test-stats.json`, screenshots, videos, API capture JSON, and `.gitlab-ci/stage-collect-artifacts/artifacts.yml`.
|
|
39
|
+
|
|
40
|
+
## Public Contracts To Implement
|
|
41
|
+
|
|
42
|
+
- Consumer config file: `overkill.config.json`
|
|
43
|
+
- MCP tool output envelope:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
type NormalizedToolOutput = {
|
|
47
|
+
summary: string;
|
|
48
|
+
evidence: Array<{
|
|
49
|
+
type: 'file' | 'symbol' | 'test' | 'artifact' | 'report' | 'diff' | 'config';
|
|
50
|
+
label: string;
|
|
51
|
+
path?: string;
|
|
52
|
+
locator?: string;
|
|
53
|
+
snippet?: string;
|
|
54
|
+
metadata?: Record<string, unknown>;
|
|
55
|
+
}>;
|
|
56
|
+
recommended_actions: string[];
|
|
57
|
+
repo_paths: string[];
|
|
58
|
+
confidence: {
|
|
59
|
+
score: number;
|
|
60
|
+
level: 'low' | 'medium' | 'high';
|
|
61
|
+
rationale: string[];
|
|
62
|
+
};
|
|
63
|
+
warnings: string[];
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- Tool registration surface:
|
|
68
|
+
- `find_existing_test_assets`
|
|
69
|
+
- `find_test_area_context`
|
|
70
|
+
- `find_frontend_contract`
|
|
71
|
+
- `find_frontend_runtime_logic`
|
|
72
|
+
- `map_feature_to_existing_coverage`
|
|
73
|
+
- `analyze_test_gaps`
|
|
74
|
+
- `generate_spec_blueprint`
|
|
75
|
+
- `recommend_selector_strategy`
|
|
76
|
+
- `build_setup_teardown_plan`
|
|
77
|
+
- `analyze_diff_impact`
|
|
78
|
+
- `triage_failed_run`
|
|
79
|
+
- `build_rerun_scope`
|
|
80
|
+
- `summarize_ci_context`
|
|
81
|
+
- Skill entrypoints:
|
|
82
|
+
- `overkill-generate-test`
|
|
83
|
+
- `overkill-find-gaps`
|
|
84
|
+
- `overkill-reuse-project-patterns`
|
|
85
|
+
- `overkill-generate-setup`
|
|
86
|
+
- `overkill-impact-analysis`
|
|
87
|
+
- `overkill-debug-failure`
|
|
88
|
+
- `overkill-review-test-draft`
|
|
89
|
+
- `overkill-onboard`
|
|
90
|
+
- `overkill-prompt-builder`
|
|
91
|
+
|
|
92
|
+
### Task 1: Bootstrap Repository Foundations
|
|
93
|
+
|
|
94
|
+
**Files:**
|
|
95
|
+
- Create: `package.json`
|
|
96
|
+
- Create: `tsconfig.json`
|
|
97
|
+
- Create: `vitest.config.ts`
|
|
98
|
+
- Create: `.gitignore`
|
|
99
|
+
- Create: `src/index.ts`
|
|
100
|
+
- Create: `src/config/consumerConfig.ts`
|
|
101
|
+
- Create: `src/contracts/toolOutput.ts`
|
|
102
|
+
- Create: `src/contracts/confidence.ts`
|
|
103
|
+
- Create: `src/contracts/errors.ts`
|
|
104
|
+
- Create: `docs/architecture/overview.md`
|
|
105
|
+
- Test: `tests/config/consumerConfig.test.ts`
|
|
106
|
+
|
|
107
|
+
- [ ] **Step 1: Write the failing config/schema test**
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { describe, expect, it } from 'vitest';
|
|
111
|
+
import { parseConsumerConfig } from '../../src/config/consumerConfig';
|
|
112
|
+
|
|
113
|
+
describe('parseConsumerConfig', () => {
|
|
114
|
+
it('normalizes repo roots and artifact locations', () => {
|
|
115
|
+
const result = parseConsumerConfig({
|
|
116
|
+
repos: {
|
|
117
|
+
autotests2: '../autotests2',
|
|
118
|
+
caseplatformWeb: '../caseplatform-web',
|
|
119
|
+
},
|
|
120
|
+
ci: {
|
|
121
|
+
artifactsRoot: '../autotests2/cypress',
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
expect(result.repos.autotests2).toContain('autotests2');
|
|
126
|
+
expect(result.repos.caseplatformWeb).toContain('caseplatform-web');
|
|
127
|
+
expect(result.ci.artifactsRoot).toContain('cypress');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- [ ] **Step 2: Run the test to verify it fails**
|
|
133
|
+
|
|
134
|
+
Run: `npm run test -- tests/config/consumerConfig.test.ts`
|
|
135
|
+
Expected: FAIL because `parseConsumerConfig` does not exist yet.
|
|
136
|
+
|
|
137
|
+
- [ ] **Step 3: Implement the minimal foundation**
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
export function parseConsumerConfig(input: ConsumerConfigInput): ConsumerConfig {
|
|
141
|
+
const parsed = consumerConfigSchema.parse(input);
|
|
142
|
+
return {
|
|
143
|
+
repos: {
|
|
144
|
+
autotests2: resolveRepoPath(parsed.repos.autotests2),
|
|
145
|
+
caseplatformWeb: resolveRepoPath(parsed.repos.caseplatformWeb),
|
|
146
|
+
},
|
|
147
|
+
ci: {
|
|
148
|
+
artifactsRoot: resolveRepoPath(parsed.ci.artifactsRoot),
|
|
149
|
+
reportPortal: parsed.ci.reportPortal ?? null,
|
|
150
|
+
gitlab: parsed.ci.gitlab ?? null,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- [ ] **Step 4: Run the targeted test to verify it passes**
|
|
157
|
+
|
|
158
|
+
Run: `npm run test -- tests/config/consumerConfig.test.ts`
|
|
159
|
+
Expected: PASS
|
|
160
|
+
|
|
161
|
+
- [ ] **Step 5: Verify repository bootstrap**
|
|
162
|
+
|
|
163
|
+
Run: `npm run build`
|
|
164
|
+
Expected: TypeScript build succeeds and emits compiled output without errors.
|
|
165
|
+
|
|
166
|
+
### Task 2: Build SQLite Knowledge Store And Snapshot Refresh
|
|
167
|
+
|
|
168
|
+
**Files:**
|
|
169
|
+
- Create: `src/knowledge/migrations.ts`
|
|
170
|
+
- Create: `src/knowledge/database.ts`
|
|
171
|
+
- Create: `src/knowledge/repositories.ts`
|
|
172
|
+
- Create: `src/indexer/snapshotStore.ts`
|
|
173
|
+
- Create: `src/indexer/refreshPipeline.ts`
|
|
174
|
+
- Test: `tests/knowledge/database.test.ts`
|
|
175
|
+
|
|
176
|
+
- [ ] **Step 1: Write the failing database test**
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { describe, expect, it } from 'vitest';
|
|
180
|
+
import { createKnowledgeDatabase } from '../../src/knowledge/database';
|
|
181
|
+
|
|
182
|
+
describe('createKnowledgeDatabase', () => {
|
|
183
|
+
it('creates tables and fts indexes', () => {
|
|
184
|
+
const db = createKnowledgeDatabase(':memory:');
|
|
185
|
+
const tables = db.prepare(\"SELECT name FROM sqlite_master WHERE type='table'\").all();
|
|
186
|
+
expect(tables.map((row: { name: string }) => row.name)).toContain('documents_fts');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
- [ ] **Step 2: Run the test to verify it fails**
|
|
192
|
+
|
|
193
|
+
Run: `npm run test -- tests/knowledge/database.test.ts`
|
|
194
|
+
Expected: FAIL because the database module is missing.
|
|
195
|
+
|
|
196
|
+
- [ ] **Step 3: Implement the schema and migration runner**
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
db.exec(`
|
|
200
|
+
CREATE TABLE IF NOT EXISTS documents (
|
|
201
|
+
id TEXT PRIMARY KEY,
|
|
202
|
+
source_kind TEXT NOT NULL,
|
|
203
|
+
repo_kind TEXT NOT NULL,
|
|
204
|
+
path TEXT NOT NULL,
|
|
205
|
+
title TEXT NOT NULL,
|
|
206
|
+
body TEXT NOT NULL,
|
|
207
|
+
metadata_json TEXT NOT NULL,
|
|
208
|
+
updated_at TEXT NOT NULL
|
|
209
|
+
);
|
|
210
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS documents_fts USING fts5(
|
|
211
|
+
id UNINDEXED,
|
|
212
|
+
path,
|
|
213
|
+
title,
|
|
214
|
+
body,
|
|
215
|
+
tokenize = 'porter unicode61'
|
|
216
|
+
);
|
|
217
|
+
`);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
- [ ] **Step 4: Run the targeted database test**
|
|
221
|
+
|
|
222
|
+
Run: `npm run test -- tests/knowledge/database.test.ts`
|
|
223
|
+
Expected: PASS
|
|
224
|
+
|
|
225
|
+
- [ ] **Step 5: Prove refresh writes snapshots without mutating consumer repos**
|
|
226
|
+
|
|
227
|
+
Run: `npm run test -- tests/indexer/refreshPipeline.test.ts`
|
|
228
|
+
Expected: PASS with snapshot files created only under this repository’s cache directory.
|
|
229
|
+
|
|
230
|
+
### Task 3: Implement Source Connectors And Extractors For `autotests2` And `caseplatform-web`
|
|
231
|
+
|
|
232
|
+
**Files:**
|
|
233
|
+
- Create: `src/connectors/filesystemConnector.ts`
|
|
234
|
+
- Create: `src/connectors/autotests2Connector.ts`
|
|
235
|
+
- Create: `src/connectors/caseplatformConnector.ts`
|
|
236
|
+
- Create: `src/indexer/extractors/testAssetExtractor.ts`
|
|
237
|
+
- Create: `src/indexer/extractors/frontendContractExtractor.ts`
|
|
238
|
+
- Create: `src/indexer/extractors/frontendRuntimeExtractor.ts`
|
|
239
|
+
- Test: `tests/indexer/testAssetExtractor.test.ts`
|
|
240
|
+
- Test: `tests/indexer/frontendContractExtractor.test.ts`
|
|
241
|
+
|
|
242
|
+
- [ ] **Step 1: Write a failing extractor test for caption contracts**
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
import { describe, expect, it } from 'vitest';
|
|
246
|
+
import { extractFrontendContract } from '../../src/indexer/extractors/frontendContractExtractor';
|
|
247
|
+
|
|
248
|
+
describe('extractFrontendContract', () => {
|
|
249
|
+
it('extracts properties, methods, and events from the caption widget', async () => {
|
|
250
|
+
const result = await extractFrontendContract({
|
|
251
|
+
root: 'C:/gitrep/caseplatform-web',
|
|
252
|
+
widgetHint: 'caption',
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
expect(result.properties).toContain('Label');
|
|
256
|
+
expect(result.methods).toContain('setLabel');
|
|
257
|
+
expect(result.events).toContain('on_click');
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
- [ ] **Step 2: Run the contract extractor test**
|
|
263
|
+
|
|
264
|
+
Run: `npm run test -- tests/indexer/frontendContractExtractor.test.ts`
|
|
265
|
+
Expected: FAIL because the extractor is missing.
|
|
266
|
+
|
|
267
|
+
- [ ] **Step 3: Implement file-system based extractors**
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
const controlFile = findFirstMatch([
|
|
271
|
+
`**/${widgetNamePascal}Control.ts`,
|
|
272
|
+
`**/${widgetNamePascal}Control.js`,
|
|
273
|
+
]);
|
|
274
|
+
const singletonFile = findFirstMatch([
|
|
275
|
+
`**/${widgetNamePascal}Singleton.ts`,
|
|
276
|
+
`**/${widgetNamePascal}Singleton.js`,
|
|
277
|
+
]);
|
|
278
|
+
const handlersFile = findFirstMatch([
|
|
279
|
+
`**/${widgetNamePascal}Handlers.ts`,
|
|
280
|
+
`**/${widgetNamePascal}Handlers.js`,
|
|
281
|
+
]);
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
- [ ] **Step 4: Add failing reuse test for existing test assets**
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
import { describe, expect, it } from 'vitest';
|
|
288
|
+
import { extractTestAssets } from '../../src/indexer/extractors/testAssetExtractor';
|
|
289
|
+
|
|
290
|
+
describe('extractTestAssets', () => {
|
|
291
|
+
it('finds caption specs and reusable commands', async () => {
|
|
292
|
+
const result = await extractTestAssets({
|
|
293
|
+
root: 'C:/gitrep/autotests2',
|
|
294
|
+
featureHint: 'caption',
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
expect(result.specs.some(spec => spec.path.includes('captions/caption.cy.js'))).toBe(true);
|
|
298
|
+
expect(result.commands.some(command => command.name.includes('getWidget'))).toBe(true);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
- [ ] **Step 5: Run both extractor suites**
|
|
304
|
+
|
|
305
|
+
Run: `npm run test -- tests/indexer/frontendContractExtractor.test.ts tests/indexer/testAssetExtractor.test.ts`
|
|
306
|
+
Expected: PASS
|
|
307
|
+
|
|
308
|
+
### Task 4: Wave 1 MCP Tools And Skills
|
|
309
|
+
|
|
310
|
+
**Files:**
|
|
311
|
+
- Create: `src/domain/findExistingTestAssets.ts`
|
|
312
|
+
- Create: `src/domain/findFrontendContract.ts`
|
|
313
|
+
- Create: `src/domain/generateSpecBlueprint.ts`
|
|
314
|
+
- Create: `src/mcp/server.ts`
|
|
315
|
+
- Create: `src/mcp/registerTools.ts`
|
|
316
|
+
- Create: `skills/overkill-generate-test/SKILL.md`
|
|
317
|
+
- Create: `skills/overkill-reuse-project-patterns/SKILL.md`
|
|
318
|
+
- Create: `templates/spec-blueprints/default.md`
|
|
319
|
+
- Test: `tests/mcp/wave1Tools.test.ts`
|
|
320
|
+
|
|
321
|
+
- [ ] **Step 1: Write the failing MCP tool contract test**
|
|
322
|
+
|
|
323
|
+
```ts
|
|
324
|
+
import { describe, expect, it } from 'vitest';
|
|
325
|
+
import { findFrontendContract } from '../../src/domain/findFrontendContract';
|
|
326
|
+
|
|
327
|
+
describe('findFrontendContract', () => {
|
|
328
|
+
it('returns the normalized output envelope', async () => {
|
|
329
|
+
const result = await findFrontendContract({ widget: 'caption' }, testContext);
|
|
330
|
+
expect(result.summary.length).toBeGreaterThan(0);
|
|
331
|
+
expect(result.evidence.length).toBeGreaterThan(0);
|
|
332
|
+
expect(result.recommended_actions.length).toBeGreaterThan(0);
|
|
333
|
+
expect(result.confidence.level).toMatch(/low|medium|high/);
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
- [ ] **Step 2: Run the Wave 1 tool test**
|
|
339
|
+
|
|
340
|
+
Run: `npm run test -- tests/mcp/wave1Tools.test.ts`
|
|
341
|
+
Expected: FAIL because the domain service is missing.
|
|
342
|
+
|
|
343
|
+
- [ ] **Step 3: Implement normalized tool orchestration**
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
return buildToolOutput({
|
|
347
|
+
summary: `${widgetName} exposes ${properties.length} properties, ${events.length} events, and ${methods.length} methods.`,
|
|
348
|
+
evidence,
|
|
349
|
+
recommended_actions: [
|
|
350
|
+
`Reuse existing specs mapped to ${widgetName} before drafting a new test.`,
|
|
351
|
+
'Inspect runtime branches before concluding coverage is complete.',
|
|
352
|
+
],
|
|
353
|
+
repo_paths: uniquePaths(evidence),
|
|
354
|
+
confidence: confidenceFromEvidence(evidence, warnings),
|
|
355
|
+
warnings,
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
- [ ] **Step 4: Register tools with MCP**
|
|
360
|
+
|
|
361
|
+
Run: `npm run test -- tests/mcp/wave1Tools.test.ts`
|
|
362
|
+
Expected: PASS with `find_existing_test_assets`, `find_frontend_contract`, and `generate_spec_blueprint` registered.
|
|
363
|
+
|
|
364
|
+
- [ ] **Step 5: Verify local MCP startup**
|
|
365
|
+
|
|
366
|
+
Run: `npm run mcp:smoke`
|
|
367
|
+
Expected: MCP server starts over stdio and a smoke client can call Wave 1 tools successfully.
|
|
368
|
+
|
|
369
|
+
### Task 5: Wave 2 Coverage Intelligence
|
|
370
|
+
|
|
371
|
+
**Files:**
|
|
372
|
+
- Create: `src/domain/findFrontendRuntimeLogic.ts`
|
|
373
|
+
- Create: `src/domain/mapFeatureToExistingCoverage.ts`
|
|
374
|
+
- Create: `src/domain/analyzeTestGaps.ts`
|
|
375
|
+
- Create: `src/domain/findTestAreaContext.ts`
|
|
376
|
+
- Create: `src/domain/recommendSelectorStrategy.ts`
|
|
377
|
+
- Create: `src/domain/buildSetupTeardownPlan.ts`
|
|
378
|
+
- Create: `skills/overkill-find-gaps/SKILL.md`
|
|
379
|
+
- Create: `skills/overkill-generate-setup/SKILL.md`
|
|
380
|
+
- Test: `tests/domain/analyzeTestGaps.test.ts`
|
|
381
|
+
|
|
382
|
+
- [ ] **Step 1: Write the failing gap-analysis test**
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
import { describe, expect, it } from 'vitest';
|
|
386
|
+
import { analyzeTestGaps } from '../../src/domain/analyzeTestGaps';
|
|
387
|
+
|
|
388
|
+
describe('analyzeTestGaps', () => {
|
|
389
|
+
it('flags runtime methods that are not asserted by mapped specs', async () => {
|
|
390
|
+
const result = await analyzeTestGaps({ widget: 'caption' }, testContext);
|
|
391
|
+
expect(result.summary).toContain('gap');
|
|
392
|
+
expect(result.evidence.length).toBeGreaterThan(0);
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
- [ ] **Step 2: Run the gap-analysis test**
|
|
398
|
+
|
|
399
|
+
Run: `npm run test -- tests/domain/analyzeTestGaps.test.ts`
|
|
400
|
+
Expected: FAIL
|
|
401
|
+
|
|
402
|
+
- [ ] **Step 3: Implement coverage mapping heuristics**
|
|
403
|
+
|
|
404
|
+
```ts
|
|
405
|
+
const coveredSignals = new Set([
|
|
406
|
+
...extractMethodMentions(specBody),
|
|
407
|
+
...extractEventMentions(specBody),
|
|
408
|
+
...extractWidgetAssertions(specBody),
|
|
409
|
+
]);
|
|
410
|
+
const uncoveredMethods = contract.methods.filter(method => !coveredSignals.has(method));
|
|
411
|
+
const uncoveredEvents = contract.events.filter(event => !coveredSignals.has(event));
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
- [ ] **Step 4: Run Wave 2 tests**
|
|
415
|
+
|
|
416
|
+
Run: `npm run test -- tests/domain/analyzeTestGaps.test.ts tests/domain/recommendSelectorStrategy.test.ts tests/domain/buildSetupTeardownPlan.test.ts`
|
|
417
|
+
Expected: PASS
|
|
418
|
+
|
|
419
|
+
- [ ] **Step 5: Verify acceptance on real widget/spec pair**
|
|
420
|
+
|
|
421
|
+
Run: `npm run acceptance:coverage -- --widget caption`
|
|
422
|
+
Expected: PASS with evidence sourced from `caseplatform-web` and `autotests2`.
|
|
423
|
+
|
|
424
|
+
### Task 6: Wave 3 Failure Intelligence
|
|
425
|
+
|
|
426
|
+
**Files:**
|
|
427
|
+
- Create: `src/connectors/ciArtifactsConnector.ts`
|
|
428
|
+
- Create: `src/domain/triageFailedRun.ts`
|
|
429
|
+
- Create: `src/domain/buildRerunScope.ts`
|
|
430
|
+
- Create: `src/domain/summarizeCiContext.ts`
|
|
431
|
+
- Create: `skills/overkill-debug-failure/SKILL.md`
|
|
432
|
+
- Test: `tests/domain/triageFailedRun.test.ts`
|
|
433
|
+
|
|
434
|
+
- [ ] **Step 1: Write the failing CI triage test**
|
|
435
|
+
|
|
436
|
+
```ts
|
|
437
|
+
import { describe, expect, it } from 'vitest';
|
|
438
|
+
import { triageFailedRun } from '../../src/domain/triageFailedRun';
|
|
439
|
+
|
|
440
|
+
describe('triageFailedRun', () => {
|
|
441
|
+
it('uses real artifact metadata and returns evidence-backed hypotheses', async () => {
|
|
442
|
+
const result = await triageFailedRun({
|
|
443
|
+
statsFile: 'C:/gitrep/autotests2/cypress/reports/test-stats.json',
|
|
444
|
+
screenshotsRoot: 'C:/gitrep/autotests2/cypress/screenshots',
|
|
445
|
+
videosRoot: 'C:/gitrep/autotests2/cypress/videos',
|
|
446
|
+
apiCaptureRoot: 'C:/gitrep/autotests2/cypress/reports/api-capture',
|
|
447
|
+
}, testContext);
|
|
448
|
+
|
|
449
|
+
expect(result.evidence.length).toBeGreaterThan(0);
|
|
450
|
+
expect(result.recommended_actions.length).toBeGreaterThan(0);
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
- [ ] **Step 2: Run the triage test**
|
|
456
|
+
|
|
457
|
+
Run: `npm run test -- tests/domain/triageFailedRun.test.ts`
|
|
458
|
+
Expected: FAIL
|
|
459
|
+
|
|
460
|
+
- [ ] **Step 3: Implement artifact ingestion and rerun scope synthesis**
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
const stats = readJson(statsFileSchema.parse(input.statsFile));
|
|
464
|
+
const screenshots = globSync('**/*.png', { cwd: screenshotsRoot, absolute: true });
|
|
465
|
+
const videos = globSync('**/*.mp4', { cwd: videosRoot, absolute: true });
|
|
466
|
+
const apiCaptures = globSync('**/*.json', { cwd: apiCaptureRoot, absolute: true });
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
- [ ] **Step 4: Run Wave 3 tests**
|
|
470
|
+
|
|
471
|
+
Run: `npm run test -- tests/domain/triageFailedRun.test.ts tests/domain/buildRerunScope.test.ts tests/domain/summarizeCiContext.test.ts`
|
|
472
|
+
Expected: PASS
|
|
473
|
+
|
|
474
|
+
- [ ] **Step 5: Verify acceptance against stored artifacts**
|
|
475
|
+
|
|
476
|
+
Run: `npm run acceptance:failure`
|
|
477
|
+
Expected: PASS with hypotheses referencing real screenshot/video/report paths.
|
|
478
|
+
|
|
479
|
+
### Task 7: Wave 4 Change Intelligence
|
|
480
|
+
|
|
481
|
+
**Files:**
|
|
482
|
+
- Create: `src/connectors/diffConnector.ts`
|
|
483
|
+
- Create: `src/domain/analyzeDiffImpact.ts`
|
|
484
|
+
- Create: `skills/overkill-impact-analysis/SKILL.md`
|
|
485
|
+
- Test: `tests/domain/analyzeDiffImpact.test.ts`
|
|
486
|
+
|
|
487
|
+
- [ ] **Step 1: Write the failing diff-impact test**
|
|
488
|
+
|
|
489
|
+
```ts
|
|
490
|
+
import { describe, expect, it } from 'vitest';
|
|
491
|
+
import { analyzeDiffImpact } from '../../src/domain/analyzeDiffImpact';
|
|
492
|
+
|
|
493
|
+
describe('analyzeDiffImpact', () => {
|
|
494
|
+
it('maps changed frontend files to affected tests and risk areas', async () => {
|
|
495
|
+
const result = await analyzeDiffImpact({
|
|
496
|
+
changedFiles: [
|
|
497
|
+
'C:/gitrep/caseplatform-web/vcm/jqVCM/widget/caption/CaptionSingleton.ts',
|
|
498
|
+
],
|
|
499
|
+
}, testContext);
|
|
500
|
+
|
|
501
|
+
expect(result.repo_paths.some(path => path.includes('caption.cy.js'))).toBe(true);
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
- [ ] **Step 2: Run the diff-impact test**
|
|
507
|
+
|
|
508
|
+
Run: `npm run test -- tests/domain/analyzeDiffImpact.test.ts`
|
|
509
|
+
Expected: FAIL
|
|
510
|
+
|
|
511
|
+
- [ ] **Step 3: Implement graph-style impact mapping**
|
|
512
|
+
|
|
513
|
+
```ts
|
|
514
|
+
const impactedSpecs = mappedCoverage
|
|
515
|
+
.filter(item => changedSignals.some(signal => item.frontendPaths.includes(signal.path)))
|
|
516
|
+
.flatMap(item => item.specPaths);
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
- [ ] **Step 4: Run the Wave 4 tests**
|
|
520
|
+
|
|
521
|
+
Run: `npm run test -- tests/domain/analyzeDiffImpact.test.ts`
|
|
522
|
+
Expected: PASS
|
|
523
|
+
|
|
524
|
+
- [ ] **Step 5: Verify acceptance on a real widget diff**
|
|
525
|
+
|
|
526
|
+
Run: `npm run acceptance:impact -- --file C:/gitrep/caseplatform-web/vcm/jqVCM/widget/caption/CaptionSingleton.ts`
|
|
527
|
+
Expected: PASS with caption specs in the affected set.
|
|
528
|
+
|
|
529
|
+
### Task 8: Wave 5 UX, Skills, Templates, And Docs
|
|
530
|
+
|
|
531
|
+
**Files:**
|
|
532
|
+
- Create: `skills/overkill-review-test-draft/SKILL.md`
|
|
533
|
+
- Create: `skills/overkill-onboard/SKILL.md`
|
|
534
|
+
- Create: `skills/overkill-prompt-builder/SKILL.md`
|
|
535
|
+
- Create: `templates/prompts/*.md`
|
|
536
|
+
- Create: `docs/operator-cookbook.md`
|
|
537
|
+
- Create: `docs/consumer-integration.md`
|
|
538
|
+
- Create: `docs/tool-catalog.md`
|
|
539
|
+
- Create: `README.md`
|
|
540
|
+
- Test: `tests/docs/readmeExamples.test.ts`
|
|
541
|
+
|
|
542
|
+
- [ ] **Step 1: Write the failing docs example test**
|
|
543
|
+
|
|
544
|
+
```ts
|
|
545
|
+
import { describe, expect, it } from 'vitest';
|
|
546
|
+
import { loadReadmeExamples } from '../../tests/helpers/loadReadmeExamples';
|
|
547
|
+
|
|
548
|
+
describe('README examples', () => {
|
|
549
|
+
it('reference valid commands and config keys', () => {
|
|
550
|
+
const examples = loadReadmeExamples();
|
|
551
|
+
expect(examples.commands).toContain('npm run index');
|
|
552
|
+
expect(examples.configKeys).toContain('repos.autotests2');
|
|
553
|
+
});
|
|
554
|
+
});
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
- [ ] **Step 2: Run the docs example test**
|
|
558
|
+
|
|
559
|
+
Run: `npm run test -- tests/docs/readmeExamples.test.ts`
|
|
560
|
+
Expected: FAIL
|
|
561
|
+
|
|
562
|
+
- [ ] **Step 3: Implement user-facing docs and skill bundle**
|
|
563
|
+
|
|
564
|
+
```md
|
|
565
|
+
## Quick Start
|
|
566
|
+
|
|
567
|
+
1. Copy `overkill.config.example.json` to `overkill.config.json`.
|
|
568
|
+
2. Point `repos.autotests2` and `repos.caseplatformWeb` to local clones.
|
|
569
|
+
3. Run `npm install`.
|
|
570
|
+
4. Run `npm run index`.
|
|
571
|
+
5. Run `npm run mcp`.
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
- [ ] **Step 4: Run docs and template verification**
|
|
575
|
+
|
|
576
|
+
Run: `npm run test -- tests/docs/readmeExamples.test.ts`
|
|
577
|
+
Expected: PASS
|
|
578
|
+
|
|
579
|
+
- [ ] **Step 5: Run full project verification**
|
|
580
|
+
|
|
581
|
+
Run: `npm run verify`
|
|
582
|
+
Expected: PASS for build, lint, unit tests, and acceptance suites.
|
|
583
|
+
|
|
584
|
+
## Risks To Track During Execution
|
|
585
|
+
|
|
586
|
+
- `caseplatform-web` widget implementation styles vary between TypeScript and legacy JavaScript; extractors must allow both.
|
|
587
|
+
- `autotests2` spec text is multilingual and often encoded inconsistently, so search/index normalization must be UTF-8 safe.
|
|
588
|
+
- CI artifact directories can be large; ingestion must be incremental and snapshot-backed.
|
|
589
|
+
- ReportPortal/GitLab network integrations must remain optional; local artifact parsing is the default path.
|
|
590
|
+
- The platform must never edit `autotests2` or `caseplatform-web` by default; all write paths stay inside this repository.
|
|
591
|
+
|
|
592
|
+
## Acceptance Matrix
|
|
593
|
+
|
|
594
|
+
- `find_frontend_contract` must return properties/events/methods for caption widget with evidence from `CaptionControl.ts`, `CaptionSingleton.ts`, and `CaptionHandlers.ts`.
|
|
595
|
+
- `find_existing_test_assets` must find `caption.cy.js`, `captionInContainers.cy.js`, and reusable Cypress helpers such as `getWidget`.
|
|
596
|
+
- `generate_spec_blueprint` must generate a draft skeleton that reuses existing area/setup conventions from `autotests2`.
|
|
597
|
+
- `analyze_test_gaps` must report at least one meaningful uncovered signal when coverage heuristics show missing runtime assertions.
|
|
598
|
+
- `triage_failed_run` must cite real artifact paths from `autotests2/cypress/reports`, `screenshots`, `videos`, or `api-capture`.
|
|
599
|
+
- `analyze_diff_impact` must connect changed caption widget files to caption-related specs.
|
|
600
|
+
- Skills must be runnable end-to-end from documented prompts without manually grepping both source repositories.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Tool Catalog
|
|
2
|
+
|
|
3
|
+
## Coverage Intelligence
|
|
4
|
+
|
|
5
|
+
- `find_existing_test_assets`: locate reusable specs, commands, helpers, selectors
|
|
6
|
+
- `find_test_area_context`: infer area-specific conventions and init flows
|
|
7
|
+
- `find_frontend_contract`: extract properties, events, methods with source evidence
|
|
8
|
+
- `find_frontend_runtime_logic`: extract runtime branches and event wiring
|
|
9
|
+
- `map_feature_to_existing_coverage`: show mapped specs for a feature
|
|
10
|
+
- `analyze_test_gaps`: identify uncovered runtime signals
|
|
11
|
+
- `generate_spec_blueprint`: generate a project-aware draft skeleton
|
|
12
|
+
- `recommend_selector_strategy`: recommend stable selector usage
|
|
13
|
+
- `build_setup_teardown_plan`: propose reuse-first setup and teardown
|
|
14
|
+
|
|
15
|
+
## Failure Intelligence
|
|
16
|
+
|
|
17
|
+
- `triage_failed_run`: analyze artifacts and produce evidence-backed hypotheses
|
|
18
|
+
- `build_rerun_scope`: build a minimal rerun pack
|
|
19
|
+
- `summarize_ci_context`: summarize run metadata and artifact presence
|
|
20
|
+
|
|
21
|
+
## Change Intelligence
|
|
22
|
+
|
|
23
|
+
- `analyze_diff_impact`: map changed files to affected tests and risk areas
|
|
24
|
+
|
|
25
|
+
## Output Contract
|
|
26
|
+
|
|
27
|
+
Each tool returns the same envelope:
|
|
28
|
+
|
|
29
|
+
- `summary`
|
|
30
|
+
- `evidence`
|
|
31
|
+
- `recommended_actions`
|
|
32
|
+
- `repo_paths`
|
|
33
|
+
- `confidence`
|
|
34
|
+
- `warnings`
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"repos": {
|
|
3
|
+
"autotests2": "../autotests2",
|
|
4
|
+
"caseplatformWeb": "../caseplatform-web"
|
|
5
|
+
},
|
|
6
|
+
"ci": {
|
|
7
|
+
"artifactsRoot": "../autotests2/cypress",
|
|
8
|
+
"reportPortal": {
|
|
9
|
+
"endpoint": "http://reportportal.local/ui"
|
|
10
|
+
},
|
|
11
|
+
"gitlab": {
|
|
12
|
+
"baseUrl": "https://gitlab.example.local"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"cacheDir": ".overkill-cache"
|
|
16
|
+
}
|