tryassay 0.15.0 → 0.16.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/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/create.js +13 -7
- package/dist/commands/create.js.map +1 -1
- package/dist/runtime/__tests__/integration-verifier.test.d.ts +9 -0
- package/dist/runtime/__tests__/integration-verifier.test.js +120 -0
- package/dist/runtime/__tests__/integration-verifier.test.js.map +1 -0
- package/dist/runtime/agents/planner-agent.js +25 -1
- package/dist/runtime/agents/planner-agent.js.map +1 -1
- package/dist/runtime/app-create-orchestrator.d.ts +2 -0
- package/dist/runtime/app-create-orchestrator.js +91 -16
- package/dist/runtime/app-create-orchestrator.js.map +1 -1
- package/dist/runtime/build-verifier.d.ts +7 -0
- package/dist/runtime/build-verifier.js +63 -0
- package/dist/runtime/build-verifier.js.map +1 -1
- package/dist/runtime/integration-verifier.d.ts +50 -0
- package/dist/runtime/integration-verifier.js +373 -0
- package/dist/runtime/integration-verifier.js.map +1 -0
- package/dist/runtime/types.d.ts +31 -2
- package/package.json +1 -1
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IntegrationVerifier — deterministic wiring checks for generated applications.
|
|
3
|
+
*
|
|
4
|
+
* Catches four classes of integration failure that compile clean but don't work:
|
|
5
|
+
* 1. Missing Router provider (pages use react-router hooks but no Router wraps them)
|
|
6
|
+
* 2. Missing IPC handlers (preload invokes channels with no main-process handler)
|
|
7
|
+
* 3. Stub functions (async functions that return literal objects without doing real work)
|
|
8
|
+
* 4. Unreachable pages (page files exist but are never imported from the entry point)
|
|
9
|
+
*
|
|
10
|
+
* Zero LLM calls. Deterministic. Uses only node:fs/promises, node:path, and regex.
|
|
11
|
+
*/
|
|
12
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
13
|
+
import { join, relative, basename, extname } from 'node:path';
|
|
14
|
+
export class IntegrationVerifier {
|
|
15
|
+
projectPath;
|
|
16
|
+
framework;
|
|
17
|
+
constructor(projectPath, framework) {
|
|
18
|
+
this.projectPath = projectPath;
|
|
19
|
+
this.framework = framework;
|
|
20
|
+
}
|
|
21
|
+
async verify() {
|
|
22
|
+
const start = Date.now();
|
|
23
|
+
const checks = [];
|
|
24
|
+
// Run all checks
|
|
25
|
+
checks.push(...await this.checkRoutingProvider());
|
|
26
|
+
if (this.framework === 'electron' || await this.hasPreloadFiles()) {
|
|
27
|
+
checks.push(...await this.checkIpcHandlerCoverage());
|
|
28
|
+
checks.push(...await this.checkStubFunctions());
|
|
29
|
+
}
|
|
30
|
+
checks.push(...await this.checkUnreachablePages());
|
|
31
|
+
const passedCount = checks.filter(c => c.verdict === 'PASS').length;
|
|
32
|
+
const failedCount = checks.filter(c => c.verdict === 'FAIL').length;
|
|
33
|
+
return {
|
|
34
|
+
checks,
|
|
35
|
+
passedCount,
|
|
36
|
+
failedCount,
|
|
37
|
+
verdict: failedCount > 0 ? 'FAIL' : 'PASS',
|
|
38
|
+
framework: this.framework,
|
|
39
|
+
totalDurationMs: Date.now() - start,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
// ── Check 1: Routing Provider ──────────────────────────────
|
|
43
|
+
/**
|
|
44
|
+
* Scan all .tsx files for react-router hook usage.
|
|
45
|
+
* If found, verify a Router provider exists in the entry point chain.
|
|
46
|
+
*/
|
|
47
|
+
async checkRoutingProvider() {
|
|
48
|
+
const tsxFiles = await this.findFiles(this.projectPath, /\.(tsx|jsx)$/);
|
|
49
|
+
const routerHookPattern = /\b(useNavigate|useParams|useLocation|useSearchParams|useMatch|useRoutes)\b/;
|
|
50
|
+
const routerProviderPattern = /\b(BrowserRouter|HashRouter|MemoryRouter|RouterProvider|createBrowserRouter|createHashRouter|createMemoryRouter)\b/;
|
|
51
|
+
// Find files that use router hooks
|
|
52
|
+
const filesUsingHooks = [];
|
|
53
|
+
for (const file of tsxFiles) {
|
|
54
|
+
const content = await readFile(file, 'utf-8');
|
|
55
|
+
if (routerHookPattern.test(content)) {
|
|
56
|
+
filesUsingHooks.push(file);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (filesUsingHooks.length === 0) {
|
|
60
|
+
return []; // No router hooks used — nothing to check
|
|
61
|
+
}
|
|
62
|
+
// Check if ANY file in the project contains a Router provider
|
|
63
|
+
let providerFound = false;
|
|
64
|
+
let providerFile = '';
|
|
65
|
+
for (const file of tsxFiles) {
|
|
66
|
+
const content = await readFile(file, 'utf-8');
|
|
67
|
+
if (routerProviderPattern.test(content)) {
|
|
68
|
+
providerFound = true;
|
|
69
|
+
providerFile = relative(this.projectPath, file);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (providerFound) {
|
|
74
|
+
return [{
|
|
75
|
+
type: 'routing_provider',
|
|
76
|
+
verdict: 'PASS',
|
|
77
|
+
evidence: `Router provider found in ${providerFile}. ${filesUsingHooks.length} file(s) use router hooks.`,
|
|
78
|
+
file: providerFile,
|
|
79
|
+
severity: 'critical',
|
|
80
|
+
}];
|
|
81
|
+
}
|
|
82
|
+
const hookFiles = filesUsingHooks.map(f => relative(this.projectPath, f)).join(', ');
|
|
83
|
+
return [{
|
|
84
|
+
type: 'routing_provider',
|
|
85
|
+
verdict: 'FAIL',
|
|
86
|
+
evidence: `${filesUsingHooks.length} file(s) use react-router hooks (${hookFiles}) but no Router provider (BrowserRouter, HashRouter, etc.) found in any .tsx file.`,
|
|
87
|
+
file: hookFiles,
|
|
88
|
+
severity: 'critical',
|
|
89
|
+
}];
|
|
90
|
+
}
|
|
91
|
+
// ── Check 2: IPC Handler Coverage ──────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* Electron only. Scan preload files for ipcRenderer.invoke calls.
|
|
94
|
+
* Scan main/ipc files for ipcMain.handle calls.
|
|
95
|
+
* Report any channel invoked but not handled.
|
|
96
|
+
*/
|
|
97
|
+
async checkIpcHandlerCoverage() {
|
|
98
|
+
const allFiles = await this.findFiles(this.projectPath, /\.(ts|tsx|js|jsx)$/);
|
|
99
|
+
// Find channels invoked in preload (renderer-side)
|
|
100
|
+
const invokedChannels = new Map(); // channel -> file
|
|
101
|
+
const invokePattern = /ipcRenderer\.invoke\(\s*['"`]([^'"`]+)['"`]/g;
|
|
102
|
+
for (const file of allFiles) {
|
|
103
|
+
const relPath = relative(this.projectPath, file);
|
|
104
|
+
if (!relPath.includes('preload'))
|
|
105
|
+
continue;
|
|
106
|
+
const content = await readFile(file, 'utf-8');
|
|
107
|
+
let match;
|
|
108
|
+
while ((match = invokePattern.exec(content)) !== null) {
|
|
109
|
+
invokedChannels.set(match[1], relPath);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (invokedChannels.size === 0) {
|
|
113
|
+
return []; // No IPC invoke calls found
|
|
114
|
+
}
|
|
115
|
+
// Find channels handled in main process
|
|
116
|
+
const handledChannels = new Set();
|
|
117
|
+
const handlePattern = /ipcMain\.handle\(\s*['"`]([^'"`]+)['"`]/g;
|
|
118
|
+
// Also check for IPC_CHANNELS.CONSTANT patterns that resolve to string literals
|
|
119
|
+
const channelConstPattern = /ipcMain\.handle\(\s*(?:IPC_CHANNELS\.\w+|[\w.]+)\s*,/g;
|
|
120
|
+
for (const file of allFiles) {
|
|
121
|
+
const relPath = relative(this.projectPath, file);
|
|
122
|
+
// Check main process files (main/, ipc/, handlers/)
|
|
123
|
+
if (!relPath.includes('main') && !relPath.includes('ipc') && !relPath.includes('handler'))
|
|
124
|
+
continue;
|
|
125
|
+
const content = await readFile(file, 'utf-8');
|
|
126
|
+
// Direct string channel handles
|
|
127
|
+
let match;
|
|
128
|
+
while ((match = handlePattern.exec(content)) !== null) {
|
|
129
|
+
handledChannels.add(match[1]);
|
|
130
|
+
}
|
|
131
|
+
// Also resolve IPC_CHANNELS constants by scanning for their definitions
|
|
132
|
+
const constDefPattern = /['"`]([^'"`]+)['"`]\s*(?:,|as\s+const)/g;
|
|
133
|
+
if (relPath.includes('handler') || relPath.includes('ipc')) {
|
|
134
|
+
while ((match = constDefPattern.exec(content)) !== null) {
|
|
135
|
+
// Only add if it looks like a channel name (contains colon)
|
|
136
|
+
if (match[1].includes(':')) {
|
|
137
|
+
handledChannels.add(match[1]);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Also scan shared types for IPC_CHANNELS constant definitions
|
|
143
|
+
for (const file of allFiles) {
|
|
144
|
+
const relPath = relative(this.projectPath, file);
|
|
145
|
+
if (!relPath.includes('shared') && !relPath.includes('types'))
|
|
146
|
+
continue;
|
|
147
|
+
const content = await readFile(file, 'utf-8');
|
|
148
|
+
const channelValuePattern = /:\s*['"`]([^'"`]+)['"`]/g;
|
|
149
|
+
if (content.includes('IPC_CHANNELS')) {
|
|
150
|
+
let match;
|
|
151
|
+
while ((match = channelValuePattern.exec(content)) !== null) {
|
|
152
|
+
if (match[1].includes(':')) {
|
|
153
|
+
handledChannels.add(match[1]);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const checks = [];
|
|
159
|
+
for (const [channel, invokeFile] of invokedChannels) {
|
|
160
|
+
if (handledChannels.has(channel)) {
|
|
161
|
+
checks.push({
|
|
162
|
+
type: 'ipc_handler_coverage',
|
|
163
|
+
verdict: 'PASS',
|
|
164
|
+
evidence: `Channel '${channel}' invoked in ${invokeFile} has a matching handler.`,
|
|
165
|
+
file: invokeFile,
|
|
166
|
+
severity: 'critical',
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
checks.push({
|
|
171
|
+
type: 'ipc_handler_coverage',
|
|
172
|
+
verdict: 'FAIL',
|
|
173
|
+
evidence: `Channel '${channel}' invoked in ${invokeFile} has NO handler in any main-process file.`,
|
|
174
|
+
file: invokeFile,
|
|
175
|
+
severity: 'critical',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return checks;
|
|
180
|
+
}
|
|
181
|
+
// ── Check 3: Stub Functions ────────────────────────────────
|
|
182
|
+
/**
|
|
183
|
+
* Find async functions in preload whose body is ONLY a return of a literal object
|
|
184
|
+
* without ipcRenderer.invoke, await, .query(), or fetch().
|
|
185
|
+
*/
|
|
186
|
+
async checkStubFunctions() {
|
|
187
|
+
const allFiles = await this.findFiles(this.projectPath, /\.(ts|tsx|js|jsx)$/);
|
|
188
|
+
const checks = [];
|
|
189
|
+
for (const file of allFiles) {
|
|
190
|
+
const relPath = relative(this.projectPath, file);
|
|
191
|
+
if (!relPath.includes('preload'))
|
|
192
|
+
continue;
|
|
193
|
+
const content = await readFile(file, 'utf-8');
|
|
194
|
+
const lines = content.split('\n');
|
|
195
|
+
// Find async arrow functions that return a literal object without real work
|
|
196
|
+
// Pattern: async (params) => { return { ... }; } or async (params): Promise<...> => { return { ... }; }
|
|
197
|
+
// But NOT functions that contain ipcRenderer.invoke, await (something), fetch, .query()
|
|
198
|
+
const stubPattern = /async\s+\(([^)]*)\)\s*(?::\s*Promise<[^>]+>)?\s*=>\s*\{/g;
|
|
199
|
+
let match;
|
|
200
|
+
while ((match = stubPattern.exec(content)) !== null) {
|
|
201
|
+
const startIdx = match.index + match[0].length;
|
|
202
|
+
const bodyEnd = this.findMatchingBrace(content, startIdx - 1);
|
|
203
|
+
if (bodyEnd === -1)
|
|
204
|
+
continue;
|
|
205
|
+
const body = content.slice(startIdx, bodyEnd).trim();
|
|
206
|
+
const hasRealWork = /ipcRenderer\.invoke|await\s+[^{]|\.query\(|fetch\(|\.send\(|\.emit\(/.test(body);
|
|
207
|
+
const isLiteralReturn = /^\s*return\s+\{[^}]*\}\s*;?\s*$/.test(body);
|
|
208
|
+
if (isLiteralReturn && !hasRealWork) {
|
|
209
|
+
// Find the function name by looking at what precedes the async keyword
|
|
210
|
+
const preceding = content.slice(Math.max(0, match.index - 80), match.index);
|
|
211
|
+
const nameMatch = preceding.match(/(\w+)\s*:\s*$/);
|
|
212
|
+
const funcName = nameMatch ? nameMatch[1] : 'anonymous';
|
|
213
|
+
// Find line number
|
|
214
|
+
const lineNum = content.slice(0, match.index).split('\n').length;
|
|
215
|
+
checks.push({
|
|
216
|
+
type: 'stub_function',
|
|
217
|
+
verdict: 'FAIL',
|
|
218
|
+
evidence: `Function '${funcName}' at line ${lineNum} is a stub: returns a literal object without ipcRenderer.invoke or any real operation. Body: ${body.trim()}`,
|
|
219
|
+
file: relPath,
|
|
220
|
+
severity: 'high',
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return checks;
|
|
226
|
+
}
|
|
227
|
+
// ── Check 4: Unreachable Pages ─────────────────────────────
|
|
228
|
+
/**
|
|
229
|
+
* Collect page files from pages/ directories.
|
|
230
|
+
* Build import graph from entry point.
|
|
231
|
+
* Report any page file not transitively imported.
|
|
232
|
+
*/
|
|
233
|
+
async checkUnreachablePages() {
|
|
234
|
+
// Find page files
|
|
235
|
+
const allFiles = await this.findFiles(this.projectPath, /\.(tsx|jsx|ts|js)$/);
|
|
236
|
+
const pageFiles = allFiles.filter(f => {
|
|
237
|
+
const rel = relative(this.projectPath, f);
|
|
238
|
+
return rel.includes('pages/') || rel.includes('pages\\');
|
|
239
|
+
});
|
|
240
|
+
if (pageFiles.length === 0) {
|
|
241
|
+
return []; // No pages directory
|
|
242
|
+
}
|
|
243
|
+
// Find entry point (file with createRoot or ReactDOM.render)
|
|
244
|
+
let entryFile = null;
|
|
245
|
+
for (const file of allFiles) {
|
|
246
|
+
const content = await readFile(file, 'utf-8');
|
|
247
|
+
if (/createRoot|ReactDOM\.render/.test(content)) {
|
|
248
|
+
entryFile = file;
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (!entryFile) {
|
|
253
|
+
return []; // No entry point found — can't trace imports
|
|
254
|
+
}
|
|
255
|
+
// Build transitive import graph from entry point
|
|
256
|
+
const reachable = new Set();
|
|
257
|
+
await this.traceImports(entryFile, reachable, allFiles);
|
|
258
|
+
const checks = [];
|
|
259
|
+
for (const pageFile of pageFiles) {
|
|
260
|
+
const relPath = relative(this.projectPath, pageFile);
|
|
261
|
+
const pageName = basename(pageFile, extname(pageFile));
|
|
262
|
+
if (reachable.has(pageFile)) {
|
|
263
|
+
checks.push({
|
|
264
|
+
type: 'unreachable_page',
|
|
265
|
+
verdict: 'PASS',
|
|
266
|
+
evidence: `Page '${pageName}' (${relPath}) is reachable from entry point.`,
|
|
267
|
+
file: relPath,
|
|
268
|
+
severity: 'high',
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
checks.push({
|
|
273
|
+
type: 'unreachable_page',
|
|
274
|
+
verdict: 'FAIL',
|
|
275
|
+
evidence: `Page '${pageName}' (${relPath}) is NOT imported from the entry point chain. It exists as a file but is unreachable at runtime.`,
|
|
276
|
+
file: relPath,
|
|
277
|
+
severity: 'high',
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return checks;
|
|
282
|
+
}
|
|
283
|
+
// ── Helpers ────────────────────────────────────────────────
|
|
284
|
+
/** Recursively find files matching a pattern. */
|
|
285
|
+
async findFiles(dir, pattern) {
|
|
286
|
+
const results = [];
|
|
287
|
+
try {
|
|
288
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
289
|
+
for (const entry of entries) {
|
|
290
|
+
const fullPath = join(dir, entry.name);
|
|
291
|
+
if (entry.isDirectory()) {
|
|
292
|
+
if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git' || entry.name === 'out' || entry.name === 'build' || entry.name === '.next')
|
|
293
|
+
continue;
|
|
294
|
+
results.push(...await this.findFiles(fullPath, pattern));
|
|
295
|
+
}
|
|
296
|
+
else if (pattern.test(entry.name)) {
|
|
297
|
+
results.push(fullPath);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// Directory doesn't exist or can't be read
|
|
303
|
+
}
|
|
304
|
+
return results;
|
|
305
|
+
}
|
|
306
|
+
/** Check if the project has preload files (indicating Electron). */
|
|
307
|
+
async hasPreloadFiles() {
|
|
308
|
+
const files = await this.findFiles(this.projectPath, /\.(ts|tsx|js|jsx)$/);
|
|
309
|
+
return files.some(f => relative(this.projectPath, f).includes('preload'));
|
|
310
|
+
}
|
|
311
|
+
/** Find the matching closing brace for an opening brace at the given index. */
|
|
312
|
+
findMatchingBrace(content, openIdx) {
|
|
313
|
+
let depth = 0;
|
|
314
|
+
for (let i = openIdx; i < content.length; i++) {
|
|
315
|
+
if (content[i] === '{')
|
|
316
|
+
depth++;
|
|
317
|
+
else if (content[i] === '}') {
|
|
318
|
+
depth--;
|
|
319
|
+
if (depth === 0)
|
|
320
|
+
return i;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return -1;
|
|
324
|
+
}
|
|
325
|
+
/** Trace imports transitively from a file. */
|
|
326
|
+
async traceImports(file, visited, allFiles) {
|
|
327
|
+
if (visited.has(file))
|
|
328
|
+
return;
|
|
329
|
+
visited.add(file);
|
|
330
|
+
let content;
|
|
331
|
+
try {
|
|
332
|
+
content = await readFile(file, 'utf-8');
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
// Match import statements: import ... from './path' or import './path'
|
|
338
|
+
const importPattern = /(?:import\s+(?:[\s\S]*?)\s+from\s+|import\s+)['"]([^'"]+)['"]/g;
|
|
339
|
+
// Also match dynamic imports: import('./path')
|
|
340
|
+
const dynamicImportPattern = /import\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
341
|
+
const importPaths = [];
|
|
342
|
+
let match;
|
|
343
|
+
while ((match = importPattern.exec(content)) !== null) {
|
|
344
|
+
importPaths.push(match[1]);
|
|
345
|
+
}
|
|
346
|
+
while ((match = dynamicImportPattern.exec(content)) !== null) {
|
|
347
|
+
importPaths.push(match[1]);
|
|
348
|
+
}
|
|
349
|
+
for (const importPath of importPaths) {
|
|
350
|
+
if (!importPath.startsWith('.'))
|
|
351
|
+
continue; // Skip node_modules imports
|
|
352
|
+
const resolved = this.resolveImport(file, importPath, allFiles);
|
|
353
|
+
if (resolved) {
|
|
354
|
+
await this.traceImports(resolved, visited, allFiles);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/** Resolve a relative import path to an actual file. */
|
|
359
|
+
resolveImport(fromFile, importPath, allFiles) {
|
|
360
|
+
const dir = join(fromFile, '..');
|
|
361
|
+
const base = join(dir, importPath);
|
|
362
|
+
// Try exact match, then with extensions
|
|
363
|
+
const extensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js', '/index.jsx'];
|
|
364
|
+
const candidates = [base, ...extensions.map(ext => base + ext)];
|
|
365
|
+
for (const candidate of candidates) {
|
|
366
|
+
if (allFiles.includes(candidate)) {
|
|
367
|
+
return candidate;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=integration-verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-verifier.js","sourceRoot":"","sources":["../../src/runtime/integration-verifier.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -1270,7 +1270,7 @@ export interface AppDescription {
|
|
|
1270
1270
|
}
|
|
1271
1271
|
export interface TechStackConfig {
|
|
1272
1272
|
readonly language: 'typescript' | 'python';
|
|
1273
|
-
readonly framework: 'next.js' | 'express' | 'sveltekit';
|
|
1273
|
+
readonly framework: 'next.js' | 'express' | 'sveltekit' | 'electron';
|
|
1274
1274
|
readonly database: 'supabase' | 'postgresql' | 'sqlite';
|
|
1275
1275
|
readonly styling?: string;
|
|
1276
1276
|
readonly deployment?: string;
|
|
@@ -1285,6 +1285,7 @@ export interface ArchitecturePlan {
|
|
|
1285
1285
|
readonly apiRoutes: readonly ApiRouteSpec[];
|
|
1286
1286
|
readonly pages: readonly PageSpec[];
|
|
1287
1287
|
readonly features: readonly FeaturePlan[];
|
|
1288
|
+
readonly ipcChannels?: readonly IpcChannel[];
|
|
1288
1289
|
readonly dependencyOrder: readonly string[];
|
|
1289
1290
|
readonly authPlan?: {
|
|
1290
1291
|
readonly provider: string;
|
|
@@ -1325,6 +1326,14 @@ export interface ApiRouteSpec {
|
|
|
1325
1326
|
readonly responseType?: string;
|
|
1326
1327
|
readonly featureId?: string;
|
|
1327
1328
|
}
|
|
1329
|
+
export interface IpcChannel {
|
|
1330
|
+
readonly channel: string;
|
|
1331
|
+
readonly direction: 'renderer-to-main' | 'main-to-renderer' | 'bidirectional';
|
|
1332
|
+
readonly description: string;
|
|
1333
|
+
readonly requestType?: string;
|
|
1334
|
+
readonly responseType?: string;
|
|
1335
|
+
readonly featureId?: string;
|
|
1336
|
+
}
|
|
1328
1337
|
export interface PageSpec {
|
|
1329
1338
|
readonly path: string;
|
|
1330
1339
|
readonly component: string;
|
|
@@ -1339,6 +1348,7 @@ export interface FeaturePlan {
|
|
|
1339
1348
|
readonly schemaEntities: readonly string[];
|
|
1340
1349
|
readonly apiRoutes: readonly string[];
|
|
1341
1350
|
readonly pages: readonly string[];
|
|
1351
|
+
readonly ipcChannels?: readonly string[];
|
|
1342
1352
|
readonly complexityEstimate: 'trivial' | 'small' | 'medium' | 'large';
|
|
1343
1353
|
}
|
|
1344
1354
|
export type AppCreatePhase = {
|
|
@@ -1368,6 +1378,8 @@ export type AppCreatePhase = {
|
|
|
1368
1378
|
readonly attempt: number;
|
|
1369
1379
|
readonly maxAttempts: number;
|
|
1370
1380
|
readonly errorCount: number;
|
|
1381
|
+
} | {
|
|
1382
|
+
readonly phase: 'integration_verifying';
|
|
1371
1383
|
} | {
|
|
1372
1384
|
readonly phase: 'cross_verifying';
|
|
1373
1385
|
} | {
|
|
@@ -1392,6 +1404,7 @@ export interface AppCreateResult {
|
|
|
1392
1404
|
readonly plan: ArchitecturePlan | null;
|
|
1393
1405
|
readonly featureResults: readonly FeatureBuildResult[];
|
|
1394
1406
|
readonly buildVerification: BuildVerificationResult | null;
|
|
1407
|
+
readonly integrationVerification: IntegrationVerificationResult | null;
|
|
1395
1408
|
readonly crossVerification: CrossFeatureVerification | null;
|
|
1396
1409
|
readonly totalDurationMs: number;
|
|
1397
1410
|
readonly auditTrail: readonly AuditEntry[];
|
|
@@ -1416,11 +1429,27 @@ export interface CrossFeatureVerification {
|
|
|
1416
1429
|
readonly verdict: 'PASS' | 'FAIL' | 'PARTIAL';
|
|
1417
1430
|
}
|
|
1418
1431
|
export interface CrossFeatureCheck {
|
|
1419
|
-
readonly type: 'api_route_exists' | 'page_references_valid' | 'schema_entity_exists' | 'dependency_consistency';
|
|
1432
|
+
readonly type: 'api_route_exists' | 'page_references_valid' | 'schema_entity_exists' | 'dependency_consistency' | 'ipc_channel_exists';
|
|
1420
1433
|
readonly description: string;
|
|
1421
1434
|
readonly verdict: 'PASS' | 'FAIL';
|
|
1422
1435
|
readonly evidence: string;
|
|
1423
1436
|
}
|
|
1437
|
+
export type IntegrationCheckType = 'routing_provider' | 'ipc_handler_coverage' | 'stub_function' | 'unreachable_page';
|
|
1438
|
+
export interface IntegrationCheck {
|
|
1439
|
+
readonly type: IntegrationCheckType;
|
|
1440
|
+
readonly verdict: 'PASS' | 'FAIL';
|
|
1441
|
+
readonly evidence: string;
|
|
1442
|
+
readonly file: string;
|
|
1443
|
+
readonly severity: 'critical' | 'high' | 'medium';
|
|
1444
|
+
}
|
|
1445
|
+
export interface IntegrationVerificationResult {
|
|
1446
|
+
readonly checks: readonly IntegrationCheck[];
|
|
1447
|
+
readonly passedCount: number;
|
|
1448
|
+
readonly failedCount: number;
|
|
1449
|
+
readonly verdict: 'PASS' | 'FAIL';
|
|
1450
|
+
readonly framework: string;
|
|
1451
|
+
readonly totalDurationMs: number;
|
|
1452
|
+
}
|
|
1424
1453
|
export type BuildStepStatus = 'pass' | 'fail' | 'skip' | 'timeout';
|
|
1425
1454
|
export interface BuildStepResult {
|
|
1426
1455
|
readonly step: 'install' | 'build' | 'start' | 'health_check';
|