allagents 1.4.9 → 1.4.11
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 +301 -42
- package/package.json +3 -3
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
|
|
@@ -28252,6 +28332,21 @@ async function updateRepositories(changes, workspacePath = process.cwd()) {
|
|
|
28252
28332
|
};
|
|
28253
28333
|
}
|
|
28254
28334
|
}
|
|
28335
|
+
async function setRepositories(repositories, workspacePath = process.cwd()) {
|
|
28336
|
+
const configPath = join11(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
28337
|
+
try {
|
|
28338
|
+
const content = await readFile7(configPath, "utf-8");
|
|
28339
|
+
const config = load(content);
|
|
28340
|
+
config.repositories = repositories;
|
|
28341
|
+
await writeFile4(configPath, dump(config, { lineWidth: -1 }), "utf-8");
|
|
28342
|
+
return { success: true };
|
|
28343
|
+
} catch (error) {
|
|
28344
|
+
return {
|
|
28345
|
+
success: false,
|
|
28346
|
+
error: error instanceof Error ? error.message : String(error)
|
|
28347
|
+
};
|
|
28348
|
+
}
|
|
28349
|
+
}
|
|
28255
28350
|
var DEFAULT_PROJECT_CLIENTS;
|
|
28256
28351
|
var init_workspace_modify = __esm(() => {
|
|
28257
28352
|
init_js_yaml();
|
|
@@ -28729,6 +28824,7 @@ function reconcileVscodeWorkspaceFolders(workspacePath, codeWorkspaceFolders, la
|
|
|
28729
28824
|
const currentAbsPaths = new Set(currentReposByAbsPath.keys());
|
|
28730
28825
|
const added = [];
|
|
28731
28826
|
const removed = [];
|
|
28827
|
+
const renamed2 = [];
|
|
28732
28828
|
const updatedRepos = [];
|
|
28733
28829
|
for (const [absPath, repo] of currentReposByAbsPath) {
|
|
28734
28830
|
const inLastSync = lastSyncedSet.has(absPath);
|
|
@@ -28736,7 +28832,19 @@ function reconcileVscodeWorkspaceFolders(workspacePath, codeWorkspaceFolders, la
|
|
|
28736
28832
|
if (inLastSync && !inCodeWorkspace) {
|
|
28737
28833
|
removed.push(repo.path);
|
|
28738
28834
|
} else {
|
|
28739
|
-
|
|
28835
|
+
const folderName = codeWorkspaceNames.get(absPath);
|
|
28836
|
+
if (folderName !== repo.name) {
|
|
28837
|
+
const updatedRepo = { ...repo };
|
|
28838
|
+
if (folderName === undefined) {
|
|
28839
|
+
delete updatedRepo.name;
|
|
28840
|
+
} else {
|
|
28841
|
+
updatedRepo.name = folderName;
|
|
28842
|
+
}
|
|
28843
|
+
updatedRepos.push(updatedRepo);
|
|
28844
|
+
renamed2.push(repo.path);
|
|
28845
|
+
} else {
|
|
28846
|
+
updatedRepos.push(repo);
|
|
28847
|
+
}
|
|
28740
28848
|
}
|
|
28741
28849
|
}
|
|
28742
28850
|
for (const absPath of codeWorkspaceAbsPaths) {
|
|
@@ -28752,7 +28860,7 @@ function reconcileVscodeWorkspaceFolders(workspacePath, codeWorkspaceFolders, la
|
|
|
28752
28860
|
updatedRepos.push(newRepo);
|
|
28753
28861
|
}
|
|
28754
28862
|
}
|
|
28755
|
-
return { updatedRepos, added, removed };
|
|
28863
|
+
return { updatedRepos, added, removed, renamed: renamed2 };
|
|
28756
28864
|
}
|
|
28757
28865
|
var DEFAULT_SETTINGS;
|
|
28758
28866
|
var init_vscode_workspace = __esm(() => {
|
|
@@ -29736,6 +29844,80 @@ var init_native = __esm(() => {
|
|
|
29736
29844
|
init_registry();
|
|
29737
29845
|
});
|
|
29738
29846
|
|
|
29847
|
+
// src/utils/stopwatch.ts
|
|
29848
|
+
class Stopwatch {
|
|
29849
|
+
entries = [];
|
|
29850
|
+
active = new Map;
|
|
29851
|
+
globalStart;
|
|
29852
|
+
constructor() {
|
|
29853
|
+
this.globalStart = performance.now();
|
|
29854
|
+
}
|
|
29855
|
+
start(label) {
|
|
29856
|
+
this.active.set(label, performance.now());
|
|
29857
|
+
}
|
|
29858
|
+
stop(label, detail) {
|
|
29859
|
+
const startTime = this.active.get(label);
|
|
29860
|
+
if (startTime === undefined) {
|
|
29861
|
+
return 0;
|
|
29862
|
+
}
|
|
29863
|
+
const durationMs = performance.now() - startTime;
|
|
29864
|
+
this.active.delete(label);
|
|
29865
|
+
this.entries.push({ label, durationMs, ...detail !== undefined && { detail } });
|
|
29866
|
+
return durationMs;
|
|
29867
|
+
}
|
|
29868
|
+
async measure(label, fn, detail) {
|
|
29869
|
+
this.start(label);
|
|
29870
|
+
try {
|
|
29871
|
+
const result = await fn();
|
|
29872
|
+
this.stop(label, detail);
|
|
29873
|
+
return result;
|
|
29874
|
+
} catch (error) {
|
|
29875
|
+
this.stop(label, detail ? `${detail} (failed)` : "(failed)");
|
|
29876
|
+
throw error;
|
|
29877
|
+
}
|
|
29878
|
+
}
|
|
29879
|
+
getEntries() {
|
|
29880
|
+
return [...this.entries];
|
|
29881
|
+
}
|
|
29882
|
+
getTotalMs() {
|
|
29883
|
+
return performance.now() - this.globalStart;
|
|
29884
|
+
}
|
|
29885
|
+
formatReport() {
|
|
29886
|
+
const lines = [];
|
|
29887
|
+
const totalMs = this.getTotalMs();
|
|
29888
|
+
lines.push(`Sync timing report (total: ${formatMs(totalMs)})`);
|
|
29889
|
+
lines.push("─".repeat(60));
|
|
29890
|
+
for (const entry of this.entries) {
|
|
29891
|
+
const pct = totalMs > 0 ? (entry.durationMs / totalMs * 100).toFixed(1) : "0.0";
|
|
29892
|
+
const detail = entry.detail ? ` [${entry.detail}]` : "";
|
|
29893
|
+
lines.push(` ${padEnd(entry.label, 40)} ${padStart2(formatMs(entry.durationMs), 8)} ${padStart2(pct, 5)}%${detail}`);
|
|
29894
|
+
}
|
|
29895
|
+
lines.push("─".repeat(60));
|
|
29896
|
+
return lines;
|
|
29897
|
+
}
|
|
29898
|
+
toJSON() {
|
|
29899
|
+
return {
|
|
29900
|
+
totalMs: Math.round(this.getTotalMs()),
|
|
29901
|
+
steps: this.entries.map((e) => ({
|
|
29902
|
+
label: e.label,
|
|
29903
|
+
durationMs: Math.round(e.durationMs),
|
|
29904
|
+
...e.detail && { detail: e.detail }
|
|
29905
|
+
}))
|
|
29906
|
+
};
|
|
29907
|
+
}
|
|
29908
|
+
}
|
|
29909
|
+
function formatMs(ms) {
|
|
29910
|
+
if (ms < 1000)
|
|
29911
|
+
return `${Math.round(ms)}ms`;
|
|
29912
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
29913
|
+
}
|
|
29914
|
+
function padEnd(str3, len) {
|
|
29915
|
+
return str3.length >= len ? str3 : str3 + " ".repeat(len - str3.length);
|
|
29916
|
+
}
|
|
29917
|
+
function padStart2(str3, len) {
|
|
29918
|
+
return str3.length >= len ? str3 : " ".repeat(len - str3.length) + str3;
|
|
29919
|
+
}
|
|
29920
|
+
|
|
29739
29921
|
// src/core/sync.ts
|
|
29740
29922
|
import { existsSync as existsSync14, readFileSync as readFileSync4, writeFileSync as writeFileSync4, lstatSync } from "node:fs";
|
|
29741
29923
|
import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
|
|
@@ -29784,7 +29966,20 @@ function mergeSyncResults(a, b) {
|
|
|
29784
29966
|
...purgedPaths.length > 0 && { purgedPaths },
|
|
29785
29967
|
...deletedArtifacts.length > 0 && { deletedArtifacts },
|
|
29786
29968
|
...mcpResults && { mcpResults },
|
|
29787
|
-
...nativeResult && { nativeResult }
|
|
29969
|
+
...nativeResult && { nativeResult },
|
|
29970
|
+
...mergeTiming(a.timing, b.timing)
|
|
29971
|
+
};
|
|
29972
|
+
}
|
|
29973
|
+
function mergeTiming(a, b) {
|
|
29974
|
+
if (!a && !b)
|
|
29975
|
+
return {};
|
|
29976
|
+
const aSteps = (a?.steps ?? []).map((s) => ({ ...s, label: `user:${s.label}` }));
|
|
29977
|
+
const bSteps = (b?.steps ?? []).map((s) => ({ ...s, label: `project:${s.label}` }));
|
|
29978
|
+
return {
|
|
29979
|
+
timing: {
|
|
29980
|
+
totalMs: (a?.totalMs ?? 0) + (b?.totalMs ?? 0),
|
|
29981
|
+
steps: [...aSteps, ...bSteps]
|
|
29982
|
+
}
|
|
29788
29983
|
};
|
|
29789
29984
|
}
|
|
29790
29985
|
function resolveNativePluginSource(vp) {
|
|
@@ -30474,8 +30669,11 @@ async function syncVscodeWorkspaceFile(workspacePath, config, configPath, previo
|
|
|
30474
30669
|
const existingWorkspace = JSON.parse(existingContent);
|
|
30475
30670
|
const folders = Array.isArray(existingWorkspace.folders) ? existingWorkspace.folders : [];
|
|
30476
30671
|
const reconciled = reconcileVscodeWorkspaceFolders(workspacePath, folders, previousState.vscodeWorkspaceRepos, config.repositories);
|
|
30477
|
-
if (reconciled.added.length > 0 || reconciled.removed.length > 0) {
|
|
30478
|
-
await updateRepositories({ remove: reconciled.removed, add: reconciled.added.map((p) => ({ path: p })) }, workspacePath);
|
|
30672
|
+
if (reconciled.added.length > 0 || reconciled.removed.length > 0 || reconciled.renamed.length > 0) {
|
|
30673
|
+
const updateResult = reconciled.renamed.length > 0 ? await setRepositories(reconciled.updatedRepos, workspacePath) : await updateRepositories({ remove: reconciled.removed, add: reconciled.added.map((p) => ({ path: p })) }, workspacePath);
|
|
30674
|
+
if (!updateResult.success) {
|
|
30675
|
+
throw new Error(updateResult.error ?? "Failed to update repositories");
|
|
30676
|
+
}
|
|
30479
30677
|
updatedConfig = await parseWorkspaceConfig(configPath);
|
|
30480
30678
|
if (reconciled.removed.length > 0) {
|
|
30481
30679
|
messages.push(`Repositories removed (from .code-workspace): ${reconciled.removed.join(", ")}`);
|
|
@@ -30483,6 +30681,9 @@ async function syncVscodeWorkspaceFile(workspacePath, config, configPath, previo
|
|
|
30483
30681
|
if (reconciled.added.length > 0) {
|
|
30484
30682
|
messages.push(`Repositories added (from .code-workspace): ${reconciled.added.join(", ")}`);
|
|
30485
30683
|
}
|
|
30684
|
+
if (reconciled.renamed.length > 0) {
|
|
30685
|
+
messages.push(`Repository names updated (from .code-workspace): ${reconciled.renamed.join(", ")}`);
|
|
30686
|
+
}
|
|
30486
30687
|
}
|
|
30487
30688
|
} catch {}
|
|
30488
30689
|
}
|
|
@@ -30523,6 +30724,7 @@ async function persistSyncState(workspacePath, pluginResults, workspaceFileResul
|
|
|
30523
30724
|
async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
30524
30725
|
await migrateWorkspaceSkillsV1toV2(workspacePath);
|
|
30525
30726
|
const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false } = options2;
|
|
30727
|
+
const sw = new Stopwatch;
|
|
30526
30728
|
const configDir = join16(workspacePath, CONFIG_DIR);
|
|
30527
30729
|
const configPath = join16(configDir, WORKSPACE_CONFIG_FILE);
|
|
30528
30730
|
if (!existsSync14(configPath)) {
|
|
@@ -30557,11 +30759,13 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
|
30557
30759
|
]
|
|
30558
30760
|
};
|
|
30559
30761
|
}
|
|
30560
|
-
await ensureMarketplacesRegistered(filteredPlans.map((plan) => plan.source));
|
|
30561
|
-
|
|
30762
|
+
const marketplaceResults = await sw.measure("marketplace-registration", () => ensureMarketplacesRegistered(filteredPlans.map((plan) => plan.source)));
|
|
30763
|
+
await seedFetchCacheFromMarketplaces(marketplaceResults);
|
|
30764
|
+
const validatedPlugins = await sw.measure("plugin-validation", () => validateAllPlugins(filteredPlans, workspacePath, offline), `${filteredPlans.length} plugin(s)`);
|
|
30562
30765
|
let validatedWorkspaceSource = null;
|
|
30563
30766
|
const workspaceSourceWarnings = [];
|
|
30564
30767
|
if (config.workspace?.source) {
|
|
30768
|
+
sw.start("workspace-source-validation");
|
|
30565
30769
|
const sourceBasePath = workspaceSourceBase ?? workspacePath;
|
|
30566
30770
|
const wsSourceResult = await validatePlugin(config.workspace.source, sourceBasePath, offline);
|
|
30567
30771
|
if (wsSourceResult.success) {
|
|
@@ -30569,6 +30773,7 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
|
30569
30773
|
} else {
|
|
30570
30774
|
workspaceSourceWarnings.push(`Workspace source: ${wsSourceResult.error}`);
|
|
30571
30775
|
}
|
|
30776
|
+
sw.stop("workspace-source-validation");
|
|
30572
30777
|
}
|
|
30573
30778
|
const failedValidations = validatedPlugins.filter((v) => !v.success);
|
|
30574
30779
|
const validPlugins = validatedPlugins.filter((v) => v.success);
|
|
@@ -30589,23 +30794,24 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30589
30794
|
paths: getPreviouslySyncedFiles(previousState, client)
|
|
30590
30795
|
})).filter((p) => p.paths.length > 0) : [];
|
|
30591
30796
|
if (!dryRun) {
|
|
30592
|
-
await selectivePurgeWorkspace(workspacePath, previousState, syncClients);
|
|
30797
|
+
await sw.measure("selective-purge", () => selectivePurgeWorkspace(workspacePath, previousState, syncClients));
|
|
30593
30798
|
}
|
|
30594
30799
|
const isV1Fallback = config.version === undefined || config.version < 2;
|
|
30595
30800
|
const disabledSkillsSet = isV1Fallback ? new Set(config.disabledSkills ?? []) : undefined;
|
|
30596
30801
|
const enabledSkillsSet = isV1Fallback && config.enabledSkills ? new Set(config.enabledSkills) : undefined;
|
|
30597
|
-
const allSkills = await collectAllSkills(validPlugins, disabledSkillsSet, enabledSkillsSet);
|
|
30802
|
+
const allSkills = await sw.measure("skill-collection", () => collectAllSkills(validPlugins, disabledSkillsSet, enabledSkillsSet));
|
|
30598
30803
|
const pluginSkillMaps = buildPluginSkillNameMaps(allSkills);
|
|
30599
30804
|
const syncMode = config.syncMode ?? "symlink";
|
|
30600
|
-
const pluginResults = await Promise.all(validPlugins.map(async (validatedPlugin) => {
|
|
30805
|
+
const pluginResults = await sw.measure("plugin-copy", () => Promise.all(validPlugins.map(async (validatedPlugin) => {
|
|
30601
30806
|
const skillNameMap = pluginSkillMaps.get(validatedPlugin.resolved);
|
|
30602
30807
|
const result = await copyValidatedPlugin(validatedPlugin, workspacePath, validatedPlugin.clients, dryRun, skillNameMap, undefined, syncMode);
|
|
30603
30808
|
return { ...result, scope: "project" };
|
|
30604
|
-
}));
|
|
30605
|
-
const nativeResult = await syncNativePlugins(validPlugins, previousState, "project", workspacePath, dryRun, warnings, messages);
|
|
30809
|
+
})), `${validPlugins.length} plugin(s)`);
|
|
30810
|
+
const nativeResult = await sw.measure("native-plugin-sync", () => syncNativePlugins(validPlugins, previousState, "project", workspacePath, dryRun, warnings, messages));
|
|
30606
30811
|
let workspaceFileResults = [];
|
|
30607
30812
|
const skipWorkspaceFiles = !!config.workspace?.source && !validatedWorkspaceSource;
|
|
30608
30813
|
if (config.workspace && !skipWorkspaceFiles) {
|
|
30814
|
+
sw.start("workspace-files");
|
|
30609
30815
|
const sourcePath = validatedWorkspaceSource?.resolved;
|
|
30610
30816
|
const filesToCopy = [...config.workspace.files];
|
|
30611
30817
|
if (hasRepositories && sourcePath) {
|
|
@@ -30642,18 +30848,20 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
30642
30848
|
await copyFile(agentsPath, claudePath);
|
|
30643
30849
|
}
|
|
30644
30850
|
}
|
|
30851
|
+
sw.stop("workspace-files");
|
|
30645
30852
|
}
|
|
30646
30853
|
if (!config.workspace && !dryRun && !skipAgentFiles) {
|
|
30647
30854
|
await updateAgentFiles(workspacePath);
|
|
30648
30855
|
}
|
|
30649
30856
|
let vscodeState;
|
|
30650
30857
|
if (syncClients.includes("vscode") && !dryRun) {
|
|
30651
|
-
const result = await syncVscodeWorkspaceFile(workspacePath, config, configPath, previousState, messages);
|
|
30858
|
+
const result = await sw.measure("vscode-workspace-file", () => syncVscodeWorkspaceFile(workspacePath, config, configPath, previousState, messages));
|
|
30652
30859
|
config = result.config;
|
|
30653
30860
|
if (result.hash && result.repos) {
|
|
30654
30861
|
vscodeState = { hash: result.hash, repos: result.repos };
|
|
30655
30862
|
}
|
|
30656
30863
|
}
|
|
30864
|
+
sw.start("mcp-sync");
|
|
30657
30865
|
const mcpResults = {};
|
|
30658
30866
|
if (syncClients.includes("vscode")) {
|
|
30659
30867
|
const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
|
|
@@ -30711,6 +30919,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
30711
30919
|
}
|
|
30712
30920
|
mcpResults.copilot = copilotMcp;
|
|
30713
30921
|
}
|
|
30922
|
+
sw.stop("mcp-sync");
|
|
30714
30923
|
const PROJECT_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
|
|
30715
30924
|
const { servers: allMcpServers } = collectMcpServers(validPlugins);
|
|
30716
30925
|
if (allMcpServers.size > 0) {
|
|
@@ -30729,12 +30938,12 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
30729
30938
|
const deletedArtifacts = computeDeletedArtifacts(previousState, newStatePaths, syncClients, resolvedMappings, availableSkillNames);
|
|
30730
30939
|
const { pluginsByClient: nativePluginsByClient } = collectNativePluginSources(validPlugins);
|
|
30731
30940
|
if (!dryRun) {
|
|
30732
|
-
await persistSyncState(workspacePath, pluginResults, workspaceFileResults, syncClients, nativePluginsByClient, nativeResult, {
|
|
30941
|
+
await sw.measure("persist-state", () => persistSyncState(workspacePath, pluginResults, workspaceFileResults, syncClients, nativePluginsByClient, nativeResult, {
|
|
30733
30942
|
...vscodeState && { vscodeState },
|
|
30734
30943
|
...Object.keys(mcpResults).length > 0 && {
|
|
30735
30944
|
mcpTrackedServers: Object.fromEntries(Object.entries(mcpResults).map(([scope, r]) => [scope, r.trackedServers]))
|
|
30736
30945
|
}
|
|
30737
|
-
});
|
|
30946
|
+
}));
|
|
30738
30947
|
}
|
|
30739
30948
|
return {
|
|
30740
30949
|
success: !hasFailures,
|
|
@@ -30748,11 +30957,36 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
30748
30957
|
...warnings.length > 0 && { warnings },
|
|
30749
30958
|
...messages.length > 0 && { messages },
|
|
30750
30959
|
...Object.keys(mcpResults).length > 0 && { mcpResults },
|
|
30751
|
-
...nativeResult && { nativeResult }
|
|
30960
|
+
...nativeResult && { nativeResult },
|
|
30961
|
+
timing: sw.toJSON()
|
|
30752
30962
|
};
|
|
30753
30963
|
}
|
|
30964
|
+
async function seedFetchCacheFromMarketplaces(results) {
|
|
30965
|
+
for (const result of results) {
|
|
30966
|
+
if (!result.success || !result.name)
|
|
30967
|
+
continue;
|
|
30968
|
+
const entry = await getMarketplace(result.name);
|
|
30969
|
+
if (!entry || entry.source.type !== "github")
|
|
30970
|
+
continue;
|
|
30971
|
+
seedFetchCache(entry.source.location, entry.path);
|
|
30972
|
+
const branch = readGitBranch(entry.path);
|
|
30973
|
+
if (branch) {
|
|
30974
|
+
seedFetchCache(entry.source.location, entry.path, branch);
|
|
30975
|
+
}
|
|
30976
|
+
}
|
|
30977
|
+
}
|
|
30978
|
+
function readGitBranch(repoPath) {
|
|
30979
|
+
try {
|
|
30980
|
+
const head = readFileSync4(join16(repoPath, ".git", "HEAD"), "utf-8").trim();
|
|
30981
|
+
const prefix = "ref: refs/heads/";
|
|
30982
|
+
return head.startsWith(prefix) ? head.slice(prefix.length) : null;
|
|
30983
|
+
} catch {
|
|
30984
|
+
return null;
|
|
30985
|
+
}
|
|
30986
|
+
}
|
|
30754
30987
|
async function syncUserWorkspace(options2 = {}) {
|
|
30755
30988
|
await migrateUserWorkspaceSkillsV1toV2();
|
|
30989
|
+
const sw = new Stopwatch;
|
|
30756
30990
|
const homeDir = resolve9(getHomeDir());
|
|
30757
30991
|
const config = await getUserWorkspaceConfig();
|
|
30758
30992
|
if (!config) {
|
|
@@ -30770,8 +31004,9 @@ async function syncUserWorkspace(options2 = {}) {
|
|
|
30770
31004
|
const { plans: allPluginPlans, warnings: planWarnings } = buildPluginSyncPlans(config.plugins, workspaceClients, "user");
|
|
30771
31005
|
const pluginPlans = allPluginPlans.filter((plan) => plan.clients.length > 0 || plan.nativeClients.length > 0);
|
|
30772
31006
|
const syncClients = collectSyncClients(workspaceClients, pluginPlans);
|
|
30773
|
-
await ensureMarketplacesRegistered(pluginPlans.map((plan) => plan.source));
|
|
30774
|
-
|
|
31007
|
+
const marketplaceResults = await sw.measure("marketplace-registration", () => ensureMarketplacesRegistered(pluginPlans.map((plan) => plan.source)));
|
|
31008
|
+
await seedFetchCacheFromMarketplaces(marketplaceResults);
|
|
31009
|
+
const validatedPlugins = await sw.measure("plugin-validation", () => validateAllPlugins(pluginPlans, homeDir, offline), `${pluginPlans.length} plugin(s)`);
|
|
30775
31010
|
const failedValidations = validatedPlugins.filter((v) => !v.success);
|
|
30776
31011
|
const validPlugins = validatedPlugins.filter((v) => v.success);
|
|
30777
31012
|
const warnings = [
|
|
@@ -30786,21 +31021,22 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30786
31021
|
}
|
|
30787
31022
|
const previousState = await loadSyncState(homeDir);
|
|
30788
31023
|
if (!dryRun) {
|
|
30789
|
-
await selectivePurgeWorkspace(homeDir, previousState, syncClients);
|
|
31024
|
+
await sw.measure("selective-purge", () => selectivePurgeWorkspace(homeDir, previousState, syncClients));
|
|
30790
31025
|
}
|
|
30791
31026
|
const isV1FallbackUser = config.version === undefined || config.version < 2;
|
|
30792
31027
|
const disabledSkillsSet = isV1FallbackUser ? new Set(config.disabledSkills ?? []) : undefined;
|
|
30793
31028
|
const enabledSkillsSet = isV1FallbackUser && config.enabledSkills ? new Set(config.enabledSkills) : undefined;
|
|
30794
|
-
const allSkills = await collectAllSkills(validPlugins, disabledSkillsSet, enabledSkillsSet);
|
|
31029
|
+
const allSkills = await sw.measure("skill-collection", () => collectAllSkills(validPlugins, disabledSkillsSet, enabledSkillsSet));
|
|
30795
31030
|
const pluginSkillMaps = buildPluginSkillNameMaps(allSkills);
|
|
30796
31031
|
const syncMode = config.syncMode ?? "symlink";
|
|
30797
|
-
const pluginResults = await Promise.all(validPlugins.map(async (vp) => {
|
|
31032
|
+
const pluginResults = await sw.measure("plugin-copy", () => Promise.all(validPlugins.map(async (vp) => {
|
|
30798
31033
|
const skillNameMap = pluginSkillMaps.get(vp.resolved);
|
|
30799
31034
|
const resolvedUserMappings2 = resolveClientMappings(vp.clients, USER_CLIENT_MAPPINGS);
|
|
30800
31035
|
const result = await copyValidatedPlugin(vp, homeDir, vp.clients, dryRun, skillNameMap, resolvedUserMappings2, syncMode);
|
|
30801
31036
|
return { ...result, scope: "user" };
|
|
30802
|
-
}));
|
|
31037
|
+
})), `${validPlugins.length} plugin(s)`);
|
|
30803
31038
|
const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, []);
|
|
31039
|
+
sw.start("mcp-sync");
|
|
30804
31040
|
const mcpResults = {};
|
|
30805
31041
|
if (syncClients.includes("vscode")) {
|
|
30806
31042
|
const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
|
|
@@ -30840,6 +31076,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30840
31076
|
}
|
|
30841
31077
|
mcpResults.copilot = copilotMcp;
|
|
30842
31078
|
}
|
|
31079
|
+
sw.stop("mcp-sync");
|
|
30843
31080
|
const USER_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
|
|
30844
31081
|
const { servers: allUserMcpServers } = collectMcpServers(validPlugins);
|
|
30845
31082
|
if (allUserMcpServers.size > 0) {
|
|
@@ -30849,7 +31086,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30849
31086
|
}
|
|
30850
31087
|
}
|
|
30851
31088
|
}
|
|
30852
|
-
const nativeResult = await syncNativePlugins(validPlugins, previousState, "user", homeDir, dryRun, warnings, messages);
|
|
31089
|
+
const nativeResult = await sw.measure("native-plugin-sync", () => syncNativePlugins(validPlugins, previousState, "user", homeDir, dryRun, warnings, messages));
|
|
30853
31090
|
const availableUserSkillNames = await collectAvailableSkillNames(validPlugins);
|
|
30854
31091
|
const allCopyResultsForState = pluginResults.flatMap((r) => r.copyResults);
|
|
30855
31092
|
const resolvedUserMappings = resolveClientMappings(syncClients, USER_CLIENT_MAPPINGS);
|
|
@@ -30857,12 +31094,12 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30857
31094
|
const deletedArtifacts = computeDeletedArtifacts(previousState, newStatePaths, syncClients, resolvedUserMappings, availableUserSkillNames);
|
|
30858
31095
|
if (!dryRun) {
|
|
30859
31096
|
const { pluginsByClient: nativePluginsByClient } = collectNativePluginSources(validPlugins);
|
|
30860
|
-
await persistSyncState(homeDir, pluginResults, [], syncClients, nativePluginsByClient, nativeResult, {
|
|
31097
|
+
await sw.measure("persist-state", () => persistSyncState(homeDir, pluginResults, [], syncClients, nativePluginsByClient, nativeResult, {
|
|
30861
31098
|
clientMappings: USER_CLIENT_MAPPINGS,
|
|
30862
31099
|
...Object.keys(mcpResults).length > 0 && {
|
|
30863
31100
|
mcpTrackedServers: Object.fromEntries(Object.entries(mcpResults).map(([scope, r]) => [scope, r.trackedServers]))
|
|
30864
31101
|
}
|
|
30865
|
-
});
|
|
31102
|
+
}));
|
|
30866
31103
|
}
|
|
30867
31104
|
return {
|
|
30868
31105
|
success: totalFailed === 0,
|
|
@@ -30875,7 +31112,8 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
|
|
|
30875
31112
|
...warnings.length > 0 && { warnings },
|
|
30876
31113
|
...messages.length > 0 && { messages },
|
|
30877
31114
|
...Object.keys(mcpResults).length > 0 && { mcpResults },
|
|
30878
|
-
...nativeResult && { nativeResult }
|
|
31115
|
+
...nativeResult && { nativeResult },
|
|
31116
|
+
timing: sw.toJSON()
|
|
30879
31117
|
};
|
|
30880
31118
|
}
|
|
30881
31119
|
var import_json53, VSCODE_TEMPLATE_FILE = "template.code-workspace";
|
|
@@ -34103,11 +34341,11 @@ var package_default;
|
|
|
34103
34341
|
var init_package = __esm(() => {
|
|
34104
34342
|
package_default = {
|
|
34105
34343
|
name: "allagents",
|
|
34106
|
-
version: "1.4.
|
|
34344
|
+
version: "1.4.11",
|
|
34107
34345
|
description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
|
|
34108
34346
|
type: "module",
|
|
34109
34347
|
bin: {
|
|
34110
|
-
allagents: "
|
|
34348
|
+
allagents: "dist/index.js"
|
|
34111
34349
|
},
|
|
34112
34350
|
files: [
|
|
34113
34351
|
"dist"
|
|
@@ -34149,7 +34387,7 @@ var init_package = __esm(() => {
|
|
|
34149
34387
|
license: "MIT",
|
|
34150
34388
|
repository: {
|
|
34151
34389
|
type: "git",
|
|
34152
|
-
url: "https://github.com/EntityProcess/allagents.git"
|
|
34390
|
+
url: "git+https://github.com/EntityProcess/allagents.git"
|
|
34153
34391
|
},
|
|
34154
34392
|
homepage: "https://allagents.dev",
|
|
34155
34393
|
dependencies: {
|
|
@@ -36080,6 +36318,8 @@ var syncCmd = import_cmd_ts2.command({
|
|
|
36080
36318
|
return;
|
|
36081
36319
|
}
|
|
36082
36320
|
let combined = null;
|
|
36321
|
+
const { resetFetchCache: resetFetchCache2 } = await Promise.resolve().then(() => (init_plugin(), exports_plugin));
|
|
36322
|
+
resetFetchCache2();
|
|
36083
36323
|
if (userConfigExists) {
|
|
36084
36324
|
const userResult = await syncUserWorkspace({ offline, dryRun, force });
|
|
36085
36325
|
combined = userResult;
|
|
@@ -36182,6 +36422,20 @@ native:`);
|
|
|
36182
36422
|
console.log(line);
|
|
36183
36423
|
}
|
|
36184
36424
|
}
|
|
36425
|
+
if (process.env.ALLAGENTS_DEBUG?.includes("timing") && result.timing) {
|
|
36426
|
+
console.error("");
|
|
36427
|
+
const totalMs = result.timing.totalMs;
|
|
36428
|
+
console.error(`[debug] Sync timing (total: ${formatTimingMs(totalMs)})`);
|
|
36429
|
+
console.error(`[debug] ${"─".repeat(56)}`);
|
|
36430
|
+
for (const step of result.timing.steps) {
|
|
36431
|
+
const pct = totalMs > 0 ? (step.durationMs / totalMs * 100).toFixed(1) : "0.0";
|
|
36432
|
+
const detail = step.detail ? ` [${step.detail}]` : "";
|
|
36433
|
+
const label = step.label.padEnd(40);
|
|
36434
|
+
const duration = formatTimingMs(step.durationMs).padStart(8);
|
|
36435
|
+
console.error(`[debug] ${label} ${duration} ${pct.padStart(5)}%${detail}`);
|
|
36436
|
+
}
|
|
36437
|
+
console.error(`[debug] ${"─".repeat(56)}`);
|
|
36438
|
+
}
|
|
36185
36439
|
if (!result.success || result.totalFailed > 0) {
|
|
36186
36440
|
process.exit(1);
|
|
36187
36441
|
}
|
|
@@ -36198,6 +36452,11 @@ native:`);
|
|
|
36198
36452
|
}
|
|
36199
36453
|
}
|
|
36200
36454
|
});
|
|
36455
|
+
function formatTimingMs(ms) {
|
|
36456
|
+
if (ms < 1000)
|
|
36457
|
+
return `${Math.round(ms)}ms`;
|
|
36458
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
36459
|
+
}
|
|
36201
36460
|
var statusCmd = import_cmd_ts2.command({
|
|
36202
36461
|
name: "status",
|
|
36203
36462
|
description: buildDescription(statusMeta),
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "allagents",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.11",
|
|
4
4
|
"description": "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"allagents": "
|
|
7
|
+
"allagents": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist"
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"license": "MIT",
|
|
47
47
|
"repository": {
|
|
48
48
|
"type": "git",
|
|
49
|
-
"url": "https://github.com/EntityProcess/allagents.git"
|
|
49
|
+
"url": "git+https://github.com/EntityProcess/allagents.git"
|
|
50
50
|
},
|
|
51
51
|
"homepage": "https://allagents.dev",
|
|
52
52
|
"dependencies": {
|