@claude-collective/cli 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.0] - 2026-01-30
9
+
10
+ ### Added
11
+
12
+ - **Marketplace support** - install stack plugins directly from configured marketplaces
13
+ - Marketplace field in project and global config for plugin installation
14
+ - CLI utilities for marketplace management (`marketplace list`, `exists`, `add`)
15
+ - Multi-source agent loading - agents can now be loaded from both CLI and custom sources
16
+ - `sourceRoot` tracking for correct template resolution with multi-source agents
17
+
18
+ ### Changed
19
+
20
+ - Removed skills eject functionality (use marketplace plugins instead)
21
+
22
+ ### Fixed
23
+
24
+ - Wizard now preserves approach selection state when toggling Expert Mode or Install Mode
25
+
26
+ [0.2.0]: https://github.com/claude-collective/cli/releases/tag/v0.2.0
27
+
8
28
  ## [0.1.3] - 2026-01-30
9
29
 
10
30
  ### Added
package/dist/cli/index.js CHANGED
@@ -209,6 +209,8 @@ function isValidGlobalConfig(obj) {
209
209
  return false;
210
210
  if (config.author !== void 0 && typeof config.author !== "string")
211
211
  return false;
212
+ if (config.marketplace !== void 0 && typeof config.marketplace !== "string")
213
+ return false;
212
214
  return true;
213
215
  }
214
216
  function isValidProjectConfig(obj) {
@@ -216,6 +218,8 @@ function isValidProjectConfig(obj) {
216
218
  const config = obj;
217
219
  if (config.source !== void 0 && typeof config.source !== "string")
218
220
  return false;
221
+ if (config.marketplace !== void 0 && typeof config.marketplace !== "string")
222
+ return false;
219
223
  return true;
220
224
  }
221
225
  function getGlobalConfigPath() {
@@ -279,32 +283,35 @@ async function saveProjectConfig(projectDir, config) {
279
283
  verbose(`Saved project config to ${configPath}`);
280
284
  }
281
285
  async function resolveSource(flagValue, projectDir) {
286
+ const projectConfig = projectDir ? await loadProjectConfig(projectDir) : null;
287
+ const globalConfig = await loadGlobalConfig();
288
+ const marketplace = projectConfig?.marketplace || globalConfig?.marketplace;
282
289
  if (flagValue !== void 0) {
283
290
  if (flagValue === "" || flagValue.trim() === "") {
284
291
  throw new Error("--source flag cannot be empty");
285
292
  }
286
293
  verbose(`Source from --source flag: ${flagValue}`);
287
- return { source: flagValue, sourceOrigin: "flag" };
294
+ return { source: flagValue, sourceOrigin: "flag", marketplace };
288
295
  }
289
296
  const envValue = process.env[SOURCE_ENV_VAR];
290
297
  if (envValue) {
291
298
  verbose(`Source from ${SOURCE_ENV_VAR} env var: ${envValue}`);
292
- return { source: envValue, sourceOrigin: "env" };
299
+ return { source: envValue, sourceOrigin: "env", marketplace };
293
300
  }
294
- if (projectDir) {
295
- const projectConfig = await loadProjectConfig(projectDir);
296
- if (projectConfig?.source) {
297
- verbose(`Source from project config: ${projectConfig.source}`);
298
- return { source: projectConfig.source, sourceOrigin: "project" };
299
- }
301
+ if (projectConfig?.source) {
302
+ verbose(`Source from project config: ${projectConfig.source}`);
303
+ return {
304
+ source: projectConfig.source,
305
+ sourceOrigin: "project",
306
+ marketplace
307
+ };
300
308
  }
301
- const globalConfig = await loadGlobalConfig();
302
309
  if (globalConfig?.source) {
303
310
  verbose(`Source from global config: ${globalConfig.source}`);
304
- return { source: globalConfig.source, sourceOrigin: "global" };
311
+ return { source: globalConfig.source, sourceOrigin: "global", marketplace };
305
312
  }
306
313
  verbose(`Using default source: ${DEFAULT_SOURCE}`);
307
- return { source: DEFAULT_SOURCE, sourceOrigin: "default" };
314
+ return { source: DEFAULT_SOURCE, sourceOrigin: "default", marketplace };
308
315
  }
309
316
  function formatSourceOrigin(origin) {
310
317
  switch (origin) {
@@ -529,7 +536,8 @@ async function loadAllAgents(projectRoot) {
529
536
  description: config.description,
530
537
  model: config.model,
531
538
  tools: config.tools,
532
- path: agentPath
539
+ path: agentPath,
540
+ sourceRoot: projectRoot
533
541
  };
534
542
  verbose(`Loaded agent: ${config.id} from ${file}`);
535
543
  }
@@ -794,7 +802,8 @@ async function resolveAgents(agents, skills, compileConfig, projectRoot) {
794
802
  model: definition.model,
795
803
  tools: definition.tools,
796
804
  skills: resolvedSkills,
797
- path: definition.path
805
+ path: definition.path,
806
+ sourceRoot: definition.sourceRoot
798
807
  };
799
808
  }
800
809
  return resolved;
@@ -1008,9 +1017,10 @@ async function determineStackVersion(stack, pluginDir) {
1008
1017
  contentHash: newHash
1009
1018
  };
1010
1019
  }
1011
- async function compileAgentForPlugin(name, agent, projectRoot, engine) {
1020
+ async function compileAgentForPlugin(name, agent, fallbackRoot, engine) {
1012
1021
  verbose(`Compiling agent: ${name}`);
1013
- const agentDir = path11.join(projectRoot, DIRS.agents, agent.path || name);
1022
+ const agentSourceRoot = agent.sourceRoot || fallbackRoot;
1023
+ const agentDir = path11.join(agentSourceRoot, DIRS.agents, agent.path || name);
1014
1024
  const intro4 = await readFile(path11.join(agentDir, "intro.md"));
1015
1025
  const workflow = await readFile(path11.join(agentDir, "workflow.md"));
1016
1026
  const examples = await readFileOptional(
@@ -1027,7 +1037,7 @@ async function compileAgentForPlugin(name, agent, projectRoot, engine) {
1027
1037
  );
1028
1038
  const agentPath = agent.path || name;
1029
1039
  const category = agentPath.split("/")[0];
1030
- const categoryDir = path11.join(projectRoot, DIRS.agents, category);
1040
+ const categoryDir = path11.join(agentSourceRoot, DIRS.agents, category);
1031
1041
  let outputFormat = await readFileOptional(
1032
1042
  path11.join(agentDir, "output-format.md"),
1033
1043
  ""
@@ -1129,19 +1139,25 @@ function generateHooksJson(hooks) {
1129
1139
  }
1130
1140
  async function compileStackPlugin(options) {
1131
1141
  const { stackId, outputDir, projectRoot, agentSourcePath } = options;
1132
- const agentRoot = agentSourcePath || projectRoot;
1142
+ const localAgentRoot = agentSourcePath || projectRoot;
1133
1143
  verbose(`Compiling stack plugin: ${stackId}`);
1134
1144
  verbose(` Stack/skills source: ${projectRoot}`);
1135
- verbose(` Agent partials source: ${agentRoot}`);
1145
+ verbose(` Local agent source: ${localAgentRoot}`);
1146
+ verbose(` CLI agent source: ${PROJECT_ROOT}`);
1136
1147
  const stack = await loadStack(stackId, projectRoot, "dev");
1137
- const agents = await loadAllAgents(agentRoot);
1148
+ const cliAgents = await loadAllAgents(PROJECT_ROOT);
1149
+ const localAgents = await loadAllAgents(localAgentRoot);
1150
+ const agents = { ...cliAgents, ...localAgents };
1151
+ verbose(
1152
+ ` Loaded ${Object.keys(localAgents).length} local agents, ${Object.keys(cliAgents).length} CLI agents`
1153
+ );
1138
1154
  const skills = await loadSkillsByIds(stack.skills || [], projectRoot);
1139
1155
  const compileConfig = stackToCompileConfig(stackId, stack);
1140
1156
  const resolvedAgents = await resolveAgents(
1141
1157
  agents,
1142
1158
  skills,
1143
1159
  compileConfig,
1144
- agentRoot
1160
+ projectRoot
1145
1161
  );
1146
1162
  const pluginDir = path11.join(outputDir, stackId);
1147
1163
  const agentsDir = path11.join(pluginDir, "agents");
@@ -1168,7 +1184,12 @@ async function compileStackPlugin(options) {
1168
1184
  const compiledAgentNames = [];
1169
1185
  const allSkillPlugins = [];
1170
1186
  for (const [name, agent] of Object.entries(resolvedAgents)) {
1171
- const output = await compileAgentForPlugin(name, agent, agentRoot, engine);
1187
+ const output = await compileAgentForPlugin(
1188
+ name,
1189
+ agent,
1190
+ PROJECT_ROOT,
1191
+ engine
1192
+ );
1172
1193
  await writeFile(path11.join(agentsDir, `${name}.md`), output);
1173
1194
  compiledAgentNames.push(name);
1174
1195
  for (const skill of agent.skills) {
@@ -2359,6 +2380,82 @@ import pc7 from "picocolors";
2359
2380
  import path25 from "path";
2360
2381
  import { stringify as stringifyYaml4 } from "yaml";
2361
2382
 
2383
+ // src/cli/utils/exec.ts
2384
+ import { spawn } from "child_process";
2385
+ async function execCommand(command, args, options) {
2386
+ return new Promise((resolve, reject) => {
2387
+ const proc = spawn(command, args, {
2388
+ cwd: options?.cwd,
2389
+ env: { ...process.env, ...options?.env },
2390
+ stdio: ["ignore", "pipe", "pipe"]
2391
+ });
2392
+ let stdout = "";
2393
+ let stderr = "";
2394
+ proc.stdout.on("data", (data) => {
2395
+ stdout += data.toString();
2396
+ });
2397
+ proc.stderr.on("data", (data) => {
2398
+ stderr += data.toString();
2399
+ });
2400
+ proc.on("close", (code) => {
2401
+ resolve({
2402
+ stdout,
2403
+ stderr,
2404
+ exitCode: code ?? 1
2405
+ });
2406
+ });
2407
+ proc.on("error", (err) => {
2408
+ reject(err);
2409
+ });
2410
+ });
2411
+ }
2412
+ async function claudePluginInstall(pluginPath, scope, projectDir) {
2413
+ const args = ["plugin", "install", pluginPath, "--scope", scope];
2414
+ const result = await execCommand("claude", args, { cwd: projectDir });
2415
+ if (result.exitCode !== 0) {
2416
+ const errorMessage = result.stderr || result.stdout || "Unknown error";
2417
+ throw new Error(`Plugin installation failed: ${errorMessage.trim()}`);
2418
+ }
2419
+ }
2420
+ async function isClaudeCLIAvailable() {
2421
+ try {
2422
+ const result = await execCommand("claude", ["--version"], {});
2423
+ return result.exitCode === 0;
2424
+ } catch {
2425
+ return false;
2426
+ }
2427
+ }
2428
+ async function claudePluginMarketplaceList() {
2429
+ const result = await execCommand(
2430
+ "claude",
2431
+ ["plugin", "marketplace", "list", "--json"],
2432
+ {}
2433
+ );
2434
+ if (result.exitCode !== 0) {
2435
+ return [];
2436
+ }
2437
+ try {
2438
+ return JSON.parse(result.stdout);
2439
+ } catch {
2440
+ return [];
2441
+ }
2442
+ }
2443
+ async function claudePluginMarketplaceExists(name) {
2444
+ const marketplaces = await claudePluginMarketplaceList();
2445
+ return marketplaces.some((m) => m.name === name);
2446
+ }
2447
+ async function claudePluginMarketplaceAdd(githubRepo, name) {
2448
+ const args = ["plugin", "marketplace", "add", githubRepo, "--name", name];
2449
+ const result = await execCommand("claude", args, {});
2450
+ if (result.exitCode !== 0) {
2451
+ const errorMessage = result.stderr || result.stdout || "Unknown error";
2452
+ if (errorMessage.includes("already installed")) {
2453
+ return;
2454
+ }
2455
+ throw new Error(`Failed to add marketplace: ${errorMessage.trim()}`);
2456
+ }
2457
+ }
2458
+
2362
2459
  // src/cli/lib/wizard.ts
2363
2460
  import * as p5 from "@clack/prompts";
2364
2461
  import pc6 from "picocolors";
@@ -2790,6 +2887,7 @@ function createInitialState(options = {}) {
2790
2887
  lastSelectedCategory: null,
2791
2888
  lastSelectedSubcategory: null,
2792
2889
  lastSelectedSkill: null,
2890
+ lastSelectedApproach: null,
2793
2891
  expertMode: options.hasLocalSkills ?? false,
2794
2892
  installMode: "plugin"
2795
2893
  };
@@ -2939,7 +3037,8 @@ async function stepApproach(state) {
2939
3037
  },
2940
3038
  formatExpertModeOption(state.expertMode),
2941
3039
  formatInstallModeOption(state.installMode)
2942
- ]
3040
+ ],
3041
+ initialValue: state.lastSelectedApproach || void 0
2943
3042
  });
2944
3043
  return result;
2945
3044
  }
@@ -3135,13 +3234,16 @@ async function runWizard(matrix, options = {}) {
3135
3234
  return null;
3136
3235
  }
3137
3236
  if (result === EXPERT_MODE_VALUE) {
3237
+ state.lastSelectedApproach = EXPERT_MODE_VALUE;
3138
3238
  state.expertMode = !state.expertMode;
3139
3239
  break;
3140
3240
  }
3141
3241
  if (result === INSTALL_MODE_VALUE) {
3242
+ state.lastSelectedApproach = INSTALL_MODE_VALUE;
3142
3243
  state.installMode = state.installMode === "plugin" ? "local" : "plugin";
3143
3244
  break;
3144
3245
  }
3246
+ state.lastSelectedApproach = null;
3145
3247
  if (result === "stack") {
3146
3248
  pushHistory(state);
3147
3249
  state.currentStep = "stack";
@@ -3826,7 +3928,8 @@ async function loadFromLocal(source, sourceConfig) {
3826
3928
  matrix: mergedMatrix,
3827
3929
  sourceConfig,
3828
3930
  sourcePath: skillsPath,
3829
- isLocal: true
3931
+ isLocal: true,
3932
+ marketplace: sourceConfig.marketplace
3830
3933
  };
3831
3934
  }
3832
3935
  async function loadFromRemote(source, sourceConfig, forceRefresh) {
@@ -3852,7 +3955,8 @@ async function loadFromRemote(source, sourceConfig, forceRefresh) {
3852
3955
  matrix: mergedMatrix,
3853
3956
  sourceConfig,
3854
3957
  sourcePath: fetchResult.path,
3855
- isLocal: false
3958
+ isLocal: false,
3959
+ marketplace: sourceConfig.marketplace
3856
3960
  };
3857
3961
  }
3858
3962
  var LOCAL_CATEGORY_TOP = {
@@ -4098,54 +4202,6 @@ For autonomous operation, add to .claude/settings.json:
4098
4202
  // src/cli/lib/stack-installer.ts
4099
4203
  import os3 from "os";
4100
4204
  import path24 from "path";
4101
-
4102
- // src/cli/utils/exec.ts
4103
- import { spawn } from "child_process";
4104
- async function execCommand(command, args, options) {
4105
- return new Promise((resolve, reject) => {
4106
- const proc = spawn(command, args, {
4107
- cwd: options?.cwd,
4108
- env: { ...process.env, ...options?.env },
4109
- stdio: ["ignore", "pipe", "pipe"]
4110
- });
4111
- let stdout = "";
4112
- let stderr = "";
4113
- proc.stdout.on("data", (data) => {
4114
- stdout += data.toString();
4115
- });
4116
- proc.stderr.on("data", (data) => {
4117
- stderr += data.toString();
4118
- });
4119
- proc.on("close", (code) => {
4120
- resolve({
4121
- stdout,
4122
- stderr,
4123
- exitCode: code ?? 1
4124
- });
4125
- });
4126
- proc.on("error", (err) => {
4127
- reject(err);
4128
- });
4129
- });
4130
- }
4131
- async function claudePluginInstall(pluginPath, scope, projectDir) {
4132
- const args = ["plugin", "install", pluginPath, "--scope", scope];
4133
- const result = await execCommand("claude", args, { cwd: projectDir });
4134
- if (result.exitCode !== 0) {
4135
- const errorMessage = result.stderr || result.stdout || "Unknown error";
4136
- throw new Error(`Plugin installation failed: ${errorMessage.trim()}`);
4137
- }
4138
- }
4139
- async function isClaudeCLIAvailable() {
4140
- try {
4141
- const result = await execCommand("claude", ["--version"], {});
4142
- return result.exitCode === 0;
4143
- } catch {
4144
- return false;
4145
- }
4146
- }
4147
-
4148
- // src/cli/lib/stack-installer.ts
4149
4205
  async function compileStackToTemp(options) {
4150
4206
  const tempDir = path24.join(os3.tmpdir(), `cc-stack-${Date.now()}`);
4151
4207
  await ensureDir(tempDir);
@@ -4163,13 +4219,27 @@ async function compileStackToTemp(options) {
4163
4219
  };
4164
4220
  }
4165
4221
  async function installStackAsPlugin(options) {
4166
- const { stackId, projectDir, sourcePath, agentSourcePath } = options;
4222
+ const { stackId, projectDir, sourcePath, agentSourcePath, marketplace } = options;
4167
4223
  const claudeAvailable = await isClaudeCLIAvailable();
4168
4224
  if (!claudeAvailable) {
4169
4225
  throw new Error(
4170
4226
  "Claude CLI not found. Please install Claude Code first: https://claude.ai/code"
4171
4227
  );
4172
4228
  }
4229
+ if (marketplace) {
4230
+ verbose(`Installing from marketplace: ${stackId}@${marketplace}`);
4231
+ const pluginRef = `${stackId}@${marketplace}`;
4232
+ await claudePluginInstall(pluginRef, "project", projectDir);
4233
+ return {
4234
+ pluginName: stackId,
4235
+ stackName: stackId,
4236
+ agents: [],
4237
+ skills: [],
4238
+ pluginPath: pluginRef,
4239
+ fromMarketplace: true
4240
+ };
4241
+ }
4242
+ verbose(`Compiling stack locally: ${stackId}`);
4173
4243
  const { result, cleanup } = await compileStackToTemp({
4174
4244
  stackId,
4175
4245
  projectRoot: sourcePath,
@@ -4182,7 +4252,8 @@ async function installStackAsPlugin(options) {
4182
4252
  stackName: result.stackName,
4183
4253
  agents: result.agents,
4184
4254
  skills: result.skillPlugins,
4185
- pluginPath: result.pluginPath
4255
+ pluginPath: result.pluginPath,
4256
+ fromMarketplace: false
4186
4257
  };
4187
4258
  } finally {
4188
4259
  await cleanup();
@@ -4520,21 +4591,35 @@ var initCommand = new Command5("init").description("Initialize Claude Collective
4520
4591
  );
4521
4592
  if (dryRun) {
4522
4593
  if (result.installMode === "plugin" && result.selectedStack) {
4523
- p7.log.info(
4524
- pc7.yellow(
4525
- `[dry-run] Would install stack "${result.selectedStack.id}" as a native plugin`
4526
- )
4527
- );
4528
- p7.log.info(
4529
- pc7.yellow(
4530
- `[dry-run] claude plugin install ./compiled-stack/${result.selectedStack.id} --scope project`
4531
- )
4532
- );
4533
- p7.log.info(
4534
- pc7.yellow(
4535
- `[dry-run] Stack includes ${result.selectedSkills.length} skills and agents bundled together`
4536
- )
4537
- );
4594
+ const useMarketplace = !!sourceResult.marketplace;
4595
+ if (useMarketplace) {
4596
+ p7.log.info(
4597
+ pc7.yellow(
4598
+ `[dry-run] Would install stack "${result.selectedStack.id}" from marketplace "${sourceResult.marketplace}"`
4599
+ )
4600
+ );
4601
+ p7.log.info(
4602
+ pc7.yellow(
4603
+ `[dry-run] claude plugin install ${result.selectedStack.id}@${sourceResult.marketplace} --scope project`
4604
+ )
4605
+ );
4606
+ } else {
4607
+ p7.log.info(
4608
+ pc7.yellow(
4609
+ `[dry-run] Would compile and install stack "${result.selectedStack.id}" as a native plugin`
4610
+ )
4611
+ );
4612
+ p7.log.info(
4613
+ pc7.yellow(
4614
+ `[dry-run] claude plugin install ./compiled-stack/${result.selectedStack.id} --scope project`
4615
+ )
4616
+ );
4617
+ p7.log.info(
4618
+ pc7.yellow(
4619
+ `[dry-run] Stack includes ${result.selectedSkills.length} skills and agents bundled together`
4620
+ )
4621
+ );
4622
+ }
4538
4623
  } else {
4539
4624
  if (result.installMode === "plugin") {
4540
4625
  p7.log.info(
@@ -4563,31 +4648,59 @@ var initCommand = new Command5("init").description("Initialize Claude Collective
4563
4648
  }
4564
4649
  if (result.installMode === "plugin") {
4565
4650
  if (result.selectedStack) {
4566
- s.start(
4567
- `Compiling and installing stack "${result.selectedStack.id}"...`
4568
- );
4651
+ if (sourceResult.marketplace) {
4652
+ const marketplaceExists = await claudePluginMarketplaceExists(
4653
+ sourceResult.marketplace
4654
+ );
4655
+ if (!marketplaceExists) {
4656
+ s.start(`Registering marketplace "${sourceResult.marketplace}"...`);
4657
+ try {
4658
+ await claudePluginMarketplaceAdd(
4659
+ sourceResult.sourceConfig.source,
4660
+ sourceResult.marketplace
4661
+ );
4662
+ s.stop(`Registered marketplace: ${sourceResult.marketplace}`);
4663
+ } catch (error) {
4664
+ s.stop("Failed to register marketplace");
4665
+ p7.log.error(
4666
+ error instanceof Error ? error.message : "Unknown error"
4667
+ );
4668
+ process.exit(EXIT_CODES.ERROR);
4669
+ }
4670
+ }
4671
+ }
4672
+ const installMethod = sourceResult.marketplace ? `Installing from marketplace "${sourceResult.marketplace}"` : "Compiling and installing";
4673
+ s.start(`${installMethod} stack "${result.selectedStack.id}"...`);
4569
4674
  try {
4570
4675
  const installResult = await installStackAsPlugin({
4571
4676
  stackId: result.selectedStack.id,
4572
4677
  projectDir,
4573
4678
  sourcePath: sourceResult.sourcePath,
4574
- agentSourcePath: sourceResult.sourcePath
4679
+ agentSourcePath: sourceResult.sourcePath,
4680
+ marketplace: sourceResult.marketplace
4575
4681
  });
4576
- s.stop(`Installed stack plugin: ${installResult.pluginName}`);
4682
+ const installedFrom = installResult.fromMarketplace ? `from marketplace` : `(compiled locally)`;
4683
+ s.stop(
4684
+ `Installed stack plugin: ${installResult.pluginName} ${installedFrom}`
4685
+ );
4577
4686
  console.log("");
4578
4687
  console.log(pc7.green("Claude Collective initialized successfully!"));
4579
4688
  console.log("");
4580
4689
  console.log(
4581
4690
  `Stack ${pc7.cyan(`"${installResult.stackName}"`)} installed as plugin`
4582
4691
  );
4583
- console.log("");
4584
- console.log(pc7.dim("Agents included:"));
4585
- for (const agentName of installResult.agents) {
4586
- console.log(` ${pc7.cyan(agentName)}`);
4692
+ if (installResult.agents.length > 0) {
4693
+ console.log("");
4694
+ console.log(pc7.dim("Agents included:"));
4695
+ for (const agentName of installResult.agents) {
4696
+ console.log(` ${pc7.cyan(agentName)}`);
4697
+ }
4698
+ console.log("");
4699
+ console.log(
4700
+ pc7.dim(`Skills bundled: ${installResult.skills.length}`)
4701
+ );
4587
4702
  }
4588
4703
  console.log("");
4589
- console.log(pc7.dim(`Skills bundled: ${installResult.skills.length}`));
4590
- console.log("");
4591
4704
  p7.outro(pc7.green("Claude Collective is ready to use!"));
4592
4705
  await checkPermissions(projectDir);
4593
4706
  return;
@@ -4626,7 +4739,9 @@ var initCommand = new Command5("init").description("Initialize Claude Collective
4626
4739
  );
4627
4740
  s.stop(`Copied ${copiedSkills.length} skills to .claude/skills/`);
4628
4741
  s.start("Generating configuration...");
4629
- const agents = await loadAllAgents(sourceResult.sourcePath);
4742
+ const cliAgents = await loadAllAgents(PROJECT_ROOT);
4743
+ const localAgents = await loadAllAgents(sourceResult.sourcePath);
4744
+ const agents = { ...cliAgents, ...localAgents };
4630
4745
  const localSkillsForResolution = {};
4631
4746
  for (const copiedSkill of copiedSkills) {
4632
4747
  const skill = matrix.skills[copiedSkill.skillId];
@@ -5938,7 +6053,7 @@ import * as p12 from "@clack/prompts";
5938
6053
  import pc12 from "picocolors";
5939
6054
  import path30 from "path";
5940
6055
  import os4 from "os";
5941
- var EJECT_TYPES = ["templates", "skills", "config", "all"];
6056
+ var EJECT_TYPES = ["templates", "config", "all"];
5942
6057
  var DEFAULT_CONFIG_CONTENT = `# Claude Collective Configuration
5943
6058
  # Agent-skill mappings for this project
5944
6059
 
@@ -5964,31 +6079,7 @@ agent_skills:
5964
6079
  - drizzle
5965
6080
  - better-auth
5966
6081
  `;
5967
- var DEFAULT_SKILL_MD_CONTENT = `---
5968
- name: example-skill
5969
- description: Short description of the skill
5970
- ---
5971
-
5972
- # Example Skill
5973
-
5974
- ## Overview
5975
- Describe what this skill teaches the agent.
5976
-
5977
- ## Instructions
5978
- Specific instructions for the agent.
5979
-
5980
- ## Examples
5981
- \`\`\`typescript
5982
- // Example code
5983
- \`\`\`
5984
- `;
5985
- var DEFAULT_METADATA_CONTENT = `# yaml-language-server: $schema=../../schemas/metadata.schema.json
5986
- category: custom
5987
- author: "@local"
5988
- cli_name: Example Skill
5989
- cli_description: Short description for CLI
5990
- `;
5991
- var ejectCommand = new Command10("eject").description("Eject bundled content for local customization").argument("[type]", "What to eject: templates, skills, config, all").option("-f, --force", "Overwrite existing files", false).option(
6082
+ var ejectCommand = new Command10("eject").description("Eject bundled content for local customization").argument("[type]", "What to eject: templates, config, all").option("-f, --force", "Overwrite existing files", false).option(
5992
6083
  "-o, --output <dir>",
5993
6084
  "Output directory (default: .claude/ in current directory)"
5994
6085
  ).configureOutput({
@@ -5997,9 +6088,7 @@ var ejectCommand = new Command10("eject").description("Eject bundled content for
5997
6088
  async (type, options) => {
5998
6089
  const projectDir = process.cwd();
5999
6090
  if (!type) {
6000
- p12.log.error(
6001
- "Please specify what to eject: templates, skills, config, or all"
6002
- );
6091
+ p12.log.error("Please specify what to eject: templates, config, or all");
6003
6092
  process.exit(EXIT_CODES.INVALID_ARGS);
6004
6093
  }
6005
6094
  if (!EJECT_TYPES.includes(type)) {
@@ -6029,15 +6118,11 @@ var ejectCommand = new Command10("eject").description("Eject bundled content for
6029
6118
  case "templates":
6030
6119
  await ejectTemplates(outputBase, options.force, directOutput);
6031
6120
  break;
6032
- case "skills":
6033
- await ejectSkills(outputBase, options.force, directOutput);
6034
- break;
6035
6121
  case "config":
6036
6122
  await ejectConfig(outputBase, options.force, directOutput);
6037
6123
  break;
6038
6124
  case "all":
6039
6125
  await ejectTemplates(outputBase, options.force, directOutput);
6040
- await ejectSkills(outputBase, options.force, directOutput);
6041
6126
  await ejectConfig(outputBase, options.force, directOutput);
6042
6127
  break;
6043
6128
  }
@@ -6060,30 +6145,6 @@ async function ejectTemplates(outputBase, force, directOutput = false) {
6060
6145
  pc12.dim("You can now customize agent.liquid and partials locally.")
6061
6146
  );
6062
6147
  }
6063
- async function ejectSkills(outputBase, force, directOutput = false) {
6064
- const destDir = directOutput ? outputBase : path30.join(outputBase, "skill-templates");
6065
- if (await directoryExists(destDir) && !force) {
6066
- p12.log.warn(
6067
- `Skill templates already exist at ${destDir}. Use --force to overwrite.`
6068
- );
6069
- return;
6070
- }
6071
- await ensureDir(destDir);
6072
- const exampleSkillDir = path30.join(destDir, "example-skill");
6073
- await ensureDir(exampleSkillDir);
6074
- await writeFile(
6075
- path30.join(exampleSkillDir, "SKILL.md"),
6076
- DEFAULT_SKILL_MD_CONTENT
6077
- );
6078
- await writeFile(
6079
- path30.join(exampleSkillDir, "metadata.yaml"),
6080
- DEFAULT_METADATA_CONTENT
6081
- );
6082
- p12.log.success(`Skill templates ejected to ${pc12.cyan(destDir)}`);
6083
- p12.log.info(
6084
- pc12.dim("Copy example-skill/ to your skills/ directory and customize.")
6085
- );
6086
- }
6087
6148
  async function ejectConfig(outputBase, force, directOutput = false) {
6088
6149
  const destPath = path30.join(outputBase, "config.yaml");
6089
6150
  if (await fileExists(destPath) && !force) {