caik-cli 0.1.1 → 0.6.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/README.md +8 -7
- package/dist/api-6OX4ICXN.js +9 -0
- package/dist/auto-improve-skills-2COKTU5C.js +8 -0
- package/dist/autoresearch-Y7WW6L4O.js +24 -0
- package/dist/chunk-2YHUDOJL.js +54 -0
- package/dist/chunk-3TXNZINH.js +775 -0
- package/dist/chunk-5MHNQAV4.js +317 -0
- package/dist/chunk-7AIZTHHZ.js +152 -0
- package/dist/chunk-D4IM3YRX.js +166 -0
- package/dist/chunk-DJJHS7KK.js +62 -0
- package/dist/chunk-DKZBQRR3.js +91 -0
- package/dist/chunk-FLSHJZLC.js +613 -0
- package/dist/chunk-H2ZKCXMJ.js +202 -0
- package/dist/chunk-ILMOSMD3.js +83 -0
- package/dist/chunk-KYTHKH6V.js +79 -0
- package/dist/chunk-LTKHLRM4.js +272 -0
- package/dist/chunk-T32AEP3O.js +146 -0
- package/dist/chunk-T73Z5UMA.js +14437 -0
- package/dist/chunk-TFKT7V7H.js +1545 -0
- package/dist/chunk-US4CYDNS.js +524 -0
- package/dist/chunk-ZLRN7Q7C.js +27 -0
- package/dist/claude-code-6DF4YARB.js +8 -0
- package/dist/config-CS7734SA.js +24 -0
- package/dist/correction-classifier-TLPKRNLI.js +93 -0
- package/dist/cursor-Z4XXDCAM.js +8 -0
- package/dist/daemon/autoresearch-2MAEM2YI.js +272 -0
- package/dist/daemon/chunk-545XA5CB.js +77 -0
- package/dist/daemon/chunk-HEYFAUHL.js +90 -0
- package/dist/daemon/chunk-MLKGABMK.js +9 -0
- package/dist/daemon/chunk-NJICGNCK.js +150 -0
- package/dist/daemon/chunk-OD5NUFH2.js +181 -0
- package/dist/daemon/chunk-SM2FSXIP.js +60 -0
- package/dist/daemon/chunk-UMDJFPN6.js +163 -0
- package/dist/daemon/config-F7HE3JRY.js +23 -0
- package/dist/daemon/db-QEXVVTAL.js +15 -0
- package/dist/daemon/eval-generator-OR2FAYLB.js +316 -0
- package/dist/daemon/improver-TGEK6MPE.js +186 -0
- package/dist/daemon/llm-FUJ2TBYT.js +11 -0
- package/dist/daemon/nudge-detector-NFRHWZY6.js +140 -0
- package/dist/daemon/platform-7N3LQDIB.js +16381 -0
- package/dist/daemon/registry-FI4GTO3H.js +20 -0
- package/dist/daemon/server.js +356 -0
- package/dist/daemon/trace-store-T7XFGQSX.js +19 -0
- package/dist/daemon-UXYMG46V.js +85 -0
- package/dist/db-TLNRIXLK.js +18 -0
- package/dist/eval-generator-GGMRPO3K.js +21 -0
- package/dist/eval-runner-EF4K6T5Y.js +15 -0
- package/dist/index.js +8033 -568
- package/dist/llm-3UUZX6PX.js +12 -0
- package/dist/platform-52NREMBS.js +33 -0
- package/dist/repo-installer-K6ADOW3E.js +25 -0
- package/dist/setup-P744STZE.js +16 -0
- package/dist/test-loop-Y7QQE55P.js +127 -0
- package/dist/trace-store-FVLMNNDK.js +20 -0
- package/package.json +9 -3
|
@@ -0,0 +1,775 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
detectPlatforms,
|
|
4
|
+
getDefaultMcpConfig,
|
|
5
|
+
getPlatformAdapter
|
|
6
|
+
} from "./chunk-TFKT7V7H.js";
|
|
7
|
+
import {
|
|
8
|
+
listRegistryEntries
|
|
9
|
+
} from "./chunk-DKZBQRR3.js";
|
|
10
|
+
import {
|
|
11
|
+
getOrCreateInstallationId,
|
|
12
|
+
readConfig,
|
|
13
|
+
resolveConfig
|
|
14
|
+
} from "./chunk-KYTHKH6V.js";
|
|
15
|
+
import {
|
|
16
|
+
CLI_NPX_PACKAGE,
|
|
17
|
+
compactNumber
|
|
18
|
+
} from "./chunk-T73Z5UMA.js";
|
|
19
|
+
|
|
20
|
+
// src/commands/setup.ts
|
|
21
|
+
import { checkbox } from "@inquirer/prompts";
|
|
22
|
+
import { existsSync } from "fs";
|
|
23
|
+
|
|
24
|
+
// src/platform/templates/claude-code-skill.ts
|
|
25
|
+
function getClaudeCodeSkillContent() {
|
|
26
|
+
return `---
|
|
27
|
+
name: caik
|
|
28
|
+
description: Search, install, and manage AI coding artifacts (skills, rules, prompts, MCP servers, knowledge packs) from the CAIK community registry. Use when the user wants to find reusable building blocks, install artifacts, or contribute back to the community.
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
# CAIK \u2014 AI Artifact Registry
|
|
32
|
+
|
|
33
|
+
CAIK is a community-driven registry for AI coding artifacts \u2014 skills, rules, prompts, MCP servers, and knowledge packs. Use CAIK to discover, install, and share reusable building blocks across projects.
|
|
34
|
+
|
|
35
|
+
## Available MCP Tools
|
|
36
|
+
|
|
37
|
+
When the CAIK MCP server is running, these tools are available:
|
|
38
|
+
|
|
39
|
+
| Tool | Description |
|
|
40
|
+
|------|-------------|
|
|
41
|
+
| \`search\` | Search the CAIK registry for artifacts |
|
|
42
|
+
| \`get_artifact\` | Get full details for an artifact by slug |
|
|
43
|
+
| \`install_artifact\` | Get install instructions for an artifact |
|
|
44
|
+
| \`report_outcome\` | Report whether an artifact worked (success: true/false) |
|
|
45
|
+
| \`submit_review\` | Upvote or downvote an artifact |
|
|
46
|
+
|
|
47
|
+
## Quick Commands
|
|
48
|
+
|
|
49
|
+
If MCP is unavailable, use the CLI directly:
|
|
50
|
+
|
|
51
|
+
- **Search:** \`caik search <query>\`
|
|
52
|
+
- **Install:** \`caik install <slug>\`
|
|
53
|
+
- **Status:** \`caik status\`
|
|
54
|
+
- **Update:** \`caik update [slug]\`
|
|
55
|
+
- **Uninstall:** \`caik uninstall <slug>\`
|
|
56
|
+
|
|
57
|
+
## Contributing Back
|
|
58
|
+
|
|
59
|
+
When an artifact works well for a task, use \`report_outcome(artifact_slug="...", success=true)\` or \`submit_review(artifact_slug="...", vote="up")\` to help the community. Your contributions earn karma on the CAIK leaderboard.
|
|
60
|
+
|
|
61
|
+
## Discovery
|
|
62
|
+
|
|
63
|
+
Ask your agent: "Find CAIK artifacts for [your use case]" \u2014 the agent will use the \`search\` tool to find relevant artifacts from the registry.
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/platform/templates/cursor-skill.ts
|
|
68
|
+
function getCursorSkillContent() {
|
|
69
|
+
return `---
|
|
70
|
+
name: caik
|
|
71
|
+
description: Search, install, and manage AI coding artifacts (skills, rules, prompts, MCP servers, knowledge packs) from the CAIK community registry. Use when the user wants to find reusable building blocks, install artifacts, or contribute back to the community.
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
# CAIK \u2014 AI Artifact Registry
|
|
75
|
+
|
|
76
|
+
CAIK is a community-driven registry for AI coding artifacts. Use CAIK to discover and install rules, prompts, and knowledge packs into your Cursor workspace.
|
|
77
|
+
|
|
78
|
+
## Cursor Rules Integration
|
|
79
|
+
|
|
80
|
+
CAIK artifacts install directly into your \`.cursorrules\` file. Installed rules are automatically loaded by Cursor's AI features.
|
|
81
|
+
|
|
82
|
+
## MCP Tools
|
|
83
|
+
|
|
84
|
+
If the CAIK MCP server is configured, these tools are available:
|
|
85
|
+
|
|
86
|
+
| Tool | Description |
|
|
87
|
+
|------|-------------|
|
|
88
|
+
| \`search\` | Search the CAIK registry for artifacts |
|
|
89
|
+
| \`get_artifact\` | Get full details for an artifact by slug |
|
|
90
|
+
| \`install_artifact\` | Install an artifact into the current project |
|
|
91
|
+
| \`report_outcome\` | Report whether an artifact worked well or poorly |
|
|
92
|
+
|
|
93
|
+
## CLI Fallback
|
|
94
|
+
|
|
95
|
+
- **Search:** \`caik search <query>\`
|
|
96
|
+
- **Install:** \`caik install <slug>\`
|
|
97
|
+
- **Status:** \`caik status\`
|
|
98
|
+
- **Uninstall:** \`caik uninstall <slug>\`
|
|
99
|
+
|
|
100
|
+
## Discovery
|
|
101
|
+
|
|
102
|
+
Ask Cursor: "Find CAIK artifacts for [your use case]" to search the registry.
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// src/platform/templates/openclaw-skill.ts
|
|
107
|
+
function getOpenClawSkillContent() {
|
|
108
|
+
return `---
|
|
109
|
+
name: caik
|
|
110
|
+
description: Search, install, and manage AI coding artifacts (skills, rules, prompts, MCP servers, knowledge packs) from the CAIK community registry. Use when the user wants to find reusable building blocks, install artifacts, or contribute back to the community.
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
# CAIK \u2014 AI Artifact Registry
|
|
114
|
+
|
|
115
|
+
CAIK is a community-driven registry for AI coding artifacts \u2014 skills, rules, prompts, MCP servers, and knowledge packs. Use CAIK to discover and install reusable building blocks.
|
|
116
|
+
|
|
117
|
+
## Skill Capabilities
|
|
118
|
+
|
|
119
|
+
CAIK artifacts integrate with OpenClaw's skill system. Installed skills are available as callable capabilities within your OpenClaw agent.
|
|
120
|
+
|
|
121
|
+
## Contribution Tracking
|
|
122
|
+
|
|
123
|
+
CAIK uses OpenClaw lifecycle hooks to track artifact usage. When you invoke a CAIK-installed skill, outcome data is reported automatically to build your contribution level and community karma. You can disable it with \`caik config set contributions false\`.
|
|
124
|
+
|
|
125
|
+
## MCP Tools
|
|
126
|
+
|
|
127
|
+
| Tool | Description |
|
|
128
|
+
|------|-------------|
|
|
129
|
+
| \`search\` | Search the CAIK registry for artifacts |
|
|
130
|
+
| \`get_artifact\` | Get full details for an artifact by slug |
|
|
131
|
+
| \`install_artifact\` | Install an artifact into the current project |
|
|
132
|
+
| \`report_outcome\` | Report whether an artifact worked well or poorly |
|
|
133
|
+
| \`get_alternatives\` | Find similar artifacts |
|
|
134
|
+
|
|
135
|
+
## CLI Fallback
|
|
136
|
+
|
|
137
|
+
- **Search:** \`caik search <query>\`
|
|
138
|
+
- **Install:** \`caik install <slug>\`
|
|
139
|
+
- **Status:** \`caik status\`
|
|
140
|
+
- **Update:** \`caik update [slug]\`
|
|
141
|
+
- **Uninstall:** \`caik uninstall <slug>\`
|
|
142
|
+
|
|
143
|
+
## Discovery
|
|
144
|
+
|
|
145
|
+
Ask your agent: "Find CAIK artifacts for [your use case]" to search the registry.
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/platform/templates/codex-skill.ts
|
|
150
|
+
function getCodexSkillContent() {
|
|
151
|
+
return `---
|
|
152
|
+
name: caik
|
|
153
|
+
description: Search, install, and manage AI coding artifacts (skills, rules, prompts, MCP servers, knowledge packs) from the CAIK community registry. Use when the user wants to find reusable building blocks, install artifacts, or contribute back to the community.
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
# CAIK \u2014 AI Artifact Registry
|
|
157
|
+
|
|
158
|
+
CAIK is a community-driven registry for AI coding artifacts \u2014 skills, rules, prompts, MCP servers, and knowledge packs. Use CAIK to discover, install, and share reusable building blocks across projects.
|
|
159
|
+
|
|
160
|
+
## Available MCP Tools
|
|
161
|
+
|
|
162
|
+
When the CAIK MCP server is running, these tools are available:
|
|
163
|
+
|
|
164
|
+
| Tool | Description |
|
|
165
|
+
|------|-------------|
|
|
166
|
+
| \`search\` | Search the CAIK registry for artifacts |
|
|
167
|
+
| \`get_artifact\` | Get full details for an artifact by slug |
|
|
168
|
+
| \`install_artifact\` | Get install instructions for an artifact |
|
|
169
|
+
| \`report_outcome\` | Report whether an artifact worked (success: true/false) |
|
|
170
|
+
| \`submit_review\` | Upvote or downvote an artifact |
|
|
171
|
+
|
|
172
|
+
## Quick Commands
|
|
173
|
+
|
|
174
|
+
If MCP is unavailable, use the CLI directly:
|
|
175
|
+
|
|
176
|
+
- **Search:** \`caik search <query>\`
|
|
177
|
+
- **Install:** \`caik install <slug>\`
|
|
178
|
+
- **Status:** \`caik status\`
|
|
179
|
+
- **Update:** \`caik update [slug]\`
|
|
180
|
+
- **Uninstall:** \`caik uninstall <slug>\`
|
|
181
|
+
|
|
182
|
+
## Codex Integration
|
|
183
|
+
|
|
184
|
+
Skills are discovered from \`~/.agents/skills/\` (user-level) and \`$CWD/.agents/skills/\` (project-level). CAIK installs skills to these directories automatically.
|
|
185
|
+
|
|
186
|
+
To enable lifecycle hooks for contribution tracking, ensure hooks are enabled:
|
|
187
|
+
|
|
188
|
+
\`\`\`toml
|
|
189
|
+
# ~/.codex/config.toml
|
|
190
|
+
[features]
|
|
191
|
+
codex_hooks = true
|
|
192
|
+
\`\`\`
|
|
193
|
+
|
|
194
|
+
## Contributing Back
|
|
195
|
+
|
|
196
|
+
When an artifact works well for a task, use \`report_outcome(artifact_slug="...", success=true)\` or \`submit_review(artifact_slug="...", vote="up")\` to help the community. Your contributions earn karma on the CAIK leaderboard.
|
|
197
|
+
|
|
198
|
+
## Discovery
|
|
199
|
+
|
|
200
|
+
Ask your agent: "Find CAIK artifacts for [your use case]" \u2014 the agent will use the \`search\` tool to find relevant artifacts from the registry.
|
|
201
|
+
`;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/platform/templates/index.ts
|
|
205
|
+
function getSkillContent(platform) {
|
|
206
|
+
switch (platform) {
|
|
207
|
+
case "claude-code":
|
|
208
|
+
return getClaudeCodeSkillContent();
|
|
209
|
+
case "cursor":
|
|
210
|
+
return getCursorSkillContent();
|
|
211
|
+
case "openclaw":
|
|
212
|
+
return getOpenClawSkillContent();
|
|
213
|
+
case "codex":
|
|
214
|
+
return getCodexSkillContent();
|
|
215
|
+
default:
|
|
216
|
+
return getGenericSkillContent();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function getGenericSkillContent() {
|
|
220
|
+
return `# CAIK \u2014 AI Artifact Registry
|
|
221
|
+
|
|
222
|
+
CAIK is a community-driven registry for AI coding artifacts \u2014 skills, rules, prompts, MCP servers, and knowledge packs.
|
|
223
|
+
|
|
224
|
+
## CLI Commands
|
|
225
|
+
|
|
226
|
+
- **Search:** \`caik search <query>\`
|
|
227
|
+
- **Install:** \`caik install <slug>\`
|
|
228
|
+
- **Status:** \`caik status\`
|
|
229
|
+
- **Update:** \`caik update [slug]\`
|
|
230
|
+
- **Uninstall:** \`caik uninstall <slug>\`
|
|
231
|
+
|
|
232
|
+
## MCP Tools
|
|
233
|
+
|
|
234
|
+
If the CAIK MCP server is configured, these tools are available:
|
|
235
|
+
|
|
236
|
+
| Tool | Description |
|
|
237
|
+
|------|-------------|
|
|
238
|
+
| \`search\` | Search the CAIK registry for artifacts |
|
|
239
|
+
| \`get_artifact\` | Get full details for an artifact by slug |
|
|
240
|
+
| \`install_artifact\` | Install an artifact into the current project |
|
|
241
|
+
| \`report_outcome\` | Report whether an artifact worked well or poorly |
|
|
242
|
+
|
|
243
|
+
## Discovery
|
|
244
|
+
|
|
245
|
+
Ask your agent: "Find CAIK artifacts for [your use case]" to search the registry.
|
|
246
|
+
`;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// src/format.ts
|
|
250
|
+
import chalk from "chalk";
|
|
251
|
+
import ora from "ora";
|
|
252
|
+
import Table from "cli-table3";
|
|
253
|
+
function success(msg) {
|
|
254
|
+
return chalk.green(`\u2713 ${msg}`);
|
|
255
|
+
}
|
|
256
|
+
function error(msg) {
|
|
257
|
+
return chalk.red(`\u2717 ${msg}`);
|
|
258
|
+
}
|
|
259
|
+
function info(msg) {
|
|
260
|
+
return chalk.cyan(`\u2192 ${msg}`);
|
|
261
|
+
}
|
|
262
|
+
function warn(msg) {
|
|
263
|
+
return chalk.yellow(`\u26A0 ${msg}`);
|
|
264
|
+
}
|
|
265
|
+
function dim(msg) {
|
|
266
|
+
return chalk.dim(msg);
|
|
267
|
+
}
|
|
268
|
+
function bold(msg) {
|
|
269
|
+
return chalk.bold(msg);
|
|
270
|
+
}
|
|
271
|
+
function heading(msg) {
|
|
272
|
+
return chalk.bold.white(msg);
|
|
273
|
+
}
|
|
274
|
+
function primary(msg) {
|
|
275
|
+
return chalk.hex("#ea580c")(msg);
|
|
276
|
+
}
|
|
277
|
+
function createSpinner(text) {
|
|
278
|
+
return ora({ text, color: "cyan" });
|
|
279
|
+
}
|
|
280
|
+
function renderTable(headers, rows) {
|
|
281
|
+
const table = new Table({
|
|
282
|
+
head: headers.map((h) => chalk.bold.cyan(h)),
|
|
283
|
+
style: { head: [], border: ["dim"] },
|
|
284
|
+
chars: {
|
|
285
|
+
top: "\u2500",
|
|
286
|
+
"top-mid": "\u252C",
|
|
287
|
+
"top-left": "\u250C",
|
|
288
|
+
"top-right": "\u2510",
|
|
289
|
+
bottom: "\u2500",
|
|
290
|
+
"bottom-mid": "\u2534",
|
|
291
|
+
"bottom-left": "\u2514",
|
|
292
|
+
"bottom-right": "\u2518",
|
|
293
|
+
left: "\u2502",
|
|
294
|
+
"left-mid": "\u251C",
|
|
295
|
+
mid: "\u2500",
|
|
296
|
+
"mid-mid": "\u253C",
|
|
297
|
+
right: "\u2502",
|
|
298
|
+
"right-mid": "\u2524",
|
|
299
|
+
middle: "\u2502"
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
for (const row of rows) {
|
|
303
|
+
table.push(row);
|
|
304
|
+
}
|
|
305
|
+
return table.toString();
|
|
306
|
+
}
|
|
307
|
+
function outputResult(data, opts) {
|
|
308
|
+
if (opts.json) {
|
|
309
|
+
console.log(JSON.stringify(data, null, 2));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function formatNumber(n) {
|
|
313
|
+
return n.toLocaleString("en-US");
|
|
314
|
+
}
|
|
315
|
+
function truncate(str, maxLen) {
|
|
316
|
+
if (str.length <= maxLen) return str;
|
|
317
|
+
return str.slice(0, maxLen - 1) + "\u2026";
|
|
318
|
+
}
|
|
319
|
+
function termWidth() {
|
|
320
|
+
return process.stdout.columns || 80;
|
|
321
|
+
}
|
|
322
|
+
function rightAlign(left, right, totalWidth = 70) {
|
|
323
|
+
const stripAnsi = (s) => s.replace(/\x1B\[[0-9;]*m/g, "");
|
|
324
|
+
const visibleLeft = stripAnsi(left).length;
|
|
325
|
+
const visibleRight = stripAnsi(right).length;
|
|
326
|
+
const gap = Math.max(1, totalWidth - visibleLeft - visibleRight);
|
|
327
|
+
return left + " ".repeat(gap) + right;
|
|
328
|
+
}
|
|
329
|
+
function secondary(msg) {
|
|
330
|
+
return chalk.hex("#2563EB")(msg);
|
|
331
|
+
}
|
|
332
|
+
function qualityGrade(score) {
|
|
333
|
+
if (score == null) return dim("\u2014");
|
|
334
|
+
if (score >= 81) return chalk.green(`A (${score})`);
|
|
335
|
+
if (score >= 61) return chalk.hex("#2563EB")(`B (${score})`);
|
|
336
|
+
if (score >= 41) return chalk.yellow(`C (${score})`);
|
|
337
|
+
return chalk.dim(`D (${score})`);
|
|
338
|
+
}
|
|
339
|
+
function trustBadgeInline(level) {
|
|
340
|
+
switch (level) {
|
|
341
|
+
case "safe":
|
|
342
|
+
return chalk.green("\u2713 safe");
|
|
343
|
+
case "cautioned":
|
|
344
|
+
return chalk.yellow("\u26A0 cautioned");
|
|
345
|
+
case "untrusted":
|
|
346
|
+
return chalk.red("\u2717 untrusted");
|
|
347
|
+
default:
|
|
348
|
+
return "";
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function adoptionSignal(installCount, ecosystemInstalls, githubStars) {
|
|
352
|
+
if (ecosystemInstalls > 100) {
|
|
353
|
+
return `${dim("\u2193")} ${compactNumber(ecosystemInstalls)}`;
|
|
354
|
+
}
|
|
355
|
+
if (installCount > 0) {
|
|
356
|
+
return `${dim("\u2193")} ${compactNumber(installCount)}`;
|
|
357
|
+
}
|
|
358
|
+
if (githubStars > 0) {
|
|
359
|
+
return `\u2B50 ${compactNumber(githubStars)}`;
|
|
360
|
+
}
|
|
361
|
+
return "";
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// src/commands/setup.ts
|
|
365
|
+
function getHookConfig(platform) {
|
|
366
|
+
if (platform === "claude-code") {
|
|
367
|
+
return {
|
|
368
|
+
hooks: {
|
|
369
|
+
SessionStart: [{ type: "command", command: `npx -y ${CLI_NPX_PACKAGE} hook session-start` }],
|
|
370
|
+
PostToolUse: [{ type: "command", command: `npx -y ${CLI_NPX_PACKAGE} hook post-tool-use` }],
|
|
371
|
+
SessionEnd: [{ type: "command", command: `npx -y ${CLI_NPX_PACKAGE} hook session-end` }]
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
if (platform === "cursor") {
|
|
376
|
+
return {
|
|
377
|
+
hooks: {
|
|
378
|
+
sessionStart: `npx -y ${CLI_NPX_PACKAGE} hook cursor-session-start`,
|
|
379
|
+
beforeMCPExecution: `npx -y ${CLI_NPX_PACKAGE} hook cursor-mcp-exec`,
|
|
380
|
+
stop: `npx -y ${CLI_NPX_PACKAGE} hook cursor-session-end`
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
hooks: {
|
|
386
|
+
session_start: `npx -y ${CLI_NPX_PACKAGE} hook session-start --platform openclaw`,
|
|
387
|
+
session_end: `npx -y ${CLI_NPX_PACKAGE} hook session-end --platform openclaw`,
|
|
388
|
+
after_tool_call: `npx -y ${CLI_NPX_PACKAGE} hook post-tool-use --platform openclaw`
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
async function runRepair() {
|
|
393
|
+
console.log(heading("\nCAIK Repair"));
|
|
394
|
+
console.log("\u2550".repeat(40));
|
|
395
|
+
console.log();
|
|
396
|
+
const spinner = createSpinner("Detecting platforms...");
|
|
397
|
+
spinner.start();
|
|
398
|
+
const detected = detectPlatforms();
|
|
399
|
+
spinner.stop();
|
|
400
|
+
if (detected.length === 0) {
|
|
401
|
+
console.log(warn("No supported agent platforms detected. Nothing to repair."));
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
console.log(info(`Detected ${detected.length} platform(s): ${detected.map((p) => p.name).join(", ")}`));
|
|
405
|
+
console.log();
|
|
406
|
+
let repairedMcp = 0;
|
|
407
|
+
let repairedHooks = 0;
|
|
408
|
+
let repairedSkills = 0;
|
|
409
|
+
let pluginCleaned = 0;
|
|
410
|
+
const registryWarnings = [];
|
|
411
|
+
const hasClaudeCode = detected.some((p) => p.name === "claude-code");
|
|
412
|
+
if (hasClaudeCode) {
|
|
413
|
+
const { ClaudeCodeAdapter } = await import("./claude-code-6DF4YARB.js");
|
|
414
|
+
const ccAdapter = new ClaudeCodeAdapter();
|
|
415
|
+
if (ccAdapter.isPluginInstalled()) {
|
|
416
|
+
const cleaned = ccAdapter.cleanupManualRegistration();
|
|
417
|
+
if (cleaned.length > 0) {
|
|
418
|
+
console.log(heading("Plugin cleanup"));
|
|
419
|
+
console.log("\u2500".repeat(40));
|
|
420
|
+
console.log(info("CAIK plugin detected \u2014 removing superseded manual registrations:"));
|
|
421
|
+
for (const item of cleaned) {
|
|
422
|
+
console.log(` ${success(item)}`);
|
|
423
|
+
pluginCleaned++;
|
|
424
|
+
}
|
|
425
|
+
console.log();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const hasCursor = detected.some((p) => p.name === "cursor");
|
|
430
|
+
if (hasCursor) {
|
|
431
|
+
const { CursorAdapter } = await import("./cursor-Z4XXDCAM.js");
|
|
432
|
+
const cursorAdapter = new CursorAdapter();
|
|
433
|
+
if (cursorAdapter.isPluginInstalled()) {
|
|
434
|
+
const cleaned = cursorAdapter.cleanupManualRegistration();
|
|
435
|
+
if (cleaned.length > 0) {
|
|
436
|
+
console.log(heading("Cursor plugin cleanup"));
|
|
437
|
+
console.log("\u2500".repeat(40));
|
|
438
|
+
console.log(info("CAIK plugin detected \u2014 removing superseded manual registrations:"));
|
|
439
|
+
for (const item of cleaned) {
|
|
440
|
+
console.log(` ${success(item)}`);
|
|
441
|
+
pluginCleaned++;
|
|
442
|
+
}
|
|
443
|
+
console.log();
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
for (const platform of detected) {
|
|
448
|
+
console.log(heading(`Checking ${platform.name}...`));
|
|
449
|
+
console.log("\u2500".repeat(40));
|
|
450
|
+
const adapter = getPlatformAdapter(platform.name);
|
|
451
|
+
let mcpRegistered = false;
|
|
452
|
+
try {
|
|
453
|
+
mcpRegistered = await adapter.isRegistered();
|
|
454
|
+
} catch {
|
|
455
|
+
}
|
|
456
|
+
if (mcpRegistered) {
|
|
457
|
+
console.log(` MCP server: ${success("registered")}`);
|
|
458
|
+
} else {
|
|
459
|
+
const mcpSpinner = createSpinner(" Re-registering MCP server...");
|
|
460
|
+
mcpSpinner.start();
|
|
461
|
+
try {
|
|
462
|
+
const mcpConfig = getDefaultMcpConfig();
|
|
463
|
+
await adapter.registerMcp(mcpConfig);
|
|
464
|
+
mcpSpinner.stop();
|
|
465
|
+
console.log(` MCP server: ${success("repaired")} (re-registered)`);
|
|
466
|
+
repairedMcp++;
|
|
467
|
+
} catch (err) {
|
|
468
|
+
mcpSpinner.stop();
|
|
469
|
+
console.log(` MCP server: ${error(`repair failed: ${err instanceof Error ? err.message : String(err)}`)}`);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (adapter.registerHooks && platform.capabilities.hooks) {
|
|
473
|
+
const hookSpinner = createSpinner(" Ensuring hooks are registered...");
|
|
474
|
+
hookSpinner.start();
|
|
475
|
+
try {
|
|
476
|
+
const hookConfig = getHookConfig(platform.name);
|
|
477
|
+
await adapter.registerHooks(hookConfig);
|
|
478
|
+
hookSpinner.stop();
|
|
479
|
+
console.log(` Hooks: ${success("ensured")}`);
|
|
480
|
+
repairedHooks++;
|
|
481
|
+
} catch (err) {
|
|
482
|
+
hookSpinner.stop();
|
|
483
|
+
console.log(` Hooks: ${error(`repair failed: ${err instanceof Error ? err.message : String(err)}`)}`);
|
|
484
|
+
}
|
|
485
|
+
} else if (!platform.capabilities.hooks) {
|
|
486
|
+
console.log(` Hooks: ${dim("not supported on this platform")}`);
|
|
487
|
+
}
|
|
488
|
+
if (adapter.installSkill && platform.capabilities.skills) {
|
|
489
|
+
const skillSpinner = createSpinner(" Ensuring SKILL.md is installed...");
|
|
490
|
+
skillSpinner.start();
|
|
491
|
+
try {
|
|
492
|
+
const content = getSkillContent(platform.name);
|
|
493
|
+
await adapter.installSkill("caik", content);
|
|
494
|
+
skillSpinner.stop();
|
|
495
|
+
console.log(` SKILL.md: ${success("ensured")}`);
|
|
496
|
+
repairedSkills++;
|
|
497
|
+
try {
|
|
498
|
+
const { getAutoImproveSkills: getAutoImproveSkills2 } = await import("./auto-improve-skills-2COKTU5C.js");
|
|
499
|
+
const autoSkills = getAutoImproveSkills2();
|
|
500
|
+
for (const skill of autoSkills) {
|
|
501
|
+
await adapter.installSkill(skill.slug, skill.content);
|
|
502
|
+
}
|
|
503
|
+
const { mkdirSync } = await import("fs");
|
|
504
|
+
const { join } = await import("path");
|
|
505
|
+
const { homedir } = await import("os");
|
|
506
|
+
const caikDir = join(homedir(), ".caik");
|
|
507
|
+
mkdirSync(join(caikDir, "observations"), { recursive: true });
|
|
508
|
+
mkdirSync(join(caikDir, "versions"), { recursive: true });
|
|
509
|
+
console.log(` Auto-improve: ${success("ensured (3 skills + dirs)")}`);
|
|
510
|
+
} catch {
|
|
511
|
+
}
|
|
512
|
+
} catch (err) {
|
|
513
|
+
skillSpinner.stop();
|
|
514
|
+
console.log(` SKILL.md: ${error(`repair failed: ${err instanceof Error ? err.message : String(err)}`)}`);
|
|
515
|
+
}
|
|
516
|
+
} else if (!platform.capabilities.skills) {
|
|
517
|
+
console.log(` SKILL.md: ${dim("not supported on this platform")}`);
|
|
518
|
+
}
|
|
519
|
+
console.log();
|
|
520
|
+
}
|
|
521
|
+
const registryEntries = listRegistryEntries();
|
|
522
|
+
if (registryEntries.length > 0) {
|
|
523
|
+
console.log(heading("Registry Integrity"));
|
|
524
|
+
console.log("\u2500".repeat(40));
|
|
525
|
+
let cleanEntries = 0;
|
|
526
|
+
for (const entry of registryEntries) {
|
|
527
|
+
const missing = entry.files.filter((f) => !existsSync(f));
|
|
528
|
+
if (missing.length > 0) {
|
|
529
|
+
const msg = `${entry.slug} (${entry.platform}): ${missing.length} missing file(s)`;
|
|
530
|
+
registryWarnings.push(msg);
|
|
531
|
+
console.log(` ${warn(msg)}`);
|
|
532
|
+
for (const f of missing) {
|
|
533
|
+
console.log(` ${dim(f)}`);
|
|
534
|
+
}
|
|
535
|
+
} else {
|
|
536
|
+
cleanEntries++;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (registryWarnings.length === 0) {
|
|
540
|
+
console.log(` ${success("All")} ${registryEntries.length} registry entries have their files intact.`);
|
|
541
|
+
} else if (cleanEntries > 0) {
|
|
542
|
+
console.log(` ${success(`${cleanEntries}`)} entries OK, ${warn(`${registryWarnings.length}`)} with missing files.`);
|
|
543
|
+
}
|
|
544
|
+
if (registryWarnings.length > 0) {
|
|
545
|
+
console.log();
|
|
546
|
+
console.log(
|
|
547
|
+
dim(" Artifact files cannot be auto-repaired. Run `caik install <slug>` to reinstall.")
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
console.log();
|
|
551
|
+
}
|
|
552
|
+
console.log(heading("Repair Summary"));
|
|
553
|
+
console.log("\u2550".repeat(40));
|
|
554
|
+
const actions = [];
|
|
555
|
+
if (pluginCleaned > 0) actions.push(`${pluginCleaned} manual registration(s) cleaned up (plugin active)`);
|
|
556
|
+
if (repairedMcp > 0) actions.push(`${repairedMcp} MCP registration(s) repaired`);
|
|
557
|
+
if (repairedHooks > 0) actions.push(`${repairedHooks} hook registration(s) ensured`);
|
|
558
|
+
if (repairedSkills > 0) actions.push(`${repairedSkills} skill installation(s) ensured`);
|
|
559
|
+
if (registryWarnings.length > 0) actions.push(`${registryWarnings.length} registry warning(s)`);
|
|
560
|
+
if (actions.length === 0) {
|
|
561
|
+
console.log(success("Everything looks good. No repairs needed."));
|
|
562
|
+
} else {
|
|
563
|
+
for (const a of actions) {
|
|
564
|
+
console.log(` ${info(a)}`);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
console.log();
|
|
568
|
+
}
|
|
569
|
+
function registerSetupCommand(program) {
|
|
570
|
+
program.command("setup", { hidden: true }).description("Interactive setup wizard \u2014 configure CAIK for your agent platforms").option("--platform <name>", "Skip detection, configure a specific platform").option("--skip-hooks", "Register MCP only, skip hook registration").option("--skip-stacks", "Skip stack recommendations").option("--repair", "Detect and fix configuration drift (re-register MCP, hooks, skills)").option("-y, --yes", "Accept all defaults (non-interactive)").addHelpText("after", `
|
|
571
|
+
Examples:
|
|
572
|
+
caik setup
|
|
573
|
+
caik setup --platform claude-code
|
|
574
|
+
caik setup --yes --skip-hooks
|
|
575
|
+
caik setup --repair`).action(async (opts) => {
|
|
576
|
+
const globalOpts = program.opts();
|
|
577
|
+
const { apiKey } = resolveConfig(globalOpts);
|
|
578
|
+
const skipHooks = Boolean(opts.skipHooks);
|
|
579
|
+
const skipStacks = Boolean(opts.skipStacks);
|
|
580
|
+
const autoYes = Boolean(opts.yes);
|
|
581
|
+
const platformFlag = opts.platform;
|
|
582
|
+
const repair = Boolean(opts.repair);
|
|
583
|
+
console.log(dim("Note: `caik setup` is now `caik init`. Consider using `caik init` instead."));
|
|
584
|
+
if (repair) {
|
|
585
|
+
await runRepair();
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
console.log(heading("\nCAIK Setup Wizard"));
|
|
589
|
+
console.log("\u2550".repeat(40));
|
|
590
|
+
console.log();
|
|
591
|
+
let detected;
|
|
592
|
+
if (platformFlag) {
|
|
593
|
+
const adapter = getPlatformAdapter(platformFlag);
|
|
594
|
+
const det = await adapter.detect();
|
|
595
|
+
if (det) {
|
|
596
|
+
detected = [det];
|
|
597
|
+
} else {
|
|
598
|
+
detected = [{
|
|
599
|
+
name: platformFlag,
|
|
600
|
+
tier: "cli-mcp",
|
|
601
|
+
configPaths: [],
|
|
602
|
+
capabilities: { hooks: false, mcp: true, skills: false }
|
|
603
|
+
}];
|
|
604
|
+
console.log(warn(`Platform "${platformFlag}" was not detected but will be configured anyway.`));
|
|
605
|
+
}
|
|
606
|
+
} else {
|
|
607
|
+
const spinner = createSpinner("Detecting installed platforms...");
|
|
608
|
+
spinner.start();
|
|
609
|
+
detected = detectPlatforms();
|
|
610
|
+
spinner.stop();
|
|
611
|
+
if (detected.length === 0) {
|
|
612
|
+
console.log(warn("No supported agent platforms detected."));
|
|
613
|
+
console.log(info("Supported platforms: claude-code, cursor, openclaw, codex, windsurf, copilot, gemini-cli, aider, cline, roo-code, amazon-q, devin, goose, warp, zed, augment, replit, and more"));
|
|
614
|
+
console.log(info("Use --platform <name> to configure a specific platform."));
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
console.log(info(`Detected ${detected.length} platform(s):`));
|
|
618
|
+
for (const p of detected) {
|
|
619
|
+
console.log(` ${success(p.name)} ${dim(`(${p.tier})`)}`);
|
|
620
|
+
}
|
|
621
|
+
console.log();
|
|
622
|
+
}
|
|
623
|
+
let selected;
|
|
624
|
+
if (autoYes || detected.length === 1 || platformFlag) {
|
|
625
|
+
selected = detected;
|
|
626
|
+
} else {
|
|
627
|
+
selected = await checkbox({
|
|
628
|
+
message: "Which platforms would you like to configure?",
|
|
629
|
+
choices: detected.map((p) => ({
|
|
630
|
+
name: `${p.name} ${dim(`(${p.tier})`)}`,
|
|
631
|
+
value: p,
|
|
632
|
+
checked: true
|
|
633
|
+
}))
|
|
634
|
+
});
|
|
635
|
+
if (selected.length === 0) {
|
|
636
|
+
console.log(warn("No platforms selected. Exiting."));
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
console.log();
|
|
641
|
+
for (const platform of selected) {
|
|
642
|
+
console.log(heading(`Configuring ${platform.name}...`));
|
|
643
|
+
console.log("\u2500".repeat(40));
|
|
644
|
+
const adapter = getPlatformAdapter(platform.name);
|
|
645
|
+
const mcpConfig = getDefaultMcpConfig();
|
|
646
|
+
const mcpSpinner = createSpinner("Registering MCP server...");
|
|
647
|
+
mcpSpinner.start();
|
|
648
|
+
try {
|
|
649
|
+
await adapter.registerMcp(mcpConfig);
|
|
650
|
+
mcpSpinner.stop();
|
|
651
|
+
console.log(success("MCP server registered"));
|
|
652
|
+
} catch (err) {
|
|
653
|
+
mcpSpinner.stop();
|
|
654
|
+
console.log(error(`Failed to register MCP server: ${err instanceof Error ? err.message : String(err)}`));
|
|
655
|
+
}
|
|
656
|
+
if (!skipHooks && adapter.registerHooks && platform.capabilities.hooks) {
|
|
657
|
+
const hookSpinner = createSpinner("Registering hooks...");
|
|
658
|
+
hookSpinner.start();
|
|
659
|
+
try {
|
|
660
|
+
const hookConfig = getHookConfig(platform.name);
|
|
661
|
+
await adapter.registerHooks(hookConfig);
|
|
662
|
+
hookSpinner.stop();
|
|
663
|
+
console.log(success("Hooks registered"));
|
|
664
|
+
if (platform.name === "openclaw") {
|
|
665
|
+
console.log(dim(" Restart the OpenClaw gateway to load hooks: openclaw daemon restart"));
|
|
666
|
+
}
|
|
667
|
+
} catch (err) {
|
|
668
|
+
hookSpinner.stop();
|
|
669
|
+
console.log(error(`Failed to register hooks: ${err instanceof Error ? err.message : String(err)}`));
|
|
670
|
+
}
|
|
671
|
+
} else if (!skipHooks && !platform.capabilities.hooks) {
|
|
672
|
+
console.log(dim(" Hooks not supported on this platform \u2014 skipped"));
|
|
673
|
+
} else if (skipHooks) {
|
|
674
|
+
console.log(dim(" Hooks skipped (--skip-hooks)"));
|
|
675
|
+
}
|
|
676
|
+
if (adapter.installSkill && platform.capabilities.skills) {
|
|
677
|
+
const skillSpinner = createSpinner("Installing SKILL.md...");
|
|
678
|
+
skillSpinner.start();
|
|
679
|
+
try {
|
|
680
|
+
const content = getSkillContent(platform.name);
|
|
681
|
+
await adapter.installSkill("caik", content);
|
|
682
|
+
skillSpinner.stop();
|
|
683
|
+
console.log(success("SKILL.md installed"));
|
|
684
|
+
} catch (err) {
|
|
685
|
+
skillSpinner.stop();
|
|
686
|
+
console.log(error(`Failed to install SKILL.md: ${err instanceof Error ? err.message : String(err)}`));
|
|
687
|
+
}
|
|
688
|
+
const improveSpinner = createSpinner("Installing auto-improvement stack...");
|
|
689
|
+
improveSpinner.start();
|
|
690
|
+
try {
|
|
691
|
+
const { getAutoImproveSkills: getAutoImproveSkills2 } = await import("./auto-improve-skills-2COKTU5C.js");
|
|
692
|
+
const autoSkills = getAutoImproveSkills2();
|
|
693
|
+
for (const skill of autoSkills) {
|
|
694
|
+
await adapter.installSkill(skill.slug, skill.content);
|
|
695
|
+
}
|
|
696
|
+
const { mkdirSync } = await import("fs");
|
|
697
|
+
const { join } = await import("path");
|
|
698
|
+
const { homedir } = await import("os");
|
|
699
|
+
const caikDir = join(homedir(), ".caik");
|
|
700
|
+
mkdirSync(join(caikDir, "observations"), { recursive: true });
|
|
701
|
+
mkdirSync(join(caikDir, "versions"), { recursive: true });
|
|
702
|
+
improveSpinner.stop();
|
|
703
|
+
console.log(success("Auto-improvement stack installed (3 skills + daemon)"));
|
|
704
|
+
} catch (err) {
|
|
705
|
+
improveSpinner.stop();
|
|
706
|
+
console.log(dim(`Auto-improvement: skipped (${err instanceof Error ? err.message : "error"})`));
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
console.log();
|
|
710
|
+
}
|
|
711
|
+
if (!skipStacks) {
|
|
712
|
+
console.log(dim("Stack recommendations: coming soon"));
|
|
713
|
+
console.log();
|
|
714
|
+
}
|
|
715
|
+
if (!apiKey) {
|
|
716
|
+
console.log(warn("Not authenticated. Run `caik init --auth` to connect your account."));
|
|
717
|
+
console.log();
|
|
718
|
+
} else {
|
|
719
|
+
try {
|
|
720
|
+
const { CaikApiClient } = await import("./api-6OX4ICXN.js");
|
|
721
|
+
const config = readConfig();
|
|
722
|
+
const installationId = getOrCreateInstallationId();
|
|
723
|
+
const registryEntries = listRegistryEntries();
|
|
724
|
+
const client = new CaikApiClient({ apiUrl: config.apiUrl, apiKey });
|
|
725
|
+
await client.post("/installations/register", {
|
|
726
|
+
installationId,
|
|
727
|
+
platform: selected[0]?.name ?? "claude-code",
|
|
728
|
+
contributionLevel: config.contributionLevel ?? "contributor",
|
|
729
|
+
installedArtifacts: registryEntries.map((e) => ({
|
|
730
|
+
slug: e.slug,
|
|
731
|
+
version: e.version,
|
|
732
|
+
installedAt: e.installedAt
|
|
733
|
+
}))
|
|
734
|
+
});
|
|
735
|
+
console.log(success(`Installation registered (${installationId.slice(0, 12)}...)`));
|
|
736
|
+
} catch {
|
|
737
|
+
}
|
|
738
|
+
console.log();
|
|
739
|
+
}
|
|
740
|
+
console.log(heading("Setup Complete"));
|
|
741
|
+
console.log("\u2550".repeat(40));
|
|
742
|
+
console.log(success(`Configured ${selected.length} platform(s): ${selected.map((p) => p.name).join(", ")}`));
|
|
743
|
+
if (!apiKey) {
|
|
744
|
+
console.log(info("Next step: run `caik init --auth` to authenticate"));
|
|
745
|
+
} else {
|
|
746
|
+
console.log(info("Next step: run `caik search <query>` to find artifacts"));
|
|
747
|
+
}
|
|
748
|
+
console.log();
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
export {
|
|
753
|
+
success,
|
|
754
|
+
error,
|
|
755
|
+
info,
|
|
756
|
+
warn,
|
|
757
|
+
dim,
|
|
758
|
+
bold,
|
|
759
|
+
heading,
|
|
760
|
+
primary,
|
|
761
|
+
createSpinner,
|
|
762
|
+
renderTable,
|
|
763
|
+
outputResult,
|
|
764
|
+
formatNumber,
|
|
765
|
+
truncate,
|
|
766
|
+
termWidth,
|
|
767
|
+
rightAlign,
|
|
768
|
+
secondary,
|
|
769
|
+
qualityGrade,
|
|
770
|
+
trustBadgeInline,
|
|
771
|
+
adoptionSignal,
|
|
772
|
+
getSkillContent,
|
|
773
|
+
runRepair,
|
|
774
|
+
registerSetupCommand
|
|
775
|
+
};
|