allagents 1.7.2 → 1.8.0
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/README.md +2 -0
- package/dist/index.js +891 -265
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11511,7 +11511,7 @@ function resolveInstallMode(pluginEntry, clientEntry) {
|
|
|
11511
11511
|
return pluginMode;
|
|
11512
11512
|
return clientEntry.install;
|
|
11513
11513
|
}
|
|
11514
|
-
var ManagedModeSchema, RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, InstallModeSchema, ClientEntrySchema, PluginSkillsConfigSchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, McpProxyServerSchema, McpProxyConfigSchema, WorkspaceConfigSchema;
|
|
11514
|
+
var ManagedModeSchema, RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, InstallModeSchema, ClientEntrySchema, PluginSkillsConfigSchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, McpProxyServerSchema, McpProxyConfigSchema, McpServerConfigSchema, WorkspaceConfigSchema;
|
|
11515
11515
|
var init_workspace_config = __esm(() => {
|
|
11516
11516
|
init_zod();
|
|
11517
11517
|
ManagedModeSchema = exports_external.union([
|
|
@@ -11629,6 +11629,21 @@ var init_workspace_config = __esm(() => {
|
|
|
11629
11629
|
clients: exports_external.array(exports_external.string()),
|
|
11630
11630
|
servers: exports_external.record(McpProxyServerSchema).optional()
|
|
11631
11631
|
});
|
|
11632
|
+
McpServerConfigSchema = exports_external.union([
|
|
11633
|
+
exports_external.object({
|
|
11634
|
+
type: exports_external.enum(["http"]).optional(),
|
|
11635
|
+
url: exports_external.string(),
|
|
11636
|
+
headers: exports_external.record(exports_external.string()).optional(),
|
|
11637
|
+
clients: exports_external.array(ClientTypeSchema).optional()
|
|
11638
|
+
}).strict(),
|
|
11639
|
+
exports_external.object({
|
|
11640
|
+
type: exports_external.enum(["stdio"]).optional(),
|
|
11641
|
+
command: exports_external.string(),
|
|
11642
|
+
args: exports_external.array(exports_external.string()).optional(),
|
|
11643
|
+
env: exports_external.record(exports_external.string()).optional(),
|
|
11644
|
+
clients: exports_external.array(ClientTypeSchema).optional()
|
|
11645
|
+
}).strict()
|
|
11646
|
+
]);
|
|
11632
11647
|
WorkspaceConfigSchema = exports_external.object({
|
|
11633
11648
|
version: exports_external.number().optional(),
|
|
11634
11649
|
workspace: WorkspaceSchema.optional(),
|
|
@@ -11638,6 +11653,7 @@ var init_workspace_config = __esm(() => {
|
|
|
11638
11653
|
vscode: VscodeConfigSchema.optional(),
|
|
11639
11654
|
syncMode: SyncModeSchema.optional(),
|
|
11640
11655
|
mcpProxy: McpProxyConfigSchema.optional(),
|
|
11656
|
+
mcpServers: exports_external.record(McpServerConfigSchema).optional(),
|
|
11641
11657
|
disabledSkills: exports_external.array(exports_external.string()).optional(),
|
|
11642
11658
|
enabledSkills: exports_external.array(exports_external.string()).optional()
|
|
11643
11659
|
});
|
|
@@ -29175,7 +29191,11 @@ function readPluginMcpConfig(pluginPath) {
|
|
|
29175
29191
|
return null;
|
|
29176
29192
|
}
|
|
29177
29193
|
}
|
|
29178
|
-
function
|
|
29194
|
+
function stripWorkspaceMcpMeta(config) {
|
|
29195
|
+
const { clients: _clients, ...rest } = config;
|
|
29196
|
+
return rest;
|
|
29197
|
+
}
|
|
29198
|
+
function collectMcpServers(validatedPlugins, workspaceServers, targetClient) {
|
|
29179
29199
|
const servers = new Map;
|
|
29180
29200
|
const warnings = [];
|
|
29181
29201
|
for (const plugin of validatedPlugins) {
|
|
@@ -29190,6 +29210,17 @@ function collectMcpServers(validatedPlugins) {
|
|
|
29190
29210
|
}
|
|
29191
29211
|
}
|
|
29192
29212
|
}
|
|
29213
|
+
if (workspaceServers) {
|
|
29214
|
+
for (const [name, config] of Object.entries(workspaceServers)) {
|
|
29215
|
+
if (targetClient && config.clients && !config.clients.includes(targetClient)) {
|
|
29216
|
+
continue;
|
|
29217
|
+
}
|
|
29218
|
+
if (servers.has(name)) {
|
|
29219
|
+
warnings.push(`MCP server '${name}' from workspace.yaml overrides plugin-provided server`);
|
|
29220
|
+
}
|
|
29221
|
+
servers.set(name, stripWorkspaceMcpMeta(config));
|
|
29222
|
+
}
|
|
29223
|
+
}
|
|
29193
29224
|
return { servers, warnings };
|
|
29194
29225
|
}
|
|
29195
29226
|
function syncVscodeMcpConfig(validatedPlugins, options2) {
|
|
@@ -29929,6 +29960,170 @@ var init_copilot_mcp = __esm(() => {
|
|
|
29929
29960
|
init_constants();
|
|
29930
29961
|
});
|
|
29931
29962
|
|
|
29963
|
+
// src/core/mcp-sync.ts
|
|
29964
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
29965
|
+
import { join as join19 } from "node:path";
|
|
29966
|
+
function buildSyncSpecs(workspacePath) {
|
|
29967
|
+
return [
|
|
29968
|
+
{
|
|
29969
|
+
client: "vscode",
|
|
29970
|
+
scope: "vscode",
|
|
29971
|
+
configPath: join19(workspacePath, ".vscode", "mcp.json"),
|
|
29972
|
+
syncFn: syncVscodeMcpConfig
|
|
29973
|
+
},
|
|
29974
|
+
{
|
|
29975
|
+
client: "claude",
|
|
29976
|
+
scope: "claude",
|
|
29977
|
+
configPath: join19(workspacePath, ".mcp.json"),
|
|
29978
|
+
syncFn: syncClaudeMcpConfig
|
|
29979
|
+
},
|
|
29980
|
+
{
|
|
29981
|
+
client: "codex",
|
|
29982
|
+
scope: "codex",
|
|
29983
|
+
configPath: join19(workspacePath, ".codex", "config.toml"),
|
|
29984
|
+
syncFn: syncCodexProjectMcpConfig
|
|
29985
|
+
},
|
|
29986
|
+
{
|
|
29987
|
+
client: "copilot",
|
|
29988
|
+
scope: "copilot",
|
|
29989
|
+
configPath: join19(workspacePath, ".copilot", "mcp-config.json"),
|
|
29990
|
+
syncFn: syncClaudeMcpConfig
|
|
29991
|
+
}
|
|
29992
|
+
];
|
|
29993
|
+
}
|
|
29994
|
+
function syncMcpServers(workspacePath, validPlugins, config, previousState, syncClients, options2 = {}) {
|
|
29995
|
+
const { dryRun = false } = options2;
|
|
29996
|
+
const warnings = [];
|
|
29997
|
+
const mcpResults = {};
|
|
29998
|
+
const trackedServers = {};
|
|
29999
|
+
const mcpProxyConfig = config.mcpProxy;
|
|
30000
|
+
let proxyMetadataPath;
|
|
30001
|
+
if (mcpProxyConfig) {
|
|
30002
|
+
if (!dryRun) {
|
|
30003
|
+
ensureProxyMetadata();
|
|
30004
|
+
}
|
|
30005
|
+
proxyMetadataPath = getProxyMetadataPath();
|
|
30006
|
+
}
|
|
30007
|
+
let collectWarningsEmitted = false;
|
|
30008
|
+
function getServersForClient(client) {
|
|
30009
|
+
const { servers, warnings: collectWarnings } = collectMcpServers(validPlugins, config.mcpServers, client);
|
|
30010
|
+
if (!collectWarningsEmitted) {
|
|
30011
|
+
warnings.push(...collectWarnings);
|
|
30012
|
+
collectWarningsEmitted = true;
|
|
30013
|
+
}
|
|
30014
|
+
if (mcpProxyConfig && proxyMetadataPath) {
|
|
30015
|
+
return applyMcpProxy(servers, client, mcpProxyConfig, proxyMetadataPath);
|
|
30016
|
+
}
|
|
30017
|
+
return servers;
|
|
30018
|
+
}
|
|
30019
|
+
const specs = buildSyncSpecs(workspacePath);
|
|
30020
|
+
for (const spec of specs) {
|
|
30021
|
+
if (!syncClients.includes(spec.client))
|
|
30022
|
+
continue;
|
|
30023
|
+
const tracked = getPreviouslySyncedMcpServers(previousState, spec.scope);
|
|
30024
|
+
const serverOverrides = getServersForClient(spec.client);
|
|
30025
|
+
const result = spec.syncFn(validPlugins, {
|
|
30026
|
+
dryRun,
|
|
30027
|
+
force: false,
|
|
30028
|
+
configPath: spec.configPath,
|
|
30029
|
+
trackedServers: tracked,
|
|
30030
|
+
serverOverrides
|
|
30031
|
+
});
|
|
30032
|
+
if (result.warnings.length > 0) {
|
|
30033
|
+
warnings.push(...result.warnings);
|
|
30034
|
+
}
|
|
30035
|
+
mcpResults[spec.scope] = result;
|
|
30036
|
+
trackedServers[spec.scope] = result.trackedServers;
|
|
30037
|
+
}
|
|
30038
|
+
const anyServers = collectMcpServers(validPlugins, config.mcpServers).servers;
|
|
30039
|
+
if (anyServers.size > 0) {
|
|
30040
|
+
for (const client of syncClients) {
|
|
30041
|
+
if (!PROJECT_MCP_CLIENTS.has(client)) {
|
|
30042
|
+
warnings.push(`MCP servers not synced for ${client} (not supported at project scope)`);
|
|
30043
|
+
}
|
|
30044
|
+
}
|
|
30045
|
+
}
|
|
30046
|
+
return { mcpResults, warnings, trackedServers };
|
|
30047
|
+
}
|
|
30048
|
+
async function syncMcpOnly(workspacePath = process.cwd(), options2 = {}) {
|
|
30049
|
+
const { offline = false, dryRun = false } = options2;
|
|
30050
|
+
await migrateWorkspaceSkillsV1toV2(workspacePath);
|
|
30051
|
+
const configPath = join19(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
30052
|
+
if (!existsSync17(configPath)) {
|
|
30053
|
+
return {
|
|
30054
|
+
success: false,
|
|
30055
|
+
mcpResults: {},
|
|
30056
|
+
warnings: [],
|
|
30057
|
+
error: `${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
|
|
30058
|
+
Run 'allagents workspace init' to create a new workspace`
|
|
30059
|
+
};
|
|
30060
|
+
}
|
|
30061
|
+
let config;
|
|
30062
|
+
try {
|
|
30063
|
+
config = await parseWorkspaceConfig(configPath);
|
|
30064
|
+
} catch (error) {
|
|
30065
|
+
return {
|
|
30066
|
+
success: false,
|
|
30067
|
+
mcpResults: {},
|
|
30068
|
+
warnings: [],
|
|
30069
|
+
error: error instanceof Error ? error.message : String(error)
|
|
30070
|
+
};
|
|
30071
|
+
}
|
|
30072
|
+
const warnings = [];
|
|
30073
|
+
const { plans, warnings: planWarnings } = buildPluginSyncPlans(config.plugins, config.clients, "project");
|
|
30074
|
+
warnings.push(...planWarnings);
|
|
30075
|
+
const filteredPlans = plans.filter((plan) => plan.clients.length > 0 || plan.nativeClients.length > 0);
|
|
30076
|
+
const syncClients = collectSyncClients(config.clients, filteredPlans);
|
|
30077
|
+
if (!offline) {
|
|
30078
|
+
const marketplaceResults = await ensureMarketplacesRegistered(filteredPlans.map((plan) => plan.source));
|
|
30079
|
+
await seedFetchCacheFromMarketplaces(marketplaceResults);
|
|
30080
|
+
}
|
|
30081
|
+
const validatedPlugins = await validateAllPlugins(filteredPlans, workspacePath, offline);
|
|
30082
|
+
const validPlugins = validatedPlugins.filter((v) => v.success);
|
|
30083
|
+
warnings.push(...validatedPlugins.filter((v) => !v.success).map((v) => `${v.plugin}: ${v.error} (skipped)`));
|
|
30084
|
+
const previousState = await loadSyncState(workspacePath);
|
|
30085
|
+
const syncResult = syncMcpServers(workspacePath, validPlugins, config, previousState, syncClients, { dryRun });
|
|
30086
|
+
warnings.push(...syncResult.warnings);
|
|
30087
|
+
if (!dryRun) {
|
|
30088
|
+
const hasMcpChanges = Object.values(syncResult.mcpResults).some((r) => r && (r.added > 0 || r.overwritten > 0 || r.removed > 0));
|
|
30089
|
+
if (hasMcpChanges) {
|
|
30090
|
+
await saveSyncState(workspacePath, {
|
|
30091
|
+
files: previousState?.files ?? {},
|
|
30092
|
+
mcpServers: syncResult.trackedServers,
|
|
30093
|
+
...previousState?.nativePlugins && { nativePlugins: previousState.nativePlugins },
|
|
30094
|
+
...previousState?.vscodeWorkspaceHash && { vscodeWorkspaceHash: previousState.vscodeWorkspaceHash },
|
|
30095
|
+
...previousState?.vscodeWorkspaceRepos && { vscodeWorkspaceRepos: previousState.vscodeWorkspaceRepos },
|
|
30096
|
+
...previousState?.skillsIndex && { skillsIndex: previousState.skillsIndex }
|
|
30097
|
+
});
|
|
30098
|
+
}
|
|
30099
|
+
}
|
|
30100
|
+
return {
|
|
30101
|
+
success: true,
|
|
30102
|
+
mcpResults: syncResult.mcpResults,
|
|
30103
|
+
warnings
|
|
30104
|
+
};
|
|
30105
|
+
}
|
|
30106
|
+
var PROJECT_MCP_CLIENTS;
|
|
30107
|
+
var init_mcp_sync = __esm(() => {
|
|
30108
|
+
init_constants();
|
|
30109
|
+
init_sync();
|
|
30110
|
+
init_vscode_mcp();
|
|
30111
|
+
init_claude_mcp();
|
|
30112
|
+
init_codex_mcp();
|
|
30113
|
+
init_mcp_proxy();
|
|
30114
|
+
init_sync_state2();
|
|
30115
|
+
init_marketplace();
|
|
30116
|
+
init_workspace_parser();
|
|
30117
|
+
init_workspace_modify();
|
|
30118
|
+
PROJECT_MCP_CLIENTS = new Set([
|
|
30119
|
+
"claude",
|
|
30120
|
+
"codex",
|
|
30121
|
+
"vscode",
|
|
30122
|
+
"copilot",
|
|
30123
|
+
"universal"
|
|
30124
|
+
]);
|
|
30125
|
+
});
|
|
30126
|
+
|
|
29932
30127
|
// src/core/native/claude.ts
|
|
29933
30128
|
class ClaudeNativeClient {
|
|
29934
30129
|
async isAvailable() {
|
|
@@ -30221,7 +30416,7 @@ function padStart2(str3, len) {
|
|
|
30221
30416
|
}
|
|
30222
30417
|
|
|
30223
30418
|
// src/core/managed-repos.ts
|
|
30224
|
-
import { existsSync as
|
|
30419
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
30225
30420
|
import { mkdir as mkdir8 } from "node:fs/promises";
|
|
30226
30421
|
import { dirname as dirname11, resolve as resolve10 } from "node:path";
|
|
30227
30422
|
function expandHome(p) {
|
|
@@ -30305,7 +30500,7 @@ async function processManagedRepos(repositories, workspacePath, options2 = {}) {
|
|
|
30305
30500
|
}
|
|
30306
30501
|
const expandedPath = expandHome(repo.path);
|
|
30307
30502
|
const absolutePath = resolve10(workspacePath, expandedPath);
|
|
30308
|
-
if (!
|
|
30503
|
+
if (!existsSync18(absolutePath)) {
|
|
30309
30504
|
if (!shouldClone(repo.managed)) {
|
|
30310
30505
|
results.push({ path: repo.path, repo: repo.repo, action: "skipped" });
|
|
30311
30506
|
continue;
|
|
@@ -30356,9 +30551,9 @@ var init_managed_repos = __esm(() => {
|
|
|
30356
30551
|
});
|
|
30357
30552
|
|
|
30358
30553
|
// src/core/sync.ts
|
|
30359
|
-
import { existsSync as
|
|
30554
|
+
import { existsSync as existsSync19, readFileSync as readFileSync4, writeFileSync as writeFileSync6, lstatSync as lstatSync2 } from "node:fs";
|
|
30360
30555
|
import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
|
|
30361
|
-
import { join as
|
|
30556
|
+
import { join as join20, resolve as resolve11, dirname as dirname12, relative as relative5 } from "node:path";
|
|
30362
30557
|
function deduplicateClientsByPath(clients, clientMappings = CLIENT_MAPPINGS) {
|
|
30363
30558
|
const pathToClients = new Map;
|
|
30364
30559
|
for (const client of clients) {
|
|
@@ -30477,7 +30672,7 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
|
|
|
30477
30672
|
const previousFiles = getPreviouslySyncedFiles(state, client);
|
|
30478
30673
|
const purgedPaths = [];
|
|
30479
30674
|
for (const filePath of previousFiles) {
|
|
30480
|
-
const fullPath =
|
|
30675
|
+
const fullPath = join20(workspacePath, filePath);
|
|
30481
30676
|
const cleanPath = fullPath.replace(/\/$/, "");
|
|
30482
30677
|
let stats;
|
|
30483
30678
|
try {
|
|
@@ -30506,8 +30701,8 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
|
|
|
30506
30701
|
async function cleanupEmptyParents(workspacePath, filePath) {
|
|
30507
30702
|
let parentPath = dirname12(filePath);
|
|
30508
30703
|
while (parentPath && parentPath !== "." && parentPath !== "/") {
|
|
30509
|
-
const fullParentPath =
|
|
30510
|
-
if (!
|
|
30704
|
+
const fullParentPath = join20(workspacePath, parentPath);
|
|
30705
|
+
if (!existsSync19(fullParentPath)) {
|
|
30511
30706
|
parentPath = dirname12(parentPath);
|
|
30512
30707
|
continue;
|
|
30513
30708
|
}
|
|
@@ -30592,8 +30787,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
|
|
|
30592
30787
|
errors2.push(`Cannot resolve file '${file}' - no workspace.source configured`);
|
|
30593
30788
|
continue;
|
|
30594
30789
|
}
|
|
30595
|
-
const fullPath =
|
|
30596
|
-
if (!
|
|
30790
|
+
const fullPath = join20(defaultSourcePath, file);
|
|
30791
|
+
if (!existsSync19(fullPath)) {
|
|
30597
30792
|
errors2.push(`File source not found: ${fullPath}`);
|
|
30598
30793
|
}
|
|
30599
30794
|
continue;
|
|
@@ -30611,8 +30806,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
|
|
|
30611
30806
|
errors2.push(`GitHub cache not found for ${cacheKey}`);
|
|
30612
30807
|
continue;
|
|
30613
30808
|
}
|
|
30614
|
-
const fullPath =
|
|
30615
|
-
if (!
|
|
30809
|
+
const fullPath = join20(cachePath, parsed.filePath);
|
|
30810
|
+
if (!existsSync19(fullPath)) {
|
|
30616
30811
|
errors2.push(`Path not found in repository: ${cacheKey}/${parsed.filePath}`);
|
|
30617
30812
|
}
|
|
30618
30813
|
} else {
|
|
@@ -30622,11 +30817,11 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
|
|
|
30622
30817
|
} else if (file.source.startsWith("../")) {
|
|
30623
30818
|
fullPath = resolve11(file.source);
|
|
30624
30819
|
} else if (defaultSourcePath) {
|
|
30625
|
-
fullPath =
|
|
30820
|
+
fullPath = join20(defaultSourcePath, file.source);
|
|
30626
30821
|
} else {
|
|
30627
30822
|
fullPath = resolve11(file.source);
|
|
30628
30823
|
}
|
|
30629
|
-
if (!
|
|
30824
|
+
if (!existsSync19(fullPath)) {
|
|
30630
30825
|
errors2.push(`File source not found: ${fullPath}`);
|
|
30631
30826
|
}
|
|
30632
30827
|
}
|
|
@@ -30635,8 +30830,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
|
|
|
30635
30830
|
errors2.push(`Cannot resolve file '${file.dest}' - no workspace.source configured and no explicit source provided`);
|
|
30636
30831
|
continue;
|
|
30637
30832
|
}
|
|
30638
|
-
const fullPath =
|
|
30639
|
-
if (!
|
|
30833
|
+
const fullPath = join20(defaultSourcePath, file.dest ?? "");
|
|
30834
|
+
if (!existsSync19(fullPath)) {
|
|
30640
30835
|
errors2.push(`File source not found: ${fullPath}`);
|
|
30641
30836
|
}
|
|
30642
30837
|
}
|
|
@@ -30782,7 +30977,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
|
|
|
30782
30977
|
...fetchResult.error && { error: fetchResult.error }
|
|
30783
30978
|
};
|
|
30784
30979
|
}
|
|
30785
|
-
const resolvedPath2 = parsed?.subpath ?
|
|
30980
|
+
const resolvedPath2 = parsed?.subpath ? join20(fetchResult.cachePath, parsed.subpath) : fetchResult.cachePath;
|
|
30786
30981
|
return {
|
|
30787
30982
|
plugin: pluginSource,
|
|
30788
30983
|
resolved: resolvedPath2,
|
|
@@ -30792,7 +30987,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
|
|
|
30792
30987
|
};
|
|
30793
30988
|
}
|
|
30794
30989
|
const resolvedPath = resolve11(workspacePath, pluginSource);
|
|
30795
|
-
if (!
|
|
30990
|
+
if (!existsSync19(resolvedPath)) {
|
|
30796
30991
|
return {
|
|
30797
30992
|
plugin: pluginSource,
|
|
30798
30993
|
resolved: resolvedPath,
|
|
@@ -30953,10 +31148,10 @@ function buildPluginSkillNameMaps(allSkills) {
|
|
|
30953
31148
|
return pluginMaps;
|
|
30954
31149
|
}
|
|
30955
31150
|
function generateVscodeWorkspaceFile(workspacePath, config) {
|
|
30956
|
-
const configDir =
|
|
30957
|
-
const templatePath =
|
|
31151
|
+
const configDir = join20(workspacePath, CONFIG_DIR);
|
|
31152
|
+
const templatePath = join20(configDir, VSCODE_TEMPLATE_FILE);
|
|
30958
31153
|
let template;
|
|
30959
|
-
if (
|
|
31154
|
+
if (existsSync19(templatePath)) {
|
|
30960
31155
|
try {
|
|
30961
31156
|
template = import_json53.default.parse(readFileSync4(templatePath, "utf-8"));
|
|
30962
31157
|
} catch (error) {
|
|
@@ -31103,7 +31298,7 @@ async function syncVscodeWorkspaceFile(workspacePath, config, configPath, previo
|
|
|
31103
31298
|
let updatedConfig = config;
|
|
31104
31299
|
if (previousState?.vscodeWorkspaceHash && previousState?.vscodeWorkspaceRepos) {
|
|
31105
31300
|
const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
|
|
31106
|
-
if (
|
|
31301
|
+
if (existsSync19(outputPath)) {
|
|
31107
31302
|
const existingContent = readFileSync4(outputPath, "utf-8");
|
|
31108
31303
|
const currentHash = computeWorkspaceHash(existingContent);
|
|
31109
31304
|
if (currentHash !== previousState.vscodeWorkspaceHash) {
|
|
@@ -31168,9 +31363,9 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
|
31168
31363
|
await migrateWorkspaceSkillsV1toV2(workspacePath);
|
|
31169
31364
|
const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false, skipManaged = false } = options2;
|
|
31170
31365
|
const sw = new Stopwatch;
|
|
31171
|
-
const configDir =
|
|
31172
|
-
const configPath =
|
|
31173
|
-
if (!
|
|
31366
|
+
const configDir = join20(workspacePath, CONFIG_DIR);
|
|
31367
|
+
const configPath = join20(configDir, WORKSPACE_CONFIG_FILE);
|
|
31368
|
+
if (!existsSync19(configPath)) {
|
|
31174
31369
|
return failedSyncResult(`${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
|
|
31175
31370
|
Run 'allagents workspace init <path>' to create a new workspace`);
|
|
31176
31371
|
}
|
|
@@ -31263,8 +31458,8 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
31263
31458
|
const filesToCopy = [...config.workspace.files];
|
|
31264
31459
|
if (hasRepositories && sourcePath) {
|
|
31265
31460
|
for (const agentFile of AGENT_FILES) {
|
|
31266
|
-
const agentPath =
|
|
31267
|
-
if (
|
|
31461
|
+
const agentPath = join20(sourcePath, agentFile);
|
|
31462
|
+
if (existsSync19(agentPath) && !filesToCopy.includes(agentFile)) {
|
|
31268
31463
|
filesToCopy.push(agentFile);
|
|
31269
31464
|
}
|
|
31270
31465
|
}
|
|
@@ -31299,10 +31494,10 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
31299
31494
|
}
|
|
31300
31495
|
workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache, repositories: config.repositories, skillsIndexRefs });
|
|
31301
31496
|
if (hasRepositories && !dryRun && syncClients.includes("claude") && sourcePath) {
|
|
31302
|
-
const claudePath =
|
|
31303
|
-
const agentsPath =
|
|
31304
|
-
const claudeExistsInSource =
|
|
31305
|
-
if (!claudeExistsInSource &&
|
|
31497
|
+
const claudePath = join20(workspacePath, "CLAUDE.md");
|
|
31498
|
+
const agentsPath = join20(workspacePath, "AGENTS.md");
|
|
31499
|
+
const claudeExistsInSource = existsSync19(join20(sourcePath, "CLAUDE.md"));
|
|
31500
|
+
if (!claudeExistsInSource && existsSync19(agentsPath) && !existsSync19(claudePath)) {
|
|
31306
31501
|
await copyFile(agentsPath, claudePath);
|
|
31307
31502
|
}
|
|
31308
31503
|
}
|
|
@@ -31319,103 +31514,11 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
31319
31514
|
vscodeState = { hash: result.hash, repos: result.repos };
|
|
31320
31515
|
}
|
|
31321
31516
|
}
|
|
31322
|
-
const mcpProxyConfig = config.mcpProxy;
|
|
31323
|
-
let proxyMetadataPath;
|
|
31324
|
-
let proxyBaseServers;
|
|
31325
|
-
if (mcpProxyConfig) {
|
|
31326
|
-
if (!dryRun) {
|
|
31327
|
-
ensureProxyMetadata();
|
|
31328
|
-
}
|
|
31329
|
-
proxyMetadataPath = getProxyMetadataPath();
|
|
31330
|
-
const { servers, warnings: proxyWarnings } = collectMcpServers(validPlugins);
|
|
31331
|
-
if (proxyWarnings.length > 0) {
|
|
31332
|
-
warnings.push(...proxyWarnings);
|
|
31333
|
-
}
|
|
31334
|
-
if (servers.size > 0) {
|
|
31335
|
-
proxyBaseServers = servers;
|
|
31336
|
-
}
|
|
31337
|
-
}
|
|
31338
|
-
function getServersForClient(client) {
|
|
31339
|
-
if (!mcpProxyConfig || !proxyMetadataPath || !proxyBaseServers)
|
|
31340
|
-
return;
|
|
31341
|
-
return applyMcpProxy(proxyBaseServers, client, mcpProxyConfig, proxyMetadataPath);
|
|
31342
|
-
}
|
|
31343
31517
|
sw.start("mcp-sync");
|
|
31344
|
-
const
|
|
31345
|
-
|
|
31346
|
-
|
|
31347
|
-
const projectMcpPath = join19(workspacePath, ".vscode", "mcp.json");
|
|
31348
|
-
const vscodeMcpOverrides = getServersForClient("vscode");
|
|
31349
|
-
const vscodeMcp = syncVscodeMcpConfig(validPlugins, {
|
|
31350
|
-
dryRun,
|
|
31351
|
-
force: false,
|
|
31352
|
-
configPath: projectMcpPath,
|
|
31353
|
-
trackedServers: trackedMcpServers,
|
|
31354
|
-
...vscodeMcpOverrides && { serverOverrides: vscodeMcpOverrides }
|
|
31355
|
-
});
|
|
31356
|
-
if (vscodeMcp.warnings.length > 0) {
|
|
31357
|
-
warnings.push(...vscodeMcp.warnings);
|
|
31358
|
-
}
|
|
31359
|
-
mcpResults.vscode = vscodeMcp;
|
|
31360
|
-
}
|
|
31361
|
-
if (syncClients.includes("claude")) {
|
|
31362
|
-
const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "claude");
|
|
31363
|
-
const projectMcpJsonPath = join19(workspacePath, ".mcp.json");
|
|
31364
|
-
const claudeMcpOverrides = getServersForClient("claude");
|
|
31365
|
-
const claudeMcp = syncClaudeMcpConfig(validPlugins, {
|
|
31366
|
-
dryRun,
|
|
31367
|
-
force: false,
|
|
31368
|
-
configPath: projectMcpJsonPath,
|
|
31369
|
-
trackedServers: trackedMcpServers,
|
|
31370
|
-
...claudeMcpOverrides && { serverOverrides: claudeMcpOverrides }
|
|
31371
|
-
});
|
|
31372
|
-
if (claudeMcp.warnings.length > 0) {
|
|
31373
|
-
warnings.push(...claudeMcp.warnings);
|
|
31374
|
-
}
|
|
31375
|
-
mcpResults.claude = claudeMcp;
|
|
31376
|
-
}
|
|
31377
|
-
if (syncClients.includes("codex")) {
|
|
31378
|
-
const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "codex");
|
|
31379
|
-
const projectCodexConfigPath = join19(workspacePath, ".codex", "config.toml");
|
|
31380
|
-
const codexMcpOverrides = getServersForClient("codex");
|
|
31381
|
-
const codexMcp = syncCodexProjectMcpConfig(validPlugins, {
|
|
31382
|
-
dryRun,
|
|
31383
|
-
force: false,
|
|
31384
|
-
configPath: projectCodexConfigPath,
|
|
31385
|
-
trackedServers: trackedMcpServers,
|
|
31386
|
-
...codexMcpOverrides && { serverOverrides: codexMcpOverrides }
|
|
31387
|
-
});
|
|
31388
|
-
if (codexMcp.warnings.length > 0) {
|
|
31389
|
-
warnings.push(...codexMcp.warnings);
|
|
31390
|
-
}
|
|
31391
|
-
mcpResults.codex = codexMcp;
|
|
31392
|
-
}
|
|
31393
|
-
if (syncClients.includes("copilot")) {
|
|
31394
|
-
const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "copilot");
|
|
31395
|
-
const projectCopilotMcpPath = join19(workspacePath, ".copilot", "mcp-config.json");
|
|
31396
|
-
const copilotMcpOverrides = getServersForClient("copilot");
|
|
31397
|
-
const copilotMcp = syncClaudeMcpConfig(validPlugins, {
|
|
31398
|
-
dryRun,
|
|
31399
|
-
force: false,
|
|
31400
|
-
configPath: projectCopilotMcpPath,
|
|
31401
|
-
trackedServers: trackedMcpServers,
|
|
31402
|
-
...copilotMcpOverrides && { serverOverrides: copilotMcpOverrides }
|
|
31403
|
-
});
|
|
31404
|
-
if (copilotMcp.warnings.length > 0) {
|
|
31405
|
-
warnings.push(...copilotMcp.warnings);
|
|
31406
|
-
}
|
|
31407
|
-
mcpResults.copilot = copilotMcp;
|
|
31408
|
-
}
|
|
31518
|
+
const mcpSyncResult = syncMcpServers(workspacePath, validPlugins, config, previousState, syncClients, { dryRun });
|
|
31519
|
+
const mcpResults = { ...mcpSyncResult.mcpResults };
|
|
31520
|
+
warnings.push(...mcpSyncResult.warnings);
|
|
31409
31521
|
sw.stop("mcp-sync");
|
|
31410
|
-
const PROJECT_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
|
|
31411
|
-
const allMcpServers = proxyBaseServers ?? collectMcpServers(validPlugins).servers;
|
|
31412
|
-
if (allMcpServers.size > 0) {
|
|
31413
|
-
for (const client of syncClients) {
|
|
31414
|
-
if (!PROJECT_MCP_CLIENTS.has(client)) {
|
|
31415
|
-
warnings.push(`MCP servers not synced for ${client} (not supported at project scope)`);
|
|
31416
|
-
}
|
|
31417
|
-
}
|
|
31418
|
-
}
|
|
31419
31522
|
const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, workspaceFileResults);
|
|
31420
31523
|
const hasFailures = pluginResults.some((r) => !r.success) || totalFailed > 0;
|
|
31421
31524
|
const availableSkillNames = await collectAvailableSkillNames(validPlugins);
|
|
@@ -31466,7 +31569,7 @@ async function seedFetchCacheFromMarketplaces(results) {
|
|
|
31466
31569
|
}
|
|
31467
31570
|
function readGitBranch(repoPath) {
|
|
31468
31571
|
try {
|
|
31469
|
-
const head = readFileSync4(
|
|
31572
|
+
const head = readFileSync4(join20(repoPath, ".git", "HEAD"), "utf-8").trim();
|
|
31470
31573
|
const prefix = "ref: refs/heads/";
|
|
31471
31574
|
return head.startsWith(prefix) ? head.slice(prefix.length) : null;
|
|
31472
31575
|
} catch {
|
|
@@ -31526,25 +31629,25 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
31526
31629
|
})), `${validPlugins.length} plugin(s)`);
|
|
31527
31630
|
const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, []);
|
|
31528
31631
|
const userMcpProxyConfig = config.mcpProxy;
|
|
31632
|
+
const userWorkspaceMcpServers = config.mcpServers;
|
|
31529
31633
|
let userProxyMetadataPath;
|
|
31530
|
-
let userProxyBaseServers;
|
|
31531
31634
|
if (userMcpProxyConfig) {
|
|
31532
31635
|
if (!dryRun) {
|
|
31533
31636
|
ensureProxyMetadata();
|
|
31534
31637
|
}
|
|
31535
31638
|
userProxyMetadataPath = getProxyMetadataPath();
|
|
31536
|
-
const { servers, warnings: proxyWarnings } = collectMcpServers(validPlugins);
|
|
31537
|
-
if (proxyWarnings.length > 0) {
|
|
31538
|
-
warnings.push(...proxyWarnings);
|
|
31539
|
-
}
|
|
31540
|
-
if (servers.size > 0) {
|
|
31541
|
-
userProxyBaseServers = servers;
|
|
31542
|
-
}
|
|
31543
31639
|
}
|
|
31640
|
+
let userCollectWarningsEmitted = false;
|
|
31544
31641
|
function getUserServersForClient(client) {
|
|
31545
|
-
|
|
31546
|
-
|
|
31547
|
-
|
|
31642
|
+
const { servers, warnings: collectWarnings } = collectMcpServers(validPlugins, userWorkspaceMcpServers, client);
|
|
31643
|
+
if (!userCollectWarningsEmitted) {
|
|
31644
|
+
warnings.push(...collectWarnings);
|
|
31645
|
+
userCollectWarningsEmitted = true;
|
|
31646
|
+
}
|
|
31647
|
+
if (userMcpProxyConfig && userProxyMetadataPath) {
|
|
31648
|
+
return applyMcpProxy(servers, client, userMcpProxyConfig, userProxyMetadataPath);
|
|
31649
|
+
}
|
|
31650
|
+
return servers;
|
|
31548
31651
|
}
|
|
31549
31652
|
sw.start("mcp-sync");
|
|
31550
31653
|
const mcpResults = {};
|
|
@@ -31555,7 +31658,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
31555
31658
|
dryRun,
|
|
31556
31659
|
force,
|
|
31557
31660
|
trackedServers: trackedMcpServers,
|
|
31558
|
-
|
|
31661
|
+
serverOverrides: vscodeMcpOverrides
|
|
31559
31662
|
});
|
|
31560
31663
|
if (vscodeMcp.warnings.length > 0) {
|
|
31561
31664
|
warnings.push(...vscodeMcp.warnings);
|
|
@@ -31606,7 +31709,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
31606
31709
|
}
|
|
31607
31710
|
sw.stop("mcp-sync");
|
|
31608
31711
|
const USER_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
|
|
31609
|
-
const allUserMcpServers =
|
|
31712
|
+
const allUserMcpServers = collectMcpServers(validPlugins, userWorkspaceMcpServers).servers;
|
|
31610
31713
|
if (allUserMcpServers.size > 0) {
|
|
31611
31714
|
for (const client of syncClients) {
|
|
31612
31715
|
if (!USER_MCP_CLIENTS.has(client)) {
|
|
@@ -31666,17 +31769,18 @@ var init_sync = __esm(() => {
|
|
|
31666
31769
|
init_codex_mcp();
|
|
31667
31770
|
init_claude_mcp();
|
|
31668
31771
|
init_copilot_mcp();
|
|
31772
|
+
init_mcp_sync();
|
|
31669
31773
|
init_native();
|
|
31670
31774
|
init_managed_repos();
|
|
31671
31775
|
import_json53 = __toESM(require_lib(), 1);
|
|
31672
31776
|
});
|
|
31673
31777
|
|
|
31674
31778
|
// src/core/github-fetch.ts
|
|
31675
|
-
import { existsSync as
|
|
31676
|
-
import { join as
|
|
31779
|
+
import { existsSync as existsSync20, readFileSync as readFileSync5 } from "node:fs";
|
|
31780
|
+
import { join as join21 } from "node:path";
|
|
31677
31781
|
function readFileFromClone(tempDir, filePath) {
|
|
31678
|
-
const fullPath =
|
|
31679
|
-
if (
|
|
31782
|
+
const fullPath = join21(tempDir, filePath);
|
|
31783
|
+
if (existsSync20(fullPath)) {
|
|
31680
31784
|
return readFileSync5(fullPath, "utf-8");
|
|
31681
31785
|
}
|
|
31682
31786
|
return null;
|
|
@@ -31776,14 +31880,14 @@ var init_github_fetch = __esm(() => {
|
|
|
31776
31880
|
|
|
31777
31881
|
// src/core/workspace.ts
|
|
31778
31882
|
import { cp as cp2, mkdir as mkdir9, readFile as readFile12, writeFile as writeFile8, copyFile as copyFile2, unlink as unlink3 } from "node:fs/promises";
|
|
31779
|
-
import { existsSync as
|
|
31780
|
-
import { join as
|
|
31883
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
31884
|
+
import { join as join22, resolve as resolve12, dirname as dirname13, relative as relative6, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
|
|
31781
31885
|
import { fileURLToPath } from "node:url";
|
|
31782
31886
|
async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
31783
31887
|
const absoluteTarget = resolve12(targetPath);
|
|
31784
|
-
const configDir =
|
|
31785
|
-
const configPath =
|
|
31786
|
-
if (
|
|
31888
|
+
const configDir = join22(absoluteTarget, CONFIG_DIR);
|
|
31889
|
+
const configPath = join22(configDir, WORKSPACE_CONFIG_FILE);
|
|
31890
|
+
if (existsSync21(configPath)) {
|
|
31787
31891
|
if (options2.force) {
|
|
31788
31892
|
await unlink3(configPath);
|
|
31789
31893
|
} else {
|
|
@@ -31794,7 +31898,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
31794
31898
|
const currentFilePath = fileURLToPath(import.meta.url);
|
|
31795
31899
|
const currentFileDir = dirname13(currentFilePath);
|
|
31796
31900
|
const isProduction = currentFilePath.includes(`${sep2}dist${sep2}`);
|
|
31797
|
-
const defaultTemplatePath = isProduction ?
|
|
31901
|
+
const defaultTemplatePath = isProduction ? join22(currentFileDir, "templates", "default") : join22(currentFileDir, "..", "templates", "default");
|
|
31798
31902
|
let githubTempDir;
|
|
31799
31903
|
let parsedFromUrl;
|
|
31800
31904
|
let githubBasePath = "";
|
|
@@ -31834,19 +31938,19 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
31834
31938
|
console.log(`✓ Using workspace.yaml from: ${options2.from}`);
|
|
31835
31939
|
} else {
|
|
31836
31940
|
const fromPath = resolve12(options2.from);
|
|
31837
|
-
if (!
|
|
31941
|
+
if (!existsSync21(fromPath)) {
|
|
31838
31942
|
throw new Error(`Template not found: ${fromPath}`);
|
|
31839
31943
|
}
|
|
31840
31944
|
const { stat: stat2 } = await import("node:fs/promises");
|
|
31841
31945
|
const fromStat = await stat2(fromPath);
|
|
31842
31946
|
let sourceYamlPath;
|
|
31843
31947
|
if (fromStat.isDirectory()) {
|
|
31844
|
-
const nestedPath =
|
|
31845
|
-
const rootPath =
|
|
31846
|
-
if (
|
|
31948
|
+
const nestedPath = join22(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
31949
|
+
const rootPath = join22(fromPath, WORKSPACE_CONFIG_FILE);
|
|
31950
|
+
if (existsSync21(nestedPath)) {
|
|
31847
31951
|
sourceYamlPath = nestedPath;
|
|
31848
31952
|
sourceDir = fromPath;
|
|
31849
|
-
} else if (
|
|
31953
|
+
} else if (existsSync21(rootPath)) {
|
|
31850
31954
|
sourceYamlPath = rootPath;
|
|
31851
31955
|
sourceDir = fromPath;
|
|
31852
31956
|
} else {
|
|
@@ -31877,8 +31981,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
31877
31981
|
console.log(`✓ Using workspace.yaml from: ${sourceYamlPath}`);
|
|
31878
31982
|
}
|
|
31879
31983
|
} else {
|
|
31880
|
-
const defaultYamlPath =
|
|
31881
|
-
if (!
|
|
31984
|
+
const defaultYamlPath = join22(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
31985
|
+
if (!existsSync21(defaultYamlPath)) {
|
|
31882
31986
|
throw new Error(`Default template not found at: ${defaultTemplatePath}`);
|
|
31883
31987
|
}
|
|
31884
31988
|
workspaceYamlContent = await readFile12(defaultYamlPath, "utf-8");
|
|
@@ -31894,8 +31998,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
31894
31998
|
const clientNames = getClientTypes(clients);
|
|
31895
31999
|
const VSCODE_TEMPLATE_FILE2 = "template.code-workspace";
|
|
31896
32000
|
if (clientNames.includes("vscode") && options2.from) {
|
|
31897
|
-
const targetTemplatePath =
|
|
31898
|
-
if (!
|
|
32001
|
+
const targetTemplatePath = join22(configDir, VSCODE_TEMPLATE_FILE2);
|
|
32002
|
+
if (!existsSync21(targetTemplatePath)) {
|
|
31899
32003
|
if (isGitHubUrl(options2.from) && githubTempDir) {
|
|
31900
32004
|
if (parsedFromUrl) {
|
|
31901
32005
|
const templatePath = githubBasePath ? `${githubBasePath}/${CONFIG_DIR}/${VSCODE_TEMPLATE_FILE2}` : `${CONFIG_DIR}/${VSCODE_TEMPLATE_FILE2}`;
|
|
@@ -31905,8 +32009,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
31905
32009
|
}
|
|
31906
32010
|
}
|
|
31907
32011
|
} else if (sourceDir) {
|
|
31908
|
-
const sourceTemplatePath =
|
|
31909
|
-
if (
|
|
32012
|
+
const sourceTemplatePath = join22(sourceDir, CONFIG_DIR, VSCODE_TEMPLATE_FILE2);
|
|
32013
|
+
if (existsSync21(sourceTemplatePath)) {
|
|
31910
32014
|
await copyFile2(sourceTemplatePath, targetTemplatePath);
|
|
31911
32015
|
}
|
|
31912
32016
|
}
|
|
@@ -31919,8 +32023,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
31919
32023
|
if (options2.from && isGitHubUrl(options2.from) && githubTempDir) {
|
|
31920
32024
|
if (parsedFromUrl) {
|
|
31921
32025
|
for (const agentFile of AGENT_FILES) {
|
|
31922
|
-
const targetFilePath =
|
|
31923
|
-
if (
|
|
32026
|
+
const targetFilePath = join22(absoluteTarget, agentFile);
|
|
32027
|
+
if (existsSync21(targetFilePath)) {
|
|
31924
32028
|
copiedAgentFiles.push(agentFile);
|
|
31925
32029
|
continue;
|
|
31926
32030
|
}
|
|
@@ -31935,13 +32039,13 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
31935
32039
|
} else {
|
|
31936
32040
|
const effectiveSourceDir = sourceDir ?? defaultTemplatePath;
|
|
31937
32041
|
for (const agentFile of AGENT_FILES) {
|
|
31938
|
-
const targetFilePath =
|
|
31939
|
-
if (
|
|
32042
|
+
const targetFilePath = join22(absoluteTarget, agentFile);
|
|
32043
|
+
if (existsSync21(targetFilePath)) {
|
|
31940
32044
|
copiedAgentFiles.push(agentFile);
|
|
31941
32045
|
continue;
|
|
31942
32046
|
}
|
|
31943
|
-
const sourcePath =
|
|
31944
|
-
if (
|
|
32047
|
+
const sourcePath = join22(effectiveSourceDir, agentFile);
|
|
32048
|
+
if (existsSync21(sourcePath)) {
|
|
31945
32049
|
const content = await readFile12(sourcePath, "utf-8");
|
|
31946
32050
|
await writeFile8(targetFilePath, content, "utf-8");
|
|
31947
32051
|
copiedAgentFiles.push(agentFile);
|
|
@@ -31949,16 +32053,16 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
31949
32053
|
}
|
|
31950
32054
|
}
|
|
31951
32055
|
if (copiedAgentFiles.length === 0) {
|
|
31952
|
-
await ensureWorkspaceRules(
|
|
32056
|
+
await ensureWorkspaceRules(join22(absoluteTarget, "AGENTS.md"), repositories);
|
|
31953
32057
|
copiedAgentFiles.push("AGENTS.md");
|
|
31954
32058
|
} else {
|
|
31955
32059
|
for (const agentFile of copiedAgentFiles) {
|
|
31956
|
-
await ensureWorkspaceRules(
|
|
32060
|
+
await ensureWorkspaceRules(join22(absoluteTarget, agentFile), repositories);
|
|
31957
32061
|
}
|
|
31958
32062
|
}
|
|
31959
32063
|
if (clientNames.includes("claude") && !copiedAgentFiles.includes("CLAUDE.md") && copiedAgentFiles.includes("AGENTS.md")) {
|
|
31960
|
-
const agentsPath =
|
|
31961
|
-
const claudePath =
|
|
32064
|
+
const agentsPath = join22(absoluteTarget, "AGENTS.md");
|
|
32065
|
+
const claudePath = join22(absoluteTarget, "CLAUDE.md");
|
|
31962
32066
|
await copyFile2(agentsPath, claudePath);
|
|
31963
32067
|
}
|
|
31964
32068
|
}
|
|
@@ -32003,14 +32107,14 @@ Next steps:`);
|
|
|
32003
32107
|
async function seedCacheFromClone(tempDir, owner, repo, branch) {
|
|
32004
32108
|
const cachePaths = [
|
|
32005
32109
|
getPluginCachePath(owner, repo, branch),
|
|
32006
|
-
|
|
32110
|
+
join22(getMarketplacesDir(), repo)
|
|
32007
32111
|
];
|
|
32008
32112
|
for (const cachePath of cachePaths) {
|
|
32009
|
-
if (
|
|
32113
|
+
if (existsSync21(cachePath))
|
|
32010
32114
|
continue;
|
|
32011
32115
|
try {
|
|
32012
32116
|
const parentDir = dirname13(cachePath);
|
|
32013
|
-
if (!
|
|
32117
|
+
if (!existsSync21(parentDir)) {
|
|
32014
32118
|
await mkdir9(parentDir, { recursive: true });
|
|
32015
32119
|
}
|
|
32016
32120
|
await cp2(tempDir, cachePath, { recursive: true });
|
|
@@ -32031,11 +32135,11 @@ var init_workspace = __esm(() => {
|
|
|
32031
32135
|
});
|
|
32032
32136
|
|
|
32033
32137
|
// src/core/status.ts
|
|
32034
|
-
import { existsSync as
|
|
32035
|
-
import { join as
|
|
32138
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
32139
|
+
import { join as join23 } from "node:path";
|
|
32036
32140
|
async function getWorkspaceStatus(workspacePath = process.cwd()) {
|
|
32037
|
-
const configPath =
|
|
32038
|
-
if (!
|
|
32141
|
+
const configPath = join23(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
32142
|
+
if (!existsSync22(configPath) || isUserConfigPath(workspacePath)) {
|
|
32039
32143
|
const userPlugins = await getUserPluginStatuses();
|
|
32040
32144
|
return {
|
|
32041
32145
|
success: true,
|
|
@@ -32077,7 +32181,7 @@ async function getWorkspaceStatus(workspacePath = process.cwd()) {
|
|
|
32077
32181
|
function getPluginStatus(parsed) {
|
|
32078
32182
|
if (parsed.type === "github") {
|
|
32079
32183
|
const cachePath = parsed.owner && parsed.repo ? getPluginCachePath(parsed.owner, parsed.repo) : "";
|
|
32080
|
-
const available2 = cachePath ?
|
|
32184
|
+
const available2 = cachePath ? existsSync22(cachePath) : false;
|
|
32081
32185
|
return {
|
|
32082
32186
|
source: parsed.original,
|
|
32083
32187
|
type: "github",
|
|
@@ -32087,7 +32191,7 @@ function getPluginStatus(parsed) {
|
|
|
32087
32191
|
...parsed.repo && { repo: parsed.repo }
|
|
32088
32192
|
};
|
|
32089
32193
|
}
|
|
32090
|
-
const available =
|
|
32194
|
+
const available = existsSync22(parsed.normalized);
|
|
32091
32195
|
return {
|
|
32092
32196
|
source: parsed.original,
|
|
32093
32197
|
type: "local",
|
|
@@ -34249,9 +34353,9 @@ var init_prompt_clients = __esm(() => {
|
|
|
34249
34353
|
});
|
|
34250
34354
|
|
|
34251
34355
|
// src/core/skills.ts
|
|
34252
|
-
import { existsSync as
|
|
34356
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
34253
34357
|
import { readFile as readFile14, readdir as readdir5 } from "node:fs/promises";
|
|
34254
|
-
import { join as
|
|
34358
|
+
import { join as join26, basename as basename7, resolve as resolve14 } from "node:path";
|
|
34255
34359
|
async function resolvePluginPath(pluginSource, workspacePath) {
|
|
34256
34360
|
if (isPluginSpec(pluginSource)) {
|
|
34257
34361
|
const resolved2 = await resolvePluginSpecWithAutoRegister(pluginSource, {
|
|
@@ -34272,15 +34376,15 @@ async function resolvePluginPath(pluginSource, workspacePath) {
|
|
|
34272
34376
|
});
|
|
34273
34377
|
if (!result.success)
|
|
34274
34378
|
return null;
|
|
34275
|
-
const path = parsed?.subpath ?
|
|
34379
|
+
const path = parsed?.subpath ? join26(result.cachePath, parsed.subpath) : result.cachePath;
|
|
34276
34380
|
return { path };
|
|
34277
34381
|
}
|
|
34278
34382
|
const resolved = resolve14(workspacePath, pluginSource);
|
|
34279
|
-
return
|
|
34383
|
+
return existsSync25(resolved) ? { path: resolved } : null;
|
|
34280
34384
|
}
|
|
34281
34385
|
async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
|
|
34282
|
-
const configPath =
|
|
34283
|
-
if (!
|
|
34386
|
+
const configPath = join26(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
34387
|
+
if (!existsSync25(configPath)) {
|
|
34284
34388
|
return [];
|
|
34285
34389
|
}
|
|
34286
34390
|
const content = await readFile14(configPath, "utf-8");
|
|
@@ -34296,29 +34400,29 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
|
|
|
34296
34400
|
continue;
|
|
34297
34401
|
const pluginPath = resolved.path;
|
|
34298
34402
|
const pluginName = resolved.pluginName ?? getPluginName(pluginPath);
|
|
34299
|
-
const skillsDir =
|
|
34403
|
+
const skillsDir = join26(pluginPath, "skills");
|
|
34300
34404
|
const pluginSkillsConfig = typeof pluginEntry === "string" ? undefined : pluginEntry.skills;
|
|
34301
34405
|
const hasEnabledEntries = !pluginSkillsConfig && enabledSkills && [...enabledSkills].some((s) => s.startsWith(`${pluginName}`));
|
|
34302
34406
|
let skillEntries;
|
|
34303
|
-
if (
|
|
34407
|
+
if (existsSync25(skillsDir)) {
|
|
34304
34408
|
const entries = await readdir5(skillsDir, { withFileTypes: true });
|
|
34305
|
-
skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath:
|
|
34409
|
+
skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath: join26(skillsDir, e.name) }));
|
|
34306
34410
|
} else {
|
|
34307
34411
|
const entries = await readdir5(pluginPath, { withFileTypes: true });
|
|
34308
34412
|
const flatSkills = [];
|
|
34309
34413
|
for (const entry of entries) {
|
|
34310
34414
|
if (!entry.isDirectory())
|
|
34311
34415
|
continue;
|
|
34312
|
-
const skillMdPath =
|
|
34313
|
-
if (
|
|
34314
|
-
flatSkills.push({ name: entry.name, skillPath:
|
|
34416
|
+
const skillMdPath = join26(pluginPath, entry.name, "SKILL.md");
|
|
34417
|
+
if (existsSync25(skillMdPath)) {
|
|
34418
|
+
flatSkills.push({ name: entry.name, skillPath: join26(pluginPath, entry.name) });
|
|
34315
34419
|
}
|
|
34316
34420
|
}
|
|
34317
34421
|
if (flatSkills.length > 0) {
|
|
34318
34422
|
skillEntries = flatSkills;
|
|
34319
34423
|
} else {
|
|
34320
|
-
const rootSkillMd =
|
|
34321
|
-
if (
|
|
34424
|
+
const rootSkillMd = join26(pluginPath, "SKILL.md");
|
|
34425
|
+
if (existsSync25(rootSkillMd)) {
|
|
34322
34426
|
const skillContent = await readFile14(rootSkillMd, "utf-8");
|
|
34323
34427
|
const metadata = parseSkillMetadata(skillContent);
|
|
34324
34428
|
const skillName = metadata?.name ?? basename7(pluginPath);
|
|
@@ -34360,10 +34464,10 @@ async function findSkillByName(skillName, workspacePath = process.cwd()) {
|
|
|
34360
34464
|
return allSkills.filter((s) => s.name === skillName);
|
|
34361
34465
|
}
|
|
34362
34466
|
async function discoverSkillNames(pluginPath) {
|
|
34363
|
-
if (!
|
|
34467
|
+
if (!existsSync25(pluginPath))
|
|
34364
34468
|
return [];
|
|
34365
|
-
const skillsDir =
|
|
34366
|
-
if (
|
|
34469
|
+
const skillsDir = join26(pluginPath, "skills");
|
|
34470
|
+
if (existsSync25(skillsDir)) {
|
|
34367
34471
|
const entries2 = await readdir5(skillsDir, { withFileTypes: true });
|
|
34368
34472
|
return entries2.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
34369
34473
|
}
|
|
@@ -34372,14 +34476,14 @@ async function discoverSkillNames(pluginPath) {
|
|
|
34372
34476
|
for (const entry of entries) {
|
|
34373
34477
|
if (!entry.isDirectory())
|
|
34374
34478
|
continue;
|
|
34375
|
-
if (
|
|
34479
|
+
if (existsSync25(join26(pluginPath, entry.name, "SKILL.md"))) {
|
|
34376
34480
|
flatSkills.push(entry.name);
|
|
34377
34481
|
}
|
|
34378
34482
|
}
|
|
34379
34483
|
if (flatSkills.length > 0)
|
|
34380
34484
|
return flatSkills;
|
|
34381
|
-
const rootSkillMd =
|
|
34382
|
-
if (
|
|
34485
|
+
const rootSkillMd = join26(pluginPath, "SKILL.md");
|
|
34486
|
+
if (existsSync25(rootSkillMd)) {
|
|
34383
34487
|
try {
|
|
34384
34488
|
const content = await readFile14(rootSkillMd, "utf-8");
|
|
34385
34489
|
const { parseSkillMetadata: parseSkillMetadata2 } = await Promise.resolve().then(() => (init_skill(), exports_skill));
|
|
@@ -34695,8 +34799,8 @@ var require_shebang_regex = __commonJS((exports, module) => {
|
|
|
34695
34799
|
// node_modules/shebang-command/index.js
|
|
34696
34800
|
var require_shebang_command = __commonJS((exports, module) => {
|
|
34697
34801
|
var shebangRegex = require_shebang_regex();
|
|
34698
|
-
module.exports = (
|
|
34699
|
-
const match =
|
|
34802
|
+
module.exports = (string5 = "") => {
|
|
34803
|
+
const match = string5.match(shebangRegex);
|
|
34700
34804
|
if (!match) {
|
|
34701
34805
|
return null;
|
|
34702
34806
|
}
|
|
@@ -34713,12 +34817,12 @@ var require_shebang_command = __commonJS((exports, module) => {
|
|
|
34713
34817
|
var require_readShebang = __commonJS((exports, module) => {
|
|
34714
34818
|
var fs = __require("fs");
|
|
34715
34819
|
var shebangCommand = require_shebang_command();
|
|
34716
|
-
function readShebang(
|
|
34820
|
+
function readShebang(command5) {
|
|
34717
34821
|
const size = 150;
|
|
34718
34822
|
const buffer = Buffer.alloc(size);
|
|
34719
34823
|
let fd;
|
|
34720
34824
|
try {
|
|
34721
|
-
fd = fs.openSync(
|
|
34825
|
+
fd = fs.openSync(command5, "r");
|
|
34722
34826
|
fs.readSync(fd, buffer, 0, size, 0);
|
|
34723
34827
|
fs.closeSync(fd);
|
|
34724
34828
|
} catch (e) {}
|
|
@@ -34764,7 +34868,7 @@ var require_parse5 = __commonJS((exports, module) => {
|
|
|
34764
34868
|
}
|
|
34765
34869
|
return parsed;
|
|
34766
34870
|
}
|
|
34767
|
-
function parse2(
|
|
34871
|
+
function parse2(command5, args, options2) {
|
|
34768
34872
|
if (args && !Array.isArray(args)) {
|
|
34769
34873
|
options2 = args;
|
|
34770
34874
|
args = null;
|
|
@@ -34772,12 +34876,12 @@ var require_parse5 = __commonJS((exports, module) => {
|
|
|
34772
34876
|
args = args ? args.slice(0) : [];
|
|
34773
34877
|
options2 = Object.assign({}, options2);
|
|
34774
34878
|
const parsed = {
|
|
34775
|
-
command:
|
|
34879
|
+
command: command5,
|
|
34776
34880
|
args,
|
|
34777
34881
|
options: options2,
|
|
34778
34882
|
file: undefined,
|
|
34779
34883
|
original: {
|
|
34780
|
-
command:
|
|
34884
|
+
command: command5,
|
|
34781
34885
|
args
|
|
34782
34886
|
}
|
|
34783
34887
|
};
|
|
@@ -34838,14 +34942,14 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
34838
34942
|
var cp3 = __require("child_process");
|
|
34839
34943
|
var parse2 = require_parse5();
|
|
34840
34944
|
var enoent = require_enoent();
|
|
34841
|
-
function spawn3(
|
|
34842
|
-
const parsed = parse2(
|
|
34945
|
+
function spawn3(command5, args, options2) {
|
|
34946
|
+
const parsed = parse2(command5, args, options2);
|
|
34843
34947
|
const spawned = cp3.spawn(parsed.command, parsed.args, parsed.options);
|
|
34844
34948
|
enoent.hookChildProcess(spawned, parsed);
|
|
34845
34949
|
return spawned;
|
|
34846
34950
|
}
|
|
34847
|
-
function spawnSync(
|
|
34848
|
-
const parsed = parse2(
|
|
34951
|
+
function spawnSync(command5, args, options2) {
|
|
34952
|
+
const parsed = parse2(command5, args, options2);
|
|
34849
34953
|
const result = cp3.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
34850
34954
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
34851
34955
|
return result;
|
|
@@ -34899,7 +35003,7 @@ var package_default;
|
|
|
34899
35003
|
var init_package = __esm(() => {
|
|
34900
35004
|
package_default = {
|
|
34901
35005
|
name: "allagents",
|
|
34902
|
-
version: "1.
|
|
35006
|
+
version: "1.8.0",
|
|
34903
35007
|
description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
|
|
34904
35008
|
type: "module",
|
|
34905
35009
|
bin: {
|
|
@@ -34981,13 +35085,13 @@ var init_package = __esm(() => {
|
|
|
34981
35085
|
});
|
|
34982
35086
|
|
|
34983
35087
|
// src/cli/update-check.ts
|
|
34984
|
-
import { readFile as
|
|
34985
|
-
import { join as
|
|
35088
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
35089
|
+
import { join as join30 } from "node:path";
|
|
34986
35090
|
import { spawn as spawn3 } from "node:child_process";
|
|
34987
35091
|
async function getCachedUpdateInfo(path3) {
|
|
34988
|
-
const filePath = path3 ??
|
|
35092
|
+
const filePath = path3 ?? join30(getHomeDir(), CONFIG_DIR, CACHE_FILE);
|
|
34989
35093
|
try {
|
|
34990
|
-
const raw = await
|
|
35094
|
+
const raw = await readFile18(filePath, "utf-8");
|
|
34991
35095
|
const data = JSON.parse(raw);
|
|
34992
35096
|
if (typeof data.latestVersion === "string" && typeof data.lastCheckedAt === "string") {
|
|
34993
35097
|
return data;
|
|
@@ -35023,8 +35127,8 @@ function buildNotice(currentVersion, latestVersion) {
|
|
|
35023
35127
|
Run \`allagents self update\` to upgrade.`);
|
|
35024
35128
|
}
|
|
35025
35129
|
function backgroundUpdateCheck() {
|
|
35026
|
-
const dir =
|
|
35027
|
-
const filePath =
|
|
35130
|
+
const dir = join30(getHomeDir(), CONFIG_DIR);
|
|
35131
|
+
const filePath = join30(dir, CACHE_FILE);
|
|
35028
35132
|
const script = `
|
|
35029
35133
|
const https = require('https');
|
|
35030
35134
|
const fs = require('fs');
|
|
@@ -35111,15 +35215,15 @@ class TuiCache {
|
|
|
35111
35215
|
}
|
|
35112
35216
|
|
|
35113
35217
|
// src/cli/tui/context.ts
|
|
35114
|
-
import { existsSync as
|
|
35115
|
-
import { join as
|
|
35218
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
35219
|
+
import { join as join31 } from "node:path";
|
|
35116
35220
|
async function getTuiContext(cwd = process.cwd(), cache2) {
|
|
35117
35221
|
const cachedContext = cache2?.getContext();
|
|
35118
35222
|
if (cachedContext) {
|
|
35119
35223
|
return cachedContext;
|
|
35120
35224
|
}
|
|
35121
|
-
const configPath =
|
|
35122
|
-
const hasWorkspace =
|
|
35225
|
+
const configPath = join31(cwd, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
35226
|
+
const hasWorkspace = existsSync29(configPath) && !isUserConfigPath(cwd);
|
|
35123
35227
|
let projectPluginCount = 0;
|
|
35124
35228
|
if (hasWorkspace) {
|
|
35125
35229
|
try {
|
|
@@ -36485,7 +36589,7 @@ var init_wizard = __esm(() => {
|
|
|
36485
36589
|
});
|
|
36486
36590
|
|
|
36487
36591
|
// src/cli/index.ts
|
|
36488
|
-
var
|
|
36592
|
+
var import_cmd_ts7 = __toESM(require_cjs(), 1);
|
|
36489
36593
|
|
|
36490
36594
|
// src/cli/help.ts
|
|
36491
36595
|
var import_cmd_ts = __toESM(require_cjs(), 1);
|
|
@@ -36535,8 +36639,8 @@ init_workspace();
|
|
|
36535
36639
|
init_sync();
|
|
36536
36640
|
init_status2();
|
|
36537
36641
|
var import_cmd_ts2 = __toESM(require_cjs(), 1);
|
|
36538
|
-
import { existsSync as
|
|
36539
|
-
import { join as
|
|
36642
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
36643
|
+
import { join as join25, resolve as resolve13 } from "node:path";
|
|
36540
36644
|
|
|
36541
36645
|
// src/core/prune.ts
|
|
36542
36646
|
init_js_yaml();
|
|
@@ -36545,8 +36649,8 @@ init_marketplace();
|
|
|
36545
36649
|
init_user_workspace();
|
|
36546
36650
|
init_workspace_config();
|
|
36547
36651
|
import { readFile as readFile13, writeFile as writeFile9 } from "node:fs/promises";
|
|
36548
|
-
import { existsSync as
|
|
36549
|
-
import { join as
|
|
36652
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
36653
|
+
import { join as join24 } from "node:path";
|
|
36550
36654
|
async function isOrphanedPlugin(pluginSpec) {
|
|
36551
36655
|
if (!isPluginSpec(pluginSpec))
|
|
36552
36656
|
return false;
|
|
@@ -36573,8 +36677,8 @@ async function prunePlugins(plugins) {
|
|
|
36573
36677
|
}
|
|
36574
36678
|
async function pruneOrphanedPlugins(workspacePath) {
|
|
36575
36679
|
let projectResult = { removed: [], kept: [], keptEntries: [] };
|
|
36576
|
-
const projectConfigPath =
|
|
36577
|
-
if (
|
|
36680
|
+
const projectConfigPath = join24(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
36681
|
+
if (existsSync23(projectConfigPath) && !isUserConfigPath(workspacePath)) {
|
|
36578
36682
|
const content = await readFile13(projectConfigPath, "utf-8");
|
|
36579
36683
|
const config = load(content);
|
|
36580
36684
|
projectResult = await prunePlugins(config.plugins);
|
|
@@ -36867,8 +36971,8 @@ var syncCmd = import_cmd_ts2.command({
|
|
|
36867
36971
|
`);
|
|
36868
36972
|
}
|
|
36869
36973
|
const userConfigExists = !!await getUserWorkspaceConfig();
|
|
36870
|
-
const projectConfigPath =
|
|
36871
|
-
const projectConfigExists =
|
|
36974
|
+
const projectConfigPath = join25(process.cwd(), ".allagents", "workspace.yaml");
|
|
36975
|
+
const projectConfigExists = existsSync24(projectConfigPath);
|
|
36872
36976
|
if (!userConfigExists && !projectConfigExists) {
|
|
36873
36977
|
await ensureUserWorkspace();
|
|
36874
36978
|
if (isJsonMode()) {
|
|
@@ -37543,9 +37647,9 @@ init_workspace_modify();
|
|
|
37543
37647
|
init_user_workspace();
|
|
37544
37648
|
init_skills();
|
|
37545
37649
|
var import_cmd_ts3 = __toESM(require_cjs(), 1);
|
|
37546
|
-
import { existsSync as
|
|
37650
|
+
import { existsSync as existsSync26 } from "node:fs";
|
|
37547
37651
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
37548
|
-
import { join as
|
|
37652
|
+
import { join as join27 } from "node:path";
|
|
37549
37653
|
|
|
37550
37654
|
// src/cli/metadata/plugin-skills.ts
|
|
37551
37655
|
var skillsListMeta = {
|
|
@@ -37636,7 +37740,7 @@ init_skill();
|
|
|
37636
37740
|
init_marketplace();
|
|
37637
37741
|
init_marketplace_manifest_parser();
|
|
37638
37742
|
function hasProjectConfig(dir) {
|
|
37639
|
-
return
|
|
37743
|
+
return existsSync26(join27(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
|
|
37640
37744
|
}
|
|
37641
37745
|
function resolveScope(cwd) {
|
|
37642
37746
|
if (isUserConfigPath(cwd))
|
|
@@ -37667,7 +37771,7 @@ async function resolveSkillNameFromRepo(url, parsed, fallbackName, fetchFn = fet
|
|
|
37667
37771
|
if (!fetchResult.success)
|
|
37668
37772
|
return fallbackName;
|
|
37669
37773
|
try {
|
|
37670
|
-
const skillMd = await readFile15(
|
|
37774
|
+
const skillMd = await readFile15(join27(fetchResult.cachePath, "SKILL.md"), "utf-8");
|
|
37671
37775
|
const metadata = parseSkillMetadata(skillMd);
|
|
37672
37776
|
return metadata?.name ?? fallbackName;
|
|
37673
37777
|
} catch {
|
|
@@ -38225,8 +38329,8 @@ init_workspace_config();
|
|
|
38225
38329
|
init_constants();
|
|
38226
38330
|
init_js_yaml();
|
|
38227
38331
|
import { readFile as readFile16 } from "node:fs/promises";
|
|
38228
|
-
import { existsSync as
|
|
38229
|
-
import { join as
|
|
38332
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
38333
|
+
import { join as join28 } from "node:path";
|
|
38230
38334
|
async function runSyncAndPrint(options2) {
|
|
38231
38335
|
if (!isJsonMode()) {
|
|
38232
38336
|
console.log(`
|
|
@@ -38471,7 +38575,7 @@ var marketplaceAddCmd = import_cmd_ts4.command({
|
|
|
38471
38575
|
process.exit(1);
|
|
38472
38576
|
}
|
|
38473
38577
|
if (effectiveScope === "project") {
|
|
38474
|
-
if (!
|
|
38578
|
+
if (!existsSync27(join28(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
|
|
38475
38579
|
const msg = 'No workspace found in current directory. Run "allagents workspace init" first.';
|
|
38476
38580
|
if (isJsonMode()) {
|
|
38477
38581
|
jsonOutput({ success: false, command: "plugin marketplace add", error: msg });
|
|
@@ -38778,7 +38882,7 @@ var pluginListCmd = import_cmd_ts4.command({
|
|
|
38778
38882
|
};
|
|
38779
38883
|
const pluginClients = new Map;
|
|
38780
38884
|
async function loadConfigClients(configPath, scope) {
|
|
38781
|
-
if (!
|
|
38885
|
+
if (!existsSync27(configPath))
|
|
38782
38886
|
return;
|
|
38783
38887
|
try {
|
|
38784
38888
|
const content = await readFile16(configPath, "utf-8");
|
|
@@ -38793,8 +38897,8 @@ var pluginListCmd = import_cmd_ts4.command({
|
|
|
38793
38897
|
}
|
|
38794
38898
|
} catch {}
|
|
38795
38899
|
}
|
|
38796
|
-
const userConfigPath =
|
|
38797
|
-
const projectConfigPath =
|
|
38900
|
+
const userConfigPath = join28(getAllagentsDir(), WORKSPACE_CONFIG_FILE);
|
|
38901
|
+
const projectConfigPath = join28(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
38798
38902
|
const cwdIsHome = isUserConfigPath(process.cwd());
|
|
38799
38903
|
await loadConfigClients(userConfigPath, "user");
|
|
38800
38904
|
if (!cwdIsHome) {
|
|
@@ -38936,7 +39040,7 @@ var pluginInstallCmd = import_cmd_ts4.command({
|
|
|
38936
39040
|
const isUser = scope === "user" || !scope && isUserConfigPath(process.cwd());
|
|
38937
39041
|
if (isUser) {
|
|
38938
39042
|
const userConfigPath = getUserWorkspaceConfigPath();
|
|
38939
|
-
if (!
|
|
39043
|
+
if (!existsSync27(userConfigPath)) {
|
|
38940
39044
|
const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
|
|
38941
39045
|
const clients = await promptForClients2();
|
|
38942
39046
|
if (clients === null) {
|
|
@@ -38948,8 +39052,8 @@ var pluginInstallCmd = import_cmd_ts4.command({
|
|
|
38948
39052
|
await ensureUserWorkspace(clients);
|
|
38949
39053
|
}
|
|
38950
39054
|
} else {
|
|
38951
|
-
const configPath =
|
|
38952
|
-
if (!
|
|
39055
|
+
const configPath = join28(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
39056
|
+
if (!existsSync27(configPath)) {
|
|
38953
39057
|
const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
|
|
38954
39058
|
const clients = await promptForClients2();
|
|
38955
39059
|
if (clients === null) {
|
|
@@ -39226,13 +39330,13 @@ var pluginUpdateCmd = import_cmd_ts4.command({
|
|
|
39226
39330
|
}
|
|
39227
39331
|
}
|
|
39228
39332
|
if (updateProject && !isUserConfigPath(process.cwd())) {
|
|
39229
|
-
const { existsSync:
|
|
39333
|
+
const { existsSync: existsSync28 } = await import("node:fs");
|
|
39230
39334
|
const { readFile: readFile17 } = await import("node:fs/promises");
|
|
39231
|
-
const { join:
|
|
39335
|
+
const { join: join29 } = await import("node:path");
|
|
39232
39336
|
const { load: load2 } = await Promise.resolve().then(() => (init_js_yaml(), exports_js_yaml));
|
|
39233
39337
|
const { CONFIG_DIR: CONFIG_DIR2, WORKSPACE_CONFIG_FILE: WORKSPACE_CONFIG_FILE2 } = await Promise.resolve().then(() => (init_constants(), exports_constants));
|
|
39234
|
-
const configPath =
|
|
39235
|
-
if (
|
|
39338
|
+
const configPath = join29(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
|
|
39339
|
+
if (existsSync28(configPath)) {
|
|
39236
39340
|
const content = await readFile17(configPath, "utf-8");
|
|
39237
39341
|
const config = load2(content);
|
|
39238
39342
|
for (const entry of config.plugins ?? []) {
|
|
@@ -39389,9 +39493,530 @@ var pluginCmd = conciseSubcommands({
|
|
|
39389
39493
|
}
|
|
39390
39494
|
});
|
|
39391
39495
|
|
|
39392
|
-
// src/cli/commands/
|
|
39496
|
+
// src/cli/commands/mcp.ts
|
|
39497
|
+
init_js_yaml();
|
|
39393
39498
|
var import_cmd_ts5 = __toESM(require_cjs(), 1);
|
|
39394
39499
|
|
|
39500
|
+
// src/core/mcp-servers.ts
|
|
39501
|
+
init_js_yaml();
|
|
39502
|
+
init_constants();
|
|
39503
|
+
init_workspace_config();
|
|
39504
|
+
init_workspace_modify();
|
|
39505
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
39506
|
+
import { readFile as readFile17, writeFile as writeFile10 } from "node:fs/promises";
|
|
39507
|
+
import { join as join29 } from "node:path";
|
|
39508
|
+
function getConfigPath(workspacePath) {
|
|
39509
|
+
return join29(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
39510
|
+
}
|
|
39511
|
+
async function readConfig(configPath) {
|
|
39512
|
+
const content = await readFile17(configPath, "utf-8");
|
|
39513
|
+
return load(content);
|
|
39514
|
+
}
|
|
39515
|
+
async function writeConfig(configPath, config) {
|
|
39516
|
+
await writeFile10(configPath, dump(config, { lineWidth: -1 }), "utf-8");
|
|
39517
|
+
}
|
|
39518
|
+
function validateServerConfig(config) {
|
|
39519
|
+
const result = McpServerConfigSchema.safeParse(config);
|
|
39520
|
+
if (!result.success) {
|
|
39521
|
+
const issues = result.error.issues.map((i2) => ` - ${i2.path.join(".")}: ${i2.message}`);
|
|
39522
|
+
return { valid: false, error: `Invalid MCP server config:
|
|
39523
|
+
${issues.join(`
|
|
39524
|
+
`)}` };
|
|
39525
|
+
}
|
|
39526
|
+
return { valid: true, data: result.data };
|
|
39527
|
+
}
|
|
39528
|
+
async function addWorkspaceMcpServer(name, config, workspacePath = process.cwd(), force = false) {
|
|
39529
|
+
const validation = validateServerConfig(config);
|
|
39530
|
+
if (!validation.valid) {
|
|
39531
|
+
return { success: false, error: validation.error };
|
|
39532
|
+
}
|
|
39533
|
+
try {
|
|
39534
|
+
await ensureWorkspace(workspacePath);
|
|
39535
|
+
const configPath = getConfigPath(workspacePath);
|
|
39536
|
+
const workspaceConfig = await readConfig(configPath);
|
|
39537
|
+
workspaceConfig.mcpServers ??= {};
|
|
39538
|
+
if (workspaceConfig.mcpServers[name] && !force) {
|
|
39539
|
+
return {
|
|
39540
|
+
success: false,
|
|
39541
|
+
error: `MCP server '${name}' already exists in workspace.yaml. Pass --force to replace it.`
|
|
39542
|
+
};
|
|
39543
|
+
}
|
|
39544
|
+
workspaceConfig.mcpServers[name] = validation.data;
|
|
39545
|
+
await writeConfig(configPath, workspaceConfig);
|
|
39546
|
+
return { success: true, config: validation.data };
|
|
39547
|
+
} catch (error) {
|
|
39548
|
+
return {
|
|
39549
|
+
success: false,
|
|
39550
|
+
error: error instanceof Error ? error.message : String(error)
|
|
39551
|
+
};
|
|
39552
|
+
}
|
|
39553
|
+
}
|
|
39554
|
+
async function removeWorkspaceMcpServer(name, workspacePath = process.cwd()) {
|
|
39555
|
+
const configPath = getConfigPath(workspacePath);
|
|
39556
|
+
if (!existsSync28(configPath)) {
|
|
39557
|
+
return {
|
|
39558
|
+
success: false,
|
|
39559
|
+
error: `${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}`
|
|
39560
|
+
};
|
|
39561
|
+
}
|
|
39562
|
+
try {
|
|
39563
|
+
const workspaceConfig = await readConfig(configPath);
|
|
39564
|
+
if (!workspaceConfig.mcpServers || !(name in workspaceConfig.mcpServers)) {
|
|
39565
|
+
return {
|
|
39566
|
+
success: false,
|
|
39567
|
+
error: `MCP server '${name}' not found in workspace.yaml`
|
|
39568
|
+
};
|
|
39569
|
+
}
|
|
39570
|
+
delete workspaceConfig.mcpServers[name];
|
|
39571
|
+
if (Object.keys(workspaceConfig.mcpServers).length === 0) {
|
|
39572
|
+
workspaceConfig.mcpServers = undefined;
|
|
39573
|
+
}
|
|
39574
|
+
await writeConfig(configPath, workspaceConfig);
|
|
39575
|
+
return { success: true };
|
|
39576
|
+
} catch (error) {
|
|
39577
|
+
return {
|
|
39578
|
+
success: false,
|
|
39579
|
+
error: error instanceof Error ? error.message : String(error)
|
|
39580
|
+
};
|
|
39581
|
+
}
|
|
39582
|
+
}
|
|
39583
|
+
async function getWorkspaceMcpServer(name, workspacePath = process.cwd()) {
|
|
39584
|
+
const configPath = getConfigPath(workspacePath);
|
|
39585
|
+
if (!existsSync28(configPath))
|
|
39586
|
+
return null;
|
|
39587
|
+
const workspaceConfig = await readConfig(configPath);
|
|
39588
|
+
return workspaceConfig.mcpServers?.[name] ?? null;
|
|
39589
|
+
}
|
|
39590
|
+
async function listWorkspaceMcpServers(workspacePath = process.cwd()) {
|
|
39591
|
+
const configPath = getConfigPath(workspacePath);
|
|
39592
|
+
if (!existsSync28(configPath))
|
|
39593
|
+
return {};
|
|
39594
|
+
const workspaceConfig = await readConfig(configPath);
|
|
39595
|
+
return workspaceConfig.mcpServers ?? {};
|
|
39596
|
+
}
|
|
39597
|
+
function buildMcpServerConfigFromFlags(options2) {
|
|
39598
|
+
const { commandOrUrl, args, env: env2, headers, clients } = options2;
|
|
39599
|
+
const transport = options2.transport ?? (/^https?:\/\//i.test(commandOrUrl) ? "http" : "stdio");
|
|
39600
|
+
if (transport === "http") {
|
|
39601
|
+
if (!/^https?:\/\//i.test(commandOrUrl)) {
|
|
39602
|
+
return {
|
|
39603
|
+
error: `HTTP transport requires a URL starting with http:// or https:// (got '${commandOrUrl}')`
|
|
39604
|
+
};
|
|
39605
|
+
}
|
|
39606
|
+
if (args && args.length > 0) {
|
|
39607
|
+
return { error: "--arg is not supported for HTTP transport" };
|
|
39608
|
+
}
|
|
39609
|
+
if (env2 && Object.keys(env2).length > 0) {
|
|
39610
|
+
return { error: "-e/--env is not supported for HTTP transport" };
|
|
39611
|
+
}
|
|
39612
|
+
const config2 = {
|
|
39613
|
+
type: "http",
|
|
39614
|
+
url: commandOrUrl,
|
|
39615
|
+
...headers && Object.keys(headers).length > 0 && { headers },
|
|
39616
|
+
...clients && clients.length > 0 && { clients }
|
|
39617
|
+
};
|
|
39618
|
+
return { config: config2 };
|
|
39619
|
+
}
|
|
39620
|
+
if (options2.transport === "stdio" && /^https?:\/\//i.test(commandOrUrl)) {
|
|
39621
|
+
return {
|
|
39622
|
+
error: `stdio transport requires a command, not a URL (got '${commandOrUrl}')`
|
|
39623
|
+
};
|
|
39624
|
+
}
|
|
39625
|
+
if (headers && Object.keys(headers).length > 0) {
|
|
39626
|
+
return { error: "--header is not supported for stdio transport" };
|
|
39627
|
+
}
|
|
39628
|
+
const config = {
|
|
39629
|
+
type: "stdio",
|
|
39630
|
+
command: commandOrUrl,
|
|
39631
|
+
...args && args.length > 0 && { args },
|
|
39632
|
+
...env2 && Object.keys(env2).length > 0 && { env: env2 },
|
|
39633
|
+
...clients && clients.length > 0 && { clients }
|
|
39634
|
+
};
|
|
39635
|
+
return { config };
|
|
39636
|
+
}
|
|
39637
|
+
function parseKeyValuePairs(pairs2, flagName) {
|
|
39638
|
+
const values = {};
|
|
39639
|
+
for (const pair of pairs2) {
|
|
39640
|
+
const eqIdx = pair.indexOf("=");
|
|
39641
|
+
if (eqIdx <= 0) {
|
|
39642
|
+
return { error: `Invalid ${flagName}: '${pair}' (expected KEY=VALUE)` };
|
|
39643
|
+
}
|
|
39644
|
+
const key = pair.slice(0, eqIdx);
|
|
39645
|
+
const value = pair.slice(eqIdx + 1);
|
|
39646
|
+
values[key] = value;
|
|
39647
|
+
}
|
|
39648
|
+
return { values };
|
|
39649
|
+
}
|
|
39650
|
+
|
|
39651
|
+
// src/cli/commands/mcp.ts
|
|
39652
|
+
init_mcp_sync();
|
|
39653
|
+
init_workspace_config();
|
|
39654
|
+
init_format_sync();
|
|
39655
|
+
|
|
39656
|
+
// src/cli/metadata/mcp.ts
|
|
39657
|
+
var mcpAddMeta = {
|
|
39658
|
+
command: "mcp add",
|
|
39659
|
+
description: "Add an MCP server to workspace.yaml and sync to clients",
|
|
39660
|
+
whenToUse: "When adding a new MCP server that you want AllAgents to manage and sync to all configured clients",
|
|
39661
|
+
examples: [
|
|
39662
|
+
"allagents mcp add deepwiki https://mcp.deepwiki.com/mcp",
|
|
39663
|
+
"allagents mcp add my-server npx --arg=-y --arg=@my/mcp-server",
|
|
39664
|
+
"allagents mcp add gh-api npx -e GH_TOKEN=abc123 --arg=-y --arg=@modelcontextprotocol/server-github",
|
|
39665
|
+
"allagents mcp add deepwiki https://mcp.deepwiki.com/mcp --client claude,copilot"
|
|
39666
|
+
],
|
|
39667
|
+
expectedOutput: "Adds the server to workspace.yaml and syncs it to all configured clients. Exit 0 on success, 1 on failure.",
|
|
39668
|
+
positionals: [
|
|
39669
|
+
{ name: "name", type: "string", required: true, description: "Server name (unique within workspace.yaml)" },
|
|
39670
|
+
{
|
|
39671
|
+
name: "commandOrUrl",
|
|
39672
|
+
type: "string",
|
|
39673
|
+
required: true,
|
|
39674
|
+
description: "HTTP URL (http://, https://) for http transport, or a command for stdio transport"
|
|
39675
|
+
}
|
|
39676
|
+
],
|
|
39677
|
+
options: [
|
|
39678
|
+
{ flag: "--transport", type: "string", description: "Transport type: 'http' or 'stdio' (auto-detected from URL by default)" },
|
|
39679
|
+
{ flag: "--arg", type: "string", description: "Argument to pass to the stdio command (repeatable)" },
|
|
39680
|
+
{ flag: "--env", short: "-e", type: "string", description: "Environment variable KEY=VALUE for stdio transport (repeatable)" },
|
|
39681
|
+
{ flag: "--header", type: "string", description: "HTTP header KEY=VALUE for http transport (repeatable)" },
|
|
39682
|
+
{ flag: "--client", type: "string", description: "Comma-separated list of clients that should receive this server (default: all project-scoped clients)" },
|
|
39683
|
+
{ flag: "--force", short: "-f", type: "boolean", description: "Replace an existing server with the same name" }
|
|
39684
|
+
]
|
|
39685
|
+
};
|
|
39686
|
+
var mcpRemoveMeta = {
|
|
39687
|
+
command: "mcp remove",
|
|
39688
|
+
description: "Remove an MCP server from workspace.yaml and all clients",
|
|
39689
|
+
whenToUse: "When you no longer need an MCP server that AllAgents added",
|
|
39690
|
+
examples: ["allagents mcp remove deepwiki"],
|
|
39691
|
+
expectedOutput: "Removes the server from workspace.yaml and unsyncs it from all configured clients. Exit 0 on success, 1 if the server is not defined in workspace.yaml.",
|
|
39692
|
+
positionals: [
|
|
39693
|
+
{ name: "name", type: "string", required: true, description: "Server name to remove" }
|
|
39694
|
+
]
|
|
39695
|
+
};
|
|
39696
|
+
var mcpListMeta = {
|
|
39697
|
+
command: "mcp list",
|
|
39698
|
+
description: "List MCP servers defined in workspace.yaml",
|
|
39699
|
+
whenToUse: "To inspect MCP servers AllAgents is managing at the workspace level",
|
|
39700
|
+
examples: ["allagents mcp list"],
|
|
39701
|
+
expectedOutput: "Prints a table of workspace-defined MCP servers with transport, target, and client filter. Exit 0 on success."
|
|
39702
|
+
};
|
|
39703
|
+
var mcpGetMeta = {
|
|
39704
|
+
command: "mcp get",
|
|
39705
|
+
description: "Show the workspace definition for an MCP server",
|
|
39706
|
+
whenToUse: "To see how an MCP server is configured in workspace.yaml",
|
|
39707
|
+
examples: ["allagents mcp get deepwiki"],
|
|
39708
|
+
expectedOutput: "Prints the server config (YAML). Exit 0 on success, 1 if not found.",
|
|
39709
|
+
positionals: [
|
|
39710
|
+
{ name: "name", type: "string", required: true, description: "Server name" }
|
|
39711
|
+
]
|
|
39712
|
+
};
|
|
39713
|
+
var mcpUpdateMeta = {
|
|
39714
|
+
command: "mcp update",
|
|
39715
|
+
description: "Sync MCP servers only, without touching other artifacts",
|
|
39716
|
+
whenToUse: "When you've edited workspace.yaml's mcpServers block or plugin .mcp.json files and want to re-sync only MCP servers without re-running the full workspace sync. To modify a server definition use 'mcp add --force'.",
|
|
39717
|
+
examples: ["allagents mcp update", "allagents mcp update --offline"],
|
|
39718
|
+
expectedOutput: "Runs the MCP portion of sync for all project-scoped clients. Prints per-scope added/updated/removed counts. Exit 0 on success, 1 on failure.",
|
|
39719
|
+
options: [
|
|
39720
|
+
{ flag: "--offline", type: "boolean", description: "Use cached plugins without fetching from remote" }
|
|
39721
|
+
]
|
|
39722
|
+
};
|
|
39723
|
+
|
|
39724
|
+
// src/cli/commands/mcp.ts
|
|
39725
|
+
function parseClientFilter(input) {
|
|
39726
|
+
const items = input.split(",").map((s) => s.trim()).filter(Boolean);
|
|
39727
|
+
const result = [];
|
|
39728
|
+
for (const item of items) {
|
|
39729
|
+
const parsed = ClientTypeSchema.safeParse(item);
|
|
39730
|
+
if (!parsed.success) {
|
|
39731
|
+
throw new Error(`Invalid client '${item}'. Valid clients: ${ClientTypeSchema.options.join(", ")}`);
|
|
39732
|
+
}
|
|
39733
|
+
result.push(parsed.data);
|
|
39734
|
+
}
|
|
39735
|
+
return result;
|
|
39736
|
+
}
|
|
39737
|
+
function exitWithError(command5, error) {
|
|
39738
|
+
if (isJsonMode()) {
|
|
39739
|
+
jsonOutput({ success: false, command: command5, error });
|
|
39740
|
+
} else {
|
|
39741
|
+
console.error(`Error: ${error}`);
|
|
39742
|
+
}
|
|
39743
|
+
process.exit(1);
|
|
39744
|
+
}
|
|
39745
|
+
function buildConfigFromAddFlags(commandName, commandOrUrl, transport, args, env2, header, client) {
|
|
39746
|
+
if (transport && transport !== "http" && transport !== "stdio") {
|
|
39747
|
+
exitWithError(commandName, `Invalid transport '${transport}'. Expected 'http' or 'stdio'.`);
|
|
39748
|
+
}
|
|
39749
|
+
const envResult = parseKeyValuePairs(env2, "-e/--env");
|
|
39750
|
+
if ("error" in envResult)
|
|
39751
|
+
exitWithError(commandName, envResult.error);
|
|
39752
|
+
const headerResult = parseKeyValuePairs(header, "--header");
|
|
39753
|
+
if ("error" in headerResult)
|
|
39754
|
+
exitWithError(commandName, headerResult.error);
|
|
39755
|
+
let clients;
|
|
39756
|
+
if (client) {
|
|
39757
|
+
try {
|
|
39758
|
+
clients = parseClientFilter(client);
|
|
39759
|
+
} catch (e) {
|
|
39760
|
+
exitWithError(commandName, e instanceof Error ? e.message : String(e));
|
|
39761
|
+
}
|
|
39762
|
+
}
|
|
39763
|
+
const buildOpts = {
|
|
39764
|
+
commandOrUrl,
|
|
39765
|
+
args,
|
|
39766
|
+
env: envResult.values,
|
|
39767
|
+
headers: headerResult.values
|
|
39768
|
+
};
|
|
39769
|
+
if (transport)
|
|
39770
|
+
buildOpts.transport = transport;
|
|
39771
|
+
if (clients)
|
|
39772
|
+
buildOpts.clients = clients;
|
|
39773
|
+
const built = buildMcpServerConfigFromFlags(buildOpts);
|
|
39774
|
+
if ("error" in built)
|
|
39775
|
+
exitWithError(commandName, built.error);
|
|
39776
|
+
return built.config;
|
|
39777
|
+
}
|
|
39778
|
+
async function runPostMutationSync(commandName, successMessage, jsonExtra) {
|
|
39779
|
+
const syncResult = await syncMcpOnly(process.cwd(), { offline: true });
|
|
39780
|
+
if (!syncResult.success) {
|
|
39781
|
+
exitWithError(commandName, syncResult.error ?? "MCP sync failed");
|
|
39782
|
+
}
|
|
39783
|
+
if (isJsonMode()) {
|
|
39784
|
+
jsonOutput({
|
|
39785
|
+
success: true,
|
|
39786
|
+
command: commandName,
|
|
39787
|
+
data: { ...jsonExtra, mcpResults: syncResult.mcpResults }
|
|
39788
|
+
});
|
|
39789
|
+
return;
|
|
39790
|
+
}
|
|
39791
|
+
console.log(successMessage);
|
|
39792
|
+
for (const [scope, result] of Object.entries(syncResult.mcpResults)) {
|
|
39793
|
+
if (!result)
|
|
39794
|
+
continue;
|
|
39795
|
+
const lines = formatMcpResult(result, scope);
|
|
39796
|
+
if (lines.length > 0) {
|
|
39797
|
+
console.log("");
|
|
39798
|
+
for (const line of lines)
|
|
39799
|
+
console.log(line);
|
|
39800
|
+
}
|
|
39801
|
+
}
|
|
39802
|
+
for (const warning of syncResult.warnings) {
|
|
39803
|
+
console.log(` ⚠ ${warning}`);
|
|
39804
|
+
}
|
|
39805
|
+
}
|
|
39806
|
+
function serverToDisplay(name, config) {
|
|
39807
|
+
const lines = [`${name}:`];
|
|
39808
|
+
const isHttp = "url" in config;
|
|
39809
|
+
lines.push(` transport: ${isHttp ? "http" : "stdio"}`);
|
|
39810
|
+
if (isHttp) {
|
|
39811
|
+
lines.push(` url: ${config.url}`);
|
|
39812
|
+
if (config.headers && Object.keys(config.headers).length > 0) {
|
|
39813
|
+
lines.push(" headers:");
|
|
39814
|
+
for (const [k3, v] of Object.entries(config.headers)) {
|
|
39815
|
+
lines.push(` ${k3}: ${v}`);
|
|
39816
|
+
}
|
|
39817
|
+
}
|
|
39818
|
+
} else {
|
|
39819
|
+
lines.push(` command: ${config.command}`);
|
|
39820
|
+
if (config.args && config.args.length > 0) {
|
|
39821
|
+
lines.push(` args: ${JSON.stringify(config.args)}`);
|
|
39822
|
+
}
|
|
39823
|
+
if (config.env && Object.keys(config.env).length > 0) {
|
|
39824
|
+
lines.push(" env:");
|
|
39825
|
+
for (const [k3, v] of Object.entries(config.env)) {
|
|
39826
|
+
lines.push(` ${k3}: ${v}`);
|
|
39827
|
+
}
|
|
39828
|
+
}
|
|
39829
|
+
}
|
|
39830
|
+
if (config.clients && config.clients.length > 0) {
|
|
39831
|
+
lines.push(` clients: [${config.clients.join(", ")}]`);
|
|
39832
|
+
}
|
|
39833
|
+
return lines;
|
|
39834
|
+
}
|
|
39835
|
+
var addArgs = {
|
|
39836
|
+
name: import_cmd_ts5.positional({ type: import_cmd_ts5.string, displayName: "name" }),
|
|
39837
|
+
commandOrUrl: import_cmd_ts5.positional({ type: import_cmd_ts5.string, displayName: "commandOrUrl" }),
|
|
39838
|
+
transport: import_cmd_ts5.option({
|
|
39839
|
+
type: import_cmd_ts5.optional(import_cmd_ts5.string),
|
|
39840
|
+
long: "transport",
|
|
39841
|
+
description: "Transport: 'http' or 'stdio' (auto-detected from URL if omitted)"
|
|
39842
|
+
}),
|
|
39843
|
+
args: import_cmd_ts5.multioption({
|
|
39844
|
+
type: import_cmd_ts5.array(import_cmd_ts5.string),
|
|
39845
|
+
long: "arg",
|
|
39846
|
+
description: "Argument for stdio command (repeatable)"
|
|
39847
|
+
}),
|
|
39848
|
+
env: import_cmd_ts5.multioption({
|
|
39849
|
+
type: import_cmd_ts5.array(import_cmd_ts5.string),
|
|
39850
|
+
long: "env",
|
|
39851
|
+
short: "e",
|
|
39852
|
+
description: "Environment variable KEY=VALUE (repeatable)"
|
|
39853
|
+
}),
|
|
39854
|
+
header: import_cmd_ts5.multioption({
|
|
39855
|
+
type: import_cmd_ts5.array(import_cmd_ts5.string),
|
|
39856
|
+
long: "header",
|
|
39857
|
+
description: "HTTP header KEY=VALUE (repeatable)"
|
|
39858
|
+
}),
|
|
39859
|
+
client: import_cmd_ts5.option({
|
|
39860
|
+
type: import_cmd_ts5.optional(import_cmd_ts5.string),
|
|
39861
|
+
long: "client",
|
|
39862
|
+
description: "Comma-separated list of client filters"
|
|
39863
|
+
})
|
|
39864
|
+
};
|
|
39865
|
+
var mcpAddCmd = import_cmd_ts5.command({
|
|
39866
|
+
name: "add",
|
|
39867
|
+
description: buildDescription(mcpAddMeta),
|
|
39868
|
+
args: {
|
|
39869
|
+
...addArgs,
|
|
39870
|
+
force: import_cmd_ts5.flag({ long: "force", short: "f", description: "Replace an existing server with the same name" })
|
|
39871
|
+
},
|
|
39872
|
+
handler: async ({ name, commandOrUrl, transport, args, env: env2, header, client, force }) => {
|
|
39873
|
+
const config = buildConfigFromAddFlags("mcp add", commandOrUrl, transport, args, env2, header, client);
|
|
39874
|
+
const addResult = await addWorkspaceMcpServer(name, config, process.cwd(), force);
|
|
39875
|
+
if (!addResult.success)
|
|
39876
|
+
exitWithError("mcp add", addResult.error ?? "Unknown error");
|
|
39877
|
+
await runPostMutationSync("mcp add", `✓ Added MCP server '${name}' to workspace.yaml`, {
|
|
39878
|
+
name,
|
|
39879
|
+
config: addResult.config
|
|
39880
|
+
});
|
|
39881
|
+
}
|
|
39882
|
+
});
|
|
39883
|
+
var mcpRemoveCmd = import_cmd_ts5.command({
|
|
39884
|
+
name: "remove",
|
|
39885
|
+
description: buildDescription(mcpRemoveMeta),
|
|
39886
|
+
args: {
|
|
39887
|
+
name: import_cmd_ts5.positional({ type: import_cmd_ts5.string, displayName: "name" })
|
|
39888
|
+
},
|
|
39889
|
+
handler: async ({ name }) => {
|
|
39890
|
+
const removeResult = await removeWorkspaceMcpServer(name, process.cwd());
|
|
39891
|
+
if (!removeResult.success)
|
|
39892
|
+
exitWithError("mcp remove", removeResult.error ?? "Unknown error");
|
|
39893
|
+
await runPostMutationSync("mcp remove", `✓ Removed MCP server '${name}' from workspace.yaml`, { name });
|
|
39894
|
+
}
|
|
39895
|
+
});
|
|
39896
|
+
var mcpListCmd = import_cmd_ts5.command({
|
|
39897
|
+
name: "list",
|
|
39898
|
+
description: buildDescription(mcpListMeta),
|
|
39899
|
+
args: {},
|
|
39900
|
+
handler: async () => {
|
|
39901
|
+
let servers;
|
|
39902
|
+
try {
|
|
39903
|
+
servers = await listWorkspaceMcpServers(process.cwd());
|
|
39904
|
+
} catch (e) {
|
|
39905
|
+
exitWithError("mcp list", e instanceof Error ? e.message : String(e));
|
|
39906
|
+
}
|
|
39907
|
+
const names = Object.keys(servers);
|
|
39908
|
+
if (isJsonMode()) {
|
|
39909
|
+
jsonOutput({
|
|
39910
|
+
success: true,
|
|
39911
|
+
command: "mcp list",
|
|
39912
|
+
data: { servers, total: names.length }
|
|
39913
|
+
});
|
|
39914
|
+
return;
|
|
39915
|
+
}
|
|
39916
|
+
if (names.length === 0) {
|
|
39917
|
+
console.log("No MCP servers defined in workspace.yaml.");
|
|
39918
|
+
console.log("");
|
|
39919
|
+
console.log("Add one with:");
|
|
39920
|
+
console.log(" allagents mcp add <name> <commandOrUrl>");
|
|
39921
|
+
return;
|
|
39922
|
+
}
|
|
39923
|
+
console.log(`MCP servers (${names.length}):`);
|
|
39924
|
+
console.log("");
|
|
39925
|
+
for (const name of names) {
|
|
39926
|
+
const config = servers[name];
|
|
39927
|
+
if (!config)
|
|
39928
|
+
continue;
|
|
39929
|
+
for (const line of serverToDisplay(name, config)) {
|
|
39930
|
+
console.log(` ${line}`);
|
|
39931
|
+
}
|
|
39932
|
+
console.log("");
|
|
39933
|
+
}
|
|
39934
|
+
}
|
|
39935
|
+
});
|
|
39936
|
+
var mcpGetCmd = import_cmd_ts5.command({
|
|
39937
|
+
name: "get",
|
|
39938
|
+
description: buildDescription(mcpGetMeta),
|
|
39939
|
+
args: {
|
|
39940
|
+
name: import_cmd_ts5.positional({ type: import_cmd_ts5.string, displayName: "name" })
|
|
39941
|
+
},
|
|
39942
|
+
handler: async ({ name }) => {
|
|
39943
|
+
let config;
|
|
39944
|
+
try {
|
|
39945
|
+
config = await getWorkspaceMcpServer(name, process.cwd());
|
|
39946
|
+
} catch (e) {
|
|
39947
|
+
exitWithError("mcp get", e instanceof Error ? e.message : String(e));
|
|
39948
|
+
}
|
|
39949
|
+
if (!config) {
|
|
39950
|
+
exitWithError("mcp get", `MCP server '${name}' not found in workspace.yaml`);
|
|
39951
|
+
}
|
|
39952
|
+
if (isJsonMode()) {
|
|
39953
|
+
jsonOutput({
|
|
39954
|
+
success: true,
|
|
39955
|
+
command: "mcp get",
|
|
39956
|
+
data: { name, config }
|
|
39957
|
+
});
|
|
39958
|
+
return;
|
|
39959
|
+
}
|
|
39960
|
+
console.log(dump({ [name]: config }, { lineWidth: -1 }).trimEnd());
|
|
39961
|
+
}
|
|
39962
|
+
});
|
|
39963
|
+
var mcpUpdateCmd = import_cmd_ts5.command({
|
|
39964
|
+
name: "update",
|
|
39965
|
+
description: buildDescription(mcpUpdateMeta),
|
|
39966
|
+
args: {
|
|
39967
|
+
offline: import_cmd_ts5.flag({ long: "offline", description: "Use cached plugins without fetching from remote" })
|
|
39968
|
+
},
|
|
39969
|
+
handler: async ({ offline }) => {
|
|
39970
|
+
const result = await syncMcpOnly(process.cwd(), { offline });
|
|
39971
|
+
if (!result.success) {
|
|
39972
|
+
exitWithError("mcp update", result.error ?? "MCP sync failed");
|
|
39973
|
+
}
|
|
39974
|
+
if (isJsonMode()) {
|
|
39975
|
+
jsonOutput({
|
|
39976
|
+
success: true,
|
|
39977
|
+
command: "mcp update",
|
|
39978
|
+
data: { mcpResults: result.mcpResults, warnings: result.warnings }
|
|
39979
|
+
});
|
|
39980
|
+
return;
|
|
39981
|
+
}
|
|
39982
|
+
const hasAnyChanges = Object.values(result.mcpResults).some((r) => r && (r.added > 0 || r.overwritten > 0 || r.removed > 0 || r.skipped > 0));
|
|
39983
|
+
if (!hasAnyChanges) {
|
|
39984
|
+
console.log("No MCP server changes.");
|
|
39985
|
+
} else {
|
|
39986
|
+
for (const [scope, mcpResult] of Object.entries(result.mcpResults)) {
|
|
39987
|
+
if (!mcpResult)
|
|
39988
|
+
continue;
|
|
39989
|
+
const lines = formatMcpResult(mcpResult, scope);
|
|
39990
|
+
if (lines.length > 0) {
|
|
39991
|
+
for (const line of lines)
|
|
39992
|
+
console.log(line);
|
|
39993
|
+
console.log("");
|
|
39994
|
+
}
|
|
39995
|
+
}
|
|
39996
|
+
}
|
|
39997
|
+
if (result.warnings.length > 0) {
|
|
39998
|
+
console.log("Warnings:");
|
|
39999
|
+
for (const warning of result.warnings) {
|
|
40000
|
+
console.log(` ⚠ ${warning}`);
|
|
40001
|
+
}
|
|
40002
|
+
}
|
|
40003
|
+
}
|
|
40004
|
+
});
|
|
40005
|
+
var mcpCmd = conciseSubcommands({
|
|
40006
|
+
name: "mcp",
|
|
40007
|
+
description: "Manage MCP servers for AI clients",
|
|
40008
|
+
cmds: {
|
|
40009
|
+
add: mcpAddCmd,
|
|
40010
|
+
remove: mcpRemoveCmd,
|
|
40011
|
+
list: mcpListCmd,
|
|
40012
|
+
get: mcpGetCmd,
|
|
40013
|
+
update: mcpUpdateCmd
|
|
40014
|
+
}
|
|
40015
|
+
});
|
|
40016
|
+
|
|
40017
|
+
// src/cli/commands/self.ts
|
|
40018
|
+
var import_cmd_ts6 = __toESM(require_cjs(), 1);
|
|
40019
|
+
|
|
39395
40020
|
// node_modules/execa/index.js
|
|
39396
40021
|
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
39397
40022
|
import { Buffer as Buffer5 } from "node:buffer";
|
|
@@ -39939,7 +40564,7 @@ var makeError = ({
|
|
|
39939
40564
|
error,
|
|
39940
40565
|
signal,
|
|
39941
40566
|
exitCode,
|
|
39942
|
-
command:
|
|
40567
|
+
command: command5,
|
|
39943
40568
|
escapedCommand,
|
|
39944
40569
|
timedOut,
|
|
39945
40570
|
isCanceled,
|
|
@@ -39951,7 +40576,7 @@ var makeError = ({
|
|
|
39951
40576
|
const signalDescription = signal === undefined ? undefined : signalsByName[signal].description;
|
|
39952
40577
|
const errorCode = error && error.code;
|
|
39953
40578
|
const prefix = getErrorPrefix({ timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled });
|
|
39954
|
-
const execaMessage = `Command ${prefix}: ${
|
|
40579
|
+
const execaMessage = `Command ${prefix}: ${command5}`;
|
|
39955
40580
|
const isError = Object.prototype.toString.call(error) === "[object Error]";
|
|
39956
40581
|
const shortMessage = isError ? `${execaMessage}
|
|
39957
40582
|
${error.message}` : execaMessage;
|
|
@@ -39964,7 +40589,7 @@ ${error.message}` : execaMessage;
|
|
|
39964
40589
|
error = new Error(message);
|
|
39965
40590
|
}
|
|
39966
40591
|
error.shortMessage = shortMessage;
|
|
39967
|
-
error.command =
|
|
40592
|
+
error.command = command5;
|
|
39968
40593
|
error.escapedCommand = escapedCommand;
|
|
39969
40594
|
error.exitCode = exitCode;
|
|
39970
40595
|
error.signal = signal;
|
|
@@ -40771,7 +41396,7 @@ var handleOutput = (options2, value, error) => {
|
|
|
40771
41396
|
};
|
|
40772
41397
|
function execa(file, args, options2) {
|
|
40773
41398
|
const parsed = handleArguments(file, args, options2);
|
|
40774
|
-
const
|
|
41399
|
+
const command5 = joinCommand(file, args);
|
|
40775
41400
|
const escapedCommand = getEscapedCommand(file, args);
|
|
40776
41401
|
logCommand(escapedCommand, parsed.options);
|
|
40777
41402
|
validateTimeout(parsed.options);
|
|
@@ -40785,7 +41410,7 @@ function execa(file, args, options2) {
|
|
|
40785
41410
|
stdout: "",
|
|
40786
41411
|
stderr: "",
|
|
40787
41412
|
all: "",
|
|
40788
|
-
command:
|
|
41413
|
+
command: command5,
|
|
40789
41414
|
escapedCommand,
|
|
40790
41415
|
parsed,
|
|
40791
41416
|
timedOut: false,
|
|
@@ -40814,7 +41439,7 @@ function execa(file, args, options2) {
|
|
|
40814
41439
|
stdout,
|
|
40815
41440
|
stderr,
|
|
40816
41441
|
all,
|
|
40817
|
-
command:
|
|
41442
|
+
command: command5,
|
|
40818
41443
|
escapedCommand,
|
|
40819
41444
|
parsed,
|
|
40820
41445
|
timedOut,
|
|
@@ -40827,7 +41452,7 @@ function execa(file, args, options2) {
|
|
|
40827
41452
|
throw returnedError;
|
|
40828
41453
|
}
|
|
40829
41454
|
return {
|
|
40830
|
-
command:
|
|
41455
|
+
command: command5,
|
|
40831
41456
|
escapedCommand,
|
|
40832
41457
|
exitCode: 0,
|
|
40833
41458
|
stdout,
|
|
@@ -40848,7 +41473,7 @@ function execa(file, args, options2) {
|
|
|
40848
41473
|
}
|
|
40849
41474
|
function execaSync(file, args, options2) {
|
|
40850
41475
|
const parsed = handleArguments(file, args, options2);
|
|
40851
|
-
const
|
|
41476
|
+
const command5 = joinCommand(file, args);
|
|
40852
41477
|
const escapedCommand = getEscapedCommand(file, args);
|
|
40853
41478
|
logCommand(escapedCommand, parsed.options);
|
|
40854
41479
|
const input = handleInputSync(parsed.options);
|
|
@@ -40861,7 +41486,7 @@ function execaSync(file, args, options2) {
|
|
|
40861
41486
|
stdout: "",
|
|
40862
41487
|
stderr: "",
|
|
40863
41488
|
all: "",
|
|
40864
|
-
command:
|
|
41489
|
+
command: command5,
|
|
40865
41490
|
escapedCommand,
|
|
40866
41491
|
parsed,
|
|
40867
41492
|
timedOut: false,
|
|
@@ -40878,7 +41503,7 @@ function execaSync(file, args, options2) {
|
|
|
40878
41503
|
error: result.error,
|
|
40879
41504
|
signal: result.signal,
|
|
40880
41505
|
exitCode: result.status,
|
|
40881
|
-
command:
|
|
41506
|
+
command: command5,
|
|
40882
41507
|
escapedCommand,
|
|
40883
41508
|
parsed,
|
|
40884
41509
|
timedOut: result.error && result.error.code === "ETIMEDOUT",
|
|
@@ -40891,7 +41516,7 @@ function execaSync(file, args, options2) {
|
|
|
40891
41516
|
throw error;
|
|
40892
41517
|
}
|
|
40893
41518
|
return {
|
|
40894
|
-
command:
|
|
41519
|
+
command: command5,
|
|
40895
41520
|
escapedCommand,
|
|
40896
41521
|
exitCode: 0,
|
|
40897
41522
|
stdout,
|
|
@@ -40963,12 +41588,12 @@ function detectPackageManager() {
|
|
|
40963
41588
|
function getCurrentVersion() {
|
|
40964
41589
|
return package_default.version;
|
|
40965
41590
|
}
|
|
40966
|
-
var updateCmd =
|
|
41591
|
+
var updateCmd = import_cmd_ts6.command({
|
|
40967
41592
|
name: "update",
|
|
40968
41593
|
description: buildDescription(updateMeta),
|
|
40969
41594
|
args: {
|
|
40970
|
-
npm:
|
|
40971
|
-
bun:
|
|
41595
|
+
npm: import_cmd_ts6.flag({ long: "npm", description: "Force update using npm" }),
|
|
41596
|
+
bun: import_cmd_ts6.flag({ long: "bun", description: "Force update using bun" })
|
|
40972
41597
|
},
|
|
40973
41598
|
handler: async ({ npm, bun }) => {
|
|
40974
41599
|
try {
|
|
@@ -41152,6 +41777,7 @@ var app = conciseSubcommands({
|
|
|
41152
41777
|
update: syncCmd,
|
|
41153
41778
|
workspace: workspaceCmd,
|
|
41154
41779
|
plugin: pluginCmd,
|
|
41780
|
+
mcp: mcpCmd,
|
|
41155
41781
|
self: selfCmd,
|
|
41156
41782
|
skills: skillsCmd
|
|
41157
41783
|
}
|
|
@@ -41174,5 +41800,5 @@ if (agentHelp) {
|
|
|
41174
41800
|
const { runWizard: runWizard2 } = await Promise.resolve().then(() => (init_wizard(), exports_wizard));
|
|
41175
41801
|
await runWizard2();
|
|
41176
41802
|
} else {
|
|
41177
|
-
|
|
41803
|
+
import_cmd_ts7.run(app, finalArgs);
|
|
41178
41804
|
}
|