@claude-collective/cli 0.2.0 → 0.8.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 +178 -0
- package/README.md +1 -1
- package/dist/chunk-3HBTELJN.js +114 -0
- package/dist/chunk-3HBTELJN.js.map +1 -0
- package/dist/chunk-3ZCB5K33.js +54 -0
- package/dist/chunk-3ZCB5K33.js.map +1 -0
- package/dist/chunk-66UDJBF6.js +96 -0
- package/dist/chunk-66UDJBF6.js.map +1 -0
- package/dist/chunk-6LS7XO3H.js +31 -0
- package/dist/chunk-6LS7XO3H.js.map +1 -0
- package/dist/chunk-A3J6IAXK.js +57 -0
- package/dist/chunk-A3J6IAXK.js.map +1 -0
- package/dist/chunk-A65SBAAJ.js +69 -0
- package/dist/chunk-A65SBAAJ.js.map +1 -0
- package/dist/chunk-ALEPJ6YN.js +80 -0
- package/dist/chunk-ALEPJ6YN.js.map +1 -0
- package/dist/chunk-C4ZTIYFR.js +84 -0
- package/dist/chunk-C4ZTIYFR.js.map +1 -0
- package/dist/chunk-CIY5UBRB.js +453 -0
- package/dist/chunk-CIY5UBRB.js.map +1 -0
- package/dist/chunk-DHET7RCE.js +50 -0
- package/dist/chunk-DHET7RCE.js.map +1 -0
- package/dist/chunk-DHFFRMF6.js +31 -0
- package/dist/chunk-DHFFRMF6.js.map +1 -0
- package/dist/chunk-DKGL77IY.js +307 -0
- package/dist/chunk-DKGL77IY.js.map +1 -0
- package/dist/chunk-ED73HCW2.js +315 -0
- package/dist/chunk-ED73HCW2.js.map +1 -0
- package/dist/chunk-FNOYEXUE.js +308 -0
- package/dist/chunk-FNOYEXUE.js.map +1 -0
- package/dist/chunk-G2FBJOZG.js +141 -0
- package/dist/chunk-G2FBJOZG.js.map +1 -0
- package/dist/chunk-HNDT5QRB.js +120 -0
- package/dist/chunk-HNDT5QRB.js.map +1 -0
- package/dist/chunk-K7PTOVX4.js +158 -0
- package/dist/chunk-K7PTOVX4.js.map +1 -0
- package/dist/chunk-LQTST4WY.js +91 -0
- package/dist/chunk-LQTST4WY.js.map +1 -0
- package/dist/chunk-LVKRVFYR.js +54 -0
- package/dist/chunk-LVKRVFYR.js.map +1 -0
- package/dist/chunk-M7YCPFIX.js +108 -0
- package/dist/chunk-M7YCPFIX.js.map +1 -0
- package/dist/chunk-MJSFR562.js +57 -0
- package/dist/chunk-MJSFR562.js.map +1 -0
- package/dist/chunk-MMDXNZPF.js +69 -0
- package/dist/chunk-MMDXNZPF.js.map +1 -0
- package/dist/chunk-MYAVQ23U.js +356 -0
- package/dist/chunk-MYAVQ23U.js.map +1 -0
- package/dist/chunk-NGBFJJ7Q.js +124 -0
- package/dist/chunk-NGBFJJ7Q.js.map +1 -0
- package/dist/chunk-OLBOTK3O.js +64 -0
- package/dist/chunk-OLBOTK3O.js.map +1 -0
- package/dist/chunk-PPNTD5LO.js +330 -0
- package/dist/chunk-PPNTD5LO.js.map +1 -0
- package/dist/chunk-Q2LH2DAB.js +392 -0
- package/dist/chunk-Q2LH2DAB.js.map +1 -0
- package/dist/chunk-Q6DR5QUH.js +547 -0
- package/dist/chunk-Q6DR5QUH.js.map +1 -0
- package/dist/chunk-QESUUPOE.js +241 -0
- package/dist/chunk-QESUUPOE.js.map +1 -0
- package/dist/chunk-QGGSLMO3.js +607 -0
- package/dist/chunk-QGGSLMO3.js.map +1 -0
- package/dist/chunk-SEBPPFUW.js +478 -0
- package/dist/chunk-SEBPPFUW.js.map +1 -0
- package/dist/chunk-SYQ7R2JO.js +95 -0
- package/dist/chunk-SYQ7R2JO.js.map +1 -0
- package/dist/chunk-TOPAIL5W.js +22 -0
- package/dist/chunk-TOPAIL5W.js.map +1 -0
- package/dist/chunk-U4VYHKPM.js +110 -0
- package/dist/chunk-U4VYHKPM.js.map +1 -0
- package/dist/chunk-UOWHJ6BE.js +83 -0
- package/dist/chunk-UOWHJ6BE.js.map +1 -0
- package/dist/chunk-XKEG3SCV.js +86 -0
- package/dist/chunk-XKEG3SCV.js.map +1 -0
- package/dist/chunk-XY3XDVMI.js +15599 -0
- package/dist/chunk-XY3XDVMI.js.map +1 -0
- package/dist/chunk-Y3V43XCU.js +76 -0
- package/dist/chunk-Y3V43XCU.js.map +1 -0
- package/dist/chunk-YKXBGCFD.js +129 -0
- package/dist/chunk-YKXBGCFD.js.map +1 -0
- package/dist/cli-v2/defaults/agent-mappings.yaml +185 -0
- package/dist/commands/build/marketplace.js +254 -0
- package/dist/commands/build/marketplace.js.map +1 -0
- package/dist/commands/build/plugins.js +324 -0
- package/dist/commands/build/plugins.js.map +1 -0
- package/dist/commands/build/stack.js +169 -0
- package/dist/commands/build/stack.js.map +1 -0
- package/dist/commands/compile.js +461 -0
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/config/get.js +60 -0
- package/dist/commands/config/get.js.map +1 -0
- package/dist/commands/config/index.js +22 -0
- package/dist/commands/config/index.js.map +1 -0
- package/dist/commands/config/path.js +35 -0
- package/dist/commands/config/path.js.map +1 -0
- package/dist/commands/config/set-project.js +61 -0
- package/dist/commands/config/set-project.js.map +1 -0
- package/dist/commands/config/set.js +60 -0
- package/dist/commands/config/set.js.map +1 -0
- package/dist/commands/config/show.js +13 -0
- package/dist/commands/config/show.js.map +1 -0
- package/dist/commands/config/unset-project.js +57 -0
- package/dist/commands/config/unset-project.js.map +1 -0
- package/dist/commands/config/unset.js +56 -0
- package/dist/commands/config/unset.js.map +1 -0
- package/dist/commands/diff.js +755 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/doctor.js +413 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/edit.js +254 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/eject.js +208 -0
- package/dist/commands/eject.js.map +1 -0
- package/dist/commands/info.js +205 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/init.js +915 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.js +44 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/new/agent.js +230 -0
- package/dist/commands/new/agent.js.map +1 -0
- package/dist/commands/new/skill.js +204 -0
- package/dist/commands/new/skill.js.map +1 -0
- package/dist/commands/outdated.js +242 -0
- package/dist/commands/outdated.js.map +1 -0
- package/dist/commands/search.js +115 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/test-imports.js +92 -0
- package/dist/commands/test-imports.js.map +1 -0
- package/dist/commands/uninstall.js +309 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.js +428 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.js +375 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/version/bump.js +95 -0
- package/dist/commands/version/bump.js.map +1 -0
- package/dist/commands/version/index.js +70 -0
- package/dist/commands/version/index.js.map +1 -0
- package/dist/commands/version/set.js +101 -0
- package/dist/commands/version/set.js.map +1 -0
- package/dist/commands/version/show.js +70 -0
- package/dist/commands/version/show.js.map +1 -0
- package/dist/components/common/confirm.js +9 -0
- package/dist/components/common/confirm.js.map +1 -0
- package/dist/components/common/message.js +24 -0
- package/dist/components/common/message.js.map +1 -0
- package/dist/components/common/spinner.js +14 -0
- package/dist/components/common/spinner.js.map +1 -0
- package/dist/components/wizard/category-grid.js +9 -0
- package/dist/components/wizard/category-grid.js.map +1 -0
- package/dist/components/wizard/category-grid.test.js +728 -0
- package/dist/components/wizard/category-grid.test.js.map +1 -0
- package/dist/components/wizard/section-progress.js +9 -0
- package/dist/components/wizard/section-progress.js.map +1 -0
- package/dist/components/wizard/section-progress.test.js +281 -0
- package/dist/components/wizard/section-progress.test.js.map +1 -0
- package/dist/components/wizard/step-approach.js +11 -0
- package/dist/components/wizard/step-approach.js.map +1 -0
- package/dist/components/wizard/step-build.js +15 -0
- package/dist/components/wizard/step-build.js.map +1 -0
- package/dist/components/wizard/step-build.test.js +729 -0
- package/dist/components/wizard/step-build.test.js.map +1 -0
- package/dist/components/wizard/step-confirm.js +9 -0
- package/dist/components/wizard/step-confirm.js.map +1 -0
- package/dist/components/wizard/step-refine.js +9 -0
- package/dist/components/wizard/step-refine.js.map +1 -0
- package/dist/components/wizard/step-refine.test.js +235 -0
- package/dist/components/wizard/step-refine.test.js.map +1 -0
- package/dist/components/wizard/step-stack-options.js +11 -0
- package/dist/components/wizard/step-stack-options.js.map +1 -0
- package/dist/components/wizard/step-stack.js +11 -0
- package/dist/components/wizard/step-stack.js.map +1 -0
- package/dist/components/wizard/wizard-tabs.js +11 -0
- package/dist/components/wizard/wizard-tabs.js.map +1 -0
- package/dist/components/wizard/wizard.js +20 -0
- package/dist/components/wizard/wizard.js.map +1 -0
- package/dist/hooks/init.js +41 -0
- package/dist/hooks/init.js.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/magic-string.es-RGXYGAW3.js +1316 -0
- package/dist/magic-string.es-RGXYGAW3.js.map +1 -0
- package/dist/stores/wizard-store.js +10 -0
- package/dist/stores/wizard-store.js.map +1 -0
- package/dist/stores/wizard-store.test.js +405 -0
- package/dist/stores/wizard-store.test.js.map +1 -0
- package/package.json +44 -25
- package/dist/cli/index.js +0 -6314
- package/dist/cli/index.js.map +0 -1
|
@@ -0,0 +1,915 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
claudePluginInstall,
|
|
4
|
+
claudePluginMarketplaceAdd,
|
|
5
|
+
claudePluginMarketplaceExists,
|
|
6
|
+
isClaudeCLIAvailable
|
|
7
|
+
} from "../chunk-M7YCPFIX.js";
|
|
8
|
+
import {
|
|
9
|
+
copySkillsToLocalFlattened
|
|
10
|
+
} from "../chunk-G2FBJOZG.js";
|
|
11
|
+
import {
|
|
12
|
+
Wizard
|
|
13
|
+
} from "../chunk-ED73HCW2.js";
|
|
14
|
+
import "../chunk-A65SBAAJ.js";
|
|
15
|
+
import "../chunk-HNDT5QRB.js";
|
|
16
|
+
import "../chunk-ALEPJ6YN.js";
|
|
17
|
+
import "../chunk-XKEG3SCV.js";
|
|
18
|
+
import "../chunk-Q6DR5QUH.js";
|
|
19
|
+
import "../chunk-LVKRVFYR.js";
|
|
20
|
+
import "../chunk-UOWHJ6BE.js";
|
|
21
|
+
import "../chunk-Y3V43XCU.js";
|
|
22
|
+
import "../chunk-PPNTD5LO.js";
|
|
23
|
+
import "../chunk-K7PTOVX4.js";
|
|
24
|
+
import {
|
|
25
|
+
compileAgentForPlugin,
|
|
26
|
+
compileStackPlugin
|
|
27
|
+
} from "../chunk-Q2LH2DAB.js";
|
|
28
|
+
import "../chunk-LQTST4WY.js";
|
|
29
|
+
import "../chunk-MJSFR562.js";
|
|
30
|
+
import {
|
|
31
|
+
createLiquidEngine,
|
|
32
|
+
resolveAgentSkillsFromStack,
|
|
33
|
+
resolveAgents,
|
|
34
|
+
resolveStackSkills
|
|
35
|
+
} from "../chunk-SEBPPFUW.js";
|
|
36
|
+
import {
|
|
37
|
+
getCollectivePluginDir
|
|
38
|
+
} from "../chunk-3HBTELJN.js";
|
|
39
|
+
import {
|
|
40
|
+
loadSkillsMatrixFromSource
|
|
41
|
+
} from "../chunk-DKGL77IY.js";
|
|
42
|
+
import {
|
|
43
|
+
loadAllAgents,
|
|
44
|
+
loadStackById
|
|
45
|
+
} from "../chunk-QGGSLMO3.js";
|
|
46
|
+
import "../chunk-NGBFJJ7Q.js";
|
|
47
|
+
import {
|
|
48
|
+
formatSourceOrigin
|
|
49
|
+
} from "../chunk-QESUUPOE.js";
|
|
50
|
+
import {
|
|
51
|
+
LOCAL_SKILLS_PATH,
|
|
52
|
+
PROJECT_ROOT
|
|
53
|
+
} from "../chunk-A3J6IAXK.js";
|
|
54
|
+
import {
|
|
55
|
+
BaseCommand,
|
|
56
|
+
EXIT_CODES
|
|
57
|
+
} from "../chunk-SYQ7R2JO.js";
|
|
58
|
+
import {
|
|
59
|
+
verbose
|
|
60
|
+
} from "../chunk-TOPAIL5W.js";
|
|
61
|
+
import {
|
|
62
|
+
directoryExists,
|
|
63
|
+
ensureDir,
|
|
64
|
+
fileExists,
|
|
65
|
+
readFile,
|
|
66
|
+
remove,
|
|
67
|
+
writeFile
|
|
68
|
+
} from "../chunk-MMDXNZPF.js";
|
|
69
|
+
import {
|
|
70
|
+
init_esm_shims
|
|
71
|
+
} from "../chunk-DHET7RCE.js";
|
|
72
|
+
|
|
73
|
+
// src/cli-v2/commands/init.tsx
|
|
74
|
+
init_esm_shims();
|
|
75
|
+
import { Flags } from "@oclif/core";
|
|
76
|
+
import { render } from "ink";
|
|
77
|
+
import path3 from "path";
|
|
78
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
79
|
+
|
|
80
|
+
// src/cli-v2/lib/permission-checker.tsx
|
|
81
|
+
init_esm_shims();
|
|
82
|
+
import path from "path";
|
|
83
|
+
import { Text, Box } from "ink";
|
|
84
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
85
|
+
async function checkPermissions(projectRoot) {
|
|
86
|
+
const settingsPath = path.join(projectRoot, ".claude", "settings.json");
|
|
87
|
+
const localSettingsPath = path.join(
|
|
88
|
+
projectRoot,
|
|
89
|
+
".claude",
|
|
90
|
+
"settings.local.json"
|
|
91
|
+
);
|
|
92
|
+
let permissions;
|
|
93
|
+
for (const filePath of [localSettingsPath, settingsPath]) {
|
|
94
|
+
if (await fileExists(filePath)) {
|
|
95
|
+
try {
|
|
96
|
+
const content = await readFile(filePath);
|
|
97
|
+
const parsed = JSON.parse(content);
|
|
98
|
+
if (parsed.permissions) {
|
|
99
|
+
permissions = parsed.permissions;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!permissions) {
|
|
107
|
+
return /* @__PURE__ */ jsxs(
|
|
108
|
+
Box,
|
|
109
|
+
{
|
|
110
|
+
flexDirection: "column",
|
|
111
|
+
borderStyle: "round",
|
|
112
|
+
borderColor: "yellow",
|
|
113
|
+
padding: 1,
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Notice" }),
|
|
116
|
+
/* @__PURE__ */ jsx(Text, { children: "No permissions configured in .claude/settings.json" }),
|
|
117
|
+
/* @__PURE__ */ jsx(Text, { children: "Agents will prompt for approval on each tool use." }),
|
|
118
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
119
|
+
/* @__PURE__ */ jsx(Text, { children: "For autonomous operation, add to .claude/settings.json:" }),
|
|
120
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
121
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: "{" }),
|
|
122
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "permissions": {' }),
|
|
123
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "allow": [' }),
|
|
124
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Read(*)",' }),
|
|
125
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(git *)",' }),
|
|
126
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(bun *)"' }),
|
|
127
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: " ]" }),
|
|
128
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: " }" }),
|
|
129
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: "}" })
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
const hasRestrictiveBash = permissions.deny?.some(
|
|
135
|
+
(rule) => rule === "Bash(*)" || rule === "Bash"
|
|
136
|
+
);
|
|
137
|
+
const hasNoAllows = !permissions.allow || permissions.allow.length === 0;
|
|
138
|
+
if (hasRestrictiveBash || hasNoAllows) {
|
|
139
|
+
return /* @__PURE__ */ jsxs(
|
|
140
|
+
Box,
|
|
141
|
+
{
|
|
142
|
+
flexDirection: "column",
|
|
143
|
+
borderStyle: "round",
|
|
144
|
+
borderColor: "yellow",
|
|
145
|
+
padding: 1,
|
|
146
|
+
children: [
|
|
147
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Warnings" }),
|
|
148
|
+
hasRestrictiveBash && /* @__PURE__ */ jsx(Text, { children: "\u26A0 Bash is denied in permissions. Some agents require Bash for git, testing, and build commands." }),
|
|
149
|
+
hasNoAllows && /* @__PURE__ */ jsx(Text, { children: "\u26A0 No allow rules configured. Agents will prompt for each tool use." })
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/cli-v2/lib/stack-installer.ts
|
|
158
|
+
init_esm_shims();
|
|
159
|
+
import os from "os";
|
|
160
|
+
import path2 from "path";
|
|
161
|
+
async function compileStackToTemp(options) {
|
|
162
|
+
const tempDir = path2.join(os.tmpdir(), `cc-stack-${Date.now()}`);
|
|
163
|
+
await ensureDir(tempDir);
|
|
164
|
+
const result = await compileStackPlugin({
|
|
165
|
+
stackId: options.stackId,
|
|
166
|
+
outputDir: tempDir,
|
|
167
|
+
projectRoot: options.projectRoot,
|
|
168
|
+
agentSourcePath: options.agentSourcePath
|
|
169
|
+
});
|
|
170
|
+
return {
|
|
171
|
+
result,
|
|
172
|
+
cleanup: async () => {
|
|
173
|
+
await remove(tempDir);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async function installStackAsPlugin(options) {
|
|
178
|
+
const { stackId, projectDir, sourcePath, agentSourcePath, marketplace } = options;
|
|
179
|
+
const claudeAvailable = await isClaudeCLIAvailable();
|
|
180
|
+
if (!claudeAvailable) {
|
|
181
|
+
throw new Error(
|
|
182
|
+
"Claude CLI not found. Please install Claude Code first: https://claude.ai/code"
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
if (marketplace) {
|
|
186
|
+
verbose(`Installing from marketplace: ${stackId}@${marketplace}`);
|
|
187
|
+
const pluginRef = `${stackId}@${marketplace}`;
|
|
188
|
+
await claudePluginInstall(pluginRef, "project", projectDir);
|
|
189
|
+
return {
|
|
190
|
+
pluginName: stackId,
|
|
191
|
+
stackName: stackId,
|
|
192
|
+
agents: [],
|
|
193
|
+
skills: [],
|
|
194
|
+
pluginPath: pluginRef,
|
|
195
|
+
fromMarketplace: true
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
verbose(`Compiling stack locally: ${stackId}`);
|
|
199
|
+
const { result, cleanup } = await compileStackToTemp({
|
|
200
|
+
stackId,
|
|
201
|
+
projectRoot: sourcePath,
|
|
202
|
+
agentSourcePath
|
|
203
|
+
});
|
|
204
|
+
try {
|
|
205
|
+
await claudePluginInstall(result.pluginPath, "project", projectDir);
|
|
206
|
+
return {
|
|
207
|
+
pluginName: `stack-${stackId}`,
|
|
208
|
+
stackName: result.stackName,
|
|
209
|
+
agents: result.agents,
|
|
210
|
+
skills: result.skillPlugins,
|
|
211
|
+
pluginPath: result.pluginPath,
|
|
212
|
+
fromMarketplace: false
|
|
213
|
+
};
|
|
214
|
+
} finally {
|
|
215
|
+
await cleanup();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/cli-v2/lib/config-generator.ts
|
|
220
|
+
init_esm_shims();
|
|
221
|
+
|
|
222
|
+
// src/cli-v2/lib/skill-agent-mappings.ts
|
|
223
|
+
init_esm_shims();
|
|
224
|
+
|
|
225
|
+
// src/cli-v2/lib/defaults-loader.ts
|
|
226
|
+
init_esm_shims();
|
|
227
|
+
import { parse as parseYaml } from "yaml";
|
|
228
|
+
var cachedDefaults = null;
|
|
229
|
+
function getCachedDefaults() {
|
|
230
|
+
return cachedDefaults;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/cli-v2/lib/skill-agent-mappings.ts
|
|
234
|
+
var SKILL_TO_AGENTS = {
|
|
235
|
+
"frontend/*": [
|
|
236
|
+
"web-developer",
|
|
237
|
+
"web-reviewer",
|
|
238
|
+
"web-researcher",
|
|
239
|
+
"web-pm",
|
|
240
|
+
"web-pattern-scout",
|
|
241
|
+
"web-pattern-critique",
|
|
242
|
+
"agent-summoner",
|
|
243
|
+
"skill-summoner",
|
|
244
|
+
"documentor"
|
|
245
|
+
],
|
|
246
|
+
"backend/*": [
|
|
247
|
+
"api-developer",
|
|
248
|
+
"api-reviewer",
|
|
249
|
+
"api-researcher",
|
|
250
|
+
"web-architecture",
|
|
251
|
+
"web-pm",
|
|
252
|
+
"web-pattern-scout",
|
|
253
|
+
"web-pattern-critique",
|
|
254
|
+
"agent-summoner",
|
|
255
|
+
"skill-summoner",
|
|
256
|
+
"documentor"
|
|
257
|
+
],
|
|
258
|
+
"mobile/*": [
|
|
259
|
+
"web-developer",
|
|
260
|
+
"web-reviewer",
|
|
261
|
+
"web-researcher",
|
|
262
|
+
"web-pm",
|
|
263
|
+
"agent-summoner",
|
|
264
|
+
"skill-summoner",
|
|
265
|
+
"documentor"
|
|
266
|
+
],
|
|
267
|
+
"setup/*": [
|
|
268
|
+
"web-architecture",
|
|
269
|
+
"web-developer",
|
|
270
|
+
"api-developer",
|
|
271
|
+
"agent-summoner",
|
|
272
|
+
"skill-summoner",
|
|
273
|
+
"documentor"
|
|
274
|
+
],
|
|
275
|
+
"security/*": [
|
|
276
|
+
"web-developer",
|
|
277
|
+
"api-developer",
|
|
278
|
+
"web-reviewer",
|
|
279
|
+
"api-reviewer",
|
|
280
|
+
"web-architecture",
|
|
281
|
+
"web-pm",
|
|
282
|
+
"agent-summoner",
|
|
283
|
+
"skill-summoner",
|
|
284
|
+
"documentor"
|
|
285
|
+
],
|
|
286
|
+
"reviewing/*": [
|
|
287
|
+
"web-reviewer",
|
|
288
|
+
"api-reviewer",
|
|
289
|
+
"cli-reviewer",
|
|
290
|
+
"web-pattern-critique",
|
|
291
|
+
"agent-summoner",
|
|
292
|
+
"skill-summoner",
|
|
293
|
+
"documentor"
|
|
294
|
+
],
|
|
295
|
+
"cli/*": [
|
|
296
|
+
"cli-developer",
|
|
297
|
+
"cli-reviewer",
|
|
298
|
+
"api-developer",
|
|
299
|
+
"api-reviewer",
|
|
300
|
+
"api-researcher",
|
|
301
|
+
"web-architecture",
|
|
302
|
+
"web-pm",
|
|
303
|
+
"agent-summoner",
|
|
304
|
+
"skill-summoner",
|
|
305
|
+
"documentor"
|
|
306
|
+
],
|
|
307
|
+
"research/*": [
|
|
308
|
+
"web-researcher",
|
|
309
|
+
"api-researcher",
|
|
310
|
+
"web-pm",
|
|
311
|
+
"web-pattern-scout",
|
|
312
|
+
"web-pattern-critique",
|
|
313
|
+
"documentor",
|
|
314
|
+
"agent-summoner",
|
|
315
|
+
"skill-summoner"
|
|
316
|
+
],
|
|
317
|
+
"methodology/*": [
|
|
318
|
+
"web-developer",
|
|
319
|
+
"api-developer",
|
|
320
|
+
"web-reviewer",
|
|
321
|
+
"api-reviewer",
|
|
322
|
+
"web-researcher",
|
|
323
|
+
"api-researcher",
|
|
324
|
+
"web-tester",
|
|
325
|
+
"web-pm",
|
|
326
|
+
"web-architecture",
|
|
327
|
+
"web-pattern-scout",
|
|
328
|
+
"web-pattern-critique",
|
|
329
|
+
"agent-summoner",
|
|
330
|
+
"skill-summoner",
|
|
331
|
+
"documentor"
|
|
332
|
+
],
|
|
333
|
+
"frontend/testing": ["web-tester", "web-developer", "web-reviewer"],
|
|
334
|
+
"backend/testing": ["web-tester", "api-developer", "api-reviewer"],
|
|
335
|
+
"frontend/mocks": ["web-tester", "web-developer", "web-reviewer"]
|
|
336
|
+
};
|
|
337
|
+
var PRELOADED_SKILLS = {
|
|
338
|
+
"web-developer": ["framework", "styling"],
|
|
339
|
+
"api-developer": ["api", "database", "cli"],
|
|
340
|
+
"cli-developer": ["cli"],
|
|
341
|
+
"web-reviewer": ["framework", "styling", "reviewing"],
|
|
342
|
+
"api-reviewer": ["api", "database", "reviewing"],
|
|
343
|
+
"cli-reviewer": ["cli", "reviewing", "cli-reviewing"],
|
|
344
|
+
"web-researcher": ["framework", "research-methodology"],
|
|
345
|
+
"api-researcher": ["api", "research-methodology"],
|
|
346
|
+
"web-tester": ["testing", "mocks"],
|
|
347
|
+
"web-architecture": ["monorepo", "turborepo", "cli"],
|
|
348
|
+
"web-pm": ["research-methodology"],
|
|
349
|
+
"web-pattern-scout": ["research-methodology"],
|
|
350
|
+
"web-pattern-critique": ["research-methodology", "reviewing"],
|
|
351
|
+
documentor: ["research-methodology"],
|
|
352
|
+
"agent-summoner": [],
|
|
353
|
+
"skill-summoner": []
|
|
354
|
+
};
|
|
355
|
+
var SUBCATEGORY_ALIASES = {
|
|
356
|
+
framework: "frontend/framework",
|
|
357
|
+
styling: "frontend/styling",
|
|
358
|
+
api: "backend/api",
|
|
359
|
+
database: "backend/database",
|
|
360
|
+
mocks: "frontend/mocks",
|
|
361
|
+
testing: "testing",
|
|
362
|
+
reviewing: "reviewing",
|
|
363
|
+
"research-methodology": "research/research-methodology",
|
|
364
|
+
monorepo: "setup/monorepo",
|
|
365
|
+
cli: "cli"
|
|
366
|
+
};
|
|
367
|
+
var DEFAULT_AGENTS = ["agent-summoner", "skill-summoner", "documentor"];
|
|
368
|
+
function getEffectiveSkillToAgents() {
|
|
369
|
+
const defaults = getCachedDefaults();
|
|
370
|
+
if (defaults?.skill_to_agents) {
|
|
371
|
+
return defaults.skill_to_agents;
|
|
372
|
+
}
|
|
373
|
+
return SKILL_TO_AGENTS;
|
|
374
|
+
}
|
|
375
|
+
function getEffectivePreloadedSkills(projectConfig) {
|
|
376
|
+
if (projectConfig?.preload_patterns) {
|
|
377
|
+
return projectConfig.preload_patterns;
|
|
378
|
+
}
|
|
379
|
+
const defaults = getCachedDefaults();
|
|
380
|
+
if (defaults?.preloaded_skills) {
|
|
381
|
+
return defaults.preloaded_skills;
|
|
382
|
+
}
|
|
383
|
+
return PRELOADED_SKILLS;
|
|
384
|
+
}
|
|
385
|
+
function getEffectiveSubcategoryAliases() {
|
|
386
|
+
const defaults = getCachedDefaults();
|
|
387
|
+
if (defaults?.subcategory_aliases) {
|
|
388
|
+
return defaults.subcategory_aliases;
|
|
389
|
+
}
|
|
390
|
+
return SUBCATEGORY_ALIASES;
|
|
391
|
+
}
|
|
392
|
+
function getAgentsForSkill(skillPath, category, projectConfig) {
|
|
393
|
+
const normalizedPath = skillPath.replace(/^skills\//, "").replace(/\/$/, "");
|
|
394
|
+
const skillToAgents = getEffectiveSkillToAgents();
|
|
395
|
+
if (skillToAgents[category]) {
|
|
396
|
+
return skillToAgents[category];
|
|
397
|
+
}
|
|
398
|
+
for (const [pattern, agents] of Object.entries(skillToAgents)) {
|
|
399
|
+
if (normalizedPath === pattern || normalizedPath.startsWith(`${pattern}/`)) {
|
|
400
|
+
return agents;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
for (const [pattern, agents] of Object.entries(skillToAgents)) {
|
|
404
|
+
if (pattern.endsWith("/*")) {
|
|
405
|
+
const prefix = pattern.slice(0, -2);
|
|
406
|
+
if (normalizedPath.startsWith(prefix)) {
|
|
407
|
+
return agents;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return DEFAULT_AGENTS;
|
|
412
|
+
}
|
|
413
|
+
function shouldPreloadSkill(skillPath, skillId, category, agentId, projectConfig) {
|
|
414
|
+
const preloadedSkills = getEffectivePreloadedSkills(projectConfig);
|
|
415
|
+
const preloadedPatterns = preloadedSkills[agentId];
|
|
416
|
+
if (!preloadedPatterns || preloadedPatterns.length === 0) {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
const normalizedPath = skillPath.replace(/^skills\//, "").replace(/\/$/, "");
|
|
420
|
+
const subcategoryAliases = getEffectiveSubcategoryAliases();
|
|
421
|
+
for (const pattern of preloadedPatterns) {
|
|
422
|
+
if (category === pattern) {
|
|
423
|
+
return true;
|
|
424
|
+
}
|
|
425
|
+
if (normalizedPath.includes(pattern)) {
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
if (skillId.toLowerCase().includes(pattern.toLowerCase())) {
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
const aliasedPath = subcategoryAliases[pattern];
|
|
432
|
+
if (aliasedPath && normalizedPath.includes(aliasedPath)) {
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// src/cli-v2/lib/config-generator.ts
|
|
440
|
+
function generateProjectConfigFromSkills(name, selectedSkillIds, matrix, options) {
|
|
441
|
+
const neededAgents = /* @__PURE__ */ new Set();
|
|
442
|
+
for (const skillId of selectedSkillIds) {
|
|
443
|
+
const skill = matrix.skills[skillId];
|
|
444
|
+
if (!skill) {
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
const skillPath = skill.path;
|
|
448
|
+
const category = skill.category;
|
|
449
|
+
const agents = getAgentsForSkill(skillPath, category);
|
|
450
|
+
for (const agentId of agents) {
|
|
451
|
+
neededAgents.add(agentId);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
const skills = selectedSkillIds.map((id) => {
|
|
455
|
+
const skill = matrix.skills[id];
|
|
456
|
+
if (skill?.local && skill?.localPath) {
|
|
457
|
+
return {
|
|
458
|
+
id,
|
|
459
|
+
local: true,
|
|
460
|
+
path: skill.localPath
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
return id;
|
|
464
|
+
});
|
|
465
|
+
const config = {
|
|
466
|
+
name,
|
|
467
|
+
agents: Array.from(neededAgents).sort()
|
|
468
|
+
};
|
|
469
|
+
if (skills.length > 0) {
|
|
470
|
+
config.skills = skills;
|
|
471
|
+
}
|
|
472
|
+
if (options?.description) {
|
|
473
|
+
config.description = options.description;
|
|
474
|
+
}
|
|
475
|
+
if (options?.framework) {
|
|
476
|
+
config.framework = options.framework;
|
|
477
|
+
}
|
|
478
|
+
if (options?.author) {
|
|
479
|
+
config.author = options.author;
|
|
480
|
+
}
|
|
481
|
+
if (options?.includeAgentSkills) {
|
|
482
|
+
const agentSkills = buildAgentSkills(
|
|
483
|
+
selectedSkillIds,
|
|
484
|
+
matrix,
|
|
485
|
+
neededAgents
|
|
486
|
+
);
|
|
487
|
+
if (Object.keys(agentSkills).length > 0) {
|
|
488
|
+
config.agent_skills = agentSkills;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return config;
|
|
492
|
+
}
|
|
493
|
+
function buildAgentSkills(selectedSkillIds, matrix, neededAgents) {
|
|
494
|
+
const agentSkills = {};
|
|
495
|
+
for (const skillId of selectedSkillIds) {
|
|
496
|
+
const skill = matrix.skills[skillId];
|
|
497
|
+
if (!skill) {
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
const skillPath = skill.path;
|
|
501
|
+
const category = skill.category;
|
|
502
|
+
const agents = getAgentsForSkill(skillPath, category);
|
|
503
|
+
for (const agentId of agents) {
|
|
504
|
+
if (!neededAgents.has(agentId)) continue;
|
|
505
|
+
if (!agentSkills[agentId]) {
|
|
506
|
+
agentSkills[agentId] = [];
|
|
507
|
+
}
|
|
508
|
+
const isPreloaded = shouldPreloadSkill(
|
|
509
|
+
skillPath,
|
|
510
|
+
skillId,
|
|
511
|
+
category,
|
|
512
|
+
agentId
|
|
513
|
+
);
|
|
514
|
+
if (isPreloaded) {
|
|
515
|
+
agentSkills[agentId].push({ id: skillId, preloaded: true });
|
|
516
|
+
} else {
|
|
517
|
+
agentSkills[agentId].push(skillId);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return agentSkills;
|
|
522
|
+
}
|
|
523
|
+
function buildStackProperty(stack, skillAliases) {
|
|
524
|
+
const result = {};
|
|
525
|
+
for (const [agentId, agentConfig] of Object.entries(stack.agents)) {
|
|
526
|
+
if (!agentConfig || Object.keys(agentConfig).length === 0) {
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
const resolvedMappings = {};
|
|
530
|
+
for (const [subcategoryId, alias] of Object.entries(
|
|
531
|
+
agentConfig
|
|
532
|
+
)) {
|
|
533
|
+
const skillId = skillAliases[alias];
|
|
534
|
+
if (skillId) {
|
|
535
|
+
resolvedMappings[subcategoryId] = skillId;
|
|
536
|
+
} else {
|
|
537
|
+
resolvedMappings[subcategoryId] = alias;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
if (Object.keys(resolvedMappings).length > 0) {
|
|
541
|
+
result[agentId] = resolvedMappings;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return result;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// src/cli-v2/commands/init.tsx
|
|
548
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
549
|
+
var PLUGIN_NAME = "claude-collective";
|
|
550
|
+
var Init = class _Init extends BaseCommand {
|
|
551
|
+
static summary = "Initialize Claude Collective in this project";
|
|
552
|
+
static description = "Interactive wizard to set up skills and agents. Supports Plugin Mode (native install) and Local Mode (copy to .claude/).";
|
|
553
|
+
static flags = {
|
|
554
|
+
...BaseCommand.baseFlags,
|
|
555
|
+
refresh: Flags.boolean({
|
|
556
|
+
description: "Force refresh from remote source",
|
|
557
|
+
default: false
|
|
558
|
+
})
|
|
559
|
+
};
|
|
560
|
+
async run() {
|
|
561
|
+
const { flags } = await this.parse(_Init);
|
|
562
|
+
const projectDir = process.cwd();
|
|
563
|
+
this.log("Claude Collective Setup\n");
|
|
564
|
+
if (flags["dry-run"]) {
|
|
565
|
+
this.log("[dry-run] Preview mode - no files will be created\n");
|
|
566
|
+
}
|
|
567
|
+
const pluginDir = getCollectivePluginDir();
|
|
568
|
+
const pluginExists = await directoryExists(pluginDir);
|
|
569
|
+
if (pluginExists) {
|
|
570
|
+
this.warn(`Claude Collective is already initialized at ${pluginDir}`);
|
|
571
|
+
this.log(`Use 'cc edit' to modify skills.`);
|
|
572
|
+
this.log("No changes made.");
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
this.log("Loading skills matrix...");
|
|
576
|
+
let sourceResult;
|
|
577
|
+
try {
|
|
578
|
+
sourceResult = await loadSkillsMatrixFromSource({
|
|
579
|
+
sourceFlag: flags.source,
|
|
580
|
+
projectDir,
|
|
581
|
+
forceRefresh: flags.refresh
|
|
582
|
+
});
|
|
583
|
+
const sourceInfo = sourceResult.isLocal ? "local" : formatSourceOrigin(sourceResult.sourceConfig.sourceOrigin);
|
|
584
|
+
this.log(
|
|
585
|
+
`Loaded ${Object.keys(sourceResult.matrix.skills).length} skills (${sourceInfo})
|
|
586
|
+
`
|
|
587
|
+
);
|
|
588
|
+
} catch (error) {
|
|
589
|
+
this.error(
|
|
590
|
+
error instanceof Error ? error.message : "Unknown error occurred",
|
|
591
|
+
{ exit: EXIT_CODES.ERROR }
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
let wizardResult = null;
|
|
595
|
+
const { waitUntilExit } = render(
|
|
596
|
+
/* @__PURE__ */ jsx2(
|
|
597
|
+
Wizard,
|
|
598
|
+
{
|
|
599
|
+
matrix: sourceResult.matrix,
|
|
600
|
+
onComplete: (result) => {
|
|
601
|
+
wizardResult = result;
|
|
602
|
+
},
|
|
603
|
+
onCancel: () => {
|
|
604
|
+
this.log("Setup cancelled");
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
)
|
|
608
|
+
);
|
|
609
|
+
await waitUntilExit();
|
|
610
|
+
if (!wizardResult || wizardResult.cancelled) {
|
|
611
|
+
this.exit(EXIT_CODES.CANCELLED);
|
|
612
|
+
}
|
|
613
|
+
if (wizardResult.selectedSkills.length === 0) {
|
|
614
|
+
this.error("No skills selected", { exit: EXIT_CODES.ERROR });
|
|
615
|
+
}
|
|
616
|
+
await this.handleInstallation(wizardResult, sourceResult, flags);
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Handle installation based on wizard result.
|
|
620
|
+
* Supports Plugin Mode (with stack) and Local Mode (copy to .claude/).
|
|
621
|
+
*/
|
|
622
|
+
async handleInstallation(result, sourceResult, flags) {
|
|
623
|
+
const projectDir = process.cwd();
|
|
624
|
+
const matrix = sourceResult.matrix;
|
|
625
|
+
const dryRun = flags["dry-run"];
|
|
626
|
+
this.log("\n");
|
|
627
|
+
this.log(`Selected ${result.selectedSkills.length} skills`);
|
|
628
|
+
this.log(
|
|
629
|
+
`Install mode: ${result.installMode === "plugin" ? "Plugin (native install)" : "Local (copy to .claude/skills/)"}`
|
|
630
|
+
);
|
|
631
|
+
this.log("\n");
|
|
632
|
+
if (dryRun) {
|
|
633
|
+
if (result.installMode === "plugin" && result.selectedStack) {
|
|
634
|
+
const useMarketplace = !!sourceResult.marketplace;
|
|
635
|
+
if (useMarketplace) {
|
|
636
|
+
this.log(
|
|
637
|
+
`[dry-run] Would install stack "${result.selectedStack.id}" from marketplace "${sourceResult.marketplace}"`
|
|
638
|
+
);
|
|
639
|
+
this.log(
|
|
640
|
+
`[dry-run] claude plugin install ${result.selectedStack.id}@${sourceResult.marketplace} --scope project`
|
|
641
|
+
);
|
|
642
|
+
} else {
|
|
643
|
+
this.log(
|
|
644
|
+
`[dry-run] Would compile and install stack "${result.selectedStack.id}" as a native plugin`
|
|
645
|
+
);
|
|
646
|
+
this.log(
|
|
647
|
+
`[dry-run] claude plugin install ./compiled-stack/${result.selectedStack.id} --scope project`
|
|
648
|
+
);
|
|
649
|
+
this.log(
|
|
650
|
+
`[dry-run] Stack includes ${result.selectedSkills.length} skills and agents bundled together`
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
} else {
|
|
654
|
+
if (result.installMode === "plugin") {
|
|
655
|
+
this.log(
|
|
656
|
+
`[dry-run] Individual skill plugin installation not yet supported`
|
|
657
|
+
);
|
|
658
|
+
this.log(`[dry-run] Would fall back to Local Mode...`);
|
|
659
|
+
}
|
|
660
|
+
const localSkillsDir = path3.join(projectDir, LOCAL_SKILLS_PATH);
|
|
661
|
+
const localAgentsDir = path3.join(projectDir, ".claude", "agents");
|
|
662
|
+
this.log(
|
|
663
|
+
`[dry-run] Would copy ${result.selectedSkills.length} skills to ${localSkillsDir}`
|
|
664
|
+
);
|
|
665
|
+
this.log(`[dry-run] Would compile agents to ${localAgentsDir}`);
|
|
666
|
+
this.log(`[dry-run] Would save config to .claude/config.yaml`);
|
|
667
|
+
}
|
|
668
|
+
this.log("\n[dry-run] Preview complete - no files were created");
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
if (result.installMode === "plugin") {
|
|
672
|
+
if (result.selectedStack) {
|
|
673
|
+
await this.installPluginMode(result, sourceResult);
|
|
674
|
+
return;
|
|
675
|
+
} else {
|
|
676
|
+
this.warn(
|
|
677
|
+
"Individual skill plugin installation not yet supported in Plugin Mode."
|
|
678
|
+
);
|
|
679
|
+
this.log(`Falling back to Local Mode (copying to .claude/skills/)...`);
|
|
680
|
+
this.log(
|
|
681
|
+
"To use Plugin Mode, select a pre-built stack instead of individual skills.\n"
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
await this.installLocalMode(result, sourceResult);
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Install in Plugin Mode: install stack as native plugin.
|
|
689
|
+
*/
|
|
690
|
+
async installPluginMode(result, sourceResult) {
|
|
691
|
+
if (!result.selectedStack) {
|
|
692
|
+
throw new Error("No stack selected for plugin mode");
|
|
693
|
+
}
|
|
694
|
+
const projectDir = process.cwd();
|
|
695
|
+
if (sourceResult.marketplace) {
|
|
696
|
+
const marketplaceExists = await claudePluginMarketplaceExists(
|
|
697
|
+
sourceResult.marketplace
|
|
698
|
+
);
|
|
699
|
+
if (!marketplaceExists) {
|
|
700
|
+
this.log(`Registering marketplace "${sourceResult.marketplace}"...`);
|
|
701
|
+
try {
|
|
702
|
+
await claudePluginMarketplaceAdd(
|
|
703
|
+
sourceResult.sourceConfig.source,
|
|
704
|
+
sourceResult.marketplace
|
|
705
|
+
);
|
|
706
|
+
this.log(`Registered marketplace: ${sourceResult.marketplace}`);
|
|
707
|
+
} catch (error) {
|
|
708
|
+
this.error(error instanceof Error ? error.message : "Unknown error", {
|
|
709
|
+
exit: EXIT_CODES.ERROR
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
const installMethod = sourceResult.marketplace ? `Installing from marketplace "${sourceResult.marketplace}"` : "Compiling and installing";
|
|
715
|
+
this.log(`${installMethod} stack "${result.selectedStack.id}"...`);
|
|
716
|
+
try {
|
|
717
|
+
const installResult = await installStackAsPlugin({
|
|
718
|
+
stackId: result.selectedStack.id,
|
|
719
|
+
projectDir,
|
|
720
|
+
sourcePath: sourceResult.sourcePath,
|
|
721
|
+
agentSourcePath: sourceResult.sourcePath,
|
|
722
|
+
marketplace: sourceResult.marketplace
|
|
723
|
+
});
|
|
724
|
+
const installedFrom = installResult.fromMarketplace ? `from marketplace` : `(compiled locally)`;
|
|
725
|
+
this.log(
|
|
726
|
+
`Installed stack plugin: ${installResult.pluginName} ${installedFrom}
|
|
727
|
+
`
|
|
728
|
+
);
|
|
729
|
+
this.log("Claude Collective initialized successfully!\n");
|
|
730
|
+
this.log(`Stack "${installResult.stackName}" installed as plugin`);
|
|
731
|
+
if (installResult.agents.length > 0) {
|
|
732
|
+
this.log("\nAgents included:");
|
|
733
|
+
for (const agentName of installResult.agents) {
|
|
734
|
+
this.log(` ${agentName}`);
|
|
735
|
+
}
|
|
736
|
+
this.log(`
|
|
737
|
+
Skills bundled: ${installResult.skills.length}`);
|
|
738
|
+
}
|
|
739
|
+
this.log("");
|
|
740
|
+
const permissionWarning = await checkPermissions(projectDir);
|
|
741
|
+
if (permissionWarning) {
|
|
742
|
+
const { waitUntilExit } = render(permissionWarning);
|
|
743
|
+
await waitUntilExit();
|
|
744
|
+
}
|
|
745
|
+
} catch (error) {
|
|
746
|
+
this.error(error instanceof Error ? error.message : "Unknown error", {
|
|
747
|
+
exit: EXIT_CODES.ERROR
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Install in Local Mode: copy skills and compile agents to .claude/.
|
|
753
|
+
*/
|
|
754
|
+
async installLocalMode(result, sourceResult) {
|
|
755
|
+
const projectDir = process.cwd();
|
|
756
|
+
const matrix = sourceResult.matrix;
|
|
757
|
+
const localSkillsDir = path3.join(projectDir, LOCAL_SKILLS_PATH);
|
|
758
|
+
const localAgentsDir = path3.join(projectDir, ".claude", "agents");
|
|
759
|
+
const localConfigPath = path3.join(projectDir, ".claude", "config.yaml");
|
|
760
|
+
this.log("Copying skills to local directory...");
|
|
761
|
+
try {
|
|
762
|
+
await ensureDir(localSkillsDir);
|
|
763
|
+
await ensureDir(localAgentsDir);
|
|
764
|
+
const copiedSkills = await copySkillsToLocalFlattened(
|
|
765
|
+
result.selectedSkills,
|
|
766
|
+
localSkillsDir,
|
|
767
|
+
matrix,
|
|
768
|
+
sourceResult
|
|
769
|
+
);
|
|
770
|
+
this.log(`Copied ${copiedSkills.length} skills to .claude/skills/
|
|
771
|
+
`);
|
|
772
|
+
this.log("Generating configuration...");
|
|
773
|
+
const cliAgents = await loadAllAgents(PROJECT_ROOT);
|
|
774
|
+
const localAgents = await loadAllAgents(sourceResult.sourcePath);
|
|
775
|
+
const agents = { ...cliAgents, ...localAgents };
|
|
776
|
+
const localSkillsForResolution = {};
|
|
777
|
+
for (const copiedSkill of copiedSkills) {
|
|
778
|
+
const skill = matrix.skills[copiedSkill.skillId];
|
|
779
|
+
if (skill) {
|
|
780
|
+
localSkillsForResolution[copiedSkill.skillId] = {
|
|
781
|
+
id: copiedSkill.skillId,
|
|
782
|
+
name: skill.name,
|
|
783
|
+
description: skill.description || "",
|
|
784
|
+
canonicalId: copiedSkill.skillId,
|
|
785
|
+
path: copiedSkill.destPath,
|
|
786
|
+
content: ""
|
|
787
|
+
// Content not needed for skill references
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
const skillAliases = matrix.aliases || {};
|
|
792
|
+
let localConfig;
|
|
793
|
+
const loadedStack = result.selectedStack ? await loadStackById(result.selectedStack.id, PROJECT_ROOT) : null;
|
|
794
|
+
if (result.selectedStack) {
|
|
795
|
+
if (loadedStack) {
|
|
796
|
+
const agentIds = Object.keys(loadedStack.agents);
|
|
797
|
+
const stackProperty = buildStackProperty(loadedStack, skillAliases);
|
|
798
|
+
localConfig = {
|
|
799
|
+
name: PLUGIN_NAME,
|
|
800
|
+
installMode: result.installMode,
|
|
801
|
+
description: loadedStack.description,
|
|
802
|
+
skills: result.selectedSkills.map((id) => id),
|
|
803
|
+
agents: agentIds,
|
|
804
|
+
philosophy: loadedStack.philosophy,
|
|
805
|
+
stack: stackProperty
|
|
806
|
+
};
|
|
807
|
+
} else {
|
|
808
|
+
throw new Error(
|
|
809
|
+
`Stack '${result.selectedStack.id}' not found in config/stacks.yaml. Available stacks are defined in the CLI's config/stacks.yaml file.`
|
|
810
|
+
);
|
|
811
|
+
}
|
|
812
|
+
} else {
|
|
813
|
+
localConfig = generateProjectConfigFromSkills(
|
|
814
|
+
PLUGIN_NAME,
|
|
815
|
+
result.selectedSkills,
|
|
816
|
+
sourceResult.matrix
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
localConfig.installMode = result.installMode;
|
|
820
|
+
const configYaml = stringifyYaml(localConfig, {
|
|
821
|
+
indent: 2,
|
|
822
|
+
lineWidth: 120
|
|
823
|
+
});
|
|
824
|
+
await writeFile(localConfigPath, configYaml);
|
|
825
|
+
this.log(`Configuration saved (${localConfig.agents.length} agents)
|
|
826
|
+
`);
|
|
827
|
+
this.log("Compiling agents...");
|
|
828
|
+
const compileAgents = {};
|
|
829
|
+
for (const agentId of localConfig.agents) {
|
|
830
|
+
if (agents[agentId]) {
|
|
831
|
+
if (loadedStack) {
|
|
832
|
+
const skillRefs = resolveAgentSkillsFromStack(
|
|
833
|
+
agentId,
|
|
834
|
+
loadedStack,
|
|
835
|
+
skillAliases
|
|
836
|
+
);
|
|
837
|
+
compileAgents[agentId] = { skills: skillRefs };
|
|
838
|
+
} else if (localConfig.agent_skills?.[agentId]) {
|
|
839
|
+
const skillRefs = resolveStackSkills(
|
|
840
|
+
localConfig,
|
|
841
|
+
agentId,
|
|
842
|
+
localSkillsForResolution
|
|
843
|
+
);
|
|
844
|
+
compileAgents[agentId] = { skills: skillRefs };
|
|
845
|
+
} else {
|
|
846
|
+
compileAgents[agentId] = {};
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
const compileConfig = {
|
|
851
|
+
name: PLUGIN_NAME,
|
|
852
|
+
description: localConfig.description || `Local setup with ${result.selectedSkills.length} skills`,
|
|
853
|
+
claude_md: "",
|
|
854
|
+
agents: compileAgents
|
|
855
|
+
};
|
|
856
|
+
const engine = await createLiquidEngine(projectDir);
|
|
857
|
+
const resolvedAgents = await resolveAgents(
|
|
858
|
+
agents,
|
|
859
|
+
localSkillsForResolution,
|
|
860
|
+
compileConfig,
|
|
861
|
+
sourceResult.sourcePath
|
|
862
|
+
);
|
|
863
|
+
const compiledAgentNames = [];
|
|
864
|
+
for (const [name, agent] of Object.entries(resolvedAgents)) {
|
|
865
|
+
const output = await compileAgentForPlugin(
|
|
866
|
+
name,
|
|
867
|
+
agent,
|
|
868
|
+
sourceResult.sourcePath,
|
|
869
|
+
engine
|
|
870
|
+
);
|
|
871
|
+
await writeFile(path3.join(localAgentsDir, `${name}.md`), output);
|
|
872
|
+
compiledAgentNames.push(name);
|
|
873
|
+
}
|
|
874
|
+
this.log(
|
|
875
|
+
`Compiled ${compiledAgentNames.length} agents to .claude/agents/
|
|
876
|
+
`
|
|
877
|
+
);
|
|
878
|
+
this.log("Claude Collective initialized successfully!\n");
|
|
879
|
+
this.log("Skills copied to:");
|
|
880
|
+
this.log(` ${localSkillsDir}`);
|
|
881
|
+
for (const copiedSkill of copiedSkills) {
|
|
882
|
+
const skill = matrix.skills[copiedSkill.skillId];
|
|
883
|
+
const displayName = skill?.alias || copiedSkill.skillId;
|
|
884
|
+
this.log(` ${displayName}/`);
|
|
885
|
+
}
|
|
886
|
+
this.log("");
|
|
887
|
+
this.log("Agents compiled to:");
|
|
888
|
+
this.log(` ${localAgentsDir}`);
|
|
889
|
+
for (const agentName of compiledAgentNames) {
|
|
890
|
+
this.log(` ${agentName}.md`);
|
|
891
|
+
}
|
|
892
|
+
this.log("");
|
|
893
|
+
this.log("Configuration:");
|
|
894
|
+
this.log(` ${localConfigPath}`);
|
|
895
|
+
this.log("");
|
|
896
|
+
this.log("To customize agent-skill assignments:");
|
|
897
|
+
this.log(` 1. Edit .claude/config.yaml`);
|
|
898
|
+
this.log(` 2. Run 'cc compile' to regenerate agents`);
|
|
899
|
+
this.log("");
|
|
900
|
+
const permissionWarning = await checkPermissions(projectDir);
|
|
901
|
+
if (permissionWarning) {
|
|
902
|
+
const { waitUntilExit } = render(permissionWarning);
|
|
903
|
+
await waitUntilExit();
|
|
904
|
+
}
|
|
905
|
+
} catch (error) {
|
|
906
|
+
this.error(error instanceof Error ? error.message : String(error), {
|
|
907
|
+
exit: EXIT_CODES.ERROR
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
export {
|
|
913
|
+
Init as default
|
|
914
|
+
};
|
|
915
|
+
//# sourceMappingURL=init.js.map
|