allagents 0.7.0 → 0.7.2
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 +5 -5
- package/dist/index.js +465 -276
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,9 +66,9 @@ allagents workspace init my-workspace --from owner/repo/path/to/template
|
|
|
66
66
|
# Add a marketplace (or let auto-registration handle it)
|
|
67
67
|
allagents plugin marketplace add anthropics/claude-plugins-official
|
|
68
68
|
|
|
69
|
-
#
|
|
70
|
-
allagents workspace plugin
|
|
71
|
-
allagents workspace plugin
|
|
69
|
+
# Install plugins to workspace
|
|
70
|
+
allagents workspace plugin install code-review@claude-plugins-official
|
|
71
|
+
allagents workspace plugin install my-plugin@someuser/their-repo
|
|
72
72
|
|
|
73
73
|
# Sync plugins to workspace
|
|
74
74
|
allagents workspace sync
|
|
@@ -113,8 +113,8 @@ allagents workspace sync [options]
|
|
|
113
113
|
# Show status of workspace and plugins
|
|
114
114
|
allagents workspace status
|
|
115
115
|
|
|
116
|
-
#
|
|
117
|
-
allagents workspace plugin
|
|
116
|
+
# Install a plugin to .allagents/workspace.yaml (auto-registers marketplace if needed)
|
|
117
|
+
allagents workspace plugin install <plugin@marketplace>
|
|
118
118
|
|
|
119
119
|
# Remove a plugin from .allagents/workspace.yaml
|
|
120
120
|
allagents workspace plugin remove <plugin>
|
package/dist/index.js
CHANGED
|
@@ -11055,13 +11055,13 @@ var {
|
|
|
11055
11055
|
|
|
11056
11056
|
// src/cli/index.ts
|
|
11057
11057
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
11058
|
-
import { dirname as dirname7, join as
|
|
11058
|
+
import { dirname as dirname7, join as join13 } from "node:path";
|
|
11059
11059
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
11060
11060
|
|
|
11061
11061
|
// src/core/workspace.ts
|
|
11062
|
-
import { mkdir as mkdir5, readFile as
|
|
11063
|
-
import { existsSync as
|
|
11064
|
-
import { join as
|
|
11062
|
+
import { mkdir as mkdir5, readFile as readFile8, writeFile as writeFile4, copyFile as copyFile2 } from "node:fs/promises";
|
|
11063
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
11064
|
+
import { join as join9, resolve as resolve6, dirname as dirname5, relative as relative2, sep, isAbsolute as isAbsolute2 } from "node:path";
|
|
11065
11065
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
11066
11066
|
|
|
11067
11067
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
@@ -13712,9 +13712,9 @@ var safeLoadAll = renamed("safeLoadAll", "loadAll");
|
|
|
13712
13712
|
var safeDump = renamed("safeDump", "dump");
|
|
13713
13713
|
|
|
13714
13714
|
// src/core/sync.ts
|
|
13715
|
-
import { existsSync as
|
|
13715
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
13716
13716
|
import { rm, unlink, rmdir, copyFile } from "node:fs/promises";
|
|
13717
|
-
import { join as
|
|
13717
|
+
import { join as join8, resolve as resolve5, dirname as dirname4, relative } from "node:path";
|
|
13718
13718
|
|
|
13719
13719
|
// src/constants.ts
|
|
13720
13720
|
var CONFIG_DIR = ".allagents";
|
|
@@ -19787,11 +19787,10 @@ import { existsSync as existsSync2 } from "node:fs";
|
|
|
19787
19787
|
import { join as join3 } from "node:path";
|
|
19788
19788
|
|
|
19789
19789
|
// src/models/skill-metadata.ts
|
|
19790
|
-
var skillNameRegex = /^[a-z0-9-]{1,64}$/;
|
|
19791
19790
|
var SkillMetadataSchema = exports_external.object({
|
|
19792
|
-
name: exports_external.string().
|
|
19791
|
+
name: exports_external.string().min(1, "Skill name is required").max(128, "Skill name too long"),
|
|
19793
19792
|
description: exports_external.string().min(1, "Description is required"),
|
|
19794
|
-
"allowed-tools": exports_external.array(exports_external.string()).optional(),
|
|
19793
|
+
"allowed-tools": exports_external.union([exports_external.array(exports_external.string()), exports_external.string().transform((s) => [s])]).optional(),
|
|
19795
19794
|
model: exports_external.string().optional()
|
|
19796
19795
|
});
|
|
19797
19796
|
|
|
@@ -20413,29 +20412,120 @@ function resolveSkillNames(skills) {
|
|
|
20413
20412
|
}
|
|
20414
20413
|
|
|
20415
20414
|
// src/core/marketplace.ts
|
|
20416
|
-
import { mkdir as mkdir3, readFile as
|
|
20415
|
+
import { mkdir as mkdir3, readFile as readFile6, readdir as readdir3, writeFile as writeFile2 } from "node:fs/promises";
|
|
20416
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
20417
|
+
import { basename as basename2, join as join6, resolve as resolve4 } from "node:path";
|
|
20418
|
+
|
|
20419
|
+
// src/utils/marketplace-manifest-parser.ts
|
|
20420
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
20417
20421
|
import { existsSync as existsSync4 } from "node:fs";
|
|
20418
|
-
import {
|
|
20422
|
+
import { join as join5, resolve as resolve3 } from "node:path";
|
|
20423
|
+
|
|
20424
|
+
// src/models/marketplace-manifest.ts
|
|
20425
|
+
var UrlSourceSchema = exports_external.object({
|
|
20426
|
+
source: exports_external.literal("url"),
|
|
20427
|
+
url: exports_external.string().url()
|
|
20428
|
+
});
|
|
20429
|
+
var PluginSourceRefSchema = exports_external.union([exports_external.string(), UrlSourceSchema]);
|
|
20430
|
+
var ContactSchema = exports_external.object({
|
|
20431
|
+
name: exports_external.string(),
|
|
20432
|
+
email: exports_external.string().optional()
|
|
20433
|
+
});
|
|
20434
|
+
var LspServerSchema = exports_external.object({
|
|
20435
|
+
command: exports_external.string(),
|
|
20436
|
+
args: exports_external.array(exports_external.string()).optional(),
|
|
20437
|
+
extensionToLanguage: exports_external.record(exports_external.string()).optional(),
|
|
20438
|
+
startupTimeout: exports_external.number().optional()
|
|
20439
|
+
});
|
|
20440
|
+
var MarketplacePluginEntrySchema = exports_external.object({
|
|
20441
|
+
name: exports_external.string().min(1),
|
|
20442
|
+
description: exports_external.string().min(1),
|
|
20443
|
+
source: PluginSourceRefSchema,
|
|
20444
|
+
version: exports_external.string().optional(),
|
|
20445
|
+
author: ContactSchema.optional(),
|
|
20446
|
+
category: exports_external.string().optional(),
|
|
20447
|
+
homepage: exports_external.string().optional(),
|
|
20448
|
+
strict: exports_external.boolean().optional(),
|
|
20449
|
+
tags: exports_external.array(exports_external.string()).optional(),
|
|
20450
|
+
lspServers: exports_external.record(LspServerSchema).optional()
|
|
20451
|
+
});
|
|
20452
|
+
var MarketplaceManifestSchema = exports_external.object({
|
|
20453
|
+
$schema: exports_external.string().optional(),
|
|
20454
|
+
name: exports_external.string().min(1),
|
|
20455
|
+
version: exports_external.string().optional(),
|
|
20456
|
+
description: exports_external.string().min(1),
|
|
20457
|
+
owner: ContactSchema.optional(),
|
|
20458
|
+
plugins: exports_external.array(MarketplacePluginEntrySchema)
|
|
20459
|
+
});
|
|
20460
|
+
|
|
20461
|
+
// src/utils/marketplace-manifest-parser.ts
|
|
20462
|
+
var MANIFEST_PATH = ".claude-plugin/marketplace.json";
|
|
20463
|
+
async function parseMarketplaceManifest(marketplacePath) {
|
|
20464
|
+
const manifestPath = join5(marketplacePath, MANIFEST_PATH);
|
|
20465
|
+
if (!existsSync4(manifestPath)) {
|
|
20466
|
+
return {
|
|
20467
|
+
success: false,
|
|
20468
|
+
error: `Marketplace manifest not found: ${manifestPath}`
|
|
20469
|
+
};
|
|
20470
|
+
}
|
|
20471
|
+
let raw;
|
|
20472
|
+
try {
|
|
20473
|
+
raw = await readFile5(manifestPath, "utf-8");
|
|
20474
|
+
} catch (err) {
|
|
20475
|
+
return {
|
|
20476
|
+
success: false,
|
|
20477
|
+
error: `Failed to read marketplace manifest: ${err instanceof Error ? err.message : String(err)}`
|
|
20478
|
+
};
|
|
20479
|
+
}
|
|
20480
|
+
let json2;
|
|
20481
|
+
try {
|
|
20482
|
+
json2 = JSON.parse(raw);
|
|
20483
|
+
} catch {
|
|
20484
|
+
return {
|
|
20485
|
+
success: false,
|
|
20486
|
+
error: "Failed to parse marketplace.json as JSON: invalid syntax"
|
|
20487
|
+
};
|
|
20488
|
+
}
|
|
20489
|
+
const result = MarketplaceManifestSchema.safeParse(json2);
|
|
20490
|
+
if (!result.success) {
|
|
20491
|
+
const issues = result.error.issues.map((i2) => ` ${i2.path.join(".")}: ${i2.message}`).join(`
|
|
20492
|
+
`);
|
|
20493
|
+
return {
|
|
20494
|
+
success: false,
|
|
20495
|
+
error: `Marketplace manifest validation failed:
|
|
20496
|
+
${issues}`
|
|
20497
|
+
};
|
|
20498
|
+
}
|
|
20499
|
+
return { success: true, data: result.data };
|
|
20500
|
+
}
|
|
20501
|
+
function resolvePluginSourcePath(source, marketplacePath) {
|
|
20502
|
+
if (typeof source === "object") {
|
|
20503
|
+
return source.url;
|
|
20504
|
+
}
|
|
20505
|
+
return resolve3(marketplacePath, source);
|
|
20506
|
+
}
|
|
20507
|
+
|
|
20508
|
+
// src/core/marketplace.ts
|
|
20419
20509
|
var WELL_KNOWN_MARKETPLACES = {
|
|
20420
20510
|
"claude-plugins-official": "anthropics/claude-plugins-official"
|
|
20421
20511
|
};
|
|
20422
20512
|
function getAllagentsDir() {
|
|
20423
20513
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "~";
|
|
20424
|
-
return
|
|
20514
|
+
return resolve4(homeDir, ".allagents");
|
|
20425
20515
|
}
|
|
20426
20516
|
function getMarketplacesDir() {
|
|
20427
|
-
return
|
|
20517
|
+
return join6(getAllagentsDir(), "marketplaces");
|
|
20428
20518
|
}
|
|
20429
20519
|
function getRegistryPath() {
|
|
20430
|
-
return
|
|
20520
|
+
return join6(getAllagentsDir(), "marketplaces.json");
|
|
20431
20521
|
}
|
|
20432
20522
|
async function loadRegistry() {
|
|
20433
20523
|
const registryPath = getRegistryPath();
|
|
20434
|
-
if (!
|
|
20524
|
+
if (!existsSync5(registryPath)) {
|
|
20435
20525
|
return { version: 1, marketplaces: {} };
|
|
20436
20526
|
}
|
|
20437
20527
|
try {
|
|
20438
|
-
const content = await
|
|
20528
|
+
const content = await readFile6(registryPath, "utf-8");
|
|
20439
20529
|
return JSON.parse(content);
|
|
20440
20530
|
} catch {
|
|
20441
20531
|
return { version: 1, marketplaces: {} };
|
|
@@ -20444,7 +20534,7 @@ async function loadRegistry() {
|
|
|
20444
20534
|
async function saveRegistry(registry) {
|
|
20445
20535
|
const registryPath = getRegistryPath();
|
|
20446
20536
|
const dir = getAllagentsDir();
|
|
20447
|
-
if (!
|
|
20537
|
+
if (!existsSync5(dir)) {
|
|
20448
20538
|
await mkdir3(dir, { recursive: true });
|
|
20449
20539
|
}
|
|
20450
20540
|
await writeFile2(registryPath, `${JSON.stringify(registry, null, 2)}
|
|
@@ -20473,7 +20563,7 @@ function parseMarketplaceSource(source) {
|
|
|
20473
20563
|
return null;
|
|
20474
20564
|
}
|
|
20475
20565
|
if (source.startsWith("/") || source.startsWith(".")) {
|
|
20476
|
-
const absPath =
|
|
20566
|
+
const absPath = resolve4(source);
|
|
20477
20567
|
const name = basename2(absPath) || "local";
|
|
20478
20568
|
return {
|
|
20479
20569
|
type: "local",
|
|
@@ -20502,7 +20592,7 @@ async function addMarketplace(source, customName) {
|
|
|
20502
20592
|
Use: GitHub URL, owner/repo, local path, or well-known name`
|
|
20503
20593
|
};
|
|
20504
20594
|
}
|
|
20505
|
-
|
|
20595
|
+
let name = customName || parsed.name;
|
|
20506
20596
|
const registry = await loadRegistry();
|
|
20507
20597
|
if (registry.marketplaces[name]) {
|
|
20508
20598
|
return {
|
|
@@ -20512,8 +20602,8 @@ async function addMarketplace(source, customName) {
|
|
|
20512
20602
|
}
|
|
20513
20603
|
let marketplacePath;
|
|
20514
20604
|
if (parsed.type === "github") {
|
|
20515
|
-
marketplacePath =
|
|
20516
|
-
if (
|
|
20605
|
+
marketplacePath = join6(getMarketplacesDir(), name);
|
|
20606
|
+
if (existsSync5(marketplacePath)) {} else {
|
|
20517
20607
|
try {
|
|
20518
20608
|
await execa("gh", ["--version"]);
|
|
20519
20609
|
} catch {
|
|
@@ -20524,7 +20614,7 @@ async function addMarketplace(source, customName) {
|
|
|
20524
20614
|
};
|
|
20525
20615
|
}
|
|
20526
20616
|
const parentDir = getMarketplacesDir();
|
|
20527
|
-
if (!
|
|
20617
|
+
if (!existsSync5(parentDir)) {
|
|
20528
20618
|
await mkdir3(parentDir, { recursive: true });
|
|
20529
20619
|
}
|
|
20530
20620
|
try {
|
|
@@ -20545,13 +20635,29 @@ async function addMarketplace(source, customName) {
|
|
|
20545
20635
|
}
|
|
20546
20636
|
} else {
|
|
20547
20637
|
marketplacePath = parsed.location;
|
|
20548
|
-
if (!
|
|
20638
|
+
if (!existsSync5(marketplacePath)) {
|
|
20549
20639
|
return {
|
|
20550
20640
|
success: false,
|
|
20551
20641
|
error: `Local directory not found: ${marketplacePath}`
|
|
20552
20642
|
};
|
|
20553
20643
|
}
|
|
20554
20644
|
}
|
|
20645
|
+
if (!customName) {
|
|
20646
|
+
const manifestResult = await parseMarketplaceManifest(marketplacePath);
|
|
20647
|
+
if (manifestResult.success && manifestResult.data.name) {
|
|
20648
|
+
const manifestName = manifestResult.data.name;
|
|
20649
|
+
if (manifestName !== name) {
|
|
20650
|
+
const existing = registry.marketplaces[manifestName];
|
|
20651
|
+
if (existing) {
|
|
20652
|
+
return {
|
|
20653
|
+
success: true,
|
|
20654
|
+
marketplace: existing
|
|
20655
|
+
};
|
|
20656
|
+
}
|
|
20657
|
+
name = manifestName;
|
|
20658
|
+
}
|
|
20659
|
+
}
|
|
20660
|
+
}
|
|
20555
20661
|
const entry = {
|
|
20556
20662
|
name,
|
|
20557
20663
|
source: {
|
|
@@ -20607,7 +20713,7 @@ async function updateMarketplace(name) {
|
|
|
20607
20713
|
});
|
|
20608
20714
|
continue;
|
|
20609
20715
|
}
|
|
20610
|
-
if (!
|
|
20716
|
+
if (!existsSync5(marketplace.path)) {
|
|
20611
20717
|
results.push({
|
|
20612
20718
|
name: marketplace.name,
|
|
20613
20719
|
success: false,
|
|
@@ -20634,20 +20740,44 @@ async function updateMarketplace(name) {
|
|
|
20634
20740
|
await saveRegistry(registry);
|
|
20635
20741
|
return results;
|
|
20636
20742
|
}
|
|
20743
|
+
async function getMarketplacePluginsFromManifest(marketplacePath) {
|
|
20744
|
+
const result = await parseMarketplaceManifest(marketplacePath);
|
|
20745
|
+
if (!result.success) {
|
|
20746
|
+
return [];
|
|
20747
|
+
}
|
|
20748
|
+
return result.data.plugins.map((plugin) => {
|
|
20749
|
+
const resolvedSource = resolvePluginSourcePath(plugin.source, marketplacePath);
|
|
20750
|
+
const info = {
|
|
20751
|
+
name: plugin.name,
|
|
20752
|
+
path: typeof plugin.source === "string" ? resolve4(marketplacePath, plugin.source) : resolvedSource,
|
|
20753
|
+
description: plugin.description,
|
|
20754
|
+
source: resolvedSource
|
|
20755
|
+
};
|
|
20756
|
+
if (plugin.category)
|
|
20757
|
+
info.category = plugin.category;
|
|
20758
|
+
if (plugin.homepage)
|
|
20759
|
+
info.homepage = plugin.homepage;
|
|
20760
|
+
return info;
|
|
20761
|
+
});
|
|
20762
|
+
}
|
|
20637
20763
|
async function listMarketplacePlugins(name) {
|
|
20638
20764
|
const marketplace = await getMarketplace(name);
|
|
20639
20765
|
if (!marketplace) {
|
|
20640
20766
|
return [];
|
|
20641
20767
|
}
|
|
20642
|
-
const
|
|
20643
|
-
if (
|
|
20768
|
+
const manifestPlugins = await getMarketplacePluginsFromManifest(marketplace.path);
|
|
20769
|
+
if (manifestPlugins.length > 0) {
|
|
20770
|
+
return manifestPlugins;
|
|
20771
|
+
}
|
|
20772
|
+
const pluginsDir = join6(marketplace.path, "plugins");
|
|
20773
|
+
if (!existsSync5(pluginsDir)) {
|
|
20644
20774
|
return [];
|
|
20645
20775
|
}
|
|
20646
20776
|
try {
|
|
20647
20777
|
const entries = await readdir3(pluginsDir, { withFileTypes: true });
|
|
20648
20778
|
return entries.filter((e) => e.isDirectory()).map((e) => ({
|
|
20649
20779
|
name: e.name,
|
|
20650
|
-
path:
|
|
20780
|
+
path: join6(pluginsDir, e.name)
|
|
20651
20781
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
20652
20782
|
} catch {
|
|
20653
20783
|
return [];
|
|
@@ -20688,21 +20818,114 @@ async function resolvePluginSpec(spec, options2 = {}) {
|
|
|
20688
20818
|
if (!parsed) {
|
|
20689
20819
|
return null;
|
|
20690
20820
|
}
|
|
20691
|
-
const
|
|
20821
|
+
const marketplaceName = options2.marketplaceNameOverride ?? parsed.marketplaceName;
|
|
20822
|
+
const marketplace = await getMarketplace(marketplaceName);
|
|
20692
20823
|
if (!marketplace) {
|
|
20693
20824
|
return null;
|
|
20694
20825
|
}
|
|
20826
|
+
const manifestResult = await parseMarketplaceManifest(marketplace.path);
|
|
20827
|
+
if (manifestResult.success) {
|
|
20828
|
+
const pluginEntry = manifestResult.data.plugins.find((p) => p.name === parsed.plugin);
|
|
20829
|
+
if (pluginEntry) {
|
|
20830
|
+
const resolvedSource = typeof pluginEntry.source === "string" ? resolve4(marketplace.path, pluginEntry.source) : pluginEntry.source.url;
|
|
20831
|
+
if (typeof resolvedSource === "string" && existsSync5(resolvedSource)) {
|
|
20832
|
+
return {
|
|
20833
|
+
path: resolvedSource,
|
|
20834
|
+
marketplace: marketplaceName,
|
|
20835
|
+
plugin: parsed.plugin
|
|
20836
|
+
};
|
|
20837
|
+
}
|
|
20838
|
+
}
|
|
20839
|
+
}
|
|
20695
20840
|
const subpath = options2.subpath ?? parsed.subpath ?? "plugins";
|
|
20696
|
-
const pluginPath =
|
|
20697
|
-
if (!
|
|
20841
|
+
const pluginPath = join6(marketplace.path, subpath, parsed.plugin);
|
|
20842
|
+
if (!existsSync5(pluginPath)) {
|
|
20698
20843
|
return null;
|
|
20699
20844
|
}
|
|
20700
20845
|
return {
|
|
20701
20846
|
path: pluginPath,
|
|
20702
|
-
marketplace:
|
|
20847
|
+
marketplace: marketplaceName,
|
|
20703
20848
|
plugin: parsed.plugin
|
|
20704
20849
|
};
|
|
20705
20850
|
}
|
|
20851
|
+
async function resolvePluginSpecWithAutoRegister(spec) {
|
|
20852
|
+
const parsed = parsePluginSpec(spec);
|
|
20853
|
+
if (!parsed) {
|
|
20854
|
+
return {
|
|
20855
|
+
success: false,
|
|
20856
|
+
error: `Invalid plugin spec format: ${spec}
|
|
20857
|
+
Expected: plugin@marketplace or plugin@owner/repo[/subpath]`
|
|
20858
|
+
};
|
|
20859
|
+
}
|
|
20860
|
+
const { plugin: pluginName, marketplaceName, owner, repo, subpath } = parsed;
|
|
20861
|
+
let marketplace = await getMarketplace(marketplaceName);
|
|
20862
|
+
if (!marketplace) {
|
|
20863
|
+
const sourceToRegister = owner && repo ? `${owner}/${repo}` : marketplaceName;
|
|
20864
|
+
const autoRegResult = await autoRegisterMarketplace(sourceToRegister);
|
|
20865
|
+
if (!autoRegResult.success) {
|
|
20866
|
+
return {
|
|
20867
|
+
success: false,
|
|
20868
|
+
error: autoRegResult.error || "Unknown error"
|
|
20869
|
+
};
|
|
20870
|
+
}
|
|
20871
|
+
marketplace = await getMarketplace(autoRegResult.name ?? marketplaceName);
|
|
20872
|
+
}
|
|
20873
|
+
if (!marketplace) {
|
|
20874
|
+
return {
|
|
20875
|
+
success: false,
|
|
20876
|
+
error: `Marketplace '${marketplaceName}' not found`
|
|
20877
|
+
};
|
|
20878
|
+
}
|
|
20879
|
+
const expectedSubpath = subpath ?? "plugins";
|
|
20880
|
+
const resolved = await resolvePluginSpec(spec, {
|
|
20881
|
+
...subpath && { subpath },
|
|
20882
|
+
marketplaceNameOverride: marketplace.name
|
|
20883
|
+
});
|
|
20884
|
+
if (!resolved) {
|
|
20885
|
+
return {
|
|
20886
|
+
success: false,
|
|
20887
|
+
error: `Plugin '${pluginName}' not found in marketplace '${marketplaceName}'
|
|
20888
|
+
Expected at: ${marketplace.path}/${expectedSubpath}/${pluginName}/`
|
|
20889
|
+
};
|
|
20890
|
+
}
|
|
20891
|
+
return {
|
|
20892
|
+
success: true,
|
|
20893
|
+
path: resolved.path,
|
|
20894
|
+
pluginName: resolved.plugin,
|
|
20895
|
+
...marketplace.name !== marketplaceName && { registeredAs: marketplace.name }
|
|
20896
|
+
};
|
|
20897
|
+
}
|
|
20898
|
+
async function autoRegisterMarketplace(name) {
|
|
20899
|
+
const wellKnown = getWellKnownMarketplaces();
|
|
20900
|
+
if (wellKnown[name]) {
|
|
20901
|
+
console.log(`Auto-registering well-known marketplace: ${name}`);
|
|
20902
|
+
const result = await addMarketplace(name);
|
|
20903
|
+
if (!result.success) {
|
|
20904
|
+
return { success: false, error: result.error || "Unknown error" };
|
|
20905
|
+
}
|
|
20906
|
+
return { success: true, name };
|
|
20907
|
+
}
|
|
20908
|
+
if (name.includes("/") && !name.includes("://")) {
|
|
20909
|
+
const parts = name.split("/");
|
|
20910
|
+
if (parts.length === 2 && parts[0] && parts[1]) {
|
|
20911
|
+
console.log(`Auto-registering GitHub marketplace: ${name}`);
|
|
20912
|
+
const result = await addMarketplace(name);
|
|
20913
|
+
if (!result.success) {
|
|
20914
|
+
return { success: false, error: result.error || "Unknown error" };
|
|
20915
|
+
}
|
|
20916
|
+
const registeredName = result.marketplace?.name ?? parts[1];
|
|
20917
|
+
return { success: true, name: registeredName };
|
|
20918
|
+
}
|
|
20919
|
+
}
|
|
20920
|
+
return {
|
|
20921
|
+
success: false,
|
|
20922
|
+
error: `Marketplace '${name}' not found.
|
|
20923
|
+
Options:
|
|
20924
|
+
1. Use fully qualified name: plugin@owner/repo
|
|
20925
|
+
2. Register first: allagents plugin marketplace add <source>
|
|
20926
|
+
3. Well-known marketplaces: ${Object.keys(wellKnown).join(", ")}`
|
|
20927
|
+
};
|
|
20928
|
+
}
|
|
20706
20929
|
function isPluginSpec(spec) {
|
|
20707
20930
|
const atIndex = spec.lastIndexOf("@");
|
|
20708
20931
|
if (atIndex === -1 || atIndex === 0 || atIndex === spec.length - 1) {
|
|
@@ -20715,9 +20938,9 @@ function getWellKnownMarketplaces() {
|
|
|
20715
20938
|
}
|
|
20716
20939
|
|
|
20717
20940
|
// src/core/sync-state.ts
|
|
20718
|
-
import { readFile as
|
|
20719
|
-
import { existsSync as
|
|
20720
|
-
import { join as
|
|
20941
|
+
import { readFile as readFile7, writeFile as writeFile3, mkdir as mkdir4 } from "node:fs/promises";
|
|
20942
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
20943
|
+
import { join as join7, dirname as dirname3 } from "node:path";
|
|
20721
20944
|
|
|
20722
20945
|
// src/models/sync-state.ts
|
|
20723
20946
|
var SyncStateSchema = exports_external.object({
|
|
@@ -20728,15 +20951,15 @@ var SyncStateSchema = exports_external.object({
|
|
|
20728
20951
|
|
|
20729
20952
|
// src/core/sync-state.ts
|
|
20730
20953
|
function getSyncStatePath(workspacePath) {
|
|
20731
|
-
return
|
|
20954
|
+
return join7(workspacePath, CONFIG_DIR, SYNC_STATE_FILE);
|
|
20732
20955
|
}
|
|
20733
20956
|
async function loadSyncState(workspacePath) {
|
|
20734
20957
|
const statePath = getSyncStatePath(workspacePath);
|
|
20735
|
-
if (!
|
|
20958
|
+
if (!existsSync6(statePath)) {
|
|
20736
20959
|
return null;
|
|
20737
20960
|
}
|
|
20738
20961
|
try {
|
|
20739
|
-
const content = await
|
|
20962
|
+
const content = await readFile7(statePath, "utf-8");
|
|
20740
20963
|
const parsed = JSON.parse(content);
|
|
20741
20964
|
const result = SyncStateSchema.safeParse(parsed);
|
|
20742
20965
|
if (!result.success) {
|
|
@@ -20765,19 +20988,19 @@ function getPreviouslySyncedFiles(state, client) {
|
|
|
20765
20988
|
}
|
|
20766
20989
|
|
|
20767
20990
|
// src/core/sync.ts
|
|
20768
|
-
async function selectivePurgeWorkspace(workspacePath, state, clients) {
|
|
20991
|
+
async function selectivePurgeWorkspace(workspacePath, state, clients, options2) {
|
|
20769
20992
|
if (!state) {
|
|
20770
20993
|
return [];
|
|
20771
20994
|
}
|
|
20772
20995
|
const result = [];
|
|
20773
20996
|
const previousClients = Object.keys(state.files);
|
|
20774
|
-
const clientsToProcess = [...new Set([...clients, ...previousClients])];
|
|
20997
|
+
const clientsToProcess = options2?.partialSync ? clients : [...new Set([...clients, ...previousClients])];
|
|
20775
20998
|
for (const client of clientsToProcess) {
|
|
20776
20999
|
const previousFiles = getPreviouslySyncedFiles(state, client);
|
|
20777
21000
|
const purgedPaths = [];
|
|
20778
21001
|
for (const filePath of previousFiles) {
|
|
20779
|
-
const fullPath =
|
|
20780
|
-
if (!
|
|
21002
|
+
const fullPath = join8(workspacePath, filePath);
|
|
21003
|
+
if (!existsSync7(fullPath)) {
|
|
20781
21004
|
continue;
|
|
20782
21005
|
}
|
|
20783
21006
|
try {
|
|
@@ -20799,8 +21022,8 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
|
|
|
20799
21022
|
async function cleanupEmptyParents(workspacePath, filePath) {
|
|
20800
21023
|
let parentPath = dirname4(filePath);
|
|
20801
21024
|
while (parentPath && parentPath !== "." && parentPath !== "/") {
|
|
20802
|
-
const fullParentPath =
|
|
20803
|
-
if (!
|
|
21025
|
+
const fullParentPath = join8(workspacePath, parentPath);
|
|
21026
|
+
if (!existsSync7(fullParentPath)) {
|
|
20804
21027
|
parentPath = dirname4(parentPath);
|
|
20805
21028
|
continue;
|
|
20806
21029
|
}
|
|
@@ -20885,8 +21108,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
|
|
|
20885
21108
|
errors2.push(`Cannot resolve file '${file}' - no workspace.source configured`);
|
|
20886
21109
|
continue;
|
|
20887
21110
|
}
|
|
20888
|
-
const fullPath =
|
|
20889
|
-
if (!
|
|
21111
|
+
const fullPath = join8(defaultSourcePath, file);
|
|
21112
|
+
if (!existsSync7(fullPath)) {
|
|
20890
21113
|
errors2.push(`File source not found: ${fullPath}`);
|
|
20891
21114
|
}
|
|
20892
21115
|
continue;
|
|
@@ -20904,8 +21127,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
|
|
|
20904
21127
|
errors2.push(`GitHub cache not found for ${cacheKey}`);
|
|
20905
21128
|
continue;
|
|
20906
21129
|
}
|
|
20907
|
-
const fullPath =
|
|
20908
|
-
if (!
|
|
21130
|
+
const fullPath = join8(cachePath, parsed.filePath);
|
|
21131
|
+
if (!existsSync7(fullPath)) {
|
|
20909
21132
|
errors2.push(`Path not found in repository: ${cacheKey}/${parsed.filePath}`);
|
|
20910
21133
|
}
|
|
20911
21134
|
} else {
|
|
@@ -20913,13 +21136,13 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
|
|
|
20913
21136
|
if (file.source.startsWith("/")) {
|
|
20914
21137
|
fullPath = file.source;
|
|
20915
21138
|
} else if (file.source.startsWith("../")) {
|
|
20916
|
-
fullPath =
|
|
21139
|
+
fullPath = resolve5(file.source);
|
|
20917
21140
|
} else if (defaultSourcePath) {
|
|
20918
|
-
fullPath =
|
|
21141
|
+
fullPath = join8(defaultSourcePath, file.source);
|
|
20919
21142
|
} else {
|
|
20920
|
-
fullPath =
|
|
21143
|
+
fullPath = resolve5(file.source);
|
|
20921
21144
|
}
|
|
20922
|
-
if (!
|
|
21145
|
+
if (!existsSync7(fullPath)) {
|
|
20923
21146
|
errors2.push(`File source not found: ${fullPath}`);
|
|
20924
21147
|
}
|
|
20925
21148
|
}
|
|
@@ -20928,8 +21151,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
|
|
|
20928
21151
|
errors2.push(`Cannot resolve file '${file.dest}' - no workspace.source configured and no explicit source provided`);
|
|
20929
21152
|
continue;
|
|
20930
21153
|
}
|
|
20931
|
-
const fullPath =
|
|
20932
|
-
if (!
|
|
21154
|
+
const fullPath = join8(defaultSourcePath, file.dest ?? "");
|
|
21155
|
+
if (!existsSync7(fullPath)) {
|
|
20933
21156
|
errors2.push(`File source not found: ${fullPath}`);
|
|
20934
21157
|
}
|
|
20935
21158
|
}
|
|
@@ -20965,7 +21188,7 @@ function collectSyncedPaths(copyResults, workspacePath, clients) {
|
|
|
20965
21188
|
}
|
|
20966
21189
|
async function validatePlugin(pluginSource, workspacePath, offline) {
|
|
20967
21190
|
if (isPluginSpec(pluginSource)) {
|
|
20968
|
-
const resolved = await resolvePluginSpecWithAutoRegister(pluginSource
|
|
21191
|
+
const resolved = await resolvePluginSpecWithAutoRegister(pluginSource);
|
|
20969
21192
|
if (!resolved.success) {
|
|
20970
21193
|
return {
|
|
20971
21194
|
plugin: pluginSource,
|
|
@@ -20977,7 +21200,8 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
|
|
|
20977
21200
|
return {
|
|
20978
21201
|
plugin: pluginSource,
|
|
20979
21202
|
resolved: resolved.path ?? "",
|
|
20980
|
-
success: true
|
|
21203
|
+
success: true,
|
|
21204
|
+
...resolved.pluginName && { pluginName: resolved.pluginName }
|
|
20981
21205
|
};
|
|
20982
21206
|
}
|
|
20983
21207
|
if (isGitHubUrl(pluginSource)) {
|
|
@@ -20994,15 +21218,15 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
|
|
|
20994
21218
|
...fetchResult.error && { error: fetchResult.error }
|
|
20995
21219
|
};
|
|
20996
21220
|
}
|
|
20997
|
-
const resolvedPath2 = parsed?.subpath ?
|
|
21221
|
+
const resolvedPath2 = parsed?.subpath ? join8(fetchResult.cachePath, parsed.subpath) : fetchResult.cachePath;
|
|
20998
21222
|
return {
|
|
20999
21223
|
plugin: pluginSource,
|
|
21000
21224
|
resolved: resolvedPath2,
|
|
21001
21225
|
success: true
|
|
21002
21226
|
};
|
|
21003
21227
|
}
|
|
21004
|
-
const resolvedPath =
|
|
21005
|
-
if (!
|
|
21228
|
+
const resolvedPath = resolve5(workspacePath, pluginSource);
|
|
21229
|
+
if (!existsSync7(resolvedPath)) {
|
|
21006
21230
|
return {
|
|
21007
21231
|
plugin: pluginSource,
|
|
21008
21232
|
resolved: resolvedPath,
|
|
@@ -21036,7 +21260,7 @@ async function copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryR
|
|
|
21036
21260
|
async function collectAllSkills(validatedPlugins) {
|
|
21037
21261
|
const allSkills = [];
|
|
21038
21262
|
for (const plugin of validatedPlugins) {
|
|
21039
|
-
const pluginName = await getPluginName(plugin.resolved);
|
|
21263
|
+
const pluginName = plugin.pluginName ?? await getPluginName(plugin.resolved);
|
|
21040
21264
|
const skills = await collectPluginSkills(plugin.resolved, plugin.plugin);
|
|
21041
21265
|
for (const skill of skills) {
|
|
21042
21266
|
allSkills.push({
|
|
@@ -21076,9 +21300,9 @@ function buildPluginSkillNameMaps(allSkills) {
|
|
|
21076
21300
|
}
|
|
21077
21301
|
async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
21078
21302
|
const { offline = false, dryRun = false, workspaceSourceBase } = options2;
|
|
21079
|
-
const configDir =
|
|
21080
|
-
const configPath =
|
|
21081
|
-
if (!
|
|
21303
|
+
const configDir = join8(workspacePath, CONFIG_DIR);
|
|
21304
|
+
const configPath = join8(configDir, WORKSPACE_CONFIG_FILE);
|
|
21305
|
+
if (!existsSync7(configPath)) {
|
|
21082
21306
|
return {
|
|
21083
21307
|
success: false,
|
|
21084
21308
|
pluginResults: [],
|
|
@@ -21104,6 +21328,22 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
|
21104
21328
|
error: error instanceof Error ? error.message : `Failed to parse ${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`
|
|
21105
21329
|
};
|
|
21106
21330
|
}
|
|
21331
|
+
const clients = options2.clients ? config.clients.filter((c) => options2.clients?.includes(c)) : config.clients;
|
|
21332
|
+
if (options2.clients) {
|
|
21333
|
+
const invalidClients = options2.clients.filter((c) => !config.clients.includes(c));
|
|
21334
|
+
if (invalidClients.length > 0) {
|
|
21335
|
+
return {
|
|
21336
|
+
success: false,
|
|
21337
|
+
pluginResults: [],
|
|
21338
|
+
totalCopied: 0,
|
|
21339
|
+
totalFailed: 0,
|
|
21340
|
+
totalSkipped: 0,
|
|
21341
|
+
totalGenerated: 0,
|
|
21342
|
+
error: `Client(s) not configured in workspace.yaml: ${invalidClients.join(", ")}
|
|
21343
|
+
Configured clients: ${config.clients.join(", ")}`
|
|
21344
|
+
};
|
|
21345
|
+
}
|
|
21346
|
+
}
|
|
21107
21347
|
const validatedPlugins = await validateAllPlugins(config.plugins, workspacePath, offline);
|
|
21108
21348
|
let validatedWorkspaceSource = null;
|
|
21109
21349
|
if (config.workspace?.source) {
|
|
@@ -21143,18 +21383,20 @@ ${errors2}`
|
|
|
21143
21383
|
};
|
|
21144
21384
|
}
|
|
21145
21385
|
const previousState = await loadSyncState(workspacePath);
|
|
21146
|
-
const purgedPaths = previousState ?
|
|
21386
|
+
const purgedPaths = previousState ? clients.map((client) => ({
|
|
21147
21387
|
client,
|
|
21148
21388
|
paths: getPreviouslySyncedFiles(previousState, client)
|
|
21149
21389
|
})).filter((p) => p.paths.length > 0) : [];
|
|
21150
21390
|
if (!dryRun) {
|
|
21151
|
-
await selectivePurgeWorkspace(workspacePath, previousState,
|
|
21391
|
+
await selectivePurgeWorkspace(workspacePath, previousState, clients, {
|
|
21392
|
+
partialSync: !!options2.clients
|
|
21393
|
+
});
|
|
21152
21394
|
}
|
|
21153
21395
|
const allSkills = await collectAllSkills(validatedPlugins);
|
|
21154
21396
|
const pluginSkillMaps = buildPluginSkillNameMaps(allSkills);
|
|
21155
21397
|
const pluginResults = await Promise.all(validatedPlugins.map((validatedPlugin) => {
|
|
21156
21398
|
const skillNameMap = pluginSkillMaps.get(validatedPlugin.resolved);
|
|
21157
|
-
return copyValidatedPlugin(validatedPlugin, workspacePath,
|
|
21399
|
+
return copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryRun, skillNameMap);
|
|
21158
21400
|
}));
|
|
21159
21401
|
let workspaceFileResults = [];
|
|
21160
21402
|
if (config.workspace) {
|
|
@@ -21162,8 +21404,8 @@ ${errors2}`
|
|
|
21162
21404
|
const filesToCopy = [...config.workspace.files];
|
|
21163
21405
|
if (sourcePath) {
|
|
21164
21406
|
for (const agentFile of AGENT_FILES) {
|
|
21165
|
-
const agentPath =
|
|
21166
|
-
if (
|
|
21407
|
+
const agentPath = join8(sourcePath, agentFile);
|
|
21408
|
+
if (existsSync7(agentPath) && !filesToCopy.includes(agentFile)) {
|
|
21167
21409
|
filesToCopy.push(agentFile);
|
|
21168
21410
|
}
|
|
21169
21411
|
}
|
|
@@ -21202,11 +21444,11 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
21202
21444
|
};
|
|
21203
21445
|
}
|
|
21204
21446
|
workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache });
|
|
21205
|
-
if (!dryRun &&
|
|
21206
|
-
const claudePath =
|
|
21207
|
-
const agentsPath =
|
|
21208
|
-
const claudeExistsInSource =
|
|
21209
|
-
if (!claudeExistsInSource &&
|
|
21447
|
+
if (!dryRun && clients.includes("claude") && sourcePath) {
|
|
21448
|
+
const claudePath = join8(workspacePath, "CLAUDE.md");
|
|
21449
|
+
const agentsPath = join8(workspacePath, "AGENTS.md");
|
|
21450
|
+
const claudeExistsInSource = existsSync7(join8(sourcePath, "CLAUDE.md"));
|
|
21451
|
+
if (!claudeExistsInSource && existsSync7(agentsPath) && !existsSync7(claudePath)) {
|
|
21210
21452
|
await copyFile(agentsPath, claudePath);
|
|
21211
21453
|
}
|
|
21212
21454
|
}
|
|
@@ -21252,7 +21494,14 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
21252
21494
|
...pluginResults.flatMap((r) => r.copyResults),
|
|
21253
21495
|
...workspaceFileResults
|
|
21254
21496
|
];
|
|
21255
|
-
const syncedFiles = collectSyncedPaths(allCopyResults, workspacePath,
|
|
21497
|
+
const syncedFiles = collectSyncedPaths(allCopyResults, workspacePath, clients);
|
|
21498
|
+
if (options2.clients && previousState) {
|
|
21499
|
+
for (const [client, files] of Object.entries(previousState.files)) {
|
|
21500
|
+
if (!clients.includes(client)) {
|
|
21501
|
+
syncedFiles[client] = files;
|
|
21502
|
+
}
|
|
21503
|
+
}
|
|
21504
|
+
}
|
|
21256
21505
|
await saveSyncState(workspacePath, syncedFiles);
|
|
21257
21506
|
}
|
|
21258
21507
|
return {
|
|
@@ -21265,79 +21514,6 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
|
|
|
21265
21514
|
purgedPaths
|
|
21266
21515
|
};
|
|
21267
21516
|
}
|
|
21268
|
-
async function resolvePluginSpecWithAutoRegister(spec, _offline = false) {
|
|
21269
|
-
const parsed = parsePluginSpec(spec);
|
|
21270
|
-
if (!parsed) {
|
|
21271
|
-
return {
|
|
21272
|
-
success: false,
|
|
21273
|
-
error: `Invalid plugin spec format: ${spec}
|
|
21274
|
-
Expected: plugin@marketplace or plugin@owner/repo[/subpath]`
|
|
21275
|
-
};
|
|
21276
|
-
}
|
|
21277
|
-
const { plugin: pluginName, marketplaceName, owner, repo, subpath } = parsed;
|
|
21278
|
-
let marketplace = await getMarketplace(marketplaceName);
|
|
21279
|
-
if (!marketplace) {
|
|
21280
|
-
const sourceToRegister = owner && repo ? `${owner}/${repo}` : marketplaceName;
|
|
21281
|
-
const autoRegResult = await autoRegisterMarketplace(sourceToRegister);
|
|
21282
|
-
if (!autoRegResult.success) {
|
|
21283
|
-
return {
|
|
21284
|
-
success: false,
|
|
21285
|
-
error: autoRegResult.error || "Unknown error"
|
|
21286
|
-
};
|
|
21287
|
-
}
|
|
21288
|
-
marketplace = await getMarketplace(autoRegResult.name ?? marketplaceName);
|
|
21289
|
-
}
|
|
21290
|
-
if (!marketplace) {
|
|
21291
|
-
return {
|
|
21292
|
-
success: false,
|
|
21293
|
-
error: `Marketplace '${marketplaceName}' not found`
|
|
21294
|
-
};
|
|
21295
|
-
}
|
|
21296
|
-
const expectedSubpath = subpath ?? "plugins";
|
|
21297
|
-
const resolved = await resolvePluginSpec(spec, subpath ? { subpath } : {});
|
|
21298
|
-
if (!resolved) {
|
|
21299
|
-
return {
|
|
21300
|
-
success: false,
|
|
21301
|
-
error: `Plugin '${pluginName}' not found in marketplace '${marketplaceName}'
|
|
21302
|
-
Expected at: ${marketplace.path}/${expectedSubpath}/${pluginName}/`
|
|
21303
|
-
};
|
|
21304
|
-
}
|
|
21305
|
-
return {
|
|
21306
|
-
success: true,
|
|
21307
|
-
path: resolved.path
|
|
21308
|
-
};
|
|
21309
|
-
}
|
|
21310
|
-
async function autoRegisterMarketplace(name) {
|
|
21311
|
-
const wellKnown = getWellKnownMarketplaces();
|
|
21312
|
-
if (wellKnown[name]) {
|
|
21313
|
-
console.log(`Auto-registering well-known marketplace: ${name}`);
|
|
21314
|
-
const result = await addMarketplace(name);
|
|
21315
|
-
if (!result.success) {
|
|
21316
|
-
return { success: false, error: result.error || "Unknown error" };
|
|
21317
|
-
}
|
|
21318
|
-
return { success: true, name };
|
|
21319
|
-
}
|
|
21320
|
-
if (name.includes("/") && !name.includes("://")) {
|
|
21321
|
-
const parts = name.split("/");
|
|
21322
|
-
if (parts.length === 2 && parts[0] && parts[1]) {
|
|
21323
|
-
console.log(`Auto-registering GitHub marketplace: ${name}`);
|
|
21324
|
-
const repoName = parts[1];
|
|
21325
|
-
const result = await addMarketplace(name, repoName);
|
|
21326
|
-
if (!result.success) {
|
|
21327
|
-
return { success: false, error: result.error || "Unknown error" };
|
|
21328
|
-
}
|
|
21329
|
-
return { success: true, name: repoName };
|
|
21330
|
-
}
|
|
21331
|
-
}
|
|
21332
|
-
return {
|
|
21333
|
-
success: false,
|
|
21334
|
-
error: `Marketplace '${name}' not found.
|
|
21335
|
-
Options:
|
|
21336
|
-
1. Use fully qualified name: plugin@owner/repo
|
|
21337
|
-
2. Register first: allagents plugin marketplace add <source>
|
|
21338
|
-
3. Well-known marketplaces: ${Object.keys(wellKnown).join(", ")}`
|
|
21339
|
-
};
|
|
21340
|
-
}
|
|
21341
21517
|
|
|
21342
21518
|
// src/core/github-fetch.ts
|
|
21343
21519
|
async function resolveBranchAndSubpath(owner, repo, pathAfterTree) {
|
|
@@ -21465,17 +21641,17 @@ async function fetchWorkspaceFromGitHub(url) {
|
|
|
21465
21641
|
|
|
21466
21642
|
// src/core/workspace.ts
|
|
21467
21643
|
async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
21468
|
-
const absoluteTarget =
|
|
21469
|
-
const configDir =
|
|
21470
|
-
const configPath =
|
|
21471
|
-
if (
|
|
21644
|
+
const absoluteTarget = resolve6(targetPath);
|
|
21645
|
+
const configDir = join9(absoluteTarget, CONFIG_DIR);
|
|
21646
|
+
const configPath = join9(configDir, WORKSPACE_CONFIG_FILE);
|
|
21647
|
+
if (existsSync8(configPath)) {
|
|
21472
21648
|
throw new Error(`Workspace already exists: ${absoluteTarget}
|
|
21473
21649
|
Found existing ${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`);
|
|
21474
21650
|
}
|
|
21475
21651
|
const currentFilePath = fileURLToPath2(import.meta.url);
|
|
21476
21652
|
const currentFileDir = dirname5(currentFilePath);
|
|
21477
21653
|
const isProduction = currentFilePath.includes(`${sep}dist${sep}`);
|
|
21478
|
-
const defaultTemplatePath = isProduction ?
|
|
21654
|
+
const defaultTemplatePath = isProduction ? join9(currentFileDir, "templates", "default") : join9(currentFileDir, "..", "templates", "default");
|
|
21479
21655
|
try {
|
|
21480
21656
|
await mkdir5(absoluteTarget, { recursive: true });
|
|
21481
21657
|
await mkdir5(configDir, { recursive: true });
|
|
@@ -21506,20 +21682,20 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
21506
21682
|
}
|
|
21507
21683
|
console.log(`✓ Using workspace.yaml from: ${options2.from}`);
|
|
21508
21684
|
} else {
|
|
21509
|
-
const fromPath =
|
|
21510
|
-
if (!
|
|
21685
|
+
const fromPath = resolve6(options2.from);
|
|
21686
|
+
if (!existsSync8(fromPath)) {
|
|
21511
21687
|
throw new Error(`Template not found: ${fromPath}`);
|
|
21512
21688
|
}
|
|
21513
21689
|
const { stat: stat2 } = await import("node:fs/promises");
|
|
21514
21690
|
const fromStat = await stat2(fromPath);
|
|
21515
21691
|
let sourceYamlPath;
|
|
21516
21692
|
if (fromStat.isDirectory()) {
|
|
21517
|
-
const nestedPath =
|
|
21518
|
-
const rootPath =
|
|
21519
|
-
if (
|
|
21693
|
+
const nestedPath = join9(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
21694
|
+
const rootPath = join9(fromPath, WORKSPACE_CONFIG_FILE);
|
|
21695
|
+
if (existsSync8(nestedPath)) {
|
|
21520
21696
|
sourceYamlPath = nestedPath;
|
|
21521
21697
|
sourceDir = fromPath;
|
|
21522
|
-
} else if (
|
|
21698
|
+
} else if (existsSync8(rootPath)) {
|
|
21523
21699
|
sourceYamlPath = rootPath;
|
|
21524
21700
|
sourceDir = fromPath;
|
|
21525
21701
|
} else {
|
|
@@ -21535,14 +21711,14 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
21535
21711
|
sourceDir = parentDir;
|
|
21536
21712
|
}
|
|
21537
21713
|
}
|
|
21538
|
-
workspaceYamlContent = await
|
|
21714
|
+
workspaceYamlContent = await readFile8(sourceYamlPath, "utf-8");
|
|
21539
21715
|
if (sourceDir) {
|
|
21540
21716
|
const parsed2 = load(workspaceYamlContent);
|
|
21541
21717
|
const workspace = parsed2?.workspace;
|
|
21542
21718
|
if (workspace?.source) {
|
|
21543
21719
|
const source = workspace.source;
|
|
21544
21720
|
if (!isGitHubUrl(source) && !isAbsolute2(source)) {
|
|
21545
|
-
workspace.source =
|
|
21721
|
+
workspace.source = resolve6(sourceDir, source);
|
|
21546
21722
|
workspaceYamlContent = dump(parsed2, { lineWidth: -1 });
|
|
21547
21723
|
}
|
|
21548
21724
|
}
|
|
@@ -21550,11 +21726,11 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
21550
21726
|
console.log(`✓ Using workspace.yaml from: ${sourceYamlPath}`);
|
|
21551
21727
|
}
|
|
21552
21728
|
} else {
|
|
21553
|
-
const defaultYamlPath =
|
|
21554
|
-
if (!
|
|
21729
|
+
const defaultYamlPath = join9(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
21730
|
+
if (!existsSync8(defaultYamlPath)) {
|
|
21555
21731
|
throw new Error(`Default template not found at: ${defaultTemplatePath}`);
|
|
21556
21732
|
}
|
|
21557
|
-
workspaceYamlContent = await
|
|
21733
|
+
workspaceYamlContent = await readFile8(defaultYamlPath, "utf-8");
|
|
21558
21734
|
}
|
|
21559
21735
|
await writeFile4(configPath, workspaceYamlContent, "utf-8");
|
|
21560
21736
|
const copiedAgentFiles = [];
|
|
@@ -21566,7 +21742,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
21566
21742
|
const filePath = basePath ? `${basePath}/${agentFile}` : agentFile;
|
|
21567
21743
|
const content = await fetchFileFromGitHub(parsedUrl.owner, parsedUrl.repo, filePath, parsedUrl.branch);
|
|
21568
21744
|
if (content) {
|
|
21569
|
-
await writeFile4(
|
|
21745
|
+
await writeFile4(join9(absoluteTarget, agentFile), content, "utf-8");
|
|
21570
21746
|
copiedAgentFiles.push(agentFile);
|
|
21571
21747
|
}
|
|
21572
21748
|
}
|
|
@@ -21574,27 +21750,27 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
21574
21750
|
} else {
|
|
21575
21751
|
const effectiveSourceDir = sourceDir ?? defaultTemplatePath;
|
|
21576
21752
|
for (const agentFile of AGENT_FILES) {
|
|
21577
|
-
const sourcePath =
|
|
21578
|
-
if (
|
|
21579
|
-
const content = await
|
|
21580
|
-
await writeFile4(
|
|
21753
|
+
const sourcePath = join9(effectiveSourceDir, agentFile);
|
|
21754
|
+
if (existsSync8(sourcePath)) {
|
|
21755
|
+
const content = await readFile8(sourcePath, "utf-8");
|
|
21756
|
+
await writeFile4(join9(absoluteTarget, agentFile), content, "utf-8");
|
|
21581
21757
|
copiedAgentFiles.push(agentFile);
|
|
21582
21758
|
}
|
|
21583
21759
|
}
|
|
21584
21760
|
}
|
|
21585
21761
|
if (copiedAgentFiles.length === 0) {
|
|
21586
|
-
await ensureWorkspaceRules(
|
|
21762
|
+
await ensureWorkspaceRules(join9(absoluteTarget, "AGENTS.md"));
|
|
21587
21763
|
copiedAgentFiles.push("AGENTS.md");
|
|
21588
21764
|
} else {
|
|
21589
21765
|
for (const agentFile of copiedAgentFiles) {
|
|
21590
|
-
await ensureWorkspaceRules(
|
|
21766
|
+
await ensureWorkspaceRules(join9(absoluteTarget, agentFile));
|
|
21591
21767
|
}
|
|
21592
21768
|
}
|
|
21593
21769
|
const parsed = load(workspaceYamlContent);
|
|
21594
21770
|
const clients = parsed?.clients ?? [];
|
|
21595
21771
|
if (clients.includes("claude") && !copiedAgentFiles.includes("CLAUDE.md") && copiedAgentFiles.includes("AGENTS.md")) {
|
|
21596
|
-
const agentsPath =
|
|
21597
|
-
const claudePath =
|
|
21772
|
+
const agentsPath = join9(absoluteTarget, "AGENTS.md");
|
|
21773
|
+
const claudePath = join9(absoluteTarget, "CLAUDE.md");
|
|
21598
21774
|
await copyFile2(agentsPath, claudePath);
|
|
21599
21775
|
}
|
|
21600
21776
|
console.log(`✓ Workspace created at: ${absoluteTarget}`);
|
|
@@ -21628,11 +21804,11 @@ Next steps:`);
|
|
|
21628
21804
|
}
|
|
21629
21805
|
|
|
21630
21806
|
// src/core/status.ts
|
|
21631
|
-
import { existsSync as
|
|
21632
|
-
import { join as
|
|
21807
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
21808
|
+
import { join as join10 } from "node:path";
|
|
21633
21809
|
async function getWorkspaceStatus(workspacePath = process.cwd()) {
|
|
21634
|
-
const configPath =
|
|
21635
|
-
if (!
|
|
21810
|
+
const configPath = join10(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
21811
|
+
if (!existsSync9(configPath)) {
|
|
21636
21812
|
return {
|
|
21637
21813
|
success: false,
|
|
21638
21814
|
error: `${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
|
|
@@ -21645,9 +21821,14 @@ async function getWorkspaceStatus(workspacePath = process.cwd()) {
|
|
|
21645
21821
|
const config = await parseWorkspaceConfig(configPath);
|
|
21646
21822
|
const plugins = [];
|
|
21647
21823
|
for (const pluginSource of config.plugins) {
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21824
|
+
if (isPluginSpec(pluginSource)) {
|
|
21825
|
+
const status = await getMarketplacePluginStatus(pluginSource);
|
|
21826
|
+
plugins.push(status);
|
|
21827
|
+
} else {
|
|
21828
|
+
const parsed = parsePluginSource(pluginSource, workspacePath);
|
|
21829
|
+
const status = getPluginStatus(parsed);
|
|
21830
|
+
plugins.push(status);
|
|
21831
|
+
}
|
|
21651
21832
|
}
|
|
21652
21833
|
return {
|
|
21653
21834
|
success: true,
|
|
@@ -21666,7 +21847,7 @@ async function getWorkspaceStatus(workspacePath = process.cwd()) {
|
|
|
21666
21847
|
function getPluginStatus(parsed) {
|
|
21667
21848
|
if (parsed.type === "github") {
|
|
21668
21849
|
const cachePath = parsed.owner && parsed.repo ? getPluginCachePath(parsed.owner, parsed.repo) : "";
|
|
21669
|
-
const available2 = cachePath ?
|
|
21850
|
+
const available2 = cachePath ? existsSync9(cachePath) : false;
|
|
21670
21851
|
return {
|
|
21671
21852
|
source: parsed.original,
|
|
21672
21853
|
type: "github",
|
|
@@ -21676,7 +21857,7 @@ function getPluginStatus(parsed) {
|
|
|
21676
21857
|
...parsed.repo && { repo: parsed.repo }
|
|
21677
21858
|
};
|
|
21678
21859
|
}
|
|
21679
|
-
const available =
|
|
21860
|
+
const available = existsSync9(parsed.normalized);
|
|
21680
21861
|
return {
|
|
21681
21862
|
source: parsed.original,
|
|
21682
21863
|
type: "local",
|
|
@@ -21684,14 +21865,23 @@ function getPluginStatus(parsed) {
|
|
|
21684
21865
|
path: parsed.normalized
|
|
21685
21866
|
};
|
|
21686
21867
|
}
|
|
21868
|
+
async function getMarketplacePluginStatus(spec) {
|
|
21869
|
+
const resolved = await resolvePluginSpecWithAutoRegister(spec);
|
|
21870
|
+
return {
|
|
21871
|
+
source: spec,
|
|
21872
|
+
type: "marketplace",
|
|
21873
|
+
available: resolved.success,
|
|
21874
|
+
path: resolved.path ?? ""
|
|
21875
|
+
};
|
|
21876
|
+
}
|
|
21687
21877
|
|
|
21688
21878
|
// src/core/workspace-modify.ts
|
|
21689
|
-
import { readFile as
|
|
21690
|
-
import { existsSync as
|
|
21691
|
-
import { join as
|
|
21879
|
+
import { readFile as readFile9, writeFile as writeFile5 } from "node:fs/promises";
|
|
21880
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
21881
|
+
import { join as join11 } from "node:path";
|
|
21692
21882
|
async function addPlugin(plugin, workspacePath = process.cwd()) {
|
|
21693
|
-
const configPath =
|
|
21694
|
-
if (!
|
|
21883
|
+
const configPath = join11(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
21884
|
+
if (!existsSync10(configPath)) {
|
|
21695
21885
|
return {
|
|
21696
21886
|
success: false,
|
|
21697
21887
|
error: `${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
|
|
@@ -21699,31 +21889,14 @@ async function addPlugin(plugin, workspacePath = process.cwd()) {
|
|
|
21699
21889
|
};
|
|
21700
21890
|
}
|
|
21701
21891
|
if (isPluginSpec(plugin)) {
|
|
21702
|
-
const
|
|
21703
|
-
if (!
|
|
21704
|
-
return {
|
|
21705
|
-
success: false,
|
|
21706
|
-
error: `Invalid plugin spec: ${plugin}`
|
|
21707
|
-
};
|
|
21708
|
-
}
|
|
21709
|
-
const autoRegResult = await ensureMarketplaceRegistered(plugin);
|
|
21710
|
-
if (!autoRegResult.success) {
|
|
21711
|
-
return {
|
|
21712
|
-
success: false,
|
|
21713
|
-
error: autoRegResult.error || "Unknown error"
|
|
21714
|
-
};
|
|
21715
|
-
}
|
|
21716
|
-
const resolved = await resolvePluginSpec(plugin, parsed.subpath ? { subpath: parsed.subpath } : {});
|
|
21717
|
-
if (!resolved) {
|
|
21718
|
-
const marketplace = await getMarketplace(autoRegResult.registeredAs || parsed.marketplaceName);
|
|
21719
|
-
const expectedSubpath = parsed.subpath ?? "plugins";
|
|
21892
|
+
const resolved = await resolvePluginSpecWithAutoRegister(plugin);
|
|
21893
|
+
if (!resolved.success) {
|
|
21720
21894
|
return {
|
|
21721
21895
|
success: false,
|
|
21722
|
-
error:
|
|
21723
|
-
Expected at: ${marketplace?.path ?? `~/.allagents/marketplaces/${parsed.marketplaceName}`}/${expectedSubpath}/${parsed.plugin}/`
|
|
21896
|
+
error: resolved.error || "Unknown error"
|
|
21724
21897
|
};
|
|
21725
21898
|
}
|
|
21726
|
-
return await addPluginToConfig(
|
|
21899
|
+
return await addPluginToConfig(resolved.registeredAs ? plugin.replace(/@[^@]+$/, `@${resolved.registeredAs}`) : plugin, configPath, resolved.registeredAs);
|
|
21727
21900
|
}
|
|
21728
21901
|
if (isGitHubUrl(plugin)) {
|
|
21729
21902
|
const validation = validatePluginSource(plugin);
|
|
@@ -21741,8 +21914,8 @@ async function addPlugin(plugin, workspacePath = process.cwd()) {
|
|
|
21741
21914
|
};
|
|
21742
21915
|
}
|
|
21743
21916
|
} else {
|
|
21744
|
-
const fullPath =
|
|
21745
|
-
if (!
|
|
21917
|
+
const fullPath = join11(workspacePath, plugin);
|
|
21918
|
+
if (!existsSync10(fullPath) && !existsSync10(plugin)) {
|
|
21746
21919
|
return {
|
|
21747
21920
|
success: false,
|
|
21748
21921
|
error: `Plugin not found at ${plugin}`
|
|
@@ -21751,58 +21924,9 @@ async function addPlugin(plugin, workspacePath = process.cwd()) {
|
|
|
21751
21924
|
}
|
|
21752
21925
|
return await addPluginToConfig(plugin, configPath);
|
|
21753
21926
|
}
|
|
21754
|
-
async function ensureMarketplaceRegistered(spec) {
|
|
21755
|
-
const atIndex = spec.lastIndexOf("@");
|
|
21756
|
-
const marketplaceName = spec.slice(atIndex + 1);
|
|
21757
|
-
if (!marketplaceName) {
|
|
21758
|
-
return {
|
|
21759
|
-
success: false,
|
|
21760
|
-
error: `Invalid plugin spec: ${spec}`
|
|
21761
|
-
};
|
|
21762
|
-
}
|
|
21763
|
-
const existing = await getMarketplace(marketplaceName);
|
|
21764
|
-
if (existing) {
|
|
21765
|
-
return { success: true };
|
|
21766
|
-
}
|
|
21767
|
-
const wellKnown = getWellKnownMarketplaces();
|
|
21768
|
-
if (wellKnown[marketplaceName]) {
|
|
21769
|
-
console.log(`Auto-registering well-known marketplace: ${marketplaceName}`);
|
|
21770
|
-
const result = await addMarketplace(marketplaceName);
|
|
21771
|
-
if (!result.success) {
|
|
21772
|
-
return { success: false, error: result.error || "Unknown error" };
|
|
21773
|
-
}
|
|
21774
|
-
return { success: true, registeredAs: marketplaceName };
|
|
21775
|
-
}
|
|
21776
|
-
if (marketplaceName.includes("/") && !marketplaceName.includes("://")) {
|
|
21777
|
-
const parts = marketplaceName.split("/");
|
|
21778
|
-
if (parts.length >= 2 && parts[0] && parts[1]) {
|
|
21779
|
-
const owner = parts[0];
|
|
21780
|
-
const repo = parts[1];
|
|
21781
|
-
const ownerRepo = `${owner}/${repo}`;
|
|
21782
|
-
const existingByRepo = await getMarketplace(repo);
|
|
21783
|
-
if (existingByRepo) {
|
|
21784
|
-
return { success: true, registeredAs: repo };
|
|
21785
|
-
}
|
|
21786
|
-
console.log(`Auto-registering GitHub marketplace: ${ownerRepo}`);
|
|
21787
|
-
const result = await addMarketplace(ownerRepo, repo);
|
|
21788
|
-
if (!result.success) {
|
|
21789
|
-
return { success: false, error: result.error || "Unknown error" };
|
|
21790
|
-
}
|
|
21791
|
-
return { success: true, registeredAs: repo };
|
|
21792
|
-
}
|
|
21793
|
-
}
|
|
21794
|
-
return {
|
|
21795
|
-
success: false,
|
|
21796
|
-
error: `Marketplace '${marketplaceName}' not found.
|
|
21797
|
-
Options:
|
|
21798
|
-
1. Use fully qualified name: plugin@owner/repo
|
|
21799
|
-
2. Register first: allagents plugin marketplace add <source>
|
|
21800
|
-
3. Well-known marketplaces: ${Object.keys(wellKnown).join(", ")}`
|
|
21801
|
-
};
|
|
21802
|
-
}
|
|
21803
21927
|
async function addPluginToConfig(plugin, configPath, autoRegistered) {
|
|
21804
21928
|
try {
|
|
21805
|
-
const content = await
|
|
21929
|
+
const content = await readFile9(configPath, "utf-8");
|
|
21806
21930
|
const config = load(content);
|
|
21807
21931
|
if (config.plugins.includes(plugin)) {
|
|
21808
21932
|
return {
|
|
@@ -21825,8 +21949,8 @@ async function addPluginToConfig(plugin, configPath, autoRegistered) {
|
|
|
21825
21949
|
}
|
|
21826
21950
|
}
|
|
21827
21951
|
async function removePlugin(plugin, workspacePath = process.cwd()) {
|
|
21828
|
-
const configPath =
|
|
21829
|
-
if (!
|
|
21952
|
+
const configPath = join11(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
21953
|
+
if (!existsSync10(configPath)) {
|
|
21830
21954
|
return {
|
|
21831
21955
|
success: false,
|
|
21832
21956
|
error: `${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
|
|
@@ -21834,7 +21958,7 @@ async function removePlugin(plugin, workspacePath = process.cwd()) {
|
|
|
21834
21958
|
};
|
|
21835
21959
|
}
|
|
21836
21960
|
try {
|
|
21837
|
-
const content = await
|
|
21961
|
+
const content = await readFile9(configPath, "utf-8");
|
|
21838
21962
|
const config = load(content);
|
|
21839
21963
|
let index = config.plugins.indexOf(plugin);
|
|
21840
21964
|
if (index === -1 && isPluginSpec(plugin) === false) {
|
|
@@ -21860,6 +21984,49 @@ async function removePlugin(plugin, workspacePath = process.cwd()) {
|
|
|
21860
21984
|
|
|
21861
21985
|
// src/cli/commands/workspace.ts
|
|
21862
21986
|
var workspaceCommand = new Command("workspace").description("Manage AI agent workspaces - initialize, sync, and configure plugins");
|
|
21987
|
+
async function runSyncAndPrint() {
|
|
21988
|
+
console.log(`
|
|
21989
|
+
Syncing workspace...
|
|
21990
|
+
`);
|
|
21991
|
+
const result = await syncWorkspace();
|
|
21992
|
+
if (!result.success && result.error) {
|
|
21993
|
+
console.error(`Sync error: ${result.error}`);
|
|
21994
|
+
return false;
|
|
21995
|
+
}
|
|
21996
|
+
for (const pluginResult of result.pluginResults) {
|
|
21997
|
+
const status = pluginResult.success ? "✓" : "✗";
|
|
21998
|
+
console.log(`${status} Plugin: ${pluginResult.plugin}`);
|
|
21999
|
+
if (pluginResult.error) {
|
|
22000
|
+
console.log(` Error: ${pluginResult.error}`);
|
|
22001
|
+
}
|
|
22002
|
+
const copied = pluginResult.copyResults.filter((r) => r.action === "copied").length;
|
|
22003
|
+
const generated = pluginResult.copyResults.filter((r) => r.action === "generated").length;
|
|
22004
|
+
const failed = pluginResult.copyResults.filter((r) => r.action === "failed").length;
|
|
22005
|
+
if (copied > 0)
|
|
22006
|
+
console.log(` Copied: ${copied} files`);
|
|
22007
|
+
if (generated > 0)
|
|
22008
|
+
console.log(` Generated: ${generated} files`);
|
|
22009
|
+
if (failed > 0) {
|
|
22010
|
+
console.log(` Failed: ${failed} files`);
|
|
22011
|
+
for (const failedResult of pluginResult.copyResults.filter((r) => r.action === "failed")) {
|
|
22012
|
+
console.log(` - ${failedResult.destination}: ${failedResult.error}`);
|
|
22013
|
+
}
|
|
22014
|
+
}
|
|
22015
|
+
}
|
|
22016
|
+
console.log(`
|
|
22017
|
+
Sync complete:`);
|
|
22018
|
+
console.log(` Total copied: ${result.totalCopied}`);
|
|
22019
|
+
if (result.totalGenerated > 0) {
|
|
22020
|
+
console.log(` Total generated: ${result.totalGenerated}`);
|
|
22021
|
+
}
|
|
22022
|
+
if (result.totalFailed > 0) {
|
|
22023
|
+
console.log(` Total failed: ${result.totalFailed}`);
|
|
22024
|
+
}
|
|
22025
|
+
if (result.totalSkipped > 0) {
|
|
22026
|
+
console.log(` Total skipped: ${result.totalSkipped}`);
|
|
22027
|
+
}
|
|
22028
|
+
return result.success && result.totalFailed === 0;
|
|
22029
|
+
}
|
|
21863
22030
|
workspaceCommand.command("init [path]").description("Create new workspace and sync plugins").option("--from <template>", "Copy workspace.yaml from existing template/workspace").action(async (path3, options2) => {
|
|
21864
22031
|
try {
|
|
21865
22032
|
const targetPath = path3 ?? ".";
|
|
@@ -21891,17 +22058,25 @@ Sync complete: ${syncResult.totalCopied} files copied`);
|
|
|
21891
22058
|
throw error;
|
|
21892
22059
|
}
|
|
21893
22060
|
});
|
|
21894
|
-
workspaceCommand.command("sync").description("Sync plugins to workspace").option("--offline", "Use cached plugins without fetching latest from remote").option("-n, --dry-run", "Simulate sync without making changes").action(async (options2) => {
|
|
22061
|
+
workspaceCommand.command("sync").description("Sync plugins to workspace").option("--offline", "Use cached plugins without fetching latest from remote").option("-n, --dry-run", "Simulate sync without making changes").option("-c, --client <client>", "Sync only the specified client (e.g., opencode, claude)").action(async (options2) => {
|
|
21895
22062
|
try {
|
|
21896
22063
|
const offline = options2.offline ?? false;
|
|
21897
22064
|
const dryRun = options2.dryRun ?? false;
|
|
21898
22065
|
if (dryRun) {
|
|
21899
22066
|
console.log(`Dry run mode - no changes will be made
|
|
22067
|
+
`);
|
|
22068
|
+
}
|
|
22069
|
+
if (options2.client) {
|
|
22070
|
+
console.log(`Syncing client: ${options2.client}
|
|
21900
22071
|
`);
|
|
21901
22072
|
}
|
|
21902
22073
|
console.log(`Syncing workspace...
|
|
21903
22074
|
`);
|
|
21904
|
-
const result = await syncWorkspace(process.cwd(), {
|
|
22075
|
+
const result = await syncWorkspace(process.cwd(), {
|
|
22076
|
+
offline,
|
|
22077
|
+
dryRun,
|
|
22078
|
+
...options2.client && { clients: [options2.client] }
|
|
22079
|
+
});
|
|
21905
22080
|
if (!result.success && result.error) {
|
|
21906
22081
|
console.error(`Error: ${result.error}`);
|
|
21907
22082
|
process.exit(1);
|
|
@@ -21974,7 +22149,14 @@ workspaceCommand.command("status").description("Show sync status of plugins").ac
|
|
|
21974
22149
|
} else {
|
|
21975
22150
|
for (const plugin of result.plugins) {
|
|
21976
22151
|
const status = plugin.available ? "✓" : "✗";
|
|
21977
|
-
|
|
22152
|
+
let typeLabel;
|
|
22153
|
+
if (plugin.type === "marketplace") {
|
|
22154
|
+
typeLabel = plugin.available ? "marketplace" : "not synced";
|
|
22155
|
+
} else if (plugin.type === "github") {
|
|
22156
|
+
typeLabel = plugin.available ? "cached" : "not cached";
|
|
22157
|
+
} else {
|
|
22158
|
+
typeLabel = "local";
|
|
22159
|
+
}
|
|
21978
22160
|
console.log(` ${status} ${plugin.source} (${typeLabel})`);
|
|
21979
22161
|
}
|
|
21980
22162
|
}
|
|
@@ -21994,7 +22176,7 @@ Clients (${result.clients.length}):`);
|
|
|
21994
22176
|
}
|
|
21995
22177
|
});
|
|
21996
22178
|
var pluginSubcommand = new Command("plugin").description("Manage plugins in .allagents/workspace.yaml");
|
|
21997
|
-
pluginSubcommand.command("
|
|
22179
|
+
pluginSubcommand.command("install <plugin>").description("Install plugin to .allagents/workspace.yaml (supports plugin@marketplace, GitHub URL, or local path)").action(async (plugin) => {
|
|
21998
22180
|
try {
|
|
21999
22181
|
const result = await addPlugin(plugin);
|
|
22000
22182
|
if (!result.success) {
|
|
@@ -22004,9 +22186,11 @@ pluginSubcommand.command("add <plugin>").description("Add plugin to .allagents/w
|
|
|
22004
22186
|
if (result.autoRegistered) {
|
|
22005
22187
|
console.log(`✓ Auto-registered marketplace: ${result.autoRegistered}`);
|
|
22006
22188
|
}
|
|
22007
|
-
console.log(`✓
|
|
22008
|
-
|
|
22009
|
-
|
|
22189
|
+
console.log(`✓ Installed plugin: ${plugin}`);
|
|
22190
|
+
const syncOk = await runSyncAndPrint();
|
|
22191
|
+
if (!syncOk) {
|
|
22192
|
+
process.exit(1);
|
|
22193
|
+
}
|
|
22010
22194
|
} catch (error) {
|
|
22011
22195
|
if (error instanceof Error) {
|
|
22012
22196
|
console.error(`Error: ${error.message}`);
|
|
@@ -22015,14 +22199,18 @@ Run "allagents workspace sync" to fetch and sync the plugin.`);
|
|
|
22015
22199
|
throw error;
|
|
22016
22200
|
}
|
|
22017
22201
|
});
|
|
22018
|
-
pluginSubcommand.command("
|
|
22202
|
+
pluginSubcommand.command("uninstall <plugin>").alias("remove").description("Uninstall plugin from .allagents/workspace.yaml").action(async (plugin) => {
|
|
22019
22203
|
try {
|
|
22020
22204
|
const result = await removePlugin(plugin);
|
|
22021
22205
|
if (!result.success) {
|
|
22022
22206
|
console.error(`Error: ${result.error}`);
|
|
22023
22207
|
process.exit(1);
|
|
22024
22208
|
}
|
|
22025
|
-
console.log(`✓
|
|
22209
|
+
console.log(`✓ Uninstalled plugin: ${plugin}`);
|
|
22210
|
+
const syncOk = await runSyncAndPrint();
|
|
22211
|
+
if (!syncOk) {
|
|
22212
|
+
process.exit(1);
|
|
22213
|
+
}
|
|
22026
22214
|
} catch (error) {
|
|
22027
22215
|
if (error instanceof Error) {
|
|
22028
22216
|
console.error(`Error: ${error.message}`);
|
|
@@ -22189,9 +22377,9 @@ pluginCommand.command("validate <path>").description("Validate plugin structure
|
|
|
22189
22377
|
console.log("(validation not yet implemented)");
|
|
22190
22378
|
});
|
|
22191
22379
|
|
|
22192
|
-
// src/cli/commands/
|
|
22380
|
+
// src/cli/commands/self.ts
|
|
22193
22381
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
22194
|
-
import { dirname as dirname6, join as
|
|
22382
|
+
import { dirname as dirname6, join as join12 } from "node:path";
|
|
22195
22383
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
22196
22384
|
function detectPackageManagerFromPath(scriptPath) {
|
|
22197
22385
|
if (scriptPath.includes(".bun")) {
|
|
@@ -22205,14 +22393,15 @@ function detectPackageManager() {
|
|
|
22205
22393
|
function getCurrentVersion() {
|
|
22206
22394
|
try {
|
|
22207
22395
|
const __dirname2 = dirname6(fileURLToPath3(import.meta.url));
|
|
22208
|
-
const packageJsonPath =
|
|
22396
|
+
const packageJsonPath = join12(__dirname2, "..", "package.json");
|
|
22209
22397
|
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
22210
22398
|
return packageJson.version;
|
|
22211
22399
|
} catch {
|
|
22212
22400
|
return "unknown";
|
|
22213
22401
|
}
|
|
22214
22402
|
}
|
|
22215
|
-
var
|
|
22403
|
+
var selfCommand = new Command("self").description("Manage the allagents installation");
|
|
22404
|
+
selfCommand.command("update").description("Update allagents to the latest version").option("--npm", "Force update using npm").option("--bun", "Force update using bun").action(async (options2) => {
|
|
22216
22405
|
try {
|
|
22217
22406
|
let packageManager;
|
|
22218
22407
|
if (options2.npm && options2.bun) {
|
|
@@ -22262,11 +22451,11 @@ Update complete.`);
|
|
|
22262
22451
|
|
|
22263
22452
|
// src/cli/index.ts
|
|
22264
22453
|
var __dirname2 = dirname7(fileURLToPath4(import.meta.url));
|
|
22265
|
-
var packageJsonPath =
|
|
22454
|
+
var packageJsonPath = join13(__dirname2, "..", "package.json");
|
|
22266
22455
|
var packageJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
22267
22456
|
var program2 = new Command;
|
|
22268
22457
|
program2.name("allagents").description("CLI tool for managing multi-repo AI agent workspaces with plugin synchronization").version(packageJson.version);
|
|
22269
22458
|
program2.addCommand(workspaceCommand);
|
|
22270
22459
|
program2.addCommand(pluginCommand);
|
|
22271
|
-
program2.addCommand(
|
|
22460
|
+
program2.addCommand(selfCommand);
|
|
22272
22461
|
program2.parse();
|