@atlasharness/atlascode 0.1.45 → 0.1.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +859 -566
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -71153,7 +71153,7 @@ var init_sendMessageTool = __esm(() => {
71153
71153
  if (!getReplBridgeHandle() || !isReplBridgeActive()) {
71154
71154
  return {
71155
71155
  result: false,
71156
- message: "Remote Control is not connected — cannot send to a bridge: target. Reconnect with /remote-control first.",
71156
+ message: "Remote Control is not connected — cannot send to a bridge: target.",
71157
71157
  errorCode: 9
71158
71158
  };
71159
71159
  }
@@ -310349,7 +310349,7 @@ var init_SendMessageTool = __esm(() => {
310349
310349
  if (!getReplBridgeHandle2() || !isReplBridgeActive2()) {
310350
310350
  return {
310351
310351
  result: false,
310352
- message: "Remote Control is not connected — cannot send to a bridge: target. Reconnect with /remote-control first.",
310352
+ message: "Remote Control is not connected — cannot send to a bridge: target.",
310353
310353
  errorCode: 9
310354
310354
  };
310355
310355
  }
@@ -329593,13 +329593,28 @@ async function saveKnownMarketplacesConfig(config) {
329593
329593
  flush: true
329594
329594
  });
329595
329595
  }
329596
+ function updateKnownMarketplacesConfig(mutator) {
329597
+ const run = knownMarketplacesRmwChain.then(async () => {
329598
+ const config = await loadKnownMarketplacesConfig();
329599
+ const next = await mutator(config);
329600
+ if (next !== undefined) {
329601
+ await saveKnownMarketplacesConfig(next);
329602
+ }
329603
+ return next;
329604
+ });
329605
+ knownMarketplacesRmwChain = run.then(() => {
329606
+ return;
329607
+ }, () => {
329608
+ return;
329609
+ });
329610
+ return run;
329611
+ }
329596
329612
  async function registerSeedMarketplaces() {
329597
329613
  const seedDirs = getPluginSeedDirs();
329598
329614
  if (seedDirs.length === 0)
329599
329615
  return false;
329600
- const primary = await loadKnownMarketplacesConfig();
329601
329616
  const claimed = new Set;
329602
- let changed = 0;
329617
+ const desired = [];
329603
329618
  for (const seedDir of seedDirs) {
329604
329619
  const seedConfig = await readSeedKnownMarketplaces(seedDir);
329605
329620
  if (!seedConfig)
@@ -329613,20 +329628,28 @@ async function registerSeedMarketplaces() {
329613
329628
  continue;
329614
329629
  }
329615
329630
  claimed.add(name);
329616
- const desired = {
329631
+ const entry = {
329617
329632
  source: seedEntry.source,
329618
329633
  installLocation: resolvedLocation,
329619
329634
  lastUpdated: seedEntry.lastUpdated,
329620
329635
  autoUpdate: false
329621
329636
  };
329622
- if (isEqual_default(primary[name], desired))
329637
+ desired.push({ name, desired: entry });
329638
+ }
329639
+ }
329640
+ if (desired.length === 0)
329641
+ return false;
329642
+ let changed = 0;
329643
+ await updateKnownMarketplacesConfig((primary) => {
329644
+ for (const { name, desired: entry } of desired) {
329645
+ if (isEqual_default(primary[name], entry))
329623
329646
  continue;
329624
- primary[name] = desired;
329647
+ primary[name] = entry;
329625
329648
  changed++;
329626
329649
  }
329627
- }
329650
+ return changed > 0 ? primary : undefined;
329651
+ });
329628
329652
  if (changed > 0) {
329629
- await saveKnownMarketplacesConfig(primary);
329630
329653
  logForDebugging3(`Synced ${changed} marketplace(s) from seed dir(s)`);
329631
329654
  return true;
329632
329655
  }
@@ -330385,34 +330408,35 @@ Tip: The shorthand "${resolvedSource.repo}" assumes github.com. ` + `For interna
330385
330408
  if (sourceValidationError) {
330386
330409
  throw new Error(sourceValidationError);
330387
330410
  }
330388
- const config = await loadKnownMarketplacesConfig();
330389
- const oldEntry = config[marketplace.name];
330390
- if (oldEntry) {
330391
- const seedDir = seedDirFor(oldEntry.installLocation);
330392
- if (seedDir) {
330393
- throw new Error(`Marketplace '${marketplace.name}' is seed-managed (${seedDir}). ` + `To use a different source, ask your admin to update the seed, ` + `or use a different marketplace name.`);
330394
- }
330395
- logForDebugging3(`Marketplace '${marketplace.name}' exists with different source — overwriting`);
330396
- if (!isLocalMarketplaceSource(oldEntry.source)) {
330397
- const cacheDir = resolve42(getMarketplacesCacheDir());
330398
- const resolvedOld = resolve42(oldEntry.installLocation);
330399
- const resolvedNew = resolve42(cachePath);
330400
- if (resolvedOld === resolvedNew) {} else if (resolvedOld === cacheDir || resolvedOld.startsWith(cacheDir + sep26)) {
330401
- const fs = getFsImplementation2();
330402
- await fs.rm(oldEntry.installLocation, { recursive: true, force: true });
330403
- } else {
330404
- logForDebugging3(`Skipping cleanup of old installLocation (${oldEntry.installLocation}) — ` + `outside ${cacheDir}. The path is corrupted; leaving it alone and ` + `overwriting the config entry.`, { level: "warn" });
330411
+ const resolvedSha = await captureResolvedSha(resolvedSource, cachePath);
330412
+ await updateKnownMarketplacesConfig(async (config) => {
330413
+ const oldEntry = config[marketplace.name];
330414
+ if (oldEntry) {
330415
+ const seedDir = seedDirFor(oldEntry.installLocation);
330416
+ if (seedDir) {
330417
+ throw new Error(`Marketplace '${marketplace.name}' is seed-managed (${seedDir}). ` + `To use a different source, ask your admin to update the seed, ` + `or use a different marketplace name.`);
330418
+ }
330419
+ logForDebugging3(`Marketplace '${marketplace.name}' exists with different source — overwriting`);
330420
+ if (!isLocalMarketplaceSource(oldEntry.source)) {
330421
+ const cacheDir = resolve42(getMarketplacesCacheDir());
330422
+ const resolvedOld = resolve42(oldEntry.installLocation);
330423
+ const resolvedNew = resolve42(cachePath);
330424
+ if (resolvedOld === resolvedNew) {} else if (resolvedOld === cacheDir || resolvedOld.startsWith(cacheDir + sep26)) {
330425
+ const fs = getFsImplementation2();
330426
+ await fs.rm(oldEntry.installLocation, { recursive: true, force: true });
330427
+ } else {
330428
+ logForDebugging3(`Skipping cleanup of old installLocation (${oldEntry.installLocation}) — ` + `outside ${cacheDir}. The path is corrupted; leaving it alone and ` + `overwriting the config entry.`, { level: "warn" });
330429
+ }
330405
330430
  }
330406
330431
  }
330407
- }
330408
- const resolvedSha = await captureResolvedSha(resolvedSource, cachePath);
330409
- config[marketplace.name] = {
330410
- source: resolvedSource,
330411
- installLocation: cachePath,
330412
- lastUpdated: new Date().toISOString(),
330413
- ...resolvedSha ? { resolvedSha } : {}
330414
- };
330415
- await saveKnownMarketplacesConfig(config);
330432
+ config[marketplace.name] = {
330433
+ source: resolvedSource,
330434
+ installLocation: cachePath,
330435
+ lastUpdated: new Date().toISOString(),
330436
+ ...resolvedSha ? { resolvedSha } : {}
330437
+ };
330438
+ return config;
330439
+ });
330416
330440
  logForDebugging3(`Added marketplace source: ${marketplace.name}`);
330417
330441
  return { name: marketplace.name, alreadyMaterialized: false, resolvedSource };
330418
330442
  }
@@ -330425,15 +330449,7 @@ async function adoptOrphanMarketplace(dirName, overrideName) {
330425
330449
  }
330426
330450
  const manifestPath = resolveMarketplaceManifestPath(dirPath);
330427
330451
  const marketplace = await parseFileWithSchema(manifestPath, PluginMarketplaceSchema());
330428
- const config = await loadKnownMarketplacesConfig();
330429
330452
  const name = overrideName ?? marketplace.name;
330430
- const existing = config[name];
330431
- if (existing) {
330432
- if (resolve42(existing.installLocation) === resolve42(dirPath)) {
330433
- return { name, source: existing.source, installLocation: dirPath };
330434
- }
330435
- throw new Error(`Marketplace name '${name}' is already registered at ` + `${existing.installLocation}. Remove it first ` + `(\`plugin marketplace remove ${name}\`) or adopt under a different name.`);
330436
- }
330437
330453
  const remoteUrl = await parseGitConfigValue2(join118(dirPath, ".git"), "remote", "origin", "url");
330438
330454
  let source;
330439
330455
  if (remoteUrl) {
@@ -330453,29 +330469,39 @@ async function adoptOrphanMarketplace(dirName, overrideName) {
330453
330469
  throw new Error(`Marketplace source '${formatSourceForDisplay(source)}' is blocked ` + `by enterprise policy and cannot be adopted.`);
330454
330470
  }
330455
330471
  const resolvedSha = await captureResolvedSha(source, dirPath);
330456
- config[name] = {
330457
- source,
330458
- installLocation: dirPath,
330459
- lastUpdated: new Date().toISOString(),
330460
- ...resolvedSha ? { resolvedSha } : {}
330461
- };
330462
- await saveKnownMarketplacesConfig(config);
330472
+ await updateKnownMarketplacesConfig((existing) => {
330473
+ const prior = existing[name];
330474
+ if (prior) {
330475
+ if (resolve42(prior.installLocation) === resolve42(dirPath)) {
330476
+ return;
330477
+ }
330478
+ throw new Error(`Marketplace name '${name}' is already registered at ` + `${prior.installLocation}. Remove it first ` + `(\`plugin marketplace remove ${name}\`) or adopt under a different name.`);
330479
+ }
330480
+ existing[name] = {
330481
+ source,
330482
+ installLocation: dirPath,
330483
+ lastUpdated: new Date().toISOString(),
330484
+ ...resolvedSha ? { resolvedSha } : {}
330485
+ };
330486
+ return existing;
330487
+ });
330463
330488
  clearAllCaches();
330464
330489
  logForDebugging3(`Adopted orphan marketplace directory '${dirName}' as '${name}' (${formatSourceForDisplay(source)})`);
330465
330490
  return { name, source, installLocation: dirPath };
330466
330491
  }
330467
330492
  async function removeMarketplaceSource(name) {
330468
- const config = await loadKnownMarketplacesConfig();
330469
- if (!config[name]) {
330470
- throw new Error(`Marketplace '${name}' not found`);
330471
- }
330472
- const entry = config[name];
330473
- const seedDir = seedDirFor(entry.installLocation);
330474
- if (seedDir) {
330475
- throw new Error(`Marketplace '${name}' is registered from the read-only seed directory ` + `(${seedDir}) and will be re-registered on next startup. ` + `To stop using its plugins: claude plugin disable <plugin>@${name}`);
330476
- }
330477
- delete config[name];
330478
- await saveKnownMarketplacesConfig(config);
330493
+ await updateKnownMarketplacesConfig((config) => {
330494
+ const entry = config[name];
330495
+ if (!entry) {
330496
+ throw new Error(`Marketplace '${name}' not found`);
330497
+ }
330498
+ const seedDir = seedDirFor(entry.installLocation);
330499
+ if (seedDir) {
330500
+ throw new Error(`Marketplace '${name}' is registered from the read-only seed directory ` + `(${seedDir}) and will be re-registered on next startup. ` + `To stop using its plugins: claude plugin disable <plugin>@${name}`);
330501
+ }
330502
+ delete config[name];
330503
+ return config;
330504
+ });
330479
330505
  const fs = getFsImplementation2();
330480
330506
  const cacheDir = getMarketplacesCacheDir();
330481
330507
  const cachePath = join118(cacheDir, name);
@@ -330758,23 +330784,24 @@ async function refreshMarketplace(name, onProgress, options) {
330758
330784
  }
330759
330785
  }
330760
330786
  async function setMarketplaceAutoUpdate(name, autoUpdate) {
330761
- const config = await loadKnownMarketplacesConfig();
330762
- const entry = config[name];
330763
- if (!entry) {
330764
- throw new Error(`Marketplace '${name}' not found. Available marketplaces: ${Object.keys(config).join(", ")}`);
330765
- }
330766
- const seedDir = seedDirFor(entry.installLocation);
330767
- if (seedDir) {
330768
- throw new Error(`Marketplace '${name}' is seed-managed (${seedDir}) and ` + `auto-update is always disabled for seed content. ` + `To update: ask your admin to update the seed.`);
330769
- }
330770
- if (entry.autoUpdate === autoUpdate) {
330771
- return;
330772
- }
330773
- config[name] = {
330774
- ...entry,
330775
- autoUpdate
330776
- };
330777
- await saveKnownMarketplacesConfig(config);
330787
+ await updateKnownMarketplacesConfig((config) => {
330788
+ const entry = config[name];
330789
+ if (!entry) {
330790
+ throw new Error(`Marketplace '${name}' not found. Available marketplaces: ${Object.keys(config).join(", ")}`);
330791
+ }
330792
+ const seedDir = seedDirFor(entry.installLocation);
330793
+ if (seedDir) {
330794
+ throw new Error(`Marketplace '${name}' is seed-managed (${seedDir}) and ` + `auto-update is always disabled for seed content. ` + `To update: ask your admin to update the seed.`);
330795
+ }
330796
+ if (entry.autoUpdate === autoUpdate) {
330797
+ return;
330798
+ }
330799
+ config[name] = {
330800
+ ...entry,
330801
+ autoUpdate
330802
+ };
330803
+ return config;
330804
+ });
330778
330805
  const declaringSource = getMarketplaceDeclaringSource(name);
330779
330806
  if (declaringSource) {
330780
330807
  const declared = getSettingsForSource2(declaringSource)?.extraKnownMarketplaces?.[name];
@@ -330784,7 +330811,7 @@ async function setMarketplaceAutoUpdate(name, autoUpdate) {
330784
330811
  }
330785
330812
  logForDebugging3(`Set autoUpdate=${autoUpdate} for marketplace: ${name}`);
330786
330813
  }
330787
- var GIT_NO_PROMPT_ENV3, DEFAULT_PLUGIN_GIT_TIMEOUT_MS, GIT_SHA_RE, getMarketplace;
330814
+ var knownMarketplacesRmwChain, GIT_NO_PROMPT_ENV3, DEFAULT_PLUGIN_GIT_TIMEOUT_MS, GIT_SHA_RE, getMarketplace;
330788
330815
  var init_marketplaceManager = __esm(() => {
330789
330816
  init_axios2();
330790
330817
  init_configDir();
@@ -330814,6 +330841,7 @@ var init_marketplaceManager = __esm(() => {
330814
330841
  init_orphanScanner();
330815
330842
  init_pluginOptionsStorage();
330816
330843
  init_schemas3();
330844
+ knownMarketplacesRmwChain = Promise.resolve();
330817
330845
  GIT_NO_PROMPT_ENV3 = {
330818
330846
  GIT_TERMINAL_PROMPT: "0",
330819
330847
  GIT_ASKPASS: ""
@@ -331424,6 +331452,217 @@ function mtimeAwareMemoize(fn, watchFiles, options) {
331424
331452
  }
331425
331453
  var init_mtimeAwareMemoize = () => {};
331426
331454
 
331455
+ // src/tui/utils/plugins/installCounts.ts
331456
+ import { randomBytes as randomBytes15 } from "crypto";
331457
+ import { readFile as readFile41, rename as rename5, unlink as unlink16, writeFile as writeFile29 } from "fs/promises";
331458
+ import { join as join120 } from "path";
331459
+ function normalizeStatsBase(raw) {
331460
+ if (!raw)
331461
+ return null;
331462
+ const trimmed = raw.replace(/\/+$/, "");
331463
+ return trimmed.length > 0 ? trimmed : null;
331464
+ }
331465
+ function getStatsSourceUrl(marketplaceName) {
331466
+ const name = marketplaceName.toLowerCase();
331467
+ if (name === OFFICIAL_MARKETPLACE_NAME) {
331468
+ return OFFICIAL_STATS_URL;
331469
+ }
331470
+ if (SELF_HOSTED_MARKETPLACES.has(name)) {
331471
+ const base = normalizeStatsBase(process.env[STATS_ENDPOINT_ENV]);
331472
+ return base ? `${base}/stats/install-counts.json` : SELF_HOSTED_STATS_URL;
331473
+ }
331474
+ return null;
331475
+ }
331476
+ function getStatsReportUrl() {
331477
+ const base = normalizeStatsBase(process.env[STATS_ENDPOINT_ENV]);
331478
+ return base ? `${base}/stats/report` : null;
331479
+ }
331480
+ function getAllStatsSourceUrls() {
331481
+ const urls = new Set;
331482
+ const official = getStatsSourceUrl(OFFICIAL_MARKETPLACE_NAME);
331483
+ if (official)
331484
+ urls.add(official);
331485
+ for (const mkt of SELF_HOSTED_MARKETPLACES) {
331486
+ const url = getStatsSourceUrl(mkt);
331487
+ if (url)
331488
+ urls.add(url);
331489
+ }
331490
+ return [...urls];
331491
+ }
331492
+ function getInstallCountsCachePath() {
331493
+ return join120(getPluginsDirectory(), INSTALL_COUNTS_CACHE_FILENAME);
331494
+ }
331495
+ async function loadInstallCountsCache() {
331496
+ const cachePath = getInstallCountsCachePath();
331497
+ try {
331498
+ const content = await readFile41(cachePath, { encoding: "utf-8" });
331499
+ const parsed = jsonParse2(content);
331500
+ if (typeof parsed !== "object" || parsed === null || !("version" in parsed) || !("entries" in parsed)) {
331501
+ logForDebugging3("Install counts cache has invalid structure");
331502
+ return null;
331503
+ }
331504
+ const cache = parsed;
331505
+ if (cache.version !== INSTALL_COUNTS_CACHE_VERSION) {
331506
+ logForDebugging3(`Install counts cache version mismatch (got ${cache.version}, expected ${INSTALL_COUNTS_CACHE_VERSION})`);
331507
+ return null;
331508
+ }
331509
+ const entries = cache.entries;
331510
+ const validated = {};
331511
+ for (const [url, rawEntry] of Object.entries(entries)) {
331512
+ const entry = rawEntry;
331513
+ if (typeof entry.fetchedAt !== "string" || Number.isNaN(new Date(entry.fetchedAt).getTime()) || !Array.isArray(entry.counts)) {
331514
+ continue;
331515
+ }
331516
+ const counts = entry.counts.filter((c) => typeof c.plugin === "string" && typeof c.unique_installs === "number");
331517
+ validated[url] = { fetchedAt: entry.fetchedAt, counts };
331518
+ }
331519
+ return { version: INSTALL_COUNTS_CACHE_VERSION, entries: validated };
331520
+ } catch (error) {
331521
+ const code = getErrnoCode2(error);
331522
+ if (code !== "ENOENT") {
331523
+ logForDebugging3(`Failed to load install counts cache: ${errorMessage2(error)}`);
331524
+ }
331525
+ return null;
331526
+ }
331527
+ }
331528
+ async function saveInstallCountsCache(cache) {
331529
+ const cachePath = getInstallCountsCachePath();
331530
+ const tempPath = `${cachePath}.${randomBytes15(8).toString("hex")}.tmp`;
331531
+ try {
331532
+ const pluginsDir = getPluginsDirectory();
331533
+ await getFsImplementation2().mkdir(pluginsDir);
331534
+ const content = jsonStringify5(cache, null, 2);
331535
+ await writeFile29(tempPath, content, {
331536
+ encoding: "utf-8",
331537
+ mode: 384
331538
+ });
331539
+ await rename5(tempPath, cachePath);
331540
+ logForDebugging3("Install counts cache saved successfully");
331541
+ } catch (error) {
331542
+ logError3(error);
331543
+ try {
331544
+ await unlink16(tempPath);
331545
+ } catch {}
331546
+ }
331547
+ }
331548
+ async function fetchStatsFromUrl(url) {
331549
+ logForDebugging3(`Fetching install counts from ${url}`);
331550
+ const started = performance.now();
331551
+ try {
331552
+ const response = await axios_default.get(url, {
331553
+ timeout: 1e4
331554
+ });
331555
+ if (!response.data?.plugins || !Array.isArray(response.data.plugins)) {
331556
+ throw new Error("Invalid response format from install counts API");
331557
+ }
331558
+ logPluginFetch("install_counts", url, "success", performance.now() - started);
331559
+ return response.data.plugins;
331560
+ } catch (error) {
331561
+ logPluginFetch("install_counts", url, "failure", performance.now() - started, classifyFetchError(error));
331562
+ throw error;
331563
+ }
331564
+ }
331565
+ async function getInstallCounts(marketplaceNames) {
331566
+ const urls = new Set;
331567
+ if (marketplaceNames && marketplaceNames.length > 0) {
331568
+ for (const name of marketplaceNames) {
331569
+ const url = getStatsSourceUrl(name);
331570
+ if (url)
331571
+ urls.add(url);
331572
+ }
331573
+ if (urls.size === 0) {
331574
+ return null;
331575
+ }
331576
+ } else {
331577
+ for (const url of getAllStatsSourceUrls()) {
331578
+ urls.add(url);
331579
+ }
331580
+ }
331581
+ const cache = await loadInstallCountsCache();
331582
+ const map = new Map;
331583
+ let gotData = false;
331584
+ for (const url of urls) {
331585
+ const cached = cache?.entries[url];
331586
+ if (cached && Date.now() - new Date(cached.fetchedAt).getTime() <= CACHE_TTL_MS3) {
331587
+ logPluginFetch("install_counts", url, "cache_hit", 0);
331588
+ for (const entry of cached.counts) {
331589
+ map.set(entry.plugin, entry.unique_installs);
331590
+ }
331591
+ if (cached.counts.length > 0)
331592
+ gotData = true;
331593
+ continue;
331594
+ }
331595
+ try {
331596
+ const counts = await fetchStatsFromUrl(url);
331597
+ for (const entry of counts) {
331598
+ map.set(entry.plugin, entry.unique_installs);
331599
+ }
331600
+ gotData = true;
331601
+ const nextCache = cache ?? {
331602
+ version: INSTALL_COUNTS_CACHE_VERSION,
331603
+ entries: {}
331604
+ };
331605
+ nextCache.entries[url] = {
331606
+ fetchedAt: new Date().toISOString(),
331607
+ counts
331608
+ };
331609
+ await saveInstallCountsCache(nextCache);
331610
+ } catch (error) {
331611
+ logError3(error);
331612
+ logForDebugging3(`Failed to fetch install counts from ${url}: ${errorMessage2(error)}`);
331613
+ }
331614
+ }
331615
+ return gotData ? map : null;
331616
+ }
331617
+ function formatInstallCount(count) {
331618
+ if (count < 1000) {
331619
+ return String(count);
331620
+ }
331621
+ if (count < 1e6) {
331622
+ const k = count / 1000;
331623
+ const formatted = k.toFixed(1);
331624
+ return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}K` : `${formatted}K`;
331625
+ }
331626
+ const m = count / 1e6;
331627
+ const formatted = m.toFixed(1);
331628
+ return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}M` : `${formatted}M`;
331629
+ }
331630
+ var INSTALL_COUNTS_CACHE_VERSION = 2, INSTALL_COUNTS_CACHE_FILENAME = "install-counts-cache.json", CACHE_TTL_MS3, OFFICIAL_STATS_URL = "https://raw.githubusercontent.com/anthropics/claude-plugins-official/refs/heads/stats/stats/plugin-installs.json", SELF_HOSTED_STATS_URL = "https://raw.githubusercontent.com/vincentlau2046/atlas-plugins/master/stats/install-counts.json", STATS_ENDPOINT_ENV = "ATLAS_STATS_ENDPOINT", SELF_HOSTED_MARKETPLACES;
331631
+ var init_installCounts = __esm(() => {
331632
+ init_axios2();
331633
+ init_debug();
331634
+ init_errors4();
331635
+ init_fsOperations();
331636
+ init_log5();
331637
+ init_slowOperations();
331638
+ init_fetchTelemetry();
331639
+ init_officialMarketplace();
331640
+ init_pluginDirectories();
331641
+ CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
331642
+ SELF_HOSTED_MARKETPLACES = new Set([
331643
+ "atlas-plugins",
331644
+ "agent-skills"
331645
+ ]);
331646
+ });
331647
+
331648
+ // src/tui/utils/plugins/installCountReporter.ts
331649
+ function reportInstall(pluginId, marketplaceName) {
331650
+ const url = getStatsReportUrl();
331651
+ if (!url) {
331652
+ return Promise.resolve();
331653
+ }
331654
+ return axios_default.post(url, { plugin: pluginId, marketplace: marketplaceName }, { timeout: 5000 }).then(() => {
331655
+ logForDebugging3(`Install count reported: ${pluginId}`);
331656
+ }).catch((error) => {
331657
+ logForDebugging3(`Install count report failed (${pluginId} @ ${marketplaceName}): ${error instanceof Error ? error.message : String(error)}`);
331658
+ });
331659
+ }
331660
+ var init_installCountReporter = __esm(() => {
331661
+ init_axios2();
331662
+ init_debug();
331663
+ init_installCounts();
331664
+ });
331665
+
331427
331666
  // src/tui/utils/plugins/pluginVersioning.ts
331428
331667
  import { createHash as createHash9 } from "crypto";
331429
331668
  async function calculatePluginVersion(pluginId, source, manifest, installPath, providedVersion, gitCommitSha) {
@@ -331467,9 +331706,9 @@ var init_pluginVersioning = __esm(() => {
331467
331706
  });
331468
331707
 
331469
331708
  // src/tui/utils/plugins/pluginInstallationHelpers.ts
331470
- import { randomBytes as randomBytes15 } from "crypto";
331471
- import { rename as rename5, rm as rm8 } from "fs/promises";
331472
- import { dirname as dirname64, join as join120, resolve as resolve43, sep as sep27 } from "path";
331709
+ import { randomBytes as randomBytes16 } from "crypto";
331710
+ import { rename as rename6, rm as rm8 } from "fs/promises";
331711
+ import { dirname as dirname64, join as join121, resolve as resolve43, sep as sep27 } from "path";
331473
331712
  function getCurrentTimestamp() {
331474
331713
  return new Date().toISOString();
331475
331714
  }
@@ -331498,12 +331737,12 @@ async function cacheAndRegisterPlugin(pluginId, entry, scope = "user", projectPa
331498
331737
  const normalizedCachePath = cacheResult.path.endsWith(sep27) ? cacheResult.path : cacheResult.path + sep27;
331499
331738
  const isSubdirectory = versionedPath.startsWith(normalizedCachePath);
331500
331739
  if (isSubdirectory) {
331501
- const tempPath = join120(dirname64(cacheResult.path), `.atlas-plugin-temp-${Date.now()}-${randomBytes15(4).toString("hex")}`);
331502
- await rename5(cacheResult.path, tempPath);
331740
+ const tempPath = join121(dirname64(cacheResult.path), `.atlas-plugin-temp-${Date.now()}-${randomBytes16(4).toString("hex")}`);
331741
+ await rename6(cacheResult.path, tempPath);
331503
331742
  await getFsImplementation2().mkdir(dirname64(versionedPath));
331504
- await rename5(tempPath, versionedPath);
331743
+ await rename6(tempPath, versionedPath);
331505
331744
  } else {
331506
- await rename5(cacheResult.path, versionedPath);
331745
+ await rename6(cacheResult.path, versionedPath);
331507
331746
  }
331508
331747
  finalPath = versionedPath;
331509
331748
  }
@@ -331674,6 +331913,7 @@ async function installPluginFromMarketplace({
331674
331913
  };
331675
331914
  }
331676
331915
  }
331916
+ reportInstall(pluginId, marketplaceName);
331677
331917
  return {
331678
331918
  success: true,
331679
331919
  message: `✓ Installed ${entry.name}${result.depNote}.`
@@ -331692,6 +331932,7 @@ var init_pluginInstallationHelpers = __esm(() => {
331692
331932
  init_settings3();
331693
331933
  init_cacheUtils();
331694
331934
  init_dependencyResolver();
331935
+ init_installCountReporter();
331695
331936
  init_installedPluginsManager();
331696
331937
  init_marketplaceManager();
331697
331938
  init_pluginIdentifier2();
@@ -331706,25 +331947,25 @@ var init_pluginInstallationHelpers = __esm(() => {
331706
331947
  import {
331707
331948
  copyFile as copyFile6,
331708
331949
  readdir as readdir24,
331709
- readFile as readFile41,
331950
+ readFile as readFile42,
331710
331951
  readlink,
331711
331952
  realpath as realpath11,
331712
- rename as rename6,
331953
+ rename as rename7,
331713
331954
  rm as rm9,
331714
331955
  rmdir,
331715
331956
  stat as stat40,
331716
331957
  symlink as symlink5
331717
331958
  } from "fs/promises";
331718
- import { basename as basename36, dirname as dirname65, join as join121, relative as relative22, resolve as resolve44, sep as sep28 } from "path";
331959
+ import { basename as basename36, dirname as dirname65, join as join122, relative as relative22, resolve as resolve44, sep as sep28 } from "path";
331719
331960
  function getPluginCachePath() {
331720
- return join121(getPluginsDirectory(), "cache");
331961
+ return join122(getPluginsDirectory(), "cache");
331721
331962
  }
331722
331963
  function getVersionedCachePathIn(baseDir, pluginId, version) {
331723
331964
  const { name: pluginName, marketplace } = parsePluginIdentifier2(pluginId);
331724
331965
  const sanitizedMarketplace = (marketplace || "unknown").replace(/[^a-zA-Z0-9\-_]/g, "-");
331725
331966
  const sanitizedPlugin = (pluginName || pluginId).replace(/[^a-zA-Z0-9\-_]/g, "-");
331726
331967
  const sanitizedVersion = version.replace(/[^a-zA-Z0-9\-_.]/g, "-");
331727
- return join121(baseDir, "cache", sanitizedMarketplace, sanitizedPlugin, sanitizedVersion);
331968
+ return join122(baseDir, "cache", sanitizedMarketplace, sanitizedPlugin, sanitizedVersion);
331728
331969
  }
331729
331970
  function getVersionedCachePath(pluginId, version) {
331730
331971
  return getVersionedCachePathIn(getPluginsDirectory(), pluginId, version);
@@ -331750,7 +331991,7 @@ async function probeSeedCacheAnyVersion(pluginId) {
331750
331991
  const versions = await readdir24(pluginDir);
331751
331992
  if (versions.length !== 1)
331752
331993
  continue;
331753
- const versionDir = join121(pluginDir, versions[0]);
331994
+ const versionDir = join122(pluginDir, versions[0]);
331754
331995
  const entries = await readdir24(versionDir);
331755
331996
  if (entries.length > 0)
331756
331997
  return versionDir;
@@ -331762,8 +332003,8 @@ async function copyDir(src, dest) {
331762
332003
  await getFsImplementation2().mkdir(dest);
331763
332004
  const entries = await readdir24(src, { withFileTypes: true });
331764
332005
  for (const entry of entries) {
331765
- const srcPath = join121(src, entry.name);
331766
- const destPath = join121(dest, entry.name);
332006
+ const srcPath = join122(src, entry.name);
332007
+ const destPath = join122(dest, entry.name);
331767
332008
  if (entry.isDirectory()) {
331768
332009
  await copyDir(srcPath, destPath);
331769
332010
  } else if (entry.isFile()) {
@@ -331786,7 +332027,7 @@ async function copyDir(src, dest) {
331786
332027
  const srcPrefix = resolvedSrc.endsWith(sep28) ? resolvedSrc : resolvedSrc + sep28;
331787
332028
  if (resolvedTarget.startsWith(srcPrefix) || resolvedTarget === resolvedSrc) {
331788
332029
  const targetRelativeToSrc = relative22(resolvedSrc, resolvedTarget);
331789
- const destTargetPath = join121(dest, targetRelativeToSrc);
332030
+ const destTargetPath = join122(dest, targetRelativeToSrc);
331790
332031
  const relativeLinkPath = relative22(dirname65(destPath), destTargetPath);
331791
332032
  await symlink5(relativeLinkPath, destPath);
331792
332033
  } else {
@@ -331834,7 +332075,7 @@ async function copyPluginToVersionedCache(sourcePath, pluginId, version, entry,
331834
332075
  logForDebugging3(`Copying plugin ${pluginId} to versioned cache (fallback to full copy)`);
331835
332076
  await copyDir(sourcePath, cachePath);
331836
332077
  }
331837
- const gitPath = join121(cachePath, ".git");
332078
+ const gitPath = join122(cachePath, ".git");
331838
332079
  await rm9(gitPath, { recursive: true, force: true });
331839
332080
  const cacheEntries = await readdir24(cachePath);
331840
332081
  if (cacheEntries.length === 0) {
@@ -331865,10 +332106,10 @@ function validateGitUrl(url) {
331865
332106
  }
331866
332107
  }
331867
332108
  async function installFromNpm(packageName, targetPath, options = {}) {
331868
- const npmCachePath = join121(getPluginsDirectory(), "npm-cache");
332109
+ const npmCachePath = join122(getPluginsDirectory(), "npm-cache");
331869
332110
  await getFsImplementation2().mkdir(npmCachePath);
331870
332111
  const packageSpec = options.version ? `${packageName}@${options.version}` : packageName;
331871
- const packagePath = join121(npmCachePath, "node_modules", packageName);
332112
+ const packagePath = join122(npmCachePath, "node_modules", packageName);
331872
332113
  const needsInstall = !await pathExists2(packagePath);
331873
332114
  if (needsInstall) {
331874
332115
  logForDebugging3(`Installing npm package ${packageSpec} to cache`);
@@ -332001,7 +332242,7 @@ async function installFromGitSubdir(url, targetPath, subdirPath, ref, sha) {
332001
332242
  }
332002
332243
  const resolvedSubdir = validatePathWithinBase(cloneDir, subdirPath);
332003
332244
  try {
332004
- await rename6(resolvedSubdir, targetPath);
332245
+ await rename7(resolvedSubdir, targetPath);
332005
332246
  } catch (e) {
332006
332247
  if (isENOENT2(e)) {
332007
332248
  throw new Error(`Subdirectory '${subdirPath}' not found in repository ${gitUrl}${ref ? ` (ref: ${ref})` : ""}. ` + "Check that the path is correct and exists at the specified ref/sha.");
@@ -332021,7 +332262,7 @@ async function installFromLocal(sourcePath, targetPath) {
332021
332262
  throw new Error(`Source path does not exist: ${sourcePath}`);
332022
332263
  }
332023
332264
  await copyDir(sourcePath, targetPath);
332024
- const gitPath = join121(targetPath, ".git");
332265
+ const gitPath = join122(targetPath, ".git");
332025
332266
  await rm9(gitPath, { recursive: true, force: true });
332026
332267
  }
332027
332268
  function generateTemporaryCacheNameForPlugin(source) {
@@ -332057,7 +332298,7 @@ async function cachePlugin(source, options) {
332057
332298
  const cachePath = getPluginCachePath();
332058
332299
  await getFsImplementation2().mkdir(cachePath);
332059
332300
  const tempName = generateTemporaryCacheNameForPlugin(source);
332060
- const tempPath = join121(cachePath, tempName);
332301
+ const tempPath = join122(cachePath, tempName);
332061
332302
  let shouldCleanup = false;
332062
332303
  let gitCommitSha;
332063
332304
  try {
@@ -332102,11 +332343,11 @@ async function cachePlugin(source, options) {
332102
332343
  throw error;
332103
332344
  }
332104
332345
  const manifestPath = findManifestInDir(tempPath, "plugin.json");
332105
- const legacyManifestPath = join121(tempPath, "plugin.json");
332346
+ const legacyManifestPath = join122(tempPath, "plugin.json");
332106
332347
  let manifest;
332107
332348
  if (await pathExists2(manifestPath)) {
332108
332349
  try {
332109
- const content = await readFile41(manifestPath, { encoding: "utf-8" });
332350
+ const content = await readFile42(manifestPath, { encoding: "utf-8" });
332110
332351
  const parsed = jsonParse2(content);
332111
332352
  const result = PluginManifestSchema().safeParse(parsed);
332112
332353
  if (result.success) {
@@ -332130,7 +332371,7 @@ async function cachePlugin(source, options) {
332130
332371
  }
332131
332372
  } else if (await pathExists2(legacyManifestPath)) {
332132
332373
  try {
332133
- const content = await readFile41(legacyManifestPath, {
332374
+ const content = await readFile42(legacyManifestPath, {
332134
332375
  encoding: "utf-8"
332135
332376
  });
332136
332377
  const parsed = jsonParse2(content);
@@ -332159,12 +332400,12 @@ async function cachePlugin(source, options) {
332159
332400
  };
332160
332401
  }
332161
332402
  const finalName = manifest.name.replace(/[^a-zA-Z0-9-_]/g, "-");
332162
- const finalPath = join121(cachePath, finalName);
332403
+ const finalPath = join122(cachePath, finalName);
332163
332404
  if (await pathExists2(finalPath)) {
332164
332405
  logForDebugging3(`Removing old cached version at ${finalPath}`);
332165
332406
  await rm9(finalPath, { recursive: true, force: true });
332166
332407
  }
332167
- await rename6(tempPath, finalPath);
332408
+ await rename7(tempPath, finalPath);
332168
332409
  logForDebugging3(`Successfully cached plugin ${manifest.name} to ${finalPath}`);
332169
332410
  return {
332170
332411
  path: finalPath,
@@ -332180,7 +332421,7 @@ async function loadPluginManifest(manifestPath, pluginName, source) {
332180
332421
  };
332181
332422
  }
332182
332423
  try {
332183
- const content = await readFile41(manifestPath, { encoding: "utf-8" });
332424
+ const content = await readFile42(manifestPath, { encoding: "utf-8" });
332184
332425
  const parsedJson = jsonParse2(content);
332185
332426
  const result = PluginManifestSchema().safeParse(parsedJson);
332186
332427
  if (result.success) {
@@ -332206,14 +332447,14 @@ async function loadPluginHooks2(hooksConfigPath, pluginName) {
332206
332447
  if (!await pathExists2(hooksConfigPath)) {
332207
332448
  throw new Error(`Hooks file not found at ${hooksConfigPath} for plugin ${pluginName}. If the manifest declares hooks, the file must exist.`);
332208
332449
  }
332209
- const content = await readFile41(hooksConfigPath, { encoding: "utf-8" });
332450
+ const content = await readFile42(hooksConfigPath, { encoding: "utf-8" });
332210
332451
  const rawHooksConfig = jsonParse2(content);
332211
332452
  const validatedPluginHooks = PluginHooksSchema().parse(rawHooksConfig);
332212
332453
  return validatedPluginHooks.hooks;
332213
332454
  }
332214
332455
  async function validatePluginPaths(relPaths, pluginPath, pluginName, source, component, componentLabel, contextLabel, errors) {
332215
332456
  const checks = await Promise.all(relPaths.map(async (relPath) => {
332216
- const fullPath = join121(pluginPath, relPath);
332457
+ const fullPath = join122(pluginPath, relPath);
332217
332458
  return { relPath, fullPath, exists: await pathExists2(fullPath) };
332218
332459
  }));
332219
332460
  const validPaths = [];
@@ -332252,12 +332493,12 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332252
332493
  skillsDirExists,
332253
332494
  outputStylesDirExists
332254
332495
  ] = await Promise.all([
332255
- !manifest.commands ? pathExists2(join121(pluginPath, "commands")) : false,
332256
- !manifest.agents ? pathExists2(join121(pluginPath, "agents")) : false,
332257
- !manifest.skills ? pathExists2(join121(pluginPath, "skills")) : false,
332258
- !manifest.outputStyles ? pathExists2(join121(pluginPath, "output-styles")) : false
332496
+ !manifest.commands ? pathExists2(join122(pluginPath, "commands")) : false,
332497
+ !manifest.agents ? pathExists2(join122(pluginPath, "agents")) : false,
332498
+ !manifest.skills ? pathExists2(join122(pluginPath, "skills")) : false,
332499
+ !manifest.outputStyles ? pathExists2(join122(pluginPath, "output-styles")) : false
332259
332500
  ]);
332260
- const commandsPath = join121(pluginPath, "commands");
332501
+ const commandsPath = join122(pluginPath, "commands");
332261
332502
  if (commandsDirExists) {
332262
332503
  plugin.commandsPath = commandsPath;
332263
332504
  }
@@ -332272,7 +332513,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332272
332513
  return { commandName, metadata, kind: "skip" };
332273
332514
  }
332274
332515
  if (metadata.source) {
332275
- const fullPath = join121(pluginPath, metadata.source);
332516
+ const fullPath = join122(pluginPath, metadata.source);
332276
332517
  return {
332277
332518
  commandName,
332278
332519
  metadata,
@@ -332320,7 +332561,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332320
332561
  if (typeof cmdPath !== "string") {
332321
332562
  return { cmdPath, kind: "invalid" };
332322
332563
  }
332323
- const fullPath = join121(pluginPath, cmdPath);
332564
+ const fullPath = join122(pluginPath, cmdPath);
332324
332565
  return {
332325
332566
  cmdPath,
332326
332567
  kind: "path",
@@ -332353,7 +332594,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332353
332594
  }
332354
332595
  }
332355
332596
  }
332356
- const agentsPath = join121(pluginPath, "agents");
332597
+ const agentsPath = join122(pluginPath, "agents");
332357
332598
  if (agentsDirExists) {
332358
332599
  plugin.agentsPath = agentsPath;
332359
332600
  }
@@ -332364,7 +332605,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332364
332605
  plugin.agentsPaths = validPaths;
332365
332606
  }
332366
332607
  }
332367
- const skillsPath = join121(pluginPath, "skills");
332608
+ const skillsPath = join122(pluginPath, "skills");
332368
332609
  if (skillsDirExists) {
332369
332610
  plugin.skillsPath = skillsPath;
332370
332611
  }
@@ -332375,7 +332616,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332375
332616
  plugin.skillsPaths = validPaths;
332376
332617
  }
332377
332618
  }
332378
- const outputStylesPath = join121(pluginPath, "output-styles");
332619
+ const outputStylesPath = join122(pluginPath, "output-styles");
332379
332620
  if (outputStylesDirExists) {
332380
332621
  plugin.outputStylesPath = outputStylesPath;
332381
332622
  }
@@ -332388,7 +332629,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332388
332629
  }
332389
332630
  let mergedHooks;
332390
332631
  const loadedHookPaths = new Set;
332391
- const standardHooksPath = join121(pluginPath, "hooks", "hooks.json");
332632
+ const standardHooksPath = join122(pluginPath, "hooks", "hooks.json");
332392
332633
  if (await pathExists2(standardHooksPath)) {
332393
332634
  try {
332394
332635
  mergedHooks = await loadPluginHooks2(standardHooksPath, manifest.name);
@@ -332417,7 +332658,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332417
332658
  const manifestHooksArray = Array.isArray(manifest.hooks) ? manifest.hooks : [manifest.hooks];
332418
332659
  for (const hookSpec of manifestHooksArray) {
332419
332660
  if (typeof hookSpec === "string") {
332420
- const hookFilePath = join121(pluginPath, hookSpec);
332661
+ const hookFilePath = join122(pluginPath, hookSpec);
332421
332662
  if (!await pathExists2(hookFilePath)) {
332422
332663
  logForDebugging3(`Hooks file ${hookSpec} specified in manifest but not found at ${hookFilePath} for ${manifest.name}`, { level: "error" });
332423
332664
  logError3(new Error(`Plugin component file not found: ${hookFilePath} for ${manifest.name}`));
@@ -332507,9 +332748,9 @@ function parsePluginSettings(raw) {
332507
332748
  return data;
332508
332749
  }
332509
332750
  async function loadPluginSettings(pluginPath, manifest) {
332510
- const settingsJsonPath = join121(pluginPath, "settings.json");
332751
+ const settingsJsonPath = join122(pluginPath, "settings.json");
332511
332752
  try {
332512
- const content = await readFile41(settingsJsonPath, { encoding: "utf-8" });
332753
+ const content = await readFile42(settingsJsonPath, { encoding: "utf-8" });
332513
332754
  const parsed = jsonParse2(content);
332514
332755
  if (isRecord(parsed)) {
332515
332756
  const filtered = parsePluginSettings(parsed);
@@ -332650,7 +332891,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
332650
332891
  if (typeof entry.source === "string") {
332651
332892
  let marketplaceDir;
332652
332893
  try {
332653
- marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join121(marketplaceInstallLocation, "..");
332894
+ marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join122(marketplaceInstallLocation, "..");
332654
332895
  } catch {
332655
332896
  errorsOut.push({
332656
332897
  type: "plugin-cache-miss",
@@ -332660,7 +332901,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
332660
332901
  });
332661
332902
  return null;
332662
332903
  }
332663
- pluginPath = join121(marketplaceDir, entry.source);
332904
+ pluginPath = join122(marketplaceDir, entry.source);
332664
332905
  } else {
332665
332906
  if (!installPath || !await pathExists2(installPath)) {
332666
332907
  errorsOut.push({
@@ -332675,7 +332916,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
332675
332916
  }
332676
332917
  if (isPluginZipCacheEnabled() && pluginPath.endsWith(".zip")) {
332677
332918
  const sessionDir = await getSessionPluginCachePath();
332678
- const extractDir = join121(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
332919
+ const extractDir = join122(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
332679
332920
  try {
332680
332921
  await extractZipToDirectory(pluginPath, extractDir);
332681
332922
  pluginPath = extractDir;
@@ -332698,8 +332939,8 @@ async function loadPluginFromMarketplaceEntry(entry, marketplaceInstallLocation,
332698
332939
  logForDebugging3(`Loading plugin ${entry.name} from source: ${jsonStringify5(entry.source)}`);
332699
332940
  let pluginPath;
332700
332941
  if (typeof entry.source === "string") {
332701
- const marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join121(marketplaceInstallLocation, "..");
332702
- const sourcePluginPath = join121(marketplaceDir, entry.source);
332942
+ const marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join122(marketplaceInstallLocation, "..");
332943
+ const sourcePluginPath = join122(marketplaceDir, entry.source);
332703
332944
  if (!await pathExists2(sourcePluginPath)) {
332704
332945
  const error = new Error(`Plugin path not found: ${sourcePluginPath}`);
332705
332946
  logForDebugging3(`Plugin path not found: ${sourcePluginPath}`, {
@@ -332770,7 +333011,7 @@ async function loadPluginFromMarketplaceEntry(entry, marketplaceInstallLocation,
332770
333011
  }
332771
333012
  if (isPluginZipCacheEnabled() && pluginPath.endsWith(".zip")) {
332772
333013
  const sessionDir = await getSessionPluginCachePath();
332773
- const extractDir = join121(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
333014
+ const extractDir = join122(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
332774
333015
  try {
332775
333016
  await extractZipToDirectory(pluginPath, extractDir);
332776
333017
  logForDebugging3(`Extracted plugin ZIP to session dir: ${extractDir}`);
@@ -332810,7 +333051,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
332810
333051
  if (!metadata || typeof metadata !== "object" || !metadata.source) {
332811
333052
  return { commandName, metadata, skip: true };
332812
333053
  }
332813
- const fullPath = join121(pluginPath, metadata.source);
333054
+ const fullPath = join122(pluginPath, metadata.source);
332814
333055
  return {
332815
333056
  commandName,
332816
333057
  metadata,
@@ -332847,7 +333088,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
332847
333088
  if (typeof cmdPath !== "string") {
332848
333089
  return { cmdPath, kind: "invalid" };
332849
333090
  }
332850
- const fullPath = join121(pluginPath, cmdPath);
333091
+ const fullPath = join122(pluginPath, cmdPath);
332851
333092
  return {
332852
333093
  cmdPath,
332853
333094
  kind: "path",
@@ -332891,7 +333132,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
332891
333132
  logForDebugging3(`Processing ${Array.isArray(entry.skills) ? entry.skills.length : 1} skill paths for plugin ${entry.name}`);
332892
333133
  const skillPaths = Array.isArray(entry.skills) ? entry.skills : [entry.skills];
332893
333134
  const checks = await Promise.all(skillPaths.map(async (skillPath) => {
332894
- const fullPath = join121(pluginPath, skillPath);
333135
+ const fullPath = join122(pluginPath, skillPath);
332895
333136
  return { skillPath, fullPath, exists: await pathExists2(fullPath) };
332896
333137
  }));
332897
333138
  const validPaths = [];
@@ -332951,7 +333192,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
332951
333192
  if (!metadata || typeof metadata !== "object" || !metadata.source) {
332952
333193
  return { commandName, metadata, skip: true };
332953
333194
  }
332954
- const fullPath = join121(pluginPath, metadata.source);
333195
+ const fullPath = join122(pluginPath, metadata.source);
332955
333196
  return {
332956
333197
  commandName,
332957
333198
  metadata,
@@ -332991,7 +333232,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
332991
333232
  if (typeof cmdPath !== "string") {
332992
333233
  return { cmdPath, kind: "invalid" };
332993
333234
  }
332994
- const fullPath = join121(pluginPath, cmdPath);
333235
+ const fullPath = join122(pluginPath, cmdPath);
332995
333236
  return {
332996
333237
  cmdPath,
332997
333238
  kind: "path",
@@ -336654,9 +336895,9 @@ var init_prefix = __esm(() => {
336654
336895
  });
336655
336896
 
336656
336897
  // src/tui/utils/bash/commands.ts
336657
- import { randomBytes as randomBytes16 } from "crypto";
336898
+ import { randomBytes as randomBytes17 } from "crypto";
336658
336899
  function generatePlaceholders2() {
336659
- const salt = randomBytes16(8).toString("hex");
336900
+ const salt = randomBytes17(8).toString("hex");
336660
336901
  return {
336661
336902
  SINGLE_QUOTE: `__SINGLE_QUOTE_${salt}__`,
336662
336903
  DOUBLE_QUOTE: `__DOUBLE_QUOTE_${salt}__`,
@@ -339299,7 +339540,7 @@ var init_projectOnboardingState = __esm(() => {
339299
339540
  // src/tui/utils/appleTerminalBackup.ts
339300
339541
  import { stat as stat41 } from "fs/promises";
339301
339542
  import { homedir as homedir30 } from "os";
339302
- import { join as join122 } from "path";
339543
+ import { join as join123 } from "path";
339303
339544
  function markTerminalSetupInProgress(backupPath) {
339304
339545
  saveGlobalConfig((current) => ({
339305
339546
  ...current,
@@ -339321,7 +339562,7 @@ function getTerminalRecoveryInfo() {
339321
339562
  };
339322
339563
  }
339323
339564
  function getTerminalPlistPath() {
339324
- return join122(homedir30(), "Library", "Preferences", "com.apple.Terminal.plist");
339565
+ return join123(homedir30(), "Library", "Preferences", "com.apple.Terminal.plist");
339325
339566
  }
339326
339567
  async function backupTerminalPreferences() {
339327
339568
  const terminalPlistPath = getTerminalPlistPath();
@@ -339402,10 +339643,10 @@ __export(exports_terminalSetup, {
339402
339643
  setupTerminal: () => setupTerminal,
339403
339644
  shouldOfferTerminalSetup: () => shouldOfferTerminalSetup
339404
339645
  });
339405
- import { randomBytes as randomBytes17 } from "crypto";
339406
- import { copyFile as copyFile7, mkdir as mkdir37, readFile as readFile42, writeFile as writeFile29 } from "fs/promises";
339646
+ import { randomBytes as randomBytes18 } from "crypto";
339647
+ import { copyFile as copyFile7, mkdir as mkdir37, readFile as readFile43, writeFile as writeFile30 } from "fs/promises";
339407
339648
  import { homedir as homedir31, platform as platform3 } from "os";
339408
- import { dirname as dirname66, join as join123 } from "path";
339649
+ import { dirname as dirname66, join as join124 } from "path";
339409
339650
  import { pathToFileURL as pathToFileURL8 } from "url";
339410
339651
  function isVSCodeRemoteSSH() {
339411
339652
  const askpassMain = process.env.VSCODE_GIT_ASKPASS_MAIN ?? "";
@@ -339539,8 +339780,8 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
339539
339780
  ]`)}${EOL4}`;
339540
339781
  }
339541
339782
  const editorDir = editor === "VSCode" ? "Code" : editor;
339542
- const userDirPath = join123(homedir31(), platform3() === "win32" ? join123("AppData", "Roaming", editorDir, "User") : platform3() === "darwin" ? join123("Library", "Application Support", editorDir, "User") : join123(".config", editorDir, "User"));
339543
- const keybindingsPath = join123(userDirPath, "keybindings.json");
339783
+ const userDirPath = join124(homedir31(), platform3() === "win32" ? join124("AppData", "Roaming", editorDir, "User") : platform3() === "darwin" ? join124("Library", "Application Support", editorDir, "User") : join124(".config", editorDir, "User"));
339784
+ const keybindingsPath = join124(userDirPath, "keybindings.json");
339544
339785
  try {
339545
339786
  await mkdir37(userDirPath, {
339546
339787
  recursive: true
@@ -339549,7 +339790,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
339549
339790
  let keybindings = [];
339550
339791
  let fileExists = false;
339551
339792
  try {
339552
- content = await readFile42(keybindingsPath, {
339793
+ content = await readFile43(keybindingsPath, {
339553
339794
  encoding: "utf-8"
339554
339795
  });
339555
339796
  fileExists = true;
@@ -339559,7 +339800,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
339559
339800
  throw e;
339560
339801
  }
339561
339802
  if (fileExists) {
339562
- const randomSha = randomBytes17(4).toString("hex");
339803
+ const randomSha = randomBytes18(4).toString("hex");
339563
339804
  const backupPath = `${keybindingsPath}.${randomSha}.bak`;
339564
339805
  try {
339565
339806
  await copyFile7(keybindingsPath, backupPath);
@@ -339580,7 +339821,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
339580
339821
  when: "terminalFocus"
339581
339822
  };
339582
339823
  const updatedContent = addItemToJSONCArray(content, newKeybinding);
339583
- await writeFile29(keybindingsPath, updatedContent, {
339824
+ await writeFile30(keybindingsPath, updatedContent, {
339584
339825
  encoding: "utf-8"
339585
339826
  });
339586
339827
  return `${color("success", theme)(`Installed ${editor} terminal Shift+Enter key binding`)}${EOL4}${source_default.dim(`See ${formatPathLink(keybindingsPath)}`)}${EOL4}`;
@@ -339681,14 +339922,14 @@ chars = "\\u001B\\r"`;
339681
339922
  const configPaths = [];
339682
339923
  const xdgConfigHome = process.env.XDG_CONFIG_HOME;
339683
339924
  if (xdgConfigHome) {
339684
- configPaths.push(join123(xdgConfigHome, "alacritty", "alacritty.toml"));
339925
+ configPaths.push(join124(xdgConfigHome, "alacritty", "alacritty.toml"));
339685
339926
  } else {
339686
- configPaths.push(join123(homedir31(), ".config", "alacritty", "alacritty.toml"));
339927
+ configPaths.push(join124(homedir31(), ".config", "alacritty", "alacritty.toml"));
339687
339928
  }
339688
339929
  if (platform3() === "win32") {
339689
339930
  const appData = process.env.APPDATA;
339690
339931
  if (appData) {
339691
- configPaths.push(join123(appData, "alacritty", "alacritty.toml"));
339932
+ configPaths.push(join124(appData, "alacritty", "alacritty.toml"));
339692
339933
  }
339693
339934
  }
339694
339935
  let configPath = null;
@@ -339696,7 +339937,7 @@ chars = "\\u001B\\r"`;
339696
339937
  let configExists = false;
339697
339938
  for (const path of configPaths) {
339698
339939
  try {
339699
- configContent = await readFile42(path, {
339940
+ configContent = await readFile43(path, {
339700
339941
  encoding: "utf-8"
339701
339942
  });
339702
339943
  configPath = path;
@@ -339718,7 +339959,7 @@ chars = "\\u001B\\r"`;
339718
339959
  if (configContent.includes('mods = "Shift"') && configContent.includes('key = "Return"')) {
339719
339960
  return `${color("warning", theme)("Found existing Alacritty Shift+Enter key binding. Remove it to continue.")}${EOL4}${source_default.dim(`See ${formatPathLink(configPath)}`)}${EOL4}`;
339720
339961
  }
339721
- const randomSha = randomBytes17(4).toString("hex");
339962
+ const randomSha = randomBytes18(4).toString("hex");
339722
339963
  const backupPath = `${configPath}.${randomSha}.bak`;
339723
339964
  try {
339724
339965
  await copyFile7(configPath, backupPath);
@@ -339739,7 +339980,7 @@ chars = "\\u001B\\r"`;
339739
339980
  updatedContent += `
339740
339981
  ` + ALACRITTY_KEYBINDING + `
339741
339982
  `;
339742
- await writeFile29(configPath, updatedContent, {
339983
+ await writeFile30(configPath, updatedContent, {
339743
339984
  encoding: "utf-8"
339744
339985
  });
339745
339986
  return `${color("success", theme)("Installed Alacritty Shift+Enter key binding")}${EOL4}${color("success", theme)("You may need to restart Alacritty for changes to take effect")}${EOL4}${source_default.dim(`See ${formatPathLink(configPath)}`)}${EOL4}`;
@@ -339749,8 +339990,8 @@ chars = "\\u001B\\r"`;
339749
339990
  }
339750
339991
  }
339751
339992
  async function installBindingsForZed(theme) {
339752
- const zedDir = join123(homedir31(), ".config", "zed");
339753
- const keymapPath = join123(zedDir, "keymap.json");
339993
+ const zedDir = join124(homedir31(), ".config", "zed");
339994
+ const keymapPath = join124(zedDir, "keymap.json");
339754
339995
  try {
339755
339996
  await mkdir37(zedDir, {
339756
339997
  recursive: true
@@ -339758,7 +339999,7 @@ async function installBindingsForZed(theme) {
339758
339999
  let keymapContent = "[]";
339759
340000
  let fileExists = false;
339760
340001
  try {
339761
- keymapContent = await readFile42(keymapPath, {
340002
+ keymapContent = await readFile43(keymapPath, {
339762
340003
  encoding: "utf-8"
339763
340004
  });
339764
340005
  fileExists = true;
@@ -339770,7 +340011,7 @@ async function installBindingsForZed(theme) {
339770
340011
  if (keymapContent.includes("shift-enter")) {
339771
340012
  return `${color("warning", theme)("Found existing Zed Shift+Enter key binding. Remove it to continue.")}${EOL4}${source_default.dim(`See ${formatPathLink(keymapPath)}`)}${EOL4}`;
339772
340013
  }
339773
- const randomSha = randomBytes17(4).toString("hex");
340014
+ const randomSha = randomBytes18(4).toString("hex");
339774
340015
  const backupPath = `${keymapPath}.${randomSha}.bak`;
339775
340016
  try {
339776
340017
  await copyFile7(keymapPath, backupPath);
@@ -339793,7 +340034,7 @@ async function installBindingsForZed(theme) {
339793
340034
  "shift-enter": ["terminal::SendText", "\x1B\r"]
339794
340035
  }
339795
340036
  });
339796
- await writeFile29(keymapPath, jsonStringify5(keymap, null, 2) + `
340037
+ await writeFile30(keymapPath, jsonStringify5(keymap, null, 2) + `
339797
340038
  `, {
339798
340039
  encoding: "utf-8"
339799
340040
  });
@@ -339830,23 +340071,23 @@ var init_terminalSetup = __esm(() => {
339830
340071
 
339831
340072
  // src/tui/utils/pasteStore.ts
339832
340073
  import { createHash as createHash10 } from "crypto";
339833
- import { mkdir as mkdir38, readdir as readdir25, readFile as readFile43, stat as stat42, unlink as unlink16, writeFile as writeFile30 } from "fs/promises";
339834
- import { join as join124 } from "path";
340074
+ import { mkdir as mkdir38, readdir as readdir25, readFile as readFile44, stat as stat42, unlink as unlink17, writeFile as writeFile31 } from "fs/promises";
340075
+ import { join as join125 } from "path";
339835
340076
  function getPasteStoreDir() {
339836
- return join124(getAtlasConfigHomeDir3(), PASTE_STORE_DIR);
340077
+ return join125(getAtlasConfigHomeDir3(), PASTE_STORE_DIR);
339837
340078
  }
339838
340079
  function hashPastedText(content) {
339839
340080
  return createHash10("sha256").update(content).digest("hex").slice(0, 16);
339840
340081
  }
339841
340082
  function getPastePath(hash) {
339842
- return join124(getPasteStoreDir(), `${hash}.txt`);
340083
+ return join125(getPasteStoreDir(), `${hash}.txt`);
339843
340084
  }
339844
340085
  async function storePastedText(hash, content) {
339845
340086
  try {
339846
340087
  const dir = getPasteStoreDir();
339847
340088
  await mkdir38(dir, { recursive: true });
339848
340089
  const pastePath = getPastePath(hash);
339849
- await writeFile30(pastePath, content, { encoding: "utf8", mode: 384 });
340090
+ await writeFile31(pastePath, content, { encoding: "utf8", mode: 384 });
339850
340091
  logForDebugging3(`Stored paste ${hash} to ${pastePath}`);
339851
340092
  } catch (error) {
339852
340093
  logForDebugging3(`Failed to store paste: ${error}`);
@@ -339855,7 +340096,7 @@ async function storePastedText(hash, content) {
339855
340096
  async function retrievePastedText(hash) {
339856
340097
  try {
339857
340098
  const pastePath = getPastePath(hash);
339858
- return await readFile43(pastePath, { encoding: "utf8" });
340099
+ return await readFile44(pastePath, { encoding: "utf8" });
339859
340100
  } catch (error) {
339860
340101
  if (!isENOENT2(error)) {
339861
340102
  logForDebugging3(`Failed to retrieve paste ${hash}: ${error}`);
@@ -339876,11 +340117,11 @@ async function cleanupOldPastes(cutoffDate) {
339876
340117
  if (!file.endsWith(".txt")) {
339877
340118
  continue;
339878
340119
  }
339879
- const filePath = join124(pasteDir, file);
340120
+ const filePath = join125(pasteDir, file);
339880
340121
  try {
339881
340122
  const stats = await stat42(filePath);
339882
340123
  if (stats.mtimeMs < cutoffTime) {
339883
- await unlink16(filePath);
340124
+ await unlink17(filePath);
339884
340125
  logForDebugging3(`Cleaned up old paste: ${filePath}`);
339885
340126
  }
339886
340127
  } catch {}
@@ -339894,8 +340135,8 @@ var init_pasteStore = __esm(() => {
339894
340135
  });
339895
340136
 
339896
340137
  // src/tui/history.ts
339897
- import { appendFile as appendFile5, writeFile as writeFile31 } from "fs/promises";
339898
- import { join as join125 } from "path";
340138
+ import { appendFile as appendFile5, writeFile as writeFile32 } from "fs/promises";
340139
+ import { join as join126 } from "path";
339899
340140
  function getPastedTextRefNumLines(text) {
339900
340141
  return (text.match(/\r\n|\r|\n/g) || []).length;
339901
340142
  }
@@ -339937,7 +340178,7 @@ async function* makeLogEntryReader() {
339937
340178
  for (let i = pendingEntries.length - 1;i >= 0; i--) {
339938
340179
  yield pendingEntries[i];
339939
340180
  }
339940
- const historyPath = join125(getAtlasConfigHomeDir3(), "history.jsonl");
340181
+ const historyPath = join126(getAtlasConfigHomeDir3(), "history.jsonl");
339941
340182
  try {
339942
340183
  for await (const line of readLinesReverse(historyPath)) {
339943
340184
  try {
@@ -340052,8 +340293,8 @@ async function immediateFlushHistory() {
340052
340293
  }
340053
340294
  let release;
340054
340295
  try {
340055
- const historyPath = join125(getAtlasConfigHomeDir3(), "history.jsonl");
340056
- await writeFile31(historyPath, "", {
340296
+ const historyPath = join126(getAtlasConfigHomeDir3(), "history.jsonl");
340297
+ await writeFile32(historyPath, "", {
340057
340298
  encoding: "utf8",
340058
340299
  mode: 384,
340059
340300
  flag: "a"
@@ -342253,7 +342494,7 @@ var init_TextInput = __esm(() => {
342253
342494
  });
342254
342495
 
342255
342496
  // src/tui/utils/suggestions/directoryCompletion.ts
342256
- import { basename as basename40, dirname as dirname67, join as join126, sep as sep29 } from "path";
342497
+ import { basename as basename40, dirname as dirname67, join as join127, sep as sep29 } from "path";
342257
342498
  function parsePartialPath(partialPath, basePath) {
342258
342499
  if (!partialPath) {
342259
342500
  const directory = basePath || getCwd();
@@ -342277,7 +342518,7 @@ async function scanDirectory(dirPath) {
342277
342518
  const entries = await fs.readdir(dirPath);
342278
342519
  const directories = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => ({
342279
342520
  name: entry.name,
342280
- path: join126(dirPath, entry.name),
342521
+ path: join127(dirPath, entry.name),
342281
342522
  type: "directory"
342282
342523
  })).slice(0, 100);
342283
342524
  directoryCache.set(dirPath, directories);
@@ -342314,7 +342555,7 @@ async function scanDirectoryForPaths(dirPath, includeHidden = false) {
342314
342555
  const entries = await fs.readdir(dirPath);
342315
342556
  const paths = entries.filter((entry) => includeHidden || !entry.name.startsWith(".")).map((entry) => ({
342316
342557
  name: entry.name,
342317
- path: join126(dirPath, entry.name),
342558
+ path: join127(dirPath, entry.name),
342318
342559
  type: entry.isDirectory() ? "directory" : "file"
342319
342560
  })).sort((a, b) => {
342320
342561
  if (a.type === "directory" && b.type !== "directory")
@@ -343924,7 +344165,7 @@ var init_btw2 = __esm(() => {
343924
344165
  });
343925
344166
 
343926
344167
  // src/tui/components/Feedback.tsx
343927
- import { readFile as readFile44, stat as stat43 } from "fs/promises";
344168
+ import { readFile as readFile45, stat as stat43 } from "fs/promises";
343928
344169
  function redactSensitiveInfo(text) {
343929
344170
  let redacted = text;
343930
344171
  redacted = redacted.replace(/"(sk-ant[^\s"']{24,})"/g, '"[REDACTED_API_KEY]"');
@@ -343963,7 +344204,7 @@ async function loadRawTranscriptJsonl() {
343963
344204
  });
343964
344205
  return null;
343965
344206
  }
343966
- return await readFile44(transcriptPath, "utf-8");
344207
+ return await readFile45(transcriptPath, "utf-8");
343967
344208
  } catch {
343968
344209
  return null;
343969
344210
  }
@@ -345428,7 +345669,7 @@ var init_postSamplingHooks = __esm(() => {
345428
345669
  });
345429
345670
 
345430
345671
  // src/tui/services/MagicDocs/prompts.ts
345431
- import { join as join128 } from "path";
345672
+ import { join as join129 } from "path";
345432
345673
  function getUpdatePromptTemplate() {
345433
345674
  return `IMPORTANT: This message and these instructions are NOT part of the actual user conversation. Do NOT include any references to "documentation updates", "magic docs", or these update instructions in the document content.
345434
345675
 
@@ -345483,7 +345724,7 @@ REMEMBER: Only update if there is substantial new information. The Magic Doc hea
345483
345724
  }
345484
345725
  async function loadMagicDocsPrompt() {
345485
345726
  const fs = getFsImplementation2();
345486
- const promptPath = join128(getAtlasConfigHomeDir3(), "magic-docs", "prompt.md");
345727
+ const promptPath = join129(getAtlasConfigHomeDir3(), "magic-docs", "prompt.md");
345487
345728
  try {
345488
345729
  return await fs.readFile(promptPath, { encoding: "utf-8" });
345489
345730
  } catch {
@@ -346054,9 +346295,9 @@ __export(exports_copy, {
346054
346295
  collectRecentAssistantTexts: () => collectRecentAssistantTexts,
346055
346296
  fileExtension: () => fileExtension2
346056
346297
  });
346057
- import { mkdir as mkdir39, writeFile as writeFile32 } from "fs/promises";
346298
+ import { mkdir as mkdir39, writeFile as writeFile33 } from "fs/promises";
346058
346299
  import { tmpdir as tmpdir8 } from "os";
346059
- import { join as join129 } from "path";
346300
+ import { join as join130 } from "path";
346060
346301
  function extractCodeBlocks(markdown) {
346061
346302
  const tokens = k2.lexer(stripPromptXMLTags(markdown));
346062
346303
  const blocks = [];
@@ -346098,11 +346339,11 @@ function fileExtension2(lang) {
346098
346339
  return ".txt";
346099
346340
  }
346100
346341
  async function writeToFile(text, filename) {
346101
- const filePath = join129(COPY_DIR, filename);
346342
+ const filePath = join130(COPY_DIR, filename);
346102
346343
  await mkdir39(COPY_DIR, {
346103
346344
  recursive: true
346104
346345
  });
346105
- await writeFile32(filePath, text, "utf-8");
346346
+ await writeFile33(filePath, text, "utf-8");
346106
346347
  return filePath;
346107
346348
  }
346108
346349
  async function copyOrWriteToFile(text, filename) {
@@ -346428,7 +346669,7 @@ var init_copy = __esm(() => {
346428
346669
  import_compiler_runtime113 = __toESM(require_compiler_runtime(), 1);
346429
346670
  import_react81 = __toESM(require_react(), 1);
346430
346671
  jsx_dev_runtime138 = __toESM(require_jsx_dev_runtime(), 1);
346431
- COPY_DIR = join129(tmpdir8(), "atlas");
346672
+ COPY_DIR = join130(tmpdir8(), "atlas");
346432
346673
  });
346433
346674
 
346434
346675
  // src/tui/commands/copy/index.ts
@@ -347803,13 +348044,13 @@ var init_Tabs = __esm(() => {
347803
348044
  });
347804
348045
 
347805
348046
  // src/tui/utils/localInstaller.ts
347806
- import { access as access3, chmod as chmod6, writeFile as writeFile33 } from "fs/promises";
347807
- import { join as join130 } from "path";
348047
+ import { access as access3, chmod as chmod6, writeFile as writeFile34 } from "fs/promises";
348048
+ import { join as join131 } from "path";
347808
348049
  function getLocalInstallDir() {
347809
- return join130(getAtlasConfigHomeDir3(), "local");
348050
+ return join131(getAtlasConfigHomeDir3(), "local");
347810
348051
  }
347811
348052
  function getLocalAtlasPath() {
347812
- return join130(getLocalInstallDir(), "atlas");
348053
+ return join131(getLocalInstallDir(), "atlas");
347813
348054
  }
347814
348055
  function isRunningFromLocalInstallation() {
347815
348056
  const execPath = process.argv[1] || "";
@@ -347817,7 +348058,7 @@ function isRunningFromLocalInstallation() {
347817
348058
  }
347818
348059
  async function writeIfMissing(path, content, mode) {
347819
348060
  try {
347820
- await writeFile33(path, content, { encoding: "utf8", flag: "wx", mode });
348061
+ await writeFile34(path, content, { encoding: "utf8", flag: "wx", mode });
347821
348062
  return true;
347822
348063
  } catch (e) {
347823
348064
  if (getErrnoCode2(e) === "EEXIST")
@@ -347829,8 +348070,8 @@ async function ensureLocalPackageEnvironment() {
347829
348070
  try {
347830
348071
  const localInstallDir = getLocalInstallDir();
347831
348072
  await getFsImplementation2().mkdir(localInstallDir);
347832
- await writeIfMissing(join130(localInstallDir, "package.json"), jsonStringify5({ name: "atlas-local", version: "0.0.1", private: true }, null, 2));
347833
- const wrapperPath = join130(localInstallDir, "atlas");
348073
+ await writeIfMissing(join131(localInstallDir, "package.json"), jsonStringify5({ name: "atlas-local", version: "0.0.1", private: true }, null, 2));
348074
+ const wrapperPath = join131(localInstallDir, "atlas");
347834
348075
  const created = await writeIfMissing(wrapperPath, `#!/bin/sh
347835
348076
  exec "${localInstallDir}/node_modules/.bin/atlas" "$@"`, 493);
347836
348077
  if (created) {
@@ -347866,7 +348107,7 @@ async function installOrUpdateClaudePackage(channel, specificVersion) {
347866
348107
  }
347867
348108
  async function localInstallationExists() {
347868
348109
  try {
347869
- await access3(join130(getLocalInstallDir(), "node_modules", ".bin", "atlas"));
348110
+ await access3(join131(getLocalInstallDir(), "node_modules", ".bin", "atlas"));
347870
348111
  return true;
347871
348112
  } catch {
347872
348113
  return false;
@@ -347893,17 +348134,17 @@ var init_localInstaller = __esm(() => {
347893
348134
  });
347894
348135
 
347895
348136
  // src/tui/utils/shellConfig.ts
347896
- import { open as open14, readFile as readFile45, stat as stat44 } from "fs/promises";
348137
+ import { open as open14, readFile as readFile46, stat as stat44 } from "fs/promises";
347897
348138
  import { homedir as osHomedir } from "os";
347898
- import { join as join131 } from "path";
348139
+ import { join as join132 } from "path";
347899
348140
  function getShellConfigPaths(options) {
347900
348141
  const home = options?.homedir ?? osHomedir();
347901
348142
  const env = options?.env ?? process.env;
347902
348143
  const zshConfigDir = env.ZDOTDIR || home;
347903
348144
  return {
347904
- zsh: join131(zshConfigDir, ".zshrc"),
347905
- bash: join131(home, ".bashrc"),
347906
- fish: join131(home, ".config/fish/config.fish")
348145
+ zsh: join132(zshConfigDir, ".zshrc"),
348146
+ bash: join132(home, ".bashrc"),
348147
+ fish: join132(home, ".config/fish/config.fish")
347907
348148
  };
347908
348149
  }
347909
348150
  function filterAtlasAliases(lines) {
@@ -347928,7 +348169,7 @@ function filterAtlasAliases(lines) {
347928
348169
  }
347929
348170
  async function readFileLines(filePath) {
347930
348171
  try {
347931
- const content = await readFile45(filePath, { encoding: "utf8" });
348172
+ const content = await readFile46(filePath, { encoding: "utf8" });
347932
348173
  return content.split(`
347933
348174
  `);
347934
348175
  } catch (e) {
@@ -347987,9 +348228,9 @@ var init_shellConfig = __esm(() => {
347987
348228
 
347988
348229
  // src/tui/utils/autoUpdater.ts
347989
348230
  import { constants as fsConstants6 } from "fs";
347990
- import { access as access4, writeFile as writeFile34 } from "fs/promises";
348231
+ import { access as access4, writeFile as writeFile35 } from "fs/promises";
347991
348232
  import { homedir as homedir32 } from "os";
347992
- import { join as join132 } from "path";
348233
+ import { join as join133 } from "path";
347993
348234
  async function assertMinVersion() {
347994
348235
  if (false) {}
347995
348236
  try {
@@ -348039,7 +348280,7 @@ function shouldSkipVersion(targetVersion) {
348039
348280
  return shouldSkip;
348040
348281
  }
348041
348282
  function getLockFilePath() {
348042
- return join132(getAtlasConfigHomeDir3(), ".update.lock");
348283
+ return join133(getAtlasConfigHomeDir3(), ".update.lock");
348043
348284
  }
348044
348285
  async function acquireLock() {
348045
348286
  const fs = getFsImplementation2();
@@ -348069,7 +348310,7 @@ async function acquireLock() {
348069
348310
  }
348070
348311
  }
348071
348312
  try {
348072
- await writeFile34(lockPath, `${process.pid}`, {
348313
+ await writeFile35(lockPath, `${process.pid}`, {
348073
348314
  encoding: "utf8",
348074
348315
  flag: "wx"
348075
348316
  });
@@ -348082,7 +348323,7 @@ async function acquireLock() {
348082
348323
  if (code === "ENOENT") {
348083
348324
  try {
348084
348325
  await fs.mkdir(getAtlasConfigHomeDir3());
348085
- await writeFile34(lockPath, `${process.pid}`, {
348326
+ await writeFile35(lockPath, `${process.pid}`, {
348086
348327
  encoding: "utf8",
348087
348328
  flag: "wx"
348088
348329
  });
@@ -348271,7 +348512,7 @@ var init_autoUpdater = __esm(() => {
348271
348512
  });
348272
348513
 
348273
348514
  // src/tui/utils/nativeInstaller/packageManagers.ts
348274
- import { readFile as readFile46 } from "fs/promises";
348515
+ import { readFile as readFile47 } from "fs/promises";
348275
348516
  function isDistroFamily(osRelease, families) {
348276
348517
  return families.includes(osRelease.id) || osRelease.idLike.some((like) => families.includes(like));
348277
348518
  }
@@ -348329,7 +348570,7 @@ var init_packageManagers = __esm(() => {
348329
348570
  init_platform3();
348330
348571
  getOsRelease = memoize_default(async () => {
348331
348572
  try {
348332
- const content = await readFile46("/etc/os-release", "utf8");
348573
+ const content = await readFile47("/etc/os-release", "utf8");
348333
348574
  const idMatch = content.match(/^ID=["']?(\S+?)["']?\s*$/m);
348334
348575
  const idLikeMatch = content.match(/^ID_LIKE=["']?(.+?)["']?\s*$/m);
348335
348576
  return {
@@ -348450,9 +348691,9 @@ var init_packageManagers = __esm(() => {
348450
348691
  });
348451
348692
 
348452
348693
  // src/tui/utils/doctorDiagnostic.ts
348453
- import { readFile as readFile47, realpath as realpath12 } from "fs/promises";
348694
+ import { readFile as readFile48, realpath as realpath12 } from "fs/promises";
348454
348695
  import { homedir as homedir33 } from "os";
348455
- import { delimiter as delimiter2, join as join133, posix as posix8, win32 as win322 } from "path";
348696
+ import { delimiter as delimiter2, join as join134, posix as posix8, win32 as win322 } from "path";
348456
348697
  function getNormalizedPaths() {
348457
348698
  let invokedPath = process.argv[1] || "";
348458
348699
  let execPath = process.execPath || process.argv[0] || "";
@@ -348515,8 +348756,8 @@ async function getInstallationPath() {
348515
348756
  }
348516
348757
  } catch {}
348517
348758
  try {
348518
- await getFsImplementation2().stat(join133(homedir33(), ".local/bingetConfigDirName()"));
348519
- return join133(homedir33(), ".local/bingetConfigDirName()");
348759
+ await getFsImplementation2().stat(join134(homedir33(), ".local/bingetConfigDirName()"));
348760
+ return join134(homedir33(), ".local/bingetConfigDirName()");
348520
348761
  } catch {}
348521
348762
  return "native";
348522
348763
  }
@@ -348539,7 +348780,7 @@ function getInvokedBinary() {
348539
348780
  async function detectMultipleInstallations() {
348540
348781
  const fs = getFsImplementation2();
348541
348782
  const installations = [];
348542
- const localPath = join133(homedir33(), getConfigDirName2(), "local");
348783
+ const localPath = join134(homedir33(), getConfigDirName2(), "local");
348543
348784
  if (await localInstallationExists()) {
348544
348785
  installations.push({ type: "npm-local", path: localPath });
348545
348786
  }
@@ -348556,7 +348797,7 @@ async function detectMultipleInstallations() {
348556
348797
  if (npmResult.code === 0 && npmResult.stdout) {
348557
348798
  const npmPrefix = npmResult.stdout.trim();
348558
348799
  const isWindows = getPlatform3() === "windows";
348559
- const globalBinPath = isWindows ? join133(npmPrefix, "atlas") : join133(npmPrefix, "bin", "atlas");
348800
+ const globalBinPath = isWindows ? join134(npmPrefix, "atlas") : join134(npmPrefix, "bin", "atlas");
348560
348801
  let globalBinExists = false;
348561
348802
  try {
348562
348803
  await fs.stat(globalBinPath);
@@ -348575,7 +348816,7 @@ async function detectMultipleInstallations() {
348575
348816
  }
348576
348817
  } else {
348577
348818
  for (const packageName of packagesToCheck) {
348578
- const globalPackagePath = isWindows ? join133(npmPrefix, "node_modules", packageName) : join133(npmPrefix, "lib", "node_modules", packageName);
348819
+ const globalPackagePath = isWindows ? join134(npmPrefix, "node_modules", packageName) : join134(npmPrefix, "lib", "node_modules", packageName);
348579
348820
  try {
348580
348821
  await fs.stat(globalPackagePath);
348581
348822
  installations.push({
@@ -348586,14 +348827,14 @@ async function detectMultipleInstallations() {
348586
348827
  }
348587
348828
  }
348588
348829
  }
348589
- const nativeBinPath = join133(homedir33(), ".local", "bin", "atlas");
348830
+ const nativeBinPath = join134(homedir33(), ".local", "bin", "atlas");
348590
348831
  try {
348591
348832
  await fs.stat(nativeBinPath);
348592
348833
  installations.push({ type: "native", path: nativeBinPath });
348593
348834
  } catch {}
348594
348835
  const config = getGlobalConfig();
348595
348836
  if (config.installMethod === "native") {
348596
- const nativeDataPath = join133(homedir33(), ".local", "share", "atlas");
348837
+ const nativeDataPath = join134(homedir33(), ".local", "share", "atlas");
348597
348838
  try {
348598
348839
  await fs.stat(nativeDataPath);
348599
348840
  if (!installations.some((i) => i.type === "native")) {
@@ -348606,7 +348847,7 @@ async function detectMultipleInstallations() {
348606
348847
  async function detectConfigurationIssues(type) {
348607
348848
  const warnings = [];
348608
348849
  try {
348609
- const raw = await readFile47(join133(getManagedFilePath(), "managed-settings.json"), "utf-8");
348850
+ const raw = await readFile48(join134(getManagedFilePath(), "managed-settings.json"), "utf-8");
348610
348851
  const parsed = jsonParse2(raw);
348611
348852
  const field = parsed && typeof parsed === "object" ? parsed.strictPluginOnlyCustomization : undefined;
348612
348853
  if (field !== undefined && typeof field !== "boolean") {
@@ -348634,7 +348875,7 @@ async function detectConfigurationIssues(type) {
348634
348875
  const path = process.env.PATH || "";
348635
348876
  const pathDirectories = path.split(delimiter2);
348636
348877
  const homeDir = homedir33();
348637
- const localBinPath = join133(homeDir, ".local", "bin");
348878
+ const localBinPath = join134(homeDir, ".local", "bin");
348638
348879
  let normalizedLocalBinPath = localBinPath;
348639
348880
  if (getPlatform3() === "windows") {
348640
348881
  normalizedLocalBinPath = localBinPath.split(win322.sep).join(posix8.sep);
@@ -348821,7 +349062,7 @@ var init_doctorDiagnostic = __esm(() => {
348821
349062
 
348822
349063
  // src/tui/utils/xdg.ts
348823
349064
  import { homedir as osHomedir2 } from "os";
348824
- import { join as join134 } from "path";
349065
+ import { join as join135 } from "path";
348825
349066
  function resolveOptions2(options) {
348826
349067
  return {
348827
349068
  env: options?.env ?? process.env,
@@ -348830,19 +349071,19 @@ function resolveOptions2(options) {
348830
349071
  }
348831
349072
  function getXDGStateHome(options) {
348832
349073
  const { env, home } = resolveOptions2(options);
348833
- return env.XDG_STATE_HOME ?? join134(home, ".local", "state");
349074
+ return env.XDG_STATE_HOME ?? join135(home, ".local", "state");
348834
349075
  }
348835
349076
  function getXDGCacheHome(options) {
348836
349077
  const { env, home } = resolveOptions2(options);
348837
- return env.XDG_CACHE_HOME ?? join134(home, ".cache");
349078
+ return env.XDG_CACHE_HOME ?? join135(home, ".cache");
348838
349079
  }
348839
349080
  function getXDGDataHome(options) {
348840
349081
  const { env, home } = resolveOptions2(options);
348841
- return env.XDG_DATA_HOME ?? join134(home, ".local", "share");
349082
+ return env.XDG_DATA_HOME ?? join135(home, ".local", "share");
348842
349083
  }
348843
349084
  function getUserBinDir(options) {
348844
349085
  const { home } = resolveOptions2(options);
348845
- return join134(home, ".local", "bin");
349086
+ return join135(home, ".local", "bin");
348846
349087
  }
348847
349088
  var init_xdg = () => {};
348848
349089
 
@@ -348869,7 +349110,7 @@ var init_download = __esm(() => {
348869
349110
  });
348870
349111
 
348871
349112
  // src/tui/utils/nativeInstaller/pidLock.ts
348872
- import { basename as basename41, join as join135 } from "path";
349113
+ import { basename as basename41, join as join136 } from "path";
348873
349114
  function isPidBasedLockingEnabled() {
348874
349115
  const envVar = process.env.ENABLE_PID_BASED_VERSION_LOCKING;
348875
349116
  if (isEnvTruthy2(envVar)) {
@@ -349037,7 +349278,7 @@ function getAllLockInfo(locksDir) {
349037
349278
  try {
349038
349279
  const lockFiles = fs.readdirStringSync(locksDir).filter((f) => f.endsWith(".lock"));
349039
349280
  for (const lockFile of lockFiles) {
349040
- const lockFilePath = join135(locksDir, lockFile);
349281
+ const lockFilePath = join136(locksDir, lockFile);
349041
349282
  const content = readLockContent(lockFilePath);
349042
349283
  if (content) {
349043
349284
  lockInfos.push({
@@ -349064,7 +349305,7 @@ function cleanupStaleLocks(locksDir) {
349064
349305
  try {
349065
349306
  const lockEntries = fs.readdirStringSync(locksDir).filter((f) => f.endsWith(".lock"));
349066
349307
  for (const lockEntry of lockEntries) {
349067
- const lockFilePath = join135(locksDir, lockEntry);
349308
+ const lockFilePath = join136(locksDir, lockEntry);
349068
349309
  try {
349069
349310
  const stats = fs.lstatSync(lockFilePath);
349070
349311
  if (stats.isDirectory()) {
@@ -349110,16 +349351,16 @@ import {
349110
349351
  readdir as readdir26,
349111
349352
  readlink as readlink2,
349112
349353
  realpath as realpath13,
349113
- rename as rename7,
349354
+ rename as rename8,
349114
349355
  rm as rm10,
349115
349356
  rmdir as rmdir2,
349116
349357
  stat as stat45,
349117
349358
  symlink as symlink6,
349118
- unlink as unlink17,
349119
- writeFile as writeFile35
349359
+ unlink as unlink18,
349360
+ writeFile as writeFile36
349120
349361
  } from "fs/promises";
349121
349362
  import { homedir as homedir34 } from "os";
349122
- import { basename as basename42, delimiter as delimiter3, dirname as dirname69, join as join136, resolve as resolve46 } from "path";
349363
+ import { basename as basename42, delimiter as delimiter3, dirname as dirname69, join as join137, resolve as resolve46 } from "path";
349123
349364
  function getPlatform4() {
349124
349365
  const os = env5.platform;
349125
349366
  const arch = process.arch === "x64" ? "x64" : process.arch === "arm64" ? "arm64" : null;
@@ -349140,10 +349381,10 @@ function getBaseDirectories() {
349140
349381
  const platform = getPlatform4();
349141
349382
  const executableName = getBinaryName(platform);
349142
349383
  return {
349143
- versions: join136(getXDGDataHome(), getConfigDirName2(), "versions"),
349144
- staging: join136(getXDGCacheHome(), getConfigDirName2(), "staging"),
349145
- locks: join136(getXDGStateHome(), getConfigDirName2(), "locks"),
349146
- executable: join136(getUserBinDir(), executableName)
349384
+ versions: join137(getXDGDataHome(), getConfigDirName2(), "versions"),
349385
+ staging: join137(getXDGCacheHome(), getConfigDirName2(), "staging"),
349386
+ locks: join137(getXDGStateHome(), getConfigDirName2(), "locks"),
349387
+ executable: join137(getUserBinDir(), executableName)
349147
349388
  };
349148
349389
  }
349149
349390
  async function isPossibleClaudeBinary(filePath) {
@@ -349164,14 +349405,14 @@ async function getVersionPaths(version) {
349164
349405
  await Promise.all(dirsToCreate.map((dir) => mkdir40(dir, { recursive: true })));
349165
349406
  const executableParentDir = dirname69(dirs.executable);
349166
349407
  await mkdir40(executableParentDir, { recursive: true });
349167
- const installPath = join136(dirs.versions, version);
349408
+ const installPath = join137(dirs.versions, version);
349168
349409
  try {
349169
349410
  await stat45(installPath);
349170
349411
  } catch {
349171
- await writeFile35(installPath, "", { encoding: "utf8" });
349412
+ await writeFile36(installPath, "", { encoding: "utf8" });
349172
349413
  }
349173
349414
  return {
349174
- stagingPath: join136(dirs.staging, version),
349415
+ stagingPath: join137(dirs.staging, version),
349175
349416
  installPath
349176
349417
  };
349177
349418
  }
@@ -349243,25 +349484,25 @@ async function atomicMoveToInstallPath(stagedBinaryPath, installPath) {
349243
349484
  try {
349244
349485
  await copyFile8(stagedBinaryPath, tempInstallPath);
349245
349486
  await chmod7(tempInstallPath, 493);
349246
- await rename7(tempInstallPath, installPath);
349487
+ await rename8(tempInstallPath, installPath);
349247
349488
  logForDebugging3(`Atomically installed binary to ${installPath}`);
349248
349489
  } catch (error) {
349249
349490
  try {
349250
- await unlink17(tempInstallPath);
349491
+ await unlink18(tempInstallPath);
349251
349492
  } catch {}
349252
349493
  throw error;
349253
349494
  }
349254
349495
  }
349255
349496
  async function installVersionFromPackage(stagingPath, installPath) {
349256
349497
  try {
349257
- const nodeModulesDir = join136(stagingPath, "node_modules", "@anthropic-ai");
349498
+ const nodeModulesDir = join137(stagingPath, "node_modules", "@anthropic-ai");
349258
349499
  const entries = await readdir26(nodeModulesDir);
349259
349500
  const nativePackage = entries.find((entry) => entry.startsWith("atlas-cli-native-") || entry.startsWith("claude-cli-native-"));
349260
349501
  if (!nativePackage) {
349261
349502
  const error = new Error("Could not find platform-specific native package");
349262
349503
  throw error;
349263
349504
  }
349264
- const stagedBinaryPath = join136(nodeModulesDir, nativePackage, "cli");
349505
+ const stagedBinaryPath = join137(nodeModulesDir, nativePackage, "cli");
349265
349506
  try {
349266
349507
  await stat45(stagedBinaryPath);
349267
349508
  } catch {
@@ -349281,7 +349522,7 @@ async function installVersionFromBinary(stagingPath, installPath) {
349281
349522
  try {
349282
349523
  const platform = getPlatform4();
349283
349524
  const binaryName = getBinaryName(platform);
349284
- const stagedBinaryPath = join136(stagingPath, binaryName);
349525
+ const stagedBinaryPath = join137(stagingPath, binaryName);
349285
349526
  try {
349286
349527
  await stat45(stagedBinaryPath);
349287
349528
  } catch {
@@ -349418,15 +349659,15 @@ async function updateSymlink(symlinkPath, targetPath) {
349418
349659
  }
349419
349660
  } catch {}
349420
349661
  const oldFileName = `${symlinkPath}.old.${Date.now()}`;
349421
- await rename7(symlinkPath, oldFileName);
349662
+ await rename8(symlinkPath, oldFileName);
349422
349663
  try {
349423
349664
  await copyFile8(targetPath, symlinkPath);
349424
349665
  try {
349425
- await unlink17(oldFileName);
349666
+ await unlink18(oldFileName);
349426
349667
  } catch {}
349427
349668
  } catch (copyError) {
349428
349669
  try {
349429
- await rename7(oldFileName, symlinkPath);
349670
+ await rename8(oldFileName, symlinkPath);
349430
349671
  } catch (restoreError) {
349431
349672
  const errorWithCause = new Error(`Failed to restore old executable: ${restoreError}`, { cause: copyError });
349432
349673
  logError3(errorWithCause);
@@ -349473,7 +349714,7 @@ async function updateSymlink(symlinkPath, targetPath) {
349473
349714
  return false;
349474
349715
  }
349475
349716
  } catch {}
349476
- await unlink17(symlinkPath);
349717
+ await unlink18(symlinkPath);
349477
349718
  }
349478
349719
  } catch (error) {
349479
349720
  logError3(new Error(`Failed to check/remove existing symlink: ${error}`));
@@ -349481,12 +349722,12 @@ async function updateSymlink(symlinkPath, targetPath) {
349481
349722
  const tempSymlink = `${symlinkPath}.tmp.${process.pid}.${Date.now()}`;
349482
349723
  try {
349483
349724
  await symlink6(targetPath, tempSymlink);
349484
- await rename7(tempSymlink, symlinkPath);
349725
+ await rename8(tempSymlink, symlinkPath);
349485
349726
  logForDebugging3(`Atomically updated symlink ${symlinkPath} -> ${targetPath}`);
349486
349727
  return true;
349487
349728
  } catch (error) {
349488
349729
  try {
349489
- await unlink17(tempSymlink);
349730
+ await unlink18(tempSymlink);
349490
349731
  } catch {}
349491
349732
  logError3(new Error(`Failed to create symlink from ${symlinkPath} to ${targetPath}: ${error}`));
349492
349733
  return false;
@@ -349647,7 +349888,7 @@ async function getVersionFromSymlink(symlinkPath) {
349647
349888
  }
349648
349889
  function getLockFilePathFromVersionPath(dirs, versionPath) {
349649
349890
  const versionName = basename42(versionPath);
349650
- return join136(dirs.locks, `${versionName}.lock`);
349891
+ return join137(dirs.locks, `${versionName}.lock`);
349651
349892
  }
349652
349893
  async function lockCurrentVersion() {
349653
349894
  const dirs = getBaseDirectories();
@@ -349706,7 +349947,7 @@ async function forceRemoveLock(versionFilePath) {
349706
349947
  const dirs = getBaseDirectories();
349707
349948
  const lockfilePath = getLockFilePathFromVersionPath(dirs, versionFilePath);
349708
349949
  try {
349709
- await unlink17(lockfilePath);
349950
+ await unlink18(lockfilePath);
349710
349951
  logForDebugging3(`Force-removed lock file at ${lockfilePath}`);
349711
349952
  } catch (error) {
349712
349953
  logForDebugging3(`Failed to force-remove lock file: ${errorMessage2(error)}`);
@@ -349725,7 +349966,7 @@ async function cleanupOldVersions() {
349725
349966
  if (!/atlas\.exe\.old\.\d+$/.test(file))
349726
349967
  continue;
349727
349968
  try {
349728
- await unlink17(join136(executableDir, file));
349969
+ await unlink18(join137(executableDir, file));
349729
349970
  cleanedCount++;
349730
349971
  } catch {}
349731
349972
  }
@@ -349742,7 +349983,7 @@ async function cleanupOldVersions() {
349742
349983
  const stagingEntries = await readdir26(dirs.staging);
349743
349984
  let stagingCleanedCount = 0;
349744
349985
  for (const entry of stagingEntries) {
349745
- const stagingPath = join136(dirs.staging, entry);
349986
+ const stagingPath = join137(dirs.staging, entry);
349746
349987
  try {
349747
349988
  const stats = await stat45(stagingPath);
349748
349989
  if (stats.mtime.getTime() < oneHourAgo) {
@@ -349778,12 +350019,12 @@ async function cleanupOldVersions() {
349778
350019
  const versionFiles = [];
349779
350020
  let tempFilesCleanedCount = 0;
349780
350021
  for (const entry of versionEntries) {
349781
- const entryPath = join136(dirs.versions, entry);
350022
+ const entryPath = join137(dirs.versions, entry);
349782
350023
  if (/\.tmp\.\d+\.\d+$/.test(entry)) {
349783
350024
  try {
349784
350025
  const stats = await stat45(entryPath);
349785
350026
  if (stats.mtime.getTime() < oneHourAgo) {
349786
- await unlink17(entryPath);
350027
+ await unlink18(entryPath);
349787
350028
  tempFilesCleanedCount++;
349788
350029
  logForDebugging3(`Cleaned up orphaned temp install file: ${entry}`);
349789
350030
  }
@@ -349854,7 +350095,7 @@ async function cleanupOldVersions() {
349854
350095
  await Promise.all(versionsToDelete.map(async (version) => {
349855
350096
  try {
349856
350097
  const deleted = await tryWithVersionLock(version.path, async () => {
349857
- await unlink17(version.path);
350098
+ await unlink18(version.path);
349858
350099
  });
349859
350100
  if (deleted) {
349860
350101
  deletedCount++;
@@ -349888,7 +350129,7 @@ async function removeInstalledSymlink() {
349888
350129
  logForDebugging3(`Skipping removal of ${dirs.executable} - appears to be npm-managed`);
349889
350130
  return;
349890
350131
  }
349891
- await unlink17(dirs.executable);
350132
+ await unlink18(dirs.executable);
349892
350133
  logForDebugging3(`Removed atlas symlink at ${dirs.executable}`);
349893
350134
  } catch (error) {
349894
350135
  if (isENOENT2(error)) {
@@ -349943,7 +350184,7 @@ async function manualRemoveNpmPackage(packageName) {
349943
350184
  let manuallyRemoved = false;
349944
350185
  async function tryRemove(filePath, description) {
349945
350186
  try {
349946
- await unlink17(filePath);
350187
+ await unlink18(filePath);
349947
350188
  logForDebugging3(`Manually removed ${description}: ${filePath}`);
349948
350189
  return true;
349949
350190
  } catch {
@@ -349951,9 +350192,9 @@ async function manualRemoveNpmPackage(packageName) {
349951
350192
  }
349952
350193
  }
349953
350194
  if (getPlatform4().startsWith("win32")) {
349954
- const binCmd = join136(globalPrefix, "atlas.cmd");
349955
- const binPs1 = join136(globalPrefix, "atlas.ps1");
349956
- const binExe = join136(globalPrefix, "atlas");
350195
+ const binCmd = join137(globalPrefix, "atlas.cmd");
350196
+ const binPs1 = join137(globalPrefix, "atlas.ps1");
350197
+ const binExe = join137(globalPrefix, "atlas");
349957
350198
  if (await tryRemove(binCmd, "bin script")) {
349958
350199
  manuallyRemoved = true;
349959
350200
  }
@@ -349964,14 +350205,14 @@ async function manualRemoveNpmPackage(packageName) {
349964
350205
  manuallyRemoved = true;
349965
350206
  }
349966
350207
  } else {
349967
- const binSymlink = join136(globalPrefix, "bin", "atlas");
350208
+ const binSymlink = join137(globalPrefix, "bin", "atlas");
349968
350209
  if (await tryRemove(binSymlink, "bin symlink")) {
349969
350210
  manuallyRemoved = true;
349970
350211
  }
349971
350212
  }
349972
350213
  if (manuallyRemoved) {
349973
350214
  logForDebugging3(`Successfully removed ${packageName} manually`);
349974
- const nodeModulesPath = getPlatform4().startsWith("win32") ? join136(globalPrefix, "node_modules", packageName) : join136(globalPrefix, "lib", "node_modules", packageName);
350215
+ const nodeModulesPath = getPlatform4().startsWith("win32") ? join137(globalPrefix, "node_modules", packageName) : join137(globalPrefix, "lib", "node_modules", packageName);
349975
350216
  return {
349976
350217
  success: true,
349977
350218
  warning: `${packageName} executables removed, but node_modules directory was left intact for safety. You may manually delete it later at: ${nodeModulesPath}`
@@ -350040,7 +350281,7 @@ async function cleanupNpmInstallations() {
350040
350281
  errors.push(macroPackageResult.error);
350041
350282
  }
350042
350283
  }
350043
- const localInstallDir = join136(homedir34(), getConfigDirName2(), "local");
350284
+ const localInstallDir = join137(homedir34(), getConfigDirName2(), "local");
350044
350285
  try {
350045
350286
  await rm10(localInstallDir, { recursive: true });
350046
350287
  removed++;
@@ -358742,7 +358983,7 @@ var init_doctorContextWarnings = __esm(() => {
358742
358983
  });
358743
358984
 
358744
358985
  // src/tui/screens/Doctor.tsx
358745
- import { join as join137 } from "path";
358986
+ import { join as join138 } from "path";
358746
358987
  function DistTagsDisplay(t0) {
358747
358988
  const $ = import_compiler_runtime139.c(8);
358748
358989
  const {
@@ -358872,8 +359113,8 @@ function Doctor(t0) {
358872
359113
  t5 = () => {
358873
359114
  getDoctorDiagnostic().then(setDiagnostic);
358874
359115
  (async () => {
358875
- const userAgentsDir = join137(getAtlasConfigHomeDir3(), "agents");
358876
- const projectAgentsDir = join137(getOriginalCwd(), "getConfigDirName()", "agents");
359116
+ const userAgentsDir = join138(getAtlasConfigHomeDir3(), "agents");
359117
+ const projectAgentsDir = join138(getOriginalCwd(), "getConfigDirName()", "agents");
358877
359118
  const {
358878
359119
  activeAgents,
358879
359120
  allAgents,
@@ -358896,7 +359137,7 @@ function Doctor(t0) {
358896
359137
  }, async () => toolPermissionContext);
358897
359138
  setContextWarnings(warnings);
358898
359139
  if (isPidBasedLockingEnabled()) {
358899
- const locksDir = join137(getXDGStateHome(), getConfigDirName2(), "locks");
359140
+ const locksDir = join138(getXDGStateHome(), getConfigDirName2(), "locks");
358900
359141
  const staleLocksCleaned = cleanupStaleLocks(locksDir);
358901
359142
  const locks = getAllLockInfo(locksDir);
358902
359143
  setVersionLockInfo({
@@ -360387,10 +360628,10 @@ var init_editor = __esm(() => {
360387
360628
  // src/tui/utils/tempfile.ts
360388
360629
  import { createHash as createHash11, randomUUID as randomUUID38 } from "crypto";
360389
360630
  import { tmpdir as tmpdir9 } from "os";
360390
- import { join as join138 } from "path";
360631
+ import { join as join139 } from "path";
360391
360632
  function generateTempFilePath2(prefix = "atlas-prompt", extension = ".md", options) {
360392
360633
  const id = options?.contentHash ? createHash11("sha256").update(options.contentHash).digest("hex").slice(0, 16) : randomUUID38();
360393
- return join138(tmpdir9(), `${prefix}-${id}${extension}`);
360634
+ return join139(tmpdir9(), `${prefix}-${id}${extension}`);
360394
360635
  }
360395
360636
  var init_tempfile = () => {};
360396
360637
 
@@ -360515,7 +360756,7 @@ var exports_memory = {};
360515
360756
  __export(exports_memory, {
360516
360757
  call: () => call16
360517
360758
  });
360518
- import { mkdir as mkdir42, writeFile as writeFile36 } from "fs/promises";
360759
+ import { mkdir as mkdir42, writeFile as writeFile37 } from "fs/promises";
360519
360760
  function MemoryCommand({
360520
360761
  onDone
360521
360762
  }) {
@@ -360527,7 +360768,7 @@ function MemoryCommand({
360527
360768
  });
360528
360769
  }
360529
360770
  try {
360530
- await writeFile36(memoryPath, "", {
360771
+ await writeFile37(memoryPath, "", {
360531
360772
  encoding: "utf8",
360532
360773
  flag: "wx"
360533
360774
  });
@@ -363019,7 +363260,7 @@ var exports_keybindings = {};
363019
363260
  __export(exports_keybindings, {
363020
363261
  call: () => call19
363021
363262
  });
363022
- import { mkdir as mkdir43, writeFile as writeFile37 } from "fs/promises";
363263
+ import { mkdir as mkdir43, writeFile as writeFile38 } from "fs/promises";
363023
363264
  import { dirname as dirname70 } from "path";
363024
363265
  async function call19() {
363025
363266
  if (!isKeybindingCustomizationEnabled()) {
@@ -363032,7 +363273,7 @@ async function call19() {
363032
363273
  let fileExists = false;
363033
363274
  await mkdir43(dirname70(keybindingsPath), { recursive: true });
363034
363275
  try {
363035
- await writeFile37(keybindingsPath, generateKeybindingsTemplate(), {
363276
+ await writeFile38(keybindingsPath, generateKeybindingsTemplate(), {
363036
363277
  encoding: "utf-8",
363037
363278
  flag: "wx"
363038
363279
  });
@@ -369748,10 +369989,10 @@ var init_mcp7 = __esm(() => {
369748
369989
  });
369749
369990
 
369750
369991
  // src/tui/utils/releaseNotes.ts
369751
- import { mkdir as mkdir44, readFile as readFile48, writeFile as writeFile38 } from "fs/promises";
369752
- import { dirname as dirname71, join as join139 } from "path";
369992
+ import { mkdir as mkdir44, readFile as readFile49, writeFile as writeFile39 } from "fs/promises";
369993
+ import { dirname as dirname71, join as join140 } from "path";
369753
369994
  function getChangelogCachePath() {
369754
- return join139(getAtlasConfigHomeDir3(), "cache", "changelog.md");
369995
+ return join140(getAtlasConfigHomeDir3(), "cache", "changelog.md");
369755
369996
  }
369756
369997
  async function migrateChangelogFromConfig() {
369757
369998
  const config = getGlobalConfig();
@@ -369761,7 +370002,7 @@ async function migrateChangelogFromConfig() {
369761
370002
  const cachePath = getChangelogCachePath();
369762
370003
  try {
369763
370004
  await mkdir44(dirname71(cachePath), { recursive: true });
369764
- await writeFile38(cachePath, config.cachedChangelog, {
370005
+ await writeFile39(cachePath, config.cachedChangelog, {
369765
370006
  encoding: "utf-8",
369766
370007
  flag: "wx"
369767
370008
  });
@@ -369783,7 +370024,7 @@ async function fetchAndStoreChangelog() {
369783
370024
  }
369784
370025
  const cachePath = getChangelogCachePath();
369785
370026
  await mkdir44(dirname71(cachePath), { recursive: true });
369786
- await writeFile38(cachePath, changelogContent, { encoding: "utf-8" });
370027
+ await writeFile39(cachePath, changelogContent, { encoding: "utf-8" });
369787
370028
  changelogMemoryCache = changelogContent;
369788
370029
  const changelogLastFetched = Date.now();
369789
370030
  saveGlobalConfig((current) => ({
@@ -369798,7 +370039,7 @@ async function getStoredChangelog() {
369798
370039
  }
369799
370040
  const cachePath = getChangelogCachePath();
369800
370041
  try {
369801
- const content = await readFile48(cachePath, "utf-8");
370042
+ const content = await readFile49(cachePath, "utf-8");
369802
370043
  changelogMemoryCache = content;
369803
370044
  return content;
369804
370045
  } catch {
@@ -370147,9 +370388,9 @@ var init_rename = __esm(() => {
370147
370388
  });
370148
370389
 
370149
370390
  // src/tui/commands/rename/index.ts
370150
- var rename8, rename_default;
370391
+ var rename9, rename_default;
370151
370392
  var init_rename2 = __esm(() => {
370152
- rename8 = {
370393
+ rename9 = {
370153
370394
  type: "local-jsx",
370154
370395
  name: "rename",
370155
370396
  description: "Rename the current conversation",
@@ -370157,7 +370398,7 @@ var init_rename2 = __esm(() => {
370157
370398
  argumentHint: "[name]",
370158
370399
  load: () => Promise.resolve().then(() => (init_rename(), exports_rename))
370159
370400
  };
370160
- rename_default = rename8;
370401
+ rename_default = rename9;
370161
370402
  });
370162
370403
 
370163
370404
  // src/tui/utils/getWorktreePaths.ts
@@ -387073,7 +387314,7 @@ var init_vim2 = __esm(() => {
387073
387314
  });
387074
387315
 
387075
387316
  // src/tui/utils/plugins/pluginStartupCheck.ts
387076
- import { join as join140 } from "path";
387317
+ import { join as join141 } from "path";
387077
387318
  function getPluginEditableScopes() {
387078
387319
  const result = new Map;
387079
387320
  const addDirPlugins = getAddDirEnabledPlugins();
@@ -387145,7 +387386,7 @@ async function installSelectedPlugins(pluginsToInstall, onProgress, scope = "use
387145
387386
  } else {
387146
387387
  registerPluginInstallation({
387147
387388
  pluginId,
387148
- installPath: join140(marketplaceInstallLocation, entry.source),
387389
+ installPath: join141(marketplaceInstallLocation, entry.source),
387149
387390
  version: entry.version
387150
387391
  }, scope, projectPath);
387151
387392
  }
@@ -387177,7 +387418,7 @@ var init_pluginStartupCheck = __esm(() => {
387177
387418
  });
387178
387419
 
387179
387420
  // src/tui/services/plugins/pluginOperations.ts
387180
- import { dirname as dirname72, join as join141 } from "path";
387421
+ import { dirname as dirname72, join as join142 } from "path";
387181
387422
  function assertInstallableScope(scope) {
387182
387423
  if (!VALID_INSTALLABLE_SCOPES.includes(scope)) {
387183
387424
  throw new Error(`Invalid scope "${scope}". Must be one of: ${VALID_INSTALLABLE_SCOPES.join(", ")}`);
@@ -387655,7 +387896,7 @@ async function performPluginUpdate({
387655
387896
  throw e;
387656
387897
  }
387657
387898
  const marketplaceDir = marketplaceStats.isDirectory() ? marketplaceInstallLocation : dirname72(marketplaceInstallLocation);
387658
- sourcePath = join141(marketplaceDir, entry.source);
387899
+ sourcePath = join142(marketplaceDir, entry.source);
387659
387900
  try {
387660
387901
  await fs.stat(sourcePath);
387661
387902
  } catch (e) {
@@ -387754,8 +387995,8 @@ __export(exports_thinkback, {
387754
387995
  call: () => call34,
387755
387996
  playAnimation: () => playAnimation
387756
387997
  });
387757
- import { readFile as readFile49 } from "fs/promises";
387758
- import { join as join142 } from "path";
387998
+ import { readFile as readFile50 } from "fs/promises";
387999
+ import { join as join143 } from "path";
387759
388000
  function getMarketplaceName() {
387760
388001
  return OFFICIAL_MARKETPLACE_NAME;
387761
388002
  }
@@ -387773,17 +388014,17 @@ async function getThinkbackSkillDir() {
387773
388014
  if (!thinkbackPlugin) {
387774
388015
  return null;
387775
388016
  }
387776
- const skillDir = join142(thinkbackPlugin.path, "skills", SKILL_NAME);
388017
+ const skillDir = join143(thinkbackPlugin.path, "skills", SKILL_NAME);
387777
388018
  if (await pathExists2(skillDir)) {
387778
388019
  return skillDir;
387779
388020
  }
387780
388021
  return null;
387781
388022
  }
387782
388023
  async function playAnimation(skillDir) {
387783
- const dataPath = join142(skillDir, "year_in_review.js");
387784
- const playerPath = join142(skillDir, "player.js");
388024
+ const dataPath = join143(skillDir, "year_in_review.js");
388025
+ const playerPath = join143(skillDir, "player.js");
387785
388026
  try {
387786
- await readFile49(dataPath);
388027
+ await readFile50(dataPath);
387787
388028
  } catch (e) {
387788
388029
  if (isENOENT2(e)) {
387789
388030
  return {
@@ -387798,7 +388039,7 @@ async function playAnimation(skillDir) {
387798
388039
  };
387799
388040
  }
387800
388041
  try {
387801
- await readFile49(playerPath);
388042
+ await readFile50(playerPath);
387802
388043
  } catch (e) {
387803
388044
  if (isENOENT2(e)) {
387804
388045
  return {
@@ -387829,7 +388070,7 @@ async function playAnimation(skillDir) {
387829
388070
  } catch {} finally {
387830
388071
  inkInstance.exitAlternateScreen();
387831
388072
  }
387832
- const htmlPath = join142(skillDir, "year_in_review.html");
388073
+ const htmlPath = join143(skillDir, "year_in_review.html");
387833
388074
  if (await pathExists2(htmlPath)) {
387834
388075
  const platform = getPlatform3();
387835
388076
  const openCmd = platform === "macos" ? "open" : platform === "windows" ? "start" : "xdg-open";
@@ -388165,7 +388406,7 @@ function ThinkbackFlow(t0) {
388165
388406
  if (!skillDir) {
388166
388407
  return;
388167
388408
  }
388168
- const dataPath = join142(skillDir, "year_in_review.js");
388409
+ const dataPath = join143(skillDir, "year_in_review.js");
388169
388410
  pathExists2(dataPath).then((exists) => {
388170
388411
  logForDebugging3(`Checking for ${dataPath}: ${exists ? "found" : "not found"}`);
388171
388412
  setHasGenerated(exists);
@@ -388339,7 +388580,7 @@ var exports_thinkback_play = {};
388339
388580
  __export(exports_thinkback_play, {
388340
388581
  call: () => call35
388341
388582
  });
388342
- import { join as join143 } from "path";
388583
+ import { join as join144 } from "path";
388343
388584
  function getPluginId2() {
388344
388585
  return `thinkback@${OFFICIAL_MARKETPLACE_NAME}`;
388345
388586
  }
@@ -388360,7 +388601,7 @@ async function call35() {
388360
388601
  value: "Thinkback plugin installation path not found."
388361
388602
  };
388362
388603
  }
388363
- const skillDir = join143(firstInstall.installPath, "skills", SKILL_NAME2);
388604
+ const skillDir = join144(firstInstall.installPath, "skills", SKILL_NAME2);
388364
388605
  const result = await playAnimation(skillDir);
388365
388606
  return { type: "text", value: result.message };
388366
388607
  }
@@ -392877,7 +393118,7 @@ __export(exports_branch, {
392877
393118
  getUniqueForkName: () => getUniqueForkName
392878
393119
  });
392879
393120
  import { randomUUID as randomUUID39 } from "crypto";
392880
- import { mkdir as mkdir45, readFile as readFile50, writeFile as writeFile39 } from "fs/promises";
393121
+ import { mkdir as mkdir45, readFile as readFile51, writeFile as writeFile40 } from "fs/promises";
392881
393122
  function deriveFirstPrompt(firstUserMessage) {
392882
393123
  const content = firstUserMessage?.message?.content;
392883
393124
  if (!content)
@@ -392896,7 +393137,7 @@ async function createFork(customTitle, target) {
392896
393137
  await mkdir45(projectDir, { recursive: true, mode: 448 });
392897
393138
  let transcriptContent;
392898
393139
  try {
392899
- transcriptContent = await readFile50(currentTranscriptPath);
393140
+ transcriptContent = await readFile51(currentTranscriptPath);
392900
393141
  } catch {
392901
393142
  throw new Error("No conversation to branch");
392902
393143
  }
@@ -392941,7 +393182,7 @@ async function createFork(customTitle, target) {
392941
393182
  };
392942
393183
  lines.push(jsonStringify5(forkedReplacementEntry));
392943
393184
  }
392944
- await writeFile39(forkSessionPath, lines.join(`
393185
+ await writeFile40(forkSessionPath, lines.join(`
392945
393186
  `) + `
392946
393187
  `, {
392947
393188
  encoding: "utf8",
@@ -393218,8 +393459,8 @@ var init_types16 = __esm(() => {
393218
393459
  });
393219
393460
 
393220
393461
  // src/tui/components/agents/agentFileUtils.ts
393221
- import { mkdir as mkdir46, open as open15, unlink as unlink18 } from "fs/promises";
393222
- import { join as join144 } from "path";
393462
+ import { mkdir as mkdir46, open as open15, unlink as unlink19 } from "fs/promises";
393463
+ import { join as join145 } from "path";
393223
393464
  function formatAgentAsMarkdown(agentType, whenToUse, tools, systemPrompt, color, model, memory, effort) {
393224
393465
  const escapedWhenToUse = whenToUse.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\\\n");
393225
393466
  const isAllTools = tools === undefined || tools.length === 1 && tools[0] === "*";
@@ -393246,26 +393487,26 @@ function getAgentDirectoryPath(location) {
393246
393487
  case "flagSettings":
393247
393488
  throw new Error(`Cannot get directory path for ${location} agents`);
393248
393489
  case "userSettings":
393249
- return join144(getAtlasConfigHomeDir3(), AGENT_PATHS.AGENTS_DIR);
393490
+ return join145(getAtlasConfigHomeDir3(), AGENT_PATHS.AGENTS_DIR);
393250
393491
  case "projectSettings":
393251
- return join144(getCwd(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
393492
+ return join145(getCwd(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
393252
393493
  case "policySettings":
393253
- return join144(getManagedFilePath(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
393494
+ return join145(getManagedFilePath(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
393254
393495
  case "localSettings":
393255
- return join144(getCwd(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
393496
+ return join145(getCwd(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
393256
393497
  }
393257
393498
  }
393258
393499
  function getRelativeAgentDirectoryPath(location) {
393259
393500
  switch (location) {
393260
393501
  case "projectSettings":
393261
- return join144(".", AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
393502
+ return join145(".", AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
393262
393503
  default:
393263
393504
  return getAgentDirectoryPath(location);
393264
393505
  }
393265
393506
  }
393266
393507
  function getNewAgentFilePath(agent) {
393267
393508
  const dirPath = getAgentDirectoryPath(agent.source);
393268
- return join144(dirPath, `${agent.agentType}.md`);
393509
+ return join145(dirPath, `${agent.agentType}.md`);
393269
393510
  }
393270
393511
  function getActualAgentFilePath(agent) {
393271
393512
  if (agent.source === "built-in") {
@@ -393276,14 +393517,14 @@ function getActualAgentFilePath(agent) {
393276
393517
  }
393277
393518
  const dirPath = getAgentDirectoryPath(agent.source);
393278
393519
  const filename = agent.filename || agent.agentType;
393279
- return join144(dirPath, `${filename}.md`);
393520
+ return join145(dirPath, `${filename}.md`);
393280
393521
  }
393281
393522
  function getNewRelativeAgentFilePath(agent) {
393282
393523
  if (agent.source === "built-in") {
393283
393524
  return "Built-in";
393284
393525
  }
393285
393526
  const dirPath = getRelativeAgentDirectoryPath(agent.source);
393286
- return join144(dirPath, `${agent.agentType}.md`);
393527
+ return join145(dirPath, `${agent.agentType}.md`);
393287
393528
  }
393288
393529
  function getActualRelativeAgentFilePath(agent) {
393289
393530
  if (isBuiltInAgent2(agent)) {
@@ -393297,7 +393538,7 @@ function getActualRelativeAgentFilePath(agent) {
393297
393538
  }
393298
393539
  const dirPath = getRelativeAgentDirectoryPath(agent.source);
393299
393540
  const filename = agent.filename || agent.agentType;
393300
- return join144(dirPath, `${filename}.md`);
393541
+ return join145(dirPath, `${filename}.md`);
393301
393542
  }
393302
393543
  async function ensureAgentDirectoryExists(source) {
393303
393544
  const dirPath = getAgentDirectoryPath(source);
@@ -393334,7 +393575,7 @@ async function deleteAgentFromFile(agent) {
393334
393575
  }
393335
393576
  const filePath = getActualAgentFilePath(agent);
393336
393577
  try {
393337
- await unlink18(filePath);
393578
+ await unlink19(filePath);
393338
393579
  } catch (e) {
393339
393580
  const code = getErrnoCode2(e);
393340
393581
  if (code !== "ENOENT") {
@@ -399562,152 +399803,6 @@ var init_MarketplaceAdopt = __esm(() => {
399562
399803
  jsx_dev_runtime281 = __toESM(require_jsx_dev_runtime(), 1);
399563
399804
  });
399564
399805
 
399565
- // src/tui/utils/plugins/installCounts.ts
399566
- import { randomBytes as randomBytes18 } from "crypto";
399567
- import { readFile as readFile51, rename as rename9, unlink as unlink19, writeFile as writeFile40 } from "fs/promises";
399568
- import { join as join145 } from "path";
399569
- function getInstallCountsCachePath() {
399570
- return join145(getPluginsDirectory(), INSTALL_COUNTS_CACHE_FILENAME);
399571
- }
399572
- async function loadInstallCountsCache() {
399573
- const cachePath = getInstallCountsCachePath();
399574
- try {
399575
- const content = await readFile51(cachePath, { encoding: "utf-8" });
399576
- const parsed = jsonParse2(content);
399577
- if (typeof parsed !== "object" || parsed === null || !("version" in parsed) || !("fetchedAt" in parsed) || !("counts" in parsed)) {
399578
- logForDebugging3("Install counts cache has invalid structure");
399579
- return null;
399580
- }
399581
- const cache = parsed;
399582
- if (cache.version !== INSTALL_COUNTS_CACHE_VERSION) {
399583
- logForDebugging3(`Install counts cache version mismatch (got ${cache.version}, expected ${INSTALL_COUNTS_CACHE_VERSION})`);
399584
- return null;
399585
- }
399586
- if (typeof cache.fetchedAt !== "string" || !Array.isArray(cache.counts)) {
399587
- logForDebugging3("Install counts cache has invalid structure");
399588
- return null;
399589
- }
399590
- const fetchedAt = new Date(cache.fetchedAt).getTime();
399591
- if (Number.isNaN(fetchedAt)) {
399592
- logForDebugging3("Install counts cache has invalid fetchedAt timestamp");
399593
- return null;
399594
- }
399595
- const validCounts = cache.counts.every((entry) => typeof entry === "object" && entry !== null && typeof entry.plugin === "string" && typeof entry.unique_installs === "number");
399596
- if (!validCounts) {
399597
- logForDebugging3("Install counts cache has malformed entries");
399598
- return null;
399599
- }
399600
- const now = Date.now();
399601
- if (now - fetchedAt > CACHE_TTL_MS3) {
399602
- logForDebugging3("Install counts cache is stale (>24h old)");
399603
- return null;
399604
- }
399605
- return {
399606
- version: cache.version,
399607
- fetchedAt: cache.fetchedAt,
399608
- counts: cache.counts
399609
- };
399610
- } catch (error) {
399611
- const code = getErrnoCode2(error);
399612
- if (code !== "ENOENT") {
399613
- logForDebugging3(`Failed to load install counts cache: ${errorMessage2(error)}`);
399614
- }
399615
- return null;
399616
- }
399617
- }
399618
- async function saveInstallCountsCache(cache) {
399619
- const cachePath = getInstallCountsCachePath();
399620
- const tempPath = `${cachePath}.${randomBytes18(8).toString("hex")}.tmp`;
399621
- try {
399622
- const pluginsDir = getPluginsDirectory();
399623
- await getFsImplementation2().mkdir(pluginsDir);
399624
- const content = jsonStringify5(cache, null, 2);
399625
- await writeFile40(tempPath, content, {
399626
- encoding: "utf-8",
399627
- mode: 384
399628
- });
399629
- await rename9(tempPath, cachePath);
399630
- logForDebugging3("Install counts cache saved successfully");
399631
- } catch (error) {
399632
- logError3(error);
399633
- try {
399634
- await unlink19(tempPath);
399635
- } catch {}
399636
- }
399637
- }
399638
- async function fetchInstallCountsFromGitHub() {
399639
- logForDebugging3(`Fetching install counts from ${INSTALL_COUNTS_URL}`);
399640
- const started = performance.now();
399641
- try {
399642
- const response = await axios_default.get(INSTALL_COUNTS_URL, {
399643
- timeout: 1e4
399644
- });
399645
- if (!response.data?.plugins || !Array.isArray(response.data.plugins)) {
399646
- throw new Error("Invalid response format from install counts API");
399647
- }
399648
- logPluginFetch("install_counts", INSTALL_COUNTS_URL, "success", performance.now() - started);
399649
- return response.data.plugins;
399650
- } catch (error) {
399651
- logPluginFetch("install_counts", INSTALL_COUNTS_URL, "failure", performance.now() - started, classifyFetchError(error));
399652
- throw error;
399653
- }
399654
- }
399655
- async function getInstallCounts() {
399656
- const cache = await loadInstallCountsCache();
399657
- if (cache) {
399658
- logForDebugging3("Using cached install counts");
399659
- logPluginFetch("install_counts", INSTALL_COUNTS_URL, "cache_hit", 0);
399660
- const map = new Map;
399661
- for (const entry of cache.counts) {
399662
- map.set(entry.plugin, entry.unique_installs);
399663
- }
399664
- return map;
399665
- }
399666
- try {
399667
- const counts = await fetchInstallCountsFromGitHub();
399668
- const newCache = {
399669
- version: INSTALL_COUNTS_CACHE_VERSION,
399670
- fetchedAt: new Date().toISOString(),
399671
- counts
399672
- };
399673
- await saveInstallCountsCache(newCache);
399674
- const map = new Map;
399675
- for (const entry of counts) {
399676
- map.set(entry.plugin, entry.unique_installs);
399677
- }
399678
- return map;
399679
- } catch (error) {
399680
- logError3(error);
399681
- logForDebugging3(`Failed to fetch install counts: ${errorMessage2(error)}`);
399682
- return null;
399683
- }
399684
- }
399685
- function formatInstallCount(count) {
399686
- if (count < 1000) {
399687
- return String(count);
399688
- }
399689
- if (count < 1e6) {
399690
- const k = count / 1000;
399691
- const formatted = k.toFixed(1);
399692
- return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}K` : `${formatted}K`;
399693
- }
399694
- const m = count / 1e6;
399695
- const formatted = m.toFixed(1);
399696
- return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}M` : `${formatted}M`;
399697
- }
399698
- var INSTALL_COUNTS_CACHE_VERSION = 1, INSTALL_COUNTS_CACHE_FILENAME = "install-counts-cache.json", INSTALL_COUNTS_URL = "https://raw.githubusercontent.com/anthropics/claude-plugins-official/refs/heads/stats/stats/plugin-installs.json", CACHE_TTL_MS3;
399699
- var init_installCounts = __esm(() => {
399700
- init_axios2();
399701
- init_debug();
399702
- init_errors4();
399703
- init_fsOperations();
399704
- init_log5();
399705
- init_slowOperations();
399706
- init_fetchTelemetry();
399707
- init_pluginDirectories();
399708
- CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
399709
- });
399710
-
399711
399806
  // src/tui/commands/plugin/PluginOptionsDialog.tsx
399712
399807
  function buildFinalValues(fields, collected, configSchema, initialValues) {
399713
399808
  const finalValues = {};
@@ -400639,7 +400734,7 @@ function BrowseMarketplace({
400639
400734
  });
400640
400735
  }
400641
400736
  try {
400642
- const counts = await getInstallCounts();
400737
+ const counts = await getInstallCounts([marketplaceName]);
400643
400738
  if (cancelled)
400644
400739
  return;
400645
400740
  setInstallCounts(counts);
@@ -401320,7 +401415,7 @@ function BrowseMarketplace({
401320
401415
  dimColor: true,
401321
401416
  children: " (installed)"
401322
401417
  }, undefined, false, undefined, this),
401323
- installCounts && selectedMarketplace === OFFICIAL_MARKETPLACE_NAME && /* @__PURE__ */ jsx_dev_runtime286.jsxDEV(ThemedText, {
401418
+ installCounts?.get(plugin_6.pluginId) != null && /* @__PURE__ */ jsx_dev_runtime286.jsxDEV(ThemedText, {
401324
401419
  dimColor: true,
401325
401420
  children: [
401326
401421
  " · ",
@@ -401395,7 +401490,6 @@ var init_BrowseMarketplace = __esm(() => {
401395
401490
  init_marketplaceHelpers();
401396
401491
  init_marketplaceDisplayName();
401397
401492
  init_marketplaceManager();
401398
- init_officialMarketplace();
401399
401493
  init_pluginInstallationHelpers();
401400
401494
  init_pluginPolicy();
401401
401495
  init_stringUtils2();
@@ -402045,7 +402139,7 @@ function DiscoverPlugins({
402045
402139
  dimColor: true,
402046
402140
  children: " [Community Managed]"
402047
402141
  }, undefined, false, undefined, this),
402048
- installCounts && plugin_5.marketplaceName === OFFICIAL_MARKETPLACE_NAME && /* @__PURE__ */ jsx_dev_runtime287.jsxDEV(ThemedText, {
402142
+ installCounts?.get(plugin_5.pluginId) != null && /* @__PURE__ */ jsx_dev_runtime287.jsxDEV(ThemedText, {
402049
402143
  dimColor: true,
402050
402144
  children: [
402051
402145
  " · ",
@@ -402338,7 +402432,6 @@ var init_DiscoverPlugins = __esm(() => {
402338
402432
  init_installedPluginsManager();
402339
402433
  init_marketplaceHelpers();
402340
402434
  init_marketplaceManager();
402341
- init_officialMarketplace();
402342
402435
  init_pluginInstallationHelpers();
402343
402436
  init_pluginPolicy();
402344
402437
  init_stringUtils2();
@@ -469090,8 +469183,100 @@ var init_useAwaySummary = __esm(() => {
469090
469183
  BLUR_DELAY_MS = 5 * 60000;
469091
469184
  });
469092
469185
 
469186
+ // src/tui/utils/plugins/builtinMarketplaceSnapshots.ts
469187
+ function getBuiltinMarketplaceSnapshot(key) {
469188
+ return BUILTIN_MARKETPLACE_SNAPSHOTS.find((s) => s.key === key);
469189
+ }
469190
+ var BUILTIN_MARKETPLACE_SNAPSHOTS;
469191
+ var init_builtinMarketplaceSnapshots = __esm(() => {
469192
+ BUILTIN_MARKETPLACE_SNAPSHOTS = [
469193
+ { key: "agent-skills", manifest: { name: "agent-skills", owner: { name: "agent-skills", url: "https://gitcode.com/Ascend/agent-skills" }, plugins: [{ name: "cannbot-ops-direct-invoke-skills", description: "Ascend C Kernel 直调算子开发 Skills(27 个)。API 检索、Tiling 设计、精度调试、性能采集、环境检查、代码模板、SIMT 最佳实践等。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.0.4", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["ascendc", "skills", "direct-invoke", "operator", "kernel", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./ascendc-api-best-practices", "./ascendc-regbase-best-practice", "./ascendc-blaze-best-practice", "./ascendc-code-review", "./ascendc-direct-invoke-template", "./ascendc-docs-search", "./ascendc-env-check", "./npu-arch", "./ascendc-precision-debug", "./ascendc-runtime-debug", "./ascendc-crash-debug", "./ascendc-tiling-design", "./ops-precision-standard", "./ops-profiling", "./torch-ascendc-op-extension", "./ascendc-direct-invoke-to-registry-invoke", "./ascendc-docs-gen", "./ascendc-performance-best-practices", "./ascendc-perf-optimize", "./ascendc-registry-invoke-template", "./ascendc-registry-invoke-to-direct-invoke", "./ascendc-simt-best-practices", "./ascendc-simt-tiling-design", "./ascendc-st-design", "./ascendc-task-focus", "./ascendc-ut-develop", "./ascendc-whitebox-design", "./cann-env-setup", "./ops-simulator", "./ops-spec-gen", "./torch-ops-profiler"] }, { name: "cannbot-aiss-tiling-solver", description: "AISS-TilingSolver:Ascend C 算子 Tiling 参数自动求解工具(MatMul / Vector)。下载安装、构造 JSON 输入、运行求解、结果解读与故障排查。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.0.0", author: { name: "AISS Group at HIT", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["tiling_solver", "MatMul", "Vector", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./aiss-tiling-solver"] }, { name: "cannbot-catlass-op-skills", description: "Catlass 算子开发 Skills(3 个)。算子设计、算子开发、性能调优。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["catlass", "skills", "operator", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./catlass-op-design", "./catlass-op-develop", "./catlass-op-perf-tune"] }, { name: "cannbot-pypto-op-orchestrator-skills", description: "PyPTO 算子开发 Skills(8 个)。API 探索、Golden 生成、需求理解、算子设计与开发、性能调优、精度调试。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.1.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["pypto", "skills", "operator", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./pypto-api-explore", "./pypto-golden-generate", "./pypto-intent-understand", "./pypto-op-design", "./pypto-op-develop", "./pypto-op-perf-tune", "./pypto-precision-compare", "./pypto-precision-debug"] }, { name: "cannbot-triton-op-generator-skills", description: "Triton-Ascend 算子代码生成与优化 Skills(6 个)。任务提取、算法设计、代码生成、功能验证、性能优化,以及 NPU 架构参考。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["triton", "ascend", "skills", "operator", "generator", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./triton-task-extractor", "./triton-op-designer", "./triton-op-coding", "./triton-op-verifier", "./triton-latency-optimizer", "./npu-arch"] }, { name: "cannbot-torch-npugraph-ex-skills", description: "PyTorch 昇腾 NPU npugraph_ex Skills(7 个)。覆盖图模式知识、代码模板、性能诊断、问题分诊、编译错误、运行时错误和自定义算子入图。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/graph", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["torch", "torchair", "npugraph_ex", "npu", "skills", "cannbot"], scenarios: ["inference", "operator"], category: "skill-pack", skills: ["./torch-custom-ops-guide", "./torch-npugraph-ex-compile-error-diagnosis", "./torch-npugraph-ex-dfx-triage", "./torch-npugraph-ex-knowledge", "./torch-npugraph-ex-performance-diagnosis", "./torch-npugraph-ex-runtime-error-diagnosis", "./torch-npugraph-ex-template"] }, { name: "cannbot-model-infer-skills", description: "NPU 模型推理优化 Skills(11 个)。覆盖框架适配、并行策略、KVCache/FA、融合算子、图模式、精度/运行时调试、多流、预取和 SuperKernel。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/model", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["model-infer", "skills", "inference", "kvcache", "graph-mode", "cannbot"], scenarios: ["inference", "operator"], category: "skill-pack", skills: ["./model-infer-migrator", "./model-infer-parallel-analysis", "./model-infer-parallel-impl", "./model-infer-kvcache", "./model-infer-fusion", "./model-infer-graph-mode", "./model-infer-precision-debug", "./model-infer-runtime-debug", "./model-infer-multi-stream", "./model-infer-prefetch", "./model-infer-superkernel"] }, { name: "cannbot-tilelang-op-orchestrator-skills", description: "TileLang 算子开发 Skills(9 个)。环境检查、子模块拉取、算子设计、算子开发、测试设计、API 最佳实践、编程模式指南、性能优化、代码审查。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops-lab/tilelang/skills", strict: false, version: "1.1.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["tilelang", "skills", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./tilelang-api-best-practices", "./tilelang-env-check", "./tilelang-op-design", "./tilelang-op-develop", "./tilelang-op-test-design", "./tilelang-perf-optimization", "./tilelang-programming-model-guide", "./tilelang-review", "./tilelang-submodule-pull"] }, { name: "cannbot-cuda2ascend-simt-skills", description: "CUDA→Ascend SIMT 迁移 Skills(1 个)。CUDA 到 Ascend C SIMT 编程模型的代码迁移,含 API 映射、语法规则、约束校验。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops-lab", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["cuda", "ascend", "simt", "migration", "cannbot"], scenarios: ["operator", "migration"], category: "skill-pack", skills: ["./cuda2ascend-simt"] }, { name: "cannbot-infra-skills", description: "CANNBot 基础设施 Skills(5 个)。Skill 审查、GitCode Issue 生成/处理、PR 处理、GitCode 工具集。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/infra", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["infra", "gitcode", "code-review", "issue", "pr", "cannbot"], scenarios: ["code-review", "devops"], category: "skill-pack", skills: ["./cannbot-skill-reviewer", "./gitcode-issue-gen", "./gitcode-issue-handler", "./gitcode-pr-handler", "./gitcode-toolkit"] }, { name: "common-infra-skills", description: "昇腾 NPU 通用基础设施 Skills(6 个)。Docker 容器创建、NPU 驱动/固件安装、CANN 全套组件安装、算子环境配置、SwanLab 实验追踪配置、npu-smi 设备管理。触发:昇腾 NPU 开发环境搭建与运维场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "infra", "env-setup", "docker", "cann", "npu"], scenarios: ["env-setup", "deployment"], category: "skill-pack", skills: ["./ascend-docker", "./ascend-npu-driver-install", "./cann-nnal-installer", "./cann-operator-env-config", "./swanlab-setup", "./npu-smi"] }, { name: "common-ops-skills", description: "昇腾 NPU 通用运维与工具 Skills(6 个)。Profiling 异常分析、故障诊断、HCCL 通信测试、ModelScope 下载、大规模集群部署、K8s 健康检查。触发:昇腾 NPU 集群运维、性能诊断、模型下载场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "ops", "profiling", "fault-diagnose", "hccl", "modelscope", "k8s"], scenarios: ["profiling", "deployment"], category: "skill-pack", skills: ["./ascend-profiling-anomaly", "./fault_diagnose", "./hccl-test", "./modelscope-cli", "./large_scale_deploy", "./k8s-check-fix"] }, { name: "common-dev-skills", description: "昇腾 NPU 通用开发辅助 Skills(6 个)。Bug 自动修复、单元测试自动生成、Python 代码重构、安全代码审查、Skill 安全审计、Arxiv 论文推荐与 NPU 适配。触发:代码质量提升、安全审查、测试补充场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "dev", "code-review", "testing", "security", "refactoring"], scenarios: ["code-review", "testing", "documentation"], category: "skill-pack", skills: ["./auto-bug-fixer", "./auto-develop-test-gen", "./python-refactoring", "./security-code-review", "./skill-auditor", "./arxiv-recommendation-npu"] }, { name: "common-migration-skills", description: "昇腾 NPU 通用模型迁移 Skills(5 个)。推理仓库智能问答、ATC 模型转换全流程、msverl 日回归分诊、NPU 适配审查、PyTorch 模型自动化 NPU 迁移。触发:模型迁移到 NPU、GPU→NPU 适配、推理服务部署场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "migration", "npu", "atc", "inference", "model-convert"], scenarios: ["migration", "inference"], category: "skill-pack", skills: ["./ascend-inference-repos-copilot", "./atc-model-converter", "./msverl-daily-regression-triage", "./npu-adapter-reviewer", "./npu-model-migration"] }, { name: "common-deploy-skills", description: "昇腾 NPU 通用部署 Skills(3 个)。OM 部署器、OM Pipeline 适配器、ONNX-ATC 推理 Pipeline。触发:模型部署、推理服务构建场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "deploy", "om", "atc", "onnx", "pipeline"], scenarios: ["deployment", "inference"], category: "skill-pack", skills: ["./ascend-om-deployer", "./ascend-om-pipeline-adapter", "./ascend-onnx-atc-pipeline"] }, { name: "common-ut-skills", description: "昇腾 NPU 算子单元测试 Skills(2 个)。算子 UT 自动生成、操作系统适配。触发:算子测试开发、UT 补充场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "ut", "unit-test", "operator", "os-adapter"], scenarios: ["testing"], category: "skill-pack", skills: ["./ascend-operator-ut-gen", "./os_adapter"] }, { name: "ascend-transformer-boost-skills", description: "昇腾 Transformer 加速库(ATB)核心 Skills(15 个)。整合 ATB 测试框架编译、算子替换设计、ATB→ACLNN 算子迁移、CSV/ATK 测试用例生成与运行、Golden 开发、调试指南、NNAL 安装、迁移工作流、知识提取、知识维护、知识泛化、Pybind 代码生成全流程。触发:ATB 开发、ACLNN 迁移、Transformer 加速场景。", source: "./official/Common/ascend-transformer-boost", strict: false, version: "1.11.0", author: { name: "community" }, keywords: ["ascend", "atb", "transformer", "aclnn", "operator", "migration"], scenarios: ["operator", "inference", "migration"], category: "skill-pack", skills: ["./skills/atb-aclnn-operator-migration", "./skills/atb-aclnn-operator-replacement-designer", "./skills/atb-atk-testcase-generator", "./skills/atb-csv-testcase-generator", "./skills/atb-csv-tester", "./skills/atb-debug-guide", "./skills/atb-golden-developer", "./skills/atb-nnal-installer", "./skills/atb-ops-to-aclnn-migration-workflow", "./skills/atb-pybind-bindgen", "./skills/atb-pybind-test-generator", "./skills/atb-testframework-build", "./skills/atb-op-knowledge-extract", "./skills/atb-op-knowledge-update", "./skills/atb-knowledge-generalize"] }, { name: "mindspeed-megatron-skills", description: "MindSpeed Megatron 变更追踪与迁移 Skills(4 个)。Megatron 变更分析、Commit 追踪与规范化、Impact 映射到 MindSpeed 子系统、迁移交付物生成。触发:Megatron-LM 上游变更同步、MindSpeed 适配时。", source: "./official/MindSpeed", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "megatron", "migration", "commit-tracking", "impact"], scenarios: ["migration", "training"], category: "skill-pack", skills: ["./megatron-change-analyzer", "./megatron-commit-tracker", "./megatron-impact-mapper", "./megatron-migration-generator"] }, { name: "mindspeed-drivingsdk-skills", description: "MindSpeed 自驾 SDK 模型迁移 Skills(14 个)。模型代码迁移、NPU 训练、SSH 远程开发套件(连接/部署/调试/隧道/长任务)、MMLab 安装套件(mmcv/mmdet/mmdet3d/detectron2)。触发:自驾模型 NPU 适配迁移场景。", source: "./official/MindSpeed/drivingsdk-ascend-model-migration", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "drivingsdk", "model-migration", "npu", "ssh", "mmlab"], scenarios: ["migration", "training", "env-setup"], category: "skill-pack", skills: ["./ascend-mmlab-install-suite", "./ascend-mmlab-install-suite/detectron2", "./ascend-mmlab-install-suite/mmcv", "./ascend-mmlab-install-suite/mmdet", "./ascend-mmlab-install-suite/mmdet3d", "./model-migration", "./model-training", "./ssh-connection", "./ssh-connection/connect", "./ssh-connection/debug", "./ssh-connection/deploy", "./ssh-connection/long-task", "./ssh-connection/tunnel"] }, { name: "drivingsdk-model-migration-analysis", description: "自驾模型 NPU 适配技能。提供从模型分析、算子替换、适配方案到优化总结的完整流程。当用户需要将新的自动驾驶模型或 VLA 世界模型适配到昇腾 NPU 时触发。", source: "./official/MindSpeed", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "drivingsdk", "model-migration", "npu", "vla"], scenarios: ["migration"], category: "atomic-skill", skills: ["./drivingsdk-model-migration-analysis"] }, { name: "mindspeed-llm-ut-skills", description: "MindSpeed LLM 自动单元测试 Skills(7 个)。覆盖率分析、代码理解、覆盖率扫描、测试生成、pytest 编写、unittest 编写、测试运行。触发:MindSpeed-LLM 项目测试开发与覆盖率提升场景。", source: "./official/MindSpeed/mindspeed-llm-auto-ut-skills/skills", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "llm", "unit-test", "coverage", "pytest", "unittest"], scenarios: ["testing"], category: "skill-pack", skills: ["./analyse-coverage", "./code-comprehension", "./coverage", "./generate-unit-test", "./pytest-writer", "./run-mindspeed-llm-test", "./unittest-writer"] }, { name: "mindspeed-fsdp2-skills", description: "MindSpeed-MM FSDP2 端到端迁移 Skills(5 个)。统筹模型/数据/配置/验证子流程迁移,实现 MindSpeed-MM 到 FSDP2 的完整适配。触发:MindSpeed-MM FSDP2 迁移场景。", source: "./official/MindSpeed/mindspeed-mm-fsdp2-migration", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "fsdp2", "migration", "model", "config", "verification"], scenarios: ["migration", "training"], category: "skill-pack", skills: ["./mindspeed-fsdp2-config-migration", "./mindspeed-fsdp2-data-migration", "./mindspeed-fsdp2-migration-main", "./mindspeed-fsdp2-model-migration", "./mindspeed-fsdp2-verification"] }, { name: "vllm-ascend-skills", description: "vLLM Ascend 推理部署与测试 Skills(3 个)。vLLM Ascend 服务部署、FAQ 生成、测试失败分析。触发:vLLM 在昇腾 NPU 上的部署与问题排查场景。", source: "./official/vllm-ascend", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["vllm", "ascend", "npu", "deploy", "faq", "test"], scenarios: ["inference", "deployment"], category: "skill-pack", skills: ["./vllm-ascend-deploy", "./vLLM-ascend_FAQ_Generator", "./vllm-tests-failure-analysis"] }, { name: "verl-skills", description: "VERL 强化学习训练 Skills(2 个)。VERL 特性部署与异步 DAPO 训练。触发:VERL 强化学习框架在昇腾 NPU 上的部署与训练场景。", source: "./official/verl", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["verl", "rlhf", "dapo", "training", "npu"], scenarios: ["training"], category: "skill-pack", skills: ["./verl-feature-deploy", "./verl-async-dapo"] }, { name: "mindstudio-profiling-skills", description: "MindStudio Profiler 性能分析 Skills(9 个)。Profiler 数据校验、计算/通信/调度分析、DB Explorer、集群快慢 Rank 检测、算子 Profiler(msOpProf)、MFU 计算、msprof-analyze CLI。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "profiler", "performance", "analysis", "communication", "computation", "schedule", "mfu"], scenarios: ["profiling", "operator"], category: "skill-pack", skills: ["./mindstudio_profiler_data_check", "./ascend-profiler-db-explorer", "./ascend-computation-analysis", "./ascend-communication-analysis", "./ascend-schedule-analysis", "./cluster-fast-slow-rank-detector", "./msot-msopprof-operator-profiler", "./op-mfu-calculator", "./msprof-analyze-cli"] }, { name: "mindstudio-precision-debug-skills", description: "MindStudio 精度调试 Skills(3 个)。确定性计算分析、NaN/Overflow 检测、RL 训练推理一致性根因分析。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "precision", "debug", "nan", "overflow", "deterministic", "consistency"], scenarios: ["profiling", "operator"], category: "skill-pack", skills: ["./deterministic-calculation-analysis", "./nan-overflow-detection", "./rl-consistency-analysis"] }, { name: "mindstudio-ascendc-perf-optim-skills", description: "MindStudio Ascend C 算子性能优化 Skills(1 个)。基于 Profiling 数据的 Ascend C 算子端到端性能优化,含 API 调优、数据搬运、流水线、Tiling 等参考。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "ascendc", "performance", "optimization", "tiling", "pipeline"], scenarios: ["operator", "profiling"], category: "skill-pack", skills: ["./ascendc-operator-performance-optim"] }, { name: "mindstudio-msmodelslim-skills", description: "MindStudio msModelSlim 量化 Skills(6 个)。快速量化指引、模型分析、模型适配、反量化、逐层量化、适配器验证。覆盖 msModelSlim 量化全流程。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "msmodelslim", "quantization", "model-adapt", "dequantization"], scenarios: ["training", "inference"], category: "skill-pack", skills: ["./msmodelslim-quick-quant", "./msmodelslim-model-analysis", "./msmodelslim-model-adapt", "./msmodelslim-model-dequant", "./msmodelslim-layer-wise-quantization", "./msmodelslim-adapter-verification"] }, { name: "mindstudio-devtools-skills", description: "MindStudio 开发工具 Skills(3 个)。GitCode PR 代码审查、GitHub 原始文件获取、文档 UX 审查。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "code-review", "gitcode", "github", "document-ux"], scenarios: ["code-review", "devops"], category: "skill-pack", skills: ["./gitcode-code-reviewer", "./github-raw-fetch", "./document-ux-review"] }, { name: "community-ascendc-op-skills", description: "社区 Ascend C 算子开发全流程 Skills(17 个)。覆盖项目初始化→设计→代码生成→开发→编译调试→代码审查→精度调试/评估→性能评估/优化→测试用例→文档生成全流程,以及内存检测和增量文档。触发:社区 Ascend C 算子端到端开发场景。", source: "./community/Op", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascendc", "operator", "community", "design", "code-gen", "precision", "performance"], scenarios: ["operator"], category: "skill-pack", skills: ["./ascendc-operator-project-init", "./ascendc-operator-design", "./ascendc-operator-code-gen", "./ascendc-operator-dev", "./ascendc-operator-compile-debug", "./ascendc-operator-code-review", "./ascendc-operator-precision-debug", "./ascendc-operator-precision-eval", "./ascendc-operator-performance-eval", "./ascendc-operator-performance-optim", "./ascendc-operator-mssanitizer", "./ascendc-operator-testcase-gen", "./ascendc-operator-doc-gen", "./ascendc-operator-doc-writer", "./ascendc-op-doc-generator", "./ascendc-op-doc-incremental", "./ascendc-operator-st-gen"] }, { name: "community-catlass-op-skills", description: "社区 Catlass 算子开发全流程 Skills(4 个)。覆盖设计→代码生成→开发→性能优化全流程。触发:社区 Catlass 模板算子开发场景。", source: "./community/Op", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["catlass", "operator", "community", "design", "code-gen", "performance"], scenarios: ["operator"], category: "skill-pack", skills: ["./catlass-operator-design", "./catlass-operator-code-gen", "./catlass-operator-dev", "./catlass-operator-performance-optim"] }, { name: "community-triton-op-skills", description: "社区 Triton 算子开发全流程 Skills(11 个)。覆盖设计→代码生成→开发→代码审查→文档生成→环境配置→精度评估→性能评估/优化全流程,以及内存检测和共享组件。触发:社区 Triton-Ascend 算子开发场景。", source: "./community/Op", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["triton", "operator", "community", "design", "code-gen", "precision", "performance"], scenarios: ["operator"], category: "skill-pack", skills: ["./triton-operator-design", "./triton-operator-code-gen", "./triton-operator-dev", "./triton-operator-code-review", "./triton-operator-doc-gen", "./triton-operator-env-config", "./triton-operator-precision-eval", "./triton-operator-performance-eval", "./triton-operator-performance-optim", "./triton-operator-mssanitizer", "./triton-operator-shared"] }, { name: "community-triton-tilelang-migration-skills", description: "社区 Triton/TileLang GPU→NPU 迁移 Skills(3 个)。Triton 向量算子 GPU→NPU 迁移、TileLang 向量算子 NPU 迁移、Triton-Ascend 算子优化。触发:GPU 算子向昇腾 NPU 迁移适配场景。", source: "./community/Op", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["triton", "tilelang", "migration", "gpu-to-npu", "community"], scenarios: ["operator", "migration"], category: "skill-pack", skills: ["./simple-vector-triton-gpu-to-npu", "./tilelang-vector-ascend-ops-migration", "./vector-triton-ascend-ops-optimizer"] }] } },
469194
+ { key: "atlas-plugins", manifest: { name: "atlas-plugins", owner: { name: "vince" }, metadata: { description: "atlas-plugins marketplace (scaffolded)" }, plugins: [{ name: "ascend-tiling-design", source: "./plugins/ascend-tiling-design", version: "0.1.0", description: "Ascend C 算子 Tiling 设计(多核切分/UB切分/Buffer规划/分支覆盖四要素 + 9 算法分类策略 + AISS 指针)" }, { name: "ascend-precision-debug", source: "./plugins/ascend-precision-debug", version: "0.1.0", description: "Ascend 精度调试(模型级 msprobe 两层级 / 算子级 DumpTensor 7 步 / PyPTO 二分 + 误差标准 + 判定决策树)" }, { name: "ascend-runtime-debug", source: "./plugins/ascend-runtime-debug", version: "0.1.0", description: "Ascend 算子运行时故障调试(错误码分类 / plog 解析 / 卡死崩溃 triage / Kernel 二进制构建排查)" }, { name: "ascend-perf-optimize", source: "./plugins/ascend-perf-optimize", version: "0.1.0", description: "Ascend 算子/模型性能优化(三层管线四步流程 + msprof 采集 + 10 类 bound 定位与定向优化)" }, { name: "ascend-test-design", source: "./plugins/ascend-test-design", version: "0.1.0", description: "Ascend C 算子测试设计(ST/UT/whitebox/golden 四类测试选择 + 设计流程 + 策略决策树)" }, { name: "ascend-code-review", source: "./plugins/ascend-code-review", version: "0.1.0", description: "Ascend C 算子代码检视(假设检验驱动逐条检视 + 5 workflow 路由 + 红线问题 + 缺陷修复路由)" }, { name: "cannbot-ops-direct-invoke", source: "./plugins/cannbot-ops-direct-invoke", version: "0.1.0", description: "官方 CANNBot 直调算子 skill 包(27 技能)的 Atlas 策展封装:API 检索/Tiling 设计/精度调试/性能采集/代码模板/SIMT 最佳实践,路由到 Atlas 算子开发工具链。触发:Ascend C 算子端到端开发(API 检索→tiling→codegen→编译→golden 验证)。" }, { name: "cannbot-aiss-tiling-solver", source: "./plugins/cannbot-aiss-tiling-solver", version: "0.1.0", description: "官方 AISS-TilingSolver skill 的 Atlas 策展封装:Ascend C 算子 Tiling 参数自动求解(MatMul/Vector),JSON 输入构造→求解→结果解读与故障排查。触发:不想手动设计 tiling、想自动求解最优 tiling 参数。" }, { name: "cannbot-catlass-op", source: "./plugins/cannbot-catlass-op", version: "0.1.0", description: "官方 CANNBot Catlass 算子 skill 包(3 技能)的 Atlas 策展封装:Catlass 算子设计/开发/性能调优。触发:用 Catlass 模板做 GEMM/卷积类算子开发或性能调优。" }, { name: "cannbot-pypto-op-orchestrator", source: "./plugins/cannbot-pypto-op-orchestrator", version: "0.1.0", description: "官方 CANNBot PyPTO 算子 skill 包(8 技能)的 Atlas 策展封装:API 探索/Golden 生成/需求理解/算子设计与开发/性能调优/精度调试。触发:PyPTO(Python 算子)开发或精度/性能调优。" }, { name: "cannbot-triton-op-generator", source: "./plugins/cannbot-triton-op-generator", version: "0.1.0", description: "官方 CANNBot Triton-Ascend 算子 skill 包(6 技能)的 Atlas 策展封装:任务提取/算法设计/代码生成/功能验证/性能优化/NPU 架构参考。触发:Triton-Ascend 算子代码生成或优化。" }, { name: "cannbot-cuda2ascend-simt", source: "./plugins/cannbot-cuda2ascend-simt", version: "0.1.0", description: "官方 CANNBot CUDA→Ascend SIMT 迁移 skill 的 Atlas 策展封装:CUDA 到 Ascend C SIMT 编程模型的代码迁移(API 映射/语法规则/约束校验)。触发:把 CUDA kernel 迁移到 Ascend C SIMT。" }, { name: "cannbot-tilelang-op", source: "./plugins/cannbot-tilelang-op", version: "0.1.0", description: "官方 CANNBot TileLang 算子 skill 包(9 技能)的 Atlas 策展封装:环境检查/子模块拉取/算子设计/开发/测试设计/API 最佳实践/编程模式指南/性能优化/代码审查。触发:TileLang 算子端到端开发。" }, { name: "community-ascendc-op", source: "./plugins/community-ascendc-op", version: "0.1.0", description: "社区 Ascend C 算子开发全流程 skill 包(17 技能)的 Atlas 策展封装:项目初始化→设计→codegen→开发→编译调试→code review→精度调试/评估→性能评估/优化→测试用例→文档。触发:社区 Ascend C 算子端到端开发。" }, { name: "community-catlass-op", source: "./plugins/community-catlass-op", version: "0.1.0", description: "社区 Catlass 算子开发全流程 skill 包(4 技能)的 Atlas 策展封装:设计→codegen→开发→性能优化。触发:社区 Catlass 模板算子开发。" }, { name: "community-triton-op", source: "./plugins/community-triton-op", version: "0.1.0", description: "社区 Triton 算子开发全流程 skill 包(11 技能)的 Atlas 策展封装:设计→codegen→开发→code review→文档→环境配置→精度评估→性能评估/优化→内存检测。触发:社区 Triton-Ascend 算子开发。" }, { name: "cannbot-infra-skills", source: "./plugins/cannbot-infra-skills", version: "0.1.0", description: "官方 CANNBot 基础设施 skill 包(5 技能)的 Atlas 策展封装:Skill 审查/GitCode Issue 生成与处理/PR 处理/GitCode 工具集 + 故障采集/错误分类/性能分析路由。触发:NPU 问题定位、故障采集与分诊、CANNBot 工程问题处理。" }, { name: "common-infra-skills", source: "./plugins/common-infra-skills", version: "0.1.0", description: "昇腾 NPU 通用基础设施 skill 包(6 技能)的 Atlas 策展封装:Docker 容器创建/驱动固件安装/CANN 全套组件安装/算子环境配置/SwanLab 追踪/npu-smi 设备管理。触发:昇腾 NPU 开发环境搭建与运维、设备状态检查。" }, { name: "mindstudio-ascendc-perf-optim", source: "./plugins/mindstudio-ascendc-perf-optim", version: "0.1.0", description: "MindStudio Ascend C 算子性能优化 skill 的 Atlas 策展封装:基于 Profiling 数据的端到端性能优化(API 调优/数据搬运/流水线/Tiling 参考)。触发:对 Ascend C 算子做数据驱动的性能优化。" }, { name: "cannbot-model-infer", source: "./plugins/cannbot-model-infer", version: "0.1.0", description: "官方 CANNBot NPU 模型推理优化 skill 包(11 技能)的 Atlas 策展封装:框架适配/并行策略/KVCache+FA/融合算子/图模式/精度运行时调试/多流/预取/SuperKernel。触发:LLM/大模型在 NPU 上的推理性能优化。" }, { name: "vllm-ascend", source: "./plugins/vllm-ascend", version: "0.1.0", description: "vLLM-Ascend 推理部署与测试 skill 包(3 技能)的 Atlas 策展封装:vLLM Ascend 服务部署/FAQ 生成/测试失败分析。触发:vLLM 在昇腾 NPU 上的部署与问题排查。" }, { name: "mindspeed-drivingsdk", source: "./plugins/mindspeed-drivingsdk", version: "0.1.0", description: "MindSpeed 自驾 SDK 模型迁移 skill 包(14 技能)的 Atlas 策展封装:模型代码迁移/NPU 训练/SSH 远程开发套件/MMLab 安装套件。触发:自驾(VLA)模型 NPU 适配迁移。" }, { name: "common-deploy", source: "./plugins/common-deploy", version: "0.1.0", description: "昇腾 NPU 通用部署 skill 包(3 技能)的 Atlas 策展封装:OM 部署器/OM Pipeline 适配器/ONNX-ATC 推理 Pipeline。触发:模型部署、推理服务构建。" }, { name: "common-migration", source: "./plugins/common-migration", version: "0.1.0", description: "昇腾 NPU 通用模型迁移 skill 包(5 技能)的 Atlas 策展封装:推理仓库智能问答/ATC 模型转换全流程/msverl 回归分诊/NPU 适配审查/PyTorch 模型 NPU 迁移。触发:模型迁移到 NPU、GPU→NPU 适配。" }] } },
469195
+ { key: "claude-plugins-official", manifest: { $schema: "https://anthropic.com/claude-code/marketplace.schema.json", name: "claude-plugins-official", description: "Directory of popular Claude Code extensions including development tools, productivity plugins, and MCP integrations", owner: { name: "Anthropic", email: "support@anthropic.com" }, renames: { adlc: "agentforce-adlc", airwallex: "airwallex-agentos", "convex-backend": "convex", vals: "valtown", "wordpress.com": "build-with-wordpress", "qodo-skills": "qodo", "atlassian-forge-skills": "forge-skills", "azure-skills": "azure", "sonarqube-agent-plugins": "sonarqube" }, plugins: [{ name: "42crunch-api-security-testing", description: "Automate API security directly in Claude Code with 42Crunch - automatically audit OpenAPI specs, detect vulnerabilities aligned with OWASP API Security risks (including BOLA/BFLA), and apply AI-powered fixes. Designed for AI-assisted development workflows, it provides continuous guardrails through an audit->scan->remediate->validate loop, ensuring APIs meet enterprise security standards before deployment.", author: { name: "42Crunch" }, category: "security", source: { source: "git-subdir", url: "https://github.com/42Crunch-AI/claude-plugins.git", path: "plugins/api-security-testing", ref: "v1.5.5", sha: "30287f5e3f122a646d1ac5ca3ab96e130c52a3ad" }, homepage: "https://42crunch.com" }, { name: "adobe-for-creativity", description: "Harness Adobe's creative AI-powered tools to edit images, automate design workflows, and bring creative visions to life — from background removal to vectorization and professional retouching.", author: { name: "Adobe" }, category: "design", source: { source: "git-subdir", url: "https://github.com/adobe/skills.git", path: "plugins/creative-cloud/adobe-for-creativity", ref: "main", sha: "304aa23dfd84aeb7b005816962d1bfb40d27750a" }, homepage: "https://github.com/adobe/skills/tree/main/plugins/creative-cloud/adobe-for-creativity" }, { name: "agent-sdk-dev", description: "Development kit for working with the Claude Agent SDK", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/agent-sdk-dev", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/agent-sdk-dev" }, { name: "agentforce-adlc", description: "Agentforce Agent Development Life Cycle — author, discover, scaffold, deploy, test, and optimize .agent files", category: "development", source: { source: "url", url: "https://github.com/SalesforceAIResearch/agentforce-adlc.git", sha: "09bf1539d41f9ff355ba3eb5d05d4a75813423bb" }, homepage: "https://github.com/SalesforceAIResearch/agentforce-adlc" }, { name: "ai-plugins", description: "Set up endorctl and use Endor Labs to scan, prioritize, and fix security risks across your software supply chain", source: { source: "url", url: "https://github.com/endorlabs/ai-plugins.git", sha: "2de00883bd2be8b8578b46ab09baf2c8731376de" }, homepage: "https://www.endorlabs.com" }, { name: "aikido", description: "Aikido Security scanning for Claude Code — SAST, secrets, and IaC vulnerability detection powered by the Aikido MCP server.", source: { source: "url", url: "https://github.com/AikidoSec/aikido-claude-plugin.git", sha: "02f018ad4da175a2a5ad6ca9451c3d309d105fab" }, homepage: "https://github.com/AikidoSec/aikido-claude-plugin" }, { name: "airtable", description: "Airtable is the database and operations layer for your agents — whether running product, marketing, sales, ops, HR, or a custom business app. It combines structured data with multiplayer visual surfaces (grid, kanban, calendar, gallery, timeline) humans and agents share — plus sync integrations to Jira, Salesforce, Zendesk, Google Drive, Databricks, and the rest of your stack, all backed by enterprise governance. This plugin makes Claude fluent in Airtable: creating bases and schema, working with records, and sharing UI for collaboration. Bundles the official Airtable MCP server.", author: { name: "Airtable" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/Airtable/skills.git", path: "plugins/airtable", ref: "main", sha: "812ee67f1fd3d76fb45ff8df40afaa0448602ba8" }, homepage: "https://www.airtable.com" }, { name: "airwallex-agentos", displayName: "Airwallex", description: "Bring Airwallex's global financial infrastructure to Claude. Orchestrate actions across your account in plain language, e.g., set up invoices from a PO, onboard suppliers from invoices, and check current cash position across currencies. AgentOS bundles pre-built finance Skills with MCP servers. A public CLI connects your agent to Airwallex's capabilities.", author: { name: "Airwallex" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/airwallex/airwallex-marketplace.git", path: "plugins/airwallex-agentos", ref: "master", sha: "d323dd68c85874f6311a1bd20184f803a96e09a9" }, homepage: "https://www.airwallex.com/docs" }, { name: "airwallex-dev", description: "Build Airwallex payment integrations in your own codebase. Generates the checkout, card-element, onboarding, and subscription-billing code for an Airwallex integration and wires it into your project: Hosted Payment Page, Drop-in and Split Card elements, connected-account KYC onboarding, and Billing Hosted Checkout for subscriptions and card-saving. Also plans card-on-file merchant-initiated flows for AI providers such as top-ups and auto-recharge.", author: { name: "Airwallex" }, category: "development", source: { source: "git-subdir", url: "https://github.com/airwallex/airwallex-marketplace.git", path: "plugins/airwallex-dev", ref: "master", sha: "d4593e33a9e1177a44b895ca0a1d6e015215736f" }, homepage: "https://www.airwallex.com/docs" }, { name: "aiven", description: "Easily deploy managed PostgreSQL (pg), Kafka, OpenSearch, Clickhouse and other databases, streaming and apps. Free tier available, up and running in minutes.", author: { name: "Aiven" }, category: "database", source: { source: "url", url: "https://github.com/aiven/aiven-ai-plugins.git", sha: "634f41d6852957cb9280e9245f2ea6f74645b4f1" }, homepage: "https://aiven.io" }, { name: "alloydb", description: "Create, connect, and interact with an AlloyDB for PostgreSQL database and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/alloydb.git", sha: "00ee6ce2bcf88b46da4bf298a3ad8c0ad85877c8" }, homepage: "https://cloud.google.com/alloydb" }, { name: "alloydb-omni", description: "Create, connect, and interact with an AlloyDB Omni database and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/alloydb-omni.git", sha: "ae7e42c4e428e303adcc96942f4fc35cb6b27d61" }, homepage: "https://github.com/gemini-cli-extensions/alloydb-omni" }, { name: "altimate-code", description: "Delegates dbt and warehouse work to altimate-code, a specialized CLI agent with 100+ purpose-built data tools (SQL analysis, column-level lineage, dbt build/test/run, warehouse profiling, FinOps, connectivity to Snowflake, BigQuery, Redshift, Databricks, Postgres, MySQL, DuckDB).", author: { name: "AltimateAI" }, category: "database", source: { source: "git-subdir", url: "https://github.com/AltimateAI/altimate-claude-plugin.git", path: "plugins/altimate-code", ref: "main", sha: "b7c8f68b3dfd303ab3ccf2f43934098811dfe2aa" }, homepage: "https://www.altimate.ai" }, { name: "amazon-location-service", description: "Guide developers through adding maps, places search, geocoding, routing, and other geospatial features with Amazon Location Service, including authentication setup, SDK integration, and best practices.", category: "location", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/amazon-location-service", ref: "main", sha: "9898ddc4dcf7dd23ddb939cec1b905311dc7381d" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "amd-skills", description: "AMD's verified Agent Skills in one plugin: route image/audio through local AI on Ryzen AI, serve LLMs on AMD Instinct GPUs with vLLM, and analyze GPU kernel and PyTorch trace performance.", author: { name: "AMD" }, category: "development", source: { source: "git-subdir", url: "https://github.com/amd/skills.git", path: "skills", ref: "main", sha: "6916fb371d1cba40757b223cf16b4cd4912b202f" }, strict: false, skills: ["./local-ai-use", "./local-ai-app-integration", "./serving-llms-on-instinct", "./tracelens-analysis-orchestrator"], homepage: "https://developer.amd.com/" }, { name: "amplitude", source: { source: "git-subdir", url: "https://github.com/amplitude/mcp-marketplace.git", path: "plugins/amplitude", ref: "main", sha: "96fc7d4c58bb33b4e60c334d34ad944c8a246869" }, description: "Use Amplitude as an expert analyst — instrument Amplitude, discover product opportunities, analyze charts, create dashboards, manage experiments, and understand users and accounts.", category: "monitoring", homepage: "https://github.com/amplitude/mcp-marketplace" }, { name: "apollo", description: "Prospect, enrich leads, load outreach sequences, and query sales analytics with Apollo.io — one-click MCP server integration for Claude Code and Cowork.", author: { name: "Apollo.io" }, category: "productivity", source: { source: "url", url: "https://github.com/apolloio/apollo-mcp-plugin.git", sha: "bd0513c961f02105492fcff0d7d29c9cccf1ed23" }, homepage: "https://www.apollo.io/" }, { name: "apollo-skills", description: "Apollo GraphQL agent skills for Claude Code — Apollo Client, Server, Federation, Connectors, Router, Rover CLI, iOS, Kotlin, and the Apollo MCP server. Covers schema design, query optimization, and GraphQL best practices.", author: { name: "Apollo GraphQL" }, category: "development", source: { source: "url", url: "https://github.com/apollographql/skills.git", sha: "c288eb80629dd2309eed81f23d693f66a452d043" }, homepage: "https://www.apollographql.com" }, { name: "appwrite", description: "Appwrite tools for Claude Code, including SDK skills, Appwrite MCP servers, and deployment commands.", author: { name: "Appwrite" }, category: "development", source: { source: "url", url: "https://github.com/appwrite/claude-plugin.git", sha: "ab3c90b37c95b7068f0c064dc562cf21958e8e19" }, homepage: "https://appwrite.io" }, { name: "asana", description: "Asana project management integration. Connects Claude Code to Asana's V2 MCP server to create and manage tasks, search projects, update assignments, and track progress. Requires a one-time Asana OAuth app setup — run /asana-setup after installing.", category: "productivity", source: "./external_plugins/asana", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/asana" }, { name: "astronomer-data-agents", description: "Data engineering for Apache Airflow and Astronomer. Author DAGs with best practices, debug pipeline failures, trace data lineage, profile tables, migrate Airflow 2 to 3, and manage local and cloud deployments.", category: "development", source: { source: "url", url: "https://github.com/astronomer/agents.git", sha: "9b5a33171e36ecda135f22e77a845d9c405b519e" }, homepage: "https://github.com/astronomer/agents" }, { name: "atlan", description: "Atlan data catalog plugin for Claude Code. Search, explore, govern, and manage your data assets through natural language. Powered by the Atlan MCP server with semantic search, lineage traversal, glossary management, data quality rules, and more.", source: { source: "url", url: "https://github.com/atlanhq/agent-toolkit.git", sha: "86bb1ad27f80e189b328333d2271b360ae579f2b" }, homepage: "https://docs.atlan.com/" }, { name: "atlassian", description: "Connect to Atlassian products including Jira and Confluence. Search and create issues, access documentation, manage sprints, and integrate your development workflow with Atlassian's collaboration tools.", category: "productivity", source: { source: "url", url: "https://github.com/atlassian/atlassian-mcp-server.git", sha: "eb9a5956a7ac6380c731c725a8382da53ad6d980" }, homepage: "https://github.com/atlassian/atlassian-mcp-server" }, { name: "atlassian-twg-cli", description: `Teamwork Graph CLI is Atlassian's agent-first interface to your entire work context: Jira issues, Confluence pages, Bitbucket PRs, along with your connected third-party data sources. Purpose-built for coding agents like Claude Code (terminal or desktop), and powered by Atlassian's context graph. Try: "draft a Jira issue from this PR and link it to the epic." Using Claude Code in the browser? Install the Atlassian Rovo MCP plugin instead. Run /twg-setup after install to connect Atlassian Teamwork Graph CLI to Claude Code.`, author: { name: "Atlassian" }, category: "productivity", source: { source: "url", url: "https://github.com/atlassian-labs/twg-plugins.git", sha: "b3336ef63d45e2636ff411a922ed602244e0f3db" }, homepage: "https://developer.atlassian.com/cloud/twg-cli/" }, { name: "atomic-agents", description: "Comprehensive development workflow for building AI agents with the Atomic Agents framework. Includes specialized agents for schema design, architecture planning, code review, and tool development. Features guided workflows, progressive-disclosure skills, and best practice validation.", category: "development", source: { source: "url", url: "https://github.com/BrainBlend-AI/atomic-agents.git", path: "claude-plugin/atomic-agents", sha: "b15ca449a81278b1c92666bdf9a2e57a817dcacd" }, homepage: "https://github.com/BrainBlend-AI/atomic-agents", tags: ["community-managed"] }, { name: "auth0", description: "Enterprise-grade auth, easy to implement. Add login, SSO, MFA, and access control to any app with framework-aware guidance.", author: { name: "Auth0", url: "https://auth0.com" }, category: "security", source: { source: "git-subdir", url: "https://github.com/auth0/agent-skills.git", path: "plugins/auth0", ref: "main", sha: "f135610540ea41e4d99882dc1f06162030c7340b" }, homepage: "https://auth0.com" }, { name: "aws-agents", description: "Build, deploy, and operate AI agents on AWS. Skills for scaffolding agents with Amazon Bedrock AgentCore, connecting tools, memory, policies, evaluation, debugging, and production hardening.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/aws/agent-toolkit-for-aws.git", path: "plugins/aws-agents", ref: "main", sha: "57ce9edb2126292efaf5298801e226e1ef661a4a" }, homepage: "https://github.com/aws/agent-toolkit-for-aws" }, { name: "aws-agents-for-devsecops", description: "Investigate incidents, review code and execute UAT for release readiness, scan code for vulnerabilities, and run penetration tests with AWS DevOps Agent and AWS Security Agent.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/aws/agent-toolkit-for-aws.git", path: "plugins/aws-agents-for-devsecops", ref: "main", sha: "68d9e8541c45afd2510662bcea69fe1e433ea9db" }, homepage: "https://github.com/aws/agent-toolkit-for-aws" }, { name: "aws-amplify", description: "Build full-stack apps with AWS Amplify Gen 2 using guided workflows for authentication, data models, storage, GraphQL APIs, and Lambda functions.", category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/aws-amplify", ref: "main", sha: "c65ee436b0db77bb75d380aef6fbdc9b114edf2a" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "aws-core", description: "Build, deploy, and operate applications on AWS. Skills to author infrastructure-as-code, use core services, and complete common tasks.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/aws/agent-toolkit-for-aws.git", path: "plugins/aws-core", ref: "main", sha: "7fcb1da17abba610d7becc973c2141b40412e02c" }, homepage: "https://github.com/aws/agent-toolkit-for-aws" }, { name: "aws-data-analytics", description: "Data lake, analytics, and ETL workflows with S3 Tables, AWS Glue, and Athena.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/aws/agent-toolkit-for-aws.git", path: "plugins/aws-data-analytics", ref: "main", sha: "08ad220e4e9bbc498821ce9360b3dcdf4813121d" }, homepage: "https://github.com/aws/agent-toolkit-for-aws" }, { name: "aws-serverless", description: "Design, build, deploy, test, and debug serverless applications with AWS Serverless services.", category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/aws-serverless", ref: "main", sha: "34afdf5005325f17d5da2d1443b87f27a53b0a20" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "aws-startup-advisor", description: "Personalized architecture, cost, security, and migration guidance for startups. From day-one account setup and security baselines to production-ready infrastructure, cost optimization, and beyond. Includes AWS Activate Credits eligibility, 60+ exclusive startup offers, and multi-account multi-region support. Built on expertise from AWS Startup Solutions Architects and patterns from 350,000+ startups.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/startups.git", path: "advisor/plugins/aws-startup-advisor", ref: "main", sha: "dd7096bd634649bc89b6511d61cff16f58623284" }, homepage: "https://github.com/awslabs/startups" }, { name: "aws-transform", description: "Migrate, modernize, and upgrade codebases to AWS. Transforms .NET Framework to .NET 8/10, mainframe COBOL to Java, VMware VMs to EC2, SQL Server to Aurora, and upgrades Java/Python/Node.js versions and AWS SDKs. AWS Transform - continuous modernization analyzes codebases for tech debt, security issues, and upgrade opportunities, then remediates them.", author: { name: "Amazon Web Services" }, category: "migration", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/aws-transform", ref: "main", sha: "adc01133bbd01433dcb2c0f98641f2b85694f92f" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "azure", description: "Transform Claude into an Azure expert. This plugin integrates the Azure MCP server and specialized Azure skills to move beyond generic advice. It enables Claude to perform real-world tasks: listing resources, validating deployments, diagnosing infrastructure issues, and optimizing costs across 50+ Azure services.", category: "deployment", source: { source: "url", url: "https://github.com/microsoft/azure-skills.git", sha: "abaf74ac8f62fbe9f83d7ccb2bd991dca929a4da" }, homepage: "https://github.com/microsoft/azure-skills" }, { name: "azure-cosmos-db-assistant", source: { source: "url", url: "https://github.com/AzureCosmosDB/cosmosdb-claude-code-plugin.git", sha: "f1e0498579a9251e5f3179b92d25d6ce3409bae5" }, description: "Expert assistant for Azure Cosmos DB — data modeling, query optimization, performance tuning, and best practices.", category: "database", homepage: "https://github.com/AzureCosmosDB/cosmosdb-claude-code-plugin" }, { name: "azure-sql-developer", description: "Agent skills for Azure SQL Developer, the Azure SQL Database engine running locally in a container. Teaches your agent to run the engine, connect, migrate, scaffold, build RAG, wire CI, and go local-to-cloud, using the real Private Preview image instead of the SQL Server image.", author: { name: "Microsoft" }, category: "database", source: { source: "url", url: "https://github.com/microsoft/azure-sql-database-container.git", sha: "8a82f442df5bb7bbf65f1eb774e32d1f55a07e04" }, homepage: "https://github.com/microsoft/azure-sql-database-container" }, { name: "base44", description: "Build and deploy Base44 full-stack apps with CLI project management and JavaScript/TypeScript SDK development skills", category: "development", source: { source: "url", url: "https://github.com/base44/skills.git", sha: "592535c8aa52a088eba364a4805e3c34612ff762" }, homepage: "https://docs.base44.com" }, { name: "bigdata-com", description: "Official Bigdata.com plugin providing financial research, analytics, and intelligence tools powered by Bigdata MCP.", author: { name: "RavenPack" }, category: "database", source: { source: "git-subdir", url: "https://github.com/Bigdata-com/bigdata-plugins-marketplace.git", path: "plugins/bigdata-com", ref: "main", sha: "2a52a001366227e205cfa7565d78e8198dc42fa8" }, homepage: "https://docs.bigdata.com" }, { name: "bigquery-data-analytics", description: "Connect, query, and generate data insights for BigQuery datasets and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/bigquery-data-analytics.git", sha: "8475b9c79e38c92a8e28cefc54890d48c74efebc" }, homepage: "https://github.com/gemini-cli-extensions/bigquery-data-analytics" }, { name: "boltz", description: "Predict structures, screen molecules and proteins, and design binders with Boltz from Claude Code.", author: { name: "Boltz" }, category: "development", source: { source: "git-subdir", url: "https://github.com/boltz-bio/boltz-api-skills.git", path: "plugins/boltz", ref: "main", sha: "beafb3c16236347ab10fb54f78a5da49cbf7c7bb" }, homepage: "https://boltz.bio" }, { name: "blackrock-advisor-center-plugin", description: "BlackRock Advisor Center 360° skills for financial advisors: portfolio review, opportunity and fund-health checks, guided benchmark selection, guided portfolio building, wealth projections, and routing to Advisor Center web workflows. Requires the BlackRock Advisor Center connector and an Advisor Center account.", author: { name: "BlackRock Advisor Center" }, category: "productivity", source: { source: "url", url: "https://github.com/blackrock/advisor-center-agent-skills.git", sha: "591c758960c18c26fe8342ddb8ad3ba4dcfac6fe" }, homepage: "https://github.com/blackrock/advisor-center-agent-skills" }, { name: "box", description: "Work with your Box content directly from Claude Code — search files, organize folders, collaborate with your team, and use Box AI to answer questions, summarize documents, and extract data without leaving your workflow.", category: "productivity", source: { source: "url", url: "https://github.com/box/skills.git", sha: "35567f913a2bfd7f8b59367c9df3ae14b5ad4cfe" }, skills: ["./skills/box", "./skills/box-legal-workflows", "./skills/box-legal-workflows-contract", "./skills/box-legal-workflows-intake", "./skills/box-legal-workflows-ma"], homepage: "https://github.com/box/skills" }, { name: "brightdata-plugin", description: "Web scraping, Google search, structured data extraction, and MCP server integration powered by Bright Data. Includes 7 skills: scrape any webpage as markdown (with bot detection/CAPTCHA bypass), search Google with structured JSON results, extract data from 40+ websites (Amazon, LinkedIn, Instagram, TikTok, YouTube, and more), orchestrate Bright Data's 60+ MCP tools, built-in best practices for Web Unlocker, SERP API, Web Scraper API, and Browser API, Python SDK best practices for the brightda...", source: { source: "url", url: "https://github.com/brightdata/skills.git", sha: "e825f02fbcd7a89087fd1053a57ddcd45113370f" }, homepage: "https://docs.brightdata.com" }, { name: "browser-use", description: "Give Claude a real browser — your Chrome or a Browser Use Cloud browser. Use it whenever a task involves a website or web app: browsing, scraping and data extraction, filling forms, testing sites, taking screenshots, automating web workflows.", author: { name: "Browser Use" }, category: "automation", source: { source: "git-subdir", url: "https://github.com/browser-use/plugins.git", path: "browser-use", ref: "main", sha: "a25f0a262928bcbb62071432636d943ed9f2b6aa" }, homepage: "https://browser-use.com" }, { name: "buildkite", description: "Official Buildkite skills for Claude Code, Cursor, and other AI coding agents — pipelines, migration, preflight, agent runtime, CLI, and API", author: { name: "Buildkite" }, category: "development", source: { source: "url", url: "https://github.com/buildkite/skills.git", sha: "a4bb20c6bf9ae535335f782015f65b9975065f27" }, homepage: "https://buildkite.com" }, { name: "canva", description: "Create, edit, review, resize, and brand-check Canva designs with the Canva MCP server.", author: { name: "Canva" }, category: "design", source: { source: "git-subdir", url: "https://github.com/canva-sdks/canva-skills.git", path: "plugins/canva", ref: "main", sha: "b56291ea0a36d0a941e1478b47959be5f1771dee" }, homepage: "https://www.canva.com" }, { name: "carbone-skill", description: "Official Carbone skill — complete templating language reference covering tags, loops, conditions, formatters, aggregators, and all output formats (DOCX, XLSX, PPTX, ODT, HTML, Markdown, PDF)", author: { name: "Carbone" }, category: "productivity", source: { source: "url", url: "https://github.com/carboneio/carbone-skill.git", sha: "25207b3f52b97872312eab997ee5c62cc5c9542d" }, homepage: "https://carbone.io" }, { name: "carta-cap-table", description: "Carta Cap Table plugin — skills and hooks for querying cap tables, grants, SAFEs, 409A valuations, waterfall scenarios, and more", author: { name: "Carta Engineering" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/carta/plugins.git", path: "plugins/carta-cap-table", ref: "main", sha: "12bb447e186f52c20aee6588761498f2acf76fc3" }, homepage: "https://carta.com" }, { name: "carta-crm", description: "Manage the Carta CRM conversationally — search, add, update, and enrich investors, companies, contacts, deals, notes, and fundraisings via the Carta CRM MCP Server.", author: { name: "Carta Engineering" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/carta/plugins.git", path: "plugins/carta-crm", ref: "main", sha: "81b8f40844bd646842538a4583409f9aa54c42db" }, homepage: "https://carta.com" }, { name: "carta-investors", description: "Carta Investors plugin — skills for querying investor data, performance benchmarks, regulatory reporting, AGM deck generation, brand extraction, and more via the Carta MCP Server.", author: { name: "Carta Engineering" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/carta/plugins.git", path: "plugins/carta-investors", ref: "main", sha: "12bb447e186f52c20aee6588761498f2acf76fc3" }, homepage: "https://carta.com" }, { name: "catalyst-by-zoho", description: "Official Claude Code plugin for Catalyst by Zoho — full-stack serverless cloud platform. With Skills that covers all services, SDKs, CLI, architecture patterns, pricing, migration guides, and Zoho MCP tool-based resource management.", author: { name: "Catalyst by Zoho" }, category: "development", source: { source: "url", url: "https://github.com/catalystbyzoho/claude-plugin.git", sha: "9670b79d72fe4923cc845ca0414d009ef3684ccb" }, homepage: "https://catalyst.zoho.com/" }, { name: "cds-mcp", description: "AI-assisted development of SAP Cloud Application Programming Model (CAP) projects. Search CDS models and CAP documentation.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "url", url: "https://github.com/cap-js/mcp-server.git", sha: "79e4546395a52b1a3881d828118a1b3a2e198876" }, homepage: "https://cap.cloud.sap/" }, { name: "chrome-devtools-mcp", description: "Control and inspect a live Chrome browser from your coding agent. Record performance traces, analyze network requests, check console messages with source-mapped stack traces, and automate browser actions with Puppeteer.", category: "development", source: { source: "url", url: "https://github.com/ChromeDevTools/chrome-devtools-mcp.git", sha: "1cec9cd1a3bbf1895c98fa4b4e0e2da5a36e4075" }, homepage: "https://github.com/ChromeDevTools/chrome-devtools-mcp" }, { name: "chronograph-gp", description: "Portfolio monitoring, valuations and analytics for private-capital GP teams using the Chronograph connector: portfolio-company one-pagers, fund quarterly review packs, markup/markdown briefs, TVPI attribution and budget-vs-actuals. Requires a Chronograph account and the Chronograph connector.", author: { name: "Chronograph" }, category: "productivity", source: { source: "url", url: "https://github.com/chronograph-pe/chronograph-gp-claude-plugin.git", sha: "35cb3d12cf4e24823c0efca4abe6f13c2fd0e5f5" }, homepage: "https://www.chronograph.pe/" }, { name: "chronograph-lp", description: "Portfolio monitoring and analytics for private-capital LP teams using the Chronograph connector: cashflow forecasting, commitment pacing, look-through exposure scans and GP-meeting prep. Requires a Chronograph account and the Chronograph connector.", author: { name: "Chronograph" }, category: "productivity", source: { source: "url", url: "https://github.com/chronograph-pe/chronograph-lp-claude-plugin.git", sha: "322b2d3fbd4db0a2eeed117e3b3c31522408ae6f" }, homepage: "https://www.chronograph.pe/" }, { name: "circle-skills", description: "Ship stablecoin apps faster. Best-practice skills for USDC payments, cross-chain transfers, wallets, and smart contracts — plus Circle's MCP server for real-time SDK and documentation guidance.", author: { name: "Circle" }, category: "development", source: { source: "git-subdir", url: "https://github.com/circlefin/skills.git", path: "plugins/circle", ref: "master", sha: "58ab8648bb1ae9d037a3bf5197ad3bb01262f5b1" }, homepage: "https://www.circle.com" }, { name: "circleback", description: "Circleback conversational context integration. Search and access meetings, emails, calendar events, and more.", category: "productivity", source: { source: "url", url: "https://github.com/circlebackai/claude-code-plugin.git", sha: "a610634c95ab310accf20a0cabdf0fa7ab784fa3" }, homepage: "https://github.com/circlebackai/claude-code-plugin.git" }, { name: "ckeditor", description: "Install, configure, and integrate CKEditor 5 (free and premium) in any JavaScript project.", author: { name: "CKEditor (CKSource)" }, category: "development", source: { source: "url", url: "https://github.com/ckeditor/skills.git", sha: "78a9e3fb6f54c6d0426e91510087e4f462d26d46" }, homepage: "https://ckeditor.com" }, { name: "clangd-lsp", description: "C/C++ language server (clangd) for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/clangd-lsp", category: "development", strict: false, lspServers: { clangd: { command: "clangd", args: ["--background-index"], extensionToLanguage: { ".c": "c", ".h": "c", ".cpp": "cpp", ".cc": "cpp", ".cxx": "cpp", ".hpp": "cpp", ".hxx": "cpp", ".C": "cpp", ".H": "cpp" } } } }, { name: "claude-code-setup", description: "Analyze codebases and recommend tailored Claude Code automations such as hooks, skills, MCP servers, and subagents.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/claude-code-setup", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/claude-code-setup" }, { name: "claude-md-management", description: "Tools to maintain and improve CLAUDE.md files - audit quality, capture session learnings, and keep project memory current.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/claude-md-management", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/claude-md-management" }, { name: "claude-security", description: "Deep vulnerability scanning of your own code, run entirely inside your Claude Code session at a chosen effort tier, with every finding challenged before it is reported and the verification tally computed in code. Turns surviving findings into targeted patches, each verified by a panel of agents, that you apply when you choose.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/claude-security", category: "security", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/claude-security" }, { name: "clay", description: "Work with Clay from Claude Code: set up and sign in to the clay CLI, query and analyze Clay tables, search Clay's GTM database for people and companies, manage audiences, signals, routines and workflows, and draft and review Sequencer campaigns. Includes hooks that auto-approve the plugin's own clay CLI calls and Clay skills; requires a Clay account.", author: { name: "Clay" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/clay-run/agent-plugins.git", path: "clay", ref: "main", sha: "86f0471654c2c855ad0346cd30a74c0f4ca85d7f" }, homepage: "https://github.com/clay-run/agent-plugins/tree/main/clay" }, { name: "clickhouse", description: "Connect Claude to your ClickHouse Cloud databases. Browse organizations, services, databases, and table schemas. Run read-only SQL queries against your data and get instant analytical answers. Monitor service backups, review billing costs, and inspect ClickPipe configurations - all through natural conversation.", author: { name: "ClickHouse" }, category: "database", source: { source: "url", url: "https://github.com/ClickHouse/clickhouse-claude-code-plugin.git", sha: "e3229ed4aafbe94e90dd91699e05eee4263d5efe" }, homepage: "https://github.com/ClickHouse/clickhouse-claude-code-plugin" }, { name: "clickhouse-best-practices", description: "28 best practice rules for ClickHouse schema design, query optimization, and data ingestion — prioritized by impact", author: { name: "ClickHouse Inc" }, category: "database", source: { source: "url", url: "https://github.com/ClickHouse/agent-skills.git", sha: "2f6ec4b17a81a435dd116f9ac19d7b45d44dbd61" }, homepage: "https://clickhouse.com" }, { name: "cloud-sql-mysql", description: "Connect and interact with a Cloud SQL for MySQL database and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/cloud-sql-mysql.git", sha: "ed4fbfe3e0cb6770b15b2a66bd1192a684547678" }, homepage: "https://github.com/gemini-cli-extensions/cloud-sql-mysql" }, { name: "cloud-sql-postgresql", description: "Create, connect, and interact with a Cloud SQL for PostgreSQL database and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/cloud-sql-postgresql.git", sha: "6191fb93757355204a5f909d41ad6c9fa2900a83" }, homepage: "https://cloud.google.com/sql" }, { name: "cloud-sql-sqlserver", description: "Connect to Cloud SQL for SQL Server", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/cloud-sql-sqlserver.git", sha: "8858b0fd066f1590ab7dad70ceacb1366af86a1f" }, homepage: "https://github.com/gemini-cli-extensions/cloud-sql-sqlserver" }, { name: "cloudflare", source: { source: "url", url: "https://github.com/cloudflare/skills.git", sha: "b052c32bab7dd493513260228a36c88294f343f1" }, description: "Skills for the Cloudflare developer platform: Workers, Durable Objects, Agents SDK, MCP servers, Wrangler CLI, and web performance.", category: "deployment", homepage: "https://github.com/cloudflare/skills" }, { name: "cloudinary", description: "Use Cloudinary directly in Claude. Manage assets, apply transformations, optimize media, and more through natural conversation.", source: { source: "url", url: "https://github.com/cloudinary-devs/cloudinary-plugin.git", sha: "86be53409e3fb1c465cd5ff4d1dc937a2860f45c" }, homepage: "https://cloudinary.com/documentation" }, { name: "cockroachdb", description: "Connect Claude Code directly to your CockroachDB clusters for hands-on database work — explore schemas, write optimized SQL, debug queries, and manage distributed database clusters. This plugin provides 14 tools across two active MCP backends (self-hosted MCP Toolbox and managed CockroachDB Cloud MCP Server), three specialized agents (DBA, Developer, Operator), 32 skills across 6 operational domains, and built-in safety hooks.", author: { name: "Cockroach Labs" }, category: "database", source: { source: "url", url: "https://github.com/cockroachdb/claude-plugin.git", sha: "6c96c6394a61f366e8ec1b7cec2281e97507cbff" }, homepage: "https://github.com/cockroachdb/claude-plugin" }, { name: "code-modernization", description: "Modernize legacy codebases (COBOL, legacy Java/C++, monolith web apps) with a structured preflight / assess / map / extract-rules / brief / reimagine / transform / harden workflow, an interactive topology viewer, and specialist review agents", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/code-modernization", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-modernization" }, { name: "code-review", description: "Automated code review for pull requests using multiple specialized agents with confidence-based scoring to filter false positives", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/code-review", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/code-review" }, { name: "code-simplifier", description: "Agent that simplifies and refines code for clarity, consistency, and maintainability while preserving functionality. Focuses on recently modified code.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/code-simplifier", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-simplifier" }, { name: "coderabbit", description: "Your code review partner. CodeRabbit provides external validation using a specialized AI architecture and 40+ integrated static analyzers—offering a different perspective that catches bugs, security vulnerabilities, logic errors, and edge cases. Context-aware analysis via AST parsing and codegraph relationships. Automatically incorporates CLAUDE.md and project coding guidelines into reviews. Useful after writing or modifying code, before commits, when implementing complex or security-sensitive logic, or when a second opinion would increase confidence in the changes. Returns specific findings with suggested fixes that can be applied immediately. Free to use.", category: "productivity", source: { source: "url", url: "https://github.com/coderabbitai/skills.git", sha: "3e8763d24d543b48615b82535d02288de3ddae40" }, homepage: "https://github.com/coderabbitai/skills" }, { name: "codspeed", description: "CodSpeed is the all-in-one performance testing toolkit. Dive into benchmarking results, flamegraphs, and performance comparisons — give Claude granular profiling context to pinpoint bottlenecks and autonomously iterate on performance via the CodSpeed MCP server.", author: { name: "CodSpeed" }, category: "development", source: { source: "url", url: "https://github.com/CodSpeedHQ/codspeed.git", sha: "f08dee66d0d200527f7f3c5a1e5276aec4d50beb" }, homepage: "https://codspeed.io" }, { name: "commit-commands", description: "Commands for git commit workflows including commit, push, and PR creation", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/commit-commands", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/commit-commands" }, { name: "confidence", description: "Access Confidence feature flags, experiments, and migration tools directly from Claude Code.", author: { name: "Spotify Confidence" }, category: "development", source: { source: "url", url: "https://github.com/spotify/confidence-ai-plugins.git", sha: "f416826fde819978ab90f1d7ae27513667aa5d0f" }, homepage: "https://confidence.spotify.com" }, { name: "context7", description: "Upstash Context7 MCP server for up-to-date documentation lookup. Connects to Context7's hosted remote MCP server (https://mcp.context7.com/mcp) — no local Node.js or npx required — to pull version-specific documentation and code examples directly from source repositories into your LLM context. Works anonymously out of the box; set CONTEXT7_API_KEY for higher rate limits.", author: { name: "Upstash" }, category: "development", source: "./external_plugins/context7", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/context7", tags: ["community-managed"] }, { name: "convex", displayName: "Convex", description: "Official Convex plugin for Claude Code with bundled Convex skills, the convex-expert subagent for code-writing, a runtime-error monitor, and MCP access for backend development, schema design, real-time features, auth, file storage, scheduled jobs, and AI agents.", author: { name: "Convex", url: "https://convex.dev" }, category: "database", source: { source: "url", url: "https://github.com/get-convex/convex-backend-skill.git", sha: "6ca54f6e2e7582812187b8a5a4783fb4dff52692" }, homepage: "https://github.com/get-convex/convex-backend-skill", keywords: ["convex", "backend", "database", "realtime", "reactive", "websocket", "auth", "storage", "scheduler", "cron", "agent", "rag", "mobile", "typescript", "mcp"] }, { name: "crowdsec", description: "Operational skill for installing, configuring, operating, and debugging CrowdSec (cscli, LAPI/CAPI, hub, bouncers, WAF/AppSec) across bare-metal, Docker, and Kubernetes.", author: { name: "CrowdSec" }, category: "security", source: { source: "url", url: "https://github.com/crowdsecurity/crowdsec-skill.git", sha: "24488e03c9c0b34596de3e21004b24d4d05a6df7" }, homepage: "https://www.crowdsec.net" }, { name: "crowdstrike-falcon-foundry", description: "CrowdStrike Falcon Foundry development skills for building cybersecurity applications on the Falcon platform. Includes UI development, collections, functions, workflows, API integration, security patterns, and debugging workflows.", author: { name: "CrowdStrike" }, category: "security", source: { source: "url", url: "https://github.com/CrowdStrike/foundry-skills.git", sha: "7f7d46687c16a9a37c9b08ad58ad58999aabe497" }, homepage: "https://github.com/CrowdStrike/foundry-skills" }, { name: "crowdstrike-falcon-fusion", description: "CrowdStrike Falcon Fusion skills for authoring, deploying, and executing Fusion workflows. Includes live action discovery, YAML authoring with schema validation, workflow import and release, execution monitoring, and Falcon Next-Gen SIEM lookup files.", author: { name: "CrowdStrike" }, category: "security", source: { source: "url", url: "https://github.com/CrowdStrike/fusion-skills.git", sha: "3e15710a94b712473e87ce7cd7c43d026156a3f3" }, homepage: "https://github.com/CrowdStrike/fusion-skills" }, { name: "csharp-lsp", description: "C# language server for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/csharp-lsp", category: "development", strict: false, lspServers: { "csharp-ls": { command: "csharp-ls", extensionToLanguage: { ".cs": "csharp" } } } }, { name: "cwc-makers", description: "Onboard a Code-with-Claude Makers Cardputer with one /maker-setup command — clones the build-with-claude repo, flashes UIFlow firmware, and installs the Claude Buddy app bundle.", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/cwc-makers", category: "productivity", homepage: "https://claude.com/cwc-makers" }, { name: "dash0", description: "OpenTelemetry observability for Claude Code sessions. Captures tool calls, LLM invocations, token usage, and errors as OTel traces. Send telemetry to Dash0 or any OpenTelemetry-compatible backend.", author: { name: "Dash0" }, category: "monitoring", source: { source: "url", url: "https://github.com/dash0hq/dash0-agent-plugin.git", sha: "72a84179e6c64871ad5b6fceb09e00f502de415a" }, homepage: "https://dash0.com/" }, { name: "data", description: "Data engineering for Apache Airflow and Astronomer. Author DAGs with best practices, debug pipeline failures, trace data lineage, profile tables, migrate Airflow 2 to 3, and manage local and cloud deployments.", category: "development", source: { source: "url", url: "https://github.com/astronomer/agents.git", sha: "9b5a33171e36ecda135f22e77a845d9c405b519e" }, homepage: "https://github.com/astronomer/agents" }, { name: "data-agent-kit-starter-pack", description: "This plugin provides a specialized suite of skills for data engineers and database practitioners working on Google Cloud. It acts as an expert assistant, allowing you to use natural language prompts in your preferred coding agent to architect complex data pipelines, transform data with dbt, write Spark and BigQuery SQL notebooks, and orchestrate end-to-end workflows across GCP's data ecosystem.", author: { name: "Google LLC" }, category: "development", source: { source: "url", url: "https://github.com/gemini-cli-extensions/data-agent-kit-starter-pack.git", sha: "2df10e25bbf7dba2570dce1b2e2e77870143969e" }, homepage: "https://github.com/gemini-cli-extensions/data-agent-kit-starter-pack" }, { name: "data-engineering", description: "Data engineering plugin - warehouse exploration, pipeline authoring, Airflow integration", source: { source: "url", url: "https://github.com/astronomer/agents.git", sha: "9b5a33171e36ecda135f22e77a845d9c405b519e" }, homepage: "https://github.com/astronomer/agents" }, { name: "databases-on-aws", description: "Expert database guidance for the AWS database portfolio. Design schemas, execute queries, handle migrations, and choose the right database for your workload.", category: "database", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/databases-on-aws", ref: "main", sha: "097fe8ad56d8a1d5e2c81d7880adf145553cf244" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "databricks", description: "Databricks skills for the CLI, Apps, Lakebase, Model Serving, Lakeflow Jobs, Spark Declarative Pipelines, Declarative Automation Bundles (DABs), and classic-to-serverless migration.", author: { name: "Databricks" }, category: "database", source: { source: "git-subdir", url: "https://github.com/databricks/databricks-agent-skills.git", path: "plugins/databricks/claude", ref: "main", sha: "0fbf9ba4cdb2fd5a0efd952e8225acc1d5099809" }, homepage: "https://developers.databricks.com/" }, { name: "datadog", description: "Use Datadog directly in Claude Code through a preconfigured Datadog MCP server. Query logs, metrics, traces, dashboards, and more through natural conversation. This plugin is in preview.", author: { name: "Datadog" }, category: "monitoring", source: { source: "url", url: "https://github.com/datadog-labs/claude-code-plugin.git", sha: "195f570c002beab3d7bd342739034d0019aa4863" }, homepage: "https://www.datadoghq.com/" }, { name: "datahub-skills", description: "DataHub development and interaction toolkit with connector planning, PR review, catalog search, metadata enrichment, lineage tracing, data quality management, and connection setup skills", author: { name: "DataHub" }, category: "database", source: { source: "url", url: "https://github.com/datahub-project/datahub-skills.git", sha: "c6d0ded76eca4c649276e39ab376ad6c66142eb7" }, homepage: "https://datahub.com" }, { name: "dataproc", description: "Manage Dataproc clusters and jobs.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/dataproc.git", sha: "afbd516845a34fcf460ec447b81868bc48962b0f" }, homepage: "https://github.com/gemini-cli-extensions/dataproc" }, { name: "datarobot-agent-skills", description: "DataRobot skills for AI/ML workflows — model training, deployment, predictions, feature engineering, monitoring, explainability, data preparation, App Framework CI/CD, and external agent monitoring.", author: { name: "DataRobot" }, category: "development", source: { source: "url", url: "https://github.com/datarobot-oss/datarobot-agent-skills.git", sha: "e6dddbe327dc2c83e9b7677a5577d33a1063feaf" }, homepage: "https://datarobot.com" }, { name: "dataverse", description: "Agent skills for building on, analyzing, and managing Microsoft Dataverse — with Dataverse MCP, PAC CLI, and Python SDK.", category: "database", source: { source: "git-subdir", url: "https://github.com/microsoft/Dataverse-skills.git", path: ".github/plugins/dataverse", ref: "main", sha: "ee929195a7d724c315e45f6dc3ebc4e59370fce2" }, homepage: "https://github.com/microsoft/Dataverse-skills" }, { name: "deepeval", description: "Skills for adding DeepEval evaluations, tracing, datasets, Confident AI reports, and iterative improvement loops to AI applications.", author: { name: "Confident AI", email: "open-source@confident-ai.com" }, category: "development", source: { source: "url", url: "https://github.com/confident-ai/deepeval.git", sha: "c144abbce848a6dfbd35bbdaaab49a62bb3fb7b6" }, homepage: "https://github.com/confident-ai/deepeval" }, { name: "deploy-on-aws", description: "Deploy applications to AWS with architecture recommendations, cost estimates, and IaC deployment.", category: "deployment", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/deploy-on-aws", ref: "main", sha: "efe040ab66ed7eb4bccc0a94133181da5bc57567" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "desktop-commander", description: "MCP server for terminal commands, process management, and file operations across text, code, PDF, DOCX, Excel, images, and structured data.", author: { name: "Desktop Commander" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/wonderwhy-er/DesktopCommanderMCP.git", path: "plugins/claude", ref: "main", sha: "1eccc8b09cc09805202a1737fd20d605356c3671" }, homepage: "https://desktopcommander.app" }, { name: "discord", description: "Discord messaging bridge with built-in access control. Manage pairing, allowlists, and policy via /discord:access.", category: "productivity", source: "./external_plugins/discord" }, { name: "dominodatalab", description: "Full Domino Data Lab platform support — workspaces, jobs, model deployment, experiment tracking, GenAI tracing, Spark/Ray/Dask, and app deployment for data science teams", author: { name: "Domino Data Lab" }, category: "development", source: { source: "url", url: "https://github.com/dominodatalab/domino-claude-plugin.git", sha: "d86698d74d56d3934c8f8ddccb4f6aa55eb2bba7" }, homepage: "https://www.domino.ai" }, { name: "dropbox", description: "The Dropbox plugin for Claude connects your Dropbox files directly to Claude, so you can search, organize, save generated content, and create sharing links without switching tools. It respects your existing Dropbox permissions, and Claude only works with files you already have access to.", author: { name: "Dropbox" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/dropbox/dropbox-ai-plugins.git", path: "claude", ref: "main", sha: "4135e81caf8275b4c97caef244479e0dcb6fb823" }, homepage: "https://www.dropbox.com" }, { name: "duckdb-skills", description: "DuckDB-powered skills for Claude Code: read any data file, attach and query DuckDB databases, search DuckDB/DuckLake docs, search past session logs, and install/update DuckDB extensions.", author: { name: "DuckDB Foundation" }, category: "database", source: { source: "url", url: "https://github.com/duckdb/duckdb-skills.git", sha: "7feda8e01e22bc0886c86123f3884947e36d8c69" }, homepage: "https://duckdb.org" }, { name: "duende-skills", description: "Duende development skills and agents for Claude Code — covering OAuth/OIDC protocols, IdentityServer, token management, ASP.NET Core authentication/authorization, BFF patterns, and secure identity architecture", author: { name: "Duende Software" }, category: "security", source: { source: "url", url: "https://github.com/DuendeSoftware/duende-skills.git", sha: "fb32edc51982bf1c600e21ba91df32c903098a9c" }, homepage: "https://duendesoftware.com" }, { name: "exa", description: "Exa AI web search, deep research, and content extraction. Provides MCP tools and research skills for comprehensive web search, people discovery, company research, academic papers, and more.", author: { name: "Exa" }, category: "productivity", source: { source: "url", url: "https://github.com/exa-labs/exa-mcp-server.git", sha: "15ffb50519e719dc791cdc750ce5ed1934c0a1ed" }, homepage: "https://exa.ai/docs/reference/exa-mcp" }, { name: "explanatory-output-style", description: "Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style)", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/explanatory-output-style", category: "learning", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/explanatory-output-style" }, { name: "expo", description: "Official Expo skills for building, deploying, upgrading, and debugging React Native apps with Expo. Covers UI development with Expo Router, SwiftUI and Jetpack Compose components, Tailwind CSS setup, API routes, data fetching, CI/CD workflows, App Store and Play Store deployment, SDK upgrades, DOM components, and dev client distribution.", category: "development", source: { source: "git-subdir", url: "https://github.com/expo/skills.git", path: "plugins/expo", ref: "main", sha: "39708666ce7014def1f8e34f3d8c93e8d3f588bb" }, homepage: "https://github.com/expo/skills/blob/main/plugins/expo/README.md" }, { name: "fakechat", description: "Localhost web chat for testing the channel notification flow. No tokens, no access control, no third-party service.", category: "development", source: "./external_plugins/fakechat" }, { name: "fastly-agent-toolkit", description: "Fastly development tools and platform skills", source: { source: "url", url: "https://github.com/fastly/fastly-agent-toolkit.git", sha: "abb9d42a5318d67b52b39db9f5b88289ec1567c4" }, homepage: "https://github.com/fastly/fastly-agent-toolkit/blob/main/README.md" }, { name: "feature-dev", description: "Comprehensive feature development workflow with specialized agents for codebase exploration, architecture design, and quality review", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/feature-dev", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/feature-dev" }, { name: "fiftyone", description: "Build high-quality datasets and computer vision models. Visualize datasets, analyze models, find duplicates, run inference, evaluate predictions, and develop custom plugins.", source: { source: "url", url: "https://github.com/voxel51/fiftyone-skills.git", sha: "e28a9a3d453b15cbefa6ccc81c89fecf723c31b2" }, homepage: "https://docs.voxel51.com/" }, { name: "figma", description: "Figma design platform integration. Access design files, extract component information, read design tokens, and translate designs into code. Bridge the gap between design and development workflows.", category: "design", source: { source: "url", url: "https://github.com/figma/mcp-server-guide.git", sha: "d638a5e055e8d95e0394a94350860398cf424b74" }, homepage: "https://github.com/figma/mcp-server-guide" }, { name: "firebase", description: "Google Firebase MCP integration. Manage Firestore databases, authentication, cloud functions, hosting, and storage. Build and manage your Firebase backend directly from your development workflow.", category: "database", source: "./external_plugins/firebase", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/firebase" }, { name: "firecrawl", description: "Web scraping and crawling powered by Firecrawl. Turn any website into clean, LLM-ready markdown or structured data. Scrape single pages, crawl entire sites, search the web, and extract structured information. Includes an AI agent for autonomous multi-source data gathering - just describe what you need and it finds, navigates, and extracts automatically.", category: "development", source: { source: "url", url: "https://github.com/firecrawl/firecrawl-claude-plugin.git", sha: "998fc11580f3edda3488a4b579ddbebf6600651f" }, homepage: "https://github.com/firecrawl/firecrawl-claude-plugin.git" }, { name: "firestore-native", description: "Connect and interact with Firestore databases, collections, and documents.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/firestore-native.git", sha: "502ff19b853e760539717d3c640300af3400bba3" }, homepage: "https://github.com/gemini-cli-extensions/firestore-native" }, { name: "forge-skills", description: "Forge-focused skills and MCP configuration for Atlassian Forge: scaffold and deploy apps (forge create, templates, dev spaces), build Teamwork Graph connectors for Rovo Search/Rovo Chat, pre-deploy review, systematic debugging, plus Forge docs and Atlassian Design System lookups via MCP.", author: { name: "Atlassian" }, category: "development", source: { source: "url", url: "https://github.com/atlassian/forge-skills.git", sha: "4f04ae02879435f23808a4798da28f75d3ab74c3" }, homepage: "https://developer.atlassian.com/platform/forge/" }, { name: "frontend-design", description: "Create distinctive, production-grade frontend interfaces with high design quality. Generates creative, polished code that avoids generic AI aesthetics.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/frontend-design", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/frontend-design" }, { name: "fullstory", description: "Connect Claude to Fullstory to query behavioral analytics, session replays, and customer experience insights.", author: { name: "Fullstory" }, category: "monitoring", source: { source: "url", url: "https://github.com/fullstorydev/fullstory-skills.git", sha: "b20614e2d08d7a7c70775bb62b5af640f60b024b" }, homepage: "https://www.fullstory.com" }, { name: "gc-ai", displayName: "GC AI", description: "Work in your GC AI legal knowledge base from Claude: upload documents, run review playbooks, and ask questions grounded in your own files, all as you.", author: { name: "GC AI" }, category: "productivity", source: { source: "url", url: "https://github.com/GC-AI-Inc/gc-ai-claude-plugin.git", sha: "efda779972c7b7162e79234e164bc2f359a8a518" }, homepage: "https://docs.gc.ai/api-reference/mcp/overview" }, { name: "github", description: "Official GitHub MCP server for repository management. Create issues, manage pull requests, review code, search repositories, and interact with GitHub's full API directly from Claude Code.", category: "productivity", source: "./external_plugins/github", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/github" }, { name: "gitkraken", description: "Gives Claude access to your real Git and project context: commits, branches, pull requests, and issues across every repo you work in. Works with GitHub, GitLab, Azure DevOps, Bitbucket, and Jira.", author: { name: "GitKraken" }, category: "development", source: { source: "url", url: "https://github.com/gitkraken/claude-plugin.git", sha: "f7a53b2cd138c22eccb977b9d93494ea6d423d12" }, homepage: "https://www.gitkraken.com" }, { name: "gitlab", description: "GitLab DevOps platform integration. Manage repositories, merge requests, CI/CD pipelines, issues, and wikis. Full access to GitLab's comprehensive DevOps lifecycle tools.", category: "productivity", source: "./external_plugins/gitlab", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/gitlab" }, { name: "google-cloud-storage", description: "Official Google Cloud Storage (GCS) plugin. Manage buckets and objects, transfer data, and configure MCP, FUSE, IAM, security, lifecycle rules, signed URLs, Terraform, and the CLI.", author: { name: "Google LLC" }, category: "deployment", source: { source: "url", url: "https://github.com/gemini-cli-extensions/google-cloud-storage.git", sha: "c7e3eeefa14ac0492a024458061d662e8b04c891" }, homepage: "https://cloud.google.com/storage" }, { name: "gopls-lsp", description: "Go language server for code intelligence and refactoring", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/gopls-lsp", category: "development", strict: false, lspServers: { gopls: { command: "gopls", extensionToLanguage: { ".go": "go" } } } }, { name: "grafana-assistant", description: "Skills and rules for developing and using the Grafana Assistant app and CLI.", author: { name: "Grafana" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/grafana/ai-marketplace.git", path: "plugins/grafana-assistant", ref: "main", sha: "a5c72f2d74c640e9675eb0249526447968535015" }, homepage: "https://grafana.com" }, { name: "grafana-cloud-mcp", description: "Hosted MCP server for AI-assisted Grafana Cloud observability — no local installation required.", author: { name: "Grafana" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/grafana/ai-marketplace.git", path: "plugins/grafana-cloud-mcp", ref: "main", sha: "12be5634a492f73c189d466c5449d09b853ad7a4" }, homepage: "https://grafana.com" }, { name: "grafana-mcp", description: "MCP server for AI-assisted Grafana dashboard, datasource, alerting, and incident management.", author: { name: "Grafana" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/grafana/ai-marketplace.git", path: "plugins/grafana-mcp", ref: "main", sha: "a5c72f2d74c640e9675eb0249526447968535015" }, homepage: "https://grafana.com" }, { name: "greptile", description: "AI code review agent for GitHub and GitLab. View and resolve Greptile's PR review comments, run reviews on your working branch, and search your organization's knowledge base and coding patterns, directly from Claude Code.", author: { name: "Greptile", url: "https://greptile.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/greptileai/claude-plugin.git", path: "plugins/greptile", ref: "greptile--v1.2.3", sha: "6b725af2636072cab79e0a5426f6a960b0fd29ef" }, homepage: "https://www.greptile.com/docs/mcp-v2/overview" }, { name: "growthbook", description: "A suite of agent skills for the full GrowthBook feature flag and experimentation lifecycle.", author: { name: "GrowthBook" }, category: "testing", source: { source: "url", url: "https://github.com/growthbook/skills.git", sha: "eb7960d4fe5034bd8d8f100320192d1691a173ac" }, homepage: "https://growthbook.io" }, { name: "honeycomb", description: "Skills, agents, and workflows for Honeycomb observability — query patterns, production investigations, SLOs, OpenTelemetry instrumentation, and Beeline migration. Designed to complement the Honeycomb MCP server.", author: { name: "Honeycomb" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/honeycombio/agent-skill.git", path: "honeycomb", ref: "main", sha: "41214b7dfb97f262adabf295fa6f0fcad85bc0f6" }, homepage: "https://www.honeycomb.io" }, { name: "hookify", description: "Easily create custom hooks to prevent unwanted behaviors by analyzing conversation patterns or from explicit instructions. Define rules via simple markdown files.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/hookify", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/hookify" }, { name: "hostinger", displayName: "Hostinger", description: "Deploy, manage and monitor Hostinger services — Websites, Domains, Ecommerce, Email Marketing, Subscriptions & Payments, and VPS. Authenticate via browser (OAuth) or API token.", author: { name: "Hostinger" }, category: "deployment", source: { source: "url", url: "https://github.com/hostinger/claude-plugin.git", sha: "569880c60681a7068b3ca8ca84e2fe7ab6cfa7ff" }, homepage: "https://www.hostinger.com" }, { name: "huggingface-skills", description: "Build, train, evaluate, and use open source AI models, datasets, and spaces.", category: "development", source: { source: "url", url: "https://github.com/huggingface/skills.git", sha: "f3186efbbc322121eb5d0f31e8a1d669ee961159" }, homepage: "https://github.com/huggingface/skills.git" }, { name: "hunter", description: "Find and verify professional email addresses, search contacts by domain, and enrich company data -- directly in Claude.", author: { name: "Hunter.io" }, category: "productivity", source: { source: "url", url: "https://github.com/hunter-io/claude-plugin.git", sha: "ce0ccac337b8ccc0506c943e765d3e4506c87080" }, homepage: "https://hunter.io" }, { name: "hyperframes", description: "HyperFrames by HeyGen. Write HTML, render video. Compositions, GSAP and runtime adapter animations, captions, voiceovers, audio-reactive visuals, and website-to-video capture for HyperFrames.", author: { name: "HeyGen" }, category: "design", source: { source: "url", url: "https://github.com/heygen-com/hyperframes.git", sha: "a8a9fdb0fe88d97c99d7bd30da94e64dd0a96f3d" }, homepage: "https://hyperframes.heygen.com" }, { name: "idmp-plugin", description: "TDengine IDMP plugin with packaged skills for discovery, schema inspection, and safe operational workflows.", author: { name: "TaosData", email: "it@taosdata.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/taosdata/agent-skills.git", path: "plugins/idmp-plugin", ref: "main", sha: "0b67242e2cd114ad9631c39aa20969fdd9780a11" }, homepage: "https://github.com/taosdata/agent-skills" }, { name: "imessage", description: "iMessage messaging bridge with built-in access control. Reads chat.db directly, sends via AppleScript. Manage pairing, allowlists, and policy via /imessage:access.", category: "productivity", source: "./external_plugins/imessage" }, { name: "incident-io", description: "Work with incident.io from Claude: respond to and investigate incidents, check on-call schedules and escalations, and author the runbooks, skills and architecture docs that incident.io investigations draw on. Bundles the official incident.io MCP server (OAuth on first use).", author: { name: "incident.io" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/incident-io/skills.git", path: "plugins/incident-io", ref: "main", sha: "6d0bbfc9e52256fc39326b9ba6d08f16831b60ae" }, homepage: "https://incident.io" }, { name: "informatica-for-claude-platform", description: "Governed catalog discovery for Informatica Intelligent Data Management Cloud (CDGC): find tables, columns, files, glossary terms and policies across the enterprise catalog, check ownership, certification, sensitivity and applicable policy, and get safe-usage guidance grounded in catalog metadata before querying any data. Requires an Informatica IDMC tenant and the Informatica Catalog Discovery connector.", author: { name: "Informatica" }, category: "database", source: { source: "git-subdir", url: "https://github.com/forcedotcom/informatica-claude-plugins.git", path: "informatica-for-claude-platform", ref: "main", sha: "554d02e0f7f2adafeaeeedbde04435b7bd310a47" }, homepage: "https://github.com/forcedotcom/informatica-claude-plugins/tree/main/informatica-for-claude-platform" }, { name: "intercom", description: "Intercom integration for Claude Code. Search conversations, analyze customer support patterns, look up contacts and companies, and install the Intercom Messenger. Connect your Intercom workspace to get real-time insights from customer data.", category: "productivity", source: { source: "url", url: "https://github.com/intercom/claude-plugin-external.git", sha: "62773a7d4b8aac31545d6888fe6479be3bc53804" }, homepage: "https://github.com/intercom/claude-plugin-external" }, { name: "intuit-quickbooks", description: "QuickBooks business insights and actions: financial health briefings across P&L, cash flow, balance sheet and A/R, industry benchmarking, payroll cost analysis, overdue-invoice reminders, estimate/invoice drafting from email, payroll onboarding and base-pay changes (with confirmation), and QuickBooks Capital lending guidance. Requires the Intuit QuickBooks connector.", author: { name: "Intuit QuickBooks" }, category: "productivity", source: { source: "url", url: "https://github.com/intuit/quickbooks-claude-plugin.git", sha: "c8daa17a64d4d0fdeabdf0516524f72549b6ad19" }, homepage: "https://github.com/intuit/quickbooks-claude-plugin" }, { name: "jdtls-lsp", description: "Java language server (Eclipse JDT.LS) for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/jdtls-lsp", category: "development", strict: false, lspServers: { jdtls: { command: "jdtls", extensionToLanguage: { ".java": "java" }, startupTimeout: 120000 } } }, { name: "jfrog", description: "Use the JFrog Platform from Claude Code: Artifactory repos and artifacts, security findings and exposures, Catalog package safety and downloads, workflows across the SDLC, and platform administration.", author: { name: "JFrog Ltd.", url: "https://jfrog.com" }, category: "security", source: { source: "url", url: "https://github.com/jfrog/claude-plugin.git", sha: "c4049d7ca5a745afed97368ab7d65e146c450673" }, homepage: "https://jfrog.com" }, { name: "knowledge-catalog", description: "Connect to Knowledge Catalog to discover, manage, monitor, and govern data and AI artifacts across your data platform", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/knowledge-catalog.git", sha: "930d73cfbb8e0637d79cb335ff0b8d80af383bd8" }, homepage: "https://github.com/gemini-cli-extensions/knowledge-catalog" }, { name: "kotlin-lsp", description: "Kotlin language server for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/kotlin-lsp", category: "development", strict: false, lspServers: { "kotlin-lsp": { command: "kotlin-lsp", args: ["--stdio"], extensionToLanguage: { ".kt": "kotlin", ".kts": "kotlin" }, startupTimeout: 120000 } } }, { name: "langfuse-observability", description: "Langfuse observability plugin for Claude Code — captures and exports traces, spans, and session telemetry from Claude Code to Langfuse for LLM monitoring, debugging, and evaluation", author: { name: "Langfuse" }, category: "monitoring", source: { source: "url", url: "https://github.com/langfuse/claude-observability-plugin.git", sha: "b5211009698fdfe79c6bbe90d6901ad255ea65d3" }, homepage: "https://langfuse.com/integrations/other/claude-code" }, { name: "laravel-boost", description: "Laravel development toolkit MCP server. Provides intelligent assistance for Laravel applications including Artisan commands, Eloquent queries, routing, migrations, and framework-specific code generation.", category: "development", source: "./external_plugins/laravel-boost", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/laravel-boost" }, { name: "leadfeeder", description: "Turn website visitor signals into pipeline with Leadfeeder: daily visitor briefs, visitor company research, buyer and contact discovery, personalised outreach drafts, and adding companies to your Leadfeeder lists, via the Leadfeeder connector. Requires a Leadfeeder account.", author: { name: "Leadfeeder" }, category: "productivity", source: { source: "url", url: "https://github.com/Leadfeeder/leadfeeder-mcp-plugin.git", sha: "f344f4383363199963c34a0c353e09d26596d501" }, homepage: "https://www.leadfeeder.com" }, { name: "learn-with-coursera", description: "Turn any learning intent into a personalized Coursera experience. Asks three quick questions (topic, familiarity, preferred format), searches Coursera's catalog, and delivers the right next step — a course, hands-on project, short video, or live roleplay — then maps a path forward. Requires the Coursera connector for catalog tools.", author: { name: "Coursera" }, category: "learning", source: { source: "git-subdir", url: "https://github.com/coursera/skills.git", path: "skills", ref: "main", sha: "ac28fd6ebf8584e3ee196159bd6d4514fa07de0f" }, strict: false, skills: ["./learn-with-coursera"], homepage: "https://github.com/coursera/skills" }, { name: "learning-output-style", description: "Interactive learning mode that requests meaningful code contributions at decision points (mimics the unshipped Learning output style)", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/learning-output-style", category: "learning", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/learning-output-style" }, { name: "legalzoom", description: "Attorney guidance and legal tools for business and personal needs. AI-powered document review identifies critical risks and important clauses, advises when to engage an attorney, and routes to LegalZoom's network when professional expertise is needed.", category: "productivity", source: { source: "git-subdir", url: "https://github.com/legalzoom/claude-plugins.git", path: "plugins/legalzoom", ref: "main", sha: "f9fd8a0ca6e1421bc1aacb113a109663a7a6f6d8" }, homepage: "https://www.legalzoom.com/" }, { name: "linear", description: "Linear issue tracking integration. Create issues, manage projects, update statuses, search across workspaces, and streamline your software development workflow with Linear's modern issue tracker.", category: "productivity", source: "./external_plugins/linear", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/linear" }, { name: "liquid-lsp", description: "LSP integration for Shopify Liquid templates via the Shopify CLI theme language server.", author: { name: "Shopify" }, category: "development", source: { source: "git-subdir", url: "https://github.com/Shopify/liquid-skills.git", path: "plugins/liquid-lsp", ref: "main", sha: "ae3e4cc3f454923e388bbd841fd931f0c7bf5be4" }, homepage: "https://github.com/Shopify/liquid-skills/tree/main/plugins/liquid-lsp" }, { name: "liquid-skills", description: "Liquid language fundamentals, CSS/JS/HTML coding standards, and WCAG accessibility patterns for Shopify themes", author: { name: "Shopify" }, category: "development", source: { source: "git-subdir", url: "https://github.com/Shopify/liquid-skills.git", path: "plugins/liquid-skills", ref: "main", sha: "ae3e4cc3f454923e388bbd841fd931f0c7bf5be4" }, homepage: "https://github.com/Shopify/liquid-skills/tree/main/plugins/liquid-skills" }, { name: "logfire", description: "Add Logfire observability to Python applications with auto-instrumentation for FastAPI, httpx, asyncpg, SQLAlchemy, and more", author: { name: "Pydantic" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/pydantic/skills.git", path: "plugins/logfire", ref: "main", sha: "501b11a5b3f92b9c78bbe9bd76442df0ad68dadf" }, homepage: "https://github.com/pydantic/skills/tree/main/plugins/logfire" }, { name: "logrocket", description: "Connect Claude Code to LogRocket to query session replays, metrics, issues, and user behavior using natural language.", author: { name: "LogRocket" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/LogRocket/logrocket-claude-plugin.git", path: "plugins/logrocket", ref: "main", sha: "2e44dbb47faf9bb54e3405a8ae2714e7c5ce9791" }, homepage: "https://logrocket.com" }, { name: "looker", description: "Connect to Looker and interact with your data using LookML.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/looker.git", sha: "eb4a1828dc7adc346f6f23d47a73421392b7f86b" }, homepage: "https://github.com/gemini-cli-extensions/looker" }, { name: "lovable", description: "Build, iterate on, deploy, and manage Lovable apps from Claude Code. Bundles the official Lovable MCP server (remote, OAuth 2.1) and adds focused commands for the common build/iterate/database workflows, with credit- and publish-safety prompts.", author: { name: "Lovable" }, category: "development", source: { source: "url", url: "https://github.com/lovablelabs/mcp.git", sha: "0336e6db8026b0f02cb89d1451cc48ea3f469791" }, homepage: "https://lovable.dev" }, { name: "lua-lsp", description: "Lua language server for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/lua-lsp", category: "development", strict: false, lspServers: { lua: { command: "lua-language-server", extensionToLanguage: { ".lua": "lua" } } } }, { name: "lumen", description: "Precise local semantic code search via MCP. Indexes your codebase with Go AST parsing, embeds with Ollama or LM Studio, and exposes vector search to Claude through an MCP server — no cloud, no npm.", author: { name: "Ory Corp" }, category: "development", source: { source: "url", url: "https://github.com/ory/lumen.git", sha: "f60f9ecee41723b42f3758e9a9409141881ac7d5" }, homepage: "https://www.ory.sh" }, { name: "lusha", description: "Prospect, enrich, and build call-ready lead lists using Lusha's B2B intelligence platform — verified phone numbers, company signals, and lookalike targeting.", author: { name: "Lusha" }, category: "productivity", source: { source: "url", url: "https://github.com/lusha-oss/lusha-mcp-plugin.git", sha: "ed34947a36754411f03cdeaba91c8cdaa153ef2e" }, homepage: "https://www.lusha.com" }, { name: "mapbox", description: "Mapbox skills and MCP servers for building location-aware applications with AI. Includes geospatial tools, style management, and patterns for web, iOS, Android, and AI agent frameworks.", author: { name: "Mapbox" }, category: "location", source: { source: "url", url: "https://github.com/mapbox/mapbox-agent-skills.git", sha: "aab3a6fef5c62b7c42c1f68e05885a1b50c42d24" }, homepage: "https://www.mapbox.com" }, { name: "math-olympiad", description: "Solve competition math (IMO, Putnam, USAMO) with adversarial verification that catches what self-verification misses. Fresh-context verifiers attack proofs with specific failure patterns. Calibrated abstention over bluffing.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/math-olympiad", category: "math", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/math-olympiad" }, { name: "mattpocock-skills", description: "Matt Pocock's agent skills for real engineering — grilling, spec/ticket flows, TDD, code review, domain modelling and more. Plug-and-play, not vibe coding.", author: { name: "Matt Pocock" }, category: "development", source: { source: "url", url: "https://github.com/mattpocock/skills.git", sha: "959a8e9f1edc3adbe2f7e3054bb6fbefa6696260" }, homepage: "https://github.com/mattpocock/skills" }, { name: "mcp-apps", description: "Skills for creating MCP Apps with the MCP Apps SDK", author: { name: "Anthropic / Model Context Protocol" }, category: "development", source: { source: "git-subdir", url: "https://github.com/modelcontextprotocol/ext-apps.git", path: "plugins/mcp-apps", ref: "main", sha: "352f6ced4d80772e92b4e7a311854481a8d65b04" }, homepage: "https://modelcontextprotocol.io" }, { name: "mcp-server-dev", description: "Skills for designing and building MCP servers that work seamlessly with Claude. Guides you through deployment models (remote HTTP, MCPB, local), tool design patterns, auth, and interactive MCP apps.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/mcp-server-dev", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/mcp-server-dev" }, { name: "mcp-tunnels", description: "Connect Claude to a private MCP server through an Anthropic MCP tunnel. The /create-docker-mcp-tunnel command drives the Docker Compose quickstart end to end: certificates, proxy config, cloudflared, and a verifiable sample server.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/mcp-tunnels", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/mcp-tunnels" }, { name: "mercadopago", description: "Mercado Pago full-product integration toolkit. One agent routes to four orchestration skills (mp-integrate wizard, mp-webhooks, mp-test-setup, mp-review) that pull every endpoint, payload, and snippet live from the official Mercado Pago MCP server. The MCP must always be connected — there is no offline mode.", author: { name: "Mercado Pago Developer Experience" }, category: "development", source: { source: "git-subdir", url: "https://github.com/mercadopago/mercadopago-claude-marketplace.git", path: "plugins/mercadopago", ref: "main", sha: "c0d06959afc90b2f3d637c35eeb51c36f512c005" }, homepage: "https://github.com/mercadopago/mercadopago-claude-marketplace/tree/main/plugins/mercadopago" }, { name: "mergify", description: "Skills for the Mergify CLI: manage merge queues, stacked pull requests, Test Insights (flaky tests, quarantine), merge protections, and Mergify configuration directly from the terminal.", author: { name: "Mergify" }, category: "development", source: { source: "url", url: "https://github.com/mergifyio/mergify-cli.git", sha: "e7c1ebbc281361f0b2b7827cf583f57339c97ebc" }, homepage: "https://mergify.com" }, { name: "microsoft-docs", description: "Access official Microsoft documentation, API references, and code samples for Azure, .NET, Windows, and more.", category: "development", source: { source: "url", url: "https://github.com/MicrosoftDocs/mcp.git", sha: "f8ffde185dfd232dbf5d187c22ce299eadc3d583" }, homepage: "https://github.com/microsoftdocs/mcp" }, { name: "migration-to-aws", description: "Plan a migration from Google Cloud Platform (and OpenAI/Gemini AI workloads) to AWS. Analyzes your Infrastructure-as-Code files, app code, and GCP billing data to discover resources, design an AWS architecture, estimate costs, and generate migration artifacts — including AI-provider mapping to Amazon Bedrock. Processing is local; your data stays in your environment.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/startups.git", path: "migrate/plugins/migration-to-aws", ref: "main", sha: "dd7096bd634649bc89b6511d61cff16f58623284" }, homepage: "https://github.com/awslabs/startups" }, { name: "mintlify", description: "Build beautiful documentation sites with Mintlify. Convert non-markdown files into properly formatted MDX pages, add and modify content with correct component use, and automate documentation updates.", category: "development", source: { source: "url", url: "https://github.com/mintlify/mintlify-claude-plugin.git", sha: "acd6d2e0128c4f235d55cfb8d8c91ecbdd5df8cc" }, homepage: "https://www.mintlify.com/" }, { name: "miro", description: "Secure access to Miro boards. Enables AI to read board context, create diagrams, and generate code with enterprise-grade security.", author: { name: "Miro" }, category: "design", source: { source: "git-subdir", url: "https://github.com/miroapp/miro-ai.git", path: "claude-plugins/miro", ref: "main", sha: "c2494b24510d01ec3e50fad94a0c5fc3ca40e339" }, homepage: "https://miro.com" }, { name: "modern-web-guidance", description: "Keep your coding agent up to date with the latest web best practices", author: { name: "Google Chrome" }, category: "development", source: { source: "url", url: "https://github.com/GoogleChrome/modern-web-guidance.git", sha: "16ed22b43fa56157adadfb25f18a354197d497b9" }, homepage: "https://goo.gle/modern-web-guidance" }, { name: "mlflow", description: "Skills for tracing, evaluating, and improving AI agents with MLflow. Supports the full agent improvement loop: instrument → trace → evaluate → iterate → validate.", author: { name: "MLflow Team" }, category: "monitoring", source: { source: "url", url: "https://github.com/mlflow/skills.git", sha: "85ab69be2df4f92db82ddbf4be9ce63ab3722249" }, homepage: "https://mlflow.org/" }, { name: "monday-crm", description: "Run your monday CRM in plain language. Build a pipeline from scratch, start the day with a ranked deal briefing, spin up a forecast dashboard, audit board health, clean up messy data in bulk, and turn meeting notes into deal updates. Every skill writes back into monday as a real update, doc, or dashboard. Built on the official monday MCP connector.", author: { name: "monday.com" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/mondaycom/mcp.git", path: "plugins/monday-crm", ref: "master", sha: "5eb0835e921de42ba603d7a8315ab4a2575a46b2" }, homepage: "https://monday.com" }, { name: "mongodb", description: "Official Claude plugin for MongoDB (MCP Server + Skills). Connect to databases, explore data, manage collections, optimize queries, generate reliable code, implement best practices, develop advanced features, and more.", category: "database", source: { source: "git-subdir", url: "https://github.com/mongodb/agent-skills.git", path: "plugins/mongodb", ref: "main", sha: "1e72df255e54e81eff078054c2cfb2b5d8c13503" }, homepage: "https://www.mongodb.com/docs/mcp-server/overview/" }, { name: "mongodb-atlas", description: "Connect to MongoDB Atlas clusters only through the Atlas Managed MCP Server. Sign in with your Atlas account to explore data, manage collections, optimize queries, generate reliable code with MongoDB best practices, and manage Atlas resources such as clusters, projects, database users, and network access. If you are running a different MongoDB deployment or want to run a local MongoDB MCP Server, install the MongoDB (Self-Managed MCP) plugin instead.", author: { name: "MongoDB" }, category: "database", source: { source: "git-subdir", url: "https://github.com/mongodb/agent-skills.git", path: "plugins/mongodb-atlas", ref: "main", sha: "1e72df255e54e81eff078054c2cfb2b5d8c13503" }, homepage: "https://www.mongodb.com/docs/mcp-server/get-started/" }, { name: "neon", description: "Manage your Neon projects and databases with the neon-postgres agent skill and the Neon MCP Server.", category: "database", source: { source: "git-subdir", url: "https://github.com/neondatabase/agent-skills.git", path: "plugins/neon-postgres", ref: "main", sha: "4a4266ac3da8cf29e3c995bad040ae4ac4476b28" }, homepage: "https://github.com/neondatabase/agent-skills/tree/main/plugins/neon-postgres" }, { name: "netlify-skills", description: "Netlify platform skills for Claude Code — functions, edge functions, blobs, database, image CDN, forms, config, CLI, frameworks, caching, AI gateway, and deployment.", category: "development", source: { source: "url", url: "https://github.com/netlify/context-and-tools.git", sha: "eddd0a3c67642651097a65b2d2d4194eaec173a1" }, homepage: "https://github.com/netlify/context-and-tools" }, { name: "netsuite-ai-companion", description: "Guides AI assistants that use the NetSuite AI Connector: tool-selection order, output formatting, NetSuite domain knowledge, multi-subsidiary and currency handling, and SuiteQL safety guardrails. Requires the NetSuite AI Connector Service.", author: { name: "Oracle NetSuite" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/oracle/netsuite-suitecloud-sdk.git", path: "anthropic/netsuite-ai-companion", ref: "ai-plugins-dist", sha: "23793a10a9bb557c684c5cb8a97f926eb3463f12" }, homepage: "https://github.com/oracle/netsuite-suitecloud-sdk/tree/ai-plugins-dist/anthropic/netsuite-ai-companion" }, { name: "netsuite-finance-analyst", description: "Director-level finance analysis on live NetSuite data: financial reporting, period close, variance, aging and reconciliation reviews, cash reporting, and board-ready narratives with next actions. Requires the NetSuite AI Connector Service.", author: { name: "Oracle NetSuite" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/oracle/netsuite-suitecloud-sdk.git", path: "anthropic/netsuite-finance-analyst", ref: "ai-plugins-dist", sha: "23793a10a9bb557c684c5cb8a97f926eb3463f12" }, homepage: "https://github.com/oracle/netsuite-suitecloud-sdk/tree/ai-plugins-dist/anthropic/netsuite-finance-analyst" }, { name: "netsuite-suitecloud", description: "Develop NetSuite SuiteCloud solutions with SuiteScript, SDF, and best practices: SuiteScript records and upgrades, SDF objects, roles and permissions, UIF single-page apps, OWASP secure coding, project documentation, and the SAFE Guide.", author: { name: "Oracle NetSuite" }, category: "development", source: { source: "git-subdir", url: "https://github.com/oracle/netsuite-suitecloud-sdk.git", path: "anthropic/netsuite-suitecloud", ref: "ai-plugins-dist", sha: "23793a10a9bb557c684c5cb8a97f926eb3463f12" }, homepage: "https://github.com/oracle/netsuite-suitecloud-sdk/tree/ai-plugins-dist/anthropic/netsuite-suitecloud" }, { name: "newrelic", displayName: "New Relic", description: "New Relic observability intelligence for Claude Code. Investigate APM performance, analyze cloud costs, debug Kubernetes, write NRQL queries, and respond to alerts — all from your terminal using New Relic telemetry data.", author: { name: "New Relic" }, category: "monitoring", source: { source: "url", url: "https://github.com/newrelic/claude-code-plugin.git", sha: "f8e5f8b62139072a22153ec92de1c0cc1af2f56a" }, homepage: "https://newrelic.com" }, { name: "nightvision", description: "Skills for working with NightVision, a DAST and API Discovery platform that finds exploitable vulnerabilities in web applications and REST APIs", source: { source: "url", url: "https://github.com/nvsecurity/nightvision-skills.git", sha: "957db6bb934839275c0f643042101bbb675ddbf7" }, homepage: "https://github.com/nvsecurity/nightvision-skills" }, { name: "nimble", description: "Nimble web data toolkit — search, extract, map, crawl the web and work with structured data agents", source: { source: "url", url: "https://github.com/Nimbleway/agent-skills.git", sha: "2890fdf94f0adfae79bf05b4de3c91667701bafb" }, homepage: "https://docs.nimbleway.com/integrations/agent-skills/plugin-installation" }, { name: "noibu", description: "Built for ecommerce, the Noibu plugin bridges the gap between customer experience and revenue by connecting Claude directly to your store's session, error, and conversion data through Noibu — and to the marketing, support, and commerce platforms that put insight into motion. Go beyond analysis: surface what's costing you revenue, take action across your stack, build workflows to automate work end-to-end.", author: { name: "Noibu" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/Noibu/ai-plugin.git", path: "src", ref: "main", sha: "3ff530b2dac2efd6a070ea8318a9705cd5d2d40f" }, homepage: "https://help.noibu.com/articles/3918362002-overview-of-the-noibu-plugin-for-claude" }, { name: "notion", description: "Notion workspace integration. Search pages, create and update documents, manage databases, and access your team's knowledge base directly from Claude Code for seamless documentation workflows.", category: "productivity", source: { source: "url", url: "https://github.com/makenotion/claude-code-notion-plugin.git", sha: "9847f2aa1a15f25df35ed1fb7b4557dbb60cd651" }, homepage: "https://github.com/makenotion/claude-code-notion-plugin" }, { name: "nvidia-skills", description: "Find the right NVIDIA skill for GPU acceleration, CUDA, AI agents, data loading, training, inference, robotics, Physical AI, Omniverse, simulation, and other NVIDIA-powered workflows.", author: { name: "NVIDIA" }, category: "development", source: { source: "git-subdir", url: "https://github.com/NVIDIA/skills.git", path: "plugins/nvidia-skills", ref: "main", sha: "2455514388e984b7e5a78a30e928f39d1401f16b" }, homepage: "https://build.nvidia.com/skills/" }, { name: "oracle-ai-data-platform-workbench-databricks-migrator", description: "Drive the Oracle AI Data Platform (AIDP) Databricks Migration Toolkit in natural language. Plans and executes automated Databricks → AIDP migrations of notebooks, jobs, schedules, and catalog DDL — Pass-1 dependency rewrite + Pass-2 cell-by-cell execute/verify/fix on a live AIDP cluster with Claude.", author: { name: "Oracle" }, category: "development", source: { source: "git-subdir", url: "https://github.com/oracle-samples/oracle-aidp-samples.git", path: "ai/claude-code-plugins/oracle-ai-data-platform-workbench-databricks-migrator", ref: "main", sha: "a88bcf3a9f9acca94663a727de42d8535e869486" }, homepage: "https://docs.oracle.com/en/cloud/paas/ai-data-platform/index.html" }, { name: "oracle-ai-data-platform-workbench-engineer-agent", description: "Oracle AI Data Platform (AIDP) Workbench engineer agent for Claude Code — a 37-skill agent that operates the full Spark/Delta lakehouse in natural language. Discovers your catalog into a grounding cache, turns plain English into accurate Spark SQL, and runs the lifecycle (CREATE/INSERT/UPDATE/DELETE/MERGE, OPTIMIZE/VACUUM, time-travel). Ingests files, profiles data and sets quality rules, authors and repairs pipelines, provisions clusters, and debugs via the Spark UI. Governs the platform (roles, credential store, Delta Sharing, audit logs), plus native Git, bundles, and MLOps/MLflow. Runs via the official Oracle aidp CLI.", author: { name: "Oracle" }, category: "development", source: { source: "git-subdir", url: "https://github.com/oracle-samples/oracle-aidp-samples.git", path: "ai/claude-code-plugins/oracle-ai-data-platform-workbench-engineer-agent", ref: "main", sha: "13e7a9139b3b62172119c7fc1a63bf4a2eac919d" }, homepage: "https://docs.oracle.com/en/cloud/paas/ai-data-platform/index.html" }, { name: "oracle-ai-data-platform-workbench-spark-connectors", description: "Oracle AI Data Platform Workbench Spark connectors for Claude Code. 18 connector skills covering every data source workbench customers commonly need: Oracle Autonomous DB family (ALH/ADW/ATP) via wallet/IAM-DB-Token/API-key, ExaCS, Fusion ERP REST, Fusion BICC, EPM Cloud Planning, Essbase 21c, OCI Streaming (Kafka), OCI Object Storage, Apache Iceberg, plus external systems (PostgreSQL, MySQL/HeatWave, SQL Server, Snowflake, Azure ADLS Gen2, AWS S3, generic REST, custom JDBC, Excel). Live-validated on the workbench `tpcds` cluster (Spark 3.5.0): 17 PASS / 4 ship-as-is out of 21 test rows.", author: { name: "Oracle" }, category: "development", source: { source: "git-subdir", url: "https://github.com/oracle-samples/oracle-aidp-samples.git", path: "ai/claude-code-plugins/oracle-ai-data-platform-workbench-spark-connectors", ref: "main", sha: "da0ce42f3b71cc16ee8b3a3e1ed2420c7eb180ad" }, homepage: "https://docs.oracle.com/en/cloud/paas/ai-data-platform/index.html" }, { name: "oracledb", description: "Connect, query, and interact with Oracle Databases and their data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/oracledb.git", sha: "f8606fea23c9e7cc5ff80470964c604e04db4cc9" }, homepage: "https://github.com/gemini-cli-extensions/oracledb" }, { name: "outputai", description: "Output.ai workflow development toolkit for Claude Code. Adds 5 specialist agents (planner, builder, debugger, prompt writer, quality reviewer), 40+ slash-command skills covering scaffolding, debugging, evaluation, and credential management, plus a SessionStart hook that auto-loads Output SDK conventions so Claude understands the framework before the first prompt.", author: { name: "Output.ai" }, category: "development", source: { source: "git-subdir", url: "https://github.com/growthxai/output.git", path: "coding_assistants/claude/plugins/outputai", ref: "main", sha: "69255d7fd577139a7828bd219637d067b86a42b1" }, homepage: "https://output.ai" }, { name: "pagerduty", description: "Enhance code quality and security through PagerDuty risk scoring and incident correlation. Score pre-commit diffs against historical incident data and surface deployment risk before you ship.", category: "monitoring", source: { source: "url", url: "https://github.com/PagerDuty/claude-code-plugins.git", sha: "761cba75bd50fd561405c3b173ecf36084432089" }, homepage: "https://github.com/PagerDuty/claude-code-plugins" }, { name: "paypal", description: "PayPal development plugin for Claude — integrate payments, subscriptions, invoices, disputes, and more using PayPal's APIs and MCP server", author: { name: "PayPal" }, category: "development", source: { source: "url", url: "https://github.com/paypal/AI-Toolkit.git", sha: "310b4962f0e5b3d09ff1c909d96ad5e226703ecb" }, homepage: "https://developer.paypal.com/" }, { name: "pendo-analytics", description: "Bring Pendo product analytics into Claude Code: account health, feature adoption, session replay lookup and triage, feedback analysis, and data-informed planning grounded in real usage data. Requires the Pendo connector and a Pendo subscription.", author: { name: "Pendo" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/pendo-analytics", ref: "main", sha: "a08842848e416be803e99184130aefca6ec9afd3" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/pendo-analytics" }, { name: "pendo-guides", description: "Create production-ready Pendo in-app guides (walkthroughs, announcements, alerts, polls, promotions) as HTML/CSS/JS from a short intake conversation, using Pendo's guide components.", author: { name: "Pendo" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/pendo-guides", ref: "main", sha: "a4699be3608ba134d8c7aa4b53e220cfde1c6aac" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/pendo-guides" }, { name: "pendo-orchestrate", description: "Create, configure and edit draft Pendo Orchestrate email journeys, including multi-email and conditional split flows, via the Pendo connector. Journeys stay in draft; activation happens in the Orchestrate UI.", author: { name: "Pendo" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/pendo-orchestrate", ref: "main", sha: "a4699be3608ba134d8c7aa4b53e220cfde1c6aac" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/pendo-orchestrate" }, { name: "php-lsp", description: "PHP language server (Intelephense) for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/php-lsp", category: "development", strict: false, lspServers: { intelephense: { command: "intelephense", args: ["--stdio"], extensionToLanguage: { ".php": "php" } } } }, { name: "pigment", description: "Analyze business data and build custom Pigment models, metrics, and boards through natural language.", author: { name: "Pigment" }, category: "productivity", source: { source: "url", url: "https://github.com/gopigment/ai-plugins.git", sha: "824f0064ad1300c73a8f136ca938ade860f3c7f9" }, homepage: "https://www.pigment.com" }, { name: "pinecone", description: "Pinecone vector database integration. Streamline your Pinecone development with powerful tools for managing vector indexes, querying data, and rapid prototyping. Use slash commands like /quickstart to generate AGENTS.md files and initialize Python projects and /query to quickly explore indexes. Access the Pinecone MCP server for creating, describing, upserting and querying indexes with Claude. Perfect for developers building semantic search, RAG applications, recommendation systems, and other vector-based applications with Pinecone.", category: "database", source: { source: "url", url: "https://github.com/pinecone-io/pinecone-claude-code-plugin.git", sha: "c383d38b5cc3c5ec219f2e68026e47ffbf46524a" }, homepage: "https://github.com/pinecone-io/pinecone-claude-code-plugin" }, { name: "pixeltable", description: "Build multimodal AI applications with Pixeltable -- tables, computed columns, embedding search, UDFs, tool-calling agents, and 25+ AI provider integrations.", author: { name: "Pixeltable" }, category: "development", source: { source: "url", url: "https://github.com/pixeltable/pixeltable-skill.git", sha: "70ec6a268a29b081b7d29e55fe0221ddf6064a9e" }, homepage: "https://docs.pixeltable.com" }, { name: "planetscale", description: "An authenticated hosted MCP server that accesses your PlanetScale organizations, databases, branches, schema, and Insights data. Query against your data, surface slow queries, and get organizational and account information.", category: "database", source: { source: "url", url: "https://github.com/planetscale/claude-plugin.git", sha: "95c80f9f391be9b1b6172bf82d4191e1ec11b637" }, homepage: "https://planetscale.com/" }, { name: "playground", description: "Creates interactive HTML playgrounds — self-contained single-file explorers with visual controls, live preview, and prompt output with copy button. Includes templates for design playgrounds, data explorers, concept maps, and document critique.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/playground", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/playground" }, { name: "playwright", description: "Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, click elements, and perform automated browser testing workflows.", category: "testing", source: "./external_plugins/playwright", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/playwright" }, { name: "plugin-dev", description: "Comprehensive toolkit for developing Claude Code plugins. Includes 7 expert skills covering hooks, MCP integration, commands, agents, and best practices. AI-assisted plugin creation and validation.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/plugin-dev", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/plugin-dev" }, { name: "posthog", description: "Access PostHog analytics, feature flags, experiments, error tracking, and insights directly from Claude Code.", category: "monitoring", source: { source: "url", url: "https://github.com/PostHog/ai-plugin.git", sha: "33c066c80776a962a4233d76b20a3317733070b4" }, homepage: "https://posthog.com/docs/model-context-protocol" }, { name: "postiz", description: "Social media automation CLI for scheduling posts, managing integrations, uploading media, and tracking analytics across 28+ platforms including X, LinkedIn, Reddit, YouTube, TikTok, Instagram, and more", source: { source: "url", url: "https://github.com/gitroomhq/postiz-agent.git", sha: "00aa5083c89fee6c673cc0ae21a70daaa3098854" }, homepage: "https://postiz.com/agent" }, { name: "postman", description: "Full API lifecycle management for Claude Code. Sync collections, generate client code, discover APIs, run tests, create mocks, publish docs, and audit security. Powered by the Postman MCP Server.", category: "development", source: { source: "url", url: "https://github.com/Postman-Devrel/postman-claude-code-plugin.git", sha: "c85c881c68c9b6338b5b75e989a79d61e76c51a0" }, homepage: "https://learning.postman.com/docs/developer/postman-mcp-server/" }, { name: "pr-review-toolkit", description: "Comprehensive PR review agents specializing in comments, tests, error handling, type design, code quality, and code simplification", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/pr-review-toolkit", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/pr-review-toolkit" }, { name: "preset-cli-skills", description: "Preset CLI skills for explicit shell, scripting, and CI/CD workflows driven by the `sup` CLI (PyPI package `superset-sup`). Use only for CLI workflows; do not use for MCP-only work or as a substitute for direct API calls when the user wants HTTP/SDK code.", author: { name: "Preset" }, category: "development", source: { source: "git-subdir", url: "https://github.com/preset-io/agent-skills.git", path: "plugins/preset-cli-skills", ref: "master", sha: "8387ac0f0538271c79a2e227c7ddec084e8a5da3" }, homepage: "https://www.preset.io" }, { name: "prisma", description: "Prisma MCP integration for Postgres database management, schema migrations, SQL queries, and connection string management. Provision Prisma Postgres databases, run migrations, and interact with your data directly.", source: { source: "url", url: "https://github.com/prisma/claude-plugin.git", sha: "815dbc4a045a29e3b81510ba0e3ab806f1baaf0e" }, homepage: "https://prisma.io" }, { name: "project-artifact", description: "Generate and publish a living project status page — overview & success criteria, the workstream sequence, and next steps — as a shareable claude.ai artifact backed by a per-project config, so refreshes re-gather live state, redeploy the same URL, and report only the delta.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/project-artifact", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/project-artifact" }, { name: "pydantic-ai", description: "Write accurate Pydantic AI code from the start. Up-to-date patterns, decision trees, and common gotchas for agents, tools, structured output, streaming, and multi-agent apps.", category: "development", source: { source: "git-subdir", url: "https://github.com/pydantic/skills.git", path: "plugins/ai", ref: "main", sha: "501b11a5b3f92b9c78bbe9bd76442df0ad68dadf" }, homepage: "https://github.com/pydantic/skills/tree/main/plugins/ai" }, { name: "pyright-lsp", description: "Python language server (Pyright) for type checking and code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/pyright-lsp", category: "development", strict: false, lspServers: { pyright: { command: "pyright-langserver", args: ["--stdio"], extensionToLanguage: { ".py": "python", ".pyi": "python" } } } }, { name: "qdrant-skills", description: "Agent skills for Qdrant vector search covering scaling, performance optimization, search quality, monitoring, deployment, model migration, version upgrades, and SDK usage across Python, TypeScript, Rust, Go, .NET, and Java.", author: { name: "Qdrant" }, category: "database", source: { source: "url", url: "https://github.com/qdrant/skills.git", sha: "7d12f624a62e6b3738fe9a8460a22adb5f21d108" }, homepage: "https://skills.qdrant.tech" }, { name: "qodo", displayName: "Qodo", description: "Bring Qodo's codebase intelligence, coding standards, and code review into your coding agent.", author: { name: "Qodo", email: "support@qodo.ai" }, category: "development", source: { source: "git-subdir", url: "https://github.com/qodo-ai/qodo-skills.git", path: "packages/qodo", ref: "main", sha: "79019ff7a574383d7146502ec5ffe7f7437a55d6" }, homepage: "https://github.com/qodo-ai/qodo-skills.git" }, { name: "qodo-standards", displayName: "Qodo Standards", description: "Optional Qodo rules discovery and standards administration workflows.", author: { name: "Qodo", email: "support@qodo.ai" }, category: "development", source: { source: "git-subdir", url: "https://github.com/qodo-ai/qodo-skills.git", path: "packages/qodo-standards", ref: "main", sha: "79019ff7a574383d7146502ec5ffe7f7437a55d6" }, homepage: "https://github.com/qodo-ai/qodo-skills.git" }, { name: "qt-development-skills", description: "Agentic engineering skills for Qt software development — Qt C++/QML code review, QML coding, and Qt C++/QML code documentation.", author: { name: "Qt Group" }, category: "development", source: { source: "url", url: "https://github.com/TheQtCompanyRnD/agent-skills.git", sha: "71d6c10da78b9a764468ae11c86ab3bc4ca4921f" }, homepage: "https://www.qt.io/" }, { name: "quarkus-agent", description: "MCP server for AI coding agents to create, manage, and interact with Quarkus applications. Provides tools for project scaffolding, dev mode lifecycle, extension skills, Dev MCP proxy, and documentation search.", author: { name: "Quarkus" }, category: "development", source: { source: "url", url: "https://github.com/quarkusio/quarkus-agent-mcp.git", sha: "31c9b96658d9afaf09f0013ad6c75b64b0019371" }, homepage: "https://quarkus.io" }, { name: "railway", description: "Deploy and manage apps, databases, and infrastructure on Railway. Covers project setup, deploys, environment configuration, networking, troubleshooting, and monitoring.", category: "deployment", source: { source: "git-subdir", url: "https://github.com/railwayapp/railway-skills.git", path: "plugins/railway", ref: "main", sha: "950acebcef3445f3915ea0709876c3ba9c237a7f" }, homepage: "https://docs.railway.com/ai/claude-code-plugin" }, { name: "ralph-loop", description: "Interactive self-referential AI loops for iterative development, implementing the Ralph Wiggum technique. Claude works on the same task repeatedly, seeing its previous work, until completion.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/ralph-loop", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/ralph-loop" }, { name: "rc", description: "Configure RevenueCat projects, apps, products, entitlements, and offerings directly from Claude Code. Manage your in-app purchase backend without leaving your development workflow.", category: "development", source: { source: "url", url: "https://github.com/RevenueCat/rc-claude-code-plugin.git", path: "revenuecat", sha: "7bf32f6bf40f790c259b8c3bb9be68dc6ef76105" }, homepage: "https://www.revenuecat.com" }, { name: "receipts", description: "A personal Claude Code impact report for justifying your usage to a manager or a self-review: what you shipped, which projects it went to, and each project's share of your usage. Reads your ~/.claude/projects transcripts and runs read-only git locally; only counts and project names are sent to write it up, and the report stays on your machine.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/receipts", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/receipts" }, { name: "redis-development", description: "Redis development best practices — data structures, query engine, vector search, caching, and performance optimization", author: { name: "Redis" }, category: "database", source: { source: "git-subdir", url: "https://github.com/redis/agent-skills.git", path: "plugins/redis-development", ref: "main", sha: "172fb9effa139cd7432ac29a9ee81c45943e5a28" }, homepage: "https://redis.io" }, { name: "remember", description: "Continuous memory for Claude Code. Extracts, summarizes, and compresses conversations into tiered daily logs. Claude remembers what you did yesterday.", source: { source: "url", url: "https://github.com/Digital-Process-Tools/claude-remember.git", sha: "a5cc87c35567cff2ff603f598fc8a7134971a280" }, homepage: "https://github.com/Digital-Process-Tools/claude-remember" }, { name: "render", description: "Deploy, debug, and monitor applications on Render. Includes skills, an agent, slash commands, and a render.yaml validation hook.", author: { name: "Render" }, category: "deployment", source: { source: "url", url: "https://github.com/render-oss/render-plugin-claude-code.git", sha: "e8f889396634dbc8c368448a7f3de993ed4a5ac1" }, homepage: "https://render.com" }, { name: "resend", description: "Agent skills for working with Resend to send and receive emails — email API integration, agent inbox, CLI, React Email components, and deliverability best practices. Includes the Resend MCP server.", author: { name: "Resend" }, category: "development", source: { source: "url", url: "https://github.com/resend/resend-skills.git", sha: "8938c2a6f17903f9168c31431c842c68a68b19f3" }, homepage: "https://resend.com" }, { name: "revenuecat", description: "Configure RevenueCat projects, apps, products, entitlements, and offerings directly from Claude Code. Manage your in-app purchase backend without leaving your development workflow.", category: "development", source: { source: "url", url: "https://github.com/RevenueCat/rc-claude-code-plugin.git", path: "revenuecat", sha: "7bf32f6bf40f790c259b8c3bb9be68dc6ef76105" }, homepage: "https://www.revenuecat.com" }, { name: "rill", description: "Skills for developing and querying projects in the Rill business intelligence platform", author: { name: "Rill Data" }, category: "development", source: { source: "url", url: "https://github.com/rilldata/agent-skills.git", sha: "440e4081f2f56e1a130a5c679f75a0826a611264" }, homepage: "https://docs.rilldata.com/developers/build/ai-configuration" }, { name: "rootly", description: "Full-lifecycle incident management: deploy safety, incident response, on-call management, and retrospectives.", author: { name: "Rootly" }, category: "monitoring", source: { source: "url", url: "https://github.com/Rootly-AI-Labs/rootly-claude-plugin.git", sha: "65832aa6ff7a7b39c6bd64899a7a64646e3948ed" }, homepage: "https://rootly.com" }, { name: "ruby-lsp", description: "Ruby language server for code intelligence and analysis", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/ruby-lsp", category: "development", strict: false, lspServers: { "ruby-lsp": { command: "ruby-lsp", extensionToLanguage: { ".rb": "ruby", ".rake": "ruby", ".gemspec": "ruby", ".ru": "ruby", ".erb": "erb" } } } }, { name: "runway-api", description: "Video generation at scale. Generate videos, images, and audio with Runway's API — batch ad campaigns, product videos, multishot stories, and creative iteration. Supports seedance2, gen4.5, veo3, Nano, Banana Pro, and more.", author: { name: "Runway" }, category: "design", source: { source: "url", url: "https://github.com/runwayml/skills.git", sha: "e3dffc15498e9588e7815f37b9ecf10e8bc2c902" }, homepage: "https://runwayml.com" }, { name: "rust-analyzer-lsp", description: "Rust language server for code intelligence and analysis", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/rust-analyzer-lsp", category: "development", strict: false, lspServers: { "rust-analyzer": { command: "rust-analyzer", extensionToLanguage: { ".rs": "rust" } } } }, { name: "sagemaker-ai", description: "Build, train, and deploy AI models with deep AWS AI/ML expertise brought directly into your coding assistants, covering the surface area of Amazon SageMaker AI.", category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/sagemaker-ai", ref: "main", sha: "bab56a3b9991aa0c6857b05198a61ba14a60bce4" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "salesforce-development", description: "Build Salesforce apps and agents using these core building blocks: metadata, Apex, deploy/retrieve, security, reporting, and generated installed-versus-available capability discovery.", author: { name: "Salesforce" }, category: "development", source: { source: "git-subdir", url: "https://github.com/forcedotcom/sf-skills.git", path: "plugins/builder/salesforce-development", ref: "main", sha: "7e04d4744792ae2defb7f4da24fe85cbdf6f6e5a" }, homepage: "https://github.com/forcedotcom/sf-skills/tree/main/plugins/builder/salesforce-development" }, { name: "sanity", description: "Sanity content platform integration with MCP server, agent skills, and slash commands. Query and author content, build and optimize GROQ queries, design schemas, and set up Visual Editing.", category: "development", author: { name: "Sanity" }, source: { source: "url", url: "https://github.com/sanity-io/agent-toolkit.git", sha: "88d6cdfa7cb06c99edd5f376efa4dac21ae3f877" }, homepage: "https://www.sanity.io" }, { name: "sap-cds-mcp", description: "AI-assisted development of SAP Cloud Application Programming Model (CAP) projects. Search CDS models and CAP documentation.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "url", url: "https://github.com/cap-js/mcp-server.git", sha: "79e4546395a52b1a3881d828118a1b3a2e198876" }, homepage: "https://cap.cloud.sap/" }, { name: "sap-fiori-mcp-server", description: "MCP server for SAP Fiori development tools for Claude Code. Build and modify SAP Fiori applications with AI assistance.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/SAP/open-ux-tools.git", path: "packages/fiori-mcp-server", ref: "main", sha: "31c1263fb76e1737dcb0a6d163c967d8f8126ddd" }, homepage: "https://github.com/SAP/open-ux-tools/tree/main/packages/fiori-mcp-server" }, { name: "sap-hana-cli", description: "150+ SAP HANA database tools for AI assistants. Query tables, import/export data, profile data quality, compare schemas, manage backups, monitor performance, and more. Connects to SAP HANA Cloud and on-premise databases.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "database", source: { source: "url", url: "https://github.com/SAP-samples/hana-cli-claude-plugin.git", sha: "abadd0aba32792b6378ed784e9f6d3e5b25dfc2a" }, homepage: "https://github.com/SAP-samples/hana-cli-claude-plugin" }, { name: "sap-mdk-server", description: "MCP server for SAP Mobile Development Kit (MDK). Build and modify MDK applications with AI assistance — schema lookups, action validation, rule editing, and project scaffolding.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "url", url: "https://github.com/SAP/mdk-mcp-server.git", sha: "68efb00cd62a905748c98c8533fecff2f3ff4a00" }, homepage: "https://help.sap.com/docs/MDK" }, { name: "save-to-spotify", description: "Create polished audio episodes with TTS narration, rich timelines, cover images, and save them to Spotify via the save-to-spotify CLI.", author: { name: "Spotify" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/spotify/save-to-spotify.git", path: "plugin", ref: "main", sha: "9d05c8cd8c8559552f84e27fe30f46b7693ce69a" }, homepage: "https://github.com/spotify/save-to-spotify" }, { name: "scandit-sdk", displayName: "Scandit SDK", description: "AI agent skills for integrating the Scandit Data Capture SDK — product selection, documentation, and implementation guides for barcode scanning, ID capture, and smart label capture.", author: { name: "Scandit" }, category: "development", source: { source: "url", url: "https://github.com/Scandit/skills.git", sha: "2f0731a090eb9c23a64b6dcd9559cf113df3313f" }, homepage: "https://www.scandit.com" }, { name: "security-guidance", description: "Security review for Claude-generated code. Pattern-based warnings on edits, LLM-powered diff review on Stop, and an agentic commit reviewer that catches injection, XSS, SSRF, hardcoded secrets, and 25+ other vulnerability classes.", version: "2.0.7", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/security-guidance", category: "security", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/security-guidance" }, { name: "semgrep", description: "Semgrep catches security vulnerabilities in real-time and guides Claude to write secure code from the start.", category: "security", source: { source: "git-subdir", url: "https://github.com/semgrep/mcp-marketplace.git", path: "plugin", sha: "f97e1ce43533ffde2eae9af2a80f95a7250c365f" }, homepage: "https://github.com/semgrep/mcp-marketplace.git" }, { name: "sentry", description: "Sentry error monitoring integration. Access error reports, analyze stack traces, search issues by fingerprint, and debug production errors directly from your development environment.", category: "monitoring", source: { source: "url", url: "https://github.com/getsentry/plugin-claude.git", sha: "73e53541d7af21672e27428c7067f4264b8a3d65" }, homepage: "https://github.com/getsentry/plugin-claude" }, { name: "sentry-cli", description: "Skills for using the Sentry CLI to interact with Sentry from the command line", author: { name: "Sentry" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/getsentry/cli.git", path: "packages/cli/plugins/sentry-cli", ref: "main", sha: "936c2cdc2ac13978ca9a843b24a0583e9309af8e" }, homepage: "https://sentry.io" }, { name: "serena", description: "Semantic code analysis MCP server providing intelligent code understanding, refactoring suggestions, and codebase navigation through language server protocol integration.", category: "development", source: "./external_plugins/serena", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/serena", tags: ["community-managed"] }, { name: "servicenow-sdk", description: "Create, edit, and deploy ServiceNow applications with the Fluent SDK effortlessly through Claude AI.", author: { name: "ServiceNow" }, category: "development", source: { source: "git-subdir", url: "https://github.com/ServiceNow/sdk.git", path: "providers/claude/plugin", ref: "master", sha: "f3e0379242b29e0039e1625d637aa1c246acbe12" }, homepage: "https://servicenow.github.io/sdk/" }, { name: "session-report", description: "Generate an explorable HTML report of Claude Code session usage — tokens, cache efficiency, subagents, skills, and the most expensive prompts — from local ~/.claude/projects transcripts.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/session-report", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/session-report" }, { name: "setup-agent-analytics", description: "Detect AI agents in your codebase and instrument them with Pendo Agent Analytics via the best-fit path: Python SDK, TypeScript SDK, client-side trackAgent(), or the Conversations API.", author: { name: "Pendo" }, category: "development", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/setup-agent-analytics", ref: "main", sha: "a4699be3608ba134d8c7aa4b53e220cfde1c6aac" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/setup-agent-analytics" }, { name: "setup-mcp-agent-analytics", description: "Detect an MCP server's language (Python, TypeScript or Go) and instrument it with the matching Pendo SDK so MCP tool calls flow into Pendo Agent Analytics.", author: { name: "Pendo" }, category: "development", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/setup-mcp-agent-analytics", ref: "main", sha: "a4699be3608ba134d8c7aa4b53e220cfde1c6aac" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/setup-mcp-agent-analytics" }, { name: "shippo", description: "Shippo connects you to USPS, UPS, FedEx, DHL, and 40+ carriers, so you can handle a shipment end to end right inside Claude. Compare live rates and pick the cheapest or best option, buy and print labels (domestic and international, with customs declarations), validate and standardize addresses, and track packages across carriers. Just ask in plain language: rate-shop a parcel, buy the right label, check a delivery status, or confirm an address before you ship. Whether you run a store or just need to send a package, Shippo turns a pile of carrier accounts into one simple conversation.", author: { name: "Shippo" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/goshippo/ai.git", path: "providers/claude/plugin", ref: "main", sha: "15cbb6364fbcfd465a134f5972da9179436d0787" }, homepage: "https://docs.goshippo.com" }, { name: "shopify-ai-toolkit", description: "Shopify's AI Toolkit provides 18 development skills for building on the Shopify platform, covering documentation search, API schema access, GraphQL and Liquid code validation, Hydrogen storefronts, Polaris UI extensions, store management via CLI, and onboarding guidance for both developers and merchants.", author: { name: "Shopify" }, category: "development", source: { source: "url", url: "https://github.com/Shopify/Shopify-AI-Toolkit.git", sha: "c6a219bf99fc5aa2576843f3c8a005f9da863383" }, homepage: "https://shopify.dev" }, { name: "skill-creator", description: "Create new skills, improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, update or optimize an existing skill, run evals to test a skill, or benchmark skill performance with variance analysis.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/skill-creator", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/skill-creator" }, { name: "slack", description: "Slack workspace integration. Search messages, access channels, read threads, and stay connected with your team's communications while coding. Find relevant discussions and context quickly.", category: "productivity", source: { source: "url", url: "https://github.com/slackapi/slack-mcp-plugin.git", sha: "8044341769fa84f85ee952dceddb67ef165ab110" }, homepage: "https://github.com/slackapi/slack-mcp-plugin/tree/main" }, { name: "snowflake-cortex-code", description: "Automatically route Snowflake prompts from Claude Code to Cortex Code for execution. Provides slash commands for code review and task delegation, plus skills for routing, run, and setup.", author: { name: "Snowflake" }, category: "development", source: { source: "git-subdir", url: "https://github.com/Snowflake-Labs/snowflake-ai-kit.git", path: "plugins/cortex-code", ref: "main", sha: "0c54225ea50b44c2ae07e1f378bf401e88b33c33" }, homepage: "https://docs.snowflake.com/en/user-guide/cortex-code" }, { name: "sonarqube", description: "Automatically enforce SonarQube code quality and security in the agent coding loop — 7,000+ rules, secrets scanning, agentic analysis, and quality gates across 40+ languages. PostToolUse hooks run analysis after every file edit. Pre-tool secrets scanning prevents 450+ patterns from reaching the LLM. Slash commands give on-demand access to quality gate status, coverage, duplication, and dependency risks. Includes SonarQube CLI, MCP Server, skills, hooks, and slash commands.", author: { name: "SonarSource" }, category: "security", source: { source: "url", url: "https://github.com/SonarSource/sonarqube-agent-plugins.git", sha: "f05d5f9890da8eb602c1aa24123e92c697ee6f2e" }, homepage: "https://www.sonarsource.com" }, { name: "sonatype-guide", description: "Sonatype Guide MCP server for software supply chain intelligence and dependency security. Analyze dependencies for vulnerabilities, get secure version recommendations, and check component quality metrics.", category: "security", source: { source: "url", url: "https://github.com/sonatype/sonatype-guide-claude-plugin.git", sha: "1dae73980f591d3196f5532ac72186513563d028" }, homepage: "https://github.com/sonatype/sonatype-guide-claude-plugin.git" }, { name: "sourcegraph", description: "Code search and understanding across codebases. Search, read, and trace references across repositories; analyze refactor impact; investigate incidents via commit and diff search; run targeted security sweeps.", category: "development", source: { source: "url", url: "https://github.com/sourcegraph-community/sourcegraph-claudecode-plugin.git", sha: "674a05e2e28677fc3fdce7491063459455ded573" }, homepage: "https://sourcegraph.com" }, { name: "spanner", description: "Connect and interact with Spanner data using natural language.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/spanner.git", sha: "a69b5f3449387a851648f8bd9be58d0b27e0411c" }, homepage: "https://github.com/gemini-cli-extensions/spanner" }, { name: "spotify-ads-api", description: "Manage Spotify ad campaigns with natural language. Create campaigns, ad sets, ads, pull reports, and handle OAuth — all through conversation.", category: "productivity", source: { source: "url", url: "https://github.com/spotify/ads-claude-plugin.git", sha: "ae7efbeb6f46a10a706234670487c3b5775b969e" }, homepage: "https://github.com/spotify/ads-claude-plugin" }, { name: "stackhawk-hawkscan", description: "Configure, run, and interpret HawkScan DAST results inside Claude Code. Generates stackhawk.yml configs, runs scans via CLI or Docker, and transforms security findings into prioritized fix tasks for your coding agent.", author: { name: "StackHawk" }, category: "security", source: { source: "git-subdir", url: "https://github.com/stackhawk/agent-skills.git", path: "plugins/hawkscan", ref: "main", sha: "66cac9baa5883a1007575faf1b22855a1124834a" }, homepage: "https://docs.stackhawk.com/ai-security/" }, { name: "stackhawk-api", description: "Query the StackHawk platform API for security posture reporting, findings analysis, and app management. Guides agents through authentication, data retrieval, and result presentation.", author: { name: "StackHawk" }, category: "security", source: { source: "git-subdir", url: "https://github.com/stackhawk/agent-skills.git", path: "plugins/api", ref: "main", sha: "66cac9baa5883a1007575faf1b22855a1124834a" }, homepage: "https://docs.stackhawk.com/ai-security/" }, { name: "streaming-skills-plugin", description: "Skills for streaming application developers, covering Kafka and Flink client libraries and Schema Registry", author: { name: "Confluent" }, category: "development", source: { source: "url", url: "https://github.com/confluentinc/agent-skills.git", sha: "914d95eff7ff50513b34bfb9ac97eda7c7fce899" }, homepage: "https://www.confluent.io" }, { name: "stripe", description: "Stripe development plugin for Claude", category: "development", source: { source: "git-subdir", url: "https://github.com/stripe/ai.git", path: "providers/claude/plugin", ref: "main", sha: "da4991b0a0b9299d423ae2d5856e6d7e2b31b031" }, homepage: "https://github.com/stripe/ai/tree/main/providers/claude/plugin" }, { name: "sumup", description: "SumUp payment integrations across terminal and online checkout flows. Build Android and iOS POS apps with SumUp card readers, online checkout with server SDKs and the checkout widget, and control card readers remotely via Cloud API.", category: "development", source: { source: "url", url: "https://github.com/sumup/sumup-skills.git", sha: "cb72003b417cec5e717c6b788d63394b7e921938" }, homepage: "https://www.sumup.com/" }, { name: "supabase", description: "Supabase MCP integration for database operations, authentication, storage, and real-time subscriptions. Manage your Supabase projects, run SQL queries, and interact with your backend directly.", category: "database", source: { source: "url", url: "https://github.com/supabase-community/supabase-plugin.git", sha: "f3f332e0164c34a8392772811737fda0cb972d06" }, homepage: "https://github.com/supabase-community/supabase-plugin" }, { name: "superdesign", description: "Design or redesign frontend UI and marketing graphics on the Superdesign infinite canvas. Reads your codebase for context, sets up a design system, and generates branchable design drafts you refine.", author: { name: "Superdesign dev, Inc." }, category: "design", source: { source: "url", url: "https://github.com/superdesigndev/superdesign-skill.git", sha: "f9f05cd988c247dce6c072eaf9ac6b162f2ffc4b" }, homepage: "https://superdesign.dev" }, { name: "superpowers", description: "Superpowers teaches Claude brainstorming, subagent driven development with built in code review, systematic debugging, and red/green TDD. Additionally, it teaches Claude how to author and test new skills.", category: "development", source: { source: "url", url: "https://github.com/obra/superpowers.git", sha: "b36e0829c6d0140e93cfef2ca599b1b07d4a7797" }, homepage: "https://github.com/obra/superpowers.git" }, { name: "swift-lsp", description: "Swift language server (SourceKit-LSP) for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/swift-lsp", category: "development", strict: false, lspServers: { "sourcekit-lsp": { command: "sourcekit-lsp", extensionToLanguage: { ".swift": "swift" } } } }, { name: "synthflow", description: "Connects Claude Code to the Synthflow AI voice-agent platform through its hosted MCP server, with skills for reviewing calls and auditing agent prompts, plus a docs-search connector.", author: { name: "Synthflow" }, category: "automation", source: { source: "git-subdir", url: "https://github.com/SynthFlowAI/AnthropicPlugin.git", path: "plugins/synthflow", ref: "main", sha: "205871ee83508502d2c982ee1bb7e65a2a29190b" }, homepage: "https://synthflow.ai" }, { name: "tavily", description: "Build AI applications with real-time web data using Tavily's search, extract, crawl, and research APIs.", author: { name: "Tavily Team" }, category: "development", source: { source: "url", url: "https://github.com/tavily-ai/skills.git", sha: "778122e5f9c680f541eeceda5a5b36405eb7980c" }, homepage: "https://www.tavily.com/" }, { name: "teamcity-cli", description: "Agent skill for interacting with TeamCity CI/CD using the teamcity CLI. Enables Claude to explore builds, view logs, start jobs, manage queues, agents, and more.", author: { name: "JetBrains" }, category: "development", source: { source: "url", url: "https://github.com/JetBrains/teamcity-cli.git", sha: "ac6c1fd83300b2e42df48fcfff365ba03f73bb92" }, homepage: "https://www.jetbrains.com/teamcity/" }, { name: "telegram", description: "Telegram messaging bridge with built-in access control. Manage pairing, allowlists, and policy via /telegram:access.", category: "productivity", source: "./external_plugins/telegram" }, { name: "terraform", description: "The Terraform MCP Server provides seamless integration with Terraform ecosystem, enabling advanced automation and interaction capabilities for Infrastructure as Code (IaC) development.", author: { name: "HashiCorp", email: "support@hashicorp.com" }, category: "development", source: "./external_plugins/terraform", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/terraform" }, { name: "togetherai-skills", description: "Agent Skills for Together AI platform — inference, training, embeddings, audio, video, images, function calling, and infrastructure. Covers serverless chat completions, image/video generation, fine-tuning, batch inference, evaluations, sandboxes, dedicated endpoints, and GPU clusters.", author: { name: "Together AI" }, category: "development", source: { source: "url", url: "https://github.com/togethercomputer/skills.git", sha: "644d38225bbdef0318462fe222f6f9883c8addcd" }, homepage: "https://www.together.ai" }, { name: "twilio-developer-kit", description: "Twilio Skills provide procedural knowledge for AI coding agents — which APIs to use, in what order, and what to avoid. Covers SMS, Voice, WhatsApp, Verify, SendGrid, Compliance, and 30+ products.", author: { name: "Twilio" }, category: "development", source: { source: "url", url: "https://github.com/twilio/ai.git", sha: "8aba46fb65dc8d9a20f4b301a68352064b4159a5" }, homepage: "https://www.twilio.com" }, { name: "typescript-lsp", description: "TypeScript/JavaScript language server for enhanced code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/typescript-lsp", category: "development", strict: false, lspServers: { typescript: { command: "typescript-language-server", args: ["--stdio"], extensionToLanguage: { ".ts": "typescript", ".tsx": "typescriptreact", ".js": "javascript", ".jsx": "javascriptreact", ".mts": "typescript", ".cts": "typescript", ".mjs": "javascript", ".cjs": "javascript" } } } }, { name: "ui-theme-designer", description: "Plugin for coding agents working with UI theme designer. Bundles two skills: how-to and conceptual answers about UI theme designer on BTP, and questions about the SAP Design System and SAP Fiori design tokens — theme parameters and component-level parameter usage in UI5, UI5 Web Components, and Fundamental Styles.", author: { name: "SAP SE" }, category: "design", source: { source: "git-subdir", url: "https://github.com/SAP/ui-theme-designer-plugins-for-coding-agents.git", path: "plugins/ui-theme-designer", ref: "main", sha: "04a0a217e129422f8a995c5a9dd31712e5a32f47" }, homepage: "https://github.com/SAP/ui-theme-designer-plugins-for-coding-agents" }, { name: "ui5", description: "SAPUI5 / OpenUI5 plugin for coding agents. Create and validate UI5 projects, access API documentation, run UI5 linter, get development guidelines and best practices for UI5 development.", author: { name: "SAP SE", email: "openui5@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/UI5/plugins-coding-agents.git", path: "plugins/ui5", ref: "main", sha: "a99b882ce364ef4b9f52fb4054f5f410c1636563" }, homepage: "https://github.com/UI5/plugins-coding-agents" }, { name: "ui5-modernization", description: "Complete UI5 modernization toolkit with workflow and specialized fix patterns for modernizing SAPUI5/OpenUI5 applications.", author: { name: "SAP SE", email: "openui5@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/UI5/plugins-coding-agents.git", path: "plugins/ui5-modernization", ref: "main", sha: "2b8c4a944e39609214bce7aef3b05260985f0e91" }, homepage: "https://github.com/UI5/plugins-coding-agents" }, { name: "ui5-typescript-conversion", description: "SAPUI5 / OpenUI5 plugin for coding agents. Convert JavaScript based UI5 projects to TypeScript.", author: { name: "SAP SE", email: "openui5@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/UI5/plugins-coding-agents.git", path: "plugins/ui5-typescript-conversion", ref: "main", sha: "2b8c4a944e39609214bce7aef3b05260985f0e91" }, homepage: "https://github.com/UI5/plugins-coding-agents" }, { name: "unity", displayName: "Unity", description: "Unity's official plugin for Claude Code, with curated skills for game development, monetization, and performance optimization.", author: { name: "Unity Technologies" }, category: "development", source: { source: "url", url: "https://github.com/Unity-Technologies/unity-agent-plugin.git", sha: "5ad4bafc1d91acfdeca800bfbae0072fcc7aeb58" }, homepage: "https://unity.com" }, { name: "unreal-engine-skills-for-claude-code", description: "Control Unreal Editor directly from Claude Code via MCP. Hundreds of tools exposed via Unreal's ToolsetRegistry across 30+ toolsets: actors, blueprints, materials, Niagara, Control Rigs, Sequencer, State Trees, widgets, Gameplay Ability System, automation testing, and more.", author: { name: "Epic Games" }, category: "development", source: { source: "url", url: "https://github.com/EpicGames/unreal-engine-skills-for-claude-code-plugin.git", sha: "a6aa73ada02a9fb1f5415bec491f9942c519b297" }, homepage: "https://dev.epicgames.com/documentation/unreal-engine/unreal-mcp-in-unreal-editor" }, { name: "valtown", description: "Build and deploy on Val Town. Bundles the Val Town MCP server and platform skills (HTTP vals, cron/intervals, SQLite, email, OAuth, React UI, third-party integrations, templates).", author: { name: "Val Town" }, category: "deployment", source: { source: "git-subdir", url: "https://github.com/val-town/plugins.git", path: "plugin", ref: "main", sha: "2d3ec654b6a7d93e209afb8f2e8848eddcb9f17b" }, homepage: "https://val.town" }, { name: "vanta", description: "The Vanta plugin connects Claude Code to Vanta's security and compliance platform through the Vanta MCP server. It combines Vanta's test-specific remediation intelligence with your local repository context to help you fix compliance failures faster.", author: { name: "Vanta" }, category: "security", source: { source: "url", url: "https://github.com/VantaInc/vanta-mcp-plugin.git", sha: "345d86b55faa649e955b7ea5569cf52d8425c2d5" }, homepage: "https://help.vanta.com/en/articles/14094979-connecting-to-vanta-mcp#h_887ce3f337" }, { name: "vanta-mcp-plugin", description: "The Vanta plugin connects Claude Code to Vanta's security and compliance platform through the Vanta MCP server. It combines Vanta's test-specific remediation intelligence with your local repository context to help you fix compliance failures faster.", author: { name: "Vanta" }, category: "security", source: { source: "url", url: "https://github.com/VantaInc/vanta-mcp-plugin.git", sha: "345d86b55faa649e955b7ea5569cf52d8425c2d5" }, homepage: "https://help.vanta.com/en/articles/14094979-connecting-to-vanta-mcp#h_887ce3f337" }, { name: "vercel", description: "Vercel deployment platform integration. Manage deployments, check build status, access logs, configure domains, and control your frontend infrastructure directly from Claude Code.", category: "deployment", source: { source: "url", url: "https://github.com/vercel/vercel-plugin.git", sha: "9ca8770143395d69606573e122c456566d6f419b" }, homepage: "https://github.com/vercel/vercel-plugin" }, { name: "vibe-prospecting", description: "Vibe Prospecting connects Claude to live B2B company and contact data so users can search, match, enrich, filter, and export prospects at scale. It turns natural-language requests into structured GTM workflows for lead generation, CRM enrichment, company research, executive discovery, and multi-step prospecting automation inside Claude Cowork and Claude Code.", author: { name: "vibeprospecting.ai" }, category: "productivity", source: { source: "url", url: "https://github.com/explorium-ai/vibeprospecting-plugin.git", sha: "9b4067473305dbba80be0fa9a492be39b96f455e" }, homepage: "https://www.vibeprospecting.ai/product/claude-plugin" }, { name: "vsql-extension-builder", description: "Builds a VillageSQL extension for MySQL end-to-end through a 7-phase persona-driven workflow. Commonly used to port PostgreSQL extensions to MySQL.", author: { name: "VillageSQL" }, category: "database", source: { source: "url", url: "https://github.com/villagesql/villagesql-skills.git", sha: "18f7d68673e2bd5d400b4ee91298e5a4b9e8d24e" }, homepage: "https://villagesql.com" }, { name: "windsor-ai", description: "Connect Claude Code to 325+ business data sources via Windsor.ai. Query marketing, sales, CRM, ecommerce, finance, and analytics data from Google Ads, Meta, HubSpot, Salesforce, Shopify, Stripe, and hundreds more — directly from your terminal.", author: { name: "Windsor.ai" }, category: "productivity", source: { source: "url", url: "https://github.com/windsor-ai/claude-windsor-ai-plugin.git", sha: "d7ba1cb036c7ca765536355fb85f13a3237ea3f9" }, homepage: "https://windsor.ai" }, { name: "wix", description: "Build, manage, and deploy Wix sites and apps. CLI development skills for dashboard extensions, backend APIs, site widgets, and service plugins with the Wix Design System, plus MCP server for site management.", category: "development", source: { source: "url", url: "https://github.com/wix/skills.git", sha: "9c48e3f65cc869868d617c5995cf852cc71f64af" }, homepage: "https://dev.wix.com/docs/wix-cli/guides/development/about-wix-skills" }, { name: "build-with-wordpress", description: "Craft production-grade WordPress sites and applications. Everything from themes and plugins to commerce and deployment.", source: { source: "url", url: "https://github.com/Automattic/claude-code-wordpress.com.git", sha: "052ca970df2c577d7c651e784935186ff93e6779" }, homepage: "https://developer.wordpress.com/wordpress-com-claude-code-plugin/" }, { name: "workos", description: "WorkOS integration skills for AuthKit, SSO, Directory Sync, RBAC, Vault, Audit Logs, migrations, and API references.", author: { name: "WorkOS" }, category: "security", source: { source: "git-subdir", url: "https://github.com/workos/skills.git", path: "plugins/workos", ref: "main", sha: "6b7d596ae28fb0bf2ecc01a8737e4bdcc70f7ab8" }, homepage: "https://workos.com" }, { name: "youdotcom-agent-skills", description: "You.com agent skills for web search, research with citations, and content extraction. Guided integrations for Vercel AI SDK, Claude Agent SDK, OpenAI Agents SDK, crewAI, LangChain, Microsoft Teams.ai, direct REST API, and bash CLI.", author: { name: "You.com" }, category: "productivity", source: { source: "url", url: "https://github.com/youdotcom-oss/agent-skills.git", sha: "08f3d80e7ca9518ccc64b38b365a78cc4a762691" }, homepage: "https://you.com" }, { name: "zapier", description: "Connect 8,000+ apps to your AI workflow. Discover, enable, and execute Zapier actions directly from your client.", category: "productivity", source: { source: "git-subdir", url: "https://github.com/zapier/zapier-mcp.git", path: "plugins/zapier", ref: "main", sha: "217d65a980f9b75536babf89ba64bf03ad95beea" }, homepage: "https://github.com/zapier/zapier-mcp/tree/main/plugins/zapier" }, { name: "zilliz", description: "Zilliz Cloud management plugin with 14 skills covering cluster lifecycle, collection schema, vector search, index tuning, bulk import, RBAC, backups, and monitoring.", author: { name: "Zilliz" }, category: "database", source: { source: "url", url: "https://github.com/zilliztech/zilliz-plugin.git", path: "plugins/zilliz", sha: "35c86c000c91abb35f3eeed5cca15ebd69cba4d5" }, homepage: "https://docs.zilliz.com" }, { name: "zocks-advisor", description: "Seven skills for financial advisors built on Zocks meeting intelligence: client behavioral profiles, attrition-risk ranking, held-away asset radar, client journey dossiers, household review packs, next-best-action analysis and a tax opportunity scan. Requires the Zocks connector and a Zocks account.", author: { name: "Zocks" }, category: "productivity", source: { source: "url", url: "https://github.com/zocks-communications/zocks-agent-plugins.git", sha: "a3e445c139665055c2f22f25c9a9f8721a7c6355" }, homepage: "https://github.com/zocks-communications/zocks-agent-plugins" }, { name: "zoom-plugin", description: "Claude plugin for planning, building, and debugging Zoom integrations across REST APIs, SDKs, webhooks, bots, and MCP workflows.", category: "development", source: { source: "url", url: "https://github.com/zoom/zoom-plugin.git", sha: "9311dd4b31e8e55c27b95479a84601576e449e97" }, homepage: "https://developers.zoom.us/" }, { name: "zoominfo", description: "Search companies and contacts, enrich leads, find lookalikes, and get AI-ranked contact recommendations. Pre-built skills chain multiple ZoomInfo tools into complete B2B sales workflows.", author: { name: "ZoomInfo" }, category: "productivity", source: { source: "url", url: "https://github.com/Zoominfo/zoominfo-mcp-plugin.git", sha: "d07402feb2b9967ccc118f55bacd41a79c822d6a" }, homepage: "https://www.zoominfo.com" }, { name: "zscaler", description: "Manage Zscaler cloud security platform including ZPA (private access), ZIA (internet access), ZDX (digital experience), ZCC (client connector), EASM (attack surface), and Z-Insights (analytics). Create and manage policies, troubleshoot connectivity, audit security configurations, and investigate incidents across the full Zscaler ecosystem.", author: { name: "Zscaler" }, category: "security", source: { source: "url", url: "https://github.com/zscaler/zscaler-mcp-server.git", sha: "809f68d6c921e0829fb2e07e9b797e7e70cf720b" }, homepage: "https://github.com/zscaler/zscaler-mcp-server" }, { name: "langfuse", description: "Skills for working with Langfuse, the open-source LLM engineering platform for tracing, prompt management, and evaluation.", author: { name: "Langfuse" }, category: "monitoring", source: { source: "url", url: "https://github.com/langfuse/skills.git", sha: "ab83111ed644c583a9ce963de773dbfbf09aebf3" }, homepage: "https://langfuse.com" }, { name: "zyte-web-data", description: "Web scraping skills for Claude Code powered by the Zyte API — scrape sites, generate and run Scrapy spiders, define extraction schemas, and ship to Scrapy Cloud.", author: { name: "Zyte" }, category: "automation", source: { source: "url", url: "https://github.com/zytedata/claude-skills.git", sha: "8b2d640fe82fadcb69c12af26e4e38ab8ab61ed1" }, homepage: "https://www.zyte.com" }, { name: "activecampaign", displayName: "ActiveCampaign", description: "Marketing automation, CRM, and email marketing powered by ActiveCampaign. Manage contacts, campaigns, automations, deals, and get AI-powered marketing insights — all from Claude.", author: { name: "ActiveCampaign" }, category: "productivity", source: { source: "url", url: "https://github.com/ActiveCampaign/activecampaign-plugin.git", sha: "0ff858728bc52aee335d5475b0d4eb5f3a9589b0" }, homepage: "https://www.activecampaign.com" }, { name: "hubspot-sales", displayName: "HubSpot Sales", description: "Run your HubSpot sales workflow directly from Claude. Adds skills that cover the full sales day: import contacts and deals into HubSpot, get a prioritised morning brief, prep for any call with full CRM context, draft personalised follow-ups grounded in deal history, log calls and update records by describing what happened, and review your pipeline to surface stalling deals. Everything writes back to HubSpot.", author: { name: "HubSpot" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/HubSpot/hubspot-mcp-plugins.git", path: "HubSpot-Sales", ref: "main", sha: "a0c59600fc1ddcf03ceca71aebf0c28aa55f49e3" }, homepage: "https://www.hubspot.com" }, { name: "dynatrace", displayName: "Dynatrace", description: "Dynatrace observability skills: DQL query patterns, application and infrastructure monitoring, log analysis, problem investigation, and incident response workflows, with the Dynatrace MCP server for live platform access.", author: { name: "Dynatrace" }, category: "monitoring", source: { source: "url", url: "https://github.com/Dynatrace/dynatrace-for-ai.git", sha: "9529e72715d96ab47738e8edf83d49798d0f8be5" }, homepage: "https://www.dynatrace.com/hub/detail/claude-code-cli/" }, { name: "wingspan", displayName: "Wingspan", description: "Ask Claude about the contractors you pay through Wingspan, what you owe them, and what is holding up a payment, then onboard contractors and log payments as drafts, with a preview before anything is written. Requires a Wingspan account; bundles the Wingspan MCP server (OAuth on first use).", author: { name: "Wingspan" }, category: "productivity", source: { source: "url", url: "https://github.com/wingspanHQ/mcp-claude-plugin.git", sha: "b989f3b303a1f605955291e34ed29b755bf436e1" }, homepage: "https://github.com/wingspanHQ/mcp-claude-plugin" }] } }
469196
+ ];
469197
+ });
469198
+
469199
+ // src/tui/utils/plugins/marketplaceSnapshotFallback.ts
469200
+ import {
469201
+ mkdir as mkdir54,
469202
+ readFile as readFile62,
469203
+ rm as rm11,
469204
+ writeFile as writeFile49
469205
+ } from "fs/promises";
469206
+ import { join as join173, resolve as resolve53, sep as sep41 } from "path";
469207
+ function getBuiltinSnapshotRoot() {
469208
+ return join173(getMarketplacesCacheDir(), "builtin-snapshots");
469209
+ }
469210
+ function getBuiltinSnapshotDir(marketplaceName) {
469211
+ return join173(getBuiltinSnapshotRoot(), marketplaceName);
469212
+ }
469213
+ function isBuiltinSnapshotEntry(entry) {
469214
+ if (!isLocalMarketplaceSource(entry.source))
469215
+ return false;
469216
+ if (entry.source.source !== "directory")
469217
+ return false;
469218
+ const root = resolve53(getBuiltinSnapshotRoot()) + sep41;
469219
+ return entry.installLocation.startsWith(root);
469220
+ }
469221
+ async function installBuiltinSnapshotFallback(marketplaceName) {
469222
+ const snapshot = getBuiltinMarketplaceSnapshot(marketplaceName);
469223
+ if (!snapshot) {
469224
+ logForDebugging3(`Snapshot fallback: no bundled snapshot for '${marketplaceName}'`);
469225
+ return { ok: false, reason: "no_snapshot" };
469226
+ }
469227
+ const snapshotDir = getBuiltinSnapshotDir(marketplaceName);
469228
+ const dirSource = { source: "directory", path: snapshotDir };
469229
+ if (!isSourceAllowedByPolicy(dirSource)) {
469230
+ logForDebugging3(`Snapshot fallback: '${marketplaceName}' blocked by enterprise policy`);
469231
+ return { ok: false, reason: "policy_blocked" };
469232
+ }
469233
+ try {
469234
+ await materializeSnapshot(snapshotDir, snapshot.manifest);
469235
+ await updateKnownMarketplacesConfig((known) => {
469236
+ known[marketplaceName] = {
469237
+ source: { source: "directory", path: snapshotDir },
469238
+ installLocation: snapshotDir,
469239
+ lastUpdated: new Date().toISOString()
469240
+ };
469241
+ return known;
469242
+ });
469243
+ logForDebugging3(`Snapshot fallback: materialized '${marketplaceName}' at ${snapshotDir}`);
469244
+ return { ok: true };
469245
+ } catch (error) {
469246
+ logForDebugging3(`Snapshot fallback: failed to materialize '${marketplaceName}': ${toError2(error).message}`, { level: "error" });
469247
+ return { ok: false, reason: "materialize_failed" };
469248
+ }
469249
+ }
469250
+ async function removeBuiltinSnapshotDir(marketplaceName) {
469251
+ try {
469252
+ await rm11(getBuiltinSnapshotDir(marketplaceName), {
469253
+ recursive: true,
469254
+ force: true
469255
+ });
469256
+ } catch {}
469257
+ }
469258
+ async function materializeSnapshot(snapshotDir, manifest) {
469259
+ const manifestDirName = getPluginManifestDirs()[0];
469260
+ const manifestPath = join173(snapshotDir, manifestDirName, "marketplace.json");
469261
+ await mkdir54(join173(snapshotDir, manifestDirName), { recursive: true });
469262
+ const content = jsonStringify5(manifest, null, 2);
469263
+ await writeFile49(manifestPath, content, { encoding: "utf-8" });
469264
+ const roundTrip = JSON.parse(await readFile62(manifestPath, "utf-8"));
469265
+ PluginMarketplaceSchema().parse(roundTrip);
469266
+ }
469267
+ var init_marketplaceSnapshotFallback = __esm(() => {
469268
+ init_configDir();
469269
+ init_debug();
469270
+ init_errors4();
469271
+ init_slowOperations();
469272
+ init_builtinMarketplaceSnapshots();
469273
+ init_marketplaceHelpers();
469274
+ init_marketplaceManager();
469275
+ init_schemas3();
469276
+ });
469277
+
469093
469278
  // src/tui/utils/plugins/officialMarketplaceStartupCheck.ts
469094
- import { join as join173 } from "path";
469279
+ import { join as join174 } from "path";
469095
469280
  function isOfficialMarketplaceAutoInstallDisabled() {
469096
469281
  return isEnvTruthy2(process.env.ATLAS_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL);
469097
469282
  }
@@ -469149,14 +469334,19 @@ async function checkAndInstallOfficialMarketplace() {
469149
469334
  return { installed: false, skipped: true, reason: "policy_blocked" };
469150
469335
  }
469151
469336
  const knownMarketplaces = await loadKnownMarketplacesConfig();
469152
- if (knownMarketplaces[OFFICIAL_MARKETPLACE_NAME]) {
469153
- logForDebugging3(`Official marketplace '${OFFICIAL_MARKETPLACE_NAME}' already installed, skipping`);
469154
- saveGlobalConfig((current) => ({
469155
- ...current,
469156
- officialMarketplaceAutoInstallAttempted: true,
469157
- officialMarketplaceAutoInstalled: true
469158
- }));
469159
- return { installed: false, skipped: true, reason: "already_installed" };
469337
+ const existingOfficial = knownMarketplaces[OFFICIAL_MARKETPLACE_NAME];
469338
+ if (existingOfficial) {
469339
+ if (isBuiltinSnapshotEntry(existingOfficial)) {
469340
+ logForDebugging3(`Official marketplace is a built-in snapshot entry — attempting live materialization`);
469341
+ } else {
469342
+ logForDebugging3(`Official marketplace '${OFFICIAL_MARKETPLACE_NAME}' already installed, skipping`);
469343
+ saveGlobalConfig((current) => ({
469344
+ ...current,
469345
+ officialMarketplaceAutoInstallAttempted: true,
469346
+ officialMarketplaceAutoInstalled: true
469347
+ }));
469348
+ return { installed: false, skipped: true, reason: "already_installed" };
469349
+ }
469160
469350
  }
469161
469351
  if (!isSourceAllowedByPolicy(OFFICIAL_MARKETPLACE_SOURCE)) {
469162
469352
  logForDebugging3("Official marketplace blocked by enterprise policy, skipping");
@@ -469169,16 +469359,18 @@ async function checkAndInstallOfficialMarketplace() {
469169
469359
  return { installed: false, skipped: true, reason: "policy_blocked" };
469170
469360
  }
469171
469361
  const cacheDir = getMarketplacesCacheDir();
469172
- const installLocation = join173(cacheDir, OFFICIAL_MARKETPLACE_NAME);
469362
+ const installLocation = join174(cacheDir, OFFICIAL_MARKETPLACE_NAME);
469173
469363
  const gcsSha = await fetchOfficialMarketplaceFromGcs(installLocation, cacheDir);
469174
469364
  if (gcsSha !== null) {
469175
- const known = await loadKnownMarketplacesConfig();
469176
- known[OFFICIAL_MARKETPLACE_NAME] = {
469177
- source: OFFICIAL_MARKETPLACE_SOURCE,
469178
- installLocation,
469179
- lastUpdated: new Date().toISOString()
469180
- };
469181
- await saveKnownMarketplacesConfig(known);
469365
+ await updateKnownMarketplacesConfig((known) => {
469366
+ known[OFFICIAL_MARKETPLACE_NAME] = {
469367
+ source: OFFICIAL_MARKETPLACE_SOURCE,
469368
+ installLocation,
469369
+ lastUpdated: new Date().toISOString()
469370
+ };
469371
+ return known;
469372
+ });
469373
+ await removeBuiltinSnapshotDir(OFFICIAL_MARKETPLACE_NAME);
469182
469374
  saveGlobalConfig((current) => ({
469183
469375
  ...current,
469184
469376
  officialMarketplaceAutoInstallAttempted: true,
@@ -469204,6 +469396,9 @@ async function checkAndInstallOfficialMarketplace() {
469204
469396
  officialMarketplaceAutoInstallLastAttemptTime: now,
469205
469397
  officialMarketplaceAutoInstallNextRetryTime: nextRetryTime
469206
469398
  }));
469399
+ const fallback = await tryOfficialSnapshotFallback("gcs_unavailable");
469400
+ if (fallback)
469401
+ return fallback;
469207
469402
  return { installed: false, skipped: true, reason: "gcs_unavailable" };
469208
469403
  }
469209
469404
  const gitAvailable = await checkGitAvailable();
@@ -469230,6 +469425,9 @@ async function checkAndInstallOfficialMarketplace() {
469230
469425
  logError3(configError);
469231
469426
  logForDebugging3(`Failed to save marketplace auto-install git_unavailable state: ${saveError}`, { level: "error" });
469232
469427
  }
469428
+ const fallback = await tryOfficialSnapshotFallback("git_unavailable");
469429
+ if (fallback)
469430
+ return fallback;
469233
469431
  return {
469234
469432
  installed: false,
469235
469433
  skipped: true,
@@ -469240,6 +469438,7 @@ async function checkAndInstallOfficialMarketplace() {
469240
469438
  logForDebugging3("Attempting to auto-install official marketplace");
469241
469439
  await addMarketplaceSource(OFFICIAL_MARKETPLACE_SOURCE);
469242
469440
  logForDebugging3("Successfully auto-installed official marketplace");
469441
+ await removeBuiltinSnapshotDir(OFFICIAL_MARKETPLACE_NAME);
469243
469442
  const previousRetryCount = config.officialMarketplaceAutoInstallRetryCount || 0;
469244
469443
  saveGlobalConfig((current) => ({
469245
469444
  ...current,
@@ -469256,6 +469455,9 @@ async function checkAndInstallOfficialMarketplace() {
469256
469455
  if (errorMessage.includes("xcrun: error:")) {
469257
469456
  markGitUnavailable();
469258
469457
  logForDebugging3("Official marketplace auto-install: git is a non-functional macOS xcrun shim, treating as git_unavailable");
469458
+ const fallback = await tryOfficialSnapshotFallback("git_unavailable");
469459
+ if (fallback)
469460
+ return fallback;
469259
469461
  return {
469260
469462
  installed: false,
469261
469463
  skipped: true,
@@ -469285,6 +469487,9 @@ async function checkAndInstallOfficialMarketplace() {
469285
469487
  logError3(configError);
469286
469488
  logForDebugging3(`Failed to save marketplace auto-install failure state: ${saveError}`, { level: "error" });
469287
469489
  }
469490
+ const fallback = await tryOfficialSnapshotFallback("unknown");
469491
+ if (fallback)
469492
+ return fallback;
469288
469493
  return {
469289
469494
  installed: false,
469290
469495
  skipped: true,
@@ -469293,6 +469498,18 @@ async function checkAndInstallOfficialMarketplace() {
469293
469498
  };
469294
469499
  }
469295
469500
  }
469501
+ async function tryOfficialSnapshotFallback(reason) {
469502
+ const result = await installBuiltinSnapshotFallback(OFFICIAL_MARKETPLACE_NAME);
469503
+ if (!result.ok)
469504
+ return null;
469505
+ logForDebugging3(`Official marketplace: live source unavailable (${reason}) — using built-in snapshot catalog`);
469506
+ return {
469507
+ installed: true,
469508
+ skipped: false,
469509
+ fallback: "builtin-snapshot",
469510
+ fallbackReason: reason
469511
+ };
469512
+ }
469296
469513
  var RETRY_CONFIG;
469297
469514
  var init_officialMarketplaceStartupCheck = __esm(() => {
469298
469515
  init_growthbook();
@@ -469304,6 +469521,7 @@ var init_officialMarketplaceStartupCheck = __esm(() => {
469304
469521
  init_gitAvailability();
469305
469522
  init_marketplaceHelpers();
469306
469523
  init_marketplaceManager();
469524
+ init_marketplaceSnapshotFallback();
469307
469525
  init_officialMarketplace();
469308
469526
  init_officialMarketplaceGcs();
469309
469527
  RETRY_CONFIG = {
@@ -469333,7 +469551,18 @@ async function _temp179() {
469333
469551
  timeoutMs: 1e4
469334
469552
  });
469335
469553
  }
469336
- if (result.installed) {
469554
+ if (result.fallback === "builtin-snapshot") {
469555
+ logForDebugging3("Showing marketplace snapshot-fallback notification");
469556
+ notifs.push({
469557
+ key: "marketplace-snapshot-fallback",
469558
+ jsx: /* @__PURE__ */ jsx_dev_runtime408.jsxDEV(ThemedText, {
469559
+ color: "warning",
469560
+ children: "官方插件源未就绪 · 已用内建快照目录(/plugin 可浏览插件清单)· 下次启动自动重试活同步"
469561
+ }, undefined, false, undefined, this),
469562
+ priority: "immediate",
469563
+ timeoutMs: 1e4
469564
+ });
469565
+ } else if (result.installed) {
469337
469566
  logForDebugging3("Showing marketplace installation success notification");
469338
469567
  notifs.push({
469339
469568
  key: "marketplace-installed",
@@ -469399,9 +469628,18 @@ async function checkAndInstallMarketplacePreset(config) {
469399
469628
  if (config.name) {
469400
469629
  try {
469401
469630
  const knownMarketplaces = await loadKnownMarketplacesConfig();
469402
- if (knownMarketplaces[config.name]) {
469403
- logForDebugging3(`${label} marketplace '${config.name}' already installed, skipping`);
469404
- return { installed: false, skipped: true, reason: "already_installed" };
469631
+ const existing = knownMarketplaces[config.name];
469632
+ if (existing) {
469633
+ if (isBuiltinSnapshotEntry(existing)) {
469634
+ logForDebugging3(`${label} marketplace '${config.name}' is a built-in snapshot entry — attempting live materialization`);
469635
+ } else {
469636
+ logForDebugging3(`${label} marketplace '${config.name}' already installed, skipping`);
469637
+ return {
469638
+ installed: false,
469639
+ skipped: true,
469640
+ reason: "already_installed"
469641
+ };
469642
+ }
469405
469643
  }
469406
469644
  } catch (error) {
469407
469645
  logForDebugging3(`${label} marketplace: failed to read known_marketplaces (${toError2(error).message}), attempting install`, { level: "error" });
@@ -469414,25 +469652,51 @@ async function checkAndInstallMarketplacePreset(config) {
469414
469652
  const gitAvailable = await checkGitAvailable();
469415
469653
  if (!gitAvailable) {
469416
469654
  logForDebugging3(`Git not available, skipping ${label} marketplace auto-install`);
469655
+ const fallback = await trySnapshotFallback(config, "git_unavailable");
469656
+ if (fallback)
469657
+ return fallback;
469417
469658
  return { installed: false, skipped: true, reason: "git_unavailable" };
469418
469659
  }
469419
469660
  try {
469420
469661
  logForDebugging3(`Attempting to auto-install ${label} marketplace`);
469421
469662
  await addMarketplaceSource(config.source);
469422
469663
  logForDebugging3(`Successfully auto-installed ${label} marketplace`);
469664
+ if (config.name) {
469665
+ await removeBuiltinSnapshotDir(config.name);
469666
+ }
469423
469667
  return { installed: true, skipped: false };
469424
469668
  } catch (error) {
469425
469669
  const errorMessage = error instanceof Error ? error.message : String(error);
469426
469670
  if (errorMessage.includes("xcrun: error:")) {
469427
469671
  markGitUnavailable();
469428
469672
  logForDebugging3(`${label} marketplace auto-install: git is a non-functional macOS xcrun shim, treating as git_unavailable`);
469673
+ const fallback = await trySnapshotFallback(config, "git_unavailable");
469674
+ if (fallback)
469675
+ return fallback;
469429
469676
  return { installed: false, skipped: true, reason: "git_unavailable" };
469430
469677
  }
469431
469678
  logForDebugging3(`Failed to auto-install ${label} marketplace: ${errorMessage}`, { level: "error" });
469432
469679
  logError3(toError2(error));
469680
+ const fallback = await trySnapshotFallback(config, "unknown");
469681
+ if (fallback)
469682
+ return fallback;
469433
469683
  return { installed: false, skipped: true, reason: "unknown" };
469434
469684
  }
469435
469685
  }
469686
+ async function trySnapshotFallback(config, reason) {
469687
+ if (!config.name)
469688
+ return null;
469689
+ const result = await installBuiltinSnapshotFallback(config.name);
469690
+ if (!result.ok)
469691
+ return null;
469692
+ logForDebugging3(`${config.displayName} marketplace: live source unavailable (${reason}) — using built-in snapshot catalog`);
469693
+ return {
469694
+ installed: true,
469695
+ skipped: false,
469696
+ fallback: "builtin-snapshot",
469697
+ fallbackReason: reason
469698
+ };
469699
+ }
469436
469700
  var init_marketplacePreset = __esm(() => {
469437
469701
  init_debug();
469438
469702
  init_envUtils2();
@@ -469441,6 +469705,7 @@ var init_marketplacePreset = __esm(() => {
469441
469705
  init_gitAvailability();
469442
469706
  init_marketplaceHelpers();
469443
469707
  init_marketplaceManager();
469708
+ init_marketplaceSnapshotFallback();
469444
469709
  });
469445
469710
 
469446
469711
  // src/tui/plugins/ascend/marketplace/ascendMarketplaceStartupCheck.ts
@@ -469490,7 +469755,21 @@ function useAscendMarketplaceNotification() {
469490
469755
  useStartupNotification(async () => {
469491
469756
  const result = await checkAndInstallAscendMarketplace();
469492
469757
  const notifs = [];
469493
- if (result.installed) {
469758
+ if (result.fallback === "builtin-snapshot") {
469759
+ logForDebugging3("Showing Ascend marketplace snapshot-fallback notification");
469760
+ notifs.push({
469761
+ key: "ascend-marketplace-snapshot-fallback",
469762
+ jsx: /* @__PURE__ */ jsx_dev_runtime409.jsxDEV(ThemedText, {
469763
+ color: "warning",
469764
+ children: [
469765
+ ASCEND_OFFICIAL_DISPLAY_LABEL,
469766
+ " 源未就绪 · 已用内建快照目录( /plugin 可浏览插件清单)· 下次启动自动重试活同步"
469767
+ ]
469768
+ }, undefined, true, undefined, this),
469769
+ priority: "immediate",
469770
+ timeoutMs: 1e4
469771
+ });
469772
+ } else if (result.installed) {
469494
469773
  logForDebugging3("Showing Ascend marketplace installation success notification");
469495
469774
  notifs.push({
469496
469775
  key: "ascend-marketplace-installed",
@@ -469573,7 +469852,21 @@ function useAtlasMarketplaceNotification() {
469573
469852
  useStartupNotification(async () => {
469574
469853
  const result = await checkAndInstallAtlasMarketplace();
469575
469854
  const notifs = [];
469576
- if (result.installed) {
469855
+ if (result.fallback === "builtin-snapshot") {
469856
+ logForDebugging3("Showing Atlas marketplace snapshot-fallback notification");
469857
+ notifs.push({
469858
+ key: "atlas-marketplace-snapshot-fallback",
469859
+ jsx: /* @__PURE__ */ jsx_dev_runtime410.jsxDEV(ThemedText, {
469860
+ color: "warning",
469861
+ children: [
469862
+ ATLAS_MARKETPLACE_DISPLAY_LABEL,
469863
+ " 源未就绪 · 已用内建快照目录( /plugin 可浏览插件清单)· 下次启动自动重试活同步"
469864
+ ]
469865
+ }, undefined, true, undefined, this),
469866
+ priority: "immediate",
469867
+ timeoutMs: 1e4
469868
+ });
469869
+ } else if (result.installed) {
469577
469870
  logForDebugging3("Showing Atlas marketplace installation success notification");
469578
469871
  notifs.push({
469579
469872
  key: "atlas-marketplace-installed",
@@ -470660,7 +470953,7 @@ var init_usePluginRecommendationBase = __esm(() => {
470660
470953
  });
470661
470954
 
470662
470955
  // src/tui/hooks/useLspPluginRecommendation.tsx
470663
- import { extname as extname19, join as join174 } from "path";
470956
+ import { extname as extname19, join as join175 } from "path";
470664
470957
  function useLspPluginRecommendation() {
470665
470958
  const $ = import_compiler_runtime310.c(12);
470666
470959
  const trackedFiles = useAppState(_temp184);
@@ -470745,7 +471038,7 @@ function useLspPluginRecommendation() {
470745
471038
  case "yes": {
470746
471039
  installPluginAndNotify(pluginId, pluginName, "lsp-plugin", addNotification, async (pluginData) => {
470747
471040
  logForDebugging3(`[useLspPluginRecommendation] Installing plugin: ${pluginId}`);
470748
- const localSourcePath = typeof pluginData.entry.source === "string" ? join174(pluginData.marketplaceInstallLocation, pluginData.entry.source) : undefined;
471041
+ const localSourcePath = typeof pluginData.entry.source === "string" ? join175(pluginData.marketplaceInstallLocation, pluginData.entry.source) : undefined;
470749
471042
  await cacheAndRegisterPlugin(pluginId, pluginData.entry, "user", undefined, localSourcePath);
470750
471043
  const settings = getSettingsForSource2("userSettings");
470751
471044
  updateSettingsForSource2("userSettings", {
@@ -471443,7 +471736,7 @@ var init_usePluginAutoupdateNotification = __esm(() => {
471443
471736
  });
471444
471737
 
471445
471738
  // src/tui/utils/plugins/reconciler.ts
471446
- import { isAbsolute as isAbsolute34, resolve as resolve53 } from "path";
471739
+ import { isAbsolute as isAbsolute34, resolve as resolve54 } from "path";
471447
471740
  function diffMarketplaces(declared, materialized, opts) {
471448
471741
  const missing = [];
471449
471742
  const sourceChanged = [];
@@ -471556,7 +471849,7 @@ function normalizeSource(source, projectRoot) {
471556
471849
  const canonicalRoot = findCanonicalGitRoot2(base);
471557
471850
  return {
471558
471851
  ...source,
471559
- path: resolve53(canonicalRoot ?? base, source.path)
471852
+ path: resolve54(canonicalRoot ?? base, source.path)
471560
471853
  };
471561
471854
  }
471562
471855
  return source;
@@ -474548,15 +474841,15 @@ var init_cronJitterConfig2 = __esm(() => {
474548
474841
  });
474549
474842
 
474550
474843
  // src/tui/utils/cronTasksLock.ts
474551
- import { mkdir as mkdir54, readFile as readFile62, unlink as unlink26, writeFile as writeFile49 } from "fs/promises";
474552
- import { dirname as dirname83, join as join175 } from "path";
474844
+ import { mkdir as mkdir55, readFile as readFile63, unlink as unlink26, writeFile as writeFile50 } from "fs/promises";
474845
+ import { dirname as dirname83, join as join176 } from "path";
474553
474846
  function getLockPath3(dir) {
474554
- return join175(dir ?? getProjectRoot(), LOCK_FILE_REL2);
474847
+ return join176(dir ?? getProjectRoot(), LOCK_FILE_REL2);
474555
474848
  }
474556
474849
  async function readLock3(dir) {
474557
474850
  let raw;
474558
474851
  try {
474559
- raw = await readFile62(getLockPath3(dir), "utf8");
474852
+ raw = await readFile63(getLockPath3(dir), "utf8");
474560
474853
  } catch {
474561
474854
  return;
474562
474855
  }
@@ -474567,16 +474860,16 @@ async function tryCreateExclusive3(lock, dir) {
474567
474860
  const path = getLockPath3(dir);
474568
474861
  const body = jsonStringify5(lock);
474569
474862
  try {
474570
- await writeFile49(path, body, { flag: "wx" });
474863
+ await writeFile50(path, body, { flag: "wx" });
474571
474864
  return true;
474572
474865
  } catch (e) {
474573
474866
  const code = getErrnoCode2(e);
474574
474867
  if (code === "EEXIST")
474575
474868
  return false;
474576
474869
  if (code === "ENOENT") {
474577
- await mkdir54(dirname83(path), { recursive: true });
474870
+ await mkdir55(dirname83(path), { recursive: true });
474578
474871
  try {
474579
- await writeFile49(path, body, { flag: "wx" });
474872
+ await writeFile50(path, body, { flag: "wx" });
474580
474873
  return true;
474581
474874
  } catch (retryErr) {
474582
474875
  if (getErrnoCode2(retryErr) === "EEXIST")
@@ -474610,7 +474903,7 @@ async function tryAcquireSchedulerLock2(opts) {
474610
474903
  const existing = await readLock3(dir);
474611
474904
  if (existing?.sessionId === sessionId) {
474612
474905
  if (existing.pid !== process.pid) {
474613
- await writeFile49(getLockPath3(dir), jsonStringify5(lock));
474906
+ await writeFile50(getLockPath3(dir), jsonStringify5(lock));
474614
474907
  registerLockCleanup3(opts);
474615
474908
  }
474616
474909
  return true;
@@ -474658,7 +474951,7 @@ var init_cronTasksLock2 = __esm(() => {
474658
474951
  init_genericProcessUtils();
474659
474952
  init_json2();
474660
474953
  init_slowOperations();
474661
- LOCK_FILE_REL2 = join175(getConfigDirName2(), "scheduled_tasks.lock");
474954
+ LOCK_FILE_REL2 = join176(getConfigDirName2(), "scheduled_tasks.lock");
474662
474955
  schedulerLockSchema2 = lazySchema2(() => object({
474663
474956
  sessionId: string2(),
474664
474957
  pid: number2(),
@@ -475003,9 +475296,9 @@ var init_useScheduledTasks = __esm(() => {
475003
475296
 
475004
475297
  // src/tui/screens/REPL.tsx
475005
475298
  import { spawnSync as spawnSync7 } from "child_process";
475006
- import { dirname as dirname84, join as join176 } from "path";
475299
+ import { dirname as dirname84, join as join177 } from "path";
475007
475300
  import { tmpdir as tmpdir12 } from "os";
475008
- import { writeFile as writeFile50 } from "fs/promises";
475301
+ import { writeFile as writeFile51 } from "fs/promises";
475009
475302
  import { randomUUID as randomUUID53 } from "crypto";
475010
475303
  function _useMoreRightStub(_args) {
475011
475304
  return {
@@ -477564,8 +477857,8 @@ Note: ctrl + z now suspends AtlasCode, ctrl + _ undoes input.
477564
477857
  const w = Math.max(80, (process.stdout.columns ?? 80) - 6);
477565
477858
  const raw = await renderMessagesToPlainText(deferredMessages, tools, w);
477566
477859
  const text = raw.replace(/[ \t]+$/gm, "");
477567
- const path = join176(tmpdir12(), `cc-transcript-${Date.now()}.txt`);
477568
- await writeFile50(path, text);
477860
+ const path = join177(tmpdir12(), `cc-transcript-${Date.now()}.txt`);
477861
+ await writeFile51(path, text);
477569
477862
  const opened = openFileInExternalEditor(path);
477570
477863
  setStatus(opened ? `opening ${path}` : `wrote ${path} · no $VISUAL/$EDITOR set`);
477571
477864
  } catch (e) {
@@ -484310,7 +484603,7 @@ var init_bundled = __esm(() => {
484310
484603
  // src/tui/utils/deepLink/banner.ts
484311
484604
  import { stat as stat53 } from "fs/promises";
484312
484605
  import { homedir as homedir44 } from "os";
484313
- import { join as join177, sep as sep41 } from "path";
484606
+ import { join as join178, sep as sep42 } from "path";
484314
484607
  function buildDeepLinkBanner(info) {
484315
484608
  const lines = [
484316
484609
  `This session was opened by an external deep link in ${tildify(info.cwd)}`
@@ -484332,8 +484625,8 @@ async function readLastFetchTime(cwd) {
484332
484625
  return;
484333
484626
  const commonDir = await getCommonDir2(gitDir);
484334
484627
  const [local, common] = await Promise.all([
484335
- mtimeOrUndefined(join177(gitDir, "FETCH_HEAD")),
484336
- commonDir ? mtimeOrUndefined(join177(commonDir, "FETCH_HEAD")) : Promise.resolve(undefined)
484628
+ mtimeOrUndefined(join178(gitDir, "FETCH_HEAD")),
484629
+ commonDir ? mtimeOrUndefined(join178(commonDir, "FETCH_HEAD")) : Promise.resolve(undefined)
484337
484630
  ]);
484338
484631
  if (local && common)
484339
484632
  return local > common ? local : common;
@@ -484351,7 +484644,7 @@ function tildify(p) {
484351
484644
  const home = homedir44();
484352
484645
  if (p === home)
484353
484646
  return "~";
484354
- if (p.startsWith(home + sep41))
484647
+ if (p.startsWith(home + sep42))
484355
484648
  return "~" + p.slice(home.length);
484356
484649
  return p;
484357
484650
  }
@@ -484692,7 +484985,7 @@ function eagerParseCliFlag2(flagName, argv = process.argv) {
484692
484985
  }
484693
484986
 
484694
484987
  // src/tui/utils/memoryFileMigration.ts
484695
- import { join as join178 } from "path";
484988
+ import { join as join179 } from "path";
484696
484989
  function migrateMemoryFiles(opts) {
484697
484990
  const fsImpl = opts?.fs ?? getFsImplementation2();
484698
484991
  const dirs = opts?.dirs ?? [getCwd(), getAtlasConfigHomeDir3(), getManagedFilePath()];
@@ -484704,8 +484997,8 @@ function migrateMemoryFiles(opts) {
484704
484997
  for (const dir of dirs) {
484705
484998
  for (const [oldName, newName] of migrations) {
484706
484999
  try {
484707
- const oldPath = join178(dir, oldName);
484708
- const newPath = join178(dir, newName);
485000
+ const oldPath = join179(dir, oldName);
485001
+ const newPath = join179(dir, newName);
484709
485002
  if (fsImpl.existsSync(oldPath) && !fsImpl.existsSync(newPath)) {
484710
485003
  fsImpl.renameSync(oldPath, newPath);
484711
485004
  logForDebugging3(`[STARTUP] Migrated memory file ${oldPath} -> ${newPath}`);
@@ -485291,12 +485584,12 @@ var init_protocolHandler = __esm(() => {
485291
485584
  });
485292
485585
 
485293
485586
  // src/tui/utils/errorLogSink.ts
485294
- import { dirname as dirname86, join as join179 } from "path";
485587
+ import { dirname as dirname86, join as join180 } from "path";
485295
485588
  function getErrorsPath() {
485296
- return join179(CACHE_PATHS.errors(), DATE + ".jsonl");
485589
+ return join180(CACHE_PATHS.errors(), DATE + ".jsonl");
485297
485590
  }
485298
485591
  function getMCPLogsPath(serverName) {
485299
- return join179(CACHE_PATHS.mcpLogs(serverName), DATE + ".jsonl");
485592
+ return join180(CACHE_PATHS.mcpLogs(serverName), DATE + ".jsonl");
485300
485593
  }
485301
485594
  function createJsonlWriter(options) {
485302
485595
  const writer = createBufferedWriter(options);
@@ -485434,12 +485727,12 @@ var init_sinks = __esm(() => {
485434
485727
  });
485435
485728
 
485436
485729
  // src/tui/utils/computerUse/setup.ts
485437
- import { join as join180 } from "path";
485730
+ import { join as join181 } from "path";
485438
485731
  import { fileURLToPath as fileURLToPath5 } from "url";
485439
485732
  function setupComputerUseMCP() {
485440
485733
  const allowedTools = buildComputerUseTools(CLI_CU_CAPABILITIES, getChicagoCoordinateMode()).map((t) => buildMcpToolName3(COMPUTER_USE_MCP_SERVER_NAME, t.name));
485441
485734
  const args = isInBundledMode2() ? ["--computer-use-mcp"] : [
485442
- join180(fileURLToPath5(import.meta.url), "..", "cli.js"),
485735
+ join181(fileURLToPath5(import.meta.url), "..", "cli.js"),
485443
485736
  "--computer-use-mcp"
485444
485737
  ];
485445
485738
  return {
@@ -485462,7 +485755,7 @@ var init_setup3 = __esm(() => {
485462
485755
  });
485463
485756
 
485464
485757
  // src/tui/services/SessionMemory/sessionMemory.ts
485465
- import { writeFile as writeFile51 } from "fs/promises";
485758
+ import { writeFile as writeFile52 } from "fs/promises";
485466
485759
  function isSessionMemoryGateEnabled() {
485467
485760
  return getFeatureValue_CACHED_MAY_BE_STALE("atlas_session_memory", false);
485468
485761
  }
@@ -485516,13 +485809,13 @@ async function setupSessionMemoryFile(toolUseContext) {
485516
485809
  await fs.mkdir(sessionMemoryDir, { mode: 448 });
485517
485810
  const memoryPath = getSessionMemoryPath();
485518
485811
  try {
485519
- await writeFile51(memoryPath, "", {
485812
+ await writeFile52(memoryPath, "", {
485520
485813
  encoding: "utf-8",
485521
485814
  mode: 384,
485522
485815
  flag: "wx"
485523
485816
  });
485524
485817
  const template = await loadSessionMemoryTemplate();
485525
- await writeFile51(memoryPath, template, {
485818
+ await writeFile52(memoryPath, template, {
485526
485819
  encoding: "utf-8",
485527
485820
  mode: 384
485528
485821
  });
@@ -485640,7 +485933,7 @@ var init_sessionMemory2 = __esm(() => {
485640
485933
  // src/tui/utils/iTermBackup.ts
485641
485934
  import { copyFile as copyFile10, stat as stat54 } from "fs/promises";
485642
485935
  import { homedir as homedir46 } from "os";
485643
- import { join as join181 } from "path";
485936
+ import { join as join182 } from "path";
485644
485937
  function markITerm2SetupComplete() {
485645
485938
  saveGlobalConfig((current) => ({
485646
485939
  ...current,
@@ -485655,7 +485948,7 @@ function getIterm2RecoveryInfo() {
485655
485948
  };
485656
485949
  }
485657
485950
  function getITerm2PlistPath() {
485658
- return join181(homedir46(), "Library", "Preferences", "com.googlecode.iterm2.plist");
485951
+ return join182(homedir46(), "Library", "Preferences", "com.googlecode.iterm2.plist");
485659
485952
  }
485660
485953
  async function checkAndRestoreITerm2Backup() {
485661
485954
  const { inProgress, backupPath } = getIterm2RecoveryInfo();
@@ -486698,16 +486991,16 @@ var init_mcp8 = __esm(() => {
486698
486991
  });
486699
486992
 
486700
486993
  // src/tui/utils/atlasDesktop.ts
486701
- import { readdir as readdir34, readFile as readFile63, stat as stat55 } from "fs/promises";
486994
+ import { readdir as readdir34, readFile as readFile64, stat as stat55 } from "fs/promises";
486702
486995
  import { homedir as homedir47 } from "os";
486703
- import { join as join182 } from "path";
486996
+ import { join as join183 } from "path";
486704
486997
  async function getDesktopConfigPath() {
486705
486998
  const platform = getPlatform3();
486706
486999
  if (!SUPPORTED_PLATFORMS2.includes(platform)) {
486707
487000
  throw new Error(`Unsupported platform: ${platform} - Claude Desktop integration only works on macOS and WSL.`);
486708
487001
  }
486709
487002
  if (platform === "macos") {
486710
- return join182(homedir47(), "Library", "Application Support", "AtlasCode", "claude_desktop_config.json");
487003
+ return join183(homedir47(), "Library", "Application Support", "AtlasCode", "claude_desktop_config.json");
486711
487004
  }
486712
487005
  const windowsHome = process.env.USERPROFILE ? process.env.USERPROFILE.replace(/\\/g, "/") : null;
486713
487006
  if (windowsHome) {
@@ -486726,7 +487019,7 @@ async function getDesktopConfigPath() {
486726
487019
  if (user.name === "Public" || user.name === "Default" || user.name === "Default User" || user.name === "All Users") {
486727
487020
  continue;
486728
487021
  }
486729
- const potentialConfigPath = join182(usersDir, user.name, "AppData", "Roaming", "AtlasCode", "claude_desktop_config.json");
487022
+ const potentialConfigPath = join183(usersDir, user.name, "AppData", "Roaming", "AtlasCode", "claude_desktop_config.json");
486730
487023
  try {
486731
487024
  await stat55(potentialConfigPath);
486732
487025
  return potentialConfigPath;
@@ -486746,7 +487039,7 @@ async function readDesktopMcpServers() {
486746
487039
  const configPath = await getDesktopConfigPath();
486747
487040
  let configContent;
486748
487041
  try {
486749
- configContent = await readFile63(configPath, { encoding: "utf8" });
487042
+ configContent = await readFile64(configPath, { encoding: "utf8" });
486750
487043
  } catch (e) {
486751
487044
  const code = getErrnoCode2(e);
486752
487045
  if (code === "ENOENT") {
@@ -487181,13 +487474,13 @@ var init_auth6 = __esm(() => {
487181
487474
  });
487182
487475
 
487183
487476
  // src/tui/utils/plugins/marketplacePublish.ts
487184
- import { cp, mkdir as mkdir55, readFile as readFile64, rm as rm11, writeFile as writeFile52 } from "fs/promises";
487477
+ import { cp, mkdir as mkdir56, readFile as readFile65, rm as rm12, writeFile as writeFile53 } from "fs/promises";
487185
487478
  import {
487186
487479
  dirname as dirname87,
487187
- join as join183,
487480
+ join as join184,
487188
487481
  relative as relative38,
487189
- resolve as resolve54,
487190
- sep as sep42
487482
+ resolve as resolve55,
487483
+ sep as sep43
487191
487484
  } from "path";
487192
487485
  function git(marketplaceDir, args, timeoutMs = 2 * 60 * 1000) {
487193
487486
  return execFileNoThrowWithCwd2("git", args, {
@@ -487199,16 +487492,16 @@ function gitFailureMessage(res) {
487199
487492
  return (res.stderr || res.error || `exit code ${res.code}`).trim();
487200
487493
  }
487201
487494
  async function publishPluginToMarketplace(opts) {
487202
- const pluginDir = resolve54(opts.pluginDir);
487203
- const marketplaceDir = resolve54(opts.marketplaceDir);
487495
+ const pluginDir = resolve55(opts.pluginDir);
487496
+ const marketplaceDir = resolve55(opts.marketplaceDir);
487204
487497
  const notes = [];
487205
- if (pluginDir === marketplaceDir || pluginDir.startsWith(marketplaceDir + sep42)) {
487498
+ if (pluginDir === marketplaceDir || pluginDir.startsWith(marketplaceDir + sep43)) {
487206
487499
  throw new Error(`Cannot publish "${pluginDir}": the plugin directory must not live inside the target marketplace (${marketplaceDir})`);
487207
487500
  }
487208
487501
  const pluginManifestPath = findManifestInDir(pluginDir, "plugin.json");
487209
487502
  let pluginManifestRaw;
487210
487503
  try {
487211
- pluginManifestRaw = await readFile64(pluginManifestPath, {
487504
+ pluginManifestRaw = await readFile65(pluginManifestPath, {
487212
487505
  encoding: "utf-8"
487213
487506
  });
487214
487507
  } catch {
@@ -487226,14 +487519,14 @@ async function publishPluginToMarketplace(opts) {
487226
487519
  }
487227
487520
  const name = manifest.name;
487228
487521
  const version = opts.version ?? (typeof manifest.version === "string" ? manifest.version : undefined);
487229
- const targetDir = join183(marketplaceDir, "plugins", name);
487230
- await rm11(targetDir, { recursive: true, force: true });
487231
- await mkdir55(dirname87(targetDir), { recursive: true });
487522
+ const targetDir = join184(marketplaceDir, "plugins", name);
487523
+ await rm12(targetDir, { recursive: true, force: true });
487524
+ await mkdir56(dirname87(targetDir), { recursive: true });
487232
487525
  await cp(pluginDir, targetDir, { recursive: true });
487233
487526
  const marketplaceManifestPath = findManifestInDir(marketplaceDir, "marketplace.json");
487234
487527
  let marketplaceRaw;
487235
487528
  try {
487236
- marketplaceRaw = await readFile64(marketplaceManifestPath, {
487529
+ marketplaceRaw = await readFile65(marketplaceManifestPath, {
487237
487530
  encoding: "utf-8"
487238
487531
  });
487239
487532
  } catch {
@@ -487260,7 +487553,7 @@ async function publishPluginToMarketplace(opts) {
487260
487553
  } else {
487261
487554
  pluginsList.push(entry);
487262
487555
  }
487263
- await writeFile52(marketplaceManifestPath, jsonStringify5(marketplaceDoc, null, 2) + `
487556
+ await writeFile53(marketplaceManifestPath, jsonStringify5(marketplaceDoc, null, 2) + `
487264
487557
  `, "utf-8");
487265
487558
  const marketplaceCheck = await validateMarketplaceManifest(marketplaceManifestPath);
487266
487559
  if (!marketplaceCheck.success) {
@@ -487330,13 +487623,13 @@ var init_marketplacePublish = __esm(() => {
487330
487623
  // src/tui/utils/plugins/marketplaceScaffold.ts
487331
487624
  import { userInfo as userInfo2 } from "os";
487332
487625
  import { existsSync as existsSync15 } from "fs";
487333
- import { mkdir as mkdir56, writeFile as writeFile53 } from "fs/promises";
487334
- import { dirname as dirname88, join as join184, resolve as resolve55 } from "path";
487626
+ import { mkdir as mkdir57, writeFile as writeFile54 } from "fs/promises";
487627
+ import { dirname as dirname88, join as join185, resolve as resolve56 } from "path";
487335
487628
  async function scaffoldMarketplace(opts) {
487336
- const targetDir = resolve55(opts.targetDir);
487629
+ const targetDir = resolve56(opts.targetDir);
487337
487630
  const name = opts.name.trim();
487338
487631
  const manifestDirName = getPluginManifestDirs()[0];
487339
- const marketplaceManifestPath = join184(targetDir, manifestDirName, "marketplace.json");
487632
+ const marketplaceManifestPath = join185(targetDir, manifestDirName, "marketplace.json");
487340
487633
  if (existsSync15(marketplaceManifestPath)) {
487341
487634
  throw new Error(`Marketplace manifest already exists at ${marketplaceManifestPath} — refusing to overwrite (delete it and re-run to re-scaffold)`);
487342
487635
  }
@@ -487378,19 +487671,19 @@ async function scaffoldMarketplace(opts) {
487378
487671
  }
487379
487672
  const files = [];
487380
487673
  const write = async (relPath, content) => {
487381
- const abs = join184(targetDir, relPath);
487382
- await mkdir56(dirname88(abs), { recursive: true });
487383
- await writeFile53(abs, content, "utf-8");
487674
+ const abs = join185(targetDir, relPath);
487675
+ await mkdir57(dirname88(abs), { recursive: true });
487676
+ await writeFile54(abs, content, "utf-8");
487384
487677
  files.push(relPath);
487385
487678
  };
487386
- await write(join184(manifestDirName, "marketplace.json"), jsonStringify5(marketplaceDoc, null, 2) + `
487679
+ await write(join185(manifestDirName, "marketplace.json"), jsonStringify5(marketplaceDoc, null, 2) + `
487387
487680
  `);
487388
487681
  if (includeExamplePlugin && pluginManifestDoc) {
487389
- await write(join184("plugins", EXAMPLE_PLUGIN, manifestDirName, "plugin.json"), jsonStringify5(pluginManifestDoc, null, 2) + `
487682
+ await write(join185("plugins", EXAMPLE_PLUGIN, manifestDirName, "plugin.json"), jsonStringify5(pluginManifestDoc, null, 2) + `
487390
487683
  `);
487391
- await write(join184("plugins", EXAMPLE_PLUGIN, "commands", "example.md"), EXAMPLE_COMMAND_MD);
487684
+ await write(join185("plugins", EXAMPLE_PLUGIN, "commands", "example.md"), EXAMPLE_COMMAND_MD);
487392
487685
  if (includeSkillPack) {
487393
- await write(join184("plugins", EXAMPLE_PLUGIN, "skills", "example-skill", "SKILL.md"), EXAMPLE_SKILL_MD);
487686
+ await write(join185("plugins", EXAMPLE_PLUGIN, "skills", "example-skill", "SKILL.md"), EXAMPLE_SKILL_MD);
487394
487687
  }
487395
487688
  }
487396
487689
  return { targetDir, marketplaceManifestPath, files };
@@ -487419,7 +487712,7 @@ var init_marketplaceScaffold = __esm(() => {
487419
487712
  });
487420
487713
 
487421
487714
  // src/tui/cli/handlers/plugins.ts
487422
- import { basename as basename65, dirname as dirname89, resolve as resolve56 } from "path";
487715
+ import { basename as basename65, dirname as dirname89, resolve as resolve57 } from "path";
487423
487716
  function handleMarketplaceError(error, action) {
487424
487717
  logError3(error);
487425
487718
  cliError2(`${figures_default.cross} Failed to ${action}: ${errorMessage2(error)}`);
@@ -487771,7 +488064,7 @@ async function marketplaceUpdateHandler(name, options) {
487771
488064
  async function marketplaceScaffoldHandler(options) {
487772
488065
  if (options.cowork)
487773
488066
  setUseCoworkPlugins(true);
487774
- const targetDir = resolve56(options.target ?? process.cwd());
488067
+ const targetDir = resolve57(options.target ?? process.cwd());
487775
488068
  try {
487776
488069
  const result = await scaffoldMarketplace({
487777
488070
  name: options.name,
@@ -487796,8 +488089,8 @@ async function marketplacePublishHandler(options) {
487796
488089
  setUseCoworkPlugins(true);
487797
488090
  try {
487798
488091
  const result = await publishPluginToMarketplace({
487799
- pluginDir: resolve56(options.plugin),
487800
- marketplaceDir: resolve56(options.marketplace),
488092
+ pluginDir: resolve57(options.plugin),
488093
+ marketplaceDir: resolve57(options.marketplace),
487801
488094
  version: options.version,
487802
488095
  push: options.push
487803
488096
  });
@@ -487954,12 +488247,12 @@ var init_plugins = __esm(() => {
487954
488247
 
487955
488248
  // src/tui/commands/install.tsx
487956
488249
  import { homedir as homedir48 } from "node:os";
487957
- import { join as join185 } from "node:path";
488250
+ import { join as join186 } from "node:path";
487958
488251
  function getInstallationPath2() {
487959
488252
  const isWindows = env5.platform === "win32";
487960
488253
  const homeDir = homedir48();
487961
488254
  if (isWindows) {
487962
- const windowsPath = join185(homeDir, ".local", "bin", "atlas.exe");
488255
+ const windowsPath = join186(homeDir, ".local", "bin", "atlas.exe");
487963
488256
  return windowsPath.replace(/\//g, "\\");
487964
488257
  }
487965
488258
  return "~/.local/bin/atlas";
@@ -488591,37 +488884,37 @@ var init_autoMode3 = __esm(() => {
488591
488884
 
488592
488885
  // src/tui/utils/completionCache.ts
488593
488886
  import { homedir as homedir49 } from "os";
488594
- import { dirname as dirname90, join as join186 } from "path";
488887
+ import { dirname as dirname90, join as join187 } from "path";
488595
488888
  function detectShell() {
488596
488889
  const shell = process.env.SHELL || "";
488597
488890
  const home = homedir49();
488598
- const claudeDir = join186(home, getConfigDirName2());
488891
+ const claudeDir = join187(home, getConfigDirName2());
488599
488892
  if (shell.endsWith("/zsh") || shell.endsWith("/zsh.exe")) {
488600
- const cacheFile = join186(claudeDir, "completion.zsh");
488893
+ const cacheFile = join187(claudeDir, "completion.zsh");
488601
488894
  return {
488602
488895
  name: "zsh",
488603
- rcFile: join186(home, ".zshrc"),
488896
+ rcFile: join187(home, ".zshrc"),
488604
488897
  cacheFile,
488605
488898
  completionLine: `[[ -f "${cacheFile}" ]] && source "${cacheFile}"`,
488606
488899
  shellFlag: "zsh"
488607
488900
  };
488608
488901
  }
488609
488902
  if (shell.endsWith("/bash") || shell.endsWith("/bash.exe")) {
488610
- const cacheFile = join186(claudeDir, "completion.bash");
488903
+ const cacheFile = join187(claudeDir, "completion.bash");
488611
488904
  return {
488612
488905
  name: "bash",
488613
- rcFile: join186(home, ".bashrc"),
488906
+ rcFile: join187(home, ".bashrc"),
488614
488907
  cacheFile,
488615
488908
  completionLine: `[ -f "${cacheFile}" ] && source "${cacheFile}"`,
488616
488909
  shellFlag: "bash"
488617
488910
  };
488618
488911
  }
488619
488912
  if (shell.endsWith("/fish") || shell.endsWith("/fish.exe")) {
488620
- const xdg = process.env.XDG_CONFIG_HOME || join186(home, ".config");
488621
- const cacheFile = join186(claudeDir, "completion.fish");
488913
+ const xdg = process.env.XDG_CONFIG_HOME || join187(home, ".config");
488914
+ const cacheFile = join187(claudeDir, "completion.fish");
488622
488915
  return {
488623
488916
  name: "fish",
488624
- rcFile: join186(xdg, "fish", "config.fish"),
488917
+ rcFile: join187(xdg, "fish", "config.fish"),
488625
488918
  cacheFile,
488626
488919
  completionLine: `[ -f "${cacheFile}" ] && source "${cacheFile}"`,
488627
488920
  shellFlag: "fish"
@@ -489013,7 +489306,7 @@ var init_update2 = __esm(() => {
489013
489306
 
489014
489307
  // src/tui/main.tsx
489015
489308
  import { readFileSync as readFileSync25 } from "fs";
489016
- import { resolve as resolve57 } from "path";
489309
+ import { resolve as resolve58 } from "path";
489017
489310
  function logManagedSettings() {
489018
489311
  try {
489019
489312
  const policySettings = getSettingsForSource2("policySettings");
@@ -489580,12 +489873,12 @@ ${getTmuxInstallInstructions3()}
489580
489873
  process.exit(1);
489581
489874
  }
489582
489875
  try {
489583
- const filePath = resolve57(options.systemPromptFile);
489876
+ const filePath = resolve58(options.systemPromptFile);
489584
489877
  systemPrompt = readFileSync25(filePath, "utf8");
489585
489878
  } catch (error) {
489586
489879
  const code = getErrnoCode2(error);
489587
489880
  if (code === "ENOENT") {
489588
- process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve57(options.systemPromptFile)}
489881
+ process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve58(options.systemPromptFile)}
489589
489882
  `));
489590
489883
  process.exit(1);
489591
489884
  }
@@ -489602,12 +489895,12 @@ ${getTmuxInstallInstructions3()}
489602
489895
  process.exit(1);
489603
489896
  }
489604
489897
  try {
489605
- const filePath = resolve57(options.appendSystemPromptFile);
489898
+ const filePath = resolve58(options.appendSystemPromptFile);
489606
489899
  appendSystemPrompt = readFileSync25(filePath, "utf8");
489607
489900
  } catch (error) {
489608
489901
  const code = getErrnoCode2(error);
489609
489902
  if (code === "ENOENT") {
489610
- process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve57(options.appendSystemPromptFile)}
489903
+ process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve58(options.appendSystemPromptFile)}
489611
489904
  `));
489612
489905
  process.exit(1);
489613
489906
  }
@@ -489657,7 +489950,7 @@ ${addendum}` : addendum;
489657
489950
  errors = result.errors;
489658
489951
  }
489659
489952
  } else {
489660
- const configPath = resolve57(configItem);
489953
+ const configPath = resolve58(configItem);
489661
489954
  const result = parseMcpConfigFromFilePath({
489662
489955
  filePath: configPath,
489663
489956
  expandVars: true,