@claude-collective/cli 0.13.4 → 0.21.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 +183 -0
- package/config/skills-matrix.yaml +180 -113
- package/config/stacks.yaml +6 -6
- package/dist/{chunk-K3NB6DSG.js → chunk-2LSGX6R4.js} +54 -114
- package/dist/chunk-2LSGX6R4.js.map +1 -0
- package/dist/chunk-2OKUEELH.js +32 -0
- package/dist/chunk-2OKUEELH.js.map +1 -0
- package/dist/{chunk-V46GGCCI.js → chunk-374JNMR6.js} +14 -96
- package/dist/chunk-374JNMR6.js.map +1 -0
- package/dist/chunk-3EHUF54X.js +133 -0
- package/dist/chunk-3EHUF54X.js.map +1 -0
- package/dist/{chunk-7Q44DMSP.js → chunk-3XR4PALU.js} +92 -145
- package/dist/chunk-3XR4PALU.js.map +1 -0
- package/dist/{chunk-IAUAQJQ2.js → chunk-5K2ZLUO5.js} +5 -5
- package/dist/{chunk-IAUAQJQ2.js.map → chunk-5K2ZLUO5.js.map} +1 -1
- package/dist/{chunk-ACNBKXXJ.js → chunk-5KXUDHAB.js} +8 -36
- package/dist/chunk-5KXUDHAB.js.map +1 -0
- package/dist/chunk-7SLV7CMF.js +615 -0
- package/dist/chunk-7SLV7CMF.js.map +1 -0
- package/dist/{chunk-CDX4W4DM.js → chunk-A46TPNBJ.js} +61 -32
- package/dist/chunk-A46TPNBJ.js.map +1 -0
- package/dist/{chunk-TKFPKEV3.js → chunk-AL74GBW4.js} +1 -1
- package/dist/chunk-AL74GBW4.js.map +1 -0
- package/dist/chunk-BQX23RBV.js +191 -0
- package/dist/chunk-BQX23RBV.js.map +1 -0
- package/dist/{chunk-IMDW5ZUP.js → chunk-CA4LH4LI.js} +5 -5
- package/dist/chunk-CA4LH4LI.js.map +1 -0
- package/dist/{chunk-D237EVNB.js → chunk-CBLPAMZO.js} +5 -8
- package/dist/chunk-CBLPAMZO.js.map +1 -0
- package/dist/{chunk-B7CCVP6Q.js → chunk-CKPQHGXR.js} +52 -274
- package/dist/chunk-CKPQHGXR.js.map +1 -0
- package/dist/{chunk-SVYPSDWY.js → chunk-CXOFOJCN.js} +6 -10
- package/dist/chunk-CXOFOJCN.js.map +1 -0
- package/dist/{chunk-UQTEPWU7.js → chunk-EHGD7HIE.js} +2 -6
- package/dist/chunk-EHGD7HIE.js.map +1 -0
- package/dist/{chunk-76DWXGQE.js → chunk-FJFEKPXF.js} +1 -1
- package/dist/chunk-FJFEKPXF.js.map +1 -0
- package/dist/{chunk-E3FJH4TF.js → chunk-HEOHU5EZ.js} +2 -13
- package/dist/chunk-HEOHU5EZ.js.map +1 -0
- package/dist/{chunk-JIPWV2FX.js → chunk-HGCBZUH5.js} +6 -27
- package/dist/chunk-HGCBZUH5.js.map +1 -0
- package/dist/{chunk-ED4E6Q2T.js → chunk-HPGFY5ZN.js} +4 -4
- package/dist/chunk-HPGFY5ZN.js.map +1 -0
- package/dist/chunk-INJ2EFRW.js +127 -0
- package/dist/chunk-INJ2EFRW.js.map +1 -0
- package/dist/{chunk-KAAEN2PO.js → chunk-IOBFMF6X.js} +6 -2
- package/dist/{chunk-KAAEN2PO.js.map → chunk-IOBFMF6X.js.map} +1 -1
- package/dist/{chunk-K7EVM5LY.js → chunk-KH3HA7J7.js} +8 -33
- package/dist/chunk-KH3HA7J7.js.map +1 -0
- package/dist/{chunk-4K4ZXQRM.js → chunk-N6JNE326.js} +38 -94
- package/dist/chunk-N6JNE326.js.map +1 -0
- package/dist/chunk-NAGU7TVZ.js +36 -0
- package/dist/chunk-NAGU7TVZ.js.map +1 -0
- package/dist/{chunk-Z7G4B5HJ.js → chunk-OQYYMQJR.js} +68 -142
- package/dist/chunk-OQYYMQJR.js.map +1 -0
- package/dist/{chunk-RFTSZDHV.js → chunk-PLZOUVDD.js} +159 -53
- package/dist/chunk-PLZOUVDD.js.map +1 -0
- package/dist/chunk-Q3J43SF3.js +21 -0
- package/dist/chunk-Q3J43SF3.js.map +1 -0
- package/dist/{chunk-3U3R4NCG.js → chunk-T25OEQFI.js} +6 -2
- package/dist/chunk-T25OEQFI.js.map +1 -0
- package/dist/chunk-UMORK7OK.js +29 -0
- package/dist/chunk-UMORK7OK.js.map +1 -0
- package/dist/{chunk-ZFPSUQOU.js → chunk-VFHWU7JU.js} +12 -121
- package/dist/chunk-VFHWU7JU.js.map +1 -0
- package/dist/{chunk-GDH553MV.js → chunk-VS4GVTZE.js} +3 -3
- package/dist/chunk-VS4GVTZE.js.map +1 -0
- package/dist/chunk-WFEFICFM.js +67 -0
- package/dist/chunk-WFEFICFM.js.map +1 -0
- package/dist/{chunk-P26A2K5N.js → chunk-WG6KIAPK.js} +6 -16
- package/dist/chunk-WG6KIAPK.js.map +1 -0
- package/dist/{chunk-X6QONICW.js → chunk-ZEI3ZUDU.js} +3 -7
- package/dist/chunk-ZEI3ZUDU.js.map +1 -0
- package/dist/chunk-ZNIDWLL5.js +68 -0
- package/dist/chunk-ZNIDWLL5.js.map +1 -0
- package/dist/chunk-ZSVMS677.js +45 -0
- package/dist/chunk-ZSVMS677.js.map +1 -0
- package/dist/cli/defaults/agent-mappings.yaml +13 -13
- package/dist/commands/build/marketplace.js +8 -14
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +10 -21
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/build/stack.js +13 -18
- package/dist/commands/build/stack.js.map +1 -1
- package/dist/commands/compile.js +25 -40
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/get.js +7 -7
- package/dist/commands/config/get.js.map +1 -1
- package/dist/commands/config/index.js +6 -6
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/path.js +5 -7
- package/dist/commands/config/path.js.map +1 -1
- package/dist/commands/config/set-project.js +8 -9
- package/dist/commands/config/set-project.js.map +1 -1
- package/dist/commands/config/show.js +5 -5
- package/dist/commands/config/unset-project.js +8 -9
- package/dist/commands/config/unset-project.js.map +1 -1
- package/dist/commands/diff.js +17 -40
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +14 -25
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +41 -54
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +24 -44
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +19 -39
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +10 -15
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +452 -451
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.js +85 -9
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +9 -10
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/skill.js +12 -16
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +12 -89
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +12 -18
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +12 -21
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +26 -146
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +407 -15
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/version/bump.js +7 -23
- package/dist/commands/version/bump.js.map +1 -1
- package/dist/commands/version/index.js +6 -21
- package/dist/commands/version/index.js.map +1 -1
- package/dist/commands/version/set.js +6 -23
- package/dist/commands/version/set.js.map +1 -1
- package/dist/commands/version/show.js +6 -21
- package/dist/commands/version/show.js.map +1 -1
- package/dist/components/common/message.js +2 -6
- package/dist/components/common/message.js.map +1 -1
- package/dist/components/common/spinner.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +1 -1
- package/dist/components/wizard/category-grid.js +1 -1
- package/dist/components/wizard/category-grid.test.js +20 -92
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/menu-item.js +9 -0
- package/dist/components/wizard/section-progress.js +1 -1
- package/dist/components/wizard/section-progress.test.js +13 -103
- package/dist/components/wizard/section-progress.test.js.map +1 -1
- package/dist/components/wizard/step-approach.js +5 -4
- package/dist/components/wizard/step-build.js +3 -4
- package/dist/components/wizard/step-build.test.js +81 -186
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +1 -2
- package/dist/components/wizard/step-refine.js +1 -2
- package/dist/components/wizard/step-refine.test.js +6 -14
- package/dist/components/wizard/step-refine.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +5 -3
- package/dist/components/wizard/view-title.js +9 -0
- package/dist/components/wizard/wizard-layout.js +16 -0
- package/dist/components/wizard/wizard-layout.js.map +1 -0
- package/dist/components/wizard/wizard-tabs.js +1 -1
- package/dist/components/wizard/wizard.js +12 -13
- package/dist/config/skills-matrix.yaml +180 -113
- package/dist/config/stacks.yaml +6 -6
- package/dist/hooks/init.js +5 -7
- package/dist/hooks/init.js.map +1 -1
- package/dist/src/agents/developer/web-developer/examples.md +1 -6
- package/dist/src/agents/meta/documentor/workflow.md +1 -5
- package/dist/src/agents/migration/cli-migrator/anti-patterns.md +1 -3
- package/dist/src/agents/tester/web-tester/output-format.md +1 -3
- package/dist/stores/wizard-store.js +2 -2
- package/dist/stores/wizard-store.test.js +60 -23
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/developer/web-developer/examples.md +1 -6
- package/src/agents/meta/documentor/workflow.md +1 -5
- package/src/agents/migration/cli-migrator/anti-patterns.md +1 -3
- package/src/agents/tester/web-tester/output-format.md +1 -3
- package/dist/chunk-3U3R4NCG.js.map +0 -1
- package/dist/chunk-4K4ZXQRM.js.map +0 -1
- package/dist/chunk-76DWXGQE.js.map +0 -1
- package/dist/chunk-7Q44DMSP.js.map +0 -1
- package/dist/chunk-ACNBKXXJ.js.map +0 -1
- package/dist/chunk-B7CCVP6Q.js.map +0 -1
- package/dist/chunk-BDLUZVKU.js +0 -54
- package/dist/chunk-BDLUZVKU.js.map +0 -1
- package/dist/chunk-CDX4W4DM.js.map +0 -1
- package/dist/chunk-D237EVNB.js.map +0 -1
- package/dist/chunk-DRXPNNPB.js +0 -393
- package/dist/chunk-DRXPNNPB.js.map +0 -1
- package/dist/chunk-E3FJH4TF.js.map +0 -1
- package/dist/chunk-ED4E6Q2T.js.map +0 -1
- package/dist/chunk-GDH553MV.js.map +0 -1
- package/dist/chunk-HLJX2FTL.js +0 -95
- package/dist/chunk-HLJX2FTL.js.map +0 -1
- package/dist/chunk-I2DSLOXZ.js +0 -75
- package/dist/chunk-I2DSLOXZ.js.map +0 -1
- package/dist/chunk-I4TPKIYX.js +0 -493
- package/dist/chunk-I4TPKIYX.js.map +0 -1
- package/dist/chunk-IBE7JIAG.js +0 -129
- package/dist/chunk-IBE7JIAG.js.map +0 -1
- package/dist/chunk-IMDW5ZUP.js.map +0 -1
- package/dist/chunk-JIPWV2FX.js.map +0 -1
- package/dist/chunk-K3NB6DSG.js.map +0 -1
- package/dist/chunk-K7EVM5LY.js.map +0 -1
- package/dist/chunk-NDY25DTL.js +0 -453
- package/dist/chunk-NDY25DTL.js.map +0 -1
- package/dist/chunk-P26A2K5N.js.map +0 -1
- package/dist/chunk-RFTSZDHV.js.map +0 -1
- package/dist/chunk-SVYPSDWY.js.map +0 -1
- package/dist/chunk-TKFPKEV3.js.map +0 -1
- package/dist/chunk-UQTEPWU7.js.map +0 -1
- package/dist/chunk-V46GGCCI.js.map +0 -1
- package/dist/chunk-X6QONICW.js.map +0 -1
- package/dist/chunk-Y2LW7R3Y.js +0 -23
- package/dist/chunk-Y2LW7R3Y.js.map +0 -1
- package/dist/chunk-Z7G4B5HJ.js.map +0 -1
- package/dist/chunk-ZENYS6KW.js +0 -90
- package/dist/chunk-ZENYS6KW.js.map +0 -1
- package/dist/chunk-ZFPSUQOU.js.map +0 -1
- package/dist/commands/config/set.js +0 -61
- package/dist/commands/config/set.js.map +0 -1
- package/dist/commands/config/unset.js +0 -57
- package/dist/commands/config/unset.js.map +0 -1
- package/dist/commands/test-imports.js +0 -92
- package/dist/commands/test-imports.js.map +0 -1
- package/dist/components/wizard/step-stack-options.js +0 -11
- package/dist/components/wizard/wizard-footer.js +0 -9
- /package/dist/components/wizard/{step-stack-options.js.map → menu-item.js.map} +0 -0
- /package/dist/components/wizard/{wizard-footer.js.map → view-title.js.map} +0 -0
package/dist/commands/init.js
CHANGED
|
@@ -4,51 +4,54 @@ import {
|
|
|
4
4
|
claudePluginMarketplaceAdd,
|
|
5
5
|
claudePluginMarketplaceExists,
|
|
6
6
|
isClaudeCLIAvailable
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-EHGD7HIE.js";
|
|
8
8
|
import {
|
|
9
9
|
Wizard
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-Y2LW7R3Y.js";
|
|
21
|
-
import "../chunk-D237EVNB.js";
|
|
10
|
+
} from "../chunk-2LSGX6R4.js";
|
|
11
|
+
import "../chunk-A46TPNBJ.js";
|
|
12
|
+
import "../chunk-3EHUF54X.js";
|
|
13
|
+
import "../chunk-ZNIDWLL5.js";
|
|
14
|
+
import "../chunk-WFEFICFM.js";
|
|
15
|
+
import "../chunk-3XR4PALU.js";
|
|
16
|
+
import "../chunk-Q3J43SF3.js";
|
|
17
|
+
import "../chunk-ZEI3ZUDU.js";
|
|
18
|
+
import "../chunk-OQYYMQJR.js";
|
|
19
|
+
import "../chunk-UMORK7OK.js";
|
|
22
20
|
import "../chunk-Z2CWURZ6.js";
|
|
21
|
+
import "../chunk-CBLPAMZO.js";
|
|
23
22
|
import {
|
|
24
23
|
compileAgentForPlugin,
|
|
25
|
-
compileStackPlugin
|
|
26
|
-
} from "../chunk-DRXPNNPB.js";
|
|
27
|
-
import "../chunk-GDH553MV.js";
|
|
28
|
-
import {
|
|
24
|
+
compileStackPlugin,
|
|
29
25
|
createLiquidEngine,
|
|
30
26
|
resolveAgentSkillsFromStack,
|
|
31
27
|
resolveAgents,
|
|
32
28
|
resolveStackSkills
|
|
33
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-7SLV7CMF.js";
|
|
30
|
+
import "../chunk-VS4GVTZE.js";
|
|
34
31
|
import {
|
|
35
32
|
getCollectivePluginDir
|
|
36
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-HPGFY5ZN.js";
|
|
37
34
|
import {
|
|
38
35
|
loadProjectConfig as loadProjectConfig2
|
|
39
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-VFHWU7JU.js";
|
|
37
|
+
import {
|
|
38
|
+
saveSourceToProjectConfig
|
|
39
|
+
} from "../chunk-NAGU7TVZ.js";
|
|
40
40
|
import {
|
|
41
41
|
copySkillsToLocalFlattened
|
|
42
|
-
} from "../chunk-
|
|
43
|
-
import "../chunk-
|
|
42
|
+
} from "../chunk-KH3HA7J7.js";
|
|
43
|
+
import "../chunk-INJ2EFRW.js";
|
|
44
|
+
import "../chunk-IOBFMF6X.js";
|
|
44
45
|
import {
|
|
45
46
|
loadSkillsMatrixFromSource
|
|
46
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-PLZOUVDD.js";
|
|
47
48
|
import {
|
|
48
|
-
loadAllAgents,
|
|
49
49
|
loadStackById
|
|
50
|
-
} from "../chunk-
|
|
51
|
-
import "../chunk-
|
|
50
|
+
} from "../chunk-CKPQHGXR.js";
|
|
51
|
+
import "../chunk-CA4LH4LI.js";
|
|
52
|
+
import {
|
|
53
|
+
loadAllAgents
|
|
54
|
+
} from "../chunk-BQX23RBV.js";
|
|
52
55
|
import {
|
|
53
56
|
BaseCommand,
|
|
54
57
|
EXIT_CODES
|
|
@@ -56,10 +59,10 @@ import {
|
|
|
56
59
|
import {
|
|
57
60
|
formatSourceOrigin,
|
|
58
61
|
loadProjectConfig
|
|
59
|
-
} from "../chunk-
|
|
62
|
+
} from "../chunk-374JNMR6.js";
|
|
60
63
|
import {
|
|
61
64
|
verbose
|
|
62
|
-
} from "../chunk-
|
|
65
|
+
} from "../chunk-T25OEQFI.js";
|
|
63
66
|
import {
|
|
64
67
|
directoryExists,
|
|
65
68
|
ensureDir,
|
|
@@ -67,13 +70,13 @@ import {
|
|
|
67
70
|
readFile,
|
|
68
71
|
remove,
|
|
69
72
|
writeFile
|
|
70
|
-
} from "../chunk-
|
|
73
|
+
} from "../chunk-AL74GBW4.js";
|
|
71
74
|
import {
|
|
72
75
|
CLAUDE_DIR,
|
|
73
76
|
CLAUDE_SRC_DIR,
|
|
74
77
|
LOCAL_SKILLS_PATH,
|
|
75
78
|
PROJECT_ROOT
|
|
76
|
-
} from "../chunk-
|
|
79
|
+
} from "../chunk-FJFEKPXF.js";
|
|
77
80
|
import {
|
|
78
81
|
init_esm_shims
|
|
79
82
|
} from "../chunk-DHET7RCE.js";
|
|
@@ -82,146 +85,97 @@ import {
|
|
|
82
85
|
init_esm_shims();
|
|
83
86
|
import { Flags } from "@oclif/core";
|
|
84
87
|
import { render } from "ink";
|
|
85
|
-
import
|
|
86
|
-
import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
|
|
88
|
+
import path4 from "path";
|
|
87
89
|
|
|
88
|
-
// src/cli/lib/
|
|
90
|
+
// src/cli/lib/local-installer.ts
|
|
89
91
|
init_esm_shims();
|
|
90
92
|
import path from "path";
|
|
91
|
-
import {
|
|
92
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
93
|
-
async function checkPermissions(projectRoot) {
|
|
94
|
-
const settingsPath = path.join(projectRoot, ".claude", "settings.json");
|
|
95
|
-
const localSettingsPath = path.join(
|
|
96
|
-
projectRoot,
|
|
97
|
-
".claude",
|
|
98
|
-
"settings.local.json"
|
|
99
|
-
);
|
|
100
|
-
let permissions;
|
|
101
|
-
for (const filePath of [localSettingsPath, settingsPath]) {
|
|
102
|
-
if (await fileExists(filePath)) {
|
|
103
|
-
try {
|
|
104
|
-
const content = await readFile(filePath);
|
|
105
|
-
const parsed = JSON.parse(content);
|
|
106
|
-
if (parsed.permissions) {
|
|
107
|
-
permissions = parsed.permissions;
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
} catch {
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (!permissions) {
|
|
115
|
-
return /* @__PURE__ */ jsxs(
|
|
116
|
-
Box,
|
|
117
|
-
{
|
|
118
|
-
flexDirection: "column",
|
|
119
|
-
borderStyle: "round",
|
|
120
|
-
borderColor: "yellow",
|
|
121
|
-
padding: 1,
|
|
122
|
-
children: [
|
|
123
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Notice" }),
|
|
124
|
-
/* @__PURE__ */ jsx(Text, { children: "No permissions configured in .claude/settings.json" }),
|
|
125
|
-
/* @__PURE__ */ jsx(Text, { children: "Agents will prompt for approval on each tool use." }),
|
|
126
|
-
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
127
|
-
/* @__PURE__ */ jsx(Text, { children: "For autonomous operation, add to .claude/settings.json:" }),
|
|
128
|
-
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
129
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: "{" }),
|
|
130
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "permissions": {' }),
|
|
131
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "allow": [' }),
|
|
132
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Read(*)",' }),
|
|
133
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(git *)",' }),
|
|
134
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(bun *)"' }),
|
|
135
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: " ]" }),
|
|
136
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: " }" }),
|
|
137
|
-
/* @__PURE__ */ jsx(Text, { color: "dim", children: "}" })
|
|
138
|
-
]
|
|
139
|
-
}
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
const hasRestrictiveBash = permissions.deny?.some(
|
|
143
|
-
(rule) => rule === "Bash(*)" || rule === "Bash"
|
|
144
|
-
);
|
|
145
|
-
const hasNoAllows = !permissions.allow || permissions.allow.length === 0;
|
|
146
|
-
if (hasRestrictiveBash || hasNoAllows) {
|
|
147
|
-
return /* @__PURE__ */ jsxs(
|
|
148
|
-
Box,
|
|
149
|
-
{
|
|
150
|
-
flexDirection: "column",
|
|
151
|
-
borderStyle: "round",
|
|
152
|
-
borderColor: "yellow",
|
|
153
|
-
padding: 1,
|
|
154
|
-
children: [
|
|
155
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Warnings" }),
|
|
156
|
-
hasRestrictiveBash && /* @__PURE__ */ jsx(Text, { children: "\u26A0 Bash is denied in permissions. Some agents require Bash for git, testing, and build commands." }),
|
|
157
|
-
hasNoAllows && /* @__PURE__ */ jsx(Text, { children: "\u26A0 No allow rules configured. Agents will prompt for each tool use." })
|
|
158
|
-
]
|
|
159
|
-
}
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
93
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
164
94
|
|
|
165
|
-
// src/cli/lib/
|
|
95
|
+
// src/cli/lib/config-merger.ts
|
|
166
96
|
init_esm_shims();
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
97
|
+
async function mergeWithExistingConfig(newConfig, context) {
|
|
98
|
+
const localConfig = { ...newConfig };
|
|
99
|
+
const existingFullConfig = await loadProjectConfig2(context.projectDir);
|
|
100
|
+
if (existingFullConfig) {
|
|
101
|
+
const existingConfig = existingFullConfig.config;
|
|
102
|
+
if (existingConfig.name) {
|
|
103
|
+
localConfig.name = existingConfig.name;
|
|
104
|
+
}
|
|
105
|
+
if (existingConfig.description) {
|
|
106
|
+
localConfig.description = existingConfig.description;
|
|
107
|
+
}
|
|
108
|
+
if (existingConfig.source) {
|
|
109
|
+
localConfig.source = existingConfig.source;
|
|
110
|
+
}
|
|
111
|
+
if (existingConfig.skills && existingConfig.skills.length > 0) {
|
|
112
|
+
const existingSkillIds = new Set(
|
|
113
|
+
existingConfig.skills.map((s) => typeof s === "string" ? s : s.id)
|
|
114
|
+
);
|
|
115
|
+
const newSkillIds = localConfig.skills?.filter(
|
|
116
|
+
(s) => !existingSkillIds.has(typeof s === "string" ? s : s.id)
|
|
117
|
+
) || [];
|
|
118
|
+
localConfig.skills = [...existingConfig.skills, ...newSkillIds];
|
|
119
|
+
}
|
|
120
|
+
if (existingConfig.agents && existingConfig.agents.length > 0) {
|
|
121
|
+
const existingAgentIds = new Set(existingConfig.agents);
|
|
122
|
+
const newAgentIds = localConfig.agents.filter((a) => !existingAgentIds.has(a));
|
|
123
|
+
localConfig.agents = [...existingConfig.agents, ...newAgentIds];
|
|
124
|
+
}
|
|
125
|
+
if (existingConfig.stack) {
|
|
126
|
+
const mergedStack = { ...localConfig.stack };
|
|
127
|
+
for (const [agentId, agentConfig] of Object.entries(existingConfig.stack)) {
|
|
128
|
+
mergedStack[agentId] = { ...mergedStack[agentId], ...agentConfig };
|
|
129
|
+
}
|
|
130
|
+
localConfig.stack = mergedStack;
|
|
131
|
+
}
|
|
132
|
+
if (existingConfig.author) {
|
|
133
|
+
localConfig.author = existingConfig.author;
|
|
134
|
+
}
|
|
135
|
+
if (existingConfig.agents_source) {
|
|
136
|
+
localConfig.agents_source = existingConfig.agents_source;
|
|
137
|
+
}
|
|
138
|
+
if (existingConfig.marketplace) {
|
|
139
|
+
localConfig.marketplace = existingConfig.marketplace;
|
|
140
|
+
}
|
|
141
|
+
if (existingConfig.philosophy) {
|
|
142
|
+
localConfig.philosophy = existingConfig.philosophy;
|
|
143
|
+
}
|
|
144
|
+
if (existingConfig.framework) {
|
|
145
|
+
localConfig.framework = existingConfig.framework;
|
|
146
|
+
}
|
|
147
|
+
if (existingConfig.principles) {
|
|
148
|
+
localConfig.principles = existingConfig.principles;
|
|
149
|
+
}
|
|
150
|
+
if (existingConfig.tags) {
|
|
151
|
+
localConfig.tags = existingConfig.tags;
|
|
152
|
+
}
|
|
153
|
+
if (existingConfig.agent_skills) {
|
|
154
|
+
localConfig.agent_skills = existingConfig.agent_skills;
|
|
155
|
+
}
|
|
156
|
+
if (existingConfig.preload_patterns) {
|
|
157
|
+
localConfig.preload_patterns = existingConfig.preload_patterns;
|
|
158
|
+
}
|
|
159
|
+
if (existingConfig.custom_agents) {
|
|
160
|
+
localConfig.custom_agents = existingConfig.custom_agents;
|
|
161
|
+
}
|
|
162
|
+
if (existingConfig.hooks) {
|
|
163
|
+
localConfig.hooks = existingConfig.hooks;
|
|
182
164
|
}
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
async function installStackAsPlugin(options) {
|
|
186
|
-
const { stackId, projectDir, sourcePath, agentSourcePath, marketplace } = options;
|
|
187
|
-
const claudeAvailable = await isClaudeCLIAvailable();
|
|
188
|
-
if (!claudeAvailable) {
|
|
189
|
-
throw new Error(
|
|
190
|
-
"Claude CLI not found. Please install Claude Code first: https://claude.ai/code"
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
if (marketplace) {
|
|
194
|
-
verbose(`Installing from marketplace: ${stackId}@${marketplace}`);
|
|
195
|
-
const pluginRef = `${stackId}@${marketplace}`;
|
|
196
|
-
await claudePluginInstall(pluginRef, "project", projectDir);
|
|
197
165
|
return {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
skills: [],
|
|
202
|
-
pluginPath: pluginRef,
|
|
203
|
-
fromMarketplace: true
|
|
166
|
+
config: localConfig,
|
|
167
|
+
merged: true,
|
|
168
|
+
existingConfigPath: existingFullConfig.configPath
|
|
204
169
|
};
|
|
205
170
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
try {
|
|
213
|
-
await claudePluginInstall(result.pluginPath, "project", projectDir);
|
|
214
|
-
return {
|
|
215
|
-
pluginName: `stack-${stackId}`,
|
|
216
|
-
stackName: result.stackName,
|
|
217
|
-
agents: result.agents,
|
|
218
|
-
skills: result.skillPlugins,
|
|
219
|
-
pluginPath: result.pluginPath,
|
|
220
|
-
fromMarketplace: false
|
|
221
|
-
};
|
|
222
|
-
} finally {
|
|
223
|
-
await cleanup();
|
|
171
|
+
const existingProjectConfig = await loadProjectConfig(context.projectDir);
|
|
172
|
+
if (existingProjectConfig?.author) {
|
|
173
|
+
localConfig.author = existingProjectConfig.author;
|
|
174
|
+
}
|
|
175
|
+
if (existingProjectConfig?.agents_source) {
|
|
176
|
+
localConfig.agents_source = existingProjectConfig.agents_source;
|
|
224
177
|
}
|
|
178
|
+
return { config: localConfig, merged: false };
|
|
225
179
|
}
|
|
226
180
|
|
|
227
181
|
// src/cli/lib/config-generator.ts
|
|
@@ -240,7 +194,7 @@ function getCachedDefaults() {
|
|
|
240
194
|
|
|
241
195
|
// src/cli/lib/skill-agent-mappings.ts
|
|
242
196
|
var SKILL_TO_AGENTS = {
|
|
243
|
-
"
|
|
197
|
+
"web/*": [
|
|
244
198
|
"web-developer",
|
|
245
199
|
"web-reviewer",
|
|
246
200
|
"web-researcher",
|
|
@@ -251,7 +205,7 @@ var SKILL_TO_AGENTS = {
|
|
|
251
205
|
"skill-summoner",
|
|
252
206
|
"documentor"
|
|
253
207
|
],
|
|
254
|
-
"
|
|
208
|
+
"api/*": [
|
|
255
209
|
"api-developer",
|
|
256
210
|
"api-reviewer",
|
|
257
211
|
"api-researcher",
|
|
@@ -272,7 +226,7 @@ var SKILL_TO_AGENTS = {
|
|
|
272
226
|
"skill-summoner",
|
|
273
227
|
"documentor"
|
|
274
228
|
],
|
|
275
|
-
"
|
|
229
|
+
"infra/*": [
|
|
276
230
|
"web-architecture",
|
|
277
231
|
"web-developer",
|
|
278
232
|
"api-developer",
|
|
@@ -338,9 +292,9 @@ var SKILL_TO_AGENTS = {
|
|
|
338
292
|
"skill-summoner",
|
|
339
293
|
"documentor"
|
|
340
294
|
],
|
|
341
|
-
"
|
|
342
|
-
"
|
|
343
|
-
"
|
|
295
|
+
"web/testing": ["web-tester", "web-developer", "web-reviewer"],
|
|
296
|
+
"api/testing": ["web-tester", "api-developer", "api-reviewer"],
|
|
297
|
+
"web/mocks": ["web-tester", "web-developer", "web-reviewer"]
|
|
344
298
|
};
|
|
345
299
|
var PRELOADED_SKILLS = {
|
|
346
300
|
"web-developer": ["framework", "styling"],
|
|
@@ -361,15 +315,15 @@ var PRELOADED_SKILLS = {
|
|
|
361
315
|
"skill-summoner": []
|
|
362
316
|
};
|
|
363
317
|
var SUBCATEGORY_ALIASES = {
|
|
364
|
-
framework: "
|
|
365
|
-
styling: "
|
|
366
|
-
api: "
|
|
367
|
-
database: "
|
|
368
|
-
mocks: "
|
|
318
|
+
framework: "web/framework",
|
|
319
|
+
styling: "web/styling",
|
|
320
|
+
api: "api/api",
|
|
321
|
+
database: "api/database",
|
|
322
|
+
mocks: "web/mocks",
|
|
369
323
|
testing: "testing",
|
|
370
324
|
reviewing: "reviewing",
|
|
371
325
|
"research-methodology": "research/research-methodology",
|
|
372
|
-
monorepo: "
|
|
326
|
+
monorepo: "infra/monorepo",
|
|
373
327
|
cli: "cli"
|
|
374
328
|
};
|
|
375
329
|
var DEFAULT_AGENTS = ["agent-summoner", "skill-summoner", "documentor"];
|
|
@@ -487,11 +441,7 @@ function generateProjectConfigFromSkills(name, selectedSkillIds, matrix, options
|
|
|
487
441
|
config.author = options.author;
|
|
488
442
|
}
|
|
489
443
|
if (options?.includeAgentSkills) {
|
|
490
|
-
const agentSkills = buildAgentSkills(
|
|
491
|
-
selectedSkillIds,
|
|
492
|
-
matrix,
|
|
493
|
-
neededAgents
|
|
494
|
-
);
|
|
444
|
+
const agentSkills = buildAgentSkills(selectedSkillIds, matrix, neededAgents);
|
|
495
445
|
if (Object.keys(agentSkills).length > 0) {
|
|
496
446
|
config.agent_skills = agentSkills;
|
|
497
447
|
}
|
|
@@ -513,12 +463,7 @@ function buildAgentSkills(selectedSkillIds, matrix, neededAgents) {
|
|
|
513
463
|
if (!agentSkills[agentId]) {
|
|
514
464
|
agentSkills[agentId] = [];
|
|
515
465
|
}
|
|
516
|
-
const isPreloaded = shouldPreloadSkill(
|
|
517
|
-
skillPath,
|
|
518
|
-
skillId,
|
|
519
|
-
category,
|
|
520
|
-
agentId
|
|
521
|
-
);
|
|
466
|
+
const isPreloaded = shouldPreloadSkill(skillPath, skillId, category, agentId);
|
|
522
467
|
if (isPreloaded) {
|
|
523
468
|
agentSkills[agentId].push({ id: skillId, preloaded: true });
|
|
524
469
|
} else {
|
|
@@ -535,9 +480,7 @@ function buildStackProperty(stack, skillAliases) {
|
|
|
535
480
|
continue;
|
|
536
481
|
}
|
|
537
482
|
const resolvedMappings = {};
|
|
538
|
-
for (const [subcategoryId, alias] of Object.entries(
|
|
539
|
-
agentConfig
|
|
540
|
-
)) {
|
|
483
|
+
for (const [subcategoryId, alias] of Object.entries(agentConfig)) {
|
|
541
484
|
const skillId = skillAliases[alias];
|
|
542
485
|
if (skillId) {
|
|
543
486
|
resolvedMappings[subcategoryId] = skillId;
|
|
@@ -552,9 +495,291 @@ function buildStackProperty(stack, skillAliases) {
|
|
|
552
495
|
return result;
|
|
553
496
|
}
|
|
554
497
|
|
|
498
|
+
// src/cli/lib/local-installer.ts
|
|
499
|
+
var PLUGIN_NAME = "claude-collective";
|
|
500
|
+
var YAML_INDENT = 2;
|
|
501
|
+
var YAML_LINE_WIDTH = 120;
|
|
502
|
+
function buildLocalSkillsMap(copiedSkills, matrix) {
|
|
503
|
+
const localSkillsForResolution = {};
|
|
504
|
+
for (const copiedSkill of copiedSkills) {
|
|
505
|
+
const skill = matrix.skills[copiedSkill.skillId];
|
|
506
|
+
if (skill) {
|
|
507
|
+
localSkillsForResolution[copiedSkill.skillId] = {
|
|
508
|
+
id: copiedSkill.skillId,
|
|
509
|
+
name: skill.name,
|
|
510
|
+
description: skill.description || "",
|
|
511
|
+
canonicalId: copiedSkill.skillId,
|
|
512
|
+
path: copiedSkill.destPath,
|
|
513
|
+
content: ""
|
|
514
|
+
// Content not needed for skill references
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return localSkillsForResolution;
|
|
519
|
+
}
|
|
520
|
+
async function buildLocalConfig(wizardResult, sourceResult, skillAliases) {
|
|
521
|
+
const loadedStack = wizardResult.selectedStackId ? await loadStackById(wizardResult.selectedStackId, PROJECT_ROOT) : null;
|
|
522
|
+
let localConfig;
|
|
523
|
+
if (wizardResult.selectedStackId) {
|
|
524
|
+
if (loadedStack) {
|
|
525
|
+
const agentIds = Object.keys(loadedStack.agents);
|
|
526
|
+
const stackProperty = buildStackProperty(loadedStack, skillAliases);
|
|
527
|
+
localConfig = {
|
|
528
|
+
name: PLUGIN_NAME,
|
|
529
|
+
installMode: wizardResult.installMode,
|
|
530
|
+
description: loadedStack.description,
|
|
531
|
+
skills: wizardResult.selectedSkills.map((id) => id),
|
|
532
|
+
agents: agentIds,
|
|
533
|
+
philosophy: loadedStack.philosophy,
|
|
534
|
+
stack: stackProperty
|
|
535
|
+
};
|
|
536
|
+
} else {
|
|
537
|
+
throw new Error(
|
|
538
|
+
`Stack '${wizardResult.selectedStackId}' not found in config/stacks.yaml. Available stacks are defined in the CLI's config/stacks.yaml file.`
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
} else {
|
|
542
|
+
localConfig = generateProjectConfigFromSkills(
|
|
543
|
+
PLUGIN_NAME,
|
|
544
|
+
wizardResult.selectedSkills,
|
|
545
|
+
sourceResult.matrix
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
return { config: localConfig, loadedStack };
|
|
549
|
+
}
|
|
550
|
+
function setConfigMetadata(config, wizardResult, sourceResult, sourceFlag) {
|
|
551
|
+
config.installMode = wizardResult.installMode;
|
|
552
|
+
if (sourceFlag) {
|
|
553
|
+
config.source = sourceFlag;
|
|
554
|
+
} else if (sourceResult.sourceConfig.source) {
|
|
555
|
+
config.source = sourceResult.sourceConfig.source;
|
|
556
|
+
}
|
|
557
|
+
if (sourceResult.marketplace) {
|
|
558
|
+
config.marketplace = sourceResult.marketplace;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
function buildCompileAgents(config, agents, loadedStack, skillAliases, localSkills) {
|
|
562
|
+
const compileAgents = {};
|
|
563
|
+
for (const agentId of config.agents) {
|
|
564
|
+
if (agents[agentId]) {
|
|
565
|
+
if (loadedStack) {
|
|
566
|
+
const skillRefs = resolveAgentSkillsFromStack(agentId, loadedStack, skillAliases);
|
|
567
|
+
compileAgents[agentId] = { skills: skillRefs };
|
|
568
|
+
} else if (config.agent_skills?.[agentId]) {
|
|
569
|
+
const skillRefs = resolveStackSkills(config, agentId, localSkills);
|
|
570
|
+
compileAgents[agentId] = { skills: skillRefs };
|
|
571
|
+
} else {
|
|
572
|
+
compileAgents[agentId] = {};
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return compileAgents;
|
|
577
|
+
}
|
|
578
|
+
async function compileAndWriteAgents(compileConfig, agents, localSkills, sourceResult, loadedStack, skillAliases, projectDir, agentsDir) {
|
|
579
|
+
const engine = await createLiquidEngine(projectDir);
|
|
580
|
+
const resolvedAgents = await resolveAgents(
|
|
581
|
+
agents,
|
|
582
|
+
localSkills,
|
|
583
|
+
compileConfig,
|
|
584
|
+
sourceResult.sourcePath,
|
|
585
|
+
loadedStack ?? void 0,
|
|
586
|
+
skillAliases
|
|
587
|
+
);
|
|
588
|
+
const compiledAgentNames = [];
|
|
589
|
+
for (const [name, agent] of Object.entries(resolvedAgents)) {
|
|
590
|
+
const output = await compileAgentForPlugin(name, agent, sourceResult.sourcePath, engine);
|
|
591
|
+
await writeFile(path.join(agentsDir, `${name}.md`), output);
|
|
592
|
+
compiledAgentNames.push(name);
|
|
593
|
+
}
|
|
594
|
+
return compiledAgentNames;
|
|
595
|
+
}
|
|
596
|
+
async function installLocal(options) {
|
|
597
|
+
const { wizardResult, sourceResult, projectDir, sourceFlag } = options;
|
|
598
|
+
const matrix = sourceResult.matrix;
|
|
599
|
+
const localSkillsDir = path.join(projectDir, LOCAL_SKILLS_PATH);
|
|
600
|
+
const localAgentsDir = path.join(projectDir, CLAUDE_DIR, "agents");
|
|
601
|
+
const localConfigPath = path.join(projectDir, CLAUDE_SRC_DIR, "config.yaml");
|
|
602
|
+
await ensureDir(localSkillsDir);
|
|
603
|
+
await ensureDir(localAgentsDir);
|
|
604
|
+
await ensureDir(path.dirname(localConfigPath));
|
|
605
|
+
const copiedSkills = await copySkillsToLocalFlattened(
|
|
606
|
+
wizardResult.selectedSkills,
|
|
607
|
+
localSkillsDir,
|
|
608
|
+
matrix,
|
|
609
|
+
sourceResult
|
|
610
|
+
);
|
|
611
|
+
const localSkillsForResolution = buildLocalSkillsMap(copiedSkills, matrix);
|
|
612
|
+
const skillAliases = matrix.aliases || {};
|
|
613
|
+
const cliAgents = await loadAllAgents(PROJECT_ROOT);
|
|
614
|
+
const localAgents = await loadAllAgents(sourceResult.sourcePath);
|
|
615
|
+
const agents = { ...cliAgents, ...localAgents };
|
|
616
|
+
const { config: builtConfig, loadedStack } = await buildLocalConfig(
|
|
617
|
+
wizardResult,
|
|
618
|
+
sourceResult,
|
|
619
|
+
skillAliases
|
|
620
|
+
);
|
|
621
|
+
setConfigMetadata(builtConfig, wizardResult, sourceResult, sourceFlag);
|
|
622
|
+
const mergeResult = await mergeWithExistingConfig(builtConfig, { projectDir });
|
|
623
|
+
const finalConfig = mergeResult.config;
|
|
624
|
+
const configYaml = stringifyYaml(finalConfig, {
|
|
625
|
+
indent: YAML_INDENT,
|
|
626
|
+
lineWidth: YAML_LINE_WIDTH
|
|
627
|
+
});
|
|
628
|
+
await writeFile(localConfigPath, configYaml);
|
|
629
|
+
const compileAgentsConfig = buildCompileAgents(
|
|
630
|
+
finalConfig,
|
|
631
|
+
agents,
|
|
632
|
+
loadedStack,
|
|
633
|
+
skillAliases,
|
|
634
|
+
localSkillsForResolution
|
|
635
|
+
);
|
|
636
|
+
const compileConfig = {
|
|
637
|
+
name: PLUGIN_NAME,
|
|
638
|
+
description: finalConfig.description || `Local setup with ${wizardResult.selectedSkills.length} skills`,
|
|
639
|
+
claude_md: "",
|
|
640
|
+
agents: compileAgentsConfig
|
|
641
|
+
};
|
|
642
|
+
const compiledAgentNames = await compileAndWriteAgents(
|
|
643
|
+
compileConfig,
|
|
644
|
+
agents,
|
|
645
|
+
localSkillsForResolution,
|
|
646
|
+
sourceResult,
|
|
647
|
+
loadedStack,
|
|
648
|
+
skillAliases,
|
|
649
|
+
projectDir,
|
|
650
|
+
localAgentsDir
|
|
651
|
+
);
|
|
652
|
+
return {
|
|
653
|
+
copiedSkills,
|
|
654
|
+
config: finalConfig,
|
|
655
|
+
configPath: localConfigPath,
|
|
656
|
+
compiledAgents: compiledAgentNames,
|
|
657
|
+
wasMerged: mergeResult.merged,
|
|
658
|
+
mergedConfigPath: mergeResult.existingConfigPath,
|
|
659
|
+
skillsDir: localSkillsDir,
|
|
660
|
+
agentsDir: localAgentsDir
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// src/cli/lib/permission-checker.tsx
|
|
665
|
+
init_esm_shims();
|
|
666
|
+
import path2 from "path";
|
|
667
|
+
import { Text, Box } from "ink";
|
|
668
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
669
|
+
async function checkPermissions(projectRoot) {
|
|
670
|
+
const settingsPath = path2.join(projectRoot, ".claude", "settings.json");
|
|
671
|
+
const localSettingsPath = path2.join(projectRoot, ".claude", "settings.local.json");
|
|
672
|
+
let permissions;
|
|
673
|
+
for (const filePath of [localSettingsPath, settingsPath]) {
|
|
674
|
+
if (await fileExists(filePath)) {
|
|
675
|
+
try {
|
|
676
|
+
const content = await readFile(filePath);
|
|
677
|
+
const parsed = JSON.parse(content);
|
|
678
|
+
if (parsed.permissions) {
|
|
679
|
+
permissions = parsed.permissions;
|
|
680
|
+
break;
|
|
681
|
+
}
|
|
682
|
+
} catch {
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (!permissions) {
|
|
687
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", padding: 1, children: [
|
|
688
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Notice" }),
|
|
689
|
+
/* @__PURE__ */ jsx(Text, { children: "No permissions configured in .claude/settings.json" }),
|
|
690
|
+
/* @__PURE__ */ jsx(Text, { children: "Agents will prompt for approval on each tool use." }),
|
|
691
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
692
|
+
/* @__PURE__ */ jsx(Text, { children: "For autonomous operation, add to .claude/settings.json:" }),
|
|
693
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
694
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: "{" }),
|
|
695
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "permissions": {' }),
|
|
696
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "allow": [' }),
|
|
697
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Read(*)",' }),
|
|
698
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(git *)",' }),
|
|
699
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: ' "Bash(bun *)"' }),
|
|
700
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: " ]" }),
|
|
701
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: " }" }),
|
|
702
|
+
/* @__PURE__ */ jsx(Text, { color: "dim", children: "}" })
|
|
703
|
+
] });
|
|
704
|
+
}
|
|
705
|
+
const hasRestrictiveBash = permissions.deny?.some(
|
|
706
|
+
(rule) => rule === "Bash(*)" || rule === "Bash"
|
|
707
|
+
);
|
|
708
|
+
const hasNoAllows = !permissions.allow || permissions.allow.length === 0;
|
|
709
|
+
if (hasRestrictiveBash || hasNoAllows) {
|
|
710
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", padding: 1, children: [
|
|
711
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Permission Warnings" }),
|
|
712
|
+
hasRestrictiveBash && /* @__PURE__ */ jsx(Text, { children: "\u26A0 Bash is denied in permissions. Some agents require Bash for git, testing, and build commands." }),
|
|
713
|
+
hasNoAllows && /* @__PURE__ */ jsx(Text, { children: "\u26A0 No allow rules configured. Agents will prompt for each tool use." })
|
|
714
|
+
] });
|
|
715
|
+
}
|
|
716
|
+
return null;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// src/cli/lib/stack-installer.ts
|
|
720
|
+
init_esm_shims();
|
|
721
|
+
import os from "os";
|
|
722
|
+
import path3 from "path";
|
|
723
|
+
async function compileStackToTemp(options) {
|
|
724
|
+
const tempDir = path3.join(os.tmpdir(), `cc-stack-${Date.now()}`);
|
|
725
|
+
await ensureDir(tempDir);
|
|
726
|
+
const result = await compileStackPlugin({
|
|
727
|
+
stackId: options.stackId,
|
|
728
|
+
outputDir: tempDir,
|
|
729
|
+
projectRoot: options.projectRoot,
|
|
730
|
+
agentSourcePath: options.agentSourcePath
|
|
731
|
+
});
|
|
732
|
+
return {
|
|
733
|
+
result,
|
|
734
|
+
cleanup: async () => {
|
|
735
|
+
await remove(tempDir);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
async function installStackAsPlugin(options) {
|
|
740
|
+
const { stackId, projectDir, sourcePath, agentSourcePath, marketplace } = options;
|
|
741
|
+
const claudeAvailable = await isClaudeCLIAvailable();
|
|
742
|
+
if (!claudeAvailable) {
|
|
743
|
+
throw new Error(
|
|
744
|
+
"Claude CLI not found. Please install Claude Code first: https://claude.ai/code"
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
if (marketplace) {
|
|
748
|
+
verbose(`Installing from marketplace: ${stackId}@${marketplace}`);
|
|
749
|
+
const pluginRef = `${stackId}@${marketplace}`;
|
|
750
|
+
await claudePluginInstall(pluginRef, "project", projectDir);
|
|
751
|
+
return {
|
|
752
|
+
pluginName: stackId,
|
|
753
|
+
stackName: stackId,
|
|
754
|
+
agents: [],
|
|
755
|
+
skills: [],
|
|
756
|
+
pluginPath: pluginRef,
|
|
757
|
+
fromMarketplace: true
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
verbose(`Compiling stack locally: ${stackId}`);
|
|
761
|
+
const { result, cleanup } = await compileStackToTemp({
|
|
762
|
+
stackId,
|
|
763
|
+
projectRoot: sourcePath,
|
|
764
|
+
agentSourcePath
|
|
765
|
+
});
|
|
766
|
+
try {
|
|
767
|
+
await claudePluginInstall(result.pluginPath, "project", projectDir);
|
|
768
|
+
return {
|
|
769
|
+
pluginName: `stack-${stackId}`,
|
|
770
|
+
stackName: result.stackName,
|
|
771
|
+
agents: result.agents,
|
|
772
|
+
skills: result.skillPlugins,
|
|
773
|
+
pluginPath: result.pluginPath,
|
|
774
|
+
fromMarketplace: false
|
|
775
|
+
};
|
|
776
|
+
} finally {
|
|
777
|
+
await cleanup();
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
555
781
|
// src/cli/commands/init.tsx
|
|
556
782
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
557
|
-
var PLUGIN_NAME = "claude-collective";
|
|
558
783
|
var Init = class _Init extends BaseCommand {
|
|
559
784
|
static summary = "Initialize Claude Collective in this project";
|
|
560
785
|
static description = "Interactive wizard to set up skills and agents. Supports Plugin Mode (native install) and Local Mode (copy to .claude/).";
|
|
@@ -568,7 +793,16 @@ var Init = class _Init extends BaseCommand {
|
|
|
568
793
|
async run() {
|
|
569
794
|
const { flags } = await this.parse(_Init);
|
|
570
795
|
const projectDir = process.cwd();
|
|
571
|
-
this.log(
|
|
796
|
+
this.log(
|
|
797
|
+
`
|
|
798
|
+
\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
799
|
+
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
|
|
800
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551
|
|
801
|
+
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551
|
|
802
|
+
\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
803
|
+
\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D
|
|
804
|
+
`
|
|
805
|
+
);
|
|
572
806
|
if (flags["dry-run"]) {
|
|
573
807
|
this.log("[dry-run] Preview mode - no files will be created\n");
|
|
574
808
|
}
|
|
@@ -580,7 +814,6 @@ var Init = class _Init extends BaseCommand {
|
|
|
580
814
|
this.log("No changes made.");
|
|
581
815
|
return;
|
|
582
816
|
}
|
|
583
|
-
this.log("Loading skills matrix...");
|
|
584
817
|
let sourceResult;
|
|
585
818
|
try {
|
|
586
819
|
sourceResult = await loadSkillsMatrixFromSource({
|
|
@@ -589,15 +822,10 @@ var Init = class _Init extends BaseCommand {
|
|
|
589
822
|
forceRefresh: flags.refresh
|
|
590
823
|
});
|
|
591
824
|
const sourceInfo = sourceResult.isLocal ? "local" : formatSourceOrigin(sourceResult.sourceConfig.sourceOrigin);
|
|
592
|
-
this.log(
|
|
593
|
-
`Loaded ${Object.keys(sourceResult.matrix.skills).length} skills (${sourceInfo})
|
|
594
|
-
`
|
|
595
|
-
);
|
|
596
825
|
} catch (error) {
|
|
597
|
-
this.error(
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
);
|
|
826
|
+
this.error(error instanceof Error ? error.message : "Unknown error occurred", {
|
|
827
|
+
exit: EXIT_CODES.ERROR
|
|
828
|
+
});
|
|
601
829
|
}
|
|
602
830
|
let wizardResult = null;
|
|
603
831
|
const { waitUntilExit } = render(
|
|
@@ -637,7 +865,6 @@ var Init = class _Init extends BaseCommand {
|
|
|
637
865
|
this.log(
|
|
638
866
|
`Install mode: ${result.installMode === "plugin" ? "Plugin (native install)" : "Local (copy to .claude/skills/)"}`
|
|
639
867
|
);
|
|
640
|
-
this.log("\n");
|
|
641
868
|
if (dryRun) {
|
|
642
869
|
if (result.installMode === "plugin" && result.selectedStackId) {
|
|
643
870
|
const useMarketplace = !!sourceResult.marketplace;
|
|
@@ -661,13 +888,11 @@ var Init = class _Init extends BaseCommand {
|
|
|
661
888
|
}
|
|
662
889
|
} else {
|
|
663
890
|
if (result.installMode === "plugin") {
|
|
664
|
-
this.log(
|
|
665
|
-
`[dry-run] Individual skill plugin installation not yet supported`
|
|
666
|
-
);
|
|
891
|
+
this.log(`[dry-run] Individual skill plugin installation not yet supported`);
|
|
667
892
|
this.log(`[dry-run] Would fall back to Local Mode...`);
|
|
668
893
|
}
|
|
669
|
-
const localSkillsDir =
|
|
670
|
-
const localAgentsDir =
|
|
894
|
+
const localSkillsDir = path4.join(projectDir, LOCAL_SKILLS_PATH);
|
|
895
|
+
const localAgentsDir = path4.join(projectDir, CLAUDE_DIR, "agents");
|
|
671
896
|
this.log(
|
|
672
897
|
`[dry-run] Would copy ${result.selectedSkills.length} skills to ${localSkillsDir}`
|
|
673
898
|
);
|
|
@@ -682,13 +907,9 @@ var Init = class _Init extends BaseCommand {
|
|
|
682
907
|
await this.installPluginMode(result, sourceResult, flags);
|
|
683
908
|
return;
|
|
684
909
|
} else {
|
|
685
|
-
this.warn(
|
|
686
|
-
"Individual skill plugin installation not yet supported in Plugin Mode."
|
|
687
|
-
);
|
|
910
|
+
this.warn("Individual skill plugin installation not yet supported in Plugin Mode.");
|
|
688
911
|
this.log(`Falling back to Local Mode (copying to .claude/skills/)...`);
|
|
689
|
-
this.log(
|
|
690
|
-
"To use Plugin Mode, select a pre-built stack instead of individual skills.\n"
|
|
691
|
-
);
|
|
912
|
+
this.log("To use Plugin Mode, select a pre-built stack instead of individual skills.\n");
|
|
692
913
|
}
|
|
693
914
|
}
|
|
694
915
|
await this.installLocalMode(result, sourceResult, flags);
|
|
@@ -702,9 +923,7 @@ var Init = class _Init extends BaseCommand {
|
|
|
702
923
|
}
|
|
703
924
|
const projectDir = process.cwd();
|
|
704
925
|
if (sourceResult.marketplace) {
|
|
705
|
-
const marketplaceExists = await claudePluginMarketplaceExists(
|
|
706
|
-
sourceResult.marketplace
|
|
707
|
-
);
|
|
926
|
+
const marketplaceExists = await claudePluginMarketplaceExists(sourceResult.marketplace);
|
|
708
927
|
if (!marketplaceExists) {
|
|
709
928
|
this.log(`Registering marketplace "${sourceResult.marketplace}"...`);
|
|
710
929
|
try {
|
|
@@ -731,10 +950,8 @@ var Init = class _Init extends BaseCommand {
|
|
|
731
950
|
marketplace: sourceResult.marketplace
|
|
732
951
|
});
|
|
733
952
|
const installedFrom = installResult.fromMarketplace ? `from marketplace` : `(compiled locally)`;
|
|
734
|
-
this.log(
|
|
735
|
-
|
|
736
|
-
`
|
|
737
|
-
);
|
|
953
|
+
this.log(`Installed stack plugin: ${installResult.pluginName} ${installedFrom}
|
|
954
|
+
`);
|
|
738
955
|
this.log("Claude Collective initialized successfully!\n");
|
|
739
956
|
this.log(`Stack "${installResult.stackName}" installed as plugin`);
|
|
740
957
|
if (installResult.agents.length > 0) {
|
|
@@ -747,7 +964,8 @@ Skills bundled: ${installResult.skills.length}`);
|
|
|
747
964
|
}
|
|
748
965
|
this.log("");
|
|
749
966
|
if (flags.source) {
|
|
750
|
-
await
|
|
967
|
+
await saveSourceToProjectConfig(projectDir, flags.source);
|
|
968
|
+
this.log(`Source saved to .claude-src/config.yaml`);
|
|
751
969
|
}
|
|
752
970
|
const permissionWarning = await checkPermissions(projectDir);
|
|
753
971
|
if (permissionWarning) {
|
|
@@ -760,265 +978,48 @@ Skills bundled: ${installResult.skills.length}`);
|
|
|
760
978
|
});
|
|
761
979
|
}
|
|
762
980
|
}
|
|
763
|
-
/**
|
|
764
|
-
* Save source to project-level .claude-src/config.yaml.
|
|
765
|
-
*/
|
|
766
|
-
async saveSourceToProjectConfig(projectDir, source) {
|
|
767
|
-
const configPath = path3.join(projectDir, CLAUDE_SRC_DIR, "config.yaml");
|
|
768
|
-
let config = {};
|
|
769
|
-
if (await fileExists(configPath)) {
|
|
770
|
-
const content = await readFile(configPath);
|
|
771
|
-
config = parseYaml2(content) || {};
|
|
772
|
-
}
|
|
773
|
-
config.source = source;
|
|
774
|
-
await ensureDir(path3.join(projectDir, CLAUDE_SRC_DIR));
|
|
775
|
-
const configYaml = stringifyYaml(config, { indent: 2 });
|
|
776
|
-
await writeFile(configPath, configYaml);
|
|
777
|
-
this.log(`Source saved to .claude-src/config.yaml`);
|
|
778
|
-
}
|
|
779
981
|
/**
|
|
780
982
|
* Install in Local Mode: copy skills and compile agents to .claude/.
|
|
781
983
|
*/
|
|
782
984
|
async installLocalMode(result, sourceResult, flags) {
|
|
783
985
|
const projectDir = process.cwd();
|
|
784
986
|
const matrix = sourceResult.matrix;
|
|
785
|
-
const localSkillsDir = path3.join(projectDir, LOCAL_SKILLS_PATH);
|
|
786
|
-
const localAgentsDir = path3.join(projectDir, CLAUDE_DIR, "agents");
|
|
787
|
-
const localConfigPath = path3.join(
|
|
788
|
-
projectDir,
|
|
789
|
-
CLAUDE_SRC_DIR,
|
|
790
|
-
"config.yaml"
|
|
791
|
-
);
|
|
792
987
|
this.log("Copying skills to local directory...");
|
|
793
988
|
try {
|
|
794
|
-
await
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
sourceResult
|
|
802
|
-
);
|
|
803
|
-
this.log(`Copied ${copiedSkills.length} skills to .claude/skills/
|
|
989
|
+
const installResult = await installLocal({
|
|
990
|
+
wizardResult: result,
|
|
991
|
+
sourceResult,
|
|
992
|
+
projectDir,
|
|
993
|
+
sourceFlag: flags.source
|
|
994
|
+
});
|
|
995
|
+
this.log(`Copied ${installResult.copiedSkills.length} skills to .claude/skills/
|
|
804
996
|
`);
|
|
805
997
|
this.log("Generating configuration...");
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
const agents = { ...cliAgents, ...localAgents };
|
|
809
|
-
const localSkillsForResolution = {};
|
|
810
|
-
for (const copiedSkill of copiedSkills) {
|
|
811
|
-
const skill = matrix.skills[copiedSkill.skillId];
|
|
812
|
-
if (skill) {
|
|
813
|
-
localSkillsForResolution[copiedSkill.skillId] = {
|
|
814
|
-
id: copiedSkill.skillId,
|
|
815
|
-
name: skill.name,
|
|
816
|
-
description: skill.description || "",
|
|
817
|
-
canonicalId: copiedSkill.skillId,
|
|
818
|
-
path: copiedSkill.destPath,
|
|
819
|
-
content: ""
|
|
820
|
-
// Content not needed for skill references
|
|
821
|
-
};
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
const skillAliases = matrix.aliases || {};
|
|
825
|
-
let localConfig;
|
|
826
|
-
const loadedStack = result.selectedStackId ? await loadStackById(result.selectedStackId, PROJECT_ROOT) : null;
|
|
827
|
-
if (result.selectedStackId) {
|
|
828
|
-
if (loadedStack) {
|
|
829
|
-
const agentIds = Object.keys(loadedStack.agents);
|
|
830
|
-
const stackProperty = buildStackProperty(loadedStack, skillAliases);
|
|
831
|
-
localConfig = {
|
|
832
|
-
name: PLUGIN_NAME,
|
|
833
|
-
installMode: result.installMode,
|
|
834
|
-
description: loadedStack.description,
|
|
835
|
-
skills: result.selectedSkills.map((id) => id),
|
|
836
|
-
agents: agentIds,
|
|
837
|
-
philosophy: loadedStack.philosophy,
|
|
838
|
-
stack: stackProperty
|
|
839
|
-
};
|
|
840
|
-
} else {
|
|
841
|
-
throw new Error(
|
|
842
|
-
`Stack '${result.selectedStackId}' not found in config/stacks.yaml. Available stacks are defined in the CLI's config/stacks.yaml file.`
|
|
843
|
-
);
|
|
844
|
-
}
|
|
845
|
-
} else {
|
|
846
|
-
localConfig = generateProjectConfigFromSkills(
|
|
847
|
-
PLUGIN_NAME,
|
|
848
|
-
result.selectedSkills,
|
|
849
|
-
sourceResult.matrix
|
|
850
|
-
);
|
|
851
|
-
}
|
|
852
|
-
localConfig.installMode = result.installMode;
|
|
853
|
-
if (flags.source) {
|
|
854
|
-
localConfig.source = flags.source;
|
|
855
|
-
} else if (sourceResult.sourceConfig.source) {
|
|
856
|
-
localConfig.source = sourceResult.sourceConfig.source;
|
|
998
|
+
if (installResult.wasMerged) {
|
|
999
|
+
this.log(`Merged with existing config at ${installResult.mergedConfigPath}`);
|
|
857
1000
|
}
|
|
858
|
-
|
|
859
|
-
localConfig.marketplace = sourceResult.marketplace;
|
|
860
|
-
}
|
|
861
|
-
const existingFullConfig = await loadProjectConfig2(projectDir);
|
|
862
|
-
if (existingFullConfig) {
|
|
863
|
-
const existingConfig = existingFullConfig.config;
|
|
864
|
-
if (existingConfig.name) {
|
|
865
|
-
localConfig.name = existingConfig.name;
|
|
866
|
-
}
|
|
867
|
-
if (existingConfig.description) {
|
|
868
|
-
localConfig.description = existingConfig.description;
|
|
869
|
-
}
|
|
870
|
-
if (existingConfig.source) {
|
|
871
|
-
localConfig.source = existingConfig.source;
|
|
872
|
-
}
|
|
873
|
-
if (existingConfig.skills && existingConfig.skills.length > 0) {
|
|
874
|
-
const existingSkillIds = new Set(
|
|
875
|
-
existingConfig.skills.map(
|
|
876
|
-
(s) => typeof s === "string" ? s : s.id
|
|
877
|
-
)
|
|
878
|
-
);
|
|
879
|
-
const newSkillIds = localConfig.skills?.filter(
|
|
880
|
-
(s) => !existingSkillIds.has(typeof s === "string" ? s : s.id)
|
|
881
|
-
) || [];
|
|
882
|
-
localConfig.skills = [...existingConfig.skills, ...newSkillIds];
|
|
883
|
-
}
|
|
884
|
-
if (existingConfig.agents && existingConfig.agents.length > 0) {
|
|
885
|
-
const existingAgentIds = new Set(existingConfig.agents);
|
|
886
|
-
const newAgentIds = localConfig.agents.filter(
|
|
887
|
-
(a) => !existingAgentIds.has(a)
|
|
888
|
-
);
|
|
889
|
-
localConfig.agents = [...existingConfig.agents, ...newAgentIds];
|
|
890
|
-
}
|
|
891
|
-
if (existingConfig.stack) {
|
|
892
|
-
const mergedStack = { ...localConfig.stack };
|
|
893
|
-
for (const [agentId, agentConfig] of Object.entries(
|
|
894
|
-
existingConfig.stack
|
|
895
|
-
)) {
|
|
896
|
-
mergedStack[agentId] = { ...mergedStack[agentId], ...agentConfig };
|
|
897
|
-
}
|
|
898
|
-
localConfig.stack = mergedStack;
|
|
899
|
-
}
|
|
900
|
-
if (existingConfig.author) {
|
|
901
|
-
localConfig.author = existingConfig.author;
|
|
902
|
-
}
|
|
903
|
-
if (existingConfig.agents_source) {
|
|
904
|
-
localConfig.agents_source = existingConfig.agents_source;
|
|
905
|
-
}
|
|
906
|
-
if (existingConfig.marketplace) {
|
|
907
|
-
localConfig.marketplace = existingConfig.marketplace;
|
|
908
|
-
}
|
|
909
|
-
if (existingConfig.philosophy) {
|
|
910
|
-
localConfig.philosophy = existingConfig.philosophy;
|
|
911
|
-
}
|
|
912
|
-
if (existingConfig.framework) {
|
|
913
|
-
localConfig.framework = existingConfig.framework;
|
|
914
|
-
}
|
|
915
|
-
if (existingConfig.principles) {
|
|
916
|
-
localConfig.principles = existingConfig.principles;
|
|
917
|
-
}
|
|
918
|
-
if (existingConfig.tags) {
|
|
919
|
-
localConfig.tags = existingConfig.tags;
|
|
920
|
-
}
|
|
921
|
-
if (existingConfig.agent_skills) {
|
|
922
|
-
localConfig.agent_skills = existingConfig.agent_skills;
|
|
923
|
-
}
|
|
924
|
-
if (existingConfig.preload_patterns) {
|
|
925
|
-
localConfig.preload_patterns = existingConfig.preload_patterns;
|
|
926
|
-
}
|
|
927
|
-
if (existingConfig.custom_agents) {
|
|
928
|
-
localConfig.custom_agents = existingConfig.custom_agents;
|
|
929
|
-
}
|
|
930
|
-
if (existingConfig.hooks) {
|
|
931
|
-
localConfig.hooks = existingConfig.hooks;
|
|
932
|
-
}
|
|
933
|
-
this.log(
|
|
934
|
-
`Merged with existing config at ${existingFullConfig.configPath}`
|
|
935
|
-
);
|
|
936
|
-
} else {
|
|
937
|
-
const existingProjectConfig = await loadProjectConfig(projectDir);
|
|
938
|
-
if (existingProjectConfig?.author) {
|
|
939
|
-
localConfig.author = existingProjectConfig.author;
|
|
940
|
-
}
|
|
941
|
-
if (existingProjectConfig?.agents_source) {
|
|
942
|
-
localConfig.agents_source = existingProjectConfig.agents_source;
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
const configYaml = stringifyYaml(localConfig, {
|
|
946
|
-
indent: 2,
|
|
947
|
-
lineWidth: 120
|
|
948
|
-
});
|
|
949
|
-
await writeFile(localConfigPath, configYaml);
|
|
950
|
-
this.log(`Configuration saved (${localConfig.agents.length} agents)
|
|
1001
|
+
this.log(`Configuration saved (${installResult.config.agents.length} agents)
|
|
951
1002
|
`);
|
|
952
1003
|
this.log("Compiling agents...");
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
if (agents[agentId]) {
|
|
956
|
-
if (loadedStack) {
|
|
957
|
-
const skillRefs = resolveAgentSkillsFromStack(
|
|
958
|
-
agentId,
|
|
959
|
-
loadedStack,
|
|
960
|
-
skillAliases
|
|
961
|
-
);
|
|
962
|
-
compileAgents[agentId] = { skills: skillRefs };
|
|
963
|
-
} else if (localConfig.agent_skills?.[agentId]) {
|
|
964
|
-
const skillRefs = resolveStackSkills(
|
|
965
|
-
localConfig,
|
|
966
|
-
agentId,
|
|
967
|
-
localSkillsForResolution
|
|
968
|
-
);
|
|
969
|
-
compileAgents[agentId] = { skills: skillRefs };
|
|
970
|
-
} else {
|
|
971
|
-
compileAgents[agentId] = {};
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
const compileConfig = {
|
|
976
|
-
name: PLUGIN_NAME,
|
|
977
|
-
description: localConfig.description || `Local setup with ${result.selectedSkills.length} skills`,
|
|
978
|
-
claude_md: "",
|
|
979
|
-
agents: compileAgents
|
|
980
|
-
};
|
|
981
|
-
const engine = await createLiquidEngine(projectDir);
|
|
982
|
-
const resolvedAgents = await resolveAgents(
|
|
983
|
-
agents,
|
|
984
|
-
localSkillsForResolution,
|
|
985
|
-
compileConfig,
|
|
986
|
-
sourceResult.sourcePath,
|
|
987
|
-
loadedStack ?? void 0,
|
|
988
|
-
skillAliases
|
|
989
|
-
);
|
|
990
|
-
const compiledAgentNames = [];
|
|
991
|
-
for (const [name, agent] of Object.entries(resolvedAgents)) {
|
|
992
|
-
const output = await compileAgentForPlugin(
|
|
993
|
-
name,
|
|
994
|
-
agent,
|
|
995
|
-
sourceResult.sourcePath,
|
|
996
|
-
engine
|
|
997
|
-
);
|
|
998
|
-
await writeFile(path3.join(localAgentsDir, `${name}.md`), output);
|
|
999
|
-
compiledAgentNames.push(name);
|
|
1000
|
-
}
|
|
1001
|
-
this.log(
|
|
1002
|
-
`Compiled ${compiledAgentNames.length} agents to .claude/agents/
|
|
1003
|
-
`
|
|
1004
|
-
);
|
|
1004
|
+
this.log(`Compiled ${installResult.compiledAgents.length} agents to .claude/agents/
|
|
1005
|
+
`);
|
|
1005
1006
|
this.log("Claude Collective initialized successfully!\n");
|
|
1006
1007
|
this.log("Skills copied to:");
|
|
1007
|
-
this.log(` ${
|
|
1008
|
-
for (const copiedSkill of copiedSkills) {
|
|
1008
|
+
this.log(` ${installResult.skillsDir}`);
|
|
1009
|
+
for (const copiedSkill of installResult.copiedSkills) {
|
|
1009
1010
|
const skill = matrix.skills[copiedSkill.skillId];
|
|
1010
1011
|
const displayName = skill?.alias || copiedSkill.skillId;
|
|
1011
1012
|
this.log(` ${displayName}/`);
|
|
1012
1013
|
}
|
|
1013
1014
|
this.log("");
|
|
1014
1015
|
this.log("Agents compiled to:");
|
|
1015
|
-
this.log(` ${
|
|
1016
|
-
for (const agentName of
|
|
1016
|
+
this.log(` ${installResult.agentsDir}`);
|
|
1017
|
+
for (const agentName of installResult.compiledAgents) {
|
|
1017
1018
|
this.log(` ${agentName}.md`);
|
|
1018
1019
|
}
|
|
1019
1020
|
this.log("");
|
|
1020
1021
|
this.log("Configuration:");
|
|
1021
|
-
this.log(` ${
|
|
1022
|
+
this.log(` ${installResult.configPath}`);
|
|
1022
1023
|
this.log("");
|
|
1023
1024
|
this.log("To customize agent-skill assignments:");
|
|
1024
1025
|
this.log(` 1. Edit .claude-src/config.yaml`);
|