genesis-ai-cli 7.4.5
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/.env.example +78 -0
- package/README.md +282 -0
- package/dist/src/active-inference/actions.d.ts +75 -0
- package/dist/src/active-inference/actions.js +250 -0
- package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
- package/dist/src/active-inference/autonomous-loop.js +289 -0
- package/dist/src/active-inference/core.d.ts +85 -0
- package/dist/src/active-inference/core.js +555 -0
- package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
- package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
- package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
- package/dist/src/active-inference/demo-value-integration.js +174 -0
- package/dist/src/active-inference/index.d.ts +32 -0
- package/dist/src/active-inference/index.js +88 -0
- package/dist/src/active-inference/integration.d.ts +114 -0
- package/dist/src/active-inference/integration.js +698 -0
- package/dist/src/active-inference/memory-integration.d.ts +51 -0
- package/dist/src/active-inference/memory-integration.js +232 -0
- package/dist/src/active-inference/observations.d.ts +67 -0
- package/dist/src/active-inference/observations.js +147 -0
- package/dist/src/active-inference/test-active-inference.d.ts +8 -0
- package/dist/src/active-inference/test-active-inference.js +320 -0
- package/dist/src/active-inference/test-value-integration.d.ts +6 -0
- package/dist/src/active-inference/test-value-integration.js +168 -0
- package/dist/src/active-inference/types.d.ts +150 -0
- package/dist/src/active-inference/types.js +59 -0
- package/dist/src/active-inference/value-integration.d.ts +164 -0
- package/dist/src/active-inference/value-integration.js +459 -0
- package/dist/src/agents/base-agent.d.ts +53 -0
- package/dist/src/agents/base-agent.js +178 -0
- package/dist/src/agents/builder.d.ts +67 -0
- package/dist/src/agents/builder.js +537 -0
- package/dist/src/agents/critic.d.ts +35 -0
- package/dist/src/agents/critic.js +322 -0
- package/dist/src/agents/ethicist.d.ts +54 -0
- package/dist/src/agents/ethicist.js +393 -0
- package/dist/src/agents/explorer.d.ts +26 -0
- package/dist/src/agents/explorer.js +216 -0
- package/dist/src/agents/feeling.d.ts +41 -0
- package/dist/src/agents/feeling.js +320 -0
- package/dist/src/agents/index.d.ts +111 -0
- package/dist/src/agents/index.js +222 -0
- package/dist/src/agents/memory.d.ts +69 -0
- package/dist/src/agents/memory.js +404 -0
- package/dist/src/agents/message-bus.d.ts +88 -0
- package/dist/src/agents/message-bus.js +267 -0
- package/dist/src/agents/narrator.d.ts +90 -0
- package/dist/src/agents/narrator.js +473 -0
- package/dist/src/agents/planner.d.ts +38 -0
- package/dist/src/agents/planner.js +341 -0
- package/dist/src/agents/predictor.d.ts +73 -0
- package/dist/src/agents/predictor.js +506 -0
- package/dist/src/agents/sensor.d.ts +88 -0
- package/dist/src/agents/sensor.js +377 -0
- package/dist/src/agents/test-agents.d.ts +6 -0
- package/dist/src/agents/test-agents.js +73 -0
- package/dist/src/agents/types.d.ts +194 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/brain/index.d.ts +185 -0
- package/dist/src/brain/index.js +843 -0
- package/dist/src/brain/trace.d.ts +91 -0
- package/dist/src/brain/trace.js +327 -0
- package/dist/src/brain/types.d.ts +165 -0
- package/dist/src/brain/types.js +51 -0
- package/dist/src/cli/chat.d.ts +237 -0
- package/dist/src/cli/chat.js +1959 -0
- package/dist/src/cli/dispatcher.d.ts +182 -0
- package/dist/src/cli/dispatcher.js +718 -0
- package/dist/src/cli/human-loop.d.ts +170 -0
- package/dist/src/cli/human-loop.js +543 -0
- package/dist/src/cli/index.d.ts +12 -0
- package/dist/src/cli/index.js +28 -0
- package/dist/src/cli/interactive.d.ts +141 -0
- package/dist/src/cli/interactive.js +757 -0
- package/dist/src/cli/ui.d.ts +205 -0
- package/dist/src/cli/ui.js +632 -0
- package/dist/src/consciousness/attention-schema.d.ts +154 -0
- package/dist/src/consciousness/attention-schema.js +432 -0
- package/dist/src/consciousness/global-workspace.d.ts +149 -0
- package/dist/src/consciousness/global-workspace.js +422 -0
- package/dist/src/consciousness/index.d.ts +186 -0
- package/dist/src/consciousness/index.js +476 -0
- package/dist/src/consciousness/phi-calculator.d.ts +119 -0
- package/dist/src/consciousness/phi-calculator.js +445 -0
- package/dist/src/consciousness/phi-decisions.d.ts +169 -0
- package/dist/src/consciousness/phi-decisions.js +383 -0
- package/dist/src/consciousness/phi-monitor.d.ts +153 -0
- package/dist/src/consciousness/phi-monitor.js +465 -0
- package/dist/src/consciousness/types.d.ts +260 -0
- package/dist/src/consciousness/types.js +44 -0
- package/dist/src/daemon/dream-mode.d.ts +115 -0
- package/dist/src/daemon/dream-mode.js +470 -0
- package/dist/src/daemon/index.d.ts +162 -0
- package/dist/src/daemon/index.js +542 -0
- package/dist/src/daemon/maintenance.d.ts +139 -0
- package/dist/src/daemon/maintenance.js +549 -0
- package/dist/src/daemon/process.d.ts +82 -0
- package/dist/src/daemon/process.js +442 -0
- package/dist/src/daemon/scheduler.d.ts +90 -0
- package/dist/src/daemon/scheduler.js +494 -0
- package/dist/src/daemon/types.d.ts +213 -0
- package/dist/src/daemon/types.js +50 -0
- package/dist/src/epistemic/index.d.ts +74 -0
- package/dist/src/epistemic/index.js +225 -0
- package/dist/src/grounding/epistemic-stack.d.ts +100 -0
- package/dist/src/grounding/epistemic-stack.js +408 -0
- package/dist/src/grounding/feedback.d.ts +98 -0
- package/dist/src/grounding/feedback.js +276 -0
- package/dist/src/grounding/index.d.ts +123 -0
- package/dist/src/grounding/index.js +224 -0
- package/dist/src/grounding/verifier.d.ts +149 -0
- package/dist/src/grounding/verifier.js +484 -0
- package/dist/src/healing/detector.d.ts +110 -0
- package/dist/src/healing/detector.js +436 -0
- package/dist/src/healing/fixer.d.ts +138 -0
- package/dist/src/healing/fixer.js +572 -0
- package/dist/src/healing/index.d.ts +23 -0
- package/dist/src/healing/index.js +43 -0
- package/dist/src/hooks/index.d.ts +135 -0
- package/dist/src/hooks/index.js +317 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +1266 -0
- package/dist/src/kernel/index.d.ts +155 -0
- package/dist/src/kernel/index.js +795 -0
- package/dist/src/kernel/invariants.d.ts +153 -0
- package/dist/src/kernel/invariants.js +355 -0
- package/dist/src/kernel/test-kernel.d.ts +6 -0
- package/dist/src/kernel/test-kernel.js +108 -0
- package/dist/src/kernel/test-real-mcp.d.ts +10 -0
- package/dist/src/kernel/test-real-mcp.js +295 -0
- package/dist/src/llm/index.d.ts +146 -0
- package/dist/src/llm/index.js +428 -0
- package/dist/src/llm/router.d.ts +136 -0
- package/dist/src/llm/router.js +510 -0
- package/dist/src/mcp/index.d.ts +85 -0
- package/dist/src/mcp/index.js +657 -0
- package/dist/src/mcp/resilient.d.ts +139 -0
- package/dist/src/mcp/resilient.js +417 -0
- package/dist/src/memory/cache.d.ts +118 -0
- package/dist/src/memory/cache.js +356 -0
- package/dist/src/memory/cognitive-workspace.d.ts +231 -0
- package/dist/src/memory/cognitive-workspace.js +521 -0
- package/dist/src/memory/consolidation.d.ts +99 -0
- package/dist/src/memory/consolidation.js +443 -0
- package/dist/src/memory/episodic.d.ts +114 -0
- package/dist/src/memory/episodic.js +394 -0
- package/dist/src/memory/forgetting.d.ts +134 -0
- package/dist/src/memory/forgetting.js +324 -0
- package/dist/src/memory/index.d.ts +211 -0
- package/dist/src/memory/index.js +367 -0
- package/dist/src/memory/indexer.d.ts +123 -0
- package/dist/src/memory/indexer.js +479 -0
- package/dist/src/memory/procedural.d.ts +136 -0
- package/dist/src/memory/procedural.js +479 -0
- package/dist/src/memory/semantic.d.ts +132 -0
- package/dist/src/memory/semantic.js +497 -0
- package/dist/src/memory/types.d.ts +193 -0
- package/dist/src/memory/types.js +15 -0
- package/dist/src/orchestrator.d.ts +65 -0
- package/dist/src/orchestrator.js +317 -0
- package/dist/src/persistence/index.d.ts +257 -0
- package/dist/src/persistence/index.js +763 -0
- package/dist/src/pipeline/executor.d.ts +51 -0
- package/dist/src/pipeline/executor.js +695 -0
- package/dist/src/pipeline/index.d.ts +7 -0
- package/dist/src/pipeline/index.js +11 -0
- package/dist/src/self-production.d.ts +67 -0
- package/dist/src/self-production.js +205 -0
- package/dist/src/subagents/executor.d.ts +58 -0
- package/dist/src/subagents/executor.js +283 -0
- package/dist/src/subagents/index.d.ts +37 -0
- package/dist/src/subagents/index.js +53 -0
- package/dist/src/subagents/registry.d.ts +23 -0
- package/dist/src/subagents/registry.js +167 -0
- package/dist/src/subagents/types.d.ts +79 -0
- package/dist/src/subagents/types.js +14 -0
- package/dist/src/tools/bash.d.ts +139 -0
- package/dist/src/tools/bash.js +583 -0
- package/dist/src/tools/edit.d.ts +125 -0
- package/dist/src/tools/edit.js +424 -0
- package/dist/src/tools/git.d.ts +179 -0
- package/dist/src/tools/git.js +504 -0
- package/dist/src/tools/index.d.ts +21 -0
- package/dist/src/tools/index.js +163 -0
- package/dist/src/types.d.ts +145 -0
- package/dist/src/types.js +7 -0
- package/dist/src/world-model/decoder.d.ts +163 -0
- package/dist/src/world-model/decoder.js +517 -0
- package/dist/src/world-model/digital-twin.d.ts +219 -0
- package/dist/src/world-model/digital-twin.js +695 -0
- package/dist/src/world-model/encoder.d.ts +141 -0
- package/dist/src/world-model/encoder.js +564 -0
- package/dist/src/world-model/index.d.ts +221 -0
- package/dist/src/world-model/index.js +772 -0
- package/dist/src/world-model/predictor.d.ts +161 -0
- package/dist/src/world-model/predictor.js +681 -0
- package/dist/src/world-model/test-value-jepa.d.ts +8 -0
- package/dist/src/world-model/test-value-jepa.js +430 -0
- package/dist/src/world-model/types.d.ts +341 -0
- package/dist/src/world-model/types.js +69 -0
- package/dist/src/world-model/value-jepa.d.ts +247 -0
- package/dist/src/world-model/value-jepa.js +622 -0
- package/dist/test/brain.test.d.ts +11 -0
- package/dist/test/brain.test.js +358 -0
- package/dist/test/cli/dispatcher.test.d.ts +4 -0
- package/dist/test/cli/dispatcher.test.js +332 -0
- package/dist/test/cli/human-loop.test.d.ts +4 -0
- package/dist/test/cli/human-loop.test.js +270 -0
- package/dist/test/grounding/feedback.test.d.ts +4 -0
- package/dist/test/grounding/feedback.test.js +462 -0
- package/dist/test/grounding/verifier.test.d.ts +4 -0
- package/dist/test/grounding/verifier.test.js +442 -0
- package/dist/test/grounding.test.d.ts +6 -0
- package/dist/test/grounding.test.js +246 -0
- package/dist/test/healing/detector.test.d.ts +4 -0
- package/dist/test/healing/detector.test.js +266 -0
- package/dist/test/healing/fixer.test.d.ts +4 -0
- package/dist/test/healing/fixer.test.js +369 -0
- package/dist/test/integration.test.d.ts +5 -0
- package/dist/test/integration.test.js +290 -0
- package/dist/test/tools/bash.test.d.ts +4 -0
- package/dist/test/tools/bash.test.js +348 -0
- package/dist/test/tools/edit.test.d.ts +4 -0
- package/dist/test/tools/edit.test.js +350 -0
- package/dist/test/tools/git.test.d.ts +4 -0
- package/dist/test/tools/git.test.js +350 -0
- package/package.json +60 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis Grounding Verifier
|
|
3
|
+
*
|
|
4
|
+
* Verifies that generated code is correct:
|
|
5
|
+
* - Compiles without errors
|
|
6
|
+
* - Tests pass
|
|
7
|
+
* - Semantic match with intent
|
|
8
|
+
* - No regressions introduced
|
|
9
|
+
*/
|
|
10
|
+
export interface VerificationContext {
|
|
11
|
+
/** Working directory */
|
|
12
|
+
workingDirectory: string;
|
|
13
|
+
/** Build command (default: npm run build) */
|
|
14
|
+
buildCommand?: string;
|
|
15
|
+
/** Test command (default: npm test) */
|
|
16
|
+
testCommand?: string;
|
|
17
|
+
/** Type check command (default: npx tsc --noEmit) */
|
|
18
|
+
typeCheckCommand?: string;
|
|
19
|
+
/** Lint command (optional) */
|
|
20
|
+
lintCommand?: string;
|
|
21
|
+
/** Timeout in ms (default: 60000) */
|
|
22
|
+
timeout?: number;
|
|
23
|
+
/** Files that were modified */
|
|
24
|
+
modifiedFiles?: string[];
|
|
25
|
+
/** Original intent/request */
|
|
26
|
+
intent?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface GroundingIssue {
|
|
29
|
+
/** Issue type */
|
|
30
|
+
type: 'compile' | 'type' | 'test' | 'lint' | 'semantic' | 'regression';
|
|
31
|
+
/** Severity */
|
|
32
|
+
severity: 'error' | 'warning' | 'info';
|
|
33
|
+
/** Issue message */
|
|
34
|
+
message: string;
|
|
35
|
+
/** File path if applicable */
|
|
36
|
+
file?: string;
|
|
37
|
+
/** Line number if applicable */
|
|
38
|
+
line?: number;
|
|
39
|
+
/** Suggested fix */
|
|
40
|
+
suggestion?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface CodeVerificationResult {
|
|
43
|
+
/** Overall success */
|
|
44
|
+
success: boolean;
|
|
45
|
+
/** Build/compile passed */
|
|
46
|
+
compiles: boolean;
|
|
47
|
+
/** Type checking passed */
|
|
48
|
+
typesValid: boolean;
|
|
49
|
+
/** Tests passed */
|
|
50
|
+
testsPass: boolean;
|
|
51
|
+
/** Tests passed count */
|
|
52
|
+
testsPassed: number;
|
|
53
|
+
/** Tests failed count */
|
|
54
|
+
testsFailed: number;
|
|
55
|
+
/** Tests total count */
|
|
56
|
+
testsTotal: number;
|
|
57
|
+
/** Lint passed (if configured) */
|
|
58
|
+
lintPass: boolean;
|
|
59
|
+
/** Semantic match score (0.0 - 1.0) */
|
|
60
|
+
semanticMatch: number;
|
|
61
|
+
/** All issues found */
|
|
62
|
+
issues: GroundingIssue[];
|
|
63
|
+
/** Execution time in ms */
|
|
64
|
+
duration: number;
|
|
65
|
+
/** Raw outputs */
|
|
66
|
+
outputs: {
|
|
67
|
+
build?: string;
|
|
68
|
+
typeCheck?: string;
|
|
69
|
+
test?: string;
|
|
70
|
+
lint?: string;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export interface VerifierConfig {
|
|
74
|
+
/** Default build command */
|
|
75
|
+
buildCommand: string;
|
|
76
|
+
/** Default test command */
|
|
77
|
+
testCommand: string;
|
|
78
|
+
/** Default type check command */
|
|
79
|
+
typeCheckCommand: string;
|
|
80
|
+
/** Default lint command */
|
|
81
|
+
lintCommand?: string;
|
|
82
|
+
/** Default timeout */
|
|
83
|
+
timeout: number;
|
|
84
|
+
/** Skip build step */
|
|
85
|
+
skipBuild: boolean;
|
|
86
|
+
/** Skip type check step */
|
|
87
|
+
skipTypeCheck: boolean;
|
|
88
|
+
/** Skip test step */
|
|
89
|
+
skipTest: boolean;
|
|
90
|
+
/** Skip lint step */
|
|
91
|
+
skipLint: boolean;
|
|
92
|
+
}
|
|
93
|
+
export declare class Verifier {
|
|
94
|
+
private config;
|
|
95
|
+
constructor(config?: Partial<VerifierConfig>);
|
|
96
|
+
/**
|
|
97
|
+
* Run full verification pipeline
|
|
98
|
+
*/
|
|
99
|
+
verify(context: VerificationContext): Promise<CodeVerificationResult>;
|
|
100
|
+
/**
|
|
101
|
+
* Quick verification (type check only)
|
|
102
|
+
*/
|
|
103
|
+
quickVerify(context: VerificationContext): Promise<CodeVerificationResult>;
|
|
104
|
+
/**
|
|
105
|
+
* Verify a single file compiles
|
|
106
|
+
*/
|
|
107
|
+
verifyFile(filePath: string, cwd: string): Promise<{
|
|
108
|
+
valid: boolean;
|
|
109
|
+
errors: GroundingIssue[];
|
|
110
|
+
}>;
|
|
111
|
+
/**
|
|
112
|
+
* Execute command with timeout
|
|
113
|
+
*/
|
|
114
|
+
private execWithTimeout;
|
|
115
|
+
/**
|
|
116
|
+
* Parse test output for pass/fail counts
|
|
117
|
+
*/
|
|
118
|
+
private parseTestOutput;
|
|
119
|
+
/**
|
|
120
|
+
* Calculate semantic match (basic heuristic)
|
|
121
|
+
*/
|
|
122
|
+
private calculateSemanticMatch;
|
|
123
|
+
/**
|
|
124
|
+
* Get current configuration
|
|
125
|
+
*/
|
|
126
|
+
getConfig(): VerifierConfig;
|
|
127
|
+
/**
|
|
128
|
+
* Update configuration
|
|
129
|
+
*/
|
|
130
|
+
updateConfig(updates: Partial<VerifierConfig>): void;
|
|
131
|
+
}
|
|
132
|
+
export declare function getVerifier(config?: Partial<VerifierConfig>): Verifier;
|
|
133
|
+
export declare function resetVerifier(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Verify code in a directory
|
|
136
|
+
*/
|
|
137
|
+
export declare function verifyCode(context: VerificationContext): Promise<CodeVerificationResult>;
|
|
138
|
+
/**
|
|
139
|
+
* Quick verify (type check only)
|
|
140
|
+
*/
|
|
141
|
+
export declare function quickVerify(context: VerificationContext): Promise<CodeVerificationResult>;
|
|
142
|
+
/**
|
|
143
|
+
* Check if code is valid (compiles and types check)
|
|
144
|
+
*/
|
|
145
|
+
export declare function isCodeValid(workingDirectory: string): Promise<boolean>;
|
|
146
|
+
/**
|
|
147
|
+
* Format verification result for display
|
|
148
|
+
*/
|
|
149
|
+
export declare function formatVerificationResult(result: CodeVerificationResult): string;
|
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis Grounding Verifier
|
|
4
|
+
*
|
|
5
|
+
* Verifies that generated code is correct:
|
|
6
|
+
* - Compiles without errors
|
|
7
|
+
* - Tests pass
|
|
8
|
+
* - Semantic match with intent
|
|
9
|
+
* - No regressions introduced
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.Verifier = void 0;
|
|
46
|
+
exports.getVerifier = getVerifier;
|
|
47
|
+
exports.resetVerifier = resetVerifier;
|
|
48
|
+
exports.verifyCode = verifyCode;
|
|
49
|
+
exports.quickVerify = quickVerify;
|
|
50
|
+
exports.isCodeValid = isCodeValid;
|
|
51
|
+
exports.formatVerificationResult = formatVerificationResult;
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const child_process_1 = require("child_process");
|
|
55
|
+
const util_1 = require("util");
|
|
56
|
+
const detector_js_1 = require("../healing/detector.js");
|
|
57
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
58
|
+
const DEFAULT_CONFIG = {
|
|
59
|
+
buildCommand: 'npm run build',
|
|
60
|
+
testCommand: 'npm test',
|
|
61
|
+
typeCheckCommand: 'npx tsc --noEmit',
|
|
62
|
+
lintCommand: undefined,
|
|
63
|
+
timeout: 120000,
|
|
64
|
+
skipBuild: false,
|
|
65
|
+
skipTypeCheck: false,
|
|
66
|
+
skipTest: false,
|
|
67
|
+
skipLint: true,
|
|
68
|
+
};
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Verifier Class
|
|
71
|
+
// ============================================================================
|
|
72
|
+
class Verifier {
|
|
73
|
+
config;
|
|
74
|
+
constructor(config) {
|
|
75
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Run full verification pipeline
|
|
79
|
+
*/
|
|
80
|
+
async verify(context) {
|
|
81
|
+
const startTime = Date.now();
|
|
82
|
+
const issues = [];
|
|
83
|
+
const outputs = {};
|
|
84
|
+
let compiles = true;
|
|
85
|
+
let typesValid = true;
|
|
86
|
+
let testsPass = true;
|
|
87
|
+
let lintPass = true;
|
|
88
|
+
let testsPassed = 0;
|
|
89
|
+
let testsFailed = 0;
|
|
90
|
+
let testsTotal = 0;
|
|
91
|
+
const timeout = context.timeout || this.config.timeout;
|
|
92
|
+
const cwd = context.workingDirectory;
|
|
93
|
+
// Step 1: Type Check
|
|
94
|
+
if (!this.config.skipTypeCheck) {
|
|
95
|
+
const typeCheckCmd = context.typeCheckCommand || this.config.typeCheckCommand;
|
|
96
|
+
try {
|
|
97
|
+
const { stdout, stderr } = await this.execWithTimeout(typeCheckCmd, cwd, timeout);
|
|
98
|
+
outputs.typeCheck = stdout + stderr;
|
|
99
|
+
const typeErrors = (0, detector_js_1.detectErrors)(outputs.typeCheck);
|
|
100
|
+
if (!typeErrors.success) {
|
|
101
|
+
typesValid = false;
|
|
102
|
+
for (const error of typeErrors.errors) {
|
|
103
|
+
if (error.severity === 'error') {
|
|
104
|
+
issues.push({
|
|
105
|
+
type: 'type',
|
|
106
|
+
severity: 'error',
|
|
107
|
+
message: error.message,
|
|
108
|
+
file: error.file,
|
|
109
|
+
line: error.line,
|
|
110
|
+
suggestion: error.fixHint,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
typesValid = false;
|
|
118
|
+
const typeCheckOutput = error.stderr || error.message || '';
|
|
119
|
+
outputs.typeCheck = typeCheckOutput;
|
|
120
|
+
const typeErrors = (0, detector_js_1.detectErrors)(typeCheckOutput);
|
|
121
|
+
for (const err of typeErrors.errors) {
|
|
122
|
+
issues.push({
|
|
123
|
+
type: 'type',
|
|
124
|
+
severity: 'error',
|
|
125
|
+
message: err.message,
|
|
126
|
+
file: err.file,
|
|
127
|
+
line: err.line,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Step 2: Build
|
|
133
|
+
if (!this.config.skipBuild) {
|
|
134
|
+
const buildCmd = context.buildCommand || this.config.buildCommand;
|
|
135
|
+
try {
|
|
136
|
+
const { stdout, stderr } = await this.execWithTimeout(buildCmd, cwd, timeout);
|
|
137
|
+
outputs.build = stdout + stderr;
|
|
138
|
+
const buildErrors = (0, detector_js_1.detectErrors)(outputs.build);
|
|
139
|
+
if (!buildErrors.success) {
|
|
140
|
+
compiles = false;
|
|
141
|
+
for (const error of buildErrors.errors) {
|
|
142
|
+
if (error.severity === 'error') {
|
|
143
|
+
issues.push({
|
|
144
|
+
type: 'compile',
|
|
145
|
+
severity: 'error',
|
|
146
|
+
message: error.message,
|
|
147
|
+
file: error.file,
|
|
148
|
+
line: error.line,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
compiles = false;
|
|
156
|
+
outputs.build = error.stderr || error.message;
|
|
157
|
+
issues.push({
|
|
158
|
+
type: 'compile',
|
|
159
|
+
severity: 'error',
|
|
160
|
+
message: `Build failed: ${error.message}`,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Step 3: Tests (only if build passed)
|
|
165
|
+
if (!this.config.skipTest && compiles) {
|
|
166
|
+
const testCmd = context.testCommand || this.config.testCommand;
|
|
167
|
+
try {
|
|
168
|
+
const { stdout, stderr } = await this.execWithTimeout(testCmd, cwd, timeout);
|
|
169
|
+
outputs.test = stdout + stderr;
|
|
170
|
+
const testResult = this.parseTestOutput(outputs.test);
|
|
171
|
+
testsPassed = testResult.passed;
|
|
172
|
+
testsFailed = testResult.failed;
|
|
173
|
+
testsTotal = testResult.total;
|
|
174
|
+
testsPass = testResult.failed === 0;
|
|
175
|
+
if (!testsPass) {
|
|
176
|
+
const testErrors = (0, detector_js_1.detectErrors)(outputs.test);
|
|
177
|
+
for (const error of testErrors.errors) {
|
|
178
|
+
if (error.category === 'test') {
|
|
179
|
+
issues.push({
|
|
180
|
+
type: 'test',
|
|
181
|
+
severity: 'error',
|
|
182
|
+
message: error.message,
|
|
183
|
+
file: error.file,
|
|
184
|
+
line: error.line,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
testsPass = false;
|
|
192
|
+
const testOutput = error.stdout || error.stderr || error.message || '';
|
|
193
|
+
outputs.test = testOutput;
|
|
194
|
+
const testResult = this.parseTestOutput(testOutput);
|
|
195
|
+
testsPassed = testResult.passed;
|
|
196
|
+
testsFailed = testResult.failed;
|
|
197
|
+
testsTotal = testResult.total;
|
|
198
|
+
const testErrors = (0, detector_js_1.detectErrors)(testOutput);
|
|
199
|
+
for (const err of testErrors.errors) {
|
|
200
|
+
if (err.category === 'test') {
|
|
201
|
+
issues.push({
|
|
202
|
+
type: 'test',
|
|
203
|
+
severity: 'error',
|
|
204
|
+
message: err.message,
|
|
205
|
+
file: err.file,
|
|
206
|
+
line: err.line,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Step 4: Lint (if configured)
|
|
213
|
+
if (!this.config.skipLint && this.config.lintCommand) {
|
|
214
|
+
const lintCmd = context.lintCommand || this.config.lintCommand;
|
|
215
|
+
try {
|
|
216
|
+
const { stdout, stderr } = await this.execWithTimeout(lintCmd, cwd, timeout);
|
|
217
|
+
outputs.lint = stdout + stderr;
|
|
218
|
+
const lintErrors = (0, detector_js_1.detectErrors)(outputs.lint);
|
|
219
|
+
if (lintErrors.byCategory.lint > 0) {
|
|
220
|
+
lintPass = lintErrors.bySeverity.error === 0;
|
|
221
|
+
for (const error of lintErrors.errors) {
|
|
222
|
+
if (error.category === 'lint') {
|
|
223
|
+
issues.push({
|
|
224
|
+
type: 'lint',
|
|
225
|
+
severity: error.severity,
|
|
226
|
+
message: error.message,
|
|
227
|
+
file: error.file,
|
|
228
|
+
line: error.line,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
outputs.lint = error.stderr || error.message;
|
|
236
|
+
// Lint errors are often non-fatal
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Calculate semantic match (basic heuristic for now)
|
|
240
|
+
const semanticMatch = this.calculateSemanticMatch(context, issues);
|
|
241
|
+
const duration = Date.now() - startTime;
|
|
242
|
+
return {
|
|
243
|
+
success: compiles && typesValid && testsPass && (lintPass || this.config.skipLint),
|
|
244
|
+
compiles,
|
|
245
|
+
typesValid,
|
|
246
|
+
testsPass,
|
|
247
|
+
testsPassed,
|
|
248
|
+
testsFailed,
|
|
249
|
+
testsTotal,
|
|
250
|
+
lintPass,
|
|
251
|
+
semanticMatch,
|
|
252
|
+
issues,
|
|
253
|
+
duration,
|
|
254
|
+
outputs,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Quick verification (type check only)
|
|
259
|
+
*/
|
|
260
|
+
async quickVerify(context) {
|
|
261
|
+
return this.verify({
|
|
262
|
+
...context,
|
|
263
|
+
buildCommand: 'true', // Skip actual build
|
|
264
|
+
testCommand: 'true', // Skip tests
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Verify a single file compiles
|
|
269
|
+
*/
|
|
270
|
+
async verifyFile(filePath, cwd) {
|
|
271
|
+
const errors = [];
|
|
272
|
+
// Check file exists
|
|
273
|
+
const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
274
|
+
if (!fs.existsSync(fullPath)) {
|
|
275
|
+
return {
|
|
276
|
+
valid: false,
|
|
277
|
+
errors: [{
|
|
278
|
+
type: 'compile',
|
|
279
|
+
severity: 'error',
|
|
280
|
+
message: `File not found: ${filePath}`,
|
|
281
|
+
file: filePath,
|
|
282
|
+
}],
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// Type check single file
|
|
286
|
+
try {
|
|
287
|
+
const cmd = `npx tsc --noEmit "${fullPath}"`;
|
|
288
|
+
await this.execWithTimeout(cmd, cwd, 30000);
|
|
289
|
+
return { valid: true, errors: [] };
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
const output = error.stderr || error.stdout || error.message;
|
|
293
|
+
const detected = (0, detector_js_1.detectErrors)(output);
|
|
294
|
+
for (const err of detected.errors) {
|
|
295
|
+
errors.push({
|
|
296
|
+
type: 'type',
|
|
297
|
+
severity: 'error',
|
|
298
|
+
message: err.message,
|
|
299
|
+
file: err.file || filePath,
|
|
300
|
+
line: err.line,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
return { valid: false, errors };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Execute command with timeout
|
|
308
|
+
*/
|
|
309
|
+
async execWithTimeout(command, cwd, timeout) {
|
|
310
|
+
return new Promise((resolve, reject) => {
|
|
311
|
+
const child = (0, child_process_1.exec)(command, { cwd, timeout }, (error, stdout, stderr) => {
|
|
312
|
+
if (error) {
|
|
313
|
+
reject({ ...error, stdout, stderr });
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
resolve({ stdout, stderr });
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
// Handle timeout
|
|
320
|
+
setTimeout(() => {
|
|
321
|
+
child.kill('SIGTERM');
|
|
322
|
+
reject(new Error(`Command timed out after ${timeout}ms: ${command}`));
|
|
323
|
+
}, timeout);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Parse test output for pass/fail counts
|
|
328
|
+
*/
|
|
329
|
+
parseTestOutput(output) {
|
|
330
|
+
let passed = 0;
|
|
331
|
+
let failed = 0;
|
|
332
|
+
let total = 0;
|
|
333
|
+
// Node test runner format
|
|
334
|
+
const nodeTestMatch = output.match(/ℹ tests (\d+)/);
|
|
335
|
+
const nodePassMatch = output.match(/ℹ pass (\d+)/);
|
|
336
|
+
const nodeFailMatch = output.match(/ℹ fail (\d+)/);
|
|
337
|
+
if (nodeTestMatch) {
|
|
338
|
+
total = parseInt(nodeTestMatch[1], 10);
|
|
339
|
+
passed = nodePassMatch ? parseInt(nodePassMatch[1], 10) : 0;
|
|
340
|
+
failed = nodeFailMatch ? parseInt(nodeFailMatch[1], 10) : 0;
|
|
341
|
+
return { passed, failed, total };
|
|
342
|
+
}
|
|
343
|
+
// Jest format
|
|
344
|
+
const jestMatch = output.match(/Tests:\s+(\d+)\s+passed,\s+(\d+)\s+total/);
|
|
345
|
+
if (jestMatch) {
|
|
346
|
+
passed = parseInt(jestMatch[1], 10);
|
|
347
|
+
total = parseInt(jestMatch[2], 10);
|
|
348
|
+
failed = total - passed;
|
|
349
|
+
return { passed, failed, total };
|
|
350
|
+
}
|
|
351
|
+
const jestFailMatch = output.match(/Tests:\s+(\d+)\s+failed,\s+(\d+)\s+passed,\s+(\d+)\s+total/);
|
|
352
|
+
if (jestFailMatch) {
|
|
353
|
+
failed = parseInt(jestFailMatch[1], 10);
|
|
354
|
+
passed = parseInt(jestFailMatch[2], 10);
|
|
355
|
+
total = parseInt(jestFailMatch[3], 10);
|
|
356
|
+
return { passed, failed, total };
|
|
357
|
+
}
|
|
358
|
+
// Count checkmarks and crosses
|
|
359
|
+
const passCount = (output.match(/✔|✓|PASS/g) || []).length;
|
|
360
|
+
const failCount = (output.match(/✖|✗|FAIL/g) || []).length;
|
|
361
|
+
return {
|
|
362
|
+
passed: passCount,
|
|
363
|
+
failed: failCount,
|
|
364
|
+
total: passCount + failCount,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Calculate semantic match (basic heuristic)
|
|
369
|
+
*/
|
|
370
|
+
calculateSemanticMatch(context, issues) {
|
|
371
|
+
// Start with 1.0 and deduct for issues
|
|
372
|
+
let score = 1.0;
|
|
373
|
+
// Deduct for each type of issue
|
|
374
|
+
for (const issue of issues) {
|
|
375
|
+
switch (issue.type) {
|
|
376
|
+
case 'compile':
|
|
377
|
+
case 'type':
|
|
378
|
+
score -= 0.2; // Major issue
|
|
379
|
+
break;
|
|
380
|
+
case 'test':
|
|
381
|
+
score -= 0.15; // Significant issue
|
|
382
|
+
break;
|
|
383
|
+
case 'lint':
|
|
384
|
+
score -= 0.05; // Minor issue
|
|
385
|
+
break;
|
|
386
|
+
case 'semantic':
|
|
387
|
+
case 'regression':
|
|
388
|
+
score -= 0.1;
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// Bonus if modified files exist and are valid
|
|
393
|
+
if (context.modifiedFiles && context.modifiedFiles.length > 0) {
|
|
394
|
+
const allExist = context.modifiedFiles.every(f => {
|
|
395
|
+
const fullPath = path.isAbsolute(f) ? f : path.join(context.workingDirectory, f);
|
|
396
|
+
return fs.existsSync(fullPath);
|
|
397
|
+
});
|
|
398
|
+
if (allExist)
|
|
399
|
+
score += 0.1;
|
|
400
|
+
}
|
|
401
|
+
return Math.max(0, Math.min(1, score));
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Get current configuration
|
|
405
|
+
*/
|
|
406
|
+
getConfig() {
|
|
407
|
+
return { ...this.config };
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Update configuration
|
|
411
|
+
*/
|
|
412
|
+
updateConfig(updates) {
|
|
413
|
+
this.config = { ...this.config, ...updates };
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
exports.Verifier = Verifier;
|
|
417
|
+
// ============================================================================
|
|
418
|
+
// Singleton Instance
|
|
419
|
+
// ============================================================================
|
|
420
|
+
let verifierInstance = null;
|
|
421
|
+
function getVerifier(config) {
|
|
422
|
+
if (!verifierInstance) {
|
|
423
|
+
verifierInstance = new Verifier(config);
|
|
424
|
+
}
|
|
425
|
+
else if (config) {
|
|
426
|
+
verifierInstance.updateConfig(config);
|
|
427
|
+
}
|
|
428
|
+
return verifierInstance;
|
|
429
|
+
}
|
|
430
|
+
function resetVerifier() {
|
|
431
|
+
verifierInstance = null;
|
|
432
|
+
}
|
|
433
|
+
// ============================================================================
|
|
434
|
+
// Convenience Functions
|
|
435
|
+
// ============================================================================
|
|
436
|
+
/**
|
|
437
|
+
* Verify code in a directory
|
|
438
|
+
*/
|
|
439
|
+
async function verifyCode(context) {
|
|
440
|
+
return getVerifier().verify(context);
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Quick verify (type check only)
|
|
444
|
+
*/
|
|
445
|
+
async function quickVerify(context) {
|
|
446
|
+
return getVerifier().quickVerify(context);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Check if code is valid (compiles and types check)
|
|
450
|
+
*/
|
|
451
|
+
async function isCodeValid(workingDirectory) {
|
|
452
|
+
const result = await getVerifier().verify({ workingDirectory });
|
|
453
|
+
return result.compiles && result.typesValid;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Format verification result for display
|
|
457
|
+
*/
|
|
458
|
+
function formatVerificationResult(result) {
|
|
459
|
+
const lines = [];
|
|
460
|
+
// Header
|
|
461
|
+
const status = result.success ? '✓ PASSED' : '✗ FAILED';
|
|
462
|
+
lines.push(`Verification ${status} (${result.duration}ms)`);
|
|
463
|
+
lines.push('');
|
|
464
|
+
// Summary
|
|
465
|
+
lines.push('Summary:');
|
|
466
|
+
lines.push(` Compiles: ${result.compiles ? '✓' : '✗'}`);
|
|
467
|
+
lines.push(` Types: ${result.typesValid ? '✓' : '✗'}`);
|
|
468
|
+
lines.push(` Tests: ${result.testsPass ? '✓' : '✗'} (${result.testsPassed}/${result.testsTotal})`);
|
|
469
|
+
if (!result.lintPass) {
|
|
470
|
+
lines.push(` Lint: ✗`);
|
|
471
|
+
}
|
|
472
|
+
lines.push(` Semantic: ${(result.semanticMatch * 100).toFixed(0)}%`);
|
|
473
|
+
lines.push('');
|
|
474
|
+
// Issues
|
|
475
|
+
if (result.issues.length > 0) {
|
|
476
|
+
lines.push(`Issues (${result.issues.length}):`);
|
|
477
|
+
for (const issue of result.issues) {
|
|
478
|
+
const prefix = issue.severity === 'error' ? '✗' : issue.severity === 'warning' ? '⚠' : 'ℹ';
|
|
479
|
+
const location = issue.file ? ` at ${issue.file}${issue.line ? `:${issue.line}` : ''}` : '';
|
|
480
|
+
lines.push(` ${prefix} [${issue.type}] ${issue.message}${location}`);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return lines.join('\n');
|
|
484
|
+
}
|