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