allagents 1.0.3 → 1.0.6

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.
Files changed (3) hide show
  1. package/README.md +4 -4
  2. package/dist/index.js +117 -40
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -44,11 +44,11 @@ CLI tool for managing multi-repo AI agent workspaces with plugin synchronization
44
44
  ## Installation
45
45
 
46
46
  ```bash
47
- # Using bun
48
- bun install -g allagents
47
+ # Using npm
48
+ npm install -g allagents
49
49
 
50
- # Or run directly
51
- bunx allagents
50
+ # Or run directly without installing
51
+ npx allagents
52
52
  ```
53
53
 
54
54
  ## Quick Start
package/dist/index.js CHANGED
@@ -29572,7 +29572,7 @@ function classifyDeletedPath(path, client, mapping) {
29572
29572
  }
29573
29573
  return null;
29574
29574
  }
29575
- function computeDeletedArtifacts(previousState, newStatePaths, clients, clientMappings) {
29575
+ function computeDeletedArtifacts(previousState, newStatePaths, clients, clientMappings, availableSkillNames) {
29576
29576
  if (!previousState)
29577
29577
  return [];
29578
29578
  const deleted = [];
@@ -29589,6 +29589,8 @@ function computeDeletedArtifacts(previousState, newStatePaths, clients, clientMa
29589
29589
  const artifact = classifyDeletedPath(path, client, mapping);
29590
29590
  if (!artifact)
29591
29591
  continue;
29592
+ if (artifact.type === "skill" && availableSkillNames?.has(artifact.name))
29593
+ continue;
29592
29594
  const key = `${client}:${artifact.type}:${artifact.name}`;
29593
29595
  if (!seen.has(key)) {
29594
29596
  seen.add(key);
@@ -29598,6 +29600,16 @@ function computeDeletedArtifacts(previousState, newStatePaths, clients, clientMa
29598
29600
  }
29599
29601
  return deleted;
29600
29602
  }
29603
+ async function collectAvailableSkillNames(validPlugins) {
29604
+ const names = new Set;
29605
+ for (const plugin of validPlugins) {
29606
+ const skills = await collectPluginSkills(plugin.resolved, plugin.plugin);
29607
+ for (const skill of skills) {
29608
+ names.add(skill.folderName);
29609
+ }
29610
+ }
29611
+ return names;
29612
+ }
29601
29613
  async function validatePlugin(pluginSource, workspacePath, offline) {
29602
29614
  if (isPluginSpec(pluginSource)) {
29603
29615
  const resolved = await resolvePluginSpecWithAutoRegister(pluginSource, {
@@ -30146,10 +30158,11 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30146
30158
  }
30147
30159
  const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, workspaceFileResults);
30148
30160
  const hasFailures = pluginResults.some((r) => !r.success) || totalFailed > 0;
30161
+ const availableSkillNames = await collectAvailableSkillNames(validPlugins);
30149
30162
  const allCopyResultsForState = [...pluginResults.flatMap((r) => r.copyResults), ...workspaceFileResults];
30150
30163
  const resolvedMappings = resolveClientMappings(syncClients, CLIENT_MAPPINGS);
30151
30164
  const newStatePaths = collectSyncedPaths(allCopyResultsForState, workspacePath, syncClients, resolvedMappings);
30152
- const deletedArtifacts = computeDeletedArtifacts(previousState, newStatePaths, syncClients, resolvedMappings);
30165
+ const deletedArtifacts = computeDeletedArtifacts(previousState, newStatePaths, syncClients, resolvedMappings, availableSkillNames);
30153
30166
  const { pluginsByClient: nativePluginsByClient } = collectNativePluginSources(validPlugins);
30154
30167
  if (!dryRun) {
30155
30168
  await persistSyncState(workspacePath, pluginResults, workspaceFileResults, syncClients, nativePluginsByClient, nativeResult, vscodeState ? { vscodeState } : undefined);
@@ -30235,10 +30248,11 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
30235
30248
  mcpResults.codex = codexMcp;
30236
30249
  }
30237
30250
  const nativeResult = await syncNativePlugins(validPlugins, previousState, "user", homeDir, dryRun, warnings, messages);
30251
+ const availableUserSkillNames = await collectAvailableSkillNames(validPlugins);
30238
30252
  const allCopyResultsForState = pluginResults.flatMap((r) => r.copyResults);
30239
30253
  const resolvedUserMappings = resolveClientMappings(syncClients, USER_CLIENT_MAPPINGS);
30240
30254
  const newStatePaths = collectSyncedPaths(allCopyResultsForState, homeDir, syncClients, resolvedUserMappings);
30241
- const deletedArtifacts = computeDeletedArtifacts(previousState, newStatePaths, syncClients, resolvedUserMappings);
30255
+ const deletedArtifacts = computeDeletedArtifacts(previousState, newStatePaths, syncClients, resolvedUserMappings, availableUserSkillNames);
30242
30256
  if (!dryRun) {
30243
30257
  const { pluginsByClient: nativePluginsByClient } = collectNativePluginSources(validPlugins);
30244
30258
  await persistSyncState(homeDir, pluginResults, [], syncClients, nativePluginsByClient, nativeResult, {
@@ -30841,28 +30855,19 @@ function formatSyncSummary(result, { dryRun = false, label = "Sync" } = {}) {
30841
30855
  return lines;
30842
30856
  }
30843
30857
  function formatDeletedArtifacts(artifacts) {
30844
- const byClient = new Map;
30845
- for (const artifact of artifacts) {
30846
- const displayName = getDisplayName(artifact.client);
30847
- let list = byClient.get(displayName);
30848
- if (!list) {
30849
- list = [];
30850
- byClient.set(displayName, list);
30851
- }
30852
- list.push(artifact);
30853
- }
30854
- return Array.from(byClient.entries()).map(([displayClient, items]) => {
30855
- const seen = new Set;
30856
- const unique = items.filter((a) => {
30857
- const key = `${a.type}:${a.name}`;
30858
- if (seen.has(key))
30859
- return false;
30860
- seen.add(key);
30861
- return true;
30862
- });
30863
- const names = unique.map((a) => `${a.type} '${a.name}'`).join(", ");
30864
- return ` Deleted (${displayClient}): ${names}`;
30865
- });
30858
+ const seen = new Set;
30859
+ const unique = [];
30860
+ for (const a of artifacts) {
30861
+ const key = `${a.type}:${a.name}`;
30862
+ if (seen.has(key))
30863
+ continue;
30864
+ seen.add(key);
30865
+ unique.push(a);
30866
+ }
30867
+ if (unique.length === 0)
30868
+ return [];
30869
+ const names = unique.map((a) => `${a.type} '${a.name}'`).join(", ");
30870
+ return [` Deleted: ${names}`];
30866
30871
  }
30867
30872
  function formatMcpResult(mcpResult, scope) {
30868
30873
  const { added, overwritten, removed, skipped } = mcpResult;
@@ -33411,7 +33416,7 @@ var package_default;
33411
33416
  var init_package = __esm(() => {
33412
33417
  package_default = {
33413
33418
  name: "allagents",
33414
- version: "1.0.3",
33419
+ version: "1.0.6",
33415
33420
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
33416
33421
  type: "module",
33417
33422
  bin: {
@@ -33438,7 +33443,8 @@ var init_package = __esm(() => {
33438
33443
  prepare: "bun run build && (test -d .git && bunx prek install -t pre-push || true)",
33439
33444
  release: "bun run scripts/release.ts",
33440
33445
  "release:next": "bun run scripts/release.ts next",
33441
- "publish:next": "bun run build && bun publish --tag next"
33446
+ "publish:next": "bun run build && bun publish --tag next",
33447
+ "promote:latest": "bun scripts/tag-channel.ts latest"
33442
33448
  },
33443
33449
  keywords: [
33444
33450
  "cli",
@@ -33484,13 +33490,13 @@ var init_package = __esm(() => {
33484
33490
  });
33485
33491
 
33486
33492
  // src/cli/update-check.ts
33487
- import { readFile as readFile14 } from "node:fs/promises";
33493
+ import { readFile as readFile15 } from "node:fs/promises";
33488
33494
  import { join as join24 } from "node:path";
33489
33495
  import { spawn as spawn3 } from "node:child_process";
33490
33496
  async function getCachedUpdateInfo(path3) {
33491
33497
  const filePath = path3 ?? join24(getHomeDir(), CONFIG_DIR, CACHE_FILE);
33492
33498
  try {
33493
- const raw = await readFile14(filePath, "utf-8");
33499
+ const raw = await readFile15(filePath, "utf-8");
33494
33500
  const data = JSON.parse(raw);
33495
33501
  if (typeof data.latestVersion === "string" && typeof data.lastCheckedAt === "string") {
33496
33502
  return data;
@@ -35997,6 +36003,7 @@ init_user_workspace();
35997
36003
  init_skills();
35998
36004
  var import_cmd_ts3 = __toESM(require_cjs(), 1);
35999
36005
  import { existsSync as existsSync19 } from "node:fs";
36006
+ import { readFile as readFile13 } from "node:fs/promises";
36000
36007
  import { join as join22 } from "node:path";
36001
36008
 
36002
36009
  // src/cli/metadata/plugin-skills.ts
@@ -36041,19 +36048,37 @@ var skillsRemoveMeta = {
36041
36048
  };
36042
36049
  var skillsAddMeta = {
36043
36050
  command: "plugin skills add",
36044
- description: "Re-enable a previously disabled skill",
36045
- whenToUse: "To re-enable a skill that was previously disabled",
36051
+ description: "Add a skill from a plugin, or re-enable a previously disabled skill",
36052
+ whenToUse: "To add a skill from a GitHub repo or marketplace plugin, or to re-enable a skill that was previously disabled",
36046
36053
  examples: [
36047
- "allagents plugin skills add brainstorming",
36048
- "allagents plugin skills add brainstorming --plugin superpowers"
36054
+ "allagents skills add reddit --from ReScienceLab/opc-skills",
36055
+ "allagents skills add https://github.com/owner/repo/tree/main/skills/my-skill",
36056
+ "allagents skills add brainstorming",
36057
+ "allagents skills add brainstorming --plugin superpowers"
36049
36058
  ],
36050
36059
  expectedOutput: "Confirms skill was enabled and runs sync",
36051
36060
  positionals: [
36052
- { name: "skill", type: "string", required: true, description: "Skill name to enable" }
36061
+ {
36062
+ name: "skill",
36063
+ type: "string",
36064
+ required: true,
36065
+ description: "Skill name to add, or a GitHub URL pointing to a skill"
36066
+ }
36053
36067
  ],
36054
36068
  options: [
36055
36069
  { flag: "--scope", short: "-s", type: "string", description: 'Scope: "project" (default) or "user"' },
36056
- { flag: "--plugin", short: "-p", type: "string", description: "Plugin name (required if skill exists in multiple plugins)" }
36070
+ {
36071
+ flag: "--plugin",
36072
+ short: "-p",
36073
+ type: "string",
36074
+ description: "Plugin name (required if skill exists in multiple plugins)"
36075
+ },
36076
+ {
36077
+ flag: "--from",
36078
+ short: "-f",
36079
+ type: "string",
36080
+ description: "Plugin source (GitHub URL, owner/repo, or plugin@marketplace) to install if the skill is not already available"
36081
+ }
36057
36082
  ],
36058
36083
  outputSchema: {
36059
36084
  skill: "string",
@@ -36064,6 +36089,9 @@ var skillsAddMeta = {
36064
36089
 
36065
36090
  // src/cli/commands/plugin-skills.ts
36066
36091
  init_constants();
36092
+ init_plugin_path();
36093
+ init_plugin();
36094
+ init_skill();
36067
36095
  function hasProjectConfig(dir) {
36068
36096
  return existsSync19(join22(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
36069
36097
  }
@@ -36074,6 +36102,35 @@ function resolveScope(cwd) {
36074
36102
  return "project";
36075
36103
  return "user";
36076
36104
  }
36105
+ function resolveSkillFromUrl(skill) {
36106
+ if (!isGitHubUrl(skill))
36107
+ return null;
36108
+ const parsed = parseGitHubUrl(skill);
36109
+ if (!parsed)
36110
+ return null;
36111
+ if (parsed.subpath) {
36112
+ const segments = parsed.subpath.split("/").filter(Boolean);
36113
+ const name = segments[segments.length - 1];
36114
+ if (!name)
36115
+ return null;
36116
+ return { skill: name, from: skill, parsed };
36117
+ }
36118
+ return { skill: parsed.repo, from: skill, parsed };
36119
+ }
36120
+ async function resolveSkillNameFromRepo(url, parsed, fallbackName, fetchFn = fetchPlugin) {
36121
+ const fetchResult = await fetchFn(url, {
36122
+ ...parsed.branch && { branch: parsed.branch }
36123
+ });
36124
+ if (!fetchResult.success)
36125
+ return fallbackName;
36126
+ try {
36127
+ const skillMd = await readFile13(join22(fetchResult.cachePath, "SKILL.md"), "utf-8");
36128
+ const metadata = parseSkillMetadata(skillMd);
36129
+ return metadata?.name ?? fallbackName;
36130
+ } catch {
36131
+ return fallbackName;
36132
+ }
36133
+ }
36077
36134
  function groupSkillsByPlugin(skills) {
36078
36135
  const grouped = new Map;
36079
36136
  for (const skill of skills) {
@@ -36322,10 +36379,30 @@ var addCmd = import_cmd_ts3.command({
36322
36379
  description: "Plugin source to install if the skill is not already available"
36323
36380
  })
36324
36381
  },
36325
- handler: async ({ skill, scope, plugin, from }) => {
36382
+ handler: async ({ skill: skillArg, scope, plugin, from: fromArg }) => {
36326
36383
  try {
36384
+ let skill = skillArg;
36385
+ let from = fromArg;
36327
36386
  const isUser = scope === "user" || !scope && resolveScope(process.cwd()) === "user";
36328
36387
  const workspacePath = isUser ? getHomeDir() : process.cwd();
36388
+ const urlResolved = resolveSkillFromUrl(skill);
36389
+ if (urlResolved) {
36390
+ if (from) {
36391
+ const error = "Cannot use --from when the skill argument is a GitHub URL. The URL is used as the plugin source automatically.";
36392
+ if (isJsonMode()) {
36393
+ jsonOutput({ success: false, command: "plugin skills add", error });
36394
+ process.exit(1);
36395
+ }
36396
+ console.error(`Error: ${error}`);
36397
+ process.exit(1);
36398
+ }
36399
+ from = urlResolved.from;
36400
+ if (urlResolved.parsed && !urlResolved.parsed.subpath) {
36401
+ skill = await resolveSkillNameFromRepo(skill, urlResolved.parsed, urlResolved.skill);
36402
+ } else {
36403
+ skill = urlResolved.skill;
36404
+ }
36405
+ }
36329
36406
  let matches = await findSkillByName(skill, workspacePath);
36330
36407
  if (matches.length === 0) {
36331
36408
  if (from) {
@@ -36480,7 +36557,7 @@ init_format_sync();
36480
36557
  init_workspace_config();
36481
36558
  init_constants();
36482
36559
  init_js_yaml();
36483
- import { readFile as readFile13 } from "node:fs/promises";
36560
+ import { readFile as readFile14 } from "node:fs/promises";
36484
36561
  import { existsSync as existsSync20 } from "node:fs";
36485
36562
  import { join as join23 } from "node:path";
36486
36563
  async function runSyncAndPrint(options2) {
@@ -37039,7 +37116,7 @@ var pluginListCmd = import_cmd_ts4.command({
37039
37116
  if (!existsSync20(configPath))
37040
37117
  return;
37041
37118
  try {
37042
- const content = await readFile13(configPath, "utf-8");
37119
+ const content = await readFile14(configPath, "utf-8");
37043
37120
  const config = load(content);
37044
37121
  if (!config?.plugins || !config?.clients)
37045
37122
  return;
@@ -37475,13 +37552,13 @@ var pluginUpdateCmd = import_cmd_ts4.command({
37475
37552
  }
37476
37553
  if (updateProject && !isUserConfigPath(process.cwd())) {
37477
37554
  const { existsSync: existsSync21 } = await import("node:fs");
37478
- const { readFile: readFile14 } = await import("node:fs/promises");
37555
+ const { readFile: readFile15 } = await import("node:fs/promises");
37479
37556
  const { join: join24 } = await import("node:path");
37480
37557
  const { load: load2 } = await Promise.resolve().then(() => (init_js_yaml(), exports_js_yaml));
37481
37558
  const { CONFIG_DIR: CONFIG_DIR2, WORKSPACE_CONFIG_FILE: WORKSPACE_CONFIG_FILE2 } = await Promise.resolve().then(() => (init_constants(), exports_constants));
37482
37559
  const configPath = join24(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
37483
37560
  if (existsSync21(configPath)) {
37484
- const content = await readFile14(configPath, "utf-8");
37561
+ const content = await readFile15(configPath, "utf-8");
37485
37562
  const config = load2(content);
37486
37563
  for (const entry of config.plugins ?? []) {
37487
37564
  const p = getPluginSource(entry);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allagents",
3
- "version": "1.0.3",
3
+ "version": "1.0.6",
4
4
  "description": "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,7 +27,8 @@
27
27
  "prepare": "bun run build && (test -d .git && bunx prek install -t pre-push || true)",
28
28
  "release": "bun run scripts/release.ts",
29
29
  "release:next": "bun run scripts/release.ts next",
30
- "publish:next": "bun run build && bun publish --tag next"
30
+ "publish:next": "bun run build && bun publish --tag next",
31
+ "promote:latest": "bun scripts/tag-channel.ts latest"
31
32
  },
32
33
  "keywords": [
33
34
  "cli",