@viberaven/cli 1.4.2 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -11558,7 +11558,7 @@ var VERSION;
11558
11558
  var init_version = __esm({
11559
11559
  "src/version.ts"() {
11560
11560
  "use strict";
11561
- VERSION = "1.4.2";
11561
+ VERSION = "1.4.4";
11562
11562
  }
11563
11563
  });
11564
11564
 
@@ -15468,6 +15468,7 @@ function providerStatusText(state) {
15468
15468
  case "connect_live":
15469
15469
  return "Connect live";
15470
15470
  case "not_detected":
15471
+ return "Not detected";
15471
15472
  default:
15472
15473
  return "Missing";
15473
15474
  }
@@ -15488,6 +15489,16 @@ function verifyActionForGap(gap) {
15488
15489
  };
15489
15490
  }
15490
15491
  function proofForProvider(providerId, gap) {
15492
+ if (providerId === "posthog") {
15493
+ return {
15494
+ level: "dashboard_needed",
15495
+ summary: "PostHog dashboard ingestion can only be confirmed in the PostHog dashboard, not from repo code.",
15496
+ checks: [
15497
+ { label: "Code found", status: "yes", source: "repo" },
15498
+ { label: "Dashboard ingestion proof", status: "unknown", source: "dashboard" }
15499
+ ]
15500
+ };
15501
+ }
15491
15502
  if (!gap) {
15492
15503
  return {
15493
15504
  level: "code_only",
@@ -15518,6 +15529,8 @@ function whereToClick(providerId) {
15518
15529
  return "Table editor -> select table -> Policies -> Enable RLS";
15519
15530
  case "vercel":
15520
15531
  return "Project settings -> Environment variables -> Production";
15532
+ case "posthog":
15533
+ return "Data management -> Events";
15521
15534
  default:
15522
15535
  return "Open provider dashboard -> complete the selected production action";
15523
15536
  }
@@ -15541,6 +15554,12 @@ function youLane(providerId, providerName, gap) {
15541
15554
  body: "Open Vercel and confirm the production environment, deployment, or domain setting that blocks launch."
15542
15555
  };
15543
15556
  }
15557
+ if (providerId === "posthog") {
15558
+ return {
15559
+ title: "Confirm PostHog dashboard ingestion",
15560
+ body: "Open PostHog and confirm live events are arriving from production. Repo code alone cannot prove ingestion."
15561
+ };
15562
+ }
15544
15563
  return {
15545
15564
  title: `Confirm ${providerName} provider proof`,
15546
15565
  body: gap?.detail ?? `Open ${providerName} and complete the selected production action.`
@@ -15767,9 +15786,19 @@ function emptyLocalUiState(cwd) {
15767
15786
  empty: true
15768
15787
  };
15769
15788
  }
15770
- function mapArtifactToLocalUiState(artifact) {
15789
+ function mapArtifactToLocalUiState(artifact, presentProviderIds) {
15771
15790
  const projectName = projectNameFromPath(artifact.workspacePath);
15772
- const providers = listLocalUiProviderCatalog().map((template) => mapProvider(template, artifact, projectName)).map((provider2) => ({ ...provider2, grade: providerGrade(provider2) }));
15791
+ const providers = listLocalUiProviderCatalog().map((template) => mapProvider(template, artifact, projectName)).map((provider2) => {
15792
+ if (presentProviderIds && !presentProviderIds.has(provider2.id)) {
15793
+ const missing = {
15794
+ ...provider2,
15795
+ state: "not_detected",
15796
+ statusText: providerStatusText("not_detected")
15797
+ };
15798
+ return { ...missing, grade: providerGrade(missing) };
15799
+ }
15800
+ return { ...provider2, grade: providerGrade(provider2) };
15801
+ });
15773
15802
  const globalProviderId = providerIdForGap(primaryGap(artifact));
15774
15803
  const selectedProvider = providers.find((provider2) => provider2.id === globalProviderId) ?? providers.find((provider2) => provider2.state === "needs_repo_fix") ?? providers.find((provider2) => provider2.state === "repo_evidence_found") ?? providers[0];
15775
15804
  const missionCards = buildMissionCards(artifact, providers);
@@ -16223,7 +16252,7 @@ function providerHealth(raw, normalized) {
16223
16252
  const allReady = total > 0 && ready === total;
16224
16253
  const summary = providerScopedDetail(raw || normalized || {});
16225
16254
  if (state === 'not_detected') {
16226
- return { label: 'Missing', tone: 'orange', summary, meta: 'Not linked' };
16255
+ return { label: 'Not detected', tone: 'orange', summary, meta: 'Not in this project' };
16227
16256
  }
16228
16257
  if (state === 'live_verified') {
16229
16258
  return { label: 'Ready', tone: 'green', summary, meta: checks + ' checks' };
@@ -16242,7 +16271,7 @@ function providerHealth(raw, normalized) {
16242
16271
 
16243
16272
  function providerHealthIcon(health) {
16244
16273
  if (health.tone === 'green' && (health.label === 'Ready' || health.label === 'Detected')) return Icon('heart');
16245
- if (health.label === 'Missing') return Icon('flag');
16274
+ if (health.label === 'Not detected') return Icon('flag');
16246
16275
  return Icon('refresh');
16247
16276
  }
16248
16277
 
@@ -16326,6 +16355,19 @@ function TradingCard(provider, variant, options) {
16326
16355
  const placedClass = opts.placed ? ' is-placed' : '';
16327
16356
  const tagOpen = opts.asDiv ? 'div' : 'button type="button"';
16328
16357
  const tagClose = opts.asDiv ? 'div' : 'button';
16358
+ if (provider.state === 'not_detected') {
16359
+ // Locked card: the provider isn't in this project. Keep the logo (dimmed)
16360
+ // behind a lock seal so you can see which provider it is and that it's
16361
+ // there to unlock by adding it \u2014 never a fake grade or a blank back.
16362
+ return '<' + tagOpen + ' class="vr-tcard is-locked ' + size + placedClass + '" data-foil="' + foil + '"' +
16363
+ (opts.asDiv ? '' : ' data-action="deal-provider" data-provider="' + foil + '" aria-label="' + escapeHtml(provider.name) + ' is not in this project \u2014 add it to unlock this card" title="' + escapeHtml(provider.name) + ' \xB7 not in this project \u2014 add to unlock"') +
16364
+ (opts.style ? ' style="' + opts.style + '"' : '') + '>' +
16365
+ (opts.placed ? '<span class="vr-tcard-unplace" data-action="unplace-card" data-unplace="' + foil + '" title="Remove from the table" role="button" aria-label="Remove from the table">&#10005;</span>' : '') +
16366
+ '<span class="vr-tcard-lockart">' + ProviderToken(provider, 'is-locked') + '<span class="vr-tcard-lockbadge">' + Icon('lock') + '</span></span>' +
16367
+ '<span class="vr-tcard-backname">' + escapeHtml(provider.name) + '</span>' +
16368
+ '<span class="vr-tcard-lockhint">Not in this project</span>' +
16369
+ '</' + tagClose + '>';
16370
+ }
16329
16371
  if (grade.tier === 'facedown' && !opts.forceFace) {
16330
16372
  return '<' + tagOpen + ' class="vr-tcard is-back ' + size + placedClass + '"' +
16331
16373
  (opts.asDiv ? '' : ' data-action="deal-provider" data-provider="' + foil + '" aria-label="Flip ' + escapeHtml(provider.name) + ' \u2014 run its first checks" title="' + escapeHtml(provider.name) + ' \xB7 face down \u2014 click to flip"') +
@@ -18309,8 +18351,8 @@ function DiscoveryModal() {
18309
18351
  return '<div class="vr-discover-card' + (demo.flippedCards['disc:' + provider.id] ? ' is-flipped' : '') + '" data-flip-card data-flip-id="disc:' + escapeHtml(provider.id) + '" data-rank="' + rank[0] + '" style="--vr-i:' + String(index) + '">' +
18310
18352
  '<span class="vr-flip-inner">' +
18311
18353
  '<span class="vr-flip-back vr-tcard is-back is-dealt" data-action="flip-discover" role="button" tabindex="0" aria-label="Flip to reveal ' + escapeHtml(provider.name) + '">' +
18312
- '<span class="vr-tcard-backart"><img src="' + mascotAssets.idle + '" alt="" /></span>' +
18313
- '<span class="vr-tcard-backname">FLIP ME</span>' +
18354
+ '<span class="vr-tcard-backart"><span class="vr-pack-seal" aria-hidden="true">&#10022;</span></span>' +
18355
+ '<span class="vr-tcard-backname">Flip to reveal</span>' +
18314
18356
  '</span>' +
18315
18357
  '<span class="vr-flip-face">' +
18316
18358
  TradingCard(provider, 'dealt', { asDiv: true, forceFace: true }) +
@@ -19641,17 +19683,47 @@ function ChatEnvironmentConnectCard() {
19641
19683
  const slotHtml = slots.map((slot) => {
19642
19684
  const provider = slot.providerId ? providers.find((item) => item.id === slot.providerId) : null;
19643
19685
  const mcp = provider ? providerMcp(provider) : null;
19644
- const connected = Boolean(mcp && mcp.status === 'connected');
19686
+ // Two independent facts, and the panel used to collapse them into one. MCP
19687
+ // status comes from the user's global config (~/.codex/config.toml), so it
19688
+ // says "connected" for providers this repo does not use \u2014 which contradicted
19689
+ // the card next to it reading actual repo evidence. Project membership wins:
19690
+ // never claim a provider is wired up when it is not in this project.
19691
+ const inProject = Boolean(provider && provider.state !== 'not_detected');
19692
+ const mcpConnected = Boolean(mcp && mcp.status === 'connected');
19693
+ const connected = inProject && mcpConnected;
19645
19694
  const icon = provider
19646
19695
  ? (provider.iconHtml || '<img src="' + providerAssetSrc(provider) + '" alt="" />')
19647
19696
  : Icon('plus');
19648
- const status = connected ? 'Connected' : slot.action === 'more' ? 'Browse' : 'Connect';
19697
+ const tone = slot.action === 'more'
19698
+ ? 'is-browse'
19699
+ : !inProject
19700
+ ? 'is-absent'
19701
+ : connected
19702
+ ? 'is-connected'
19703
+ : 'is-disconnected';
19704
+ const status = slot.action === 'more'
19705
+ ? 'Browse'
19706
+ : !inProject
19707
+ ? 'Not in project'
19708
+ : connected
19709
+ ? 'Connected'
19710
+ : 'Connect';
19711
+ const hint = slot.action === 'more'
19712
+ ? 'Browse every provider card'
19713
+ : !inProject
19714
+ ? slot.label + ' was not found in this repo' + (mcpConnected ? ', even though its MCP server is in your global config' : '')
19715
+ : connected
19716
+ ? slot.label + ' is in this repo and chat can read its live state'
19717
+ : slot.label + ' is in this repo. Connect MCP so chat reads live state instead of guessing.';
19718
+ // A provider that is not in the repo has nothing to connect, so send that
19719
+ // click to the provider context flow (which prefills the "help me add it"
19720
+ // mission) rather than an MCP connect that would not mean anything.
19649
19721
  const attrs = slot.action === 'more'
19650
19722
  ? 'data-action="add-provider"'
19651
- : connected
19723
+ : connected || !inProject
19652
19724
  ? 'data-provider="' + escapeHtml(slot.providerId) + '"'
19653
19725
  : 'data-action="connect-mcp" data-provider-id="' + escapeHtml(slot.providerId) + '"';
19654
- return '<button type="button" class="vr-env-connect-option ' + (connected ? 'is-connected' : 'is-disconnected') + '" ' + attrs + '>' +
19726
+ return '<button type="button" class="vr-env-connect-option ' + tone + '" ' + attrs + ' title="' + escapeHtml(hint) + '">' +
19655
19727
  '<span>' + icon + '</span>' +
19656
19728
  '<strong>' + escapeHtml(slot.label) + '</strong>' +
19657
19729
  '<b>' + escapeHtml(status) + '</b>' +
@@ -19874,9 +19946,20 @@ function TablePlaque() {
19874
19946
  const graded = detected.filter((item) => item.grade && typeof item.grade.value === 'number');
19875
19947
  const avg = graded.length ? graded.reduce((sum, item) => sum + item.grade.value, 0) / graded.length : 0;
19876
19948
  const dirty = (demo.worktree && Number(demo.worktree.dirtyCount)) || 0;
19949
+ // Two different numbers used to sit here unlabelled: the average provider card
19950
+ // grade (0-10) and, in the terminal, the gate score (0-100). A repo could read
19951
+ // "GRADE 0.0" here and "score 65" from viberaven check with nothing saying
19952
+ // they measure different things. Both now carry their scale, and the gate score
19953
+ // is shown so the header and the terminal agree on the headline verdict.
19954
+ const gateScore = typeof gate.score === 'number' ? gate.score : null;
19877
19955
  const cells = [
19878
19956
  { label: 'Providers', value: String(detected.length), tone: 'gold' },
19879
- { label: 'Grade', value: graded.length ? avg.toFixed(1) : '&#8212;', tone: 'gold' },
19957
+ {
19958
+ label: 'Gate score /100',
19959
+ value: gateScore == null ? '&#8212;' : String(gateScore),
19960
+ tone: gateClear ? 'green' : gateScore == null ? 'muted' : 'orange',
19961
+ },
19962
+ { label: 'Grade /10', value: graded.length ? avg.toFixed(1) : '&#8212;', tone: 'gold' },
19880
19963
  { label: 'Review', value: String(review), tone: review > 0 ? 'orange' : 'muted' },
19881
19964
  { label: 'Uncommitted', value: String(dirty), tone: dirty > 0 ? 'orange' : 'green' },
19882
19965
  ];
@@ -30976,6 +31059,17 @@ body:has(.vr-app.is-dragging) {
30976
31059
  color: #86efac;
30977
31060
  }
30978
31061
 
31062
+ /* Not in this repo. Same orange the provider cards use for "Not detected", so
31063
+ the panel and the card agree instead of contradicting each other. */
31064
+ .vr-env-connect-option.is-absent b {
31065
+ background: rgba(148, 163, 184, 0.08);
31066
+ color: #94a3b8;
31067
+ }
31068
+
31069
+ .vr-env-connect-option.is-absent > span {
31070
+ opacity: 0.5;
31071
+ }
31072
+
30979
31073
  /* Gate chip is a button now \xE2\u20AC\u201D keep the pill look. */
30980
31074
  button.vr-chat-gate-chip {
30981
31075
  cursor: pointer;
@@ -35122,7 +35216,9 @@ button.vr-chat-gate-chip.vr-stamp i { display: none; }
35122
35216
  .vr-start-here-cta:hover { background: #e6e9ef; }
35123
35217
  .vr-start-here-cta:active { transform: translateY(2px); box-shadow: 0 1px 0 rgba(0, 0, 0, 0.55); }
35124
35218
  .vr-start-here-cta svg { stroke: #0a0b0e; color: #0a0b0e; }
35125
- .vr-start-here-cta span { color: #0a0b0e; }
35219
+ .vr-start-here-cta,
35220
+ .vr-start-here-cta span { font-family: Geist, Inter, "Segoe UI", system-ui, sans-serif !important; }
35221
+ .vr-start-here-cta span { color: #0a0b0e; letter-spacing: 0.02em; text-transform: none; font-weight: 700; }
35126
35222
 
35127
35223
  /* ==========================================================================
35128
35224
  HUD layer: manga ink pass \u2014 the perceptual redesign.
@@ -37908,6 +38004,99 @@ button.vr-tcard { appearance: none; }
37908
38004
  drop-shadow(0 5px 12px rgba(0, 0, 0, 0.65))
37909
38005
  drop-shadow(0 0 22px rgba(232, 193, 90, 0.65));
37910
38006
  }
38007
+ /* Locked card: a provider that is not in this project. Dimmed logo + gold
38008
+ lock seal, dashed inner frame (vs the solid frame of a graded card). */
38009
+ .vr-tcard.is-locked {
38010
+ position: relative;
38011
+ border: 2.5px solid rgba(184, 135, 63, 0.5);
38012
+ padding: 0;
38013
+ gap: 0;
38014
+ display: flex;
38015
+ flex-direction: column;
38016
+ align-items: center;
38017
+ justify-content: flex-end;
38018
+ background:
38019
+ radial-gradient(circle at 50% 40%, rgba(232, 193, 90, 0.08), transparent 55%),
38020
+ conic-gradient(from 210deg at 50% 46%, #141418, #1b1b21 22%, #141419 48%, #191922 74%, #141418),
38021
+ #0b0b0f;
38022
+ }
38023
+ .vr-tcard.is-locked::after {
38024
+ content: '';
38025
+ position: absolute;
38026
+ inset: 5px;
38027
+ border: 1.5px dashed rgba(232, 193, 90, 0.26);
38028
+ border-radius: 7px;
38029
+ pointer-events: none;
38030
+ }
38031
+ .vr-tcard.is-locked .vr-tcard-lockart {
38032
+ position: relative;
38033
+ flex: 1;
38034
+ width: 100%;
38035
+ display: grid;
38036
+ place-items: center;
38037
+ }
38038
+ .vr-tcard.is-locked .vr-provider-token {
38039
+ width: 48%;
38040
+ opacity: 0.35;
38041
+ filter: grayscale(1) brightness(1.3);
38042
+ }
38043
+ .vr-tcard.is-locked .vr-provider-token svg,
38044
+ .vr-tcard.is-locked .vr-provider-token img {
38045
+ width: 100%;
38046
+ height: auto;
38047
+ }
38048
+ .vr-tcard.is-locked .vr-tcard-lockbadge {
38049
+ position: absolute;
38050
+ top: 50%;
38051
+ left: 50%;
38052
+ transform: translate(-50%, -50%);
38053
+ width: 30%;
38054
+ aspect-ratio: 1 / 1;
38055
+ display: grid;
38056
+ place-items: center;
38057
+ border-radius: 50%;
38058
+ color: #e8c15a;
38059
+ background: radial-gradient(circle at 42% 34%, #2b2b34, #121216);
38060
+ border: 1.5px solid rgba(232, 193, 90, 0.6);
38061
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 0 8px rgba(232, 193, 90, 0.15);
38062
+ }
38063
+ .vr-tcard.is-locked .vr-tcard-lockbadge svg {
38064
+ width: 52%;
38065
+ height: 52%;
38066
+ }
38067
+ .vr-tcard.is-locked .vr-tcard-lockhint {
38068
+ font-size: 7.5px;
38069
+ letter-spacing: 0.2px;
38070
+ text-transform: uppercase;
38071
+ font-weight: 800;
38072
+ color: #2a1c02;
38073
+ text-shadow: 0 1px 0 rgba(255, 245, 205, 0.45);
38074
+ margin-bottom: 6px;
38075
+ }
38076
+ .vr-tcard.is-locked .vr-tcard-backname {
38077
+ margin-bottom: 3px;
38078
+ font-size: 10px;
38079
+ letter-spacing: 0.3px;
38080
+ font-weight: 800;
38081
+ color: #1a1201;
38082
+ text-shadow: 0 1px 0 rgba(255, 245, 205, 0.45);
38083
+ }
38084
+ .vr-tcard.is-locked:hover {
38085
+ border-color: rgba(232, 193, 90, 0.7);
38086
+ }
38087
+ .vr-tcard.is-locked:hover .vr-provider-token {
38088
+ opacity: 0.5;
38089
+ }
38090
+ .vr-tcard.is-locked:hover .vr-tcard-lockbadge {
38091
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.6), 0 0 14px rgba(232, 193, 90, 0.4), inset 0 0 8px rgba(232, 193, 90, 0.2);
38092
+ }
38093
+ /* Pack card back: a sealed mystery \u2014 no provider identity until you flip. */
38094
+ .vr-discover-card .vr-flip-back .vr-pack-seal {
38095
+ font-size: 34px;
38096
+ line-height: 1;
38097
+ color: rgba(232, 193, 90, 0.5);
38098
+ text-shadow: 0 0 18px rgba(232, 193, 90, 0.4);
38099
+ }
37911
38100
  /* inside a flip card the back must stay an absolute overlay \u2014 the
37912
38101
  position: relative above would otherwise stack it under the face */
37913
38102
  [data-flip-card] .vr-flip-back,
@@ -40241,25 +40430,25 @@ function hasFile(files, needles) {
40241
40430
  function providerDetected(providerId, deps, files) {
40242
40431
  switch (providerId) {
40243
40432
  case "supabase":
40244
- return hasDependency(deps, ["@supabase/supabase-js", "supabase"]) || hasFile(files, ["supabase/", "supabase\\", "supabase.ts"]);
40433
+ return hasDependency(deps, ["@supabase/supabase-js", "@supabase/ssr", "supabase"]) || hasFile(files, ["supabase/", "supabase.ts"]);
40245
40434
  case "vercel":
40246
- return hasFile(files, ["vercel.json", ".vercel/project.json"]) || hasDependency(deps, ["@vercel/"]);
40435
+ return hasDependency(deps, ["@vercel/"]) || hasFile(files, ["vercel.json", ".vercel/project.json"]);
40247
40436
  case "stripe":
40248
- return hasDependency(deps, ["stripe", "@stripe/stripe-js"]) || hasFile(files, ["stripe", "webhook"]);
40437
+ return hasDependency(deps, ["stripe", "@stripe/stripe-js"]) || hasFile(files, ["stripe."]);
40249
40438
  case "github":
40250
- return hasFile(files, [".github/workflows", ".github/dependabot.yml"]) || files.includes("readme.md");
40439
+ return hasFile(files, [".github/workflows", ".github/dependabot.yml"]);
40251
40440
  case "sentry":
40252
- return hasDependency(deps, ["@sentry/"]) || hasFile(files, ["sentry.", "instrumentation.ts", "instrumentation.js"]);
40441
+ return hasDependency(deps, ["@sentry/"]) || hasFile(files, ["sentry."]);
40253
40442
  case "posthog":
40254
- return hasDependency(deps, ["posthog", "posthog-js"]) || hasFile(files, ["posthog"]);
40443
+ return hasDependency(deps, ["posthog", "posthog-js", "posthog-node"]) || hasFile(files, ["posthog."]);
40255
40444
  case "clerk":
40256
- return hasDependency(deps, ["@clerk/"]) || hasFile(files, ["clerk", "middleware.ts", "middleware.js"]);
40445
+ return hasDependency(deps, ["@clerk/"]) || hasFile(files, ["clerk."]);
40257
40446
  case "authjs":
40258
- return hasDependency(deps, ["next-auth", "@auth/"]) || hasFile(files, ["auth.ts", "auth.js", "nextauth"]);
40447
+ return hasDependency(deps, ["next-auth", "@auth/"]) || hasFile(files, ["nextauth", "auth.config."]);
40259
40448
  case "resend":
40260
- return hasDependency(deps, ["resend"]) || hasFile(files, ["resend", "email", "mail"]);
40449
+ return hasDependency(deps, ["resend"]) || hasFile(files, ["resend."]);
40261
40450
  case "upstash":
40262
- return hasDependency(deps, ["@upstash/", "upstash"]) || hasFile(files, ["upstash", "ratelimit", "rate-limit", "redis"]);
40451
+ return hasDependency(deps, ["@upstash/", "upstash"]);
40263
40452
  default:
40264
40453
  return false;
40265
40454
  }
@@ -40284,7 +40473,7 @@ function applyProviderDetection(state, deps, files) {
40284
40473
  return {
40285
40474
  ...provider2,
40286
40475
  state: providerState2,
40287
- statusText: detected ? "Detected in repo" : "Missing",
40476
+ statusText: detected ? "Detected in repo" : "Not detected",
40288
40477
  connectLabel: detected ? "Open slot" : "Add provider",
40289
40478
  launchPath: provider2.launchPath.map((item4, index) => ({
40290
40479
  ...item4,
@@ -40760,7 +40949,11 @@ async function readState(cwd) {
40760
40949
  let state;
40761
40950
  try {
40762
40951
  const raw = await (0, import_promises23.readFile)((0, import_node_path30.join)(cwd, ".viberaven", "last-scan.json"), "utf8");
40763
- state = mapArtifactToLocalUiState(JSON.parse(raw));
40952
+ const packageJson = await readPackageJson(cwd);
40953
+ const deps = dependencyNames(packageJson);
40954
+ const files = await listProjectFiles(cwd);
40955
+ const present = new Set(PROVIDER_IDS.filter((id) => providerDetected(id, deps, files)));
40956
+ state = mapArtifactToLocalUiState(JSON.parse(raw), present);
40764
40957
  } catch {
40765
40958
  state = emptyLocalUiState(cwd);
40766
40959
  }
@@ -41911,7 +42104,7 @@ async function waitForServerShutdown() {
41911
42104
  process.once("SIGTERM", done);
41912
42105
  });
41913
42106
  }
41914
- var import_node_http, import_node_child_process4, import_promises23, import_node_path30, CLI_AGENT_SETUP, MCP_CONFIG_PATHS, MCP_PROVIDER_NEEDLES, MCP_CONNECT_COMMANDS, MCP_SERVER_RECIPES, CLI_AUTH_PROBE;
42107
+ var import_node_http, import_node_child_process4, import_promises23, import_node_path30, CLI_AGENT_SETUP, MCP_CONFIG_PATHS, MCP_PROVIDER_NEEDLES, MCP_CONNECT_COMMANDS, MCP_SERVER_RECIPES, PROVIDER_IDS, CLI_AUTH_PROBE;
41915
42108
  var init_server = __esm({
41916
42109
  "src/local-ui/server.ts"() {
41917
42110
  "use strict";
@@ -42025,6 +42218,7 @@ var init_server = __esm({
42025
42218
  note: "Set UPSTASH_EMAIL and UPSTASH_API_KEY in your shell before the agent starts."
42026
42219
  }
42027
42220
  };
42221
+ PROVIDER_IDS = ["supabase", "vercel", "stripe", "github", "sentry", "posthog", "clerk", "authjs", "resend", "upstash"];
42028
42222
  CLI_AUTH_PROBE = {
42029
42223
  codex: "codex login status",
42030
42224
  claude: "claude auth status",