vibecheck-ai 1.2.2 → 1.2.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.
package/dist/index.js CHANGED
@@ -9,8 +9,9 @@ import * as os5 from 'os';
9
9
  import os5__default from 'os';
10
10
  import * as crypto52 from 'crypto';
11
11
  import crypto52__default, { createHash, randomUUID, createHmac } from 'crypto';
12
+ import { AsyncResource } from 'async_hooks';
12
13
  import { glob } from 'glob';
13
- import fg from 'fast-glob';
14
+ import fg2 from 'fast-glob';
14
15
  import * as fs15 from 'fs';
15
16
  import fs15__default, { existsSync, mkdirSync, promises, readFileSync, writeFileSync, readdirSync, statSync, realpathSync } from 'fs';
16
17
  import { exec, execSync, spawn, execFileSync } from 'child_process';
@@ -28,7 +29,7 @@ import { Command, InvalidArgumentError } from 'commander';
28
29
  import updateNotifier from 'update-notifier';
29
30
  import chalk9 from 'chalk';
30
31
  import gradient from 'gradient-string';
31
- import figlet from 'figlet';
32
+ import 'figlet';
32
33
  import ci from 'ci-info';
33
34
  import 'ink';
34
35
  import 'react/jsx-runtime';
@@ -82,7 +83,7 @@ function getErrorDefaults(code) {
82
83
  CONFIG_NOT_FOUND: {
83
84
  message: "Configuration file not found",
84
85
  suggestions: [
85
- "Run `vibecheck init` to create a configuration file",
86
+ "Run `vibecheck link` to create a configuration file",
86
87
  "Create a vibecheck.config.mjs file manually",
87
88
  "Specify a config path with --config <path>"
88
89
  ],
@@ -637,7 +638,7 @@ ${errors}`,
637
638
  suggestions: [
638
639
  "Check your configuration file for typos",
639
640
  "Refer to the documentation for valid options",
640
- "Use `vibecheck init --force` to regenerate a valid config"
641
+ "Use `vibecheck link --force` to regenerate a valid config"
641
642
  ]
642
643
  }
643
644
  );
@@ -1547,6 +1548,12 @@ var init_credentials = __esm({
1547
1548
  }
1548
1549
  });
1549
1550
 
1551
+ // ../../packages/shared-types/dist/chunk-X7ZL25I6.js
1552
+ var init_chunk_X7ZL25I6 = __esm({
1553
+ "../../packages/shared-types/dist/chunk-X7ZL25I6.js"() {
1554
+ }
1555
+ });
1556
+
1550
1557
  // ../../packages/shared-types/dist/index.js
1551
1558
  function tierMeetsRequirement(userTier, requiredTier) {
1552
1559
  const userIndex = TIER_ORDER.indexOf(userTier);
@@ -1692,6 +1699,7 @@ function createDriftEvent(type, severity, file2, operation, description, context
1692
1699
  var ENTITLEMENTS, FREE_ENTITLEMENTS, PRO_ENTITLEMENTS, FEATURE_KEYS, FEATURE_METADATA, PLAN_DEFINITIONS, TIER_ORDER, UPGRADE_URLS, VERDICT_THRESHOLDS, SEVERITY_PENALTIES, PERMISSIONS;
1693
1700
  var init_dist = __esm({
1694
1701
  "../../packages/shared-types/dist/index.js"() {
1702
+ init_chunk_X7ZL25I6();
1695
1703
  ENTITLEMENTS = {
1696
1704
  // === FREE Tier Entitlements ===
1697
1705
  SCAN_UNLIMITED: "scan_unlimited",
@@ -1711,6 +1719,8 @@ var init_dist = __esm({
1711
1719
  GITHUB_ACTION_WARN: "github_action_warn",
1712
1720
  FIREWALL_OBSERVE: "firewall_observe",
1713
1721
  FILE_LOCKING: "file_locking",
1722
+ AUTOFIX_LIMITED: "autofix_limited",
1723
+ // 3 fixes per month for free tier
1714
1724
  // === PRO Tier Entitlements ===
1715
1725
  REALITY_MODE: "reality_mode",
1716
1726
  CONTEXT_ENGINE: "context_engine",
@@ -1766,7 +1776,9 @@ var init_dist = __esm({
1766
1776
  ENTITLEMENTS.TRACE_ANALYSIS,
1767
1777
  ENTITLEMENTS.GITHUB_ACTION_WARN,
1768
1778
  ENTITLEMENTS.FIREWALL_OBSERVE,
1769
- ENTITLEMENTS.FILE_LOCKING
1779
+ ENTITLEMENTS.FILE_LOCKING,
1780
+ ENTITLEMENTS.AUTOFIX_LIMITED
1781
+ // 3 fixes per month
1770
1782
  ]);
1771
1783
  PRO_ENTITLEMENTS = /* @__PURE__ */ new Set([
1772
1784
  // Includes all FREE entitlements
@@ -1862,12 +1874,24 @@ var init_dist = __esm({
1862
1874
  ],
1863
1875
  docsUrl: "/docs/firewall"
1864
1876
  },
1877
+ [ENTITLEMENTS.AUTOFIX_LIMITED]: {
1878
+ entitlement: ENTITLEMENTS.AUTOFIX_LIMITED,
1879
+ title: "Auto-Fix (Limited)",
1880
+ description: "AI-powered code repair with 3 fixes per month on free tier.",
1881
+ benefits: [
1882
+ "3 AI-powered fixes per month",
1883
+ "One-click application",
1884
+ "Preview before applying",
1885
+ "Upgrade for unlimited"
1886
+ ],
1887
+ docsUrl: "/docs/autofix"
1888
+ },
1865
1889
  [ENTITLEMENTS.AUTOFIX_APPLY]: {
1866
1890
  entitlement: ENTITLEMENTS.AUTOFIX_APPLY,
1867
- title: "Auto-Fix Apply",
1868
- description: "AI-powered code repair with rollback support.",
1891
+ title: "Auto-Fix Unlimited",
1892
+ description: "AI-powered code repair with rollback support. 100 fixes per month.",
1869
1893
  benefits: [
1870
- "One-click fixes",
1894
+ "100 fixes per month",
1871
1895
  "Rollback support",
1872
1896
  "Fix verification",
1873
1897
  "Batch application"
@@ -2596,6 +2620,7 @@ var init_dist = __esm({
2596
2620
  features: [
2597
2621
  "Unlimited scans",
2598
2622
  "Unlimited ship decisions",
2623
+ "3 AI fixes per month",
2599
2624
  "Doctor (health checks)",
2600
2625
  "HTML reports",
2601
2626
  "Checkpoint create/restore",
@@ -3250,6 +3275,201 @@ var init_chunk_7A7U3ABV = __esm({
3250
3275
  };
3251
3276
  }
3252
3277
  });
3278
+
3279
+ // ../../packages/shared-utils/src/retry.ts
3280
+ var init_retry = __esm({
3281
+ "../../packages/shared-utils/src/retry.ts"() {
3282
+ }
3283
+ });
3284
+
3285
+ // ../../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
3286
+ var Node, Queue;
3287
+ var init_yocto_queue = __esm({
3288
+ "../../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js"() {
3289
+ Node = class {
3290
+ value;
3291
+ next;
3292
+ constructor(value) {
3293
+ this.value = value;
3294
+ }
3295
+ };
3296
+ Queue = class {
3297
+ #head;
3298
+ #tail;
3299
+ #size;
3300
+ constructor() {
3301
+ this.clear();
3302
+ }
3303
+ enqueue(value) {
3304
+ const node = new Node(value);
3305
+ if (this.#head) {
3306
+ this.#tail.next = node;
3307
+ this.#tail = node;
3308
+ } else {
3309
+ this.#head = node;
3310
+ this.#tail = node;
3311
+ }
3312
+ this.#size++;
3313
+ }
3314
+ dequeue() {
3315
+ const current = this.#head;
3316
+ if (!current) {
3317
+ return;
3318
+ }
3319
+ this.#head = this.#head.next;
3320
+ this.#size--;
3321
+ if (!this.#head) {
3322
+ this.#tail = void 0;
3323
+ }
3324
+ return current.value;
3325
+ }
3326
+ peek() {
3327
+ if (!this.#head) {
3328
+ return;
3329
+ }
3330
+ return this.#head.value;
3331
+ }
3332
+ clear() {
3333
+ this.#head = void 0;
3334
+ this.#tail = void 0;
3335
+ this.#size = 0;
3336
+ }
3337
+ get size() {
3338
+ return this.#size;
3339
+ }
3340
+ *[Symbol.iterator]() {
3341
+ let current = this.#head;
3342
+ while (current) {
3343
+ yield current.value;
3344
+ current = current.next;
3345
+ }
3346
+ }
3347
+ *drain() {
3348
+ while (this.#head) {
3349
+ yield this.dequeue();
3350
+ }
3351
+ }
3352
+ };
3353
+ }
3354
+ });
3355
+ function pLimit(concurrency) {
3356
+ if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
3357
+ throw new TypeError("Expected `concurrency` to be a number from 1 and up");
3358
+ }
3359
+ const queue = new Queue();
3360
+ let activeCount = 0;
3361
+ const next = () => {
3362
+ activeCount--;
3363
+ if (queue.size > 0) {
3364
+ queue.dequeue()();
3365
+ }
3366
+ };
3367
+ const run = async (function_, resolve6, arguments_) => {
3368
+ activeCount++;
3369
+ const result = (async () => function_(...arguments_))();
3370
+ resolve6(result);
3371
+ try {
3372
+ await result;
3373
+ } catch {
3374
+ }
3375
+ next();
3376
+ };
3377
+ const enqueue = (function_, resolve6, arguments_) => {
3378
+ queue.enqueue(
3379
+ AsyncResource.bind(run.bind(void 0, function_, resolve6, arguments_))
3380
+ );
3381
+ (async () => {
3382
+ await Promise.resolve();
3383
+ if (activeCount < concurrency && queue.size > 0) {
3384
+ queue.dequeue()();
3385
+ }
3386
+ })();
3387
+ };
3388
+ const generator = (function_, ...arguments_) => new Promise((resolve6) => {
3389
+ enqueue(function_, resolve6, arguments_);
3390
+ });
3391
+ Object.defineProperties(generator, {
3392
+ activeCount: {
3393
+ get: () => activeCount
3394
+ },
3395
+ pendingCount: {
3396
+ get: () => queue.size
3397
+ },
3398
+ clearQueue: {
3399
+ value() {
3400
+ queue.clear();
3401
+ }
3402
+ }
3403
+ });
3404
+ return generator;
3405
+ }
3406
+ var init_p_limit = __esm({
3407
+ "../../node_modules/.pnpm/p-limit@5.0.0/node_modules/p-limit/index.js"() {
3408
+ init_yocto_queue();
3409
+ }
3410
+ });
3411
+
3412
+ // ../../packages/shared-utils/src/concurrency.ts
3413
+ function getUploadLimiter(concurrency = UPLOAD_CONCURRENCY) {
3414
+ if (!uploadLimiter) {
3415
+ uploadLimiter = pLimit(concurrency);
3416
+ }
3417
+ return uploadLimiter;
3418
+ }
3419
+ function getApiCallLimiter(concurrency = API_CALL_CONCURRENCY) {
3420
+ if (!apiCallLimiter) {
3421
+ apiCallLimiter = pLimit(concurrency);
3422
+ }
3423
+ return apiCallLimiter;
3424
+ }
3425
+ async function withUploadLimit(fn) {
3426
+ return getUploadLimiter()(fn);
3427
+ }
3428
+ async function withApiCallLimit(fn) {
3429
+ return getApiCallLimiter()(fn);
3430
+ }
3431
+ var UPLOAD_CONCURRENCY, API_CALL_CONCURRENCY, uploadLimiter, apiCallLimiter;
3432
+ var init_concurrency = __esm({
3433
+ "../../packages/shared-utils/src/concurrency.ts"() {
3434
+ init_p_limit();
3435
+ UPLOAD_CONCURRENCY = 4;
3436
+ API_CALL_CONCURRENCY = 6;
3437
+ uploadLimiter = null;
3438
+ apiCallLimiter = null;
3439
+ }
3440
+ });
3441
+
3442
+ // ../../packages/shared-utils/src/index.ts
3443
+ async function fetchWithTimeout(input, init, timeoutMs = DEFAULT_FETCH_TIMEOUT_MS) {
3444
+ const controller = new AbortController();
3445
+ const teardown = () => controller.abort();
3446
+ const timeoutId = setTimeout(teardown, timeoutMs);
3447
+ if (init?.signal) {
3448
+ if (init.signal.aborted) {
3449
+ clearTimeout(timeoutId);
3450
+ throw new DOMException("Aborted", "AbortError");
3451
+ }
3452
+ init.signal.addEventListener("abort", teardown);
3453
+ }
3454
+ try {
3455
+ const response = await fetch(input, { ...init, signal: controller.signal });
3456
+ clearTimeout(timeoutId);
3457
+ if (init?.signal) init.signal.removeEventListener("abort", teardown);
3458
+ return response;
3459
+ } catch (err) {
3460
+ clearTimeout(timeoutId);
3461
+ if (init?.signal) init.signal.removeEventListener("abort", teardown);
3462
+ throw err;
3463
+ }
3464
+ }
3465
+ var DEFAULT_FETCH_TIMEOUT_MS;
3466
+ var init_src = __esm({
3467
+ "../../packages/shared-utils/src/index.ts"() {
3468
+ init_retry();
3469
+ init_concurrency();
3470
+ DEFAULT_FETCH_TIMEOUT_MS = 3e4;
3471
+ }
3472
+ });
3253
3473
  function getContentType(filePath) {
3254
3474
  const ext = path18.extname(filePath).toLowerCase();
3255
3475
  return CONTENT_TYPES[ext] || "application/octet-stream";
@@ -3272,8 +3492,9 @@ function createVideoStorageService(env2) {
3272
3492
  return new VideoStorageService(config);
3273
3493
  }
3274
3494
  var CONTENT_TYPES, S3StorageClient, LocalStorageClient, VideoStorageService;
3275
- var init_chunk_ALU7SPZV = __esm({
3276
- "../../packages/core/dist/chunk-ALU7SPZV.js"() {
3495
+ var init_chunk_2NLPIC5E = __esm({
3496
+ "../../packages/core/dist/chunk-2NLPIC5E.js"() {
3497
+ init_src();
3277
3498
  CONTENT_TYPES = {
3278
3499
  ".webm": "video/webm",
3279
3500
  ".mp4": "video/mp4",
@@ -3549,19 +3770,23 @@ var init_chunk_ALU7SPZV = __esm({
3549
3770
  }
3550
3771
  /**
3551
3772
  * Upload all reality check artifacts from a directory.
3773
+ * Uses concurrency limiting to avoid exhausting memory/connections.
3552
3774
  */
3553
3775
  async uploadRealityCheckArtifacts(artifactsDir, projectId, checkId) {
3554
3776
  const result = {
3555
3777
  videoUrl: "",
3556
3778
  screenshots: []
3557
3779
  };
3780
+ const uploadLimit = getUploadLimiter();
3558
3781
  const videosDir = path18.join(artifactsDir, "videos");
3559
3782
  try {
3560
3783
  const videoFiles = await fs102.readdir(videosDir);
3561
3784
  const videoFile = videoFiles.find((f) => f.endsWith(".webm") || f.endsWith(".mp4"));
3562
3785
  if (videoFile) {
3563
3786
  const videoPath = path18.join(videosDir, videoFile);
3564
- const uploadResult = await this.uploadVideo(videoPath, projectId, checkId);
3787
+ const uploadResult = await uploadLimit(
3788
+ () => this.uploadVideo(videoPath, projectId, checkId)
3789
+ );
3565
3790
  result.videoUrl = uploadResult.url;
3566
3791
  result.duration = await this.getVideoDuration(videoPath);
3567
3792
  }
@@ -3573,26 +3798,26 @@ var init_chunk_ALU7SPZV = __esm({
3573
3798
  const imageFiles = screenshotFiles.filter(
3574
3799
  (f) => f.endsWith(".png") || f.endsWith(".jpg") || f.endsWith(".jpeg")
3575
3800
  );
3576
- let index = 0;
3577
- for (const file2 of imageFiles.sort()) {
3801
+ const screenshotTasks = imageFiles.sort().map((file2, index) => {
3578
3802
  const screenshotPath = path18.join(screenshotsDir, file2);
3579
3803
  const timestampMatch = file2.match(/-(\d+)ms\./);
3580
3804
  const timestamp = timestampMatch ? parseInt(timestampMatch[1], 10) : index * 1e3;
3581
3805
  const routeMatch = file2.match(/^(.+?)-\d+ms\./);
3582
3806
  const route = routeMatch ? routeMatch[1].replace(/-/g, "/") : void 0;
3583
- const uploadResult = await this.uploadScreenshot(
3584
- screenshotPath,
3585
- projectId,
3586
- checkId,
3587
- index,
3588
- { timestamp, route }
3589
- );
3590
- result.screenshots.push({
3591
- url: uploadResult.url,
3592
- timestamp,
3593
- route
3807
+ return uploadLimit(async () => {
3808
+ const uploadResult = await this.uploadScreenshot(
3809
+ screenshotPath,
3810
+ projectId,
3811
+ checkId,
3812
+ index,
3813
+ { timestamp, route }
3814
+ );
3815
+ return { url: uploadResult.url, timestamp, route };
3594
3816
  });
3595
- index++;
3817
+ });
3818
+ const screenshotResults = await Promise.all(screenshotTasks);
3819
+ for (const s of screenshotResults) {
3820
+ result.screenshots.push(s);
3596
3821
  }
3597
3822
  } catch {
3598
3823
  }
@@ -5687,7 +5912,7 @@ async function discoverFiles(options) {
5687
5912
  };
5688
5913
  }
5689
5914
  }
5690
- const files = await fg(includePatterns, {
5915
+ const files = await fg2(includePatterns, {
5691
5916
  cwd: rootDir,
5692
5917
  absolute: true,
5693
5918
  ignore: excludePatterns,
@@ -12634,10 +12859,11 @@ function getISLTranslator(config) {
12634
12859
  function resetISLTranslator() {
12635
12860
  globalTranslator = null;
12636
12861
  }
12637
- var ISLTypeRef, ISLField, ISLExpression, ISLPostconditionBranch, ISLEntity, ISLBehavior, ISLDomain, TranslatorAssumption, TranslatorQuestion, ClauseConfidence, TranslatorOutput, TRANSLATOR_OUTPUT_SCHEMA, ISL_TRANSLATOR_SYSTEM_PROMPT, SPEC_TEMPLATES, DEFAULT_CONFIG4, ISLTranslator, globalTranslator;
12638
- var init_chunk_KZUPVFL2 = __esm({
12639
- "../../packages/core/dist/chunk-KZUPVFL2.js"() {
12862
+ var ISLTypeRef, ISLField, ISLExpression, ISLPostconditionBranch, ISLEntity, ISLBehavior, ISLDomain, TranslatorAssumption, TranslatorQuestion, ClauseConfidence, TranslatorOutput, TRANSLATOR_OUTPUT_SCHEMA, ISL_TRANSLATOR_SYSTEM_PROMPT, SPEC_TEMPLATES, LLM_REQUEST_TIMEOUT_MS, DEFAULT_CONFIG4, ISLTranslator, globalTranslator;
12863
+ var init_chunk_3M5P5OHI = __esm({
12864
+ "../../packages/core/dist/chunk-3M5P5OHI.js"() {
12640
12865
  init_chunk_CKFIPOYN();
12866
+ init_src();
12641
12867
  init_dist2();
12642
12868
  ISLTypeRef = z.object({
12643
12869
  kind: z.literal("TypeRef"),
@@ -13140,6 +13366,7 @@ Remember: Your job is to EXTRACT intent and structure it, not to generate code.
13140
13366
  }
13141
13367
  }
13142
13368
  };
13369
+ LLM_REQUEST_TIMEOUT_MS = 6e4;
13143
13370
  DEFAULT_CONFIG4 = {
13144
13371
  provider: "anthropic",
13145
13372
  model: "claude-sonnet-4-20250514",
@@ -13355,23 +13582,25 @@ Please fix these issues in your next output.`;
13355
13582
  if (!apiKey) {
13356
13583
  throw new Error("Anthropic API key not configured");
13357
13584
  }
13358
- const response = await fetch("https://api.anthropic.com/v1/messages", {
13359
- method: "POST",
13360
- headers: {
13361
- "Content-Type": "application/json",
13362
- "x-api-key": apiKey,
13363
- "anthropic-version": "2023-06-01"
13585
+ const response = await fetchWithTimeout(
13586
+ "https://api.anthropic.com/v1/messages",
13587
+ {
13588
+ method: "POST",
13589
+ headers: {
13590
+ "Content-Type": "application/json",
13591
+ "x-api-key": apiKey,
13592
+ "anthropic-version": "2023-06-01"
13593
+ },
13594
+ body: JSON.stringify({
13595
+ model: this.config.model,
13596
+ max_tokens: 4096,
13597
+ temperature: this.config.temperature,
13598
+ system: systemPrompt,
13599
+ messages: [{ role: "user", content: userPrompt }]
13600
+ })
13364
13601
  },
13365
- body: JSON.stringify({
13366
- model: this.config.model,
13367
- max_tokens: 4096,
13368
- temperature: this.config.temperature,
13369
- system: systemPrompt,
13370
- messages: [
13371
- { role: "user", content: userPrompt }
13372
- ]
13373
- })
13374
- });
13602
+ LLM_REQUEST_TIMEOUT_MS
13603
+ );
13375
13604
  if (!response.ok) {
13376
13605
  const error = await response.text();
13377
13606
  throw new Error(`Anthropic API error: ${error}`);
@@ -13391,22 +13620,26 @@ Please fix these issues in your next output.`;
13391
13620
  if (!apiKey) {
13392
13621
  throw new Error("OpenAI API key not configured");
13393
13622
  }
13394
- const response = await fetch("https://api.openai.com/v1/chat/completions", {
13395
- method: "POST",
13396
- headers: {
13397
- "Content-Type": "application/json",
13398
- "Authorization": `Bearer ${apiKey}`
13623
+ const response = await fetchWithTimeout(
13624
+ "https://api.openai.com/v1/chat/completions",
13625
+ {
13626
+ method: "POST",
13627
+ headers: {
13628
+ "Content-Type": "application/json",
13629
+ "Authorization": `Bearer ${apiKey}`
13630
+ },
13631
+ body: JSON.stringify({
13632
+ model: this.config.model,
13633
+ temperature: this.config.temperature,
13634
+ messages: [
13635
+ { role: "system", content: systemPrompt },
13636
+ { role: "user", content: userPrompt }
13637
+ ],
13638
+ response_format: { type: "json_object" }
13639
+ })
13399
13640
  },
13400
- body: JSON.stringify({
13401
- model: this.config.model,
13402
- temperature: this.config.temperature,
13403
- messages: [
13404
- { role: "system", content: systemPrompt },
13405
- { role: "user", content: userPrompt }
13406
- ],
13407
- response_format: { type: "json_object" }
13408
- })
13409
- });
13641
+ LLM_REQUEST_TIMEOUT_MS
13642
+ );
13410
13643
  if (!response.ok) {
13411
13644
  const error = await response.text();
13412
13645
  throw new Error(`OpenAI API error: ${error}`);
@@ -13423,20 +13656,22 @@ Please fix these issues in your next output.`;
13423
13656
  */
13424
13657
  async callLocal(systemPrompt, userPrompt) {
13425
13658
  const apiBase = this.config.apiBase || "http://localhost:11434";
13426
- const response = await fetch(`${apiBase}/api/generate`, {
13427
- method: "POST",
13428
- headers: {
13429
- "Content-Type": "application/json"
13430
- },
13431
- body: JSON.stringify({
13432
- model: this.config.model,
13433
- prompt: `${systemPrompt}
13659
+ const response = await fetchWithTimeout(
13660
+ `${apiBase}/api/generate`,
13661
+ {
13662
+ method: "POST",
13663
+ headers: { "Content-Type": "application/json" },
13664
+ body: JSON.stringify({
13665
+ model: this.config.model,
13666
+ prompt: `${systemPrompt}
13434
13667
 
13435
13668
  ${userPrompt}`,
13436
- stream: false,
13437
- format: "json"
13438
- })
13439
- });
13669
+ stream: false,
13670
+ format: "json"
13671
+ })
13672
+ },
13673
+ LLM_REQUEST_TIMEOUT_MS
13674
+ );
13440
13675
  if (!response.ok) {
13441
13676
  const error = await response.text();
13442
13677
  throw new Error(`Local API error: ${error}`);
@@ -40862,7 +41097,7 @@ function deepFreeze(obj) {
40862
41097
  }
40863
41098
  return obj;
40864
41099
  }
40865
- async function withRetry(fn, config = {}) {
41100
+ async function withRetry2(fn, config = {}) {
40866
41101
  const cfg = { ...DEFAULT_RETRY_CONFIG, ...config };
40867
41102
  let lastError = null;
40868
41103
  let delay = cfg.initialDelayMs;
@@ -41798,8 +42033,8 @@ async function isAllowed(projectRoot, type, value) {
41798
42033
  }
41799
42034
  }
41800
42035
  var DEFAULT_CONFIG10, DRIFT_WEIGHTS, ScopeCreepDetector, IntentValidator, DEFAULT_OPTIONS6, PARSER_OPTIONS, ClaimExtractor, DEFAULT_CONFIG25, BUILTIN_MODULES, EvidenceResolver, POLICY_LIMITS, VALID_SEVERITIES, PolicyEngine, UnblockPlanner, DEFAULT_CONFIG34, modeValidator, actionValidator, AgentFirewall, ContractGenerator, ContractVerifier, DEFAULT_WEIGHTS, TrustScorer, BEHAVIOR_TEMPLATES, ENTITY_TEMPLATES, ISLGenerator, globalGenerator, IntentStore, globalIntentStore, MissionService, globalMissionService, TIER_A_RULES, TIER_B_RULES, TIER_C_RULES, BaseRule, DEFAULT_CONFIG44, GhostRouteRule, DEFAULT_CONFIG54, GhostEnvRule, DEFAULT_CONFIG63, AuthDriftRule, DEFAULT_CONFIG72, ContractDriftRule, DEFAULT_CONFIG82, ScopeExplosionRule, DEFAULT_CONFIG92, UnsafeSideEffectRule, ObserveModeManager, DEFAULT_ALLOWLIST, ALLOWLIST_FILENAME, AllowlistManager;
41801
- var init_chunk_4MEEGNJS = __esm({
41802
- "../../packages/core/dist/chunk-4MEEGNJS.js"() {
42036
+ var init_chunk_QXRHICLP = __esm({
42037
+ "../../packages/core/dist/chunk-QXRHICLP.js"() {
41803
42038
  init_chunk_DFJL4MLU();
41804
42039
  init_chunk_SKXQ6JUA();
41805
42040
  init_chunk_4EQXFW4J();
@@ -43077,7 +43312,7 @@ var init_chunk_4MEEGNJS = __esm({
43077
43312
  async loadTruthpack(name) {
43078
43313
  const filePath = path18.join(this.config.projectRoot, this.config.truthpackPath, `${name}.json`);
43079
43314
  try {
43080
- return await withRetry(
43315
+ return await withRetry2(
43081
43316
  async () => {
43082
43317
  const content = await fs102.readFile(filePath, "utf-8");
43083
43318
  return JSON.parse(content);
@@ -44514,7 +44749,7 @@ var init_chunk_4MEEGNJS = __esm({
44514
44749
  if (this.auditBuffer.length === 0) return;
44515
44750
  const entries = this.auditBuffer.splice(0, this.auditBuffer.length);
44516
44751
  try {
44517
- await withRetry(
44752
+ await withRetry2(
44518
44753
  async () => {
44519
44754
  const logPath = path18.isAbsolute(this.config.auditLogPath) ? this.config.auditLogPath : path18.join(this.config.projectRoot, this.config.auditLogPath);
44520
44755
  await fs102.mkdir(path18.dirname(logPath), { recursive: true });
@@ -63200,7 +63435,7 @@ __export(dist_exports, {
63200
63435
  visualizePath: () => visualizePath,
63201
63436
  visualizeReport: () => visualizeReport,
63202
63437
  vulnToSarifResult: () => vulnToSarifResult,
63203
- withRetry: () => withRetry,
63438
+ withRetry: () => withRetry2,
63204
63439
  wrapError: () => wrapError2,
63205
63440
  writeCursorRules: () => writeCursorRules,
63206
63441
  writeHooks: () => writeHooks,
@@ -63752,8 +63987,8 @@ async function loadFiles(projectPath, patterns, excludePatterns, incremental, lo
63752
63987
  const files = /* @__PURE__ */ new Map();
63753
63988
  const oldHashes = incremental ? await loadHashCache(projectPath) : /* @__PURE__ */ new Map();
63754
63989
  const newHashes = /* @__PURE__ */ new Map();
63755
- const fg22 = await import('fast-glob');
63756
- const glob42 = fg22.default || fg22;
63990
+ const fg32 = await import('fast-glob');
63991
+ const glob42 = fg32.default || fg32;
63757
63992
  const filePaths = await glob42(patterns, {
63758
63993
  cwd: projectPath,
63759
63994
  absolute: true,
@@ -66857,6 +67092,68 @@ function shouldGenerateForPlatform(platform2, detection, forceAll = false) {
66857
67092
  }
66858
67093
  return detection.recommendedPlatforms.includes(platform2);
66859
67094
  }
67095
+ async function scanTruthpack(projectRoot, config) {
67096
+ const scanner = new TruthpackScanner(projectRoot, config);
67097
+ return scanner.scan();
67098
+ }
67099
+ async function saveTruthpack(projectRoot, data) {
67100
+ const truthpackDir = path18.join(projectRoot, TRUTHPACK_DIR);
67101
+ await fs102.mkdir(truthpackDir, { recursive: true });
67102
+ await Promise.all([
67103
+ fs102.writeFile(
67104
+ path18.join(truthpackDir, "routes.json"),
67105
+ JSON.stringify(
67106
+ {
67107
+ version: "1.0.0",
67108
+ generatedAt: data.meta.generatedAt,
67109
+ routes: data.routes
67110
+ },
67111
+ null,
67112
+ 2
67113
+ )
67114
+ ),
67115
+ fs102.writeFile(
67116
+ path18.join(truthpackDir, "env.json"),
67117
+ JSON.stringify(
67118
+ {
67119
+ version: "1.0.0",
67120
+ generatedAt: data.meta.generatedAt,
67121
+ variables: data.envVars
67122
+ },
67123
+ null,
67124
+ 2
67125
+ )
67126
+ ),
67127
+ fs102.writeFile(
67128
+ path18.join(truthpackDir, "auth.json"),
67129
+ JSON.stringify(
67130
+ {
67131
+ version: "1.0.0",
67132
+ generatedAt: data.meta.generatedAt,
67133
+ rules: data.authRules
67134
+ },
67135
+ null,
67136
+ 2
67137
+ )
67138
+ ),
67139
+ fs102.writeFile(
67140
+ path18.join(truthpackDir, "contracts.json"),
67141
+ JSON.stringify(
67142
+ {
67143
+ version: "1.0.0",
67144
+ generatedAt: data.meta.generatedAt,
67145
+ contracts: data.contracts
67146
+ },
67147
+ null,
67148
+ 2
67149
+ )
67150
+ ),
67151
+ fs102.writeFile(
67152
+ path18.join(truthpackDir, "meta.json"),
67153
+ JSON.stringify(data.meta, null, 2)
67154
+ )
67155
+ ]);
67156
+ }
66860
67157
  async function detectPhase(config, contextMemory) {
66861
67158
  const signals = [];
66862
67159
  const [
@@ -68771,18 +69068,29 @@ async function extractTruthpackContext(projectPath) {
68771
69068
  const envPath = path18.join(truthpackDir, "env.json");
68772
69069
  if (fs15.existsSync(envPath)) {
68773
69070
  const envData = JSON.parse(fs15.readFileSync(envPath, "utf-8"));
68774
- const variables = envData.variables || {};
68775
- context.envVars = Object.entries(variables).map(([name, info]) => ({
68776
- name,
68777
- required: info.required,
68778
- hasDefault: !!info.default
68779
- }));
69071
+ const variables = envData.variables;
69072
+ if (Array.isArray(variables)) {
69073
+ context.envVars = variables.map((v) => ({
69074
+ name: v.name,
69075
+ required: v.required,
69076
+ hasDefault: !!(v.hasDefault ?? v.defaultValue)
69077
+ }));
69078
+ } else if (variables && typeof variables === "object") {
69079
+ context.envVars = Object.entries(variables).map(([name, info]) => ({
69080
+ name,
69081
+ required: info.required,
69082
+ hasDefault: !!info.default
69083
+ }));
69084
+ }
68780
69085
  }
68781
69086
  const authPath = path18.join(truthpackDir, "auth.json");
68782
69087
  if (fs15.existsSync(authPath)) {
68783
69088
  const authData = JSON.parse(fs15.readFileSync(authPath, "utf-8"));
68784
69089
  context.authProviders = authData.providers || [];
68785
69090
  context.authMiddleware = authData.middleware || [];
69091
+ if (authData.rules?.length && !context.authMiddleware.length) {
69092
+ context.authMiddleware = authData.rules.map((r) => r.name);
69093
+ }
68786
69094
  }
68787
69095
  const contractsPath = path18.join(truthpackDir, "contracts.json");
68788
69096
  if (fs15.existsSync(contractsPath)) {
@@ -68801,6 +69109,21 @@ async function forge(projectPath, options = {}) {
68801
69109
  const config = { ...DEFAULT_FORGE_CONFIG, ...options };
68802
69110
  const startTime = Date.now();
68803
69111
  const absProjectPath = path18.resolve(projectPath);
69112
+ const truthpackDir = path18.join(absProjectPath, ".vibecheck", "truthpack");
69113
+ const hasTruthpack = fs15.existsSync(path18.join(truthpackDir, "routes.json"));
69114
+ if (!hasTruthpack || config.refreshTruthpack) {
69115
+ try {
69116
+ const data = await scanTruthpack(absProjectPath, DEFAULT_TRUTHPACK_SCANNER);
69117
+ await saveTruthpack(absProjectPath, data);
69118
+ if (config.verbose) {
69119
+ console.log(`\u{1F4CA} Truthpack refreshed: ${data.routes.length} routes, ${data.contracts.length} contracts`);
69120
+ }
69121
+ } catch (err) {
69122
+ if (config.verbose) {
69123
+ console.warn("\u26A0\uFE0F Truthpack refresh skipped:", err instanceof Error ? err.message : err);
69124
+ }
69125
+ }
69126
+ }
68804
69127
  let ideDetection = null;
68805
69128
  let effectivePlatforms = config.platforms;
68806
69129
  if (config.autoDetectIDE !== false) {
@@ -68992,6 +69315,7 @@ function parseArgs(args) {
68992
69315
  if (arg === "standard") opts.tier = "standard";
68993
69316
  if (arg === "extended") opts.tier = "extended";
68994
69317
  if (arg === "comprehensive") opts.tier = "comprehensive";
69318
+ if (arg === "--refresh-truthpack") opts.refreshTruthpack = true;
68995
69319
  }
68996
69320
  return opts;
68997
69321
  }
@@ -69022,6 +69346,7 @@ OPTIONS:
69022
69346
  --auto-detect Auto-detect IDE (default behavior)
69023
69347
  --no-auto-detect Disable IDE auto-detection
69024
69348
  --all-platforms Generate rules for ALL platforms (no auto-detect)
69349
+ --refresh-truthpack Rescan codebase and refresh .vibecheck/truthpack before generating
69025
69350
  --verbose, -v Show detailed output
69026
69351
  --help, -h Show this help
69027
69352
 
@@ -69437,11 +69762,11 @@ function findAllPaths(startId, endId, adjacency, nodes, edges, maxDepth) {
69437
69762
  { path: [startId], visited: /* @__PURE__ */ new Set([startId]) }
69438
69763
  ];
69439
69764
  while (queue.length > 0) {
69440
- const { path: path342, visited } = queue.shift();
69441
- const current = path342[path342.length - 1];
69442
- if (path342.length > maxDepth) continue;
69765
+ const { path: path352, visited } = queue.shift();
69766
+ const current = path352[path352.length - 1];
69767
+ if (path352.length > maxDepth) continue;
69443
69768
  if (current === endId) {
69444
- paths.push([...path342]);
69769
+ paths.push([...path352]);
69445
69770
  continue;
69446
69771
  }
69447
69772
  const neighbors = adjacency.get(current) || [];
@@ -69449,7 +69774,7 @@ function findAllPaths(startId, endId, adjacency, nodes, edges, maxDepth) {
69449
69774
  if (!visited.has(neighbor)) {
69450
69775
  const newVisited = new Set(visited);
69451
69776
  newVisited.add(neighbor);
69452
- queue.push({ path: [...path342, neighbor], visited: newVisited });
69777
+ queue.push({ path: [...path352, neighbor], visited: newVisited });
69453
69778
  }
69454
69779
  }
69455
69780
  }
@@ -69467,21 +69792,21 @@ function getPathEdges(nodeIds, allEdges) {
69467
69792
  }
69468
69793
  function detectFlowIssues(paths) {
69469
69794
  const issues = [];
69470
- for (const path342 of paths) {
69471
- if (!path342.hasValidation && path342.risk.level !== "low") {
69795
+ for (const path352 of paths) {
69796
+ if (!path352.hasValidation && path352.risk.level !== "low") {
69472
69797
  issues.push({
69473
69798
  id: generateId2(),
69474
- severity: path342.risk.level === "critical" ? "critical" : path342.risk.level === "high" ? "error" : "warning",
69799
+ severity: path352.risk.level === "critical" ? "critical" : path352.risk.level === "high" ? "error" : "warning",
69475
69800
  type: "missing_validation",
69476
- title: `Unvalidated data flow to ${path342.sink.sinkCategory}`,
69477
- description: `Data from ${path342.source.sourceCategory} flows to ${path342.sink.sinkCategory} without validation.`,
69478
- path: path342,
69479
- suggestion: getSuggestionForSink(path342.sink.sinkCategory),
69801
+ title: `Unvalidated data flow to ${path352.sink.sinkCategory}`,
69802
+ description: `Data from ${path352.source.sourceCategory} flows to ${path352.sink.sinkCategory} without validation.`,
69803
+ path: path352,
69804
+ suggestion: getSuggestionForSink(path352.sink.sinkCategory),
69480
69805
  docLink: getDocLinkForIssue("missing_validation")
69481
69806
  });
69482
69807
  }
69483
- if (path342.sink.riskLevel === "critical") {
69484
- const hasProperSanitization = path342.validations.some(
69808
+ if (path352.sink.riskLevel === "critical") {
69809
+ const hasProperSanitization = path352.validations.some(
69485
69810
  (v) => v.metadata?.patternName === "sanitization" || v.metadata?.patternName === "parameterized_query"
69486
69811
  );
69487
69812
  if (!hasProperSanitization) {
@@ -69489,22 +69814,22 @@ function detectFlowIssues(paths) {
69489
69814
  id: generateId2(),
69490
69815
  severity: "critical",
69491
69816
  type: "unsafe_sink",
69492
- title: `Potentially unsafe ${path342.sink.sinkCategory}`,
69493
- description: `Data flows to a critical sink (${path342.sink.label}) without proper sanitization.`,
69494
- path: path342,
69495
- suggestion: getSuggestionForSink(path342.sink.sinkCategory),
69817
+ title: `Potentially unsafe ${path352.sink.sinkCategory}`,
69818
+ description: `Data flows to a critical sink (${path352.sink.label}) without proper sanitization.`,
69819
+ path: path352,
69820
+ suggestion: getSuggestionForSink(path352.sink.sinkCategory),
69496
69821
  docLink: getDocLinkForIssue("unsafe_sink")
69497
69822
  });
69498
69823
  }
69499
69824
  }
69500
- if (path342.source.sourceCategory === "user_input" && ["sql_query", "shell_exec", "eval", "html_render"].includes(path342.sink.sinkCategory || "")) {
69825
+ if (path352.source.sourceCategory === "user_input" && ["sql_query", "shell_exec", "eval", "html_render"].includes(path352.sink.sinkCategory || "")) {
69501
69826
  issues.push({
69502
69827
  id: generateId2(),
69503
69828
  severity: "critical",
69504
69829
  type: "untrusted_source",
69505
69830
  title: "User input flows to sensitive operation",
69506
- description: `User input from ${path342.source.label} flows directly to ${path342.sink.label}.`,
69507
- path: path342,
69831
+ description: `User input from ${path352.source.label} flows directly to ${path352.sink.label}.`,
69832
+ path: path352,
69508
69833
  suggestion: "Always validate and sanitize user input before using it in sensitive operations.",
69509
69834
  docLink: getDocLinkForIssue("untrusted_source")
69510
69835
  });
@@ -69999,17 +70324,17 @@ async function recordTelemetryEvent(projectRoot, event, context) {
69999
70324
  await service.load();
70000
70325
  await service.recordEvent(event, context);
70001
70326
  }
70002
- var DEFAULT_CONFIG15, PostSaveHook, execAsync2, DEFAULT_CONFIG210, PreCommitHook, DEFAULT_CONFIG38, BUILTINS, DependencyCheckHook, DEFAULT_CONFIG48, hookTypeValidator, HooksManager, DEFAULT_CONFIG58, AUDIT_TYPES, typeValidator, resultValidator, AuditLogger, DEFAULT_CONFIG66, HallucinationAnalytics, DEFAULT_CONFIG75, EvidencePackGenerator, HybridModeService, DEFAULT_PREDICTIVE_CONFIG, DEFAULT_INTELLIGENCE_CONFIG, DEFAULT_CONFIG84, ProjectLearner, globalLearner, DEFAULT_CONFIG93, FILE_TYPE_PATTERNS, PURPOSE_PATTERNS, SENSITIVITY_INDICATORS, SemanticContextAnalyzer, globalAnalyzer, DEFAULT_CONFIG102, PredictiveEngine, globalEngine2, DEFAULT_CONFIG112, IntelligenceEngine, globalEngine22, DEFAULT_INCREMENTAL_CONFIG, DEFAULT_WORKER_POOL_CONFIG, DEFAULT_STREAM_CONFIG, DEFAULT_MULTI_CACHE_CONFIG, DEFAULT_CONFIG122, IncrementalEngine, globalEngine3, DEFAULT_CONFIG132, WorkerPool, DEFAULT_CONFIG142, ProgressTracker, gzipAsync2, gunzipAsync2, DEFAULT_CONFIG152, MultiLevelCache, globalCache, DEFAULT_CONFIG16, PerformanceScanner, globalScanner2, DEFAULT_OPTIONS7, HallucinationEngine, globalEngine4, EXTRACTION_PATTERNS, PROMPT_PATTERNS, ClaimExtractor2, globalExtractor2, DEFAULT_CONFIG17, RealtimeAnalyzer, globalAnalyzer2, DEFAULT_OPTIONS23, HASH_CACHE_PATH, FILE_CONTENT_CACHE, DEFAULT_LEARNING_CONFIG, LearningStorage, ConfidenceCalibrator2, IssueTracker, LearningSystem, globalLearningSystem, DEFAULT_WORKER_CONFIG, WorkerPool2, globalPool, DEFAULT_OPTIONS33, ResultStream, GitChangeDetector, ParallelAnalyzer, DEFAULT_POLICY_OPTIONS, severitySchema, metavariableComparisonSchema, pathFilterSchema, autofixSchema, ruleMetadataSchema, policyRuleSchema, policyConfigSchema, EXAMPLE_POLICY, policyCache, PolicyParser, PolicyResolver, PolicyEngine2, globalEngine5, DEFAULT_PERMISSIONS, DEFAULT_OPTIONS42, PluginLoader, DEFAULT_SANDBOX_OPTIONS, SandboxedRuleContext, PluginSandbox, FROZEN_GLOBALS, BLOCKED_GLOBALS, PluginManager, globalManager, TIER_CONFIGS, DEFAULT_FORGE_CONFIG, PHASE_RULE_CONFIGS, CATEGORY_IMPACT_WEIGHTS, VIBECHECK_ATTRIBUTION, VIBECHECK_ATTRIBUTION2, VIBECHECK_ATTRIBUTION_SKILL, SIGNAL_WEIGHTS, IGNORED_DIRS, SOURCE_EXTENSIONS, TEST_PATTERNS2, CONTEXT_FILE, VIBECHECK_DIR, MEMORY_VERSION, MAX_HISTORY_ENTRIES, MAX_BEHAVIOR_SIGNALS, VELOCITY_WINDOW_DAYS, ContextMemory, DEFAULT_DEBOUNCE_MS, DEFAULT_BATCH_THRESHOLD, BATCH_WINDOW_MS, COMMIT_SETTLE_MS, DEFAULT_WATCH_PATTERNS, DEFAULT_IGNORE_PATTERNS, STRUCTURAL_PATTERNS, CONFIG_PATTERNS2, DEPENDENCY_PATTERNS, ForgeWatcher, ChangeAccumulator, DEFAULT_WINDOW_MS, DEFAULT_THRESHOLD, CLEANUP_INTERVAL_MS, BatchDetector, SCAFFOLD_PATTERNS, PHASE_CONFIGS, CHANGE_TO_RULE_MAP, RuleOrchestrator, MEMORY_VERSION2, MEMORY_FILE, VIBECHECK_DIR2, MAX_TIMELINE_EVENTS, MAX_CONVERSATIONS, MAX_CODE_CHANGES2, MAX_INSIGHTS, MAX_SESSIONS, EnhancedMemorySystem, SUPPORTED_EXTENSIONS, PATTERNS22, analysisCache, IGNORED_DIRS2, SOURCE_EXTENSIONS2, COMPLEXITY_THRESHOLDS, MIN_FREQUENCY_THRESHOLD, MIN_EXAMPLES, IGNORED_DIRS3, SOURCE_EXTENSIONS3, generateId, DEFAULT_SOURCE_PATTERNS, DEFAULT_SINK_PATTERNS, DEFAULT_VALIDATION_PATTERNS, generateId2, FlowTracingEngine, COLORS, BOX, DEFAULT_SAFE_MODE_CONFIG, AGGRESSIVE_MODE_CONFIG, SafeModeManager, SAFE_PATTERNS, MEDIUM_PATTERNS, HIGH_PATTERNS, DESTRUCTIVE_PATTERNS, ActionClassifier, ChaosSessionRecorder, DEFAULT_REPLAY_OPTIONS, TELEMETRY_FILENAME, FIRST_SESSION_DURATION_MS, TelemetryService;
70327
+ var DEFAULT_CONFIG15, PostSaveHook, execAsync2, DEFAULT_CONFIG210, PreCommitHook, DEFAULT_CONFIG38, BUILTINS, DependencyCheckHook, DEFAULT_CONFIG48, hookTypeValidator, HooksManager, DEFAULT_CONFIG58, AUDIT_TYPES, typeValidator, resultValidator, AuditLogger, DEFAULT_CONFIG66, HallucinationAnalytics, DEFAULT_CONFIG75, EvidencePackGenerator, HybridModeService, DEFAULT_PREDICTIVE_CONFIG, DEFAULT_INTELLIGENCE_CONFIG, DEFAULT_CONFIG84, ProjectLearner, globalLearner, DEFAULT_CONFIG93, FILE_TYPE_PATTERNS, PURPOSE_PATTERNS, SENSITIVITY_INDICATORS, SemanticContextAnalyzer, globalAnalyzer, DEFAULT_CONFIG102, PredictiveEngine, globalEngine2, DEFAULT_CONFIG112, IntelligenceEngine, globalEngine22, DEFAULT_INCREMENTAL_CONFIG, DEFAULT_WORKER_POOL_CONFIG, DEFAULT_STREAM_CONFIG, DEFAULT_MULTI_CACHE_CONFIG, DEFAULT_CONFIG122, IncrementalEngine, globalEngine3, DEFAULT_CONFIG132, WorkerPool, DEFAULT_CONFIG142, ProgressTracker, gzipAsync2, gunzipAsync2, DEFAULT_CONFIG152, MultiLevelCache, globalCache, DEFAULT_CONFIG16, PerformanceScanner, globalScanner2, DEFAULT_OPTIONS7, HallucinationEngine, globalEngine4, EXTRACTION_PATTERNS, PROMPT_PATTERNS, ClaimExtractor2, globalExtractor2, DEFAULT_CONFIG17, RealtimeAnalyzer, globalAnalyzer2, DEFAULT_OPTIONS23, HASH_CACHE_PATH, FILE_CONTENT_CACHE, DEFAULT_LEARNING_CONFIG, LearningStorage, ConfidenceCalibrator2, IssueTracker, LearningSystem, globalLearningSystem, DEFAULT_WORKER_CONFIG, WorkerPool2, globalPool, DEFAULT_OPTIONS33, ResultStream, GitChangeDetector, ParallelAnalyzer, DEFAULT_POLICY_OPTIONS, severitySchema, metavariableComparisonSchema, pathFilterSchema, autofixSchema, ruleMetadataSchema, policyRuleSchema, policyConfigSchema, EXAMPLE_POLICY, policyCache, PolicyParser, PolicyResolver, PolicyEngine2, globalEngine5, DEFAULT_PERMISSIONS, DEFAULT_OPTIONS42, PluginLoader, DEFAULT_SANDBOX_OPTIONS, SandboxedRuleContext, PluginSandbox, FROZEN_GLOBALS, BLOCKED_GLOBALS, PluginManager, globalManager, TIER_CONFIGS, DEFAULT_FORGE_CONFIG, PHASE_RULE_CONFIGS, CATEGORY_IMPACT_WEIGHTS, VIBECHECK_ATTRIBUTION, VIBECHECK_ATTRIBUTION2, VIBECHECK_ATTRIBUTION_SKILL, TRUTHPACK_DIR, TruthpackScanner, SIGNAL_WEIGHTS, IGNORED_DIRS, SOURCE_EXTENSIONS, TEST_PATTERNS2, CONTEXT_FILE, VIBECHECK_DIR, MEMORY_VERSION, MAX_HISTORY_ENTRIES, MAX_BEHAVIOR_SIGNALS, VELOCITY_WINDOW_DAYS, ContextMemory, DEFAULT_DEBOUNCE_MS, DEFAULT_BATCH_THRESHOLD, BATCH_WINDOW_MS, COMMIT_SETTLE_MS, DEFAULT_WATCH_PATTERNS, DEFAULT_IGNORE_PATTERNS, STRUCTURAL_PATTERNS, CONFIG_PATTERNS2, DEPENDENCY_PATTERNS, ForgeWatcher, ChangeAccumulator, DEFAULT_WINDOW_MS, DEFAULT_THRESHOLD, CLEANUP_INTERVAL_MS, BatchDetector, SCAFFOLD_PATTERNS, PHASE_CONFIGS, CHANGE_TO_RULE_MAP, RuleOrchestrator, MEMORY_VERSION2, MEMORY_FILE, VIBECHECK_DIR2, MAX_TIMELINE_EVENTS, MAX_CONVERSATIONS, MAX_CODE_CHANGES2, MAX_INSIGHTS, MAX_SESSIONS, EnhancedMemorySystem, SUPPORTED_EXTENSIONS, PATTERNS22, analysisCache, IGNORED_DIRS2, SOURCE_EXTENSIONS2, COMPLEXITY_THRESHOLDS, MIN_FREQUENCY_THRESHOLD, MIN_EXAMPLES, IGNORED_DIRS3, SOURCE_EXTENSIONS3, DEFAULT_TRUTHPACK_SCANNER, generateId, DEFAULT_SOURCE_PATTERNS, DEFAULT_SINK_PATTERNS, DEFAULT_VALIDATION_PATTERNS, generateId2, FlowTracingEngine, COLORS, BOX, DEFAULT_SAFE_MODE_CONFIG, AGGRESSIVE_MODE_CONFIG, SafeModeManager, SAFE_PATTERNS, MEDIUM_PATTERNS, HIGH_PATTERNS, DESTRUCTIVE_PATTERNS, ActionClassifier, ChaosSessionRecorder, DEFAULT_REPLAY_OPTIONS, TELEMETRY_FILENAME, FIRST_SESSION_DURATION_MS, TelemetryService;
70003
70328
  var init_dist3 = __esm({
70004
70329
  "../../packages/core/dist/index.js"() {
70005
70330
  init_chunk_77VSC4EV();
70006
70331
  init_chunk_7A7U3ABV();
70007
- init_chunk_ALU7SPZV();
70332
+ init_chunk_2NLPIC5E();
70008
70333
  init_chunk_VHEV5Y4C();
70009
70334
  init_chunk_3AO6JE6F();
70010
70335
  init_chunk_KCKIH3Q3();
70011
70336
  init_chunk_KCKIH3Q3();
70012
- init_chunk_KZUPVFL2();
70337
+ init_chunk_3M5P5OHI();
70013
70338
  init_chunk_J2QKZNYI();
70014
70339
  init_chunk_CKFIPOYN();
70015
70340
  init_chunk_BCWLBWUJ();
@@ -70030,8 +70355,8 @@ var init_dist3 = __esm({
70030
70355
  init_chunk_ENJMGXRB();
70031
70356
  init_chunk_VB6M3WM5();
70032
70357
  init_chunk_VB6M3WM5();
70033
- init_chunk_4MEEGNJS();
70034
- init_chunk_4MEEGNJS();
70358
+ init_chunk_QXRHICLP();
70359
+ init_chunk_QXRHICLP();
70035
70360
  init_chunk_DFJL4MLU();
70036
70361
  init_chunk_WS67ECG2();
70037
70362
  init_chunk_WS67ECG2();
@@ -70975,7 +71300,7 @@ ${errors} error(s), ${warnings} warning(s), ${infos} info`;
70975
71300
  this.logger.debug(`Running ${hookType} hook`);
70976
71301
  try {
70977
71302
  const result = await circuitBreaker.execute(async () => {
70978
- return withRetry(
71303
+ return withRetry2(
70979
71304
  async () => {
70980
71305
  return withTimeout2(
70981
71306
  fn,
@@ -71476,7 +71801,7 @@ ${issues.map((i) => ` - ${i}`).join("\n")}`;
71476
71801
  async doFlush(entries) {
71477
71802
  const logDir = path18.join(this.projectRoot, this.config.logDirectory);
71478
71803
  try {
71479
- await withRetry(
71804
+ await withRetry2(
71480
71805
  async () => {
71481
71806
  await fs102.mkdir(logDir, { recursive: true });
71482
71807
  if (!this.currentLogFile || await this.shouldRotate()) {
@@ -76101,8 +76426,8 @@ ${content}`;
76101
76426
  const findings = [];
76102
76427
  const absolutePath = path18.join(this.options.projectRoot, filePath);
76103
76428
  try {
76104
- const fs30 = await import('fs/promises');
76105
- const content = await fs30.readFile(absolutePath, "utf-8");
76429
+ const fs31 = await import('fs/promises');
76430
+ const content = await fs31.readFile(absolutePath, "utf-8");
76106
76431
  if (this.codeValidator) {
76107
76432
  const result = await this.codeValidator.validate(content, filePath);
76108
76433
  for (const error of result.errors) {
@@ -76216,34 +76541,34 @@ ${content}`;
76216
76541
  }
76217
76542
  async validateTruthpack() {
76218
76543
  const truthpackDir = path18.join(this.options.projectRoot, ".vibecheck/truthpack");
76219
- const fs30 = await import('fs/promises');
76544
+ const fs31 = await import('fs/promises');
76220
76545
  const validation = {};
76221
76546
  try {
76222
76547
  try {
76223
- const routesContent = await fs30.readFile(path18.join(truthpackDir, "routes.json"), "utf-8");
76548
+ const routesContent = await fs31.readFile(path18.join(truthpackDir, "routes.json"), "utf-8");
76224
76549
  validation.routes = TruthpackValidators.validateRoutes(JSON.parse(routesContent));
76225
76550
  } catch {
76226
76551
  }
76227
76552
  try {
76228
- const envContent = await fs30.readFile(path18.join(truthpackDir, "env.json"), "utf-8");
76553
+ const envContent = await fs31.readFile(path18.join(truthpackDir, "env.json"), "utf-8");
76229
76554
  validation.env = TruthpackValidators.validateEnv(JSON.parse(envContent));
76230
76555
  } catch {
76231
76556
  }
76232
76557
  try {
76233
- const authContent = await fs30.readFile(path18.join(truthpackDir, "auth.json"), "utf-8");
76558
+ const authContent = await fs31.readFile(path18.join(truthpackDir, "auth.json"), "utf-8");
76234
76559
  validation.auth = TruthpackValidators.validateAuth(JSON.parse(authContent));
76235
76560
  } catch {
76236
76561
  }
76237
76562
  try {
76238
- const contractsContent = await fs30.readFile(path18.join(truthpackDir, "contracts.json"), "utf-8");
76563
+ const contractsContent = await fs31.readFile(path18.join(truthpackDir, "contracts.json"), "utf-8");
76239
76564
  validation.contracts = TruthpackValidators.validateContracts(JSON.parse(contractsContent));
76240
76565
  } catch {
76241
76566
  }
76242
76567
  if (validation.routes || validation.auth || validation.contracts) {
76243
76568
  validation.crossValidation = TruthpackValidators.crossValidate({
76244
- routes: validation.routes ? JSON.parse(await fs30.readFile(path18.join(truthpackDir, "routes.json"), "utf-8").catch(() => "{}")) : void 0,
76245
- auth: validation.auth ? JSON.parse(await fs30.readFile(path18.join(truthpackDir, "auth.json"), "utf-8").catch(() => "{}")) : void 0,
76246
- contracts: validation.contracts ? JSON.parse(await fs30.readFile(path18.join(truthpackDir, "contracts.json"), "utf-8").catch(() => "{}")) : void 0
76569
+ routes: validation.routes ? JSON.parse(await fs31.readFile(path18.join(truthpackDir, "routes.json"), "utf-8").catch(() => "{}")) : void 0,
76570
+ auth: validation.auth ? JSON.parse(await fs31.readFile(path18.join(truthpackDir, "auth.json"), "utf-8").catch(() => "{}")) : void 0,
76571
+ contracts: validation.contracts ? JSON.parse(await fs31.readFile(path18.join(truthpackDir, "contracts.json"), "utf-8").catch(() => "{}")) : void 0
76247
76572
  });
76248
76573
  }
76249
76574
  } catch (error) {
@@ -78855,8 +79180,8 @@ ${content}`;
78855
79180
  await this.pool.destroy();
78856
79181
  }
78857
79182
  async readFile(filePath) {
78858
- const fs30 = await import('fs/promises');
78859
- return fs30.readFile(filePath, "utf-8");
79183
+ const fs31 = await import('fs/promises');
79184
+ return fs31.readFile(filePath, "utf-8");
78860
79185
  }
78861
79186
  };
78862
79187
  DEFAULT_POLICY_OPTIONS = {
@@ -80428,6 +80753,314 @@ ${content}`;
80428
80753
  ---
80429
80754
  <!-- vibecheck:attribution -->
80430
80755
  *Verified by VibeCheck \u2713*`;
80756
+ TRUTHPACK_DIR = ".vibecheck/truthpack";
80757
+ TruthpackScanner = class {
80758
+ projectRoot;
80759
+ config;
80760
+ constructor(projectRoot, config) {
80761
+ this.projectRoot = projectRoot;
80762
+ this.config = config;
80763
+ }
80764
+ async scan() {
80765
+ const [routes, envVars, authRules, contracts] = await Promise.all([
80766
+ this.config.routes.enabled ? this.scanRoutes() : Promise.resolve([]),
80767
+ this.config.env.enabled ? this.scanEnvVars() : Promise.resolve([]),
80768
+ this.config.auth.enabled ? this.scanAuth() : Promise.resolve([]),
80769
+ this.config.contracts.enabled ? this.scanContracts() : Promise.resolve([])
80770
+ ]);
80771
+ const meta = {
80772
+ version: "1.0.0",
80773
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
80774
+ hash: await this.computeHash({ routes, envVars, authRules, contracts }),
80775
+ scannerVersions: {
80776
+ routes: "1.0.0",
80777
+ env: "1.0.0",
80778
+ auth: "1.0.0",
80779
+ contracts: "1.0.0"
80780
+ },
80781
+ summary: {
80782
+ routes: routes.length,
80783
+ envVars: envVars.length,
80784
+ authRules: authRules.length,
80785
+ contracts: contracts.length
80786
+ }
80787
+ };
80788
+ return { routes, envVars, authRules, contracts, meta };
80789
+ }
80790
+ async scanRoutes() {
80791
+ const routes = [];
80792
+ const files = await fg2(this.config.routes.patterns, {
80793
+ cwd: this.projectRoot,
80794
+ ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
80795
+ absolute: true
80796
+ });
80797
+ for (const file2 of files) {
80798
+ const content = await fs102.readFile(file2, "utf-8");
80799
+ const fileRoutes = this.extractRoutes(content, file2);
80800
+ routes.push(...fileRoutes);
80801
+ }
80802
+ return routes;
80803
+ }
80804
+ extractRoutes(content, file2) {
80805
+ const routes = [];
80806
+ const relativePath = path18.relative(this.projectRoot, file2);
80807
+ const expressPattern = /\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/gi;
80808
+ let match;
80809
+ while ((match = expressPattern.exec(content)) !== null) {
80810
+ const method = match[1].toUpperCase();
80811
+ const routePath = match[2];
80812
+ const line = content.substring(0, match.index).split("\n").length;
80813
+ routes.push({
80814
+ path: routePath,
80815
+ method,
80816
+ handler: this.extractHandler(content, match.index),
80817
+ file: relativePath,
80818
+ line,
80819
+ parameters: this.extractRouteParams(routePath),
80820
+ middleware: this.extractMiddleware(content, match.index),
80821
+ auth: this.detectAuthRequirement(content, match.index)
80822
+ });
80823
+ }
80824
+ const routerPattern = /router\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/gi;
80825
+ while ((match = routerPattern.exec(content)) !== null) {
80826
+ const method = match[1].toUpperCase();
80827
+ const routePath = match[2];
80828
+ const line = content.substring(0, match.index).split("\n").length;
80829
+ routes.push({
80830
+ path: routePath,
80831
+ method,
80832
+ handler: this.extractHandler(content, match.index),
80833
+ file: relativePath,
80834
+ line,
80835
+ parameters: this.extractRouteParams(routePath),
80836
+ middleware: this.extractMiddleware(content, match.index),
80837
+ auth: this.detectAuthRequirement(content, match.index)
80838
+ });
80839
+ }
80840
+ if (file2.includes("/api/") || file2.includes("\\api\\")) {
80841
+ const nextPattern = /export\s+(default\s+)?(async\s+)?function\s+(\w+)/i;
80842
+ const nextMatch = content.match(nextPattern);
80843
+ if (nextMatch) {
80844
+ const apiPath = this.filePathToApiRoute(file2);
80845
+ routes.push({
80846
+ path: apiPath,
80847
+ method: "GET",
80848
+ handler: nextMatch[3] || "handler",
80849
+ file: relativePath,
80850
+ line: 1,
80851
+ parameters: this.extractRouteParams(apiPath),
80852
+ middleware: []
80853
+ });
80854
+ }
80855
+ }
80856
+ return routes;
80857
+ }
80858
+ extractHandler(content, index) {
80859
+ const afterRoute = content.substring(index, index + 200);
80860
+ const handlerMatch = afterRoute.match(/,\s*(\w+)/);
80861
+ return handlerMatch?.[1] ?? "anonymous";
80862
+ }
80863
+ extractRouteParams(routePath) {
80864
+ const params = [];
80865
+ const paramPattern = /:(\w+)/g;
80866
+ let match;
80867
+ while ((match = paramPattern.exec(routePath)) !== null) {
80868
+ params.push({
80869
+ name: match[1],
80870
+ type: "string",
80871
+ required: true,
80872
+ in: "path"
80873
+ });
80874
+ }
80875
+ return params;
80876
+ }
80877
+ extractMiddleware(content, index) {
80878
+ const middleware = [];
80879
+ const beforeRoute = content.substring(Math.max(0, index - 500), index);
80880
+ const authMiddleware = ["authenticate", "auth", "requireAuth", "isAuthenticated", "protect"];
80881
+ const validationMiddleware = ["validate", "validateBody", "validateParams"];
80882
+ for (const mw of [...authMiddleware, ...validationMiddleware]) {
80883
+ if (beforeRoute.includes(mw)) middleware.push(mw);
80884
+ }
80885
+ return middleware;
80886
+ }
80887
+ detectAuthRequirement(content, index) {
80888
+ const context = content.substring(Math.max(0, index - 200), index + 200);
80889
+ const authPatterns = [
80890
+ "authenticate",
80891
+ "auth",
80892
+ "requireAuth",
80893
+ "isAuthenticated",
80894
+ "protect",
80895
+ "jwt",
80896
+ "session"
80897
+ ];
80898
+ for (const pattern of authPatterns) {
80899
+ if (context.toLowerCase().includes(pattern)) {
80900
+ return { required: true };
80901
+ }
80902
+ }
80903
+ return void 0;
80904
+ }
80905
+ filePathToApiRoute(file2) {
80906
+ const relativePath = path18.relative(this.projectRoot, file2);
80907
+ const apiMatch = relativePath.match(/(?:pages|app)\/api\/(.+)\.(ts|js|tsx|jsx)/i);
80908
+ if (apiMatch) {
80909
+ const route = "/" + apiMatch[1].replace(/\[\.\.\.(\w+)\]/g, "*").replace(/\[(\w+)\]/g, ":$1").replace(/\/index$/, "").replace(/\\/g, "/");
80910
+ return "/api" + route;
80911
+ }
80912
+ return "/api/unknown";
80913
+ }
80914
+ async scanEnvVars() {
80915
+ const envVars = [];
80916
+ for (const envFile of this.config.env.files) {
80917
+ const filePath = path18.join(this.projectRoot, envFile);
80918
+ try {
80919
+ const content = await fs102.readFile(filePath, "utf-8");
80920
+ const lines = content.split("\n");
80921
+ for (let i = 0; i < lines.length; i++) {
80922
+ const line = lines[i].trim();
80923
+ if (line.startsWith("#") || !line) continue;
80924
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);
80925
+ if (match) {
80926
+ const [, name, value] = match;
80927
+ const isSensitive = this.isSensitiveEnvVar(name ?? "");
80928
+ envVars.push({
80929
+ name: name ?? "",
80930
+ file: envFile,
80931
+ line: i + 1,
80932
+ hasDefault: (value?.length ?? 0) > 0,
80933
+ defaultValue: isSensitive ? "[REDACTED]" : value,
80934
+ required: (value?.length ?? 0) === 0,
80935
+ sensitive: isSensitive
80936
+ });
80937
+ }
80938
+ }
80939
+ } catch {
80940
+ }
80941
+ }
80942
+ return envVars;
80943
+ }
80944
+ isSensitiveEnvVar(name) {
80945
+ const sensitivePatterns = [
80946
+ "SECRET",
80947
+ "KEY",
80948
+ "PASSWORD",
80949
+ "TOKEN",
80950
+ "PRIVATE",
80951
+ "CREDENTIAL",
80952
+ "AUTH",
80953
+ "API_KEY",
80954
+ "APIKEY"
80955
+ ];
80956
+ return sensitivePatterns.some((p7) => name.toUpperCase().includes(p7));
80957
+ }
80958
+ async scanAuth() {
80959
+ const authRules = [];
80960
+ const files = await fg2(this.config.auth.patterns, {
80961
+ cwd: this.projectRoot,
80962
+ ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
80963
+ absolute: true
80964
+ });
80965
+ for (const file2 of files) {
80966
+ const content = await fs102.readFile(file2, "utf-8");
80967
+ const relativePath = path18.relative(this.projectRoot, file2);
80968
+ const rolePattern = /(?:role|ROLE|Role)\s*[=:]\s*['"`](\w+)['"`]/g;
80969
+ let match;
80970
+ while ((match = rolePattern.exec(content)) !== null) {
80971
+ const line = content.substring(0, match.index).split("\n").length;
80972
+ authRules.push({ name: match[1], type: "role", file: relativePath, line });
80973
+ }
80974
+ const permPattern = /(?:permission|PERMISSION|Permission)\s*[=:]\s*['"`](\w+)['"`]/g;
80975
+ while ((match = permPattern.exec(content)) !== null) {
80976
+ const line = content.substring(0, match.index).split("\n").length;
80977
+ authRules.push({ name: match[1], type: "permission", file: relativePath, line });
80978
+ }
80979
+ const middlewarePattern = /(?:export\s+(?:const|function|async function)\s+)?(authenticate|requireAuth|isAuthenticated|protect|authMiddleware)\b/gi;
80980
+ while ((match = middlewarePattern.exec(content)) !== null) {
80981
+ const line = content.substring(0, match.index).split("\n").length;
80982
+ authRules.push({ name: match[1], type: "middleware", file: relativePath, line });
80983
+ }
80984
+ }
80985
+ return Array.from(
80986
+ new Map(authRules.map((r) => [`${r.name}-${r.type}`, r])).values()
80987
+ );
80988
+ }
80989
+ async scanContracts() {
80990
+ const contracts = [];
80991
+ const files = await fg2(["**/*.ts", "**/*.tsx"], {
80992
+ cwd: this.projectRoot,
80993
+ ignore: [
80994
+ "**/node_modules/**",
80995
+ "**/dist/**",
80996
+ "**/build/**",
80997
+ "**/*.test.ts",
80998
+ "**/*.spec.ts"
80999
+ ],
81000
+ absolute: true
81001
+ });
81002
+ for (const file2 of files) {
81003
+ const content = await fs102.readFile(file2, "utf-8");
81004
+ const relativePath = path18.relative(this.projectRoot, file2);
81005
+ const interfacePattern = /export\s+interface\s+(\w+)/g;
81006
+ let match;
81007
+ while ((match = interfacePattern.exec(content)) !== null) {
81008
+ const line = content.substring(0, match.index).split("\n").length;
81009
+ contracts.push({
81010
+ name: match[1],
81011
+ type: "interface",
81012
+ file: relativePath,
81013
+ line,
81014
+ source: "typescript"
81015
+ });
81016
+ }
81017
+ const typePattern = /export\s+type\s+(\w+)\s*=/g;
81018
+ while ((match = typePattern.exec(content)) !== null) {
81019
+ const line = content.substring(0, match.index).split("\n").length;
81020
+ contracts.push({
81021
+ name: match[1],
81022
+ type: "type",
81023
+ file: relativePath,
81024
+ line,
81025
+ source: "typescript"
81026
+ });
81027
+ }
81028
+ const zodPattern = /(?:export\s+)?(?:const|let)\s+(\w+Schema|\w+Validator)\s*=\s*z\./g;
81029
+ while ((match = zodPattern.exec(content)) !== null) {
81030
+ const line = content.substring(0, match.index).split("\n").length;
81031
+ contracts.push({
81032
+ name: match[1],
81033
+ type: "schema",
81034
+ file: relativePath,
81035
+ line,
81036
+ source: "zod"
81037
+ });
81038
+ }
81039
+ const enumPattern = /export\s+(?:const\s+)?enum\s+(\w+)/g;
81040
+ while ((match = enumPattern.exec(content)) !== null) {
81041
+ const line = content.substring(0, match.index).split("\n").length;
81042
+ contracts.push({
81043
+ name: match[1],
81044
+ type: "enum",
81045
+ file: relativePath,
81046
+ line,
81047
+ source: "typescript"
81048
+ });
81049
+ }
81050
+ }
81051
+ return contracts;
81052
+ }
81053
+ async computeHash(data) {
81054
+ const str = JSON.stringify(data);
81055
+ let hash = 0;
81056
+ for (let i = 0; i < str.length; i++) {
81057
+ const char = str.charCodeAt(i);
81058
+ hash = (hash << 5) - hash + char;
81059
+ hash = hash & hash;
81060
+ }
81061
+ return Math.abs(hash).toString(16).padStart(16, "0");
81062
+ }
81063
+ };
80431
81064
  SIGNAL_WEIGHTS = {
80432
81065
  fileCount: 0.15,
80433
81066
  gitHistory: 0.15,
@@ -82530,6 +83163,12 @@ ${content}`;
82530
83163
  "coverage"
82531
83164
  ];
82532
83165
  SOURCE_EXTENSIONS3 = [".ts", ".tsx", ".js", ".jsx"];
83166
+ DEFAULT_TRUTHPACK_SCANNER = {
83167
+ routes: { enabled: true, frameworks: ["express", "nextjs", "fastify", "hono"], patterns: ["**/*.ts", "**/*.js"] },
83168
+ env: { enabled: true, files: [".env", ".env.local", ".env.example", ".env.development"] },
83169
+ auth: { enabled: true, patterns: ["**/*.ts", "**/*.js"] },
83170
+ contracts: { enabled: true, sources: ["typescript", "zod", "openapi"] }
83171
+ };
82533
83172
  generateId = () => randomUUID().slice(0, 12);
82534
83173
  DEFAULT_SOURCE_PATTERNS = [
82535
83174
  // User Input
@@ -83013,7 +83652,7 @@ ${content}`;
83013
83652
  * Find all files to analyze
83014
83653
  */
83015
83654
  async findFiles() {
83016
- const files = await fg(this.options.include, {
83655
+ const files = await fg2(this.options.include, {
83017
83656
  cwd: this.options.rootDir,
83018
83657
  ignore: this.options.exclude,
83019
83658
  absolute: true,
@@ -83424,10 +84063,10 @@ ${content}`;
83424
84063
  /**
83425
84064
  * Check if a path matches a glob pattern
83426
84065
  */
83427
- matchesPattern(path342, pattern) {
84066
+ matchesPattern(path352, pattern) {
83428
84067
  const regexPattern = pattern.replace(/\*\*/g, "<<<GLOBSTAR>>>").replace(/\*/g, "[^/]*").replace(/<<<GLOBSTAR>>>/g, ".*");
83429
84068
  const regex = new RegExp(`^${regexPattern}$`);
83430
- return regex.test(path342);
84069
+ return regex.test(path352);
83431
84070
  }
83432
84071
  /**
83433
84072
  * Check if a selector might match a denied selector pattern
@@ -84185,7 +84824,7 @@ __export(utils_exports, {
84185
84824
  throttle: () => throttle,
84186
84825
  unregisterTempFile: () => unregisterTempFile,
84187
84826
  validateOrThrow: () => validateOrThrow,
84188
- withRetry: () => withRetry,
84827
+ withRetry: () => withRetry2,
84189
84828
  withTimeout: () => withTimeout2,
84190
84829
  wrapError: () => wrapError2
84191
84830
  });
@@ -84684,7 +85323,7 @@ var symbols = {
84684
85323
  };
84685
85324
  var colors = getCachedColors();
84686
85325
  var BRAND_COLORS = ["#00d4ff", "#7b2dff", "#ff00aa"];
84687
- var brandGradient = gradient(BRAND_COLORS);
85326
+ gradient(BRAND_COLORS);
84688
85327
  ({
84689
85328
  brand: gradient(BRAND_COLORS),
84690
85329
  success: gradient(["#00ff87", "#60efff"]),
@@ -84694,48 +85333,6 @@ var brandGradient = gradient(BRAND_COLORS);
84694
85333
  cool: gradient(["#00c6ff", "#0072ff"]),
84695
85334
  warm: gradient(["#ff9a9e", "#fecfef"])
84696
85335
  });
84697
- function printBanner(options) {
84698
- const env2 = getEnvironment();
84699
- const showTagline = true;
84700
- const compact = false;
84701
- if (!env2.isInteractive || env2.terminal.width < 60) {
84702
- console.log("");
84703
- console.log("VibeCheck");
84704
- {
84705
- console.log(chalk9.dim("Hallucination prevention for AI-assisted development"));
84706
- }
84707
- console.log("");
84708
- return;
84709
- }
84710
- try {
84711
- const font = compact ? "Small" : "Standard";
84712
- const banner = figlet.textSync("VibeCheck", {
84713
- font,
84714
- horizontalLayout: "default"
84715
- });
84716
- console.log("");
84717
- if (shouldUseColors()) {
84718
- console.log(brandGradient.multiline(banner));
84719
- } else {
84720
- console.log(banner);
84721
- }
84722
- if (showTagline) {
84723
- console.log(chalk9.dim(" Hallucination prevention for AI-assisted development"));
84724
- }
84725
- console.log("");
84726
- } catch {
84727
- console.log("");
84728
- if (shouldUseColors()) {
84729
- console.log(brandGradient("VibeCheck"));
84730
- } else {
84731
- console.log("VibeCheck");
84732
- }
84733
- {
84734
- console.log(chalk9.dim("Hallucination prevention for AI-assisted development"));
84735
- }
84736
- console.log("");
84737
- }
84738
- }
84739
85336
  function formatKeyValue(key, value) {
84740
85337
  const c = getCachedColors();
84741
85338
  let formattedValue;
@@ -84806,7 +85403,7 @@ async function runInitWizard() {
84806
85403
  configContent: generateConfigTemplate("standard")
84807
85404
  };
84808
85405
  }
84809
- p4.intro(chalk9.cyan("vibecheck init"));
85406
+ p4.intro(chalk9.cyan("vibecheck link"));
84810
85407
  const template = await p4.select({
84811
85408
  message: "Choose a configuration template:",
84812
85409
  options: [
@@ -85072,7 +85669,7 @@ async function configureOutput(currentConfig) {
85072
85669
  }
85073
85670
 
85074
85671
  // src/lib/version.ts
85075
- var CLI_VERSION = "1.2.2" ;
85672
+ var CLI_VERSION = "1.2.3" ;
85076
85673
  var CLI_NAME = "vibecheck-ai" ;
85077
85674
 
85078
85675
  // src/ui/command-header.tsx
@@ -85158,6 +85755,14 @@ var COMMAND_ASCII = {
85158
85755
  "\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 ",
85159
85756
  "\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D "
85160
85757
  ],
85758
+ LINK: [
85759
+ "\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557",
85760
+ "\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u255D",
85761
+ "\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2554\u255D ",
85762
+ "\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2588\u2588\u2557 ",
85763
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2557",
85764
+ "\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D"
85765
+ ],
85161
85766
  WATCH: [
85162
85767
  "\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557",
85163
85768
  "\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551",
@@ -85507,8 +86112,26 @@ var LOGO = `
85507
86112
  `;
85508
86113
  var COMMANDS = [
85509
86114
  // ═══════════════════════════════════════════════════════════════════════════════
85510
- // THE FLOW: quickstart → certify → status → ship
86115
+ // SETUP: link, quickstart → certify → status → ship
85511
86116
  // ═══════════════════════════════════════════════════════════════════════════════
86117
+ {
86118
+ name: "link",
86119
+ description: "Bind project to VibeCheck (instant setup, auto-detects stack). Aliases: init, setup, configure",
86120
+ usage: "vibecheck link [options]",
86121
+ icon: "\u{1F517}",
86122
+ category: "core",
86123
+ options: [
86124
+ { flag: "-f, --force", description: "Overwrite existing configuration" },
86125
+ { flag: "-m, --minimal", description: "Config only, skip scan" },
86126
+ { flag: "--forge", description: "Generate AI context rules" },
86127
+ { flag: "--connect", description: "Connect to CI/CD pipeline" }
86128
+ ],
86129
+ examples: [
86130
+ "vibecheck link",
86131
+ "vibecheck link --force",
86132
+ "vibecheck link --json"
86133
+ ]
86134
+ },
85512
86135
  {
85513
86136
  name: "quickstart",
85514
86137
  description: "First-time setup: truthpack + forge rules + guardrails",
@@ -85623,8 +86246,26 @@ var COMMANDS = [
85623
86246
  ]
85624
86247
  },
85625
86248
  // ═══════════════════════════════════════════════════════════════════════════════
85626
- // TOOLS: Fix, Forge, Scan, Trace
86249
+ // TOOLS: Audit, Fix, Forge, Scan, Trace
85627
86250
  // ═══════════════════════════════════════════════════════════════════════════════
86251
+ {
86252
+ name: "audit",
86253
+ description: "Find code that looks done but doesn't work (validate + drift). Aliases: check, validate",
86254
+ usage: "vibecheck audit [files...] [options]",
86255
+ icon: "\u{1F50D}",
86256
+ category: "tools",
86257
+ options: [
86258
+ { flag: "-m, --mode <mode>", description: "full (validate + drift), validate, or drift", default: "full" },
86259
+ { flag: "-s, --strict", description: "Enable strict validation/checking" },
86260
+ { flag: "--fix", description: "Attempt to fix issues (validate mode)" },
86261
+ { flag: "--fail-fast", description: "Stop on first error (drift mode)" }
86262
+ ],
86263
+ examples: [
86264
+ "vibecheck audit",
86265
+ "vibecheck audit --mode drift",
86266
+ "vibecheck audit src/ --strict"
86267
+ ]
86268
+ },
85628
86269
  {
85629
86270
  name: "fix",
85630
86271
  description: "Auto-fix simple issues (complex \u2192 use vibecheck ship --missions)",
@@ -85733,6 +86374,21 @@ var COMMANDS = [
85733
86374
  "vibecheck doctor"
85734
86375
  ]
85735
86376
  },
86377
+ {
86378
+ name: "watch",
86379
+ description: "Watch for changes and re-run validation",
86380
+ usage: "vibecheck watch [options]",
86381
+ icon: "\u{1F441}\uFE0F",
86382
+ category: "config",
86383
+ options: [
86384
+ { flag: "-d, --debounce <ms>", description: "Debounce delay in ms" },
86385
+ { flag: "--once", description: "Run once and exit" }
86386
+ ],
86387
+ examples: [
86388
+ "vibecheck watch",
86389
+ "vibecheck watch --once"
86390
+ ]
86391
+ },
85736
86392
  // ═══════════════════════════════════════════════════════════════════════════════
85737
86393
  // REPORTS & BADGES
85738
86394
  // ═══════════════════════════════════════════════════════════════════════════════
@@ -85768,6 +86424,17 @@ var COMMANDS = [
85768
86424
  "vibecheck badge --project-id abc123",
85769
86425
  "vibecheck badge --style for-the-badge"
85770
86426
  ]
86427
+ },
86428
+ {
86429
+ name: "menu",
86430
+ description: "Open interactive menu to run any command",
86431
+ usage: "vibecheck menu",
86432
+ icon: "\u{1F4CB}",
86433
+ category: "config",
86434
+ options: [],
86435
+ examples: [
86436
+ "vibecheck menu"
86437
+ ]
85771
86438
  }
85772
86439
  ];
85773
86440
  var GLOBAL_OPTIONS = [
@@ -85848,16 +86515,16 @@ function renderHelp() {
85848
86515
  console.log("");
85849
86516
  console.log(chalk9.white.bold(" QUICK START"));
85850
86517
  console.log("");
85851
- console.log(" " + chalk9.dim("# 1. First-time setup (generates truthpack + AI rules)"));
86518
+ console.log(" " + chalk9.dim("# 1. Bind project (instant setup)"));
86519
+ console.log(" " + chalk9.green("$ vibecheck link"));
86520
+ console.log("");
86521
+ console.log(" " + chalk9.dim("# 2. First-time setup (truthpack + AI rules)"));
85852
86522
  console.log(" " + chalk9.green("$ vibecheck quickstart"));
85853
86523
  console.log("");
85854
- console.log(" " + chalk9.dim("# 2. Certify your app (Reality + Chaos \u2192 Ship Score)"));
86524
+ console.log(" " + chalk9.dim("# 3. Certify (Reality + Chaos \u2192 Badge)"));
85855
86525
  console.log(" " + chalk9.green("$ vibecheck certify"));
85856
86526
  console.log("");
85857
- console.log(" " + chalk9.dim("# 3. View proof replay"));
85858
- console.log(" " + chalk9.green("$ vibecheck reality replay last --web"));
85859
- console.log("");
85860
- console.log(" " + chalk9.dim("# 4. Check what's active"));
86527
+ console.log(" " + chalk9.dim("# 4. Check status"));
85861
86528
  console.log(" " + chalk9.green("$ vibecheck status"));
85862
86529
  console.log("");
85863
86530
  console.log(chalk9.dim(" " + "\u2500".repeat(68)));
@@ -85868,55 +86535,118 @@ function renderHelp() {
85868
86535
  console.log(" " + chalk9.dim("Docs:") + " " + chalk9.cyan.underline("https://vibecheck.dev/docs"));
85869
86536
  console.log("");
85870
86537
  }
85871
- function renderCommandHelp(commandName) {
86538
+ function getMainHelpText() {
86539
+ const lines = [];
86540
+ lines.push("");
86541
+ lines.push(vibeGradient(LOGO));
86542
+ lines.push("");
86543
+ lines.push(chalk9.dim(" " + "\u2500".repeat(68)));
86544
+ lines.push(chalk9.white.bold(" \u{1F6E1}\uFE0F Stop AI hallucinations. Ship with confidence."));
86545
+ lines.push(chalk9.dim(" " + "\u2500".repeat(68)));
86546
+ lines.push("");
86547
+ lines.push(chalk9.white.bold(" USAGE"));
86548
+ lines.push("");
86549
+ lines.push(" " + chalk9.cyan("vibecheck") + chalk9.dim(" <command>") + chalk9.yellow(" [options]"));
86550
+ lines.push("");
86551
+ const coreCommands = COMMANDS.filter((c) => c.category === "core");
86552
+ lines.push(chalk9.white.bold(" THE FLOW"));
86553
+ lines.push("");
86554
+ for (const cmd of coreCommands) {
86555
+ lines.push(" " + cmd.icon + " " + chalk9.cyan.bold(cmd.name.padEnd(12)) + chalk9.dim(cmd.description));
86556
+ }
86557
+ lines.push("");
86558
+ lines.push(chalk9.dim(" link \u2192 quickstart \u2192 certify \u2192 status \u2192 ship (repeat)"));
86559
+ lines.push("");
86560
+ const verifyCommands = COMMANDS.filter((c) => c.category === "verify");
86561
+ lines.push(chalk9.white.bold(" VERIFICATION"));
86562
+ lines.push("");
86563
+ for (const cmd of verifyCommands) {
86564
+ lines.push(" " + cmd.icon + " " + chalk9.cyan.bold(cmd.name.padEnd(12)) + chalk9.dim(cmd.description));
86565
+ }
86566
+ lines.push("");
86567
+ const toolCommands = COMMANDS.filter((c) => c.category === "tools");
86568
+ lines.push(chalk9.white.bold(" TOOLS"));
86569
+ lines.push("");
86570
+ for (const cmd of toolCommands) {
86571
+ lines.push(" " + cmd.icon + " " + chalk9.cyan.bold(cmd.name.padEnd(12)) + chalk9.dim(cmd.description));
86572
+ }
86573
+ lines.push("");
86574
+ const configCommands = COMMANDS.filter((c) => c.category === "config");
86575
+ lines.push(chalk9.white.bold(" CONFIG"));
86576
+ lines.push("");
86577
+ for (const cmd of configCommands) {
86578
+ lines.push(" " + cmd.icon + " " + chalk9.cyan.bold(cmd.name.padEnd(12)) + chalk9.dim(cmd.description));
86579
+ }
86580
+ lines.push("");
86581
+ const advancedCommands = COMMANDS.filter((c) => c.category === "advanced");
86582
+ lines.push(chalk9.white.bold(" ADVANCED"));
86583
+ lines.push("");
86584
+ for (const cmd of advancedCommands) {
86585
+ lines.push(" " + cmd.icon + " " + chalk9.cyan.bold(cmd.name.padEnd(12)) + chalk9.dim(cmd.description));
86586
+ }
86587
+ lines.push("");
86588
+ lines.push(chalk9.white.bold(" OPTIONS"));
86589
+ lines.push("");
86590
+ for (const opt of GLOBAL_OPTIONS) {
86591
+ lines.push(" " + chalk9.yellow(opt.flag.padEnd(24)) + chalk9.dim(opt.description));
86592
+ }
86593
+ lines.push("");
86594
+ lines.push(chalk9.white.bold(" QUICK START"));
86595
+ lines.push("");
86596
+ lines.push(" " + chalk9.dim("# 1. Bind project") + " " + chalk9.green("$ vibecheck link"));
86597
+ lines.push(" " + chalk9.dim("# 2. First-time setup") + " " + chalk9.green("$ vibecheck quickstart"));
86598
+ lines.push(" " + chalk9.dim("# 3. Certify") + " " + chalk9.green("$ vibecheck certify"));
86599
+ lines.push(" " + chalk9.dim("# 4. Status") + " " + chalk9.green("$ vibecheck status"));
86600
+ lines.push("");
86601
+ lines.push(chalk9.dim(" Run") + " vibecheck " + chalk9.cyan("<command>") + " --help " + chalk9.dim("for command help"));
86602
+ lines.push(chalk9.dim(" Run") + " vibecheck " + chalk9.magenta("menu") + " " + chalk9.dim("for interactive mode"));
86603
+ lines.push("");
86604
+ return lines.join("\n");
86605
+ }
86606
+ function getCommandHelpText(commandName) {
85872
86607
  const cmd = COMMANDS.find((c) => c.name === commandName);
85873
86608
  if (!cmd) {
85874
- console.log(chalk9.red(`
85875
- Unknown command: ${commandName}
85876
- `));
85877
- console.log(chalk9.dim(` Run ${chalk9.cyan("vibecheck --help")} for available commands.
85878
- `));
85879
- return;
86609
+ return chalk9.red("\n Unknown command: " + commandName + "\n") + chalk9.dim(" Run vibecheck --help for available commands.\n");
85880
86610
  }
85881
- console.log("");
85882
- console.log(vibeGradient(LOGO));
85883
- console.log(chalk9.dim(" " + "\u2500".repeat(68)));
85884
- console.log(" " + cmd.icon + " " + chalk9.white.bold(cmd.name.toUpperCase()) + " " + chalk9.dim("\u2500") + " " + cmd.description);
85885
- console.log(chalk9.dim(" " + "\u2500".repeat(68)));
85886
- console.log("");
85887
- console.log(chalk9.white.bold(" USAGE"));
85888
- console.log("");
85889
- console.log(" " + chalk9.green("$") + " " + cmd.usage);
85890
- console.log("");
86611
+ const lines = [];
86612
+ lines.push("");
86613
+ lines.push(vibeGradient(LOGO));
86614
+ lines.push(chalk9.dim(" " + "\u2500".repeat(68)));
86615
+ lines.push(" " + cmd.icon + " " + chalk9.white.bold(cmd.name.toUpperCase()) + " " + chalk9.dim("\u2500") + " " + cmd.description);
86616
+ lines.push(chalk9.dim(" " + "\u2500".repeat(68)));
86617
+ lines.push("");
86618
+ lines.push(chalk9.white.bold(" USAGE"));
86619
+ lines.push("");
86620
+ lines.push(" " + chalk9.green("$") + " " + cmd.usage);
86621
+ lines.push("");
85891
86622
  if (cmd.options.length > 0) {
85892
- console.log(chalk9.white.bold(" OPTIONS"));
85893
- console.log("");
86623
+ lines.push(chalk9.white.bold(" OPTIONS"));
86624
+ lines.push("");
85894
86625
  for (const opt of cmd.options) {
85895
- console.log(
85896
- " " + chalk9.yellow(opt.flag.padEnd(28)) + chalk9.dim(opt.description) + (opt.default ? chalk9.cyan(` [default: ${opt.default}]`) : "")
85897
- );
86626
+ lines.push(" " + chalk9.yellow(opt.flag.padEnd(28)) + chalk9.dim(opt.description) + (opt.default ? chalk9.cyan(` [default: ${opt.default}]`) : ""));
85898
86627
  }
85899
- console.log("");
86628
+ lines.push("");
85900
86629
  }
85901
- console.log(chalk9.white.bold(" GLOBAL OPTIONS"));
85902
- console.log("");
85903
- console.log(" " + chalk9.dim("Also accepts: --verbose, --quiet, --json, --config <path>"));
85904
- console.log("");
86630
+ lines.push(chalk9.white.bold(" GLOBAL OPTIONS"));
86631
+ lines.push("");
86632
+ lines.push(" " + chalk9.dim("Also accepts: --verbose, --quiet, --json, --config <path>"));
86633
+ lines.push("");
85905
86634
  if (cmd.examples.length > 0) {
85906
- console.log(chalk9.white.bold(" EXAMPLES"));
85907
- console.log("");
85908
- for (const example of cmd.examples) {
85909
- console.log(" " + chalk9.green("$") + " " + example);
86635
+ lines.push(chalk9.white.bold(" EXAMPLES"));
86636
+ lines.push("");
86637
+ for (const ex of cmd.examples) {
86638
+ lines.push(" " + chalk9.green("$") + " " + ex);
85910
86639
  }
85911
- console.log("");
86640
+ lines.push("");
85912
86641
  }
85913
- console.log(chalk9.white.bold(" SEE ALSO"));
85914
- console.log("");
86642
+ lines.push(chalk9.white.bold(" SEE ALSO"));
86643
+ lines.push("");
85915
86644
  const related = COMMANDS.filter((c) => c.name !== cmd.name).slice(0, 3);
85916
86645
  for (const r of related) {
85917
- console.log(" " + r.icon + " " + chalk9.cyan(r.name) + " - " + chalk9.dim(r.description));
86646
+ lines.push(" " + r.icon + " " + chalk9.cyan(r.name) + " - " + chalk9.dim(r.description));
85918
86647
  }
85919
- console.log("");
86648
+ lines.push("");
86649
+ return lines.join("\n");
85920
86650
  }
85921
86651
  ({
85922
86652
  loaded: chalk9.green,
@@ -86031,8 +86761,14 @@ var MENU_LOGO = `
86031
86761
  `;
86032
86762
  var MAIN_MENU_ITEMS = [
86033
86763
  // ═══════════════════════════════════════════════════════════════════════════════
86034
- // THE FLOW: quickstart → certify → status → ship
86764
+ // SETUP: link → quickstart → certify → status → ship
86035
86765
  // ═══════════════════════════════════════════════════════════════════════════════
86766
+ {
86767
+ value: "link",
86768
+ label: "Link Project",
86769
+ hint: "Bind project to VibeCheck (instant setup)",
86770
+ icon: "\u{1F517}"
86771
+ },
86036
86772
  {
86037
86773
  value: "quickstart",
86038
86774
  label: "Quickstart",
@@ -86111,6 +86847,12 @@ var MAIN_MENU_ITEMS = [
86111
86847
  hint: "Regenerate truthpack from codebase",
86112
86848
  icon: "\u{1F50D}"
86113
86849
  },
86850
+ {
86851
+ value: "audit",
86852
+ label: "Audit",
86853
+ hint: "Validate + drift detection (find wrongness)",
86854
+ icon: "\u{1F50E}"
86855
+ },
86114
86856
  {
86115
86857
  value: "divider3",
86116
86858
  label: "\u2500".repeat(40),
@@ -86168,6 +86910,12 @@ var MAIN_MENU_ITEMS = [
86168
86910
  // ═══════════════════════════════════════════════════════════════════════════════
86169
86911
  // HELP & EXIT
86170
86912
  // ═══════════════════════════════════════════════════════════════════════════════
86913
+ {
86914
+ value: "login",
86915
+ label: "Login / Account",
86916
+ hint: "Sign in to VibeCheck Cloud",
86917
+ icon: "\u{1F510}"
86918
+ },
86171
86919
  {
86172
86920
  value: "help",
86173
86921
  label: "Help",
@@ -86933,6 +87681,7 @@ function wrapText(text4, maxWidth) {
86933
87681
  if (currentLine) lines.push(currentLine);
86934
87682
  return lines;
86935
87683
  }
87684
+ init_dist();
86936
87685
  ({
86937
87686
  /** Score thresholds for coloring */
86938
87687
  thresholds: [
@@ -87390,6 +88139,25 @@ async function generateReport(data, options = {}) {
87390
88139
 
87391
88140
  // src/lib/index.ts
87392
88141
  init_errors();
88142
+ var SILENCE_ENV = "VIBECHECK_SILENCE_DEPRECATIONS";
88143
+ function isDeprecationSilenced() {
88144
+ return process.env[SILENCE_ENV] === "1" || process.env[SILENCE_ENV] === "true";
88145
+ }
88146
+ function printDeprecation(options) {
88147
+ if (isDeprecationSilenced()) return;
88148
+ const { command, replacement, reason = "Renamed for clarity", removeIn = "v5.0.0" } = options;
88149
+ console.error("");
88150
+ console.error(chalk9.yellow.bold("\u26A0 Deprecation Warning"));
88151
+ console.error(chalk9.dim("\u2501".repeat(60)));
88152
+ console.error(` ${chalk9.dim("Command:")} ${chalk9.yellow(`vibecheck ${command}`)}`);
88153
+ console.error(` ${chalk9.dim("Replacement:")} ${chalk9.cyan(`vibecheck ${replacement}`)}`);
88154
+ console.error(` ${chalk9.dim("Reason:")} ${reason}`);
88155
+ console.error(` ${chalk9.dim("Remove in:")} ${removeIn}`);
88156
+ console.error("");
88157
+ console.error(` ${chalk9.dim(`Silence with: ${SILENCE_ENV}=1`)}`);
88158
+ console.error(chalk9.dim("\u2501".repeat(60)));
88159
+ console.error("");
88160
+ }
87393
88161
  init_errors();
87394
88162
  var LOG_LEVEL_MAP = {
87395
88163
  silent: -1,
@@ -87757,7 +88525,8 @@ async function runForgeInternal(options) {
87757
88525
  incremental: true,
87758
88526
  generateContract: hasFeatureAccess(userTier, FEATURE_KEYS.FORGE_EXTENDED),
87759
88527
  verbose: verbose ?? false,
87760
- platforms: ["cursor", "windsurf"]
88528
+ platforms: []
88529
+ // Auto-detect: only generate for the IDE in use
87761
88530
  };
87762
88531
  const output = await forge(projectPath, config);
87763
88532
  if (!quiet && !json) {
@@ -87959,7 +88728,7 @@ function generateGitHubActionsWorkflow(options) {
87959
88728
  bun: "bunx"
87960
88729
  }[pm];
87961
88730
  let workflow = `# VibeCheck CI/CD Integration
87962
- # Auto-generated by vibecheck init --connect
88731
+ # Auto-generated by vibecheck link --connect
87963
88732
  # Learn more: https://vibecheck.dev/docs/ci-cd
87964
88733
 
87965
88734
  name: VibeCheck
@@ -88008,7 +88777,7 @@ jobs:
88008
88777
  if (options.includeCheck !== false) {
88009
88778
  workflow += `
88010
88779
  - name: Run VibeCheck
88011
- run: ${runCmd} vibecheck check${failFlag}
88780
+ run: ${runCmd} vibecheck audit${failFlag}
88012
88781
  env:
88013
88782
  VIBECHECK_CI: true
88014
88783
 
@@ -88049,7 +88818,7 @@ function generateGitLabCI(options) {
88049
88818
  bun: "bunx"
88050
88819
  }[pm];
88051
88820
  let config = `# VibeCheck GitLab CI Integration
88052
- # Auto-generated by vibecheck init --connect
88821
+ # Auto-generated by vibecheck link --connect
88053
88822
 
88054
88823
  image: node:${nodeVersion}
88055
88824
 
@@ -88076,7 +88845,7 @@ vibecheck:
88076
88845
  `;
88077
88846
  }
88078
88847
  if (options.includeCheck !== false) {
88079
- config += ` - ${runCmd} vibecheck check${failFlag}
88848
+ config += ` - ${runCmd} vibecheck audit${failFlag}
88080
88849
  `;
88081
88850
  }
88082
88851
  config += ` artifacts:
@@ -88112,7 +88881,7 @@ function generateCircleCI(options) {
88112
88881
  bun: "bunx"
88113
88882
  }[pm];
88114
88883
  let config = `# VibeCheck CircleCI Integration
88115
- # Auto-generated by vibecheck init --connect
88884
+ # Auto-generated by vibecheck link --connect
88116
88885
 
88117
88886
  version: 2.1
88118
88887
 
@@ -88142,7 +88911,7 @@ jobs:
88142
88911
  if (options.includeCheck !== false) {
88143
88912
  config += ` - run:
88144
88913
  name: Run VibeCheck
88145
- command: ${runCmd} vibecheck check${failFlag}
88914
+ command: ${runCmd} vibecheck audit${failFlag}
88146
88915
  `;
88147
88916
  }
88148
88917
  config += ` - store_artifacts:
@@ -88206,7 +88975,7 @@ function generateAzurePipelines(options) {
88206
88975
  bun: "bunx"
88207
88976
  }[pm];
88208
88977
  let config = `# VibeCheck Azure Pipelines Integration
88209
- # Auto-generated by vibecheck init --connect
88978
+ # Auto-generated by vibecheck link --connect
88210
88979
 
88211
88980
  trigger:
88212
88981
  branches:
@@ -88245,7 +89014,7 @@ stages:
88245
89014
  }
88246
89015
  if (options.includeCheck !== false) {
88247
89016
  config += `
88248
- - script: ${runCmd} vibecheck check${failFlag}
89017
+ - script: ${runCmd} vibecheck audit${failFlag}
88249
89018
  displayName: 'Run VibeCheck'
88250
89019
 
88251
89020
  - task: PublishBuildArtifacts@1
@@ -88291,7 +89060,7 @@ function generateVercelConfig(options) {
88291
89060
  }[pm];
88292
89061
  return `{
88293
89062
  "$schema": "https://openapi.vercel.sh/vercel.json",
88294
- "buildCommand": "${runCmd} vibecheck check && ${pm === "npm" ? "npm run" : pm} build",
89063
+ "buildCommand": "${runCmd} vibecheck audit && ${pm === "npm" ? "npm run" : pm} build",
88295
89064
  "installCommand": "${pm} install && npm install -g vibecheck-ai",
88296
89065
  "framework": null,
88297
89066
  "env": {
@@ -88309,10 +89078,10 @@ function generateNetlifyConfig(options) {
88309
89078
  bun: "bunx"
88310
89079
  }[pm];
88311
89080
  return `# VibeCheck Netlify Integration
88312
- # Auto-generated by vibecheck init --connect
89081
+ # Auto-generated by vibecheck link --connect
88313
89082
 
88314
89083
  [build]
88315
- command = "npm install -g vibecheck-ai && ${runCmd} vibecheck check && ${pm === "npm" ? "npm run" : pm} build"
89084
+ command = "npm install -g vibecheck-ai && ${runCmd} vibecheck audit && ${pm === "npm" ? "npm run" : pm} build"
88316
89085
 
88317
89086
  [build.environment]
88318
89087
  VIBECHECK_CI = "true"
@@ -88320,7 +89089,7 @@ function generateNetlifyConfig(options) {
88320
89089
 
88321
89090
  # Run VibeCheck on deploy previews
88322
89091
  [context.deploy-preview]
88323
- command = "npm install -g vibecheck-ai && ${runCmd} vibecheck check && ${pm === "npm" ? "npm run" : pm} build"
89092
+ command = "npm install -g vibecheck-ai && ${runCmd} vibecheck audit && ${pm === "npm" ? "npm run" : pm} build"
88324
89093
 
88325
89094
  # Run ship gate on production
88326
89095
  [context.production]
@@ -88451,7 +89220,7 @@ async function integrateWithCI(options) {
88451
89220
  if (detection.existing) {
88452
89221
  result.errors?.push("Netlify config exists. Please add VibeCheck manually.");
88453
89222
  result.instructions.push(
88454
- "Add to your build command: vibecheck check &&",
89223
+ "Add to your build command: vibecheck audit &&",
88455
89224
  "See: https://vibecheck.dev/docs/ci-cd/netlify"
88456
89225
  );
88457
89226
  } else {
@@ -88472,7 +89241,7 @@ async function integrateWithCI(options) {
88472
89241
  result.instructions.push(
88473
89242
  "You can manually integrate VibeCheck by adding these commands to your CI:",
88474
89243
  " npm install -g vibecheck-ai",
88475
- " vibecheck check",
89244
+ " vibecheck audit",
88476
89245
  "See: https://vibecheck.dev/docs/ci-cd"
88477
89246
  );
88478
89247
  }
@@ -88484,6 +89253,7 @@ async function integrateWithCI(options) {
88484
89253
  }
88485
89254
 
88486
89255
  // src/lib/reality-uploader.ts
89256
+ init_src();
88487
89257
  init_dist3();
88488
89258
  init_credentials();
88489
89259
  async function uploadVideoArtifacts(artifactsDir, projectId, checkId) {
@@ -88560,7 +89330,9 @@ async function uploadRealityCheckResults(result, options) {
88560
89330
  const checkId = `rc_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
88561
89331
  let videoUpload = null;
88562
89332
  if (result.artifactsDir) {
88563
- videoUpload = await uploadVideoArtifacts(result.artifactsDir, projectId, checkId);
89333
+ videoUpload = await withUploadLimit(
89334
+ () => uploadVideoArtifacts(result.artifactsDir, projectId, checkId)
89335
+ );
88564
89336
  }
88565
89337
  const payload = {
88566
89338
  projectId,
@@ -88592,7 +89364,9 @@ async function uploadRealityCheckResults(result, options) {
88592
89364
  startedAt: result.summary.startedAt,
88593
89365
  completedAt: result.summary.completedAt
88594
89366
  };
88595
- const record = await createRealityCheckRecord(apiUrl, authToken, payload);
89367
+ const record = await withApiCallLimit(
89368
+ () => createRealityCheckRecord(apiUrl, authToken, payload)
89369
+ );
88596
89370
  if (!record) {
88597
89371
  return null;
88598
89372
  }
@@ -88760,6 +89534,7 @@ function formatQuotaMessage(status) {
88760
89534
  // src/lib/proof-run-client.ts
88761
89535
  init_credentials();
88762
89536
  var execAsync3 = promisify(exec);
89537
+ var API_TIMEOUT_MS = 3e4;
88763
89538
  var DEFAULT_API_URL3 = "https://api.vibecheckai.dev";
88764
89539
  async function createProofRun(input) {
88765
89540
  const { credentials, error } = await getCredentialsAndUrl2();
@@ -88795,38 +89570,46 @@ async function createProofRun(input) {
88795
89570
  body.actionsRunId = input.github.actionsRunId;
88796
89571
  body.actionsRunUrl = input.github.actionsRunUrl;
88797
89572
  }
88798
- const response = await fetch(`${credentials.apiUrl}/api/v1/proof-runs`, {
88799
- method: "POST",
88800
- headers,
88801
- body: JSON.stringify(body)
88802
- });
88803
- const data = await response.json();
88804
- if (!response.ok) {
89573
+ const controller = new AbortController();
89574
+ const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT_MS);
89575
+ try {
89576
+ const response = await fetch(`${credentials.apiUrl}/api/v1/proof-runs`, {
89577
+ method: "POST",
89578
+ headers,
89579
+ body: JSON.stringify(body),
89580
+ signal: controller.signal
89581
+ });
89582
+ clearTimeout(timeoutId);
89583
+ const data = await response.json();
89584
+ if (!response.ok) {
89585
+ return {
89586
+ success: false,
89587
+ error: data.error ?? {
89588
+ code: "API_ERROR",
89589
+ message: data.message ?? "Failed to create proof run"
89590
+ }
89591
+ };
89592
+ }
89593
+ const proofRunId = data.proofRun?.id;
89594
+ const dashboardUrl = proofRunId ? `${credentials.apiUrl.replace("api.", "app.")}/proof-runs/${proofRunId}` : void 0;
88805
89595
  return {
88806
- success: false,
88807
- error: data.error ?? {
88808
- code: "API_ERROR",
88809
- message: data.message ?? "Failed to create proof run"
89596
+ success: true,
89597
+ data: {
89598
+ id: proofRunId ?? "",
89599
+ projectId: input.projectId,
89600
+ status: input.status ?? "completed",
89601
+ verdict: input.verdict,
89602
+ scores: input.scoreOverall ? {
89603
+ overall: input.scoreOverall,
89604
+ previousScore: input.scorePrevious,
89605
+ delta: input.scoreDelta
89606
+ } : void 0,
89607
+ dashboardUrl
88810
89608
  }
88811
89609
  };
89610
+ } finally {
89611
+ clearTimeout(timeoutId);
88812
89612
  }
88813
- const proofRunId = data.proofRun?.id;
88814
- const dashboardUrl = proofRunId ? `${credentials.apiUrl.replace("api.", "app.")}/proof-runs/${proofRunId}` : void 0;
88815
- return {
88816
- success: true,
88817
- data: {
88818
- id: proofRunId ?? "",
88819
- projectId: input.projectId,
88820
- status: input.status ?? "completed",
88821
- verdict: input.verdict,
88822
- scores: input.scoreOverall ? {
88823
- overall: input.scoreOverall,
88824
- previousScore: input.scorePrevious,
88825
- delta: input.scoreDelta
88826
- } : void 0,
88827
- dashboardUrl
88828
- }
88829
- };
88830
89613
  } catch (err) {
88831
89614
  return {
88832
89615
  success: false,
@@ -89505,15 +90288,18 @@ async function scanCommand(options) {
89505
90288
  if (!isAuthenticated() && !options.quiet) {
89506
90289
  logger2.newline();
89507
90290
  console.log(colors.primary("\u2501".repeat(50)));
89508
- console.log(`${symbols.raw.star} ${chalk9.bold("Pro Features Available")}`);
90291
+ console.log(`${symbols.raw.star} ${chalk9.bold("Pro Commands & Features")}`);
89509
90292
  console.log(colors.primary("\u2501".repeat(50)));
89510
90293
  console.log("");
89511
- console.log(colors.muted("With Pro, this scan would also:"));
89512
- console.log(` ${colors.success("+")} Sync to cloud dashboard`);
89513
- console.log(` ${colors.success("+")} Track scan history (90 days)`);
89514
- console.log(` ${colors.success("+")} Generate verified Ship Badges`);
89515
- console.log(` ${colors.success("+")} Auto-fix issues with AI`);
89516
- console.log(` ${colors.success("+")} Post results to GitHub PRs`);
90294
+ console.log(colors.muted("Upgrade to Pro to unlock:"));
90295
+ console.log(` ${colors.success("vibecheck certify")} ${chalk9.dim("Full proof: ISL + Reality + Chaos \u2192 Badge")}`);
90296
+ console.log(` ${colors.success("vibecheck ship --reality")} ${chalk9.dim("Pre-deploy gate with browser verification")}`);
90297
+ console.log(` ${colors.success("vibecheck ship --chaos")} ${chalk9.dim("AI Chaos Agent (autonomous bug hunting)")}`);
90298
+ console.log(` ${colors.success("vibecheck fix")} ${chalk9.dim("Mission-based auto-fix with safety gates")}`);
90299
+ console.log(` ${colors.success("vibecheck report")} ${chalk9.dim("Executive summary, compliance, PDF reports")}`);
90300
+ console.log(` ${colors.success("MCP server")} ${chalk9.dim("AI IDE integration (Cursor, etc.)")}`);
90301
+ console.log("");
90302
+ console.log(colors.muted("Cloud:") + " Sync dashboard, 90-day history, verified badges, GitHub PR comments");
89517
90303
  console.log("");
89518
90304
  console.log(`${colors.muted("Start free trial:")} ${colors.info("vibecheck.dev/pro")}`);
89519
90305
  console.log("");
@@ -89607,7 +90393,7 @@ async function scanCommand(options) {
89607
90393
  init_validation();
89608
90394
  init_scoring();
89609
90395
  init_dist();
89610
- var { glob: glob8 } = fg;
90396
+ var { glob: glob8 } = fg2;
89611
90397
  async function validateCommand(files, options) {
89612
90398
  const logger2 = createLogger({
89613
90399
  level: options.verbose ? "verbose" : options.quiet ? "quiet" : "normal",
@@ -89860,7 +90646,7 @@ async function validateCommand(files, options) {
89860
90646
  init_validation();
89861
90647
  init_scoring();
89862
90648
  init_dist();
89863
- var { glob: glob9 } = fg;
90649
+ var { glob: glob9 } = fg2;
89864
90650
  async function checkCommand(options) {
89865
90651
  const logger2 = createLogger({
89866
90652
  level: options.verbose ? "verbose" : options.quiet ? "quiet" : "normal",
@@ -90166,6 +90952,39 @@ async function checkCommand(options) {
90166
90952
  process.exit(1);
90167
90953
  }
90168
90954
  }
90955
+
90956
+ // src/commands/audit.ts
90957
+ async function auditCommand(files, options) {
90958
+ createLogger({
90959
+ level: options.verbose ? "verbose" : options.quiet ? "quiet" : "normal",
90960
+ json: options.json
90961
+ });
90962
+ const mode = options.mode ?? "full";
90963
+ if (env.isInteractive && !options.json && !options.quiet) {
90964
+ safeRenderHeader({
90965
+ command: "audit",
90966
+ target: process.cwd(),
90967
+ elapsedTime: 0
90968
+ });
90969
+ }
90970
+ if (mode === "full" || mode === "validate") {
90971
+ await validateCommand(files, {
90972
+ ...options,
90973
+ strict: options.strict,
90974
+ fix: options.fix,
90975
+ maxErrors: options.maxErrors,
90976
+ timeout: options.timeout
90977
+ });
90978
+ }
90979
+ if (mode === "full" || mode === "drift") {
90980
+ await checkCommand({
90981
+ ...options,
90982
+ strict: options.strict,
90983
+ failFast: options.failFast,
90984
+ timeout: options.timeout
90985
+ });
90986
+ }
90987
+ }
90169
90988
  var VERDICT_COLORS3 = {
90170
90989
  SHIP: chalk9.green,
90171
90990
  WARN: chalk9.yellow,
@@ -90706,7 +91525,7 @@ async function initCommand(options) {
90706
91525
  }
90707
91526
  if (env.isInteractive && !options.json) {
90708
91527
  safeRenderHeader({
90709
- command: "init",
91528
+ command: "link",
90710
91529
  version: CLI_VERSION,
90711
91530
  target: process.cwd(),
90712
91531
  elapsedTime: 0
@@ -90904,13 +91723,13 @@ async function initCommand(options) {
90904
91723
  }
90905
91724
  if (env.isInteractive && !options.json) {
90906
91725
  safeRenderHeader({
90907
- command: "init",
91726
+ command: "link",
90908
91727
  version: CLI_VERSION,
90909
91728
  target: process.cwd(),
90910
91729
  elapsedTime: duration,
90911
91730
  vitals: [
90912
91731
  {
90913
- label: "INITIALIZATION",
91732
+ label: "LINK",
90914
91733
  status: "optimal",
90915
91734
  value: "Complete",
90916
91735
  percentage: 100
@@ -90989,12 +91808,12 @@ async function initCommand(options) {
90989
91808
  logger2.newline();
90990
91809
  console.log(chalk9.dim("Next steps:"));
90991
91810
  console.log(` ${symbols.arrow} Run ${chalk9.cyan("vibecheck scan")} to generate your truthpack`);
90992
- console.log(` ${symbols.arrow} Run ${chalk9.cyan("vibecheck check")} to validate your codebase`);
91811
+ console.log(` ${symbols.arrow} Run ${chalk9.cyan("vibecheck audit")} to validate your codebase`);
90993
91812
  if (!options.forge) {
90994
- console.log(` ${symbols.arrow} Run ${chalk9.cyan("vibecheck init --forge")} to generate AI context rules`);
91813
+ console.log(` ${symbols.arrow} Run ${chalk9.cyan("vibecheck link --forge")} to generate AI context rules`);
90995
91814
  }
90996
91815
  if (!options.connect) {
90997
- console.log(` ${symbols.arrow} Run ${chalk9.cyan("vibecheck init --connect")} to integrate with CI/CD`);
91816
+ console.log(` ${symbols.arrow} Run ${chalk9.cyan("vibecheck link --connect")} to integrate with CI/CD`);
90998
91817
  }
90999
91818
  console.log(` ${symbols.arrow} Edit ${chalk9.cyan(CONFIG_FILENAME)} to customize settings`);
91000
91819
  if (ciResult?.success && ciResult.instructions.length > 0) {
@@ -91048,6 +91867,13 @@ async function configCommand(options) {
91048
91867
  level: options.verbose ? "verbose" : options.quiet ? "quiet" : "normal",
91049
91868
  json: options.json
91050
91869
  });
91870
+ if (env.isInteractive && !options.json && !options.quiet && !options.get && !options.set && !options.list) {
91871
+ safeRenderHeader({
91872
+ command: "config",
91873
+ target: process.cwd(),
91874
+ elapsedTime: 0
91875
+ });
91876
+ }
91051
91877
  try {
91052
91878
  let configPath = null;
91053
91879
  let config = null;
@@ -91117,7 +91943,7 @@ async function configCommand(options) {
91117
91943
  repoRoot,
91118
91944
  defaultConfigPath,
91119
91945
  message: "No VibeCheck configuration found",
91120
- suggestion: "Run `vibecheck init` to create a configuration file",
91946
+ suggestion: "Run `vibecheck link` to create a configuration file",
91121
91947
  loadError: configLoadError
91122
91948
  }, null, 2));
91123
91949
  } else {
@@ -91130,7 +91956,7 @@ async function configCommand(options) {
91130
91956
  }
91131
91957
  logger2.newline();
91132
91958
  logger2.info("To create a configuration file, run:");
91133
- logger2.dim(" vibecheck init");
91959
+ logger2.dim(" vibecheck link");
91134
91960
  logger2.newline();
91135
91961
  logger2.dim("Using default configuration in the meantime.");
91136
91962
  }
@@ -91571,7 +92397,11 @@ async function fixCommand(options) {
91571
92397
  try {
91572
92398
  validateOptions2(options);
91573
92399
  if (env.isInteractive && !options.json && !options.quiet) {
91574
- printBanner();
92400
+ safeRenderHeader({
92401
+ command: "fix",
92402
+ target: process.cwd(),
92403
+ elapsedTime: 0
92404
+ });
91575
92405
  }
91576
92406
  if (options.rollback) {
91577
92407
  await handleRollback(options.rollback, logger2, options);
@@ -91590,12 +92420,12 @@ async function fixCommand(options) {
91590
92420
  success: true,
91591
92421
  message: "Nothing to fix (no VibeCheck configuration file)",
91592
92422
  configExists: false,
91593
- suggestion: "Run `vibecheck init` to configure this project",
92423
+ suggestion: "Run `vibecheck link` to configure this project",
91594
92424
  results: { totalIssues: 0, fixableIssues: 0, appliedFixes: 0 }
91595
92425
  }, null, 2));
91596
92426
  } else {
91597
92427
  logger2.warn("No VibeCheck configuration file found");
91598
- logger2.dim("Run `vibecheck init` to configure this project");
92428
+ logger2.dim("Run `vibecheck link` to configure this project");
91599
92429
  logger2.newline();
91600
92430
  logger2.success("Nothing to fix");
91601
92431
  }
@@ -91608,7 +92438,7 @@ async function fixCommand(options) {
91608
92438
  config = defaultConfig2;
91609
92439
  if (!options.dryRun) {
91610
92440
  logger2.warn("No configuration found, using defaults");
91611
- logger2.dim("Run `vibecheck init` to create a configuration file");
92441
+ logger2.dim("Run `vibecheck link` to create a configuration file");
91612
92442
  }
91613
92443
  }
91614
92444
  const projectRoot = process.cwd();
@@ -92179,7 +93009,7 @@ async function shipCommand(options) {
92179
93009
  details: configError instanceof Error ? configError.message : String(configError)
92180
93010
  }, null, 2));
92181
93011
  } else {
92182
- logger2.error('Failed to load configuration. Run "vibecheck init" first.');
93012
+ logger2.error('Failed to load configuration. Run "vibecheck link" first.');
92183
93013
  }
92184
93014
  process.exit(1);
92185
93015
  }
@@ -92695,7 +93525,7 @@ async function runTruthpackCheck(projectRoot, config) {
92695
93525
  name: "truthpack",
92696
93526
  status: "fail",
92697
93527
  message: "Truthpack path not configured",
92698
- details: ['Run "vibecheck init" to configure'],
93528
+ details: ['Run "vibecheck link" to configure'],
92699
93529
  fixable: true,
92700
93530
  durationMs: Date.now() - startTime
92701
93531
  };
@@ -94130,7 +94960,7 @@ async function reportCommand(options) {
94130
94960
  config = await loadConfig(options.config);
94131
94961
  } catch {
94132
94962
  throw new VibeCheckError(
94133
- 'Failed to load configuration. Run "vibecheck init" first.',
94963
+ 'Failed to load configuration. Run "vibecheck link" first.',
94134
94964
  "CONFIG_NOT_FOUND"
94135
94965
  );
94136
94966
  }
@@ -95131,7 +95961,7 @@ async function runForgeWatch(projectPath, config, logger2) {
95131
95961
  await new Promise(() => {
95132
95962
  });
95133
95963
  }
95134
- var forgeCommand = new Command("forge").description("Generate AI context rules to prevent drift and hallucinations").option("-o, --output <path>", "Output directory (default: project root)").option("-t, --tier <tier>", "Rule tier: minimal, standard, extended, comprehensive").option("-w, --watch", "Watch mode: auto-update rules when project changes").option("-p, --platform <platform>", "Target platform: cursor, windsurf, both", "both").option("--incremental", "Only update changed rules (default: true)", true).option("--no-incremental", "Regenerate all rules").option("--contract", "Generate AI Contract (Pro+ feature)").option("--no-contract", "Skip AI Contract generation").action(async (options, command) => {
95964
+ var forgeCommand = new Command("forge").description("Generate AI context rules to prevent drift and hallucinations").option("-o, --output <path>", "Output directory (default: project root)").option("-t, --tier <tier>", "Rule tier: minimal, standard, extended, comprehensive").option("-w, --watch", "Watch mode: auto-update rules when project changes").option("-p, --platform <platform>", "Target platform: cursor, windsurf, both, auto (auto = detect IDE, default)", "auto").option("--incremental", "Only update changed rules (default: true)", true).option("--no-incremental", "Regenerate all rules").option("--contract", "Generate AI Contract (Pro+ feature)").option("--no-contract", "Skip AI Contract generation").action(async (options, command) => {
95135
95965
  const globalOpts = command.optsWithGlobals();
95136
95966
  const logger2 = createLogger({
95137
95967
  level: globalOpts.verbose ? "debug" : "info",
@@ -95140,12 +95970,12 @@ var forgeCommand = new Command("forge").description("Generate AI context rules t
95140
95970
  try {
95141
95971
  const projectPath = await findProjectRoot(process.cwd());
95142
95972
  if (!projectPath) {
95143
- logger2.error('Not in a VibeCheck project. Run "vibecheck init" first.');
95973
+ logger2.error('Not in a VibeCheck project. Run "vibecheck link" first.');
95144
95974
  process.exit(1);
95145
95975
  }
95146
95976
  const userTier = await getCurrentTierAsync();
95147
95977
  const tierConfig = options.tier ? { tier: options.tier, maxRules: getTierLimit(options.tier) } : getForgeConfigForTier(userTier);
95148
- const platforms = options.platform === "both" ? ["cursor", "windsurf"] : [options.platform ?? "cursor"];
95978
+ const platforms = options.platform === "auto" || options.platform === void 0 ? [] : options.platform === "both" ? ["cursor", "windsurf"] : [options.platform];
95149
95979
  const isPro2 = userTier === "pro" || userTier === "enterprise";
95150
95980
  const config = {
95151
95981
  tier: tierConfig.tier,
@@ -95164,7 +95994,7 @@ var forgeCommand = new Command("forge").description("Generate AI context rules t
95164
95994
  }
95165
95995
  logger2.info(chalk9.bold("Generating AI context rules..."));
95166
95996
  logger2.dim(`Tier: ${tierConfig.tier} (max ${tierConfig.maxRules} rules)`);
95167
- logger2.dim(`Platforms: ${platforms.join(", ")}`);
95997
+ logger2.dim(`Platforms: ${platforms.length === 0 ? "auto-detect (IDE in use)" : platforms.join(", ")}`);
95168
95998
  const output = await forge(projectPath, config);
95169
95999
  if (globalOpts.json) {
95170
96000
  console.log(JSON.stringify(formatForgeOutputForJson(output), null, 2));
@@ -95355,7 +96185,7 @@ init_scoring();
95355
96185
  init_truthpack();
95356
96186
 
95357
96187
  // ../../packages/core/dist/firewall/index.js
95358
- init_chunk_4MEEGNJS();
96188
+ init_chunk_QXRHICLP();
95359
96189
  init_chunk_DFJL4MLU();
95360
96190
  init_chunk_SKXQ6JUA();
95361
96191
  init_chunk_4EQXFW4J();
@@ -97473,14 +98303,11 @@ ${str}`);
97473
98303
  }
97474
98304
  });
97475
98305
  function addCustomHelp(cmd, cmdName) {
97476
- cmd.on("option:help", () => {
97477
- renderCommandHelp(cmdName);
97478
- process.exit(0);
97479
- });
98306
+ cmd.helpInformation = () => getCommandHelpText(cmdName);
97480
98307
  return cmd;
97481
98308
  }
97482
98309
  addCustomHelp(
97483
- program2.command("init").description("Initialize VibeCheck (runs quickstart for first-time users)").option("-f, --force", "Overwrite existing configuration").option("-m, --minimal", "Minimal mode: create config only, skip scan").option("-q, --quick", "Quick mode: auto-scan, show Ship Score and top issues").option(
98310
+ program2.command("link").alias("init").alias("setup").alias("configure").description("Bind project to VibeCheck (instant setup, auto-detects stack)").option("-f, --force", "Overwrite existing configuration").option("-m, --minimal", "Minimal mode: create config only, skip scan").option("-q, --quick", "Quick mode: auto-scan, show Ship Score and top issues").option(
97484
98311
  "-t, --template <template>",
97485
98312
  "Configuration template (minimal, standard, strict)",
97486
98313
  (value) => {
@@ -97493,114 +98320,152 @@ addCustomHelp(
97493
98320
  return value;
97494
98321
  }
97495
98322
  ).option("--forge", "Generate AI context rules (Cursor, Windsurf, etc.)").option("--connect", "Connect VibeCheck to your CI/CD pipeline").option("--ship-gate", "Include ship gate in CI/CD (use with --connect)").action(async (options, command) => {
98323
+ if (command.name() === "init") {
98324
+ printDeprecation({
98325
+ command: "init",
98326
+ replacement: "link",
98327
+ reason: "Renamed for clarity",
98328
+ removeIn: "v5.0.0"
98329
+ });
98330
+ }
97496
98331
  const globalOpts = command.optsWithGlobals();
97497
98332
  await initCommand({
97498
98333
  ...options,
97499
98334
  ...globalOpts
97500
98335
  });
97501
98336
  }),
97502
- "init"
98337
+ "link"
98338
+ );
98339
+ addCustomHelp(
98340
+ program2.command("quickstart").alias("start").description("Interactive setup wizard for new users").option("--skip-prompts", "Run without interactive prompts").action(async (options, command) => {
98341
+ const globalOpts = command.optsWithGlobals();
98342
+ await quickstartCommand({
98343
+ ...options,
98344
+ ...globalOpts
98345
+ });
98346
+ }),
98347
+ "quickstart"
98348
+ );
98349
+ addCustomHelp(
98350
+ program2.command("missions").description("View fix missions grouped by category").option("-c, --category <category>", "Filter by category (auth, env, routes, contracts)").option("-s, --status <status>", "Filter by status (pending, in-progress, done)").option("-a, --all", "Show completed missions too").action(async (options, command) => {
98351
+ const globalOpts = command.optsWithGlobals();
98352
+ await missionsCommand({
98353
+ ...options,
98354
+ ...globalOpts
98355
+ });
98356
+ }),
98357
+ "missions"
98358
+ );
98359
+ addCustomHelp(
98360
+ program2.command("github").description("Set up GitHub Action for CI gate").option("--action", "Create GitHub Action workflow file (default)").option("--threshold <score>", "Fail threshold score (0-100)", (v) => {
98361
+ const num = parseInt(v, 10);
98362
+ if (isNaN(num) || num < 0 || num > 100) {
98363
+ throw new InvalidArgumentError("Threshold must be between 0 and 100");
98364
+ }
98365
+ return num;
98366
+ }).option("--autofix", "Enable auto-fix in CI workflow").action(async (options, command) => {
98367
+ const globalOpts = command.optsWithGlobals();
98368
+ await githubCommand({
98369
+ ...options,
98370
+ ...globalOpts
98371
+ });
98372
+ }),
98373
+ "github"
98374
+ );
98375
+ addCustomHelp(
98376
+ program2.command("scan").description("Scan codebase and generate truthpack").option("-o, --output <path>", "Output path for truthpack", validatePath).option("-i, --include <patterns...>", "Include patterns").option("-e, --exclude <patterns...>", "Exclude patterns").option(
98377
+ "--timeout <ms>",
98378
+ "Scan timeout in milliseconds",
98379
+ (v) => parsePositiveInteger(v, "timeout")
98380
+ ).option("--force", "Force regeneration even if truthpack exists").action(async (options, command) => {
98381
+ const globalOpts = command.optsWithGlobals();
98382
+ await scanCommand({
98383
+ ...options,
98384
+ ...globalOpts
98385
+ });
98386
+ }),
98387
+ "scan"
98388
+ );
98389
+ addCustomHelp(
98390
+ program2.command("audit [files...]").alias("check").alias("validate").description("Find code that looks done but doesn't work (validate + drift detection)").option(
98391
+ "-m, --mode <mode>",
98392
+ "Audit mode: full (validate + drift), validate (files vs truthpack), drift (hallucination + drift)",
98393
+ (value) => {
98394
+ const valid = ["full", "validate", "drift"];
98395
+ if (!valid.includes(value)) {
98396
+ throw new InvalidArgumentError(
98397
+ `Mode must be one of: ${valid.join(", ")}`
98398
+ );
98399
+ }
98400
+ return value;
98401
+ }
98402
+ ).option("-s, --strict", "Enable strict validation/checking").option("--fix", "Attempt to fix issues (validate mode only)").option(
98403
+ "--max-errors <count>",
98404
+ "Maximum errors to report (validate mode)",
98405
+ (v) => parsePositiveInteger(v, "max-errors")
98406
+ ).option("--fail-fast", "Stop on first error (drift mode)").option(
98407
+ "--timeout <ms>",
98408
+ "Timeout in milliseconds",
98409
+ (v) => parsePositiveInteger(v, "timeout")
98410
+ ).action(async (files, options, command) => {
98411
+ const globalOpts = command.optsWithGlobals();
98412
+ const invokedAs = command.name();
98413
+ const mode = invokedAs === "audit" ? options.mode ?? "full" : invokedAs === "validate" ? "validate" : "drift";
98414
+ await auditCommand(files ?? [], {
98415
+ ...options,
98416
+ ...globalOpts,
98417
+ mode
98418
+ });
98419
+ }),
98420
+ "audit"
98421
+ );
98422
+ addCustomHelp(
98423
+ program2.command("trace [target]").description("Trace data flow from sources to sinks").option("-f, --format <format>", "Output format (text, json, mermaid)", "text").option("-o, --output <path>", "Output file path").option("--max-depth <n>", "Maximum path depth", (v) => parsePositiveInteger(v, "max-depth")).option("--show-all", "Show all paths, not just issues").action(async (target, options, command) => {
98424
+ const globalOpts = command.optsWithGlobals();
98425
+ await traceCommand({
98426
+ target,
98427
+ format: options.format,
98428
+ output: options.output,
98429
+ maxDepth: options.maxDepth,
98430
+ showAll: options.showAll,
98431
+ ...globalOpts
98432
+ });
98433
+ }),
98434
+ "trace"
98435
+ );
98436
+ addCustomHelp(
98437
+ program2.command("config").description("View or edit configuration").option("--get <key>", "Get a configuration value").option("--set <key=value>", "Set a configuration value").option("--list", "List all configuration values").option("--validate", "Validate the configuration file").option("--path", "Show the configuration file path").action(async (options, command) => {
98438
+ const globalOpts = command.optsWithGlobals();
98439
+ await configCommand({
98440
+ ...options,
98441
+ ...globalOpts
98442
+ });
98443
+ }),
98444
+ "config"
98445
+ );
98446
+ addCustomHelp(
98447
+ program2.command("watch").description("Watch for changes and validate continuously").option(
98448
+ "-d, --debounce <ms>",
98449
+ "Debounce delay in milliseconds",
98450
+ (v) => parsePositiveInteger(v, "debounce")
98451
+ ).option("--once", "Run validation once and exit").action(async (options, command) => {
98452
+ const globalOpts = command.optsWithGlobals();
98453
+ await watchCommand({
98454
+ ...options,
98455
+ ...globalOpts
98456
+ });
98457
+ }),
98458
+ "watch"
98459
+ );
98460
+ addCustomHelp(
98461
+ program2.command("doctor").description("Validate system dependencies and configuration").action(async (options, command) => {
98462
+ const globalOpts = command.optsWithGlobals();
98463
+ await doctorCommand({
98464
+ ...globalOpts
98465
+ });
98466
+ }),
98467
+ "doctor"
97503
98468
  );
97504
- program2.command("quickstart").alias("start").description("Interactive setup wizard for new users").option("--skip-prompts", "Run without interactive prompts").action(async (options, command) => {
97505
- const globalOpts = command.optsWithGlobals();
97506
- await quickstartCommand({
97507
- ...options,
97508
- ...globalOpts
97509
- });
97510
- });
97511
- program2.command("missions").description("View fix missions grouped by category").option("-c, --category <category>", "Filter by category (auth, env, routes, contracts)").option("-s, --status <status>", "Filter by status (pending, in-progress, done)").option("-a, --all", "Show completed missions too").action(async (options, command) => {
97512
- const globalOpts = command.optsWithGlobals();
97513
- await missionsCommand({
97514
- ...options,
97515
- ...globalOpts
97516
- });
97517
- });
97518
- program2.command("github").description("Set up GitHub Action for CI gate").option("--action", "Create GitHub Action workflow file (default)").option("--threshold <score>", "Fail threshold score (0-100)", (v) => {
97519
- const num = parseInt(v, 10);
97520
- if (isNaN(num) || num < 0 || num > 100) {
97521
- throw new InvalidArgumentError("Threshold must be between 0 and 100");
97522
- }
97523
- return num;
97524
- }).option("--autofix", "Enable auto-fix in CI workflow").action(async (options, command) => {
97525
- const globalOpts = command.optsWithGlobals();
97526
- await githubCommand({
97527
- ...options,
97528
- ...globalOpts
97529
- });
97530
- });
97531
- program2.command("scan").description("Scan codebase and generate truthpack").option("-o, --output <path>", "Output path for truthpack", validatePath).option("-i, --include <patterns...>", "Include patterns").option("-e, --exclude <patterns...>", "Exclude patterns").option(
97532
- "--timeout <ms>",
97533
- "Scan timeout in milliseconds",
97534
- (v) => parsePositiveInteger(v, "timeout")
97535
- ).option("--force", "Force regeneration even if truthpack exists").action(async (options, command) => {
97536
- const globalOpts = command.optsWithGlobals();
97537
- await scanCommand({
97538
- ...options,
97539
- ...globalOpts
97540
- });
97541
- });
97542
- program2.command("validate [files...]").description("Validate files against truthpack").option("-s, --strict", "Enable strict validation").option("--fix", "Attempt to fix issues automatically").option(
97543
- "--max-errors <count>",
97544
- "Maximum number of errors to report",
97545
- (v) => parsePositiveInteger(v, "max-errors")
97546
- ).option(
97547
- "--timeout <ms>",
97548
- "Validation timeout in milliseconds",
97549
- (v) => parsePositiveInteger(v, "timeout")
97550
- ).action(async (files, options, command) => {
97551
- const globalOpts = command.optsWithGlobals();
97552
- await validateCommand(files, {
97553
- ...options,
97554
- ...globalOpts
97555
- });
97556
- });
97557
- program2.command("check").description("Run hallucination and drift detection").option("-s, --strict", "Enable strict checking").option("--fail-fast", "Stop on first error").option(
97558
- "--timeout <ms>",
97559
- "Check timeout in milliseconds",
97560
- (v) => parsePositiveInteger(v, "timeout")
97561
- ).action(async (options, command) => {
97562
- const globalOpts = command.optsWithGlobals();
97563
- await checkCommand({
97564
- ...options,
97565
- failFast: options.failFast,
97566
- ...globalOpts
97567
- });
97568
- });
97569
- program2.command("trace [target]").description("Trace data flow from sources to sinks").option("-f, --format <format>", "Output format (text, json, mermaid)", "text").option("-o, --output <path>", "Output file path").option("--max-depth <n>", "Maximum path depth", (v) => parsePositiveInteger(v, "max-depth")).option("--show-all", "Show all paths, not just issues").action(async (target, options, command) => {
97570
- const globalOpts = command.optsWithGlobals();
97571
- await traceCommand({
97572
- target,
97573
- format: options.format,
97574
- output: options.output,
97575
- maxDepth: options.maxDepth,
97576
- showAll: options.showAll,
97577
- ...globalOpts
97578
- });
97579
- });
97580
- program2.command("config").description("View or edit configuration").option("--get <key>", "Get a configuration value").option("--set <key=value>", "Set a configuration value").option("--list", "List all configuration values").option("--validate", "Validate the configuration file").option("--path", "Show the configuration file path").action(async (options, command) => {
97581
- const globalOpts = command.optsWithGlobals();
97582
- await configCommand({
97583
- ...options,
97584
- ...globalOpts
97585
- });
97586
- });
97587
- program2.command("watch").description("Watch for changes and validate continuously").option(
97588
- "-d, --debounce <ms>",
97589
- "Debounce delay in milliseconds",
97590
- (v) => parsePositiveInteger(v, "debounce")
97591
- ).option("--once", "Run validation once and exit").action(async (options, command) => {
97592
- const globalOpts = command.optsWithGlobals();
97593
- await watchCommand({
97594
- ...options,
97595
- ...globalOpts
97596
- });
97597
- });
97598
- program2.command("doctor").description("Validate system dependencies and configuration").action(async (options, command) => {
97599
- const globalOpts = command.optsWithGlobals();
97600
- await doctorCommand({
97601
- ...globalOpts
97602
- });
97603
- });
97604
98469
  program2.addCommand(forgeCommand);
97605
98470
  var realityCommand = program2.command("reality").description("\u{1F3AC} Reality Mode 2.0 - Runtime verification with proof bundles");
97606
98471
  realityCommand.command("run").description("Run Reality Mode and produce a Proof Bundle").option("-u, --url <url>", "Target URL (auto-detects if not provided)").option("-s, --scenarios <preset|ids>", "Scenario preset (smoke, standard, chaos) or comma-separated IDs", "standard").option("--headless", "Run browser in headless mode", true).option("--no-headless", "Run browser in headed mode (show browser)").option("-b, --browser <browser>", "Browser to use (chromium, firefox, webkit)", "chromium").option("--timeout <seconds>", "Global timeout in seconds", (v) => parsePositiveInteger(v, "timeout")).option("--video", "Enable video recording", true).option("--no-video", "Disable video recording").option("-o, --output <path>", "Output directory for proof bundle").option("--open", "Open report in browser after run").action(async (options, command) => {
@@ -97651,165 +98516,205 @@ realityCommand.command("clean").description("Clean up old proof bundles").option
97651
98516
  ...globalOpts
97652
98517
  });
97653
98518
  });
97654
- program2.command("ship").description("Pre-deployment checks with optional auto-fix").option("--fix", "Auto-fix issues before shipping").option("--force", "Proceed despite blockers").option("--strict", "Stricter pre-deploy checks").option(
97655
- "-m, --mode <mode>",
97656
- "Scoring mode: isl (spec-first), traditional (scan-based), or hybrid",
97657
- (value) => {
97658
- const valid = ["isl", "traditional", "hybrid"];
97659
- if (!valid.includes(value)) {
97660
- throw new InvalidArgumentError(
97661
- `Mode must be one of: ${valid.join(", ")}`
97662
- );
98519
+ addCustomHelp(
98520
+ program2.command("ship").description("Pre-deployment checks with optional auto-fix").option("--fix", "Auto-fix issues before shipping").option("--force", "Proceed despite blockers").option("--strict", "Stricter pre-deploy checks").option(
98521
+ "-m, --mode <mode>",
98522
+ "Scoring mode: isl (spec-first), traditional (scan-based), or hybrid",
98523
+ (value) => {
98524
+ const valid = ["isl", "traditional", "hybrid"];
98525
+ if (!valid.includes(value)) {
98526
+ throw new InvalidArgumentError(
98527
+ `Mode must be one of: ${valid.join(", ")}`
98528
+ );
98529
+ }
98530
+ return value;
97663
98531
  }
97664
- return value;
97665
- }
97666
- ).option("--spec <path>", "Path to ISL spec file (enables ISL verification)").option("--reality", "Enable Reality Mode (auto-starts your app, runs browser tests)").option("--reality-url <url>", "Use existing server instead of auto-starting").option(
97667
- "--reality-timeout <seconds>",
97668
- "Reality Mode timeout in seconds",
97669
- (v) => parsePositiveInteger(v, "reality-timeout")
97670
- ).option(
97671
- "--reality-startup-timeout <seconds>",
97672
- "Server startup timeout in seconds",
97673
- (v) => parsePositiveInteger(v, "reality-startup-timeout")
97674
- ).option("--reality-headless", "Run browser in headless mode", true).option("--no-reality-headless", "Run browser in headed mode (see browser)").option("--chaos", "Enable AI Chaos Agent (autonomous bug hunting)").option("--chaos-aggressive", "Aggressive chaos mode (includes security tests)").option(
97675
- "--chaos-actions <number>",
97676
- "Maximum chaos actions to perform",
97677
- (v) => parsePositiveInteger(v, "chaos-actions")
97678
- ).option("--chaos-provider <provider>", "AI provider: auto (default), fallback (no AI), ollama (free), anthropic, openai", "auto").option("--chaos-model <model>", "Model to use (default: llava for ollama, gpt-4o for openai)").option("--chaos-url <url>", "Base URL for ollama/local provider (default: http://localhost:11434)").option("--chaos-api-key <key>", "API key for anthropic/openai (or use OPENAI_API_KEY/ANTHROPIC_API_KEY env)").option("--chaos-no-vision", "Disable vision (DOM-only mode, works with any LLM)").option("--detailed", "Show detailed 6-dimension Ship Score breakdown").option("--missions", "Group findings into actionable fix missions").option("--github-pr <number>", "Post results as GitHub PR comment", (v) => parsePositiveInteger(v, "github-pr")).option("--github-repo <repo>", "GitHub repository (owner/repo format)").option("--report", "Generate HTML report and open in browser").action(async (options, command) => {
97679
- const globalOpts = command.optsWithGlobals();
97680
- await shipCommand({
97681
- ...options,
97682
- mode: options.mode,
97683
- spec: options.spec,
97684
- reality: options.reality,
97685
- realityUrl: options.realityUrl,
97686
- realityTimeout: options.realityTimeout,
97687
- realityStartupTimeout: options.realityStartupTimeout,
97688
- realityHeadless: options.realityHeadless,
97689
- chaos: options.chaos,
97690
- chaosAggressive: options.chaosAggressive,
97691
- chaosActions: options.chaosActions,
97692
- chaosProvider: options.chaosProvider,
97693
- chaosModel: options.chaosModel,
97694
- chaosUrl: options.chaosUrl,
97695
- chaosApiKey: options.chaosApiKey,
97696
- chaosNoVision: options.chaosNoVision,
97697
- detailed: options.detailed,
97698
- missions: options.missions,
97699
- githubPr: options.githubPr,
97700
- githubRepo: options.githubRepo,
97701
- ...globalOpts
97702
- });
97703
- });
97704
- program2.command("certify").description("\u{1F3C6} Final certification: ISL + Reality + Chaos \u2192 Badge (zero setup)").option("--spec <path>", "Path to ISL spec file (auto-generates if missing)").option("--skip-isl", "Skip ISL verification step").option("--skip-reality", "Skip Reality Mode verification").option("--skip-chaos", "Skip Chaos Agent testing").option("--chaos-actions <number>", "Maximum chaos actions to perform", (v) => parsePositiveInteger(v, "chaos-actions")).option("--timeout <seconds>", "Reality Mode timeout in seconds", (v) => parsePositiveInteger(v, "timeout")).option("--headless", "Run browser in headless mode", true).option("--no-headless", "Run browser in headed mode (show browser)").option("-o, --output <path>", "Output directory for proof bundle").option("--threshold <score>", "Minimum score required for certification (default: 85)", (v) => parsePositiveInteger(v, "threshold")).option("--open", "Open report in browser after completion").action(async (options, command) => {
97705
- const globalOpts = command.optsWithGlobals();
97706
- await certifyCommand({
97707
- spec: options.spec,
97708
- skipIsl: options.skipIsl,
97709
- skipReality: options.skipReality,
97710
- skipChaos: options.skipChaos,
97711
- chaosActions: options.chaosActions,
97712
- timeout: options.timeout,
97713
- headless: options.headless,
97714
- output: options.output,
97715
- threshold: options.threshold,
97716
- open: options.open,
97717
- ...globalOpts
97718
- });
97719
- });
97720
- program2.command("status").description("Show current VibeCheck module status").action(async (options, command) => {
97721
- const globalOpts = command.optsWithGlobals();
97722
- await statusCommand({
97723
- ...globalOpts
97724
- });
97725
- });
97726
- program2.command("fix [files...]").description("Auto-fix simple issues (env vars, empty catches, stubs) - use --missions for complex ones").option("-a, --apply", "Apply fixes automatically without review").option("-i, --interactive", "Interactive mode - review each fix").option("-d, --dry-run", "Show fixes without applying").option("-r, --rollback <transactionId>", "Rollback a previous fix transaction").option(
97727
- "--confidence <threshold>",
97728
- "Minimum confidence threshold (0-1)",
97729
- (v) => {
97730
- const parsed = parseFloat(v);
97731
- if (isNaN(parsed) || parsed < 0 || parsed > 1) {
97732
- throw new InvalidArgumentError("Confidence must be a number between 0 and 1");
98532
+ ).option("--spec <path>", "Path to ISL spec file (enables ISL verification)").option("--reality", "Enable Reality Mode (auto-starts your app, runs browser tests)").option("--reality-url <url>", "Use existing server instead of auto-starting").option(
98533
+ "--reality-timeout <seconds>",
98534
+ "Reality Mode timeout in seconds",
98535
+ (v) => parsePositiveInteger(v, "reality-timeout")
98536
+ ).option(
98537
+ "--reality-startup-timeout <seconds>",
98538
+ "Server startup timeout in seconds",
98539
+ (v) => parsePositiveInteger(v, "reality-startup-timeout")
98540
+ ).option("--reality-headless", "Run browser in headless mode", true).option("--no-reality-headless", "Run browser in headed mode (see browser)").option("--chaos", "Enable AI Chaos Agent (autonomous bug hunting)").option("--chaos-aggressive", "Aggressive chaos mode (includes security tests)").option(
98541
+ "--chaos-actions <number>",
98542
+ "Maximum chaos actions to perform",
98543
+ (v) => parsePositiveInteger(v, "chaos-actions")
98544
+ ).option("--chaos-provider <provider>", "AI provider: auto (default), fallback (no AI), ollama (free), anthropic, openai", "auto").option("--chaos-model <model>", "Model to use (default: llava for ollama, gpt-4o for openai)").option("--chaos-url <url>", "Base URL for ollama/local provider (default: http://localhost:11434)").option("--chaos-api-key <key>", "API key for anthropic/openai (or use OPENAI_API_KEY/ANTHROPIC_API_KEY env)").option("--chaos-no-vision", "Disable vision (DOM-only mode, works with any LLM)").option("--detailed", "Show detailed 6-dimension Ship Score breakdown").option("--missions", "Group findings into actionable fix missions").option("--github-pr <number>", "Post results as GitHub PR comment", (v) => parsePositiveInteger(v, "github-pr")).option("--github-repo <repo>", "GitHub repository (owner/repo format)").option("--report", "Generate HTML report and open in browser").action(async (options, command) => {
98545
+ const globalOpts = command.optsWithGlobals();
98546
+ await shipCommand({
98547
+ ...options,
98548
+ mode: options.mode,
98549
+ spec: options.spec,
98550
+ reality: options.reality,
98551
+ realityUrl: options.realityUrl,
98552
+ realityTimeout: options.realityTimeout,
98553
+ realityStartupTimeout: options.realityStartupTimeout,
98554
+ realityHeadless: options.realityHeadless,
98555
+ chaos: options.chaos,
98556
+ chaosAggressive: options.chaosAggressive,
98557
+ chaosActions: options.chaosActions,
98558
+ chaosProvider: options.chaosProvider,
98559
+ chaosModel: options.chaosModel,
98560
+ chaosUrl: options.chaosUrl,
98561
+ chaosApiKey: options.chaosApiKey,
98562
+ chaosNoVision: options.chaosNoVision,
98563
+ detailed: options.detailed,
98564
+ missions: options.missions,
98565
+ githubPr: options.githubPr,
98566
+ githubRepo: options.githubRepo,
98567
+ ...globalOpts
98568
+ });
98569
+ }),
98570
+ "ship"
98571
+ );
98572
+ addCustomHelp(
98573
+ program2.command("certify").description("\u{1F3C6} Final certification: ISL + Reality + Chaos \u2192 Badge (zero setup)").option("--spec <path>", "Path to ISL spec file (auto-generates if missing)").option("--skip-isl", "Skip ISL verification step").option("--skip-reality", "Skip Reality Mode verification").option("--skip-chaos", "Skip Chaos Agent testing").option("--chaos-actions <number>", "Maximum chaos actions to perform", (v) => parsePositiveInteger(v, "chaos-actions")).option("--timeout <seconds>", "Reality Mode timeout in seconds", (v) => parsePositiveInteger(v, "timeout")).option("--headless", "Run browser in headless mode", true).option("--no-headless", "Run browser in headed mode (show browser)").option("-o, --output <path>", "Output directory for proof bundle").option("--threshold <score>", "Minimum score required for certification (default: 85)", (v) => parsePositiveInteger(v, "threshold")).option("--open", "Open report in browser after completion").action(async (options, command) => {
98574
+ const globalOpts = command.optsWithGlobals();
98575
+ await certifyCommand({
98576
+ spec: options.spec,
98577
+ skipIsl: options.skipIsl,
98578
+ skipReality: options.skipReality,
98579
+ skipChaos: options.skipChaos,
98580
+ chaosActions: options.chaosActions,
98581
+ timeout: options.timeout,
98582
+ headless: options.headless,
98583
+ output: options.output,
98584
+ threshold: options.threshold,
98585
+ open: options.open,
98586
+ ...globalOpts
98587
+ });
98588
+ }),
98589
+ "certify"
98590
+ );
98591
+ addCustomHelp(
98592
+ program2.command("verify").description("Full proof loop with runtime verification (alias for certify)").option("--spec <path>", "Path to ISL spec file (auto-generates if missing)").option("--skip-isl", "Skip ISL verification step").option("--skip-reality", "Skip Reality Mode verification").option("--skip-chaos", "Skip Chaos Agent testing").option("--chaos-actions <number>", "Maximum chaos actions to perform", (v) => parsePositiveInteger(v, "chaos-actions")).option("--timeout <seconds>", "Reality Mode timeout in seconds", (v) => parsePositiveInteger(v, "timeout")).option("--headless", "Run browser in headless mode", true).option("--no-headless", "Run browser in headed mode (show browser)").option("-o, --output <path>", "Output directory for proof bundle").option("--threshold <score>", "Minimum score required for certification (default: 85)", (v) => parsePositiveInteger(v, "threshold")).option("--open", "Open report in browser after completion").action(async (options, command) => {
98593
+ const globalOpts = command.optsWithGlobals();
98594
+ await certifyCommand({
98595
+ spec: options.spec,
98596
+ skipIsl: options.skipIsl,
98597
+ skipReality: options.skipReality,
98598
+ skipChaos: options.skipChaos,
98599
+ chaosActions: options.chaosActions,
98600
+ timeout: options.timeout,
98601
+ headless: options.headless,
98602
+ output: options.output,
98603
+ threshold: options.threshold,
98604
+ open: options.open,
98605
+ ...globalOpts
98606
+ });
98607
+ }),
98608
+ "certify"
98609
+ );
98610
+ addCustomHelp(
98611
+ program2.command("status").description("Show current VibeCheck module status").action(async (options, command) => {
98612
+ const globalOpts = command.optsWithGlobals();
98613
+ await statusCommand({
98614
+ ...globalOpts
98615
+ });
98616
+ }),
98617
+ "status"
98618
+ );
98619
+ addCustomHelp(
98620
+ program2.command("fix [files...]").description("Auto-fix simple issues (env vars, empty catches, stubs) - use --missions for complex ones").option("-a, --apply", "Apply fixes automatically without review").option("-i, --interactive", "Interactive mode - review each fix").option("-d, --dry-run", "Show fixes without applying").option("-r, --rollback <transactionId>", "Rollback a previous fix transaction").option(
98621
+ "--confidence <threshold>",
98622
+ "Minimum confidence threshold (0-1)",
98623
+ (v) => {
98624
+ const parsed = parseFloat(v);
98625
+ if (isNaN(parsed) || parsed < 0 || parsed > 1) {
98626
+ throw new InvalidArgumentError("Confidence must be a number between 0 and 1");
98627
+ }
98628
+ return parsed;
97733
98629
  }
97734
- return parsed;
97735
- }
97736
- ).action(async (files, options, command) => {
97737
- const globalOpts = command.optsWithGlobals();
97738
- await fixCommand({
97739
- files: files.length > 0 ? files : void 0,
97740
- ...options,
97741
- ...globalOpts
97742
- });
97743
- });
97744
- program2.command("report").description("Generate enterprise-grade HTML/PDF reports").option(
97745
- "-t, --type <type>",
97746
- "Report type (reality-check, ship-readiness, executive-summary, detailed-technical, compliance)",
97747
- (value) => {
97748
- const valid = ["reality-check", "ship-readiness", "executive-summary", "detailed-technical", "compliance"];
97749
- if (!valid.includes(value)) {
97750
- throw new InvalidArgumentError(`Report type must be one of: ${valid.join(", ")}`);
97751
- }
97752
- return value;
97753
- }
97754
- ).option(
97755
- "-f, --format <format>",
97756
- "Output format (html, pdf)",
97757
- (value) => {
97758
- const valid = ["html", "pdf"];
97759
- if (!valid.includes(value)) {
97760
- throw new InvalidArgumentError(`Format must be one of: ${valid.join(", ")}`);
97761
- }
97762
- return value;
97763
- }
97764
- ).option("-o, --output <path>", "Output file path", validatePath).option(
97765
- "--theme <theme>",
97766
- "Color theme (dark, light)",
97767
- (value) => {
97768
- const valid = ["dark", "light"];
97769
- if (!valid.includes(value)) {
97770
- throw new InvalidArgumentError(`Theme must be one of: ${valid.join(", ")}`);
97771
- }
97772
- return value;
97773
- }
97774
- ).option("--branding <name>", "Company name for report branding").option("--open", "Open report in browser after generation").action(async (options, command) => {
97775
- const globalOpts = command.optsWithGlobals();
97776
- await reportCommand({
97777
- ...options,
97778
- ...globalOpts
97779
- });
97780
- });
97781
- program2.command("badge").description("Generate Ship Score badge embed codes for README").option("-p, --project-id <id>", "Project ID from dashboard").option(
97782
- "-s, --style <style>",
97783
- "Badge style (flat, flat-square, plastic, for-the-badge)",
97784
- (value) => {
97785
- const valid = ["flat", "flat-square", "plastic", "for-the-badge"];
97786
- if (!valid.includes(value)) {
97787
- throw new InvalidArgumentError(`Style must be one of: ${valid.join(", ")}`);
97788
- }
97789
- return value;
97790
- }
97791
- ).option(
97792
- "-f, --format <format>",
97793
- "Output format (markdown, html, url)",
97794
- (value) => {
97795
- const valid = ["markdown", "html", "url"];
97796
- if (!valid.includes(value)) {
97797
- throw new InvalidArgumentError(`Format must be one of: ${valid.join(", ")}`);
97798
- }
97799
- return value;
97800
- }
97801
- ).action(async (options, command) => {
97802
- const globalOpts = command.optsWithGlobals();
97803
- await badgeCommand({
97804
- projectId: options.projectId,
97805
- style: options.style,
97806
- format: options.format,
97807
- ...globalOpts
97808
- });
97809
- });
97810
- program2.command("menu").description("Open interactive menu").action(async () => {
97811
- await runInteractiveMode();
97812
- });
98630
+ ).action(async (files, options, command) => {
98631
+ const globalOpts = command.optsWithGlobals();
98632
+ await fixCommand({
98633
+ files: files.length > 0 ? files : void 0,
98634
+ ...options,
98635
+ ...globalOpts
98636
+ });
98637
+ }),
98638
+ "fix"
98639
+ );
98640
+ addCustomHelp(
98641
+ program2.command("report").description("Generate enterprise-grade HTML/PDF reports").option(
98642
+ "-t, --type <type>",
98643
+ "Report type (reality-check, ship-readiness, executive-summary, detailed-technical, compliance)",
98644
+ (value) => {
98645
+ const valid = ["reality-check", "ship-readiness", "executive-summary", "detailed-technical", "compliance"];
98646
+ if (!valid.includes(value)) {
98647
+ throw new InvalidArgumentError(`Report type must be one of: ${valid.join(", ")}`);
98648
+ }
98649
+ return value;
98650
+ }
98651
+ ).option(
98652
+ "-f, --format <format>",
98653
+ "Output format (html, pdf)",
98654
+ (value) => {
98655
+ const valid = ["html", "pdf"];
98656
+ if (!valid.includes(value)) {
98657
+ throw new InvalidArgumentError(`Format must be one of: ${valid.join(", ")}`);
98658
+ }
98659
+ return value;
98660
+ }
98661
+ ).option("-o, --output <path>", "Output file path", validatePath).option(
98662
+ "--theme <theme>",
98663
+ "Color theme (dark, light)",
98664
+ (value) => {
98665
+ const valid = ["dark", "light"];
98666
+ if (!valid.includes(value)) {
98667
+ throw new InvalidArgumentError(`Theme must be one of: ${valid.join(", ")}`);
98668
+ }
98669
+ return value;
98670
+ }
98671
+ ).option("--branding <name>", "Company name for report branding").option("--open", "Open report in browser after generation").action(async (options, command) => {
98672
+ const globalOpts = command.optsWithGlobals();
98673
+ await reportCommand({
98674
+ ...options,
98675
+ ...globalOpts
98676
+ });
98677
+ }),
98678
+ "report"
98679
+ );
98680
+ addCustomHelp(
98681
+ program2.command("badge").description("Generate Ship Score badge embed codes for README").option("-p, --project-id <id>", "Project ID from dashboard").option(
98682
+ "-s, --style <style>",
98683
+ "Badge style (flat, flat-square, plastic, for-the-badge)",
98684
+ (value) => {
98685
+ const valid = ["flat", "flat-square", "plastic", "for-the-badge"];
98686
+ if (!valid.includes(value)) {
98687
+ throw new InvalidArgumentError(`Style must be one of: ${valid.join(", ")}`);
98688
+ }
98689
+ return value;
98690
+ }
98691
+ ).option(
98692
+ "-f, --format <format>",
98693
+ "Output format (markdown, html, url)",
98694
+ (value) => {
98695
+ const valid = ["markdown", "html", "url"];
98696
+ if (!valid.includes(value)) {
98697
+ throw new InvalidArgumentError(`Format must be one of: ${valid.join(", ")}`);
98698
+ }
98699
+ return value;
98700
+ }
98701
+ ).action(async (options, command) => {
98702
+ const globalOpts = command.optsWithGlobals();
98703
+ await badgeCommand({
98704
+ projectId: options.projectId,
98705
+ style: options.style,
98706
+ format: options.format,
98707
+ ...globalOpts
98708
+ });
98709
+ }),
98710
+ "badge"
98711
+ );
98712
+ addCustomHelp(
98713
+ program2.command("menu").description("Open interactive menu").action(async () => {
98714
+ await runInteractiveMode();
98715
+ }),
98716
+ "menu"
98717
+ );
97813
98718
  program2.command("login").description("Login to VibeCheck Cloud").action(async () => {
97814
98719
  const session = await showLoginScreen();
97815
98720
  if (session) {
@@ -97827,10 +98732,7 @@ program2.command("logout").description("Logout from VibeCheck Cloud").action(asy
97827
98732
  printSuccess("Logged out successfully. See you next time!");
97828
98733
  });
97829
98734
  program2.helpOption("-h, --help", "Display gorgeous help");
97830
- program2.on("option:help", () => {
97831
- renderHelp();
97832
- process.exit(0);
97833
- });
98735
+ program2.helpInformation = () => getMainHelpText();
97834
98736
  program2.action(async () => {
97835
98737
  await runInteractiveMode();
97836
98738
  });
@@ -97844,12 +98746,16 @@ async function runInteractiveMode() {
97844
98746
  try {
97845
98747
  switch (selection) {
97846
98748
  // ═══════════════════════════════════════════════════════════════════════
97847
- // THE FLOW
98749
+ // SETUP & FLOW
97848
98750
  // ═══════════════════════════════════════════════════════════════════════
98751
+ case "link":
98752
+ await initCommand({ ...globalOpts });
98753
+ break;
97849
98754
  case "quickstart":
97850
98755
  await quickstartCommand({ ...globalOpts });
97851
98756
  break;
97852
98757
  case "certify":
98758
+ case "verify":
97853
98759
  await certifyCommand({ open: true, ...globalOpts });
97854
98760
  break;
97855
98761
  case "status":
@@ -97876,6 +98782,9 @@ async function runInteractiveMode() {
97876
98782
  case "scan":
97877
98783
  await scanCommand({ ...globalOpts });
97878
98784
  break;
98785
+ case "audit":
98786
+ await auditCommand([], { ...globalOpts, mode: "full" });
98787
+ break;
97879
98788
  case "forge":
97880
98789
  await forgeCommand.parseAsync(["forge"], { from: "user" });
97881
98790
  break;
@@ -97891,6 +98800,9 @@ async function runInteractiveMode() {
97891
98800
  case "doctor":
97892
98801
  await doctorCommand({ ...globalOpts });
97893
98802
  break;
98803
+ case "login":
98804
+ await showLoginScreen();
98805
+ break;
97894
98806
  case "help":
97895
98807
  renderHelp();
97896
98808
  break;