@vibecheckai/cli 3.0.2 → 3.0.3

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.
Files changed (68) hide show
  1. package/package.json +9 -1
  2. package/bin/cli-hygiene.js +0 -241
  3. package/bin/guardrail.js +0 -834
  4. package/bin/runners/cli-utils.js +0 -1070
  5. package/bin/runners/context/ai-task-decomposer.js +0 -337
  6. package/bin/runners/context/analyzer.js +0 -462
  7. package/bin/runners/context/api-contracts.js +0 -427
  8. package/bin/runners/context/context-diff.js +0 -342
  9. package/bin/runners/context/context-pruner.js +0 -291
  10. package/bin/runners/context/dependency-graph.js +0 -414
  11. package/bin/runners/context/generators/claude.js +0 -107
  12. package/bin/runners/context/generators/codex.js +0 -108
  13. package/bin/runners/context/generators/copilot.js +0 -119
  14. package/bin/runners/context/generators/cursor.js +0 -514
  15. package/bin/runners/context/generators/mcp.js +0 -151
  16. package/bin/runners/context/generators/windsurf.js +0 -180
  17. package/bin/runners/context/git-context.js +0 -302
  18. package/bin/runners/context/index.js +0 -1042
  19. package/bin/runners/context/insights.js +0 -173
  20. package/bin/runners/context/mcp-server/generate-rules.js +0 -337
  21. package/bin/runners/context/mcp-server/index.js +0 -1176
  22. package/bin/runners/context/mcp-server/package.json +0 -24
  23. package/bin/runners/context/memory.js +0 -200
  24. package/bin/runners/context/monorepo.js +0 -215
  25. package/bin/runners/context/multi-repo-federation.js +0 -404
  26. package/bin/runners/context/patterns.js +0 -253
  27. package/bin/runners/context/proof-context.js +0 -972
  28. package/bin/runners/context/security-scanner.js +0 -303
  29. package/bin/runners/context/semantic-search.js +0 -350
  30. package/bin/runners/context/shared.js +0 -264
  31. package/bin/runners/context/team-conventions.js +0 -310
  32. package/bin/runners/lib/ai-bridge.js +0 -416
  33. package/bin/runners/lib/analysis-core.js +0 -271
  34. package/bin/runners/lib/analyzers.js +0 -541
  35. package/bin/runners/lib/audit-bridge.js +0 -391
  36. package/bin/runners/lib/auth-truth.js +0 -193
  37. package/bin/runners/lib/auth.js +0 -215
  38. package/bin/runners/lib/backup.js +0 -62
  39. package/bin/runners/lib/billing.js +0 -107
  40. package/bin/runners/lib/claims.js +0 -118
  41. package/bin/runners/lib/cli-ui.js +0 -540
  42. package/bin/runners/lib/compliance-bridge-new.js +0 -0
  43. package/bin/runners/lib/compliance-bridge.js +0 -165
  44. package/bin/runners/lib/contracts/auth-contract.js +0 -194
  45. package/bin/runners/lib/contracts/env-contract.js +0 -178
  46. package/bin/runners/lib/contracts/external-contract.js +0 -198
  47. package/bin/runners/lib/contracts/guard.js +0 -168
  48. package/bin/runners/lib/contracts/index.js +0 -89
  49. package/bin/runners/lib/contracts/plan-validator.js +0 -311
  50. package/bin/runners/lib/contracts/route-contract.js +0 -192
  51. package/bin/runners/lib/detect.js +0 -89
  52. package/bin/runners/lib/doctor/autofix.js +0 -254
  53. package/bin/runners/lib/doctor/index.js +0 -37
  54. package/bin/runners/lib/doctor/modules/dependencies.js +0 -325
  55. package/bin/runners/lib/doctor/modules/index.js +0 -46
  56. package/bin/runners/lib/doctor/modules/network.js +0 -250
  57. package/bin/runners/lib/doctor/modules/project.js +0 -312
  58. package/bin/runners/lib/doctor/modules/runtime.js +0 -224
  59. package/bin/runners/lib/doctor/modules/security.js +0 -348
  60. package/bin/runners/lib/doctor/modules/system.js +0 -213
  61. package/bin/runners/lib/doctor/modules/vibecheck.js +0 -394
  62. package/bin/runners/lib/doctor/reporter.js +0 -262
  63. package/bin/runners/lib/doctor/service.js +0 -262
  64. package/bin/runners/lib/doctor/types.js +0 -113
  65. package/bin/runners/lib/doctor/ui.js +0 -263
  66. package/bin/runners/lib/doctor-enhanced.js +0 -233
  67. package/bin/runners/lib/doctor-v2.js +0 -608
  68. package/bin/runners/lib/enforcement.js +0 -72
@@ -1,391 +0,0 @@
1
- /**
2
- * Audit Bridge - CLI Integration
3
- *
4
- * Provides a CommonJS wrapper for the audit trail functionality.
5
- * Used by CLI runners to emit audit events.
6
- */
7
-
8
- "use strict";
9
-
10
- const path = require("path");
11
- const fs = require("fs");
12
- const crypto = require("crypto");
13
-
14
- // Configuration
15
- const AUDIT_DIR = ".vibecheck/audit";
16
- const AUDIT_FILE = "audit.log.jsonl";
17
- const GENESIS_HASH = "0".repeat(64);
18
-
19
- // Tier from environment or default
20
- function getCurrentTier() {
21
- return process.env.VIBECHECK_TIER || "free";
22
- }
23
-
24
- // Get current actor from environment
25
- function getCurrentActor() {
26
- const userId = process.env.VIBECHECK_USER_ID || process.env.USER || process.env.USERNAME || "anonymous";
27
- const userName = process.env.VIBECHECK_USER_NAME || process.env.USERNAME;
28
- const userEmail = process.env.VIBECHECK_USER_EMAIL;
29
-
30
- // Detect CI environment
31
- if (process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI) {
32
- return {
33
- id: process.env.GITHUB_ACTOR || process.env.GITLAB_USER_LOGIN || "ci-system",
34
- type: "ci",
35
- name: process.env.GITHUB_ACTOR || process.env.GITLAB_USER_NAME,
36
- };
37
- }
38
-
39
- return {
40
- id: userId,
41
- type: "user",
42
- name: userName,
43
- email: userEmail,
44
- };
45
- }
46
-
47
- // Redaction patterns for sensitive data
48
- const REDACTION_PATTERNS = [
49
- /(?:api[_-]?key|apikey|token|secret|password|pwd|auth)[=:]\s*['"]?([a-zA-Z0-9_\-]{16,})['"]?/gi,
50
- /eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+/g,
51
- /(?:AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16}/g,
52
- /(?:sk_live_|sk_test_|pk_live_|pk_test_)[a-zA-Z0-9]+/g,
53
- ];
54
-
55
- function redactSensitive(input) {
56
- if (typeof input !== "string") return input;
57
- let result = input;
58
- for (const pattern of REDACTION_PATTERNS) {
59
- result = result.replace(pattern, "[REDACTED]");
60
- }
61
- return result;
62
- }
63
-
64
- function redactMetadata(metadata, tier) {
65
- if (!metadata) return undefined;
66
-
67
- // Compliance+ gets full metadata (still redact secrets)
68
- if (["compliance", "enterprise", "unlimited"].includes(tier)) {
69
- return redactObject(metadata);
70
- }
71
-
72
- // Pro gets limited metadata
73
- if (tier === "pro") {
74
- return {
75
- command: metadata.command,
76
- score: metadata.score,
77
- grade: metadata.grade,
78
- issueCount: metadata.issueCount,
79
- fixCount: metadata.fixCount,
80
- durationMs: metadata.durationMs,
81
- errorCode: metadata.errorCode,
82
- };
83
- }
84
-
85
- // Free/Starter get minimal
86
- return {
87
- score: metadata.score,
88
- grade: metadata.grade,
89
- };
90
- }
91
-
92
- function redactObject(obj) {
93
- if (!obj || typeof obj !== "object") return obj;
94
- const result = {};
95
- for (const [key, value] of Object.entries(obj)) {
96
- if (typeof value === "string") {
97
- result[key] = redactSensitive(value);
98
- } else if (Array.isArray(value)) {
99
- result[key] = value.map((v) => (typeof v === "string" ? redactSensitive(v) : v));
100
- } else if (typeof value === "object" && value !== null) {
101
- result[key] = redactObject(value);
102
- } else {
103
- result[key] = value;
104
- }
105
- }
106
- return result;
107
- }
108
-
109
- // Compute SHA-256 hash
110
- function computeHash(event) {
111
- const payload = JSON.stringify({
112
- id: event.id,
113
- timestamp: event.timestamp,
114
- actor: event.actor,
115
- surface: event.surface,
116
- action: event.action,
117
- category: event.category,
118
- target: event.target,
119
- tier: event.tier,
120
- result: event.result,
121
- metadata: event.metadata,
122
- prevHash: event.prevHash,
123
- version: event.version,
124
- });
125
- return crypto.createHash("sha256").update(payload).digest("hex");
126
- }
127
-
128
- // Get audit file path
129
- function getAuditFilePath(basePath = process.cwd()) {
130
- return path.join(basePath, AUDIT_DIR, AUDIT_FILE);
131
- }
132
-
133
- // Ensure audit directory exists
134
- function ensureAuditDir(basePath = process.cwd()) {
135
- const dir = path.join(basePath, AUDIT_DIR);
136
- if (!fs.existsSync(dir)) {
137
- fs.mkdirSync(dir, { recursive: true });
138
- }
139
- }
140
-
141
- // Get last hash from audit log
142
- function getLastHash(basePath = process.cwd()) {
143
- const filePath = getAuditFilePath(basePath);
144
- if (!fs.existsSync(filePath)) {
145
- return GENESIS_HASH;
146
- }
147
-
148
- const content = fs.readFileSync(filePath, "utf8");
149
- const lines = content.split("\n").filter((line) => line.trim());
150
- if (lines.length === 0) {
151
- return GENESIS_HASH;
152
- }
153
-
154
- try {
155
- const lastEvent = JSON.parse(lines[lines.length - 1]);
156
- return lastEvent.hash || GENESIS_HASH;
157
- } catch {
158
- return GENESIS_HASH;
159
- }
160
- }
161
-
162
- // Create audit event
163
- function createEvent(input, prevHash) {
164
- const tier = getCurrentTier();
165
- const id = crypto.randomUUID();
166
- const timestamp = new Date().toISOString();
167
-
168
- const eventWithoutHash = {
169
- id,
170
- timestamp,
171
- actor: input.actor || getCurrentActor(),
172
- surface: input.surface,
173
- action: input.action,
174
- category: input.category,
175
- target: input.target,
176
- tier,
177
- result: input.result,
178
- metadata: redactMetadata(input.metadata, tier),
179
- prevHash,
180
- version: 1,
181
- };
182
-
183
- const hash = computeHash(eventWithoutHash);
184
-
185
- return {
186
- ...eventWithoutHash,
187
- hash,
188
- };
189
- }
190
-
191
- // Emit audit event
192
- function emit(input, basePath = process.cwd()) {
193
- try {
194
- ensureAuditDir(basePath);
195
- const prevHash = getLastHash(basePath);
196
- const event = createEvent(input, prevHash);
197
-
198
- const filePath = getAuditFilePath(basePath);
199
- fs.appendFileSync(filePath, JSON.stringify(event) + "\n", "utf8");
200
-
201
- return event;
202
- } catch (err) {
203
- // Silently fail - audit should not break main functionality
204
- if (process.env.VIBECHECK_DEBUG) {
205
- console.error("[audit] Failed to emit event:", err.message);
206
- }
207
- return null;
208
- }
209
- }
210
-
211
- // Pre-defined actions
212
- const AuditActions = {
213
- SCAN_START: "scan.start",
214
- SCAN_COMPLETE: "scan.complete",
215
- SCAN_ERROR: "scan.error",
216
- SHIP_CHECK: "ship.check",
217
- SHIP_APPROVE: "ship.approve",
218
- SHIP_REJECT: "ship.reject",
219
- REALITY_START: "reality.start",
220
- REALITY_COMPLETE: "reality.complete",
221
- REALITY_ERROR: "reality.error",
222
- AUTOPILOT_ENABLE: "autopilot.enable",
223
- AUTOPILOT_DISABLE: "autopilot.disable",
224
- AUTOPILOT_RUN: "autopilot.run",
225
- AUTOPILOT_REPORT: "autopilot.report",
226
- FIX_PLAN: "fix.plan",
227
- FIX_APPLY: "fix.apply",
228
- FIX_REVERT: "fix.revert",
229
- GATE_CHECK: "gate.check",
230
- GATE_PASS: "gate.pass",
231
- GATE_FAIL: "gate.fail",
232
- AUTH_LOGIN: "auth.login",
233
- AUTH_LOGOUT: "auth.logout",
234
- TOOL_INVOKE: "tool.invoke",
235
- TOOL_COMPLETE: "tool.complete",
236
- TOOL_ERROR: "tool.error",
237
- };
238
-
239
- // Convenience emitters
240
- function emitScanStart(projectPath, args) {
241
- return emit({
242
- surface: "cli",
243
- action: AuditActions.SCAN_START,
244
- category: "scan",
245
- target: { type: "project", path: projectPath },
246
- result: "success",
247
- metadata: { command: "scan", args, projectPath },
248
- });
249
- }
250
-
251
- function emitScanComplete(projectPath, result, metadata) {
252
- return emit({
253
- surface: "cli",
254
- action: AuditActions.SCAN_COMPLETE,
255
- category: "scan",
256
- target: { type: "project", path: projectPath },
257
- result,
258
- metadata: { command: "scan", projectPath, ...metadata },
259
- });
260
- }
261
-
262
- function emitShipCheck(projectPath, result, metadata) {
263
- return emit({
264
- surface: "cli",
265
- action: AuditActions.SHIP_CHECK,
266
- category: "ship",
267
- target: { type: "project", path: projectPath },
268
- result,
269
- metadata: { command: "ship", projectPath, ...metadata },
270
- });
271
- }
272
-
273
- function emitRealityStart(url, flows) {
274
- return emit({
275
- surface: "cli",
276
- action: AuditActions.REALITY_START,
277
- category: "reality",
278
- target: { type: "url", path: url },
279
- result: "success",
280
- metadata: { command: "reality", url, flows },
281
- });
282
- }
283
-
284
- function emitRealityComplete(url, result, metadata) {
285
- return emit({
286
- surface: "cli",
287
- action: AuditActions.REALITY_COMPLETE,
288
- category: "reality",
289
- target: { type: "url", path: url },
290
- result,
291
- metadata: { command: "reality", ...metadata },
292
- });
293
- }
294
-
295
- function emitAutopilotAction(action, projectPath, result, metadata) {
296
- const actionMap = {
297
- enable: AuditActions.AUTOPILOT_ENABLE,
298
- disable: AuditActions.AUTOPILOT_DISABLE,
299
- run: AuditActions.AUTOPILOT_RUN,
300
- report: AuditActions.AUTOPILOT_REPORT,
301
- };
302
-
303
- return emit({
304
- surface: "cli",
305
- action: actionMap[action] || action,
306
- category: "autopilot",
307
- target: { type: "project", path: projectPath },
308
- result,
309
- metadata: { command: "autopilot", projectPath, ...metadata },
310
- });
311
- }
312
-
313
- function emitFixPlan(projectPath, result, metadata) {
314
- return emit({
315
- surface: "cli",
316
- action: AuditActions.FIX_PLAN,
317
- category: "fix",
318
- target: { type: "project", path: projectPath },
319
- result,
320
- metadata: { command: "fix", projectPath, ...metadata },
321
- });
322
- }
323
-
324
- function emitFixApply(projectPath, result, metadata) {
325
- return emit({
326
- surface: "cli",
327
- action: AuditActions.FIX_APPLY,
328
- category: "fix",
329
- target: { type: "project", path: projectPath },
330
- result,
331
- metadata: { command: "fix", projectPath, ...metadata },
332
- });
333
- }
334
-
335
- function emitGateCheck(projectPath, passed, metadata) {
336
- return emit({
337
- surface: "cli",
338
- action: passed ? AuditActions.GATE_PASS : AuditActions.GATE_FAIL,
339
- category: "gate",
340
- target: { type: "project", path: projectPath },
341
- result: passed ? "success" : "failure",
342
- metadata: { command: "gate", projectPath, ...metadata },
343
- });
344
- }
345
-
346
- function emitToolInvoke(surface, toolName, args, result, metadata) {
347
- return emit({
348
- surface,
349
- action: AuditActions.TOOL_INVOKE,
350
- category: "tool",
351
- target: { type: "tool", name: toolName },
352
- result,
353
- metadata: { command: toolName, args, ...metadata },
354
- });
355
- }
356
-
357
- function emitAuth(action, result, metadata) {
358
- const actionMap = {
359
- login: AuditActions.AUTH_LOGIN,
360
- logout: AuditActions.AUTH_LOGOUT,
361
- };
362
-
363
- return emit({
364
- surface: "cli",
365
- action: actionMap[action] || action,
366
- category: "auth",
367
- target: { type: "auth" },
368
- result,
369
- metadata,
370
- });
371
- }
372
-
373
- // Export the audit bridge
374
- module.exports = {
375
- emit,
376
- AuditActions,
377
- emitScanStart,
378
- emitScanComplete,
379
- emitShipCheck,
380
- emitRealityStart,
381
- emitRealityComplete,
382
- emitAutopilotAction,
383
- emitFixPlan,
384
- emitFixApply,
385
- emitGateCheck,
386
- emitToolInvoke,
387
- emitAuth,
388
- getCurrentTier,
389
- getCurrentActor,
390
- getAuditFilePath,
391
- };
@@ -1,193 +0,0 @@
1
- // bin/runners/lib/auth-truth.js
2
- // Auth Truth v1 - Detects auth/protection patterns in Next + Fastify codebases
3
- const fg = require("fast-glob");
4
- const fs = require("fs");
5
- const path = require("path");
6
- const crypto = require("crypto");
7
-
8
- function sha256(text) {
9
- return "sha256:" + crypto.createHash("sha256").update(text).digest("hex");
10
- }
11
-
12
- function safeRead(fileAbs) {
13
- return fs.readFileSync(fileAbs, "utf8");
14
- }
15
-
16
- function evidenceFromLine({ fileAbs, repoRoot, lineNo, reason }) {
17
- const fileRel = path.relative(repoRoot, fileAbs).replace(/\\/g, "/");
18
- const lines = safeRead(fileAbs).split(/\r?\n/);
19
- const idx = Math.max(0, Math.min(lines.length - 1, lineNo - 1));
20
- const snippet = lines[idx] || "";
21
- return {
22
- id: `ev_${crypto.randomBytes(4).toString("hex")}`,
23
- file: fileRel,
24
- lines: `${lineNo}-${lineNo}`,
25
- snippetHash: sha256(snippet),
26
- reason
27
- };
28
- }
29
-
30
- function findLineMatches(code, regex) {
31
- const out = [];
32
- const lines = code.split(/\r?\n/);
33
- for (let i = 0; i < lines.length; i++) {
34
- if (regex.test(lines[i])) out.push(i + 1);
35
- }
36
- return out;
37
- }
38
-
39
- function guessAuthSignalsFromCode(code) {
40
- const signals = [];
41
-
42
- const patterns = [
43
- { key: "next_middleware", rx: /\bNextResponse\.(redirect|rewrite)\b/ },
44
- { key: "next_auth", rx: /\bgetServerSession\b|\bNextAuth\b|\bauth\(\)\b/ },
45
- { key: "clerk", rx: /\bclerkMiddleware\b|\bauthMiddleware\b|@clerk\/nextjs/ },
46
- { key: "supabase", rx: /\bcreateRouteHandlerClient\b|\bcreateServerClient\b|@supabase/ },
47
- { key: "jwt_verify", rx: /\b(jwtVerify|verifyJWT|verifyToken|authorization|bearer)\b/i },
48
- { key: "session", rx: /\b(session|cookie|setCookie|getCookie)\b/i },
49
- { key: "rbac", rx: /\b(role|roles|permissions|rbac|isAdmin|adminOnly)\b/i },
50
- { key: "fastify_hook", rx: /\.addHook\(\s*['"](onRequest|preHandler|preValidation)['"]/ },
51
- { key: "fastify_jwt", rx: /@fastify\/jwt|fastify-jwt|fastify\.jwt/i },
52
- ];
53
-
54
- for (const p of patterns) {
55
- if (p.rx.test(code)) signals.push(p.key);
56
- }
57
- return Array.from(new Set(signals));
58
- }
59
-
60
- async function resolveNextMiddleware(repoRoot) {
61
- const candidates = await fg(
62
- ["middleware.@(ts|js)", "src/middleware.@(ts|js)"],
63
- { cwd: repoRoot, absolute: true, onlyFiles: true }
64
- );
65
-
66
- const middlewares = [];
67
-
68
- for (const fileAbs of candidates) {
69
- const code = safeRead(fileAbs);
70
- const fileRel = path.relative(repoRoot, fileAbs).replace(/\\/g, "/");
71
-
72
- const matcherLines = findLineMatches(code, /\bmatcher\b/);
73
- const redirectLines = findLineMatches(code, /\bNextResponse\.(redirect|rewrite)\b/);
74
-
75
- const evidence = [];
76
- for (const ln of matcherLines.slice(0, 5)) {
77
- evidence.push(evidenceFromLine({ fileAbs, repoRoot, lineNo: ln, reason: "Next middleware matcher config" }));
78
- }
79
- for (const ln of redirectLines.slice(0, 5)) {
80
- evidence.push(evidenceFromLine({ fileAbs, repoRoot, lineNo: ln, reason: "Next middleware redirect/rewrite" }));
81
- }
82
-
83
- const matcher = [];
84
- const matcherBlock = code.match(/matcher\s*:\s*(\[[\s\S]*?\])/);
85
- if (matcherBlock && matcherBlock[1]) {
86
- const raw = matcherBlock[1];
87
- const strings = Array.from(raw.matchAll(/['"`]([^'"`]+)['"`]/g)).map(m => m[1]);
88
- matcher.push(...strings);
89
- }
90
-
91
- middlewares.push({
92
- file: fileRel,
93
- matcher,
94
- signals: guessAuthSignalsFromCode(code),
95
- evidence
96
- });
97
- }
98
-
99
- return middlewares;
100
- }
101
-
102
- async function resolveFastifyAuthSignals(repoRoot, truthpackRoutes) {
103
- const handlerFiles = new Set((truthpackRoutes || []).map(r => r.handler).filter(Boolean));
104
- const signals = [];
105
- const evidence = [];
106
-
107
- for (const fileRel of handlerFiles) {
108
- const fileAbs = path.join(repoRoot, fileRel);
109
- if (!fs.existsSync(fileAbs)) continue;
110
-
111
- const code = safeRead(fileAbs);
112
- const sigs = guessAuthSignalsFromCode(code);
113
- if (!sigs.length) continue;
114
-
115
- for (const s of sigs) signals.push({ type: s, file: fileRel });
116
-
117
- const authLinePatterns = [
118
- { rx: /\.addHook\(\s*['"](onRequest|preHandler|preValidation)['"]/, reason: "Fastify hook likely used for auth" },
119
- { rx: /\b(jwtVerify|authorization|bearer)\b/i, reason: "JWT/Authorization verification signal" },
120
- { rx: /@fastify\/jwt|fastify\.jwt/i, reason: "Fastify JWT plugin signal" },
121
- { rx: /\b(isAdmin|adminOnly|permissions|rbac)\b/i, reason: "RBAC/permissions signal" },
122
- ];
123
-
124
- const lines = code.split(/\r?\n/);
125
- for (let i = 0; i < lines.length; i++) {
126
- const line = lines[i];
127
- for (const p of authLinePatterns) {
128
- if (p.rx.test(line)) {
129
- evidence.push({
130
- id: `ev_${crypto.randomBytes(4).toString("hex")}`,
131
- file: fileRel,
132
- lines: `${i + 1}-${i + 1}`,
133
- snippetHash: sha256(line),
134
- reason: p.reason
135
- });
136
- }
137
- }
138
- if (evidence.length > 30) break;
139
- }
140
- }
141
-
142
- const uniqueTypes = Array.from(new Set(signals.map(s => s.type)));
143
-
144
- return {
145
- signalTypes: uniqueTypes,
146
- signals,
147
- evidence
148
- };
149
- }
150
-
151
- function matcherCoversPath(matcherList, p) {
152
- if (!Array.isArray(matcherList) || !matcherList.length) return false;
153
- const pathStr = p.startsWith("/") ? p : `/${p}`;
154
-
155
- return matcherList.some(m => {
156
- if (!m) return false;
157
-
158
- if (m.includes(":path*")) {
159
- const prefix = m.split(":path*")[0].replace(/\/$/, "");
160
- return pathStr.startsWith(prefix || "/");
161
- }
162
- if (m.includes("(.*)")) {
163
- const prefix = m.split("(.*)")[0].replace(/\/$/, "");
164
- return pathStr.startsWith(prefix || "/");
165
- }
166
-
167
- if (m === pathStr) return true;
168
- if (pathStr.startsWith(m.endsWith("/") ? m : m + "/")) return true;
169
-
170
- return false;
171
- });
172
- }
173
-
174
- async function buildAuthTruth(repoRoot, routesServer) {
175
- const middlewares = await resolveNextMiddleware(repoRoot);
176
- const matchers = middlewares.flatMap(mw => mw.matcher || []);
177
- const fastify = await resolveFastifyAuthSignals(repoRoot, routesServer);
178
-
179
- return {
180
- nextMiddleware: middlewares,
181
- nextMatcherPatterns: matchers,
182
- fastify,
183
- helpers: {
184
- matcherCoversPath: "runtime-only"
185
- }
186
- };
187
- }
188
-
189
- module.exports = {
190
- buildAuthTruth,
191
- matcherCoversPath,
192
- guessAuthSignalsFromCode
193
- };