allagents 1.4.9 → 1.4.10
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/index.js +261 -36
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15959,9 +15959,37 @@ var init_plugin_path = __esm(() => {
|
|
|
15959
15959
|
});
|
|
15960
15960
|
|
|
15961
15961
|
// src/core/plugin.ts
|
|
15962
|
+
var exports_plugin = {};
|
|
15963
|
+
__export(exports_plugin, {
|
|
15964
|
+
updatePlugin: () => updatePlugin,
|
|
15965
|
+
updateCachedPlugins: () => updateCachedPlugins,
|
|
15966
|
+
seedFetchCache: () => seedFetchCache,
|
|
15967
|
+
resetFetchCache: () => resetFetchCache,
|
|
15968
|
+
listCachedPlugins: () => listCachedPlugins,
|
|
15969
|
+
getPluginName: () => getPluginName,
|
|
15970
|
+
getPluginCacheDir: () => getPluginCacheDir,
|
|
15971
|
+
fetchPlugin: () => fetchPlugin
|
|
15972
|
+
});
|
|
15962
15973
|
import { mkdir, readdir, stat } from "node:fs/promises";
|
|
15963
15974
|
import { existsSync as existsSync2 } from "node:fs";
|
|
15964
15975
|
import { basename, dirname, join as join3, resolve as resolve3 } from "node:path";
|
|
15976
|
+
function resetFetchCache() {
|
|
15977
|
+
fetchCache.clear();
|
|
15978
|
+
}
|
|
15979
|
+
function seedFetchCache(url, path, branch) {
|
|
15980
|
+
const parsed = parseGitHubUrl(url);
|
|
15981
|
+
if (!parsed)
|
|
15982
|
+
return;
|
|
15983
|
+
const { owner, repo } = parsed;
|
|
15984
|
+
const cachePath = getPluginCachePath(owner, repo, branch ?? parsed.branch);
|
|
15985
|
+
if (fetchCache.has(cachePath))
|
|
15986
|
+
return;
|
|
15987
|
+
fetchCache.set(cachePath, Promise.resolve({
|
|
15988
|
+
success: true,
|
|
15989
|
+
action: "skipped",
|
|
15990
|
+
cachePath: path
|
|
15991
|
+
}));
|
|
15992
|
+
}
|
|
15965
15993
|
async function fetchPlugin(url, options2 = {}, deps = {}) {
|
|
15966
15994
|
const { offline = false, branch } = options2;
|
|
15967
15995
|
const validation = validatePluginSource(url);
|
|
@@ -15984,17 +16012,13 @@ async function fetchPlugin(url, options2 = {}, deps = {}) {
|
|
|
15984
16012
|
}
|
|
15985
16013
|
const { owner, repo } = parsed;
|
|
15986
16014
|
const cachePath = getPluginCachePath(owner, repo, branch);
|
|
15987
|
-
const
|
|
15988
|
-
if (
|
|
15989
|
-
return
|
|
16015
|
+
const cached = fetchCache.get(cachePath);
|
|
16016
|
+
if (cached) {
|
|
16017
|
+
return cached;
|
|
15990
16018
|
}
|
|
15991
16019
|
const promise = doFetchPlugin(cachePath, owner, repo, offline, branch, deps);
|
|
15992
|
-
|
|
15993
|
-
|
|
15994
|
-
return await promise;
|
|
15995
|
-
} finally {
|
|
15996
|
-
inflight.delete(cachePath);
|
|
15997
|
-
}
|
|
16020
|
+
fetchCache.set(cachePath, promise);
|
|
16021
|
+
return promise;
|
|
15998
16022
|
}
|
|
15999
16023
|
async function doFetchPlugin(cachePath, owner, repo, offline, branch, deps) {
|
|
16000
16024
|
const {
|
|
@@ -16014,8 +16038,10 @@ async function doFetchPlugin(cachePath, owner, repo, offline, branch, deps) {
|
|
|
16014
16038
|
const repoUrl = gitHubUrl(owner, repo);
|
|
16015
16039
|
if (isCached) {
|
|
16016
16040
|
try {
|
|
16041
|
+
const pullStart = performance.now();
|
|
16017
16042
|
await pullFn(cachePath);
|
|
16018
|
-
|
|
16043
|
+
const pullMs = Math.round(performance.now() - pullStart);
|
|
16044
|
+
return { success: true, action: "updated", cachePath, durationMs: pullMs };
|
|
16019
16045
|
} catch {
|
|
16020
16046
|
return { success: true, action: "skipped", cachePath };
|
|
16021
16047
|
}
|
|
@@ -16023,11 +16049,14 @@ async function doFetchPlugin(cachePath, owner, repo, offline, branch, deps) {
|
|
|
16023
16049
|
try {
|
|
16024
16050
|
const parentDir = dirname(cachePath);
|
|
16025
16051
|
await mkdirFn(parentDir, { recursive: true });
|
|
16052
|
+
const cloneStart = performance.now();
|
|
16026
16053
|
await cloneToFn(repoUrl, cachePath, branch);
|
|
16054
|
+
const cloneMs = Math.round(performance.now() - cloneStart);
|
|
16027
16055
|
return {
|
|
16028
16056
|
success: true,
|
|
16029
16057
|
action: "fetched",
|
|
16030
|
-
cachePath
|
|
16058
|
+
cachePath,
|
|
16059
|
+
durationMs: cloneMs
|
|
16031
16060
|
};
|
|
16032
16061
|
} catch (error) {
|
|
16033
16062
|
if (error instanceof GitCloneError) {
|
|
@@ -16058,6 +16087,57 @@ async function doFetchPlugin(cachePath, owner, repo, offline, branch, deps) {
|
|
|
16058
16087
|
};
|
|
16059
16088
|
}
|
|
16060
16089
|
}
|
|
16090
|
+
function getPluginCacheDir() {
|
|
16091
|
+
return resolve3(getHomeDir(), ".allagents", "plugins", "marketplaces");
|
|
16092
|
+
}
|
|
16093
|
+
async function listCachedPlugins() {
|
|
16094
|
+
const cacheDir = getPluginCacheDir();
|
|
16095
|
+
if (!existsSync2(cacheDir)) {
|
|
16096
|
+
return [];
|
|
16097
|
+
}
|
|
16098
|
+
const entries = await readdir(cacheDir, { withFileTypes: true });
|
|
16099
|
+
const plugins = [];
|
|
16100
|
+
for (const entry of entries) {
|
|
16101
|
+
if (entry.isDirectory()) {
|
|
16102
|
+
const pluginPath = join3(cacheDir, entry.name);
|
|
16103
|
+
const stats = await stat(pluginPath);
|
|
16104
|
+
plugins.push({
|
|
16105
|
+
name: entry.name,
|
|
16106
|
+
path: pluginPath,
|
|
16107
|
+
lastModified: stats.mtime
|
|
16108
|
+
});
|
|
16109
|
+
}
|
|
16110
|
+
}
|
|
16111
|
+
plugins.sort((a, b) => a.name.localeCompare(b.name));
|
|
16112
|
+
return plugins;
|
|
16113
|
+
}
|
|
16114
|
+
async function updateCachedPlugins(name) {
|
|
16115
|
+
const plugins = await listCachedPlugins();
|
|
16116
|
+
const results = [];
|
|
16117
|
+
const toUpdate = name ? plugins.filter((p) => p.name === name) : plugins;
|
|
16118
|
+
if (name && toUpdate.length === 0) {
|
|
16119
|
+
return [
|
|
16120
|
+
{
|
|
16121
|
+
name,
|
|
16122
|
+
success: false,
|
|
16123
|
+
error: `Plugin not found in cache: ${name}`
|
|
16124
|
+
}
|
|
16125
|
+
];
|
|
16126
|
+
}
|
|
16127
|
+
for (const plugin of toUpdate) {
|
|
16128
|
+
try {
|
|
16129
|
+
await pull(plugin.path);
|
|
16130
|
+
results.push({ name: plugin.name, success: true });
|
|
16131
|
+
} catch (error) {
|
|
16132
|
+
results.push({
|
|
16133
|
+
name: plugin.name,
|
|
16134
|
+
success: false,
|
|
16135
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
16136
|
+
});
|
|
16137
|
+
}
|
|
16138
|
+
}
|
|
16139
|
+
return results;
|
|
16140
|
+
}
|
|
16061
16141
|
function getPluginName(pluginPath) {
|
|
16062
16142
|
return basename(pluginPath);
|
|
16063
16143
|
}
|
|
@@ -16135,12 +16215,12 @@ async function updatePlugin(pluginSpec, deps) {
|
|
|
16135
16215
|
...fetchResult.error && { error: fetchResult.error }
|
|
16136
16216
|
};
|
|
16137
16217
|
}
|
|
16138
|
-
var
|
|
16218
|
+
var fetchCache;
|
|
16139
16219
|
var init_plugin = __esm(() => {
|
|
16140
16220
|
init_plugin_path();
|
|
16141
16221
|
init_constants();
|
|
16142
16222
|
init_git();
|
|
16143
|
-
|
|
16223
|
+
fetchCache = new Map;
|
|
16144
16224
|
});
|
|
16145
16225
|
|
|
16146
16226
|
// node_modules/braces/lib/utils.js
|
|
@@ -29736,6 +29816,80 @@ var init_native = __esm(() => {
|
|
|
29736
29816
|
init_registry();
|
|
29737
29817
|
});
|
|
29738
29818
|
|
|
29819
|
+
// src/utils/stopwatch.ts
|
|
29820
|
+
class Stopwatch {
|
|
29821
|
+
entries = [];
|
|
29822
|
+
active = new Map;
|
|
29823
|
+
globalStart;
|
|
29824
|
+
constructor() {
|
|
29825
|
+
this.globalStart = performance.now();
|
|
29826
|
+
}
|
|
29827
|
+
start(label) {
|
|
29828
|
+
this.active.set(label, performance.now());
|
|
29829
|
+
}
|
|
29830
|
+
stop(label, detail) {
|
|
29831
|
+
const startTime = this.active.get(label);
|
|
29832
|
+
if (startTime === undefined) {
|
|
29833
|
+
return 0;
|
|
29834
|
+
}
|
|
29835
|
+
const durationMs = performance.now() - startTime;
|
|
29836
|
+
this.active.delete(label);
|
|
29837
|
+
this.entries.push({ label, durationMs, ...detail !== undefined && { detail } });
|
|
29838
|
+
return durationMs;
|
|
29839
|
+
}
|
|
29840
|
+
async measure(label, fn, detail) {
|
|
29841
|
+
this.start(label);
|
|
29842
|
+
try {
|
|
29843
|
+
const result = await fn();
|
|
29844
|
+
this.stop(label, detail);
|
|
29845
|
+
return result;
|
|
29846
|
+
} catch (error) {
|
|
29847
|
+
this.stop(label, detail ? `${detail} (failed)` : "(failed)");
|
|
29848
|
+
throw error;
|
|
29849
|
+
}
|
|
29850
|
+
}
|
|
29851
|
+
getEntries() {
|
|
29852
|
+
return [...this.entries];
|
|
29853
|
+
}
|
|
29854
|
+
getTotalMs() {
|
|
29855
|
+
return performance.now() - this.globalStart;
|
|
29856
|
+
}
|
|
29857
|
+
formatReport() {
|
|
29858
|
+
const lines = [];
|
|
29859
|
+
const totalMs = this.getTotalMs();
|
|
29860
|
+
lines.push(`Sync timing report (total: ${formatMs(totalMs)})`);
|
|
29861
|
+
lines.push("─".repeat(60));
|
|
29862
|
+
for (const entry of this.entries) {
|
|
29863
|
+
const pct = totalMs > 0 ? (entry.durationMs / totalMs * 100).toFixed(1) : "0.0";
|
|
29864
|
+
const detail = entry.detail ? ` [${entry.detail}]` : "";
|
|
29865
|
+
lines.push(` ${padEnd(entry.label, 40)} ${padStart2(formatMs(entry.durationMs), 8)} ${padStart2(pct, 5)}%${detail}`);
|
|
29866
|
+
}
|
|
29867
|
+
lines.push("─".repeat(60));
|
|
29868
|
+
return lines;
|
|
29869
|
+
}
|
|
29870
|
+
toJSON() {
|
|
29871
|
+
return {
|
|
29872
|
+
totalMs: Math.round(this.getTotalMs()),
|
|
29873
|
+
steps: this.entries.map((e) => ({
|
|
29874
|
+
label: e.label,
|
|
29875
|
+
durationMs: Math.round(e.durationMs),
|
|
29876
|
+
...e.detail && { detail: e.detail }
|
|
29877
|
+
}))
|
|
29878
|
+
};
|
|
29879
|
+
}
|
|
29880
|
+
}
|
|
29881
|
+
function formatMs(ms) {
|
|
29882
|
+
if (ms < 1000)
|
|
29883
|
+
return `${Math.round(ms)}ms`;
|
|
29884
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
29885
|
+
}
|
|
29886
|
+
function padEnd(str3, len) {
|
|
29887
|
+
return str3.length >= len ? str3 : str3 + " ".repeat(len - str3.length);
|
|
29888
|
+
}
|
|
29889
|
+
function padStart2(str3, len) {
|
|
29890
|
+
return str3.length >= len ? str3 : " ".repeat(len - str3.length) + str3;
|
|
29891
|
+
}
|
|
29892
|
+
|
|
29739
29893
|
// src/core/sync.ts
|
|
29740
29894
|
import { existsSync as existsSync14, readFileSync as readFileSync4, writeFileSync as writeFileSync4, lstatSync } from "node:fs";
|
|
29741
29895
|
import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
|
|
@@ -29784,7 +29938,20 @@ function mergeSyncResults(a, b) {
|
|
|
29784
29938
|
...purgedPaths.length > 0 && { purgedPaths },
|
|
29785
29939
|
...deletedArtifacts.length > 0 && { deletedArtifacts },
|
|
29786
29940
|
...mcpResults && { mcpResults },
|
|
29787
|
-
...nativeResult && { nativeResult }
|
|
29941
|
+
...nativeResult && { nativeResult },
|
|
29942
|
+
...mergeTiming(a.timing, b.timing)
|
|
29943
|
+
};
|
|
29944
|
+
}
|
|
29945
|
+
function mergeTiming(a, b) {
|
|
29946
|
+
if (!a && !b)
|
|
29947
|
+
return {};
|
|
29948
|
+
const aSteps = (a?.steps ?? []).map((s) => ({ ...s, label: `user:${s.label}` }));
|
|
29949
|
+
const bSteps = (b?.steps ?? []).map((s) => ({ ...s, label: `project:${s.label}` }));
|
|
29950
|
+
return {
|
|
29951
|
+
timing: {
|
|
29952
|
+
totalMs: (a?.totalMs ?? 0) + (b?.totalMs ?? 0),
|
|
29953
|
+
steps: [...aSteps, ...bSteps]
|
|
29954
|
+
}
|
|
29788
29955
|
};
|
|
29789
29956
|
}
|
|
29790
29957
|
function resolveNativePluginSource(vp) {
|
|
@@ -30523,6 +30690,7 @@ async function persistSyncState(workspacePath, pluginResults, workspaceFileResul
|
|
|
30523
30690
|
async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
30524
30691
|
await migrateWorkspaceSkillsV1toV2(workspacePath);
|
|
30525
30692
|
const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false } = options2;
|
|
30693
|
+
const sw = new Stopwatch;
|
|
30526
30694
|
const configDir = join16(workspacePath, CONFIG_DIR);
|
|
30527
30695
|
const configPath = join16(configDir, WORKSPACE_CONFIG_FILE);
|
|
30528
30696
|
if (!existsSync14(configPath)) {
|
|
@@ -30557,11 +30725,13 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
|
30557
30725
|
]
|
|
30558
30726
|
};
|
|
30559
30727
|
}
|
|
30560
|
-
await ensureMarketplacesRegistered(filteredPlans.map((plan) => plan.source));
|
|
30561
|
-
|
|
30728
|
+
const marketplaceResults = await sw.measure("marketplace-registration", () => ensureMarketplacesRegistered(filteredPlans.map((plan) => plan.source)));
|
|
30729
|
+
await seedFetchCacheFromMarketplaces(marketplaceResults);
|
|
30730
|
+
const validatedPlugins = await sw.measure("plugin-validation", () => validateAllPlugins(filteredPlans, workspacePath, offline), `${filteredPlans.length} plugin(s)`);
|
|
30562
30731
|
let validatedWorkspaceSource = null;
|
|
30563
30732
|
const workspaceSourceWarnings = [];
|
|
30564
30733
|
if (config.workspace?.source) {
|
|
30734
|
+
sw.start("workspace-source-validation");
|
|
30565
30735
|
const sourceBasePath = workspaceSourceBase ?? workspacePath;
|
|
30566
30736
|
const wsSourceResult = await validatePlugin(config.workspace.source, sourceBasePath, offline);
|
|
30567
30737
|
if (wsSourceResult.success) {
|
|
@@ -30569,6 +30739,7 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
|
30569
30739
|
} else {
|
|
30570
30740
|
workspaceSourceWarnings.push(`Workspace source: ${wsSourceResult.error}`);
|
|
30571
30741
|
}
|
|
30742
|
+
sw.stop("workspace-source-validation");
|
|
30572
30743
|
}
|
|
30573
30744
|
const failedValidations = validatedPlugins.filter((v) => !v.success);
|
|
30574
30745
|
const validPlugins = validatedPlugins.filter((v) => v.success);
|
|
@@ -30589,23 +30760,24 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30589
30760
|
paths: getPreviouslySyncedFiles(previousState, client)
|
|
30590
30761
|
})).filter((p) => p.paths.length > 0) : [];
|
|
30591
30762
|
if (!dryRun) {
|
|
30592
|
-
await selectivePurgeWorkspace(workspacePath, previousState, syncClients);
|
|
30763
|
+
await sw.measure("selective-purge", () => selectivePurgeWorkspace(workspacePath, previousState, syncClients));
|
|
30593
30764
|
}
|
|
30594
30765
|
const isV1Fallback = config.version === undefined || config.version < 2;
|
|
30595
30766
|
const disabledSkillsSet = isV1Fallback ? new Set(config.disabledSkills ?? []) : undefined;
|
|
30596
30767
|
const enabledSkillsSet = isV1Fallback && config.enabledSkills ? new Set(config.enabledSkills) : undefined;
|
|
30597
|
-
const allSkills = await collectAllSkills(validPlugins, disabledSkillsSet, enabledSkillsSet);
|
|
30768
|
+
const allSkills = await sw.measure("skill-collection", () => collectAllSkills(validPlugins, disabledSkillsSet, enabledSkillsSet));
|
|
30598
30769
|
const pluginSkillMaps = buildPluginSkillNameMaps(allSkills);
|
|
30599
30770
|
const syncMode = config.syncMode ?? "symlink";
|
|
30600
|
-
const pluginResults = await Promise.all(validPlugins.map(async (validatedPlugin) => {
|
|
30771
|
+
const pluginResults = await sw.measure("plugin-copy", () => Promise.all(validPlugins.map(async (validatedPlugin) => {
|
|
30601
30772
|
const skillNameMap = pluginSkillMaps.get(validatedPlugin.resolved);
|
|
30602
30773
|
const result = await copyValidatedPlugin(validatedPlugin, workspacePath, validatedPlugin.clients, dryRun, skillNameMap, undefined, syncMode);
|
|
30603
30774
|
return { ...result, scope: "project" };
|
|
30604
|
-
}));
|
|
30605
|
-
const nativeResult = await syncNativePlugins(validPlugins, previousState, "project", workspacePath, dryRun, warnings, messages);
|
|
30775
|
+
})), `${validPlugins.length} plugin(s)`);
|
|
30776
|
+
const nativeResult = await sw.measure("native-plugin-sync", () => syncNativePlugins(validPlugins, previousState, "project", workspacePath, dryRun, warnings, messages));
|
|
30606
30777
|
let workspaceFileResults = [];
|
|
30607
30778
|
const skipWorkspaceFiles = !!config.workspace?.source && !validatedWorkspaceSource;
|
|
30608
30779
|
if (config.workspace && !skipWorkspaceFiles) {
|
|
30780
|
+
sw.start("workspace-files");
|
|
30609
30781
|
const sourcePath = validatedWorkspaceSource?.resolved;
|
|
30610
30782
|
const filesToCopy = [...config.workspace.files];
|
|
30611
30783
|
if (hasRepositories && sourcePath) {
|
|
@@ -30642,18 +30814,20 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
30642
30814
|
await copyFile(agentsPath, claudePath);
|
|
30643
30815
|
}
|
|
30644
30816
|
}
|
|
30817
|
+
sw.stop("workspace-files");
|
|
30645
30818
|
}
|
|
30646
30819
|
if (!config.workspace && !dryRun && !skipAgentFiles) {
|
|
30647
30820
|
await updateAgentFiles(workspacePath);
|
|
30648
30821
|
}
|
|
30649
30822
|
let vscodeState;
|
|
30650
30823
|
if (syncClients.includes("vscode") && !dryRun) {
|
|
30651
|
-
const result = await syncVscodeWorkspaceFile(workspacePath, config, configPath, previousState, messages);
|
|
30824
|
+
const result = await sw.measure("vscode-workspace-file", () => syncVscodeWorkspaceFile(workspacePath, config, configPath, previousState, messages));
|
|
30652
30825
|
config = result.config;
|
|
30653
30826
|
if (result.hash && result.repos) {
|
|
30654
30827
|
vscodeState = { hash: result.hash, repos: result.repos };
|
|
30655
30828
|
}
|
|
30656
30829
|
}
|
|
30830
|
+
sw.start("mcp-sync");
|
|
30657
30831
|
const mcpResults = {};
|
|
30658
30832
|
if (syncClients.includes("vscode")) {
|
|
30659
30833
|
const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
|
|
@@ -30711,6 +30885,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
30711
30885
|
}
|
|
30712
30886
|
mcpResults.copilot = copilotMcp;
|
|
30713
30887
|
}
|
|
30888
|
+
sw.stop("mcp-sync");
|
|
30714
30889
|
const PROJECT_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
|
|
30715
30890
|
const { servers: allMcpServers } = collectMcpServers(validPlugins);
|
|
30716
30891
|
if (allMcpServers.size > 0) {
|
|
@@ -30729,12 +30904,12 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
30729
30904
|
const deletedArtifacts = computeDeletedArtifacts(previousState, newStatePaths, syncClients, resolvedMappings, availableSkillNames);
|
|
30730
30905
|
const { pluginsByClient: nativePluginsByClient } = collectNativePluginSources(validPlugins);
|
|
30731
30906
|
if (!dryRun) {
|
|
30732
|
-
await persistSyncState(workspacePath, pluginResults, workspaceFileResults, syncClients, nativePluginsByClient, nativeResult, {
|
|
30907
|
+
await sw.measure("persist-state", () => persistSyncState(workspacePath, pluginResults, workspaceFileResults, syncClients, nativePluginsByClient, nativeResult, {
|
|
30733
30908
|
...vscodeState && { vscodeState },
|
|
30734
30909
|
...Object.keys(mcpResults).length > 0 && {
|
|
30735
30910
|
mcpTrackedServers: Object.fromEntries(Object.entries(mcpResults).map(([scope, r]) => [scope, r.trackedServers]))
|
|
30736
30911
|
}
|
|
30737
|
-
});
|
|
30912
|
+
}));
|
|
30738
30913
|
}
|
|
30739
30914
|
return {
|
|
30740
30915
|
success: !hasFailures,
|
|
@@ -30748,11 +30923,36 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
30748
30923
|
...warnings.length > 0 && { warnings },
|
|
30749
30924
|
...messages.length > 0 && { messages },
|
|
30750
30925
|
...Object.keys(mcpResults).length > 0 && { mcpResults },
|
|
30751
|
-
...nativeResult && { nativeResult }
|
|
30926
|
+
...nativeResult && { nativeResult },
|
|
30927
|
+
timing: sw.toJSON()
|
|
30752
30928
|
};
|
|
30753
30929
|
}
|
|
30930
|
+
async function seedFetchCacheFromMarketplaces(results) {
|
|
30931
|
+
for (const result of results) {
|
|
30932
|
+
if (!result.success || !result.name)
|
|
30933
|
+
continue;
|
|
30934
|
+
const entry = await getMarketplace(result.name);
|
|
30935
|
+
if (!entry || entry.source.type !== "github")
|
|
30936
|
+
continue;
|
|
30937
|
+
seedFetchCache(entry.source.location, entry.path);
|
|
30938
|
+
const branch = readGitBranch(entry.path);
|
|
30939
|
+
if (branch) {
|
|
30940
|
+
seedFetchCache(entry.source.location, entry.path, branch);
|
|
30941
|
+
}
|
|
30942
|
+
}
|
|
30943
|
+
}
|
|
30944
|
+
function readGitBranch(repoPath) {
|
|
30945
|
+
try {
|
|
30946
|
+
const head = readFileSync4(join16(repoPath, ".git", "HEAD"), "utf-8").trim();
|
|
30947
|
+
const prefix = "ref: refs/heads/";
|
|
30948
|
+
return head.startsWith(prefix) ? head.slice(prefix.length) : null;
|
|
30949
|
+
} catch {
|
|
30950
|
+
return null;
|
|
30951
|
+
}
|
|
30952
|
+
}
|
|
30754
30953
|
async function syncUserWorkspace(options2 = {}) {
|
|
30755
30954
|
await migrateUserWorkspaceSkillsV1toV2();
|
|
30955
|
+
const sw = new Stopwatch;
|
|
30756
30956
|
const homeDir = resolve9(getHomeDir());
|
|
30757
30957
|
const config = await getUserWorkspaceConfig();
|
|
30758
30958
|
if (!config) {
|
|
@@ -30770,8 +30970,9 @@ async function syncUserWorkspace(options2 = {}) {
|
|
|
30770
30970
|
const { plans: allPluginPlans, warnings: planWarnings } = buildPluginSyncPlans(config.plugins, workspaceClients, "user");
|
|
30771
30971
|
const pluginPlans = allPluginPlans.filter((plan) => plan.clients.length > 0 || plan.nativeClients.length > 0);
|
|
30772
30972
|
const syncClients = collectSyncClients(workspaceClients, pluginPlans);
|
|
30773
|
-
await ensureMarketplacesRegistered(pluginPlans.map((plan) => plan.source));
|
|
30774
|
-
|
|
30973
|
+
const marketplaceResults = await sw.measure("marketplace-registration", () => ensureMarketplacesRegistered(pluginPlans.map((plan) => plan.source)));
|
|
30974
|
+
await seedFetchCacheFromMarketplaces(marketplaceResults);
|
|
30975
|
+
const validatedPlugins = await sw.measure("plugin-validation", () => validateAllPlugins(pluginPlans, homeDir, offline), `${pluginPlans.length} plugin(s)`);
|
|
30775
30976
|
const failedValidations = validatedPlugins.filter((v) => !v.success);
|
|
30776
30977
|
const validPlugins = validatedPlugins.filter((v) => v.success);
|
|
30777
30978
|
const warnings = [
|
|
@@ -30786,21 +30987,22 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30786
30987
|
}
|
|
30787
30988
|
const previousState = await loadSyncState(homeDir);
|
|
30788
30989
|
if (!dryRun) {
|
|
30789
|
-
await selectivePurgeWorkspace(homeDir, previousState, syncClients);
|
|
30990
|
+
await sw.measure("selective-purge", () => selectivePurgeWorkspace(homeDir, previousState, syncClients));
|
|
30790
30991
|
}
|
|
30791
30992
|
const isV1FallbackUser = config.version === undefined || config.version < 2;
|
|
30792
30993
|
const disabledSkillsSet = isV1FallbackUser ? new Set(config.disabledSkills ?? []) : undefined;
|
|
30793
30994
|
const enabledSkillsSet = isV1FallbackUser && config.enabledSkills ? new Set(config.enabledSkills) : undefined;
|
|
30794
|
-
const allSkills = await collectAllSkills(validPlugins, disabledSkillsSet, enabledSkillsSet);
|
|
30995
|
+
const allSkills = await sw.measure("skill-collection", () => collectAllSkills(validPlugins, disabledSkillsSet, enabledSkillsSet));
|
|
30795
30996
|
const pluginSkillMaps = buildPluginSkillNameMaps(allSkills);
|
|
30796
30997
|
const syncMode = config.syncMode ?? "symlink";
|
|
30797
|
-
const pluginResults = await Promise.all(validPlugins.map(async (vp) => {
|
|
30998
|
+
const pluginResults = await sw.measure("plugin-copy", () => Promise.all(validPlugins.map(async (vp) => {
|
|
30798
30999
|
const skillNameMap = pluginSkillMaps.get(vp.resolved);
|
|
30799
31000
|
const resolvedUserMappings2 = resolveClientMappings(vp.clients, USER_CLIENT_MAPPINGS);
|
|
30800
31001
|
const result = await copyValidatedPlugin(vp, homeDir, vp.clients, dryRun, skillNameMap, resolvedUserMappings2, syncMode);
|
|
30801
31002
|
return { ...result, scope: "user" };
|
|
30802
|
-
}));
|
|
31003
|
+
})), `${validPlugins.length} plugin(s)`);
|
|
30803
31004
|
const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, []);
|
|
31005
|
+
sw.start("mcp-sync");
|
|
30804
31006
|
const mcpResults = {};
|
|
30805
31007
|
if (syncClients.includes("vscode")) {
|
|
30806
31008
|
const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
|
|
@@ -30840,6 +31042,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30840
31042
|
}
|
|
30841
31043
|
mcpResults.copilot = copilotMcp;
|
|
30842
31044
|
}
|
|
31045
|
+
sw.stop("mcp-sync");
|
|
30843
31046
|
const USER_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
|
|
30844
31047
|
const { servers: allUserMcpServers } = collectMcpServers(validPlugins);
|
|
30845
31048
|
if (allUserMcpServers.size > 0) {
|
|
@@ -30849,7 +31052,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30849
31052
|
}
|
|
30850
31053
|
}
|
|
30851
31054
|
}
|
|
30852
|
-
const nativeResult = await syncNativePlugins(validPlugins, previousState, "user", homeDir, dryRun, warnings, messages);
|
|
31055
|
+
const nativeResult = await sw.measure("native-plugin-sync", () => syncNativePlugins(validPlugins, previousState, "user", homeDir, dryRun, warnings, messages));
|
|
30853
31056
|
const availableUserSkillNames = await collectAvailableSkillNames(validPlugins);
|
|
30854
31057
|
const allCopyResultsForState = pluginResults.flatMap((r) => r.copyResults);
|
|
30855
31058
|
const resolvedUserMappings = resolveClientMappings(syncClients, USER_CLIENT_MAPPINGS);
|
|
@@ -30857,12 +31060,12 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30857
31060
|
const deletedArtifacts = computeDeletedArtifacts(previousState, newStatePaths, syncClients, resolvedUserMappings, availableUserSkillNames);
|
|
30858
31061
|
if (!dryRun) {
|
|
30859
31062
|
const { pluginsByClient: nativePluginsByClient } = collectNativePluginSources(validPlugins);
|
|
30860
|
-
await persistSyncState(homeDir, pluginResults, [], syncClients, nativePluginsByClient, nativeResult, {
|
|
31063
|
+
await sw.measure("persist-state", () => persistSyncState(homeDir, pluginResults, [], syncClients, nativePluginsByClient, nativeResult, {
|
|
30861
31064
|
clientMappings: USER_CLIENT_MAPPINGS,
|
|
30862
31065
|
...Object.keys(mcpResults).length > 0 && {
|
|
30863
31066
|
mcpTrackedServers: Object.fromEntries(Object.entries(mcpResults).map(([scope, r]) => [scope, r.trackedServers]))
|
|
30864
31067
|
}
|
|
30865
|
-
});
|
|
31068
|
+
}));
|
|
30866
31069
|
}
|
|
30867
31070
|
return {
|
|
30868
31071
|
success: totalFailed === 0,
|
|
@@ -30875,7 +31078,8 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30875
31078
|
...warnings.length > 0 && { warnings },
|
|
30876
31079
|
...messages.length > 0 && { messages },
|
|
30877
31080
|
...Object.keys(mcpResults).length > 0 && { mcpResults },
|
|
30878
|
-
...nativeResult && { nativeResult }
|
|
31081
|
+
...nativeResult && { nativeResult },
|
|
31082
|
+
timing: sw.toJSON()
|
|
30879
31083
|
};
|
|
30880
31084
|
}
|
|
30881
31085
|
var import_json53, VSCODE_TEMPLATE_FILE = "template.code-workspace";
|
|
@@ -34103,7 +34307,7 @@ var package_default;
|
|
|
34103
34307
|
var init_package = __esm(() => {
|
|
34104
34308
|
package_default = {
|
|
34105
34309
|
name: "allagents",
|
|
34106
|
-
version: "1.4.
|
|
34310
|
+
version: "1.4.10",
|
|
34107
34311
|
description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
|
|
34108
34312
|
type: "module",
|
|
34109
34313
|
bin: {
|
|
@@ -36080,6 +36284,8 @@ var syncCmd = import_cmd_ts2.command({
|
|
|
36080
36284
|
return;
|
|
36081
36285
|
}
|
|
36082
36286
|
let combined = null;
|
|
36287
|
+
const { resetFetchCache: resetFetchCache2 } = await Promise.resolve().then(() => (init_plugin(), exports_plugin));
|
|
36288
|
+
resetFetchCache2();
|
|
36083
36289
|
if (userConfigExists) {
|
|
36084
36290
|
const userResult = await syncUserWorkspace({ offline, dryRun, force });
|
|
36085
36291
|
combined = userResult;
|
|
@@ -36182,6 +36388,20 @@ native:`);
|
|
|
36182
36388
|
console.log(line);
|
|
36183
36389
|
}
|
|
36184
36390
|
}
|
|
36391
|
+
if (process.env.ALLAGENTS_DEBUG?.includes("timing") && result.timing) {
|
|
36392
|
+
console.error("");
|
|
36393
|
+
const totalMs = result.timing.totalMs;
|
|
36394
|
+
console.error(`[debug] Sync timing (total: ${formatTimingMs(totalMs)})`);
|
|
36395
|
+
console.error(`[debug] ${"─".repeat(56)}`);
|
|
36396
|
+
for (const step of result.timing.steps) {
|
|
36397
|
+
const pct = totalMs > 0 ? (step.durationMs / totalMs * 100).toFixed(1) : "0.0";
|
|
36398
|
+
const detail = step.detail ? ` [${step.detail}]` : "";
|
|
36399
|
+
const label = step.label.padEnd(40);
|
|
36400
|
+
const duration = formatTimingMs(step.durationMs).padStart(8);
|
|
36401
|
+
console.error(`[debug] ${label} ${duration} ${pct.padStart(5)}%${detail}`);
|
|
36402
|
+
}
|
|
36403
|
+
console.error(`[debug] ${"─".repeat(56)}`);
|
|
36404
|
+
}
|
|
36185
36405
|
if (!result.success || result.totalFailed > 0) {
|
|
36186
36406
|
process.exit(1);
|
|
36187
36407
|
}
|
|
@@ -36198,6 +36418,11 @@ native:`);
|
|
|
36198
36418
|
}
|
|
36199
36419
|
}
|
|
36200
36420
|
});
|
|
36421
|
+
function formatTimingMs(ms) {
|
|
36422
|
+
if (ms < 1000)
|
|
36423
|
+
return `${Math.round(ms)}ms`;
|
|
36424
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
36425
|
+
}
|
|
36201
36426
|
var statusCmd = import_cmd_ts2.command({
|
|
36202
36427
|
name: "status",
|
|
36203
36428
|
description: buildDescription(statusMeta),
|