@rigour-labs/core 6.6.6 → 6.7.1
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 +16 -92
- package/dist/environment.test.js +0 -4
- package/dist/gates/agent-team.d.ts +0 -2
- package/dist/gates/agent-team.js +0 -8
- package/dist/gates/checkpoint.d.ts +0 -1
- package/dist/gates/checkpoint.js +0 -1
- package/dist/gates/context.d.ts +0 -4
- package/dist/gates/context.js +7 -17
- package/dist/gates/deep-analysis.d.ts +0 -1
- package/dist/gates/deep-runner.js +0 -1
- package/dist/gates/frontend-secret-exposure.test.js +2 -2
- package/dist/gates/hallucinated-imports/index.d.ts +0 -2
- package/dist/gates/hallucinated-imports/index.js +2 -2
- package/dist/gates/hallucinated-imports/js-resolver.js +1 -0
- package/dist/gates/hallucinated-imports.test.js +10 -0
- package/dist/gates/runner.js +3 -4
- package/dist/gates/test-quality-matchers.d.ts +0 -4
- package/dist/gates/test-quality-matchers.js +0 -7
- package/dist/gates/test-quality.d.ts +0 -2
- package/dist/gates/test-quality.js +1 -10
- package/dist/hooks/checker.js +1 -1
- package/dist/hooks/index.d.ts +1 -2
- package/dist/hooks/index.js +0 -1
- package/dist/hooks/types.d.ts +0 -14
- package/dist/hooks/types.js +1 -15
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/inference/cloud-provider.d.ts +2 -0
- package/dist/inference/cloud-provider.js +16 -6
- package/dist/inference/cloud-provider.test.js +21 -0
- package/dist/pattern-index/embeddings.d.ts +0 -5
- package/dist/pattern-index/embeddings.js +11 -4
- package/dist/pattern-index/semantic-runtime.d.ts +10 -0
- package/dist/pattern-index/semantic-runtime.js +46 -0
- package/dist/pattern-index/semantic-runtime.test.d.ts +1 -0
- package/dist/pattern-index/semantic-runtime.test.js +31 -0
- package/dist/review/backtest-judges.d.ts +38 -0
- package/dist/review/backtest-judges.js +63 -0
- package/dist/review/backtest-judges.test.d.ts +1 -0
- package/dist/review/backtest-judges.test.js +32 -0
- package/dist/review/backtest.d.ts +9 -4
- package/dist/review/backtest.js +19 -9
- package/dist/review/backtest.test.js +2 -2
- package/dist/review/baseline.js +2 -1
- package/dist/review/dead-code.test.js +7 -0
- package/dist/review/fix-scope.d.ts +21 -0
- package/dist/review/fix-scope.js +94 -0
- package/dist/review/fix-scope.test.d.ts +1 -0
- package/dist/review/fix-scope.test.js +104 -0
- package/dist/review/lint-overlay.js +1 -1
- package/dist/review/orphan-files.js +3 -2
- package/dist/review/partial-wiring.js +5 -3
- package/dist/review/query-patterns.js +3 -2
- package/dist/review/review.js +2 -1
- package/dist/review/reviewer/adapters.d.ts +23 -7
- package/dist/review/reviewer/adapters.js +32 -7
- package/dist/review/reviewer/adapters.test.d.ts +1 -0
- package/dist/review/reviewer/adapters.test.js +23 -0
- package/dist/review/reviewer/background.d.ts +8 -1
- package/dist/review/reviewer/background.js +34 -9
- package/dist/review/reviewer/background.test.js +16 -2
- package/dist/review/reviewer/consensus.d.ts +36 -0
- package/dist/review/reviewer/consensus.js +144 -0
- package/dist/review/reviewer/context.d.ts +75 -0
- package/dist/review/reviewer/context.js +140 -0
- package/dist/review/reviewer/context.test.d.ts +1 -0
- package/dist/review/reviewer/context.test.js +18 -0
- package/dist/review/reviewer/exec.js +6 -2
- package/dist/review/reviewer/exec.test.d.ts +1 -0
- package/dist/review/reviewer/exec.test.js +23 -0
- package/dist/review/reviewer/inputs.d.ts +2 -0
- package/dist/review/reviewer/inputs.js +5 -1
- package/dist/review/reviewer/panel.d.ts +67 -0
- package/dist/review/reviewer/panel.js +101 -0
- package/dist/review/reviewer/panel.test.d.ts +1 -0
- package/dist/review/reviewer/panel.test.js +110 -0
- package/dist/review/reviewer/prompt.d.ts +11 -0
- package/dist/review/reviewer/prompt.js +26 -4
- package/dist/review/reviewer/settings.d.ts +58 -0
- package/dist/review/reviewer/settings.js +152 -0
- package/dist/review/reviewer/settings.test.d.ts +1 -0
- package/dist/review/reviewer/settings.test.js +57 -0
- package/dist/review/reviewer/store.d.ts +25 -2
- package/dist/review/reviewer/store.js +43 -1
- package/dist/review/reviewer/usage.d.ts +2 -0
- package/dist/review/reviewer/usage.js +28 -0
- package/dist/review/reviewer/usage.test.d.ts +1 -0
- package/dist/review/reviewer/usage.test.js +14 -0
- package/dist/review/reviewer/verdict.d.ts +15 -1
- package/dist/review/reviewer/verdict.js +17 -7
- package/dist/review/reviewer.d.ts +45 -2
- package/dist/review/reviewer.js +186 -25
- package/dist/review/reviewer.test.js +127 -12
- package/dist/review/test-files.d.ts +5 -1
- package/dist/review/test-files.js +6 -2
- package/dist/review/toolchain.js +10 -3
- package/dist/review/toolchain.test.js +6 -3
- package/dist/review/typed/program.d.ts +0 -1
- package/dist/review/typed/program.js +3 -3
- package/dist/review/typed/redundancy.js +43 -4
- package/dist/review/typed/redundancy.test.js +58 -0
- package/dist/review/typed/schema-nullability.d.ts +6 -0
- package/dist/review/typed/schema-nullability.js +218 -0
- package/dist/review/typed/schema-nullability.test.d.ts +1 -0
- package/dist/review/typed/schema-nullability.test.js +63 -0
- package/dist/review/unused-exports.js +5 -6
- package/dist/semantic/learn/types.d.ts +2 -2
- package/dist/services/adaptive-thresholds.d.ts +2 -52
- package/dist/services/adaptive-thresholds.js +2 -147
- package/dist/services/adaptive-thresholds.test.js +1 -81
- package/dist/settings.d.ts +14 -6
- package/dist/settings.js +0 -12
- package/dist/storage/team-diagnostics.js +1 -1
- package/dist/storage/team-schema.d.ts +1 -1
- package/dist/storage/team-schema.js +2 -0
- package/dist/storage/team-store.js +26 -3
- package/dist/storage/team-sync-scope.test.js +35 -2
- package/dist/telemetry/telemetry.d.ts +5 -0
- package/dist/telemetry/telemetry.js +11 -1
- package/dist/templates/paradigms.js +0 -8
- package/dist/templates/presets.d.ts +0 -1
- package/dist/templates/presets.js +0 -23
- package/dist/templates/universal-config.js +8 -45
- package/dist/types/index.d.ts +108 -566
- package/dist/types/index.js +41 -66
- package/dist/types/index.test.d.ts +1 -0
- package/dist/types/index.test.js +33 -0
- package/dist/utils/command-line.d.ts +8 -0
- package/dist/utils/command-line.js +8 -0
- package/dist/utils/command-line.test.d.ts +1 -0
- package/dist/utils/command-line.test.js +8 -0
- package/dist/utils/profile.js +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -1,104 +1,28 @@
|
|
|
1
1
|
# @rigour-labs/core
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@rigour-labs/core)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
The engine behind [Rigour](https://github.com/rigour-labs/rigour): the checks, the review of a change, the
|
|
7
|
+
reviewer that runs coding agents' own CLIs as judges, model review, local learning and the team database.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
Most people want the command, [@rigour-labs/cli](https://www.npmjs.com/package/@rigour-labs/cli), or the MCP
|
|
10
|
+
server, [@rigour-labs/mcp](https://www.npmjs.com/package/@rigour-labs/mcp). This package is for building on
|
|
11
|
+
the engine.
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
## What's Inside
|
|
13
|
-
|
|
14
|
-
### 27+ Deterministic Quality Gates
|
|
15
|
-
|
|
16
|
-
**Structural:** File size, cyclomatic complexity, method count, parameter count, nesting depth, required docs, content hygiene.
|
|
17
|
-
|
|
18
|
-
**Security:** Hardcoded secrets, SQL injection, XSS, command injection, path traversal, frontend secret exposure.
|
|
19
|
-
|
|
20
|
-
**AI Drift Detection:**
|
|
21
|
-
- **Three-pass duplication drift** — MD5 exact → AST Jaccard (tree-sitter) → semantic embedding (all-MiniLM-L6-v2, 384D cosine). Catches `.find()` vs `.filter()[0]` — same intent, different implementation.
|
|
22
|
-
- **Hallucinated imports** — language-aware resolution for relative + package imports.
|
|
23
|
-
- **Phantom APIs** — non-existent stdlib/framework methods the LLM invented.
|
|
24
|
-
- **Style drift** — fingerprints naming, error handling, import style, quote preferences against project baseline.
|
|
25
|
-
- **Logic drift** — tracks comparison operators (>= → >), branch counts, return statements per function across scans.
|
|
26
|
-
- **Dependency bloat** — unused deps, heavy alternatives (moment→dayjs), duplicate purpose packages.
|
|
27
|
-
- **Context-window artifacts**, inconsistent error handling, promise safety, deprecated APIs.
|
|
28
|
-
|
|
29
|
-
**Semantic Bugs (type-aware, on by default):** a TypeScript program with the checker and cross-file value tracing proves a defect before reporting it: credentials forwarded on redirect, paged reads aggregated in memory, cached responses that can carry a failure fallback. Rules learned from fixes (`rigour learn`) run alongside them from `.rigour/rules/`.
|
|
30
|
-
|
|
31
|
-
**Agent Governance:** Multi-agent scope isolation, EWMA-based checkpoint supervision, context drift, retry loop breaker, memory & skills governance with DLP scanning.
|
|
32
|
-
|
|
33
|
-
### Real-Time Hook Engine
|
|
34
|
-
|
|
35
|
-
Sub-200ms per-file-write checker with 5 fast gates (governance, hallucinated imports, promise safety, security patterns, file size). Generates native hook configs for Claude Code, Cursor, Cline, and Windsurf.
|
|
36
|
-
|
|
37
|
-
### AI Agent DLP (Data Loss Prevention)
|
|
38
|
-
|
|
39
|
-
29 credential patterns with anti-evasion hardening (unicode normalization, zero-width char removal, bidi control stripping, Shannon entropy detection >4.5 bits). Compliance-mapped to SOC2-CC6.1, HIPAA-164.312, PCI-DSS-3.4/3.5/6.5, OWASP-A2, CWE-798.
|
|
40
|
-
|
|
41
|
-
### Five-Signal Deep Analysis Pipeline
|
|
42
|
-
|
|
43
|
-
Rigour's deep analysis is not a wrapper around a generic LLM. The model operates within a cage of deterministic facts:
|
|
44
|
-
|
|
45
|
-
1. **Extract** — five independent signal streams (AST facts, semantic embeddings, style fingerprints, logic baselines, dependency graphs) computed deterministically before the LLM sees anything.
|
|
46
|
-
2. **Interpret** — the model receives structured facts (not raw source), focuses on SOLID, design patterns, language idioms, architecture. Constrained input prevents hallucination.
|
|
47
|
-
3. **Verify** — every LLM finding is cross-referenced against all five signal streams. Wrong line numbers, phantom patterns, non-existent functions → discarded. Only verified findings with confidence scores reach the report.
|
|
48
|
-
|
|
49
|
-
Deep review is built for frontier models: your own key, or the coding agent's own model. The small local models (lite and deep tiers fine-tuned via the [DriftBench RLAIF pipeline](https://github.com/rigour-labs/driftbench); max is the stock Qwen2.5-Coder-7B) remain available offline but are no longer developed.
|
|
50
|
-
|
|
51
|
-
### Temporal Drift Engine (v5.1)
|
|
52
|
-
|
|
53
|
-
Cross-session trend analysis powered by EWMA and Z-score anomaly detection. Tracks three independent provenance streams (AI drift, structural, security) with separate trend directions. Reads from the SQLite brain for month-over-month analysis.
|
|
54
|
-
|
|
55
|
-
Key capabilities: per-provenance EWMA streams (alpha=0.3), Z-score anomaly detection (|Z| > 2.0), monthly/weekly rollups, semantic duplicate tracking, style + logic baseline evolution, human-readable narrative generation.
|
|
56
|
-
|
|
57
|
-
### Multi-Language Support
|
|
58
|
-
|
|
59
|
-
Hallucinated import detection supports 8 languages with stdlib whitelists and dependency manifest parsing: TypeScript, JavaScript, Python, Go, Ruby, C#/.NET, Rust, Java, and Kotlin. Core structural gates support all languages via AST analysis.
|
|
60
|
-
|
|
61
|
-
### Two-Score System
|
|
62
|
-
|
|
63
|
-
Every failure carries a **provenance tag** (`ai-drift`, `traditional`, `security`, `governance`) and contributes to two sub-scores:
|
|
64
|
-
|
|
65
|
-
- **AI Health Score** (0–100) — AI-specific failures
|
|
66
|
-
- **Structural Score** (0–100) — Traditional code quality
|
|
67
|
-
|
|
68
|
-
### Fix Packets (v2)
|
|
69
|
-
|
|
70
|
-
Machine-readable JSON diagnostics with severity, provenance, file, line number, and step-by-step remediation instructions that AI agents can consume directly.
|
|
71
|
-
|
|
72
|
-
## Usage
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
import { GateRunner } from '@rigour-labs/core';
|
|
76
|
-
|
|
77
|
-
const runner = new GateRunner(config);
|
|
78
|
-
const report = await runner.run(projectRoot);
|
|
79
|
-
|
|
80
|
-
console.log(report.status); // 'PASS' or 'FAIL'
|
|
81
|
-
console.log(report.stats.score); // 0-100
|
|
82
|
-
console.log(report.failures); // Failure[]
|
|
13
|
+
```bash
|
|
14
|
+
npm install @rigour-labs/core
|
|
83
15
|
```
|
|
84
16
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
import { GateRunner } from '@rigour-labs/core';
|
|
17
|
+
```ts
|
|
18
|
+
import { ConfigSchema, reviewChange } from '@rigour-labs/core';
|
|
89
19
|
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
pro: false, // true for full-power model
|
|
94
|
-
provider: 'local', // or 'claude', 'openai', etc.
|
|
95
|
-
});
|
|
20
|
+
const config = ConfigSchema.parse({}); // or the parsed rigour.yml
|
|
21
|
+
const result = await reviewChange({ cwd: process.cwd(), config, source: { mode: 'working' } });
|
|
22
|
+
console.log(result.status, result.findings);
|
|
96
23
|
```
|
|
97
24
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
**[Full docs at docs.rigour.run](https://docs.rigour.run)**
|
|
101
|
-
|
|
102
|
-
## License
|
|
25
|
+
What each check finds and whether it blocks: [What Rigour checks](https://github.com/rigour-labs/rigour/blob/main/docs/CHECKS.md). Every setting:
|
|
26
|
+
[Configuration reference](https://github.com/rigour-labs/rigour/blob/main/docs/CONFIG_REFERENCE.md). Node 22 or later.
|
|
103
27
|
|
|
104
28
|
MIT © [Rigour Labs](https://github.com/rigour-labs)
|
package/dist/environment.test.js
CHANGED
|
@@ -14,7 +14,6 @@ describe('Environment Alignment Gate', () => {
|
|
|
14
14
|
});
|
|
15
15
|
it('should detect tool version mismatch (Explicit)', async () => {
|
|
16
16
|
const rawConfig = {
|
|
17
|
-
version: 1,
|
|
18
17
|
gates: {
|
|
19
18
|
environment: {
|
|
20
19
|
enabled: true,
|
|
@@ -36,7 +35,6 @@ describe('Environment Alignment Gate', () => {
|
|
|
36
35
|
});
|
|
37
36
|
it('should detect missing environment variables', async () => {
|
|
38
37
|
const rawConfig = {
|
|
39
|
-
version: 1,
|
|
40
38
|
gates: {
|
|
41
39
|
environment: {
|
|
42
40
|
enabled: true,
|
|
@@ -57,7 +55,6 @@ describe('Environment Alignment Gate', () => {
|
|
|
57
55
|
ruff = ">=99.14.0"
|
|
58
56
|
`);
|
|
59
57
|
const rawConfig = {
|
|
60
|
-
version: 1,
|
|
61
58
|
gates: {
|
|
62
59
|
environment: {
|
|
63
60
|
enabled: true,
|
|
@@ -77,7 +74,6 @@ ruff = ">=99.14.0"
|
|
|
77
74
|
});
|
|
78
75
|
it('should prioritize environment gate and run it first', async () => {
|
|
79
76
|
const rawConfig = {
|
|
80
|
-
version: 1,
|
|
81
77
|
gates: {
|
|
82
78
|
max_file_lines: 1,
|
|
83
79
|
environment: {
|
|
@@ -26,8 +26,6 @@ export interface AgentTeamSession {
|
|
|
26
26
|
export interface AgentTeamConfig {
|
|
27
27
|
enabled?: boolean;
|
|
28
28
|
max_concurrent_agents?: number;
|
|
29
|
-
cross_agent_pattern_check?: boolean;
|
|
30
|
-
handoff_verification?: boolean;
|
|
31
29
|
task_ownership?: 'strict' | 'collaborative';
|
|
32
30
|
}
|
|
33
31
|
/**
|
package/dist/gates/agent-team.js
CHANGED
|
@@ -114,8 +114,6 @@ export class AgentTeamGate extends Gate {
|
|
|
114
114
|
this.config = {
|
|
115
115
|
enabled: config.enabled ?? false,
|
|
116
116
|
max_concurrent_agents: config.max_concurrent_agents ?? 3,
|
|
117
|
-
cross_agent_pattern_check: config.cross_agent_pattern_check ?? true,
|
|
118
|
-
handoff_verification: config.handoff_verification ?? true,
|
|
119
117
|
task_ownership: config.task_ownership ?? 'strict',
|
|
120
118
|
};
|
|
121
119
|
}
|
|
@@ -148,12 +146,6 @@ export class AgentTeamGate extends Gate {
|
|
|
148
146
|
}
|
|
149
147
|
}
|
|
150
148
|
}
|
|
151
|
-
// Check 3: Cross-agent pattern detection (if enabled)
|
|
152
|
-
if (this.config.cross_agent_pattern_check && context.record) {
|
|
153
|
-
// This would integrate with the Pattern Index to detect conflicting patterns
|
|
154
|
-
// For now, we log that we would do this check
|
|
155
|
-
Logger.debug('Cross-agent pattern check: would analyze patterns across agent scopes');
|
|
156
|
-
}
|
|
157
149
|
return failures;
|
|
158
150
|
}
|
|
159
151
|
}
|
|
@@ -44,7 +44,6 @@ export interface CheckpointConfig {
|
|
|
44
44
|
interval_minutes?: number;
|
|
45
45
|
quality_threshold?: number;
|
|
46
46
|
drift_detection?: boolean;
|
|
47
|
-
auto_save_on_failure?: boolean;
|
|
48
47
|
/** EWMA smoothing factor. Higher = more weight on recent data. Default 0.3 */
|
|
49
48
|
ewma_alpha?: number;
|
|
50
49
|
/** Drop from EWMA that triggers drift warning. Default 15 */
|
package/dist/gates/checkpoint.js
CHANGED
|
@@ -256,7 +256,6 @@ export class CheckpointGate extends Gate {
|
|
|
256
256
|
interval_minutes: config.interval_minutes ?? 15,
|
|
257
257
|
quality_threshold: config.quality_threshold ?? 80,
|
|
258
258
|
drift_detection: config.drift_detection ?? true,
|
|
259
|
-
auto_save_on_failure: config.auto_save_on_failure ?? true,
|
|
260
259
|
ewma_alpha: config.ewma_alpha ?? 0.3,
|
|
261
260
|
drift_drop_threshold: config.drift_drop_threshold ?? 15,
|
|
262
261
|
};
|
package/dist/gates/context.d.ts
CHANGED
|
@@ -8,10 +8,6 @@ export interface ExtendedContextConfig {
|
|
|
8
8
|
enabled?: boolean;
|
|
9
9
|
sensitivity?: number;
|
|
10
10
|
mining_depth?: number;
|
|
11
|
-
cross_file_patterns?: boolean;
|
|
12
|
-
naming_consistency?: boolean;
|
|
13
|
-
import_relationships?: boolean;
|
|
14
|
-
max_cross_file_depth?: number;
|
|
15
11
|
}
|
|
16
12
|
export declare class ContextGate extends Gate {
|
|
17
13
|
private config;
|
package/dist/gates/context.js
CHANGED
|
@@ -13,10 +13,6 @@ export class ContextGate extends Gate {
|
|
|
13
13
|
enabled: config.context?.enabled ?? false,
|
|
14
14
|
sensitivity: config.context?.sensitivity ?? 0.8,
|
|
15
15
|
mining_depth: config.context?.mining_depth ?? 100,
|
|
16
|
-
cross_file_patterns: true, // Default ON for frontier model support
|
|
17
|
-
naming_consistency: true,
|
|
18
|
-
import_relationships: true,
|
|
19
|
-
max_cross_file_depth: 50,
|
|
20
16
|
};
|
|
21
17
|
}
|
|
22
18
|
get provenance() { return 'ai-drift'; }
|
|
@@ -42,22 +38,16 @@ export class ContextGate extends Gate {
|
|
|
42
38
|
const codeContent = this.stripComments(content);
|
|
43
39
|
// 1. Original: Detect Redundant Suffixes (The Golden Example)
|
|
44
40
|
this.checkEnvDrift(codeContent, file, envAnchors, failures);
|
|
45
|
-
// 2.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.collectImportPatterns(codeContent, file, importPatterns);
|
|
49
|
-
}
|
|
41
|
+
// 2. Cross-file pattern collection
|
|
42
|
+
this.collectNamingPatterns(codeContent, file, namingPatterns);
|
|
43
|
+
this.collectImportPatterns(codeContent, file, importPatterns);
|
|
50
44
|
}
|
|
51
45
|
catch (e) { }
|
|
52
46
|
}
|
|
53
|
-
// 3.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// 4. NEW: Analyze import relationship patterns
|
|
58
|
-
if (this.extendedConfig.import_relationships) {
|
|
59
|
-
this.analyzeImportPatterns(importPatterns, failures);
|
|
60
|
-
}
|
|
47
|
+
// 3. Naming consistency across files
|
|
48
|
+
this.analyzeNamingConsistency(namingPatterns, failures);
|
|
49
|
+
// 4. Import relationship patterns
|
|
50
|
+
this.analyzeImportPatterns(importPatterns, failures);
|
|
61
51
|
// Cross-file patterns need the whole repo, but a scoped run reports
|
|
62
52
|
// only findings that cite a file in scope.
|
|
63
53
|
if (isScoped(context.patterns)) {
|
|
@@ -16,7 +16,6 @@ export async function runDeepAnalysis(config, context, deepOptions) {
|
|
|
16
16
|
const deepGate = new DeepAnalysisGate({
|
|
17
17
|
options: deepOptions,
|
|
18
18
|
checks: config.gates.deep?.checks,
|
|
19
|
-
threads: config.gates.deep?.threads,
|
|
20
19
|
maxTokens: config.gates.deep?.max_tokens,
|
|
21
20
|
temperature: config.gates.deep?.temperature,
|
|
22
21
|
timeoutMs: config.gates.deep?.timeout_ms,
|
|
@@ -97,9 +97,9 @@ describe('FrontendSecretExposureGate', () => {
|
|
|
97
97
|
expect(await gate.run({ cwd: testDir })).toHaveLength(0);
|
|
98
98
|
});
|
|
99
99
|
it('ignores shell files even when a broad project scan passes them in', async () => {
|
|
100
|
-
const shellPath = path.join(testDir, 'scripts/rigour-
|
|
100
|
+
const shellPath = path.join(testDir, 'scripts/rigour-team.sh');
|
|
101
101
|
fs.mkdirSync(path.dirname(shellPath), { recursive: true });
|
|
102
|
-
fs.writeFileSync(shellPath, 'node -e "process.env.
|
|
102
|
+
fs.writeFileSync(shellPath, 'node -e "process.env.APP_DATABASE_URL"');
|
|
103
103
|
const gate = new FrontendSecretExposureGate();
|
|
104
104
|
expect(await gate.run({ cwd: testDir, patterns: ['**/*'] })).toHaveLength(0);
|
|
105
105
|
});
|
|
@@ -27,8 +27,6 @@ export interface HallucinatedImport {
|
|
|
27
27
|
}
|
|
28
28
|
export interface HallucinatedImportsConfig {
|
|
29
29
|
enabled?: boolean;
|
|
30
|
-
check_relative?: boolean;
|
|
31
|
-
check_packages?: boolean;
|
|
32
30
|
ignore_patterns?: string[];
|
|
33
31
|
}
|
|
34
32
|
export declare class HallucinatedImportsGate extends Gate {
|
|
@@ -33,8 +33,6 @@ export class HallucinatedImportsGate extends Gate {
|
|
|
33
33
|
super('hallucinated-imports', 'Hallucinated Import Detection');
|
|
34
34
|
this.config = {
|
|
35
35
|
enabled: config.enabled ?? true,
|
|
36
|
-
check_relative: config.check_relative ?? true,
|
|
37
|
-
check_packages: config.check_packages ?? true,
|
|
38
36
|
ignore_patterns: config.ignore_patterns ?? [
|
|
39
37
|
'\\.css$', '\\.scss$', '\\.less$', '\\.svg$', '\\.png$', '\\.jpg$',
|
|
40
38
|
'\\.json$', '\\.wasm$', '\\.graphql$', '\\.gql$',
|
|
@@ -70,6 +68,8 @@ export class HallucinatedImportsGate extends Gate {
|
|
|
70
68
|
const allProjectFiles = projectFiles;
|
|
71
69
|
const packageJson = await loadPackageJson(context.cwd);
|
|
72
70
|
const rootDeps = new Set([
|
|
71
|
+
// A package importing itself by its own name (type tests, examples) is Node's self-reference.
|
|
72
|
+
...(typeof packageJson?.name === 'string' ? [packageJson.name] : []),
|
|
73
73
|
...Object.keys(packageJson?.dependencies || {}),
|
|
74
74
|
...Object.keys(packageJson?.devDependencies || {}),
|
|
75
75
|
...Object.keys(packageJson?.peerDependencies || {}),
|
|
@@ -180,6 +180,7 @@ export async function resolveJSDepsForFile(file, cwd, rootDeps, depCacheByDir) {
|
|
|
180
180
|
const packageJson = await fs.readJson(packageJsonPath);
|
|
181
181
|
const deps = new Set([
|
|
182
182
|
...rootDeps,
|
|
183
|
+
...(typeof packageJson?.name === 'string' ? [packageJson.name] : []),
|
|
183
184
|
...Object.keys(packageJson?.dependencies || {}),
|
|
184
185
|
...Object.keys(packageJson?.devDependencies || {}),
|
|
185
186
|
...Object.keys(packageJson?.peerDependencies || {}),
|
|
@@ -423,6 +423,16 @@ import { cfg } from '~shared/config';
|
|
|
423
423
|
expect(details.includes("Path alias '@/utils/missing' does not resolve to a project file")
|
|
424
424
|
|| details.includes("Package '@/utils' not in package.json dependencies")).toBe(true);
|
|
425
425
|
});
|
|
426
|
+
it('should NOT flag a package importing itself by its own name (type tests, examples), and still flag an undeclared one', async () => {
|
|
427
|
+
FileScanner.findFiles.mockResolvedValue(['test-d/types.ts']);
|
|
428
|
+
mockReadFile.mockResolvedValue(`import ky from 'ky';\nimport left from 'left-pad';\n`);
|
|
429
|
+
mockPathExists.mockImplementation(async (p) => normalizePath(p) === `${testCwdNormalized}/package.json`);
|
|
430
|
+
mockReadJson.mockResolvedValue({ name: 'ky', dependencies: {}, devDependencies: {} });
|
|
431
|
+
const failures = await gate.run(context);
|
|
432
|
+
const details = failures.map(f => f.details).join('\n');
|
|
433
|
+
expect(details).not.toContain("Package 'ky'");
|
|
434
|
+
expect(details).toContain("Package 'left-pad' not in package.json dependencies");
|
|
435
|
+
});
|
|
426
436
|
it('should resolve configured aliases to hidden generated files', async () => {
|
|
427
437
|
const jsContent = `import { docs } from '@/.source';`;
|
|
428
438
|
const tsconfigContent = `{
|
package/dist/gates/runner.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SEVERITY_WEIGHTS } from '../types/index.js';
|
|
2
2
|
import { runDeepAnalysis } from './deep-runner.js';
|
|
3
3
|
import { persistAndReinforce } from '../storage/local-memory.js';
|
|
4
|
+
import { splitCommand } from '../utils/command-line.js';
|
|
4
5
|
import { recordGateRun } from '../services/adaptive-thresholds.js';
|
|
5
6
|
import { FileGate } from './file.js';
|
|
6
7
|
import { ContentGate } from './content.js';
|
|
@@ -71,7 +72,7 @@ export class GateRunner {
|
|
|
71
72
|
if (this.config.gates.checkpoint?.enabled) {
|
|
72
73
|
this.gates.push(new CheckpointGate(this.config.gates.checkpoint));
|
|
73
74
|
}
|
|
74
|
-
// Semantic Bugs Gate (type-aware, proven findings)
|
|
75
|
+
// Semantic Bugs Gate (type-aware, proven findings); on by default, `enabled: false` turns it off
|
|
75
76
|
if (this.config.gates.semantic_bugs?.enabled) {
|
|
76
77
|
this.gates.push(new SemanticBugsGate(this.config.gates.semantic_bugs));
|
|
77
78
|
}
|
|
@@ -192,9 +193,7 @@ export class GateRunner {
|
|
|
192
193
|
}
|
|
193
194
|
try {
|
|
194
195
|
Logger.info(`Running command gate: ${key} (${cmd})`);
|
|
195
|
-
const
|
|
196
|
-
const bin = parts[0];
|
|
197
|
-
const args = parts.slice(1).map(a => a.replace(/^["']|["']$/g, ''));
|
|
196
|
+
const { bin, args } = splitCommand(cmd);
|
|
198
197
|
await execa(bin, args, { cwd });
|
|
199
198
|
summary[key] = 'PASS';
|
|
200
199
|
}
|
|
@@ -35,10 +35,6 @@ export declare const JS_TAUTOLOGICAL_PATTERNS: RegExp[];
|
|
|
35
35
|
* Variable tautology pattern for JavaScript
|
|
36
36
|
*/
|
|
37
37
|
export declare const JS_VAR_TAUTOLOGY_PATTERN: RegExp;
|
|
38
|
-
/**
|
|
39
|
-
* Snapshot test patterns
|
|
40
|
-
*/
|
|
41
|
-
export declare const SNAPSHOT_PATTERNS: RegExp[];
|
|
42
38
|
/**
|
|
43
39
|
* Python tautological patterns
|
|
44
40
|
*/
|
|
@@ -64,13 +64,6 @@ export const JS_TAUTOLOGICAL_PATTERNS = [
|
|
|
64
64
|
* Variable tautology pattern for JavaScript
|
|
65
65
|
*/
|
|
66
66
|
export const JS_VAR_TAUTOLOGY_PATTERN = /expect\s*\(\s*(\w+)\s*\)\s*\.(?:toBe|toEqual|toStrictEqual)\s*\(\s*(\w+)\s*\)/;
|
|
67
|
-
/**
|
|
68
|
-
* Snapshot test patterns
|
|
69
|
-
*/
|
|
70
|
-
export const SNAPSHOT_PATTERNS = [
|
|
71
|
-
/\.toMatchSnapshot\s*\(/,
|
|
72
|
-
/\.toMatchInlineSnapshot\s*\(/,
|
|
73
|
-
];
|
|
74
67
|
/**
|
|
75
68
|
* Python tautological patterns
|
|
76
69
|
*/
|
|
@@ -33,10 +33,8 @@ export interface TestQualityConfig {
|
|
|
33
33
|
check_empty_tests?: boolean;
|
|
34
34
|
check_tautological?: boolean;
|
|
35
35
|
check_mock_heavy?: boolean;
|
|
36
|
-
check_snapshot_abuse?: boolean;
|
|
37
36
|
check_assertion_free_async?: boolean;
|
|
38
37
|
max_mocks_per_test?: number;
|
|
39
|
-
ignore_patterns?: string[];
|
|
40
38
|
}
|
|
41
39
|
export declare class TestQualityGate extends Gate {
|
|
42
40
|
private config;
|
|
@@ -25,7 +25,7 @@ import { FileScanner } from '../utils/scanner.js';
|
|
|
25
25
|
import { Logger } from '../utils/logger.js';
|
|
26
26
|
import { languageAdapters } from './language-adapters/index.js';
|
|
27
27
|
import { checkGoTestQuality, checkJavaKotlinTestQuality } from './test-quality-lang.js';
|
|
28
|
-
import { JS_TEST_START_PATTERN, JS_ASSERTION_PATTERNS, JS_MOCK_PATTERNS, JS_TAUTOLOGICAL_PATTERNS, JS_VAR_TAUTOLOGY_PATTERN,
|
|
28
|
+
import { JS_TEST_START_PATTERN, JS_ASSERTION_PATTERNS, JS_MOCK_PATTERNS, JS_TAUTOLOGICAL_PATTERNS, JS_VAR_TAUTOLOGY_PATTERN, PYTHON_TEST_FUNC_PATTERN, PYTHON_ASSERTION_PATTERNS, PYTHON_MOCK_PATTERNS, PYTHON_TAUTOLOGICAL_PATTERNS, PYTHON_FIXTURE_PATTERN, PYTHON_CONFTEST_NAME, } from './test-quality-matchers.js';
|
|
29
29
|
import fs from 'fs-extra';
|
|
30
30
|
import path from 'path';
|
|
31
31
|
export class TestQualityGate extends Gate {
|
|
@@ -37,10 +37,8 @@ export class TestQualityGate extends Gate {
|
|
|
37
37
|
check_empty_tests: config.check_empty_tests ?? true,
|
|
38
38
|
check_tautological: config.check_tautological ?? true,
|
|
39
39
|
check_mock_heavy: config.check_mock_heavy ?? true,
|
|
40
|
-
check_snapshot_abuse: config.check_snapshot_abuse ?? true,
|
|
41
40
|
check_assertion_free_async: config.check_assertion_free_async ?? true,
|
|
42
41
|
max_mocks_per_test: config.max_mocks_per_test ?? 5,
|
|
43
|
-
ignore_patterns: config.ignore_patterns ?? [],
|
|
44
42
|
};
|
|
45
43
|
}
|
|
46
44
|
get provenance() { return 'ai-drift'; }
|
|
@@ -200,13 +198,6 @@ export class TestQualityGate extends Gate {
|
|
|
200
198
|
});
|
|
201
199
|
}
|
|
202
200
|
}
|
|
203
|
-
// Check for snapshot-only tests
|
|
204
|
-
if (this.config.check_snapshot_abuse) {
|
|
205
|
-
if (SNAPSHOT_PATTERNS.some(p => p.test(line))) {
|
|
206
|
-
// This is fine IF there are also semantic assertions
|
|
207
|
-
// We'll check when the block ends
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
201
|
// End of test block
|
|
211
202
|
if (braceDepth === 0) {
|
|
212
203
|
this.analyzeJSTestBlock(testBlockContent, file, testStartLine, mockCount, hasAssertion, hasAwait, isAsync, issues);
|
package/dist/hooks/checker.js
CHANGED
|
@@ -40,7 +40,7 @@ async function loadConfig(cwd) {
|
|
|
40
40
|
const raw = yaml.parse(await fs.readFile(configPath, 'utf-8'));
|
|
41
41
|
return ConfigSchema.parse(raw);
|
|
42
42
|
}
|
|
43
|
-
return ConfigSchema.parse({
|
|
43
|
+
return ConfigSchema.parse({});
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* Resolve a file path to absolute, read its content, and return metadata.
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -6,8 +6,7 @@ export { runHookChecker } from './checker.js';
|
|
|
6
6
|
export type { CheckerOptions } from './checker.js';
|
|
7
7
|
export { generateHookFiles, pushGateShell } from './templates.js';
|
|
8
8
|
export type { GeneratedHookFile } from './templates.js';
|
|
9
|
-
export type { HookTool,
|
|
10
|
-
export { DEFAULT_HOOK_CONFIG, FAST_GATE_IDS } from './types.js';
|
|
9
|
+
export type { HookTool, HookCheckerResult } from './types.js';
|
|
11
10
|
export { scanInputForCredentials, formatDLPAlert, createDLPAuditEntry } from './input-validator.js';
|
|
12
11
|
export type { CredentialDetection, InputValidationResult, InputValidationConfig } from './input-validator.js';
|
|
13
12
|
export { recordDLPFeedback, allowLastDLPBlock, writeDLPBlockManifest, getLearnedAllowCount, loadDLPFeedbackStore, loadDLPFeedbackStoreSync, fingerprintDetection, } from './dlp-feedback.js';
|
package/dist/hooks/index.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { runHookChecker } from './checker.js';
|
|
6
6
|
export { generateHookFiles, pushGateShell } from './templates.js';
|
|
7
|
-
export { DEFAULT_HOOK_CONFIG, FAST_GATE_IDS } from './types.js';
|
|
8
7
|
// DLP (Data Loss Prevention) — v4.2.0
|
|
9
8
|
export { scanInputForCredentials, formatDLPAlert, createDLPAuditEntry } from './input-validator.js';
|
|
10
9
|
export { recordDLPFeedback, allowLastDLPBlock, writeDLPBlockManifest, getLearnedAllowCount, loadDLPFeedbackStore, loadDLPFeedbackStoreSync, fingerprintDetection, } from './dlp-feedback.js';
|
package/dist/hooks/types.d.ts
CHANGED
|
@@ -6,20 +6,6 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
export type HookTool = 'claude' | 'cursor' | 'cline' | 'windsurf';
|
|
9
|
-
export interface HookConfig {
|
|
10
|
-
/** Which tools to generate hooks for */
|
|
11
|
-
tools: HookTool[];
|
|
12
|
-
/** Gates to run in the hook checker (fast subset) */
|
|
13
|
-
fast_gates: string[];
|
|
14
|
-
/** Max execution time in ms before the checker aborts */
|
|
15
|
-
timeout_ms: number;
|
|
16
|
-
/** Whether to block the tool on failure (exit 2) or just warn */
|
|
17
|
-
block_on_failure: boolean;
|
|
18
|
-
}
|
|
19
|
-
/** The fast gates that can run per-file in <200ms */
|
|
20
|
-
export declare const FAST_GATE_IDS: readonly ["file-guard", "governance", "hallucinated-imports", "promise-safety", "security-patterns", "file-size"];
|
|
21
|
-
export declare const DEFAULT_HOOK_CONFIG: HookConfig;
|
|
22
|
-
export type FastGateId = typeof FAST_GATE_IDS[number];
|
|
23
9
|
export interface HookCheckerResult {
|
|
24
10
|
status: 'pass' | 'fail' | 'error';
|
|
25
11
|
failures: Array<{
|
package/dist/hooks/types.js
CHANGED
|
@@ -5,18 +5,4 @@
|
|
|
5
5
|
* has its own hook format. These types unify the config generation.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
export const FAST_GATE_IDS = [
|
|
10
|
-
'file-guard',
|
|
11
|
-
'governance',
|
|
12
|
-
'hallucinated-imports',
|
|
13
|
-
'promise-safety',
|
|
14
|
-
'security-patterns',
|
|
15
|
-
'file-size',
|
|
16
|
-
];
|
|
17
|
-
export const DEFAULT_HOOK_CONFIG = {
|
|
18
|
-
tools: ['claude'],
|
|
19
|
-
fast_gates: [...FAST_GATE_IDS],
|
|
20
|
-
timeout_ms: 5000,
|
|
21
|
-
block_on_failure: false,
|
|
22
|
-
};
|
|
8
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -12,20 +12,25 @@ export * from './utils/logger.js';
|
|
|
12
12
|
export { normalizeScopePatterns, isScoped } from './utils/scope.js';
|
|
13
13
|
export { deepAnalysisError } from './utils/deep-status.js';
|
|
14
14
|
export { rigourUserDir, repoStateDir } from './utils/user-state.js';
|
|
15
|
+
export { locateTransformers, semanticRuntimeDir, semanticRuntimeInstalled, TRANSFORMERS_SPEC } from './pattern-index/semantic-runtime.js';
|
|
15
16
|
export { reviewChange, toReviewFinding, type ReviewInput, type ReviewResult, type ReviewFinding } from './review/review.js';
|
|
16
17
|
export { splitByChangedLines, type ChangedLineSplit } from './review/changed-lines.js';
|
|
17
18
|
export { isControlFile, mergeBaseOf, readStateFile } from './review/trusted-state.js';
|
|
18
19
|
export { dismissFinding, dismissedKeys, findingKey, isProven, mustFix, quietSplit, DISMISSED_FILE } from './review/quiet.js';
|
|
19
20
|
export { loadLedger, ledgerProblems, runBacktest, backtestPassed, formatBacktest, LEDGER_PATH, type Ledger, type RoundResult } from './review/backtest.js';
|
|
20
21
|
export { scaffoldLedger } from './review/backtest-init.js';
|
|
22
|
+
export { fixScope, type FixScope } from './review/fix-scope.js';
|
|
21
23
|
export { isGeneratedFile } from './review/generated-files.js';
|
|
22
|
-
export { countUsage, durationBucket, flushDailyUsage, isTelemetryEnabled, readTelemetryState, setTelemetryEnabled, shouldAskTelemetry, telemetryToken, trackUsage } from './telemetry/telemetry.js';
|
|
24
|
+
export { costBucket, countUsage, doNotTrack, durationBucket, flushDailyUsage, isTelemetryEnabled, readTelemetryState, setTelemetryEnabled, shouldAskTelemetry, telemetryToken, trackUsage } from './telemetry/telemetry.js';
|
|
23
25
|
export { buildReviewTask, type ReviewTask, type ReviewTaskItem } from './review/review-task.js';
|
|
24
26
|
export { buildQualityReceipt, receiptReport, type QualityReceipt, type ReceiptGap, type ReceiptOptions } from './review/receipt.js';
|
|
25
27
|
export { runToolchain, type ToolResult, type ToolStatus } from './review/toolchain.js';
|
|
26
28
|
export { branchFailures, mergeConflicts, staleReferences } from './review/branch-checks.js';
|
|
27
29
|
export { runReviewer, reviewerBlocks, itemLine, type ReviewerOptions, type ReviewerResult, type ReviewerOutcome, type OpenItem } from './review/reviewer.js';
|
|
28
30
|
export { startBackgroundReview, backgroundReview, reviewStatus, type ReviewStatus } from './review/reviewer/background.js';
|
|
31
|
+
export { dismissReviewerFinding, REVIEW_DISMISSALS, reviewerInputs } from './review/reviewer/context.js';
|
|
32
|
+
export { resolveReviewer, saveUserReviewer, type ResolvedReviewer, type RunChoice, type UserReviewerPatch } from './review/reviewer/settings.js';
|
|
33
|
+
export { reviewerAvailability } from './review/reviewer/adapters.js';
|
|
29
34
|
export { branchBase, type BranchBase } from './gates/logic-drift-git-base.js';
|
|
30
35
|
export { acknowledgeReview, type ReviewAck, type AckResult } from './review/review-ack.js';
|
|
31
36
|
export { exportReviewed, readLedger, reviewedKeys, isReviewed, recordReview, REVIEWED_FILE, type LedgerEntry, type ReviewedKey, type ReviewVerdict } from './review/ledger.js';
|
package/dist/index.js
CHANGED
|
@@ -12,20 +12,25 @@ export * from './utils/logger.js';
|
|
|
12
12
|
export { normalizeScopePatterns, isScoped } from './utils/scope.js';
|
|
13
13
|
export { deepAnalysisError } from './utils/deep-status.js';
|
|
14
14
|
export { rigourUserDir, repoStateDir } from './utils/user-state.js';
|
|
15
|
+
export { locateTransformers, semanticRuntimeDir, semanticRuntimeInstalled, TRANSFORMERS_SPEC } from './pattern-index/semantic-runtime.js';
|
|
15
16
|
export { reviewChange, toReviewFinding } from './review/review.js';
|
|
16
17
|
export { splitByChangedLines } from './review/changed-lines.js';
|
|
17
18
|
export { isControlFile, mergeBaseOf, readStateFile } from './review/trusted-state.js';
|
|
18
19
|
export { dismissFinding, dismissedKeys, findingKey, isProven, mustFix, quietSplit, DISMISSED_FILE } from './review/quiet.js';
|
|
19
20
|
export { loadLedger, ledgerProblems, runBacktest, backtestPassed, formatBacktest, LEDGER_PATH } from './review/backtest.js';
|
|
20
21
|
export { scaffoldLedger } from './review/backtest-init.js';
|
|
22
|
+
export { fixScope } from './review/fix-scope.js';
|
|
21
23
|
export { isGeneratedFile } from './review/generated-files.js';
|
|
22
|
-
export { countUsage, durationBucket, flushDailyUsage, isTelemetryEnabled, readTelemetryState, setTelemetryEnabled, shouldAskTelemetry, telemetryToken, trackUsage } from './telemetry/telemetry.js';
|
|
24
|
+
export { costBucket, countUsage, doNotTrack, durationBucket, flushDailyUsage, isTelemetryEnabled, readTelemetryState, setTelemetryEnabled, shouldAskTelemetry, telemetryToken, trackUsage } from './telemetry/telemetry.js';
|
|
23
25
|
export { buildReviewTask } from './review/review-task.js';
|
|
24
26
|
export { buildQualityReceipt, receiptReport } from './review/receipt.js';
|
|
25
27
|
export { runToolchain } from './review/toolchain.js';
|
|
26
28
|
export { branchFailures, mergeConflicts, staleReferences } from './review/branch-checks.js';
|
|
27
29
|
export { runReviewer, reviewerBlocks, itemLine } from './review/reviewer.js';
|
|
28
30
|
export { startBackgroundReview, backgroundReview, reviewStatus } from './review/reviewer/background.js';
|
|
31
|
+
export { dismissReviewerFinding, REVIEW_DISMISSALS, reviewerInputs } from './review/reviewer/context.js';
|
|
32
|
+
export { resolveReviewer, saveUserReviewer } from './review/reviewer/settings.js';
|
|
33
|
+
export { reviewerAvailability } from './review/reviewer/adapters.js';
|
|
29
34
|
export { branchBase } from './gates/logic-drift-git-base.js';
|
|
30
35
|
export { acknowledgeReview } from './review/review-ack.js';
|
|
31
36
|
export { exportReviewed, readLedger, reviewedKeys, isReviewed, recordReview, REVIEWED_FILE } from './review/ledger.js';
|
|
@@ -41,5 +41,7 @@ export declare class CloudProvider implements InferenceProvider {
|
|
|
41
41
|
/** OpenRouter forwards Anthropic's cache_control to Claude models. */
|
|
42
42
|
private cachesPrompts;
|
|
43
43
|
private isOpenRouter;
|
|
44
|
+
/** The API base URL: the one given, else the provider's own. */
|
|
45
|
+
private endpoint;
|
|
44
46
|
dispose(): void;
|
|
45
47
|
}
|