@hover-dev/core 0.17.0 → 0.18.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/dist/engine.d.ts +14 -39
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +16 -67
- package/dist/specs/pageObjectManifest.d.ts.map +1 -1
- package/dist/specs/pageObjectManifest.js +11 -10
- package/dist/specs/replayGrounded.d.ts.map +1 -1
- package/package.json +5 -22
- package/dist/agents/argv.d.ts +0 -11
- package/dist/agents/argv.d.ts.map +0 -1
- package/dist/agents/argv.js +0 -23
- package/dist/agents/claude.d.ts +0 -3
- package/dist/agents/claude.d.ts.map +0 -1
- package/dist/agents/claude.js +0 -220
- package/dist/agents/codex.d.ts +0 -19
- package/dist/agents/codex.d.ts.map +0 -1
- package/dist/agents/codex.js +0 -231
- package/dist/agents/detect.d.ts +0 -46
- package/dist/agents/detect.d.ts.map +0 -1
- package/dist/agents/detect.js +0 -80
- package/dist/agents/gemini.d.ts +0 -17
- package/dist/agents/gemini.d.ts.map +0 -1
- package/dist/agents/gemini.js +0 -186
- package/dist/agents/index.d.ts +0 -6
- package/dist/agents/index.d.ts.map +0 -1
- package/dist/agents/index.js +0 -5
- package/dist/agents/invoke.d.ts +0 -12
- package/dist/agents/invoke.d.ts.map +0 -1
- package/dist/agents/invoke.js +0 -93
- package/dist/agents/qwen.d.ts +0 -17
- package/dist/agents/qwen.d.ts.map +0 -1
- package/dist/agents/qwen.js +0 -172
- package/dist/agents/registry.d.ts +0 -19
- package/dist/agents/registry.d.ts.map +0 -1
- package/dist/agents/registry.js +0 -30
- package/dist/agents/shared.d.ts +0 -28
- package/dist/agents/shared.d.ts.map +0 -1
- package/dist/agents/shared.js +0 -35
- package/dist/agents/types.d.ts +0 -194
- package/dist/agents/types.d.ts.map +0 -1
- package/dist/agents/types.js +0 -23
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -2
- package/dist/mcp/actuateServer.d.ts +0 -3
- package/dist/mcp/actuateServer.d.ts.map +0 -1
- package/dist/mcp/actuateServer.js +0 -594
- package/dist/mcp/sourceFence.d.ts +0 -23
- package/dist/mcp/sourceFence.d.ts.map +0 -1
- package/dist/mcp/sourceFence.js +0 -79
- package/dist/mcp/sourceServer.d.ts +0 -3
- package/dist/mcp/sourceServer.d.ts.map +0 -1
- package/dist/mcp/sourceServer.js +0 -191
- package/dist/modes.d.ts +0 -39
- package/dist/modes.d.ts.map +0 -1
- package/dist/modes.js +0 -34
- package/dist/playwright/cdpStatus.d.ts +0 -14
- package/dist/playwright/cdpStatus.d.ts.map +0 -1
- package/dist/playwright/cdpStatus.js +0 -52
- package/dist/playwright/preflight.d.ts +0 -31
- package/dist/playwright/preflight.d.ts.map +0 -1
- package/dist/playwright/preflight.js +0 -82
- package/dist/playwright/preflightCache.d.ts +0 -27
- package/dist/playwright/preflightCache.d.ts.map +0 -1
- package/dist/playwright/preflightCache.js +0 -21
- package/dist/playwright/resolveMcpConfig.d.ts +0 -61
- package/dist/playwright/resolveMcpConfig.d.ts.map +0 -1
- package/dist/playwright/resolveMcpConfig.js +0 -84
- package/dist/plugin-api.d.ts +0 -237
- package/dist/plugin-api.d.ts.map +0 -1
- package/dist/plugin-api.js +0 -52
- package/dist/qa/classify.d.ts +0 -38
- package/dist/qa/classify.d.ts.map +0 -1
- package/dist/qa/classify.js +0 -138
- package/dist/runSession.d.ts +0 -53
- package/dist/runSession.d.ts.map +0 -1
- package/dist/runSession.js +0 -96
- package/dist/service/cdpHandlers.d.ts +0 -24
- package/dist/service/cdpHandlers.d.ts.map +0 -1
- package/dist/service/cdpHandlers.js +0 -50
- package/dist/service/cdpHint.d.ts +0 -41
- package/dist/service/cdpHint.d.ts.map +0 -1
- package/dist/service/cdpHint.js +0 -158
- package/dist/service/conventions.d.ts +0 -8
- package/dist/service/conventions.d.ts.map +0 -1
- package/dist/service/conventions.js +0 -42
- package/dist/service/relayHandlers.d.ts +0 -28
- package/dist/service/relayHandlers.d.ts.map +0 -1
- package/dist/service/relayHandlers.js +0 -105
- package/dist/service/saveHandlers.d.ts +0 -50
- package/dist/service/saveHandlers.d.ts.map +0 -1
- package/dist/service/saveHandlers.js +0 -77
- package/dist/service/types.d.ts +0 -158
- package/dist/service/types.d.ts.map +0 -1
- package/dist/service/types.js +0 -26
- package/dist/service.d.ts +0 -54
- package/dist/service.d.ts.map +0 -1
- package/dist/service.js +0 -1772
- package/dist/specs/businessMap.d.ts +0 -29
- package/dist/specs/businessMap.d.ts.map +0 -1
- package/dist/specs/businessMap.js +0 -95
- package/dist/specs/extractPageObjects.d.ts +0 -18
- package/dist/specs/extractPageObjects.d.ts.map +0 -1
- package/dist/specs/extractPageObjects.js +0 -98
- package/dist/specs/optimizeSpecWithAgent.d.ts +0 -9
- package/dist/specs/optimizeSpecWithAgent.d.ts.map +0 -1
- package/dist/specs/optimizeSpecWithAgent.js +0 -39
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export type MapNodeKind = 'app' | 'area' | 'line' | 'spec';
|
|
2
|
-
export type CoverageStatus = 'covered' | 'uncovered';
|
|
3
|
-
export interface MapNode {
|
|
4
|
-
id: string;
|
|
5
|
-
label: string;
|
|
6
|
-
kind: MapNodeKind;
|
|
7
|
-
/** Coverage of a business line (only on `line` nodes). */
|
|
8
|
-
status?: CoverageStatus;
|
|
9
|
-
/** Entry route of a business line, if given. */
|
|
10
|
-
route?: string;
|
|
11
|
-
/** Spec filename a line is covered by (on `line` and `spec` nodes). */
|
|
12
|
-
spec?: string;
|
|
13
|
-
}
|
|
14
|
-
export interface MapEdge {
|
|
15
|
-
source: string;
|
|
16
|
-
target: string;
|
|
17
|
-
}
|
|
18
|
-
export interface BusinessMapGraph {
|
|
19
|
-
app: string;
|
|
20
|
-
nodes: MapNode[];
|
|
21
|
-
edges: MapEdge[];
|
|
22
|
-
stats: {
|
|
23
|
-
lines: number;
|
|
24
|
-
covered: number;
|
|
25
|
-
areas: number;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
export declare function parseBusinessMap(md: string, fallbackApp?: string): BusinessMapGraph;
|
|
29
|
-
//# sourceMappingURL=businessMap.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"businessMap.d.ts","sourceRoot":"","sources":["../../src/specs/businessMap.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAC3D,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;AAErD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AA8BD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,SAAQ,GAAG,gBAAgB,CAwDlF"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Business-map parser: turn the `.hover/hover-map.md` wiki the agent maintains
|
|
3
|
-
* into a graph model the cockpit renders (areas → business lines → specs, with
|
|
4
|
-
* coverage). The map is a human-curated markdown checklist:
|
|
5
|
-
*
|
|
6
|
-
* # Business map — myapp
|
|
7
|
-
* ## Auth
|
|
8
|
-
* - [ ] Log in — /login
|
|
9
|
-
* - [x] Checkout — /checkout — checkout.spec.ts
|
|
10
|
-
*
|
|
11
|
-
* Pure + total: malformed lines are skipped, never thrown. The graph is
|
|
12
|
-
* hierarchical (app → area → line → spec); richer relationship edges
|
|
13
|
-
* (depends-on / shares-state / navigates-to) are a later format extension.
|
|
14
|
-
*/
|
|
15
|
-
function slug(s) {
|
|
16
|
-
return (s
|
|
17
|
-
.toLowerCase()
|
|
18
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
19
|
-
.replace(/^-+|-+$/g, '') || 'x');
|
|
20
|
-
}
|
|
21
|
-
const SPEC_RE = /\.spec\.tsx?$/;
|
|
22
|
-
/** Split a business-line item on " — " / " – " / " - " (em/en/hyphen, spaced). */
|
|
23
|
-
function splitItem(rest) {
|
|
24
|
-
const parts = rest
|
|
25
|
-
.split(/\s+[—–-]\s+/)
|
|
26
|
-
.map((p) => p.trim())
|
|
27
|
-
.filter(Boolean);
|
|
28
|
-
const name = parts.shift() ?? rest.trim();
|
|
29
|
-
let route;
|
|
30
|
-
let spec;
|
|
31
|
-
for (const p of parts) {
|
|
32
|
-
if (SPEC_RE.test(p))
|
|
33
|
-
spec = p;
|
|
34
|
-
else if (p.startsWith('/'))
|
|
35
|
-
route = p;
|
|
36
|
-
else if (!spec && SPEC_RE.test(p))
|
|
37
|
-
spec = p;
|
|
38
|
-
}
|
|
39
|
-
return { name, route, spec };
|
|
40
|
-
}
|
|
41
|
-
export function parseBusinessMap(md, fallbackApp = 'app') {
|
|
42
|
-
const nodes = [];
|
|
43
|
-
const edges = [];
|
|
44
|
-
const seen = new Set();
|
|
45
|
-
const add = (n) => {
|
|
46
|
-
if (seen.has(n.id))
|
|
47
|
-
return;
|
|
48
|
-
seen.add(n.id);
|
|
49
|
-
nodes.push(n);
|
|
50
|
-
};
|
|
51
|
-
let app = fallbackApp;
|
|
52
|
-
// Title: `# Business map — <app>` (or any `# <title>`).
|
|
53
|
-
const title = md.match(/^#\s+(.+)$/m);
|
|
54
|
-
if (title) {
|
|
55
|
-
const t = title[1].trim();
|
|
56
|
-
const m = t.match(/business\s*map\s*[—–-]\s*(.+)$/i);
|
|
57
|
-
app = (m ? m[1] : t).trim() || fallbackApp;
|
|
58
|
-
}
|
|
59
|
-
add({ id: 'app', label: app, kind: 'app' });
|
|
60
|
-
let area = null;
|
|
61
|
-
let covered = 0;
|
|
62
|
-
let lineCount = 0;
|
|
63
|
-
let areaCount = 0;
|
|
64
|
-
for (const raw of md.split('\n')) {
|
|
65
|
-
const line = raw.trimEnd();
|
|
66
|
-
const areaM = line.match(/^##\s+(.+)$/);
|
|
67
|
-
if (areaM) {
|
|
68
|
-
const label = areaM[1].trim();
|
|
69
|
-
const id = `area:${slug(label)}`;
|
|
70
|
-
area = { id };
|
|
71
|
-
add({ id, label, kind: 'area' });
|
|
72
|
-
edges.push({ source: 'app', target: id });
|
|
73
|
-
areaCount++;
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
const itemM = line.match(/^\s*-\s*\[([ xX])\]\s+(.+)$/);
|
|
77
|
-
if (itemM) {
|
|
78
|
-
const status = itemM[1].toLowerCase() === 'x' ? 'covered' : 'uncovered';
|
|
79
|
-
const { name, route, spec } = splitItem(itemM[2]);
|
|
80
|
-
const parentId = area?.id ?? 'app';
|
|
81
|
-
const lineId = `line:${slug(area ? area.id.slice(5) : 'top')}/${slug(name)}`;
|
|
82
|
-
add({ id: lineId, label: name, kind: 'line', status, route, spec });
|
|
83
|
-
edges.push({ source: parentId, target: lineId });
|
|
84
|
-
lineCount++;
|
|
85
|
-
if (status === 'covered')
|
|
86
|
-
covered++;
|
|
87
|
-
if (spec) {
|
|
88
|
-
const specId = `spec:${spec}`;
|
|
89
|
-
add({ id: specId, label: spec, kind: 'spec', spec });
|
|
90
|
-
edges.push({ source: lineId, target: specId });
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return { app, nodes, edges, stats: { lines: lineCount, covered, areas: areaCount } };
|
|
95
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface ExtractedPage {
|
|
2
|
-
className: string;
|
|
3
|
-
methodName: string;
|
|
4
|
-
fileName: string;
|
|
5
|
-
/** Absolute path written. */
|
|
6
|
-
path: string;
|
|
7
|
-
/** Slugs of the specs that share this flow. */
|
|
8
|
-
specs: string[];
|
|
9
|
-
}
|
|
10
|
-
export interface ExtractResult {
|
|
11
|
-
pages: ExtractedPage[];
|
|
12
|
-
/** Absolute path of the written fixtures.ts, or null when nothing extracted. */
|
|
13
|
-
fixturesPath: string | null;
|
|
14
|
-
}
|
|
15
|
-
export declare function extractPageObjects(devRoot: string, opts?: {
|
|
16
|
-
minSpecs?: number;
|
|
17
|
-
}): Promise<ExtractResult>;
|
|
18
|
-
//# sourceMappingURL=extractPageObjects.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extractPageObjects.d.ts","sourceRoot":"","sources":["../../src/specs/extractPageObjects.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,gFAAgF;IAChF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,OAAO,CAAC,aAAa,CAAC,CA4CxB"}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stage 3 (F4): extract Page Objects + a fixtures entry point from flows shared
|
|
3
|
-
* across saved specs.
|
|
4
|
-
*
|
|
5
|
-
* Reads detectSharedFlows (>= 3 specs sharing an entry prefix — the scaffold's
|
|
6
|
-
* 3-use threshold), generates a `pages/<Name>.ts` per flow, and (re)writes a
|
|
7
|
-
* single `fixtures.ts` that registers each Page Object via `base.extend`. New
|
|
8
|
-
* specs `import { test, expect } from './fixtures'` and consume e.g.
|
|
9
|
-
* `async ({ page, loginPage }) => …`.
|
|
10
|
-
*
|
|
11
|
-
* Manual trigger (Stage 3b): invoked by a CLI command, not on every save, and
|
|
12
|
-
* it never rewrites already-committed specs (D6) — it only emits the shared
|
|
13
|
-
* pages/ + fixtures.ts going forward.
|
|
14
|
-
*/
|
|
15
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
16
|
-
import { join } from 'node:path';
|
|
17
|
-
import { detectSharedFlows } from './detectSharedFlows.js';
|
|
18
|
-
import { generatePageObject } from './generatePageObject.js';
|
|
19
|
-
import { writePageObjectManifest } from './pageObjectManifest.js';
|
|
20
|
-
export async function extractPageObjects(devRoot, opts = {}) {
|
|
21
|
-
// 3-use threshold for extraction; lower thresholds only *report* (Stage 2).
|
|
22
|
-
const flows = await detectSharedFlows(devRoot, { minSpecs: opts.minSpecs ?? 3 });
|
|
23
|
-
if (flows.length === 0)
|
|
24
|
-
return { pages: [], fixturesPath: null };
|
|
25
|
-
const testsDir = join(devRoot, '__vibe_tests__');
|
|
26
|
-
const pagesDir = join(testsDir, 'pages');
|
|
27
|
-
await mkdir(pagesDir, { recursive: true });
|
|
28
|
-
const pages = [];
|
|
29
|
-
const entries = [];
|
|
30
|
-
const usedNames = new Set();
|
|
31
|
-
for (const flow of flows) {
|
|
32
|
-
const probe = generatePageObject(flow.prefixSteps);
|
|
33
|
-
const className = uniqueName(probe.className, usedNames);
|
|
34
|
-
const po = className === probe.className
|
|
35
|
-
? probe
|
|
36
|
-
: generatePageObject(flow.prefixSteps, { className });
|
|
37
|
-
const path = join(pagesDir, po.fileName);
|
|
38
|
-
await writeFile(path, po.source, 'utf-8');
|
|
39
|
-
pages.push({
|
|
40
|
-
className: po.className,
|
|
41
|
-
methodName: po.methodName,
|
|
42
|
-
fileName: po.fileName,
|
|
43
|
-
path,
|
|
44
|
-
specs: flow.specs,
|
|
45
|
-
});
|
|
46
|
-
entries.push({
|
|
47
|
-
className: po.className,
|
|
48
|
-
methodName: po.methodName,
|
|
49
|
-
fixtureName: fixtureName(po.className),
|
|
50
|
-
fileName: po.fileName,
|
|
51
|
-
signatures: flow.signatures,
|
|
52
|
-
specs: flow.specs,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
const fixturesPath = join(testsDir, 'fixtures.ts');
|
|
56
|
-
await writeFile(fixturesPath, renderFixtures(pages), 'utf-8');
|
|
57
|
-
// Manifest lets writeSpec match a new spec's prefix to a Page Object and
|
|
58
|
-
// consume it (Stage 3c) without re-running detection.
|
|
59
|
-
await writePageObjectManifest(devRoot, entries);
|
|
60
|
-
return { pages, fixturesPath };
|
|
61
|
-
}
|
|
62
|
-
function renderFixtures(pages) {
|
|
63
|
-
const lines = [];
|
|
64
|
-
lines.push(`import { test as base } from '@playwright/test';`);
|
|
65
|
-
for (const p of pages) {
|
|
66
|
-
lines.push(`import { ${p.className} } from './pages/${p.className}';`);
|
|
67
|
-
}
|
|
68
|
-
lines.push('');
|
|
69
|
-
lines.push('/**');
|
|
70
|
-
lines.push(' * Generated by Hover — Page Object fixtures lifted from flows shared');
|
|
71
|
-
lines.push(" * across specs. In a new spec: `import { test, expect } from './fixtures';`");
|
|
72
|
-
lines.push(' * then consume e.g. `async ({ page, loginPage }) => …`.');
|
|
73
|
-
lines.push(' */');
|
|
74
|
-
const typeMembers = pages.map(p => `${fixtureName(p.className)}: ${p.className}`).join('; ');
|
|
75
|
-
lines.push(`export const test = base.extend<{ ${typeMembers} }>({`);
|
|
76
|
-
for (const p of pages) {
|
|
77
|
-
lines.push(` ${fixtureName(p.className)}: async ({ page }, use) => {`);
|
|
78
|
-
lines.push(` await use(new ${p.className}(page));`);
|
|
79
|
-
lines.push(` },`);
|
|
80
|
-
}
|
|
81
|
-
lines.push(`});`);
|
|
82
|
-
lines.push('');
|
|
83
|
-
lines.push(`export { expect } from '@playwright/test';`);
|
|
84
|
-
lines.push('');
|
|
85
|
-
return lines.join('\n');
|
|
86
|
-
}
|
|
87
|
-
/** Class name -> fixture key: LoginPage -> loginPage. */
|
|
88
|
-
function fixtureName(className) {
|
|
89
|
-
return className.charAt(0).toLowerCase() + className.slice(1);
|
|
90
|
-
}
|
|
91
|
-
function uniqueName(base, used) {
|
|
92
|
-
let name = base;
|
|
93
|
-
let n = 2;
|
|
94
|
-
while (used.has(name))
|
|
95
|
-
name = `${base}${n++}`;
|
|
96
|
-
used.add(name);
|
|
97
|
-
return name;
|
|
98
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type OptimizeResult } from './optimizeSpec.js';
|
|
2
|
-
export interface OptimizeAgentOptions {
|
|
3
|
-
agentId: string;
|
|
4
|
-
model?: string;
|
|
5
|
-
maxBudgetUsd?: number;
|
|
6
|
-
signal?: AbortSignal;
|
|
7
|
-
}
|
|
8
|
-
export declare function optimizeSpecWithAgent(devRoot: string, slug: string, opts: OptimizeAgentOptions): Promise<OptimizeResult>;
|
|
9
|
-
//# sourceMappingURL=optimizeSpecWithAgent.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"optimizeSpecWithAgent.d.ts","sourceRoot":"","sources":["../../src/specs/optimizeSpecWithAgent.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgB,KAAK,cAAc,EAAmB,MAAM,mBAAmB,CAAC;AAEvF,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,cAAc,CAAC,CA2BzB"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wires optimizeSpec's injected codegen call to a real agent via invokeAgent,
|
|
3
|
-
* in "codegen mode": no MCP, no browser tools, the agent's own built-in tools
|
|
4
|
-
* disallowed — it just reads the prompt and emits the improved spec as text.
|
|
5
|
-
*
|
|
6
|
-
* Kept separate from optimizeSpec.ts so the core (prompt / extract / validate /
|
|
7
|
-
* write) stays a pure, spawn-free module that tests import directly.
|
|
8
|
-
*/
|
|
9
|
-
import { invokeAgent } from '../agents/invoke.js';
|
|
10
|
-
import { getAgent } from '../agents/registry.js';
|
|
11
|
-
import { optimizeSpec } from './optimizeSpec.js';
|
|
12
|
-
export async function optimizeSpecWithAgent(devRoot, slug, opts) {
|
|
13
|
-
const descriptor = getAgent(opts.agentId);
|
|
14
|
-
// Codegen mode: deny the agent's built-in tools so it answers with text only;
|
|
15
|
-
// pass no mcpConfig / allowedTools so it never reaches a browser.
|
|
16
|
-
const disallowedTools = descriptor?.defaultDisallowedTools
|
|
17
|
-
? [...descriptor.defaultDisallowedTools]
|
|
18
|
-
: undefined;
|
|
19
|
-
const runCodegen = async (prompt) => {
|
|
20
|
-
let streamed = '';
|
|
21
|
-
let summary = '';
|
|
22
|
-
for await (const ev of invokeAgent({
|
|
23
|
-
agentId: opts.agentId,
|
|
24
|
-
prompt,
|
|
25
|
-
model: opts.model,
|
|
26
|
-
maxBudgetUsd: opts.maxBudgetUsd,
|
|
27
|
-
signal: opts.signal,
|
|
28
|
-
disallowedTools,
|
|
29
|
-
})) {
|
|
30
|
-
if (ev.kind === 'text' && ev.text)
|
|
31
|
-
streamed += `${ev.text}\n`;
|
|
32
|
-
else if (ev.kind === 'session_end' && ev.summary)
|
|
33
|
-
summary = ev.summary;
|
|
34
|
-
}
|
|
35
|
-
// Prefer the final result summary; fall back to streamed text blocks.
|
|
36
|
-
return summary || streamed;
|
|
37
|
-
};
|
|
38
|
-
return optimizeSpec(devRoot, slug, runCodegen);
|
|
39
|
-
}
|