@atlasharness/atlascode 0.1.44 → 0.1.46

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 +928 -971
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -31975,9 +31975,6 @@ function setQuestionPreviewFormat(f) {
31975
31975
  function getQuestionPreviewFormat() {
31976
31976
  return _questionPreviewFormat;
31977
31977
  }
31978
- function setSessionSource(s) {
31979
- _sessionSource = s;
31980
- }
31981
31978
  function setSessionBypassPermissionsMode(v) {
31982
31979
  _sessionBypassPermissionsMode = v;
31983
31980
  }
@@ -32079,7 +32076,7 @@ function setTrustAccepted(accepted) {
32079
32076
  function hasTrustAccepted() {
32080
32077
  return _trustAccepted;
32081
32078
  }
32082
- var _originalCwd2, _cwdState, _sessionId2, _isNonInteractiveSession = false, _clientType, _questionPreviewFormat, _sessionSource, _sessionBypassPermissionsMode = false, _sessionPersistenceDisabled = false, _flagSettingsPath, _allowedSettingSources, _costState, sessionCreatedTeams, _transcriptDir, _mainThreadAgentType, _trustAccepted = true;
32079
+ var _originalCwd2, _cwdState, _sessionId2, _isNonInteractiveSession = false, _clientType, _questionPreviewFormat, _sessionBypassPermissionsMode = false, _sessionPersistenceDisabled = false, _flagSettingsPath, _allowedSettingSources, _costState, sessionCreatedTeams, _transcriptDir, _mainThreadAgentType, _trustAccepted = true;
32083
32080
  var init_state = __esm(() => {
32084
32081
  init_shared();
32085
32082
  _originalCwd2 = process.cwd();
@@ -84065,8 +84062,7 @@ async function main() {
84065
84062
  const cliArgs = process.argv.slice(2);
84066
84063
  const hasPrintFlag = cliArgs.includes("-p") || cliArgs.includes("--print");
84067
84064
  const hasInitOnlyFlag = cliArgs.includes("--init-only");
84068
- const hasSdkUrl = cliArgs.some((arg) => arg.startsWith("--sdk-url"));
84069
- const isNonInteractive = hasPrintFlag || hasInitOnlyFlag || hasSdkUrl || !process.stdout.isTTY;
84065
+ const isNonInteractive = hasPrintFlag || hasInitOnlyFlag || !process.stdout.isTTY;
84070
84066
  const isInteractive = !isNonInteractive;
84071
84067
  setIsInteractive(isInteractive);
84072
84068
  initializeEntrypoint(isNonInteractive);
@@ -84098,9 +84094,6 @@ async function main() {
84098
84094
  } else if (!clientType.startsWith("sdk-") && clientType !== "claude-desktop" && clientType !== "local-agent" && clientType !== "remote") {
84099
84095
  setQuestionPreviewFormat("markdown");
84100
84096
  }
84101
- if (process.env.ATLAS_ENVIRONMENT_KIND === "bridge") {
84102
- setSessionSource("remote-control");
84103
- }
84104
84097
  eagerLoadSettings();
84105
84098
  await runCli();
84106
84099
  }
@@ -85217,9 +85210,6 @@ function extractUserText(message) {
85217
85210
  return "";
85218
85211
  }
85219
85212
  function createStructuredIO(inputPrompt, options) {
85220
- if (options.sdkUrl) {
85221
- throw new Error("--sdk-url is not available in this build (cloud transport cut; see cli 域裁登记)");
85222
- }
85223
85213
  const inputStream = typeof inputPrompt === "string" ? fromArray([]) : inputPrompt;
85224
85214
  return new StructuredIO(inputStream, options.replayUserMessages);
85225
85215
  }
@@ -85320,8 +85310,7 @@ async function runHeadless(inputPrompt, options) {
85320
85310
  process.exit(1);
85321
85311
  }
85322
85312
  const hasValidResumeSessionId = typeof options.resume === "string" && (validateUuidLocal(options.resume) || options.resume.endsWith(".jsonl"));
85323
- const isUsingSdkUrl = Boolean(options.sdkUrl);
85324
- if (!inputPrompt && !hasValidResumeSessionId && !isUsingSdkUrl) {
85313
+ if (!inputPrompt && !hasValidResumeSessionId) {
85325
85314
  process.stderr.write(`Error: Input must be provided either through stdin or as a prompt argument when using --print
85326
85315
  `);
85327
85316
  process.exit(1);
@@ -85332,7 +85321,6 @@ async function runHeadless(inputPrompt, options) {
85332
85321
  process.exit(1);
85333
85322
  }
85334
85323
  const structuredIO = createStructuredIO(inputPrompt, {
85335
- sdkUrl: options.sdkUrl,
85336
85324
  replayUserMessages: options.replayUserMessages
85337
85325
  });
85338
85326
  if (options.outputFormat === "stream-json") {
@@ -85351,7 +85339,7 @@ async function runHeadless(inputPrompt, options) {
85351
85339
  const mcpConnections = await buildMcpEngineConnectionsLocal(mcpManager);
85352
85340
  const mcpTools = createMcpTools(mcpConnections);
85353
85341
  syncMcpClientRegistryLocal(mcpManager);
85354
- const hasPromptRoute = isUsingSdkUrl || options.permissionPromptToolName === "stdio";
85342
+ const hasPromptRoute = options.permissionPromptToolName === "stdio";
85355
85343
  const role = options.model ? modelToRole(options.model) : "premium";
85356
85344
  const roleModel = getRoleModel(role);
85357
85345
  logForDebugging2(modelLine(role, options.model ?? roleModel));
@@ -85403,7 +85391,7 @@ async function runHeadless(inputPrompt, options) {
85403
85391
  },
85404
85392
  options: { isNonInteractiveSession: true }
85405
85393
  });
85406
- const canUseTool = getCanUseToolFn(isUsingSdkUrl ? "stdio" : options.permissionPromptToolName, structuredIO, () => mcpTools, hasPromptRoute ? onPermissionPrompt : undefined);
85394
+ const canUseTool = getCanUseToolFn(options.permissionPromptToolName, structuredIO, () => mcpTools, hasPromptRoute ? onPermissionPrompt : undefined);
85407
85395
  const checkPermission = async (tool, input) => {
85408
85396
  const gate = createPermissionGate(tpcRef.current, {
85409
85397
  getAppState: () => ({ toolPermissionContext: tpcRef.current })
@@ -86743,7 +86731,6 @@ function buildHeadlessOptions(options) {
86743
86731
  model: options.model,
86744
86732
  dangerouslySkipPermissions: options.dangerouslySkipPermissions === true ? true : undefined,
86745
86733
  addDirs: options.addDir,
86746
- sdkUrl: options.sdkUrl,
86747
86734
  replayUserMessages: options.replayUserMessages === true ? true : undefined,
86748
86735
  agent: options.agent,
86749
86736
  disablePersistence: options.sessionPersistence === false ? true : undefined,
@@ -86786,11 +86773,6 @@ async function mainActionSeam(prompt, options) {
86786
86773
  const outputFormat = options.outputFormat;
86787
86774
  if (inputFormat === "stream-json" && outputFormat !== "stream-json") {
86788
86775
  process.stderr.write(`Error: --input-format=stream-json requires output-format=stream-json.
86789
- `);
86790
- process.exit(1);
86791
- }
86792
- if (options.sdkUrl && (inputFormat !== "stream-json" || outputFormat !== "stream-json")) {
86793
- process.stderr.write(`Error: --sdk-url requires both --input-format=stream-json and --output-format=stream-json.
86794
86776
  `);
86795
86777
  process.exit(1);
86796
86778
  }
@@ -86852,7 +86834,6 @@ function buildProgram() {
86852
86834
  program.addOption(new Option("--parent-session-id <id>", "Parent session ID for analytics correlation").hideHelp());
86853
86835
  program.addOption(new Option("--teammate-mode <mode>", 'How to spawn teammates: "tmux", "in-process", or "auto"').choices(["auto", "tmux", "in-process"]).hideHelp());
86854
86836
  program.addOption(new Option("--agent-type <type>", "Custom agent type for this teammate").hideHelp());
86855
- program.addOption(new Option("--sdk-url <url>", "Use remote WebSocket endpoint for SDK I/O streaming (only with -p and stream-json format)").hideHelp());
86856
86837
  if (feature("HARD_FAIL")) {
86857
86838
  program.addOption(new Option("--hard-fail", "Crash on logError calls instead of silently logging").hideHelp());
86858
86839
  }
@@ -121224,12 +121205,6 @@ function getGlobalConfig() {
121224
121205
  return migrateConfigFields(getConfig2(getGlobalClaudeFile(), createDefaultGlobalConfig));
121225
121206
  }
121226
121207
  }
121227
- function getRemoteControlAtStartup() {
121228
- const explicit = getGlobalConfig().remoteControlAtStartup;
121229
- if (explicit !== undefined)
121230
- return explicit;
121231
- return false;
121232
- }
121233
121208
  function getCustomApiKeyStatus(truncatedApiKey) {
121234
121209
  const config = getGlobalConfig();
121235
121210
  if (config.customApiKeyResponses?.approved?.includes(truncatedApiKey)) {
@@ -298060,7 +298035,6 @@ function getPath2(key) {
298060
298035
  var SUPPORTED_SETTINGS2;
298061
298036
  var init_supportedSettings2 = __esm(() => {
298062
298037
  init_shared();
298063
- init_config6();
298064
298038
  init_configConstants();
298065
298039
  init_modelOptions();
298066
298040
  init_validateModel();
@@ -298169,14 +298143,6 @@ var init_supportedSettings2 = __esm(() => {
298169
298143
  type: "boolean",
298170
298144
  description: "Enable voice dictation (hold-to-talk)"
298171
298145
  }
298172
- } : {},
298173
- ...feature("BRIDGE_MODE") ? {
298174
- remoteControlAtStartup: {
298175
- source: "global",
298176
- type: "boolean",
298177
- description: "Enable Remote Control for all sessions (true | false | default)",
298178
- formatOnRead: () => getRemoteControlAtStartup()
298179
- }
298180
298146
  } : {}
298181
298147
  };
298182
298148
  });
@@ -298836,33 +298802,6 @@ var init_ConfigTool = __esm(() => {
298836
298802
  data: { success: true, operation: "get", setting, value: displayValue }
298837
298803
  };
298838
298804
  }
298839
- if (setting === "remoteControlAtStartup" && typeof value === "string" && value.toLowerCase().trim() === "default") {
298840
- saveGlobalConfig((prev) => {
298841
- if (prev.remoteControlAtStartup === undefined)
298842
- return prev;
298843
- const next = { ...prev };
298844
- delete next.remoteControlAtStartup;
298845
- return next;
298846
- });
298847
- const resolved = getRemoteControlAtStartup();
298848
- context.setAppState((prev) => {
298849
- if (prev.replBridgeEnabled === resolved && !prev.replBridgeOutboundOnly)
298850
- return prev;
298851
- return {
298852
- ...prev,
298853
- replBridgeEnabled: resolved,
298854
- replBridgeOutboundOnly: false
298855
- };
298856
- });
298857
- return {
298858
- data: {
298859
- success: true,
298860
- operation: "set",
298861
- setting,
298862
- value: resolved
298863
- }
298864
- };
298865
- }
298866
298805
  let finalValue = value;
298867
298806
  if (config.type === "boolean") {
298868
298807
  if (typeof value === "string") {
@@ -299007,18 +298946,6 @@ var init_ConfigTool = __esm(() => {
299007
298946
  return { ...prev, [appKey]: finalValue };
299008
298947
  });
299009
298948
  }
299010
- if (setting === "remoteControlAtStartup") {
299011
- const resolved = getRemoteControlAtStartup();
299012
- context.setAppState((prev) => {
299013
- if (prev.replBridgeEnabled === resolved && !prev.replBridgeOutboundOnly)
299014
- return prev;
299015
- return {
299016
- ...prev,
299017
- replBridgeEnabled: resolved,
299018
- replBridgeOutboundOnly: false
299019
- };
299020
- });
299021
- }
299022
298949
  return {
299023
298950
  data: {
299024
298951
  success: true,
@@ -329666,13 +329593,28 @@ async function saveKnownMarketplacesConfig(config) {
329666
329593
  flush: true
329667
329594
  });
329668
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
+ }
329669
329612
  async function registerSeedMarketplaces() {
329670
329613
  const seedDirs = getPluginSeedDirs();
329671
329614
  if (seedDirs.length === 0)
329672
329615
  return false;
329673
- const primary = await loadKnownMarketplacesConfig();
329674
329616
  const claimed = new Set;
329675
- let changed = 0;
329617
+ const desired = [];
329676
329618
  for (const seedDir of seedDirs) {
329677
329619
  const seedConfig = await readSeedKnownMarketplaces(seedDir);
329678
329620
  if (!seedConfig)
@@ -329686,20 +329628,28 @@ async function registerSeedMarketplaces() {
329686
329628
  continue;
329687
329629
  }
329688
329630
  claimed.add(name);
329689
- const desired = {
329631
+ const entry = {
329690
329632
  source: seedEntry.source,
329691
329633
  installLocation: resolvedLocation,
329692
329634
  lastUpdated: seedEntry.lastUpdated,
329693
329635
  autoUpdate: false
329694
329636
  };
329695
- 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))
329696
329646
  continue;
329697
- primary[name] = desired;
329647
+ primary[name] = entry;
329698
329648
  changed++;
329699
329649
  }
329700
- }
329650
+ return changed > 0 ? primary : undefined;
329651
+ });
329701
329652
  if (changed > 0) {
329702
- await saveKnownMarketplacesConfig(primary);
329703
329653
  logForDebugging3(`Synced ${changed} marketplace(s) from seed dir(s)`);
329704
329654
  return true;
329705
329655
  }
@@ -330458,34 +330408,35 @@ Tip: The shorthand "${resolvedSource.repo}" assumes github.com. ` + `For interna
330458
330408
  if (sourceValidationError) {
330459
330409
  throw new Error(sourceValidationError);
330460
330410
  }
330461
- const config = await loadKnownMarketplacesConfig();
330462
- const oldEntry = config[marketplace.name];
330463
- if (oldEntry) {
330464
- const seedDir = seedDirFor(oldEntry.installLocation);
330465
- if (seedDir) {
330466
- 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.`);
330467
- }
330468
- logForDebugging3(`Marketplace '${marketplace.name}' exists with different source — overwriting`);
330469
- if (!isLocalMarketplaceSource(oldEntry.source)) {
330470
- const cacheDir = resolve42(getMarketplacesCacheDir());
330471
- const resolvedOld = resolve42(oldEntry.installLocation);
330472
- const resolvedNew = resolve42(cachePath);
330473
- if (resolvedOld === resolvedNew) {} else if (resolvedOld === cacheDir || resolvedOld.startsWith(cacheDir + sep26)) {
330474
- const fs = getFsImplementation2();
330475
- await fs.rm(oldEntry.installLocation, { recursive: true, force: true });
330476
- } else {
330477
- 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
+ }
330478
330430
  }
330479
330431
  }
330480
- }
330481
- const resolvedSha = await captureResolvedSha(resolvedSource, cachePath);
330482
- config[marketplace.name] = {
330483
- source: resolvedSource,
330484
- installLocation: cachePath,
330485
- lastUpdated: new Date().toISOString(),
330486
- ...resolvedSha ? { resolvedSha } : {}
330487
- };
330488
- 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
+ });
330489
330440
  logForDebugging3(`Added marketplace source: ${marketplace.name}`);
330490
330441
  return { name: marketplace.name, alreadyMaterialized: false, resolvedSource };
330491
330442
  }
@@ -330498,15 +330449,7 @@ async function adoptOrphanMarketplace(dirName, overrideName) {
330498
330449
  }
330499
330450
  const manifestPath = resolveMarketplaceManifestPath(dirPath);
330500
330451
  const marketplace = await parseFileWithSchema(manifestPath, PluginMarketplaceSchema());
330501
- const config = await loadKnownMarketplacesConfig();
330502
330452
  const name = overrideName ?? marketplace.name;
330503
- const existing = config[name];
330504
- if (existing) {
330505
- if (resolve42(existing.installLocation) === resolve42(dirPath)) {
330506
- return { name, source: existing.source, installLocation: dirPath };
330507
- }
330508
- 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.`);
330509
- }
330510
330453
  const remoteUrl = await parseGitConfigValue2(join118(dirPath, ".git"), "remote", "origin", "url");
330511
330454
  let source;
330512
330455
  if (remoteUrl) {
@@ -330526,29 +330469,39 @@ async function adoptOrphanMarketplace(dirName, overrideName) {
330526
330469
  throw new Error(`Marketplace source '${formatSourceForDisplay(source)}' is blocked ` + `by enterprise policy and cannot be adopted.`);
330527
330470
  }
330528
330471
  const resolvedSha = await captureResolvedSha(source, dirPath);
330529
- config[name] = {
330530
- source,
330531
- installLocation: dirPath,
330532
- lastUpdated: new Date().toISOString(),
330533
- ...resolvedSha ? { resolvedSha } : {}
330534
- };
330535
- 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
+ });
330536
330488
  clearAllCaches();
330537
330489
  logForDebugging3(`Adopted orphan marketplace directory '${dirName}' as '${name}' (${formatSourceForDisplay(source)})`);
330538
330490
  return { name, source, installLocation: dirPath };
330539
330491
  }
330540
330492
  async function removeMarketplaceSource(name) {
330541
- const config = await loadKnownMarketplacesConfig();
330542
- if (!config[name]) {
330543
- throw new Error(`Marketplace '${name}' not found`);
330544
- }
330545
- const entry = config[name];
330546
- const seedDir = seedDirFor(entry.installLocation);
330547
- if (seedDir) {
330548
- 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}`);
330549
- }
330550
- delete config[name];
330551
- 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
+ });
330552
330505
  const fs = getFsImplementation2();
330553
330506
  const cacheDir = getMarketplacesCacheDir();
330554
330507
  const cachePath = join118(cacheDir, name);
@@ -330831,23 +330784,24 @@ async function refreshMarketplace(name, onProgress, options) {
330831
330784
  }
330832
330785
  }
330833
330786
  async function setMarketplaceAutoUpdate(name, autoUpdate) {
330834
- const config = await loadKnownMarketplacesConfig();
330835
- const entry = config[name];
330836
- if (!entry) {
330837
- throw new Error(`Marketplace '${name}' not found. Available marketplaces: ${Object.keys(config).join(", ")}`);
330838
- }
330839
- const seedDir = seedDirFor(entry.installLocation);
330840
- if (seedDir) {
330841
- 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.`);
330842
- }
330843
- if (entry.autoUpdate === autoUpdate) {
330844
- return;
330845
- }
330846
- config[name] = {
330847
- ...entry,
330848
- autoUpdate
330849
- };
330850
- 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
+ });
330851
330805
  const declaringSource = getMarketplaceDeclaringSource(name);
330852
330806
  if (declaringSource) {
330853
330807
  const declared = getSettingsForSource2(declaringSource)?.extraKnownMarketplaces?.[name];
@@ -330857,7 +330811,7 @@ async function setMarketplaceAutoUpdate(name, autoUpdate) {
330857
330811
  }
330858
330812
  logForDebugging3(`Set autoUpdate=${autoUpdate} for marketplace: ${name}`);
330859
330813
  }
330860
- 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;
330861
330815
  var init_marketplaceManager = __esm(() => {
330862
330816
  init_axios2();
330863
330817
  init_configDir();
@@ -330887,6 +330841,7 @@ var init_marketplaceManager = __esm(() => {
330887
330841
  init_orphanScanner();
330888
330842
  init_pluginOptionsStorage();
330889
330843
  init_schemas3();
330844
+ knownMarketplacesRmwChain = Promise.resolve();
330890
330845
  GIT_NO_PROMPT_ENV3 = {
330891
330846
  GIT_TERMINAL_PROMPT: "0",
330892
330847
  GIT_ASKPASS: ""
@@ -331497,6 +331452,217 @@ function mtimeAwareMemoize(fn, watchFiles, options) {
331497
331452
  }
331498
331453
  var init_mtimeAwareMemoize = () => {};
331499
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
+
331500
331666
  // src/tui/utils/plugins/pluginVersioning.ts
331501
331667
  import { createHash as createHash9 } from "crypto";
331502
331668
  async function calculatePluginVersion(pluginId, source, manifest, installPath, providedVersion, gitCommitSha) {
@@ -331540,9 +331706,9 @@ var init_pluginVersioning = __esm(() => {
331540
331706
  });
331541
331707
 
331542
331708
  // src/tui/utils/plugins/pluginInstallationHelpers.ts
331543
- import { randomBytes as randomBytes15 } from "crypto";
331544
- import { rename as rename5, rm as rm8 } from "fs/promises";
331545
- 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";
331546
331712
  function getCurrentTimestamp() {
331547
331713
  return new Date().toISOString();
331548
331714
  }
@@ -331571,12 +331737,12 @@ async function cacheAndRegisterPlugin(pluginId, entry, scope = "user", projectPa
331571
331737
  const normalizedCachePath = cacheResult.path.endsWith(sep27) ? cacheResult.path : cacheResult.path + sep27;
331572
331738
  const isSubdirectory = versionedPath.startsWith(normalizedCachePath);
331573
331739
  if (isSubdirectory) {
331574
- const tempPath = join120(dirname64(cacheResult.path), `.atlas-plugin-temp-${Date.now()}-${randomBytes15(4).toString("hex")}`);
331575
- 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);
331576
331742
  await getFsImplementation2().mkdir(dirname64(versionedPath));
331577
- await rename5(tempPath, versionedPath);
331743
+ await rename6(tempPath, versionedPath);
331578
331744
  } else {
331579
- await rename5(cacheResult.path, versionedPath);
331745
+ await rename6(cacheResult.path, versionedPath);
331580
331746
  }
331581
331747
  finalPath = versionedPath;
331582
331748
  }
@@ -331747,6 +331913,7 @@ async function installPluginFromMarketplace({
331747
331913
  };
331748
331914
  }
331749
331915
  }
331916
+ reportInstall(pluginId, marketplaceName);
331750
331917
  return {
331751
331918
  success: true,
331752
331919
  message: `✓ Installed ${entry.name}${result.depNote}.`
@@ -331765,6 +331932,7 @@ var init_pluginInstallationHelpers = __esm(() => {
331765
331932
  init_settings3();
331766
331933
  init_cacheUtils();
331767
331934
  init_dependencyResolver();
331935
+ init_installCountReporter();
331768
331936
  init_installedPluginsManager();
331769
331937
  init_marketplaceManager();
331770
331938
  init_pluginIdentifier2();
@@ -331779,25 +331947,25 @@ var init_pluginInstallationHelpers = __esm(() => {
331779
331947
  import {
331780
331948
  copyFile as copyFile6,
331781
331949
  readdir as readdir24,
331782
- readFile as readFile41,
331950
+ readFile as readFile42,
331783
331951
  readlink,
331784
331952
  realpath as realpath11,
331785
- rename as rename6,
331953
+ rename as rename7,
331786
331954
  rm as rm9,
331787
331955
  rmdir,
331788
331956
  stat as stat40,
331789
331957
  symlink as symlink5
331790
331958
  } from "fs/promises";
331791
- 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";
331792
331960
  function getPluginCachePath() {
331793
- return join121(getPluginsDirectory(), "cache");
331961
+ return join122(getPluginsDirectory(), "cache");
331794
331962
  }
331795
331963
  function getVersionedCachePathIn(baseDir, pluginId, version) {
331796
331964
  const { name: pluginName, marketplace } = parsePluginIdentifier2(pluginId);
331797
331965
  const sanitizedMarketplace = (marketplace || "unknown").replace(/[^a-zA-Z0-9\-_]/g, "-");
331798
331966
  const sanitizedPlugin = (pluginName || pluginId).replace(/[^a-zA-Z0-9\-_]/g, "-");
331799
331967
  const sanitizedVersion = version.replace(/[^a-zA-Z0-9\-_.]/g, "-");
331800
- return join121(baseDir, "cache", sanitizedMarketplace, sanitizedPlugin, sanitizedVersion);
331968
+ return join122(baseDir, "cache", sanitizedMarketplace, sanitizedPlugin, sanitizedVersion);
331801
331969
  }
331802
331970
  function getVersionedCachePath(pluginId, version) {
331803
331971
  return getVersionedCachePathIn(getPluginsDirectory(), pluginId, version);
@@ -331823,7 +331991,7 @@ async function probeSeedCacheAnyVersion(pluginId) {
331823
331991
  const versions = await readdir24(pluginDir);
331824
331992
  if (versions.length !== 1)
331825
331993
  continue;
331826
- const versionDir = join121(pluginDir, versions[0]);
331994
+ const versionDir = join122(pluginDir, versions[0]);
331827
331995
  const entries = await readdir24(versionDir);
331828
331996
  if (entries.length > 0)
331829
331997
  return versionDir;
@@ -331835,8 +332003,8 @@ async function copyDir(src, dest) {
331835
332003
  await getFsImplementation2().mkdir(dest);
331836
332004
  const entries = await readdir24(src, { withFileTypes: true });
331837
332005
  for (const entry of entries) {
331838
- const srcPath = join121(src, entry.name);
331839
- const destPath = join121(dest, entry.name);
332006
+ const srcPath = join122(src, entry.name);
332007
+ const destPath = join122(dest, entry.name);
331840
332008
  if (entry.isDirectory()) {
331841
332009
  await copyDir(srcPath, destPath);
331842
332010
  } else if (entry.isFile()) {
@@ -331859,7 +332027,7 @@ async function copyDir(src, dest) {
331859
332027
  const srcPrefix = resolvedSrc.endsWith(sep28) ? resolvedSrc : resolvedSrc + sep28;
331860
332028
  if (resolvedTarget.startsWith(srcPrefix) || resolvedTarget === resolvedSrc) {
331861
332029
  const targetRelativeToSrc = relative22(resolvedSrc, resolvedTarget);
331862
- const destTargetPath = join121(dest, targetRelativeToSrc);
332030
+ const destTargetPath = join122(dest, targetRelativeToSrc);
331863
332031
  const relativeLinkPath = relative22(dirname65(destPath), destTargetPath);
331864
332032
  await symlink5(relativeLinkPath, destPath);
331865
332033
  } else {
@@ -331907,7 +332075,7 @@ async function copyPluginToVersionedCache(sourcePath, pluginId, version, entry,
331907
332075
  logForDebugging3(`Copying plugin ${pluginId} to versioned cache (fallback to full copy)`);
331908
332076
  await copyDir(sourcePath, cachePath);
331909
332077
  }
331910
- const gitPath = join121(cachePath, ".git");
332078
+ const gitPath = join122(cachePath, ".git");
331911
332079
  await rm9(gitPath, { recursive: true, force: true });
331912
332080
  const cacheEntries = await readdir24(cachePath);
331913
332081
  if (cacheEntries.length === 0) {
@@ -331938,10 +332106,10 @@ function validateGitUrl(url) {
331938
332106
  }
331939
332107
  }
331940
332108
  async function installFromNpm(packageName, targetPath, options = {}) {
331941
- const npmCachePath = join121(getPluginsDirectory(), "npm-cache");
332109
+ const npmCachePath = join122(getPluginsDirectory(), "npm-cache");
331942
332110
  await getFsImplementation2().mkdir(npmCachePath);
331943
332111
  const packageSpec = options.version ? `${packageName}@${options.version}` : packageName;
331944
- const packagePath = join121(npmCachePath, "node_modules", packageName);
332112
+ const packagePath = join122(npmCachePath, "node_modules", packageName);
331945
332113
  const needsInstall = !await pathExists2(packagePath);
331946
332114
  if (needsInstall) {
331947
332115
  logForDebugging3(`Installing npm package ${packageSpec} to cache`);
@@ -332074,7 +332242,7 @@ async function installFromGitSubdir(url, targetPath, subdirPath, ref, sha) {
332074
332242
  }
332075
332243
  const resolvedSubdir = validatePathWithinBase(cloneDir, subdirPath);
332076
332244
  try {
332077
- await rename6(resolvedSubdir, targetPath);
332245
+ await rename7(resolvedSubdir, targetPath);
332078
332246
  } catch (e) {
332079
332247
  if (isENOENT2(e)) {
332080
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.");
@@ -332094,7 +332262,7 @@ async function installFromLocal(sourcePath, targetPath) {
332094
332262
  throw new Error(`Source path does not exist: ${sourcePath}`);
332095
332263
  }
332096
332264
  await copyDir(sourcePath, targetPath);
332097
- const gitPath = join121(targetPath, ".git");
332265
+ const gitPath = join122(targetPath, ".git");
332098
332266
  await rm9(gitPath, { recursive: true, force: true });
332099
332267
  }
332100
332268
  function generateTemporaryCacheNameForPlugin(source) {
@@ -332130,7 +332298,7 @@ async function cachePlugin(source, options) {
332130
332298
  const cachePath = getPluginCachePath();
332131
332299
  await getFsImplementation2().mkdir(cachePath);
332132
332300
  const tempName = generateTemporaryCacheNameForPlugin(source);
332133
- const tempPath = join121(cachePath, tempName);
332301
+ const tempPath = join122(cachePath, tempName);
332134
332302
  let shouldCleanup = false;
332135
332303
  let gitCommitSha;
332136
332304
  try {
@@ -332175,11 +332343,11 @@ async function cachePlugin(source, options) {
332175
332343
  throw error;
332176
332344
  }
332177
332345
  const manifestPath = findManifestInDir(tempPath, "plugin.json");
332178
- const legacyManifestPath = join121(tempPath, "plugin.json");
332346
+ const legacyManifestPath = join122(tempPath, "plugin.json");
332179
332347
  let manifest;
332180
332348
  if (await pathExists2(manifestPath)) {
332181
332349
  try {
332182
- const content = await readFile41(manifestPath, { encoding: "utf-8" });
332350
+ const content = await readFile42(manifestPath, { encoding: "utf-8" });
332183
332351
  const parsed = jsonParse2(content);
332184
332352
  const result = PluginManifestSchema().safeParse(parsed);
332185
332353
  if (result.success) {
@@ -332203,7 +332371,7 @@ async function cachePlugin(source, options) {
332203
332371
  }
332204
332372
  } else if (await pathExists2(legacyManifestPath)) {
332205
332373
  try {
332206
- const content = await readFile41(legacyManifestPath, {
332374
+ const content = await readFile42(legacyManifestPath, {
332207
332375
  encoding: "utf-8"
332208
332376
  });
332209
332377
  const parsed = jsonParse2(content);
@@ -332232,12 +332400,12 @@ async function cachePlugin(source, options) {
332232
332400
  };
332233
332401
  }
332234
332402
  const finalName = manifest.name.replace(/[^a-zA-Z0-9-_]/g, "-");
332235
- const finalPath = join121(cachePath, finalName);
332403
+ const finalPath = join122(cachePath, finalName);
332236
332404
  if (await pathExists2(finalPath)) {
332237
332405
  logForDebugging3(`Removing old cached version at ${finalPath}`);
332238
332406
  await rm9(finalPath, { recursive: true, force: true });
332239
332407
  }
332240
- await rename6(tempPath, finalPath);
332408
+ await rename7(tempPath, finalPath);
332241
332409
  logForDebugging3(`Successfully cached plugin ${manifest.name} to ${finalPath}`);
332242
332410
  return {
332243
332411
  path: finalPath,
@@ -332253,7 +332421,7 @@ async function loadPluginManifest(manifestPath, pluginName, source) {
332253
332421
  };
332254
332422
  }
332255
332423
  try {
332256
- const content = await readFile41(manifestPath, { encoding: "utf-8" });
332424
+ const content = await readFile42(manifestPath, { encoding: "utf-8" });
332257
332425
  const parsedJson = jsonParse2(content);
332258
332426
  const result = PluginManifestSchema().safeParse(parsedJson);
332259
332427
  if (result.success) {
@@ -332279,14 +332447,14 @@ async function loadPluginHooks2(hooksConfigPath, pluginName) {
332279
332447
  if (!await pathExists2(hooksConfigPath)) {
332280
332448
  throw new Error(`Hooks file not found at ${hooksConfigPath} for plugin ${pluginName}. If the manifest declares hooks, the file must exist.`);
332281
332449
  }
332282
- const content = await readFile41(hooksConfigPath, { encoding: "utf-8" });
332450
+ const content = await readFile42(hooksConfigPath, { encoding: "utf-8" });
332283
332451
  const rawHooksConfig = jsonParse2(content);
332284
332452
  const validatedPluginHooks = PluginHooksSchema().parse(rawHooksConfig);
332285
332453
  return validatedPluginHooks.hooks;
332286
332454
  }
332287
332455
  async function validatePluginPaths(relPaths, pluginPath, pluginName, source, component, componentLabel, contextLabel, errors) {
332288
332456
  const checks = await Promise.all(relPaths.map(async (relPath) => {
332289
- const fullPath = join121(pluginPath, relPath);
332457
+ const fullPath = join122(pluginPath, relPath);
332290
332458
  return { relPath, fullPath, exists: await pathExists2(fullPath) };
332291
332459
  }));
332292
332460
  const validPaths = [];
@@ -332325,12 +332493,12 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332325
332493
  skillsDirExists,
332326
332494
  outputStylesDirExists
332327
332495
  ] = await Promise.all([
332328
- !manifest.commands ? pathExists2(join121(pluginPath, "commands")) : false,
332329
- !manifest.agents ? pathExists2(join121(pluginPath, "agents")) : false,
332330
- !manifest.skills ? pathExists2(join121(pluginPath, "skills")) : false,
332331
- !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
332332
332500
  ]);
332333
- const commandsPath = join121(pluginPath, "commands");
332501
+ const commandsPath = join122(pluginPath, "commands");
332334
332502
  if (commandsDirExists) {
332335
332503
  plugin.commandsPath = commandsPath;
332336
332504
  }
@@ -332345,7 +332513,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332345
332513
  return { commandName, metadata, kind: "skip" };
332346
332514
  }
332347
332515
  if (metadata.source) {
332348
- const fullPath = join121(pluginPath, metadata.source);
332516
+ const fullPath = join122(pluginPath, metadata.source);
332349
332517
  return {
332350
332518
  commandName,
332351
332519
  metadata,
@@ -332393,7 +332561,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332393
332561
  if (typeof cmdPath !== "string") {
332394
332562
  return { cmdPath, kind: "invalid" };
332395
332563
  }
332396
- const fullPath = join121(pluginPath, cmdPath);
332564
+ const fullPath = join122(pluginPath, cmdPath);
332397
332565
  return {
332398
332566
  cmdPath,
332399
332567
  kind: "path",
@@ -332426,7 +332594,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332426
332594
  }
332427
332595
  }
332428
332596
  }
332429
- const agentsPath = join121(pluginPath, "agents");
332597
+ const agentsPath = join122(pluginPath, "agents");
332430
332598
  if (agentsDirExists) {
332431
332599
  plugin.agentsPath = agentsPath;
332432
332600
  }
@@ -332437,7 +332605,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332437
332605
  plugin.agentsPaths = validPaths;
332438
332606
  }
332439
332607
  }
332440
- const skillsPath = join121(pluginPath, "skills");
332608
+ const skillsPath = join122(pluginPath, "skills");
332441
332609
  if (skillsDirExists) {
332442
332610
  plugin.skillsPath = skillsPath;
332443
332611
  }
@@ -332448,7 +332616,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332448
332616
  plugin.skillsPaths = validPaths;
332449
332617
  }
332450
332618
  }
332451
- const outputStylesPath = join121(pluginPath, "output-styles");
332619
+ const outputStylesPath = join122(pluginPath, "output-styles");
332452
332620
  if (outputStylesDirExists) {
332453
332621
  plugin.outputStylesPath = outputStylesPath;
332454
332622
  }
@@ -332461,7 +332629,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332461
332629
  }
332462
332630
  let mergedHooks;
332463
332631
  const loadedHookPaths = new Set;
332464
- const standardHooksPath = join121(pluginPath, "hooks", "hooks.json");
332632
+ const standardHooksPath = join122(pluginPath, "hooks", "hooks.json");
332465
332633
  if (await pathExists2(standardHooksPath)) {
332466
332634
  try {
332467
332635
  mergedHooks = await loadPluginHooks2(standardHooksPath, manifest.name);
@@ -332490,7 +332658,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332490
332658
  const manifestHooksArray = Array.isArray(manifest.hooks) ? manifest.hooks : [manifest.hooks];
332491
332659
  for (const hookSpec of manifestHooksArray) {
332492
332660
  if (typeof hookSpec === "string") {
332493
- const hookFilePath = join121(pluginPath, hookSpec);
332661
+ const hookFilePath = join122(pluginPath, hookSpec);
332494
332662
  if (!await pathExists2(hookFilePath)) {
332495
332663
  logForDebugging3(`Hooks file ${hookSpec} specified in manifest but not found at ${hookFilePath} for ${manifest.name}`, { level: "error" });
332496
332664
  logError3(new Error(`Plugin component file not found: ${hookFilePath} for ${manifest.name}`));
@@ -332580,9 +332748,9 @@ function parsePluginSettings(raw) {
332580
332748
  return data;
332581
332749
  }
332582
332750
  async function loadPluginSettings(pluginPath, manifest) {
332583
- const settingsJsonPath = join121(pluginPath, "settings.json");
332751
+ const settingsJsonPath = join122(pluginPath, "settings.json");
332584
332752
  try {
332585
- const content = await readFile41(settingsJsonPath, { encoding: "utf-8" });
332753
+ const content = await readFile42(settingsJsonPath, { encoding: "utf-8" });
332586
332754
  const parsed = jsonParse2(content);
332587
332755
  if (isRecord(parsed)) {
332588
332756
  const filtered = parsePluginSettings(parsed);
@@ -332723,7 +332891,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
332723
332891
  if (typeof entry.source === "string") {
332724
332892
  let marketplaceDir;
332725
332893
  try {
332726
- marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join121(marketplaceInstallLocation, "..");
332894
+ marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join122(marketplaceInstallLocation, "..");
332727
332895
  } catch {
332728
332896
  errorsOut.push({
332729
332897
  type: "plugin-cache-miss",
@@ -332733,7 +332901,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
332733
332901
  });
332734
332902
  return null;
332735
332903
  }
332736
- pluginPath = join121(marketplaceDir, entry.source);
332904
+ pluginPath = join122(marketplaceDir, entry.source);
332737
332905
  } else {
332738
332906
  if (!installPath || !await pathExists2(installPath)) {
332739
332907
  errorsOut.push({
@@ -332748,7 +332916,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
332748
332916
  }
332749
332917
  if (isPluginZipCacheEnabled() && pluginPath.endsWith(".zip")) {
332750
332918
  const sessionDir = await getSessionPluginCachePath();
332751
- const extractDir = join121(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
332919
+ const extractDir = join122(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
332752
332920
  try {
332753
332921
  await extractZipToDirectory(pluginPath, extractDir);
332754
332922
  pluginPath = extractDir;
@@ -332771,8 +332939,8 @@ async function loadPluginFromMarketplaceEntry(entry, marketplaceInstallLocation,
332771
332939
  logForDebugging3(`Loading plugin ${entry.name} from source: ${jsonStringify5(entry.source)}`);
332772
332940
  let pluginPath;
332773
332941
  if (typeof entry.source === "string") {
332774
- const marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join121(marketplaceInstallLocation, "..");
332775
- const sourcePluginPath = join121(marketplaceDir, entry.source);
332942
+ const marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join122(marketplaceInstallLocation, "..");
332943
+ const sourcePluginPath = join122(marketplaceDir, entry.source);
332776
332944
  if (!await pathExists2(sourcePluginPath)) {
332777
332945
  const error = new Error(`Plugin path not found: ${sourcePluginPath}`);
332778
332946
  logForDebugging3(`Plugin path not found: ${sourcePluginPath}`, {
@@ -332843,7 +333011,7 @@ async function loadPluginFromMarketplaceEntry(entry, marketplaceInstallLocation,
332843
333011
  }
332844
333012
  if (isPluginZipCacheEnabled() && pluginPath.endsWith(".zip")) {
332845
333013
  const sessionDir = await getSessionPluginCachePath();
332846
- const extractDir = join121(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
333014
+ const extractDir = join122(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
332847
333015
  try {
332848
333016
  await extractZipToDirectory(pluginPath, extractDir);
332849
333017
  logForDebugging3(`Extracted plugin ZIP to session dir: ${extractDir}`);
@@ -332883,7 +333051,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
332883
333051
  if (!metadata || typeof metadata !== "object" || !metadata.source) {
332884
333052
  return { commandName, metadata, skip: true };
332885
333053
  }
332886
- const fullPath = join121(pluginPath, metadata.source);
333054
+ const fullPath = join122(pluginPath, metadata.source);
332887
333055
  return {
332888
333056
  commandName,
332889
333057
  metadata,
@@ -332920,7 +333088,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
332920
333088
  if (typeof cmdPath !== "string") {
332921
333089
  return { cmdPath, kind: "invalid" };
332922
333090
  }
332923
- const fullPath = join121(pluginPath, cmdPath);
333091
+ const fullPath = join122(pluginPath, cmdPath);
332924
333092
  return {
332925
333093
  cmdPath,
332926
333094
  kind: "path",
@@ -332964,7 +333132,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
332964
333132
  logForDebugging3(`Processing ${Array.isArray(entry.skills) ? entry.skills.length : 1} skill paths for plugin ${entry.name}`);
332965
333133
  const skillPaths = Array.isArray(entry.skills) ? entry.skills : [entry.skills];
332966
333134
  const checks = await Promise.all(skillPaths.map(async (skillPath) => {
332967
- const fullPath = join121(pluginPath, skillPath);
333135
+ const fullPath = join122(pluginPath, skillPath);
332968
333136
  return { skillPath, fullPath, exists: await pathExists2(fullPath) };
332969
333137
  }));
332970
333138
  const validPaths = [];
@@ -333024,7 +333192,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
333024
333192
  if (!metadata || typeof metadata !== "object" || !metadata.source) {
333025
333193
  return { commandName, metadata, skip: true };
333026
333194
  }
333027
- const fullPath = join121(pluginPath, metadata.source);
333195
+ const fullPath = join122(pluginPath, metadata.source);
333028
333196
  return {
333029
333197
  commandName,
333030
333198
  metadata,
@@ -333064,7 +333232,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
333064
333232
  if (typeof cmdPath !== "string") {
333065
333233
  return { cmdPath, kind: "invalid" };
333066
333234
  }
333067
- const fullPath = join121(pluginPath, cmdPath);
333235
+ const fullPath = join122(pluginPath, cmdPath);
333068
333236
  return {
333069
333237
  cmdPath,
333070
333238
  kind: "path",
@@ -336727,9 +336895,9 @@ var init_prefix = __esm(() => {
336727
336895
  });
336728
336896
 
336729
336897
  // src/tui/utils/bash/commands.ts
336730
- import { randomBytes as randomBytes16 } from "crypto";
336898
+ import { randomBytes as randomBytes17 } from "crypto";
336731
336899
  function generatePlaceholders2() {
336732
- const salt = randomBytes16(8).toString("hex");
336900
+ const salt = randomBytes17(8).toString("hex");
336733
336901
  return {
336734
336902
  SINGLE_QUOTE: `__SINGLE_QUOTE_${salt}__`,
336735
336903
  DOUBLE_QUOTE: `__DOUBLE_QUOTE_${salt}__`,
@@ -339372,7 +339540,7 @@ var init_projectOnboardingState = __esm(() => {
339372
339540
  // src/tui/utils/appleTerminalBackup.ts
339373
339541
  import { stat as stat41 } from "fs/promises";
339374
339542
  import { homedir as homedir30 } from "os";
339375
- import { join as join122 } from "path";
339543
+ import { join as join123 } from "path";
339376
339544
  function markTerminalSetupInProgress(backupPath) {
339377
339545
  saveGlobalConfig((current) => ({
339378
339546
  ...current,
@@ -339394,7 +339562,7 @@ function getTerminalRecoveryInfo() {
339394
339562
  };
339395
339563
  }
339396
339564
  function getTerminalPlistPath() {
339397
- return join122(homedir30(), "Library", "Preferences", "com.apple.Terminal.plist");
339565
+ return join123(homedir30(), "Library", "Preferences", "com.apple.Terminal.plist");
339398
339566
  }
339399
339567
  async function backupTerminalPreferences() {
339400
339568
  const terminalPlistPath = getTerminalPlistPath();
@@ -339475,10 +339643,10 @@ __export(exports_terminalSetup, {
339475
339643
  setupTerminal: () => setupTerminal,
339476
339644
  shouldOfferTerminalSetup: () => shouldOfferTerminalSetup
339477
339645
  });
339478
- import { randomBytes as randomBytes17 } from "crypto";
339479
- 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";
339480
339648
  import { homedir as homedir31, platform as platform3 } from "os";
339481
- import { dirname as dirname66, join as join123 } from "path";
339649
+ import { dirname as dirname66, join as join124 } from "path";
339482
339650
  import { pathToFileURL as pathToFileURL8 } from "url";
339483
339651
  function isVSCodeRemoteSSH() {
339484
339652
  const askpassMain = process.env.VSCODE_GIT_ASKPASS_MAIN ?? "";
@@ -339612,8 +339780,8 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
339612
339780
  ]`)}${EOL4}`;
339613
339781
  }
339614
339782
  const editorDir = editor === "VSCode" ? "Code" : editor;
339615
- const userDirPath = join123(homedir31(), platform3() === "win32" ? join123("AppData", "Roaming", editorDir, "User") : platform3() === "darwin" ? join123("Library", "Application Support", editorDir, "User") : join123(".config", editorDir, "User"));
339616
- 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");
339617
339785
  try {
339618
339786
  await mkdir37(userDirPath, {
339619
339787
  recursive: true
@@ -339622,7 +339790,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
339622
339790
  let keybindings = [];
339623
339791
  let fileExists = false;
339624
339792
  try {
339625
- content = await readFile42(keybindingsPath, {
339793
+ content = await readFile43(keybindingsPath, {
339626
339794
  encoding: "utf-8"
339627
339795
  });
339628
339796
  fileExists = true;
@@ -339632,7 +339800,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
339632
339800
  throw e;
339633
339801
  }
339634
339802
  if (fileExists) {
339635
- const randomSha = randomBytes17(4).toString("hex");
339803
+ const randomSha = randomBytes18(4).toString("hex");
339636
339804
  const backupPath = `${keybindingsPath}.${randomSha}.bak`;
339637
339805
  try {
339638
339806
  await copyFile7(keybindingsPath, backupPath);
@@ -339653,7 +339821,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
339653
339821
  when: "terminalFocus"
339654
339822
  };
339655
339823
  const updatedContent = addItemToJSONCArray(content, newKeybinding);
339656
- await writeFile29(keybindingsPath, updatedContent, {
339824
+ await writeFile30(keybindingsPath, updatedContent, {
339657
339825
  encoding: "utf-8"
339658
339826
  });
339659
339827
  return `${color("success", theme)(`Installed ${editor} terminal Shift+Enter key binding`)}${EOL4}${source_default.dim(`See ${formatPathLink(keybindingsPath)}`)}${EOL4}`;
@@ -339754,14 +339922,14 @@ chars = "\\u001B\\r"`;
339754
339922
  const configPaths = [];
339755
339923
  const xdgConfigHome = process.env.XDG_CONFIG_HOME;
339756
339924
  if (xdgConfigHome) {
339757
- configPaths.push(join123(xdgConfigHome, "alacritty", "alacritty.toml"));
339925
+ configPaths.push(join124(xdgConfigHome, "alacritty", "alacritty.toml"));
339758
339926
  } else {
339759
- configPaths.push(join123(homedir31(), ".config", "alacritty", "alacritty.toml"));
339927
+ configPaths.push(join124(homedir31(), ".config", "alacritty", "alacritty.toml"));
339760
339928
  }
339761
339929
  if (platform3() === "win32") {
339762
339930
  const appData = process.env.APPDATA;
339763
339931
  if (appData) {
339764
- configPaths.push(join123(appData, "alacritty", "alacritty.toml"));
339932
+ configPaths.push(join124(appData, "alacritty", "alacritty.toml"));
339765
339933
  }
339766
339934
  }
339767
339935
  let configPath = null;
@@ -339769,7 +339937,7 @@ chars = "\\u001B\\r"`;
339769
339937
  let configExists = false;
339770
339938
  for (const path of configPaths) {
339771
339939
  try {
339772
- configContent = await readFile42(path, {
339940
+ configContent = await readFile43(path, {
339773
339941
  encoding: "utf-8"
339774
339942
  });
339775
339943
  configPath = path;
@@ -339791,7 +339959,7 @@ chars = "\\u001B\\r"`;
339791
339959
  if (configContent.includes('mods = "Shift"') && configContent.includes('key = "Return"')) {
339792
339960
  return `${color("warning", theme)("Found existing Alacritty Shift+Enter key binding. Remove it to continue.")}${EOL4}${source_default.dim(`See ${formatPathLink(configPath)}`)}${EOL4}`;
339793
339961
  }
339794
- const randomSha = randomBytes17(4).toString("hex");
339962
+ const randomSha = randomBytes18(4).toString("hex");
339795
339963
  const backupPath = `${configPath}.${randomSha}.bak`;
339796
339964
  try {
339797
339965
  await copyFile7(configPath, backupPath);
@@ -339812,7 +339980,7 @@ chars = "\\u001B\\r"`;
339812
339980
  updatedContent += `
339813
339981
  ` + ALACRITTY_KEYBINDING + `
339814
339982
  `;
339815
- await writeFile29(configPath, updatedContent, {
339983
+ await writeFile30(configPath, updatedContent, {
339816
339984
  encoding: "utf-8"
339817
339985
  });
339818
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}`;
@@ -339822,8 +339990,8 @@ chars = "\\u001B\\r"`;
339822
339990
  }
339823
339991
  }
339824
339992
  async function installBindingsForZed(theme) {
339825
- const zedDir = join123(homedir31(), ".config", "zed");
339826
- const keymapPath = join123(zedDir, "keymap.json");
339993
+ const zedDir = join124(homedir31(), ".config", "zed");
339994
+ const keymapPath = join124(zedDir, "keymap.json");
339827
339995
  try {
339828
339996
  await mkdir37(zedDir, {
339829
339997
  recursive: true
@@ -339831,7 +339999,7 @@ async function installBindingsForZed(theme) {
339831
339999
  let keymapContent = "[]";
339832
340000
  let fileExists = false;
339833
340001
  try {
339834
- keymapContent = await readFile42(keymapPath, {
340002
+ keymapContent = await readFile43(keymapPath, {
339835
340003
  encoding: "utf-8"
339836
340004
  });
339837
340005
  fileExists = true;
@@ -339843,7 +340011,7 @@ async function installBindingsForZed(theme) {
339843
340011
  if (keymapContent.includes("shift-enter")) {
339844
340012
  return `${color("warning", theme)("Found existing Zed Shift+Enter key binding. Remove it to continue.")}${EOL4}${source_default.dim(`See ${formatPathLink(keymapPath)}`)}${EOL4}`;
339845
340013
  }
339846
- const randomSha = randomBytes17(4).toString("hex");
340014
+ const randomSha = randomBytes18(4).toString("hex");
339847
340015
  const backupPath = `${keymapPath}.${randomSha}.bak`;
339848
340016
  try {
339849
340017
  await copyFile7(keymapPath, backupPath);
@@ -339866,7 +340034,7 @@ async function installBindingsForZed(theme) {
339866
340034
  "shift-enter": ["terminal::SendText", "\x1B\r"]
339867
340035
  }
339868
340036
  });
339869
- await writeFile29(keymapPath, jsonStringify5(keymap, null, 2) + `
340037
+ await writeFile30(keymapPath, jsonStringify5(keymap, null, 2) + `
339870
340038
  `, {
339871
340039
  encoding: "utf-8"
339872
340040
  });
@@ -339903,23 +340071,23 @@ var init_terminalSetup = __esm(() => {
339903
340071
 
339904
340072
  // src/tui/utils/pasteStore.ts
339905
340073
  import { createHash as createHash10 } from "crypto";
339906
- import { mkdir as mkdir38, readdir as readdir25, readFile as readFile43, stat as stat42, unlink as unlink16, writeFile as writeFile30 } from "fs/promises";
339907
- 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";
339908
340076
  function getPasteStoreDir() {
339909
- return join124(getAtlasConfigHomeDir3(), PASTE_STORE_DIR);
340077
+ return join125(getAtlasConfigHomeDir3(), PASTE_STORE_DIR);
339910
340078
  }
339911
340079
  function hashPastedText(content) {
339912
340080
  return createHash10("sha256").update(content).digest("hex").slice(0, 16);
339913
340081
  }
339914
340082
  function getPastePath(hash) {
339915
- return join124(getPasteStoreDir(), `${hash}.txt`);
340083
+ return join125(getPasteStoreDir(), `${hash}.txt`);
339916
340084
  }
339917
340085
  async function storePastedText(hash, content) {
339918
340086
  try {
339919
340087
  const dir = getPasteStoreDir();
339920
340088
  await mkdir38(dir, { recursive: true });
339921
340089
  const pastePath = getPastePath(hash);
339922
- await writeFile30(pastePath, content, { encoding: "utf8", mode: 384 });
340090
+ await writeFile31(pastePath, content, { encoding: "utf8", mode: 384 });
339923
340091
  logForDebugging3(`Stored paste ${hash} to ${pastePath}`);
339924
340092
  } catch (error) {
339925
340093
  logForDebugging3(`Failed to store paste: ${error}`);
@@ -339928,7 +340096,7 @@ async function storePastedText(hash, content) {
339928
340096
  async function retrievePastedText(hash) {
339929
340097
  try {
339930
340098
  const pastePath = getPastePath(hash);
339931
- return await readFile43(pastePath, { encoding: "utf8" });
340099
+ return await readFile44(pastePath, { encoding: "utf8" });
339932
340100
  } catch (error) {
339933
340101
  if (!isENOENT2(error)) {
339934
340102
  logForDebugging3(`Failed to retrieve paste ${hash}: ${error}`);
@@ -339949,11 +340117,11 @@ async function cleanupOldPastes(cutoffDate) {
339949
340117
  if (!file.endsWith(".txt")) {
339950
340118
  continue;
339951
340119
  }
339952
- const filePath = join124(pasteDir, file);
340120
+ const filePath = join125(pasteDir, file);
339953
340121
  try {
339954
340122
  const stats = await stat42(filePath);
339955
340123
  if (stats.mtimeMs < cutoffTime) {
339956
- await unlink16(filePath);
340124
+ await unlink17(filePath);
339957
340125
  logForDebugging3(`Cleaned up old paste: ${filePath}`);
339958
340126
  }
339959
340127
  } catch {}
@@ -339967,8 +340135,8 @@ var init_pasteStore = __esm(() => {
339967
340135
  });
339968
340136
 
339969
340137
  // src/tui/history.ts
339970
- import { appendFile as appendFile5, writeFile as writeFile31 } from "fs/promises";
339971
- import { join as join125 } from "path";
340138
+ import { appendFile as appendFile5, writeFile as writeFile32 } from "fs/promises";
340139
+ import { join as join126 } from "path";
339972
340140
  function getPastedTextRefNumLines(text) {
339973
340141
  return (text.match(/\r\n|\r|\n/g) || []).length;
339974
340142
  }
@@ -340010,7 +340178,7 @@ async function* makeLogEntryReader() {
340010
340178
  for (let i = pendingEntries.length - 1;i >= 0; i--) {
340011
340179
  yield pendingEntries[i];
340012
340180
  }
340013
- const historyPath = join125(getAtlasConfigHomeDir3(), "history.jsonl");
340181
+ const historyPath = join126(getAtlasConfigHomeDir3(), "history.jsonl");
340014
340182
  try {
340015
340183
  for await (const line of readLinesReverse(historyPath)) {
340016
340184
  try {
@@ -340125,8 +340293,8 @@ async function immediateFlushHistory() {
340125
340293
  }
340126
340294
  let release;
340127
340295
  try {
340128
- const historyPath = join125(getAtlasConfigHomeDir3(), "history.jsonl");
340129
- await writeFile31(historyPath, "", {
340296
+ const historyPath = join126(getAtlasConfigHomeDir3(), "history.jsonl");
340297
+ await writeFile32(historyPath, "", {
340130
340298
  encoding: "utf8",
340131
340299
  mode: 384,
340132
340300
  flag: "a"
@@ -342326,7 +342494,7 @@ var init_TextInput = __esm(() => {
342326
342494
  });
342327
342495
 
342328
342496
  // src/tui/utils/suggestions/directoryCompletion.ts
342329
- 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";
342330
342498
  function parsePartialPath(partialPath, basePath) {
342331
342499
  if (!partialPath) {
342332
342500
  const directory = basePath || getCwd();
@@ -342350,7 +342518,7 @@ async function scanDirectory(dirPath) {
342350
342518
  const entries = await fs.readdir(dirPath);
342351
342519
  const directories = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => ({
342352
342520
  name: entry.name,
342353
- path: join126(dirPath, entry.name),
342521
+ path: join127(dirPath, entry.name),
342354
342522
  type: "directory"
342355
342523
  })).slice(0, 100);
342356
342524
  directoryCache.set(dirPath, directories);
@@ -342387,7 +342555,7 @@ async function scanDirectoryForPaths(dirPath, includeHidden = false) {
342387
342555
  const entries = await fs.readdir(dirPath);
342388
342556
  const paths = entries.filter((entry) => includeHidden || !entry.name.startsWith(".")).map((entry) => ({
342389
342557
  name: entry.name,
342390
- path: join126(dirPath, entry.name),
342558
+ path: join127(dirPath, entry.name),
342391
342559
  type: entry.isDirectory() ? "directory" : "file"
342392
342560
  })).sort((a, b) => {
342393
342561
  if (a.type === "directory" && b.type !== "directory")
@@ -343997,7 +344165,7 @@ var init_btw2 = __esm(() => {
343997
344165
  });
343998
344166
 
343999
344167
  // src/tui/components/Feedback.tsx
344000
- import { readFile as readFile44, stat as stat43 } from "fs/promises";
344168
+ import { readFile as readFile45, stat as stat43 } from "fs/promises";
344001
344169
  function redactSensitiveInfo(text) {
344002
344170
  let redacted = text;
344003
344171
  redacted = redacted.replace(/"(sk-ant[^\s"']{24,})"/g, '"[REDACTED_API_KEY]"');
@@ -344036,7 +344204,7 @@ async function loadRawTranscriptJsonl() {
344036
344204
  });
344037
344205
  return null;
344038
344206
  }
344039
- return await readFile44(transcriptPath, "utf-8");
344207
+ return await readFile45(transcriptPath, "utf-8");
344040
344208
  } catch {
344041
344209
  return null;
344042
344210
  }
@@ -345501,7 +345669,7 @@ var init_postSamplingHooks = __esm(() => {
345501
345669
  });
345502
345670
 
345503
345671
  // src/tui/services/MagicDocs/prompts.ts
345504
- import { join as join128 } from "path";
345672
+ import { join as join129 } from "path";
345505
345673
  function getUpdatePromptTemplate() {
345506
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.
345507
345675
 
@@ -345556,7 +345724,7 @@ REMEMBER: Only update if there is substantial new information. The Magic Doc hea
345556
345724
  }
345557
345725
  async function loadMagicDocsPrompt() {
345558
345726
  const fs = getFsImplementation2();
345559
- const promptPath = join128(getAtlasConfigHomeDir3(), "magic-docs", "prompt.md");
345727
+ const promptPath = join129(getAtlasConfigHomeDir3(), "magic-docs", "prompt.md");
345560
345728
  try {
345561
345729
  return await fs.readFile(promptPath, { encoding: "utf-8" });
345562
345730
  } catch {
@@ -346127,9 +346295,9 @@ __export(exports_copy, {
346127
346295
  collectRecentAssistantTexts: () => collectRecentAssistantTexts,
346128
346296
  fileExtension: () => fileExtension2
346129
346297
  });
346130
- import { mkdir as mkdir39, writeFile as writeFile32 } from "fs/promises";
346298
+ import { mkdir as mkdir39, writeFile as writeFile33 } from "fs/promises";
346131
346299
  import { tmpdir as tmpdir8 } from "os";
346132
- import { join as join129 } from "path";
346300
+ import { join as join130 } from "path";
346133
346301
  function extractCodeBlocks(markdown) {
346134
346302
  const tokens = k2.lexer(stripPromptXMLTags(markdown));
346135
346303
  const blocks = [];
@@ -346171,11 +346339,11 @@ function fileExtension2(lang) {
346171
346339
  return ".txt";
346172
346340
  }
346173
346341
  async function writeToFile(text, filename) {
346174
- const filePath = join129(COPY_DIR, filename);
346342
+ const filePath = join130(COPY_DIR, filename);
346175
346343
  await mkdir39(COPY_DIR, {
346176
346344
  recursive: true
346177
346345
  });
346178
- await writeFile32(filePath, text, "utf-8");
346346
+ await writeFile33(filePath, text, "utf-8");
346179
346347
  return filePath;
346180
346348
  }
346181
346349
  async function copyOrWriteToFile(text, filename) {
@@ -346501,7 +346669,7 @@ var init_copy = __esm(() => {
346501
346669
  import_compiler_runtime113 = __toESM(require_compiler_runtime(), 1);
346502
346670
  import_react81 = __toESM(require_react(), 1);
346503
346671
  jsx_dev_runtime138 = __toESM(require_jsx_dev_runtime(), 1);
346504
- COPY_DIR = join129(tmpdir8(), "atlas");
346672
+ COPY_DIR = join130(tmpdir8(), "atlas");
346505
346673
  });
346506
346674
 
346507
346675
  // src/tui/commands/copy/index.ts
@@ -347876,13 +348044,13 @@ var init_Tabs = __esm(() => {
347876
348044
  });
347877
348045
 
347878
348046
  // src/tui/utils/localInstaller.ts
347879
- import { access as access3, chmod as chmod6, writeFile as writeFile33 } from "fs/promises";
347880
- 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";
347881
348049
  function getLocalInstallDir() {
347882
- return join130(getAtlasConfigHomeDir3(), "local");
348050
+ return join131(getAtlasConfigHomeDir3(), "local");
347883
348051
  }
347884
348052
  function getLocalAtlasPath() {
347885
- return join130(getLocalInstallDir(), "atlas");
348053
+ return join131(getLocalInstallDir(), "atlas");
347886
348054
  }
347887
348055
  function isRunningFromLocalInstallation() {
347888
348056
  const execPath = process.argv[1] || "";
@@ -347890,7 +348058,7 @@ function isRunningFromLocalInstallation() {
347890
348058
  }
347891
348059
  async function writeIfMissing(path, content, mode) {
347892
348060
  try {
347893
- await writeFile33(path, content, { encoding: "utf8", flag: "wx", mode });
348061
+ await writeFile34(path, content, { encoding: "utf8", flag: "wx", mode });
347894
348062
  return true;
347895
348063
  } catch (e) {
347896
348064
  if (getErrnoCode2(e) === "EEXIST")
@@ -347902,8 +348070,8 @@ async function ensureLocalPackageEnvironment() {
347902
348070
  try {
347903
348071
  const localInstallDir = getLocalInstallDir();
347904
348072
  await getFsImplementation2().mkdir(localInstallDir);
347905
- await writeIfMissing(join130(localInstallDir, "package.json"), jsonStringify5({ name: "atlas-local", version: "0.0.1", private: true }, null, 2));
347906
- 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");
347907
348075
  const created = await writeIfMissing(wrapperPath, `#!/bin/sh
347908
348076
  exec "${localInstallDir}/node_modules/.bin/atlas" "$@"`, 493);
347909
348077
  if (created) {
@@ -347939,7 +348107,7 @@ async function installOrUpdateClaudePackage(channel, specificVersion) {
347939
348107
  }
347940
348108
  async function localInstallationExists() {
347941
348109
  try {
347942
- await access3(join130(getLocalInstallDir(), "node_modules", ".bin", "atlas"));
348110
+ await access3(join131(getLocalInstallDir(), "node_modules", ".bin", "atlas"));
347943
348111
  return true;
347944
348112
  } catch {
347945
348113
  return false;
@@ -347966,17 +348134,17 @@ var init_localInstaller = __esm(() => {
347966
348134
  });
347967
348135
 
347968
348136
  // src/tui/utils/shellConfig.ts
347969
- 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";
347970
348138
  import { homedir as osHomedir } from "os";
347971
- import { join as join131 } from "path";
348139
+ import { join as join132 } from "path";
347972
348140
  function getShellConfigPaths(options) {
347973
348141
  const home = options?.homedir ?? osHomedir();
347974
348142
  const env = options?.env ?? process.env;
347975
348143
  const zshConfigDir = env.ZDOTDIR || home;
347976
348144
  return {
347977
- zsh: join131(zshConfigDir, ".zshrc"),
347978
- bash: join131(home, ".bashrc"),
347979
- 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")
347980
348148
  };
347981
348149
  }
347982
348150
  function filterAtlasAliases(lines) {
@@ -348001,7 +348169,7 @@ function filterAtlasAliases(lines) {
348001
348169
  }
348002
348170
  async function readFileLines(filePath) {
348003
348171
  try {
348004
- const content = await readFile45(filePath, { encoding: "utf8" });
348172
+ const content = await readFile46(filePath, { encoding: "utf8" });
348005
348173
  return content.split(`
348006
348174
  `);
348007
348175
  } catch (e) {
@@ -348060,9 +348228,9 @@ var init_shellConfig = __esm(() => {
348060
348228
 
348061
348229
  // src/tui/utils/autoUpdater.ts
348062
348230
  import { constants as fsConstants6 } from "fs";
348063
- import { access as access4, writeFile as writeFile34 } from "fs/promises";
348231
+ import { access as access4, writeFile as writeFile35 } from "fs/promises";
348064
348232
  import { homedir as homedir32 } from "os";
348065
- import { join as join132 } from "path";
348233
+ import { join as join133 } from "path";
348066
348234
  async function assertMinVersion() {
348067
348235
  if (false) {}
348068
348236
  try {
@@ -348112,7 +348280,7 @@ function shouldSkipVersion(targetVersion) {
348112
348280
  return shouldSkip;
348113
348281
  }
348114
348282
  function getLockFilePath() {
348115
- return join132(getAtlasConfigHomeDir3(), ".update.lock");
348283
+ return join133(getAtlasConfigHomeDir3(), ".update.lock");
348116
348284
  }
348117
348285
  async function acquireLock() {
348118
348286
  const fs = getFsImplementation2();
@@ -348142,7 +348310,7 @@ async function acquireLock() {
348142
348310
  }
348143
348311
  }
348144
348312
  try {
348145
- await writeFile34(lockPath, `${process.pid}`, {
348313
+ await writeFile35(lockPath, `${process.pid}`, {
348146
348314
  encoding: "utf8",
348147
348315
  flag: "wx"
348148
348316
  });
@@ -348155,7 +348323,7 @@ async function acquireLock() {
348155
348323
  if (code === "ENOENT") {
348156
348324
  try {
348157
348325
  await fs.mkdir(getAtlasConfigHomeDir3());
348158
- await writeFile34(lockPath, `${process.pid}`, {
348326
+ await writeFile35(lockPath, `${process.pid}`, {
348159
348327
  encoding: "utf8",
348160
348328
  flag: "wx"
348161
348329
  });
@@ -348344,7 +348512,7 @@ var init_autoUpdater = __esm(() => {
348344
348512
  });
348345
348513
 
348346
348514
  // src/tui/utils/nativeInstaller/packageManagers.ts
348347
- import { readFile as readFile46 } from "fs/promises";
348515
+ import { readFile as readFile47 } from "fs/promises";
348348
348516
  function isDistroFamily(osRelease, families) {
348349
348517
  return families.includes(osRelease.id) || osRelease.idLike.some((like) => families.includes(like));
348350
348518
  }
@@ -348402,7 +348570,7 @@ var init_packageManagers = __esm(() => {
348402
348570
  init_platform3();
348403
348571
  getOsRelease = memoize_default(async () => {
348404
348572
  try {
348405
- const content = await readFile46("/etc/os-release", "utf8");
348573
+ const content = await readFile47("/etc/os-release", "utf8");
348406
348574
  const idMatch = content.match(/^ID=["']?(\S+?)["']?\s*$/m);
348407
348575
  const idLikeMatch = content.match(/^ID_LIKE=["']?(.+?)["']?\s*$/m);
348408
348576
  return {
@@ -348523,9 +348691,9 @@ var init_packageManagers = __esm(() => {
348523
348691
  });
348524
348692
 
348525
348693
  // src/tui/utils/doctorDiagnostic.ts
348526
- import { readFile as readFile47, realpath as realpath12 } from "fs/promises";
348694
+ import { readFile as readFile48, realpath as realpath12 } from "fs/promises";
348527
348695
  import { homedir as homedir33 } from "os";
348528
- 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";
348529
348697
  function getNormalizedPaths() {
348530
348698
  let invokedPath = process.argv[1] || "";
348531
348699
  let execPath = process.execPath || process.argv[0] || "";
@@ -348588,8 +348756,8 @@ async function getInstallationPath() {
348588
348756
  }
348589
348757
  } catch {}
348590
348758
  try {
348591
- await getFsImplementation2().stat(join133(homedir33(), ".local/bingetConfigDirName()"));
348592
- return join133(homedir33(), ".local/bingetConfigDirName()");
348759
+ await getFsImplementation2().stat(join134(homedir33(), ".local/bingetConfigDirName()"));
348760
+ return join134(homedir33(), ".local/bingetConfigDirName()");
348593
348761
  } catch {}
348594
348762
  return "native";
348595
348763
  }
@@ -348612,7 +348780,7 @@ function getInvokedBinary() {
348612
348780
  async function detectMultipleInstallations() {
348613
348781
  const fs = getFsImplementation2();
348614
348782
  const installations = [];
348615
- const localPath = join133(homedir33(), getConfigDirName2(), "local");
348783
+ const localPath = join134(homedir33(), getConfigDirName2(), "local");
348616
348784
  if (await localInstallationExists()) {
348617
348785
  installations.push({ type: "npm-local", path: localPath });
348618
348786
  }
@@ -348629,7 +348797,7 @@ async function detectMultipleInstallations() {
348629
348797
  if (npmResult.code === 0 && npmResult.stdout) {
348630
348798
  const npmPrefix = npmResult.stdout.trim();
348631
348799
  const isWindows = getPlatform3() === "windows";
348632
- const globalBinPath = isWindows ? join133(npmPrefix, "atlas") : join133(npmPrefix, "bin", "atlas");
348800
+ const globalBinPath = isWindows ? join134(npmPrefix, "atlas") : join134(npmPrefix, "bin", "atlas");
348633
348801
  let globalBinExists = false;
348634
348802
  try {
348635
348803
  await fs.stat(globalBinPath);
@@ -348648,7 +348816,7 @@ async function detectMultipleInstallations() {
348648
348816
  }
348649
348817
  } else {
348650
348818
  for (const packageName of packagesToCheck) {
348651
- 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);
348652
348820
  try {
348653
348821
  await fs.stat(globalPackagePath);
348654
348822
  installations.push({
@@ -348659,14 +348827,14 @@ async function detectMultipleInstallations() {
348659
348827
  }
348660
348828
  }
348661
348829
  }
348662
- const nativeBinPath = join133(homedir33(), ".local", "bin", "atlas");
348830
+ const nativeBinPath = join134(homedir33(), ".local", "bin", "atlas");
348663
348831
  try {
348664
348832
  await fs.stat(nativeBinPath);
348665
348833
  installations.push({ type: "native", path: nativeBinPath });
348666
348834
  } catch {}
348667
348835
  const config = getGlobalConfig();
348668
348836
  if (config.installMethod === "native") {
348669
- const nativeDataPath = join133(homedir33(), ".local", "share", "atlas");
348837
+ const nativeDataPath = join134(homedir33(), ".local", "share", "atlas");
348670
348838
  try {
348671
348839
  await fs.stat(nativeDataPath);
348672
348840
  if (!installations.some((i) => i.type === "native")) {
@@ -348679,7 +348847,7 @@ async function detectMultipleInstallations() {
348679
348847
  async function detectConfigurationIssues(type) {
348680
348848
  const warnings = [];
348681
348849
  try {
348682
- const raw = await readFile47(join133(getManagedFilePath(), "managed-settings.json"), "utf-8");
348850
+ const raw = await readFile48(join134(getManagedFilePath(), "managed-settings.json"), "utf-8");
348683
348851
  const parsed = jsonParse2(raw);
348684
348852
  const field = parsed && typeof parsed === "object" ? parsed.strictPluginOnlyCustomization : undefined;
348685
348853
  if (field !== undefined && typeof field !== "boolean") {
@@ -348707,7 +348875,7 @@ async function detectConfigurationIssues(type) {
348707
348875
  const path = process.env.PATH || "";
348708
348876
  const pathDirectories = path.split(delimiter2);
348709
348877
  const homeDir = homedir33();
348710
- const localBinPath = join133(homeDir, ".local", "bin");
348878
+ const localBinPath = join134(homeDir, ".local", "bin");
348711
348879
  let normalizedLocalBinPath = localBinPath;
348712
348880
  if (getPlatform3() === "windows") {
348713
348881
  normalizedLocalBinPath = localBinPath.split(win322.sep).join(posix8.sep);
@@ -348894,7 +349062,7 @@ var init_doctorDiagnostic = __esm(() => {
348894
349062
 
348895
349063
  // src/tui/utils/xdg.ts
348896
349064
  import { homedir as osHomedir2 } from "os";
348897
- import { join as join134 } from "path";
349065
+ import { join as join135 } from "path";
348898
349066
  function resolveOptions2(options) {
348899
349067
  return {
348900
349068
  env: options?.env ?? process.env,
@@ -348903,193 +349071,42 @@ function resolveOptions2(options) {
348903
349071
  }
348904
349072
  function getXDGStateHome(options) {
348905
349073
  const { env, home } = resolveOptions2(options);
348906
- return env.XDG_STATE_HOME ?? join134(home, ".local", "state");
349074
+ return env.XDG_STATE_HOME ?? join135(home, ".local", "state");
348907
349075
  }
348908
349076
  function getXDGCacheHome(options) {
348909
349077
  const { env, home } = resolveOptions2(options);
348910
- return env.XDG_CACHE_HOME ?? join134(home, ".cache");
349078
+ return env.XDG_CACHE_HOME ?? join135(home, ".cache");
348911
349079
  }
348912
349080
  function getXDGDataHome(options) {
348913
349081
  const { env, home } = resolveOptions2(options);
348914
- return env.XDG_DATA_HOME ?? join134(home, ".local", "share");
349082
+ return env.XDG_DATA_HOME ?? join135(home, ".local", "share");
348915
349083
  }
348916
349084
  function getUserBinDir(options) {
348917
349085
  const { home } = resolveOptions2(options);
348918
- return join134(home, ".local", "bin");
349086
+ return join135(home, ".local", "bin");
348919
349087
  }
348920
349088
  var init_xdg = () => {};
348921
349089
 
348922
349090
  // src/tui/utils/nativeInstaller/download.ts
348923
- import { createHash as createHash11 } from "crypto";
348924
- import { chmod as chmod7, writeFile as writeFile35 } from "fs/promises";
348925
- import { join as join135 } from "path";
348926
- async function getLatestVersionFromBinaryRepo(channel = "latest", baseUrl, authConfig) {
348927
- const startTime = Date.now();
348928
- try {
348929
- const response = await axios_default.get(`${baseUrl}/${channel}`, {
348930
- timeout: 30000,
348931
- responseType: "text",
348932
- ...authConfig
348933
- });
348934
- const latencyMs = Date.now() - startTime;
348935
- return response.data.trim();
348936
- } catch (error) {
348937
- const latencyMs = Date.now() - startTime;
348938
- const errorMessage = error instanceof Error ? error.message : String(error);
348939
- let httpStatus;
348940
- if (axios_default.isAxiosError(error) && error.response) {
348941
- httpStatus = error.response.status;
348942
- }
348943
- const fetchError = new Error(`Failed to fetch version from ${baseUrl}/${channel}: ${errorMessage}`);
348944
- logError3(fetchError);
348945
- throw fetchError;
348946
- }
348947
- }
348948
349091
  async function getLatestVersion2(channelOrVersion) {
348949
349092
  if (/^v?\d+\.\d+\.\d+(-\S+)?$/.test(channelOrVersion)) {
348950
349093
  const normalized = channelOrVersion.startsWith("v") ? channelOrVersion.slice(1) : channelOrVersion;
348951
349094
  if (/^99\.99\./.test(normalized) && !feature("ALLOW_TEST_VERSIONS")) {
348952
349095
  throw new Error(`Version ${normalized} is not available for installation. Use 'stable' or 'latest'.`);
348953
349096
  }
348954
- return normalized;
349097
+ throw new Error(`Version ${normalized} cannot be installed: this product has no native distribution form (npm package / git source only)`);
348955
349098
  }
348956
349099
  const channel = channelOrVersion;
348957
349100
  if (channel !== "stable" && channel !== "latest") {
348958
349101
  throw new Error(`Invalid channel: ${channelOrVersion}. Use 'stable' or 'latest'`);
348959
349102
  }
348960
- return getLatestVersionFromBinaryRepo(channel, GCS_BUCKET_URL);
349103
+ throw new Error(`Channel '${channel}' cannot be resolved: this product has no native distribution form (npm package / git source only)`);
348961
349104
  }
348962
- function getStallTimeoutMs() {
348963
- return Number(process.env.ATLAS_STALL_TIMEOUT_MS_FOR_TESTING) || DEFAULT_STALL_TIMEOUT_MS;
348964
- }
348965
- async function downloadAndVerifyBinary(binaryUrl, expectedChecksum, binaryPath, requestConfig = {}) {
348966
- let lastError;
348967
- for (let attempt = 1;attempt <= MAX_DOWNLOAD_RETRIES; attempt++) {
348968
- const controller = new AbortController;
348969
- let stallTimer;
348970
- const clearStallTimer = () => {
348971
- if (stallTimer) {
348972
- clearTimeout(stallTimer);
348973
- stallTimer = undefined;
348974
- }
348975
- };
348976
- const resetStallTimer = () => {
348977
- clearStallTimer();
348978
- stallTimer = setTimeout((c) => c.abort(), getStallTimeoutMs(), controller);
348979
- };
348980
- try {
348981
- resetStallTimer();
348982
- const response = await axios_default.get(binaryUrl, {
348983
- timeout: 5 * 60000,
348984
- responseType: "arraybuffer",
348985
- signal: controller.signal,
348986
- onDownloadProgress: () => {
348987
- resetStallTimer();
348988
- },
348989
- ...requestConfig
348990
- });
348991
- clearStallTimer();
348992
- const hash = createHash11("sha256");
348993
- hash.update(response.data);
348994
- const actualChecksum = hash.digest("hex");
348995
- if (actualChecksum !== expectedChecksum) {
348996
- throw new Error(`Checksum mismatch: expected ${expectedChecksum}, got ${actualChecksum}`);
348997
- }
348998
- await writeFile35(binaryPath, Buffer.from(response.data));
348999
- await chmod7(binaryPath, 493);
349000
- return;
349001
- } catch (error) {
349002
- clearStallTimer();
349003
- const isStallTimeout = axios_default.isCancel(error);
349004
- if (isStallTimeout) {
349005
- lastError = new StallTimeoutError;
349006
- } else {
349007
- lastError = toError2(error);
349008
- }
349009
- if (isStallTimeout && attempt < MAX_DOWNLOAD_RETRIES) {
349010
- logForDebugging3(`Download stalled on attempt ${attempt}/${MAX_DOWNLOAD_RETRIES}, retrying...`);
349011
- await sleep9(1000);
349012
- continue;
349013
- }
349014
- throw lastError;
349015
- }
349016
- }
349017
- throw lastError ?? new Error("Download failed after all retries");
349105
+ async function downloadVersion(_version, _stagingPath) {
349106
+ throw new Error("Native binary download is not available in this product (no native distribution form; npm package / git source only)");
349018
349107
  }
349019
- async function downloadVersionFromBinaryRepo(version, stagingPath, baseUrl, authConfig) {
349020
- const fs = getFsImplementation2();
349021
- await fs.rm(stagingPath, { recursive: true, force: true });
349022
- const platform = getPlatform4();
349023
- const startTime = Date.now();
349024
- let manifest;
349025
- try {
349026
- const manifestResponse = await axios_default.get(`${baseUrl}/${version}/manifest.json`, {
349027
- timeout: 1e4,
349028
- responseType: "json",
349029
- ...authConfig
349030
- });
349031
- manifest = manifestResponse.data;
349032
- } catch (error) {
349033
- const latencyMs = Date.now() - startTime;
349034
- const errorMessage = error instanceof Error ? error.message : String(error);
349035
- let httpStatus;
349036
- if (axios_default.isAxiosError(error) && error.response) {
349037
- httpStatus = error.response.status;
349038
- }
349039
- logError3(new Error(`Failed to fetch manifest from ${baseUrl}/${version}/manifest.json: ${errorMessage}`));
349040
- throw error;
349041
- }
349042
- const platformInfo = manifest.platforms[platform];
349043
- if (!platformInfo) {
349044
- throw new Error(`Platform ${platform} not found in manifest for version ${version}`);
349045
- }
349046
- const expectedChecksum = platformInfo.checksum;
349047
- const binaryName = getBinaryName(platform);
349048
- const binaryUrl = `${baseUrl}/${version}/${platform}/${binaryName}`;
349049
- await fs.mkdir(stagingPath);
349050
- const binaryPath = join135(stagingPath, binaryName);
349051
- try {
349052
- await downloadAndVerifyBinary(binaryUrl, expectedChecksum, binaryPath, authConfig || {});
349053
- const latencyMs = Date.now() - startTime;
349054
- } catch (error) {
349055
- const latencyMs = Date.now() - startTime;
349056
- const errorMessage = error instanceof Error ? error.message : String(error);
349057
- let httpStatus;
349058
- if (axios_default.isAxiosError(error) && error.response) {
349059
- httpStatus = error.response.status;
349060
- }
349061
- logError3(new Error(`Failed to download binary from ${binaryUrl}: ${errorMessage}`));
349062
- throw error;
349063
- }
349064
- }
349065
- async function downloadVersion(version, stagingPath) {
349066
- if (feature("ALLOW_TEST_VERSIONS") && /^99\.99\./.test(version)) {
349067
- const { stdout } = await execFileNoThrowWithCwd2("gcloud", [
349068
- "auth",
349069
- "print-access-token"
349070
- ]);
349071
- await downloadVersionFromBinaryRepo(version, stagingPath, "https://storage.googleapis.com/claude-code-ci-sentinel", { headers: { Authorization: `Bearer ${stdout.trim()}` } });
349072
- return "binary";
349073
- }
349074
- await downloadVersionFromBinaryRepo(version, stagingPath, GCS_BUCKET_URL);
349075
- return "binary";
349076
- }
349077
- var GCS_BUCKET_URL = "https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases", DEFAULT_STALL_TIMEOUT_MS = 60000, MAX_DOWNLOAD_RETRIES = 3, StallTimeoutError;
349078
349108
  var init_download = __esm(() => {
349079
349109
  init_shared();
349080
- init_axios2();
349081
- init_debug();
349082
- init_errors4();
349083
- init_execFileNoThrow2();
349084
- init_fsOperations();
349085
- init_log5();
349086
- init_installer();
349087
- StallTimeoutError = class StallTimeoutError extends Error {
349088
- constructor() {
349089
- super("Download stalled: no data received for 60 seconds");
349090
- this.name = "StallTimeoutError";
349091
- }
349092
- };
349093
349110
  });
349094
349111
 
349095
349112
  // src/tui/utils/nativeInstaller/pidLock.ts
@@ -349327,19 +349344,19 @@ var init_pidLock = __esm(() => {
349327
349344
  import { constants as fsConstants7 } from "fs";
349328
349345
  import {
349329
349346
  access as access5,
349330
- chmod as chmod8,
349347
+ chmod as chmod7,
349331
349348
  copyFile as copyFile8,
349332
349349
  lstat as lstat6,
349333
349350
  mkdir as mkdir40,
349334
349351
  readdir as readdir26,
349335
349352
  readlink as readlink2,
349336
349353
  realpath as realpath13,
349337
- rename as rename7,
349354
+ rename as rename8,
349338
349355
  rm as rm10,
349339
349356
  rmdir as rmdir2,
349340
349357
  stat as stat45,
349341
349358
  symlink as symlink6,
349342
- unlink as unlink17,
349359
+ unlink as unlink18,
349343
349360
  writeFile as writeFile36
349344
349361
  } from "fs/promises";
349345
349362
  import { homedir as homedir34 } from "os";
@@ -349466,12 +349483,12 @@ async function atomicMoveToInstallPath(stagedBinaryPath, installPath) {
349466
349483
  const tempInstallPath = `${installPath}.tmp.${process.pid}.${Date.now()}`;
349467
349484
  try {
349468
349485
  await copyFile8(stagedBinaryPath, tempInstallPath);
349469
- await chmod8(tempInstallPath, 493);
349470
- await rename7(tempInstallPath, installPath);
349486
+ await chmod7(tempInstallPath, 493);
349487
+ await rename8(tempInstallPath, installPath);
349471
349488
  logForDebugging3(`Atomically installed binary to ${installPath}`);
349472
349489
  } catch (error) {
349473
349490
  try {
349474
- await unlink17(tempInstallPath);
349491
+ await unlink18(tempInstallPath);
349475
349492
  } catch {}
349476
349493
  throw error;
349477
349494
  }
@@ -349642,15 +349659,15 @@ async function updateSymlink(symlinkPath, targetPath) {
349642
349659
  }
349643
349660
  } catch {}
349644
349661
  const oldFileName = `${symlinkPath}.old.${Date.now()}`;
349645
- await rename7(symlinkPath, oldFileName);
349662
+ await rename8(symlinkPath, oldFileName);
349646
349663
  try {
349647
349664
  await copyFile8(targetPath, symlinkPath);
349648
349665
  try {
349649
- await unlink17(oldFileName);
349666
+ await unlink18(oldFileName);
349650
349667
  } catch {}
349651
349668
  } catch (copyError) {
349652
349669
  try {
349653
- await rename7(oldFileName, symlinkPath);
349670
+ await rename8(oldFileName, symlinkPath);
349654
349671
  } catch (restoreError) {
349655
349672
  const errorWithCause = new Error(`Failed to restore old executable: ${restoreError}`, { cause: copyError });
349656
349673
  logError3(errorWithCause);
@@ -349697,7 +349714,7 @@ async function updateSymlink(symlinkPath, targetPath) {
349697
349714
  return false;
349698
349715
  }
349699
349716
  } catch {}
349700
- await unlink17(symlinkPath);
349717
+ await unlink18(symlinkPath);
349701
349718
  }
349702
349719
  } catch (error) {
349703
349720
  logError3(new Error(`Failed to check/remove existing symlink: ${error}`));
@@ -349705,12 +349722,12 @@ async function updateSymlink(symlinkPath, targetPath) {
349705
349722
  const tempSymlink = `${symlinkPath}.tmp.${process.pid}.${Date.now()}`;
349706
349723
  try {
349707
349724
  await symlink6(targetPath, tempSymlink);
349708
- await rename7(tempSymlink, symlinkPath);
349725
+ await rename8(tempSymlink, symlinkPath);
349709
349726
  logForDebugging3(`Atomically updated symlink ${symlinkPath} -> ${targetPath}`);
349710
349727
  return true;
349711
349728
  } catch (error) {
349712
349729
  try {
349713
- await unlink17(tempSymlink);
349730
+ await unlink18(tempSymlink);
349714
349731
  } catch {}
349715
349732
  logError3(new Error(`Failed to create symlink from ${symlinkPath} to ${targetPath}: ${error}`));
349716
349733
  return false;
@@ -349930,7 +349947,7 @@ async function forceRemoveLock(versionFilePath) {
349930
349947
  const dirs = getBaseDirectories();
349931
349948
  const lockfilePath = getLockFilePathFromVersionPath(dirs, versionFilePath);
349932
349949
  try {
349933
- await unlink17(lockfilePath);
349950
+ await unlink18(lockfilePath);
349934
349951
  logForDebugging3(`Force-removed lock file at ${lockfilePath}`);
349935
349952
  } catch (error) {
349936
349953
  logForDebugging3(`Failed to force-remove lock file: ${errorMessage2(error)}`);
@@ -349949,7 +349966,7 @@ async function cleanupOldVersions() {
349949
349966
  if (!/atlas\.exe\.old\.\d+$/.test(file))
349950
349967
  continue;
349951
349968
  try {
349952
- await unlink17(join137(executableDir, file));
349969
+ await unlink18(join137(executableDir, file));
349953
349970
  cleanedCount++;
349954
349971
  } catch {}
349955
349972
  }
@@ -350007,7 +350024,7 @@ async function cleanupOldVersions() {
350007
350024
  try {
350008
350025
  const stats = await stat45(entryPath);
350009
350026
  if (stats.mtime.getTime() < oneHourAgo) {
350010
- await unlink17(entryPath);
350027
+ await unlink18(entryPath);
350011
350028
  tempFilesCleanedCount++;
350012
350029
  logForDebugging3(`Cleaned up orphaned temp install file: ${entry}`);
350013
350030
  }
@@ -350078,7 +350095,7 @@ async function cleanupOldVersions() {
350078
350095
  await Promise.all(versionsToDelete.map(async (version) => {
350079
350096
  try {
350080
350097
  const deleted = await tryWithVersionLock(version.path, async () => {
350081
- await unlink17(version.path);
350098
+ await unlink18(version.path);
350082
350099
  });
350083
350100
  if (deleted) {
350084
350101
  deletedCount++;
@@ -350112,7 +350129,7 @@ async function removeInstalledSymlink() {
350112
350129
  logForDebugging3(`Skipping removal of ${dirs.executable} - appears to be npm-managed`);
350113
350130
  return;
350114
350131
  }
350115
- await unlink17(dirs.executable);
350132
+ await unlink18(dirs.executable);
350116
350133
  logForDebugging3(`Removed atlas symlink at ${dirs.executable}`);
350117
350134
  } catch (error) {
350118
350135
  if (isENOENT2(error)) {
@@ -350167,7 +350184,7 @@ async function manualRemoveNpmPackage(packageName) {
350167
350184
  let manuallyRemoved = false;
350168
350185
  async function tryRemove(filePath, description) {
350169
350186
  try {
350170
- await unlink17(filePath);
350187
+ await unlink18(filePath);
350171
350188
  logForDebugging3(`Manually removed ${description}: ${filePath}`);
350172
350189
  return true;
350173
350190
  } catch {
@@ -353493,54 +353510,6 @@ function Config({
353493
353510
  onChange() {}
353494
353511
  }];
353495
353512
  })() : [],
353496
- ...feature("BRIDGE_MODE") && isBridgeEnabled() ? [{
353497
- id: "remoteControlAtStartup",
353498
- label: "Enable Remote Control for all sessions",
353499
- value: globalConfig.remoteControlAtStartup === undefined ? "default" : String(globalConfig.remoteControlAtStartup),
353500
- options: ["true", "false", "default"],
353501
- type: "enum",
353502
- onChange(selected_0) {
353503
- if (selected_0 === "default") {
353504
- saveGlobalConfig((current_20) => {
353505
- if (current_20.remoteControlAtStartup === undefined)
353506
- return current_20;
353507
- const next_0 = {
353508
- ...current_20
353509
- };
353510
- delete next_0.remoteControlAtStartup;
353511
- return next_0;
353512
- });
353513
- setGlobalConfig({
353514
- ...getGlobalConfig(),
353515
- remoteControlAtStartup: undefined
353516
- });
353517
- } else {
353518
- const enabled_6 = selected_0 === "true";
353519
- saveGlobalConfig((current_21) => {
353520
- if (current_21.remoteControlAtStartup === enabled_6)
353521
- return current_21;
353522
- return {
353523
- ...current_21,
353524
- remoteControlAtStartup: enabled_6
353525
- };
353526
- });
353527
- setGlobalConfig({
353528
- ...getGlobalConfig(),
353529
- remoteControlAtStartup: enabled_6
353530
- });
353531
- }
353532
- const resolved = getRemoteControlAtStartup();
353533
- setAppState((prev_20) => {
353534
- if (prev_20.replBridgeEnabled === resolved && !prev_20.replBridgeOutboundOnly)
353535
- return prev_20;
353536
- return {
353537
- ...prev_20,
353538
- replBridgeEnabled: resolved,
353539
- replBridgeOutboundOnly: false
353540
- };
353541
- });
353542
- }
353543
- }] : [],
353544
353513
  ...shouldShowExternalIncludesToggle ? [{
353545
353514
  id: "showExternalIncludesDialog",
353546
353515
  label: "External ATLAS.md includes",
@@ -353708,10 +353677,6 @@ function Config({
353708
353677
  if (globalConfig.showTurnDuration !== initialConfig.current.showTurnDuration) {
353709
353678
  formattedChanges.push(`${globalConfig.showTurnDuration ? "Enabled" : "Disabled"} turn duration`);
353710
353679
  }
353711
- if (globalConfig.remoteControlAtStartup !== initialConfig.current.remoteControlAtStartup) {
353712
- const remoteLabel = globalConfig.remoteControlAtStartup === undefined ? "Reset Remote Control to default" : `${globalConfig.remoteControlAtStartup ? "Enabled" : "Disabled"} Remote Control for all sessions`;
353713
- formattedChanges.push(remoteLabel);
353714
- }
353715
353680
  if (settingsData?.autoUpdatesChannel !== initialSettingsData.current?.autoUpdatesChannel) {
353716
353681
  formattedChanges.push(`Set auto-update channel to ${source_default.bold(settingsData?.autoUpdatesChannel ?? "latest")}`);
353717
353682
  }
@@ -354520,7 +354485,7 @@ function NotifChannelLabel(t0) {
354520
354485
  }
354521
354486
  }
354522
354487
  }
354523
- var import_compiler_runtime124, React45, import_react90, jsx_dev_runtime151, isBridgeEnabled = () => false, THEME_LABELS;
354488
+ var import_compiler_runtime124, React45, import_react90, jsx_dev_runtime151, THEME_LABELS;
354524
354489
  var init_Config = __esm(() => {
354525
354490
  init_shared();
354526
354491
  init_ink2();
@@ -360661,11 +360626,11 @@ var init_editor = __esm(() => {
360661
360626
  });
360662
360627
 
360663
360628
  // src/tui/utils/tempfile.ts
360664
- import { createHash as createHash12, randomUUID as randomUUID38 } from "crypto";
360629
+ import { createHash as createHash11, randomUUID as randomUUID38 } from "crypto";
360665
360630
  import { tmpdir as tmpdir9 } from "os";
360666
360631
  import { join as join139 } from "path";
360667
360632
  function generateTempFilePath2(prefix = "atlas-prompt", extension = ".md", options) {
360668
- const id = options?.contentHash ? createHash12("sha256").update(options.contentHash).digest("hex").slice(0, 16) : randomUUID38();
360633
+ const id = options?.contentHash ? createHash11("sha256").update(options.contentHash).digest("hex").slice(0, 16) : randomUUID38();
360669
360634
  return join139(tmpdir9(), `${prefix}-${id}${extension}`);
360670
360635
  }
360671
360636
  var init_tempfile = () => {};
@@ -370024,7 +369989,7 @@ var init_mcp7 = __esm(() => {
370024
369989
  });
370025
369990
 
370026
369991
  // src/tui/utils/releaseNotes.ts
370027
- import { mkdir as mkdir44, readFile as readFile48, writeFile as writeFile39 } from "fs/promises";
369992
+ import { mkdir as mkdir44, readFile as readFile49, writeFile as writeFile39 } from "fs/promises";
370028
369993
  import { dirname as dirname71, join as join140 } from "path";
370029
369994
  function getChangelogCachePath() {
370030
369995
  return join140(getAtlasConfigHomeDir3(), "cache", "changelog.md");
@@ -370074,7 +370039,7 @@ async function getStoredChangelog() {
370074
370039
  }
370075
370040
  const cachePath = getChangelogCachePath();
370076
370041
  try {
370077
- const content = await readFile48(cachePath, "utf-8");
370042
+ const content = await readFile49(cachePath, "utf-8");
370078
370043
  changelogMemoryCache = content;
370079
370044
  return content;
370080
370045
  } catch {
@@ -370423,9 +370388,9 @@ var init_rename = __esm(() => {
370423
370388
  });
370424
370389
 
370425
370390
  // src/tui/commands/rename/index.ts
370426
- var rename8, rename_default;
370391
+ var rename9, rename_default;
370427
370392
  var init_rename2 = __esm(() => {
370428
- rename8 = {
370393
+ rename9 = {
370429
370394
  type: "local-jsx",
370430
370395
  name: "rename",
370431
370396
  description: "Rename the current conversation",
@@ -370433,7 +370398,7 @@ var init_rename2 = __esm(() => {
370433
370398
  argumentHint: "[name]",
370434
370399
  load: () => Promise.resolve().then(() => (init_rename(), exports_rename))
370435
370400
  };
370436
- rename_default = rename8;
370401
+ rename_default = rename9;
370437
370402
  });
370438
370403
 
370439
370404
  // src/tui/utils/getWorktreePaths.ts
@@ -388030,7 +387995,7 @@ __export(exports_thinkback, {
388030
387995
  call: () => call34,
388031
387996
  playAnimation: () => playAnimation
388032
387997
  });
388033
- import { readFile as readFile49 } from "fs/promises";
387998
+ import { readFile as readFile50 } from "fs/promises";
388034
387999
  import { join as join143 } from "path";
388035
388000
  function getMarketplaceName() {
388036
388001
  return OFFICIAL_MARKETPLACE_NAME;
@@ -388059,7 +388024,7 @@ async function playAnimation(skillDir) {
388059
388024
  const dataPath = join143(skillDir, "year_in_review.js");
388060
388025
  const playerPath = join143(skillDir, "player.js");
388061
388026
  try {
388062
- await readFile49(dataPath);
388027
+ await readFile50(dataPath);
388063
388028
  } catch (e) {
388064
388029
  if (isENOENT2(e)) {
388065
388030
  return {
@@ -388074,7 +388039,7 @@ async function playAnimation(skillDir) {
388074
388039
  };
388075
388040
  }
388076
388041
  try {
388077
- await readFile49(playerPath);
388042
+ await readFile50(playerPath);
388078
388043
  } catch (e) {
388079
388044
  if (isENOENT2(e)) {
388080
388045
  return {
@@ -393153,7 +393118,7 @@ __export(exports_branch, {
393153
393118
  getUniqueForkName: () => getUniqueForkName
393154
393119
  });
393155
393120
  import { randomUUID as randomUUID39 } from "crypto";
393156
- import { mkdir as mkdir45, readFile as readFile50, writeFile as writeFile40 } from "fs/promises";
393121
+ import { mkdir as mkdir45, readFile as readFile51, writeFile as writeFile40 } from "fs/promises";
393157
393122
  function deriveFirstPrompt(firstUserMessage) {
393158
393123
  const content = firstUserMessage?.message?.content;
393159
393124
  if (!content)
@@ -393172,7 +393137,7 @@ async function createFork(customTitle, target) {
393172
393137
  await mkdir45(projectDir, { recursive: true, mode: 448 });
393173
393138
  let transcriptContent;
393174
393139
  try {
393175
- transcriptContent = await readFile50(currentTranscriptPath);
393140
+ transcriptContent = await readFile51(currentTranscriptPath);
393176
393141
  } catch {
393177
393142
  throw new Error("No conversation to branch");
393178
393143
  }
@@ -393494,7 +393459,7 @@ var init_types16 = __esm(() => {
393494
393459
  });
393495
393460
 
393496
393461
  // src/tui/components/agents/agentFileUtils.ts
393497
- import { mkdir as mkdir46, open as open15, unlink as unlink18 } from "fs/promises";
393462
+ import { mkdir as mkdir46, open as open15, unlink as unlink19 } from "fs/promises";
393498
393463
  import { join as join145 } from "path";
393499
393464
  function formatAgentAsMarkdown(agentType, whenToUse, tools, systemPrompt, color, model, memory, effort) {
393500
393465
  const escapedWhenToUse = whenToUse.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\\\n");
@@ -393610,7 +393575,7 @@ async function deleteAgentFromFile(agent) {
393610
393575
  }
393611
393576
  const filePath = getActualAgentFilePath(agent);
393612
393577
  try {
393613
- await unlink18(filePath);
393578
+ await unlink19(filePath);
393614
393579
  } catch (e) {
393615
393580
  const code = getErrnoCode2(e);
393616
393581
  if (code !== "ENOENT") {
@@ -399838,152 +399803,6 @@ var init_MarketplaceAdopt = __esm(() => {
399838
399803
  jsx_dev_runtime281 = __toESM(require_jsx_dev_runtime(), 1);
399839
399804
  });
399840
399805
 
399841
- // src/tui/utils/plugins/installCounts.ts
399842
- import { randomBytes as randomBytes18 } from "crypto";
399843
- import { readFile as readFile51, rename as rename9, unlink as unlink19, writeFile as writeFile41 } from "fs/promises";
399844
- import { join as join146 } from "path";
399845
- function getInstallCountsCachePath() {
399846
- return join146(getPluginsDirectory(), INSTALL_COUNTS_CACHE_FILENAME);
399847
- }
399848
- async function loadInstallCountsCache() {
399849
- const cachePath = getInstallCountsCachePath();
399850
- try {
399851
- const content = await readFile51(cachePath, { encoding: "utf-8" });
399852
- const parsed = jsonParse2(content);
399853
- if (typeof parsed !== "object" || parsed === null || !("version" in parsed) || !("fetchedAt" in parsed) || !("counts" in parsed)) {
399854
- logForDebugging3("Install counts cache has invalid structure");
399855
- return null;
399856
- }
399857
- const cache = parsed;
399858
- if (cache.version !== INSTALL_COUNTS_CACHE_VERSION) {
399859
- logForDebugging3(`Install counts cache version mismatch (got ${cache.version}, expected ${INSTALL_COUNTS_CACHE_VERSION})`);
399860
- return null;
399861
- }
399862
- if (typeof cache.fetchedAt !== "string" || !Array.isArray(cache.counts)) {
399863
- logForDebugging3("Install counts cache has invalid structure");
399864
- return null;
399865
- }
399866
- const fetchedAt = new Date(cache.fetchedAt).getTime();
399867
- if (Number.isNaN(fetchedAt)) {
399868
- logForDebugging3("Install counts cache has invalid fetchedAt timestamp");
399869
- return null;
399870
- }
399871
- const validCounts = cache.counts.every((entry) => typeof entry === "object" && entry !== null && typeof entry.plugin === "string" && typeof entry.unique_installs === "number");
399872
- if (!validCounts) {
399873
- logForDebugging3("Install counts cache has malformed entries");
399874
- return null;
399875
- }
399876
- const now = Date.now();
399877
- if (now - fetchedAt > CACHE_TTL_MS3) {
399878
- logForDebugging3("Install counts cache is stale (>24h old)");
399879
- return null;
399880
- }
399881
- return {
399882
- version: cache.version,
399883
- fetchedAt: cache.fetchedAt,
399884
- counts: cache.counts
399885
- };
399886
- } catch (error) {
399887
- const code = getErrnoCode2(error);
399888
- if (code !== "ENOENT") {
399889
- logForDebugging3(`Failed to load install counts cache: ${errorMessage2(error)}`);
399890
- }
399891
- return null;
399892
- }
399893
- }
399894
- async function saveInstallCountsCache(cache) {
399895
- const cachePath = getInstallCountsCachePath();
399896
- const tempPath = `${cachePath}.${randomBytes18(8).toString("hex")}.tmp`;
399897
- try {
399898
- const pluginsDir = getPluginsDirectory();
399899
- await getFsImplementation2().mkdir(pluginsDir);
399900
- const content = jsonStringify5(cache, null, 2);
399901
- await writeFile41(tempPath, content, {
399902
- encoding: "utf-8",
399903
- mode: 384
399904
- });
399905
- await rename9(tempPath, cachePath);
399906
- logForDebugging3("Install counts cache saved successfully");
399907
- } catch (error) {
399908
- logError3(error);
399909
- try {
399910
- await unlink19(tempPath);
399911
- } catch {}
399912
- }
399913
- }
399914
- async function fetchInstallCountsFromGitHub() {
399915
- logForDebugging3(`Fetching install counts from ${INSTALL_COUNTS_URL}`);
399916
- const started = performance.now();
399917
- try {
399918
- const response = await axios_default.get(INSTALL_COUNTS_URL, {
399919
- timeout: 1e4
399920
- });
399921
- if (!response.data?.plugins || !Array.isArray(response.data.plugins)) {
399922
- throw new Error("Invalid response format from install counts API");
399923
- }
399924
- logPluginFetch("install_counts", INSTALL_COUNTS_URL, "success", performance.now() - started);
399925
- return response.data.plugins;
399926
- } catch (error) {
399927
- logPluginFetch("install_counts", INSTALL_COUNTS_URL, "failure", performance.now() - started, classifyFetchError(error));
399928
- throw error;
399929
- }
399930
- }
399931
- async function getInstallCounts() {
399932
- const cache = await loadInstallCountsCache();
399933
- if (cache) {
399934
- logForDebugging3("Using cached install counts");
399935
- logPluginFetch("install_counts", INSTALL_COUNTS_URL, "cache_hit", 0);
399936
- const map = new Map;
399937
- for (const entry of cache.counts) {
399938
- map.set(entry.plugin, entry.unique_installs);
399939
- }
399940
- return map;
399941
- }
399942
- try {
399943
- const counts = await fetchInstallCountsFromGitHub();
399944
- const newCache = {
399945
- version: INSTALL_COUNTS_CACHE_VERSION,
399946
- fetchedAt: new Date().toISOString(),
399947
- counts
399948
- };
399949
- await saveInstallCountsCache(newCache);
399950
- const map = new Map;
399951
- for (const entry of counts) {
399952
- map.set(entry.plugin, entry.unique_installs);
399953
- }
399954
- return map;
399955
- } catch (error) {
399956
- logError3(error);
399957
- logForDebugging3(`Failed to fetch install counts: ${errorMessage2(error)}`);
399958
- return null;
399959
- }
399960
- }
399961
- function formatInstallCount(count) {
399962
- if (count < 1000) {
399963
- return String(count);
399964
- }
399965
- if (count < 1e6) {
399966
- const k = count / 1000;
399967
- const formatted = k.toFixed(1);
399968
- return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}K` : `${formatted}K`;
399969
- }
399970
- const m = count / 1e6;
399971
- const formatted = m.toFixed(1);
399972
- return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}M` : `${formatted}M`;
399973
- }
399974
- 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;
399975
- var init_installCounts = __esm(() => {
399976
- init_axios2();
399977
- init_debug();
399978
- init_errors4();
399979
- init_fsOperations();
399980
- init_log5();
399981
- init_slowOperations();
399982
- init_fetchTelemetry();
399983
- init_pluginDirectories();
399984
- CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
399985
- });
399986
-
399987
399806
  // src/tui/commands/plugin/PluginOptionsDialog.tsx
399988
399807
  function buildFinalValues(fields, collected, configSchema, initialValues) {
399989
399808
  const finalValues = {};
@@ -400915,7 +400734,7 @@ function BrowseMarketplace({
400915
400734
  });
400916
400735
  }
400917
400736
  try {
400918
- const counts = await getInstallCounts();
400737
+ const counts = await getInstallCounts([marketplaceName]);
400919
400738
  if (cancelled)
400920
400739
  return;
400921
400740
  setInstallCounts(counts);
@@ -401596,7 +401415,7 @@ function BrowseMarketplace({
401596
401415
  dimColor: true,
401597
401416
  children: " (installed)"
401598
401417
  }, undefined, false, undefined, this),
401599
- installCounts && selectedMarketplace === OFFICIAL_MARKETPLACE_NAME && /* @__PURE__ */ jsx_dev_runtime286.jsxDEV(ThemedText, {
401418
+ installCounts?.get(plugin_6.pluginId) != null && /* @__PURE__ */ jsx_dev_runtime286.jsxDEV(ThemedText, {
401600
401419
  dimColor: true,
401601
401420
  children: [
401602
401421
  " · ",
@@ -401671,7 +401490,6 @@ var init_BrowseMarketplace = __esm(() => {
401671
401490
  init_marketplaceHelpers();
401672
401491
  init_marketplaceDisplayName();
401673
401492
  init_marketplaceManager();
401674
- init_officialMarketplace();
401675
401493
  init_pluginInstallationHelpers();
401676
401494
  init_pluginPolicy();
401677
401495
  init_stringUtils2();
@@ -402321,7 +402139,7 @@ function DiscoverPlugins({
402321
402139
  dimColor: true,
402322
402140
  children: " [Community Managed]"
402323
402141
  }, undefined, false, undefined, this),
402324
- 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, {
402325
402143
  dimColor: true,
402326
402144
  children: [
402327
402145
  " · ",
@@ -402614,7 +402432,6 @@ var init_DiscoverPlugins = __esm(() => {
402614
402432
  init_installedPluginsManager();
402615
402433
  init_marketplaceHelpers();
402616
402434
  init_marketplaceManager();
402617
- init_officialMarketplace();
402618
402435
  init_pluginInstallationHelpers();
402619
402436
  init_pluginPolicy();
402620
402437
  init_stringUtils2();
@@ -402631,7 +402448,7 @@ var init_DiscoverPlugins = __esm(() => {
402631
402448
 
402632
402449
  // src/tui/utils/plugins/skillSearch.ts
402633
402450
  import { readdir as readdir27, readFile as readFile52, stat as stat46 } from "fs/promises";
402634
- import { join as join147 } from "path";
402451
+ import { join as join146 } from "path";
402635
402452
  async function searchSkillsAcrossMarketplaces(query) {
402636
402453
  const config = await loadKnownMarketplacesConfig();
402637
402454
  const q = query?.trim().toLowerCase();
@@ -402643,20 +402460,20 @@ async function searchSkillsAcrossMarketplaces(query) {
402643
402460
  let marketplaceDir;
402644
402461
  try {
402645
402462
  const locStat = await stat46(marketplaceConfig.installLocation);
402646
- marketplaceDir = locStat.isDirectory() ? marketplaceConfig.installLocation : join147(marketplaceConfig.installLocation, "..");
402463
+ marketplaceDir = locStat.isDirectory() ? marketplaceConfig.installLocation : join146(marketplaceConfig.installLocation, "..");
402647
402464
  } catch {
402648
402465
  continue;
402649
402466
  }
402650
402467
  for (const entry of data.plugins) {
402651
402468
  if (typeof entry.source !== "string")
402652
402469
  continue;
402653
- const pluginPath = join147(marketplaceDir, entry.source);
402654
- const skillDirCandidates = [join147(pluginPath, "skills")];
402470
+ const pluginPath = join146(marketplaceDir, entry.source);
402471
+ const skillDirCandidates = [join146(pluginPath, "skills")];
402655
402472
  if (typeof entry.skills === "string") {
402656
- skillDirCandidates.push(join147(pluginPath, entry.skills));
402473
+ skillDirCandidates.push(join146(pluginPath, entry.skills));
402657
402474
  } else if (Array.isArray(entry.skills)) {
402658
402475
  for (const extra of entry.skills) {
402659
- skillDirCandidates.push(join147(pluginPath, extra));
402476
+ skillDirCandidates.push(join146(pluginPath, extra));
402660
402477
  }
402661
402478
  }
402662
402479
  const seen = new Set;
@@ -402670,7 +402487,7 @@ async function searchSkillsAcrossMarketplaces(query) {
402670
402487
  for (const d of dirEntries) {
402671
402488
  if (!d.isDirectory())
402672
402489
  continue;
402673
- const skillFile = join147(skillDir, d.name, "SKILL.md");
402490
+ const skillFile = join146(skillDir, d.name, "SKILL.md");
402674
402491
  if (seen.has(skillFile))
402675
402492
  continue;
402676
402493
  seen.add(skillFile);
@@ -404170,10 +403987,10 @@ var init_ManageMarketplaces = __esm(() => {
404170
403987
 
404171
403988
  // src/tui/utils/plugins/pluginFlagging.ts
404172
403989
  import { randomBytes as randomBytes19 } from "crypto";
404173
- import { readFile as readFile53, rename as rename10, unlink as unlink20, writeFile as writeFile42 } from "fs/promises";
404174
- import { join as join148 } from "path";
403990
+ import { readFile as readFile53, rename as rename10, unlink as unlink20, writeFile as writeFile41 } from "fs/promises";
403991
+ import { join as join147 } from "path";
404175
403992
  function getFlaggedPluginsPath() {
404176
- return join148(getPluginsDirectory(), FLAGGED_PLUGINS_FILENAME);
403993
+ return join147(getPluginsDirectory(), FLAGGED_PLUGINS_FILENAME);
404177
403994
  }
404178
403995
  function parsePluginsData(content) {
404179
403996
  const parsed = jsonParse2(content);
@@ -404211,7 +404028,7 @@ async function writeToDisk(plugins) {
404211
404028
  try {
404212
404029
  await getFsImplementation2().mkdir(getPluginsDirectory());
404213
404030
  const content = jsonStringify5({ plugins }, null, 2);
404214
- await writeFile42(tempPath, content, {
404031
+ await writeFile41(tempPath, content, {
404215
404032
  encoding: "utf-8",
404216
404033
  mode: 384
404217
404034
  });
@@ -409691,8 +409508,8 @@ var init_rewind = __esm(() => {
409691
409508
 
409692
409509
  // src/tui/utils/heapDumpService.ts
409693
409510
  import { createWriteStream as createWriteStream3, writeFileSync as writeFileSync8 } from "fs";
409694
- import { readdir as readdir30, readFile as readFile56, writeFile as writeFile43 } from "fs/promises";
409695
- import { join as join151 } from "path";
409511
+ import { readdir as readdir30, readFile as readFile56, writeFile as writeFile42 } from "fs/promises";
409512
+ import { join as join150 } from "path";
409696
409513
  import { pipeline as pipeline2 } from "stream/promises";
409697
409514
  import {
409698
409515
  getHeapSnapshot,
@@ -409800,9 +409617,9 @@ async function performHeapDump(trigger = "manual", dumpNumber = 0) {
409800
409617
  const suffix = dumpNumber > 0 ? `-dump${dumpNumber}` : "";
409801
409618
  const heapFilename = `${sessionId}${suffix}.heapsnapshot`;
409802
409619
  const diagFilename = `${sessionId}${suffix}-diagnostics.json`;
409803
- const heapPath = join151(dumpDir, heapFilename);
409804
- const diagPath = join151(dumpDir, diagFilename);
409805
- await writeFile43(diagPath, jsonStringify5(diagnostics, null, 2), {
409620
+ const heapPath = join150(dumpDir, heapFilename);
409621
+ const diagPath = join150(dumpDir, diagFilename);
409622
+ await writeFile42(diagPath, jsonStringify5(diagnostics, null, 2), {
409806
409623
  mode: 384
409807
409624
  });
409808
409625
  logForDebugging3(`[HeapDump] Diagnostics written to ${diagPath}`);
@@ -411138,7 +410955,7 @@ var init_stickers2 = __esm(() => {
411138
410955
  // src/tui/skills/bundledSkills.ts
411139
410956
  import { constants as fsConstants8 } from "fs";
411140
410957
  import { mkdir as mkdir47, open as open16 } from "fs/promises";
411141
- import { dirname as dirname74, isAbsolute as isAbsolute32, join as join152, normalize as normalize14, sep as pathSep3 } from "path";
410958
+ import { dirname as dirname74, isAbsolute as isAbsolute32, join as join151, normalize as normalize14, sep as pathSep3 } from "path";
411142
410959
  function registerBundledSkill2(definition) {
411143
410960
  const { files } = definition;
411144
410961
  let skillRoot;
@@ -411186,7 +411003,7 @@ function getBundledSkills2() {
411186
411003
  return [...bundledSkills2];
411187
411004
  }
411188
411005
  function getBundledSkillExtractDir2(skillName) {
411189
- return join152(getBundledSkillsRoot2(), skillName);
411006
+ return join151(getBundledSkillsRoot2(), skillName);
411190
411007
  }
411191
411008
  async function extractBundledSkillFiles(skillName, files) {
411192
411009
  const dir = getBundledSkillExtractDir2(skillName);
@@ -411228,7 +411045,7 @@ function resolveSkillFilePath(baseDir, relPath) {
411228
411045
  if (isAbsolute32(normalized) || normalized.split(pathSep3).includes("..") || normalized.split("/").includes("..")) {
411229
411046
  throw new Error(`bundled skill file path escapes skill dir: ${relPath}`);
411230
411047
  }
411231
- return join152(baseDir, normalized);
411048
+ return join151(baseDir, normalized);
411232
411049
  }
411233
411050
  function prependBaseDir(blocks, baseDir) {
411234
411051
  const prefix = `Base directory for this skill: ${baseDir}
@@ -411523,10 +411340,10 @@ var init_ExitFlow = __esm(() => {
411523
411340
  });
411524
411341
 
411525
411342
  // src/tui/utils/concurrentSessions.ts
411526
- import { chmod as chmod9, mkdir as mkdir48, readdir as readdir31, readFile as readFile57, unlink as unlink21, writeFile as writeFile44 } from "fs/promises";
411527
- import { join as join153 } from "path";
411343
+ import { chmod as chmod8, mkdir as mkdir48, readdir as readdir31, readFile as readFile57, unlink as unlink21, writeFile as writeFile43 } from "fs/promises";
411344
+ import { join as join152 } from "path";
411528
411345
  function getSessionsDir() {
411529
- return join153(getAtlasConfigHomeDir3(), "sessions");
411346
+ return join152(getAtlasConfigHomeDir3(), "sessions");
411530
411347
  }
411531
411348
  function envSessionKind() {
411532
411349
  if (feature("BG_SESSIONS")) {
@@ -411544,7 +411361,7 @@ async function registerSession2() {
411544
411361
  return false;
411545
411362
  const kind = envSessionKind() ?? "interactive";
411546
411363
  const dir = getSessionsDir();
411547
- const pidFile = join153(dir, `${process.pid}.json`);
411364
+ const pidFile = join152(dir, `${process.pid}.json`);
411548
411365
  registerCleanup3(async () => {
411549
411366
  try {
411550
411367
  await unlink21(pidFile);
@@ -411552,8 +411369,8 @@ async function registerSession2() {
411552
411369
  });
411553
411370
  try {
411554
411371
  await mkdir48(dir, { recursive: true, mode: 448 });
411555
- await chmod9(dir, 448);
411556
- await writeFile44(pidFile, jsonStringify5({
411372
+ await chmod8(dir, 448);
411373
+ await writeFile43(pidFile, jsonStringify5({
411557
411374
  pid: process.pid,
411558
411375
  sessionId: getSessionId(),
411559
411376
  cwd: getOriginalCwd(),
@@ -411577,10 +411394,10 @@ async function registerSession2() {
411577
411394
  }
411578
411395
  }
411579
411396
  async function updatePidFile(patch) {
411580
- const pidFile = join153(getSessionsDir(), `${process.pid}.json`);
411397
+ const pidFile = join152(getSessionsDir(), `${process.pid}.json`);
411581
411398
  try {
411582
411399
  const data = jsonParse2(await readFile57(pidFile, "utf8"));
411583
- await writeFile44(pidFile, jsonStringify5({ ...data, ...patch }));
411400
+ await writeFile43(pidFile, jsonStringify5({ ...data, ...patch }));
411584
411401
  } catch (e) {
411585
411402
  logForDebugging3(`[concurrentSessions] updatePidFile failed: ${errorMessage2(e)}`);
411586
411403
  }
@@ -411618,7 +411435,7 @@ async function countConcurrentSessions2() {
411618
411435
  if (isProcessRunning2(pid)) {
411619
411436
  count++;
411620
411437
  } else if (getPlatform3() !== "wsl") {
411621
- unlink21(join153(dir, file)).catch(() => {});
411438
+ unlink21(join152(dir, file)).catch(() => {});
411622
411439
  }
411623
411440
  }
411624
411441
  return count;
@@ -411693,7 +411510,7 @@ var init_exit2 = __esm(() => {
411693
411510
  });
411694
411511
 
411695
411512
  // src/tui/components/ExportDialog.tsx
411696
- import { join as join154 } from "path";
411513
+ import { join as join153 } from "path";
411697
411514
  function ExportDialog({
411698
411515
  content,
411699
411516
  defaultFilename,
@@ -411726,7 +411543,7 @@ function ExportDialog({
411726
411543
  };
411727
411544
  const handleFilenameSubmit = () => {
411728
411545
  const finalFilename = filename.endsWith(".txt") ? filename : filename.replace(/\.[^.]+$/, "") + ".txt";
411729
- const filepath = join154(getCwd(), finalFilename);
411546
+ const filepath = join153(getCwd(), finalFilename);
411730
411547
  try {
411731
411548
  writeFileSync_DEPRECATED(filepath, content, {
411732
411549
  encoding: "utf-8",
@@ -411949,7 +411766,7 @@ __export(exports_export, {
411949
411766
  extractFirstPrompt: () => extractFirstPrompt2,
411950
411767
  sanitizeFilename: () => sanitizeFilename
411951
411768
  });
411952
- import { join as join155 } from "path";
411769
+ import { join as join154 } from "path";
411953
411770
  function formatTimestamp(date) {
411954
411771
  const year = date.getFullYear();
411955
411772
  const month = String(date.getMonth() + 1).padStart(2, "0");
@@ -411993,7 +411810,7 @@ async function call50(onDone, context, args) {
411993
411810
  const filename = args.trim();
411994
411811
  if (filename) {
411995
411812
  const finalFilename = filename.endsWith(".txt") ? filename : filename.replace(/\.[^.]+$/, "") + ".txt";
411996
- const filepath = join155(getCwd(), finalFilename);
411813
+ const filepath = join154(getCwd(), finalFilename);
411997
411814
  try {
411998
411815
  writeFileSync_DEPRECATED(filepath, content, {
411999
411816
  encoding: "utf-8",
@@ -412879,7 +412696,7 @@ var require_asciichart = __commonJS(function(exports) {
412879
412696
  // src/tui/utils/statsCache.ts
412880
412697
  import { randomBytes as randomBytes20 } from "crypto";
412881
412698
  import { open as open17 } from "fs/promises";
412882
- import { join as join156 } from "path";
412699
+ import { join as join155 } from "path";
412883
412700
  async function withStatsCacheLock(fn) {
412884
412701
  while (statsCacheLockPromise) {
412885
412702
  await statsCacheLockPromise;
@@ -412896,7 +412713,7 @@ async function withStatsCacheLock(fn) {
412896
412713
  }
412897
412714
  }
412898
412715
  function getStatsCachePath() {
412899
- return join156(getAtlasConfigHomeDir3(), STATS_CACHE_FILENAME);
412716
+ return join155(getAtlasConfigHomeDir3(), STATS_CACHE_FILENAME);
412900
412717
  }
412901
412718
  function getEmptyCache() {
412902
412719
  return {
@@ -413577,16 +413394,16 @@ var init_ansiToPng = __esm(() => {
413577
413394
  });
413578
413395
 
413579
413396
  // src/tui/utils/screenshotClipboard.ts
413580
- import { mkdir as mkdir49, unlink as unlink22, writeFile as writeFile45 } from "fs/promises";
413397
+ import { mkdir as mkdir49, unlink as unlink22, writeFile as writeFile44 } from "fs/promises";
413581
413398
  import { tmpdir as tmpdir10 } from "os";
413582
- import { join as join157 } from "path";
413399
+ import { join as join156 } from "path";
413583
413400
  async function copyAnsiToClipboard(ansiText, options) {
413584
413401
  try {
413585
- const tempDir = join157(tmpdir10(), "atlas-screenshots");
413402
+ const tempDir = join156(tmpdir10(), "atlas-screenshots");
413586
413403
  await mkdir49(tempDir, { recursive: true });
413587
- const pngPath = join157(tempDir, `screenshot-${Date.now()}.png`);
413404
+ const pngPath = join156(tempDir, `screenshot-${Date.now()}.png`);
413588
413405
  const pngBuffer = ansiToPng(ansiText, options);
413589
- await writeFile45(pngPath, pngBuffer);
413406
+ await writeFile44(pngPath, pngBuffer);
413590
413407
  const result = await copyPngToClipboard(pngPath);
413591
413408
  try {
413592
413409
  await unlink22(pngPath);
@@ -413655,7 +413472,7 @@ var init_screenshotClipboard = __esm(() => {
413655
413472
 
413656
413473
  // src/tui/utils/stats.ts
413657
413474
  import { open as open18 } from "fs/promises";
413658
- import { basename as basename46, dirname as dirname75, join as join158, sep as sep33 } from "path";
413475
+ import { basename as basename46, dirname as dirname75, join as join157, sep as sep33 } from "path";
413659
413476
  async function processSessionFiles(sessionFiles, options = {}) {
413660
413477
  const { fromDate, toDate } = options;
413661
413478
  const fs = getFsImplementation2();
@@ -413841,17 +413658,17 @@ async function getAllSessionFiles() {
413841
413658
  return [];
413842
413659
  throw e;
413843
413660
  }
413844
- const projectDirs = allEntries.filter((dirent) => dirent.isDirectory()).map((dirent) => join158(projectsDir, dirent.name));
413661
+ const projectDirs = allEntries.filter((dirent) => dirent.isDirectory()).map((dirent) => join157(projectsDir, dirent.name));
413845
413662
  const projectResults = await Promise.all(projectDirs.map(async (projectDir) => {
413846
413663
  try {
413847
413664
  const entries = await fs.readdir(projectDir);
413848
- const mainFiles = entries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl")).map((dirent) => join158(projectDir, dirent.name));
413665
+ const mainFiles = entries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl")).map((dirent) => join157(projectDir, dirent.name));
413849
413666
  const sessionDirs = entries.filter((dirent) => dirent.isDirectory());
413850
413667
  const subagentResults = await Promise.all(sessionDirs.map(async (sessionDir) => {
413851
- const subagentsDir = join158(projectDir, sessionDir.name, "subagents");
413668
+ const subagentsDir = join157(projectDir, sessionDir.name, "subagents");
413852
413669
  try {
413853
413670
  const subagentEntries = await fs.readdir(subagentsDir);
413854
- return subagentEntries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl") && dirent.name.startsWith("agent-")).map((dirent) => join158(subagentsDir, dirent.name));
413671
+ return subagentEntries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl") && dirent.name.startsWith("agent-")).map((dirent) => join157(subagentsDir, dirent.name));
413855
413672
  } catch {
413856
413673
  return [];
413857
413674
  }
@@ -416704,9 +416521,9 @@ import {
416704
416521
  readdir as readdir32,
416705
416522
  readFile as readFile58,
416706
416523
  unlink as unlink23,
416707
- writeFile as writeFile46
416524
+ writeFile as writeFile45
416708
416525
  } from "fs/promises";
416709
- import { extname as extname16, join as join159 } from "path";
416526
+ import { extname as extname16, join as join158 } from "path";
416710
416527
  function getAnalysisModel() {
416711
416528
  return getDefaultPremiumModel();
416712
416529
  }
@@ -416714,13 +416531,13 @@ function getInsightsModel() {
416714
416531
  return getDefaultPremiumModel();
416715
416532
  }
416716
416533
  function getDataDir() {
416717
- return join159(getAtlasConfigHomeDir3(), "usage-data");
416534
+ return join158(getAtlasConfigHomeDir3(), "usage-data");
416718
416535
  }
416719
416536
  function getFacetsDir() {
416720
- return join159(getDataDir(), "facets");
416537
+ return join158(getDataDir(), "facets");
416721
416538
  }
416722
416539
  function getSessionMetaDir() {
416723
- return join159(getDataDir(), "session-meta");
416540
+ return join158(getDataDir(), "session-meta");
416724
416541
  }
416725
416542
  function getLanguageFromPath(filePath) {
416726
416543
  const ext = extname16(filePath).toLowerCase();
@@ -417061,7 +416878,7 @@ async function formatTranscriptWithSummarization(log) {
417061
416878
  `);
417062
416879
  }
417063
416880
  async function loadCachedFacets(sessionId) {
417064
- const facetPath = join159(getFacetsDir(), `${sessionId}.json`);
416881
+ const facetPath = join158(getFacetsDir(), `${sessionId}.json`);
417065
416882
  try {
417066
416883
  const content = await readFile58(facetPath, { encoding: "utf-8" });
417067
416884
  const parsed = jsonParse2(content);
@@ -417080,14 +416897,14 @@ async function saveFacets(facets) {
417080
416897
  try {
417081
416898
  await mkdir50(getFacetsDir(), { recursive: true });
417082
416899
  } catch {}
417083
- const facetPath = join159(getFacetsDir(), `${facets.session_id}.json`);
417084
- await writeFile46(facetPath, jsonStringify5(facets, null, 2), {
416900
+ const facetPath = join158(getFacetsDir(), `${facets.session_id}.json`);
416901
+ await writeFile45(facetPath, jsonStringify5(facets, null, 2), {
417085
416902
  encoding: "utf-8",
417086
416903
  mode: 384
417087
416904
  });
417088
416905
  }
417089
416906
  async function loadCachedSessionMeta(sessionId) {
417090
- const metaPath = join159(getSessionMetaDir(), `${sessionId}.json`);
416907
+ const metaPath = join158(getSessionMetaDir(), `${sessionId}.json`);
417091
416908
  try {
417092
416909
  const content = await readFile58(metaPath, { encoding: "utf-8" });
417093
416910
  return jsonParse2(content);
@@ -417099,8 +416916,8 @@ async function saveSessionMeta(meta) {
417099
416916
  try {
417100
416917
  await mkdir50(getSessionMetaDir(), { recursive: true });
417101
416918
  } catch {}
417102
- const metaPath = join159(getSessionMetaDir(), `${meta.session_id}.json`);
417103
- await writeFile46(metaPath, jsonStringify5(meta, null, 2), {
416919
+ const metaPath = join158(getSessionMetaDir(), `${meta.session_id}.json`);
416920
+ await writeFile45(metaPath, jsonStringify5(meta, null, 2), {
417104
416921
  encoding: "utf-8",
417105
416922
  mode: 384
417106
416923
  });
@@ -418179,7 +417996,7 @@ async function scanAllSessions() {
418179
417996
  } catch {
418180
417997
  return [];
418181
417998
  }
418182
- const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join159(projectsDir, dirent.name));
417999
+ const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join158(projectsDir, dirent.name));
418183
418000
  const allSessions = [];
418184
418001
  for (let i = 0;i < projectDirs.length; i++) {
418185
418002
  const sessionFiles = await getSessionFilesWithMtime(projectDirs[i]);
@@ -418335,8 +418152,8 @@ async function generateUsageReport(options) {
418335
418152
  try {
418336
418153
  await mkdir50(getDataDir(), { recursive: true });
418337
418154
  } catch {}
418338
- const htmlPath = join159(getDataDir(), "report.html");
418339
- await writeFile46(htmlPath, htmlReport, {
418155
+ const htmlPath = join158(getDataDir(), "report.html");
418156
+ await writeFile45(htmlPath, htmlReport, {
418340
418157
  encoding: "utf-8",
418341
418158
  mode: 384
418342
418159
  });
@@ -419139,9 +418956,9 @@ import {
419139
418956
  readFile as readFile59,
419140
418957
  stat as stat49,
419141
418958
  unlink as unlink24,
419142
- writeFile as writeFile47
418959
+ writeFile as writeFile46
419143
418960
  } from "fs/promises";
419144
- import { basename as basename48, dirname as dirname76, join as join160 } from "path";
418961
+ import { basename as basename48, dirname as dirname76, join as join159 } from "path";
419145
418962
  function isTranscriptMessage2(entry) {
419146
418963
  return entry.type === "user" || entry.type === "assistant" || entry.type === "attachment" || entry.type === "system";
419147
418964
  }
@@ -419155,18 +418972,18 @@ function isEphemeralToolProgress2(dataType) {
419155
418972
  return typeof dataType === "string" && EPHEMERAL_PROGRESS_TYPES2.has(dataType);
419156
418973
  }
419157
418974
  function getProjectsDir3() {
419158
- return join160(getAtlasConfigHomeDir3(), "projects");
418975
+ return join159(getAtlasConfigHomeDir3(), "projects");
419159
418976
  }
419160
418977
  function getTranscriptPath2() {
419161
418978
  const projectDir = getSessionProjectDir() ?? getProjectDir3(getOriginalCwd());
419162
- return join160(projectDir, `${getSessionId()}.jsonl`);
418979
+ return join159(projectDir, `${getSessionId()}.jsonl`);
419163
418980
  }
419164
418981
  function getTranscriptPathForSession3(sessionId) {
419165
418982
  if (sessionId === getSessionId()) {
419166
418983
  return getTranscriptPath2();
419167
418984
  }
419168
418985
  const projectDir = getProjectDir3(getOriginalCwd());
419169
- return join160(projectDir, `${sessionId}.jsonl`);
418986
+ return join159(projectDir, `${sessionId}.jsonl`);
419170
418987
  }
419171
418988
  function setAgentTranscriptSubdir2(agentId, subdir) {
419172
418989
  agentTranscriptSubdirs2.set(agentId, subdir);
@@ -419178,8 +418995,8 @@ function getAgentTranscriptPath2(agentId) {
419178
418995
  const projectDir = getSessionProjectDir() ?? getProjectDir3(getOriginalCwd());
419179
418996
  const sessionId = getSessionId();
419180
418997
  const subdir = agentTranscriptSubdirs2.get(agentId);
419181
- const base = subdir ? join160(projectDir, sessionId, "subagents", subdir) : join160(projectDir, sessionId, "subagents");
419182
- return join160(base, `agent-${agentId}.jsonl`);
418998
+ const base = subdir ? join159(projectDir, sessionId, "subagents", subdir) : join159(projectDir, sessionId, "subagents");
418999
+ return join159(base, `agent-${agentId}.jsonl`);
419183
419000
  }
419184
419001
  function getAgentMetadataPath(agentId) {
419185
419002
  return getAgentTranscriptPath2(agentId).replace(/\.jsonl$/, ".meta.json");
@@ -419187,7 +419004,7 @@ function getAgentMetadataPath(agentId) {
419187
419004
  async function writeAgentMetadata(agentId, metadata) {
419188
419005
  const path = getAgentMetadataPath(agentId);
419189
419006
  await mkdir51(dirname76(path), { recursive: true });
419190
- await writeFile47(path, JSON.stringify(metadata));
419007
+ await writeFile46(path, JSON.stringify(metadata));
419191
419008
  }
419192
419009
  async function readAgentMetadata(agentId) {
419193
419010
  const path = getAgentMetadataPath(agentId);
@@ -419202,7 +419019,7 @@ async function readAgentMetadata(agentId) {
419202
419019
  }
419203
419020
  function sessionIdExists(sessionId) {
419204
419021
  const projectDir = getProjectDir3(getOriginalCwd());
419205
- const sessionFile = join160(projectDir, `${sessionId}.jsonl`);
419022
+ const sessionFile = join159(projectDir, `${sessionId}.jsonl`);
419206
419023
  const fs = getFsImplementation2();
419207
419024
  try {
419208
419025
  fs.statSync(sessionFile);
@@ -419529,7 +419346,7 @@ class Project2 {
419529
419346
  return true;
419530
419347
  }
419531
419348
  });
419532
- await writeFile47(this.sessionFile, lines.join(`
419349
+ await writeFile46(this.sessionFile, lines.join(`
419533
419350
  `), {
419534
419351
  encoding: "utf8"
419535
419352
  });
@@ -420934,7 +420751,7 @@ async function loadTranscriptFile2(filePath, opts) {
420934
420751
  };
420935
420752
  }
420936
420753
  async function loadSessionFile2(sessionId) {
420937
- const sessionFile = join160(getSessionProjectDir() ?? getProjectDir3(getOriginalCwd()), `${sessionId}.jsonl`);
420754
+ const sessionFile = join159(getSessionProjectDir() ?? getProjectDir3(getOriginalCwd()), `${sessionId}.jsonl`);
420938
420755
  return loadTranscriptFile2(sessionFile);
420939
420756
  }
420940
420757
  function clearSessionMessagesCache2() {
@@ -420998,7 +420815,7 @@ async function loadAllProjectsMessageLogsFull(limit) {
420998
420815
  } catch {
420999
420816
  return [];
421000
420817
  }
421001
- const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join160(projectsDir, dirent.name));
420818
+ const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join159(projectsDir, dirent.name));
421002
420819
  const logsPerProject = await Promise.all(projectDirs.map((projectDir) => getLogsWithoutIndex(projectDir, limit)));
421003
420820
  const allLogs = logsPerProject.flat();
421004
420821
  const deduped = new Map;
@@ -421023,7 +420840,7 @@ async function loadAllProjectsMessageLogsProgressive(limit, initialEnrichCount =
421023
420840
  } catch {
421024
420841
  return { logs: [], allStatLogs: [], nextIndex: 0 };
421025
420842
  }
421026
- const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join160(projectsDir, dirent.name));
420843
+ const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join159(projectsDir, dirent.name));
421027
420844
  const rawLogs = [];
421028
420845
  for (const projectDir of projectDirs) {
421029
420846
  rawLogs.push(...await getSessionFilesLite(projectDir, limit));
@@ -421099,7 +420916,7 @@ async function getStatOnlyLogsForWorktrees(worktreePaths, limit) {
421099
420916
  for (const { path: wtPath, prefix } of indexed) {
421100
420917
  if (dirName === prefix || dirName.startsWith(prefix + "-")) {
421101
420918
  seenDirs.add(dirName);
421102
- allLogs.push(...await getSessionFilesLite(join160(projectsDir, dirent.name), undefined, wtPath));
420919
+ allLogs.push(...await getSessionFilesLite(join159(projectsDir, dirent.name), undefined, wtPath));
421103
420920
  break;
421104
420921
  }
421105
420922
  }
@@ -421159,7 +420976,7 @@ async function loadSubagentTranscripts(agentIds) {
421159
420976
  return transcripts;
421160
420977
  }
421161
420978
  async function loadAllSubagentTranscriptsFromDisk() {
421162
- const subagentsDir = join160(getSessionProjectDir() ?? getProjectDir3(getOriginalCwd()), getSessionId(), "subagents");
420979
+ const subagentsDir = join159(getSessionProjectDir() ?? getProjectDir3(getOriginalCwd()), getSessionId(), "subagents");
421163
420980
  let entries;
421164
420981
  try {
421165
420982
  entries = await readdir33(subagentsDir, { withFileTypes: true });
@@ -421254,7 +421071,7 @@ async function getSessionFilesWithMtime(projectDir) {
421254
421071
  const sessionId = validateUuid2(basename48(dirent.name, ".jsonl"));
421255
421072
  if (!sessionId)
421256
421073
  continue;
421257
- candidates.push({ sessionId, filePath: join160(projectDir, dirent.name) });
421074
+ candidates.push({ sessionId, filePath: join159(projectDir, dirent.name) });
421258
421075
  }
421259
421076
  await Promise.all(candidates.map(async ({ sessionId, filePath }) => {
421260
421077
  try {
@@ -421676,7 +421493,7 @@ var init_sessionStorage = __esm(() => {
421676
421493
  MAX_TRANSCRIPT_READ_BYTES2 = 50 * 1024 * 1024;
421677
421494
  agentTranscriptSubdirs2 = new Map;
421678
421495
  getProjectDir3 = memoize_default((projectDir) => {
421679
- return join160(getProjectsDir3(), sanitizePath3(projectDir));
421496
+ return join159(getProjectsDir3(), sanitizePath3(projectDir));
421680
421497
  });
421681
421498
  METADATA_TYPE_MARKERS2 = [
421682
421499
  '"type":"summary"',
@@ -421694,8 +421511,8 @@ var init_sessionStorage = __esm(() => {
421694
421511
 
421695
421512
  // src/tui/utils/plans.ts
421696
421513
  import { randomUUID as randomUUID40 } from "crypto";
421697
- import { copyFile as copyFile9, writeFile as writeFile48 } from "fs/promises";
421698
- import { join as join161, resolve as resolve50, sep as sep34 } from "path";
421514
+ import { copyFile as copyFile9, writeFile as writeFile47 } from "fs/promises";
421515
+ import { join as join160, resolve as resolve50, sep as sep34 } from "path";
421699
421516
  function getPlanSlug2(sessionId) {
421700
421517
  const id = sessionId ?? getSessionId();
421701
421518
  const cache = getPlanSlugCache();
@@ -421704,7 +421521,7 @@ function getPlanSlug2(sessionId) {
421704
421521
  const plansDir = getPlansDirectory2();
421705
421522
  for (let i = 0;i < MAX_SLUG_RETRIES2; i++) {
421706
421523
  slug = generateWordSlug2();
421707
- const filePath = join161(plansDir, `${slug}.md`);
421524
+ const filePath = join160(plansDir, `${slug}.md`);
421708
421525
  if (!getFsImplementation2().existsSync(filePath)) {
421709
421526
  break;
421710
421527
  }
@@ -421722,9 +421539,9 @@ function clearAllPlanSlugs2() {
421722
421539
  function getPlanFilePath2(agentId) {
421723
421540
  const planSlug = getPlanSlug2(getSessionId());
421724
421541
  if (!agentId) {
421725
- return join161(getPlansDirectory2(), `${planSlug}.md`);
421542
+ return join160(getPlansDirectory2(), `${planSlug}.md`);
421726
421543
  }
421727
- return join161(getPlansDirectory2(), `${planSlug}-agent-${agentId}.md`);
421544
+ return join160(getPlansDirectory2(), `${planSlug}-agent-${agentId}.md`);
421728
421545
  }
421729
421546
  function getPlan2(agentId) {
421730
421547
  const filePath = getPlanFilePath2(agentId);
@@ -421747,7 +421564,7 @@ async function copyPlanForResume(log, targetSessionId) {
421747
421564
  }
421748
421565
  const sessionId = targetSessionId ?? getSessionId();
421749
421566
  setPlanSlug2(sessionId, slug);
421750
- const planPath = join161(getPlansDirectory2(), `${slug}.md`);
421567
+ const planPath = join160(getPlansDirectory2(), `${slug}.md`);
421751
421568
  try {
421752
421569
  await getFsImplementation2().readFile(planPath, { encoding: "utf-8" });
421753
421570
  return true;
@@ -421773,7 +421590,7 @@ async function copyPlanForResume(log, targetSessionId) {
421773
421590
  }
421774
421591
  if (recovered) {
421775
421592
  try {
421776
- await writeFile48(planPath, recovered, { encoding: "utf-8" });
421593
+ await writeFile47(planPath, recovered, { encoding: "utf-8" });
421777
421594
  return true;
421778
421595
  } catch (writeError) {
421779
421596
  logError3(writeError);
@@ -421790,9 +421607,9 @@ async function copyPlanForFork(log, targetSessionId) {
421790
421607
  return false;
421791
421608
  }
421792
421609
  const plansDir = getPlansDirectory2();
421793
- const originalPlanPath = join161(plansDir, `${originalSlug}.md`);
421610
+ const originalPlanPath = join160(plansDir, `${originalSlug}.md`);
421794
421611
  const newSlug = getPlanSlug2(targetSessionId);
421795
- const newPlanPath = join161(plansDir, `${newSlug}.md`);
421612
+ const newPlanPath = join160(plansDir, `${newSlug}.md`);
421796
421613
  try {
421797
421614
  await copyFile9(originalPlanPath, newPlanPath);
421798
421615
  return true;
@@ -421908,12 +421725,12 @@ var init_plans = __esm(() => {
421908
421725
  const resolved = resolve50(cwd, settingsDir);
421909
421726
  if (!resolved.startsWith(cwd + sep34) && resolved !== cwd) {
421910
421727
  logError3(new Error(`plansDirectory must be within project root: ${settingsDir}`));
421911
- plansPath = join161(getAtlasConfigHomeDir3(), "plans");
421728
+ plansPath = join160(getAtlasConfigHomeDir3(), "plans");
421912
421729
  } else {
421913
421730
  plansPath = resolved;
421914
421731
  }
421915
421732
  } else {
421916
- plansPath = join161(getAtlasConfigHomeDir3(), "plans");
421733
+ plansPath = join160(getAtlasConfigHomeDir3(), "plans");
421917
421734
  }
421918
421735
  try {
421919
421736
  getFsImplementation2().mkdirSync(plansPath);
@@ -421927,7 +421744,7 @@ var init_plans = __esm(() => {
421927
421744
  // src/tui/utils/permissions/filesystem.ts
421928
421745
  import { randomBytes as randomBytes21 } from "crypto";
421929
421746
  import { homedir as homedir38, tmpdir as tmpdir11 } from "os";
421930
- import { join as join162, normalize as normalize15, posix as posix9, sep as sep35 } from "path";
421747
+ import { join as join161, normalize as normalize15, posix as posix9, sep as sep35 } from "path";
421931
421748
  function normalizeCaseForComparison2(path) {
421932
421749
  return path.toLowerCase();
421933
421750
  }
@@ -421937,11 +421754,11 @@ function getClaudeSkillScope(filePath) {
421937
421754
  const configDir = getConfigDirName2();
421938
421755
  const bases = [
421939
421756
  {
421940
- dir: expandPath2(join162(getOriginalCwd(), configDir, "skills")),
421757
+ dir: expandPath2(join161(getOriginalCwd(), configDir, "skills")),
421941
421758
  prefix: `/${configDir}/skills/`
421942
421759
  },
421943
421760
  {
421944
- dir: expandPath2(join162(homedir38(), configDir, "skills")),
421761
+ dir: expandPath2(join161(homedir38(), configDir, "skills")),
421945
421762
  prefix: `~/${configDir}/skills/`
421946
421763
  }
421947
421764
  ];
@@ -421996,21 +421813,21 @@ function isClaudeConfigFilePath2(filePath) {
421996
421813
  if (isAtlasSettingsPath2(filePath)) {
421997
421814
  return true;
421998
421815
  }
421999
- const commandsDir = join162(getOriginalCwd(), getConfigDirName2(), "commands");
422000
- const agentsDir = join162(getOriginalCwd(), getConfigDirName2(), "agents");
422001
- const skillsDir = join162(getOriginalCwd(), getConfigDirName2(), "skills");
421816
+ const commandsDir = join161(getOriginalCwd(), getConfigDirName2(), "commands");
421817
+ const agentsDir = join161(getOriginalCwd(), getConfigDirName2(), "agents");
421818
+ const skillsDir = join161(getOriginalCwd(), getConfigDirName2(), "skills");
422002
421819
  return pathInWorkingPath2(filePath, commandsDir) || pathInWorkingPath2(filePath, agentsDir) || pathInWorkingPath2(filePath, skillsDir);
422003
421820
  }
422004
421821
  function isSessionPlanFile(absolutePath) {
422005
- const expectedPrefix = join162(getPlansDirectory2(), getPlanSlug2());
421822
+ const expectedPrefix = join161(getPlansDirectory2(), getPlanSlug2());
422006
421823
  const normalizedPath = normalize15(absolutePath);
422007
421824
  return normalizedPath.startsWith(expectedPrefix) && normalizedPath.endsWith(".md");
422008
421825
  }
422009
421826
  function getSessionMemoryDir() {
422010
- return join162(getProjectDir3(getCwd()), getSessionId(), "session-memory") + sep35;
421827
+ return join161(getProjectDir3(getCwd()), getSessionId(), "session-memory") + sep35;
422011
421828
  }
422012
421829
  function getSessionMemoryPath() {
422013
- return join162(getSessionMemoryDir(), "summary.md");
421830
+ return join161(getSessionMemoryDir(), "summary.md");
422014
421831
  }
422015
421832
  function isSessionMemoryPath(absolutePath) {
422016
421833
  const normalizedPath = normalize15(absolutePath);
@@ -422032,10 +421849,10 @@ function getAtlasTempDirName2() {
422032
421849
  return `${getConfigDirName2()}-${uid}`;
422033
421850
  }
422034
421851
  function getProjectTempDir2() {
422035
- return join162(getAtlasTempDir2(), sanitizePath3(getOriginalCwd())) + sep35;
421852
+ return join161(getAtlasTempDir2(), sanitizePath3(getOriginalCwd())) + sep35;
422036
421853
  }
422037
421854
  function getScratchpadDir() {
422038
- return join162(getProjectTempDir2(), getSessionId(), "scratchpad");
421855
+ return join161(getProjectTempDir2(), getSessionId(), "scratchpad");
422039
421856
  }
422040
421857
  async function ensureScratchpadDir() {
422041
421858
  if (!isScratchpadEnabled()) {
@@ -422595,7 +422412,7 @@ function checkEditableInternalPath2(absolutePath, input) {
422595
422412
  if (feature("TEMPLATES")) {
422596
422413
  const jobDir = process.env.ATLAS_JOB_DIR;
422597
422414
  if (jobDir) {
422598
- const jobsRoot = join162(getAtlasConfigHomeDir3(), "jobs");
422415
+ const jobsRoot = join161(getAtlasConfigHomeDir3(), "jobs");
422599
422416
  const jobDirForms = getPathsForPermissionCheck2(jobDir).map(normalize15);
422600
422417
  const jobsRootForms = getPathsForPermissionCheck2(jobsRoot).map(normalize15);
422601
422418
  const isUnderJobsRoot = jobDirForms.every((jd) => jobsRootForms.some((jr) => jd.startsWith(jr + sep35)));
@@ -422638,7 +422455,7 @@ function checkEditableInternalPath2(absolutePath, input) {
422638
422455
  }
422639
422456
  };
422640
422457
  }
422641
- if (normalizeCaseForComparison2(normalizedPath) === normalizeCaseForComparison2(join162(getOriginalCwd(), getConfigDirName2(), "launch.json"))) {
422458
+ if (normalizeCaseForComparison2(normalizedPath) === normalizeCaseForComparison2(join161(getOriginalCwd(), getConfigDirName2(), "launch.json"))) {
422642
422459
  return {
422643
422460
  behavior: "allow",
422644
422461
  updatedInput: input,
@@ -422735,7 +422552,7 @@ function checkReadableInternalPath2(absolutePath, input) {
422735
422552
  }
422736
422553
  };
422737
422554
  }
422738
- const tasksDir = join162(getAtlasConfigHomeDir3(), "tasks") + sep35;
422555
+ const tasksDir = join161(getAtlasConfigHomeDir3(), "tasks") + sep35;
422739
422556
  if (normalizedPath === tasksDir.slice(0, -1) || normalizedPath.startsWith(tasksDir)) {
422740
422557
  return {
422741
422558
  behavior: "allow",
@@ -422746,7 +422563,7 @@ function checkReadableInternalPath2(absolutePath, input) {
422746
422563
  }
422747
422564
  };
422748
422565
  }
422749
- const teamsReadDir = join162(getAtlasConfigHomeDir3(), "teams") + sep35;
422566
+ const teamsReadDir = join161(getAtlasConfigHomeDir3(), "teams") + sep35;
422750
422567
  if (normalizedPath === teamsReadDir.slice(0, -1) || normalizedPath.startsWith(teamsReadDir)) {
422751
422568
  return {
422752
422569
  behavior: "allow",
@@ -422823,11 +422640,11 @@ var init_filesystem2 = __esm(() => {
422823
422640
  try {
422824
422641
  resolvedBaseTmpDir = fs.realpathSync(baseTmpDir);
422825
422642
  } catch {}
422826
- return join162(resolvedBaseTmpDir, getAtlasTempDirName2()) + sep35;
422643
+ return join161(resolvedBaseTmpDir, getAtlasTempDirName2()) + sep35;
422827
422644
  });
422828
422645
  getBundledSkillsRoot2 = memoize_default(function getBundledSkillsRoot() {
422829
422646
  const nonce = randomBytes21(16).toString("hex");
422830
- return join162(getAtlasTempDir2(), "bundled-skills", MACRO.VERSION, nonce);
422647
+ return join161(getAtlasTempDir2(), "bundled-skills", MACRO.VERSION, nonce);
422831
422648
  });
422832
422649
  getResolvedWorkingDirPaths2 = memoize_default(getPathsForPermissionCheck2);
422833
422650
  });
@@ -422841,10 +422658,10 @@ import {
422841
422658
  symlink as symlink7,
422842
422659
  unlink as unlink25
422843
422660
  } from "fs/promises";
422844
- import { join as join163 } from "path";
422661
+ import { join as join162 } from "path";
422845
422662
  function getTaskOutputDir2() {
422846
422663
  if (_taskOutputDir2 === undefined) {
422847
- _taskOutputDir2 = join163(getProjectTempDir2(), getSessionId(), "tasks");
422664
+ _taskOutputDir2 = join162(getProjectTempDir2(), getSessionId(), "tasks");
422848
422665
  }
422849
422666
  return _taskOutputDir2;
422850
422667
  }
@@ -422852,7 +422669,7 @@ async function ensureOutputDir2() {
422852
422669
  await mkdir52(getTaskOutputDir2(), { recursive: true });
422853
422670
  }
422854
422671
  function getTaskOutputPath2(taskId) {
422855
- return join163(getTaskOutputDir2(), `${taskId}.output`);
422672
+ return join162(getTaskOutputDir2(), `${taskId}.output`);
422856
422673
  }
422857
422674
  function track2(p) {
422858
422675
  _pendingOps2.add(p);
@@ -429778,7 +429595,7 @@ var init_compact4 = __esm(() => {
429778
429595
 
429779
429596
  // src/tui/services/SessionMemory/prompts.ts
429780
429597
  import { readFile as readFile60 } from "fs/promises";
429781
- import { join as join164 } from "path";
429598
+ import { join as join163 } from "path";
429782
429599
  function getDefaultUpdatePrompt() {
429783
429600
  return `IMPORTANT: This message and these instructions are NOT part of the actual user conversation. Do NOT include any references to "note-taking", "session notes extraction", or these update instructions in the notes content.
429784
429601
 
@@ -429819,7 +429636,7 @@ You ONLY update the actual content that comes AFTER these two preserved lines. T
429819
429636
  REMEMBER: Use the Edit tool in parallel and stop. Do not continue after the edits. Only include insights from the actual user conversation, never from these note-taking instructions. Do not delete or change section headers or italic _section descriptions_.`;
429820
429637
  }
429821
429638
  async function loadSessionMemoryTemplate() {
429822
- const templatePath = join164(getAtlasConfigHomeDir3(), "session-memory", "config", "template.md");
429639
+ const templatePath = join163(getAtlasConfigHomeDir3(), "session-memory", "config", "template.md");
429823
429640
  try {
429824
429641
  return await readFile60(templatePath, { encoding: "utf-8" });
429825
429642
  } catch (e) {
@@ -429832,7 +429649,7 @@ async function loadSessionMemoryTemplate() {
429832
429649
  }
429833
429650
  }
429834
429651
  async function loadSessionMemoryPrompt() {
429835
- const promptPath = join164(getAtlasConfigHomeDir3(), "session-memory", "config", "prompt.md");
429652
+ const promptPath = join163(getAtlasConfigHomeDir3(), "session-memory", "config", "prompt.md");
429836
429653
  try {
429837
429654
  return await readFile60(promptPath, { encoding: "utf-8" });
429838
429655
  } catch (e) {
@@ -430438,7 +430255,7 @@ var init_contextHostWiring = __esm(() => {
430438
430255
 
430439
430256
  // src/tui/core/executor/AscendFreshnessPort.ts
430440
430257
  import { readFileSync as readFileSync22, existsSync as existsSync12 } from "fs";
430441
- import { join as join165, dirname as dirname77 } from "path";
430258
+ import { join as join164, dirname as dirname77 } from "path";
430442
430259
 
430443
430260
  class DefaultAscendFreshnessPort {
430444
430261
  injectedCache;
@@ -430452,8 +430269,8 @@ class DefaultAscendFreshnessPort {
430452
430269
  return env;
430453
430270
  let dir = dirname77(new URL(import.meta.url).pathname);
430454
430271
  for (let i = 0;i < MAX_WALK_UP; i++) {
430455
- if (existsSync12(join165(dir, "package.json")))
430456
- return join165(dir, ".freshness-cache.json");
430272
+ if (existsSync12(join164(dir, "package.json")))
430273
+ return join164(dir, ".freshness-cache.json");
430457
430274
  const parent = dirname77(dir);
430458
430275
  if (parent === dir)
430459
430276
  break;
@@ -430926,7 +430743,7 @@ import {
430926
430743
  dirname as dirname78,
430927
430744
  extname as extname17,
430928
430745
  isAbsolute as isAbsolute33,
430929
- join as join166,
430746
+ join as join165,
430930
430747
  parse as parse13,
430931
430748
  relative as relative29,
430932
430749
  sep as sep36
@@ -431166,7 +430983,7 @@ async function processMdRules({
431166
430983
  throw e;
431167
430984
  }
431168
430985
  for (const entry of entries) {
431169
- const entryPath = join166(rulesDir, entry.name);
430986
+ const entryPath = join165(rulesDir, entry.name);
431170
430987
  const { resolvedPath: resolvedEntryPath, isSymlink } = safeResolvePath3(fs, entryPath);
431171
430988
  const stats = isSymlink ? await fs.stat(resolvedEntryPath) : null;
431172
430989
  const isDirectory = stats ? stats.isDirectory() : entry.isDirectory();
@@ -431234,14 +431051,14 @@ async function getMemoryFilesForNestedDirectory(dir, targetPath, processedPaths)
431234
431051
  if (isSettingSourceEnabled2("projectSettings")) {
431235
431052
  const projectPath = findMemoryFile(dir);
431236
431053
  result.push(...await processMemoryFile(projectPath, "Project", processedPaths, false));
431237
- const dotClaudePath = findMemoryFile(join166(dir, getConfigDirName2()));
431054
+ const dotClaudePath = findMemoryFile(join165(dir, getConfigDirName2()));
431238
431055
  result.push(...await processMemoryFile(dotClaudePath, "Project", processedPaths, false));
431239
431056
  }
431240
431057
  if (isSettingSourceEnabled2("localSettings")) {
431241
- const localPath = join166(dir, "CLAUDE.local.md");
431058
+ const localPath = join165(dir, "CLAUDE.local.md");
431242
431059
  result.push(...await processMemoryFile(localPath, "Local", processedPaths, false));
431243
431060
  }
431244
- const rulesDir = join166(dir, getConfigDirName2(), "rules");
431061
+ const rulesDir = join165(dir, getConfigDirName2(), "rules");
431245
431062
  const unconditionalProcessedPaths = new Set(processedPaths);
431246
431063
  result.push(...await processMdRules({
431247
431064
  rulesDir,
@@ -431257,7 +431074,7 @@ async function getMemoryFilesForNestedDirectory(dir, targetPath, processedPaths)
431257
431074
  return result;
431258
431075
  }
431259
431076
  async function getConditionalRulesForCwdLevelDirectory(dir, targetPath, processedPaths) {
431260
- const rulesDir = join166(dir, getConfigDirName2(), "rules");
431077
+ const rulesDir = join165(dir, getConfigDirName2(), "rules");
431261
431078
  return processConditionedMdRules(targetPath, rulesDir, "Project", processedPaths, false);
431262
431079
  }
431263
431080
  async function processConditionedMdRules(targetPath, rulesDir, type, processedPaths, includeExternal) {
@@ -431513,9 +431330,9 @@ var init_memoryFiles = __esm(() => {
431513
431330
  if (isSettingSourceEnabled2("projectSettings") && !skipProject) {
431514
431331
  const projectPath = findMemoryFile(dir);
431515
431332
  result.push(...await processMemoryFile(projectPath, "Project", processedPaths, includeExternal));
431516
- const dotClaudePath = findMemoryFile(join166(dir, getConfigDirName2()));
431333
+ const dotClaudePath = findMemoryFile(join165(dir, getConfigDirName2()));
431517
431334
  result.push(...await processMemoryFile(dotClaudePath, "Project", processedPaths, includeExternal));
431518
- const rulesDir = join166(dir, getConfigDirName2(), "rules");
431335
+ const rulesDir = join165(dir, getConfigDirName2(), "rules");
431519
431336
  result.push(...await processMdRules({
431520
431337
  rulesDir,
431521
431338
  type: "Project",
@@ -431525,7 +431342,7 @@ var init_memoryFiles = __esm(() => {
431525
431342
  }));
431526
431343
  }
431527
431344
  if (isSettingSourceEnabled2("localSettings")) {
431528
- const localPath = join166(dir, "CLAUDE.local.md");
431345
+ const localPath = join165(dir, "CLAUDE.local.md");
431529
431346
  result.push(...await processMemoryFile(localPath, "Local", processedPaths, includeExternal));
431530
431347
  }
431531
431348
  }
@@ -431534,9 +431351,9 @@ var init_memoryFiles = __esm(() => {
431534
431351
  for (const dir of additionalDirs) {
431535
431352
  const projectPath = findMemoryFile(dir);
431536
431353
  result.push(...await processMemoryFile(projectPath, "Project", processedPaths, includeExternal));
431537
- const dotClaudePath = findMemoryFile(join166(dir, getConfigDirName2()));
431354
+ const dotClaudePath = findMemoryFile(join165(dir, getConfigDirName2()));
431538
431355
  result.push(...await processMemoryFile(dotClaudePath, "Project", processedPaths, includeExternal));
431539
- const rulesDir = join166(dir, getConfigDirName2(), "rules");
431356
+ const rulesDir = join165(dir, getConfigDirName2(), "rules");
431540
431357
  result.push(...await processMdRules({
431541
431358
  rulesDir,
431542
431359
  type: "Project",
@@ -440060,7 +439877,7 @@ var init_AutoModeConfirm = __esm(() => {
440060
439877
 
440061
439878
  // src/tui/components/permissions/FilePermissionDialog/permissionOptions.tsx
440062
439879
  import { homedir as homedir39 } from "os";
440063
- import { basename as basename54, join as join167, sep as sep37 } from "path";
439880
+ import { basename as basename54, join as join166, sep as sep37 } from "path";
440064
439881
  function isInClaudeFolder(filePath) {
440065
439882
  const absolutePath = expandPath2(filePath);
440066
439883
  const claudeFolderPath = expandPath2(`${getOriginalCwd()}/${getConfigDirName2()}`);
@@ -440070,7 +439887,7 @@ function isInClaudeFolder(filePath) {
440070
439887
  }
440071
439888
  function isInGlobalClaudeFolder(filePath) {
440072
439889
  const absolutePath = expandPath2(filePath);
440073
- const globalClaudeFolderPath = join167(homedir39(), getConfigDirName2());
439890
+ const globalClaudeFolderPath = join166(homedir39(), getConfigDirName2());
440074
439891
  const normalizedAbsolutePath = normalizeCaseForComparison2(absolutePath);
440075
439892
  const normalizedGlobalClaudeFolderPath = normalizeCaseForComparison2(globalClaudeFolderPath);
440076
439893
  return normalizedAbsolutePath.startsWith(normalizedGlobalClaudeFolderPath + sep37.toLowerCase()) || normalizedAbsolutePath.startsWith(normalizedGlobalClaudeFolderPath + "/");
@@ -457791,10 +457608,10 @@ var init_segments = __esm(() => {
457791
457608
 
457792
457609
  // src/tui/components/StatusLine/segments/statusLineConfig.ts
457793
457610
  import { readFileSync as readFileSync23, existsSync as existsSync13, writeFileSync as writeFileSync9, renameSync as renameSync3, mkdirSync as mkdirSync9 } from "fs";
457794
- import { join as join168 } from "path";
457611
+ import { join as join167 } from "path";
457795
457612
  import { homedir as homedir41 } from "os";
457796
457613
  function getStatusLineJsonPath() {
457797
- return join168(homedir41(), getConfigDirName2(), "statusline.json");
457614
+ return join167(homedir41(), getConfigDirName2(), "statusline.json");
457798
457615
  }
457799
457616
  function getDefaultConfig() {
457800
457617
  return {
@@ -463219,7 +463036,7 @@ var init_autoDream = __esm(() => {
463219
463036
  });
463220
463037
 
463221
463038
  // src/tui/utils/cleanup.ts
463222
- import { join as join169 } from "path";
463039
+ import { join as join168 } from "path";
463223
463040
  function getCutoffDate() {
463224
463041
  const settings = getSettings_DEPRECATED() || {};
463225
463042
  const cleanupPeriodDays = settings.cleanupPeriodDays ?? DEFAULT_CLEANUP_PERIOD_DAYS;
@@ -463244,7 +463061,7 @@ async function cleanupOldFilesInDirectory(dirPath, cutoffDate, isMessagePath) {
463244
463061
  try {
463245
463062
  const timestamp = convertFileNameToDate(file.name);
463246
463063
  if (timestamp < cutoffDate) {
463247
- await getFsImplementation2().unlink(join169(dirPath, file.name));
463064
+ await getFsImplementation2().unlink(join168(dirPath, file.name));
463248
463065
  if (isMessagePath) {
463249
463066
  result.messages++;
463250
463067
  } else {
@@ -463275,7 +463092,7 @@ async function cleanupOldMessageFiles() {
463275
463092
  } catch {
463276
463093
  return result;
463277
463094
  }
463278
- const mcpLogDirs = dirents.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("mcp-logs-")).map((dirent) => join169(baseCachePath, dirent.name));
463095
+ const mcpLogDirs = dirents.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("mcp-logs-")).map((dirent) => join168(baseCachePath, dirent.name));
463279
463096
  for (const mcpLogDir of mcpLogDirs) {
463280
463097
  result = addCleanupResults(result, await cleanupOldFilesInDirectory(mcpLogDir, cutoffDate, true));
463281
463098
  await tryRmdir(mcpLogDir, fsImpl);
@@ -463314,7 +463131,7 @@ async function cleanupOldSessionFiles() {
463314
463131
  for (const projectDirent of projectDirents) {
463315
463132
  if (!projectDirent.isDirectory())
463316
463133
  continue;
463317
- const projectDir = join169(projectsDir, projectDirent.name);
463134
+ const projectDir = join168(projectsDir, projectDirent.name);
463318
463135
  let entries;
463319
463136
  try {
463320
463137
  entries = await fsImpl.readdir(projectDir);
@@ -463328,15 +463145,15 @@ async function cleanupOldSessionFiles() {
463328
463145
  continue;
463329
463146
  }
463330
463147
  try {
463331
- if (await unlinkIfOld(join169(projectDir, entry.name), cutoffDate, fsImpl)) {
463148
+ if (await unlinkIfOld(join168(projectDir, entry.name), cutoffDate, fsImpl)) {
463332
463149
  result.messages++;
463333
463150
  }
463334
463151
  } catch {
463335
463152
  result.errors++;
463336
463153
  }
463337
463154
  } else if (entry.isDirectory()) {
463338
- const sessionDir = join169(projectDir, entry.name);
463339
- const toolResultsDir = join169(sessionDir, TOOL_RESULTS_SUBDIR3);
463155
+ const sessionDir = join168(projectDir, entry.name);
463156
+ const toolResultsDir = join168(sessionDir, TOOL_RESULTS_SUBDIR3);
463340
463157
  let toolDirs;
463341
463158
  try {
463342
463159
  toolDirs = await fsImpl.readdir(toolResultsDir);
@@ -463347,14 +463164,14 @@ async function cleanupOldSessionFiles() {
463347
463164
  for (const toolEntry of toolDirs) {
463348
463165
  if (toolEntry.isFile()) {
463349
463166
  try {
463350
- if (await unlinkIfOld(join169(toolResultsDir, toolEntry.name), cutoffDate, fsImpl)) {
463167
+ if (await unlinkIfOld(join168(toolResultsDir, toolEntry.name), cutoffDate, fsImpl)) {
463351
463168
  result.messages++;
463352
463169
  }
463353
463170
  } catch {
463354
463171
  result.errors++;
463355
463172
  }
463356
463173
  } else if (toolEntry.isDirectory()) {
463357
- const toolDirPath = join169(toolResultsDir, toolEntry.name);
463174
+ const toolDirPath = join168(toolResultsDir, toolEntry.name);
463358
463175
  let toolFiles;
463359
463176
  try {
463360
463177
  toolFiles = await fsImpl.readdir(toolDirPath);
@@ -463365,7 +463182,7 @@ async function cleanupOldSessionFiles() {
463365
463182
  if (!tf.isFile())
463366
463183
  continue;
463367
463184
  try {
463368
- if (await unlinkIfOld(join169(toolDirPath, tf.name), cutoffDate, fsImpl)) {
463185
+ if (await unlinkIfOld(join168(toolDirPath, tf.name), cutoffDate, fsImpl)) {
463369
463186
  result.messages++;
463370
463187
  }
463371
463188
  } catch {
@@ -463397,7 +463214,7 @@ async function cleanupSingleDirectory(dirPath, extension, removeEmptyDir = true)
463397
463214
  if (!dirent.isFile() || !dirent.name.endsWith(extension))
463398
463215
  continue;
463399
463216
  try {
463400
- if (await unlinkIfOld(join169(dirPath, dirent.name), cutoffDate, fsImpl)) {
463217
+ if (await unlinkIfOld(join168(dirPath, dirent.name), cutoffDate, fsImpl)) {
463401
463218
  result.messages++;
463402
463219
  }
463403
463220
  } catch {
@@ -463410,7 +463227,7 @@ async function cleanupSingleDirectory(dirPath, extension, removeEmptyDir = true)
463410
463227
  return result;
463411
463228
  }
463412
463229
  function cleanupOldPlanFiles() {
463413
- const plansDir = join169(getAtlasConfigHomeDir3(), "plans");
463230
+ const plansDir = join168(getAtlasConfigHomeDir3(), "plans");
463414
463231
  return cleanupSingleDirectory(plansDir, ".md");
463415
463232
  }
463416
463233
  async function cleanupOldFileHistoryBackups() {
@@ -463419,14 +463236,14 @@ async function cleanupOldFileHistoryBackups() {
463419
463236
  const fsImpl = getFsImplementation2();
463420
463237
  try {
463421
463238
  const configDir = getAtlasConfigHomeDir3();
463422
- const fileHistoryStorageDir = join169(configDir, "file-history");
463239
+ const fileHistoryStorageDir = join168(configDir, "file-history");
463423
463240
  let dirents;
463424
463241
  try {
463425
463242
  dirents = await fsImpl.readdir(fileHistoryStorageDir);
463426
463243
  } catch {
463427
463244
  return result;
463428
463245
  }
463429
- const fileHistorySessionsDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join169(fileHistoryStorageDir, dirent.name));
463246
+ const fileHistorySessionsDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join168(fileHistoryStorageDir, dirent.name));
463430
463247
  await Promise.all(fileHistorySessionsDirs.map(async (fileHistorySessionDir) => {
463431
463248
  try {
463432
463249
  const stats = await fsImpl.stat(fileHistorySessionDir);
@@ -463453,14 +463270,14 @@ async function cleanupOldSessionEnvDirs() {
463453
463270
  const fsImpl = getFsImplementation2();
463454
463271
  try {
463455
463272
  const configDir = getAtlasConfigHomeDir3();
463456
- const sessionEnvBaseDir = join169(configDir, "session-env");
463273
+ const sessionEnvBaseDir = join168(configDir, "session-env");
463457
463274
  let dirents;
463458
463275
  try {
463459
463276
  dirents = await fsImpl.readdir(sessionEnvBaseDir);
463460
463277
  } catch {
463461
463278
  return result;
463462
463279
  }
463463
- const sessionEnvDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join169(sessionEnvBaseDir, dirent.name));
463280
+ const sessionEnvDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join168(sessionEnvBaseDir, dirent.name));
463464
463281
  for (const sessionEnvDir of sessionEnvDirs) {
463465
463282
  try {
463466
463283
  const stats = await fsImpl.stat(sessionEnvDir);
@@ -463482,7 +463299,7 @@ async function cleanupOldDebugLogs() {
463482
463299
  const cutoffDate = getCutoffDate();
463483
463300
  const result = { messages: 0, errors: 0 };
463484
463301
  const fsImpl = getFsImplementation2();
463485
- const debugDir = join169(getAtlasConfigHomeDir3(), "debug");
463302
+ const debugDir = join168(getAtlasConfigHomeDir3(), "debug");
463486
463303
  let dirents;
463487
463304
  try {
463488
463305
  dirents = await fsImpl.readdir(debugDir);
@@ -463494,7 +463311,7 @@ async function cleanupOldDebugLogs() {
463494
463311
  continue;
463495
463312
  }
463496
463313
  try {
463497
- if (await unlinkIfOld(join169(debugDir, dirent.name), cutoffDate, fsImpl)) {
463314
+ if (await unlinkIfOld(join168(debugDir, dirent.name), cutoffDate, fsImpl)) {
463498
463315
  result.messages++;
463499
463316
  }
463500
463317
  } catch {
@@ -464939,10 +464756,10 @@ var init_coordinatorHandler = __esm(() => {
464939
464756
  });
464940
464757
 
464941
464758
  // src/tui/utils/permissions/sessionPermissionRules.ts
464942
- import { mkdir as mkdir53, readFile as readFile61, rename as rename11, writeFile as writeFile49 } from "fs/promises";
464943
- import { dirname as dirname80, join as join171 } from "path";
464759
+ import { mkdir as mkdir53, readFile as readFile61, rename as rename11, writeFile as writeFile48 } from "fs/promises";
464760
+ import { dirname as dirname80, join as join170 } from "path";
464944
464761
  function sessionRulesPath(sessionId, projectDir) {
464945
- return join171(projectDir, `${sessionId}${SESSION_RULES_FILE_SUFFIX}`);
464762
+ return join170(projectDir, `${sessionId}${SESSION_RULES_FILE_SUFFIX}`);
464946
464763
  }
464947
464764
  function parseSessionRulesJson(json) {
464948
464765
  if (json.length > MAX_SESSION_RULES_BYTES)
@@ -465002,7 +464819,7 @@ async function mergeSessionPermissionRules(sessionId, projectDir, updates) {
465002
464819
  await mkdir53(projectDir, { recursive: true });
465003
464820
  const target = sessionRulesPath(sessionId, projectDir);
465004
464821
  const tmp = `${target}.tmp-${process.pid}`;
465005
- await writeFile49(tmp, JSON.stringify({ version: 1, updates: merged }, null, 2));
464822
+ await writeFile48(tmp, JSON.stringify({ version: 1, updates: merged }, null, 2));
465006
464823
  await rename11(tmp, target);
465007
464824
  return true;
465008
464825
  } catch (e) {
@@ -467929,7 +467746,7 @@ var init_conversationRecovery = __esm(() => {
467929
467746
 
467930
467747
  // src/tui/utils/asciicast.ts
467931
467748
  import { appendFile as appendFile6, rename as rename12 } from "fs/promises";
467932
- import { basename as basename63, dirname as dirname81, join as join173 } from "path";
467749
+ import { basename as basename63, dirname as dirname81, join as join172 } from "path";
467933
467750
  function getRecordFilePath() {
467934
467751
  if (recordingState.filePath !== null) {
467935
467752
  return recordingState.filePath;
@@ -467940,10 +467757,10 @@ function getRecordFilePath() {
467940
467757
  if (!isEnvTruthy2(process.env.ATLAS_TERMINAL_RECORDING)) {
467941
467758
  return null;
467942
467759
  }
467943
- const projectsDir = join173(getAtlasConfigHomeDir3(), "projects");
467944
- const projectDir = join173(projectsDir, sanitizePath3(getOriginalCwd()));
467760
+ const projectsDir = join172(getAtlasConfigHomeDir3(), "projects");
467761
+ const projectDir = join172(projectsDir, sanitizePath3(getOriginalCwd()));
467945
467762
  recordingState.timestamp = Date.now();
467946
- recordingState.filePath = join173(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
467763
+ recordingState.filePath = join172(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
467947
467764
  return recordingState.filePath;
467948
467765
  }
467949
467766
  async function renameRecordingForSession() {
@@ -467951,9 +467768,9 @@ async function renameRecordingForSession() {
467951
467768
  if (!oldPath || recordingState.timestamp === 0) {
467952
467769
  return;
467953
467770
  }
467954
- const projectsDir = join173(getAtlasConfigHomeDir3(), "projects");
467955
- const projectDir = join173(projectsDir, sanitizePath3(getOriginalCwd()));
467956
- const newPath = join173(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
467771
+ const projectsDir = join172(getAtlasConfigHomeDir3(), "projects");
467772
+ const projectDir = join172(projectsDir, sanitizePath3(getOriginalCwd()));
467773
+ const newPath = join172(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
467957
467774
  if (oldPath === newPath) {
467958
467775
  return;
467959
467776
  }
@@ -469366,6 +469183,98 @@ var init_useAwaySummary = __esm(() => {
469366
469183
  BLUR_DELAY_MS = 5 * 60000;
469367
469184
  });
469368
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
+
469369
469278
  // src/tui/utils/plugins/officialMarketplaceStartupCheck.ts
469370
469279
  import { join as join174 } from "path";
469371
469280
  function isOfficialMarketplaceAutoInstallDisabled() {
@@ -469425,14 +469334,19 @@ async function checkAndInstallOfficialMarketplace() {
469425
469334
  return { installed: false, skipped: true, reason: "policy_blocked" };
469426
469335
  }
469427
469336
  const knownMarketplaces = await loadKnownMarketplacesConfig();
469428
- if (knownMarketplaces[OFFICIAL_MARKETPLACE_NAME]) {
469429
- logForDebugging3(`Official marketplace '${OFFICIAL_MARKETPLACE_NAME}' already installed, skipping`);
469430
- saveGlobalConfig((current) => ({
469431
- ...current,
469432
- officialMarketplaceAutoInstallAttempted: true,
469433
- officialMarketplaceAutoInstalled: true
469434
- }));
469435
- 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
+ }
469436
469350
  }
469437
469351
  if (!isSourceAllowedByPolicy(OFFICIAL_MARKETPLACE_SOURCE)) {
469438
469352
  logForDebugging3("Official marketplace blocked by enterprise policy, skipping");
@@ -469448,13 +469362,15 @@ async function checkAndInstallOfficialMarketplace() {
469448
469362
  const installLocation = join174(cacheDir, OFFICIAL_MARKETPLACE_NAME);
469449
469363
  const gcsSha = await fetchOfficialMarketplaceFromGcs(installLocation, cacheDir);
469450
469364
  if (gcsSha !== null) {
469451
- const known = await loadKnownMarketplacesConfig();
469452
- known[OFFICIAL_MARKETPLACE_NAME] = {
469453
- source: OFFICIAL_MARKETPLACE_SOURCE,
469454
- installLocation,
469455
- lastUpdated: new Date().toISOString()
469456
- };
469457
- 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);
469458
469374
  saveGlobalConfig((current) => ({
469459
469375
  ...current,
469460
469376
  officialMarketplaceAutoInstallAttempted: true,
@@ -469480,6 +469396,9 @@ async function checkAndInstallOfficialMarketplace() {
469480
469396
  officialMarketplaceAutoInstallLastAttemptTime: now,
469481
469397
  officialMarketplaceAutoInstallNextRetryTime: nextRetryTime
469482
469398
  }));
469399
+ const fallback = await tryOfficialSnapshotFallback("gcs_unavailable");
469400
+ if (fallback)
469401
+ return fallback;
469483
469402
  return { installed: false, skipped: true, reason: "gcs_unavailable" };
469484
469403
  }
469485
469404
  const gitAvailable = await checkGitAvailable();
@@ -469506,6 +469425,9 @@ async function checkAndInstallOfficialMarketplace() {
469506
469425
  logError3(configError);
469507
469426
  logForDebugging3(`Failed to save marketplace auto-install git_unavailable state: ${saveError}`, { level: "error" });
469508
469427
  }
469428
+ const fallback = await tryOfficialSnapshotFallback("git_unavailable");
469429
+ if (fallback)
469430
+ return fallback;
469509
469431
  return {
469510
469432
  installed: false,
469511
469433
  skipped: true,
@@ -469516,6 +469438,7 @@ async function checkAndInstallOfficialMarketplace() {
469516
469438
  logForDebugging3("Attempting to auto-install official marketplace");
469517
469439
  await addMarketplaceSource(OFFICIAL_MARKETPLACE_SOURCE);
469518
469440
  logForDebugging3("Successfully auto-installed official marketplace");
469441
+ await removeBuiltinSnapshotDir(OFFICIAL_MARKETPLACE_NAME);
469519
469442
  const previousRetryCount = config.officialMarketplaceAutoInstallRetryCount || 0;
469520
469443
  saveGlobalConfig((current) => ({
469521
469444
  ...current,
@@ -469532,6 +469455,9 @@ async function checkAndInstallOfficialMarketplace() {
469532
469455
  if (errorMessage.includes("xcrun: error:")) {
469533
469456
  markGitUnavailable();
469534
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;
469535
469461
  return {
469536
469462
  installed: false,
469537
469463
  skipped: true,
@@ -469561,6 +469487,9 @@ async function checkAndInstallOfficialMarketplace() {
469561
469487
  logError3(configError);
469562
469488
  logForDebugging3(`Failed to save marketplace auto-install failure state: ${saveError}`, { level: "error" });
469563
469489
  }
469490
+ const fallback = await tryOfficialSnapshotFallback("unknown");
469491
+ if (fallback)
469492
+ return fallback;
469564
469493
  return {
469565
469494
  installed: false,
469566
469495
  skipped: true,
@@ -469569,6 +469498,18 @@ async function checkAndInstallOfficialMarketplace() {
469569
469498
  };
469570
469499
  }
469571
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
+ }
469572
469513
  var RETRY_CONFIG;
469573
469514
  var init_officialMarketplaceStartupCheck = __esm(() => {
469574
469515
  init_growthbook();
@@ -469580,6 +469521,7 @@ var init_officialMarketplaceStartupCheck = __esm(() => {
469580
469521
  init_gitAvailability();
469581
469522
  init_marketplaceHelpers();
469582
469523
  init_marketplaceManager();
469524
+ init_marketplaceSnapshotFallback();
469583
469525
  init_officialMarketplace();
469584
469526
  init_officialMarketplaceGcs();
469585
469527
  RETRY_CONFIG = {
@@ -469609,7 +469551,18 @@ async function _temp179() {
469609
469551
  timeoutMs: 1e4
469610
469552
  });
469611
469553
  }
469612
- 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) {
469613
469566
  logForDebugging3("Showing marketplace installation success notification");
469614
469567
  notifs.push({
469615
469568
  key: "marketplace-installed",
@@ -469675,9 +469628,18 @@ async function checkAndInstallMarketplacePreset(config) {
469675
469628
  if (config.name) {
469676
469629
  try {
469677
469630
  const knownMarketplaces = await loadKnownMarketplacesConfig();
469678
- if (knownMarketplaces[config.name]) {
469679
- logForDebugging3(`${label} marketplace '${config.name}' already installed, skipping`);
469680
- 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
+ }
469681
469643
  }
469682
469644
  } catch (error) {
469683
469645
  logForDebugging3(`${label} marketplace: failed to read known_marketplaces (${toError2(error).message}), attempting install`, { level: "error" });
@@ -469690,25 +469652,51 @@ async function checkAndInstallMarketplacePreset(config) {
469690
469652
  const gitAvailable = await checkGitAvailable();
469691
469653
  if (!gitAvailable) {
469692
469654
  logForDebugging3(`Git not available, skipping ${label} marketplace auto-install`);
469655
+ const fallback = await trySnapshotFallback(config, "git_unavailable");
469656
+ if (fallback)
469657
+ return fallback;
469693
469658
  return { installed: false, skipped: true, reason: "git_unavailable" };
469694
469659
  }
469695
469660
  try {
469696
469661
  logForDebugging3(`Attempting to auto-install ${label} marketplace`);
469697
469662
  await addMarketplaceSource(config.source);
469698
469663
  logForDebugging3(`Successfully auto-installed ${label} marketplace`);
469664
+ if (config.name) {
469665
+ await removeBuiltinSnapshotDir(config.name);
469666
+ }
469699
469667
  return { installed: true, skipped: false };
469700
469668
  } catch (error) {
469701
469669
  const errorMessage = error instanceof Error ? error.message : String(error);
469702
469670
  if (errorMessage.includes("xcrun: error:")) {
469703
469671
  markGitUnavailable();
469704
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;
469705
469676
  return { installed: false, skipped: true, reason: "git_unavailable" };
469706
469677
  }
469707
469678
  logForDebugging3(`Failed to auto-install ${label} marketplace: ${errorMessage}`, { level: "error" });
469708
469679
  logError3(toError2(error));
469680
+ const fallback = await trySnapshotFallback(config, "unknown");
469681
+ if (fallback)
469682
+ return fallback;
469709
469683
  return { installed: false, skipped: true, reason: "unknown" };
469710
469684
  }
469711
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
+ }
469712
469700
  var init_marketplacePreset = __esm(() => {
469713
469701
  init_debug();
469714
469702
  init_envUtils2();
@@ -469717,6 +469705,7 @@ var init_marketplacePreset = __esm(() => {
469717
469705
  init_gitAvailability();
469718
469706
  init_marketplaceHelpers();
469719
469707
  init_marketplaceManager();
469708
+ init_marketplaceSnapshotFallback();
469720
469709
  });
469721
469710
 
469722
469711
  // src/tui/plugins/ascend/marketplace/ascendMarketplaceStartupCheck.ts
@@ -469766,7 +469755,21 @@ function useAscendMarketplaceNotification() {
469766
469755
  useStartupNotification(async () => {
469767
469756
  const result = await checkAndInstallAscendMarketplace();
469768
469757
  const notifs = [];
469769
- 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) {
469770
469773
  logForDebugging3("Showing Ascend marketplace installation success notification");
469771
469774
  notifs.push({
469772
469775
  key: "ascend-marketplace-installed",
@@ -469849,7 +469852,21 @@ function useAtlasMarketplaceNotification() {
469849
469852
  useStartupNotification(async () => {
469850
469853
  const result = await checkAndInstallAtlasMarketplace();
469851
469854
  const notifs = [];
469852
- 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) {
469853
469870
  logForDebugging3("Showing Atlas marketplace installation success notification");
469854
469871
  notifs.push({
469855
469872
  key: "atlas-marketplace-installed",
@@ -471719,7 +471736,7 @@ var init_usePluginAutoupdateNotification = __esm(() => {
471719
471736
  });
471720
471737
 
471721
471738
  // src/tui/utils/plugins/reconciler.ts
471722
- import { isAbsolute as isAbsolute34, resolve as resolve53 } from "path";
471739
+ import { isAbsolute as isAbsolute34, resolve as resolve54 } from "path";
471723
471740
  function diffMarketplaces(declared, materialized, opts) {
471724
471741
  const missing = [];
471725
471742
  const sourceChanged = [];
@@ -471832,7 +471849,7 @@ function normalizeSource(source, projectRoot) {
471832
471849
  const canonicalRoot = findCanonicalGitRoot2(base);
471833
471850
  return {
471834
471851
  ...source,
471835
- path: resolve53(canonicalRoot ?? base, source.path)
471852
+ path: resolve54(canonicalRoot ?? base, source.path)
471836
471853
  };
471837
471854
  }
471838
471855
  return source;
@@ -474824,7 +474841,7 @@ var init_cronJitterConfig2 = __esm(() => {
474824
474841
  });
474825
474842
 
474826
474843
  // src/tui/utils/cronTasksLock.ts
474827
- import { mkdir as mkdir54, readFile as readFile62, unlink as unlink26, writeFile as writeFile50 } from "fs/promises";
474844
+ import { mkdir as mkdir55, readFile as readFile63, unlink as unlink26, writeFile as writeFile50 } from "fs/promises";
474828
474845
  import { dirname as dirname83, join as join176 } from "path";
474829
474846
  function getLockPath3(dir) {
474830
474847
  return join176(dir ?? getProjectRoot(), LOCK_FILE_REL2);
@@ -474832,7 +474849,7 @@ function getLockPath3(dir) {
474832
474849
  async function readLock3(dir) {
474833
474850
  let raw;
474834
474851
  try {
474835
- raw = await readFile62(getLockPath3(dir), "utf8");
474852
+ raw = await readFile63(getLockPath3(dir), "utf8");
474836
474853
  } catch {
474837
474854
  return;
474838
474855
  }
@@ -474850,7 +474867,7 @@ async function tryCreateExclusive3(lock, dir) {
474850
474867
  if (code === "EEXIST")
474851
474868
  return false;
474852
474869
  if (code === "ENOENT") {
474853
- await mkdir54(dirname83(path), { recursive: true });
474870
+ await mkdir55(dirname83(path), { recursive: true });
474854
474871
  try {
474855
474872
  await writeFile50(path, body, { flag: "wx" });
474856
474873
  return true;
@@ -484586,7 +484603,7 @@ var init_bundled = __esm(() => {
484586
484603
  // src/tui/utils/deepLink/banner.ts
484587
484604
  import { stat as stat53 } from "fs/promises";
484588
484605
  import { homedir as homedir44 } from "os";
484589
- import { join as join178, sep as sep41 } from "path";
484606
+ import { join as join178, sep as sep42 } from "path";
484590
484607
  function buildDeepLinkBanner(info) {
484591
484608
  const lines = [
484592
484609
  `This session was opened by an external deep link in ${tildify(info.cwd)}`
@@ -484627,7 +484644,7 @@ function tildify(p) {
484627
484644
  const home = homedir44();
484628
484645
  if (p === home)
484629
484646
  return "~";
484630
- if (p.startsWith(home + sep41))
484647
+ if (p.startsWith(home + sep42))
484631
484648
  return "~" + p.slice(home.length);
484632
484649
  return p;
484633
484650
  }
@@ -485134,23 +485151,6 @@ var init_migrateEnableAllProjectMcpServersToSettings = __esm(() => {
485134
485151
  init_settings3();
485135
485152
  });
485136
485153
 
485137
- // src/tui/migrations/migrateReplBridgeEnabledToRemoteControlAtStartup.ts
485138
- function migrateReplBridgeEnabledToRemoteControlAtStartup() {
485139
- saveGlobalConfig((prev) => {
485140
- const oldValue = prev["replBridgeEnabled"];
485141
- if (oldValue === undefined)
485142
- return prev;
485143
- if (prev.remoteControlAtStartup !== undefined)
485144
- return prev;
485145
- const next = { ...prev, remoteControlAtStartup: Boolean(oldValue) };
485146
- delete next["replBridgeEnabled"];
485147
- return next;
485148
- });
485149
- }
485150
- var init_migrateReplBridgeEnabledToRemoteControlAtStartup = __esm(() => {
485151
- init_config6();
485152
- });
485153
-
485154
485154
  // src/tui/migrations/resetAutoModeOptInForDefaultOffer.ts
485155
485155
  function resetAutoModeOptInForDefaultOffer() {
485156
485156
  if (feature("TRANSCRIPT_CLASSIFIER")) {
@@ -486991,7 +486991,7 @@ var init_mcp8 = __esm(() => {
486991
486991
  });
486992
486992
 
486993
486993
  // src/tui/utils/atlasDesktop.ts
486994
- 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";
486995
486995
  import { homedir as homedir47 } from "os";
486996
486996
  import { join as join183 } from "path";
486997
486997
  async function getDesktopConfigPath() {
@@ -487039,7 +487039,7 @@ async function readDesktopMcpServers() {
487039
487039
  const configPath = await getDesktopConfigPath();
487040
487040
  let configContent;
487041
487041
  try {
487042
- configContent = await readFile63(configPath, { encoding: "utf8" });
487042
+ configContent = await readFile64(configPath, { encoding: "utf8" });
487043
487043
  } catch (e) {
487044
487044
  const code = getErrnoCode2(e);
487045
487045
  if (code === "ENOENT") {
@@ -487474,13 +487474,13 @@ var init_auth6 = __esm(() => {
487474
487474
  });
487475
487475
 
487476
487476
  // src/tui/utils/plugins/marketplacePublish.ts
487477
- import { cp, mkdir as mkdir55, readFile as readFile64, rm as rm11, writeFile as writeFile53 } from "fs/promises";
487477
+ import { cp, mkdir as mkdir56, readFile as readFile65, rm as rm12, writeFile as writeFile53 } from "fs/promises";
487478
487478
  import {
487479
487479
  dirname as dirname87,
487480
487480
  join as join184,
487481
487481
  relative as relative38,
487482
- resolve as resolve54,
487483
- sep as sep42
487482
+ resolve as resolve55,
487483
+ sep as sep43
487484
487484
  } from "path";
487485
487485
  function git(marketplaceDir, args, timeoutMs = 2 * 60 * 1000) {
487486
487486
  return execFileNoThrowWithCwd2("git", args, {
@@ -487492,16 +487492,16 @@ function gitFailureMessage(res) {
487492
487492
  return (res.stderr || res.error || `exit code ${res.code}`).trim();
487493
487493
  }
487494
487494
  async function publishPluginToMarketplace(opts) {
487495
- const pluginDir = resolve54(opts.pluginDir);
487496
- const marketplaceDir = resolve54(opts.marketplaceDir);
487495
+ const pluginDir = resolve55(opts.pluginDir);
487496
+ const marketplaceDir = resolve55(opts.marketplaceDir);
487497
487497
  const notes = [];
487498
- if (pluginDir === marketplaceDir || pluginDir.startsWith(marketplaceDir + sep42)) {
487498
+ if (pluginDir === marketplaceDir || pluginDir.startsWith(marketplaceDir + sep43)) {
487499
487499
  throw new Error(`Cannot publish "${pluginDir}": the plugin directory must not live inside the target marketplace (${marketplaceDir})`);
487500
487500
  }
487501
487501
  const pluginManifestPath = findManifestInDir(pluginDir, "plugin.json");
487502
487502
  let pluginManifestRaw;
487503
487503
  try {
487504
- pluginManifestRaw = await readFile64(pluginManifestPath, {
487504
+ pluginManifestRaw = await readFile65(pluginManifestPath, {
487505
487505
  encoding: "utf-8"
487506
487506
  });
487507
487507
  } catch {
@@ -487520,13 +487520,13 @@ async function publishPluginToMarketplace(opts) {
487520
487520
  const name = manifest.name;
487521
487521
  const version = opts.version ?? (typeof manifest.version === "string" ? manifest.version : undefined);
487522
487522
  const targetDir = join184(marketplaceDir, "plugins", name);
487523
- await rm11(targetDir, { recursive: true, force: true });
487524
- await mkdir55(dirname87(targetDir), { recursive: true });
487523
+ await rm12(targetDir, { recursive: true, force: true });
487524
+ await mkdir56(dirname87(targetDir), { recursive: true });
487525
487525
  await cp(pluginDir, targetDir, { recursive: true });
487526
487526
  const marketplaceManifestPath = findManifestInDir(marketplaceDir, "marketplace.json");
487527
487527
  let marketplaceRaw;
487528
487528
  try {
487529
- marketplaceRaw = await readFile64(marketplaceManifestPath, {
487529
+ marketplaceRaw = await readFile65(marketplaceManifestPath, {
487530
487530
  encoding: "utf-8"
487531
487531
  });
487532
487532
  } catch {
@@ -487623,10 +487623,10 @@ var init_marketplacePublish = __esm(() => {
487623
487623
  // src/tui/utils/plugins/marketplaceScaffold.ts
487624
487624
  import { userInfo as userInfo2 } from "os";
487625
487625
  import { existsSync as existsSync15 } from "fs";
487626
- import { mkdir as mkdir56, writeFile as writeFile54 } from "fs/promises";
487627
- import { dirname as dirname88, join as join185, 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";
487628
487628
  async function scaffoldMarketplace(opts) {
487629
- const targetDir = resolve55(opts.targetDir);
487629
+ const targetDir = resolve56(opts.targetDir);
487630
487630
  const name = opts.name.trim();
487631
487631
  const manifestDirName = getPluginManifestDirs()[0];
487632
487632
  const marketplaceManifestPath = join185(targetDir, manifestDirName, "marketplace.json");
@@ -487672,7 +487672,7 @@ async function scaffoldMarketplace(opts) {
487672
487672
  const files = [];
487673
487673
  const write = async (relPath, content) => {
487674
487674
  const abs = join185(targetDir, relPath);
487675
- await mkdir56(dirname88(abs), { recursive: true });
487675
+ await mkdir57(dirname88(abs), { recursive: true });
487676
487676
  await writeFile54(abs, content, "utf-8");
487677
487677
  files.push(relPath);
487678
487678
  };
@@ -487712,7 +487712,7 @@ var init_marketplaceScaffold = __esm(() => {
487712
487712
  });
487713
487713
 
487714
487714
  // src/tui/cli/handlers/plugins.ts
487715
- 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";
487716
487716
  function handleMarketplaceError(error, action) {
487717
487717
  logError3(error);
487718
487718
  cliError2(`${figures_default.cross} Failed to ${action}: ${errorMessage2(error)}`);
@@ -488064,7 +488064,7 @@ async function marketplaceUpdateHandler(name, options) {
488064
488064
  async function marketplaceScaffoldHandler(options) {
488065
488065
  if (options.cowork)
488066
488066
  setUseCoworkPlugins(true);
488067
- const targetDir = resolve56(options.target ?? process.cwd());
488067
+ const targetDir = resolve57(options.target ?? process.cwd());
488068
488068
  try {
488069
488069
  const result = await scaffoldMarketplace({
488070
488070
  name: options.name,
@@ -488089,8 +488089,8 @@ async function marketplacePublishHandler(options) {
488089
488089
  setUseCoworkPlugins(true);
488090
488090
  try {
488091
488091
  const result = await publishPluginToMarketplace({
488092
- pluginDir: resolve56(options.plugin),
488093
- marketplaceDir: resolve56(options.marketplace),
488092
+ pluginDir: resolve57(options.plugin),
488093
+ marketplaceDir: resolve57(options.marketplace),
488094
488094
  version: options.version,
488095
488095
  push: options.push
488096
488096
  });
@@ -489306,7 +489306,7 @@ var init_update2 = __esm(() => {
489306
489306
 
489307
489307
  // src/tui/main.tsx
489308
489308
  import { readFileSync as readFileSync25 } from "fs";
489309
- import { resolve as resolve57 } from "path";
489309
+ import { resolve as resolve58 } from "path";
489310
489310
  function logManagedSettings() {
489311
489311
  try {
489312
489312
  const policySettings = getSettingsForSource2("policySettings");
@@ -489353,7 +489353,6 @@ function runMigrations() {
489353
489353
  migrateAutoUpdatesToSettings();
489354
489354
  migrateBypassPermissionsAcceptedToSettings();
489355
489355
  migrateEnableAllProjectMcpServersToSettings();
489356
- migrateReplBridgeEnabledToRemoteControlAtStartup();
489357
489356
  if (feature("TRANSCRIPT_CLASSIFIER")) {
489358
489357
  resetAutoModeOptInForDefaultOffer();
489359
489358
  }
@@ -489616,8 +489615,7 @@ async function main2() {
489616
489615
  const cliArgs = process.argv.slice(2);
489617
489616
  const hasPrintFlag = cliArgs.includes("-p") || cliArgs.includes("--print");
489618
489617
  const hasInitOnlyFlag = cliArgs.includes("--init-only");
489619
- const hasSdkUrl = cliArgs.some((arg) => arg.startsWith("--sdk-url"));
489620
- const isNonInteractive = hasPrintFlag || hasInitOnlyFlag || hasSdkUrl || !process.stdout.isTTY;
489618
+ const isNonInteractive = hasPrintFlag || hasInitOnlyFlag || !process.stdout.isTTY;
489621
489619
  if (isNonInteractive) {
489622
489620
  stopCapturingEarlyInput();
489623
489621
  }
@@ -489652,9 +489650,6 @@ async function main2() {
489652
489650
  } else if (!clientType.startsWith("sdk-") && clientType !== "claude-desktop" && clientType !== "local-agent" && clientType !== "remote") {
489653
489651
  setQuestionPreviewFormat("markdown");
489654
489652
  }
489655
- if (process.env.ATLAS_ENVIRONMENT_KIND === "bridge") {
489656
- setSessionSource("remote-control");
489657
- }
489658
489653
  profileCheckpoint("main_client_type_determined");
489659
489654
  eagerLoadSettings2();
489660
489655
  profileCheckpoint("main_before_run");
@@ -489837,49 +489832,26 @@ ${getTmuxInstallInstructions3()}
489837
489832
  getTeammateModeSnapshot().setCliTeammateModeOverride?.(teammateOpts.teammateMode);
489838
489833
  }
489839
489834
  }
489840
- const sdkUrl = options.sdkUrl ?? undefined;
489841
489835
  const effectiveIncludePartialMessages = includePartialMessages || isEnvTruthy2(process.env.ATLAS_INCLUDE_PARTIAL_MESSAGES);
489842
489836
  if (includeHookEvents || isEnvTruthy2(process.env.ATLAS_REMOTE)) {
489843
489837
  setAllHookEventsEnabled(true);
489844
489838
  }
489845
- if (sdkUrl) {
489846
- if (!inputFormat) {
489847
- inputFormat = "stream-json";
489848
- }
489849
- if (!outputFormat) {
489850
- outputFormat = "stream-json";
489851
- }
489852
- if (options.verbose === undefined) {
489853
- verbose = true;
489854
- }
489855
- if (!options.print) {
489856
- print = true;
489857
- }
489858
- }
489859
- const teleport = options.teleport ?? null;
489860
- const remoteOption = options.remote;
489861
- const remote = remoteOption === true ? "" : remoteOption ?? null;
489862
- const remoteControlOption = options.remoteControl ?? options.rc;
489863
- let remoteControl = false;
489864
- const remoteControlName = typeof remoteControlOption === "string" && remoteControlOption.length > 0 ? remoteControlOption : undefined;
489865
489839
  if (sessionId) {
489866
489840
  if ((options.continue || options.resume) && !options.forkSession) {
489867
489841
  process.stderr.write(source_default.red(`Error: --session-id can only be used with --continue or --resume if --fork-session is also specified.
489868
489842
  `));
489869
489843
  process.exit(1);
489870
489844
  }
489871
- if (!sdkUrl) {
489872
- const validatedSessionId = validateUuid2(sessionId);
489873
- if (!validatedSessionId) {
489874
- process.stderr.write(source_default.red(`Error: Invalid session ID. Must be a valid UUID.
489845
+ const validatedSessionId = validateUuid2(sessionId);
489846
+ if (!validatedSessionId) {
489847
+ process.stderr.write(source_default.red(`Error: Invalid session ID. Must be a valid UUID.
489875
489848
  `));
489876
- process.exit(1);
489877
- }
489878
- if (sessionIdExists(validatedSessionId)) {
489879
- process.stderr.write(source_default.red(`Error: Session ID ${validatedSessionId} is already in use.
489849
+ process.exit(1);
489850
+ }
489851
+ if (sessionIdExists(validatedSessionId)) {
489852
+ process.stderr.write(source_default.red(`Error: Session ID ${validatedSessionId} is already in use.
489880
489853
  `));
489881
- process.exit(1);
489882
- }
489854
+ process.exit(1);
489883
489855
  }
489884
489856
  }
489885
489857
  const fileSpecs = options.file;
@@ -489901,12 +489873,12 @@ ${getTmuxInstallInstructions3()}
489901
489873
  process.exit(1);
489902
489874
  }
489903
489875
  try {
489904
- const filePath = resolve57(options.systemPromptFile);
489876
+ const filePath = resolve58(options.systemPromptFile);
489905
489877
  systemPrompt = readFileSync25(filePath, "utf8");
489906
489878
  } catch (error) {
489907
489879
  const code = getErrnoCode2(error);
489908
489880
  if (code === "ENOENT") {
489909
- 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)}
489910
489882
  `));
489911
489883
  process.exit(1);
489912
489884
  }
@@ -489923,12 +489895,12 @@ ${getTmuxInstallInstructions3()}
489923
489895
  process.exit(1);
489924
489896
  }
489925
489897
  try {
489926
- const filePath = resolve57(options.appendSystemPromptFile);
489898
+ const filePath = resolve58(options.appendSystemPromptFile);
489927
489899
  appendSystemPrompt = readFileSync25(filePath, "utf8");
489928
489900
  } catch (error) {
489929
489901
  const code = getErrnoCode2(error);
489930
489902
  if (code === "ENOENT") {
489931
- 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)}
489932
489904
  `));
489933
489905
  process.exit(1);
489934
489906
  }
@@ -489978,7 +489950,7 @@ ${addendum}` : addendum;
489978
489950
  errors = result.errors;
489979
489951
  }
489980
489952
  } else {
489981
- const configPath = resolve57(configItem);
489953
+ const configPath = resolve58(configItem);
489982
489954
  const result = parseMcpConfigFromFilePath({
489983
489955
  filePath: configPath,
489984
489956
  expandVars: true,
@@ -490073,7 +490045,7 @@ ${formattedErrors}
490073
490045
  }
490074
490046
  }
490075
490047
  setAdditionalDirectoriesForClaudeMd(addDir);
490076
- const shouldAvoidPermissionPrompts = isNonInteractiveSession && !sdkUrl && !options.permissionPromptTool;
490048
+ const shouldAvoidPermissionPrompts = isNonInteractiveSession && !options.permissionPromptTool;
490077
490049
  const initResult = await initializeToolPermissionContext2({
490078
490050
  allowedToolsCli: allowedTools,
490079
490051
  disallowedToolsCli: disallowedTools,
@@ -490114,12 +490086,6 @@ ${formattedErrors}
490114
490086
  console.error(`Error: --input-format=stream-json requires output-format=stream-json.`);
490115
490087
  process.exit(1);
490116
490088
  }
490117
- if (sdkUrl) {
490118
- if (inputFormat !== "stream-json" || outputFormat !== "stream-json") {
490119
- console.error(`Error: --sdk-url requires both --input-format=stream-json and --output-format=stream-json.`);
490120
- process.exit(1);
490121
- }
490122
- }
490123
490089
  if (options.replayUserMessages) {
490124
490090
  if (inputFormat !== "stream-json" || outputFormat !== "stream-json") {
490125
490091
  console.error(`Error: --replay-user-messages requires both --input-format=stream-json and --output-format=stream-json.`);
@@ -490489,7 +490455,7 @@ ${inputPrompt}` : mergePrompt;
490489
490455
  }
490490
490456
  applyConfigEnvironmentVariables2();
490491
490457
  initializeTelemetryAfterTrust();
490492
- const sessionStartHooksPromise = options.continue || options.resume || teleport || setupTrigger ? undefined : processSessionStartHooks("startup");
490458
+ const sessionStartHooksPromise = options.continue || options.resume || setupTrigger ? undefined : processSessionStartHooks("startup");
490493
490459
  sessionStartHooksPromise?.catch(() => {});
490494
490460
  profileCheckpoint("before_validateForceLoginOrg");
490495
490461
  const orgValidation = await validateForceLoginOrg();
@@ -490657,7 +490623,6 @@ ${inputPrompt}` : mergePrompt;
490657
490623
  permissionPromptToolName: options.permissionPromptTool,
490658
490624
  maxTurns: options.maxTurns,
490659
490625
  model: effectiveModel,
490660
- sdkUrl,
490661
490626
  replayUserMessages: effectiveReplayUserMessages,
490662
490627
  agent: agentCli
490663
490628
  });
@@ -490696,7 +490661,7 @@ ${inputPrompt}` : mergePrompt;
490696
490661
  ...toolPermissionContext,
490697
490662
  mode: isAgentSwarmsEnabled2() && getTeammateUtils().isPlanModeRequired() ? "plan" : toolPermissionContext.mode
490698
490663
  };
490699
- const fullRemoteControl = remoteControl || getRemoteControlAtStartup();
490664
+ const fullRemoteControl = false;
490700
490665
  let ccrMirrorEnabled = false;
490701
490666
  const initialState = {
490702
490667
  settings: getInitialSettings2(),
@@ -490737,7 +490702,7 @@ ${inputPrompt}` : mergePrompt;
490737
490702
  remoteConnectionStatus: "connecting",
490738
490703
  remoteBackgroundTaskCount: 0,
490739
490704
  replBridgeEnabled: fullRemoteControl || ccrMirrorEnabled,
490740
- replBridgeExplicit: remoteControl,
490705
+ replBridgeExplicit: false,
490741
490706
  replBridgeOutboundOnly: ccrMirrorEnabled,
490742
490707
  replBridgeConnected: false,
490743
490708
  replBridgeSessionActive: false,
@@ -490747,7 +490712,7 @@ ${inputPrompt}` : mergePrompt;
490747
490712
  replBridgeEnvironmentId: undefined,
490748
490713
  replBridgeSessionId: undefined,
490749
490714
  replBridgeError: undefined,
490750
- replBridgeInitialName: remoteControlName,
490715
+ replBridgeInitialName: undefined,
490751
490716
  showRemoteCallout: false,
490752
490717
  notifications: {
490753
490718
  current: null,
@@ -490876,7 +490841,7 @@ ${inputPrompt}` : mergePrompt;
490876
490841
  } else if (feature("SSH_REMOTE") && _pendingSSH?.host) {
490877
490842
  return await exitWithError(root, "SSH_REMOTE feature not available in this build.", () => gracefulShutdown(1));
490878
490843
  }
490879
- if (options.resume || options.fromPr || teleport || remote !== null) {
490844
+ if (options.resume || options.fromPr) {
490880
490845
  await Promise.resolve().then(() => init_caches());
490881
490846
  clearSessionCaches();
490882
490847
  let messages = null;
@@ -491010,13 +490975,6 @@ ${inputPrompt}` : mergePrompt;
491010
490975
  program.addOption(new Option("--parent-session-id <id>", "Parent session ID for analytics correlation").hideHelp());
491011
490976
  program.addOption(new Option("--teammate-mode <mode>", 'How to spawn teammates: "tmux", "in-process", or "auto"').choices(["auto", "tmux", "in-process"]).hideHelp());
491012
490977
  program.addOption(new Option("--agent-type <type>", "Custom agent type for this teammate").hideHelp());
491013
- program.addOption(new Option("--sdk-url <url>", "Use remote WebSocket endpoint for SDK I/O streaming (only with -p and stream-json format)").hideHelp());
491014
- program.addOption(new Option("--teleport [session]", "Resume a teleport session, optionally specify session ID").hideHelp());
491015
- program.addOption(new Option("--remote [description]", "Create a remote session with the given description").hideHelp());
491016
- if (feature("BRIDGE_MODE")) {
491017
- program.addOption(new Option("--remote-control [name]", "Start an interactive session with Remote Control enabled (optionally named)").argParser((value) => value || true).hideHelp());
491018
- program.addOption(new Option("--rc [name]", "Alias for --remote-control").argParser((value) => value || true).hideHelp());
491019
- }
491020
490978
  if (feature("HARD_FAIL")) {
491021
490979
  program.addOption(new Option("--hard-fail", "Crash on logError calls instead of silently logging").hideHelp());
491022
490980
  }
@@ -491426,7 +491384,6 @@ var init_main3 = __esm(() => {
491426
491384
  init_migrateAutoUpdatesToSettings();
491427
491385
  init_migrateBypassPermissionsAcceptedToSettings();
491428
491386
  init_migrateEnableAllProjectMcpServersToSettings();
491429
- init_migrateReplBridgeEnabledToRemoteControlAtStartup();
491430
491387
  init_resetAutoModeOptInForDefaultOffer();
491431
491388
  init_manager();
491432
491389
  init_promptSuggestion();