@juho0719/cckit 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/agents-AEKT67A6.js +9 -0
  2. package/dist/{chunk-T5VPG46W.js → chunk-3GUKEMND.js} +0 -5
  3. package/dist/{chunk-33CGM7PI.js → chunk-3Y26YU4R.js} +3 -7
  4. package/dist/{chunk-4NEXS2FY.js → chunk-5XOKKPAA.js} +0 -5
  5. package/dist/{chunk-6COBMJZ6.js → chunk-E3INXQNO.js} +1 -5
  6. package/dist/{chunk-ZBGGTONN.js → chunk-EYY2IZ7N.js} +3 -7
  7. package/dist/{chunk-H4YDYF2X.js → chunk-ID643AV4.js} +3 -7
  8. package/dist/{chunk-FLBB3OH4.js → chunk-K25UZZVG.js} +0 -5
  9. package/dist/{chunk-MSCXXA2X.js → chunk-KEENFBLL.js} +2 -6
  10. package/dist/{chunk-7VVGOZDZ.js → chunk-SW3OJLHC.js} +1 -5
  11. package/dist/{chunk-VN5S6JGZ.js → chunk-W63UKEIT.js} +0 -5
  12. package/dist/{chunk-52Q6TDAH.js → chunk-W7RWPDBH.js} +3 -7
  13. package/dist/claudemd-KKQ2DL7P.js +7 -0
  14. package/dist/cli-DABSKXWN.js +477 -0
  15. package/dist/commands-P5LILVZ5.js +9 -0
  16. package/dist/hooks-A2WQ2LGG.js +9 -0
  17. package/dist/index.js +17 -21
  18. package/dist/mcps-67Q7TBGW.js +6 -0
  19. package/dist/{paths-B754SP2D.js → paths-FT6KBIRD.js} +1 -2
  20. package/dist/{registry-6CLDID6R.js → registry-KRLOB4TH.js} +2 -3
  21. package/dist/rules-EFSJ3L3A.js +9 -0
  22. package/dist/skills-ULMW3UCM.js +8 -0
  23. package/dist/{uninstall-cli-XU7E26JX.js → uninstall-cli-GLYJG5V2.js} +2 -14
  24. package/package.json +2 -1
  25. package/dist/agents-LI3AHTTX.js +0 -10
  26. package/dist/chunk-TLOORH3N.js +0 -50
  27. package/dist/claudemd-NWG63O2G.js +0 -8
  28. package/dist/cli-KHRWBZPV.js +0 -2735
  29. package/dist/commands-UAOYWGUX.js +0 -10
  30. package/dist/hooks-NONUWI6V.js +0 -10
  31. package/dist/mcps-ISPG3F7T.js +0 -7
  32. package/dist/rules-GZEAGCSL.js +0 -10
  33. package/dist/skills-ML3QLXUK.js +0 -9
@@ -0,0 +1,9 @@
1
+ import {
2
+ installAgents
3
+ } from "./chunk-EYY2IZ7N.js";
4
+ import "./chunk-K25UZZVG.js";
5
+ import "./chunk-3GUKEMND.js";
6
+ import "./chunk-5XOKKPAA.js";
7
+ export {
8
+ installAgents
9
+ };
@@ -1,9 +1,4 @@
1
- import {
2
- init_esm_shims
3
- } from "./chunk-TLOORH3N.js";
4
-
5
1
  // src/utils/file.ts
6
- init_esm_shims();
7
2
  import { mkdir, copyFile, readdir } from "fs/promises";
8
3
  import { join } from "path";
9
4
  async function ensureDir(dirPath) {
@@ -1,19 +1,15 @@
1
1
  import {
2
2
  backupIfExists
3
- } from "./chunk-FLBB3OH4.js";
3
+ } from "./chunk-K25UZZVG.js";
4
4
  import {
5
5
  copyFileUtil,
6
6
  ensureDir
7
- } from "./chunk-T5VPG46W.js";
7
+ } from "./chunk-3GUKEMND.js";
8
8
  import {
9
9
  getAssetsDir
10
- } from "./chunk-4NEXS2FY.js";
11
- import {
12
- init_esm_shims
13
- } from "./chunk-TLOORH3N.js";
10
+ } from "./chunk-5XOKKPAA.js";
14
11
 
15
12
  // src/installers/commands.ts
16
- init_esm_shims();
17
13
  import { join } from "path";
18
14
  async function installCommands(commands, targetDir) {
19
15
  const destDir = join(targetDir, "commands");
@@ -1,9 +1,4 @@
1
- import {
2
- init_esm_shims
3
- } from "./chunk-TLOORH3N.js";
4
-
5
1
  // src/utils/paths.ts
6
- init_esm_shims();
7
2
  import { fileURLToPath } from "url";
8
3
  import { dirname, join } from "path";
9
4
  import { homedir } from "os";
@@ -1,12 +1,8 @@
1
1
  import {
2
2
  getAssetsDir
3
- } from "./chunk-4NEXS2FY.js";
4
- import {
5
- init_esm_shims
6
- } from "./chunk-TLOORH3N.js";
3
+ } from "./chunk-5XOKKPAA.js";
7
4
 
8
5
  // src/registry.ts
9
- init_esm_shims();
10
6
  import { readFile, readdir } from "fs/promises";
11
7
  import { join, basename } from "path";
12
8
  function parseFrontmatter(content) {
@@ -1,19 +1,15 @@
1
1
  import {
2
2
  backupIfExists
3
- } from "./chunk-FLBB3OH4.js";
3
+ } from "./chunk-K25UZZVG.js";
4
4
  import {
5
5
  copyFileUtil,
6
6
  ensureDir
7
- } from "./chunk-T5VPG46W.js";
7
+ } from "./chunk-3GUKEMND.js";
8
8
  import {
9
9
  getAssetsDir
10
- } from "./chunk-4NEXS2FY.js";
11
- import {
12
- init_esm_shims
13
- } from "./chunk-TLOORH3N.js";
10
+ } from "./chunk-5XOKKPAA.js";
14
11
 
15
12
  // src/installers/agents.ts
16
- init_esm_shims();
17
13
  import { join } from "path";
18
14
  async function installAgents(agents, targetDir) {
19
15
  const destDir = join(targetDir, "agents");
@@ -1,19 +1,15 @@
1
1
  import {
2
2
  backupIfExists
3
- } from "./chunk-FLBB3OH4.js";
3
+ } from "./chunk-K25UZZVG.js";
4
4
  import {
5
5
  copyFileUtil,
6
6
  ensureDir
7
- } from "./chunk-T5VPG46W.js";
7
+ } from "./chunk-3GUKEMND.js";
8
8
  import {
9
9
  getAssetsDir
10
- } from "./chunk-4NEXS2FY.js";
11
- import {
12
- init_esm_shims
13
- } from "./chunk-TLOORH3N.js";
10
+ } from "./chunk-5XOKKPAA.js";
14
11
 
15
12
  // src/installers/rules.ts
16
- init_esm_shims();
17
13
  import { join } from "path";
18
14
  import { readdir } from "fs/promises";
19
15
  async function installRules(categories, targetDir) {
@@ -1,9 +1,4 @@
1
- import {
2
- init_esm_shims
3
- } from "./chunk-TLOORH3N.js";
4
-
5
1
  // src/utils/backup.ts
6
- init_esm_shims();
7
2
  import { copyFile, access } from "fs/promises";
8
3
  import { constants } from "fs";
9
4
  async function backupFile(filePath) {
@@ -1,16 +1,12 @@
1
1
  import {
2
2
  copyDir,
3
3
  ensureDir
4
- } from "./chunk-T5VPG46W.js";
4
+ } from "./chunk-3GUKEMND.js";
5
5
  import {
6
6
  getAssetsDir
7
- } from "./chunk-4NEXS2FY.js";
8
- import {
9
- init_esm_shims
10
- } from "./chunk-TLOORH3N.js";
7
+ } from "./chunk-5XOKKPAA.js";
11
8
 
12
9
  // src/installers/skills.ts
13
- init_esm_shims();
14
10
  import { join } from "path";
15
11
  async function installSkills(skills, targetDir) {
16
12
  const destBase = join(targetDir, "skills");
@@ -1,12 +1,8 @@
1
1
  import {
2
2
  getAssetsDir
3
- } from "./chunk-4NEXS2FY.js";
4
- import {
5
- init_esm_shims
6
- } from "./chunk-TLOORH3N.js";
3
+ } from "./chunk-5XOKKPAA.js";
7
4
 
8
5
  // src/installers/claudemd.ts
9
- init_esm_shims();
10
6
  import { join } from "path";
11
7
  import { readFile, writeFile, access } from "fs/promises";
12
8
  import { constants } from "fs";
@@ -1,9 +1,4 @@
1
- import {
2
- init_esm_shims
3
- } from "./chunk-TLOORH3N.js";
4
-
5
1
  // src/installers/mcps.ts
6
- init_esm_shims();
7
2
  import { join } from "path";
8
3
  import { readFile, writeFile, access } from "fs/promises";
9
4
  import { constants } from "fs";
@@ -1,19 +1,15 @@
1
1
  import {
2
2
  backupIfExists
3
- } from "./chunk-FLBB3OH4.js";
3
+ } from "./chunk-K25UZZVG.js";
4
4
  import {
5
5
  copyFileUtil,
6
6
  ensureDir
7
- } from "./chunk-T5VPG46W.js";
7
+ } from "./chunk-3GUKEMND.js";
8
8
  import {
9
9
  getAssetsDir
10
- } from "./chunk-4NEXS2FY.js";
11
- import {
12
- init_esm_shims
13
- } from "./chunk-TLOORH3N.js";
10
+ } from "./chunk-5XOKKPAA.js";
14
11
 
15
12
  // src/installers/hooks.ts
16
- init_esm_shims();
17
13
  import { join } from "path";
18
14
  import { readFile, writeFile, access, chmod } from "fs/promises";
19
15
  import { constants } from "fs";
@@ -0,0 +1,7 @@
1
+ import {
2
+ installClaudemd
3
+ } from "./chunk-SW3OJLHC.js";
4
+ import "./chunk-5XOKKPAA.js";
5
+ export {
6
+ installClaudemd
7
+ };
@@ -0,0 +1,477 @@
1
+ import {
2
+ installMcps
3
+ } from "./chunk-W63UKEIT.js";
4
+ import {
5
+ installClaudemd
6
+ } from "./chunk-SW3OJLHC.js";
7
+ import {
8
+ getAgents,
9
+ getClaudemdItems,
10
+ getCommands,
11
+ getHooks,
12
+ getMcpServers,
13
+ getRuleCategories,
14
+ getSkills
15
+ } from "./chunk-E3INXQNO.js";
16
+ import {
17
+ installAgents
18
+ } from "./chunk-EYY2IZ7N.js";
19
+ import {
20
+ installSkills
21
+ } from "./chunk-KEENFBLL.js";
22
+ import {
23
+ installCommands
24
+ } from "./chunk-3Y26YU4R.js";
25
+ import {
26
+ installHooks
27
+ } from "./chunk-W7RWPDBH.js";
28
+ import {
29
+ installRules
30
+ } from "./chunk-ID643AV4.js";
31
+ import {
32
+ backupIfExists
33
+ } from "./chunk-K25UZZVG.js";
34
+ import {
35
+ copyFileUtil
36
+ } from "./chunk-3GUKEMND.js";
37
+ import {
38
+ getAssetsDir,
39
+ getGlobalDir,
40
+ getProjectDir
41
+ } from "./chunk-5XOKKPAA.js";
42
+
43
+ // src/cli.ts
44
+ import { checkbox, select, input, confirm } from "@inquirer/prompts";
45
+ import { AbortPromptError, ExitPromptError } from "@inquirer/core";
46
+ import chalk from "chalk";
47
+ import ora from "ora";
48
+ import { join as join2 } from "path";
49
+
50
+ // src/installers/statusline.ts
51
+ import { join } from "path";
52
+ import { chmod } from "fs/promises";
53
+ async function installStatusline() {
54
+ const src = join(getAssetsDir(), "statusline", "statusline.sh");
55
+ const dest = join(getGlobalDir(), "statusline.sh");
56
+ await backupIfExists(dest);
57
+ await copyFileUtil(src, dest);
58
+ await chmod(dest, 493);
59
+ }
60
+
61
+ // src/cli.ts
62
+ var BACK = /* @__PURE__ */ Symbol("BACK");
63
+ var STEP_SCOPE = 0;
64
+ var STEP_CATEGORIES = 1;
65
+ var STEP_ITEMS = 2;
66
+ var STEP_CONFIRM = 3;
67
+ async function withEsc(promptFn) {
68
+ const ac = new AbortController();
69
+ const onData = (data) => {
70
+ if (data.length === 1 && data[0] === 27) {
71
+ ac.abort();
72
+ }
73
+ };
74
+ process.stdin.on("data", onData);
75
+ try {
76
+ return await promptFn({ signal: ac.signal });
77
+ } catch (err) {
78
+ if (err instanceof AbortPromptError) {
79
+ return BACK;
80
+ }
81
+ throw err;
82
+ } finally {
83
+ process.stdin.removeListener("data", onData);
84
+ }
85
+ }
86
+ function printBanner() {
87
+ console.log(
88
+ chalk.cyan.bold(`
89
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
90
+ \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D
91
+ \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551
92
+ \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551
93
+ \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551
94
+ \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
95
+ `)
96
+ );
97
+ console.log(chalk.gray(" Claude Code Harness Installer"));
98
+ console.log(chalk.gray(" ESC: back / Ctrl+C: exit\n"));
99
+ }
100
+ function createEmptyPlan(scope) {
101
+ return {
102
+ scope,
103
+ agents: [],
104
+ skills: [],
105
+ commands: [],
106
+ hooks: [],
107
+ ruleCategories: [],
108
+ mcps: [],
109
+ mcpEnvValues: /* @__PURE__ */ new Map(),
110
+ claudemds: [],
111
+ statusline: false
112
+ };
113
+ }
114
+ async function runCli() {
115
+ printBanner();
116
+ let step = STEP_SCOPE;
117
+ let scope = "global";
118
+ let targetDir = "";
119
+ let selectedCategories = [];
120
+ let plan = createEmptyPlan(scope);
121
+ let skippedMcps = /* @__PURE__ */ new Map();
122
+ try {
123
+ while (step <= STEP_CONFIRM) {
124
+ switch (step) {
125
+ // ── Step 0: 설치 범위 선택 ──
126
+ case STEP_SCOPE: {
127
+ const result = await withEsc(
128
+ (ctx) => select({
129
+ message: "Install scope:",
130
+ choices: [
131
+ {
132
+ name: `Global ${chalk.gray("~/.claude/")}`,
133
+ value: "global"
134
+ },
135
+ {
136
+ name: `Project ${chalk.gray("./.claude/")}`,
137
+ value: "project"
138
+ }
139
+ ]
140
+ }, ctx)
141
+ );
142
+ if (result === BACK) {
143
+ console.log(chalk.yellow("\n Exiting."));
144
+ return;
145
+ }
146
+ scope = result;
147
+ targetDir = scope === "global" ? getGlobalDir() : getProjectDir();
148
+ step = STEP_CATEGORIES;
149
+ break;
150
+ }
151
+ // ── Step 1: 카테고리 멀티셀렉트 ──
152
+ case STEP_CATEGORIES: {
153
+ const result = await withEsc(
154
+ (ctx) => checkbox({
155
+ message: "Select categories to install:",
156
+ choices: [
157
+ { name: "Agents - AI sub-agents", value: "agents" },
158
+ { name: "Skills - Reusable skill prompts", value: "skills" },
159
+ { name: "Commands - Slash commands", value: "commands" },
160
+ { name: "Hooks - Post-tool hooks", value: "hooks" },
161
+ { name: "Rules - CLAUDE.md rules", value: "rules" },
162
+ { name: "MCPs - MCP server configs", value: "mcps" },
163
+ { name: "ClaudeMd - Behavioral guidelines", value: "claudemd" },
164
+ { name: "Statusline - Terminal statusline script", value: "statusline" }
165
+ ]
166
+ }, ctx)
167
+ );
168
+ if (result === BACK) {
169
+ step = STEP_SCOPE;
170
+ break;
171
+ }
172
+ if (result.length === 0) {
173
+ console.log(chalk.yellow("\n No categories selected.\n"));
174
+ break;
175
+ }
176
+ selectedCategories = result;
177
+ plan = createEmptyPlan(scope);
178
+ skippedMcps = /* @__PURE__ */ new Map();
179
+ step = STEP_ITEMS;
180
+ break;
181
+ }
182
+ // ── Step 2: 각 카테고리별 항목 선택 ──
183
+ case STEP_ITEMS: {
184
+ let wentBack = false;
185
+ for (const cat of selectedCategories) {
186
+ if (cat === "statusline") {
187
+ plan.statusline = true;
188
+ continue;
189
+ }
190
+ if (cat === "agents") {
191
+ const allAgents = await getAgents();
192
+ const result = await withEsc(
193
+ (ctx) => checkbox({
194
+ message: "Select agents:",
195
+ choices: allAgents.map((a) => ({
196
+ name: `${chalk.bold(a.name.padEnd(30))} ${chalk.gray(a.description.slice(0, 60))}`,
197
+ value: a,
198
+ checked: false
199
+ }))
200
+ }, ctx)
201
+ );
202
+ if (result === BACK) {
203
+ wentBack = true;
204
+ break;
205
+ }
206
+ plan.agents = result;
207
+ }
208
+ if (cat === "skills") {
209
+ const allSkills = await getSkills();
210
+ const result = await withEsc(
211
+ (ctx) => checkbox({
212
+ message: "Select skills:",
213
+ choices: allSkills.map((s) => ({
214
+ name: `${chalk.bold(s.name.padEnd(35))} ${chalk.gray(s.description.slice(0, 55))}`,
215
+ value: s,
216
+ checked: false
217
+ }))
218
+ }, ctx)
219
+ );
220
+ if (result === BACK) {
221
+ wentBack = true;
222
+ break;
223
+ }
224
+ plan.skills = result;
225
+ }
226
+ if (cat === "commands") {
227
+ const allCommands = await getCommands();
228
+ const result = await withEsc(
229
+ (ctx) => checkbox({
230
+ message: "Select commands:",
231
+ choices: allCommands.map((c) => ({
232
+ name: `${chalk.bold(c.name.padEnd(25))} ${chalk.gray(c.description.slice(0, 65))}`,
233
+ value: c,
234
+ checked: false
235
+ }))
236
+ }, ctx)
237
+ );
238
+ if (result === BACK) {
239
+ wentBack = true;
240
+ break;
241
+ }
242
+ plan.commands = result;
243
+ }
244
+ if (cat === "hooks") {
245
+ const allHooks = await getHooks();
246
+ const result = await withEsc(
247
+ (ctx) => checkbox({
248
+ message: "Select hooks:",
249
+ choices: allHooks.map((h) => ({
250
+ name: `${chalk.bold(h.name.padEnd(35))} ${chalk.gray(h.description.slice(0, 55))}`,
251
+ value: h,
252
+ checked: false
253
+ }))
254
+ }, ctx)
255
+ );
256
+ if (result === BACK) {
257
+ wentBack = true;
258
+ break;
259
+ }
260
+ plan.hooks = result;
261
+ }
262
+ if (cat === "rules") {
263
+ const allCategories = await getRuleCategories();
264
+ const result = await withEsc(
265
+ (ctx) => checkbox({
266
+ message: "Select rule categories:",
267
+ choices: allCategories.map((rc) => ({
268
+ name: `${chalk.bold(rc.category.padEnd(20))} ${chalk.gray(`(${rc.files.length} files)`)}`,
269
+ value: rc.category,
270
+ checked: false
271
+ }))
272
+ }, ctx)
273
+ );
274
+ if (result === BACK) {
275
+ wentBack = true;
276
+ break;
277
+ }
278
+ plan.ruleCategories = result;
279
+ }
280
+ if (cat === "claudemd") {
281
+ const allClaudemds = await getClaudemdItems();
282
+ const result = await withEsc(
283
+ (ctx) => checkbox({
284
+ message: "Select claudemd items:",
285
+ choices: allClaudemds.map((c) => ({
286
+ name: `${chalk.bold(c.name.padEnd(35))} ${chalk.gray(c.description.slice(0, 55))}`,
287
+ value: c,
288
+ checked: false
289
+ }))
290
+ }, ctx)
291
+ );
292
+ if (result === BACK) {
293
+ wentBack = true;
294
+ break;
295
+ }
296
+ plan.claudemds = result;
297
+ }
298
+ if (cat === "mcps") {
299
+ const allMcps = await getMcpServers();
300
+ const mcpResult = await withEsc(
301
+ (ctx) => checkbox({
302
+ message: "Select MCP servers:",
303
+ choices: allMcps.map((m) => ({
304
+ name: `${chalk.bold(m.name.padEnd(30))} ${chalk.gray(m.description.slice(0, 55))}`,
305
+ value: m,
306
+ checked: false
307
+ }))
308
+ }, ctx)
309
+ );
310
+ if (mcpResult === BACK) {
311
+ wentBack = true;
312
+ break;
313
+ }
314
+ plan.mcps = mcpResult;
315
+ for (const server of plan.mcps) {
316
+ if (server.type === "http" || server.envVars.length === 0) continue;
317
+ console.log(chalk.yellow(`
318
+ ${server.name} requires environment variables:`));
319
+ const envMap = {};
320
+ const skippedKeys = [];
321
+ for (const envKey of server.envVars) {
322
+ const action = await withEsc(
323
+ (ctx) => select({
324
+ message: ` How do you want to set ${chalk.bold(envKey)}?`,
325
+ choices: [
326
+ { name: "Enter value now", value: "enter" },
327
+ { name: `Skip ${chalk.gray(`(keep placeholder: YOUR_${envKey}_HERE)`)}`, value: "skip" }
328
+ ]
329
+ }, ctx)
330
+ );
331
+ if (action === BACK) {
332
+ wentBack = true;
333
+ break;
334
+ }
335
+ if (action === "skip") {
336
+ skippedKeys.push(envKey);
337
+ } else {
338
+ const value = await withEsc(
339
+ (ctx) => input({
340
+ message: ` ${envKey}:`,
341
+ default: ""
342
+ }, ctx)
343
+ );
344
+ if (value === BACK) {
345
+ wentBack = true;
346
+ break;
347
+ }
348
+ if (value) envMap[envKey] = value;
349
+ }
350
+ }
351
+ if (wentBack) break;
352
+ plan.mcpEnvValues.set(server.name, envMap);
353
+ if (skippedKeys.length > 0) {
354
+ skippedMcps.set(server.name, skippedKeys);
355
+ }
356
+ }
357
+ if (wentBack) break;
358
+ }
359
+ }
360
+ if (wentBack) {
361
+ plan = createEmptyPlan(scope);
362
+ skippedMcps = /* @__PURE__ */ new Map();
363
+ step = STEP_CATEGORIES;
364
+ } else {
365
+ step = STEP_CONFIRM;
366
+ }
367
+ break;
368
+ }
369
+ // ── Step 3: 설치 요약 + 확인 ──
370
+ case STEP_CONFIRM: {
371
+ console.log(chalk.bold("\n Installation Summary"));
372
+ console.log(chalk.gray(" \u2500".repeat(40)));
373
+ console.log(` Scope : ${chalk.cyan(scope)} (${targetDir})`);
374
+ if (plan.agents.length) console.log(` Agents : ${plan.agents.map((a) => a.name).join(", ")}`);
375
+ if (plan.skills.length) console.log(` Skills : ${plan.skills.map((s) => s.name).join(", ")}`);
376
+ if (plan.commands.length) console.log(` Commands: ${plan.commands.map((c) => c.name).join(", ")}`);
377
+ if (plan.hooks.length) console.log(` Hooks : ${plan.hooks.map((h) => h.name).join(", ")}`);
378
+ if (plan.ruleCategories.length) console.log(` Rules : ${plan.ruleCategories.join(", ")}`);
379
+ if (plan.mcps.length) console.log(` MCPs : ${plan.mcps.map((m) => m.name).join(", ")}`);
380
+ if (plan.claudemds.length) console.log(` ClaudeMd : ${plan.claudemds.map((c) => c.name).join(", ")}`);
381
+ if (plan.statusline) console.log(` Statusline: statusline.sh \u2192 ~/.claude/statusline.sh`);
382
+ console.log("");
383
+ const totalItems = plan.agents.length + plan.skills.length + plan.commands.length + plan.hooks.length + plan.ruleCategories.length + plan.mcps.length + plan.claudemds.length + (plan.statusline ? 1 : 0);
384
+ if (totalItems === 0) {
385
+ console.log(chalk.yellow(" Nothing selected.\n"));
386
+ plan = createEmptyPlan(scope);
387
+ skippedMcps = /* @__PURE__ */ new Map();
388
+ step = STEP_CATEGORIES;
389
+ break;
390
+ }
391
+ const ok = await withEsc(
392
+ (ctx) => confirm({ message: "Proceed with installation?", default: true }, ctx)
393
+ );
394
+ if (ok === BACK) {
395
+ plan = createEmptyPlan(scope);
396
+ skippedMcps = /* @__PURE__ */ new Map();
397
+ step = STEP_CATEGORIES;
398
+ break;
399
+ }
400
+ if (!ok) {
401
+ console.log(chalk.yellow("\n Aborted."));
402
+ return;
403
+ }
404
+ console.log("");
405
+ const spinner = ora("Installing...").start();
406
+ try {
407
+ if (plan.agents.length) {
408
+ spinner.text = "Installing agents...";
409
+ await installAgents(plan.agents, targetDir);
410
+ }
411
+ if (plan.skills.length) {
412
+ spinner.text = "Installing skills...";
413
+ await installSkills(plan.skills, targetDir);
414
+ }
415
+ if (plan.commands.length) {
416
+ spinner.text = "Installing commands...";
417
+ await installCommands(plan.commands, targetDir);
418
+ }
419
+ if (plan.hooks.length) {
420
+ spinner.text = "Installing hooks...";
421
+ await installHooks(plan.hooks, targetDir);
422
+ }
423
+ if (plan.ruleCategories.length) {
424
+ spinner.text = "Installing rules...";
425
+ await installRules(plan.ruleCategories, targetDir);
426
+ }
427
+ if (plan.mcps.length) {
428
+ spinner.text = "Installing MCP servers...";
429
+ await installMcps(plan.mcps, plan.scope, plan.mcpEnvValues);
430
+ }
431
+ if (plan.claudemds.length) {
432
+ spinner.text = "Installing claudemd...";
433
+ await installClaudemd(plan.claudemds, targetDir);
434
+ }
435
+ if (plan.statusline) {
436
+ spinner.text = "Installing statusline...";
437
+ await installStatusline();
438
+ }
439
+ spinner.succeed(chalk.green("Installation complete!"));
440
+ console.log("");
441
+ if (plan.agents.length) console.log(` ${chalk.green("\u2713")} ${plan.agents.length} agent(s) \u2192 ${join2(targetDir, "agents")}`);
442
+ if (plan.skills.length) console.log(` ${chalk.green("\u2713")} ${plan.skills.length} skill(s) \u2192 ${join2(targetDir, "skills")}`);
443
+ if (plan.commands.length) console.log(` ${chalk.green("\u2713")} ${plan.commands.length} command(s) \u2192 ${join2(targetDir, "commands")}`);
444
+ if (plan.hooks.length) console.log(` ${chalk.green("\u2713")} ${plan.hooks.length} hook(s) \u2192 ${join2(targetDir, "hooks")}`);
445
+ if (plan.ruleCategories.length) console.log(` ${chalk.green("\u2713")} Rules copied \u2192 ${join2(targetDir, "rules")}`);
446
+ if (plan.mcps.length) console.log(` ${chalk.green("\u2713")} ${plan.mcps.length} MCP server(s) \u2192 ${scope === "global" ? "~/.claude.json" : "./.claude.json"}`);
447
+ if (plan.claudemds.length) console.log(` ${chalk.green("\u2713")} ClaudeMd appended \u2192 ${join2(targetDir, "CLAUDE.md")}`);
448
+ if (plan.statusline) console.log(` ${chalk.green("\u2713")} Statusline installed \u2192 ~/.claude/statusline.sh`);
449
+ console.log("");
450
+ if (skippedMcps.size > 0) {
451
+ console.log(chalk.yellow(" \u26A0 The following MCP servers have placeholder env vars:"));
452
+ for (const [serverName, keys] of skippedMcps) {
453
+ console.log(` ${chalk.bold("-")} ${serverName} ${chalk.gray(`(${keys.join(", ")})`)} `);
454
+ }
455
+ const configPath = scope === "global" ? "~/.claude.json" : "./.claude.json";
456
+ console.log(chalk.gray(` \u2192 Edit ${configPath} to set the actual values`));
457
+ console.log("");
458
+ }
459
+ } catch (err) {
460
+ spinner.fail(chalk.red("Installation failed"));
461
+ throw err;
462
+ }
463
+ return;
464
+ }
465
+ }
466
+ }
467
+ } catch (err) {
468
+ if (err instanceof ExitPromptError) {
469
+ console.log(chalk.yellow("\n Exiting."));
470
+ return;
471
+ }
472
+ throw err;
473
+ }
474
+ }
475
+ export {
476
+ runCli
477
+ };