pi-lens 3.6.2 → 3.6.4
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/CHANGELOG.md +10 -2
- package/package.json +4 -4
- package/tsconfig.json +1 -1
- package/clients/__tests__/file-time.test.js +0 -216
- package/clients/__tests__/file-time.test.ts +0 -276
- package/clients/__tests__/format-service.test.js +0 -245
- package/clients/__tests__/format-service.test.ts +0 -339
- package/clients/__tests__/formatters.test.js +0 -271
- package/clients/__tests__/formatters.test.ts +0 -401
- package/clients/agent-behavior-client.js +0 -110
- package/clients/agent-behavior-client.test.js +0 -94
- package/clients/agent-behavior-client.test.ts +0 -116
- package/clients/amain-types.js +0 -164
- package/clients/architect-client.js +0 -291
- package/clients/ast-grep-client.js +0 -253
- package/clients/ast-grep-parser.js +0 -84
- package/clients/ast-grep-rule-manager.js +0 -89
- package/clients/ast-grep-types.js +0 -9
- package/clients/auto-loop.js +0 -131
- package/clients/biome-client.js +0 -420
- package/clients/biome-client.test.js +0 -144
- package/clients/biome-client.test.ts +0 -163
- package/clients/cache/rule-cache.js +0 -72
- package/clients/cache-manager.js +0 -245
- package/clients/cache-manager.test.js +0 -197
- package/clients/cache-manager.test.ts +0 -299
- package/clients/complexity-client.js +0 -675
- package/clients/complexity-client.test.js +0 -234
- package/clients/complexity-client.test.ts +0 -255
- package/clients/config-validator.js +0 -465
- package/clients/dependency-checker.js +0 -325
- package/clients/dependency-checker.test.js +0 -60
- package/clients/dependency-checker.test.ts +0 -71
- package/clients/dispatch/__tests__/autofix-integration.test.js +0 -245
- package/clients/dispatch/__tests__/autofix-integration.test.ts +0 -300
- package/clients/dispatch/__tests__/runner-registration.test.js +0 -234
- package/clients/dispatch/__tests__/runner-registration.test.ts +0 -286
- package/clients/dispatch/debug.log +0 -1
- package/clients/dispatch/dispatcher.edge.test.js +0 -82
- package/clients/dispatch/dispatcher.edge.test.ts +0 -100
- package/clients/dispatch/dispatcher.format.test.js +0 -46
- package/clients/dispatch/dispatcher.format.test.ts +0 -58
- package/clients/dispatch/dispatcher.inline.test.js +0 -74
- package/clients/dispatch/dispatcher.inline.test.ts +0 -93
- package/clients/dispatch/dispatcher.js +0 -381
- package/clients/dispatch/dispatcher.test.js +0 -116
- package/clients/dispatch/dispatcher.test.ts +0 -149
- package/clients/dispatch/integration.js +0 -108
- package/clients/dispatch/plan.js +0 -183
- package/clients/dispatch/runners/architect.js +0 -83
- package/clients/dispatch/runners/architect.test.js +0 -138
- package/clients/dispatch/runners/architect.test.ts +0 -162
- package/clients/dispatch/runners/ast-grep-napi.js +0 -405
- package/clients/dispatch/runners/ast-grep-napi.test.js +0 -107
- package/clients/dispatch/runners/ast-grep-napi.test.ts +0 -129
- package/clients/dispatch/runners/ast-grep.js +0 -157
- package/clients/dispatch/runners/biome.js +0 -55
- package/clients/dispatch/runners/config-validation.js +0 -67
- package/clients/dispatch/runners/go-vet.js +0 -48
- package/clients/dispatch/runners/index.js +0 -47
- package/clients/dispatch/runners/lsp.js +0 -102
- package/clients/dispatch/runners/oxlint.js +0 -67
- package/clients/dispatch/runners/oxlint.test.js +0 -230
- package/clients/dispatch/runners/oxlint.test.ts +0 -303
- package/clients/dispatch/runners/pyright.js +0 -100
- package/clients/dispatch/runners/pyright.test.js +0 -98
- package/clients/dispatch/runners/pyright.test.ts +0 -121
- package/clients/dispatch/runners/python-slop.js +0 -97
- package/clients/dispatch/runners/python-slop.test.js +0 -203
- package/clients/dispatch/runners/python-slop.test.ts +0 -298
- package/clients/dispatch/runners/ruff.js +0 -48
- package/clients/dispatch/runners/rust-clippy.js +0 -102
- package/clients/dispatch/runners/scan_codebase.test.js +0 -89
- package/clients/dispatch/runners/scan_codebase.test.ts +0 -105
- package/clients/dispatch/runners/shellcheck.js +0 -147
- package/clients/dispatch/runners/shellcheck.test.js +0 -98
- package/clients/dispatch/runners/shellcheck.test.ts +0 -129
- package/clients/dispatch/runners/similarity.js +0 -230
- package/clients/dispatch/runners/spellcheck.js +0 -106
- package/clients/dispatch/runners/spellcheck.test.js +0 -158
- package/clients/dispatch/runners/spellcheck.test.ts +0 -214
- package/clients/dispatch/runners/tree-sitter.js +0 -246
- package/clients/dispatch/runners/ts-lsp.js +0 -125
- package/clients/dispatch/runners/ts-slop.js +0 -113
- package/clients/dispatch/runners/type-safety.js +0 -142
- package/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -134
- package/clients/dispatch/runners/utils/runner-helpers.js +0 -115
- package/clients/dispatch/runners/utils.js +0 -51
- package/clients/dispatch/runners/yaml-rule-parser.js +0 -360
- package/clients/dispatch/types.js +0 -16
- package/clients/dispatch/utils/format-utils.js +0 -44
- package/clients/dogfood.test.js +0 -201
- package/clients/dogfood.test.ts +0 -269
- package/clients/file-kinds.js +0 -177
- package/clients/file-kinds.test.js +0 -169
- package/clients/file-kinds.test.ts +0 -210
- package/clients/file-time.js +0 -152
- package/clients/file-utils.js +0 -40
- package/clients/fix-scanners.js +0 -204
- package/clients/format-service.js +0 -184
- package/clients/formatters.js +0 -488
- package/clients/go-client.js +0 -203
- package/clients/go-client.test.js +0 -127
- package/clients/go-client.test.ts +0 -143
- package/clients/installer/index.js +0 -403
- package/clients/interviewer-templates.js +0 -75
- package/clients/interviewer.js +0 -173
- package/clients/jscpd-client.js +0 -196
- package/clients/jscpd-client.test.js +0 -127
- package/clients/jscpd-client.test.ts +0 -145
- package/clients/knip-client.js +0 -239
- package/clients/knip-client.test.js +0 -112
- package/clients/knip-client.test.ts +0 -128
- package/clients/latency-logger.js +0 -40
- package/clients/lsp/__tests__/client.test.js +0 -310
- package/clients/lsp/__tests__/client.test.ts +0 -412
- package/clients/lsp/__tests__/config.test.js +0 -167
- package/clients/lsp/__tests__/config.test.ts +0 -217
- package/clients/lsp/__tests__/error-recovery.test.js +0 -213
- package/clients/lsp/__tests__/error-recovery.test.ts +0 -279
- package/clients/lsp/__tests__/integration.test.js +0 -127
- package/clients/lsp/__tests__/integration.test.ts +0 -160
- package/clients/lsp/__tests__/launch.test.js +0 -313
- package/clients/lsp/__tests__/launch.test.ts +0 -394
- package/clients/lsp/__tests__/server.test.js +0 -259
- package/clients/lsp/__tests__/server.test.ts +0 -332
- package/clients/lsp/__tests__/service.test.js +0 -438
- package/clients/lsp/__tests__/service.test.ts +0 -530
- package/clients/lsp/client.js +0 -350
- package/clients/lsp/config.js +0 -112
- package/clients/lsp/index.js +0 -318
- package/clients/lsp/installer/index.js +0 -391
- package/clients/lsp/interactive-install.js +0 -221
- package/clients/lsp/language.js +0 -170
- package/clients/lsp/launch.js +0 -329
- package/clients/lsp/lsp/launch.js +0 -116
- package/clients/lsp/lsp/server.js +0 -532
- package/clients/lsp/lsp-index.js +0 -10
- package/clients/lsp/path-utils.js +0 -5
- package/clients/lsp/server.js +0 -725
- package/clients/lsp/test-py-spawn/requirements.txt +0 -1
- package/clients/lsp/test-py-spawn/test.py +0 -3
- package/clients/lsp/test-py-svc/requirements.txt +0 -1
- package/clients/lsp/test-py-svc/test.py +0 -3
- package/clients/lsp/test-python-project/requirements.txt +0 -1
- package/clients/lsp/test-python-project/test.py +0 -5
- package/clients/metrics-client.js +0 -107
- package/clients/metrics-client.test.js +0 -128
- package/clients/metrics-client.test.ts +0 -163
- package/clients/metrics-history.js +0 -367
- package/clients/path-utils.js +0 -142
- package/clients/pipeline.js +0 -272
- package/clients/production-readiness.js +0 -522
- package/clients/project-index.js +0 -255
- package/clients/project-metadata.js +0 -531
- package/clients/ruff-client.js +0 -325
- package/clients/ruff-client.test.js +0 -132
- package/clients/ruff-client.test.ts +0 -153
- package/clients/rules-scanner.js +0 -97
- package/clients/runner-tracker.js +0 -152
- package/clients/rust-client.js +0 -205
- package/clients/rust-client.test.js +0 -108
- package/clients/rust-client.test.ts +0 -130
- package/clients/safe-spawn-async.js +0 -163
- package/clients/safe-spawn.js +0 -241
- package/clients/sanitize.js +0 -291
- package/clients/sanitize.test.js +0 -177
- package/clients/sanitize.test.ts +0 -223
- package/clients/scan-architectural-debt.js +0 -167
- package/clients/scan-utils.js +0 -83
- package/clients/secrets-scanner.js +0 -119
- package/clients/secrets-scanner.test.js +0 -100
- package/clients/secrets-scanner.test.ts +0 -113
- package/clients/sg-runner.js +0 -292
- package/clients/state-matrix.js +0 -160
- package/clients/subprocess-client.js +0 -65
- package/clients/symbol-types.js +0 -5
- package/clients/test-runner-client.js +0 -523
- package/clients/test-runner-client.test.js +0 -192
- package/clients/test-runner-client.test.ts +0 -253
- package/clients/test-utils.js +0 -27
- package/clients/test-utils.ts +0 -36
- package/clients/todo-scanner.js +0 -200
- package/clients/todo-scanner.test.js +0 -301
- package/clients/todo-scanner.test.ts +0 -352
- package/clients/tool-availability.js +0 -207
- package/clients/tree-sitter-client.js +0 -601
- package/clients/tree-sitter-query-loader.js +0 -355
- package/clients/tree-sitter-symbol-extractor.js +0 -289
- package/clients/ts-service.js +0 -129
- package/clients/type-coverage-client.js +0 -127
- package/clients/type-coverage-client.test.js +0 -105
- package/clients/type-coverage-client.test.ts +0 -125
- package/clients/type-safety-client.js +0 -138
- package/clients/types.js +0 -11
- package/clients/typescript-client.codefix.test.js +0 -157
- package/clients/typescript-client.codefix.test.ts +0 -186
- package/clients/typescript-client.js +0 -509
- package/clients/typescript-client.test.js +0 -105
- package/clients/typescript-client.test.ts +0 -126
- package/commands/booboo.js +0 -1007
- package/commands/fix-from-booboo.js +0 -398
- package/commands/fix-simplified.js +0 -618
- package/commands/rate.js +0 -281
- package/commands/rate.test.js +0 -119
- package/commands/rate.test.ts +0 -131
- package/commands/refactor.js +0 -130
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dispatch integration helpers
|
|
3
|
-
*
|
|
4
|
-
* Provides utilities for integrating the declarative dispatch system
|
|
5
|
-
* with the existing index.ts tool_result handler.
|
|
6
|
-
*/
|
|
7
|
-
import { detectFileKind } from "../file-kinds.js";
|
|
8
|
-
import { clearLatencyReports, createBaselineStore, createDispatchContext, formatLatencyReport, getLatencyReports, } from "./dispatcher.js";
|
|
9
|
-
// Re-export latency tracking types and functions
|
|
10
|
-
export { clearLatencyReports, formatLatencyReport, getLatencyReports };
|
|
11
|
-
// Import runners to register them
|
|
12
|
-
import "./runners/index.js";
|
|
13
|
-
// --- Persistent Baseline Store ---
|
|
14
|
-
// Survives across dispatchLint calls within a session.
|
|
15
|
-
// Without this, delta mode is a no-op: every call creates a fresh empty
|
|
16
|
-
// store, so baselines.get() always returns undefined and every issue
|
|
17
|
-
// looks "new" every time.
|
|
18
|
-
const sessionBaselines = createBaselineStore();
|
|
19
|
-
/**
|
|
20
|
-
* Reset baselines — call on session_start so a new session
|
|
21
|
-
* starts with a clean slate.
|
|
22
|
-
*/
|
|
23
|
-
export function resetDispatchBaselines() {
|
|
24
|
-
sessionBaselines.clear();
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Run linting for a file using the declarative dispatch system
|
|
28
|
-
*
|
|
29
|
-
* @param filePath - Path to the file to lint
|
|
30
|
-
* @param cwd - Project root directory
|
|
31
|
-
* @param pi - Pi agent API (for flags)
|
|
32
|
-
* @returns Output string to display to user
|
|
33
|
-
*/
|
|
34
|
-
export async function dispatchLint(filePath, cwd, pi) {
|
|
35
|
-
// By default, only run BLOCKING rules for fast feedback on file write
|
|
36
|
-
// Uses persistent sessionBaselines so delta mode actually filters
|
|
37
|
-
// pre-existing issues after the first write.
|
|
38
|
-
const ctx = createDispatchContext(filePath, cwd, pi, sessionBaselines, true);
|
|
39
|
-
// Import dispatchForFile dynamically to avoid circular deps
|
|
40
|
-
const { dispatchForFile } = await import("./dispatcher.js");
|
|
41
|
-
const { getRunnersForKind } = await import("./dispatcher.js");
|
|
42
|
-
const { TOOL_PLANS } = await import("./plan.js");
|
|
43
|
-
const kind = ctx.kind;
|
|
44
|
-
if (!kind)
|
|
45
|
-
return "";
|
|
46
|
-
const plan = TOOL_PLANS[kind];
|
|
47
|
-
if (!plan)
|
|
48
|
-
return "";
|
|
49
|
-
const result = await dispatchForFile(ctx, plan.groups);
|
|
50
|
-
return result.output;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Run linting and return full result (including diagnostics)
|
|
54
|
-
*/
|
|
55
|
-
export async function dispatchLintWithResult(filePath, cwd, pi) {
|
|
56
|
-
const ctx = createDispatchContext(filePath, cwd, pi, sessionBaselines, true);
|
|
57
|
-
const { dispatchForFile } = await import("./dispatcher.js");
|
|
58
|
-
const { getRunnersForKind } = await import("./dispatcher.js");
|
|
59
|
-
const { TOOL_PLANS } = await import("./plan.js");
|
|
60
|
-
const kind = ctx.kind;
|
|
61
|
-
if (!kind) {
|
|
62
|
-
return {
|
|
63
|
-
diagnostics: [],
|
|
64
|
-
blockers: [],
|
|
65
|
-
warnings: [],
|
|
66
|
-
fixed: [],
|
|
67
|
-
output: "",
|
|
68
|
-
hasBlockers: false,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
const plan = TOOL_PLANS[kind];
|
|
72
|
-
if (!plan) {
|
|
73
|
-
return {
|
|
74
|
-
diagnostics: [],
|
|
75
|
-
blockers: [],
|
|
76
|
-
warnings: [],
|
|
77
|
-
fixed: [],
|
|
78
|
-
output: "",
|
|
79
|
-
hasBlockers: false,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return await dispatchForFile(ctx, plan.groups);
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Create a baseline store for delta mode tracking
|
|
86
|
-
*/
|
|
87
|
-
export function createLintBaselines() {
|
|
88
|
-
return createBaselineStore();
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Check if a file should be processed by the dispatcher
|
|
92
|
-
* based on the file kind
|
|
93
|
-
*/
|
|
94
|
-
export function shouldDispatch(filePath) {
|
|
95
|
-
const kind = detectFileKind(filePath);
|
|
96
|
-
return kind !== undefined;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Get list of available runners for a file
|
|
100
|
-
*/
|
|
101
|
-
export async function getAvailableRunners(filePath) {
|
|
102
|
-
const kind = detectFileKind(filePath);
|
|
103
|
-
if (!kind)
|
|
104
|
-
return [];
|
|
105
|
-
const { getRunnersForKind } = await import("./dispatcher.js");
|
|
106
|
-
const runners = getRunnersForKind(kind);
|
|
107
|
-
return runners.map((r) => r.id);
|
|
108
|
-
}
|
package/clients/dispatch/plan.js
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool execution plan for pi-lens
|
|
3
|
-
*
|
|
4
|
-
* Defines which tools run for each file kind and in what order.
|
|
5
|
-
* This is the declarative alternative to the if/else chains in index.ts.
|
|
6
|
-
*
|
|
7
|
-
* Modes:
|
|
8
|
-
* - "all": Run all runners in the group
|
|
9
|
-
* - "fallback": Run first available runner
|
|
10
|
-
* - "first-success": Run until one succeeds
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Tool plans organized by purpose
|
|
14
|
-
*
|
|
15
|
-
* CORE PRINCIPLE: File write only runs BLOCKING tools
|
|
16
|
-
* - Type checking (LSP) - blocking errors
|
|
17
|
-
* - Security/correctness lint - blocking errors
|
|
18
|
-
* - Auto-format/auto-fix handled by direct calls in index.ts (not here)
|
|
19
|
-
*
|
|
20
|
-
* Warning-only tools run on /lens-booboo command only
|
|
21
|
-
*/
|
|
22
|
-
export const TOOL_PLANS = {
|
|
23
|
-
/**
|
|
24
|
-
* Linting tools for JS/TS files
|
|
25
|
-
*/
|
|
26
|
-
jsts: {
|
|
27
|
-
name: "JavaScript/TypeScript Linting",
|
|
28
|
-
groups: [
|
|
29
|
-
// LSP type checking (unified for all languages) - priority 4, blocking errors
|
|
30
|
-
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["jsts"] },
|
|
31
|
-
// Tree-sitter native structural analysis (blocking rules: constructor-super, dangerouslySetInnerHTML, etc.)
|
|
32
|
-
{ mode: "all", runnerIds: ["tree-sitter"], filterKinds: ["jsts"] },
|
|
33
|
-
// AST structural analysis (blocking: no-dupe-keys, no-hardcoded-secrets, jwt-no-verify, etc.)
|
|
34
|
-
// Only error-severity rules fire inline (blockingOnly=true). Warnings are booboo-only.
|
|
35
|
-
{ mode: "all", runnerIds: ["ast-grep-napi"], filterKinds: ["jsts"] },
|
|
36
|
-
// Type safety checks (has some blocking errors)
|
|
37
|
-
{ mode: "fallback", runnerIds: ["type-safety"], filterKinds: ["jsts"] },
|
|
38
|
-
// Similarity detection — warns about duplicated/reusable code
|
|
39
|
-
{ mode: "fallback", runnerIds: ["similarity"], filterKinds: ["jsts"] },
|
|
40
|
-
// Note: ast-grep CLI kept for ast_grep_search/ast_grep_replace tools only
|
|
41
|
-
// Note: biome, oxlint handled by direct auto-fix calls in index.ts (not in dispatch)
|
|
42
|
-
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
43
|
-
],
|
|
44
|
-
},
|
|
45
|
-
/**
|
|
46
|
-
* Python linting tools
|
|
47
|
-
*/
|
|
48
|
-
python: {
|
|
49
|
-
name: "Python Linting",
|
|
50
|
-
groups: [
|
|
51
|
-
// Pyright type checking (standard mode - no LSP flag needed)
|
|
52
|
-
// Provides Python type errors in standard pi mode
|
|
53
|
-
{ mode: "all", runnerIds: ["pyright"], filterKinds: ["python"] },
|
|
54
|
-
// LSP type checking (unified) - when --lens-lsp enabled
|
|
55
|
-
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["python"] },
|
|
56
|
-
// Note: ruff handled by direct auto-fix calls in index.ts (not in dispatch)
|
|
57
|
-
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
58
|
-
],
|
|
59
|
-
},
|
|
60
|
-
/**
|
|
61
|
-
* Go linting tools
|
|
62
|
-
*/
|
|
63
|
-
go: {
|
|
64
|
-
name: "Go Linting",
|
|
65
|
-
groups: [
|
|
66
|
-
// LSP type checking (gopls)
|
|
67
|
-
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["go"] },
|
|
68
|
-
// Go vet for additional checks (warning only, but low cost)
|
|
69
|
-
{ mode: "fallback", runnerIds: ["go-vet"], filterKinds: ["go"] },
|
|
70
|
-
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
71
|
-
],
|
|
72
|
-
},
|
|
73
|
-
/**
|
|
74
|
-
* Rust linting tools
|
|
75
|
-
*/
|
|
76
|
-
rust: {
|
|
77
|
-
name: "Rust Linting",
|
|
78
|
-
groups: [
|
|
79
|
-
// LSP type checking (rust-analyzer)
|
|
80
|
-
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["rust"] },
|
|
81
|
-
// Cargo clippy for additional checks
|
|
82
|
-
{ mode: "fallback", runnerIds: ["rust-clippy"], filterKinds: ["rust"] },
|
|
83
|
-
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
84
|
-
],
|
|
85
|
-
},
|
|
86
|
-
/**
|
|
87
|
-
* C/C++ linting tools
|
|
88
|
-
*/
|
|
89
|
-
cxx: {
|
|
90
|
-
name: "C/C++ Linting",
|
|
91
|
-
groups: [
|
|
92
|
-
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
93
|
-
],
|
|
94
|
-
},
|
|
95
|
-
/**
|
|
96
|
-
* JSON/JSONC files
|
|
97
|
-
*/
|
|
98
|
-
json: {
|
|
99
|
-
name: "JSON Processing",
|
|
100
|
-
groups: [
|
|
101
|
-
// Note: Biome handles JSON formatting via direct call in index.ts
|
|
102
|
-
// No additional linting needed for JSON
|
|
103
|
-
],
|
|
104
|
-
},
|
|
105
|
-
/**
|
|
106
|
-
* Markdown files
|
|
107
|
-
*/
|
|
108
|
-
markdown: {
|
|
109
|
-
name: "Markdown Processing",
|
|
110
|
-
groups: [
|
|
111
|
-
// Spellcheck for typos (warning only, but useful)
|
|
112
|
-
{ mode: "fallback", runnerIds: ["spellcheck"] },
|
|
113
|
-
],
|
|
114
|
-
},
|
|
115
|
-
/**
|
|
116
|
-
* Shell scripts
|
|
117
|
-
*/
|
|
118
|
-
shell: {
|
|
119
|
-
name: "Shell Script Linting",
|
|
120
|
-
groups: [
|
|
121
|
-
// Shellcheck for bash/sh/zsh linting (has blocking errors for syntax)
|
|
122
|
-
{ mode: "fallback", runnerIds: ["shellcheck"] },
|
|
123
|
-
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
124
|
-
],
|
|
125
|
-
},
|
|
126
|
-
/**
|
|
127
|
-
* CMake files
|
|
128
|
-
*/
|
|
129
|
-
cmake: {
|
|
130
|
-
name: "CMake Processing",
|
|
131
|
-
groups: [
|
|
132
|
-
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
133
|
-
],
|
|
134
|
-
},
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* Get the tool plan for a specific file kind
|
|
138
|
-
*/
|
|
139
|
-
export function getToolPlan(kind) {
|
|
140
|
-
return TOOL_PLANS[kind];
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Get all registered tool plans
|
|
144
|
-
*/
|
|
145
|
-
export function getAllToolPlans() {
|
|
146
|
-
return TOOL_PLANS;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Full lint plan for /lens-booboo command (includes warning-only tools)
|
|
150
|
-
* This includes ALL runners for comprehensive analysis
|
|
151
|
-
*/
|
|
152
|
-
export const FULL_LINT_PLANS = {
|
|
153
|
-
...TOOL_PLANS,
|
|
154
|
-
// Override jsts to include warning-only tools
|
|
155
|
-
jsts: {
|
|
156
|
-
name: "JavaScript/TypeScript Full Lint",
|
|
157
|
-
groups: [
|
|
158
|
-
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["jsts"] },
|
|
159
|
-
{ mode: "all", runnerIds: ["tree-sitter"], filterKinds: ["jsts"] },
|
|
160
|
-
{ mode: "all", runnerIds: ["ast-grep-napi"], filterKinds: ["jsts"] },
|
|
161
|
-
// Warning-only tools (for full lint, not file write)
|
|
162
|
-
{
|
|
163
|
-
mode: "fallback",
|
|
164
|
-
runnerIds: ["biome-lint", "oxlint"],
|
|
165
|
-
filterKinds: ["jsts"],
|
|
166
|
-
},
|
|
167
|
-
{ mode: "fallback", runnerIds: ["type-safety"], filterKinds: ["jsts"] },
|
|
168
|
-
{ mode: "fallback", runnerIds: ["similarity"], filterKinds: ["jsts"] },
|
|
169
|
-
{ mode: "fallback", runnerIds: ["architect"], filterKinds: ["jsts"] },
|
|
170
|
-
],
|
|
171
|
-
},
|
|
172
|
-
// Override python to include warning-only tools
|
|
173
|
-
python: {
|
|
174
|
-
name: "Python Full Lint",
|
|
175
|
-
groups: [
|
|
176
|
-
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["python"] },
|
|
177
|
-
// Warning-only tools
|
|
178
|
-
{ mode: "fallback", runnerIds: ["ruff-lint"], filterKinds: ["python"] },
|
|
179
|
-
{ mode: "fallback", runnerIds: ["python-slop"], filterKinds: ["python"] },
|
|
180
|
-
{ mode: "fallback", runnerIds: ["architect"], filterKinds: ["python"] },
|
|
181
|
-
],
|
|
182
|
-
},
|
|
183
|
-
};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Architectural rules runner for dispatch system
|
|
3
|
-
*
|
|
4
|
-
* Checks for architectural violations:
|
|
5
|
-
* - Absolute Windows/Unix paths
|
|
6
|
-
* - Hardcoded localhost URLs
|
|
7
|
-
* - Empty catch blocks
|
|
8
|
-
* - Secrets in code
|
|
9
|
-
* - File size limits
|
|
10
|
-
*/
|
|
11
|
-
import { ArchitectClient } from "../../architect-client.js";
|
|
12
|
-
import { readFileContent } from "./utils.js";
|
|
13
|
-
const architectRunner = {
|
|
14
|
-
id: "architect",
|
|
15
|
-
appliesTo: ["jsts", "python", "go", "rust", "cxx", "shell", "cmake"],
|
|
16
|
-
priority: 40,
|
|
17
|
-
enabledByDefault: true,
|
|
18
|
-
skipTestFiles: true, // Skip test files - rules can be noisy there
|
|
19
|
-
async run(ctx) {
|
|
20
|
-
const relPath = ctx.filePath.replace(ctx.cwd, "").replace(/\\/g, "/");
|
|
21
|
-
const content = readFileContent(ctx.filePath);
|
|
22
|
-
if (!content) {
|
|
23
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
24
|
-
}
|
|
25
|
-
const architectClient = new ArchitectClient();
|
|
26
|
-
architectClient.loadConfig(ctx.cwd);
|
|
27
|
-
if (!architectClient.hasConfig()) {
|
|
28
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
29
|
-
}
|
|
30
|
-
const diagnostics = [];
|
|
31
|
-
// Check for violations
|
|
32
|
-
const violations = architectClient.checkFile(relPath, content);
|
|
33
|
-
for (const v of violations) {
|
|
34
|
-
// Build message with inline fix guidance
|
|
35
|
-
let message = v.message;
|
|
36
|
-
let fixSuggestion = v.fix;
|
|
37
|
-
if (v.fix) {
|
|
38
|
-
const fixPreview = v.fix.length > 60 ? `${v.fix.substring(0, 60)}...` : v.fix;
|
|
39
|
-
message += `\n💡 Suggested fix: ${fixPreview}`;
|
|
40
|
-
}
|
|
41
|
-
else if (v.note) {
|
|
42
|
-
const notePreview = v.note.length > 80 ? `${v.note.substring(0, 80)}...` : v.note;
|
|
43
|
-
message += `\n📝 ${notePreview}`;
|
|
44
|
-
}
|
|
45
|
-
diagnostics.push({
|
|
46
|
-
id: `architect-${v.line || 0}-${v.pattern}`,
|
|
47
|
-
message,
|
|
48
|
-
filePath: ctx.filePath,
|
|
49
|
-
line: v.line,
|
|
50
|
-
severity: "warning",
|
|
51
|
-
semantic: "warning",
|
|
52
|
-
tool: "architect",
|
|
53
|
-
rule: v.pattern,
|
|
54
|
-
fixable: !!v.fix,
|
|
55
|
-
fixSuggestion,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
// Check file size limit
|
|
59
|
-
const lineCount = content.split("\n").length;
|
|
60
|
-
const sizeViolation = architectClient.checkFileSize(relPath, lineCount);
|
|
61
|
-
if (sizeViolation) {
|
|
62
|
-
diagnostics.push({
|
|
63
|
-
id: `architect-size-${lineCount}`,
|
|
64
|
-
message: sizeViolation.message,
|
|
65
|
-
filePath: ctx.filePath,
|
|
66
|
-
severity: "warning",
|
|
67
|
-
semantic: "warning",
|
|
68
|
-
tool: "architect",
|
|
69
|
-
rule: "file-size-limit",
|
|
70
|
-
fixSuggestion: "Split into smaller modules",
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
if (diagnostics.length === 0) {
|
|
74
|
-
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
75
|
-
}
|
|
76
|
-
return {
|
|
77
|
-
status: "succeeded", // Warnings don't fail the run
|
|
78
|
-
diagnostics,
|
|
79
|
-
semantic: "warning",
|
|
80
|
-
};
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
export default architectRunner;
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { describe, expect, it, beforeAll, afterAll } from "vitest";
|
|
4
|
-
function createMockContext(filePath, kind = "jsts", cwd) {
|
|
5
|
-
return {
|
|
6
|
-
filePath,
|
|
7
|
-
cwd: cwd || process.cwd(),
|
|
8
|
-
kind,
|
|
9
|
-
autofix: false,
|
|
10
|
-
deltaMode: false,
|
|
11
|
-
baselines: { get: () => undefined, set: () => { }, clear: () => { } },
|
|
12
|
-
pi: { getFlag: () => false },
|
|
13
|
-
hasTool: async () => false,
|
|
14
|
-
log: () => { },
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
describe("architect runner", () => {
|
|
18
|
-
const testDir = path.join(process.env.TEMP || "/tmp", `architect_test_${Date.now()}`);
|
|
19
|
-
const configPath = path.join(testDir, ".pi-lens", "architect.yaml");
|
|
20
|
-
beforeAll(() => {
|
|
21
|
-
// Create test config
|
|
22
|
-
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
23
|
-
fs.writeFileSync(configPath, `version: "1.0"
|
|
24
|
-
rules:
|
|
25
|
-
- pattern: "**/*.ts"
|
|
26
|
-
max_lines: 50
|
|
27
|
-
must_not:
|
|
28
|
-
- pattern: 'hardcoded_secret_12345'
|
|
29
|
-
message: "No hardcoded secrets"
|
|
30
|
-
fix: "Use process.env.SECRET"
|
|
31
|
-
- pattern: 'console\.log'
|
|
32
|
-
message: "No console.log in production"
|
|
33
|
-
`);
|
|
34
|
-
});
|
|
35
|
-
afterAll(() => {
|
|
36
|
-
try {
|
|
37
|
-
if (fs.existsSync(testDir)) {
|
|
38
|
-
fs.rmSync(testDir, { recursive: true, force: true });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
// Ignore cleanup errors
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
it("should load default config when no user config exists", async () => {
|
|
46
|
-
const module = await import("./architect.js");
|
|
47
|
-
const runner = module.default;
|
|
48
|
-
// Use a unique temp dir with no user config (will fall back to default)
|
|
49
|
-
const noUserConfigDir = path.join(process.env.TEMP || "/tmp", `no_arch_user_config_${Date.now()}`);
|
|
50
|
-
fs.mkdirSync(noUserConfigDir, { recursive: true });
|
|
51
|
-
// Create a very large file that should trigger default max_lines rule
|
|
52
|
-
const tmpFile = path.join(noUserConfigDir, `large_${Date.now()}.ts`);
|
|
53
|
-
fs.writeFileSync(tmpFile, Array(5000).fill("// line").join("\n"));
|
|
54
|
-
try {
|
|
55
|
-
const result = await runner.run(createMockContext(tmpFile, "jsts", noUserConfigDir));
|
|
56
|
-
// Should use default config and find violations
|
|
57
|
-
expect(result.status).toBe("succeeded");
|
|
58
|
-
// Should have size violation from default config
|
|
59
|
-
expect(result.diagnostics.some((d) => d.message.includes("line limit"))).toBe(true);
|
|
60
|
-
}
|
|
61
|
-
finally {
|
|
62
|
-
try {
|
|
63
|
-
if (fs.existsSync(tmpFile))
|
|
64
|
-
fs.unlinkSync(tmpFile);
|
|
65
|
-
if (fs.existsSync(noUserConfigDir))
|
|
66
|
-
fs.rmdirSync(noUserConfigDir);
|
|
67
|
-
}
|
|
68
|
-
catch { }
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
it("should detect file size violations", async () => {
|
|
72
|
-
const module = await import("./architect.js");
|
|
73
|
-
const runner = module.default;
|
|
74
|
-
const tmpFile = path.join(testDir, `large_file_${Date.now()}.ts`);
|
|
75
|
-
// Create file with 100 lines (exceeds 50 line limit)
|
|
76
|
-
fs.writeFileSync(tmpFile, Array(100).fill("// line").join("\n"));
|
|
77
|
-
try {
|
|
78
|
-
const result = await runner.run(createMockContext(tmpFile, "jsts", testDir));
|
|
79
|
-
expect(result.status).toBe("succeeded");
|
|
80
|
-
expect(result.diagnostics.length).toBeGreaterThan(0);
|
|
81
|
-
expect(result.diagnostics.some((d) => d.message.includes("50 line limit"))).toBe(true);
|
|
82
|
-
}
|
|
83
|
-
finally {
|
|
84
|
-
try {
|
|
85
|
-
if (fs.existsSync(tmpFile))
|
|
86
|
-
fs.unlinkSync(tmpFile);
|
|
87
|
-
}
|
|
88
|
-
catch { }
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
it("should detect pattern violations", async () => {
|
|
92
|
-
const module = await import("./architect.js");
|
|
93
|
-
const runner = module.default;
|
|
94
|
-
const tmpFile = path.join(testDir, `bad_patterns_${Date.now()}.ts`);
|
|
95
|
-
fs.writeFileSync(tmpFile, `const x = hardcoded_secret_12345;
|
|
96
|
-
console.log(x);
|
|
97
|
-
`);
|
|
98
|
-
try {
|
|
99
|
-
const result = await runner.run(createMockContext(tmpFile, "jsts", testDir));
|
|
100
|
-
expect(result.status).toBe("succeeded");
|
|
101
|
-
expect(result.diagnostics.length).toBeGreaterThanOrEqual(2);
|
|
102
|
-
expect(result.diagnostics.some((d) => d.message.includes("hardcoded"))).toBe(true);
|
|
103
|
-
expect(result.diagnostics.some((d) => d.message.includes("console.log"))).toBe(true);
|
|
104
|
-
}
|
|
105
|
-
finally {
|
|
106
|
-
try {
|
|
107
|
-
if (fs.existsSync(tmpFile))
|
|
108
|
-
fs.unlinkSync(tmpFile);
|
|
109
|
-
}
|
|
110
|
-
catch { }
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
it("should return no diagnostics for clean files", async () => {
|
|
114
|
-
const module = await import("./architect.js");
|
|
115
|
-
const runner = module.default;
|
|
116
|
-
const tmpFile = path.join(testDir, `clean_${Date.now()}.ts`);
|
|
117
|
-
// Small file (20 lines) with no violations
|
|
118
|
-
fs.writeFileSync(tmpFile, Array(20).fill("// clean code").join("\n"));
|
|
119
|
-
try {
|
|
120
|
-
const result = await runner.run(createMockContext(tmpFile, "jsts", testDir));
|
|
121
|
-
expect(result.status).toBe("succeeded");
|
|
122
|
-
expect(result.diagnostics.length).toBe(0);
|
|
123
|
-
}
|
|
124
|
-
finally {
|
|
125
|
-
try {
|
|
126
|
-
if (fs.existsSync(tmpFile))
|
|
127
|
-
fs.unlinkSync(tmpFile);
|
|
128
|
-
}
|
|
129
|
-
catch { }
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
it("should skip test files", async () => {
|
|
133
|
-
const module = await import("./architect.js");
|
|
134
|
-
const runner = module.default;
|
|
135
|
-
// The runner should have skipTestFiles: true
|
|
136
|
-
expect(runner.skipTestFiles).toBe(true);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { describe, expect, it, beforeAll, afterAll } from "vitest";
|
|
4
|
-
import type { DispatchContext } from "../types.js";
|
|
5
|
-
|
|
6
|
-
function createMockContext(
|
|
7
|
-
filePath: string,
|
|
8
|
-
kind: "jsts" | "python" | "go" | "rust" = "jsts",
|
|
9
|
-
cwd?: string,
|
|
10
|
-
): DispatchContext {
|
|
11
|
-
return {
|
|
12
|
-
filePath,
|
|
13
|
-
cwd: cwd || process.cwd(),
|
|
14
|
-
kind,
|
|
15
|
-
autofix: false,
|
|
16
|
-
deltaMode: false,
|
|
17
|
-
baselines: { get: () => undefined, set: () => {}, clear: () => {} } as any,
|
|
18
|
-
pi: { getFlag: () => false } as any,
|
|
19
|
-
hasTool: async () => false,
|
|
20
|
-
log: () => {},
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
describe("architect runner", () => {
|
|
25
|
-
const testDir = path.join(process.env.TEMP || "/tmp", `architect_test_${Date.now()}`);
|
|
26
|
-
const configPath = path.join(testDir, ".pi-lens", "architect.yaml");
|
|
27
|
-
|
|
28
|
-
beforeAll(() => {
|
|
29
|
-
// Create test config
|
|
30
|
-
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
31
|
-
fs.writeFileSync(
|
|
32
|
-
configPath,
|
|
33
|
-
`version: "1.0"
|
|
34
|
-
rules:
|
|
35
|
-
- pattern: "**/*.ts"
|
|
36
|
-
max_lines: 50
|
|
37
|
-
must_not:
|
|
38
|
-
- pattern: 'hardcoded_secret_12345'
|
|
39
|
-
message: "No hardcoded secrets"
|
|
40
|
-
fix: "Use process.env.SECRET"
|
|
41
|
-
- pattern: 'console\.log'
|
|
42
|
-
message: "No console.log in production"
|
|
43
|
-
`,
|
|
44
|
-
);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
afterAll(() => {
|
|
48
|
-
try {
|
|
49
|
-
if (fs.existsSync(testDir)) {
|
|
50
|
-
fs.rmSync(testDir, { recursive: true, force: true });
|
|
51
|
-
}
|
|
52
|
-
} catch {
|
|
53
|
-
// Ignore cleanup errors
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("should load default config when no user config exists", async () => {
|
|
58
|
-
const module = await import("./architect.js");
|
|
59
|
-
const runner = module.default;
|
|
60
|
-
|
|
61
|
-
// Use a unique temp dir with no user config (will fall back to default)
|
|
62
|
-
const noUserConfigDir = path.join(process.env.TEMP || "/tmp", `no_arch_user_config_${Date.now()}`);
|
|
63
|
-
fs.mkdirSync(noUserConfigDir, { recursive: true });
|
|
64
|
-
|
|
65
|
-
// Create a very large file that should trigger default max_lines rule
|
|
66
|
-
const tmpFile = path.join(noUserConfigDir, `large_${Date.now()}.ts`);
|
|
67
|
-
fs.writeFileSync(tmpFile, Array(5000).fill("// line").join("\n"));
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
const result = await runner.run(
|
|
71
|
-
createMockContext(tmpFile, "jsts", noUserConfigDir),
|
|
72
|
-
);
|
|
73
|
-
// Should use default config and find violations
|
|
74
|
-
expect(result.status).toBe("succeeded");
|
|
75
|
-
// Should have size violation from default config
|
|
76
|
-
expect(result.diagnostics.some((d) => d.message.includes("line limit"))).toBe(true);
|
|
77
|
-
} finally {
|
|
78
|
-
try {
|
|
79
|
-
if (fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile);
|
|
80
|
-
if (fs.existsSync(noUserConfigDir)) fs.rmdirSync(noUserConfigDir);
|
|
81
|
-
} catch {}
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("should detect file size violations", async () => {
|
|
86
|
-
const module = await import("./architect.js");
|
|
87
|
-
const runner = module.default;
|
|
88
|
-
|
|
89
|
-
const tmpFile = path.join(testDir, `large_file_${Date.now()}.ts`);
|
|
90
|
-
// Create file with 100 lines (exceeds 50 line limit)
|
|
91
|
-
fs.writeFileSync(tmpFile, Array(100).fill("// line").join("\n"));
|
|
92
|
-
|
|
93
|
-
try {
|
|
94
|
-
const result = await runner.run(createMockContext(tmpFile, "jsts", testDir));
|
|
95
|
-
expect(result.status).toBe("succeeded");
|
|
96
|
-
expect(result.diagnostics.length).toBeGreaterThan(0);
|
|
97
|
-
expect(result.diagnostics.some((d) => d.message.includes("50 line limit"))).toBe(
|
|
98
|
-
true,
|
|
99
|
-
);
|
|
100
|
-
} finally {
|
|
101
|
-
try {
|
|
102
|
-
if (fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile);
|
|
103
|
-
} catch {}
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("should detect pattern violations", async () => {
|
|
108
|
-
const module = await import("./architect.js");
|
|
109
|
-
const runner = module.default;
|
|
110
|
-
|
|
111
|
-
const tmpFile = path.join(testDir, `bad_patterns_${Date.now()}.ts`);
|
|
112
|
-
fs.writeFileSync(
|
|
113
|
-
tmpFile,
|
|
114
|
-
`const x = hardcoded_secret_12345;
|
|
115
|
-
console.log(x);
|
|
116
|
-
`,
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
const result = await runner.run(createMockContext(tmpFile, "jsts", testDir));
|
|
121
|
-
expect(result.status).toBe("succeeded");
|
|
122
|
-
expect(result.diagnostics.length).toBeGreaterThanOrEqual(2);
|
|
123
|
-
expect(
|
|
124
|
-
result.diagnostics.some((d) => d.message.includes("hardcoded")),
|
|
125
|
-
).toBe(true);
|
|
126
|
-
expect(
|
|
127
|
-
result.diagnostics.some((d) => d.message.includes("console.log")),
|
|
128
|
-
).toBe(true);
|
|
129
|
-
} finally {
|
|
130
|
-
try {
|
|
131
|
-
if (fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile);
|
|
132
|
-
} catch {}
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it("should return no diagnostics for clean files", async () => {
|
|
137
|
-
const module = await import("./architect.js");
|
|
138
|
-
const runner = module.default;
|
|
139
|
-
|
|
140
|
-
const tmpFile = path.join(testDir, `clean_${Date.now()}.ts`);
|
|
141
|
-
// Small file (20 lines) with no violations
|
|
142
|
-
fs.writeFileSync(tmpFile, Array(20).fill("// clean code").join("\n"));
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
const result = await runner.run(createMockContext(tmpFile, "jsts", testDir));
|
|
146
|
-
expect(result.status).toBe("succeeded");
|
|
147
|
-
expect(result.diagnostics.length).toBe(0);
|
|
148
|
-
} finally {
|
|
149
|
-
try {
|
|
150
|
-
if (fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile);
|
|
151
|
-
} catch {}
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it("should skip test files", async () => {
|
|
156
|
-
const module = await import("./architect.js");
|
|
157
|
-
const runner = module.default;
|
|
158
|
-
|
|
159
|
-
// The runner should have skipTestFiles: true
|
|
160
|
-
expect(runner.skipTestFiles).toBe(true);
|
|
161
|
-
});
|
|
162
|
-
});
|