@atlasharness/atlascode 0.1.44 → 0.1.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +928 -971
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -31975,9 +31975,6 @@ function setQuestionPreviewFormat(f) {
|
|
|
31975
31975
|
function getQuestionPreviewFormat() {
|
|
31976
31976
|
return _questionPreviewFormat;
|
|
31977
31977
|
}
|
|
31978
|
-
function setSessionSource(s) {
|
|
31979
|
-
_sessionSource = s;
|
|
31980
|
-
}
|
|
31981
31978
|
function setSessionBypassPermissionsMode(v) {
|
|
31982
31979
|
_sessionBypassPermissionsMode = v;
|
|
31983
31980
|
}
|
|
@@ -32079,7 +32076,7 @@ function setTrustAccepted(accepted) {
|
|
|
32079
32076
|
function hasTrustAccepted() {
|
|
32080
32077
|
return _trustAccepted;
|
|
32081
32078
|
}
|
|
32082
|
-
var _originalCwd2, _cwdState, _sessionId2, _isNonInteractiveSession = false, _clientType, _questionPreviewFormat,
|
|
32079
|
+
var _originalCwd2, _cwdState, _sessionId2, _isNonInteractiveSession = false, _clientType, _questionPreviewFormat, _sessionBypassPermissionsMode = false, _sessionPersistenceDisabled = false, _flagSettingsPath, _allowedSettingSources, _costState, sessionCreatedTeams, _transcriptDir, _mainThreadAgentType, _trustAccepted = true;
|
|
32083
32080
|
var init_state = __esm(() => {
|
|
32084
32081
|
init_shared();
|
|
32085
32082
|
_originalCwd2 = process.cwd();
|
|
@@ -84065,8 +84062,7 @@ async function main() {
|
|
|
84065
84062
|
const cliArgs = process.argv.slice(2);
|
|
84066
84063
|
const hasPrintFlag = cliArgs.includes("-p") || cliArgs.includes("--print");
|
|
84067
84064
|
const hasInitOnlyFlag = cliArgs.includes("--init-only");
|
|
84068
|
-
const
|
|
84069
|
-
const isNonInteractive = hasPrintFlag || hasInitOnlyFlag || hasSdkUrl || !process.stdout.isTTY;
|
|
84065
|
+
const isNonInteractive = hasPrintFlag || hasInitOnlyFlag || !process.stdout.isTTY;
|
|
84070
84066
|
const isInteractive = !isNonInteractive;
|
|
84071
84067
|
setIsInteractive(isInteractive);
|
|
84072
84068
|
initializeEntrypoint(isNonInteractive);
|
|
@@ -84098,9 +84094,6 @@ async function main() {
|
|
|
84098
84094
|
} else if (!clientType.startsWith("sdk-") && clientType !== "claude-desktop" && clientType !== "local-agent" && clientType !== "remote") {
|
|
84099
84095
|
setQuestionPreviewFormat("markdown");
|
|
84100
84096
|
}
|
|
84101
|
-
if (process.env.ATLAS_ENVIRONMENT_KIND === "bridge") {
|
|
84102
|
-
setSessionSource("remote-control");
|
|
84103
|
-
}
|
|
84104
84097
|
eagerLoadSettings();
|
|
84105
84098
|
await runCli();
|
|
84106
84099
|
}
|
|
@@ -85217,9 +85210,6 @@ function extractUserText(message) {
|
|
|
85217
85210
|
return "";
|
|
85218
85211
|
}
|
|
85219
85212
|
function createStructuredIO(inputPrompt, options) {
|
|
85220
|
-
if (options.sdkUrl) {
|
|
85221
|
-
throw new Error("--sdk-url is not available in this build (cloud transport cut; see cli 域裁登记)");
|
|
85222
|
-
}
|
|
85223
85213
|
const inputStream = typeof inputPrompt === "string" ? fromArray([]) : inputPrompt;
|
|
85224
85214
|
return new StructuredIO(inputStream, options.replayUserMessages);
|
|
85225
85215
|
}
|
|
@@ -85320,8 +85310,7 @@ async function runHeadless(inputPrompt, options) {
|
|
|
85320
85310
|
process.exit(1);
|
|
85321
85311
|
}
|
|
85322
85312
|
const hasValidResumeSessionId = typeof options.resume === "string" && (validateUuidLocal(options.resume) || options.resume.endsWith(".jsonl"));
|
|
85323
|
-
|
|
85324
|
-
if (!inputPrompt && !hasValidResumeSessionId && !isUsingSdkUrl) {
|
|
85313
|
+
if (!inputPrompt && !hasValidResumeSessionId) {
|
|
85325
85314
|
process.stderr.write(`Error: Input must be provided either through stdin or as a prompt argument when using --print
|
|
85326
85315
|
`);
|
|
85327
85316
|
process.exit(1);
|
|
@@ -85332,7 +85321,6 @@ async function runHeadless(inputPrompt, options) {
|
|
|
85332
85321
|
process.exit(1);
|
|
85333
85322
|
}
|
|
85334
85323
|
const structuredIO = createStructuredIO(inputPrompt, {
|
|
85335
|
-
sdkUrl: options.sdkUrl,
|
|
85336
85324
|
replayUserMessages: options.replayUserMessages
|
|
85337
85325
|
});
|
|
85338
85326
|
if (options.outputFormat === "stream-json") {
|
|
@@ -85351,7 +85339,7 @@ async function runHeadless(inputPrompt, options) {
|
|
|
85351
85339
|
const mcpConnections = await buildMcpEngineConnectionsLocal(mcpManager);
|
|
85352
85340
|
const mcpTools = createMcpTools(mcpConnections);
|
|
85353
85341
|
syncMcpClientRegistryLocal(mcpManager);
|
|
85354
|
-
const hasPromptRoute =
|
|
85342
|
+
const hasPromptRoute = options.permissionPromptToolName === "stdio";
|
|
85355
85343
|
const role = options.model ? modelToRole(options.model) : "premium";
|
|
85356
85344
|
const roleModel = getRoleModel(role);
|
|
85357
85345
|
logForDebugging2(modelLine(role, options.model ?? roleModel));
|
|
@@ -85403,7 +85391,7 @@ async function runHeadless(inputPrompt, options) {
|
|
|
85403
85391
|
},
|
|
85404
85392
|
options: { isNonInteractiveSession: true }
|
|
85405
85393
|
});
|
|
85406
|
-
const canUseTool = getCanUseToolFn(
|
|
85394
|
+
const canUseTool = getCanUseToolFn(options.permissionPromptToolName, structuredIO, () => mcpTools, hasPromptRoute ? onPermissionPrompt : undefined);
|
|
85407
85395
|
const checkPermission = async (tool, input) => {
|
|
85408
85396
|
const gate = createPermissionGate(tpcRef.current, {
|
|
85409
85397
|
getAppState: () => ({ toolPermissionContext: tpcRef.current })
|
|
@@ -86743,7 +86731,6 @@ function buildHeadlessOptions(options) {
|
|
|
86743
86731
|
model: options.model,
|
|
86744
86732
|
dangerouslySkipPermissions: options.dangerouslySkipPermissions === true ? true : undefined,
|
|
86745
86733
|
addDirs: options.addDir,
|
|
86746
|
-
sdkUrl: options.sdkUrl,
|
|
86747
86734
|
replayUserMessages: options.replayUserMessages === true ? true : undefined,
|
|
86748
86735
|
agent: options.agent,
|
|
86749
86736
|
disablePersistence: options.sessionPersistence === false ? true : undefined,
|
|
@@ -86786,11 +86773,6 @@ async function mainActionSeam(prompt, options) {
|
|
|
86786
86773
|
const outputFormat = options.outputFormat;
|
|
86787
86774
|
if (inputFormat === "stream-json" && outputFormat !== "stream-json") {
|
|
86788
86775
|
process.stderr.write(`Error: --input-format=stream-json requires output-format=stream-json.
|
|
86789
|
-
`);
|
|
86790
|
-
process.exit(1);
|
|
86791
|
-
}
|
|
86792
|
-
if (options.sdkUrl && (inputFormat !== "stream-json" || outputFormat !== "stream-json")) {
|
|
86793
|
-
process.stderr.write(`Error: --sdk-url requires both --input-format=stream-json and --output-format=stream-json.
|
|
86794
86776
|
`);
|
|
86795
86777
|
process.exit(1);
|
|
86796
86778
|
}
|
|
@@ -86852,7 +86834,6 @@ function buildProgram() {
|
|
|
86852
86834
|
program.addOption(new Option("--parent-session-id <id>", "Parent session ID for analytics correlation").hideHelp());
|
|
86853
86835
|
program.addOption(new Option("--teammate-mode <mode>", 'How to spawn teammates: "tmux", "in-process", or "auto"').choices(["auto", "tmux", "in-process"]).hideHelp());
|
|
86854
86836
|
program.addOption(new Option("--agent-type <type>", "Custom agent type for this teammate").hideHelp());
|
|
86855
|
-
program.addOption(new Option("--sdk-url <url>", "Use remote WebSocket endpoint for SDK I/O streaming (only with -p and stream-json format)").hideHelp());
|
|
86856
86837
|
if (feature("HARD_FAIL")) {
|
|
86857
86838
|
program.addOption(new Option("--hard-fail", "Crash on logError calls instead of silently logging").hideHelp());
|
|
86858
86839
|
}
|
|
@@ -121224,12 +121205,6 @@ function getGlobalConfig() {
|
|
|
121224
121205
|
return migrateConfigFields(getConfig2(getGlobalClaudeFile(), createDefaultGlobalConfig));
|
|
121225
121206
|
}
|
|
121226
121207
|
}
|
|
121227
|
-
function getRemoteControlAtStartup() {
|
|
121228
|
-
const explicit = getGlobalConfig().remoteControlAtStartup;
|
|
121229
|
-
if (explicit !== undefined)
|
|
121230
|
-
return explicit;
|
|
121231
|
-
return false;
|
|
121232
|
-
}
|
|
121233
121208
|
function getCustomApiKeyStatus(truncatedApiKey) {
|
|
121234
121209
|
const config = getGlobalConfig();
|
|
121235
121210
|
if (config.customApiKeyResponses?.approved?.includes(truncatedApiKey)) {
|
|
@@ -298060,7 +298035,6 @@ function getPath2(key) {
|
|
|
298060
298035
|
var SUPPORTED_SETTINGS2;
|
|
298061
298036
|
var init_supportedSettings2 = __esm(() => {
|
|
298062
298037
|
init_shared();
|
|
298063
|
-
init_config6();
|
|
298064
298038
|
init_configConstants();
|
|
298065
298039
|
init_modelOptions();
|
|
298066
298040
|
init_validateModel();
|
|
@@ -298169,14 +298143,6 @@ var init_supportedSettings2 = __esm(() => {
|
|
|
298169
298143
|
type: "boolean",
|
|
298170
298144
|
description: "Enable voice dictation (hold-to-talk)"
|
|
298171
298145
|
}
|
|
298172
|
-
} : {},
|
|
298173
|
-
...feature("BRIDGE_MODE") ? {
|
|
298174
|
-
remoteControlAtStartup: {
|
|
298175
|
-
source: "global",
|
|
298176
|
-
type: "boolean",
|
|
298177
|
-
description: "Enable Remote Control for all sessions (true | false | default)",
|
|
298178
|
-
formatOnRead: () => getRemoteControlAtStartup()
|
|
298179
|
-
}
|
|
298180
298146
|
} : {}
|
|
298181
298147
|
};
|
|
298182
298148
|
});
|
|
@@ -298836,33 +298802,6 @@ var init_ConfigTool = __esm(() => {
|
|
|
298836
298802
|
data: { success: true, operation: "get", setting, value: displayValue }
|
|
298837
298803
|
};
|
|
298838
298804
|
}
|
|
298839
|
-
if (setting === "remoteControlAtStartup" && typeof value === "string" && value.toLowerCase().trim() === "default") {
|
|
298840
|
-
saveGlobalConfig((prev) => {
|
|
298841
|
-
if (prev.remoteControlAtStartup === undefined)
|
|
298842
|
-
return prev;
|
|
298843
|
-
const next = { ...prev };
|
|
298844
|
-
delete next.remoteControlAtStartup;
|
|
298845
|
-
return next;
|
|
298846
|
-
});
|
|
298847
|
-
const resolved = getRemoteControlAtStartup();
|
|
298848
|
-
context.setAppState((prev) => {
|
|
298849
|
-
if (prev.replBridgeEnabled === resolved && !prev.replBridgeOutboundOnly)
|
|
298850
|
-
return prev;
|
|
298851
|
-
return {
|
|
298852
|
-
...prev,
|
|
298853
|
-
replBridgeEnabled: resolved,
|
|
298854
|
-
replBridgeOutboundOnly: false
|
|
298855
|
-
};
|
|
298856
|
-
});
|
|
298857
|
-
return {
|
|
298858
|
-
data: {
|
|
298859
|
-
success: true,
|
|
298860
|
-
operation: "set",
|
|
298861
|
-
setting,
|
|
298862
|
-
value: resolved
|
|
298863
|
-
}
|
|
298864
|
-
};
|
|
298865
|
-
}
|
|
298866
298805
|
let finalValue = value;
|
|
298867
298806
|
if (config.type === "boolean") {
|
|
298868
298807
|
if (typeof value === "string") {
|
|
@@ -299007,18 +298946,6 @@ var init_ConfigTool = __esm(() => {
|
|
|
299007
298946
|
return { ...prev, [appKey]: finalValue };
|
|
299008
298947
|
});
|
|
299009
298948
|
}
|
|
299010
|
-
if (setting === "remoteControlAtStartup") {
|
|
299011
|
-
const resolved = getRemoteControlAtStartup();
|
|
299012
|
-
context.setAppState((prev) => {
|
|
299013
|
-
if (prev.replBridgeEnabled === resolved && !prev.replBridgeOutboundOnly)
|
|
299014
|
-
return prev;
|
|
299015
|
-
return {
|
|
299016
|
-
...prev,
|
|
299017
|
-
replBridgeEnabled: resolved,
|
|
299018
|
-
replBridgeOutboundOnly: false
|
|
299019
|
-
};
|
|
299020
|
-
});
|
|
299021
|
-
}
|
|
299022
298949
|
return {
|
|
299023
298950
|
data: {
|
|
299024
298951
|
success: true,
|
|
@@ -329666,13 +329593,28 @@ async function saveKnownMarketplacesConfig(config) {
|
|
|
329666
329593
|
flush: true
|
|
329667
329594
|
});
|
|
329668
329595
|
}
|
|
329596
|
+
function updateKnownMarketplacesConfig(mutator) {
|
|
329597
|
+
const run = knownMarketplacesRmwChain.then(async () => {
|
|
329598
|
+
const config = await loadKnownMarketplacesConfig();
|
|
329599
|
+
const next = await mutator(config);
|
|
329600
|
+
if (next !== undefined) {
|
|
329601
|
+
await saveKnownMarketplacesConfig(next);
|
|
329602
|
+
}
|
|
329603
|
+
return next;
|
|
329604
|
+
});
|
|
329605
|
+
knownMarketplacesRmwChain = run.then(() => {
|
|
329606
|
+
return;
|
|
329607
|
+
}, () => {
|
|
329608
|
+
return;
|
|
329609
|
+
});
|
|
329610
|
+
return run;
|
|
329611
|
+
}
|
|
329669
329612
|
async function registerSeedMarketplaces() {
|
|
329670
329613
|
const seedDirs = getPluginSeedDirs();
|
|
329671
329614
|
if (seedDirs.length === 0)
|
|
329672
329615
|
return false;
|
|
329673
|
-
const primary = await loadKnownMarketplacesConfig();
|
|
329674
329616
|
const claimed = new Set;
|
|
329675
|
-
|
|
329617
|
+
const desired = [];
|
|
329676
329618
|
for (const seedDir of seedDirs) {
|
|
329677
329619
|
const seedConfig = await readSeedKnownMarketplaces(seedDir);
|
|
329678
329620
|
if (!seedConfig)
|
|
@@ -329686,20 +329628,28 @@ async function registerSeedMarketplaces() {
|
|
|
329686
329628
|
continue;
|
|
329687
329629
|
}
|
|
329688
329630
|
claimed.add(name);
|
|
329689
|
-
const
|
|
329631
|
+
const entry = {
|
|
329690
329632
|
source: seedEntry.source,
|
|
329691
329633
|
installLocation: resolvedLocation,
|
|
329692
329634
|
lastUpdated: seedEntry.lastUpdated,
|
|
329693
329635
|
autoUpdate: false
|
|
329694
329636
|
};
|
|
329695
|
-
|
|
329637
|
+
desired.push({ name, desired: entry });
|
|
329638
|
+
}
|
|
329639
|
+
}
|
|
329640
|
+
if (desired.length === 0)
|
|
329641
|
+
return false;
|
|
329642
|
+
let changed = 0;
|
|
329643
|
+
await updateKnownMarketplacesConfig((primary) => {
|
|
329644
|
+
for (const { name, desired: entry } of desired) {
|
|
329645
|
+
if (isEqual_default(primary[name], entry))
|
|
329696
329646
|
continue;
|
|
329697
|
-
primary[name] =
|
|
329647
|
+
primary[name] = entry;
|
|
329698
329648
|
changed++;
|
|
329699
329649
|
}
|
|
329700
|
-
|
|
329650
|
+
return changed > 0 ? primary : undefined;
|
|
329651
|
+
});
|
|
329701
329652
|
if (changed > 0) {
|
|
329702
|
-
await saveKnownMarketplacesConfig(primary);
|
|
329703
329653
|
logForDebugging3(`Synced ${changed} marketplace(s) from seed dir(s)`);
|
|
329704
329654
|
return true;
|
|
329705
329655
|
}
|
|
@@ -330458,34 +330408,35 @@ Tip: The shorthand "${resolvedSource.repo}" assumes github.com. ` + `For interna
|
|
|
330458
330408
|
if (sourceValidationError) {
|
|
330459
330409
|
throw new Error(sourceValidationError);
|
|
330460
330410
|
}
|
|
330461
|
-
const
|
|
330462
|
-
|
|
330463
|
-
|
|
330464
|
-
|
|
330465
|
-
|
|
330466
|
-
|
|
330467
|
-
|
|
330468
|
-
|
|
330469
|
-
|
|
330470
|
-
|
|
330471
|
-
|
|
330472
|
-
|
|
330473
|
-
|
|
330474
|
-
|
|
330475
|
-
|
|
330476
|
-
|
|
330477
|
-
|
|
330411
|
+
const resolvedSha = await captureResolvedSha(resolvedSource, cachePath);
|
|
330412
|
+
await updateKnownMarketplacesConfig(async (config) => {
|
|
330413
|
+
const oldEntry = config[marketplace.name];
|
|
330414
|
+
if (oldEntry) {
|
|
330415
|
+
const seedDir = seedDirFor(oldEntry.installLocation);
|
|
330416
|
+
if (seedDir) {
|
|
330417
|
+
throw new Error(`Marketplace '${marketplace.name}' is seed-managed (${seedDir}). ` + `To use a different source, ask your admin to update the seed, ` + `or use a different marketplace name.`);
|
|
330418
|
+
}
|
|
330419
|
+
logForDebugging3(`Marketplace '${marketplace.name}' exists with different source — overwriting`);
|
|
330420
|
+
if (!isLocalMarketplaceSource(oldEntry.source)) {
|
|
330421
|
+
const cacheDir = resolve42(getMarketplacesCacheDir());
|
|
330422
|
+
const resolvedOld = resolve42(oldEntry.installLocation);
|
|
330423
|
+
const resolvedNew = resolve42(cachePath);
|
|
330424
|
+
if (resolvedOld === resolvedNew) {} else if (resolvedOld === cacheDir || resolvedOld.startsWith(cacheDir + sep26)) {
|
|
330425
|
+
const fs = getFsImplementation2();
|
|
330426
|
+
await fs.rm(oldEntry.installLocation, { recursive: true, force: true });
|
|
330427
|
+
} else {
|
|
330428
|
+
logForDebugging3(`Skipping cleanup of old installLocation (${oldEntry.installLocation}) — ` + `outside ${cacheDir}. The path is corrupted; leaving it alone and ` + `overwriting the config entry.`, { level: "warn" });
|
|
330429
|
+
}
|
|
330478
330430
|
}
|
|
330479
330431
|
}
|
|
330480
|
-
|
|
330481
|
-
|
|
330482
|
-
|
|
330483
|
-
|
|
330484
|
-
|
|
330485
|
-
|
|
330486
|
-
|
|
330487
|
-
};
|
|
330488
|
-
await saveKnownMarketplacesConfig(config);
|
|
330432
|
+
config[marketplace.name] = {
|
|
330433
|
+
source: resolvedSource,
|
|
330434
|
+
installLocation: cachePath,
|
|
330435
|
+
lastUpdated: new Date().toISOString(),
|
|
330436
|
+
...resolvedSha ? { resolvedSha } : {}
|
|
330437
|
+
};
|
|
330438
|
+
return config;
|
|
330439
|
+
});
|
|
330489
330440
|
logForDebugging3(`Added marketplace source: ${marketplace.name}`);
|
|
330490
330441
|
return { name: marketplace.name, alreadyMaterialized: false, resolvedSource };
|
|
330491
330442
|
}
|
|
@@ -330498,15 +330449,7 @@ async function adoptOrphanMarketplace(dirName, overrideName) {
|
|
|
330498
330449
|
}
|
|
330499
330450
|
const manifestPath = resolveMarketplaceManifestPath(dirPath);
|
|
330500
330451
|
const marketplace = await parseFileWithSchema(manifestPath, PluginMarketplaceSchema());
|
|
330501
|
-
const config = await loadKnownMarketplacesConfig();
|
|
330502
330452
|
const name = overrideName ?? marketplace.name;
|
|
330503
|
-
const existing = config[name];
|
|
330504
|
-
if (existing) {
|
|
330505
|
-
if (resolve42(existing.installLocation) === resolve42(dirPath)) {
|
|
330506
|
-
return { name, source: existing.source, installLocation: dirPath };
|
|
330507
|
-
}
|
|
330508
|
-
throw new Error(`Marketplace name '${name}' is already registered at ` + `${existing.installLocation}. Remove it first ` + `(\`plugin marketplace remove ${name}\`) or adopt under a different name.`);
|
|
330509
|
-
}
|
|
330510
330453
|
const remoteUrl = await parseGitConfigValue2(join118(dirPath, ".git"), "remote", "origin", "url");
|
|
330511
330454
|
let source;
|
|
330512
330455
|
if (remoteUrl) {
|
|
@@ -330526,29 +330469,39 @@ async function adoptOrphanMarketplace(dirName, overrideName) {
|
|
|
330526
330469
|
throw new Error(`Marketplace source '${formatSourceForDisplay(source)}' is blocked ` + `by enterprise policy and cannot be adopted.`);
|
|
330527
330470
|
}
|
|
330528
330471
|
const resolvedSha = await captureResolvedSha(source, dirPath);
|
|
330529
|
-
|
|
330530
|
-
|
|
330531
|
-
|
|
330532
|
-
|
|
330533
|
-
|
|
330534
|
-
|
|
330535
|
-
|
|
330472
|
+
await updateKnownMarketplacesConfig((existing) => {
|
|
330473
|
+
const prior = existing[name];
|
|
330474
|
+
if (prior) {
|
|
330475
|
+
if (resolve42(prior.installLocation) === resolve42(dirPath)) {
|
|
330476
|
+
return;
|
|
330477
|
+
}
|
|
330478
|
+
throw new Error(`Marketplace name '${name}' is already registered at ` + `${prior.installLocation}. Remove it first ` + `(\`plugin marketplace remove ${name}\`) or adopt under a different name.`);
|
|
330479
|
+
}
|
|
330480
|
+
existing[name] = {
|
|
330481
|
+
source,
|
|
330482
|
+
installLocation: dirPath,
|
|
330483
|
+
lastUpdated: new Date().toISOString(),
|
|
330484
|
+
...resolvedSha ? { resolvedSha } : {}
|
|
330485
|
+
};
|
|
330486
|
+
return existing;
|
|
330487
|
+
});
|
|
330536
330488
|
clearAllCaches();
|
|
330537
330489
|
logForDebugging3(`Adopted orphan marketplace directory '${dirName}' as '${name}' (${formatSourceForDisplay(source)})`);
|
|
330538
330490
|
return { name, source, installLocation: dirPath };
|
|
330539
330491
|
}
|
|
330540
330492
|
async function removeMarketplaceSource(name) {
|
|
330541
|
-
|
|
330542
|
-
|
|
330543
|
-
|
|
330544
|
-
|
|
330545
|
-
|
|
330546
|
-
|
|
330547
|
-
|
|
330548
|
-
|
|
330549
|
-
|
|
330550
|
-
|
|
330551
|
-
|
|
330493
|
+
await updateKnownMarketplacesConfig((config) => {
|
|
330494
|
+
const entry = config[name];
|
|
330495
|
+
if (!entry) {
|
|
330496
|
+
throw new Error(`Marketplace '${name}' not found`);
|
|
330497
|
+
}
|
|
330498
|
+
const seedDir = seedDirFor(entry.installLocation);
|
|
330499
|
+
if (seedDir) {
|
|
330500
|
+
throw new Error(`Marketplace '${name}' is registered from the read-only seed directory ` + `(${seedDir}) and will be re-registered on next startup. ` + `To stop using its plugins: claude plugin disable <plugin>@${name}`);
|
|
330501
|
+
}
|
|
330502
|
+
delete config[name];
|
|
330503
|
+
return config;
|
|
330504
|
+
});
|
|
330552
330505
|
const fs = getFsImplementation2();
|
|
330553
330506
|
const cacheDir = getMarketplacesCacheDir();
|
|
330554
330507
|
const cachePath = join118(cacheDir, name);
|
|
@@ -330831,23 +330784,24 @@ async function refreshMarketplace(name, onProgress, options) {
|
|
|
330831
330784
|
}
|
|
330832
330785
|
}
|
|
330833
330786
|
async function setMarketplaceAutoUpdate(name, autoUpdate) {
|
|
330834
|
-
|
|
330835
|
-
|
|
330836
|
-
|
|
330837
|
-
|
|
330838
|
-
|
|
330839
|
-
|
|
330840
|
-
|
|
330841
|
-
|
|
330842
|
-
|
|
330843
|
-
|
|
330844
|
-
|
|
330845
|
-
|
|
330846
|
-
|
|
330847
|
-
|
|
330848
|
-
|
|
330849
|
-
|
|
330850
|
-
|
|
330787
|
+
await updateKnownMarketplacesConfig((config) => {
|
|
330788
|
+
const entry = config[name];
|
|
330789
|
+
if (!entry) {
|
|
330790
|
+
throw new Error(`Marketplace '${name}' not found. Available marketplaces: ${Object.keys(config).join(", ")}`);
|
|
330791
|
+
}
|
|
330792
|
+
const seedDir = seedDirFor(entry.installLocation);
|
|
330793
|
+
if (seedDir) {
|
|
330794
|
+
throw new Error(`Marketplace '${name}' is seed-managed (${seedDir}) and ` + `auto-update is always disabled for seed content. ` + `To update: ask your admin to update the seed.`);
|
|
330795
|
+
}
|
|
330796
|
+
if (entry.autoUpdate === autoUpdate) {
|
|
330797
|
+
return;
|
|
330798
|
+
}
|
|
330799
|
+
config[name] = {
|
|
330800
|
+
...entry,
|
|
330801
|
+
autoUpdate
|
|
330802
|
+
};
|
|
330803
|
+
return config;
|
|
330804
|
+
});
|
|
330851
330805
|
const declaringSource = getMarketplaceDeclaringSource(name);
|
|
330852
330806
|
if (declaringSource) {
|
|
330853
330807
|
const declared = getSettingsForSource2(declaringSource)?.extraKnownMarketplaces?.[name];
|
|
@@ -330857,7 +330811,7 @@ async function setMarketplaceAutoUpdate(name, autoUpdate) {
|
|
|
330857
330811
|
}
|
|
330858
330812
|
logForDebugging3(`Set autoUpdate=${autoUpdate} for marketplace: ${name}`);
|
|
330859
330813
|
}
|
|
330860
|
-
var GIT_NO_PROMPT_ENV3, DEFAULT_PLUGIN_GIT_TIMEOUT_MS, GIT_SHA_RE, getMarketplace;
|
|
330814
|
+
var knownMarketplacesRmwChain, GIT_NO_PROMPT_ENV3, DEFAULT_PLUGIN_GIT_TIMEOUT_MS, GIT_SHA_RE, getMarketplace;
|
|
330861
330815
|
var init_marketplaceManager = __esm(() => {
|
|
330862
330816
|
init_axios2();
|
|
330863
330817
|
init_configDir();
|
|
@@ -330887,6 +330841,7 @@ var init_marketplaceManager = __esm(() => {
|
|
|
330887
330841
|
init_orphanScanner();
|
|
330888
330842
|
init_pluginOptionsStorage();
|
|
330889
330843
|
init_schemas3();
|
|
330844
|
+
knownMarketplacesRmwChain = Promise.resolve();
|
|
330890
330845
|
GIT_NO_PROMPT_ENV3 = {
|
|
330891
330846
|
GIT_TERMINAL_PROMPT: "0",
|
|
330892
330847
|
GIT_ASKPASS: ""
|
|
@@ -331497,6 +331452,217 @@ function mtimeAwareMemoize(fn, watchFiles, options) {
|
|
|
331497
331452
|
}
|
|
331498
331453
|
var init_mtimeAwareMemoize = () => {};
|
|
331499
331454
|
|
|
331455
|
+
// src/tui/utils/plugins/installCounts.ts
|
|
331456
|
+
import { randomBytes as randomBytes15 } from "crypto";
|
|
331457
|
+
import { readFile as readFile41, rename as rename5, unlink as unlink16, writeFile as writeFile29 } from "fs/promises";
|
|
331458
|
+
import { join as join120 } from "path";
|
|
331459
|
+
function normalizeStatsBase(raw) {
|
|
331460
|
+
if (!raw)
|
|
331461
|
+
return null;
|
|
331462
|
+
const trimmed = raw.replace(/\/+$/, "");
|
|
331463
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
331464
|
+
}
|
|
331465
|
+
function getStatsSourceUrl(marketplaceName) {
|
|
331466
|
+
const name = marketplaceName.toLowerCase();
|
|
331467
|
+
if (name === OFFICIAL_MARKETPLACE_NAME) {
|
|
331468
|
+
return OFFICIAL_STATS_URL;
|
|
331469
|
+
}
|
|
331470
|
+
if (SELF_HOSTED_MARKETPLACES.has(name)) {
|
|
331471
|
+
const base = normalizeStatsBase(process.env[STATS_ENDPOINT_ENV]);
|
|
331472
|
+
return base ? `${base}/stats/install-counts.json` : SELF_HOSTED_STATS_URL;
|
|
331473
|
+
}
|
|
331474
|
+
return null;
|
|
331475
|
+
}
|
|
331476
|
+
function getStatsReportUrl() {
|
|
331477
|
+
const base = normalizeStatsBase(process.env[STATS_ENDPOINT_ENV]);
|
|
331478
|
+
return base ? `${base}/stats/report` : null;
|
|
331479
|
+
}
|
|
331480
|
+
function getAllStatsSourceUrls() {
|
|
331481
|
+
const urls = new Set;
|
|
331482
|
+
const official = getStatsSourceUrl(OFFICIAL_MARKETPLACE_NAME);
|
|
331483
|
+
if (official)
|
|
331484
|
+
urls.add(official);
|
|
331485
|
+
for (const mkt of SELF_HOSTED_MARKETPLACES) {
|
|
331486
|
+
const url = getStatsSourceUrl(mkt);
|
|
331487
|
+
if (url)
|
|
331488
|
+
urls.add(url);
|
|
331489
|
+
}
|
|
331490
|
+
return [...urls];
|
|
331491
|
+
}
|
|
331492
|
+
function getInstallCountsCachePath() {
|
|
331493
|
+
return join120(getPluginsDirectory(), INSTALL_COUNTS_CACHE_FILENAME);
|
|
331494
|
+
}
|
|
331495
|
+
async function loadInstallCountsCache() {
|
|
331496
|
+
const cachePath = getInstallCountsCachePath();
|
|
331497
|
+
try {
|
|
331498
|
+
const content = await readFile41(cachePath, { encoding: "utf-8" });
|
|
331499
|
+
const parsed = jsonParse2(content);
|
|
331500
|
+
if (typeof parsed !== "object" || parsed === null || !("version" in parsed) || !("entries" in parsed)) {
|
|
331501
|
+
logForDebugging3("Install counts cache has invalid structure");
|
|
331502
|
+
return null;
|
|
331503
|
+
}
|
|
331504
|
+
const cache = parsed;
|
|
331505
|
+
if (cache.version !== INSTALL_COUNTS_CACHE_VERSION) {
|
|
331506
|
+
logForDebugging3(`Install counts cache version mismatch (got ${cache.version}, expected ${INSTALL_COUNTS_CACHE_VERSION})`);
|
|
331507
|
+
return null;
|
|
331508
|
+
}
|
|
331509
|
+
const entries = cache.entries;
|
|
331510
|
+
const validated = {};
|
|
331511
|
+
for (const [url, rawEntry] of Object.entries(entries)) {
|
|
331512
|
+
const entry = rawEntry;
|
|
331513
|
+
if (typeof entry.fetchedAt !== "string" || Number.isNaN(new Date(entry.fetchedAt).getTime()) || !Array.isArray(entry.counts)) {
|
|
331514
|
+
continue;
|
|
331515
|
+
}
|
|
331516
|
+
const counts = entry.counts.filter((c) => typeof c.plugin === "string" && typeof c.unique_installs === "number");
|
|
331517
|
+
validated[url] = { fetchedAt: entry.fetchedAt, counts };
|
|
331518
|
+
}
|
|
331519
|
+
return { version: INSTALL_COUNTS_CACHE_VERSION, entries: validated };
|
|
331520
|
+
} catch (error) {
|
|
331521
|
+
const code = getErrnoCode2(error);
|
|
331522
|
+
if (code !== "ENOENT") {
|
|
331523
|
+
logForDebugging3(`Failed to load install counts cache: ${errorMessage2(error)}`);
|
|
331524
|
+
}
|
|
331525
|
+
return null;
|
|
331526
|
+
}
|
|
331527
|
+
}
|
|
331528
|
+
async function saveInstallCountsCache(cache) {
|
|
331529
|
+
const cachePath = getInstallCountsCachePath();
|
|
331530
|
+
const tempPath = `${cachePath}.${randomBytes15(8).toString("hex")}.tmp`;
|
|
331531
|
+
try {
|
|
331532
|
+
const pluginsDir = getPluginsDirectory();
|
|
331533
|
+
await getFsImplementation2().mkdir(pluginsDir);
|
|
331534
|
+
const content = jsonStringify5(cache, null, 2);
|
|
331535
|
+
await writeFile29(tempPath, content, {
|
|
331536
|
+
encoding: "utf-8",
|
|
331537
|
+
mode: 384
|
|
331538
|
+
});
|
|
331539
|
+
await rename5(tempPath, cachePath);
|
|
331540
|
+
logForDebugging3("Install counts cache saved successfully");
|
|
331541
|
+
} catch (error) {
|
|
331542
|
+
logError3(error);
|
|
331543
|
+
try {
|
|
331544
|
+
await unlink16(tempPath);
|
|
331545
|
+
} catch {}
|
|
331546
|
+
}
|
|
331547
|
+
}
|
|
331548
|
+
async function fetchStatsFromUrl(url) {
|
|
331549
|
+
logForDebugging3(`Fetching install counts from ${url}`);
|
|
331550
|
+
const started = performance.now();
|
|
331551
|
+
try {
|
|
331552
|
+
const response = await axios_default.get(url, {
|
|
331553
|
+
timeout: 1e4
|
|
331554
|
+
});
|
|
331555
|
+
if (!response.data?.plugins || !Array.isArray(response.data.plugins)) {
|
|
331556
|
+
throw new Error("Invalid response format from install counts API");
|
|
331557
|
+
}
|
|
331558
|
+
logPluginFetch("install_counts", url, "success", performance.now() - started);
|
|
331559
|
+
return response.data.plugins;
|
|
331560
|
+
} catch (error) {
|
|
331561
|
+
logPluginFetch("install_counts", url, "failure", performance.now() - started, classifyFetchError(error));
|
|
331562
|
+
throw error;
|
|
331563
|
+
}
|
|
331564
|
+
}
|
|
331565
|
+
async function getInstallCounts(marketplaceNames) {
|
|
331566
|
+
const urls = new Set;
|
|
331567
|
+
if (marketplaceNames && marketplaceNames.length > 0) {
|
|
331568
|
+
for (const name of marketplaceNames) {
|
|
331569
|
+
const url = getStatsSourceUrl(name);
|
|
331570
|
+
if (url)
|
|
331571
|
+
urls.add(url);
|
|
331572
|
+
}
|
|
331573
|
+
if (urls.size === 0) {
|
|
331574
|
+
return null;
|
|
331575
|
+
}
|
|
331576
|
+
} else {
|
|
331577
|
+
for (const url of getAllStatsSourceUrls()) {
|
|
331578
|
+
urls.add(url);
|
|
331579
|
+
}
|
|
331580
|
+
}
|
|
331581
|
+
const cache = await loadInstallCountsCache();
|
|
331582
|
+
const map = new Map;
|
|
331583
|
+
let gotData = false;
|
|
331584
|
+
for (const url of urls) {
|
|
331585
|
+
const cached = cache?.entries[url];
|
|
331586
|
+
if (cached && Date.now() - new Date(cached.fetchedAt).getTime() <= CACHE_TTL_MS3) {
|
|
331587
|
+
logPluginFetch("install_counts", url, "cache_hit", 0);
|
|
331588
|
+
for (const entry of cached.counts) {
|
|
331589
|
+
map.set(entry.plugin, entry.unique_installs);
|
|
331590
|
+
}
|
|
331591
|
+
if (cached.counts.length > 0)
|
|
331592
|
+
gotData = true;
|
|
331593
|
+
continue;
|
|
331594
|
+
}
|
|
331595
|
+
try {
|
|
331596
|
+
const counts = await fetchStatsFromUrl(url);
|
|
331597
|
+
for (const entry of counts) {
|
|
331598
|
+
map.set(entry.plugin, entry.unique_installs);
|
|
331599
|
+
}
|
|
331600
|
+
gotData = true;
|
|
331601
|
+
const nextCache = cache ?? {
|
|
331602
|
+
version: INSTALL_COUNTS_CACHE_VERSION,
|
|
331603
|
+
entries: {}
|
|
331604
|
+
};
|
|
331605
|
+
nextCache.entries[url] = {
|
|
331606
|
+
fetchedAt: new Date().toISOString(),
|
|
331607
|
+
counts
|
|
331608
|
+
};
|
|
331609
|
+
await saveInstallCountsCache(nextCache);
|
|
331610
|
+
} catch (error) {
|
|
331611
|
+
logError3(error);
|
|
331612
|
+
logForDebugging3(`Failed to fetch install counts from ${url}: ${errorMessage2(error)}`);
|
|
331613
|
+
}
|
|
331614
|
+
}
|
|
331615
|
+
return gotData ? map : null;
|
|
331616
|
+
}
|
|
331617
|
+
function formatInstallCount(count) {
|
|
331618
|
+
if (count < 1000) {
|
|
331619
|
+
return String(count);
|
|
331620
|
+
}
|
|
331621
|
+
if (count < 1e6) {
|
|
331622
|
+
const k = count / 1000;
|
|
331623
|
+
const formatted = k.toFixed(1);
|
|
331624
|
+
return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}K` : `${formatted}K`;
|
|
331625
|
+
}
|
|
331626
|
+
const m = count / 1e6;
|
|
331627
|
+
const formatted = m.toFixed(1);
|
|
331628
|
+
return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}M` : `${formatted}M`;
|
|
331629
|
+
}
|
|
331630
|
+
var INSTALL_COUNTS_CACHE_VERSION = 2, INSTALL_COUNTS_CACHE_FILENAME = "install-counts-cache.json", CACHE_TTL_MS3, OFFICIAL_STATS_URL = "https://raw.githubusercontent.com/anthropics/claude-plugins-official/refs/heads/stats/stats/plugin-installs.json", SELF_HOSTED_STATS_URL = "https://raw.githubusercontent.com/vincentlau2046/atlas-plugins/master/stats/install-counts.json", STATS_ENDPOINT_ENV = "ATLAS_STATS_ENDPOINT", SELF_HOSTED_MARKETPLACES;
|
|
331631
|
+
var init_installCounts = __esm(() => {
|
|
331632
|
+
init_axios2();
|
|
331633
|
+
init_debug();
|
|
331634
|
+
init_errors4();
|
|
331635
|
+
init_fsOperations();
|
|
331636
|
+
init_log5();
|
|
331637
|
+
init_slowOperations();
|
|
331638
|
+
init_fetchTelemetry();
|
|
331639
|
+
init_officialMarketplace();
|
|
331640
|
+
init_pluginDirectories();
|
|
331641
|
+
CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
331642
|
+
SELF_HOSTED_MARKETPLACES = new Set([
|
|
331643
|
+
"atlas-plugins",
|
|
331644
|
+
"agent-skills"
|
|
331645
|
+
]);
|
|
331646
|
+
});
|
|
331647
|
+
|
|
331648
|
+
// src/tui/utils/plugins/installCountReporter.ts
|
|
331649
|
+
function reportInstall(pluginId, marketplaceName) {
|
|
331650
|
+
const url = getStatsReportUrl();
|
|
331651
|
+
if (!url) {
|
|
331652
|
+
return Promise.resolve();
|
|
331653
|
+
}
|
|
331654
|
+
return axios_default.post(url, { plugin: pluginId, marketplace: marketplaceName }, { timeout: 5000 }).then(() => {
|
|
331655
|
+
logForDebugging3(`Install count reported: ${pluginId}`);
|
|
331656
|
+
}).catch((error) => {
|
|
331657
|
+
logForDebugging3(`Install count report failed (${pluginId} @ ${marketplaceName}): ${error instanceof Error ? error.message : String(error)}`);
|
|
331658
|
+
});
|
|
331659
|
+
}
|
|
331660
|
+
var init_installCountReporter = __esm(() => {
|
|
331661
|
+
init_axios2();
|
|
331662
|
+
init_debug();
|
|
331663
|
+
init_installCounts();
|
|
331664
|
+
});
|
|
331665
|
+
|
|
331500
331666
|
// src/tui/utils/plugins/pluginVersioning.ts
|
|
331501
331667
|
import { createHash as createHash9 } from "crypto";
|
|
331502
331668
|
async function calculatePluginVersion(pluginId, source, manifest, installPath, providedVersion, gitCommitSha) {
|
|
@@ -331540,9 +331706,9 @@ var init_pluginVersioning = __esm(() => {
|
|
|
331540
331706
|
});
|
|
331541
331707
|
|
|
331542
331708
|
// src/tui/utils/plugins/pluginInstallationHelpers.ts
|
|
331543
|
-
import { randomBytes as
|
|
331544
|
-
import { rename as
|
|
331545
|
-
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";
|
|
331546
331712
|
function getCurrentTimestamp() {
|
|
331547
331713
|
return new Date().toISOString();
|
|
331548
331714
|
}
|
|
@@ -331571,12 +331737,12 @@ async function cacheAndRegisterPlugin(pluginId, entry, scope = "user", projectPa
|
|
|
331571
331737
|
const normalizedCachePath = cacheResult.path.endsWith(sep27) ? cacheResult.path : cacheResult.path + sep27;
|
|
331572
331738
|
const isSubdirectory = versionedPath.startsWith(normalizedCachePath);
|
|
331573
331739
|
if (isSubdirectory) {
|
|
331574
|
-
const tempPath =
|
|
331575
|
-
await
|
|
331740
|
+
const tempPath = join121(dirname64(cacheResult.path), `.atlas-plugin-temp-${Date.now()}-${randomBytes16(4).toString("hex")}`);
|
|
331741
|
+
await rename6(cacheResult.path, tempPath);
|
|
331576
331742
|
await getFsImplementation2().mkdir(dirname64(versionedPath));
|
|
331577
|
-
await
|
|
331743
|
+
await rename6(tempPath, versionedPath);
|
|
331578
331744
|
} else {
|
|
331579
|
-
await
|
|
331745
|
+
await rename6(cacheResult.path, versionedPath);
|
|
331580
331746
|
}
|
|
331581
331747
|
finalPath = versionedPath;
|
|
331582
331748
|
}
|
|
@@ -331747,6 +331913,7 @@ async function installPluginFromMarketplace({
|
|
|
331747
331913
|
};
|
|
331748
331914
|
}
|
|
331749
331915
|
}
|
|
331916
|
+
reportInstall(pluginId, marketplaceName);
|
|
331750
331917
|
return {
|
|
331751
331918
|
success: true,
|
|
331752
331919
|
message: `✓ Installed ${entry.name}${result.depNote}.`
|
|
@@ -331765,6 +331932,7 @@ var init_pluginInstallationHelpers = __esm(() => {
|
|
|
331765
331932
|
init_settings3();
|
|
331766
331933
|
init_cacheUtils();
|
|
331767
331934
|
init_dependencyResolver();
|
|
331935
|
+
init_installCountReporter();
|
|
331768
331936
|
init_installedPluginsManager();
|
|
331769
331937
|
init_marketplaceManager();
|
|
331770
331938
|
init_pluginIdentifier2();
|
|
@@ -331779,25 +331947,25 @@ var init_pluginInstallationHelpers = __esm(() => {
|
|
|
331779
331947
|
import {
|
|
331780
331948
|
copyFile as copyFile6,
|
|
331781
331949
|
readdir as readdir24,
|
|
331782
|
-
readFile as
|
|
331950
|
+
readFile as readFile42,
|
|
331783
331951
|
readlink,
|
|
331784
331952
|
realpath as realpath11,
|
|
331785
|
-
rename as
|
|
331953
|
+
rename as rename7,
|
|
331786
331954
|
rm as rm9,
|
|
331787
331955
|
rmdir,
|
|
331788
331956
|
stat as stat40,
|
|
331789
331957
|
symlink as symlink5
|
|
331790
331958
|
} from "fs/promises";
|
|
331791
|
-
import { basename as basename36, dirname as dirname65, join as
|
|
331959
|
+
import { basename as basename36, dirname as dirname65, join as join122, relative as relative22, resolve as resolve44, sep as sep28 } from "path";
|
|
331792
331960
|
function getPluginCachePath() {
|
|
331793
|
-
return
|
|
331961
|
+
return join122(getPluginsDirectory(), "cache");
|
|
331794
331962
|
}
|
|
331795
331963
|
function getVersionedCachePathIn(baseDir, pluginId, version) {
|
|
331796
331964
|
const { name: pluginName, marketplace } = parsePluginIdentifier2(pluginId);
|
|
331797
331965
|
const sanitizedMarketplace = (marketplace || "unknown").replace(/[^a-zA-Z0-9\-_]/g, "-");
|
|
331798
331966
|
const sanitizedPlugin = (pluginName || pluginId).replace(/[^a-zA-Z0-9\-_]/g, "-");
|
|
331799
331967
|
const sanitizedVersion = version.replace(/[^a-zA-Z0-9\-_.]/g, "-");
|
|
331800
|
-
return
|
|
331968
|
+
return join122(baseDir, "cache", sanitizedMarketplace, sanitizedPlugin, sanitizedVersion);
|
|
331801
331969
|
}
|
|
331802
331970
|
function getVersionedCachePath(pluginId, version) {
|
|
331803
331971
|
return getVersionedCachePathIn(getPluginsDirectory(), pluginId, version);
|
|
@@ -331823,7 +331991,7 @@ async function probeSeedCacheAnyVersion(pluginId) {
|
|
|
331823
331991
|
const versions = await readdir24(pluginDir);
|
|
331824
331992
|
if (versions.length !== 1)
|
|
331825
331993
|
continue;
|
|
331826
|
-
const versionDir =
|
|
331994
|
+
const versionDir = join122(pluginDir, versions[0]);
|
|
331827
331995
|
const entries = await readdir24(versionDir);
|
|
331828
331996
|
if (entries.length > 0)
|
|
331829
331997
|
return versionDir;
|
|
@@ -331835,8 +332003,8 @@ async function copyDir(src, dest) {
|
|
|
331835
332003
|
await getFsImplementation2().mkdir(dest);
|
|
331836
332004
|
const entries = await readdir24(src, { withFileTypes: true });
|
|
331837
332005
|
for (const entry of entries) {
|
|
331838
|
-
const srcPath =
|
|
331839
|
-
const destPath =
|
|
332006
|
+
const srcPath = join122(src, entry.name);
|
|
332007
|
+
const destPath = join122(dest, entry.name);
|
|
331840
332008
|
if (entry.isDirectory()) {
|
|
331841
332009
|
await copyDir(srcPath, destPath);
|
|
331842
332010
|
} else if (entry.isFile()) {
|
|
@@ -331859,7 +332027,7 @@ async function copyDir(src, dest) {
|
|
|
331859
332027
|
const srcPrefix = resolvedSrc.endsWith(sep28) ? resolvedSrc : resolvedSrc + sep28;
|
|
331860
332028
|
if (resolvedTarget.startsWith(srcPrefix) || resolvedTarget === resolvedSrc) {
|
|
331861
332029
|
const targetRelativeToSrc = relative22(resolvedSrc, resolvedTarget);
|
|
331862
|
-
const destTargetPath =
|
|
332030
|
+
const destTargetPath = join122(dest, targetRelativeToSrc);
|
|
331863
332031
|
const relativeLinkPath = relative22(dirname65(destPath), destTargetPath);
|
|
331864
332032
|
await symlink5(relativeLinkPath, destPath);
|
|
331865
332033
|
} else {
|
|
@@ -331907,7 +332075,7 @@ async function copyPluginToVersionedCache(sourcePath, pluginId, version, entry,
|
|
|
331907
332075
|
logForDebugging3(`Copying plugin ${pluginId} to versioned cache (fallback to full copy)`);
|
|
331908
332076
|
await copyDir(sourcePath, cachePath);
|
|
331909
332077
|
}
|
|
331910
|
-
const gitPath =
|
|
332078
|
+
const gitPath = join122(cachePath, ".git");
|
|
331911
332079
|
await rm9(gitPath, { recursive: true, force: true });
|
|
331912
332080
|
const cacheEntries = await readdir24(cachePath);
|
|
331913
332081
|
if (cacheEntries.length === 0) {
|
|
@@ -331938,10 +332106,10 @@ function validateGitUrl(url) {
|
|
|
331938
332106
|
}
|
|
331939
332107
|
}
|
|
331940
332108
|
async function installFromNpm(packageName, targetPath, options = {}) {
|
|
331941
|
-
const npmCachePath =
|
|
332109
|
+
const npmCachePath = join122(getPluginsDirectory(), "npm-cache");
|
|
331942
332110
|
await getFsImplementation2().mkdir(npmCachePath);
|
|
331943
332111
|
const packageSpec = options.version ? `${packageName}@${options.version}` : packageName;
|
|
331944
|
-
const packagePath =
|
|
332112
|
+
const packagePath = join122(npmCachePath, "node_modules", packageName);
|
|
331945
332113
|
const needsInstall = !await pathExists2(packagePath);
|
|
331946
332114
|
if (needsInstall) {
|
|
331947
332115
|
logForDebugging3(`Installing npm package ${packageSpec} to cache`);
|
|
@@ -332074,7 +332242,7 @@ async function installFromGitSubdir(url, targetPath, subdirPath, ref, sha) {
|
|
|
332074
332242
|
}
|
|
332075
332243
|
const resolvedSubdir = validatePathWithinBase(cloneDir, subdirPath);
|
|
332076
332244
|
try {
|
|
332077
|
-
await
|
|
332245
|
+
await rename7(resolvedSubdir, targetPath);
|
|
332078
332246
|
} catch (e) {
|
|
332079
332247
|
if (isENOENT2(e)) {
|
|
332080
332248
|
throw new Error(`Subdirectory '${subdirPath}' not found in repository ${gitUrl}${ref ? ` (ref: ${ref})` : ""}. ` + "Check that the path is correct and exists at the specified ref/sha.");
|
|
@@ -332094,7 +332262,7 @@ async function installFromLocal(sourcePath, targetPath) {
|
|
|
332094
332262
|
throw new Error(`Source path does not exist: ${sourcePath}`);
|
|
332095
332263
|
}
|
|
332096
332264
|
await copyDir(sourcePath, targetPath);
|
|
332097
|
-
const gitPath =
|
|
332265
|
+
const gitPath = join122(targetPath, ".git");
|
|
332098
332266
|
await rm9(gitPath, { recursive: true, force: true });
|
|
332099
332267
|
}
|
|
332100
332268
|
function generateTemporaryCacheNameForPlugin(source) {
|
|
@@ -332130,7 +332298,7 @@ async function cachePlugin(source, options) {
|
|
|
332130
332298
|
const cachePath = getPluginCachePath();
|
|
332131
332299
|
await getFsImplementation2().mkdir(cachePath);
|
|
332132
332300
|
const tempName = generateTemporaryCacheNameForPlugin(source);
|
|
332133
|
-
const tempPath =
|
|
332301
|
+
const tempPath = join122(cachePath, tempName);
|
|
332134
332302
|
let shouldCleanup = false;
|
|
332135
332303
|
let gitCommitSha;
|
|
332136
332304
|
try {
|
|
@@ -332175,11 +332343,11 @@ async function cachePlugin(source, options) {
|
|
|
332175
332343
|
throw error;
|
|
332176
332344
|
}
|
|
332177
332345
|
const manifestPath = findManifestInDir(tempPath, "plugin.json");
|
|
332178
|
-
const legacyManifestPath =
|
|
332346
|
+
const legacyManifestPath = join122(tempPath, "plugin.json");
|
|
332179
332347
|
let manifest;
|
|
332180
332348
|
if (await pathExists2(manifestPath)) {
|
|
332181
332349
|
try {
|
|
332182
|
-
const content = await
|
|
332350
|
+
const content = await readFile42(manifestPath, { encoding: "utf-8" });
|
|
332183
332351
|
const parsed = jsonParse2(content);
|
|
332184
332352
|
const result = PluginManifestSchema().safeParse(parsed);
|
|
332185
332353
|
if (result.success) {
|
|
@@ -332203,7 +332371,7 @@ async function cachePlugin(source, options) {
|
|
|
332203
332371
|
}
|
|
332204
332372
|
} else if (await pathExists2(legacyManifestPath)) {
|
|
332205
332373
|
try {
|
|
332206
|
-
const content = await
|
|
332374
|
+
const content = await readFile42(legacyManifestPath, {
|
|
332207
332375
|
encoding: "utf-8"
|
|
332208
332376
|
});
|
|
332209
332377
|
const parsed = jsonParse2(content);
|
|
@@ -332232,12 +332400,12 @@ async function cachePlugin(source, options) {
|
|
|
332232
332400
|
};
|
|
332233
332401
|
}
|
|
332234
332402
|
const finalName = manifest.name.replace(/[^a-zA-Z0-9-_]/g, "-");
|
|
332235
|
-
const finalPath =
|
|
332403
|
+
const finalPath = join122(cachePath, finalName);
|
|
332236
332404
|
if (await pathExists2(finalPath)) {
|
|
332237
332405
|
logForDebugging3(`Removing old cached version at ${finalPath}`);
|
|
332238
332406
|
await rm9(finalPath, { recursive: true, force: true });
|
|
332239
332407
|
}
|
|
332240
|
-
await
|
|
332408
|
+
await rename7(tempPath, finalPath);
|
|
332241
332409
|
logForDebugging3(`Successfully cached plugin ${manifest.name} to ${finalPath}`);
|
|
332242
332410
|
return {
|
|
332243
332411
|
path: finalPath,
|
|
@@ -332253,7 +332421,7 @@ async function loadPluginManifest(manifestPath, pluginName, source) {
|
|
|
332253
332421
|
};
|
|
332254
332422
|
}
|
|
332255
332423
|
try {
|
|
332256
|
-
const content = await
|
|
332424
|
+
const content = await readFile42(manifestPath, { encoding: "utf-8" });
|
|
332257
332425
|
const parsedJson = jsonParse2(content);
|
|
332258
332426
|
const result = PluginManifestSchema().safeParse(parsedJson);
|
|
332259
332427
|
if (result.success) {
|
|
@@ -332279,14 +332447,14 @@ async function loadPluginHooks2(hooksConfigPath, pluginName) {
|
|
|
332279
332447
|
if (!await pathExists2(hooksConfigPath)) {
|
|
332280
332448
|
throw new Error(`Hooks file not found at ${hooksConfigPath} for plugin ${pluginName}. If the manifest declares hooks, the file must exist.`);
|
|
332281
332449
|
}
|
|
332282
|
-
const content = await
|
|
332450
|
+
const content = await readFile42(hooksConfigPath, { encoding: "utf-8" });
|
|
332283
332451
|
const rawHooksConfig = jsonParse2(content);
|
|
332284
332452
|
const validatedPluginHooks = PluginHooksSchema().parse(rawHooksConfig);
|
|
332285
332453
|
return validatedPluginHooks.hooks;
|
|
332286
332454
|
}
|
|
332287
332455
|
async function validatePluginPaths(relPaths, pluginPath, pluginName, source, component, componentLabel, contextLabel, errors) {
|
|
332288
332456
|
const checks = await Promise.all(relPaths.map(async (relPath) => {
|
|
332289
|
-
const fullPath =
|
|
332457
|
+
const fullPath = join122(pluginPath, relPath);
|
|
332290
332458
|
return { relPath, fullPath, exists: await pathExists2(fullPath) };
|
|
332291
332459
|
}));
|
|
332292
332460
|
const validPaths = [];
|
|
@@ -332325,12 +332493,12 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
|
|
|
332325
332493
|
skillsDirExists,
|
|
332326
332494
|
outputStylesDirExists
|
|
332327
332495
|
] = await Promise.all([
|
|
332328
|
-
!manifest.commands ? pathExists2(
|
|
332329
|
-
!manifest.agents ? pathExists2(
|
|
332330
|
-
!manifest.skills ? pathExists2(
|
|
332331
|
-
!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
|
|
332332
332500
|
]);
|
|
332333
|
-
const commandsPath =
|
|
332501
|
+
const commandsPath = join122(pluginPath, "commands");
|
|
332334
332502
|
if (commandsDirExists) {
|
|
332335
332503
|
plugin.commandsPath = commandsPath;
|
|
332336
332504
|
}
|
|
@@ -332345,7 +332513,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
|
|
|
332345
332513
|
return { commandName, metadata, kind: "skip" };
|
|
332346
332514
|
}
|
|
332347
332515
|
if (metadata.source) {
|
|
332348
|
-
const fullPath =
|
|
332516
|
+
const fullPath = join122(pluginPath, metadata.source);
|
|
332349
332517
|
return {
|
|
332350
332518
|
commandName,
|
|
332351
332519
|
metadata,
|
|
@@ -332393,7 +332561,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
|
|
|
332393
332561
|
if (typeof cmdPath !== "string") {
|
|
332394
332562
|
return { cmdPath, kind: "invalid" };
|
|
332395
332563
|
}
|
|
332396
|
-
const fullPath =
|
|
332564
|
+
const fullPath = join122(pluginPath, cmdPath);
|
|
332397
332565
|
return {
|
|
332398
332566
|
cmdPath,
|
|
332399
332567
|
kind: "path",
|
|
@@ -332426,7 +332594,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
|
|
|
332426
332594
|
}
|
|
332427
332595
|
}
|
|
332428
332596
|
}
|
|
332429
|
-
const agentsPath =
|
|
332597
|
+
const agentsPath = join122(pluginPath, "agents");
|
|
332430
332598
|
if (agentsDirExists) {
|
|
332431
332599
|
plugin.agentsPath = agentsPath;
|
|
332432
332600
|
}
|
|
@@ -332437,7 +332605,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
|
|
|
332437
332605
|
plugin.agentsPaths = validPaths;
|
|
332438
332606
|
}
|
|
332439
332607
|
}
|
|
332440
|
-
const skillsPath =
|
|
332608
|
+
const skillsPath = join122(pluginPath, "skills");
|
|
332441
332609
|
if (skillsDirExists) {
|
|
332442
332610
|
plugin.skillsPath = skillsPath;
|
|
332443
332611
|
}
|
|
@@ -332448,7 +332616,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
|
|
|
332448
332616
|
plugin.skillsPaths = validPaths;
|
|
332449
332617
|
}
|
|
332450
332618
|
}
|
|
332451
|
-
const outputStylesPath =
|
|
332619
|
+
const outputStylesPath = join122(pluginPath, "output-styles");
|
|
332452
332620
|
if (outputStylesDirExists) {
|
|
332453
332621
|
plugin.outputStylesPath = outputStylesPath;
|
|
332454
332622
|
}
|
|
@@ -332461,7 +332629,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
|
|
|
332461
332629
|
}
|
|
332462
332630
|
let mergedHooks;
|
|
332463
332631
|
const loadedHookPaths = new Set;
|
|
332464
|
-
const standardHooksPath =
|
|
332632
|
+
const standardHooksPath = join122(pluginPath, "hooks", "hooks.json");
|
|
332465
332633
|
if (await pathExists2(standardHooksPath)) {
|
|
332466
332634
|
try {
|
|
332467
332635
|
mergedHooks = await loadPluginHooks2(standardHooksPath, manifest.name);
|
|
@@ -332490,7 +332658,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
|
|
|
332490
332658
|
const manifestHooksArray = Array.isArray(manifest.hooks) ? manifest.hooks : [manifest.hooks];
|
|
332491
332659
|
for (const hookSpec of manifestHooksArray) {
|
|
332492
332660
|
if (typeof hookSpec === "string") {
|
|
332493
|
-
const hookFilePath =
|
|
332661
|
+
const hookFilePath = join122(pluginPath, hookSpec);
|
|
332494
332662
|
if (!await pathExists2(hookFilePath)) {
|
|
332495
332663
|
logForDebugging3(`Hooks file ${hookSpec} specified in manifest but not found at ${hookFilePath} for ${manifest.name}`, { level: "error" });
|
|
332496
332664
|
logError3(new Error(`Plugin component file not found: ${hookFilePath} for ${manifest.name}`));
|
|
@@ -332580,9 +332748,9 @@ function parsePluginSettings(raw) {
|
|
|
332580
332748
|
return data;
|
|
332581
332749
|
}
|
|
332582
332750
|
async function loadPluginSettings(pluginPath, manifest) {
|
|
332583
|
-
const settingsJsonPath =
|
|
332751
|
+
const settingsJsonPath = join122(pluginPath, "settings.json");
|
|
332584
332752
|
try {
|
|
332585
|
-
const content = await
|
|
332753
|
+
const content = await readFile42(settingsJsonPath, { encoding: "utf-8" });
|
|
332586
332754
|
const parsed = jsonParse2(content);
|
|
332587
332755
|
if (isRecord(parsed)) {
|
|
332588
332756
|
const filtered = parsePluginSettings(parsed);
|
|
@@ -332723,7 +332891,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
|
|
|
332723
332891
|
if (typeof entry.source === "string") {
|
|
332724
332892
|
let marketplaceDir;
|
|
332725
332893
|
try {
|
|
332726
|
-
marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation :
|
|
332894
|
+
marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join122(marketplaceInstallLocation, "..");
|
|
332727
332895
|
} catch {
|
|
332728
332896
|
errorsOut.push({
|
|
332729
332897
|
type: "plugin-cache-miss",
|
|
@@ -332733,7 +332901,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
|
|
|
332733
332901
|
});
|
|
332734
332902
|
return null;
|
|
332735
332903
|
}
|
|
332736
|
-
pluginPath =
|
|
332904
|
+
pluginPath = join122(marketplaceDir, entry.source);
|
|
332737
332905
|
} else {
|
|
332738
332906
|
if (!installPath || !await pathExists2(installPath)) {
|
|
332739
332907
|
errorsOut.push({
|
|
@@ -332748,7 +332916,7 @@ async function loadPluginFromMarketplaceEntryCacheOnly(entry, marketplaceInstall
|
|
|
332748
332916
|
}
|
|
332749
332917
|
if (isPluginZipCacheEnabled() && pluginPath.endsWith(".zip")) {
|
|
332750
332918
|
const sessionDir = await getSessionPluginCachePath();
|
|
332751
|
-
const extractDir =
|
|
332919
|
+
const extractDir = join122(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
|
|
332752
332920
|
try {
|
|
332753
332921
|
await extractZipToDirectory(pluginPath, extractDir);
|
|
332754
332922
|
pluginPath = extractDir;
|
|
@@ -332771,8 +332939,8 @@ async function loadPluginFromMarketplaceEntry(entry, marketplaceInstallLocation,
|
|
|
332771
332939
|
logForDebugging3(`Loading plugin ${entry.name} from source: ${jsonStringify5(entry.source)}`);
|
|
332772
332940
|
let pluginPath;
|
|
332773
332941
|
if (typeof entry.source === "string") {
|
|
332774
|
-
const marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation :
|
|
332775
|
-
const sourcePluginPath =
|
|
332942
|
+
const marketplaceDir = (await stat40(marketplaceInstallLocation)).isDirectory() ? marketplaceInstallLocation : join122(marketplaceInstallLocation, "..");
|
|
332943
|
+
const sourcePluginPath = join122(marketplaceDir, entry.source);
|
|
332776
332944
|
if (!await pathExists2(sourcePluginPath)) {
|
|
332777
332945
|
const error = new Error(`Plugin path not found: ${sourcePluginPath}`);
|
|
332778
332946
|
logForDebugging3(`Plugin path not found: ${sourcePluginPath}`, {
|
|
@@ -332843,7 +333011,7 @@ async function loadPluginFromMarketplaceEntry(entry, marketplaceInstallLocation,
|
|
|
332843
333011
|
}
|
|
332844
333012
|
if (isPluginZipCacheEnabled() && pluginPath.endsWith(".zip")) {
|
|
332845
333013
|
const sessionDir = await getSessionPluginCachePath();
|
|
332846
|
-
const extractDir =
|
|
333014
|
+
const extractDir = join122(sessionDir, pluginId.replace(/[^a-zA-Z0-9@\-_]/g, "-"));
|
|
332847
333015
|
try {
|
|
332848
333016
|
await extractZipToDirectory(pluginPath, extractDir);
|
|
332849
333017
|
logForDebugging3(`Extracted plugin ZIP to session dir: ${extractDir}`);
|
|
@@ -332883,7 +333051,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
|
|
|
332883
333051
|
if (!metadata || typeof metadata !== "object" || !metadata.source) {
|
|
332884
333052
|
return { commandName, metadata, skip: true };
|
|
332885
333053
|
}
|
|
332886
|
-
const fullPath =
|
|
333054
|
+
const fullPath = join122(pluginPath, metadata.source);
|
|
332887
333055
|
return {
|
|
332888
333056
|
commandName,
|
|
332889
333057
|
metadata,
|
|
@@ -332920,7 +333088,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
|
|
|
332920
333088
|
if (typeof cmdPath !== "string") {
|
|
332921
333089
|
return { cmdPath, kind: "invalid" };
|
|
332922
333090
|
}
|
|
332923
|
-
const fullPath =
|
|
333091
|
+
const fullPath = join122(pluginPath, cmdPath);
|
|
332924
333092
|
return {
|
|
332925
333093
|
cmdPath,
|
|
332926
333094
|
kind: "path",
|
|
@@ -332964,7 +333132,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
|
|
|
332964
333132
|
logForDebugging3(`Processing ${Array.isArray(entry.skills) ? entry.skills.length : 1} skill paths for plugin ${entry.name}`);
|
|
332965
333133
|
const skillPaths = Array.isArray(entry.skills) ? entry.skills : [entry.skills];
|
|
332966
333134
|
const checks = await Promise.all(skillPaths.map(async (skillPath) => {
|
|
332967
|
-
const fullPath =
|
|
333135
|
+
const fullPath = join122(pluginPath, skillPath);
|
|
332968
333136
|
return { skillPath, fullPath, exists: await pathExists2(fullPath) };
|
|
332969
333137
|
}));
|
|
332970
333138
|
const validPaths = [];
|
|
@@ -333024,7 +333192,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
|
|
|
333024
333192
|
if (!metadata || typeof metadata !== "object" || !metadata.source) {
|
|
333025
333193
|
return { commandName, metadata, skip: true };
|
|
333026
333194
|
}
|
|
333027
|
-
const fullPath =
|
|
333195
|
+
const fullPath = join122(pluginPath, metadata.source);
|
|
333028
333196
|
return {
|
|
333029
333197
|
commandName,
|
|
333030
333198
|
metadata,
|
|
@@ -333064,7 +333232,7 @@ async function finishLoadingPluginFromPath(entry, pluginId, enabled, errorsOut,
|
|
|
333064
333232
|
if (typeof cmdPath !== "string") {
|
|
333065
333233
|
return { cmdPath, kind: "invalid" };
|
|
333066
333234
|
}
|
|
333067
|
-
const fullPath =
|
|
333235
|
+
const fullPath = join122(pluginPath, cmdPath);
|
|
333068
333236
|
return {
|
|
333069
333237
|
cmdPath,
|
|
333070
333238
|
kind: "path",
|
|
@@ -336727,9 +336895,9 @@ var init_prefix = __esm(() => {
|
|
|
336727
336895
|
});
|
|
336728
336896
|
|
|
336729
336897
|
// src/tui/utils/bash/commands.ts
|
|
336730
|
-
import { randomBytes as
|
|
336898
|
+
import { randomBytes as randomBytes17 } from "crypto";
|
|
336731
336899
|
function generatePlaceholders2() {
|
|
336732
|
-
const salt =
|
|
336900
|
+
const salt = randomBytes17(8).toString("hex");
|
|
336733
336901
|
return {
|
|
336734
336902
|
SINGLE_QUOTE: `__SINGLE_QUOTE_${salt}__`,
|
|
336735
336903
|
DOUBLE_QUOTE: `__DOUBLE_QUOTE_${salt}__`,
|
|
@@ -339372,7 +339540,7 @@ var init_projectOnboardingState = __esm(() => {
|
|
|
339372
339540
|
// src/tui/utils/appleTerminalBackup.ts
|
|
339373
339541
|
import { stat as stat41 } from "fs/promises";
|
|
339374
339542
|
import { homedir as homedir30 } from "os";
|
|
339375
|
-
import { join as
|
|
339543
|
+
import { join as join123 } from "path";
|
|
339376
339544
|
function markTerminalSetupInProgress(backupPath) {
|
|
339377
339545
|
saveGlobalConfig((current) => ({
|
|
339378
339546
|
...current,
|
|
@@ -339394,7 +339562,7 @@ function getTerminalRecoveryInfo() {
|
|
|
339394
339562
|
};
|
|
339395
339563
|
}
|
|
339396
339564
|
function getTerminalPlistPath() {
|
|
339397
|
-
return
|
|
339565
|
+
return join123(homedir30(), "Library", "Preferences", "com.apple.Terminal.plist");
|
|
339398
339566
|
}
|
|
339399
339567
|
async function backupTerminalPreferences() {
|
|
339400
339568
|
const terminalPlistPath = getTerminalPlistPath();
|
|
@@ -339475,10 +339643,10 @@ __export(exports_terminalSetup, {
|
|
|
339475
339643
|
setupTerminal: () => setupTerminal,
|
|
339476
339644
|
shouldOfferTerminalSetup: () => shouldOfferTerminalSetup
|
|
339477
339645
|
});
|
|
339478
|
-
import { randomBytes as
|
|
339479
|
-
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";
|
|
339480
339648
|
import { homedir as homedir31, platform as platform3 } from "os";
|
|
339481
|
-
import { dirname as dirname66, join as
|
|
339649
|
+
import { dirname as dirname66, join as join124 } from "path";
|
|
339482
339650
|
import { pathToFileURL as pathToFileURL8 } from "url";
|
|
339483
339651
|
function isVSCodeRemoteSSH() {
|
|
339484
339652
|
const askpassMain = process.env.VSCODE_GIT_ASKPASS_MAIN ?? "";
|
|
@@ -339612,8 +339780,8 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
|
|
|
339612
339780
|
]`)}${EOL4}`;
|
|
339613
339781
|
}
|
|
339614
339782
|
const editorDir = editor === "VSCode" ? "Code" : editor;
|
|
339615
|
-
const userDirPath =
|
|
339616
|
-
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");
|
|
339617
339785
|
try {
|
|
339618
339786
|
await mkdir37(userDirPath, {
|
|
339619
339787
|
recursive: true
|
|
@@ -339622,7 +339790,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
|
|
|
339622
339790
|
let keybindings = [];
|
|
339623
339791
|
let fileExists = false;
|
|
339624
339792
|
try {
|
|
339625
|
-
content = await
|
|
339793
|
+
content = await readFile43(keybindingsPath, {
|
|
339626
339794
|
encoding: "utf-8"
|
|
339627
339795
|
});
|
|
339628
339796
|
fileExists = true;
|
|
@@ -339632,7 +339800,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
|
|
|
339632
339800
|
throw e;
|
|
339633
339801
|
}
|
|
339634
339802
|
if (fileExists) {
|
|
339635
|
-
const randomSha =
|
|
339803
|
+
const randomSha = randomBytes18(4).toString("hex");
|
|
339636
339804
|
const backupPath = `${keybindingsPath}.${randomSha}.bak`;
|
|
339637
339805
|
try {
|
|
339638
339806
|
await copyFile7(keybindingsPath, backupPath);
|
|
@@ -339653,7 +339821,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
|
|
|
339653
339821
|
when: "terminalFocus"
|
|
339654
339822
|
};
|
|
339655
339823
|
const updatedContent = addItemToJSONCArray(content, newKeybinding);
|
|
339656
|
-
await
|
|
339824
|
+
await writeFile30(keybindingsPath, updatedContent, {
|
|
339657
339825
|
encoding: "utf-8"
|
|
339658
339826
|
});
|
|
339659
339827
|
return `${color("success", theme)(`Installed ${editor} terminal Shift+Enter key binding`)}${EOL4}${source_default.dim(`See ${formatPathLink(keybindingsPath)}`)}${EOL4}`;
|
|
@@ -339754,14 +339922,14 @@ chars = "\\u001B\\r"`;
|
|
|
339754
339922
|
const configPaths = [];
|
|
339755
339923
|
const xdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
339756
339924
|
if (xdgConfigHome) {
|
|
339757
|
-
configPaths.push(
|
|
339925
|
+
configPaths.push(join124(xdgConfigHome, "alacritty", "alacritty.toml"));
|
|
339758
339926
|
} else {
|
|
339759
|
-
configPaths.push(
|
|
339927
|
+
configPaths.push(join124(homedir31(), ".config", "alacritty", "alacritty.toml"));
|
|
339760
339928
|
}
|
|
339761
339929
|
if (platform3() === "win32") {
|
|
339762
339930
|
const appData = process.env.APPDATA;
|
|
339763
339931
|
if (appData) {
|
|
339764
|
-
configPaths.push(
|
|
339932
|
+
configPaths.push(join124(appData, "alacritty", "alacritty.toml"));
|
|
339765
339933
|
}
|
|
339766
339934
|
}
|
|
339767
339935
|
let configPath = null;
|
|
@@ -339769,7 +339937,7 @@ chars = "\\u001B\\r"`;
|
|
|
339769
339937
|
let configExists = false;
|
|
339770
339938
|
for (const path of configPaths) {
|
|
339771
339939
|
try {
|
|
339772
|
-
configContent = await
|
|
339940
|
+
configContent = await readFile43(path, {
|
|
339773
339941
|
encoding: "utf-8"
|
|
339774
339942
|
});
|
|
339775
339943
|
configPath = path;
|
|
@@ -339791,7 +339959,7 @@ chars = "\\u001B\\r"`;
|
|
|
339791
339959
|
if (configContent.includes('mods = "Shift"') && configContent.includes('key = "Return"')) {
|
|
339792
339960
|
return `${color("warning", theme)("Found existing Alacritty Shift+Enter key binding. Remove it to continue.")}${EOL4}${source_default.dim(`See ${formatPathLink(configPath)}`)}${EOL4}`;
|
|
339793
339961
|
}
|
|
339794
|
-
const randomSha =
|
|
339962
|
+
const randomSha = randomBytes18(4).toString("hex");
|
|
339795
339963
|
const backupPath = `${configPath}.${randomSha}.bak`;
|
|
339796
339964
|
try {
|
|
339797
339965
|
await copyFile7(configPath, backupPath);
|
|
@@ -339812,7 +339980,7 @@ chars = "\\u001B\\r"`;
|
|
|
339812
339980
|
updatedContent += `
|
|
339813
339981
|
` + ALACRITTY_KEYBINDING + `
|
|
339814
339982
|
`;
|
|
339815
|
-
await
|
|
339983
|
+
await writeFile30(configPath, updatedContent, {
|
|
339816
339984
|
encoding: "utf-8"
|
|
339817
339985
|
});
|
|
339818
339986
|
return `${color("success", theme)("Installed Alacritty Shift+Enter key binding")}${EOL4}${color("success", theme)("You may need to restart Alacritty for changes to take effect")}${EOL4}${source_default.dim(`See ${formatPathLink(configPath)}`)}${EOL4}`;
|
|
@@ -339822,8 +339990,8 @@ chars = "\\u001B\\r"`;
|
|
|
339822
339990
|
}
|
|
339823
339991
|
}
|
|
339824
339992
|
async function installBindingsForZed(theme) {
|
|
339825
|
-
const zedDir =
|
|
339826
|
-
const keymapPath =
|
|
339993
|
+
const zedDir = join124(homedir31(), ".config", "zed");
|
|
339994
|
+
const keymapPath = join124(zedDir, "keymap.json");
|
|
339827
339995
|
try {
|
|
339828
339996
|
await mkdir37(zedDir, {
|
|
339829
339997
|
recursive: true
|
|
@@ -339831,7 +339999,7 @@ async function installBindingsForZed(theme) {
|
|
|
339831
339999
|
let keymapContent = "[]";
|
|
339832
340000
|
let fileExists = false;
|
|
339833
340001
|
try {
|
|
339834
|
-
keymapContent = await
|
|
340002
|
+
keymapContent = await readFile43(keymapPath, {
|
|
339835
340003
|
encoding: "utf-8"
|
|
339836
340004
|
});
|
|
339837
340005
|
fileExists = true;
|
|
@@ -339843,7 +340011,7 @@ async function installBindingsForZed(theme) {
|
|
|
339843
340011
|
if (keymapContent.includes("shift-enter")) {
|
|
339844
340012
|
return `${color("warning", theme)("Found existing Zed Shift+Enter key binding. Remove it to continue.")}${EOL4}${source_default.dim(`See ${formatPathLink(keymapPath)}`)}${EOL4}`;
|
|
339845
340013
|
}
|
|
339846
|
-
const randomSha =
|
|
340014
|
+
const randomSha = randomBytes18(4).toString("hex");
|
|
339847
340015
|
const backupPath = `${keymapPath}.${randomSha}.bak`;
|
|
339848
340016
|
try {
|
|
339849
340017
|
await copyFile7(keymapPath, backupPath);
|
|
@@ -339866,7 +340034,7 @@ async function installBindingsForZed(theme) {
|
|
|
339866
340034
|
"shift-enter": ["terminal::SendText", "\x1B\r"]
|
|
339867
340035
|
}
|
|
339868
340036
|
});
|
|
339869
|
-
await
|
|
340037
|
+
await writeFile30(keymapPath, jsonStringify5(keymap, null, 2) + `
|
|
339870
340038
|
`, {
|
|
339871
340039
|
encoding: "utf-8"
|
|
339872
340040
|
});
|
|
@@ -339903,23 +340071,23 @@ var init_terminalSetup = __esm(() => {
|
|
|
339903
340071
|
|
|
339904
340072
|
// src/tui/utils/pasteStore.ts
|
|
339905
340073
|
import { createHash as createHash10 } from "crypto";
|
|
339906
|
-
import { mkdir as mkdir38, readdir as readdir25, readFile as
|
|
339907
|
-
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";
|
|
339908
340076
|
function getPasteStoreDir() {
|
|
339909
|
-
return
|
|
340077
|
+
return join125(getAtlasConfigHomeDir3(), PASTE_STORE_DIR);
|
|
339910
340078
|
}
|
|
339911
340079
|
function hashPastedText(content) {
|
|
339912
340080
|
return createHash10("sha256").update(content).digest("hex").slice(0, 16);
|
|
339913
340081
|
}
|
|
339914
340082
|
function getPastePath(hash) {
|
|
339915
|
-
return
|
|
340083
|
+
return join125(getPasteStoreDir(), `${hash}.txt`);
|
|
339916
340084
|
}
|
|
339917
340085
|
async function storePastedText(hash, content) {
|
|
339918
340086
|
try {
|
|
339919
340087
|
const dir = getPasteStoreDir();
|
|
339920
340088
|
await mkdir38(dir, { recursive: true });
|
|
339921
340089
|
const pastePath = getPastePath(hash);
|
|
339922
|
-
await
|
|
340090
|
+
await writeFile31(pastePath, content, { encoding: "utf8", mode: 384 });
|
|
339923
340091
|
logForDebugging3(`Stored paste ${hash} to ${pastePath}`);
|
|
339924
340092
|
} catch (error) {
|
|
339925
340093
|
logForDebugging3(`Failed to store paste: ${error}`);
|
|
@@ -339928,7 +340096,7 @@ async function storePastedText(hash, content) {
|
|
|
339928
340096
|
async function retrievePastedText(hash) {
|
|
339929
340097
|
try {
|
|
339930
340098
|
const pastePath = getPastePath(hash);
|
|
339931
|
-
return await
|
|
340099
|
+
return await readFile44(pastePath, { encoding: "utf8" });
|
|
339932
340100
|
} catch (error) {
|
|
339933
340101
|
if (!isENOENT2(error)) {
|
|
339934
340102
|
logForDebugging3(`Failed to retrieve paste ${hash}: ${error}`);
|
|
@@ -339949,11 +340117,11 @@ async function cleanupOldPastes(cutoffDate) {
|
|
|
339949
340117
|
if (!file.endsWith(".txt")) {
|
|
339950
340118
|
continue;
|
|
339951
340119
|
}
|
|
339952
|
-
const filePath =
|
|
340120
|
+
const filePath = join125(pasteDir, file);
|
|
339953
340121
|
try {
|
|
339954
340122
|
const stats = await stat42(filePath);
|
|
339955
340123
|
if (stats.mtimeMs < cutoffTime) {
|
|
339956
|
-
await
|
|
340124
|
+
await unlink17(filePath);
|
|
339957
340125
|
logForDebugging3(`Cleaned up old paste: ${filePath}`);
|
|
339958
340126
|
}
|
|
339959
340127
|
} catch {}
|
|
@@ -339967,8 +340135,8 @@ var init_pasteStore = __esm(() => {
|
|
|
339967
340135
|
});
|
|
339968
340136
|
|
|
339969
340137
|
// src/tui/history.ts
|
|
339970
|
-
import { appendFile as appendFile5, writeFile as
|
|
339971
|
-
import { join as
|
|
340138
|
+
import { appendFile as appendFile5, writeFile as writeFile32 } from "fs/promises";
|
|
340139
|
+
import { join as join126 } from "path";
|
|
339972
340140
|
function getPastedTextRefNumLines(text) {
|
|
339973
340141
|
return (text.match(/\r\n|\r|\n/g) || []).length;
|
|
339974
340142
|
}
|
|
@@ -340010,7 +340178,7 @@ async function* makeLogEntryReader() {
|
|
|
340010
340178
|
for (let i = pendingEntries.length - 1;i >= 0; i--) {
|
|
340011
340179
|
yield pendingEntries[i];
|
|
340012
340180
|
}
|
|
340013
|
-
const historyPath =
|
|
340181
|
+
const historyPath = join126(getAtlasConfigHomeDir3(), "history.jsonl");
|
|
340014
340182
|
try {
|
|
340015
340183
|
for await (const line of readLinesReverse(historyPath)) {
|
|
340016
340184
|
try {
|
|
@@ -340125,8 +340293,8 @@ async function immediateFlushHistory() {
|
|
|
340125
340293
|
}
|
|
340126
340294
|
let release;
|
|
340127
340295
|
try {
|
|
340128
|
-
const historyPath =
|
|
340129
|
-
await
|
|
340296
|
+
const historyPath = join126(getAtlasConfigHomeDir3(), "history.jsonl");
|
|
340297
|
+
await writeFile32(historyPath, "", {
|
|
340130
340298
|
encoding: "utf8",
|
|
340131
340299
|
mode: 384,
|
|
340132
340300
|
flag: "a"
|
|
@@ -342326,7 +342494,7 @@ var init_TextInput = __esm(() => {
|
|
|
342326
342494
|
});
|
|
342327
342495
|
|
|
342328
342496
|
// src/tui/utils/suggestions/directoryCompletion.ts
|
|
342329
|
-
import { basename as basename40, dirname as dirname67, join as
|
|
342497
|
+
import { basename as basename40, dirname as dirname67, join as join127, sep as sep29 } from "path";
|
|
342330
342498
|
function parsePartialPath(partialPath, basePath) {
|
|
342331
342499
|
if (!partialPath) {
|
|
342332
342500
|
const directory = basePath || getCwd();
|
|
@@ -342350,7 +342518,7 @@ async function scanDirectory(dirPath) {
|
|
|
342350
342518
|
const entries = await fs.readdir(dirPath);
|
|
342351
342519
|
const directories = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => ({
|
|
342352
342520
|
name: entry.name,
|
|
342353
|
-
path:
|
|
342521
|
+
path: join127(dirPath, entry.name),
|
|
342354
342522
|
type: "directory"
|
|
342355
342523
|
})).slice(0, 100);
|
|
342356
342524
|
directoryCache.set(dirPath, directories);
|
|
@@ -342387,7 +342555,7 @@ async function scanDirectoryForPaths(dirPath, includeHidden = false) {
|
|
|
342387
342555
|
const entries = await fs.readdir(dirPath);
|
|
342388
342556
|
const paths = entries.filter((entry) => includeHidden || !entry.name.startsWith(".")).map((entry) => ({
|
|
342389
342557
|
name: entry.name,
|
|
342390
|
-
path:
|
|
342558
|
+
path: join127(dirPath, entry.name),
|
|
342391
342559
|
type: entry.isDirectory() ? "directory" : "file"
|
|
342392
342560
|
})).sort((a, b) => {
|
|
342393
342561
|
if (a.type === "directory" && b.type !== "directory")
|
|
@@ -343997,7 +344165,7 @@ var init_btw2 = __esm(() => {
|
|
|
343997
344165
|
});
|
|
343998
344166
|
|
|
343999
344167
|
// src/tui/components/Feedback.tsx
|
|
344000
|
-
import { readFile as
|
|
344168
|
+
import { readFile as readFile45, stat as stat43 } from "fs/promises";
|
|
344001
344169
|
function redactSensitiveInfo(text) {
|
|
344002
344170
|
let redacted = text;
|
|
344003
344171
|
redacted = redacted.replace(/"(sk-ant[^\s"']{24,})"/g, '"[REDACTED_API_KEY]"');
|
|
@@ -344036,7 +344204,7 @@ async function loadRawTranscriptJsonl() {
|
|
|
344036
344204
|
});
|
|
344037
344205
|
return null;
|
|
344038
344206
|
}
|
|
344039
|
-
return await
|
|
344207
|
+
return await readFile45(transcriptPath, "utf-8");
|
|
344040
344208
|
} catch {
|
|
344041
344209
|
return null;
|
|
344042
344210
|
}
|
|
@@ -345501,7 +345669,7 @@ var init_postSamplingHooks = __esm(() => {
|
|
|
345501
345669
|
});
|
|
345502
345670
|
|
|
345503
345671
|
// src/tui/services/MagicDocs/prompts.ts
|
|
345504
|
-
import { join as
|
|
345672
|
+
import { join as join129 } from "path";
|
|
345505
345673
|
function getUpdatePromptTemplate() {
|
|
345506
345674
|
return `IMPORTANT: This message and these instructions are NOT part of the actual user conversation. Do NOT include any references to "documentation updates", "magic docs", or these update instructions in the document content.
|
|
345507
345675
|
|
|
@@ -345556,7 +345724,7 @@ REMEMBER: Only update if there is substantial new information. The Magic Doc hea
|
|
|
345556
345724
|
}
|
|
345557
345725
|
async function loadMagicDocsPrompt() {
|
|
345558
345726
|
const fs = getFsImplementation2();
|
|
345559
|
-
const promptPath =
|
|
345727
|
+
const promptPath = join129(getAtlasConfigHomeDir3(), "magic-docs", "prompt.md");
|
|
345560
345728
|
try {
|
|
345561
345729
|
return await fs.readFile(promptPath, { encoding: "utf-8" });
|
|
345562
345730
|
} catch {
|
|
@@ -346127,9 +346295,9 @@ __export(exports_copy, {
|
|
|
346127
346295
|
collectRecentAssistantTexts: () => collectRecentAssistantTexts,
|
|
346128
346296
|
fileExtension: () => fileExtension2
|
|
346129
346297
|
});
|
|
346130
|
-
import { mkdir as mkdir39, writeFile as
|
|
346298
|
+
import { mkdir as mkdir39, writeFile as writeFile33 } from "fs/promises";
|
|
346131
346299
|
import { tmpdir as tmpdir8 } from "os";
|
|
346132
|
-
import { join as
|
|
346300
|
+
import { join as join130 } from "path";
|
|
346133
346301
|
function extractCodeBlocks(markdown) {
|
|
346134
346302
|
const tokens = k2.lexer(stripPromptXMLTags(markdown));
|
|
346135
346303
|
const blocks = [];
|
|
@@ -346171,11 +346339,11 @@ function fileExtension2(lang) {
|
|
|
346171
346339
|
return ".txt";
|
|
346172
346340
|
}
|
|
346173
346341
|
async function writeToFile(text, filename) {
|
|
346174
|
-
const filePath =
|
|
346342
|
+
const filePath = join130(COPY_DIR, filename);
|
|
346175
346343
|
await mkdir39(COPY_DIR, {
|
|
346176
346344
|
recursive: true
|
|
346177
346345
|
});
|
|
346178
|
-
await
|
|
346346
|
+
await writeFile33(filePath, text, "utf-8");
|
|
346179
346347
|
return filePath;
|
|
346180
346348
|
}
|
|
346181
346349
|
async function copyOrWriteToFile(text, filename) {
|
|
@@ -346501,7 +346669,7 @@ var init_copy = __esm(() => {
|
|
|
346501
346669
|
import_compiler_runtime113 = __toESM(require_compiler_runtime(), 1);
|
|
346502
346670
|
import_react81 = __toESM(require_react(), 1);
|
|
346503
346671
|
jsx_dev_runtime138 = __toESM(require_jsx_dev_runtime(), 1);
|
|
346504
|
-
COPY_DIR =
|
|
346672
|
+
COPY_DIR = join130(tmpdir8(), "atlas");
|
|
346505
346673
|
});
|
|
346506
346674
|
|
|
346507
346675
|
// src/tui/commands/copy/index.ts
|
|
@@ -347876,13 +348044,13 @@ var init_Tabs = __esm(() => {
|
|
|
347876
348044
|
});
|
|
347877
348045
|
|
|
347878
348046
|
// src/tui/utils/localInstaller.ts
|
|
347879
|
-
import { access as access3, chmod as chmod6, writeFile as
|
|
347880
|
-
import { join as
|
|
348047
|
+
import { access as access3, chmod as chmod6, writeFile as writeFile34 } from "fs/promises";
|
|
348048
|
+
import { join as join131 } from "path";
|
|
347881
348049
|
function getLocalInstallDir() {
|
|
347882
|
-
return
|
|
348050
|
+
return join131(getAtlasConfigHomeDir3(), "local");
|
|
347883
348051
|
}
|
|
347884
348052
|
function getLocalAtlasPath() {
|
|
347885
|
-
return
|
|
348053
|
+
return join131(getLocalInstallDir(), "atlas");
|
|
347886
348054
|
}
|
|
347887
348055
|
function isRunningFromLocalInstallation() {
|
|
347888
348056
|
const execPath = process.argv[1] || "";
|
|
@@ -347890,7 +348058,7 @@ function isRunningFromLocalInstallation() {
|
|
|
347890
348058
|
}
|
|
347891
348059
|
async function writeIfMissing(path, content, mode) {
|
|
347892
348060
|
try {
|
|
347893
|
-
await
|
|
348061
|
+
await writeFile34(path, content, { encoding: "utf8", flag: "wx", mode });
|
|
347894
348062
|
return true;
|
|
347895
348063
|
} catch (e) {
|
|
347896
348064
|
if (getErrnoCode2(e) === "EEXIST")
|
|
@@ -347902,8 +348070,8 @@ async function ensureLocalPackageEnvironment() {
|
|
|
347902
348070
|
try {
|
|
347903
348071
|
const localInstallDir = getLocalInstallDir();
|
|
347904
348072
|
await getFsImplementation2().mkdir(localInstallDir);
|
|
347905
|
-
await writeIfMissing(
|
|
347906
|
-
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");
|
|
347907
348075
|
const created = await writeIfMissing(wrapperPath, `#!/bin/sh
|
|
347908
348076
|
exec "${localInstallDir}/node_modules/.bin/atlas" "$@"`, 493);
|
|
347909
348077
|
if (created) {
|
|
@@ -347939,7 +348107,7 @@ async function installOrUpdateClaudePackage(channel, specificVersion) {
|
|
|
347939
348107
|
}
|
|
347940
348108
|
async function localInstallationExists() {
|
|
347941
348109
|
try {
|
|
347942
|
-
await access3(
|
|
348110
|
+
await access3(join131(getLocalInstallDir(), "node_modules", ".bin", "atlas"));
|
|
347943
348111
|
return true;
|
|
347944
348112
|
} catch {
|
|
347945
348113
|
return false;
|
|
@@ -347966,17 +348134,17 @@ var init_localInstaller = __esm(() => {
|
|
|
347966
348134
|
});
|
|
347967
348135
|
|
|
347968
348136
|
// src/tui/utils/shellConfig.ts
|
|
347969
|
-
import { open as open14, readFile as
|
|
348137
|
+
import { open as open14, readFile as readFile46, stat as stat44 } from "fs/promises";
|
|
347970
348138
|
import { homedir as osHomedir } from "os";
|
|
347971
|
-
import { join as
|
|
348139
|
+
import { join as join132 } from "path";
|
|
347972
348140
|
function getShellConfigPaths(options) {
|
|
347973
348141
|
const home = options?.homedir ?? osHomedir();
|
|
347974
348142
|
const env = options?.env ?? process.env;
|
|
347975
348143
|
const zshConfigDir = env.ZDOTDIR || home;
|
|
347976
348144
|
return {
|
|
347977
|
-
zsh:
|
|
347978
|
-
bash:
|
|
347979
|
-
fish:
|
|
348145
|
+
zsh: join132(zshConfigDir, ".zshrc"),
|
|
348146
|
+
bash: join132(home, ".bashrc"),
|
|
348147
|
+
fish: join132(home, ".config/fish/config.fish")
|
|
347980
348148
|
};
|
|
347981
348149
|
}
|
|
347982
348150
|
function filterAtlasAliases(lines) {
|
|
@@ -348001,7 +348169,7 @@ function filterAtlasAliases(lines) {
|
|
|
348001
348169
|
}
|
|
348002
348170
|
async function readFileLines(filePath) {
|
|
348003
348171
|
try {
|
|
348004
|
-
const content = await
|
|
348172
|
+
const content = await readFile46(filePath, { encoding: "utf8" });
|
|
348005
348173
|
return content.split(`
|
|
348006
348174
|
`);
|
|
348007
348175
|
} catch (e) {
|
|
@@ -348060,9 +348228,9 @@ var init_shellConfig = __esm(() => {
|
|
|
348060
348228
|
|
|
348061
348229
|
// src/tui/utils/autoUpdater.ts
|
|
348062
348230
|
import { constants as fsConstants6 } from "fs";
|
|
348063
|
-
import { access as access4, writeFile as
|
|
348231
|
+
import { access as access4, writeFile as writeFile35 } from "fs/promises";
|
|
348064
348232
|
import { homedir as homedir32 } from "os";
|
|
348065
|
-
import { join as
|
|
348233
|
+
import { join as join133 } from "path";
|
|
348066
348234
|
async function assertMinVersion() {
|
|
348067
348235
|
if (false) {}
|
|
348068
348236
|
try {
|
|
@@ -348112,7 +348280,7 @@ function shouldSkipVersion(targetVersion) {
|
|
|
348112
348280
|
return shouldSkip;
|
|
348113
348281
|
}
|
|
348114
348282
|
function getLockFilePath() {
|
|
348115
|
-
return
|
|
348283
|
+
return join133(getAtlasConfigHomeDir3(), ".update.lock");
|
|
348116
348284
|
}
|
|
348117
348285
|
async function acquireLock() {
|
|
348118
348286
|
const fs = getFsImplementation2();
|
|
@@ -348142,7 +348310,7 @@ async function acquireLock() {
|
|
|
348142
348310
|
}
|
|
348143
348311
|
}
|
|
348144
348312
|
try {
|
|
348145
|
-
await
|
|
348313
|
+
await writeFile35(lockPath, `${process.pid}`, {
|
|
348146
348314
|
encoding: "utf8",
|
|
348147
348315
|
flag: "wx"
|
|
348148
348316
|
});
|
|
@@ -348155,7 +348323,7 @@ async function acquireLock() {
|
|
|
348155
348323
|
if (code === "ENOENT") {
|
|
348156
348324
|
try {
|
|
348157
348325
|
await fs.mkdir(getAtlasConfigHomeDir3());
|
|
348158
|
-
await
|
|
348326
|
+
await writeFile35(lockPath, `${process.pid}`, {
|
|
348159
348327
|
encoding: "utf8",
|
|
348160
348328
|
flag: "wx"
|
|
348161
348329
|
});
|
|
@@ -348344,7 +348512,7 @@ var init_autoUpdater = __esm(() => {
|
|
|
348344
348512
|
});
|
|
348345
348513
|
|
|
348346
348514
|
// src/tui/utils/nativeInstaller/packageManagers.ts
|
|
348347
|
-
import { readFile as
|
|
348515
|
+
import { readFile as readFile47 } from "fs/promises";
|
|
348348
348516
|
function isDistroFamily(osRelease, families) {
|
|
348349
348517
|
return families.includes(osRelease.id) || osRelease.idLike.some((like) => families.includes(like));
|
|
348350
348518
|
}
|
|
@@ -348402,7 +348570,7 @@ var init_packageManagers = __esm(() => {
|
|
|
348402
348570
|
init_platform3();
|
|
348403
348571
|
getOsRelease = memoize_default(async () => {
|
|
348404
348572
|
try {
|
|
348405
|
-
const content = await
|
|
348573
|
+
const content = await readFile47("/etc/os-release", "utf8");
|
|
348406
348574
|
const idMatch = content.match(/^ID=["']?(\S+?)["']?\s*$/m);
|
|
348407
348575
|
const idLikeMatch = content.match(/^ID_LIKE=["']?(.+?)["']?\s*$/m);
|
|
348408
348576
|
return {
|
|
@@ -348523,9 +348691,9 @@ var init_packageManagers = __esm(() => {
|
|
|
348523
348691
|
});
|
|
348524
348692
|
|
|
348525
348693
|
// src/tui/utils/doctorDiagnostic.ts
|
|
348526
|
-
import { readFile as
|
|
348694
|
+
import { readFile as readFile48, realpath as realpath12 } from "fs/promises";
|
|
348527
348695
|
import { homedir as homedir33 } from "os";
|
|
348528
|
-
import { delimiter as delimiter2, join as
|
|
348696
|
+
import { delimiter as delimiter2, join as join134, posix as posix8, win32 as win322 } from "path";
|
|
348529
348697
|
function getNormalizedPaths() {
|
|
348530
348698
|
let invokedPath = process.argv[1] || "";
|
|
348531
348699
|
let execPath = process.execPath || process.argv[0] || "";
|
|
@@ -348588,8 +348756,8 @@ async function getInstallationPath() {
|
|
|
348588
348756
|
}
|
|
348589
348757
|
} catch {}
|
|
348590
348758
|
try {
|
|
348591
|
-
await getFsImplementation2().stat(
|
|
348592
|
-
return
|
|
348759
|
+
await getFsImplementation2().stat(join134(homedir33(), ".local/bingetConfigDirName()"));
|
|
348760
|
+
return join134(homedir33(), ".local/bingetConfigDirName()");
|
|
348593
348761
|
} catch {}
|
|
348594
348762
|
return "native";
|
|
348595
348763
|
}
|
|
@@ -348612,7 +348780,7 @@ function getInvokedBinary() {
|
|
|
348612
348780
|
async function detectMultipleInstallations() {
|
|
348613
348781
|
const fs = getFsImplementation2();
|
|
348614
348782
|
const installations = [];
|
|
348615
|
-
const localPath =
|
|
348783
|
+
const localPath = join134(homedir33(), getConfigDirName2(), "local");
|
|
348616
348784
|
if (await localInstallationExists()) {
|
|
348617
348785
|
installations.push({ type: "npm-local", path: localPath });
|
|
348618
348786
|
}
|
|
@@ -348629,7 +348797,7 @@ async function detectMultipleInstallations() {
|
|
|
348629
348797
|
if (npmResult.code === 0 && npmResult.stdout) {
|
|
348630
348798
|
const npmPrefix = npmResult.stdout.trim();
|
|
348631
348799
|
const isWindows = getPlatform3() === "windows";
|
|
348632
|
-
const globalBinPath = isWindows ?
|
|
348800
|
+
const globalBinPath = isWindows ? join134(npmPrefix, "atlas") : join134(npmPrefix, "bin", "atlas");
|
|
348633
348801
|
let globalBinExists = false;
|
|
348634
348802
|
try {
|
|
348635
348803
|
await fs.stat(globalBinPath);
|
|
@@ -348648,7 +348816,7 @@ async function detectMultipleInstallations() {
|
|
|
348648
348816
|
}
|
|
348649
348817
|
} else {
|
|
348650
348818
|
for (const packageName of packagesToCheck) {
|
|
348651
|
-
const globalPackagePath = isWindows ?
|
|
348819
|
+
const globalPackagePath = isWindows ? join134(npmPrefix, "node_modules", packageName) : join134(npmPrefix, "lib", "node_modules", packageName);
|
|
348652
348820
|
try {
|
|
348653
348821
|
await fs.stat(globalPackagePath);
|
|
348654
348822
|
installations.push({
|
|
@@ -348659,14 +348827,14 @@ async function detectMultipleInstallations() {
|
|
|
348659
348827
|
}
|
|
348660
348828
|
}
|
|
348661
348829
|
}
|
|
348662
|
-
const nativeBinPath =
|
|
348830
|
+
const nativeBinPath = join134(homedir33(), ".local", "bin", "atlas");
|
|
348663
348831
|
try {
|
|
348664
348832
|
await fs.stat(nativeBinPath);
|
|
348665
348833
|
installations.push({ type: "native", path: nativeBinPath });
|
|
348666
348834
|
} catch {}
|
|
348667
348835
|
const config = getGlobalConfig();
|
|
348668
348836
|
if (config.installMethod === "native") {
|
|
348669
|
-
const nativeDataPath =
|
|
348837
|
+
const nativeDataPath = join134(homedir33(), ".local", "share", "atlas");
|
|
348670
348838
|
try {
|
|
348671
348839
|
await fs.stat(nativeDataPath);
|
|
348672
348840
|
if (!installations.some((i) => i.type === "native")) {
|
|
@@ -348679,7 +348847,7 @@ async function detectMultipleInstallations() {
|
|
|
348679
348847
|
async function detectConfigurationIssues(type) {
|
|
348680
348848
|
const warnings = [];
|
|
348681
348849
|
try {
|
|
348682
|
-
const raw = await
|
|
348850
|
+
const raw = await readFile48(join134(getManagedFilePath(), "managed-settings.json"), "utf-8");
|
|
348683
348851
|
const parsed = jsonParse2(raw);
|
|
348684
348852
|
const field = parsed && typeof parsed === "object" ? parsed.strictPluginOnlyCustomization : undefined;
|
|
348685
348853
|
if (field !== undefined && typeof field !== "boolean") {
|
|
@@ -348707,7 +348875,7 @@ async function detectConfigurationIssues(type) {
|
|
|
348707
348875
|
const path = process.env.PATH || "";
|
|
348708
348876
|
const pathDirectories = path.split(delimiter2);
|
|
348709
348877
|
const homeDir = homedir33();
|
|
348710
|
-
const localBinPath =
|
|
348878
|
+
const localBinPath = join134(homeDir, ".local", "bin");
|
|
348711
348879
|
let normalizedLocalBinPath = localBinPath;
|
|
348712
348880
|
if (getPlatform3() === "windows") {
|
|
348713
348881
|
normalizedLocalBinPath = localBinPath.split(win322.sep).join(posix8.sep);
|
|
@@ -348894,7 +349062,7 @@ var init_doctorDiagnostic = __esm(() => {
|
|
|
348894
349062
|
|
|
348895
349063
|
// src/tui/utils/xdg.ts
|
|
348896
349064
|
import { homedir as osHomedir2 } from "os";
|
|
348897
|
-
import { join as
|
|
349065
|
+
import { join as join135 } from "path";
|
|
348898
349066
|
function resolveOptions2(options) {
|
|
348899
349067
|
return {
|
|
348900
349068
|
env: options?.env ?? process.env,
|
|
@@ -348903,193 +349071,42 @@ function resolveOptions2(options) {
|
|
|
348903
349071
|
}
|
|
348904
349072
|
function getXDGStateHome(options) {
|
|
348905
349073
|
const { env, home } = resolveOptions2(options);
|
|
348906
|
-
return env.XDG_STATE_HOME ??
|
|
349074
|
+
return env.XDG_STATE_HOME ?? join135(home, ".local", "state");
|
|
348907
349075
|
}
|
|
348908
349076
|
function getXDGCacheHome(options) {
|
|
348909
349077
|
const { env, home } = resolveOptions2(options);
|
|
348910
|
-
return env.XDG_CACHE_HOME ??
|
|
349078
|
+
return env.XDG_CACHE_HOME ?? join135(home, ".cache");
|
|
348911
349079
|
}
|
|
348912
349080
|
function getXDGDataHome(options) {
|
|
348913
349081
|
const { env, home } = resolveOptions2(options);
|
|
348914
|
-
return env.XDG_DATA_HOME ??
|
|
349082
|
+
return env.XDG_DATA_HOME ?? join135(home, ".local", "share");
|
|
348915
349083
|
}
|
|
348916
349084
|
function getUserBinDir(options) {
|
|
348917
349085
|
const { home } = resolveOptions2(options);
|
|
348918
|
-
return
|
|
349086
|
+
return join135(home, ".local", "bin");
|
|
348919
349087
|
}
|
|
348920
349088
|
var init_xdg = () => {};
|
|
348921
349089
|
|
|
348922
349090
|
// src/tui/utils/nativeInstaller/download.ts
|
|
348923
|
-
import { createHash as createHash11 } from "crypto";
|
|
348924
|
-
import { chmod as chmod7, writeFile as writeFile35 } from "fs/promises";
|
|
348925
|
-
import { join as join135 } from "path";
|
|
348926
|
-
async function getLatestVersionFromBinaryRepo(channel = "latest", baseUrl, authConfig) {
|
|
348927
|
-
const startTime = Date.now();
|
|
348928
|
-
try {
|
|
348929
|
-
const response = await axios_default.get(`${baseUrl}/${channel}`, {
|
|
348930
|
-
timeout: 30000,
|
|
348931
|
-
responseType: "text",
|
|
348932
|
-
...authConfig
|
|
348933
|
-
});
|
|
348934
|
-
const latencyMs = Date.now() - startTime;
|
|
348935
|
-
return response.data.trim();
|
|
348936
|
-
} catch (error) {
|
|
348937
|
-
const latencyMs = Date.now() - startTime;
|
|
348938
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
348939
|
-
let httpStatus;
|
|
348940
|
-
if (axios_default.isAxiosError(error) && error.response) {
|
|
348941
|
-
httpStatus = error.response.status;
|
|
348942
|
-
}
|
|
348943
|
-
const fetchError = new Error(`Failed to fetch version from ${baseUrl}/${channel}: ${errorMessage}`);
|
|
348944
|
-
logError3(fetchError);
|
|
348945
|
-
throw fetchError;
|
|
348946
|
-
}
|
|
348947
|
-
}
|
|
348948
349091
|
async function getLatestVersion2(channelOrVersion) {
|
|
348949
349092
|
if (/^v?\d+\.\d+\.\d+(-\S+)?$/.test(channelOrVersion)) {
|
|
348950
349093
|
const normalized = channelOrVersion.startsWith("v") ? channelOrVersion.slice(1) : channelOrVersion;
|
|
348951
349094
|
if (/^99\.99\./.test(normalized) && !feature("ALLOW_TEST_VERSIONS")) {
|
|
348952
349095
|
throw new Error(`Version ${normalized} is not available for installation. Use 'stable' or 'latest'.`);
|
|
348953
349096
|
}
|
|
348954
|
-
|
|
349097
|
+
throw new Error(`Version ${normalized} cannot be installed: this product has no native distribution form (npm package / git source only)`);
|
|
348955
349098
|
}
|
|
348956
349099
|
const channel = channelOrVersion;
|
|
348957
349100
|
if (channel !== "stable" && channel !== "latest") {
|
|
348958
349101
|
throw new Error(`Invalid channel: ${channelOrVersion}. Use 'stable' or 'latest'`);
|
|
348959
349102
|
}
|
|
348960
|
-
|
|
349103
|
+
throw new Error(`Channel '${channel}' cannot be resolved: this product has no native distribution form (npm package / git source only)`);
|
|
348961
349104
|
}
|
|
348962
|
-
function
|
|
348963
|
-
|
|
348964
|
-
}
|
|
348965
|
-
async function downloadAndVerifyBinary(binaryUrl, expectedChecksum, binaryPath, requestConfig = {}) {
|
|
348966
|
-
let lastError;
|
|
348967
|
-
for (let attempt = 1;attempt <= MAX_DOWNLOAD_RETRIES; attempt++) {
|
|
348968
|
-
const controller = new AbortController;
|
|
348969
|
-
let stallTimer;
|
|
348970
|
-
const clearStallTimer = () => {
|
|
348971
|
-
if (stallTimer) {
|
|
348972
|
-
clearTimeout(stallTimer);
|
|
348973
|
-
stallTimer = undefined;
|
|
348974
|
-
}
|
|
348975
|
-
};
|
|
348976
|
-
const resetStallTimer = () => {
|
|
348977
|
-
clearStallTimer();
|
|
348978
|
-
stallTimer = setTimeout((c) => c.abort(), getStallTimeoutMs(), controller);
|
|
348979
|
-
};
|
|
348980
|
-
try {
|
|
348981
|
-
resetStallTimer();
|
|
348982
|
-
const response = await axios_default.get(binaryUrl, {
|
|
348983
|
-
timeout: 5 * 60000,
|
|
348984
|
-
responseType: "arraybuffer",
|
|
348985
|
-
signal: controller.signal,
|
|
348986
|
-
onDownloadProgress: () => {
|
|
348987
|
-
resetStallTimer();
|
|
348988
|
-
},
|
|
348989
|
-
...requestConfig
|
|
348990
|
-
});
|
|
348991
|
-
clearStallTimer();
|
|
348992
|
-
const hash = createHash11("sha256");
|
|
348993
|
-
hash.update(response.data);
|
|
348994
|
-
const actualChecksum = hash.digest("hex");
|
|
348995
|
-
if (actualChecksum !== expectedChecksum) {
|
|
348996
|
-
throw new Error(`Checksum mismatch: expected ${expectedChecksum}, got ${actualChecksum}`);
|
|
348997
|
-
}
|
|
348998
|
-
await writeFile35(binaryPath, Buffer.from(response.data));
|
|
348999
|
-
await chmod7(binaryPath, 493);
|
|
349000
|
-
return;
|
|
349001
|
-
} catch (error) {
|
|
349002
|
-
clearStallTimer();
|
|
349003
|
-
const isStallTimeout = axios_default.isCancel(error);
|
|
349004
|
-
if (isStallTimeout) {
|
|
349005
|
-
lastError = new StallTimeoutError;
|
|
349006
|
-
} else {
|
|
349007
|
-
lastError = toError2(error);
|
|
349008
|
-
}
|
|
349009
|
-
if (isStallTimeout && attempt < MAX_DOWNLOAD_RETRIES) {
|
|
349010
|
-
logForDebugging3(`Download stalled on attempt ${attempt}/${MAX_DOWNLOAD_RETRIES}, retrying...`);
|
|
349011
|
-
await sleep9(1000);
|
|
349012
|
-
continue;
|
|
349013
|
-
}
|
|
349014
|
-
throw lastError;
|
|
349015
|
-
}
|
|
349016
|
-
}
|
|
349017
|
-
throw lastError ?? new Error("Download failed after all retries");
|
|
349105
|
+
async function downloadVersion(_version, _stagingPath) {
|
|
349106
|
+
throw new Error("Native binary download is not available in this product (no native distribution form; npm package / git source only)");
|
|
349018
349107
|
}
|
|
349019
|
-
async function downloadVersionFromBinaryRepo(version, stagingPath, baseUrl, authConfig) {
|
|
349020
|
-
const fs = getFsImplementation2();
|
|
349021
|
-
await fs.rm(stagingPath, { recursive: true, force: true });
|
|
349022
|
-
const platform = getPlatform4();
|
|
349023
|
-
const startTime = Date.now();
|
|
349024
|
-
let manifest;
|
|
349025
|
-
try {
|
|
349026
|
-
const manifestResponse = await axios_default.get(`${baseUrl}/${version}/manifest.json`, {
|
|
349027
|
-
timeout: 1e4,
|
|
349028
|
-
responseType: "json",
|
|
349029
|
-
...authConfig
|
|
349030
|
-
});
|
|
349031
|
-
manifest = manifestResponse.data;
|
|
349032
|
-
} catch (error) {
|
|
349033
|
-
const latencyMs = Date.now() - startTime;
|
|
349034
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
349035
|
-
let httpStatus;
|
|
349036
|
-
if (axios_default.isAxiosError(error) && error.response) {
|
|
349037
|
-
httpStatus = error.response.status;
|
|
349038
|
-
}
|
|
349039
|
-
logError3(new Error(`Failed to fetch manifest from ${baseUrl}/${version}/manifest.json: ${errorMessage}`));
|
|
349040
|
-
throw error;
|
|
349041
|
-
}
|
|
349042
|
-
const platformInfo = manifest.platforms[platform];
|
|
349043
|
-
if (!platformInfo) {
|
|
349044
|
-
throw new Error(`Platform ${platform} not found in manifest for version ${version}`);
|
|
349045
|
-
}
|
|
349046
|
-
const expectedChecksum = platformInfo.checksum;
|
|
349047
|
-
const binaryName = getBinaryName(platform);
|
|
349048
|
-
const binaryUrl = `${baseUrl}/${version}/${platform}/${binaryName}`;
|
|
349049
|
-
await fs.mkdir(stagingPath);
|
|
349050
|
-
const binaryPath = join135(stagingPath, binaryName);
|
|
349051
|
-
try {
|
|
349052
|
-
await downloadAndVerifyBinary(binaryUrl, expectedChecksum, binaryPath, authConfig || {});
|
|
349053
|
-
const latencyMs = Date.now() - startTime;
|
|
349054
|
-
} catch (error) {
|
|
349055
|
-
const latencyMs = Date.now() - startTime;
|
|
349056
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
349057
|
-
let httpStatus;
|
|
349058
|
-
if (axios_default.isAxiosError(error) && error.response) {
|
|
349059
|
-
httpStatus = error.response.status;
|
|
349060
|
-
}
|
|
349061
|
-
logError3(new Error(`Failed to download binary from ${binaryUrl}: ${errorMessage}`));
|
|
349062
|
-
throw error;
|
|
349063
|
-
}
|
|
349064
|
-
}
|
|
349065
|
-
async function downloadVersion(version, stagingPath) {
|
|
349066
|
-
if (feature("ALLOW_TEST_VERSIONS") && /^99\.99\./.test(version)) {
|
|
349067
|
-
const { stdout } = await execFileNoThrowWithCwd2("gcloud", [
|
|
349068
|
-
"auth",
|
|
349069
|
-
"print-access-token"
|
|
349070
|
-
]);
|
|
349071
|
-
await downloadVersionFromBinaryRepo(version, stagingPath, "https://storage.googleapis.com/claude-code-ci-sentinel", { headers: { Authorization: `Bearer ${stdout.trim()}` } });
|
|
349072
|
-
return "binary";
|
|
349073
|
-
}
|
|
349074
|
-
await downloadVersionFromBinaryRepo(version, stagingPath, GCS_BUCKET_URL);
|
|
349075
|
-
return "binary";
|
|
349076
|
-
}
|
|
349077
|
-
var GCS_BUCKET_URL = "https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases", DEFAULT_STALL_TIMEOUT_MS = 60000, MAX_DOWNLOAD_RETRIES = 3, StallTimeoutError;
|
|
349078
349108
|
var init_download = __esm(() => {
|
|
349079
349109
|
init_shared();
|
|
349080
|
-
init_axios2();
|
|
349081
|
-
init_debug();
|
|
349082
|
-
init_errors4();
|
|
349083
|
-
init_execFileNoThrow2();
|
|
349084
|
-
init_fsOperations();
|
|
349085
|
-
init_log5();
|
|
349086
|
-
init_installer();
|
|
349087
|
-
StallTimeoutError = class StallTimeoutError extends Error {
|
|
349088
|
-
constructor() {
|
|
349089
|
-
super("Download stalled: no data received for 60 seconds");
|
|
349090
|
-
this.name = "StallTimeoutError";
|
|
349091
|
-
}
|
|
349092
|
-
};
|
|
349093
349110
|
});
|
|
349094
349111
|
|
|
349095
349112
|
// src/tui/utils/nativeInstaller/pidLock.ts
|
|
@@ -349327,19 +349344,19 @@ var init_pidLock = __esm(() => {
|
|
|
349327
349344
|
import { constants as fsConstants7 } from "fs";
|
|
349328
349345
|
import {
|
|
349329
349346
|
access as access5,
|
|
349330
|
-
chmod as
|
|
349347
|
+
chmod as chmod7,
|
|
349331
349348
|
copyFile as copyFile8,
|
|
349332
349349
|
lstat as lstat6,
|
|
349333
349350
|
mkdir as mkdir40,
|
|
349334
349351
|
readdir as readdir26,
|
|
349335
349352
|
readlink as readlink2,
|
|
349336
349353
|
realpath as realpath13,
|
|
349337
|
-
rename as
|
|
349354
|
+
rename as rename8,
|
|
349338
349355
|
rm as rm10,
|
|
349339
349356
|
rmdir as rmdir2,
|
|
349340
349357
|
stat as stat45,
|
|
349341
349358
|
symlink as symlink6,
|
|
349342
|
-
unlink as
|
|
349359
|
+
unlink as unlink18,
|
|
349343
349360
|
writeFile as writeFile36
|
|
349344
349361
|
} from "fs/promises";
|
|
349345
349362
|
import { homedir as homedir34 } from "os";
|
|
@@ -349466,12 +349483,12 @@ async function atomicMoveToInstallPath(stagedBinaryPath, installPath) {
|
|
|
349466
349483
|
const tempInstallPath = `${installPath}.tmp.${process.pid}.${Date.now()}`;
|
|
349467
349484
|
try {
|
|
349468
349485
|
await copyFile8(stagedBinaryPath, tempInstallPath);
|
|
349469
|
-
await
|
|
349470
|
-
await
|
|
349486
|
+
await chmod7(tempInstallPath, 493);
|
|
349487
|
+
await rename8(tempInstallPath, installPath);
|
|
349471
349488
|
logForDebugging3(`Atomically installed binary to ${installPath}`);
|
|
349472
349489
|
} catch (error) {
|
|
349473
349490
|
try {
|
|
349474
|
-
await
|
|
349491
|
+
await unlink18(tempInstallPath);
|
|
349475
349492
|
} catch {}
|
|
349476
349493
|
throw error;
|
|
349477
349494
|
}
|
|
@@ -349642,15 +349659,15 @@ async function updateSymlink(symlinkPath, targetPath) {
|
|
|
349642
349659
|
}
|
|
349643
349660
|
} catch {}
|
|
349644
349661
|
const oldFileName = `${symlinkPath}.old.${Date.now()}`;
|
|
349645
|
-
await
|
|
349662
|
+
await rename8(symlinkPath, oldFileName);
|
|
349646
349663
|
try {
|
|
349647
349664
|
await copyFile8(targetPath, symlinkPath);
|
|
349648
349665
|
try {
|
|
349649
|
-
await
|
|
349666
|
+
await unlink18(oldFileName);
|
|
349650
349667
|
} catch {}
|
|
349651
349668
|
} catch (copyError) {
|
|
349652
349669
|
try {
|
|
349653
|
-
await
|
|
349670
|
+
await rename8(oldFileName, symlinkPath);
|
|
349654
349671
|
} catch (restoreError) {
|
|
349655
349672
|
const errorWithCause = new Error(`Failed to restore old executable: ${restoreError}`, { cause: copyError });
|
|
349656
349673
|
logError3(errorWithCause);
|
|
@@ -349697,7 +349714,7 @@ async function updateSymlink(symlinkPath, targetPath) {
|
|
|
349697
349714
|
return false;
|
|
349698
349715
|
}
|
|
349699
349716
|
} catch {}
|
|
349700
|
-
await
|
|
349717
|
+
await unlink18(symlinkPath);
|
|
349701
349718
|
}
|
|
349702
349719
|
} catch (error) {
|
|
349703
349720
|
logError3(new Error(`Failed to check/remove existing symlink: ${error}`));
|
|
@@ -349705,12 +349722,12 @@ async function updateSymlink(symlinkPath, targetPath) {
|
|
|
349705
349722
|
const tempSymlink = `${symlinkPath}.tmp.${process.pid}.${Date.now()}`;
|
|
349706
349723
|
try {
|
|
349707
349724
|
await symlink6(targetPath, tempSymlink);
|
|
349708
|
-
await
|
|
349725
|
+
await rename8(tempSymlink, symlinkPath);
|
|
349709
349726
|
logForDebugging3(`Atomically updated symlink ${symlinkPath} -> ${targetPath}`);
|
|
349710
349727
|
return true;
|
|
349711
349728
|
} catch (error) {
|
|
349712
349729
|
try {
|
|
349713
|
-
await
|
|
349730
|
+
await unlink18(tempSymlink);
|
|
349714
349731
|
} catch {}
|
|
349715
349732
|
logError3(new Error(`Failed to create symlink from ${symlinkPath} to ${targetPath}: ${error}`));
|
|
349716
349733
|
return false;
|
|
@@ -349930,7 +349947,7 @@ async function forceRemoveLock(versionFilePath) {
|
|
|
349930
349947
|
const dirs = getBaseDirectories();
|
|
349931
349948
|
const lockfilePath = getLockFilePathFromVersionPath(dirs, versionFilePath);
|
|
349932
349949
|
try {
|
|
349933
|
-
await
|
|
349950
|
+
await unlink18(lockfilePath);
|
|
349934
349951
|
logForDebugging3(`Force-removed lock file at ${lockfilePath}`);
|
|
349935
349952
|
} catch (error) {
|
|
349936
349953
|
logForDebugging3(`Failed to force-remove lock file: ${errorMessage2(error)}`);
|
|
@@ -349949,7 +349966,7 @@ async function cleanupOldVersions() {
|
|
|
349949
349966
|
if (!/atlas\.exe\.old\.\d+$/.test(file))
|
|
349950
349967
|
continue;
|
|
349951
349968
|
try {
|
|
349952
|
-
await
|
|
349969
|
+
await unlink18(join137(executableDir, file));
|
|
349953
349970
|
cleanedCount++;
|
|
349954
349971
|
} catch {}
|
|
349955
349972
|
}
|
|
@@ -350007,7 +350024,7 @@ async function cleanupOldVersions() {
|
|
|
350007
350024
|
try {
|
|
350008
350025
|
const stats = await stat45(entryPath);
|
|
350009
350026
|
if (stats.mtime.getTime() < oneHourAgo) {
|
|
350010
|
-
await
|
|
350027
|
+
await unlink18(entryPath);
|
|
350011
350028
|
tempFilesCleanedCount++;
|
|
350012
350029
|
logForDebugging3(`Cleaned up orphaned temp install file: ${entry}`);
|
|
350013
350030
|
}
|
|
@@ -350078,7 +350095,7 @@ async function cleanupOldVersions() {
|
|
|
350078
350095
|
await Promise.all(versionsToDelete.map(async (version) => {
|
|
350079
350096
|
try {
|
|
350080
350097
|
const deleted = await tryWithVersionLock(version.path, async () => {
|
|
350081
|
-
await
|
|
350098
|
+
await unlink18(version.path);
|
|
350082
350099
|
});
|
|
350083
350100
|
if (deleted) {
|
|
350084
350101
|
deletedCount++;
|
|
@@ -350112,7 +350129,7 @@ async function removeInstalledSymlink() {
|
|
|
350112
350129
|
logForDebugging3(`Skipping removal of ${dirs.executable} - appears to be npm-managed`);
|
|
350113
350130
|
return;
|
|
350114
350131
|
}
|
|
350115
|
-
await
|
|
350132
|
+
await unlink18(dirs.executable);
|
|
350116
350133
|
logForDebugging3(`Removed atlas symlink at ${dirs.executable}`);
|
|
350117
350134
|
} catch (error) {
|
|
350118
350135
|
if (isENOENT2(error)) {
|
|
@@ -350167,7 +350184,7 @@ async function manualRemoveNpmPackage(packageName) {
|
|
|
350167
350184
|
let manuallyRemoved = false;
|
|
350168
350185
|
async function tryRemove(filePath, description) {
|
|
350169
350186
|
try {
|
|
350170
|
-
await
|
|
350187
|
+
await unlink18(filePath);
|
|
350171
350188
|
logForDebugging3(`Manually removed ${description}: ${filePath}`);
|
|
350172
350189
|
return true;
|
|
350173
350190
|
} catch {
|
|
@@ -353493,54 +353510,6 @@ function Config({
|
|
|
353493
353510
|
onChange() {}
|
|
353494
353511
|
}];
|
|
353495
353512
|
})() : [],
|
|
353496
|
-
...feature("BRIDGE_MODE") && isBridgeEnabled() ? [{
|
|
353497
|
-
id: "remoteControlAtStartup",
|
|
353498
|
-
label: "Enable Remote Control for all sessions",
|
|
353499
|
-
value: globalConfig.remoteControlAtStartup === undefined ? "default" : String(globalConfig.remoteControlAtStartup),
|
|
353500
|
-
options: ["true", "false", "default"],
|
|
353501
|
-
type: "enum",
|
|
353502
|
-
onChange(selected_0) {
|
|
353503
|
-
if (selected_0 === "default") {
|
|
353504
|
-
saveGlobalConfig((current_20) => {
|
|
353505
|
-
if (current_20.remoteControlAtStartup === undefined)
|
|
353506
|
-
return current_20;
|
|
353507
|
-
const next_0 = {
|
|
353508
|
-
...current_20
|
|
353509
|
-
};
|
|
353510
|
-
delete next_0.remoteControlAtStartup;
|
|
353511
|
-
return next_0;
|
|
353512
|
-
});
|
|
353513
|
-
setGlobalConfig({
|
|
353514
|
-
...getGlobalConfig(),
|
|
353515
|
-
remoteControlAtStartup: undefined
|
|
353516
|
-
});
|
|
353517
|
-
} else {
|
|
353518
|
-
const enabled_6 = selected_0 === "true";
|
|
353519
|
-
saveGlobalConfig((current_21) => {
|
|
353520
|
-
if (current_21.remoteControlAtStartup === enabled_6)
|
|
353521
|
-
return current_21;
|
|
353522
|
-
return {
|
|
353523
|
-
...current_21,
|
|
353524
|
-
remoteControlAtStartup: enabled_6
|
|
353525
|
-
};
|
|
353526
|
-
});
|
|
353527
|
-
setGlobalConfig({
|
|
353528
|
-
...getGlobalConfig(),
|
|
353529
|
-
remoteControlAtStartup: enabled_6
|
|
353530
|
-
});
|
|
353531
|
-
}
|
|
353532
|
-
const resolved = getRemoteControlAtStartup();
|
|
353533
|
-
setAppState((prev_20) => {
|
|
353534
|
-
if (prev_20.replBridgeEnabled === resolved && !prev_20.replBridgeOutboundOnly)
|
|
353535
|
-
return prev_20;
|
|
353536
|
-
return {
|
|
353537
|
-
...prev_20,
|
|
353538
|
-
replBridgeEnabled: resolved,
|
|
353539
|
-
replBridgeOutboundOnly: false
|
|
353540
|
-
};
|
|
353541
|
-
});
|
|
353542
|
-
}
|
|
353543
|
-
}] : [],
|
|
353544
353513
|
...shouldShowExternalIncludesToggle ? [{
|
|
353545
353514
|
id: "showExternalIncludesDialog",
|
|
353546
353515
|
label: "External ATLAS.md includes",
|
|
@@ -353708,10 +353677,6 @@ function Config({
|
|
|
353708
353677
|
if (globalConfig.showTurnDuration !== initialConfig.current.showTurnDuration) {
|
|
353709
353678
|
formattedChanges.push(`${globalConfig.showTurnDuration ? "Enabled" : "Disabled"} turn duration`);
|
|
353710
353679
|
}
|
|
353711
|
-
if (globalConfig.remoteControlAtStartup !== initialConfig.current.remoteControlAtStartup) {
|
|
353712
|
-
const remoteLabel = globalConfig.remoteControlAtStartup === undefined ? "Reset Remote Control to default" : `${globalConfig.remoteControlAtStartup ? "Enabled" : "Disabled"} Remote Control for all sessions`;
|
|
353713
|
-
formattedChanges.push(remoteLabel);
|
|
353714
|
-
}
|
|
353715
353680
|
if (settingsData?.autoUpdatesChannel !== initialSettingsData.current?.autoUpdatesChannel) {
|
|
353716
353681
|
formattedChanges.push(`Set auto-update channel to ${source_default.bold(settingsData?.autoUpdatesChannel ?? "latest")}`);
|
|
353717
353682
|
}
|
|
@@ -354520,7 +354485,7 @@ function NotifChannelLabel(t0) {
|
|
|
354520
354485
|
}
|
|
354521
354486
|
}
|
|
354522
354487
|
}
|
|
354523
|
-
var import_compiler_runtime124, React45, import_react90, jsx_dev_runtime151,
|
|
354488
|
+
var import_compiler_runtime124, React45, import_react90, jsx_dev_runtime151, THEME_LABELS;
|
|
354524
354489
|
var init_Config = __esm(() => {
|
|
354525
354490
|
init_shared();
|
|
354526
354491
|
init_ink2();
|
|
@@ -360661,11 +360626,11 @@ var init_editor = __esm(() => {
|
|
|
360661
360626
|
});
|
|
360662
360627
|
|
|
360663
360628
|
// src/tui/utils/tempfile.ts
|
|
360664
|
-
import { createHash as
|
|
360629
|
+
import { createHash as createHash11, randomUUID as randomUUID38 } from "crypto";
|
|
360665
360630
|
import { tmpdir as tmpdir9 } from "os";
|
|
360666
360631
|
import { join as join139 } from "path";
|
|
360667
360632
|
function generateTempFilePath2(prefix = "atlas-prompt", extension = ".md", options) {
|
|
360668
|
-
const id = options?.contentHash ?
|
|
360633
|
+
const id = options?.contentHash ? createHash11("sha256").update(options.contentHash).digest("hex").slice(0, 16) : randomUUID38();
|
|
360669
360634
|
return join139(tmpdir9(), `${prefix}-${id}${extension}`);
|
|
360670
360635
|
}
|
|
360671
360636
|
var init_tempfile = () => {};
|
|
@@ -370024,7 +369989,7 @@ var init_mcp7 = __esm(() => {
|
|
|
370024
369989
|
});
|
|
370025
369990
|
|
|
370026
369991
|
// src/tui/utils/releaseNotes.ts
|
|
370027
|
-
import { mkdir as mkdir44, readFile as
|
|
369992
|
+
import { mkdir as mkdir44, readFile as readFile49, writeFile as writeFile39 } from "fs/promises";
|
|
370028
369993
|
import { dirname as dirname71, join as join140 } from "path";
|
|
370029
369994
|
function getChangelogCachePath() {
|
|
370030
369995
|
return join140(getAtlasConfigHomeDir3(), "cache", "changelog.md");
|
|
@@ -370074,7 +370039,7 @@ async function getStoredChangelog() {
|
|
|
370074
370039
|
}
|
|
370075
370040
|
const cachePath = getChangelogCachePath();
|
|
370076
370041
|
try {
|
|
370077
|
-
const content = await
|
|
370042
|
+
const content = await readFile49(cachePath, "utf-8");
|
|
370078
370043
|
changelogMemoryCache = content;
|
|
370079
370044
|
return content;
|
|
370080
370045
|
} catch {
|
|
@@ -370423,9 +370388,9 @@ var init_rename = __esm(() => {
|
|
|
370423
370388
|
});
|
|
370424
370389
|
|
|
370425
370390
|
// src/tui/commands/rename/index.ts
|
|
370426
|
-
var
|
|
370391
|
+
var rename9, rename_default;
|
|
370427
370392
|
var init_rename2 = __esm(() => {
|
|
370428
|
-
|
|
370393
|
+
rename9 = {
|
|
370429
370394
|
type: "local-jsx",
|
|
370430
370395
|
name: "rename",
|
|
370431
370396
|
description: "Rename the current conversation",
|
|
@@ -370433,7 +370398,7 @@ var init_rename2 = __esm(() => {
|
|
|
370433
370398
|
argumentHint: "[name]",
|
|
370434
370399
|
load: () => Promise.resolve().then(() => (init_rename(), exports_rename))
|
|
370435
370400
|
};
|
|
370436
|
-
rename_default =
|
|
370401
|
+
rename_default = rename9;
|
|
370437
370402
|
});
|
|
370438
370403
|
|
|
370439
370404
|
// src/tui/utils/getWorktreePaths.ts
|
|
@@ -388030,7 +387995,7 @@ __export(exports_thinkback, {
|
|
|
388030
387995
|
call: () => call34,
|
|
388031
387996
|
playAnimation: () => playAnimation
|
|
388032
387997
|
});
|
|
388033
|
-
import { readFile as
|
|
387998
|
+
import { readFile as readFile50 } from "fs/promises";
|
|
388034
387999
|
import { join as join143 } from "path";
|
|
388035
388000
|
function getMarketplaceName() {
|
|
388036
388001
|
return OFFICIAL_MARKETPLACE_NAME;
|
|
@@ -388059,7 +388024,7 @@ async function playAnimation(skillDir) {
|
|
|
388059
388024
|
const dataPath = join143(skillDir, "year_in_review.js");
|
|
388060
388025
|
const playerPath = join143(skillDir, "player.js");
|
|
388061
388026
|
try {
|
|
388062
|
-
await
|
|
388027
|
+
await readFile50(dataPath);
|
|
388063
388028
|
} catch (e) {
|
|
388064
388029
|
if (isENOENT2(e)) {
|
|
388065
388030
|
return {
|
|
@@ -388074,7 +388039,7 @@ async function playAnimation(skillDir) {
|
|
|
388074
388039
|
};
|
|
388075
388040
|
}
|
|
388076
388041
|
try {
|
|
388077
|
-
await
|
|
388042
|
+
await readFile50(playerPath);
|
|
388078
388043
|
} catch (e) {
|
|
388079
388044
|
if (isENOENT2(e)) {
|
|
388080
388045
|
return {
|
|
@@ -393153,7 +393118,7 @@ __export(exports_branch, {
|
|
|
393153
393118
|
getUniqueForkName: () => getUniqueForkName
|
|
393154
393119
|
});
|
|
393155
393120
|
import { randomUUID as randomUUID39 } from "crypto";
|
|
393156
|
-
import { mkdir as mkdir45, readFile as
|
|
393121
|
+
import { mkdir as mkdir45, readFile as readFile51, writeFile as writeFile40 } from "fs/promises";
|
|
393157
393122
|
function deriveFirstPrompt(firstUserMessage) {
|
|
393158
393123
|
const content = firstUserMessage?.message?.content;
|
|
393159
393124
|
if (!content)
|
|
@@ -393172,7 +393137,7 @@ async function createFork(customTitle, target) {
|
|
|
393172
393137
|
await mkdir45(projectDir, { recursive: true, mode: 448 });
|
|
393173
393138
|
let transcriptContent;
|
|
393174
393139
|
try {
|
|
393175
|
-
transcriptContent = await
|
|
393140
|
+
transcriptContent = await readFile51(currentTranscriptPath);
|
|
393176
393141
|
} catch {
|
|
393177
393142
|
throw new Error("No conversation to branch");
|
|
393178
393143
|
}
|
|
@@ -393494,7 +393459,7 @@ var init_types16 = __esm(() => {
|
|
|
393494
393459
|
});
|
|
393495
393460
|
|
|
393496
393461
|
// src/tui/components/agents/agentFileUtils.ts
|
|
393497
|
-
import { mkdir as mkdir46, open as open15, unlink as
|
|
393462
|
+
import { mkdir as mkdir46, open as open15, unlink as unlink19 } from "fs/promises";
|
|
393498
393463
|
import { join as join145 } from "path";
|
|
393499
393464
|
function formatAgentAsMarkdown(agentType, whenToUse, tools, systemPrompt, color, model, memory, effort) {
|
|
393500
393465
|
const escapedWhenToUse = whenToUse.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\\\n");
|
|
@@ -393610,7 +393575,7 @@ async function deleteAgentFromFile(agent) {
|
|
|
393610
393575
|
}
|
|
393611
393576
|
const filePath = getActualAgentFilePath(agent);
|
|
393612
393577
|
try {
|
|
393613
|
-
await
|
|
393578
|
+
await unlink19(filePath);
|
|
393614
393579
|
} catch (e) {
|
|
393615
393580
|
const code = getErrnoCode2(e);
|
|
393616
393581
|
if (code !== "ENOENT") {
|
|
@@ -399838,152 +399803,6 @@ var init_MarketplaceAdopt = __esm(() => {
|
|
|
399838
399803
|
jsx_dev_runtime281 = __toESM(require_jsx_dev_runtime(), 1);
|
|
399839
399804
|
});
|
|
399840
399805
|
|
|
399841
|
-
// src/tui/utils/plugins/installCounts.ts
|
|
399842
|
-
import { randomBytes as randomBytes18 } from "crypto";
|
|
399843
|
-
import { readFile as readFile51, rename as rename9, unlink as unlink19, writeFile as writeFile41 } from "fs/promises";
|
|
399844
|
-
import { join as join146 } from "path";
|
|
399845
|
-
function getInstallCountsCachePath() {
|
|
399846
|
-
return join146(getPluginsDirectory(), INSTALL_COUNTS_CACHE_FILENAME);
|
|
399847
|
-
}
|
|
399848
|
-
async function loadInstallCountsCache() {
|
|
399849
|
-
const cachePath = getInstallCountsCachePath();
|
|
399850
|
-
try {
|
|
399851
|
-
const content = await readFile51(cachePath, { encoding: "utf-8" });
|
|
399852
|
-
const parsed = jsonParse2(content);
|
|
399853
|
-
if (typeof parsed !== "object" || parsed === null || !("version" in parsed) || !("fetchedAt" in parsed) || !("counts" in parsed)) {
|
|
399854
|
-
logForDebugging3("Install counts cache has invalid structure");
|
|
399855
|
-
return null;
|
|
399856
|
-
}
|
|
399857
|
-
const cache = parsed;
|
|
399858
|
-
if (cache.version !== INSTALL_COUNTS_CACHE_VERSION) {
|
|
399859
|
-
logForDebugging3(`Install counts cache version mismatch (got ${cache.version}, expected ${INSTALL_COUNTS_CACHE_VERSION})`);
|
|
399860
|
-
return null;
|
|
399861
|
-
}
|
|
399862
|
-
if (typeof cache.fetchedAt !== "string" || !Array.isArray(cache.counts)) {
|
|
399863
|
-
logForDebugging3("Install counts cache has invalid structure");
|
|
399864
|
-
return null;
|
|
399865
|
-
}
|
|
399866
|
-
const fetchedAt = new Date(cache.fetchedAt).getTime();
|
|
399867
|
-
if (Number.isNaN(fetchedAt)) {
|
|
399868
|
-
logForDebugging3("Install counts cache has invalid fetchedAt timestamp");
|
|
399869
|
-
return null;
|
|
399870
|
-
}
|
|
399871
|
-
const validCounts = cache.counts.every((entry) => typeof entry === "object" && entry !== null && typeof entry.plugin === "string" && typeof entry.unique_installs === "number");
|
|
399872
|
-
if (!validCounts) {
|
|
399873
|
-
logForDebugging3("Install counts cache has malformed entries");
|
|
399874
|
-
return null;
|
|
399875
|
-
}
|
|
399876
|
-
const now = Date.now();
|
|
399877
|
-
if (now - fetchedAt > CACHE_TTL_MS3) {
|
|
399878
|
-
logForDebugging3("Install counts cache is stale (>24h old)");
|
|
399879
|
-
return null;
|
|
399880
|
-
}
|
|
399881
|
-
return {
|
|
399882
|
-
version: cache.version,
|
|
399883
|
-
fetchedAt: cache.fetchedAt,
|
|
399884
|
-
counts: cache.counts
|
|
399885
|
-
};
|
|
399886
|
-
} catch (error) {
|
|
399887
|
-
const code = getErrnoCode2(error);
|
|
399888
|
-
if (code !== "ENOENT") {
|
|
399889
|
-
logForDebugging3(`Failed to load install counts cache: ${errorMessage2(error)}`);
|
|
399890
|
-
}
|
|
399891
|
-
return null;
|
|
399892
|
-
}
|
|
399893
|
-
}
|
|
399894
|
-
async function saveInstallCountsCache(cache) {
|
|
399895
|
-
const cachePath = getInstallCountsCachePath();
|
|
399896
|
-
const tempPath = `${cachePath}.${randomBytes18(8).toString("hex")}.tmp`;
|
|
399897
|
-
try {
|
|
399898
|
-
const pluginsDir = getPluginsDirectory();
|
|
399899
|
-
await getFsImplementation2().mkdir(pluginsDir);
|
|
399900
|
-
const content = jsonStringify5(cache, null, 2);
|
|
399901
|
-
await writeFile41(tempPath, content, {
|
|
399902
|
-
encoding: "utf-8",
|
|
399903
|
-
mode: 384
|
|
399904
|
-
});
|
|
399905
|
-
await rename9(tempPath, cachePath);
|
|
399906
|
-
logForDebugging3("Install counts cache saved successfully");
|
|
399907
|
-
} catch (error) {
|
|
399908
|
-
logError3(error);
|
|
399909
|
-
try {
|
|
399910
|
-
await unlink19(tempPath);
|
|
399911
|
-
} catch {}
|
|
399912
|
-
}
|
|
399913
|
-
}
|
|
399914
|
-
async function fetchInstallCountsFromGitHub() {
|
|
399915
|
-
logForDebugging3(`Fetching install counts from ${INSTALL_COUNTS_URL}`);
|
|
399916
|
-
const started = performance.now();
|
|
399917
|
-
try {
|
|
399918
|
-
const response = await axios_default.get(INSTALL_COUNTS_URL, {
|
|
399919
|
-
timeout: 1e4
|
|
399920
|
-
});
|
|
399921
|
-
if (!response.data?.plugins || !Array.isArray(response.data.plugins)) {
|
|
399922
|
-
throw new Error("Invalid response format from install counts API");
|
|
399923
|
-
}
|
|
399924
|
-
logPluginFetch("install_counts", INSTALL_COUNTS_URL, "success", performance.now() - started);
|
|
399925
|
-
return response.data.plugins;
|
|
399926
|
-
} catch (error) {
|
|
399927
|
-
logPluginFetch("install_counts", INSTALL_COUNTS_URL, "failure", performance.now() - started, classifyFetchError(error));
|
|
399928
|
-
throw error;
|
|
399929
|
-
}
|
|
399930
|
-
}
|
|
399931
|
-
async function getInstallCounts() {
|
|
399932
|
-
const cache = await loadInstallCountsCache();
|
|
399933
|
-
if (cache) {
|
|
399934
|
-
logForDebugging3("Using cached install counts");
|
|
399935
|
-
logPluginFetch("install_counts", INSTALL_COUNTS_URL, "cache_hit", 0);
|
|
399936
|
-
const map = new Map;
|
|
399937
|
-
for (const entry of cache.counts) {
|
|
399938
|
-
map.set(entry.plugin, entry.unique_installs);
|
|
399939
|
-
}
|
|
399940
|
-
return map;
|
|
399941
|
-
}
|
|
399942
|
-
try {
|
|
399943
|
-
const counts = await fetchInstallCountsFromGitHub();
|
|
399944
|
-
const newCache = {
|
|
399945
|
-
version: INSTALL_COUNTS_CACHE_VERSION,
|
|
399946
|
-
fetchedAt: new Date().toISOString(),
|
|
399947
|
-
counts
|
|
399948
|
-
};
|
|
399949
|
-
await saveInstallCountsCache(newCache);
|
|
399950
|
-
const map = new Map;
|
|
399951
|
-
for (const entry of counts) {
|
|
399952
|
-
map.set(entry.plugin, entry.unique_installs);
|
|
399953
|
-
}
|
|
399954
|
-
return map;
|
|
399955
|
-
} catch (error) {
|
|
399956
|
-
logError3(error);
|
|
399957
|
-
logForDebugging3(`Failed to fetch install counts: ${errorMessage2(error)}`);
|
|
399958
|
-
return null;
|
|
399959
|
-
}
|
|
399960
|
-
}
|
|
399961
|
-
function formatInstallCount(count) {
|
|
399962
|
-
if (count < 1000) {
|
|
399963
|
-
return String(count);
|
|
399964
|
-
}
|
|
399965
|
-
if (count < 1e6) {
|
|
399966
|
-
const k = count / 1000;
|
|
399967
|
-
const formatted = k.toFixed(1);
|
|
399968
|
-
return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}K` : `${formatted}K`;
|
|
399969
|
-
}
|
|
399970
|
-
const m = count / 1e6;
|
|
399971
|
-
const formatted = m.toFixed(1);
|
|
399972
|
-
return formatted.endsWith(".0") ? `${formatted.slice(0, -2)}M` : `${formatted}M`;
|
|
399973
|
-
}
|
|
399974
|
-
var INSTALL_COUNTS_CACHE_VERSION = 1, INSTALL_COUNTS_CACHE_FILENAME = "install-counts-cache.json", INSTALL_COUNTS_URL = "https://raw.githubusercontent.com/anthropics/claude-plugins-official/refs/heads/stats/stats/plugin-installs.json", CACHE_TTL_MS3;
|
|
399975
|
-
var init_installCounts = __esm(() => {
|
|
399976
|
-
init_axios2();
|
|
399977
|
-
init_debug();
|
|
399978
|
-
init_errors4();
|
|
399979
|
-
init_fsOperations();
|
|
399980
|
-
init_log5();
|
|
399981
|
-
init_slowOperations();
|
|
399982
|
-
init_fetchTelemetry();
|
|
399983
|
-
init_pluginDirectories();
|
|
399984
|
-
CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
399985
|
-
});
|
|
399986
|
-
|
|
399987
399806
|
// src/tui/commands/plugin/PluginOptionsDialog.tsx
|
|
399988
399807
|
function buildFinalValues(fields, collected, configSchema, initialValues) {
|
|
399989
399808
|
const finalValues = {};
|
|
@@ -400915,7 +400734,7 @@ function BrowseMarketplace({
|
|
|
400915
400734
|
});
|
|
400916
400735
|
}
|
|
400917
400736
|
try {
|
|
400918
|
-
const counts = await getInstallCounts();
|
|
400737
|
+
const counts = await getInstallCounts([marketplaceName]);
|
|
400919
400738
|
if (cancelled)
|
|
400920
400739
|
return;
|
|
400921
400740
|
setInstallCounts(counts);
|
|
@@ -401596,7 +401415,7 @@ function BrowseMarketplace({
|
|
|
401596
401415
|
dimColor: true,
|
|
401597
401416
|
children: " (installed)"
|
|
401598
401417
|
}, undefined, false, undefined, this),
|
|
401599
|
-
installCounts
|
|
401418
|
+
installCounts?.get(plugin_6.pluginId) != null && /* @__PURE__ */ jsx_dev_runtime286.jsxDEV(ThemedText, {
|
|
401600
401419
|
dimColor: true,
|
|
401601
401420
|
children: [
|
|
401602
401421
|
" · ",
|
|
@@ -401671,7 +401490,6 @@ var init_BrowseMarketplace = __esm(() => {
|
|
|
401671
401490
|
init_marketplaceHelpers();
|
|
401672
401491
|
init_marketplaceDisplayName();
|
|
401673
401492
|
init_marketplaceManager();
|
|
401674
|
-
init_officialMarketplace();
|
|
401675
401493
|
init_pluginInstallationHelpers();
|
|
401676
401494
|
init_pluginPolicy();
|
|
401677
401495
|
init_stringUtils2();
|
|
@@ -402321,7 +402139,7 @@ function DiscoverPlugins({
|
|
|
402321
402139
|
dimColor: true,
|
|
402322
402140
|
children: " [Community Managed]"
|
|
402323
402141
|
}, undefined, false, undefined, this),
|
|
402324
|
-
installCounts
|
|
402142
|
+
installCounts?.get(plugin_5.pluginId) != null && /* @__PURE__ */ jsx_dev_runtime287.jsxDEV(ThemedText, {
|
|
402325
402143
|
dimColor: true,
|
|
402326
402144
|
children: [
|
|
402327
402145
|
" · ",
|
|
@@ -402614,7 +402432,6 @@ var init_DiscoverPlugins = __esm(() => {
|
|
|
402614
402432
|
init_installedPluginsManager();
|
|
402615
402433
|
init_marketplaceHelpers();
|
|
402616
402434
|
init_marketplaceManager();
|
|
402617
|
-
init_officialMarketplace();
|
|
402618
402435
|
init_pluginInstallationHelpers();
|
|
402619
402436
|
init_pluginPolicy();
|
|
402620
402437
|
init_stringUtils2();
|
|
@@ -402631,7 +402448,7 @@ var init_DiscoverPlugins = __esm(() => {
|
|
|
402631
402448
|
|
|
402632
402449
|
// src/tui/utils/plugins/skillSearch.ts
|
|
402633
402450
|
import { readdir as readdir27, readFile as readFile52, stat as stat46 } from "fs/promises";
|
|
402634
|
-
import { join as
|
|
402451
|
+
import { join as join146 } from "path";
|
|
402635
402452
|
async function searchSkillsAcrossMarketplaces(query) {
|
|
402636
402453
|
const config = await loadKnownMarketplacesConfig();
|
|
402637
402454
|
const q = query?.trim().toLowerCase();
|
|
@@ -402643,20 +402460,20 @@ async function searchSkillsAcrossMarketplaces(query) {
|
|
|
402643
402460
|
let marketplaceDir;
|
|
402644
402461
|
try {
|
|
402645
402462
|
const locStat = await stat46(marketplaceConfig.installLocation);
|
|
402646
|
-
marketplaceDir = locStat.isDirectory() ? marketplaceConfig.installLocation :
|
|
402463
|
+
marketplaceDir = locStat.isDirectory() ? marketplaceConfig.installLocation : join146(marketplaceConfig.installLocation, "..");
|
|
402647
402464
|
} catch {
|
|
402648
402465
|
continue;
|
|
402649
402466
|
}
|
|
402650
402467
|
for (const entry of data.plugins) {
|
|
402651
402468
|
if (typeof entry.source !== "string")
|
|
402652
402469
|
continue;
|
|
402653
|
-
const pluginPath =
|
|
402654
|
-
const skillDirCandidates = [
|
|
402470
|
+
const pluginPath = join146(marketplaceDir, entry.source);
|
|
402471
|
+
const skillDirCandidates = [join146(pluginPath, "skills")];
|
|
402655
402472
|
if (typeof entry.skills === "string") {
|
|
402656
|
-
skillDirCandidates.push(
|
|
402473
|
+
skillDirCandidates.push(join146(pluginPath, entry.skills));
|
|
402657
402474
|
} else if (Array.isArray(entry.skills)) {
|
|
402658
402475
|
for (const extra of entry.skills) {
|
|
402659
|
-
skillDirCandidates.push(
|
|
402476
|
+
skillDirCandidates.push(join146(pluginPath, extra));
|
|
402660
402477
|
}
|
|
402661
402478
|
}
|
|
402662
402479
|
const seen = new Set;
|
|
@@ -402670,7 +402487,7 @@ async function searchSkillsAcrossMarketplaces(query) {
|
|
|
402670
402487
|
for (const d of dirEntries) {
|
|
402671
402488
|
if (!d.isDirectory())
|
|
402672
402489
|
continue;
|
|
402673
|
-
const skillFile =
|
|
402490
|
+
const skillFile = join146(skillDir, d.name, "SKILL.md");
|
|
402674
402491
|
if (seen.has(skillFile))
|
|
402675
402492
|
continue;
|
|
402676
402493
|
seen.add(skillFile);
|
|
@@ -404170,10 +403987,10 @@ var init_ManageMarketplaces = __esm(() => {
|
|
|
404170
403987
|
|
|
404171
403988
|
// src/tui/utils/plugins/pluginFlagging.ts
|
|
404172
403989
|
import { randomBytes as randomBytes19 } from "crypto";
|
|
404173
|
-
import { readFile as readFile53, rename as rename10, unlink as unlink20, writeFile as
|
|
404174
|
-
import { join as
|
|
403990
|
+
import { readFile as readFile53, rename as rename10, unlink as unlink20, writeFile as writeFile41 } from "fs/promises";
|
|
403991
|
+
import { join as join147 } from "path";
|
|
404175
403992
|
function getFlaggedPluginsPath() {
|
|
404176
|
-
return
|
|
403993
|
+
return join147(getPluginsDirectory(), FLAGGED_PLUGINS_FILENAME);
|
|
404177
403994
|
}
|
|
404178
403995
|
function parsePluginsData(content) {
|
|
404179
403996
|
const parsed = jsonParse2(content);
|
|
@@ -404211,7 +404028,7 @@ async function writeToDisk(plugins) {
|
|
|
404211
404028
|
try {
|
|
404212
404029
|
await getFsImplementation2().mkdir(getPluginsDirectory());
|
|
404213
404030
|
const content = jsonStringify5({ plugins }, null, 2);
|
|
404214
|
-
await
|
|
404031
|
+
await writeFile41(tempPath, content, {
|
|
404215
404032
|
encoding: "utf-8",
|
|
404216
404033
|
mode: 384
|
|
404217
404034
|
});
|
|
@@ -409691,8 +409508,8 @@ var init_rewind = __esm(() => {
|
|
|
409691
409508
|
|
|
409692
409509
|
// src/tui/utils/heapDumpService.ts
|
|
409693
409510
|
import { createWriteStream as createWriteStream3, writeFileSync as writeFileSync8 } from "fs";
|
|
409694
|
-
import { readdir as readdir30, readFile as readFile56, writeFile as
|
|
409695
|
-
import { join as
|
|
409511
|
+
import { readdir as readdir30, readFile as readFile56, writeFile as writeFile42 } from "fs/promises";
|
|
409512
|
+
import { join as join150 } from "path";
|
|
409696
409513
|
import { pipeline as pipeline2 } from "stream/promises";
|
|
409697
409514
|
import {
|
|
409698
409515
|
getHeapSnapshot,
|
|
@@ -409800,9 +409617,9 @@ async function performHeapDump(trigger = "manual", dumpNumber = 0) {
|
|
|
409800
409617
|
const suffix = dumpNumber > 0 ? `-dump${dumpNumber}` : "";
|
|
409801
409618
|
const heapFilename = `${sessionId}${suffix}.heapsnapshot`;
|
|
409802
409619
|
const diagFilename = `${sessionId}${suffix}-diagnostics.json`;
|
|
409803
|
-
const heapPath =
|
|
409804
|
-
const diagPath =
|
|
409805
|
-
await
|
|
409620
|
+
const heapPath = join150(dumpDir, heapFilename);
|
|
409621
|
+
const diagPath = join150(dumpDir, diagFilename);
|
|
409622
|
+
await writeFile42(diagPath, jsonStringify5(diagnostics, null, 2), {
|
|
409806
409623
|
mode: 384
|
|
409807
409624
|
});
|
|
409808
409625
|
logForDebugging3(`[HeapDump] Diagnostics written to ${diagPath}`);
|
|
@@ -411138,7 +410955,7 @@ var init_stickers2 = __esm(() => {
|
|
|
411138
410955
|
// src/tui/skills/bundledSkills.ts
|
|
411139
410956
|
import { constants as fsConstants8 } from "fs";
|
|
411140
410957
|
import { mkdir as mkdir47, open as open16 } from "fs/promises";
|
|
411141
|
-
import { dirname as dirname74, isAbsolute as isAbsolute32, join as
|
|
410958
|
+
import { dirname as dirname74, isAbsolute as isAbsolute32, join as join151, normalize as normalize14, sep as pathSep3 } from "path";
|
|
411142
410959
|
function registerBundledSkill2(definition) {
|
|
411143
410960
|
const { files } = definition;
|
|
411144
410961
|
let skillRoot;
|
|
@@ -411186,7 +411003,7 @@ function getBundledSkills2() {
|
|
|
411186
411003
|
return [...bundledSkills2];
|
|
411187
411004
|
}
|
|
411188
411005
|
function getBundledSkillExtractDir2(skillName) {
|
|
411189
|
-
return
|
|
411006
|
+
return join151(getBundledSkillsRoot2(), skillName);
|
|
411190
411007
|
}
|
|
411191
411008
|
async function extractBundledSkillFiles(skillName, files) {
|
|
411192
411009
|
const dir = getBundledSkillExtractDir2(skillName);
|
|
@@ -411228,7 +411045,7 @@ function resolveSkillFilePath(baseDir, relPath) {
|
|
|
411228
411045
|
if (isAbsolute32(normalized) || normalized.split(pathSep3).includes("..") || normalized.split("/").includes("..")) {
|
|
411229
411046
|
throw new Error(`bundled skill file path escapes skill dir: ${relPath}`);
|
|
411230
411047
|
}
|
|
411231
|
-
return
|
|
411048
|
+
return join151(baseDir, normalized);
|
|
411232
411049
|
}
|
|
411233
411050
|
function prependBaseDir(blocks, baseDir) {
|
|
411234
411051
|
const prefix = `Base directory for this skill: ${baseDir}
|
|
@@ -411523,10 +411340,10 @@ var init_ExitFlow = __esm(() => {
|
|
|
411523
411340
|
});
|
|
411524
411341
|
|
|
411525
411342
|
// src/tui/utils/concurrentSessions.ts
|
|
411526
|
-
import { chmod as
|
|
411527
|
-
import { join as
|
|
411343
|
+
import { chmod as chmod8, mkdir as mkdir48, readdir as readdir31, readFile as readFile57, unlink as unlink21, writeFile as writeFile43 } from "fs/promises";
|
|
411344
|
+
import { join as join152 } from "path";
|
|
411528
411345
|
function getSessionsDir() {
|
|
411529
|
-
return
|
|
411346
|
+
return join152(getAtlasConfigHomeDir3(), "sessions");
|
|
411530
411347
|
}
|
|
411531
411348
|
function envSessionKind() {
|
|
411532
411349
|
if (feature("BG_SESSIONS")) {
|
|
@@ -411544,7 +411361,7 @@ async function registerSession2() {
|
|
|
411544
411361
|
return false;
|
|
411545
411362
|
const kind = envSessionKind() ?? "interactive";
|
|
411546
411363
|
const dir = getSessionsDir();
|
|
411547
|
-
const pidFile =
|
|
411364
|
+
const pidFile = join152(dir, `${process.pid}.json`);
|
|
411548
411365
|
registerCleanup3(async () => {
|
|
411549
411366
|
try {
|
|
411550
411367
|
await unlink21(pidFile);
|
|
@@ -411552,8 +411369,8 @@ async function registerSession2() {
|
|
|
411552
411369
|
});
|
|
411553
411370
|
try {
|
|
411554
411371
|
await mkdir48(dir, { recursive: true, mode: 448 });
|
|
411555
|
-
await
|
|
411556
|
-
await
|
|
411372
|
+
await chmod8(dir, 448);
|
|
411373
|
+
await writeFile43(pidFile, jsonStringify5({
|
|
411557
411374
|
pid: process.pid,
|
|
411558
411375
|
sessionId: getSessionId(),
|
|
411559
411376
|
cwd: getOriginalCwd(),
|
|
@@ -411577,10 +411394,10 @@ async function registerSession2() {
|
|
|
411577
411394
|
}
|
|
411578
411395
|
}
|
|
411579
411396
|
async function updatePidFile(patch) {
|
|
411580
|
-
const pidFile =
|
|
411397
|
+
const pidFile = join152(getSessionsDir(), `${process.pid}.json`);
|
|
411581
411398
|
try {
|
|
411582
411399
|
const data = jsonParse2(await readFile57(pidFile, "utf8"));
|
|
411583
|
-
await
|
|
411400
|
+
await writeFile43(pidFile, jsonStringify5({ ...data, ...patch }));
|
|
411584
411401
|
} catch (e) {
|
|
411585
411402
|
logForDebugging3(`[concurrentSessions] updatePidFile failed: ${errorMessage2(e)}`);
|
|
411586
411403
|
}
|
|
@@ -411618,7 +411435,7 @@ async function countConcurrentSessions2() {
|
|
|
411618
411435
|
if (isProcessRunning2(pid)) {
|
|
411619
411436
|
count++;
|
|
411620
411437
|
} else if (getPlatform3() !== "wsl") {
|
|
411621
|
-
unlink21(
|
|
411438
|
+
unlink21(join152(dir, file)).catch(() => {});
|
|
411622
411439
|
}
|
|
411623
411440
|
}
|
|
411624
411441
|
return count;
|
|
@@ -411693,7 +411510,7 @@ var init_exit2 = __esm(() => {
|
|
|
411693
411510
|
});
|
|
411694
411511
|
|
|
411695
411512
|
// src/tui/components/ExportDialog.tsx
|
|
411696
|
-
import { join as
|
|
411513
|
+
import { join as join153 } from "path";
|
|
411697
411514
|
function ExportDialog({
|
|
411698
411515
|
content,
|
|
411699
411516
|
defaultFilename,
|
|
@@ -411726,7 +411543,7 @@ function ExportDialog({
|
|
|
411726
411543
|
};
|
|
411727
411544
|
const handleFilenameSubmit = () => {
|
|
411728
411545
|
const finalFilename = filename.endsWith(".txt") ? filename : filename.replace(/\.[^.]+$/, "") + ".txt";
|
|
411729
|
-
const filepath =
|
|
411546
|
+
const filepath = join153(getCwd(), finalFilename);
|
|
411730
411547
|
try {
|
|
411731
411548
|
writeFileSync_DEPRECATED(filepath, content, {
|
|
411732
411549
|
encoding: "utf-8",
|
|
@@ -411949,7 +411766,7 @@ __export(exports_export, {
|
|
|
411949
411766
|
extractFirstPrompt: () => extractFirstPrompt2,
|
|
411950
411767
|
sanitizeFilename: () => sanitizeFilename
|
|
411951
411768
|
});
|
|
411952
|
-
import { join as
|
|
411769
|
+
import { join as join154 } from "path";
|
|
411953
411770
|
function formatTimestamp(date) {
|
|
411954
411771
|
const year = date.getFullYear();
|
|
411955
411772
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
@@ -411993,7 +411810,7 @@ async function call50(onDone, context, args) {
|
|
|
411993
411810
|
const filename = args.trim();
|
|
411994
411811
|
if (filename) {
|
|
411995
411812
|
const finalFilename = filename.endsWith(".txt") ? filename : filename.replace(/\.[^.]+$/, "") + ".txt";
|
|
411996
|
-
const filepath =
|
|
411813
|
+
const filepath = join154(getCwd(), finalFilename);
|
|
411997
411814
|
try {
|
|
411998
411815
|
writeFileSync_DEPRECATED(filepath, content, {
|
|
411999
411816
|
encoding: "utf-8",
|
|
@@ -412879,7 +412696,7 @@ var require_asciichart = __commonJS(function(exports) {
|
|
|
412879
412696
|
// src/tui/utils/statsCache.ts
|
|
412880
412697
|
import { randomBytes as randomBytes20 } from "crypto";
|
|
412881
412698
|
import { open as open17 } from "fs/promises";
|
|
412882
|
-
import { join as
|
|
412699
|
+
import { join as join155 } from "path";
|
|
412883
412700
|
async function withStatsCacheLock(fn) {
|
|
412884
412701
|
while (statsCacheLockPromise) {
|
|
412885
412702
|
await statsCacheLockPromise;
|
|
@@ -412896,7 +412713,7 @@ async function withStatsCacheLock(fn) {
|
|
|
412896
412713
|
}
|
|
412897
412714
|
}
|
|
412898
412715
|
function getStatsCachePath() {
|
|
412899
|
-
return
|
|
412716
|
+
return join155(getAtlasConfigHomeDir3(), STATS_CACHE_FILENAME);
|
|
412900
412717
|
}
|
|
412901
412718
|
function getEmptyCache() {
|
|
412902
412719
|
return {
|
|
@@ -413577,16 +413394,16 @@ var init_ansiToPng = __esm(() => {
|
|
|
413577
413394
|
});
|
|
413578
413395
|
|
|
413579
413396
|
// src/tui/utils/screenshotClipboard.ts
|
|
413580
|
-
import { mkdir as mkdir49, unlink as unlink22, writeFile as
|
|
413397
|
+
import { mkdir as mkdir49, unlink as unlink22, writeFile as writeFile44 } from "fs/promises";
|
|
413581
413398
|
import { tmpdir as tmpdir10 } from "os";
|
|
413582
|
-
import { join as
|
|
413399
|
+
import { join as join156 } from "path";
|
|
413583
413400
|
async function copyAnsiToClipboard(ansiText, options) {
|
|
413584
413401
|
try {
|
|
413585
|
-
const tempDir =
|
|
413402
|
+
const tempDir = join156(tmpdir10(), "atlas-screenshots");
|
|
413586
413403
|
await mkdir49(tempDir, { recursive: true });
|
|
413587
|
-
const pngPath =
|
|
413404
|
+
const pngPath = join156(tempDir, `screenshot-${Date.now()}.png`);
|
|
413588
413405
|
const pngBuffer = ansiToPng(ansiText, options);
|
|
413589
|
-
await
|
|
413406
|
+
await writeFile44(pngPath, pngBuffer);
|
|
413590
413407
|
const result = await copyPngToClipboard(pngPath);
|
|
413591
413408
|
try {
|
|
413592
413409
|
await unlink22(pngPath);
|
|
@@ -413655,7 +413472,7 @@ var init_screenshotClipboard = __esm(() => {
|
|
|
413655
413472
|
|
|
413656
413473
|
// src/tui/utils/stats.ts
|
|
413657
413474
|
import { open as open18 } from "fs/promises";
|
|
413658
|
-
import { basename as basename46, dirname as dirname75, join as
|
|
413475
|
+
import { basename as basename46, dirname as dirname75, join as join157, sep as sep33 } from "path";
|
|
413659
413476
|
async function processSessionFiles(sessionFiles, options = {}) {
|
|
413660
413477
|
const { fromDate, toDate } = options;
|
|
413661
413478
|
const fs = getFsImplementation2();
|
|
@@ -413841,17 +413658,17 @@ async function getAllSessionFiles() {
|
|
|
413841
413658
|
return [];
|
|
413842
413659
|
throw e;
|
|
413843
413660
|
}
|
|
413844
|
-
const projectDirs = allEntries.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
413661
|
+
const projectDirs = allEntries.filter((dirent) => dirent.isDirectory()).map((dirent) => join157(projectsDir, dirent.name));
|
|
413845
413662
|
const projectResults = await Promise.all(projectDirs.map(async (projectDir) => {
|
|
413846
413663
|
try {
|
|
413847
413664
|
const entries = await fs.readdir(projectDir);
|
|
413848
|
-
const mainFiles = entries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl")).map((dirent) =>
|
|
413665
|
+
const mainFiles = entries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl")).map((dirent) => join157(projectDir, dirent.name));
|
|
413849
413666
|
const sessionDirs = entries.filter((dirent) => dirent.isDirectory());
|
|
413850
413667
|
const subagentResults = await Promise.all(sessionDirs.map(async (sessionDir) => {
|
|
413851
|
-
const subagentsDir =
|
|
413668
|
+
const subagentsDir = join157(projectDir, sessionDir.name, "subagents");
|
|
413852
413669
|
try {
|
|
413853
413670
|
const subagentEntries = await fs.readdir(subagentsDir);
|
|
413854
|
-
return subagentEntries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl") && dirent.name.startsWith("agent-")).map((dirent) =>
|
|
413671
|
+
return subagentEntries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl") && dirent.name.startsWith("agent-")).map((dirent) => join157(subagentsDir, dirent.name));
|
|
413855
413672
|
} catch {
|
|
413856
413673
|
return [];
|
|
413857
413674
|
}
|
|
@@ -416704,9 +416521,9 @@ import {
|
|
|
416704
416521
|
readdir as readdir32,
|
|
416705
416522
|
readFile as readFile58,
|
|
416706
416523
|
unlink as unlink23,
|
|
416707
|
-
writeFile as
|
|
416524
|
+
writeFile as writeFile45
|
|
416708
416525
|
} from "fs/promises";
|
|
416709
|
-
import { extname as extname16, join as
|
|
416526
|
+
import { extname as extname16, join as join158 } from "path";
|
|
416710
416527
|
function getAnalysisModel() {
|
|
416711
416528
|
return getDefaultPremiumModel();
|
|
416712
416529
|
}
|
|
@@ -416714,13 +416531,13 @@ function getInsightsModel() {
|
|
|
416714
416531
|
return getDefaultPremiumModel();
|
|
416715
416532
|
}
|
|
416716
416533
|
function getDataDir() {
|
|
416717
|
-
return
|
|
416534
|
+
return join158(getAtlasConfigHomeDir3(), "usage-data");
|
|
416718
416535
|
}
|
|
416719
416536
|
function getFacetsDir() {
|
|
416720
|
-
return
|
|
416537
|
+
return join158(getDataDir(), "facets");
|
|
416721
416538
|
}
|
|
416722
416539
|
function getSessionMetaDir() {
|
|
416723
|
-
return
|
|
416540
|
+
return join158(getDataDir(), "session-meta");
|
|
416724
416541
|
}
|
|
416725
416542
|
function getLanguageFromPath(filePath) {
|
|
416726
416543
|
const ext = extname16(filePath).toLowerCase();
|
|
@@ -417061,7 +416878,7 @@ async function formatTranscriptWithSummarization(log) {
|
|
|
417061
416878
|
`);
|
|
417062
416879
|
}
|
|
417063
416880
|
async function loadCachedFacets(sessionId) {
|
|
417064
|
-
const facetPath =
|
|
416881
|
+
const facetPath = join158(getFacetsDir(), `${sessionId}.json`);
|
|
417065
416882
|
try {
|
|
417066
416883
|
const content = await readFile58(facetPath, { encoding: "utf-8" });
|
|
417067
416884
|
const parsed = jsonParse2(content);
|
|
@@ -417080,14 +416897,14 @@ async function saveFacets(facets) {
|
|
|
417080
416897
|
try {
|
|
417081
416898
|
await mkdir50(getFacetsDir(), { recursive: true });
|
|
417082
416899
|
} catch {}
|
|
417083
|
-
const facetPath =
|
|
417084
|
-
await
|
|
416900
|
+
const facetPath = join158(getFacetsDir(), `${facets.session_id}.json`);
|
|
416901
|
+
await writeFile45(facetPath, jsonStringify5(facets, null, 2), {
|
|
417085
416902
|
encoding: "utf-8",
|
|
417086
416903
|
mode: 384
|
|
417087
416904
|
});
|
|
417088
416905
|
}
|
|
417089
416906
|
async function loadCachedSessionMeta(sessionId) {
|
|
417090
|
-
const metaPath =
|
|
416907
|
+
const metaPath = join158(getSessionMetaDir(), `${sessionId}.json`);
|
|
417091
416908
|
try {
|
|
417092
416909
|
const content = await readFile58(metaPath, { encoding: "utf-8" });
|
|
417093
416910
|
return jsonParse2(content);
|
|
@@ -417099,8 +416916,8 @@ async function saveSessionMeta(meta) {
|
|
|
417099
416916
|
try {
|
|
417100
416917
|
await mkdir50(getSessionMetaDir(), { recursive: true });
|
|
417101
416918
|
} catch {}
|
|
417102
|
-
const metaPath =
|
|
417103
|
-
await
|
|
416919
|
+
const metaPath = join158(getSessionMetaDir(), `${meta.session_id}.json`);
|
|
416920
|
+
await writeFile45(metaPath, jsonStringify5(meta, null, 2), {
|
|
417104
416921
|
encoding: "utf-8",
|
|
417105
416922
|
mode: 384
|
|
417106
416923
|
});
|
|
@@ -418179,7 +417996,7 @@ async function scanAllSessions() {
|
|
|
418179
417996
|
} catch {
|
|
418180
417997
|
return [];
|
|
418181
417998
|
}
|
|
418182
|
-
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
417999
|
+
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join158(projectsDir, dirent.name));
|
|
418183
418000
|
const allSessions = [];
|
|
418184
418001
|
for (let i = 0;i < projectDirs.length; i++) {
|
|
418185
418002
|
const sessionFiles = await getSessionFilesWithMtime(projectDirs[i]);
|
|
@@ -418335,8 +418152,8 @@ async function generateUsageReport(options) {
|
|
|
418335
418152
|
try {
|
|
418336
418153
|
await mkdir50(getDataDir(), { recursive: true });
|
|
418337
418154
|
} catch {}
|
|
418338
|
-
const htmlPath =
|
|
418339
|
-
await
|
|
418155
|
+
const htmlPath = join158(getDataDir(), "report.html");
|
|
418156
|
+
await writeFile45(htmlPath, htmlReport, {
|
|
418340
418157
|
encoding: "utf-8",
|
|
418341
418158
|
mode: 384
|
|
418342
418159
|
});
|
|
@@ -419139,9 +418956,9 @@ import {
|
|
|
419139
418956
|
readFile as readFile59,
|
|
419140
418957
|
stat as stat49,
|
|
419141
418958
|
unlink as unlink24,
|
|
419142
|
-
writeFile as
|
|
418959
|
+
writeFile as writeFile46
|
|
419143
418960
|
} from "fs/promises";
|
|
419144
|
-
import { basename as basename48, dirname as dirname76, join as
|
|
418961
|
+
import { basename as basename48, dirname as dirname76, join as join159 } from "path";
|
|
419145
418962
|
function isTranscriptMessage2(entry) {
|
|
419146
418963
|
return entry.type === "user" || entry.type === "assistant" || entry.type === "attachment" || entry.type === "system";
|
|
419147
418964
|
}
|
|
@@ -419155,18 +418972,18 @@ function isEphemeralToolProgress2(dataType) {
|
|
|
419155
418972
|
return typeof dataType === "string" && EPHEMERAL_PROGRESS_TYPES2.has(dataType);
|
|
419156
418973
|
}
|
|
419157
418974
|
function getProjectsDir3() {
|
|
419158
|
-
return
|
|
418975
|
+
return join159(getAtlasConfigHomeDir3(), "projects");
|
|
419159
418976
|
}
|
|
419160
418977
|
function getTranscriptPath2() {
|
|
419161
418978
|
const projectDir = getSessionProjectDir() ?? getProjectDir3(getOriginalCwd());
|
|
419162
|
-
return
|
|
418979
|
+
return join159(projectDir, `${getSessionId()}.jsonl`);
|
|
419163
418980
|
}
|
|
419164
418981
|
function getTranscriptPathForSession3(sessionId) {
|
|
419165
418982
|
if (sessionId === getSessionId()) {
|
|
419166
418983
|
return getTranscriptPath2();
|
|
419167
418984
|
}
|
|
419168
418985
|
const projectDir = getProjectDir3(getOriginalCwd());
|
|
419169
|
-
return
|
|
418986
|
+
return join159(projectDir, `${sessionId}.jsonl`);
|
|
419170
418987
|
}
|
|
419171
418988
|
function setAgentTranscriptSubdir2(agentId, subdir) {
|
|
419172
418989
|
agentTranscriptSubdirs2.set(agentId, subdir);
|
|
@@ -419178,8 +418995,8 @@ function getAgentTranscriptPath2(agentId) {
|
|
|
419178
418995
|
const projectDir = getSessionProjectDir() ?? getProjectDir3(getOriginalCwd());
|
|
419179
418996
|
const sessionId = getSessionId();
|
|
419180
418997
|
const subdir = agentTranscriptSubdirs2.get(agentId);
|
|
419181
|
-
const base = subdir ?
|
|
419182
|
-
return
|
|
418998
|
+
const base = subdir ? join159(projectDir, sessionId, "subagents", subdir) : join159(projectDir, sessionId, "subagents");
|
|
418999
|
+
return join159(base, `agent-${agentId}.jsonl`);
|
|
419183
419000
|
}
|
|
419184
419001
|
function getAgentMetadataPath(agentId) {
|
|
419185
419002
|
return getAgentTranscriptPath2(agentId).replace(/\.jsonl$/, ".meta.json");
|
|
@@ -419187,7 +419004,7 @@ function getAgentMetadataPath(agentId) {
|
|
|
419187
419004
|
async function writeAgentMetadata(agentId, metadata) {
|
|
419188
419005
|
const path = getAgentMetadataPath(agentId);
|
|
419189
419006
|
await mkdir51(dirname76(path), { recursive: true });
|
|
419190
|
-
await
|
|
419007
|
+
await writeFile46(path, JSON.stringify(metadata));
|
|
419191
419008
|
}
|
|
419192
419009
|
async function readAgentMetadata(agentId) {
|
|
419193
419010
|
const path = getAgentMetadataPath(agentId);
|
|
@@ -419202,7 +419019,7 @@ async function readAgentMetadata(agentId) {
|
|
|
419202
419019
|
}
|
|
419203
419020
|
function sessionIdExists(sessionId) {
|
|
419204
419021
|
const projectDir = getProjectDir3(getOriginalCwd());
|
|
419205
|
-
const sessionFile =
|
|
419022
|
+
const sessionFile = join159(projectDir, `${sessionId}.jsonl`);
|
|
419206
419023
|
const fs = getFsImplementation2();
|
|
419207
419024
|
try {
|
|
419208
419025
|
fs.statSync(sessionFile);
|
|
@@ -419529,7 +419346,7 @@ class Project2 {
|
|
|
419529
419346
|
return true;
|
|
419530
419347
|
}
|
|
419531
419348
|
});
|
|
419532
|
-
await
|
|
419349
|
+
await writeFile46(this.sessionFile, lines.join(`
|
|
419533
419350
|
`), {
|
|
419534
419351
|
encoding: "utf8"
|
|
419535
419352
|
});
|
|
@@ -420934,7 +420751,7 @@ async function loadTranscriptFile2(filePath, opts) {
|
|
|
420934
420751
|
};
|
|
420935
420752
|
}
|
|
420936
420753
|
async function loadSessionFile2(sessionId) {
|
|
420937
|
-
const sessionFile =
|
|
420754
|
+
const sessionFile = join159(getSessionProjectDir() ?? getProjectDir3(getOriginalCwd()), `${sessionId}.jsonl`);
|
|
420938
420755
|
return loadTranscriptFile2(sessionFile);
|
|
420939
420756
|
}
|
|
420940
420757
|
function clearSessionMessagesCache2() {
|
|
@@ -420998,7 +420815,7 @@ async function loadAllProjectsMessageLogsFull(limit) {
|
|
|
420998
420815
|
} catch {
|
|
420999
420816
|
return [];
|
|
421000
420817
|
}
|
|
421001
|
-
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
420818
|
+
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join159(projectsDir, dirent.name));
|
|
421002
420819
|
const logsPerProject = await Promise.all(projectDirs.map((projectDir) => getLogsWithoutIndex(projectDir, limit)));
|
|
421003
420820
|
const allLogs = logsPerProject.flat();
|
|
421004
420821
|
const deduped = new Map;
|
|
@@ -421023,7 +420840,7 @@ async function loadAllProjectsMessageLogsProgressive(limit, initialEnrichCount =
|
|
|
421023
420840
|
} catch {
|
|
421024
420841
|
return { logs: [], allStatLogs: [], nextIndex: 0 };
|
|
421025
420842
|
}
|
|
421026
|
-
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
420843
|
+
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join159(projectsDir, dirent.name));
|
|
421027
420844
|
const rawLogs = [];
|
|
421028
420845
|
for (const projectDir of projectDirs) {
|
|
421029
420846
|
rawLogs.push(...await getSessionFilesLite(projectDir, limit));
|
|
@@ -421099,7 +420916,7 @@ async function getStatOnlyLogsForWorktrees(worktreePaths, limit) {
|
|
|
421099
420916
|
for (const { path: wtPath, prefix } of indexed) {
|
|
421100
420917
|
if (dirName === prefix || dirName.startsWith(prefix + "-")) {
|
|
421101
420918
|
seenDirs.add(dirName);
|
|
421102
|
-
allLogs.push(...await getSessionFilesLite(
|
|
420919
|
+
allLogs.push(...await getSessionFilesLite(join159(projectsDir, dirent.name), undefined, wtPath));
|
|
421103
420920
|
break;
|
|
421104
420921
|
}
|
|
421105
420922
|
}
|
|
@@ -421159,7 +420976,7 @@ async function loadSubagentTranscripts(agentIds) {
|
|
|
421159
420976
|
return transcripts;
|
|
421160
420977
|
}
|
|
421161
420978
|
async function loadAllSubagentTranscriptsFromDisk() {
|
|
421162
|
-
const subagentsDir =
|
|
420979
|
+
const subagentsDir = join159(getSessionProjectDir() ?? getProjectDir3(getOriginalCwd()), getSessionId(), "subagents");
|
|
421163
420980
|
let entries;
|
|
421164
420981
|
try {
|
|
421165
420982
|
entries = await readdir33(subagentsDir, { withFileTypes: true });
|
|
@@ -421254,7 +421071,7 @@ async function getSessionFilesWithMtime(projectDir) {
|
|
|
421254
421071
|
const sessionId = validateUuid2(basename48(dirent.name, ".jsonl"));
|
|
421255
421072
|
if (!sessionId)
|
|
421256
421073
|
continue;
|
|
421257
|
-
candidates.push({ sessionId, filePath:
|
|
421074
|
+
candidates.push({ sessionId, filePath: join159(projectDir, dirent.name) });
|
|
421258
421075
|
}
|
|
421259
421076
|
await Promise.all(candidates.map(async ({ sessionId, filePath }) => {
|
|
421260
421077
|
try {
|
|
@@ -421676,7 +421493,7 @@ var init_sessionStorage = __esm(() => {
|
|
|
421676
421493
|
MAX_TRANSCRIPT_READ_BYTES2 = 50 * 1024 * 1024;
|
|
421677
421494
|
agentTranscriptSubdirs2 = new Map;
|
|
421678
421495
|
getProjectDir3 = memoize_default((projectDir) => {
|
|
421679
|
-
return
|
|
421496
|
+
return join159(getProjectsDir3(), sanitizePath3(projectDir));
|
|
421680
421497
|
});
|
|
421681
421498
|
METADATA_TYPE_MARKERS2 = [
|
|
421682
421499
|
'"type":"summary"',
|
|
@@ -421694,8 +421511,8 @@ var init_sessionStorage = __esm(() => {
|
|
|
421694
421511
|
|
|
421695
421512
|
// src/tui/utils/plans.ts
|
|
421696
421513
|
import { randomUUID as randomUUID40 } from "crypto";
|
|
421697
|
-
import { copyFile as copyFile9, writeFile as
|
|
421698
|
-
import { join as
|
|
421514
|
+
import { copyFile as copyFile9, writeFile as writeFile47 } from "fs/promises";
|
|
421515
|
+
import { join as join160, resolve as resolve50, sep as sep34 } from "path";
|
|
421699
421516
|
function getPlanSlug2(sessionId) {
|
|
421700
421517
|
const id = sessionId ?? getSessionId();
|
|
421701
421518
|
const cache = getPlanSlugCache();
|
|
@@ -421704,7 +421521,7 @@ function getPlanSlug2(sessionId) {
|
|
|
421704
421521
|
const plansDir = getPlansDirectory2();
|
|
421705
421522
|
for (let i = 0;i < MAX_SLUG_RETRIES2; i++) {
|
|
421706
421523
|
slug = generateWordSlug2();
|
|
421707
|
-
const filePath =
|
|
421524
|
+
const filePath = join160(plansDir, `${slug}.md`);
|
|
421708
421525
|
if (!getFsImplementation2().existsSync(filePath)) {
|
|
421709
421526
|
break;
|
|
421710
421527
|
}
|
|
@@ -421722,9 +421539,9 @@ function clearAllPlanSlugs2() {
|
|
|
421722
421539
|
function getPlanFilePath2(agentId) {
|
|
421723
421540
|
const planSlug = getPlanSlug2(getSessionId());
|
|
421724
421541
|
if (!agentId) {
|
|
421725
|
-
return
|
|
421542
|
+
return join160(getPlansDirectory2(), `${planSlug}.md`);
|
|
421726
421543
|
}
|
|
421727
|
-
return
|
|
421544
|
+
return join160(getPlansDirectory2(), `${planSlug}-agent-${agentId}.md`);
|
|
421728
421545
|
}
|
|
421729
421546
|
function getPlan2(agentId) {
|
|
421730
421547
|
const filePath = getPlanFilePath2(agentId);
|
|
@@ -421747,7 +421564,7 @@ async function copyPlanForResume(log, targetSessionId) {
|
|
|
421747
421564
|
}
|
|
421748
421565
|
const sessionId = targetSessionId ?? getSessionId();
|
|
421749
421566
|
setPlanSlug2(sessionId, slug);
|
|
421750
|
-
const planPath =
|
|
421567
|
+
const planPath = join160(getPlansDirectory2(), `${slug}.md`);
|
|
421751
421568
|
try {
|
|
421752
421569
|
await getFsImplementation2().readFile(planPath, { encoding: "utf-8" });
|
|
421753
421570
|
return true;
|
|
@@ -421773,7 +421590,7 @@ async function copyPlanForResume(log, targetSessionId) {
|
|
|
421773
421590
|
}
|
|
421774
421591
|
if (recovered) {
|
|
421775
421592
|
try {
|
|
421776
|
-
await
|
|
421593
|
+
await writeFile47(planPath, recovered, { encoding: "utf-8" });
|
|
421777
421594
|
return true;
|
|
421778
421595
|
} catch (writeError) {
|
|
421779
421596
|
logError3(writeError);
|
|
@@ -421790,9 +421607,9 @@ async function copyPlanForFork(log, targetSessionId) {
|
|
|
421790
421607
|
return false;
|
|
421791
421608
|
}
|
|
421792
421609
|
const plansDir = getPlansDirectory2();
|
|
421793
|
-
const originalPlanPath =
|
|
421610
|
+
const originalPlanPath = join160(plansDir, `${originalSlug}.md`);
|
|
421794
421611
|
const newSlug = getPlanSlug2(targetSessionId);
|
|
421795
|
-
const newPlanPath =
|
|
421612
|
+
const newPlanPath = join160(plansDir, `${newSlug}.md`);
|
|
421796
421613
|
try {
|
|
421797
421614
|
await copyFile9(originalPlanPath, newPlanPath);
|
|
421798
421615
|
return true;
|
|
@@ -421908,12 +421725,12 @@ var init_plans = __esm(() => {
|
|
|
421908
421725
|
const resolved = resolve50(cwd, settingsDir);
|
|
421909
421726
|
if (!resolved.startsWith(cwd + sep34) && resolved !== cwd) {
|
|
421910
421727
|
logError3(new Error(`plansDirectory must be within project root: ${settingsDir}`));
|
|
421911
|
-
plansPath =
|
|
421728
|
+
plansPath = join160(getAtlasConfigHomeDir3(), "plans");
|
|
421912
421729
|
} else {
|
|
421913
421730
|
plansPath = resolved;
|
|
421914
421731
|
}
|
|
421915
421732
|
} else {
|
|
421916
|
-
plansPath =
|
|
421733
|
+
plansPath = join160(getAtlasConfigHomeDir3(), "plans");
|
|
421917
421734
|
}
|
|
421918
421735
|
try {
|
|
421919
421736
|
getFsImplementation2().mkdirSync(plansPath);
|
|
@@ -421927,7 +421744,7 @@ var init_plans = __esm(() => {
|
|
|
421927
421744
|
// src/tui/utils/permissions/filesystem.ts
|
|
421928
421745
|
import { randomBytes as randomBytes21 } from "crypto";
|
|
421929
421746
|
import { homedir as homedir38, tmpdir as tmpdir11 } from "os";
|
|
421930
|
-
import { join as
|
|
421747
|
+
import { join as join161, normalize as normalize15, posix as posix9, sep as sep35 } from "path";
|
|
421931
421748
|
function normalizeCaseForComparison2(path) {
|
|
421932
421749
|
return path.toLowerCase();
|
|
421933
421750
|
}
|
|
@@ -421937,11 +421754,11 @@ function getClaudeSkillScope(filePath) {
|
|
|
421937
421754
|
const configDir = getConfigDirName2();
|
|
421938
421755
|
const bases = [
|
|
421939
421756
|
{
|
|
421940
|
-
dir: expandPath2(
|
|
421757
|
+
dir: expandPath2(join161(getOriginalCwd(), configDir, "skills")),
|
|
421941
421758
|
prefix: `/${configDir}/skills/`
|
|
421942
421759
|
},
|
|
421943
421760
|
{
|
|
421944
|
-
dir: expandPath2(
|
|
421761
|
+
dir: expandPath2(join161(homedir38(), configDir, "skills")),
|
|
421945
421762
|
prefix: `~/${configDir}/skills/`
|
|
421946
421763
|
}
|
|
421947
421764
|
];
|
|
@@ -421996,21 +421813,21 @@ function isClaudeConfigFilePath2(filePath) {
|
|
|
421996
421813
|
if (isAtlasSettingsPath2(filePath)) {
|
|
421997
421814
|
return true;
|
|
421998
421815
|
}
|
|
421999
|
-
const commandsDir =
|
|
422000
|
-
const agentsDir =
|
|
422001
|
-
const skillsDir =
|
|
421816
|
+
const commandsDir = join161(getOriginalCwd(), getConfigDirName2(), "commands");
|
|
421817
|
+
const agentsDir = join161(getOriginalCwd(), getConfigDirName2(), "agents");
|
|
421818
|
+
const skillsDir = join161(getOriginalCwd(), getConfigDirName2(), "skills");
|
|
422002
421819
|
return pathInWorkingPath2(filePath, commandsDir) || pathInWorkingPath2(filePath, agentsDir) || pathInWorkingPath2(filePath, skillsDir);
|
|
422003
421820
|
}
|
|
422004
421821
|
function isSessionPlanFile(absolutePath) {
|
|
422005
|
-
const expectedPrefix =
|
|
421822
|
+
const expectedPrefix = join161(getPlansDirectory2(), getPlanSlug2());
|
|
422006
421823
|
const normalizedPath = normalize15(absolutePath);
|
|
422007
421824
|
return normalizedPath.startsWith(expectedPrefix) && normalizedPath.endsWith(".md");
|
|
422008
421825
|
}
|
|
422009
421826
|
function getSessionMemoryDir() {
|
|
422010
|
-
return
|
|
421827
|
+
return join161(getProjectDir3(getCwd()), getSessionId(), "session-memory") + sep35;
|
|
422011
421828
|
}
|
|
422012
421829
|
function getSessionMemoryPath() {
|
|
422013
|
-
return
|
|
421830
|
+
return join161(getSessionMemoryDir(), "summary.md");
|
|
422014
421831
|
}
|
|
422015
421832
|
function isSessionMemoryPath(absolutePath) {
|
|
422016
421833
|
const normalizedPath = normalize15(absolutePath);
|
|
@@ -422032,10 +421849,10 @@ function getAtlasTempDirName2() {
|
|
|
422032
421849
|
return `${getConfigDirName2()}-${uid}`;
|
|
422033
421850
|
}
|
|
422034
421851
|
function getProjectTempDir2() {
|
|
422035
|
-
return
|
|
421852
|
+
return join161(getAtlasTempDir2(), sanitizePath3(getOriginalCwd())) + sep35;
|
|
422036
421853
|
}
|
|
422037
421854
|
function getScratchpadDir() {
|
|
422038
|
-
return
|
|
421855
|
+
return join161(getProjectTempDir2(), getSessionId(), "scratchpad");
|
|
422039
421856
|
}
|
|
422040
421857
|
async function ensureScratchpadDir() {
|
|
422041
421858
|
if (!isScratchpadEnabled()) {
|
|
@@ -422595,7 +422412,7 @@ function checkEditableInternalPath2(absolutePath, input) {
|
|
|
422595
422412
|
if (feature("TEMPLATES")) {
|
|
422596
422413
|
const jobDir = process.env.ATLAS_JOB_DIR;
|
|
422597
422414
|
if (jobDir) {
|
|
422598
|
-
const jobsRoot =
|
|
422415
|
+
const jobsRoot = join161(getAtlasConfigHomeDir3(), "jobs");
|
|
422599
422416
|
const jobDirForms = getPathsForPermissionCheck2(jobDir).map(normalize15);
|
|
422600
422417
|
const jobsRootForms = getPathsForPermissionCheck2(jobsRoot).map(normalize15);
|
|
422601
422418
|
const isUnderJobsRoot = jobDirForms.every((jd) => jobsRootForms.some((jr) => jd.startsWith(jr + sep35)));
|
|
@@ -422638,7 +422455,7 @@ function checkEditableInternalPath2(absolutePath, input) {
|
|
|
422638
422455
|
}
|
|
422639
422456
|
};
|
|
422640
422457
|
}
|
|
422641
|
-
if (normalizeCaseForComparison2(normalizedPath) === normalizeCaseForComparison2(
|
|
422458
|
+
if (normalizeCaseForComparison2(normalizedPath) === normalizeCaseForComparison2(join161(getOriginalCwd(), getConfigDirName2(), "launch.json"))) {
|
|
422642
422459
|
return {
|
|
422643
422460
|
behavior: "allow",
|
|
422644
422461
|
updatedInput: input,
|
|
@@ -422735,7 +422552,7 @@ function checkReadableInternalPath2(absolutePath, input) {
|
|
|
422735
422552
|
}
|
|
422736
422553
|
};
|
|
422737
422554
|
}
|
|
422738
|
-
const tasksDir =
|
|
422555
|
+
const tasksDir = join161(getAtlasConfigHomeDir3(), "tasks") + sep35;
|
|
422739
422556
|
if (normalizedPath === tasksDir.slice(0, -1) || normalizedPath.startsWith(tasksDir)) {
|
|
422740
422557
|
return {
|
|
422741
422558
|
behavior: "allow",
|
|
@@ -422746,7 +422563,7 @@ function checkReadableInternalPath2(absolutePath, input) {
|
|
|
422746
422563
|
}
|
|
422747
422564
|
};
|
|
422748
422565
|
}
|
|
422749
|
-
const teamsReadDir =
|
|
422566
|
+
const teamsReadDir = join161(getAtlasConfigHomeDir3(), "teams") + sep35;
|
|
422750
422567
|
if (normalizedPath === teamsReadDir.slice(0, -1) || normalizedPath.startsWith(teamsReadDir)) {
|
|
422751
422568
|
return {
|
|
422752
422569
|
behavior: "allow",
|
|
@@ -422823,11 +422640,11 @@ var init_filesystem2 = __esm(() => {
|
|
|
422823
422640
|
try {
|
|
422824
422641
|
resolvedBaseTmpDir = fs.realpathSync(baseTmpDir);
|
|
422825
422642
|
} catch {}
|
|
422826
|
-
return
|
|
422643
|
+
return join161(resolvedBaseTmpDir, getAtlasTempDirName2()) + sep35;
|
|
422827
422644
|
});
|
|
422828
422645
|
getBundledSkillsRoot2 = memoize_default(function getBundledSkillsRoot() {
|
|
422829
422646
|
const nonce = randomBytes21(16).toString("hex");
|
|
422830
|
-
return
|
|
422647
|
+
return join161(getAtlasTempDir2(), "bundled-skills", MACRO.VERSION, nonce);
|
|
422831
422648
|
});
|
|
422832
422649
|
getResolvedWorkingDirPaths2 = memoize_default(getPathsForPermissionCheck2);
|
|
422833
422650
|
});
|
|
@@ -422841,10 +422658,10 @@ import {
|
|
|
422841
422658
|
symlink as symlink7,
|
|
422842
422659
|
unlink as unlink25
|
|
422843
422660
|
} from "fs/promises";
|
|
422844
|
-
import { join as
|
|
422661
|
+
import { join as join162 } from "path";
|
|
422845
422662
|
function getTaskOutputDir2() {
|
|
422846
422663
|
if (_taskOutputDir2 === undefined) {
|
|
422847
|
-
_taskOutputDir2 =
|
|
422664
|
+
_taskOutputDir2 = join162(getProjectTempDir2(), getSessionId(), "tasks");
|
|
422848
422665
|
}
|
|
422849
422666
|
return _taskOutputDir2;
|
|
422850
422667
|
}
|
|
@@ -422852,7 +422669,7 @@ async function ensureOutputDir2() {
|
|
|
422852
422669
|
await mkdir52(getTaskOutputDir2(), { recursive: true });
|
|
422853
422670
|
}
|
|
422854
422671
|
function getTaskOutputPath2(taskId) {
|
|
422855
|
-
return
|
|
422672
|
+
return join162(getTaskOutputDir2(), `${taskId}.output`);
|
|
422856
422673
|
}
|
|
422857
422674
|
function track2(p) {
|
|
422858
422675
|
_pendingOps2.add(p);
|
|
@@ -429778,7 +429595,7 @@ var init_compact4 = __esm(() => {
|
|
|
429778
429595
|
|
|
429779
429596
|
// src/tui/services/SessionMemory/prompts.ts
|
|
429780
429597
|
import { readFile as readFile60 } from "fs/promises";
|
|
429781
|
-
import { join as
|
|
429598
|
+
import { join as join163 } from "path";
|
|
429782
429599
|
function getDefaultUpdatePrompt() {
|
|
429783
429600
|
return `IMPORTANT: This message and these instructions are NOT part of the actual user conversation. Do NOT include any references to "note-taking", "session notes extraction", or these update instructions in the notes content.
|
|
429784
429601
|
|
|
@@ -429819,7 +429636,7 @@ You ONLY update the actual content that comes AFTER these two preserved lines. T
|
|
|
429819
429636
|
REMEMBER: Use the Edit tool in parallel and stop. Do not continue after the edits. Only include insights from the actual user conversation, never from these note-taking instructions. Do not delete or change section headers or italic _section descriptions_.`;
|
|
429820
429637
|
}
|
|
429821
429638
|
async function loadSessionMemoryTemplate() {
|
|
429822
|
-
const templatePath =
|
|
429639
|
+
const templatePath = join163(getAtlasConfigHomeDir3(), "session-memory", "config", "template.md");
|
|
429823
429640
|
try {
|
|
429824
429641
|
return await readFile60(templatePath, { encoding: "utf-8" });
|
|
429825
429642
|
} catch (e) {
|
|
@@ -429832,7 +429649,7 @@ async function loadSessionMemoryTemplate() {
|
|
|
429832
429649
|
}
|
|
429833
429650
|
}
|
|
429834
429651
|
async function loadSessionMemoryPrompt() {
|
|
429835
|
-
const promptPath =
|
|
429652
|
+
const promptPath = join163(getAtlasConfigHomeDir3(), "session-memory", "config", "prompt.md");
|
|
429836
429653
|
try {
|
|
429837
429654
|
return await readFile60(promptPath, { encoding: "utf-8" });
|
|
429838
429655
|
} catch (e) {
|
|
@@ -430438,7 +430255,7 @@ var init_contextHostWiring = __esm(() => {
|
|
|
430438
430255
|
|
|
430439
430256
|
// src/tui/core/executor/AscendFreshnessPort.ts
|
|
430440
430257
|
import { readFileSync as readFileSync22, existsSync as existsSync12 } from "fs";
|
|
430441
|
-
import { join as
|
|
430258
|
+
import { join as join164, dirname as dirname77 } from "path";
|
|
430442
430259
|
|
|
430443
430260
|
class DefaultAscendFreshnessPort {
|
|
430444
430261
|
injectedCache;
|
|
@@ -430452,8 +430269,8 @@ class DefaultAscendFreshnessPort {
|
|
|
430452
430269
|
return env;
|
|
430453
430270
|
let dir = dirname77(new URL(import.meta.url).pathname);
|
|
430454
430271
|
for (let i = 0;i < MAX_WALK_UP; i++) {
|
|
430455
|
-
if (existsSync12(
|
|
430456
|
-
return
|
|
430272
|
+
if (existsSync12(join164(dir, "package.json")))
|
|
430273
|
+
return join164(dir, ".freshness-cache.json");
|
|
430457
430274
|
const parent = dirname77(dir);
|
|
430458
430275
|
if (parent === dir)
|
|
430459
430276
|
break;
|
|
@@ -430926,7 +430743,7 @@ import {
|
|
|
430926
430743
|
dirname as dirname78,
|
|
430927
430744
|
extname as extname17,
|
|
430928
430745
|
isAbsolute as isAbsolute33,
|
|
430929
|
-
join as
|
|
430746
|
+
join as join165,
|
|
430930
430747
|
parse as parse13,
|
|
430931
430748
|
relative as relative29,
|
|
430932
430749
|
sep as sep36
|
|
@@ -431166,7 +430983,7 @@ async function processMdRules({
|
|
|
431166
430983
|
throw e;
|
|
431167
430984
|
}
|
|
431168
430985
|
for (const entry of entries) {
|
|
431169
|
-
const entryPath =
|
|
430986
|
+
const entryPath = join165(rulesDir, entry.name);
|
|
431170
430987
|
const { resolvedPath: resolvedEntryPath, isSymlink } = safeResolvePath3(fs, entryPath);
|
|
431171
430988
|
const stats = isSymlink ? await fs.stat(resolvedEntryPath) : null;
|
|
431172
430989
|
const isDirectory = stats ? stats.isDirectory() : entry.isDirectory();
|
|
@@ -431234,14 +431051,14 @@ async function getMemoryFilesForNestedDirectory(dir, targetPath, processedPaths)
|
|
|
431234
431051
|
if (isSettingSourceEnabled2("projectSettings")) {
|
|
431235
431052
|
const projectPath = findMemoryFile(dir);
|
|
431236
431053
|
result.push(...await processMemoryFile(projectPath, "Project", processedPaths, false));
|
|
431237
|
-
const dotClaudePath = findMemoryFile(
|
|
431054
|
+
const dotClaudePath = findMemoryFile(join165(dir, getConfigDirName2()));
|
|
431238
431055
|
result.push(...await processMemoryFile(dotClaudePath, "Project", processedPaths, false));
|
|
431239
431056
|
}
|
|
431240
431057
|
if (isSettingSourceEnabled2("localSettings")) {
|
|
431241
|
-
const localPath =
|
|
431058
|
+
const localPath = join165(dir, "CLAUDE.local.md");
|
|
431242
431059
|
result.push(...await processMemoryFile(localPath, "Local", processedPaths, false));
|
|
431243
431060
|
}
|
|
431244
|
-
const rulesDir =
|
|
431061
|
+
const rulesDir = join165(dir, getConfigDirName2(), "rules");
|
|
431245
431062
|
const unconditionalProcessedPaths = new Set(processedPaths);
|
|
431246
431063
|
result.push(...await processMdRules({
|
|
431247
431064
|
rulesDir,
|
|
@@ -431257,7 +431074,7 @@ async function getMemoryFilesForNestedDirectory(dir, targetPath, processedPaths)
|
|
|
431257
431074
|
return result;
|
|
431258
431075
|
}
|
|
431259
431076
|
async function getConditionalRulesForCwdLevelDirectory(dir, targetPath, processedPaths) {
|
|
431260
|
-
const rulesDir =
|
|
431077
|
+
const rulesDir = join165(dir, getConfigDirName2(), "rules");
|
|
431261
431078
|
return processConditionedMdRules(targetPath, rulesDir, "Project", processedPaths, false);
|
|
431262
431079
|
}
|
|
431263
431080
|
async function processConditionedMdRules(targetPath, rulesDir, type, processedPaths, includeExternal) {
|
|
@@ -431513,9 +431330,9 @@ var init_memoryFiles = __esm(() => {
|
|
|
431513
431330
|
if (isSettingSourceEnabled2("projectSettings") && !skipProject) {
|
|
431514
431331
|
const projectPath = findMemoryFile(dir);
|
|
431515
431332
|
result.push(...await processMemoryFile(projectPath, "Project", processedPaths, includeExternal));
|
|
431516
|
-
const dotClaudePath = findMemoryFile(
|
|
431333
|
+
const dotClaudePath = findMemoryFile(join165(dir, getConfigDirName2()));
|
|
431517
431334
|
result.push(...await processMemoryFile(dotClaudePath, "Project", processedPaths, includeExternal));
|
|
431518
|
-
const rulesDir =
|
|
431335
|
+
const rulesDir = join165(dir, getConfigDirName2(), "rules");
|
|
431519
431336
|
result.push(...await processMdRules({
|
|
431520
431337
|
rulesDir,
|
|
431521
431338
|
type: "Project",
|
|
@@ -431525,7 +431342,7 @@ var init_memoryFiles = __esm(() => {
|
|
|
431525
431342
|
}));
|
|
431526
431343
|
}
|
|
431527
431344
|
if (isSettingSourceEnabled2("localSettings")) {
|
|
431528
|
-
const localPath =
|
|
431345
|
+
const localPath = join165(dir, "CLAUDE.local.md");
|
|
431529
431346
|
result.push(...await processMemoryFile(localPath, "Local", processedPaths, includeExternal));
|
|
431530
431347
|
}
|
|
431531
431348
|
}
|
|
@@ -431534,9 +431351,9 @@ var init_memoryFiles = __esm(() => {
|
|
|
431534
431351
|
for (const dir of additionalDirs) {
|
|
431535
431352
|
const projectPath = findMemoryFile(dir);
|
|
431536
431353
|
result.push(...await processMemoryFile(projectPath, "Project", processedPaths, includeExternal));
|
|
431537
|
-
const dotClaudePath = findMemoryFile(
|
|
431354
|
+
const dotClaudePath = findMemoryFile(join165(dir, getConfigDirName2()));
|
|
431538
431355
|
result.push(...await processMemoryFile(dotClaudePath, "Project", processedPaths, includeExternal));
|
|
431539
|
-
const rulesDir =
|
|
431356
|
+
const rulesDir = join165(dir, getConfigDirName2(), "rules");
|
|
431540
431357
|
result.push(...await processMdRules({
|
|
431541
431358
|
rulesDir,
|
|
431542
431359
|
type: "Project",
|
|
@@ -440060,7 +439877,7 @@ var init_AutoModeConfirm = __esm(() => {
|
|
|
440060
439877
|
|
|
440061
439878
|
// src/tui/components/permissions/FilePermissionDialog/permissionOptions.tsx
|
|
440062
439879
|
import { homedir as homedir39 } from "os";
|
|
440063
|
-
import { basename as basename54, join as
|
|
439880
|
+
import { basename as basename54, join as join166, sep as sep37 } from "path";
|
|
440064
439881
|
function isInClaudeFolder(filePath) {
|
|
440065
439882
|
const absolutePath = expandPath2(filePath);
|
|
440066
439883
|
const claudeFolderPath = expandPath2(`${getOriginalCwd()}/${getConfigDirName2()}`);
|
|
@@ -440070,7 +439887,7 @@ function isInClaudeFolder(filePath) {
|
|
|
440070
439887
|
}
|
|
440071
439888
|
function isInGlobalClaudeFolder(filePath) {
|
|
440072
439889
|
const absolutePath = expandPath2(filePath);
|
|
440073
|
-
const globalClaudeFolderPath =
|
|
439890
|
+
const globalClaudeFolderPath = join166(homedir39(), getConfigDirName2());
|
|
440074
439891
|
const normalizedAbsolutePath = normalizeCaseForComparison2(absolutePath);
|
|
440075
439892
|
const normalizedGlobalClaudeFolderPath = normalizeCaseForComparison2(globalClaudeFolderPath);
|
|
440076
439893
|
return normalizedAbsolutePath.startsWith(normalizedGlobalClaudeFolderPath + sep37.toLowerCase()) || normalizedAbsolutePath.startsWith(normalizedGlobalClaudeFolderPath + "/");
|
|
@@ -457791,10 +457608,10 @@ var init_segments = __esm(() => {
|
|
|
457791
457608
|
|
|
457792
457609
|
// src/tui/components/StatusLine/segments/statusLineConfig.ts
|
|
457793
457610
|
import { readFileSync as readFileSync23, existsSync as existsSync13, writeFileSync as writeFileSync9, renameSync as renameSync3, mkdirSync as mkdirSync9 } from "fs";
|
|
457794
|
-
import { join as
|
|
457611
|
+
import { join as join167 } from "path";
|
|
457795
457612
|
import { homedir as homedir41 } from "os";
|
|
457796
457613
|
function getStatusLineJsonPath() {
|
|
457797
|
-
return
|
|
457614
|
+
return join167(homedir41(), getConfigDirName2(), "statusline.json");
|
|
457798
457615
|
}
|
|
457799
457616
|
function getDefaultConfig() {
|
|
457800
457617
|
return {
|
|
@@ -463219,7 +463036,7 @@ var init_autoDream = __esm(() => {
|
|
|
463219
463036
|
});
|
|
463220
463037
|
|
|
463221
463038
|
// src/tui/utils/cleanup.ts
|
|
463222
|
-
import { join as
|
|
463039
|
+
import { join as join168 } from "path";
|
|
463223
463040
|
function getCutoffDate() {
|
|
463224
463041
|
const settings = getSettings_DEPRECATED() || {};
|
|
463225
463042
|
const cleanupPeriodDays = settings.cleanupPeriodDays ?? DEFAULT_CLEANUP_PERIOD_DAYS;
|
|
@@ -463244,7 +463061,7 @@ async function cleanupOldFilesInDirectory(dirPath, cutoffDate, isMessagePath) {
|
|
|
463244
463061
|
try {
|
|
463245
463062
|
const timestamp = convertFileNameToDate(file.name);
|
|
463246
463063
|
if (timestamp < cutoffDate) {
|
|
463247
|
-
await getFsImplementation2().unlink(
|
|
463064
|
+
await getFsImplementation2().unlink(join168(dirPath, file.name));
|
|
463248
463065
|
if (isMessagePath) {
|
|
463249
463066
|
result.messages++;
|
|
463250
463067
|
} else {
|
|
@@ -463275,7 +463092,7 @@ async function cleanupOldMessageFiles() {
|
|
|
463275
463092
|
} catch {
|
|
463276
463093
|
return result;
|
|
463277
463094
|
}
|
|
463278
|
-
const mcpLogDirs = dirents.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("mcp-logs-")).map((dirent) =>
|
|
463095
|
+
const mcpLogDirs = dirents.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("mcp-logs-")).map((dirent) => join168(baseCachePath, dirent.name));
|
|
463279
463096
|
for (const mcpLogDir of mcpLogDirs) {
|
|
463280
463097
|
result = addCleanupResults(result, await cleanupOldFilesInDirectory(mcpLogDir, cutoffDate, true));
|
|
463281
463098
|
await tryRmdir(mcpLogDir, fsImpl);
|
|
@@ -463314,7 +463131,7 @@ async function cleanupOldSessionFiles() {
|
|
|
463314
463131
|
for (const projectDirent of projectDirents) {
|
|
463315
463132
|
if (!projectDirent.isDirectory())
|
|
463316
463133
|
continue;
|
|
463317
|
-
const projectDir =
|
|
463134
|
+
const projectDir = join168(projectsDir, projectDirent.name);
|
|
463318
463135
|
let entries;
|
|
463319
463136
|
try {
|
|
463320
463137
|
entries = await fsImpl.readdir(projectDir);
|
|
@@ -463328,15 +463145,15 @@ async function cleanupOldSessionFiles() {
|
|
|
463328
463145
|
continue;
|
|
463329
463146
|
}
|
|
463330
463147
|
try {
|
|
463331
|
-
if (await unlinkIfOld(
|
|
463148
|
+
if (await unlinkIfOld(join168(projectDir, entry.name), cutoffDate, fsImpl)) {
|
|
463332
463149
|
result.messages++;
|
|
463333
463150
|
}
|
|
463334
463151
|
} catch {
|
|
463335
463152
|
result.errors++;
|
|
463336
463153
|
}
|
|
463337
463154
|
} else if (entry.isDirectory()) {
|
|
463338
|
-
const sessionDir =
|
|
463339
|
-
const toolResultsDir =
|
|
463155
|
+
const sessionDir = join168(projectDir, entry.name);
|
|
463156
|
+
const toolResultsDir = join168(sessionDir, TOOL_RESULTS_SUBDIR3);
|
|
463340
463157
|
let toolDirs;
|
|
463341
463158
|
try {
|
|
463342
463159
|
toolDirs = await fsImpl.readdir(toolResultsDir);
|
|
@@ -463347,14 +463164,14 @@ async function cleanupOldSessionFiles() {
|
|
|
463347
463164
|
for (const toolEntry of toolDirs) {
|
|
463348
463165
|
if (toolEntry.isFile()) {
|
|
463349
463166
|
try {
|
|
463350
|
-
if (await unlinkIfOld(
|
|
463167
|
+
if (await unlinkIfOld(join168(toolResultsDir, toolEntry.name), cutoffDate, fsImpl)) {
|
|
463351
463168
|
result.messages++;
|
|
463352
463169
|
}
|
|
463353
463170
|
} catch {
|
|
463354
463171
|
result.errors++;
|
|
463355
463172
|
}
|
|
463356
463173
|
} else if (toolEntry.isDirectory()) {
|
|
463357
|
-
const toolDirPath =
|
|
463174
|
+
const toolDirPath = join168(toolResultsDir, toolEntry.name);
|
|
463358
463175
|
let toolFiles;
|
|
463359
463176
|
try {
|
|
463360
463177
|
toolFiles = await fsImpl.readdir(toolDirPath);
|
|
@@ -463365,7 +463182,7 @@ async function cleanupOldSessionFiles() {
|
|
|
463365
463182
|
if (!tf.isFile())
|
|
463366
463183
|
continue;
|
|
463367
463184
|
try {
|
|
463368
|
-
if (await unlinkIfOld(
|
|
463185
|
+
if (await unlinkIfOld(join168(toolDirPath, tf.name), cutoffDate, fsImpl)) {
|
|
463369
463186
|
result.messages++;
|
|
463370
463187
|
}
|
|
463371
463188
|
} catch {
|
|
@@ -463397,7 +463214,7 @@ async function cleanupSingleDirectory(dirPath, extension, removeEmptyDir = true)
|
|
|
463397
463214
|
if (!dirent.isFile() || !dirent.name.endsWith(extension))
|
|
463398
463215
|
continue;
|
|
463399
463216
|
try {
|
|
463400
|
-
if (await unlinkIfOld(
|
|
463217
|
+
if (await unlinkIfOld(join168(dirPath, dirent.name), cutoffDate, fsImpl)) {
|
|
463401
463218
|
result.messages++;
|
|
463402
463219
|
}
|
|
463403
463220
|
} catch {
|
|
@@ -463410,7 +463227,7 @@ async function cleanupSingleDirectory(dirPath, extension, removeEmptyDir = true)
|
|
|
463410
463227
|
return result;
|
|
463411
463228
|
}
|
|
463412
463229
|
function cleanupOldPlanFiles() {
|
|
463413
|
-
const plansDir =
|
|
463230
|
+
const plansDir = join168(getAtlasConfigHomeDir3(), "plans");
|
|
463414
463231
|
return cleanupSingleDirectory(plansDir, ".md");
|
|
463415
463232
|
}
|
|
463416
463233
|
async function cleanupOldFileHistoryBackups() {
|
|
@@ -463419,14 +463236,14 @@ async function cleanupOldFileHistoryBackups() {
|
|
|
463419
463236
|
const fsImpl = getFsImplementation2();
|
|
463420
463237
|
try {
|
|
463421
463238
|
const configDir = getAtlasConfigHomeDir3();
|
|
463422
|
-
const fileHistoryStorageDir =
|
|
463239
|
+
const fileHistoryStorageDir = join168(configDir, "file-history");
|
|
463423
463240
|
let dirents;
|
|
463424
463241
|
try {
|
|
463425
463242
|
dirents = await fsImpl.readdir(fileHistoryStorageDir);
|
|
463426
463243
|
} catch {
|
|
463427
463244
|
return result;
|
|
463428
463245
|
}
|
|
463429
|
-
const fileHistorySessionsDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
463246
|
+
const fileHistorySessionsDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join168(fileHistoryStorageDir, dirent.name));
|
|
463430
463247
|
await Promise.all(fileHistorySessionsDirs.map(async (fileHistorySessionDir) => {
|
|
463431
463248
|
try {
|
|
463432
463249
|
const stats = await fsImpl.stat(fileHistorySessionDir);
|
|
@@ -463453,14 +463270,14 @@ async function cleanupOldSessionEnvDirs() {
|
|
|
463453
463270
|
const fsImpl = getFsImplementation2();
|
|
463454
463271
|
try {
|
|
463455
463272
|
const configDir = getAtlasConfigHomeDir3();
|
|
463456
|
-
const sessionEnvBaseDir =
|
|
463273
|
+
const sessionEnvBaseDir = join168(configDir, "session-env");
|
|
463457
463274
|
let dirents;
|
|
463458
463275
|
try {
|
|
463459
463276
|
dirents = await fsImpl.readdir(sessionEnvBaseDir);
|
|
463460
463277
|
} catch {
|
|
463461
463278
|
return result;
|
|
463462
463279
|
}
|
|
463463
|
-
const sessionEnvDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
463280
|
+
const sessionEnvDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join168(sessionEnvBaseDir, dirent.name));
|
|
463464
463281
|
for (const sessionEnvDir of sessionEnvDirs) {
|
|
463465
463282
|
try {
|
|
463466
463283
|
const stats = await fsImpl.stat(sessionEnvDir);
|
|
@@ -463482,7 +463299,7 @@ async function cleanupOldDebugLogs() {
|
|
|
463482
463299
|
const cutoffDate = getCutoffDate();
|
|
463483
463300
|
const result = { messages: 0, errors: 0 };
|
|
463484
463301
|
const fsImpl = getFsImplementation2();
|
|
463485
|
-
const debugDir =
|
|
463302
|
+
const debugDir = join168(getAtlasConfigHomeDir3(), "debug");
|
|
463486
463303
|
let dirents;
|
|
463487
463304
|
try {
|
|
463488
463305
|
dirents = await fsImpl.readdir(debugDir);
|
|
@@ -463494,7 +463311,7 @@ async function cleanupOldDebugLogs() {
|
|
|
463494
463311
|
continue;
|
|
463495
463312
|
}
|
|
463496
463313
|
try {
|
|
463497
|
-
if (await unlinkIfOld(
|
|
463314
|
+
if (await unlinkIfOld(join168(debugDir, dirent.name), cutoffDate, fsImpl)) {
|
|
463498
463315
|
result.messages++;
|
|
463499
463316
|
}
|
|
463500
463317
|
} catch {
|
|
@@ -464939,10 +464756,10 @@ var init_coordinatorHandler = __esm(() => {
|
|
|
464939
464756
|
});
|
|
464940
464757
|
|
|
464941
464758
|
// src/tui/utils/permissions/sessionPermissionRules.ts
|
|
464942
|
-
import { mkdir as mkdir53, readFile as readFile61, rename as rename11, writeFile as
|
|
464943
|
-
import { dirname as dirname80, join as
|
|
464759
|
+
import { mkdir as mkdir53, readFile as readFile61, rename as rename11, writeFile as writeFile48 } from "fs/promises";
|
|
464760
|
+
import { dirname as dirname80, join as join170 } from "path";
|
|
464944
464761
|
function sessionRulesPath(sessionId, projectDir) {
|
|
464945
|
-
return
|
|
464762
|
+
return join170(projectDir, `${sessionId}${SESSION_RULES_FILE_SUFFIX}`);
|
|
464946
464763
|
}
|
|
464947
464764
|
function parseSessionRulesJson(json) {
|
|
464948
464765
|
if (json.length > MAX_SESSION_RULES_BYTES)
|
|
@@ -465002,7 +464819,7 @@ async function mergeSessionPermissionRules(sessionId, projectDir, updates) {
|
|
|
465002
464819
|
await mkdir53(projectDir, { recursive: true });
|
|
465003
464820
|
const target = sessionRulesPath(sessionId, projectDir);
|
|
465004
464821
|
const tmp = `${target}.tmp-${process.pid}`;
|
|
465005
|
-
await
|
|
464822
|
+
await writeFile48(tmp, JSON.stringify({ version: 1, updates: merged }, null, 2));
|
|
465006
464823
|
await rename11(tmp, target);
|
|
465007
464824
|
return true;
|
|
465008
464825
|
} catch (e) {
|
|
@@ -467929,7 +467746,7 @@ var init_conversationRecovery = __esm(() => {
|
|
|
467929
467746
|
|
|
467930
467747
|
// src/tui/utils/asciicast.ts
|
|
467931
467748
|
import { appendFile as appendFile6, rename as rename12 } from "fs/promises";
|
|
467932
|
-
import { basename as basename63, dirname as dirname81, join as
|
|
467749
|
+
import { basename as basename63, dirname as dirname81, join as join172 } from "path";
|
|
467933
467750
|
function getRecordFilePath() {
|
|
467934
467751
|
if (recordingState.filePath !== null) {
|
|
467935
467752
|
return recordingState.filePath;
|
|
@@ -467940,10 +467757,10 @@ function getRecordFilePath() {
|
|
|
467940
467757
|
if (!isEnvTruthy2(process.env.ATLAS_TERMINAL_RECORDING)) {
|
|
467941
467758
|
return null;
|
|
467942
467759
|
}
|
|
467943
|
-
const projectsDir =
|
|
467944
|
-
const projectDir =
|
|
467760
|
+
const projectsDir = join172(getAtlasConfigHomeDir3(), "projects");
|
|
467761
|
+
const projectDir = join172(projectsDir, sanitizePath3(getOriginalCwd()));
|
|
467945
467762
|
recordingState.timestamp = Date.now();
|
|
467946
|
-
recordingState.filePath =
|
|
467763
|
+
recordingState.filePath = join172(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
|
|
467947
467764
|
return recordingState.filePath;
|
|
467948
467765
|
}
|
|
467949
467766
|
async function renameRecordingForSession() {
|
|
@@ -467951,9 +467768,9 @@ async function renameRecordingForSession() {
|
|
|
467951
467768
|
if (!oldPath || recordingState.timestamp === 0) {
|
|
467952
467769
|
return;
|
|
467953
467770
|
}
|
|
467954
|
-
const projectsDir =
|
|
467955
|
-
const projectDir =
|
|
467956
|
-
const newPath =
|
|
467771
|
+
const projectsDir = join172(getAtlasConfigHomeDir3(), "projects");
|
|
467772
|
+
const projectDir = join172(projectsDir, sanitizePath3(getOriginalCwd()));
|
|
467773
|
+
const newPath = join172(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
|
|
467957
467774
|
if (oldPath === newPath) {
|
|
467958
467775
|
return;
|
|
467959
467776
|
}
|
|
@@ -469366,6 +469183,98 @@ var init_useAwaySummary = __esm(() => {
|
|
|
469366
469183
|
BLUR_DELAY_MS = 5 * 60000;
|
|
469367
469184
|
});
|
|
469368
469185
|
|
|
469186
|
+
// src/tui/utils/plugins/builtinMarketplaceSnapshots.ts
|
|
469187
|
+
function getBuiltinMarketplaceSnapshot(key) {
|
|
469188
|
+
return BUILTIN_MARKETPLACE_SNAPSHOTS.find((s) => s.key === key);
|
|
469189
|
+
}
|
|
469190
|
+
var BUILTIN_MARKETPLACE_SNAPSHOTS;
|
|
469191
|
+
var init_builtinMarketplaceSnapshots = __esm(() => {
|
|
469192
|
+
BUILTIN_MARKETPLACE_SNAPSHOTS = [
|
|
469193
|
+
{ key: "agent-skills", manifest: { name: "agent-skills", owner: { name: "agent-skills", url: "https://gitcode.com/Ascend/agent-skills" }, plugins: [{ name: "cannbot-ops-direct-invoke-skills", description: "Ascend C Kernel 直调算子开发 Skills(27 个)。API 检索、Tiling 设计、精度调试、性能采集、环境检查、代码模板、SIMT 最佳实践等。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.0.4", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["ascendc", "skills", "direct-invoke", "operator", "kernel", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./ascendc-api-best-practices", "./ascendc-regbase-best-practice", "./ascendc-blaze-best-practice", "./ascendc-code-review", "./ascendc-direct-invoke-template", "./ascendc-docs-search", "./ascendc-env-check", "./npu-arch", "./ascendc-precision-debug", "./ascendc-runtime-debug", "./ascendc-crash-debug", "./ascendc-tiling-design", "./ops-precision-standard", "./ops-profiling", "./torch-ascendc-op-extension", "./ascendc-direct-invoke-to-registry-invoke", "./ascendc-docs-gen", "./ascendc-performance-best-practices", "./ascendc-perf-optimize", "./ascendc-registry-invoke-template", "./ascendc-registry-invoke-to-direct-invoke", "./ascendc-simt-best-practices", "./ascendc-simt-tiling-design", "./ascendc-st-design", "./ascendc-task-focus", "./ascendc-ut-develop", "./ascendc-whitebox-design", "./cann-env-setup", "./ops-simulator", "./ops-spec-gen", "./torch-ops-profiler"] }, { name: "cannbot-aiss-tiling-solver", description: "AISS-TilingSolver:Ascend C 算子 Tiling 参数自动求解工具(MatMul / Vector)。下载安装、构造 JSON 输入、运行求解、结果解读与故障排查。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.0.0", author: { name: "AISS Group at HIT", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["tiling_solver", "MatMul", "Vector", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./aiss-tiling-solver"] }, { name: "cannbot-catlass-op-skills", description: "Catlass 算子开发 Skills(3 个)。算子设计、算子开发、性能调优。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["catlass", "skills", "operator", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./catlass-op-design", "./catlass-op-develop", "./catlass-op-perf-tune"] }, { name: "cannbot-pypto-op-orchestrator-skills", description: "PyPTO 算子开发 Skills(8 个)。API 探索、Golden 生成、需求理解、算子设计与开发、性能调优、精度调试。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.1.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["pypto", "skills", "operator", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./pypto-api-explore", "./pypto-golden-generate", "./pypto-intent-understand", "./pypto-op-design", "./pypto-op-develop", "./pypto-op-perf-tune", "./pypto-precision-compare", "./pypto-precision-debug"] }, { name: "cannbot-triton-op-generator-skills", description: "Triton-Ascend 算子代码生成与优化 Skills(6 个)。任务提取、算法设计、代码生成、功能验证、性能优化,以及 NPU 架构参考。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["triton", "ascend", "skills", "operator", "generator", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./triton-task-extractor", "./triton-op-designer", "./triton-op-coding", "./triton-op-verifier", "./triton-latency-optimizer", "./npu-arch"] }, { name: "cannbot-torch-npugraph-ex-skills", description: "PyTorch 昇腾 NPU npugraph_ex Skills(7 个)。覆盖图模式知识、代码模板、性能诊断、问题分诊、编译错误、运行时错误和自定义算子入图。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/graph", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["torch", "torchair", "npugraph_ex", "npu", "skills", "cannbot"], scenarios: ["inference", "operator"], category: "skill-pack", skills: ["./torch-custom-ops-guide", "./torch-npugraph-ex-compile-error-diagnosis", "./torch-npugraph-ex-dfx-triage", "./torch-npugraph-ex-knowledge", "./torch-npugraph-ex-performance-diagnosis", "./torch-npugraph-ex-runtime-error-diagnosis", "./torch-npugraph-ex-template"] }, { name: "cannbot-model-infer-skills", description: "NPU 模型推理优化 Skills(11 个)。覆盖框架适配、并行策略、KVCache/FA、融合算子、图模式、精度/运行时调试、多流、预取和 SuperKernel。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/model", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["model-infer", "skills", "inference", "kvcache", "graph-mode", "cannbot"], scenarios: ["inference", "operator"], category: "skill-pack", skills: ["./model-infer-migrator", "./model-infer-parallel-analysis", "./model-infer-parallel-impl", "./model-infer-kvcache", "./model-infer-fusion", "./model-infer-graph-mode", "./model-infer-precision-debug", "./model-infer-runtime-debug", "./model-infer-multi-stream", "./model-infer-prefetch", "./model-infer-superkernel"] }, { name: "cannbot-tilelang-op-orchestrator-skills", description: "TileLang 算子开发 Skills(9 个)。环境检查、子模块拉取、算子设计、算子开发、测试设计、API 最佳实践、编程模式指南、性能优化、代码审查。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops-lab/tilelang/skills", strict: false, version: "1.1.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["tilelang", "skills", "cannbot"], scenarios: ["operator"], category: "skill-pack", skills: ["./tilelang-api-best-practices", "./tilelang-env-check", "./tilelang-op-design", "./tilelang-op-develop", "./tilelang-op-test-design", "./tilelang-perf-optimization", "./tilelang-programming-model-guide", "./tilelang-review", "./tilelang-submodule-pull"] }, { name: "cannbot-cuda2ascend-simt-skills", description: "CUDA→Ascend SIMT 迁移 Skills(1 个)。CUDA 到 Ascend C SIMT 编程模型的代码迁移,含 API 映射、语法规则、约束校验。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/ops-lab", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["cuda", "ascend", "simt", "migration", "cannbot"], scenarios: ["operator", "migration"], category: "skill-pack", skills: ["./cuda2ascend-simt"] }, { name: "cannbot-infra-skills", description: "CANNBot 基础设施 Skills(5 个)。Skill 审查、GitCode Issue 生成/处理、PR 处理、GitCode 工具集。通过 submodule 从 cannbot-skills 仓库同步。", source: "./official/CANNBot/infra", strict: false, version: "1.0.0", author: { name: "CANNBot", url: "https://gitcode.com/cann/cannbot-skills" }, keywords: ["infra", "gitcode", "code-review", "issue", "pr", "cannbot"], scenarios: ["code-review", "devops"], category: "skill-pack", skills: ["./cannbot-skill-reviewer", "./gitcode-issue-gen", "./gitcode-issue-handler", "./gitcode-pr-handler", "./gitcode-toolkit"] }, { name: "common-infra-skills", description: "昇腾 NPU 通用基础设施 Skills(6 个)。Docker 容器创建、NPU 驱动/固件安装、CANN 全套组件安装、算子环境配置、SwanLab 实验追踪配置、npu-smi 设备管理。触发:昇腾 NPU 开发环境搭建与运维场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "infra", "env-setup", "docker", "cann", "npu"], scenarios: ["env-setup", "deployment"], category: "skill-pack", skills: ["./ascend-docker", "./ascend-npu-driver-install", "./cann-nnal-installer", "./cann-operator-env-config", "./swanlab-setup", "./npu-smi"] }, { name: "common-ops-skills", description: "昇腾 NPU 通用运维与工具 Skills(6 个)。Profiling 异常分析、故障诊断、HCCL 通信测试、ModelScope 下载、大规模集群部署、K8s 健康检查。触发:昇腾 NPU 集群运维、性能诊断、模型下载场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "ops", "profiling", "fault-diagnose", "hccl", "modelscope", "k8s"], scenarios: ["profiling", "deployment"], category: "skill-pack", skills: ["./ascend-profiling-anomaly", "./fault_diagnose", "./hccl-test", "./modelscope-cli", "./large_scale_deploy", "./k8s-check-fix"] }, { name: "common-dev-skills", description: "昇腾 NPU 通用开发辅助 Skills(6 个)。Bug 自动修复、单元测试自动生成、Python 代码重构、安全代码审查、Skill 安全审计、Arxiv 论文推荐与 NPU 适配。触发:代码质量提升、安全审查、测试补充场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "dev", "code-review", "testing", "security", "refactoring"], scenarios: ["code-review", "testing", "documentation"], category: "skill-pack", skills: ["./auto-bug-fixer", "./auto-develop-test-gen", "./python-refactoring", "./security-code-review", "./skill-auditor", "./arxiv-recommendation-npu"] }, { name: "common-migration-skills", description: "昇腾 NPU 通用模型迁移 Skills(5 个)。推理仓库智能问答、ATC 模型转换全流程、msverl 日回归分诊、NPU 适配审查、PyTorch 模型自动化 NPU 迁移。触发:模型迁移到 NPU、GPU→NPU 适配、推理服务部署场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "migration", "npu", "atc", "inference", "model-convert"], scenarios: ["migration", "inference"], category: "skill-pack", skills: ["./ascend-inference-repos-copilot", "./atc-model-converter", "./msverl-daily-regression-triage", "./npu-adapter-reviewer", "./npu-model-migration"] }, { name: "common-deploy-skills", description: "昇腾 NPU 通用部署 Skills(3 个)。OM 部署器、OM Pipeline 适配器、ONNX-ATC 推理 Pipeline。触发:模型部署、推理服务构建场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "deploy", "om", "atc", "onnx", "pipeline"], scenarios: ["deployment", "inference"], category: "skill-pack", skills: ["./ascend-om-deployer", "./ascend-om-pipeline-adapter", "./ascend-onnx-atc-pipeline"] }, { name: "common-ut-skills", description: "昇腾 NPU 算子单元测试 Skills(2 个)。算子 UT 自动生成、操作系统适配。触发:算子测试开发、UT 补充场景。", source: "./official/Common", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascend", "ut", "unit-test", "operator", "os-adapter"], scenarios: ["testing"], category: "skill-pack", skills: ["./ascend-operator-ut-gen", "./os_adapter"] }, { name: "ascend-transformer-boost-skills", description: "昇腾 Transformer 加速库(ATB)核心 Skills(15 个)。整合 ATB 测试框架编译、算子替换设计、ATB→ACLNN 算子迁移、CSV/ATK 测试用例生成与运行、Golden 开发、调试指南、NNAL 安装、迁移工作流、知识提取、知识维护、知识泛化、Pybind 代码生成全流程。触发:ATB 开发、ACLNN 迁移、Transformer 加速场景。", source: "./official/Common/ascend-transformer-boost", strict: false, version: "1.11.0", author: { name: "community" }, keywords: ["ascend", "atb", "transformer", "aclnn", "operator", "migration"], scenarios: ["operator", "inference", "migration"], category: "skill-pack", skills: ["./skills/atb-aclnn-operator-migration", "./skills/atb-aclnn-operator-replacement-designer", "./skills/atb-atk-testcase-generator", "./skills/atb-csv-testcase-generator", "./skills/atb-csv-tester", "./skills/atb-debug-guide", "./skills/atb-golden-developer", "./skills/atb-nnal-installer", "./skills/atb-ops-to-aclnn-migration-workflow", "./skills/atb-pybind-bindgen", "./skills/atb-pybind-test-generator", "./skills/atb-testframework-build", "./skills/atb-op-knowledge-extract", "./skills/atb-op-knowledge-update", "./skills/atb-knowledge-generalize"] }, { name: "mindspeed-megatron-skills", description: "MindSpeed Megatron 变更追踪与迁移 Skills(4 个)。Megatron 变更分析、Commit 追踪与规范化、Impact 映射到 MindSpeed 子系统、迁移交付物生成。触发:Megatron-LM 上游变更同步、MindSpeed 适配时。", source: "./official/MindSpeed", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "megatron", "migration", "commit-tracking", "impact"], scenarios: ["migration", "training"], category: "skill-pack", skills: ["./megatron-change-analyzer", "./megatron-commit-tracker", "./megatron-impact-mapper", "./megatron-migration-generator"] }, { name: "mindspeed-drivingsdk-skills", description: "MindSpeed 自驾 SDK 模型迁移 Skills(14 个)。模型代码迁移、NPU 训练、SSH 远程开发套件(连接/部署/调试/隧道/长任务)、MMLab 安装套件(mmcv/mmdet/mmdet3d/detectron2)。触发:自驾模型 NPU 适配迁移场景。", source: "./official/MindSpeed/drivingsdk-ascend-model-migration", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "drivingsdk", "model-migration", "npu", "ssh", "mmlab"], scenarios: ["migration", "training", "env-setup"], category: "skill-pack", skills: ["./ascend-mmlab-install-suite", "./ascend-mmlab-install-suite/detectron2", "./ascend-mmlab-install-suite/mmcv", "./ascend-mmlab-install-suite/mmdet", "./ascend-mmlab-install-suite/mmdet3d", "./model-migration", "./model-training", "./ssh-connection", "./ssh-connection/connect", "./ssh-connection/debug", "./ssh-connection/deploy", "./ssh-connection/long-task", "./ssh-connection/tunnel"] }, { name: "drivingsdk-model-migration-analysis", description: "自驾模型 NPU 适配技能。提供从模型分析、算子替换、适配方案到优化总结的完整流程。当用户需要将新的自动驾驶模型或 VLA 世界模型适配到昇腾 NPU 时触发。", source: "./official/MindSpeed", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "drivingsdk", "model-migration", "npu", "vla"], scenarios: ["migration"], category: "atomic-skill", skills: ["./drivingsdk-model-migration-analysis"] }, { name: "mindspeed-llm-ut-skills", description: "MindSpeed LLM 自动单元测试 Skills(7 个)。覆盖率分析、代码理解、覆盖率扫描、测试生成、pytest 编写、unittest 编写、测试运行。触发:MindSpeed-LLM 项目测试开发与覆盖率提升场景。", source: "./official/MindSpeed/mindspeed-llm-auto-ut-skills/skills", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "llm", "unit-test", "coverage", "pytest", "unittest"], scenarios: ["testing"], category: "skill-pack", skills: ["./analyse-coverage", "./code-comprehension", "./coverage", "./generate-unit-test", "./pytest-writer", "./run-mindspeed-llm-test", "./unittest-writer"] }, { name: "mindspeed-fsdp2-skills", description: "MindSpeed-MM FSDP2 端到端迁移 Skills(5 个)。统筹模型/数据/配置/验证子流程迁移,实现 MindSpeed-MM 到 FSDP2 的完整适配。触发:MindSpeed-MM FSDP2 迁移场景。", source: "./official/MindSpeed/mindspeed-mm-fsdp2-migration", strict: false, version: "1.0.0", author: { name: "MindSpeed" }, keywords: ["mindspeed", "fsdp2", "migration", "model", "config", "verification"], scenarios: ["migration", "training"], category: "skill-pack", skills: ["./mindspeed-fsdp2-config-migration", "./mindspeed-fsdp2-data-migration", "./mindspeed-fsdp2-migration-main", "./mindspeed-fsdp2-model-migration", "./mindspeed-fsdp2-verification"] }, { name: "vllm-ascend-skills", description: "vLLM Ascend 推理部署与测试 Skills(3 个)。vLLM Ascend 服务部署、FAQ 生成、测试失败分析。触发:vLLM 在昇腾 NPU 上的部署与问题排查场景。", source: "./official/vllm-ascend", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["vllm", "ascend", "npu", "deploy", "faq", "test"], scenarios: ["inference", "deployment"], category: "skill-pack", skills: ["./vllm-ascend-deploy", "./vLLM-ascend_FAQ_Generator", "./vllm-tests-failure-analysis"] }, { name: "verl-skills", description: "VERL 强化学习训练 Skills(2 个)。VERL 特性部署与异步 DAPO 训练。触发:VERL 强化学习框架在昇腾 NPU 上的部署与训练场景。", source: "./official/verl", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["verl", "rlhf", "dapo", "training", "npu"], scenarios: ["training"], category: "skill-pack", skills: ["./verl-feature-deploy", "./verl-async-dapo"] }, { name: "mindstudio-profiling-skills", description: "MindStudio Profiler 性能分析 Skills(9 个)。Profiler 数据校验、计算/通信/调度分析、DB Explorer、集群快慢 Rank 检测、算子 Profiler(msOpProf)、MFU 计算、msprof-analyze CLI。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "profiler", "performance", "analysis", "communication", "computation", "schedule", "mfu"], scenarios: ["profiling", "operator"], category: "skill-pack", skills: ["./mindstudio_profiler_data_check", "./ascend-profiler-db-explorer", "./ascend-computation-analysis", "./ascend-communication-analysis", "./ascend-schedule-analysis", "./cluster-fast-slow-rank-detector", "./msot-msopprof-operator-profiler", "./op-mfu-calculator", "./msprof-analyze-cli"] }, { name: "mindstudio-precision-debug-skills", description: "MindStudio 精度调试 Skills(3 个)。确定性计算分析、NaN/Overflow 检测、RL 训练推理一致性根因分析。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "precision", "debug", "nan", "overflow", "deterministic", "consistency"], scenarios: ["profiling", "operator"], category: "skill-pack", skills: ["./deterministic-calculation-analysis", "./nan-overflow-detection", "./rl-consistency-analysis"] }, { name: "mindstudio-ascendc-perf-optim-skills", description: "MindStudio Ascend C 算子性能优化 Skills(1 个)。基于 Profiling 数据的 Ascend C 算子端到端性能优化,含 API 调优、数据搬运、流水线、Tiling 等参考。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "ascendc", "performance", "optimization", "tiling", "pipeline"], scenarios: ["operator", "profiling"], category: "skill-pack", skills: ["./ascendc-operator-performance-optim"] }, { name: "mindstudio-msmodelslim-skills", description: "MindStudio msModelSlim 量化 Skills(6 个)。快速量化指引、模型分析、模型适配、反量化、逐层量化、适配器验证。覆盖 msModelSlim 量化全流程。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "msmodelslim", "quantization", "model-adapt", "dequantization"], scenarios: ["training", "inference"], category: "skill-pack", skills: ["./msmodelslim-quick-quant", "./msmodelslim-model-analysis", "./msmodelslim-model-adapt", "./msmodelslim-model-dequant", "./msmodelslim-layer-wise-quantization", "./msmodelslim-adapter-verification"] }, { name: "mindstudio-devtools-skills", description: "MindStudio 开发工具 Skills(3 个)。GitCode PR 代码审查、GitHub 原始文件获取、文档 UX 审查。通过 submodule 从 msagent 仓库同步。", source: "./official/MindStudio/skills", strict: false, version: "1.0.0", author: { name: "MindStudio", url: "https://gitcode.com/Ascend/msagent" }, keywords: ["mindstudio", "code-review", "gitcode", "github", "document-ux"], scenarios: ["code-review", "devops"], category: "skill-pack", skills: ["./gitcode-code-reviewer", "./github-raw-fetch", "./document-ux-review"] }, { name: "community-ascendc-op-skills", description: "社区 Ascend C 算子开发全流程 Skills(17 个)。覆盖项目初始化→设计→代码生成→开发→编译调试→代码审查→精度调试/评估→性能评估/优化→测试用例→文档生成全流程,以及内存检测和增量文档。触发:社区 Ascend C 算子端到端开发场景。", source: "./community/Op", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["ascendc", "operator", "community", "design", "code-gen", "precision", "performance"], scenarios: ["operator"], category: "skill-pack", skills: ["./ascendc-operator-project-init", "./ascendc-operator-design", "./ascendc-operator-code-gen", "./ascendc-operator-dev", "./ascendc-operator-compile-debug", "./ascendc-operator-code-review", "./ascendc-operator-precision-debug", "./ascendc-operator-precision-eval", "./ascendc-operator-performance-eval", "./ascendc-operator-performance-optim", "./ascendc-operator-mssanitizer", "./ascendc-operator-testcase-gen", "./ascendc-operator-doc-gen", "./ascendc-operator-doc-writer", "./ascendc-op-doc-generator", "./ascendc-op-doc-incremental", "./ascendc-operator-st-gen"] }, { name: "community-catlass-op-skills", description: "社区 Catlass 算子开发全流程 Skills(4 个)。覆盖设计→代码生成→开发→性能优化全流程。触发:社区 Catlass 模板算子开发场景。", source: "./community/Op", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["catlass", "operator", "community", "design", "code-gen", "performance"], scenarios: ["operator"], category: "skill-pack", skills: ["./catlass-operator-design", "./catlass-operator-code-gen", "./catlass-operator-dev", "./catlass-operator-performance-optim"] }, { name: "community-triton-op-skills", description: "社区 Triton 算子开发全流程 Skills(11 个)。覆盖设计→代码生成→开发→代码审查→文档生成→环境配置→精度评估→性能评估/优化全流程,以及内存检测和共享组件。触发:社区 Triton-Ascend 算子开发场景。", source: "./community/Op", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["triton", "operator", "community", "design", "code-gen", "precision", "performance"], scenarios: ["operator"], category: "skill-pack", skills: ["./triton-operator-design", "./triton-operator-code-gen", "./triton-operator-dev", "./triton-operator-code-review", "./triton-operator-doc-gen", "./triton-operator-env-config", "./triton-operator-precision-eval", "./triton-operator-performance-eval", "./triton-operator-performance-optim", "./triton-operator-mssanitizer", "./triton-operator-shared"] }, { name: "community-triton-tilelang-migration-skills", description: "社区 Triton/TileLang GPU→NPU 迁移 Skills(3 个)。Triton 向量算子 GPU→NPU 迁移、TileLang 向量算子 NPU 迁移、Triton-Ascend 算子优化。触发:GPU 算子向昇腾 NPU 迁移适配场景。", source: "./community/Op", strict: false, version: "1.0.0", author: { name: "community" }, keywords: ["triton", "tilelang", "migration", "gpu-to-npu", "community"], scenarios: ["operator", "migration"], category: "skill-pack", skills: ["./simple-vector-triton-gpu-to-npu", "./tilelang-vector-ascend-ops-migration", "./vector-triton-ascend-ops-optimizer"] }] } },
|
|
469194
|
+
{ key: "atlas-plugins", manifest: { name: "atlas-plugins", owner: { name: "vince" }, metadata: { description: "atlas-plugins marketplace (scaffolded)" }, plugins: [{ name: "ascend-tiling-design", source: "./plugins/ascend-tiling-design", version: "0.1.0", description: "Ascend C 算子 Tiling 设计(多核切分/UB切分/Buffer规划/分支覆盖四要素 + 9 算法分类策略 + AISS 指针)" }, { name: "ascend-precision-debug", source: "./plugins/ascend-precision-debug", version: "0.1.0", description: "Ascend 精度调试(模型级 msprobe 两层级 / 算子级 DumpTensor 7 步 / PyPTO 二分 + 误差标准 + 判定决策树)" }, { name: "ascend-runtime-debug", source: "./plugins/ascend-runtime-debug", version: "0.1.0", description: "Ascend 算子运行时故障调试(错误码分类 / plog 解析 / 卡死崩溃 triage / Kernel 二进制构建排查)" }, { name: "ascend-perf-optimize", source: "./plugins/ascend-perf-optimize", version: "0.1.0", description: "Ascend 算子/模型性能优化(三层管线四步流程 + msprof 采集 + 10 类 bound 定位与定向优化)" }, { name: "ascend-test-design", source: "./plugins/ascend-test-design", version: "0.1.0", description: "Ascend C 算子测试设计(ST/UT/whitebox/golden 四类测试选择 + 设计流程 + 策略决策树)" }, { name: "ascend-code-review", source: "./plugins/ascend-code-review", version: "0.1.0", description: "Ascend C 算子代码检视(假设检验驱动逐条检视 + 5 workflow 路由 + 红线问题 + 缺陷修复路由)" }, { name: "cannbot-ops-direct-invoke", source: "./plugins/cannbot-ops-direct-invoke", version: "0.1.0", description: "官方 CANNBot 直调算子 skill 包(27 技能)的 Atlas 策展封装:API 检索/Tiling 设计/精度调试/性能采集/代码模板/SIMT 最佳实践,路由到 Atlas 算子开发工具链。触发:Ascend C 算子端到端开发(API 检索→tiling→codegen→编译→golden 验证)。" }, { name: "cannbot-aiss-tiling-solver", source: "./plugins/cannbot-aiss-tiling-solver", version: "0.1.0", description: "官方 AISS-TilingSolver skill 的 Atlas 策展封装:Ascend C 算子 Tiling 参数自动求解(MatMul/Vector),JSON 输入构造→求解→结果解读与故障排查。触发:不想手动设计 tiling、想自动求解最优 tiling 参数。" }, { name: "cannbot-catlass-op", source: "./plugins/cannbot-catlass-op", version: "0.1.0", description: "官方 CANNBot Catlass 算子 skill 包(3 技能)的 Atlas 策展封装:Catlass 算子设计/开发/性能调优。触发:用 Catlass 模板做 GEMM/卷积类算子开发或性能调优。" }, { name: "cannbot-pypto-op-orchestrator", source: "./plugins/cannbot-pypto-op-orchestrator", version: "0.1.0", description: "官方 CANNBot PyPTO 算子 skill 包(8 技能)的 Atlas 策展封装:API 探索/Golden 生成/需求理解/算子设计与开发/性能调优/精度调试。触发:PyPTO(Python 算子)开发或精度/性能调优。" }, { name: "cannbot-triton-op-generator", source: "./plugins/cannbot-triton-op-generator", version: "0.1.0", description: "官方 CANNBot Triton-Ascend 算子 skill 包(6 技能)的 Atlas 策展封装:任务提取/算法设计/代码生成/功能验证/性能优化/NPU 架构参考。触发:Triton-Ascend 算子代码生成或优化。" }, { name: "cannbot-cuda2ascend-simt", source: "./plugins/cannbot-cuda2ascend-simt", version: "0.1.0", description: "官方 CANNBot CUDA→Ascend SIMT 迁移 skill 的 Atlas 策展封装:CUDA 到 Ascend C SIMT 编程模型的代码迁移(API 映射/语法规则/约束校验)。触发:把 CUDA kernel 迁移到 Ascend C SIMT。" }, { name: "cannbot-tilelang-op", source: "./plugins/cannbot-tilelang-op", version: "0.1.0", description: "官方 CANNBot TileLang 算子 skill 包(9 技能)的 Atlas 策展封装:环境检查/子模块拉取/算子设计/开发/测试设计/API 最佳实践/编程模式指南/性能优化/代码审查。触发:TileLang 算子端到端开发。" }, { name: "community-ascendc-op", source: "./plugins/community-ascendc-op", version: "0.1.0", description: "社区 Ascend C 算子开发全流程 skill 包(17 技能)的 Atlas 策展封装:项目初始化→设计→codegen→开发→编译调试→code review→精度调试/评估→性能评估/优化→测试用例→文档。触发:社区 Ascend C 算子端到端开发。" }, { name: "community-catlass-op", source: "./plugins/community-catlass-op", version: "0.1.0", description: "社区 Catlass 算子开发全流程 skill 包(4 技能)的 Atlas 策展封装:设计→codegen→开发→性能优化。触发:社区 Catlass 模板算子开发。" }, { name: "community-triton-op", source: "./plugins/community-triton-op", version: "0.1.0", description: "社区 Triton 算子开发全流程 skill 包(11 技能)的 Atlas 策展封装:设计→codegen→开发→code review→文档→环境配置→精度评估→性能评估/优化→内存检测。触发:社区 Triton-Ascend 算子开发。" }, { name: "cannbot-infra-skills", source: "./plugins/cannbot-infra-skills", version: "0.1.0", description: "官方 CANNBot 基础设施 skill 包(5 技能)的 Atlas 策展封装:Skill 审查/GitCode Issue 生成与处理/PR 处理/GitCode 工具集 + 故障采集/错误分类/性能分析路由。触发:NPU 问题定位、故障采集与分诊、CANNBot 工程问题处理。" }, { name: "common-infra-skills", source: "./plugins/common-infra-skills", version: "0.1.0", description: "昇腾 NPU 通用基础设施 skill 包(6 技能)的 Atlas 策展封装:Docker 容器创建/驱动固件安装/CANN 全套组件安装/算子环境配置/SwanLab 追踪/npu-smi 设备管理。触发:昇腾 NPU 开发环境搭建与运维、设备状态检查。" }, { name: "mindstudio-ascendc-perf-optim", source: "./plugins/mindstudio-ascendc-perf-optim", version: "0.1.0", description: "MindStudio Ascend C 算子性能优化 skill 的 Atlas 策展封装:基于 Profiling 数据的端到端性能优化(API 调优/数据搬运/流水线/Tiling 参考)。触发:对 Ascend C 算子做数据驱动的性能优化。" }, { name: "cannbot-model-infer", source: "./plugins/cannbot-model-infer", version: "0.1.0", description: "官方 CANNBot NPU 模型推理优化 skill 包(11 技能)的 Atlas 策展封装:框架适配/并行策略/KVCache+FA/融合算子/图模式/精度运行时调试/多流/预取/SuperKernel。触发:LLM/大模型在 NPU 上的推理性能优化。" }, { name: "vllm-ascend", source: "./plugins/vllm-ascend", version: "0.1.0", description: "vLLM-Ascend 推理部署与测试 skill 包(3 技能)的 Atlas 策展封装:vLLM Ascend 服务部署/FAQ 生成/测试失败分析。触发:vLLM 在昇腾 NPU 上的部署与问题排查。" }, { name: "mindspeed-drivingsdk", source: "./plugins/mindspeed-drivingsdk", version: "0.1.0", description: "MindSpeed 自驾 SDK 模型迁移 skill 包(14 技能)的 Atlas 策展封装:模型代码迁移/NPU 训练/SSH 远程开发套件/MMLab 安装套件。触发:自驾(VLA)模型 NPU 适配迁移。" }, { name: "common-deploy", source: "./plugins/common-deploy", version: "0.1.0", description: "昇腾 NPU 通用部署 skill 包(3 技能)的 Atlas 策展封装:OM 部署器/OM Pipeline 适配器/ONNX-ATC 推理 Pipeline。触发:模型部署、推理服务构建。" }, { name: "common-migration", source: "./plugins/common-migration", version: "0.1.0", description: "昇腾 NPU 通用模型迁移 skill 包(5 技能)的 Atlas 策展封装:推理仓库智能问答/ATC 模型转换全流程/msverl 回归分诊/NPU 适配审查/PyTorch 模型 NPU 迁移。触发:模型迁移到 NPU、GPU→NPU 适配。" }] } },
|
|
469195
|
+
{ key: "claude-plugins-official", manifest: { $schema: "https://anthropic.com/claude-code/marketplace.schema.json", name: "claude-plugins-official", description: "Directory of popular Claude Code extensions including development tools, productivity plugins, and MCP integrations", owner: { name: "Anthropic", email: "support@anthropic.com" }, renames: { adlc: "agentforce-adlc", airwallex: "airwallex-agentos", "convex-backend": "convex", vals: "valtown", "wordpress.com": "build-with-wordpress", "qodo-skills": "qodo", "atlassian-forge-skills": "forge-skills", "azure-skills": "azure", "sonarqube-agent-plugins": "sonarqube" }, plugins: [{ name: "42crunch-api-security-testing", description: "Automate API security directly in Claude Code with 42Crunch - automatically audit OpenAPI specs, detect vulnerabilities aligned with OWASP API Security risks (including BOLA/BFLA), and apply AI-powered fixes. Designed for AI-assisted development workflows, it provides continuous guardrails through an audit->scan->remediate->validate loop, ensuring APIs meet enterprise security standards before deployment.", author: { name: "42Crunch" }, category: "security", source: { source: "git-subdir", url: "https://github.com/42Crunch-AI/claude-plugins.git", path: "plugins/api-security-testing", ref: "v1.5.5", sha: "30287f5e3f122a646d1ac5ca3ab96e130c52a3ad" }, homepage: "https://42crunch.com" }, { name: "adobe-for-creativity", description: "Harness Adobe's creative AI-powered tools to edit images, automate design workflows, and bring creative visions to life — from background removal to vectorization and professional retouching.", author: { name: "Adobe" }, category: "design", source: { source: "git-subdir", url: "https://github.com/adobe/skills.git", path: "plugins/creative-cloud/adobe-for-creativity", ref: "main", sha: "304aa23dfd84aeb7b005816962d1bfb40d27750a" }, homepage: "https://github.com/adobe/skills/tree/main/plugins/creative-cloud/adobe-for-creativity" }, { name: "agent-sdk-dev", description: "Development kit for working with the Claude Agent SDK", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/agent-sdk-dev", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/agent-sdk-dev" }, { name: "agentforce-adlc", description: "Agentforce Agent Development Life Cycle — author, discover, scaffold, deploy, test, and optimize .agent files", category: "development", source: { source: "url", url: "https://github.com/SalesforceAIResearch/agentforce-adlc.git", sha: "09bf1539d41f9ff355ba3eb5d05d4a75813423bb" }, homepage: "https://github.com/SalesforceAIResearch/agentforce-adlc" }, { name: "ai-plugins", description: "Set up endorctl and use Endor Labs to scan, prioritize, and fix security risks across your software supply chain", source: { source: "url", url: "https://github.com/endorlabs/ai-plugins.git", sha: "2de00883bd2be8b8578b46ab09baf2c8731376de" }, homepage: "https://www.endorlabs.com" }, { name: "aikido", description: "Aikido Security scanning for Claude Code — SAST, secrets, and IaC vulnerability detection powered by the Aikido MCP server.", source: { source: "url", url: "https://github.com/AikidoSec/aikido-claude-plugin.git", sha: "02f018ad4da175a2a5ad6ca9451c3d309d105fab" }, homepage: "https://github.com/AikidoSec/aikido-claude-plugin" }, { name: "airtable", description: "Airtable is the database and operations layer for your agents — whether running product, marketing, sales, ops, HR, or a custom business app. It combines structured data with multiplayer visual surfaces (grid, kanban, calendar, gallery, timeline) humans and agents share — plus sync integrations to Jira, Salesforce, Zendesk, Google Drive, Databricks, and the rest of your stack, all backed by enterprise governance. This plugin makes Claude fluent in Airtable: creating bases and schema, working with records, and sharing UI for collaboration. Bundles the official Airtable MCP server.", author: { name: "Airtable" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/Airtable/skills.git", path: "plugins/airtable", ref: "main", sha: "812ee67f1fd3d76fb45ff8df40afaa0448602ba8" }, homepage: "https://www.airtable.com" }, { name: "airwallex-agentos", displayName: "Airwallex", description: "Bring Airwallex's global financial infrastructure to Claude. Orchestrate actions across your account in plain language, e.g., set up invoices from a PO, onboard suppliers from invoices, and check current cash position across currencies. AgentOS bundles pre-built finance Skills with MCP servers. A public CLI connects your agent to Airwallex's capabilities.", author: { name: "Airwallex" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/airwallex/airwallex-marketplace.git", path: "plugins/airwallex-agentos", ref: "master", sha: "d323dd68c85874f6311a1bd20184f803a96e09a9" }, homepage: "https://www.airwallex.com/docs" }, { name: "airwallex-dev", description: "Build Airwallex payment integrations in your own codebase. Generates the checkout, card-element, onboarding, and subscription-billing code for an Airwallex integration and wires it into your project: Hosted Payment Page, Drop-in and Split Card elements, connected-account KYC onboarding, and Billing Hosted Checkout for subscriptions and card-saving. Also plans card-on-file merchant-initiated flows for AI providers such as top-ups and auto-recharge.", author: { name: "Airwallex" }, category: "development", source: { source: "git-subdir", url: "https://github.com/airwallex/airwallex-marketplace.git", path: "plugins/airwallex-dev", ref: "master", sha: "d4593e33a9e1177a44b895ca0a1d6e015215736f" }, homepage: "https://www.airwallex.com/docs" }, { name: "aiven", description: "Easily deploy managed PostgreSQL (pg), Kafka, OpenSearch, Clickhouse and other databases, streaming and apps. Free tier available, up and running in minutes.", author: { name: "Aiven" }, category: "database", source: { source: "url", url: "https://github.com/aiven/aiven-ai-plugins.git", sha: "634f41d6852957cb9280e9245f2ea6f74645b4f1" }, homepage: "https://aiven.io" }, { name: "alloydb", description: "Create, connect, and interact with an AlloyDB for PostgreSQL database and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/alloydb.git", sha: "00ee6ce2bcf88b46da4bf298a3ad8c0ad85877c8" }, homepage: "https://cloud.google.com/alloydb" }, { name: "alloydb-omni", description: "Create, connect, and interact with an AlloyDB Omni database and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/alloydb-omni.git", sha: "ae7e42c4e428e303adcc96942f4fc35cb6b27d61" }, homepage: "https://github.com/gemini-cli-extensions/alloydb-omni" }, { name: "altimate-code", description: "Delegates dbt and warehouse work to altimate-code, a specialized CLI agent with 100+ purpose-built data tools (SQL analysis, column-level lineage, dbt build/test/run, warehouse profiling, FinOps, connectivity to Snowflake, BigQuery, Redshift, Databricks, Postgres, MySQL, DuckDB).", author: { name: "AltimateAI" }, category: "database", source: { source: "git-subdir", url: "https://github.com/AltimateAI/altimate-claude-plugin.git", path: "plugins/altimate-code", ref: "main", sha: "b7c8f68b3dfd303ab3ccf2f43934098811dfe2aa" }, homepage: "https://www.altimate.ai" }, { name: "amazon-location-service", description: "Guide developers through adding maps, places search, geocoding, routing, and other geospatial features with Amazon Location Service, including authentication setup, SDK integration, and best practices.", category: "location", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/amazon-location-service", ref: "main", sha: "9898ddc4dcf7dd23ddb939cec1b905311dc7381d" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "amd-skills", description: "AMD's verified Agent Skills in one plugin: route image/audio through local AI on Ryzen AI, serve LLMs on AMD Instinct GPUs with vLLM, and analyze GPU kernel and PyTorch trace performance.", author: { name: "AMD" }, category: "development", source: { source: "git-subdir", url: "https://github.com/amd/skills.git", path: "skills", ref: "main", sha: "6916fb371d1cba40757b223cf16b4cd4912b202f" }, strict: false, skills: ["./local-ai-use", "./local-ai-app-integration", "./serving-llms-on-instinct", "./tracelens-analysis-orchestrator"], homepage: "https://developer.amd.com/" }, { name: "amplitude", source: { source: "git-subdir", url: "https://github.com/amplitude/mcp-marketplace.git", path: "plugins/amplitude", ref: "main", sha: "96fc7d4c58bb33b4e60c334d34ad944c8a246869" }, description: "Use Amplitude as an expert analyst — instrument Amplitude, discover product opportunities, analyze charts, create dashboards, manage experiments, and understand users and accounts.", category: "monitoring", homepage: "https://github.com/amplitude/mcp-marketplace" }, { name: "apollo", description: "Prospect, enrich leads, load outreach sequences, and query sales analytics with Apollo.io — one-click MCP server integration for Claude Code and Cowork.", author: { name: "Apollo.io" }, category: "productivity", source: { source: "url", url: "https://github.com/apolloio/apollo-mcp-plugin.git", sha: "bd0513c961f02105492fcff0d7d29c9cccf1ed23" }, homepage: "https://www.apollo.io/" }, { name: "apollo-skills", description: "Apollo GraphQL agent skills for Claude Code — Apollo Client, Server, Federation, Connectors, Router, Rover CLI, iOS, Kotlin, and the Apollo MCP server. Covers schema design, query optimization, and GraphQL best practices.", author: { name: "Apollo GraphQL" }, category: "development", source: { source: "url", url: "https://github.com/apollographql/skills.git", sha: "c288eb80629dd2309eed81f23d693f66a452d043" }, homepage: "https://www.apollographql.com" }, { name: "appwrite", description: "Appwrite tools for Claude Code, including SDK skills, Appwrite MCP servers, and deployment commands.", author: { name: "Appwrite" }, category: "development", source: { source: "url", url: "https://github.com/appwrite/claude-plugin.git", sha: "ab3c90b37c95b7068f0c064dc562cf21958e8e19" }, homepage: "https://appwrite.io" }, { name: "asana", description: "Asana project management integration. Connects Claude Code to Asana's V2 MCP server to create and manage tasks, search projects, update assignments, and track progress. Requires a one-time Asana OAuth app setup — run /asana-setup after installing.", category: "productivity", source: "./external_plugins/asana", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/asana" }, { name: "astronomer-data-agents", description: "Data engineering for Apache Airflow and Astronomer. Author DAGs with best practices, debug pipeline failures, trace data lineage, profile tables, migrate Airflow 2 to 3, and manage local and cloud deployments.", category: "development", source: { source: "url", url: "https://github.com/astronomer/agents.git", sha: "9b5a33171e36ecda135f22e77a845d9c405b519e" }, homepage: "https://github.com/astronomer/agents" }, { name: "atlan", description: "Atlan data catalog plugin for Claude Code. Search, explore, govern, and manage your data assets through natural language. Powered by the Atlan MCP server with semantic search, lineage traversal, glossary management, data quality rules, and more.", source: { source: "url", url: "https://github.com/atlanhq/agent-toolkit.git", sha: "86bb1ad27f80e189b328333d2271b360ae579f2b" }, homepage: "https://docs.atlan.com/" }, { name: "atlassian", description: "Connect to Atlassian products including Jira and Confluence. Search and create issues, access documentation, manage sprints, and integrate your development workflow with Atlassian's collaboration tools.", category: "productivity", source: { source: "url", url: "https://github.com/atlassian/atlassian-mcp-server.git", sha: "eb9a5956a7ac6380c731c725a8382da53ad6d980" }, homepage: "https://github.com/atlassian/atlassian-mcp-server" }, { name: "atlassian-twg-cli", description: `Teamwork Graph CLI is Atlassian's agent-first interface to your entire work context: Jira issues, Confluence pages, Bitbucket PRs, along with your connected third-party data sources. Purpose-built for coding agents like Claude Code (terminal or desktop), and powered by Atlassian's context graph. Try: "draft a Jira issue from this PR and link it to the epic." Using Claude Code in the browser? Install the Atlassian Rovo MCP plugin instead. Run /twg-setup after install to connect Atlassian Teamwork Graph CLI to Claude Code.`, author: { name: "Atlassian" }, category: "productivity", source: { source: "url", url: "https://github.com/atlassian-labs/twg-plugins.git", sha: "b3336ef63d45e2636ff411a922ed602244e0f3db" }, homepage: "https://developer.atlassian.com/cloud/twg-cli/" }, { name: "atomic-agents", description: "Comprehensive development workflow for building AI agents with the Atomic Agents framework. Includes specialized agents for schema design, architecture planning, code review, and tool development. Features guided workflows, progressive-disclosure skills, and best practice validation.", category: "development", source: { source: "url", url: "https://github.com/BrainBlend-AI/atomic-agents.git", path: "claude-plugin/atomic-agents", sha: "b15ca449a81278b1c92666bdf9a2e57a817dcacd" }, homepage: "https://github.com/BrainBlend-AI/atomic-agents", tags: ["community-managed"] }, { name: "auth0", description: "Enterprise-grade auth, easy to implement. Add login, SSO, MFA, and access control to any app with framework-aware guidance.", author: { name: "Auth0", url: "https://auth0.com" }, category: "security", source: { source: "git-subdir", url: "https://github.com/auth0/agent-skills.git", path: "plugins/auth0", ref: "main", sha: "f135610540ea41e4d99882dc1f06162030c7340b" }, homepage: "https://auth0.com" }, { name: "aws-agents", description: "Build, deploy, and operate AI agents on AWS. Skills for scaffolding agents with Amazon Bedrock AgentCore, connecting tools, memory, policies, evaluation, debugging, and production hardening.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/aws/agent-toolkit-for-aws.git", path: "plugins/aws-agents", ref: "main", sha: "57ce9edb2126292efaf5298801e226e1ef661a4a" }, homepage: "https://github.com/aws/agent-toolkit-for-aws" }, { name: "aws-agents-for-devsecops", description: "Investigate incidents, review code and execute UAT for release readiness, scan code for vulnerabilities, and run penetration tests with AWS DevOps Agent and AWS Security Agent.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/aws/agent-toolkit-for-aws.git", path: "plugins/aws-agents-for-devsecops", ref: "main", sha: "68d9e8541c45afd2510662bcea69fe1e433ea9db" }, homepage: "https://github.com/aws/agent-toolkit-for-aws" }, { name: "aws-amplify", description: "Build full-stack apps with AWS Amplify Gen 2 using guided workflows for authentication, data models, storage, GraphQL APIs, and Lambda functions.", category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/aws-amplify", ref: "main", sha: "c65ee436b0db77bb75d380aef6fbdc9b114edf2a" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "aws-core", description: "Build, deploy, and operate applications on AWS. Skills to author infrastructure-as-code, use core services, and complete common tasks.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/aws/agent-toolkit-for-aws.git", path: "plugins/aws-core", ref: "main", sha: "7fcb1da17abba610d7becc973c2141b40412e02c" }, homepage: "https://github.com/aws/agent-toolkit-for-aws" }, { name: "aws-data-analytics", description: "Data lake, analytics, and ETL workflows with S3 Tables, AWS Glue, and Athena.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/aws/agent-toolkit-for-aws.git", path: "plugins/aws-data-analytics", ref: "main", sha: "08ad220e4e9bbc498821ce9360b3dcdf4813121d" }, homepage: "https://github.com/aws/agent-toolkit-for-aws" }, { name: "aws-serverless", description: "Design, build, deploy, test, and debug serverless applications with AWS Serverless services.", category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/aws-serverless", ref: "main", sha: "34afdf5005325f17d5da2d1443b87f27a53b0a20" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "aws-startup-advisor", description: "Personalized architecture, cost, security, and migration guidance for startups. From day-one account setup and security baselines to production-ready infrastructure, cost optimization, and beyond. Includes AWS Activate Credits eligibility, 60+ exclusive startup offers, and multi-account multi-region support. Built on expertise from AWS Startup Solutions Architects and patterns from 350,000+ startups.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/startups.git", path: "advisor/plugins/aws-startup-advisor", ref: "main", sha: "dd7096bd634649bc89b6511d61cff16f58623284" }, homepage: "https://github.com/awslabs/startups" }, { name: "aws-transform", description: "Migrate, modernize, and upgrade codebases to AWS. Transforms .NET Framework to .NET 8/10, mainframe COBOL to Java, VMware VMs to EC2, SQL Server to Aurora, and upgrades Java/Python/Node.js versions and AWS SDKs. AWS Transform - continuous modernization analyzes codebases for tech debt, security issues, and upgrade opportunities, then remediates them.", author: { name: "Amazon Web Services" }, category: "migration", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/aws-transform", ref: "main", sha: "adc01133bbd01433dcb2c0f98641f2b85694f92f" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "azure", description: "Transform Claude into an Azure expert. This plugin integrates the Azure MCP server and specialized Azure skills to move beyond generic advice. It enables Claude to perform real-world tasks: listing resources, validating deployments, diagnosing infrastructure issues, and optimizing costs across 50+ Azure services.", category: "deployment", source: { source: "url", url: "https://github.com/microsoft/azure-skills.git", sha: "abaf74ac8f62fbe9f83d7ccb2bd991dca929a4da" }, homepage: "https://github.com/microsoft/azure-skills" }, { name: "azure-cosmos-db-assistant", source: { source: "url", url: "https://github.com/AzureCosmosDB/cosmosdb-claude-code-plugin.git", sha: "f1e0498579a9251e5f3179b92d25d6ce3409bae5" }, description: "Expert assistant for Azure Cosmos DB — data modeling, query optimization, performance tuning, and best practices.", category: "database", homepage: "https://github.com/AzureCosmosDB/cosmosdb-claude-code-plugin" }, { name: "azure-sql-developer", description: "Agent skills for Azure SQL Developer, the Azure SQL Database engine running locally in a container. Teaches your agent to run the engine, connect, migrate, scaffold, build RAG, wire CI, and go local-to-cloud, using the real Private Preview image instead of the SQL Server image.", author: { name: "Microsoft" }, category: "database", source: { source: "url", url: "https://github.com/microsoft/azure-sql-database-container.git", sha: "8a82f442df5bb7bbf65f1eb774e32d1f55a07e04" }, homepage: "https://github.com/microsoft/azure-sql-database-container" }, { name: "base44", description: "Build and deploy Base44 full-stack apps with CLI project management and JavaScript/TypeScript SDK development skills", category: "development", source: { source: "url", url: "https://github.com/base44/skills.git", sha: "592535c8aa52a088eba364a4805e3c34612ff762" }, homepage: "https://docs.base44.com" }, { name: "bigdata-com", description: "Official Bigdata.com plugin providing financial research, analytics, and intelligence tools powered by Bigdata MCP.", author: { name: "RavenPack" }, category: "database", source: { source: "git-subdir", url: "https://github.com/Bigdata-com/bigdata-plugins-marketplace.git", path: "plugins/bigdata-com", ref: "main", sha: "2a52a001366227e205cfa7565d78e8198dc42fa8" }, homepage: "https://docs.bigdata.com" }, { name: "bigquery-data-analytics", description: "Connect, query, and generate data insights for BigQuery datasets and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/bigquery-data-analytics.git", sha: "8475b9c79e38c92a8e28cefc54890d48c74efebc" }, homepage: "https://github.com/gemini-cli-extensions/bigquery-data-analytics" }, { name: "boltz", description: "Predict structures, screen molecules and proteins, and design binders with Boltz from Claude Code.", author: { name: "Boltz" }, category: "development", source: { source: "git-subdir", url: "https://github.com/boltz-bio/boltz-api-skills.git", path: "plugins/boltz", ref: "main", sha: "beafb3c16236347ab10fb54f78a5da49cbf7c7bb" }, homepage: "https://boltz.bio" }, { name: "blackrock-advisor-center-plugin", description: "BlackRock Advisor Center 360° skills for financial advisors: portfolio review, opportunity and fund-health checks, guided benchmark selection, guided portfolio building, wealth projections, and routing to Advisor Center web workflows. Requires the BlackRock Advisor Center connector and an Advisor Center account.", author: { name: "BlackRock Advisor Center" }, category: "productivity", source: { source: "url", url: "https://github.com/blackrock/advisor-center-agent-skills.git", sha: "591c758960c18c26fe8342ddb8ad3ba4dcfac6fe" }, homepage: "https://github.com/blackrock/advisor-center-agent-skills" }, { name: "box", description: "Work with your Box content directly from Claude Code — search files, organize folders, collaborate with your team, and use Box AI to answer questions, summarize documents, and extract data without leaving your workflow.", category: "productivity", source: { source: "url", url: "https://github.com/box/skills.git", sha: "35567f913a2bfd7f8b59367c9df3ae14b5ad4cfe" }, skills: ["./skills/box", "./skills/box-legal-workflows", "./skills/box-legal-workflows-contract", "./skills/box-legal-workflows-intake", "./skills/box-legal-workflows-ma"], homepage: "https://github.com/box/skills" }, { name: "brightdata-plugin", description: "Web scraping, Google search, structured data extraction, and MCP server integration powered by Bright Data. Includes 7 skills: scrape any webpage as markdown (with bot detection/CAPTCHA bypass), search Google with structured JSON results, extract data from 40+ websites (Amazon, LinkedIn, Instagram, TikTok, YouTube, and more), orchestrate Bright Data's 60+ MCP tools, built-in best practices for Web Unlocker, SERP API, Web Scraper API, and Browser API, Python SDK best practices for the brightda...", source: { source: "url", url: "https://github.com/brightdata/skills.git", sha: "e825f02fbcd7a89087fd1053a57ddcd45113370f" }, homepage: "https://docs.brightdata.com" }, { name: "browser-use", description: "Give Claude a real browser — your Chrome or a Browser Use Cloud browser. Use it whenever a task involves a website or web app: browsing, scraping and data extraction, filling forms, testing sites, taking screenshots, automating web workflows.", author: { name: "Browser Use" }, category: "automation", source: { source: "git-subdir", url: "https://github.com/browser-use/plugins.git", path: "browser-use", ref: "main", sha: "a25f0a262928bcbb62071432636d943ed9f2b6aa" }, homepage: "https://browser-use.com" }, { name: "buildkite", description: "Official Buildkite skills for Claude Code, Cursor, and other AI coding agents — pipelines, migration, preflight, agent runtime, CLI, and API", author: { name: "Buildkite" }, category: "development", source: { source: "url", url: "https://github.com/buildkite/skills.git", sha: "a4bb20c6bf9ae535335f782015f65b9975065f27" }, homepage: "https://buildkite.com" }, { name: "canva", description: "Create, edit, review, resize, and brand-check Canva designs with the Canva MCP server.", author: { name: "Canva" }, category: "design", source: { source: "git-subdir", url: "https://github.com/canva-sdks/canva-skills.git", path: "plugins/canva", ref: "main", sha: "b56291ea0a36d0a941e1478b47959be5f1771dee" }, homepage: "https://www.canva.com" }, { name: "carbone-skill", description: "Official Carbone skill — complete templating language reference covering tags, loops, conditions, formatters, aggregators, and all output formats (DOCX, XLSX, PPTX, ODT, HTML, Markdown, PDF)", author: { name: "Carbone" }, category: "productivity", source: { source: "url", url: "https://github.com/carboneio/carbone-skill.git", sha: "25207b3f52b97872312eab997ee5c62cc5c9542d" }, homepage: "https://carbone.io" }, { name: "carta-cap-table", description: "Carta Cap Table plugin — skills and hooks for querying cap tables, grants, SAFEs, 409A valuations, waterfall scenarios, and more", author: { name: "Carta Engineering" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/carta/plugins.git", path: "plugins/carta-cap-table", ref: "main", sha: "12bb447e186f52c20aee6588761498f2acf76fc3" }, homepage: "https://carta.com" }, { name: "carta-crm", description: "Manage the Carta CRM conversationally — search, add, update, and enrich investors, companies, contacts, deals, notes, and fundraisings via the Carta CRM MCP Server.", author: { name: "Carta Engineering" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/carta/plugins.git", path: "plugins/carta-crm", ref: "main", sha: "81b8f40844bd646842538a4583409f9aa54c42db" }, homepage: "https://carta.com" }, { name: "carta-investors", description: "Carta Investors plugin — skills for querying investor data, performance benchmarks, regulatory reporting, AGM deck generation, brand extraction, and more via the Carta MCP Server.", author: { name: "Carta Engineering" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/carta/plugins.git", path: "plugins/carta-investors", ref: "main", sha: "12bb447e186f52c20aee6588761498f2acf76fc3" }, homepage: "https://carta.com" }, { name: "catalyst-by-zoho", description: "Official Claude Code plugin for Catalyst by Zoho — full-stack serverless cloud platform. With Skills that covers all services, SDKs, CLI, architecture patterns, pricing, migration guides, and Zoho MCP tool-based resource management.", author: { name: "Catalyst by Zoho" }, category: "development", source: { source: "url", url: "https://github.com/catalystbyzoho/claude-plugin.git", sha: "9670b79d72fe4923cc845ca0414d009ef3684ccb" }, homepage: "https://catalyst.zoho.com/" }, { name: "cds-mcp", description: "AI-assisted development of SAP Cloud Application Programming Model (CAP) projects. Search CDS models and CAP documentation.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "url", url: "https://github.com/cap-js/mcp-server.git", sha: "79e4546395a52b1a3881d828118a1b3a2e198876" }, homepage: "https://cap.cloud.sap/" }, { name: "chrome-devtools-mcp", description: "Control and inspect a live Chrome browser from your coding agent. Record performance traces, analyze network requests, check console messages with source-mapped stack traces, and automate browser actions with Puppeteer.", category: "development", source: { source: "url", url: "https://github.com/ChromeDevTools/chrome-devtools-mcp.git", sha: "1cec9cd1a3bbf1895c98fa4b4e0e2da5a36e4075" }, homepage: "https://github.com/ChromeDevTools/chrome-devtools-mcp" }, { name: "chronograph-gp", description: "Portfolio monitoring, valuations and analytics for private-capital GP teams using the Chronograph connector: portfolio-company one-pagers, fund quarterly review packs, markup/markdown briefs, TVPI attribution and budget-vs-actuals. Requires a Chronograph account and the Chronograph connector.", author: { name: "Chronograph" }, category: "productivity", source: { source: "url", url: "https://github.com/chronograph-pe/chronograph-gp-claude-plugin.git", sha: "35cb3d12cf4e24823c0efca4abe6f13c2fd0e5f5" }, homepage: "https://www.chronograph.pe/" }, { name: "chronograph-lp", description: "Portfolio monitoring and analytics for private-capital LP teams using the Chronograph connector: cashflow forecasting, commitment pacing, look-through exposure scans and GP-meeting prep. Requires a Chronograph account and the Chronograph connector.", author: { name: "Chronograph" }, category: "productivity", source: { source: "url", url: "https://github.com/chronograph-pe/chronograph-lp-claude-plugin.git", sha: "322b2d3fbd4db0a2eeed117e3b3c31522408ae6f" }, homepage: "https://www.chronograph.pe/" }, { name: "circle-skills", description: "Ship stablecoin apps faster. Best-practice skills for USDC payments, cross-chain transfers, wallets, and smart contracts — plus Circle's MCP server for real-time SDK and documentation guidance.", author: { name: "Circle" }, category: "development", source: { source: "git-subdir", url: "https://github.com/circlefin/skills.git", path: "plugins/circle", ref: "master", sha: "58ab8648bb1ae9d037a3bf5197ad3bb01262f5b1" }, homepage: "https://www.circle.com" }, { name: "circleback", description: "Circleback conversational context integration. Search and access meetings, emails, calendar events, and more.", category: "productivity", source: { source: "url", url: "https://github.com/circlebackai/claude-code-plugin.git", sha: "a610634c95ab310accf20a0cabdf0fa7ab784fa3" }, homepage: "https://github.com/circlebackai/claude-code-plugin.git" }, { name: "ckeditor", description: "Install, configure, and integrate CKEditor 5 (free and premium) in any JavaScript project.", author: { name: "CKEditor (CKSource)" }, category: "development", source: { source: "url", url: "https://github.com/ckeditor/skills.git", sha: "78a9e3fb6f54c6d0426e91510087e4f462d26d46" }, homepage: "https://ckeditor.com" }, { name: "clangd-lsp", description: "C/C++ language server (clangd) for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/clangd-lsp", category: "development", strict: false, lspServers: { clangd: { command: "clangd", args: ["--background-index"], extensionToLanguage: { ".c": "c", ".h": "c", ".cpp": "cpp", ".cc": "cpp", ".cxx": "cpp", ".hpp": "cpp", ".hxx": "cpp", ".C": "cpp", ".H": "cpp" } } } }, { name: "claude-code-setup", description: "Analyze codebases and recommend tailored Claude Code automations such as hooks, skills, MCP servers, and subagents.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/claude-code-setup", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/claude-code-setup" }, { name: "claude-md-management", description: "Tools to maintain and improve CLAUDE.md files - audit quality, capture session learnings, and keep project memory current.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/claude-md-management", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/claude-md-management" }, { name: "claude-security", description: "Deep vulnerability scanning of your own code, run entirely inside your Claude Code session at a chosen effort tier, with every finding challenged before it is reported and the verification tally computed in code. Turns surviving findings into targeted patches, each verified by a panel of agents, that you apply when you choose.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/claude-security", category: "security", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/claude-security" }, { name: "clay", description: "Work with Clay from Claude Code: set up and sign in to the clay CLI, query and analyze Clay tables, search Clay's GTM database for people and companies, manage audiences, signals, routines and workflows, and draft and review Sequencer campaigns. Includes hooks that auto-approve the plugin's own clay CLI calls and Clay skills; requires a Clay account.", author: { name: "Clay" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/clay-run/agent-plugins.git", path: "clay", ref: "main", sha: "86f0471654c2c855ad0346cd30a74c0f4ca85d7f" }, homepage: "https://github.com/clay-run/agent-plugins/tree/main/clay" }, { name: "clickhouse", description: "Connect Claude to your ClickHouse Cloud databases. Browse organizations, services, databases, and table schemas. Run read-only SQL queries against your data and get instant analytical answers. Monitor service backups, review billing costs, and inspect ClickPipe configurations - all through natural conversation.", author: { name: "ClickHouse" }, category: "database", source: { source: "url", url: "https://github.com/ClickHouse/clickhouse-claude-code-plugin.git", sha: "e3229ed4aafbe94e90dd91699e05eee4263d5efe" }, homepage: "https://github.com/ClickHouse/clickhouse-claude-code-plugin" }, { name: "clickhouse-best-practices", description: "28 best practice rules for ClickHouse schema design, query optimization, and data ingestion — prioritized by impact", author: { name: "ClickHouse Inc" }, category: "database", source: { source: "url", url: "https://github.com/ClickHouse/agent-skills.git", sha: "2f6ec4b17a81a435dd116f9ac19d7b45d44dbd61" }, homepage: "https://clickhouse.com" }, { name: "cloud-sql-mysql", description: "Connect and interact with a Cloud SQL for MySQL database and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/cloud-sql-mysql.git", sha: "ed4fbfe3e0cb6770b15b2a66bd1192a684547678" }, homepage: "https://github.com/gemini-cli-extensions/cloud-sql-mysql" }, { name: "cloud-sql-postgresql", description: "Create, connect, and interact with a Cloud SQL for PostgreSQL database and data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/cloud-sql-postgresql.git", sha: "6191fb93757355204a5f909d41ad6c9fa2900a83" }, homepage: "https://cloud.google.com/sql" }, { name: "cloud-sql-sqlserver", description: "Connect to Cloud SQL for SQL Server", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/cloud-sql-sqlserver.git", sha: "8858b0fd066f1590ab7dad70ceacb1366af86a1f" }, homepage: "https://github.com/gemini-cli-extensions/cloud-sql-sqlserver" }, { name: "cloudflare", source: { source: "url", url: "https://github.com/cloudflare/skills.git", sha: "b052c32bab7dd493513260228a36c88294f343f1" }, description: "Skills for the Cloudflare developer platform: Workers, Durable Objects, Agents SDK, MCP servers, Wrangler CLI, and web performance.", category: "deployment", homepage: "https://github.com/cloudflare/skills" }, { name: "cloudinary", description: "Use Cloudinary directly in Claude. Manage assets, apply transformations, optimize media, and more through natural conversation.", source: { source: "url", url: "https://github.com/cloudinary-devs/cloudinary-plugin.git", sha: "86be53409e3fb1c465cd5ff4d1dc937a2860f45c" }, homepage: "https://cloudinary.com/documentation" }, { name: "cockroachdb", description: "Connect Claude Code directly to your CockroachDB clusters for hands-on database work — explore schemas, write optimized SQL, debug queries, and manage distributed database clusters. This plugin provides 14 tools across two active MCP backends (self-hosted MCP Toolbox and managed CockroachDB Cloud MCP Server), three specialized agents (DBA, Developer, Operator), 32 skills across 6 operational domains, and built-in safety hooks.", author: { name: "Cockroach Labs" }, category: "database", source: { source: "url", url: "https://github.com/cockroachdb/claude-plugin.git", sha: "6c96c6394a61f366e8ec1b7cec2281e97507cbff" }, homepage: "https://github.com/cockroachdb/claude-plugin" }, { name: "code-modernization", description: "Modernize legacy codebases (COBOL, legacy Java/C++, monolith web apps) with a structured preflight / assess / map / extract-rules / brief / reimagine / transform / harden workflow, an interactive topology viewer, and specialist review agents", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/code-modernization", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-modernization" }, { name: "code-review", description: "Automated code review for pull requests using multiple specialized agents with confidence-based scoring to filter false positives", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/code-review", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/code-review" }, { name: "code-simplifier", description: "Agent that simplifies and refines code for clarity, consistency, and maintainability while preserving functionality. Focuses on recently modified code.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/code-simplifier", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-simplifier" }, { name: "coderabbit", description: "Your code review partner. CodeRabbit provides external validation using a specialized AI architecture and 40+ integrated static analyzers—offering a different perspective that catches bugs, security vulnerabilities, logic errors, and edge cases. Context-aware analysis via AST parsing and codegraph relationships. Automatically incorporates CLAUDE.md and project coding guidelines into reviews. Useful after writing or modifying code, before commits, when implementing complex or security-sensitive logic, or when a second opinion would increase confidence in the changes. Returns specific findings with suggested fixes that can be applied immediately. Free to use.", category: "productivity", source: { source: "url", url: "https://github.com/coderabbitai/skills.git", sha: "3e8763d24d543b48615b82535d02288de3ddae40" }, homepage: "https://github.com/coderabbitai/skills" }, { name: "codspeed", description: "CodSpeed is the all-in-one performance testing toolkit. Dive into benchmarking results, flamegraphs, and performance comparisons — give Claude granular profiling context to pinpoint bottlenecks and autonomously iterate on performance via the CodSpeed MCP server.", author: { name: "CodSpeed" }, category: "development", source: { source: "url", url: "https://github.com/CodSpeedHQ/codspeed.git", sha: "f08dee66d0d200527f7f3c5a1e5276aec4d50beb" }, homepage: "https://codspeed.io" }, { name: "commit-commands", description: "Commands for git commit workflows including commit, push, and PR creation", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/commit-commands", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/commit-commands" }, { name: "confidence", description: "Access Confidence feature flags, experiments, and migration tools directly from Claude Code.", author: { name: "Spotify Confidence" }, category: "development", source: { source: "url", url: "https://github.com/spotify/confidence-ai-plugins.git", sha: "f416826fde819978ab90f1d7ae27513667aa5d0f" }, homepage: "https://confidence.spotify.com" }, { name: "context7", description: "Upstash Context7 MCP server for up-to-date documentation lookup. Connects to Context7's hosted remote MCP server (https://mcp.context7.com/mcp) — no local Node.js or npx required — to pull version-specific documentation and code examples directly from source repositories into your LLM context. Works anonymously out of the box; set CONTEXT7_API_KEY for higher rate limits.", author: { name: "Upstash" }, category: "development", source: "./external_plugins/context7", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/context7", tags: ["community-managed"] }, { name: "convex", displayName: "Convex", description: "Official Convex plugin for Claude Code with bundled Convex skills, the convex-expert subagent for code-writing, a runtime-error monitor, and MCP access for backend development, schema design, real-time features, auth, file storage, scheduled jobs, and AI agents.", author: { name: "Convex", url: "https://convex.dev" }, category: "database", source: { source: "url", url: "https://github.com/get-convex/convex-backend-skill.git", sha: "6ca54f6e2e7582812187b8a5a4783fb4dff52692" }, homepage: "https://github.com/get-convex/convex-backend-skill", keywords: ["convex", "backend", "database", "realtime", "reactive", "websocket", "auth", "storage", "scheduler", "cron", "agent", "rag", "mobile", "typescript", "mcp"] }, { name: "crowdsec", description: "Operational skill for installing, configuring, operating, and debugging CrowdSec (cscli, LAPI/CAPI, hub, bouncers, WAF/AppSec) across bare-metal, Docker, and Kubernetes.", author: { name: "CrowdSec" }, category: "security", source: { source: "url", url: "https://github.com/crowdsecurity/crowdsec-skill.git", sha: "24488e03c9c0b34596de3e21004b24d4d05a6df7" }, homepage: "https://www.crowdsec.net" }, { name: "crowdstrike-falcon-foundry", description: "CrowdStrike Falcon Foundry development skills for building cybersecurity applications on the Falcon platform. Includes UI development, collections, functions, workflows, API integration, security patterns, and debugging workflows.", author: { name: "CrowdStrike" }, category: "security", source: { source: "url", url: "https://github.com/CrowdStrike/foundry-skills.git", sha: "7f7d46687c16a9a37c9b08ad58ad58999aabe497" }, homepage: "https://github.com/CrowdStrike/foundry-skills" }, { name: "crowdstrike-falcon-fusion", description: "CrowdStrike Falcon Fusion skills for authoring, deploying, and executing Fusion workflows. Includes live action discovery, YAML authoring with schema validation, workflow import and release, execution monitoring, and Falcon Next-Gen SIEM lookup files.", author: { name: "CrowdStrike" }, category: "security", source: { source: "url", url: "https://github.com/CrowdStrike/fusion-skills.git", sha: "3e15710a94b712473e87ce7cd7c43d026156a3f3" }, homepage: "https://github.com/CrowdStrike/fusion-skills" }, { name: "csharp-lsp", description: "C# language server for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/csharp-lsp", category: "development", strict: false, lspServers: { "csharp-ls": { command: "csharp-ls", extensionToLanguage: { ".cs": "csharp" } } } }, { name: "cwc-makers", description: "Onboard a Code-with-Claude Makers Cardputer with one /maker-setup command — clones the build-with-claude repo, flashes UIFlow firmware, and installs the Claude Buddy app bundle.", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/cwc-makers", category: "productivity", homepage: "https://claude.com/cwc-makers" }, { name: "dash0", description: "OpenTelemetry observability for Claude Code sessions. Captures tool calls, LLM invocations, token usage, and errors as OTel traces. Send telemetry to Dash0 or any OpenTelemetry-compatible backend.", author: { name: "Dash0" }, category: "monitoring", source: { source: "url", url: "https://github.com/dash0hq/dash0-agent-plugin.git", sha: "72a84179e6c64871ad5b6fceb09e00f502de415a" }, homepage: "https://dash0.com/" }, { name: "data", description: "Data engineering for Apache Airflow and Astronomer. Author DAGs with best practices, debug pipeline failures, trace data lineage, profile tables, migrate Airflow 2 to 3, and manage local and cloud deployments.", category: "development", source: { source: "url", url: "https://github.com/astronomer/agents.git", sha: "9b5a33171e36ecda135f22e77a845d9c405b519e" }, homepage: "https://github.com/astronomer/agents" }, { name: "data-agent-kit-starter-pack", description: "This plugin provides a specialized suite of skills for data engineers and database practitioners working on Google Cloud. It acts as an expert assistant, allowing you to use natural language prompts in your preferred coding agent to architect complex data pipelines, transform data with dbt, write Spark and BigQuery SQL notebooks, and orchestrate end-to-end workflows across GCP's data ecosystem.", author: { name: "Google LLC" }, category: "development", source: { source: "url", url: "https://github.com/gemini-cli-extensions/data-agent-kit-starter-pack.git", sha: "2df10e25bbf7dba2570dce1b2e2e77870143969e" }, homepage: "https://github.com/gemini-cli-extensions/data-agent-kit-starter-pack" }, { name: "data-engineering", description: "Data engineering plugin - warehouse exploration, pipeline authoring, Airflow integration", source: { source: "url", url: "https://github.com/astronomer/agents.git", sha: "9b5a33171e36ecda135f22e77a845d9c405b519e" }, homepage: "https://github.com/astronomer/agents" }, { name: "databases-on-aws", description: "Expert database guidance for the AWS database portfolio. Design schemas, execute queries, handle migrations, and choose the right database for your workload.", category: "database", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/databases-on-aws", ref: "main", sha: "097fe8ad56d8a1d5e2c81d7880adf145553cf244" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "databricks", description: "Databricks skills for the CLI, Apps, Lakebase, Model Serving, Lakeflow Jobs, Spark Declarative Pipelines, Declarative Automation Bundles (DABs), and classic-to-serverless migration.", author: { name: "Databricks" }, category: "database", source: { source: "git-subdir", url: "https://github.com/databricks/databricks-agent-skills.git", path: "plugins/databricks/claude", ref: "main", sha: "0fbf9ba4cdb2fd5a0efd952e8225acc1d5099809" }, homepage: "https://developers.databricks.com/" }, { name: "datadog", description: "Use Datadog directly in Claude Code through a preconfigured Datadog MCP server. Query logs, metrics, traces, dashboards, and more through natural conversation. This plugin is in preview.", author: { name: "Datadog" }, category: "monitoring", source: { source: "url", url: "https://github.com/datadog-labs/claude-code-plugin.git", sha: "195f570c002beab3d7bd342739034d0019aa4863" }, homepage: "https://www.datadoghq.com/" }, { name: "datahub-skills", description: "DataHub development and interaction toolkit with connector planning, PR review, catalog search, metadata enrichment, lineage tracing, data quality management, and connection setup skills", author: { name: "DataHub" }, category: "database", source: { source: "url", url: "https://github.com/datahub-project/datahub-skills.git", sha: "c6d0ded76eca4c649276e39ab376ad6c66142eb7" }, homepage: "https://datahub.com" }, { name: "dataproc", description: "Manage Dataproc clusters and jobs.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/dataproc.git", sha: "afbd516845a34fcf460ec447b81868bc48962b0f" }, homepage: "https://github.com/gemini-cli-extensions/dataproc" }, { name: "datarobot-agent-skills", description: "DataRobot skills for AI/ML workflows — model training, deployment, predictions, feature engineering, monitoring, explainability, data preparation, App Framework CI/CD, and external agent monitoring.", author: { name: "DataRobot" }, category: "development", source: { source: "url", url: "https://github.com/datarobot-oss/datarobot-agent-skills.git", sha: "e6dddbe327dc2c83e9b7677a5577d33a1063feaf" }, homepage: "https://datarobot.com" }, { name: "dataverse", description: "Agent skills for building on, analyzing, and managing Microsoft Dataverse — with Dataverse MCP, PAC CLI, and Python SDK.", category: "database", source: { source: "git-subdir", url: "https://github.com/microsoft/Dataverse-skills.git", path: ".github/plugins/dataverse", ref: "main", sha: "ee929195a7d724c315e45f6dc3ebc4e59370fce2" }, homepage: "https://github.com/microsoft/Dataverse-skills" }, { name: "deepeval", description: "Skills for adding DeepEval evaluations, tracing, datasets, Confident AI reports, and iterative improvement loops to AI applications.", author: { name: "Confident AI", email: "open-source@confident-ai.com" }, category: "development", source: { source: "url", url: "https://github.com/confident-ai/deepeval.git", sha: "c144abbce848a6dfbd35bbdaaab49a62bb3fb7b6" }, homepage: "https://github.com/confident-ai/deepeval" }, { name: "deploy-on-aws", description: "Deploy applications to AWS with architecture recommendations, cost estimates, and IaC deployment.", category: "deployment", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/deploy-on-aws", ref: "main", sha: "efe040ab66ed7eb4bccc0a94133181da5bc57567" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "desktop-commander", description: "MCP server for terminal commands, process management, and file operations across text, code, PDF, DOCX, Excel, images, and structured data.", author: { name: "Desktop Commander" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/wonderwhy-er/DesktopCommanderMCP.git", path: "plugins/claude", ref: "main", sha: "1eccc8b09cc09805202a1737fd20d605356c3671" }, homepage: "https://desktopcommander.app" }, { name: "discord", description: "Discord messaging bridge with built-in access control. Manage pairing, allowlists, and policy via /discord:access.", category: "productivity", source: "./external_plugins/discord" }, { name: "dominodatalab", description: "Full Domino Data Lab platform support — workspaces, jobs, model deployment, experiment tracking, GenAI tracing, Spark/Ray/Dask, and app deployment for data science teams", author: { name: "Domino Data Lab" }, category: "development", source: { source: "url", url: "https://github.com/dominodatalab/domino-claude-plugin.git", sha: "d86698d74d56d3934c8f8ddccb4f6aa55eb2bba7" }, homepage: "https://www.domino.ai" }, { name: "dropbox", description: "The Dropbox plugin for Claude connects your Dropbox files directly to Claude, so you can search, organize, save generated content, and create sharing links without switching tools. It respects your existing Dropbox permissions, and Claude only works with files you already have access to.", author: { name: "Dropbox" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/dropbox/dropbox-ai-plugins.git", path: "claude", ref: "main", sha: "4135e81caf8275b4c97caef244479e0dcb6fb823" }, homepage: "https://www.dropbox.com" }, { name: "duckdb-skills", description: "DuckDB-powered skills for Claude Code: read any data file, attach and query DuckDB databases, search DuckDB/DuckLake docs, search past session logs, and install/update DuckDB extensions.", author: { name: "DuckDB Foundation" }, category: "database", source: { source: "url", url: "https://github.com/duckdb/duckdb-skills.git", sha: "7feda8e01e22bc0886c86123f3884947e36d8c69" }, homepage: "https://duckdb.org" }, { name: "duende-skills", description: "Duende development skills and agents for Claude Code — covering OAuth/OIDC protocols, IdentityServer, token management, ASP.NET Core authentication/authorization, BFF patterns, and secure identity architecture", author: { name: "Duende Software" }, category: "security", source: { source: "url", url: "https://github.com/DuendeSoftware/duende-skills.git", sha: "fb32edc51982bf1c600e21ba91df32c903098a9c" }, homepage: "https://duendesoftware.com" }, { name: "exa", description: "Exa AI web search, deep research, and content extraction. Provides MCP tools and research skills for comprehensive web search, people discovery, company research, academic papers, and more.", author: { name: "Exa" }, category: "productivity", source: { source: "url", url: "https://github.com/exa-labs/exa-mcp-server.git", sha: "15ffb50519e719dc791cdc750ce5ed1934c0a1ed" }, homepage: "https://exa.ai/docs/reference/exa-mcp" }, { name: "explanatory-output-style", description: "Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style)", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/explanatory-output-style", category: "learning", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/explanatory-output-style" }, { name: "expo", description: "Official Expo skills for building, deploying, upgrading, and debugging React Native apps with Expo. Covers UI development with Expo Router, SwiftUI and Jetpack Compose components, Tailwind CSS setup, API routes, data fetching, CI/CD workflows, App Store and Play Store deployment, SDK upgrades, DOM components, and dev client distribution.", category: "development", source: { source: "git-subdir", url: "https://github.com/expo/skills.git", path: "plugins/expo", ref: "main", sha: "39708666ce7014def1f8e34f3d8c93e8d3f588bb" }, homepage: "https://github.com/expo/skills/blob/main/plugins/expo/README.md" }, { name: "fakechat", description: "Localhost web chat for testing the channel notification flow. No tokens, no access control, no third-party service.", category: "development", source: "./external_plugins/fakechat" }, { name: "fastly-agent-toolkit", description: "Fastly development tools and platform skills", source: { source: "url", url: "https://github.com/fastly/fastly-agent-toolkit.git", sha: "abb9d42a5318d67b52b39db9f5b88289ec1567c4" }, homepage: "https://github.com/fastly/fastly-agent-toolkit/blob/main/README.md" }, { name: "feature-dev", description: "Comprehensive feature development workflow with specialized agents for codebase exploration, architecture design, and quality review", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/feature-dev", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/feature-dev" }, { name: "fiftyone", description: "Build high-quality datasets and computer vision models. Visualize datasets, analyze models, find duplicates, run inference, evaluate predictions, and develop custom plugins.", source: { source: "url", url: "https://github.com/voxel51/fiftyone-skills.git", sha: "e28a9a3d453b15cbefa6ccc81c89fecf723c31b2" }, homepage: "https://docs.voxel51.com/" }, { name: "figma", description: "Figma design platform integration. Access design files, extract component information, read design tokens, and translate designs into code. Bridge the gap between design and development workflows.", category: "design", source: { source: "url", url: "https://github.com/figma/mcp-server-guide.git", sha: "d638a5e055e8d95e0394a94350860398cf424b74" }, homepage: "https://github.com/figma/mcp-server-guide" }, { name: "firebase", description: "Google Firebase MCP integration. Manage Firestore databases, authentication, cloud functions, hosting, and storage. Build and manage your Firebase backend directly from your development workflow.", category: "database", source: "./external_plugins/firebase", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/firebase" }, { name: "firecrawl", description: "Web scraping and crawling powered by Firecrawl. Turn any website into clean, LLM-ready markdown or structured data. Scrape single pages, crawl entire sites, search the web, and extract structured information. Includes an AI agent for autonomous multi-source data gathering - just describe what you need and it finds, navigates, and extracts automatically.", category: "development", source: { source: "url", url: "https://github.com/firecrawl/firecrawl-claude-plugin.git", sha: "998fc11580f3edda3488a4b579ddbebf6600651f" }, homepage: "https://github.com/firecrawl/firecrawl-claude-plugin.git" }, { name: "firestore-native", description: "Connect and interact with Firestore databases, collections, and documents.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/firestore-native.git", sha: "502ff19b853e760539717d3c640300af3400bba3" }, homepage: "https://github.com/gemini-cli-extensions/firestore-native" }, { name: "forge-skills", description: "Forge-focused skills and MCP configuration for Atlassian Forge: scaffold and deploy apps (forge create, templates, dev spaces), build Teamwork Graph connectors for Rovo Search/Rovo Chat, pre-deploy review, systematic debugging, plus Forge docs and Atlassian Design System lookups via MCP.", author: { name: "Atlassian" }, category: "development", source: { source: "url", url: "https://github.com/atlassian/forge-skills.git", sha: "4f04ae02879435f23808a4798da28f75d3ab74c3" }, homepage: "https://developer.atlassian.com/platform/forge/" }, { name: "frontend-design", description: "Create distinctive, production-grade frontend interfaces with high design quality. Generates creative, polished code that avoids generic AI aesthetics.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/frontend-design", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/frontend-design" }, { name: "fullstory", description: "Connect Claude to Fullstory to query behavioral analytics, session replays, and customer experience insights.", author: { name: "Fullstory" }, category: "monitoring", source: { source: "url", url: "https://github.com/fullstorydev/fullstory-skills.git", sha: "b20614e2d08d7a7c70775bb62b5af640f60b024b" }, homepage: "https://www.fullstory.com" }, { name: "gc-ai", displayName: "GC AI", description: "Work in your GC AI legal knowledge base from Claude: upload documents, run review playbooks, and ask questions grounded in your own files, all as you.", author: { name: "GC AI" }, category: "productivity", source: { source: "url", url: "https://github.com/GC-AI-Inc/gc-ai-claude-plugin.git", sha: "efda779972c7b7162e79234e164bc2f359a8a518" }, homepage: "https://docs.gc.ai/api-reference/mcp/overview" }, { name: "github", description: "Official GitHub MCP server for repository management. Create issues, manage pull requests, review code, search repositories, and interact with GitHub's full API directly from Claude Code.", category: "productivity", source: "./external_plugins/github", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/github" }, { name: "gitkraken", description: "Gives Claude access to your real Git and project context: commits, branches, pull requests, and issues across every repo you work in. Works with GitHub, GitLab, Azure DevOps, Bitbucket, and Jira.", author: { name: "GitKraken" }, category: "development", source: { source: "url", url: "https://github.com/gitkraken/claude-plugin.git", sha: "f7a53b2cd138c22eccb977b9d93494ea6d423d12" }, homepage: "https://www.gitkraken.com" }, { name: "gitlab", description: "GitLab DevOps platform integration. Manage repositories, merge requests, CI/CD pipelines, issues, and wikis. Full access to GitLab's comprehensive DevOps lifecycle tools.", category: "productivity", source: "./external_plugins/gitlab", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/gitlab" }, { name: "google-cloud-storage", description: "Official Google Cloud Storage (GCS) plugin. Manage buckets and objects, transfer data, and configure MCP, FUSE, IAM, security, lifecycle rules, signed URLs, Terraform, and the CLI.", author: { name: "Google LLC" }, category: "deployment", source: { source: "url", url: "https://github.com/gemini-cli-extensions/google-cloud-storage.git", sha: "c7e3eeefa14ac0492a024458061d662e8b04c891" }, homepage: "https://cloud.google.com/storage" }, { name: "gopls-lsp", description: "Go language server for code intelligence and refactoring", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/gopls-lsp", category: "development", strict: false, lspServers: { gopls: { command: "gopls", extensionToLanguage: { ".go": "go" } } } }, { name: "grafana-assistant", description: "Skills and rules for developing and using the Grafana Assistant app and CLI.", author: { name: "Grafana" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/grafana/ai-marketplace.git", path: "plugins/grafana-assistant", ref: "main", sha: "a5c72f2d74c640e9675eb0249526447968535015" }, homepage: "https://grafana.com" }, { name: "grafana-cloud-mcp", description: "Hosted MCP server for AI-assisted Grafana Cloud observability — no local installation required.", author: { name: "Grafana" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/grafana/ai-marketplace.git", path: "plugins/grafana-cloud-mcp", ref: "main", sha: "12be5634a492f73c189d466c5449d09b853ad7a4" }, homepage: "https://grafana.com" }, { name: "grafana-mcp", description: "MCP server for AI-assisted Grafana dashboard, datasource, alerting, and incident management.", author: { name: "Grafana" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/grafana/ai-marketplace.git", path: "plugins/grafana-mcp", ref: "main", sha: "a5c72f2d74c640e9675eb0249526447968535015" }, homepage: "https://grafana.com" }, { name: "greptile", description: "AI code review agent for GitHub and GitLab. View and resolve Greptile's PR review comments, run reviews on your working branch, and search your organization's knowledge base and coding patterns, directly from Claude Code.", author: { name: "Greptile", url: "https://greptile.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/greptileai/claude-plugin.git", path: "plugins/greptile", ref: "greptile--v1.2.3", sha: "6b725af2636072cab79e0a5426f6a960b0fd29ef" }, homepage: "https://www.greptile.com/docs/mcp-v2/overview" }, { name: "growthbook", description: "A suite of agent skills for the full GrowthBook feature flag and experimentation lifecycle.", author: { name: "GrowthBook" }, category: "testing", source: { source: "url", url: "https://github.com/growthbook/skills.git", sha: "eb7960d4fe5034bd8d8f100320192d1691a173ac" }, homepage: "https://growthbook.io" }, { name: "honeycomb", description: "Skills, agents, and workflows for Honeycomb observability — query patterns, production investigations, SLOs, OpenTelemetry instrumentation, and Beeline migration. Designed to complement the Honeycomb MCP server.", author: { name: "Honeycomb" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/honeycombio/agent-skill.git", path: "honeycomb", ref: "main", sha: "41214b7dfb97f262adabf295fa6f0fcad85bc0f6" }, homepage: "https://www.honeycomb.io" }, { name: "hookify", description: "Easily create custom hooks to prevent unwanted behaviors by analyzing conversation patterns or from explicit instructions. Define rules via simple markdown files.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/hookify", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/hookify" }, { name: "hostinger", displayName: "Hostinger", description: "Deploy, manage and monitor Hostinger services — Websites, Domains, Ecommerce, Email Marketing, Subscriptions & Payments, and VPS. Authenticate via browser (OAuth) or API token.", author: { name: "Hostinger" }, category: "deployment", source: { source: "url", url: "https://github.com/hostinger/claude-plugin.git", sha: "569880c60681a7068b3ca8ca84e2fe7ab6cfa7ff" }, homepage: "https://www.hostinger.com" }, { name: "huggingface-skills", description: "Build, train, evaluate, and use open source AI models, datasets, and spaces.", category: "development", source: { source: "url", url: "https://github.com/huggingface/skills.git", sha: "f3186efbbc322121eb5d0f31e8a1d669ee961159" }, homepage: "https://github.com/huggingface/skills.git" }, { name: "hunter", description: "Find and verify professional email addresses, search contacts by domain, and enrich company data -- directly in Claude.", author: { name: "Hunter.io" }, category: "productivity", source: { source: "url", url: "https://github.com/hunter-io/claude-plugin.git", sha: "ce0ccac337b8ccc0506c943e765d3e4506c87080" }, homepage: "https://hunter.io" }, { name: "hyperframes", description: "HyperFrames by HeyGen. Write HTML, render video. Compositions, GSAP and runtime adapter animations, captions, voiceovers, audio-reactive visuals, and website-to-video capture for HyperFrames.", author: { name: "HeyGen" }, category: "design", source: { source: "url", url: "https://github.com/heygen-com/hyperframes.git", sha: "a8a9fdb0fe88d97c99d7bd30da94e64dd0a96f3d" }, homepage: "https://hyperframes.heygen.com" }, { name: "idmp-plugin", description: "TDengine IDMP plugin with packaged skills for discovery, schema inspection, and safe operational workflows.", author: { name: "TaosData", email: "it@taosdata.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/taosdata/agent-skills.git", path: "plugins/idmp-plugin", ref: "main", sha: "0b67242e2cd114ad9631c39aa20969fdd9780a11" }, homepage: "https://github.com/taosdata/agent-skills" }, { name: "imessage", description: "iMessage messaging bridge with built-in access control. Reads chat.db directly, sends via AppleScript. Manage pairing, allowlists, and policy via /imessage:access.", category: "productivity", source: "./external_plugins/imessage" }, { name: "incident-io", description: "Work with incident.io from Claude: respond to and investigate incidents, check on-call schedules and escalations, and author the runbooks, skills and architecture docs that incident.io investigations draw on. Bundles the official incident.io MCP server (OAuth on first use).", author: { name: "incident.io" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/incident-io/skills.git", path: "plugins/incident-io", ref: "main", sha: "6d0bbfc9e52256fc39326b9ba6d08f16831b60ae" }, homepage: "https://incident.io" }, { name: "informatica-for-claude-platform", description: "Governed catalog discovery for Informatica Intelligent Data Management Cloud (CDGC): find tables, columns, files, glossary terms and policies across the enterprise catalog, check ownership, certification, sensitivity and applicable policy, and get safe-usage guidance grounded in catalog metadata before querying any data. Requires an Informatica IDMC tenant and the Informatica Catalog Discovery connector.", author: { name: "Informatica" }, category: "database", source: { source: "git-subdir", url: "https://github.com/forcedotcom/informatica-claude-plugins.git", path: "informatica-for-claude-platform", ref: "main", sha: "554d02e0f7f2adafeaeeedbde04435b7bd310a47" }, homepage: "https://github.com/forcedotcom/informatica-claude-plugins/tree/main/informatica-for-claude-platform" }, { name: "intercom", description: "Intercom integration for Claude Code. Search conversations, analyze customer support patterns, look up contacts and companies, and install the Intercom Messenger. Connect your Intercom workspace to get real-time insights from customer data.", category: "productivity", source: { source: "url", url: "https://github.com/intercom/claude-plugin-external.git", sha: "62773a7d4b8aac31545d6888fe6479be3bc53804" }, homepage: "https://github.com/intercom/claude-plugin-external" }, { name: "intuit-quickbooks", description: "QuickBooks business insights and actions: financial health briefings across P&L, cash flow, balance sheet and A/R, industry benchmarking, payroll cost analysis, overdue-invoice reminders, estimate/invoice drafting from email, payroll onboarding and base-pay changes (with confirmation), and QuickBooks Capital lending guidance. Requires the Intuit QuickBooks connector.", author: { name: "Intuit QuickBooks" }, category: "productivity", source: { source: "url", url: "https://github.com/intuit/quickbooks-claude-plugin.git", sha: "c8daa17a64d4d0fdeabdf0516524f72549b6ad19" }, homepage: "https://github.com/intuit/quickbooks-claude-plugin" }, { name: "jdtls-lsp", description: "Java language server (Eclipse JDT.LS) for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/jdtls-lsp", category: "development", strict: false, lspServers: { jdtls: { command: "jdtls", extensionToLanguage: { ".java": "java" }, startupTimeout: 120000 } } }, { name: "jfrog", description: "Use the JFrog Platform from Claude Code: Artifactory repos and artifacts, security findings and exposures, Catalog package safety and downloads, workflows across the SDLC, and platform administration.", author: { name: "JFrog Ltd.", url: "https://jfrog.com" }, category: "security", source: { source: "url", url: "https://github.com/jfrog/claude-plugin.git", sha: "c4049d7ca5a745afed97368ab7d65e146c450673" }, homepage: "https://jfrog.com" }, { name: "knowledge-catalog", description: "Connect to Knowledge Catalog to discover, manage, monitor, and govern data and AI artifacts across your data platform", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/knowledge-catalog.git", sha: "930d73cfbb8e0637d79cb335ff0b8d80af383bd8" }, homepage: "https://github.com/gemini-cli-extensions/knowledge-catalog" }, { name: "kotlin-lsp", description: "Kotlin language server for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/kotlin-lsp", category: "development", strict: false, lspServers: { "kotlin-lsp": { command: "kotlin-lsp", args: ["--stdio"], extensionToLanguage: { ".kt": "kotlin", ".kts": "kotlin" }, startupTimeout: 120000 } } }, { name: "langfuse-observability", description: "Langfuse observability plugin for Claude Code — captures and exports traces, spans, and session telemetry from Claude Code to Langfuse for LLM monitoring, debugging, and evaluation", author: { name: "Langfuse" }, category: "monitoring", source: { source: "url", url: "https://github.com/langfuse/claude-observability-plugin.git", sha: "b5211009698fdfe79c6bbe90d6901ad255ea65d3" }, homepage: "https://langfuse.com/integrations/other/claude-code" }, { name: "laravel-boost", description: "Laravel development toolkit MCP server. Provides intelligent assistance for Laravel applications including Artisan commands, Eloquent queries, routing, migrations, and framework-specific code generation.", category: "development", source: "./external_plugins/laravel-boost", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/laravel-boost" }, { name: "leadfeeder", description: "Turn website visitor signals into pipeline with Leadfeeder: daily visitor briefs, visitor company research, buyer and contact discovery, personalised outreach drafts, and adding companies to your Leadfeeder lists, via the Leadfeeder connector. Requires a Leadfeeder account.", author: { name: "Leadfeeder" }, category: "productivity", source: { source: "url", url: "https://github.com/Leadfeeder/leadfeeder-mcp-plugin.git", sha: "f344f4383363199963c34a0c353e09d26596d501" }, homepage: "https://www.leadfeeder.com" }, { name: "learn-with-coursera", description: "Turn any learning intent into a personalized Coursera experience. Asks three quick questions (topic, familiarity, preferred format), searches Coursera's catalog, and delivers the right next step — a course, hands-on project, short video, or live roleplay — then maps a path forward. Requires the Coursera connector for catalog tools.", author: { name: "Coursera" }, category: "learning", source: { source: "git-subdir", url: "https://github.com/coursera/skills.git", path: "skills", ref: "main", sha: "ac28fd6ebf8584e3ee196159bd6d4514fa07de0f" }, strict: false, skills: ["./learn-with-coursera"], homepage: "https://github.com/coursera/skills" }, { name: "learning-output-style", description: "Interactive learning mode that requests meaningful code contributions at decision points (mimics the unshipped Learning output style)", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/learning-output-style", category: "learning", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/learning-output-style" }, { name: "legalzoom", description: "Attorney guidance and legal tools for business and personal needs. AI-powered document review identifies critical risks and important clauses, advises when to engage an attorney, and routes to LegalZoom's network when professional expertise is needed.", category: "productivity", source: { source: "git-subdir", url: "https://github.com/legalzoom/claude-plugins.git", path: "plugins/legalzoom", ref: "main", sha: "f9fd8a0ca6e1421bc1aacb113a109663a7a6f6d8" }, homepage: "https://www.legalzoom.com/" }, { name: "linear", description: "Linear issue tracking integration. Create issues, manage projects, update statuses, search across workspaces, and streamline your software development workflow with Linear's modern issue tracker.", category: "productivity", source: "./external_plugins/linear", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/linear" }, { name: "liquid-lsp", description: "LSP integration for Shopify Liquid templates via the Shopify CLI theme language server.", author: { name: "Shopify" }, category: "development", source: { source: "git-subdir", url: "https://github.com/Shopify/liquid-skills.git", path: "plugins/liquid-lsp", ref: "main", sha: "ae3e4cc3f454923e388bbd841fd931f0c7bf5be4" }, homepage: "https://github.com/Shopify/liquid-skills/tree/main/plugins/liquid-lsp" }, { name: "liquid-skills", description: "Liquid language fundamentals, CSS/JS/HTML coding standards, and WCAG accessibility patterns for Shopify themes", author: { name: "Shopify" }, category: "development", source: { source: "git-subdir", url: "https://github.com/Shopify/liquid-skills.git", path: "plugins/liquid-skills", ref: "main", sha: "ae3e4cc3f454923e388bbd841fd931f0c7bf5be4" }, homepage: "https://github.com/Shopify/liquid-skills/tree/main/plugins/liquid-skills" }, { name: "logfire", description: "Add Logfire observability to Python applications with auto-instrumentation for FastAPI, httpx, asyncpg, SQLAlchemy, and more", author: { name: "Pydantic" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/pydantic/skills.git", path: "plugins/logfire", ref: "main", sha: "501b11a5b3f92b9c78bbe9bd76442df0ad68dadf" }, homepage: "https://github.com/pydantic/skills/tree/main/plugins/logfire" }, { name: "logrocket", description: "Connect Claude Code to LogRocket to query session replays, metrics, issues, and user behavior using natural language.", author: { name: "LogRocket" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/LogRocket/logrocket-claude-plugin.git", path: "plugins/logrocket", ref: "main", sha: "2e44dbb47faf9bb54e3405a8ae2714e7c5ce9791" }, homepage: "https://logrocket.com" }, { name: "looker", description: "Connect to Looker and interact with your data using LookML.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/looker.git", sha: "eb4a1828dc7adc346f6f23d47a73421392b7f86b" }, homepage: "https://github.com/gemini-cli-extensions/looker" }, { name: "lovable", description: "Build, iterate on, deploy, and manage Lovable apps from Claude Code. Bundles the official Lovable MCP server (remote, OAuth 2.1) and adds focused commands for the common build/iterate/database workflows, with credit- and publish-safety prompts.", author: { name: "Lovable" }, category: "development", source: { source: "url", url: "https://github.com/lovablelabs/mcp.git", sha: "0336e6db8026b0f02cb89d1451cc48ea3f469791" }, homepage: "https://lovable.dev" }, { name: "lua-lsp", description: "Lua language server for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/lua-lsp", category: "development", strict: false, lspServers: { lua: { command: "lua-language-server", extensionToLanguage: { ".lua": "lua" } } } }, { name: "lumen", description: "Precise local semantic code search via MCP. Indexes your codebase with Go AST parsing, embeds with Ollama or LM Studio, and exposes vector search to Claude through an MCP server — no cloud, no npm.", author: { name: "Ory Corp" }, category: "development", source: { source: "url", url: "https://github.com/ory/lumen.git", sha: "f60f9ecee41723b42f3758e9a9409141881ac7d5" }, homepage: "https://www.ory.sh" }, { name: "lusha", description: "Prospect, enrich, and build call-ready lead lists using Lusha's B2B intelligence platform — verified phone numbers, company signals, and lookalike targeting.", author: { name: "Lusha" }, category: "productivity", source: { source: "url", url: "https://github.com/lusha-oss/lusha-mcp-plugin.git", sha: "ed34947a36754411f03cdeaba91c8cdaa153ef2e" }, homepage: "https://www.lusha.com" }, { name: "mapbox", description: "Mapbox skills and MCP servers for building location-aware applications with AI. Includes geospatial tools, style management, and patterns for web, iOS, Android, and AI agent frameworks.", author: { name: "Mapbox" }, category: "location", source: { source: "url", url: "https://github.com/mapbox/mapbox-agent-skills.git", sha: "aab3a6fef5c62b7c42c1f68e05885a1b50c42d24" }, homepage: "https://www.mapbox.com" }, { name: "math-olympiad", description: "Solve competition math (IMO, Putnam, USAMO) with adversarial verification that catches what self-verification misses. Fresh-context verifiers attack proofs with specific failure patterns. Calibrated abstention over bluffing.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/math-olympiad", category: "math", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/math-olympiad" }, { name: "mattpocock-skills", description: "Matt Pocock's agent skills for real engineering — grilling, spec/ticket flows, TDD, code review, domain modelling and more. Plug-and-play, not vibe coding.", author: { name: "Matt Pocock" }, category: "development", source: { source: "url", url: "https://github.com/mattpocock/skills.git", sha: "959a8e9f1edc3adbe2f7e3054bb6fbefa6696260" }, homepage: "https://github.com/mattpocock/skills" }, { name: "mcp-apps", description: "Skills for creating MCP Apps with the MCP Apps SDK", author: { name: "Anthropic / Model Context Protocol" }, category: "development", source: { source: "git-subdir", url: "https://github.com/modelcontextprotocol/ext-apps.git", path: "plugins/mcp-apps", ref: "main", sha: "352f6ced4d80772e92b4e7a311854481a8d65b04" }, homepage: "https://modelcontextprotocol.io" }, { name: "mcp-server-dev", description: "Skills for designing and building MCP servers that work seamlessly with Claude. Guides you through deployment models (remote HTTP, MCPB, local), tool design patterns, auth, and interactive MCP apps.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/mcp-server-dev", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/mcp-server-dev" }, { name: "mcp-tunnels", description: "Connect Claude to a private MCP server through an Anthropic MCP tunnel. The /create-docker-mcp-tunnel command drives the Docker Compose quickstart end to end: certificates, proxy config, cloudflared, and a verifiable sample server.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/mcp-tunnels", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/mcp-tunnels" }, { name: "mercadopago", description: "Mercado Pago full-product integration toolkit. One agent routes to four orchestration skills (mp-integrate wizard, mp-webhooks, mp-test-setup, mp-review) that pull every endpoint, payload, and snippet live from the official Mercado Pago MCP server. The MCP must always be connected — there is no offline mode.", author: { name: "Mercado Pago Developer Experience" }, category: "development", source: { source: "git-subdir", url: "https://github.com/mercadopago/mercadopago-claude-marketplace.git", path: "plugins/mercadopago", ref: "main", sha: "c0d06959afc90b2f3d637c35eeb51c36f512c005" }, homepage: "https://github.com/mercadopago/mercadopago-claude-marketplace/tree/main/plugins/mercadopago" }, { name: "mergify", description: "Skills for the Mergify CLI: manage merge queues, stacked pull requests, Test Insights (flaky tests, quarantine), merge protections, and Mergify configuration directly from the terminal.", author: { name: "Mergify" }, category: "development", source: { source: "url", url: "https://github.com/mergifyio/mergify-cli.git", sha: "e7c1ebbc281361f0b2b7827cf583f57339c97ebc" }, homepage: "https://mergify.com" }, { name: "microsoft-docs", description: "Access official Microsoft documentation, API references, and code samples for Azure, .NET, Windows, and more.", category: "development", source: { source: "url", url: "https://github.com/MicrosoftDocs/mcp.git", sha: "f8ffde185dfd232dbf5d187c22ce299eadc3d583" }, homepage: "https://github.com/microsoftdocs/mcp" }, { name: "migration-to-aws", description: "Plan a migration from Google Cloud Platform (and OpenAI/Gemini AI workloads) to AWS. Analyzes your Infrastructure-as-Code files, app code, and GCP billing data to discover resources, design an AWS architecture, estimate costs, and generate migration artifacts — including AI-provider mapping to Amazon Bedrock. Processing is local; your data stays in your environment.", author: { name: "Amazon Web Services" }, category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/startups.git", path: "migrate/plugins/migration-to-aws", ref: "main", sha: "dd7096bd634649bc89b6511d61cff16f58623284" }, homepage: "https://github.com/awslabs/startups" }, { name: "mintlify", description: "Build beautiful documentation sites with Mintlify. Convert non-markdown files into properly formatted MDX pages, add and modify content with correct component use, and automate documentation updates.", category: "development", source: { source: "url", url: "https://github.com/mintlify/mintlify-claude-plugin.git", sha: "acd6d2e0128c4f235d55cfb8d8c91ecbdd5df8cc" }, homepage: "https://www.mintlify.com/" }, { name: "miro", description: "Secure access to Miro boards. Enables AI to read board context, create diagrams, and generate code with enterprise-grade security.", author: { name: "Miro" }, category: "design", source: { source: "git-subdir", url: "https://github.com/miroapp/miro-ai.git", path: "claude-plugins/miro", ref: "main", sha: "c2494b24510d01ec3e50fad94a0c5fc3ca40e339" }, homepage: "https://miro.com" }, { name: "modern-web-guidance", description: "Keep your coding agent up to date with the latest web best practices", author: { name: "Google Chrome" }, category: "development", source: { source: "url", url: "https://github.com/GoogleChrome/modern-web-guidance.git", sha: "16ed22b43fa56157adadfb25f18a354197d497b9" }, homepage: "https://goo.gle/modern-web-guidance" }, { name: "mlflow", description: "Skills for tracing, evaluating, and improving AI agents with MLflow. Supports the full agent improvement loop: instrument → trace → evaluate → iterate → validate.", author: { name: "MLflow Team" }, category: "monitoring", source: { source: "url", url: "https://github.com/mlflow/skills.git", sha: "85ab69be2df4f92db82ddbf4be9ce63ab3722249" }, homepage: "https://mlflow.org/" }, { name: "monday-crm", description: "Run your monday CRM in plain language. Build a pipeline from scratch, start the day with a ranked deal briefing, spin up a forecast dashboard, audit board health, clean up messy data in bulk, and turn meeting notes into deal updates. Every skill writes back into monday as a real update, doc, or dashboard. Built on the official monday MCP connector.", author: { name: "monday.com" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/mondaycom/mcp.git", path: "plugins/monday-crm", ref: "master", sha: "5eb0835e921de42ba603d7a8315ab4a2575a46b2" }, homepage: "https://monday.com" }, { name: "mongodb", description: "Official Claude plugin for MongoDB (MCP Server + Skills). Connect to databases, explore data, manage collections, optimize queries, generate reliable code, implement best practices, develop advanced features, and more.", category: "database", source: { source: "git-subdir", url: "https://github.com/mongodb/agent-skills.git", path: "plugins/mongodb", ref: "main", sha: "1e72df255e54e81eff078054c2cfb2b5d8c13503" }, homepage: "https://www.mongodb.com/docs/mcp-server/overview/" }, { name: "mongodb-atlas", description: "Connect to MongoDB Atlas clusters only through the Atlas Managed MCP Server. Sign in with your Atlas account to explore data, manage collections, optimize queries, generate reliable code with MongoDB best practices, and manage Atlas resources such as clusters, projects, database users, and network access. If you are running a different MongoDB deployment or want to run a local MongoDB MCP Server, install the MongoDB (Self-Managed MCP) plugin instead.", author: { name: "MongoDB" }, category: "database", source: { source: "git-subdir", url: "https://github.com/mongodb/agent-skills.git", path: "plugins/mongodb-atlas", ref: "main", sha: "1e72df255e54e81eff078054c2cfb2b5d8c13503" }, homepage: "https://www.mongodb.com/docs/mcp-server/get-started/" }, { name: "neon", description: "Manage your Neon projects and databases with the neon-postgres agent skill and the Neon MCP Server.", category: "database", source: { source: "git-subdir", url: "https://github.com/neondatabase/agent-skills.git", path: "plugins/neon-postgres", ref: "main", sha: "4a4266ac3da8cf29e3c995bad040ae4ac4476b28" }, homepage: "https://github.com/neondatabase/agent-skills/tree/main/plugins/neon-postgres" }, { name: "netlify-skills", description: "Netlify platform skills for Claude Code — functions, edge functions, blobs, database, image CDN, forms, config, CLI, frameworks, caching, AI gateway, and deployment.", category: "development", source: { source: "url", url: "https://github.com/netlify/context-and-tools.git", sha: "eddd0a3c67642651097a65b2d2d4194eaec173a1" }, homepage: "https://github.com/netlify/context-and-tools" }, { name: "netsuite-ai-companion", description: "Guides AI assistants that use the NetSuite AI Connector: tool-selection order, output formatting, NetSuite domain knowledge, multi-subsidiary and currency handling, and SuiteQL safety guardrails. Requires the NetSuite AI Connector Service.", author: { name: "Oracle NetSuite" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/oracle/netsuite-suitecloud-sdk.git", path: "anthropic/netsuite-ai-companion", ref: "ai-plugins-dist", sha: "23793a10a9bb557c684c5cb8a97f926eb3463f12" }, homepage: "https://github.com/oracle/netsuite-suitecloud-sdk/tree/ai-plugins-dist/anthropic/netsuite-ai-companion" }, { name: "netsuite-finance-analyst", description: "Director-level finance analysis on live NetSuite data: financial reporting, period close, variance, aging and reconciliation reviews, cash reporting, and board-ready narratives with next actions. Requires the NetSuite AI Connector Service.", author: { name: "Oracle NetSuite" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/oracle/netsuite-suitecloud-sdk.git", path: "anthropic/netsuite-finance-analyst", ref: "ai-plugins-dist", sha: "23793a10a9bb557c684c5cb8a97f926eb3463f12" }, homepage: "https://github.com/oracle/netsuite-suitecloud-sdk/tree/ai-plugins-dist/anthropic/netsuite-finance-analyst" }, { name: "netsuite-suitecloud", description: "Develop NetSuite SuiteCloud solutions with SuiteScript, SDF, and best practices: SuiteScript records and upgrades, SDF objects, roles and permissions, UIF single-page apps, OWASP secure coding, project documentation, and the SAFE Guide.", author: { name: "Oracle NetSuite" }, category: "development", source: { source: "git-subdir", url: "https://github.com/oracle/netsuite-suitecloud-sdk.git", path: "anthropic/netsuite-suitecloud", ref: "ai-plugins-dist", sha: "23793a10a9bb557c684c5cb8a97f926eb3463f12" }, homepage: "https://github.com/oracle/netsuite-suitecloud-sdk/tree/ai-plugins-dist/anthropic/netsuite-suitecloud" }, { name: "newrelic", displayName: "New Relic", description: "New Relic observability intelligence for Claude Code. Investigate APM performance, analyze cloud costs, debug Kubernetes, write NRQL queries, and respond to alerts — all from your terminal using New Relic telemetry data.", author: { name: "New Relic" }, category: "monitoring", source: { source: "url", url: "https://github.com/newrelic/claude-code-plugin.git", sha: "f8e5f8b62139072a22153ec92de1c0cc1af2f56a" }, homepage: "https://newrelic.com" }, { name: "nightvision", description: "Skills for working with NightVision, a DAST and API Discovery platform that finds exploitable vulnerabilities in web applications and REST APIs", source: { source: "url", url: "https://github.com/nvsecurity/nightvision-skills.git", sha: "957db6bb934839275c0f643042101bbb675ddbf7" }, homepage: "https://github.com/nvsecurity/nightvision-skills" }, { name: "nimble", description: "Nimble web data toolkit — search, extract, map, crawl the web and work with structured data agents", source: { source: "url", url: "https://github.com/Nimbleway/agent-skills.git", sha: "2890fdf94f0adfae79bf05b4de3c91667701bafb" }, homepage: "https://docs.nimbleway.com/integrations/agent-skills/plugin-installation" }, { name: "noibu", description: "Built for ecommerce, the Noibu plugin bridges the gap between customer experience and revenue by connecting Claude directly to your store's session, error, and conversion data through Noibu — and to the marketing, support, and commerce platforms that put insight into motion. Go beyond analysis: surface what's costing you revenue, take action across your stack, build workflows to automate work end-to-end.", author: { name: "Noibu" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/Noibu/ai-plugin.git", path: "src", ref: "main", sha: "3ff530b2dac2efd6a070ea8318a9705cd5d2d40f" }, homepage: "https://help.noibu.com/articles/3918362002-overview-of-the-noibu-plugin-for-claude" }, { name: "notion", description: "Notion workspace integration. Search pages, create and update documents, manage databases, and access your team's knowledge base directly from Claude Code for seamless documentation workflows.", category: "productivity", source: { source: "url", url: "https://github.com/makenotion/claude-code-notion-plugin.git", sha: "9847f2aa1a15f25df35ed1fb7b4557dbb60cd651" }, homepage: "https://github.com/makenotion/claude-code-notion-plugin" }, { name: "nvidia-skills", description: "Find the right NVIDIA skill for GPU acceleration, CUDA, AI agents, data loading, training, inference, robotics, Physical AI, Omniverse, simulation, and other NVIDIA-powered workflows.", author: { name: "NVIDIA" }, category: "development", source: { source: "git-subdir", url: "https://github.com/NVIDIA/skills.git", path: "plugins/nvidia-skills", ref: "main", sha: "2455514388e984b7e5a78a30e928f39d1401f16b" }, homepage: "https://build.nvidia.com/skills/" }, { name: "oracle-ai-data-platform-workbench-databricks-migrator", description: "Drive the Oracle AI Data Platform (AIDP) Databricks Migration Toolkit in natural language. Plans and executes automated Databricks → AIDP migrations of notebooks, jobs, schedules, and catalog DDL — Pass-1 dependency rewrite + Pass-2 cell-by-cell execute/verify/fix on a live AIDP cluster with Claude.", author: { name: "Oracle" }, category: "development", source: { source: "git-subdir", url: "https://github.com/oracle-samples/oracle-aidp-samples.git", path: "ai/claude-code-plugins/oracle-ai-data-platform-workbench-databricks-migrator", ref: "main", sha: "a88bcf3a9f9acca94663a727de42d8535e869486" }, homepage: "https://docs.oracle.com/en/cloud/paas/ai-data-platform/index.html" }, { name: "oracle-ai-data-platform-workbench-engineer-agent", description: "Oracle AI Data Platform (AIDP) Workbench engineer agent for Claude Code — a 37-skill agent that operates the full Spark/Delta lakehouse in natural language. Discovers your catalog into a grounding cache, turns plain English into accurate Spark SQL, and runs the lifecycle (CREATE/INSERT/UPDATE/DELETE/MERGE, OPTIMIZE/VACUUM, time-travel). Ingests files, profiles data and sets quality rules, authors and repairs pipelines, provisions clusters, and debugs via the Spark UI. Governs the platform (roles, credential store, Delta Sharing, audit logs), plus native Git, bundles, and MLOps/MLflow. Runs via the official Oracle aidp CLI.", author: { name: "Oracle" }, category: "development", source: { source: "git-subdir", url: "https://github.com/oracle-samples/oracle-aidp-samples.git", path: "ai/claude-code-plugins/oracle-ai-data-platform-workbench-engineer-agent", ref: "main", sha: "13e7a9139b3b62172119c7fc1a63bf4a2eac919d" }, homepage: "https://docs.oracle.com/en/cloud/paas/ai-data-platform/index.html" }, { name: "oracle-ai-data-platform-workbench-spark-connectors", description: "Oracle AI Data Platform Workbench Spark connectors for Claude Code. 18 connector skills covering every data source workbench customers commonly need: Oracle Autonomous DB family (ALH/ADW/ATP) via wallet/IAM-DB-Token/API-key, ExaCS, Fusion ERP REST, Fusion BICC, EPM Cloud Planning, Essbase 21c, OCI Streaming (Kafka), OCI Object Storage, Apache Iceberg, plus external systems (PostgreSQL, MySQL/HeatWave, SQL Server, Snowflake, Azure ADLS Gen2, AWS S3, generic REST, custom JDBC, Excel). Live-validated on the workbench `tpcds` cluster (Spark 3.5.0): 17 PASS / 4 ship-as-is out of 21 test rows.", author: { name: "Oracle" }, category: "development", source: { source: "git-subdir", url: "https://github.com/oracle-samples/oracle-aidp-samples.git", path: "ai/claude-code-plugins/oracle-ai-data-platform-workbench-spark-connectors", ref: "main", sha: "da0ce42f3b71cc16ee8b3a3e1ed2420c7eb180ad" }, homepage: "https://docs.oracle.com/en/cloud/paas/ai-data-platform/index.html" }, { name: "oracledb", description: "Connect, query, and interact with Oracle Databases and their data.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/oracledb.git", sha: "f8606fea23c9e7cc5ff80470964c604e04db4cc9" }, homepage: "https://github.com/gemini-cli-extensions/oracledb" }, { name: "outputai", description: "Output.ai workflow development toolkit for Claude Code. Adds 5 specialist agents (planner, builder, debugger, prompt writer, quality reviewer), 40+ slash-command skills covering scaffolding, debugging, evaluation, and credential management, plus a SessionStart hook that auto-loads Output SDK conventions so Claude understands the framework before the first prompt.", author: { name: "Output.ai" }, category: "development", source: { source: "git-subdir", url: "https://github.com/growthxai/output.git", path: "coding_assistants/claude/plugins/outputai", ref: "main", sha: "69255d7fd577139a7828bd219637d067b86a42b1" }, homepage: "https://output.ai" }, { name: "pagerduty", description: "Enhance code quality and security through PagerDuty risk scoring and incident correlation. Score pre-commit diffs against historical incident data and surface deployment risk before you ship.", category: "monitoring", source: { source: "url", url: "https://github.com/PagerDuty/claude-code-plugins.git", sha: "761cba75bd50fd561405c3b173ecf36084432089" }, homepage: "https://github.com/PagerDuty/claude-code-plugins" }, { name: "paypal", description: "PayPal development plugin for Claude — integrate payments, subscriptions, invoices, disputes, and more using PayPal's APIs and MCP server", author: { name: "PayPal" }, category: "development", source: { source: "url", url: "https://github.com/paypal/AI-Toolkit.git", sha: "310b4962f0e5b3d09ff1c909d96ad5e226703ecb" }, homepage: "https://developer.paypal.com/" }, { name: "pendo-analytics", description: "Bring Pendo product analytics into Claude Code: account health, feature adoption, session replay lookup and triage, feedback analysis, and data-informed planning grounded in real usage data. Requires the Pendo connector and a Pendo subscription.", author: { name: "Pendo" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/pendo-analytics", ref: "main", sha: "a08842848e416be803e99184130aefca6ec9afd3" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/pendo-analytics" }, { name: "pendo-guides", description: "Create production-ready Pendo in-app guides (walkthroughs, announcements, alerts, polls, promotions) as HTML/CSS/JS from a short intake conversation, using Pendo's guide components.", author: { name: "Pendo" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/pendo-guides", ref: "main", sha: "a4699be3608ba134d8c7aa4b53e220cfde1c6aac" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/pendo-guides" }, { name: "pendo-orchestrate", description: "Create, configure and edit draft Pendo Orchestrate email journeys, including multi-email and conditional split flows, via the Pendo connector. Journeys stay in draft; activation happens in the Orchestrate UI.", author: { name: "Pendo" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/pendo-orchestrate", ref: "main", sha: "a4699be3608ba134d8c7aa4b53e220cfde1c6aac" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/pendo-orchestrate" }, { name: "php-lsp", description: "PHP language server (Intelephense) for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/php-lsp", category: "development", strict: false, lspServers: { intelephense: { command: "intelephense", args: ["--stdio"], extensionToLanguage: { ".php": "php" } } } }, { name: "pigment", description: "Analyze business data and build custom Pigment models, metrics, and boards through natural language.", author: { name: "Pigment" }, category: "productivity", source: { source: "url", url: "https://github.com/gopigment/ai-plugins.git", sha: "824f0064ad1300c73a8f136ca938ade860f3c7f9" }, homepage: "https://www.pigment.com" }, { name: "pinecone", description: "Pinecone vector database integration. Streamline your Pinecone development with powerful tools for managing vector indexes, querying data, and rapid prototyping. Use slash commands like /quickstart to generate AGENTS.md files and initialize Python projects and /query to quickly explore indexes. Access the Pinecone MCP server for creating, describing, upserting and querying indexes with Claude. Perfect for developers building semantic search, RAG applications, recommendation systems, and other vector-based applications with Pinecone.", category: "database", source: { source: "url", url: "https://github.com/pinecone-io/pinecone-claude-code-plugin.git", sha: "c383d38b5cc3c5ec219f2e68026e47ffbf46524a" }, homepage: "https://github.com/pinecone-io/pinecone-claude-code-plugin" }, { name: "pixeltable", description: "Build multimodal AI applications with Pixeltable -- tables, computed columns, embedding search, UDFs, tool-calling agents, and 25+ AI provider integrations.", author: { name: "Pixeltable" }, category: "development", source: { source: "url", url: "https://github.com/pixeltable/pixeltable-skill.git", sha: "70ec6a268a29b081b7d29e55fe0221ddf6064a9e" }, homepage: "https://docs.pixeltable.com" }, { name: "planetscale", description: "An authenticated hosted MCP server that accesses your PlanetScale organizations, databases, branches, schema, and Insights data. Query against your data, surface slow queries, and get organizational and account information.", category: "database", source: { source: "url", url: "https://github.com/planetscale/claude-plugin.git", sha: "95c80f9f391be9b1b6172bf82d4191e1ec11b637" }, homepage: "https://planetscale.com/" }, { name: "playground", description: "Creates interactive HTML playgrounds — self-contained single-file explorers with visual controls, live preview, and prompt output with copy button. Includes templates for design playgrounds, data explorers, concept maps, and document critique.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/playground", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/playground" }, { name: "playwright", description: "Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, click elements, and perform automated browser testing workflows.", category: "testing", source: "./external_plugins/playwright", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/playwright" }, { name: "plugin-dev", description: "Comprehensive toolkit for developing Claude Code plugins. Includes 7 expert skills covering hooks, MCP integration, commands, agents, and best practices. AI-assisted plugin creation and validation.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/plugin-dev", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/plugin-dev" }, { name: "posthog", description: "Access PostHog analytics, feature flags, experiments, error tracking, and insights directly from Claude Code.", category: "monitoring", source: { source: "url", url: "https://github.com/PostHog/ai-plugin.git", sha: "33c066c80776a962a4233d76b20a3317733070b4" }, homepage: "https://posthog.com/docs/model-context-protocol" }, { name: "postiz", description: "Social media automation CLI for scheduling posts, managing integrations, uploading media, and tracking analytics across 28+ platforms including X, LinkedIn, Reddit, YouTube, TikTok, Instagram, and more", source: { source: "url", url: "https://github.com/gitroomhq/postiz-agent.git", sha: "00aa5083c89fee6c673cc0ae21a70daaa3098854" }, homepage: "https://postiz.com/agent" }, { name: "postman", description: "Full API lifecycle management for Claude Code. Sync collections, generate client code, discover APIs, run tests, create mocks, publish docs, and audit security. Powered by the Postman MCP Server.", category: "development", source: { source: "url", url: "https://github.com/Postman-Devrel/postman-claude-code-plugin.git", sha: "c85c881c68c9b6338b5b75e989a79d61e76c51a0" }, homepage: "https://learning.postman.com/docs/developer/postman-mcp-server/" }, { name: "pr-review-toolkit", description: "Comprehensive PR review agents specializing in comments, tests, error handling, type design, code quality, and code simplification", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/pr-review-toolkit", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/pr-review-toolkit" }, { name: "preset-cli-skills", description: "Preset CLI skills for explicit shell, scripting, and CI/CD workflows driven by the `sup` CLI (PyPI package `superset-sup`). Use only for CLI workflows; do not use for MCP-only work or as a substitute for direct API calls when the user wants HTTP/SDK code.", author: { name: "Preset" }, category: "development", source: { source: "git-subdir", url: "https://github.com/preset-io/agent-skills.git", path: "plugins/preset-cli-skills", ref: "master", sha: "8387ac0f0538271c79a2e227c7ddec084e8a5da3" }, homepage: "https://www.preset.io" }, { name: "prisma", description: "Prisma MCP integration for Postgres database management, schema migrations, SQL queries, and connection string management. Provision Prisma Postgres databases, run migrations, and interact with your data directly.", source: { source: "url", url: "https://github.com/prisma/claude-plugin.git", sha: "815dbc4a045a29e3b81510ba0e3ab806f1baaf0e" }, homepage: "https://prisma.io" }, { name: "project-artifact", description: "Generate and publish a living project status page — overview & success criteria, the workstream sequence, and next steps — as a shareable claude.ai artifact backed by a per-project config, so refreshes re-gather live state, redeploy the same URL, and report only the delta.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/project-artifact", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/project-artifact" }, { name: "pydantic-ai", description: "Write accurate Pydantic AI code from the start. Up-to-date patterns, decision trees, and common gotchas for agents, tools, structured output, streaming, and multi-agent apps.", category: "development", source: { source: "git-subdir", url: "https://github.com/pydantic/skills.git", path: "plugins/ai", ref: "main", sha: "501b11a5b3f92b9c78bbe9bd76442df0ad68dadf" }, homepage: "https://github.com/pydantic/skills/tree/main/plugins/ai" }, { name: "pyright-lsp", description: "Python language server (Pyright) for type checking and code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/pyright-lsp", category: "development", strict: false, lspServers: { pyright: { command: "pyright-langserver", args: ["--stdio"], extensionToLanguage: { ".py": "python", ".pyi": "python" } } } }, { name: "qdrant-skills", description: "Agent skills for Qdrant vector search covering scaling, performance optimization, search quality, monitoring, deployment, model migration, version upgrades, and SDK usage across Python, TypeScript, Rust, Go, .NET, and Java.", author: { name: "Qdrant" }, category: "database", source: { source: "url", url: "https://github.com/qdrant/skills.git", sha: "7d12f624a62e6b3738fe9a8460a22adb5f21d108" }, homepage: "https://skills.qdrant.tech" }, { name: "qodo", displayName: "Qodo", description: "Bring Qodo's codebase intelligence, coding standards, and code review into your coding agent.", author: { name: "Qodo", email: "support@qodo.ai" }, category: "development", source: { source: "git-subdir", url: "https://github.com/qodo-ai/qodo-skills.git", path: "packages/qodo", ref: "main", sha: "79019ff7a574383d7146502ec5ffe7f7437a55d6" }, homepage: "https://github.com/qodo-ai/qodo-skills.git" }, { name: "qodo-standards", displayName: "Qodo Standards", description: "Optional Qodo rules discovery and standards administration workflows.", author: { name: "Qodo", email: "support@qodo.ai" }, category: "development", source: { source: "git-subdir", url: "https://github.com/qodo-ai/qodo-skills.git", path: "packages/qodo-standards", ref: "main", sha: "79019ff7a574383d7146502ec5ffe7f7437a55d6" }, homepage: "https://github.com/qodo-ai/qodo-skills.git" }, { name: "qt-development-skills", description: "Agentic engineering skills for Qt software development — Qt C++/QML code review, QML coding, and Qt C++/QML code documentation.", author: { name: "Qt Group" }, category: "development", source: { source: "url", url: "https://github.com/TheQtCompanyRnD/agent-skills.git", sha: "71d6c10da78b9a764468ae11c86ab3bc4ca4921f" }, homepage: "https://www.qt.io/" }, { name: "quarkus-agent", description: "MCP server for AI coding agents to create, manage, and interact with Quarkus applications. Provides tools for project scaffolding, dev mode lifecycle, extension skills, Dev MCP proxy, and documentation search.", author: { name: "Quarkus" }, category: "development", source: { source: "url", url: "https://github.com/quarkusio/quarkus-agent-mcp.git", sha: "31c9b96658d9afaf09f0013ad6c75b64b0019371" }, homepage: "https://quarkus.io" }, { name: "railway", description: "Deploy and manage apps, databases, and infrastructure on Railway. Covers project setup, deploys, environment configuration, networking, troubleshooting, and monitoring.", category: "deployment", source: { source: "git-subdir", url: "https://github.com/railwayapp/railway-skills.git", path: "plugins/railway", ref: "main", sha: "950acebcef3445f3915ea0709876c3ba9c237a7f" }, homepage: "https://docs.railway.com/ai/claude-code-plugin" }, { name: "ralph-loop", description: "Interactive self-referential AI loops for iterative development, implementing the Ralph Wiggum technique. Claude works on the same task repeatedly, seeing its previous work, until completion.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/ralph-loop", category: "development", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/plugins/ralph-loop" }, { name: "rc", description: "Configure RevenueCat projects, apps, products, entitlements, and offerings directly from Claude Code. Manage your in-app purchase backend without leaving your development workflow.", category: "development", source: { source: "url", url: "https://github.com/RevenueCat/rc-claude-code-plugin.git", path: "revenuecat", sha: "7bf32f6bf40f790c259b8c3bb9be68dc6ef76105" }, homepage: "https://www.revenuecat.com" }, { name: "receipts", description: "A personal Claude Code impact report for justifying your usage to a manager or a self-review: what you shipped, which projects it went to, and each project's share of your usage. Reads your ~/.claude/projects transcripts and runs read-only git locally; only counts and project names are sent to write it up, and the report stays on your machine.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/receipts", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/receipts" }, { name: "redis-development", description: "Redis development best practices — data structures, query engine, vector search, caching, and performance optimization", author: { name: "Redis" }, category: "database", source: { source: "git-subdir", url: "https://github.com/redis/agent-skills.git", path: "plugins/redis-development", ref: "main", sha: "172fb9effa139cd7432ac29a9ee81c45943e5a28" }, homepage: "https://redis.io" }, { name: "remember", description: "Continuous memory for Claude Code. Extracts, summarizes, and compresses conversations into tiered daily logs. Claude remembers what you did yesterday.", source: { source: "url", url: "https://github.com/Digital-Process-Tools/claude-remember.git", sha: "a5cc87c35567cff2ff603f598fc8a7134971a280" }, homepage: "https://github.com/Digital-Process-Tools/claude-remember" }, { name: "render", description: "Deploy, debug, and monitor applications on Render. Includes skills, an agent, slash commands, and a render.yaml validation hook.", author: { name: "Render" }, category: "deployment", source: { source: "url", url: "https://github.com/render-oss/render-plugin-claude-code.git", sha: "e8f889396634dbc8c368448a7f3de993ed4a5ac1" }, homepage: "https://render.com" }, { name: "resend", description: "Agent skills for working with Resend to send and receive emails — email API integration, agent inbox, CLI, React Email components, and deliverability best practices. Includes the Resend MCP server.", author: { name: "Resend" }, category: "development", source: { source: "url", url: "https://github.com/resend/resend-skills.git", sha: "8938c2a6f17903f9168c31431c842c68a68b19f3" }, homepage: "https://resend.com" }, { name: "revenuecat", description: "Configure RevenueCat projects, apps, products, entitlements, and offerings directly from Claude Code. Manage your in-app purchase backend without leaving your development workflow.", category: "development", source: { source: "url", url: "https://github.com/RevenueCat/rc-claude-code-plugin.git", path: "revenuecat", sha: "7bf32f6bf40f790c259b8c3bb9be68dc6ef76105" }, homepage: "https://www.revenuecat.com" }, { name: "rill", description: "Skills for developing and querying projects in the Rill business intelligence platform", author: { name: "Rill Data" }, category: "development", source: { source: "url", url: "https://github.com/rilldata/agent-skills.git", sha: "440e4081f2f56e1a130a5c679f75a0826a611264" }, homepage: "https://docs.rilldata.com/developers/build/ai-configuration" }, { name: "rootly", description: "Full-lifecycle incident management: deploy safety, incident response, on-call management, and retrospectives.", author: { name: "Rootly" }, category: "monitoring", source: { source: "url", url: "https://github.com/Rootly-AI-Labs/rootly-claude-plugin.git", sha: "65832aa6ff7a7b39c6bd64899a7a64646e3948ed" }, homepage: "https://rootly.com" }, { name: "ruby-lsp", description: "Ruby language server for code intelligence and analysis", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/ruby-lsp", category: "development", strict: false, lspServers: { "ruby-lsp": { command: "ruby-lsp", extensionToLanguage: { ".rb": "ruby", ".rake": "ruby", ".gemspec": "ruby", ".ru": "ruby", ".erb": "erb" } } } }, { name: "runway-api", description: "Video generation at scale. Generate videos, images, and audio with Runway's API — batch ad campaigns, product videos, multishot stories, and creative iteration. Supports seedance2, gen4.5, veo3, Nano, Banana Pro, and more.", author: { name: "Runway" }, category: "design", source: { source: "url", url: "https://github.com/runwayml/skills.git", sha: "e3dffc15498e9588e7815f37b9ecf10e8bc2c902" }, homepage: "https://runwayml.com" }, { name: "rust-analyzer-lsp", description: "Rust language server for code intelligence and analysis", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/rust-analyzer-lsp", category: "development", strict: false, lspServers: { "rust-analyzer": { command: "rust-analyzer", extensionToLanguage: { ".rs": "rust" } } } }, { name: "sagemaker-ai", description: "Build, train, and deploy AI models with deep AWS AI/ML expertise brought directly into your coding assistants, covering the surface area of Amazon SageMaker AI.", category: "development", source: { source: "git-subdir", url: "https://github.com/awslabs/agent-plugins.git", path: "plugins/sagemaker-ai", ref: "main", sha: "bab56a3b9991aa0c6857b05198a61ba14a60bce4" }, homepage: "https://github.com/awslabs/agent-plugins" }, { name: "salesforce-development", description: "Build Salesforce apps and agents using these core building blocks: metadata, Apex, deploy/retrieve, security, reporting, and generated installed-versus-available capability discovery.", author: { name: "Salesforce" }, category: "development", source: { source: "git-subdir", url: "https://github.com/forcedotcom/sf-skills.git", path: "plugins/builder/salesforce-development", ref: "main", sha: "7e04d4744792ae2defb7f4da24fe85cbdf6f6e5a" }, homepage: "https://github.com/forcedotcom/sf-skills/tree/main/plugins/builder/salesforce-development" }, { name: "sanity", description: "Sanity content platform integration with MCP server, agent skills, and slash commands. Query and author content, build and optimize GROQ queries, design schemas, and set up Visual Editing.", category: "development", author: { name: "Sanity" }, source: { source: "url", url: "https://github.com/sanity-io/agent-toolkit.git", sha: "88d6cdfa7cb06c99edd5f376efa4dac21ae3f877" }, homepage: "https://www.sanity.io" }, { name: "sap-cds-mcp", description: "AI-assisted development of SAP Cloud Application Programming Model (CAP) projects. Search CDS models and CAP documentation.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "url", url: "https://github.com/cap-js/mcp-server.git", sha: "79e4546395a52b1a3881d828118a1b3a2e198876" }, homepage: "https://cap.cloud.sap/" }, { name: "sap-fiori-mcp-server", description: "MCP server for SAP Fiori development tools for Claude Code. Build and modify SAP Fiori applications with AI assistance.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/SAP/open-ux-tools.git", path: "packages/fiori-mcp-server", ref: "main", sha: "31c1263fb76e1737dcb0a6d163c967d8f8126ddd" }, homepage: "https://github.com/SAP/open-ux-tools/tree/main/packages/fiori-mcp-server" }, { name: "sap-hana-cli", description: "150+ SAP HANA database tools for AI assistants. Query tables, import/export data, profile data quality, compare schemas, manage backups, monitor performance, and more. Connects to SAP HANA Cloud and on-premise databases.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "database", source: { source: "url", url: "https://github.com/SAP-samples/hana-cli-claude-plugin.git", sha: "abadd0aba32792b6378ed784e9f6d3e5b25dfc2a" }, homepage: "https://github.com/SAP-samples/hana-cli-claude-plugin" }, { name: "sap-mdk-server", description: "MCP server for SAP Mobile Development Kit (MDK). Build and modify MDK applications with AI assistance — schema lookups, action validation, rule editing, and project scaffolding.", author: { name: "SAP SE", email: "ospo@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "url", url: "https://github.com/SAP/mdk-mcp-server.git", sha: "68efb00cd62a905748c98c8533fecff2f3ff4a00" }, homepage: "https://help.sap.com/docs/MDK" }, { name: "save-to-spotify", description: "Create polished audio episodes with TTS narration, rich timelines, cover images, and save them to Spotify via the save-to-spotify CLI.", author: { name: "Spotify" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/spotify/save-to-spotify.git", path: "plugin", ref: "main", sha: "9d05c8cd8c8559552f84e27fe30f46b7693ce69a" }, homepage: "https://github.com/spotify/save-to-spotify" }, { name: "scandit-sdk", displayName: "Scandit SDK", description: "AI agent skills for integrating the Scandit Data Capture SDK — product selection, documentation, and implementation guides for barcode scanning, ID capture, and smart label capture.", author: { name: "Scandit" }, category: "development", source: { source: "url", url: "https://github.com/Scandit/skills.git", sha: "2f0731a090eb9c23a64b6dcd9559cf113df3313f" }, homepage: "https://www.scandit.com" }, { name: "security-guidance", description: "Security review for Claude-generated code. Pattern-based warnings on edits, LLM-powered diff review on Stop, and an agentic commit reviewer that catches injection, XSS, SSRF, hardcoded secrets, and 25+ other vulnerability classes.", version: "2.0.7", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/security-guidance", category: "security", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/security-guidance" }, { name: "semgrep", description: "Semgrep catches security vulnerabilities in real-time and guides Claude to write secure code from the start.", category: "security", source: { source: "git-subdir", url: "https://github.com/semgrep/mcp-marketplace.git", path: "plugin", sha: "f97e1ce43533ffde2eae9af2a80f95a7250c365f" }, homepage: "https://github.com/semgrep/mcp-marketplace.git" }, { name: "sentry", description: "Sentry error monitoring integration. Access error reports, analyze stack traces, search issues by fingerprint, and debug production errors directly from your development environment.", category: "monitoring", source: { source: "url", url: "https://github.com/getsentry/plugin-claude.git", sha: "73e53541d7af21672e27428c7067f4264b8a3d65" }, homepage: "https://github.com/getsentry/plugin-claude" }, { name: "sentry-cli", description: "Skills for using the Sentry CLI to interact with Sentry from the command line", author: { name: "Sentry" }, category: "monitoring", source: { source: "git-subdir", url: "https://github.com/getsentry/cli.git", path: "packages/cli/plugins/sentry-cli", ref: "main", sha: "936c2cdc2ac13978ca9a843b24a0583e9309af8e" }, homepage: "https://sentry.io" }, { name: "serena", description: "Semantic code analysis MCP server providing intelligent code understanding, refactoring suggestions, and codebase navigation through language server protocol integration.", category: "development", source: "./external_plugins/serena", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/serena", tags: ["community-managed"] }, { name: "servicenow-sdk", description: "Create, edit, and deploy ServiceNow applications with the Fluent SDK effortlessly through Claude AI.", author: { name: "ServiceNow" }, category: "development", source: { source: "git-subdir", url: "https://github.com/ServiceNow/sdk.git", path: "providers/claude/plugin", ref: "master", sha: "f3e0379242b29e0039e1625d637aa1c246acbe12" }, homepage: "https://servicenow.github.io/sdk/" }, { name: "session-report", description: "Generate an explorable HTML report of Claude Code session usage — tokens, cache efficiency, subagents, skills, and the most expensive prompts — from local ~/.claude/projects transcripts.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/session-report", category: "productivity", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/session-report" }, { name: "setup-agent-analytics", description: "Detect AI agents in your codebase and instrument them with Pendo Agent Analytics via the best-fit path: Python SDK, TypeScript SDK, client-side trackAgent(), or the Conversations API.", author: { name: "Pendo" }, category: "development", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/setup-agent-analytics", ref: "main", sha: "a4699be3608ba134d8c7aa4b53e220cfde1c6aac" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/setup-agent-analytics" }, { name: "setup-mcp-agent-analytics", description: "Detect an MCP server's language (Python, TypeScript or Go) and instrument it with the matching Pendo SDK so MCP tool calls flow into Pendo Agent Analytics.", author: { name: "Pendo" }, category: "development", source: { source: "git-subdir", url: "https://github.com/pendo-io/claude-pendo-plugin.git", path: "plugins/setup-mcp-agent-analytics", ref: "main", sha: "a4699be3608ba134d8c7aa4b53e220cfde1c6aac" }, homepage: "https://github.com/pendo-io/claude-pendo-plugin/tree/main/plugins/setup-mcp-agent-analytics" }, { name: "shippo", description: "Shippo connects you to USPS, UPS, FedEx, DHL, and 40+ carriers, so you can handle a shipment end to end right inside Claude. Compare live rates and pick the cheapest or best option, buy and print labels (domestic and international, with customs declarations), validate and standardize addresses, and track packages across carriers. Just ask in plain language: rate-shop a parcel, buy the right label, check a delivery status, or confirm an address before you ship. Whether you run a store or just need to send a package, Shippo turns a pile of carrier accounts into one simple conversation.", author: { name: "Shippo" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/goshippo/ai.git", path: "providers/claude/plugin", ref: "main", sha: "15cbb6364fbcfd465a134f5972da9179436d0787" }, homepage: "https://docs.goshippo.com" }, { name: "shopify-ai-toolkit", description: "Shopify's AI Toolkit provides 18 development skills for building on the Shopify platform, covering documentation search, API schema access, GraphQL and Liquid code validation, Hydrogen storefronts, Polaris UI extensions, store management via CLI, and onboarding guidance for both developers and merchants.", author: { name: "Shopify" }, category: "development", source: { source: "url", url: "https://github.com/Shopify/Shopify-AI-Toolkit.git", sha: "c6a219bf99fc5aa2576843f3c8a005f9da863383" }, homepage: "https://shopify.dev" }, { name: "skill-creator", description: "Create new skills, improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, update or optimize an existing skill, run evals to test a skill, or benchmark skill performance with variance analysis.", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/skill-creator", category: "development", homepage: "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/skill-creator" }, { name: "slack", description: "Slack workspace integration. Search messages, access channels, read threads, and stay connected with your team's communications while coding. Find relevant discussions and context quickly.", category: "productivity", source: { source: "url", url: "https://github.com/slackapi/slack-mcp-plugin.git", sha: "8044341769fa84f85ee952dceddb67ef165ab110" }, homepage: "https://github.com/slackapi/slack-mcp-plugin/tree/main" }, { name: "snowflake-cortex-code", description: "Automatically route Snowflake prompts from Claude Code to Cortex Code for execution. Provides slash commands for code review and task delegation, plus skills for routing, run, and setup.", author: { name: "Snowflake" }, category: "development", source: { source: "git-subdir", url: "https://github.com/Snowflake-Labs/snowflake-ai-kit.git", path: "plugins/cortex-code", ref: "main", sha: "0c54225ea50b44c2ae07e1f378bf401e88b33c33" }, homepage: "https://docs.snowflake.com/en/user-guide/cortex-code" }, { name: "sonarqube", description: "Automatically enforce SonarQube code quality and security in the agent coding loop — 7,000+ rules, secrets scanning, agentic analysis, and quality gates across 40+ languages. PostToolUse hooks run analysis after every file edit. Pre-tool secrets scanning prevents 450+ patterns from reaching the LLM. Slash commands give on-demand access to quality gate status, coverage, duplication, and dependency risks. Includes SonarQube CLI, MCP Server, skills, hooks, and slash commands.", author: { name: "SonarSource" }, category: "security", source: { source: "url", url: "https://github.com/SonarSource/sonarqube-agent-plugins.git", sha: "f05d5f9890da8eb602c1aa24123e92c697ee6f2e" }, homepage: "https://www.sonarsource.com" }, { name: "sonatype-guide", description: "Sonatype Guide MCP server for software supply chain intelligence and dependency security. Analyze dependencies for vulnerabilities, get secure version recommendations, and check component quality metrics.", category: "security", source: { source: "url", url: "https://github.com/sonatype/sonatype-guide-claude-plugin.git", sha: "1dae73980f591d3196f5532ac72186513563d028" }, homepage: "https://github.com/sonatype/sonatype-guide-claude-plugin.git" }, { name: "sourcegraph", description: "Code search and understanding across codebases. Search, read, and trace references across repositories; analyze refactor impact; investigate incidents via commit and diff search; run targeted security sweeps.", category: "development", source: { source: "url", url: "https://github.com/sourcegraph-community/sourcegraph-claudecode-plugin.git", sha: "674a05e2e28677fc3fdce7491063459455ded573" }, homepage: "https://sourcegraph.com" }, { name: "spanner", description: "Connect and interact with Spanner data using natural language.", author: { name: "Google LLC" }, category: "database", source: { source: "url", url: "https://github.com/gemini-cli-extensions/spanner.git", sha: "a69b5f3449387a851648f8bd9be58d0b27e0411c" }, homepage: "https://github.com/gemini-cli-extensions/spanner" }, { name: "spotify-ads-api", description: "Manage Spotify ad campaigns with natural language. Create campaigns, ad sets, ads, pull reports, and handle OAuth — all through conversation.", category: "productivity", source: { source: "url", url: "https://github.com/spotify/ads-claude-plugin.git", sha: "ae7efbeb6f46a10a706234670487c3b5775b969e" }, homepage: "https://github.com/spotify/ads-claude-plugin" }, { name: "stackhawk-hawkscan", description: "Configure, run, and interpret HawkScan DAST results inside Claude Code. Generates stackhawk.yml configs, runs scans via CLI or Docker, and transforms security findings into prioritized fix tasks for your coding agent.", author: { name: "StackHawk" }, category: "security", source: { source: "git-subdir", url: "https://github.com/stackhawk/agent-skills.git", path: "plugins/hawkscan", ref: "main", sha: "66cac9baa5883a1007575faf1b22855a1124834a" }, homepage: "https://docs.stackhawk.com/ai-security/" }, { name: "stackhawk-api", description: "Query the StackHawk platform API for security posture reporting, findings analysis, and app management. Guides agents through authentication, data retrieval, and result presentation.", author: { name: "StackHawk" }, category: "security", source: { source: "git-subdir", url: "https://github.com/stackhawk/agent-skills.git", path: "plugins/api", ref: "main", sha: "66cac9baa5883a1007575faf1b22855a1124834a" }, homepage: "https://docs.stackhawk.com/ai-security/" }, { name: "streaming-skills-plugin", description: "Skills for streaming application developers, covering Kafka and Flink client libraries and Schema Registry", author: { name: "Confluent" }, category: "development", source: { source: "url", url: "https://github.com/confluentinc/agent-skills.git", sha: "914d95eff7ff50513b34bfb9ac97eda7c7fce899" }, homepage: "https://www.confluent.io" }, { name: "stripe", description: "Stripe development plugin for Claude", category: "development", source: { source: "git-subdir", url: "https://github.com/stripe/ai.git", path: "providers/claude/plugin", ref: "main", sha: "da4991b0a0b9299d423ae2d5856e6d7e2b31b031" }, homepage: "https://github.com/stripe/ai/tree/main/providers/claude/plugin" }, { name: "sumup", description: "SumUp payment integrations across terminal and online checkout flows. Build Android and iOS POS apps with SumUp card readers, online checkout with server SDKs and the checkout widget, and control card readers remotely via Cloud API.", category: "development", source: { source: "url", url: "https://github.com/sumup/sumup-skills.git", sha: "cb72003b417cec5e717c6b788d63394b7e921938" }, homepage: "https://www.sumup.com/" }, { name: "supabase", description: "Supabase MCP integration for database operations, authentication, storage, and real-time subscriptions. Manage your Supabase projects, run SQL queries, and interact with your backend directly.", category: "database", source: { source: "url", url: "https://github.com/supabase-community/supabase-plugin.git", sha: "f3f332e0164c34a8392772811737fda0cb972d06" }, homepage: "https://github.com/supabase-community/supabase-plugin" }, { name: "superdesign", description: "Design or redesign frontend UI and marketing graphics on the Superdesign infinite canvas. Reads your codebase for context, sets up a design system, and generates branchable design drafts you refine.", author: { name: "Superdesign dev, Inc." }, category: "design", source: { source: "url", url: "https://github.com/superdesigndev/superdesign-skill.git", sha: "f9f05cd988c247dce6c072eaf9ac6b162f2ffc4b" }, homepage: "https://superdesign.dev" }, { name: "superpowers", description: "Superpowers teaches Claude brainstorming, subagent driven development with built in code review, systematic debugging, and red/green TDD. Additionally, it teaches Claude how to author and test new skills.", category: "development", source: { source: "url", url: "https://github.com/obra/superpowers.git", sha: "b36e0829c6d0140e93cfef2ca599b1b07d4a7797" }, homepage: "https://github.com/obra/superpowers.git" }, { name: "swift-lsp", description: "Swift language server (SourceKit-LSP) for code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/swift-lsp", category: "development", strict: false, lspServers: { "sourcekit-lsp": { command: "sourcekit-lsp", extensionToLanguage: { ".swift": "swift" } } } }, { name: "synthflow", description: "Connects Claude Code to the Synthflow AI voice-agent platform through its hosted MCP server, with skills for reviewing calls and auditing agent prompts, plus a docs-search connector.", author: { name: "Synthflow" }, category: "automation", source: { source: "git-subdir", url: "https://github.com/SynthFlowAI/AnthropicPlugin.git", path: "plugins/synthflow", ref: "main", sha: "205871ee83508502d2c982ee1bb7e65a2a29190b" }, homepage: "https://synthflow.ai" }, { name: "tavily", description: "Build AI applications with real-time web data using Tavily's search, extract, crawl, and research APIs.", author: { name: "Tavily Team" }, category: "development", source: { source: "url", url: "https://github.com/tavily-ai/skills.git", sha: "778122e5f9c680f541eeceda5a5b36405eb7980c" }, homepage: "https://www.tavily.com/" }, { name: "teamcity-cli", description: "Agent skill for interacting with TeamCity CI/CD using the teamcity CLI. Enables Claude to explore builds, view logs, start jobs, manage queues, agents, and more.", author: { name: "JetBrains" }, category: "development", source: { source: "url", url: "https://github.com/JetBrains/teamcity-cli.git", sha: "ac6c1fd83300b2e42df48fcfff365ba03f73bb92" }, homepage: "https://www.jetbrains.com/teamcity/" }, { name: "telegram", description: "Telegram messaging bridge with built-in access control. Manage pairing, allowlists, and policy via /telegram:access.", category: "productivity", source: "./external_plugins/telegram" }, { name: "terraform", description: "The Terraform MCP Server provides seamless integration with Terraform ecosystem, enabling advanced automation and interaction capabilities for Infrastructure as Code (IaC) development.", author: { name: "HashiCorp", email: "support@hashicorp.com" }, category: "development", source: "./external_plugins/terraform", homepage: "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/terraform" }, { name: "togetherai-skills", description: "Agent Skills for Together AI platform — inference, training, embeddings, audio, video, images, function calling, and infrastructure. Covers serverless chat completions, image/video generation, fine-tuning, batch inference, evaluations, sandboxes, dedicated endpoints, and GPU clusters.", author: { name: "Together AI" }, category: "development", source: { source: "url", url: "https://github.com/togethercomputer/skills.git", sha: "644d38225bbdef0318462fe222f6f9883c8addcd" }, homepage: "https://www.together.ai" }, { name: "twilio-developer-kit", description: "Twilio Skills provide procedural knowledge for AI coding agents — which APIs to use, in what order, and what to avoid. Covers SMS, Voice, WhatsApp, Verify, SendGrid, Compliance, and 30+ products.", author: { name: "Twilio" }, category: "development", source: { source: "url", url: "https://github.com/twilio/ai.git", sha: "8aba46fb65dc8d9a20f4b301a68352064b4159a5" }, homepage: "https://www.twilio.com" }, { name: "typescript-lsp", description: "TypeScript/JavaScript language server for enhanced code intelligence", version: "1.0.0", author: { name: "Anthropic", email: "support@anthropic.com" }, source: "./plugins/typescript-lsp", category: "development", strict: false, lspServers: { typescript: { command: "typescript-language-server", args: ["--stdio"], extensionToLanguage: { ".ts": "typescript", ".tsx": "typescriptreact", ".js": "javascript", ".jsx": "javascriptreact", ".mts": "typescript", ".cts": "typescript", ".mjs": "javascript", ".cjs": "javascript" } } } }, { name: "ui-theme-designer", description: "Plugin for coding agents working with UI theme designer. Bundles two skills: how-to and conceptual answers about UI theme designer on BTP, and questions about the SAP Design System and SAP Fiori design tokens — theme parameters and component-level parameter usage in UI5, UI5 Web Components, and Fundamental Styles.", author: { name: "SAP SE" }, category: "design", source: { source: "git-subdir", url: "https://github.com/SAP/ui-theme-designer-plugins-for-coding-agents.git", path: "plugins/ui-theme-designer", ref: "main", sha: "04a0a217e129422f8a995c5a9dd31712e5a32f47" }, homepage: "https://github.com/SAP/ui-theme-designer-plugins-for-coding-agents" }, { name: "ui5", description: "SAPUI5 / OpenUI5 plugin for coding agents. Create and validate UI5 projects, access API documentation, run UI5 linter, get development guidelines and best practices for UI5 development.", author: { name: "SAP SE", email: "openui5@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/UI5/plugins-coding-agents.git", path: "plugins/ui5", ref: "main", sha: "a99b882ce364ef4b9f52fb4054f5f410c1636563" }, homepage: "https://github.com/UI5/plugins-coding-agents" }, { name: "ui5-modernization", description: "Complete UI5 modernization toolkit with workflow and specialized fix patterns for modernizing SAPUI5/OpenUI5 applications.", author: { name: "SAP SE", email: "openui5@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/UI5/plugins-coding-agents.git", path: "plugins/ui5-modernization", ref: "main", sha: "2b8c4a944e39609214bce7aef3b05260985f0e91" }, homepage: "https://github.com/UI5/plugins-coding-agents" }, { name: "ui5-typescript-conversion", description: "SAPUI5 / OpenUI5 plugin for coding agents. Convert JavaScript based UI5 projects to TypeScript.", author: { name: "SAP SE", email: "openui5@sap.com", url: "https://www.sap.com" }, category: "development", source: { source: "git-subdir", url: "https://github.com/UI5/plugins-coding-agents.git", path: "plugins/ui5-typescript-conversion", ref: "main", sha: "2b8c4a944e39609214bce7aef3b05260985f0e91" }, homepage: "https://github.com/UI5/plugins-coding-agents" }, { name: "unity", displayName: "Unity", description: "Unity's official plugin for Claude Code, with curated skills for game development, monetization, and performance optimization.", author: { name: "Unity Technologies" }, category: "development", source: { source: "url", url: "https://github.com/Unity-Technologies/unity-agent-plugin.git", sha: "5ad4bafc1d91acfdeca800bfbae0072fcc7aeb58" }, homepage: "https://unity.com" }, { name: "unreal-engine-skills-for-claude-code", description: "Control Unreal Editor directly from Claude Code via MCP. Hundreds of tools exposed via Unreal's ToolsetRegistry across 30+ toolsets: actors, blueprints, materials, Niagara, Control Rigs, Sequencer, State Trees, widgets, Gameplay Ability System, automation testing, and more.", author: { name: "Epic Games" }, category: "development", source: { source: "url", url: "https://github.com/EpicGames/unreal-engine-skills-for-claude-code-plugin.git", sha: "a6aa73ada02a9fb1f5415bec491f9942c519b297" }, homepage: "https://dev.epicgames.com/documentation/unreal-engine/unreal-mcp-in-unreal-editor" }, { name: "valtown", description: "Build and deploy on Val Town. Bundles the Val Town MCP server and platform skills (HTTP vals, cron/intervals, SQLite, email, OAuth, React UI, third-party integrations, templates).", author: { name: "Val Town" }, category: "deployment", source: { source: "git-subdir", url: "https://github.com/val-town/plugins.git", path: "plugin", ref: "main", sha: "2d3ec654b6a7d93e209afb8f2e8848eddcb9f17b" }, homepage: "https://val.town" }, { name: "vanta", description: "The Vanta plugin connects Claude Code to Vanta's security and compliance platform through the Vanta MCP server. It combines Vanta's test-specific remediation intelligence with your local repository context to help you fix compliance failures faster.", author: { name: "Vanta" }, category: "security", source: { source: "url", url: "https://github.com/VantaInc/vanta-mcp-plugin.git", sha: "345d86b55faa649e955b7ea5569cf52d8425c2d5" }, homepage: "https://help.vanta.com/en/articles/14094979-connecting-to-vanta-mcp#h_887ce3f337" }, { name: "vanta-mcp-plugin", description: "The Vanta plugin connects Claude Code to Vanta's security and compliance platform through the Vanta MCP server. It combines Vanta's test-specific remediation intelligence with your local repository context to help you fix compliance failures faster.", author: { name: "Vanta" }, category: "security", source: { source: "url", url: "https://github.com/VantaInc/vanta-mcp-plugin.git", sha: "345d86b55faa649e955b7ea5569cf52d8425c2d5" }, homepage: "https://help.vanta.com/en/articles/14094979-connecting-to-vanta-mcp#h_887ce3f337" }, { name: "vercel", description: "Vercel deployment platform integration. Manage deployments, check build status, access logs, configure domains, and control your frontend infrastructure directly from Claude Code.", category: "deployment", source: { source: "url", url: "https://github.com/vercel/vercel-plugin.git", sha: "9ca8770143395d69606573e122c456566d6f419b" }, homepage: "https://github.com/vercel/vercel-plugin" }, { name: "vibe-prospecting", description: "Vibe Prospecting connects Claude to live B2B company and contact data so users can search, match, enrich, filter, and export prospects at scale. It turns natural-language requests into structured GTM workflows for lead generation, CRM enrichment, company research, executive discovery, and multi-step prospecting automation inside Claude Cowork and Claude Code.", author: { name: "vibeprospecting.ai" }, category: "productivity", source: { source: "url", url: "https://github.com/explorium-ai/vibeprospecting-plugin.git", sha: "9b4067473305dbba80be0fa9a492be39b96f455e" }, homepage: "https://www.vibeprospecting.ai/product/claude-plugin" }, { name: "vsql-extension-builder", description: "Builds a VillageSQL extension for MySQL end-to-end through a 7-phase persona-driven workflow. Commonly used to port PostgreSQL extensions to MySQL.", author: { name: "VillageSQL" }, category: "database", source: { source: "url", url: "https://github.com/villagesql/villagesql-skills.git", sha: "18f7d68673e2bd5d400b4ee91298e5a4b9e8d24e" }, homepage: "https://villagesql.com" }, { name: "windsor-ai", description: "Connect Claude Code to 325+ business data sources via Windsor.ai. Query marketing, sales, CRM, ecommerce, finance, and analytics data from Google Ads, Meta, HubSpot, Salesforce, Shopify, Stripe, and hundreds more — directly from your terminal.", author: { name: "Windsor.ai" }, category: "productivity", source: { source: "url", url: "https://github.com/windsor-ai/claude-windsor-ai-plugin.git", sha: "d7ba1cb036c7ca765536355fb85f13a3237ea3f9" }, homepage: "https://windsor.ai" }, { name: "wix", description: "Build, manage, and deploy Wix sites and apps. CLI development skills for dashboard extensions, backend APIs, site widgets, and service plugins with the Wix Design System, plus MCP server for site management.", category: "development", source: { source: "url", url: "https://github.com/wix/skills.git", sha: "9c48e3f65cc869868d617c5995cf852cc71f64af" }, homepage: "https://dev.wix.com/docs/wix-cli/guides/development/about-wix-skills" }, { name: "build-with-wordpress", description: "Craft production-grade WordPress sites and applications. Everything from themes and plugins to commerce and deployment.", source: { source: "url", url: "https://github.com/Automattic/claude-code-wordpress.com.git", sha: "052ca970df2c577d7c651e784935186ff93e6779" }, homepage: "https://developer.wordpress.com/wordpress-com-claude-code-plugin/" }, { name: "workos", description: "WorkOS integration skills for AuthKit, SSO, Directory Sync, RBAC, Vault, Audit Logs, migrations, and API references.", author: { name: "WorkOS" }, category: "security", source: { source: "git-subdir", url: "https://github.com/workos/skills.git", path: "plugins/workos", ref: "main", sha: "6b7d596ae28fb0bf2ecc01a8737e4bdcc70f7ab8" }, homepage: "https://workos.com" }, { name: "youdotcom-agent-skills", description: "You.com agent skills for web search, research with citations, and content extraction. Guided integrations for Vercel AI SDK, Claude Agent SDK, OpenAI Agents SDK, crewAI, LangChain, Microsoft Teams.ai, direct REST API, and bash CLI.", author: { name: "You.com" }, category: "productivity", source: { source: "url", url: "https://github.com/youdotcom-oss/agent-skills.git", sha: "08f3d80e7ca9518ccc64b38b365a78cc4a762691" }, homepage: "https://you.com" }, { name: "zapier", description: "Connect 8,000+ apps to your AI workflow. Discover, enable, and execute Zapier actions directly from your client.", category: "productivity", source: { source: "git-subdir", url: "https://github.com/zapier/zapier-mcp.git", path: "plugins/zapier", ref: "main", sha: "217d65a980f9b75536babf89ba64bf03ad95beea" }, homepage: "https://github.com/zapier/zapier-mcp/tree/main/plugins/zapier" }, { name: "zilliz", description: "Zilliz Cloud management plugin with 14 skills covering cluster lifecycle, collection schema, vector search, index tuning, bulk import, RBAC, backups, and monitoring.", author: { name: "Zilliz" }, category: "database", source: { source: "url", url: "https://github.com/zilliztech/zilliz-plugin.git", path: "plugins/zilliz", sha: "35c86c000c91abb35f3eeed5cca15ebd69cba4d5" }, homepage: "https://docs.zilliz.com" }, { name: "zocks-advisor", description: "Seven skills for financial advisors built on Zocks meeting intelligence: client behavioral profiles, attrition-risk ranking, held-away asset radar, client journey dossiers, household review packs, next-best-action analysis and a tax opportunity scan. Requires the Zocks connector and a Zocks account.", author: { name: "Zocks" }, category: "productivity", source: { source: "url", url: "https://github.com/zocks-communications/zocks-agent-plugins.git", sha: "a3e445c139665055c2f22f25c9a9f8721a7c6355" }, homepage: "https://github.com/zocks-communications/zocks-agent-plugins" }, { name: "zoom-plugin", description: "Claude plugin for planning, building, and debugging Zoom integrations across REST APIs, SDKs, webhooks, bots, and MCP workflows.", category: "development", source: { source: "url", url: "https://github.com/zoom/zoom-plugin.git", sha: "9311dd4b31e8e55c27b95479a84601576e449e97" }, homepage: "https://developers.zoom.us/" }, { name: "zoominfo", description: "Search companies and contacts, enrich leads, find lookalikes, and get AI-ranked contact recommendations. Pre-built skills chain multiple ZoomInfo tools into complete B2B sales workflows.", author: { name: "ZoomInfo" }, category: "productivity", source: { source: "url", url: "https://github.com/Zoominfo/zoominfo-mcp-plugin.git", sha: "d07402feb2b9967ccc118f55bacd41a79c822d6a" }, homepage: "https://www.zoominfo.com" }, { name: "zscaler", description: "Manage Zscaler cloud security platform including ZPA (private access), ZIA (internet access), ZDX (digital experience), ZCC (client connector), EASM (attack surface), and Z-Insights (analytics). Create and manage policies, troubleshoot connectivity, audit security configurations, and investigate incidents across the full Zscaler ecosystem.", author: { name: "Zscaler" }, category: "security", source: { source: "url", url: "https://github.com/zscaler/zscaler-mcp-server.git", sha: "809f68d6c921e0829fb2e07e9b797e7e70cf720b" }, homepage: "https://github.com/zscaler/zscaler-mcp-server" }, { name: "langfuse", description: "Skills for working with Langfuse, the open-source LLM engineering platform for tracing, prompt management, and evaluation.", author: { name: "Langfuse" }, category: "monitoring", source: { source: "url", url: "https://github.com/langfuse/skills.git", sha: "ab83111ed644c583a9ce963de773dbfbf09aebf3" }, homepage: "https://langfuse.com" }, { name: "zyte-web-data", description: "Web scraping skills for Claude Code powered by the Zyte API — scrape sites, generate and run Scrapy spiders, define extraction schemas, and ship to Scrapy Cloud.", author: { name: "Zyte" }, category: "automation", source: { source: "url", url: "https://github.com/zytedata/claude-skills.git", sha: "8b2d640fe82fadcb69c12af26e4e38ab8ab61ed1" }, homepage: "https://www.zyte.com" }, { name: "activecampaign", displayName: "ActiveCampaign", description: "Marketing automation, CRM, and email marketing powered by ActiveCampaign. Manage contacts, campaigns, automations, deals, and get AI-powered marketing insights — all from Claude.", author: { name: "ActiveCampaign" }, category: "productivity", source: { source: "url", url: "https://github.com/ActiveCampaign/activecampaign-plugin.git", sha: "0ff858728bc52aee335d5475b0d4eb5f3a9589b0" }, homepage: "https://www.activecampaign.com" }, { name: "hubspot-sales", displayName: "HubSpot Sales", description: "Run your HubSpot sales workflow directly from Claude. Adds skills that cover the full sales day: import contacts and deals into HubSpot, get a prioritised morning brief, prep for any call with full CRM context, draft personalised follow-ups grounded in deal history, log calls and update records by describing what happened, and review your pipeline to surface stalling deals. Everything writes back to HubSpot.", author: { name: "HubSpot" }, category: "productivity", source: { source: "git-subdir", url: "https://github.com/HubSpot/hubspot-mcp-plugins.git", path: "HubSpot-Sales", ref: "main", sha: "a0c59600fc1ddcf03ceca71aebf0c28aa55f49e3" }, homepage: "https://www.hubspot.com" }, { name: "dynatrace", displayName: "Dynatrace", description: "Dynatrace observability skills: DQL query patterns, application and infrastructure monitoring, log analysis, problem investigation, and incident response workflows, with the Dynatrace MCP server for live platform access.", author: { name: "Dynatrace" }, category: "monitoring", source: { source: "url", url: "https://github.com/Dynatrace/dynatrace-for-ai.git", sha: "9529e72715d96ab47738e8edf83d49798d0f8be5" }, homepage: "https://www.dynatrace.com/hub/detail/claude-code-cli/" }, { name: "wingspan", displayName: "Wingspan", description: "Ask Claude about the contractors you pay through Wingspan, what you owe them, and what is holding up a payment, then onboard contractors and log payments as drafts, with a preview before anything is written. Requires a Wingspan account; bundles the Wingspan MCP server (OAuth on first use).", author: { name: "Wingspan" }, category: "productivity", source: { source: "url", url: "https://github.com/wingspanHQ/mcp-claude-plugin.git", sha: "b989f3b303a1f605955291e34ed29b755bf436e1" }, homepage: "https://github.com/wingspanHQ/mcp-claude-plugin" }] } }
|
|
469196
|
+
];
|
|
469197
|
+
});
|
|
469198
|
+
|
|
469199
|
+
// src/tui/utils/plugins/marketplaceSnapshotFallback.ts
|
|
469200
|
+
import {
|
|
469201
|
+
mkdir as mkdir54,
|
|
469202
|
+
readFile as readFile62,
|
|
469203
|
+
rm as rm11,
|
|
469204
|
+
writeFile as writeFile49
|
|
469205
|
+
} from "fs/promises";
|
|
469206
|
+
import { join as join173, resolve as resolve53, sep as sep41 } from "path";
|
|
469207
|
+
function getBuiltinSnapshotRoot() {
|
|
469208
|
+
return join173(getMarketplacesCacheDir(), "builtin-snapshots");
|
|
469209
|
+
}
|
|
469210
|
+
function getBuiltinSnapshotDir(marketplaceName) {
|
|
469211
|
+
return join173(getBuiltinSnapshotRoot(), marketplaceName);
|
|
469212
|
+
}
|
|
469213
|
+
function isBuiltinSnapshotEntry(entry) {
|
|
469214
|
+
if (!isLocalMarketplaceSource(entry.source))
|
|
469215
|
+
return false;
|
|
469216
|
+
if (entry.source.source !== "directory")
|
|
469217
|
+
return false;
|
|
469218
|
+
const root = resolve53(getBuiltinSnapshotRoot()) + sep41;
|
|
469219
|
+
return entry.installLocation.startsWith(root);
|
|
469220
|
+
}
|
|
469221
|
+
async function installBuiltinSnapshotFallback(marketplaceName) {
|
|
469222
|
+
const snapshot = getBuiltinMarketplaceSnapshot(marketplaceName);
|
|
469223
|
+
if (!snapshot) {
|
|
469224
|
+
logForDebugging3(`Snapshot fallback: no bundled snapshot for '${marketplaceName}'`);
|
|
469225
|
+
return { ok: false, reason: "no_snapshot" };
|
|
469226
|
+
}
|
|
469227
|
+
const snapshotDir = getBuiltinSnapshotDir(marketplaceName);
|
|
469228
|
+
const dirSource = { source: "directory", path: snapshotDir };
|
|
469229
|
+
if (!isSourceAllowedByPolicy(dirSource)) {
|
|
469230
|
+
logForDebugging3(`Snapshot fallback: '${marketplaceName}' blocked by enterprise policy`);
|
|
469231
|
+
return { ok: false, reason: "policy_blocked" };
|
|
469232
|
+
}
|
|
469233
|
+
try {
|
|
469234
|
+
await materializeSnapshot(snapshotDir, snapshot.manifest);
|
|
469235
|
+
await updateKnownMarketplacesConfig((known) => {
|
|
469236
|
+
known[marketplaceName] = {
|
|
469237
|
+
source: { source: "directory", path: snapshotDir },
|
|
469238
|
+
installLocation: snapshotDir,
|
|
469239
|
+
lastUpdated: new Date().toISOString()
|
|
469240
|
+
};
|
|
469241
|
+
return known;
|
|
469242
|
+
});
|
|
469243
|
+
logForDebugging3(`Snapshot fallback: materialized '${marketplaceName}' at ${snapshotDir}`);
|
|
469244
|
+
return { ok: true };
|
|
469245
|
+
} catch (error) {
|
|
469246
|
+
logForDebugging3(`Snapshot fallback: failed to materialize '${marketplaceName}': ${toError2(error).message}`, { level: "error" });
|
|
469247
|
+
return { ok: false, reason: "materialize_failed" };
|
|
469248
|
+
}
|
|
469249
|
+
}
|
|
469250
|
+
async function removeBuiltinSnapshotDir(marketplaceName) {
|
|
469251
|
+
try {
|
|
469252
|
+
await rm11(getBuiltinSnapshotDir(marketplaceName), {
|
|
469253
|
+
recursive: true,
|
|
469254
|
+
force: true
|
|
469255
|
+
});
|
|
469256
|
+
} catch {}
|
|
469257
|
+
}
|
|
469258
|
+
async function materializeSnapshot(snapshotDir, manifest) {
|
|
469259
|
+
const manifestDirName = getPluginManifestDirs()[0];
|
|
469260
|
+
const manifestPath = join173(snapshotDir, manifestDirName, "marketplace.json");
|
|
469261
|
+
await mkdir54(join173(snapshotDir, manifestDirName), { recursive: true });
|
|
469262
|
+
const content = jsonStringify5(manifest, null, 2);
|
|
469263
|
+
await writeFile49(manifestPath, content, { encoding: "utf-8" });
|
|
469264
|
+
const roundTrip = JSON.parse(await readFile62(manifestPath, "utf-8"));
|
|
469265
|
+
PluginMarketplaceSchema().parse(roundTrip);
|
|
469266
|
+
}
|
|
469267
|
+
var init_marketplaceSnapshotFallback = __esm(() => {
|
|
469268
|
+
init_configDir();
|
|
469269
|
+
init_debug();
|
|
469270
|
+
init_errors4();
|
|
469271
|
+
init_slowOperations();
|
|
469272
|
+
init_builtinMarketplaceSnapshots();
|
|
469273
|
+
init_marketplaceHelpers();
|
|
469274
|
+
init_marketplaceManager();
|
|
469275
|
+
init_schemas3();
|
|
469276
|
+
});
|
|
469277
|
+
|
|
469369
469278
|
// src/tui/utils/plugins/officialMarketplaceStartupCheck.ts
|
|
469370
469279
|
import { join as join174 } from "path";
|
|
469371
469280
|
function isOfficialMarketplaceAutoInstallDisabled() {
|
|
@@ -469425,14 +469334,19 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
469425
469334
|
return { installed: false, skipped: true, reason: "policy_blocked" };
|
|
469426
469335
|
}
|
|
469427
469336
|
const knownMarketplaces = await loadKnownMarketplacesConfig();
|
|
469428
|
-
|
|
469429
|
-
|
|
469430
|
-
|
|
469431
|
-
|
|
469432
|
-
|
|
469433
|
-
|
|
469434
|
-
|
|
469435
|
-
|
|
469337
|
+
const existingOfficial = knownMarketplaces[OFFICIAL_MARKETPLACE_NAME];
|
|
469338
|
+
if (existingOfficial) {
|
|
469339
|
+
if (isBuiltinSnapshotEntry(existingOfficial)) {
|
|
469340
|
+
logForDebugging3(`Official marketplace is a built-in snapshot entry — attempting live materialization`);
|
|
469341
|
+
} else {
|
|
469342
|
+
logForDebugging3(`Official marketplace '${OFFICIAL_MARKETPLACE_NAME}' already installed, skipping`);
|
|
469343
|
+
saveGlobalConfig((current) => ({
|
|
469344
|
+
...current,
|
|
469345
|
+
officialMarketplaceAutoInstallAttempted: true,
|
|
469346
|
+
officialMarketplaceAutoInstalled: true
|
|
469347
|
+
}));
|
|
469348
|
+
return { installed: false, skipped: true, reason: "already_installed" };
|
|
469349
|
+
}
|
|
469436
469350
|
}
|
|
469437
469351
|
if (!isSourceAllowedByPolicy(OFFICIAL_MARKETPLACE_SOURCE)) {
|
|
469438
469352
|
logForDebugging3("Official marketplace blocked by enterprise policy, skipping");
|
|
@@ -469448,13 +469362,15 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
469448
469362
|
const installLocation = join174(cacheDir, OFFICIAL_MARKETPLACE_NAME);
|
|
469449
469363
|
const gcsSha = await fetchOfficialMarketplaceFromGcs(installLocation, cacheDir);
|
|
469450
469364
|
if (gcsSha !== null) {
|
|
469451
|
-
|
|
469452
|
-
|
|
469453
|
-
|
|
469454
|
-
|
|
469455
|
-
|
|
469456
|
-
|
|
469457
|
-
|
|
469365
|
+
await updateKnownMarketplacesConfig((known) => {
|
|
469366
|
+
known[OFFICIAL_MARKETPLACE_NAME] = {
|
|
469367
|
+
source: OFFICIAL_MARKETPLACE_SOURCE,
|
|
469368
|
+
installLocation,
|
|
469369
|
+
lastUpdated: new Date().toISOString()
|
|
469370
|
+
};
|
|
469371
|
+
return known;
|
|
469372
|
+
});
|
|
469373
|
+
await removeBuiltinSnapshotDir(OFFICIAL_MARKETPLACE_NAME);
|
|
469458
469374
|
saveGlobalConfig((current) => ({
|
|
469459
469375
|
...current,
|
|
469460
469376
|
officialMarketplaceAutoInstallAttempted: true,
|
|
@@ -469480,6 +469396,9 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
469480
469396
|
officialMarketplaceAutoInstallLastAttemptTime: now,
|
|
469481
469397
|
officialMarketplaceAutoInstallNextRetryTime: nextRetryTime
|
|
469482
469398
|
}));
|
|
469399
|
+
const fallback = await tryOfficialSnapshotFallback("gcs_unavailable");
|
|
469400
|
+
if (fallback)
|
|
469401
|
+
return fallback;
|
|
469483
469402
|
return { installed: false, skipped: true, reason: "gcs_unavailable" };
|
|
469484
469403
|
}
|
|
469485
469404
|
const gitAvailable = await checkGitAvailable();
|
|
@@ -469506,6 +469425,9 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
469506
469425
|
logError3(configError);
|
|
469507
469426
|
logForDebugging3(`Failed to save marketplace auto-install git_unavailable state: ${saveError}`, { level: "error" });
|
|
469508
469427
|
}
|
|
469428
|
+
const fallback = await tryOfficialSnapshotFallback("git_unavailable");
|
|
469429
|
+
if (fallback)
|
|
469430
|
+
return fallback;
|
|
469509
469431
|
return {
|
|
469510
469432
|
installed: false,
|
|
469511
469433
|
skipped: true,
|
|
@@ -469516,6 +469438,7 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
469516
469438
|
logForDebugging3("Attempting to auto-install official marketplace");
|
|
469517
469439
|
await addMarketplaceSource(OFFICIAL_MARKETPLACE_SOURCE);
|
|
469518
469440
|
logForDebugging3("Successfully auto-installed official marketplace");
|
|
469441
|
+
await removeBuiltinSnapshotDir(OFFICIAL_MARKETPLACE_NAME);
|
|
469519
469442
|
const previousRetryCount = config.officialMarketplaceAutoInstallRetryCount || 0;
|
|
469520
469443
|
saveGlobalConfig((current) => ({
|
|
469521
469444
|
...current,
|
|
@@ -469532,6 +469455,9 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
469532
469455
|
if (errorMessage.includes("xcrun: error:")) {
|
|
469533
469456
|
markGitUnavailable();
|
|
469534
469457
|
logForDebugging3("Official marketplace auto-install: git is a non-functional macOS xcrun shim, treating as git_unavailable");
|
|
469458
|
+
const fallback = await tryOfficialSnapshotFallback("git_unavailable");
|
|
469459
|
+
if (fallback)
|
|
469460
|
+
return fallback;
|
|
469535
469461
|
return {
|
|
469536
469462
|
installed: false,
|
|
469537
469463
|
skipped: true,
|
|
@@ -469561,6 +469487,9 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
469561
469487
|
logError3(configError);
|
|
469562
469488
|
logForDebugging3(`Failed to save marketplace auto-install failure state: ${saveError}`, { level: "error" });
|
|
469563
469489
|
}
|
|
469490
|
+
const fallback = await tryOfficialSnapshotFallback("unknown");
|
|
469491
|
+
if (fallback)
|
|
469492
|
+
return fallback;
|
|
469564
469493
|
return {
|
|
469565
469494
|
installed: false,
|
|
469566
469495
|
skipped: true,
|
|
@@ -469569,6 +469498,18 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
469569
469498
|
};
|
|
469570
469499
|
}
|
|
469571
469500
|
}
|
|
469501
|
+
async function tryOfficialSnapshotFallback(reason) {
|
|
469502
|
+
const result = await installBuiltinSnapshotFallback(OFFICIAL_MARKETPLACE_NAME);
|
|
469503
|
+
if (!result.ok)
|
|
469504
|
+
return null;
|
|
469505
|
+
logForDebugging3(`Official marketplace: live source unavailable (${reason}) — using built-in snapshot catalog`);
|
|
469506
|
+
return {
|
|
469507
|
+
installed: true,
|
|
469508
|
+
skipped: false,
|
|
469509
|
+
fallback: "builtin-snapshot",
|
|
469510
|
+
fallbackReason: reason
|
|
469511
|
+
};
|
|
469512
|
+
}
|
|
469572
469513
|
var RETRY_CONFIG;
|
|
469573
469514
|
var init_officialMarketplaceStartupCheck = __esm(() => {
|
|
469574
469515
|
init_growthbook();
|
|
@@ -469580,6 +469521,7 @@ var init_officialMarketplaceStartupCheck = __esm(() => {
|
|
|
469580
469521
|
init_gitAvailability();
|
|
469581
469522
|
init_marketplaceHelpers();
|
|
469582
469523
|
init_marketplaceManager();
|
|
469524
|
+
init_marketplaceSnapshotFallback();
|
|
469583
469525
|
init_officialMarketplace();
|
|
469584
469526
|
init_officialMarketplaceGcs();
|
|
469585
469527
|
RETRY_CONFIG = {
|
|
@@ -469609,7 +469551,18 @@ async function _temp179() {
|
|
|
469609
469551
|
timeoutMs: 1e4
|
|
469610
469552
|
});
|
|
469611
469553
|
}
|
|
469612
|
-
if (result.
|
|
469554
|
+
if (result.fallback === "builtin-snapshot") {
|
|
469555
|
+
logForDebugging3("Showing marketplace snapshot-fallback notification");
|
|
469556
|
+
notifs.push({
|
|
469557
|
+
key: "marketplace-snapshot-fallback",
|
|
469558
|
+
jsx: /* @__PURE__ */ jsx_dev_runtime408.jsxDEV(ThemedText, {
|
|
469559
|
+
color: "warning",
|
|
469560
|
+
children: "官方插件源未就绪 · 已用内建快照目录(/plugin 可浏览插件清单)· 下次启动自动重试活同步"
|
|
469561
|
+
}, undefined, false, undefined, this),
|
|
469562
|
+
priority: "immediate",
|
|
469563
|
+
timeoutMs: 1e4
|
|
469564
|
+
});
|
|
469565
|
+
} else if (result.installed) {
|
|
469613
469566
|
logForDebugging3("Showing marketplace installation success notification");
|
|
469614
469567
|
notifs.push({
|
|
469615
469568
|
key: "marketplace-installed",
|
|
@@ -469675,9 +469628,18 @@ async function checkAndInstallMarketplacePreset(config) {
|
|
|
469675
469628
|
if (config.name) {
|
|
469676
469629
|
try {
|
|
469677
469630
|
const knownMarketplaces = await loadKnownMarketplacesConfig();
|
|
469678
|
-
|
|
469679
|
-
|
|
469680
|
-
|
|
469631
|
+
const existing = knownMarketplaces[config.name];
|
|
469632
|
+
if (existing) {
|
|
469633
|
+
if (isBuiltinSnapshotEntry(existing)) {
|
|
469634
|
+
logForDebugging3(`${label} marketplace '${config.name}' is a built-in snapshot entry — attempting live materialization`);
|
|
469635
|
+
} else {
|
|
469636
|
+
logForDebugging3(`${label} marketplace '${config.name}' already installed, skipping`);
|
|
469637
|
+
return {
|
|
469638
|
+
installed: false,
|
|
469639
|
+
skipped: true,
|
|
469640
|
+
reason: "already_installed"
|
|
469641
|
+
};
|
|
469642
|
+
}
|
|
469681
469643
|
}
|
|
469682
469644
|
} catch (error) {
|
|
469683
469645
|
logForDebugging3(`${label} marketplace: failed to read known_marketplaces (${toError2(error).message}), attempting install`, { level: "error" });
|
|
@@ -469690,25 +469652,51 @@ async function checkAndInstallMarketplacePreset(config) {
|
|
|
469690
469652
|
const gitAvailable = await checkGitAvailable();
|
|
469691
469653
|
if (!gitAvailable) {
|
|
469692
469654
|
logForDebugging3(`Git not available, skipping ${label} marketplace auto-install`);
|
|
469655
|
+
const fallback = await trySnapshotFallback(config, "git_unavailable");
|
|
469656
|
+
if (fallback)
|
|
469657
|
+
return fallback;
|
|
469693
469658
|
return { installed: false, skipped: true, reason: "git_unavailable" };
|
|
469694
469659
|
}
|
|
469695
469660
|
try {
|
|
469696
469661
|
logForDebugging3(`Attempting to auto-install ${label} marketplace`);
|
|
469697
469662
|
await addMarketplaceSource(config.source);
|
|
469698
469663
|
logForDebugging3(`Successfully auto-installed ${label} marketplace`);
|
|
469664
|
+
if (config.name) {
|
|
469665
|
+
await removeBuiltinSnapshotDir(config.name);
|
|
469666
|
+
}
|
|
469699
469667
|
return { installed: true, skipped: false };
|
|
469700
469668
|
} catch (error) {
|
|
469701
469669
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
469702
469670
|
if (errorMessage.includes("xcrun: error:")) {
|
|
469703
469671
|
markGitUnavailable();
|
|
469704
469672
|
logForDebugging3(`${label} marketplace auto-install: git is a non-functional macOS xcrun shim, treating as git_unavailable`);
|
|
469673
|
+
const fallback = await trySnapshotFallback(config, "git_unavailable");
|
|
469674
|
+
if (fallback)
|
|
469675
|
+
return fallback;
|
|
469705
469676
|
return { installed: false, skipped: true, reason: "git_unavailable" };
|
|
469706
469677
|
}
|
|
469707
469678
|
logForDebugging3(`Failed to auto-install ${label} marketplace: ${errorMessage}`, { level: "error" });
|
|
469708
469679
|
logError3(toError2(error));
|
|
469680
|
+
const fallback = await trySnapshotFallback(config, "unknown");
|
|
469681
|
+
if (fallback)
|
|
469682
|
+
return fallback;
|
|
469709
469683
|
return { installed: false, skipped: true, reason: "unknown" };
|
|
469710
469684
|
}
|
|
469711
469685
|
}
|
|
469686
|
+
async function trySnapshotFallback(config, reason) {
|
|
469687
|
+
if (!config.name)
|
|
469688
|
+
return null;
|
|
469689
|
+
const result = await installBuiltinSnapshotFallback(config.name);
|
|
469690
|
+
if (!result.ok)
|
|
469691
|
+
return null;
|
|
469692
|
+
logForDebugging3(`${config.displayName} marketplace: live source unavailable (${reason}) — using built-in snapshot catalog`);
|
|
469693
|
+
return {
|
|
469694
|
+
installed: true,
|
|
469695
|
+
skipped: false,
|
|
469696
|
+
fallback: "builtin-snapshot",
|
|
469697
|
+
fallbackReason: reason
|
|
469698
|
+
};
|
|
469699
|
+
}
|
|
469712
469700
|
var init_marketplacePreset = __esm(() => {
|
|
469713
469701
|
init_debug();
|
|
469714
469702
|
init_envUtils2();
|
|
@@ -469717,6 +469705,7 @@ var init_marketplacePreset = __esm(() => {
|
|
|
469717
469705
|
init_gitAvailability();
|
|
469718
469706
|
init_marketplaceHelpers();
|
|
469719
469707
|
init_marketplaceManager();
|
|
469708
|
+
init_marketplaceSnapshotFallback();
|
|
469720
469709
|
});
|
|
469721
469710
|
|
|
469722
469711
|
// src/tui/plugins/ascend/marketplace/ascendMarketplaceStartupCheck.ts
|
|
@@ -469766,7 +469755,21 @@ function useAscendMarketplaceNotification() {
|
|
|
469766
469755
|
useStartupNotification(async () => {
|
|
469767
469756
|
const result = await checkAndInstallAscendMarketplace();
|
|
469768
469757
|
const notifs = [];
|
|
469769
|
-
if (result.
|
|
469758
|
+
if (result.fallback === "builtin-snapshot") {
|
|
469759
|
+
logForDebugging3("Showing Ascend marketplace snapshot-fallback notification");
|
|
469760
|
+
notifs.push({
|
|
469761
|
+
key: "ascend-marketplace-snapshot-fallback",
|
|
469762
|
+
jsx: /* @__PURE__ */ jsx_dev_runtime409.jsxDEV(ThemedText, {
|
|
469763
|
+
color: "warning",
|
|
469764
|
+
children: [
|
|
469765
|
+
ASCEND_OFFICIAL_DISPLAY_LABEL,
|
|
469766
|
+
" 源未就绪 · 已用内建快照目录( /plugin 可浏览插件清单)· 下次启动自动重试活同步"
|
|
469767
|
+
]
|
|
469768
|
+
}, undefined, true, undefined, this),
|
|
469769
|
+
priority: "immediate",
|
|
469770
|
+
timeoutMs: 1e4
|
|
469771
|
+
});
|
|
469772
|
+
} else if (result.installed) {
|
|
469770
469773
|
logForDebugging3("Showing Ascend marketplace installation success notification");
|
|
469771
469774
|
notifs.push({
|
|
469772
469775
|
key: "ascend-marketplace-installed",
|
|
@@ -469849,7 +469852,21 @@ function useAtlasMarketplaceNotification() {
|
|
|
469849
469852
|
useStartupNotification(async () => {
|
|
469850
469853
|
const result = await checkAndInstallAtlasMarketplace();
|
|
469851
469854
|
const notifs = [];
|
|
469852
|
-
if (result.
|
|
469855
|
+
if (result.fallback === "builtin-snapshot") {
|
|
469856
|
+
logForDebugging3("Showing Atlas marketplace snapshot-fallback notification");
|
|
469857
|
+
notifs.push({
|
|
469858
|
+
key: "atlas-marketplace-snapshot-fallback",
|
|
469859
|
+
jsx: /* @__PURE__ */ jsx_dev_runtime410.jsxDEV(ThemedText, {
|
|
469860
|
+
color: "warning",
|
|
469861
|
+
children: [
|
|
469862
|
+
ATLAS_MARKETPLACE_DISPLAY_LABEL,
|
|
469863
|
+
" 源未就绪 · 已用内建快照目录( /plugin 可浏览插件清单)· 下次启动自动重试活同步"
|
|
469864
|
+
]
|
|
469865
|
+
}, undefined, true, undefined, this),
|
|
469866
|
+
priority: "immediate",
|
|
469867
|
+
timeoutMs: 1e4
|
|
469868
|
+
});
|
|
469869
|
+
} else if (result.installed) {
|
|
469853
469870
|
logForDebugging3("Showing Atlas marketplace installation success notification");
|
|
469854
469871
|
notifs.push({
|
|
469855
469872
|
key: "atlas-marketplace-installed",
|
|
@@ -471719,7 +471736,7 @@ var init_usePluginAutoupdateNotification = __esm(() => {
|
|
|
471719
471736
|
});
|
|
471720
471737
|
|
|
471721
471738
|
// src/tui/utils/plugins/reconciler.ts
|
|
471722
|
-
import { isAbsolute as isAbsolute34, resolve as
|
|
471739
|
+
import { isAbsolute as isAbsolute34, resolve as resolve54 } from "path";
|
|
471723
471740
|
function diffMarketplaces(declared, materialized, opts) {
|
|
471724
471741
|
const missing = [];
|
|
471725
471742
|
const sourceChanged = [];
|
|
@@ -471832,7 +471849,7 @@ function normalizeSource(source, projectRoot) {
|
|
|
471832
471849
|
const canonicalRoot = findCanonicalGitRoot2(base);
|
|
471833
471850
|
return {
|
|
471834
471851
|
...source,
|
|
471835
|
-
path:
|
|
471852
|
+
path: resolve54(canonicalRoot ?? base, source.path)
|
|
471836
471853
|
};
|
|
471837
471854
|
}
|
|
471838
471855
|
return source;
|
|
@@ -474824,7 +474841,7 @@ var init_cronJitterConfig2 = __esm(() => {
|
|
|
474824
474841
|
});
|
|
474825
474842
|
|
|
474826
474843
|
// src/tui/utils/cronTasksLock.ts
|
|
474827
|
-
import { mkdir as
|
|
474844
|
+
import { mkdir as mkdir55, readFile as readFile63, unlink as unlink26, writeFile as writeFile50 } from "fs/promises";
|
|
474828
474845
|
import { dirname as dirname83, join as join176 } from "path";
|
|
474829
474846
|
function getLockPath3(dir) {
|
|
474830
474847
|
return join176(dir ?? getProjectRoot(), LOCK_FILE_REL2);
|
|
@@ -474832,7 +474849,7 @@ function getLockPath3(dir) {
|
|
|
474832
474849
|
async function readLock3(dir) {
|
|
474833
474850
|
let raw;
|
|
474834
474851
|
try {
|
|
474835
|
-
raw = await
|
|
474852
|
+
raw = await readFile63(getLockPath3(dir), "utf8");
|
|
474836
474853
|
} catch {
|
|
474837
474854
|
return;
|
|
474838
474855
|
}
|
|
@@ -474850,7 +474867,7 @@ async function tryCreateExclusive3(lock, dir) {
|
|
|
474850
474867
|
if (code === "EEXIST")
|
|
474851
474868
|
return false;
|
|
474852
474869
|
if (code === "ENOENT") {
|
|
474853
|
-
await
|
|
474870
|
+
await mkdir55(dirname83(path), { recursive: true });
|
|
474854
474871
|
try {
|
|
474855
474872
|
await writeFile50(path, body, { flag: "wx" });
|
|
474856
474873
|
return true;
|
|
@@ -484586,7 +484603,7 @@ var init_bundled = __esm(() => {
|
|
|
484586
484603
|
// src/tui/utils/deepLink/banner.ts
|
|
484587
484604
|
import { stat as stat53 } from "fs/promises";
|
|
484588
484605
|
import { homedir as homedir44 } from "os";
|
|
484589
|
-
import { join as join178, sep as
|
|
484606
|
+
import { join as join178, sep as sep42 } from "path";
|
|
484590
484607
|
function buildDeepLinkBanner(info) {
|
|
484591
484608
|
const lines = [
|
|
484592
484609
|
`This session was opened by an external deep link in ${tildify(info.cwd)}`
|
|
@@ -484627,7 +484644,7 @@ function tildify(p) {
|
|
|
484627
484644
|
const home = homedir44();
|
|
484628
484645
|
if (p === home)
|
|
484629
484646
|
return "~";
|
|
484630
|
-
if (p.startsWith(home +
|
|
484647
|
+
if (p.startsWith(home + sep42))
|
|
484631
484648
|
return "~" + p.slice(home.length);
|
|
484632
484649
|
return p;
|
|
484633
484650
|
}
|
|
@@ -485134,23 +485151,6 @@ var init_migrateEnableAllProjectMcpServersToSettings = __esm(() => {
|
|
|
485134
485151
|
init_settings3();
|
|
485135
485152
|
});
|
|
485136
485153
|
|
|
485137
|
-
// src/tui/migrations/migrateReplBridgeEnabledToRemoteControlAtStartup.ts
|
|
485138
|
-
function migrateReplBridgeEnabledToRemoteControlAtStartup() {
|
|
485139
|
-
saveGlobalConfig((prev) => {
|
|
485140
|
-
const oldValue = prev["replBridgeEnabled"];
|
|
485141
|
-
if (oldValue === undefined)
|
|
485142
|
-
return prev;
|
|
485143
|
-
if (prev.remoteControlAtStartup !== undefined)
|
|
485144
|
-
return prev;
|
|
485145
|
-
const next = { ...prev, remoteControlAtStartup: Boolean(oldValue) };
|
|
485146
|
-
delete next["replBridgeEnabled"];
|
|
485147
|
-
return next;
|
|
485148
|
-
});
|
|
485149
|
-
}
|
|
485150
|
-
var init_migrateReplBridgeEnabledToRemoteControlAtStartup = __esm(() => {
|
|
485151
|
-
init_config6();
|
|
485152
|
-
});
|
|
485153
|
-
|
|
485154
485154
|
// src/tui/migrations/resetAutoModeOptInForDefaultOffer.ts
|
|
485155
485155
|
function resetAutoModeOptInForDefaultOffer() {
|
|
485156
485156
|
if (feature("TRANSCRIPT_CLASSIFIER")) {
|
|
@@ -486991,7 +486991,7 @@ var init_mcp8 = __esm(() => {
|
|
|
486991
486991
|
});
|
|
486992
486992
|
|
|
486993
486993
|
// src/tui/utils/atlasDesktop.ts
|
|
486994
|
-
import { readdir as readdir34, readFile as
|
|
486994
|
+
import { readdir as readdir34, readFile as readFile64, stat as stat55 } from "fs/promises";
|
|
486995
486995
|
import { homedir as homedir47 } from "os";
|
|
486996
486996
|
import { join as join183 } from "path";
|
|
486997
486997
|
async function getDesktopConfigPath() {
|
|
@@ -487039,7 +487039,7 @@ async function readDesktopMcpServers() {
|
|
|
487039
487039
|
const configPath = await getDesktopConfigPath();
|
|
487040
487040
|
let configContent;
|
|
487041
487041
|
try {
|
|
487042
|
-
configContent = await
|
|
487042
|
+
configContent = await readFile64(configPath, { encoding: "utf8" });
|
|
487043
487043
|
} catch (e) {
|
|
487044
487044
|
const code = getErrnoCode2(e);
|
|
487045
487045
|
if (code === "ENOENT") {
|
|
@@ -487474,13 +487474,13 @@ var init_auth6 = __esm(() => {
|
|
|
487474
487474
|
});
|
|
487475
487475
|
|
|
487476
487476
|
// src/tui/utils/plugins/marketplacePublish.ts
|
|
487477
|
-
import { cp, mkdir as
|
|
487477
|
+
import { cp, mkdir as mkdir56, readFile as readFile65, rm as rm12, writeFile as writeFile53 } from "fs/promises";
|
|
487478
487478
|
import {
|
|
487479
487479
|
dirname as dirname87,
|
|
487480
487480
|
join as join184,
|
|
487481
487481
|
relative as relative38,
|
|
487482
|
-
resolve as
|
|
487483
|
-
sep as
|
|
487482
|
+
resolve as resolve55,
|
|
487483
|
+
sep as sep43
|
|
487484
487484
|
} from "path";
|
|
487485
487485
|
function git(marketplaceDir, args, timeoutMs = 2 * 60 * 1000) {
|
|
487486
487486
|
return execFileNoThrowWithCwd2("git", args, {
|
|
@@ -487492,16 +487492,16 @@ function gitFailureMessage(res) {
|
|
|
487492
487492
|
return (res.stderr || res.error || `exit code ${res.code}`).trim();
|
|
487493
487493
|
}
|
|
487494
487494
|
async function publishPluginToMarketplace(opts) {
|
|
487495
|
-
const pluginDir =
|
|
487496
|
-
const marketplaceDir =
|
|
487495
|
+
const pluginDir = resolve55(opts.pluginDir);
|
|
487496
|
+
const marketplaceDir = resolve55(opts.marketplaceDir);
|
|
487497
487497
|
const notes = [];
|
|
487498
|
-
if (pluginDir === marketplaceDir || pluginDir.startsWith(marketplaceDir +
|
|
487498
|
+
if (pluginDir === marketplaceDir || pluginDir.startsWith(marketplaceDir + sep43)) {
|
|
487499
487499
|
throw new Error(`Cannot publish "${pluginDir}": the plugin directory must not live inside the target marketplace (${marketplaceDir})`);
|
|
487500
487500
|
}
|
|
487501
487501
|
const pluginManifestPath = findManifestInDir(pluginDir, "plugin.json");
|
|
487502
487502
|
let pluginManifestRaw;
|
|
487503
487503
|
try {
|
|
487504
|
-
pluginManifestRaw = await
|
|
487504
|
+
pluginManifestRaw = await readFile65(pluginManifestPath, {
|
|
487505
487505
|
encoding: "utf-8"
|
|
487506
487506
|
});
|
|
487507
487507
|
} catch {
|
|
@@ -487520,13 +487520,13 @@ async function publishPluginToMarketplace(opts) {
|
|
|
487520
487520
|
const name = manifest.name;
|
|
487521
487521
|
const version = opts.version ?? (typeof manifest.version === "string" ? manifest.version : undefined);
|
|
487522
487522
|
const targetDir = join184(marketplaceDir, "plugins", name);
|
|
487523
|
-
await
|
|
487524
|
-
await
|
|
487523
|
+
await rm12(targetDir, { recursive: true, force: true });
|
|
487524
|
+
await mkdir56(dirname87(targetDir), { recursive: true });
|
|
487525
487525
|
await cp(pluginDir, targetDir, { recursive: true });
|
|
487526
487526
|
const marketplaceManifestPath = findManifestInDir(marketplaceDir, "marketplace.json");
|
|
487527
487527
|
let marketplaceRaw;
|
|
487528
487528
|
try {
|
|
487529
|
-
marketplaceRaw = await
|
|
487529
|
+
marketplaceRaw = await readFile65(marketplaceManifestPath, {
|
|
487530
487530
|
encoding: "utf-8"
|
|
487531
487531
|
});
|
|
487532
487532
|
} catch {
|
|
@@ -487623,10 +487623,10 @@ var init_marketplacePublish = __esm(() => {
|
|
|
487623
487623
|
// src/tui/utils/plugins/marketplaceScaffold.ts
|
|
487624
487624
|
import { userInfo as userInfo2 } from "os";
|
|
487625
487625
|
import { existsSync as existsSync15 } from "fs";
|
|
487626
|
-
import { mkdir as
|
|
487627
|
-
import { dirname as dirname88, join as join185, resolve 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";
|
|
487628
487628
|
async function scaffoldMarketplace(opts) {
|
|
487629
|
-
const targetDir =
|
|
487629
|
+
const targetDir = resolve56(opts.targetDir);
|
|
487630
487630
|
const name = opts.name.trim();
|
|
487631
487631
|
const manifestDirName = getPluginManifestDirs()[0];
|
|
487632
487632
|
const marketplaceManifestPath = join185(targetDir, manifestDirName, "marketplace.json");
|
|
@@ -487672,7 +487672,7 @@ async function scaffoldMarketplace(opts) {
|
|
|
487672
487672
|
const files = [];
|
|
487673
487673
|
const write = async (relPath, content) => {
|
|
487674
487674
|
const abs = join185(targetDir, relPath);
|
|
487675
|
-
await
|
|
487675
|
+
await mkdir57(dirname88(abs), { recursive: true });
|
|
487676
487676
|
await writeFile54(abs, content, "utf-8");
|
|
487677
487677
|
files.push(relPath);
|
|
487678
487678
|
};
|
|
@@ -487712,7 +487712,7 @@ var init_marketplaceScaffold = __esm(() => {
|
|
|
487712
487712
|
});
|
|
487713
487713
|
|
|
487714
487714
|
// src/tui/cli/handlers/plugins.ts
|
|
487715
|
-
import { basename as basename65, dirname as dirname89, resolve as
|
|
487715
|
+
import { basename as basename65, dirname as dirname89, resolve as resolve57 } from "path";
|
|
487716
487716
|
function handleMarketplaceError(error, action) {
|
|
487717
487717
|
logError3(error);
|
|
487718
487718
|
cliError2(`${figures_default.cross} Failed to ${action}: ${errorMessage2(error)}`);
|
|
@@ -488064,7 +488064,7 @@ async function marketplaceUpdateHandler(name, options) {
|
|
|
488064
488064
|
async function marketplaceScaffoldHandler(options) {
|
|
488065
488065
|
if (options.cowork)
|
|
488066
488066
|
setUseCoworkPlugins(true);
|
|
488067
|
-
const targetDir =
|
|
488067
|
+
const targetDir = resolve57(options.target ?? process.cwd());
|
|
488068
488068
|
try {
|
|
488069
488069
|
const result = await scaffoldMarketplace({
|
|
488070
488070
|
name: options.name,
|
|
@@ -488089,8 +488089,8 @@ async function marketplacePublishHandler(options) {
|
|
|
488089
488089
|
setUseCoworkPlugins(true);
|
|
488090
488090
|
try {
|
|
488091
488091
|
const result = await publishPluginToMarketplace({
|
|
488092
|
-
pluginDir:
|
|
488093
|
-
marketplaceDir:
|
|
488092
|
+
pluginDir: resolve57(options.plugin),
|
|
488093
|
+
marketplaceDir: resolve57(options.marketplace),
|
|
488094
488094
|
version: options.version,
|
|
488095
488095
|
push: options.push
|
|
488096
488096
|
});
|
|
@@ -489306,7 +489306,7 @@ var init_update2 = __esm(() => {
|
|
|
489306
489306
|
|
|
489307
489307
|
// src/tui/main.tsx
|
|
489308
489308
|
import { readFileSync as readFileSync25 } from "fs";
|
|
489309
|
-
import { resolve as
|
|
489309
|
+
import { resolve as resolve58 } from "path";
|
|
489310
489310
|
function logManagedSettings() {
|
|
489311
489311
|
try {
|
|
489312
489312
|
const policySettings = getSettingsForSource2("policySettings");
|
|
@@ -489353,7 +489353,6 @@ function runMigrations() {
|
|
|
489353
489353
|
migrateAutoUpdatesToSettings();
|
|
489354
489354
|
migrateBypassPermissionsAcceptedToSettings();
|
|
489355
489355
|
migrateEnableAllProjectMcpServersToSettings();
|
|
489356
|
-
migrateReplBridgeEnabledToRemoteControlAtStartup();
|
|
489357
489356
|
if (feature("TRANSCRIPT_CLASSIFIER")) {
|
|
489358
489357
|
resetAutoModeOptInForDefaultOffer();
|
|
489359
489358
|
}
|
|
@@ -489616,8 +489615,7 @@ async function main2() {
|
|
|
489616
489615
|
const cliArgs = process.argv.slice(2);
|
|
489617
489616
|
const hasPrintFlag = cliArgs.includes("-p") || cliArgs.includes("--print");
|
|
489618
489617
|
const hasInitOnlyFlag = cliArgs.includes("--init-only");
|
|
489619
|
-
const
|
|
489620
|
-
const isNonInteractive = hasPrintFlag || hasInitOnlyFlag || hasSdkUrl || !process.stdout.isTTY;
|
|
489618
|
+
const isNonInteractive = hasPrintFlag || hasInitOnlyFlag || !process.stdout.isTTY;
|
|
489621
489619
|
if (isNonInteractive) {
|
|
489622
489620
|
stopCapturingEarlyInput();
|
|
489623
489621
|
}
|
|
@@ -489652,9 +489650,6 @@ async function main2() {
|
|
|
489652
489650
|
} else if (!clientType.startsWith("sdk-") && clientType !== "claude-desktop" && clientType !== "local-agent" && clientType !== "remote") {
|
|
489653
489651
|
setQuestionPreviewFormat("markdown");
|
|
489654
489652
|
}
|
|
489655
|
-
if (process.env.ATLAS_ENVIRONMENT_KIND === "bridge") {
|
|
489656
|
-
setSessionSource("remote-control");
|
|
489657
|
-
}
|
|
489658
489653
|
profileCheckpoint("main_client_type_determined");
|
|
489659
489654
|
eagerLoadSettings2();
|
|
489660
489655
|
profileCheckpoint("main_before_run");
|
|
@@ -489837,49 +489832,26 @@ ${getTmuxInstallInstructions3()}
|
|
|
489837
489832
|
getTeammateModeSnapshot().setCliTeammateModeOverride?.(teammateOpts.teammateMode);
|
|
489838
489833
|
}
|
|
489839
489834
|
}
|
|
489840
|
-
const sdkUrl = options.sdkUrl ?? undefined;
|
|
489841
489835
|
const effectiveIncludePartialMessages = includePartialMessages || isEnvTruthy2(process.env.ATLAS_INCLUDE_PARTIAL_MESSAGES);
|
|
489842
489836
|
if (includeHookEvents || isEnvTruthy2(process.env.ATLAS_REMOTE)) {
|
|
489843
489837
|
setAllHookEventsEnabled(true);
|
|
489844
489838
|
}
|
|
489845
|
-
if (sdkUrl) {
|
|
489846
|
-
if (!inputFormat) {
|
|
489847
|
-
inputFormat = "stream-json";
|
|
489848
|
-
}
|
|
489849
|
-
if (!outputFormat) {
|
|
489850
|
-
outputFormat = "stream-json";
|
|
489851
|
-
}
|
|
489852
|
-
if (options.verbose === undefined) {
|
|
489853
|
-
verbose = true;
|
|
489854
|
-
}
|
|
489855
|
-
if (!options.print) {
|
|
489856
|
-
print = true;
|
|
489857
|
-
}
|
|
489858
|
-
}
|
|
489859
|
-
const teleport = options.teleport ?? null;
|
|
489860
|
-
const remoteOption = options.remote;
|
|
489861
|
-
const remote = remoteOption === true ? "" : remoteOption ?? null;
|
|
489862
|
-
const remoteControlOption = options.remoteControl ?? options.rc;
|
|
489863
|
-
let remoteControl = false;
|
|
489864
|
-
const remoteControlName = typeof remoteControlOption === "string" && remoteControlOption.length > 0 ? remoteControlOption : undefined;
|
|
489865
489839
|
if (sessionId) {
|
|
489866
489840
|
if ((options.continue || options.resume) && !options.forkSession) {
|
|
489867
489841
|
process.stderr.write(source_default.red(`Error: --session-id can only be used with --continue or --resume if --fork-session is also specified.
|
|
489868
489842
|
`));
|
|
489869
489843
|
process.exit(1);
|
|
489870
489844
|
}
|
|
489871
|
-
|
|
489872
|
-
|
|
489873
|
-
|
|
489874
|
-
process.stderr.write(source_default.red(`Error: Invalid session ID. Must be a valid UUID.
|
|
489845
|
+
const validatedSessionId = validateUuid2(sessionId);
|
|
489846
|
+
if (!validatedSessionId) {
|
|
489847
|
+
process.stderr.write(source_default.red(`Error: Invalid session ID. Must be a valid UUID.
|
|
489875
489848
|
`));
|
|
489876
|
-
|
|
489877
|
-
|
|
489878
|
-
|
|
489879
|
-
|
|
489849
|
+
process.exit(1);
|
|
489850
|
+
}
|
|
489851
|
+
if (sessionIdExists(validatedSessionId)) {
|
|
489852
|
+
process.stderr.write(source_default.red(`Error: Session ID ${validatedSessionId} is already in use.
|
|
489880
489853
|
`));
|
|
489881
|
-
|
|
489882
|
-
}
|
|
489854
|
+
process.exit(1);
|
|
489883
489855
|
}
|
|
489884
489856
|
}
|
|
489885
489857
|
const fileSpecs = options.file;
|
|
@@ -489901,12 +489873,12 @@ ${getTmuxInstallInstructions3()}
|
|
|
489901
489873
|
process.exit(1);
|
|
489902
489874
|
}
|
|
489903
489875
|
try {
|
|
489904
|
-
const filePath =
|
|
489876
|
+
const filePath = resolve58(options.systemPromptFile);
|
|
489905
489877
|
systemPrompt = readFileSync25(filePath, "utf8");
|
|
489906
489878
|
} catch (error) {
|
|
489907
489879
|
const code = getErrnoCode2(error);
|
|
489908
489880
|
if (code === "ENOENT") {
|
|
489909
|
-
process.stderr.write(source_default.red(`Error: System prompt file not found: ${
|
|
489881
|
+
process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve58(options.systemPromptFile)}
|
|
489910
489882
|
`));
|
|
489911
489883
|
process.exit(1);
|
|
489912
489884
|
}
|
|
@@ -489923,12 +489895,12 @@ ${getTmuxInstallInstructions3()}
|
|
|
489923
489895
|
process.exit(1);
|
|
489924
489896
|
}
|
|
489925
489897
|
try {
|
|
489926
|
-
const filePath =
|
|
489898
|
+
const filePath = resolve58(options.appendSystemPromptFile);
|
|
489927
489899
|
appendSystemPrompt = readFileSync25(filePath, "utf8");
|
|
489928
489900
|
} catch (error) {
|
|
489929
489901
|
const code = getErrnoCode2(error);
|
|
489930
489902
|
if (code === "ENOENT") {
|
|
489931
|
-
process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${
|
|
489903
|
+
process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve58(options.appendSystemPromptFile)}
|
|
489932
489904
|
`));
|
|
489933
489905
|
process.exit(1);
|
|
489934
489906
|
}
|
|
@@ -489978,7 +489950,7 @@ ${addendum}` : addendum;
|
|
|
489978
489950
|
errors = result.errors;
|
|
489979
489951
|
}
|
|
489980
489952
|
} else {
|
|
489981
|
-
const configPath =
|
|
489953
|
+
const configPath = resolve58(configItem);
|
|
489982
489954
|
const result = parseMcpConfigFromFilePath({
|
|
489983
489955
|
filePath: configPath,
|
|
489984
489956
|
expandVars: true,
|
|
@@ -490073,7 +490045,7 @@ ${formattedErrors}
|
|
|
490073
490045
|
}
|
|
490074
490046
|
}
|
|
490075
490047
|
setAdditionalDirectoriesForClaudeMd(addDir);
|
|
490076
|
-
const shouldAvoidPermissionPrompts = isNonInteractiveSession && !
|
|
490048
|
+
const shouldAvoidPermissionPrompts = isNonInteractiveSession && !options.permissionPromptTool;
|
|
490077
490049
|
const initResult = await initializeToolPermissionContext2({
|
|
490078
490050
|
allowedToolsCli: allowedTools,
|
|
490079
490051
|
disallowedToolsCli: disallowedTools,
|
|
@@ -490114,12 +490086,6 @@ ${formattedErrors}
|
|
|
490114
490086
|
console.error(`Error: --input-format=stream-json requires output-format=stream-json.`);
|
|
490115
490087
|
process.exit(1);
|
|
490116
490088
|
}
|
|
490117
|
-
if (sdkUrl) {
|
|
490118
|
-
if (inputFormat !== "stream-json" || outputFormat !== "stream-json") {
|
|
490119
|
-
console.error(`Error: --sdk-url requires both --input-format=stream-json and --output-format=stream-json.`);
|
|
490120
|
-
process.exit(1);
|
|
490121
|
-
}
|
|
490122
|
-
}
|
|
490123
490089
|
if (options.replayUserMessages) {
|
|
490124
490090
|
if (inputFormat !== "stream-json" || outputFormat !== "stream-json") {
|
|
490125
490091
|
console.error(`Error: --replay-user-messages requires both --input-format=stream-json and --output-format=stream-json.`);
|
|
@@ -490489,7 +490455,7 @@ ${inputPrompt}` : mergePrompt;
|
|
|
490489
490455
|
}
|
|
490490
490456
|
applyConfigEnvironmentVariables2();
|
|
490491
490457
|
initializeTelemetryAfterTrust();
|
|
490492
|
-
const sessionStartHooksPromise = options.continue || options.resume ||
|
|
490458
|
+
const sessionStartHooksPromise = options.continue || options.resume || setupTrigger ? undefined : processSessionStartHooks("startup");
|
|
490493
490459
|
sessionStartHooksPromise?.catch(() => {});
|
|
490494
490460
|
profileCheckpoint("before_validateForceLoginOrg");
|
|
490495
490461
|
const orgValidation = await validateForceLoginOrg();
|
|
@@ -490657,7 +490623,6 @@ ${inputPrompt}` : mergePrompt;
|
|
|
490657
490623
|
permissionPromptToolName: options.permissionPromptTool,
|
|
490658
490624
|
maxTurns: options.maxTurns,
|
|
490659
490625
|
model: effectiveModel,
|
|
490660
|
-
sdkUrl,
|
|
490661
490626
|
replayUserMessages: effectiveReplayUserMessages,
|
|
490662
490627
|
agent: agentCli
|
|
490663
490628
|
});
|
|
@@ -490696,7 +490661,7 @@ ${inputPrompt}` : mergePrompt;
|
|
|
490696
490661
|
...toolPermissionContext,
|
|
490697
490662
|
mode: isAgentSwarmsEnabled2() && getTeammateUtils().isPlanModeRequired() ? "plan" : toolPermissionContext.mode
|
|
490698
490663
|
};
|
|
490699
|
-
const fullRemoteControl =
|
|
490664
|
+
const fullRemoteControl = false;
|
|
490700
490665
|
let ccrMirrorEnabled = false;
|
|
490701
490666
|
const initialState = {
|
|
490702
490667
|
settings: getInitialSettings2(),
|
|
@@ -490737,7 +490702,7 @@ ${inputPrompt}` : mergePrompt;
|
|
|
490737
490702
|
remoteConnectionStatus: "connecting",
|
|
490738
490703
|
remoteBackgroundTaskCount: 0,
|
|
490739
490704
|
replBridgeEnabled: fullRemoteControl || ccrMirrorEnabled,
|
|
490740
|
-
replBridgeExplicit:
|
|
490705
|
+
replBridgeExplicit: false,
|
|
490741
490706
|
replBridgeOutboundOnly: ccrMirrorEnabled,
|
|
490742
490707
|
replBridgeConnected: false,
|
|
490743
490708
|
replBridgeSessionActive: false,
|
|
@@ -490747,7 +490712,7 @@ ${inputPrompt}` : mergePrompt;
|
|
|
490747
490712
|
replBridgeEnvironmentId: undefined,
|
|
490748
490713
|
replBridgeSessionId: undefined,
|
|
490749
490714
|
replBridgeError: undefined,
|
|
490750
|
-
replBridgeInitialName:
|
|
490715
|
+
replBridgeInitialName: undefined,
|
|
490751
490716
|
showRemoteCallout: false,
|
|
490752
490717
|
notifications: {
|
|
490753
490718
|
current: null,
|
|
@@ -490876,7 +490841,7 @@ ${inputPrompt}` : mergePrompt;
|
|
|
490876
490841
|
} else if (feature("SSH_REMOTE") && _pendingSSH?.host) {
|
|
490877
490842
|
return await exitWithError(root, "SSH_REMOTE feature not available in this build.", () => gracefulShutdown(1));
|
|
490878
490843
|
}
|
|
490879
|
-
if (options.resume || options.fromPr
|
|
490844
|
+
if (options.resume || options.fromPr) {
|
|
490880
490845
|
await Promise.resolve().then(() => init_caches());
|
|
490881
490846
|
clearSessionCaches();
|
|
490882
490847
|
let messages = null;
|
|
@@ -491010,13 +490975,6 @@ ${inputPrompt}` : mergePrompt;
|
|
|
491010
490975
|
program.addOption(new Option("--parent-session-id <id>", "Parent session ID for analytics correlation").hideHelp());
|
|
491011
490976
|
program.addOption(new Option("--teammate-mode <mode>", 'How to spawn teammates: "tmux", "in-process", or "auto"').choices(["auto", "tmux", "in-process"]).hideHelp());
|
|
491012
490977
|
program.addOption(new Option("--agent-type <type>", "Custom agent type for this teammate").hideHelp());
|
|
491013
|
-
program.addOption(new Option("--sdk-url <url>", "Use remote WebSocket endpoint for SDK I/O streaming (only with -p and stream-json format)").hideHelp());
|
|
491014
|
-
program.addOption(new Option("--teleport [session]", "Resume a teleport session, optionally specify session ID").hideHelp());
|
|
491015
|
-
program.addOption(new Option("--remote [description]", "Create a remote session with the given description").hideHelp());
|
|
491016
|
-
if (feature("BRIDGE_MODE")) {
|
|
491017
|
-
program.addOption(new Option("--remote-control [name]", "Start an interactive session with Remote Control enabled (optionally named)").argParser((value) => value || true).hideHelp());
|
|
491018
|
-
program.addOption(new Option("--rc [name]", "Alias for --remote-control").argParser((value) => value || true).hideHelp());
|
|
491019
|
-
}
|
|
491020
490978
|
if (feature("HARD_FAIL")) {
|
|
491021
490979
|
program.addOption(new Option("--hard-fail", "Crash on logError calls instead of silently logging").hideHelp());
|
|
491022
490980
|
}
|
|
@@ -491426,7 +491384,6 @@ var init_main3 = __esm(() => {
|
|
|
491426
491384
|
init_migrateAutoUpdatesToSettings();
|
|
491427
491385
|
init_migrateBypassPermissionsAcceptedToSettings();
|
|
491428
491386
|
init_migrateEnableAllProjectMcpServersToSettings();
|
|
491429
|
-
init_migrateReplBridgeEnabledToRemoteControlAtStartup();
|
|
491430
491387
|
init_resetAutoModeOptInForDefaultOffer();
|
|
491431
491388
|
init_manager();
|
|
491432
491389
|
init_promptSuggestion();
|