pikakit 1.0.0 → 1.0.2

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/bin/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  /**
3
3
  * Agent Skill Kit CLI - Main Entry Point
4
4
  * Using .mjs extension for Windows npx compatibility
@@ -177,36 +177,36 @@ export async function run(spec) {
177
177
  // NOTE: Order matters! Specialized categories FIRST, Core is fallback
178
178
  const CATEGORY_KEYWORDS = {
179
179
  // Specialized domains
180
- "🎨 Frontend & UI": [
180
+ "🎨 Frontend & UI": [
181
181
  "frontend", "nextjs", "tailwind", "css", "ui", "ux", "visual",
182
182
  "studio", "web-core", "design-system", "react-architect", "react"
183
183
  ],
184
- "🎮 Game Development": [
184
+ "🎮 Game Development": [
185
185
  "game", "development", "engine", "unity", "unreal", "godot", "phaser"
186
186
  ],
187
- "📱 Mobile": [
187
+ "📱 Mobile": [
188
188
  "mobile", "first", "developer", "react-native", "flutter",
189
189
  "ios", "android", "swift", "kotlin"
190
190
  ],
191
- "🔒 Security & DevOps": [
191
+ "🔒 Security & DevOps": [
192
192
  "security", "vulnerability", "offensive", "scanner", "red-team", "governance",
193
193
  "cicd", "pipeline", "gitops", "docker", "deploy", "server-ops"
194
194
  ],
195
195
  // Technical domains
196
- "🧪 Testing & Quality": [
196
+ "🧪 Testing & Quality": [
197
197
  "test", "testing", "tdd", "e2e", "debug", "quality", "review",
198
198
  "lint", "validate", "automation", "problem", "checker"
199
199
  ],
200
- "🤖 AI & Agents": [
200
+ "🤖 AI & Agents": [
201
201
  "agent", "pattern", "auto-learn", "execution", "self-evolution",
202
202
  "lifecycle", "skill-forge", "intelligent", "routing"
203
203
  ],
204
- "📚 Docs & Planning": [
204
+ "📚 Docs & Planning": [
205
205
  "doc", "template", "plan", "project", "idea", "brainstorm",
206
206
  "geo", "seo", "i18n", "writing"
207
207
  ],
208
208
  // Fallback (core backend/infra)
209
- "⚙️ Backend & Core": [
209
+ "⚙️ Backend & Core": [
210
210
  "backend", "api", "nodejs", "python", "server", "database",
211
211
  "prisma", "mcp", "data", "architect", "scaffold", "system",
212
212
  "typescript", "shell", "bash", "powershell", "git", "code-craft",
@@ -221,7 +221,7 @@ export async function run(spec) {
221
221
  return category;
222
222
  }
223
223
  }
224
- return "⚙️ Backend & Core"; // Default fallback (no "Other" category)
224
+ return "⚙️ Backend & Core"; // Default fallback (no "Other" category)
225
225
  }
226
226
 
227
227
  // REQUIRED SKILLS - Always installed, not shown in selection
package/bin/lib/ui.js CHANGED
@@ -1,329 +1,329 @@
1
- /**
2
- * @fileoverview UI components - Install Agent Skill theme
3
- */
4
-
5
- import kleur from "kleur";
6
- import boxen from "boxen";
7
- import { intro, outro, multiselect, select, confirm, isCancel, cancel, text } from "@clack/prompts";
8
- import ora from "ora";
9
- import gradient from "gradient-string";
10
-
11
- export { intro, outro, multiselect, select, confirm, isCancel, cancel, text };
12
-
13
- // --- ASCII Art Banner ---
14
- const PIKAKIT_BANNER = `
15
- ____ _ _ _ ___ _
16
- | _ \\(_) | ____ _| |/ (_) |_
17
- | |_) | | |/ / _\` | ' /| | __|
18
- | __/| | < (_| | . \\| | |_
19
- |_| |_|_|\\_\\__,_|_|\\_\\_|\\__|
20
- `;
21
-
22
- // Custom gradient: white → gray (like vercel style)
23
- const pikaGradient = gradient(['#ffffff', '#bbbbbb', '#888888', '#555555']);
24
-
25
- /**
26
- * Create a spinner
27
- */
28
- export function spinner() {
29
- return {
30
- _s: null,
31
- start(msg) {
32
- this._s = ora({
33
- text: " " + msg,
34
- prefixText: "",
35
- color: "blue",
36
- spinner: {
37
- interval: 80,
38
- frames: ['◒', '◐', '◓', '◑']
39
- }
40
- }).start();
41
- },
42
- stop(msg) {
43
- if (this._s) {
44
- this._s.stopAndPersist({
45
- symbol: c.cyan(S.diamond),
46
- text: " " + msg
47
- });
48
- }
49
- },
50
- fail(msg) {
51
- if (this._s) {
52
- this._s.stopAndPersist({
53
- symbol: c.red(S.cross),
54
- text: " " + msg
55
- });
56
- }
57
- },
58
- message(msg) {
59
- if (this._s) this._s.text = " " + msg;
60
- }
61
- };
62
- }
63
-
64
- // --- Symbols ---
65
-
66
- /** UI symbols for tree structure */
67
- export const S = {
68
- branch: "│",
69
- diamond: "â—‡",
70
- diamondFilled: "â—†",
71
- check: "✓",
72
- cross: "x",
73
- arrow: "→"
74
- };
75
-
76
- // --- Colors ---
77
-
78
- /** Color helper functions */
79
- export const c = {
80
- cyan: kleur.cyan,
81
- gray: kleur.gray,
82
- green: kleur.green,
83
- red: kleur.red,
84
- yellow: kleur.yellow,
85
- magenta: kleur.magenta,
86
- blue: kleur.blue,
87
- white: kleur.white,
88
- bgBlue: kleur.bgBlue,
89
- bold: kleur.bold,
90
- dim: kleur.dim,
91
- inverse: kleur.inverse
92
- };
93
-
94
- // --- UI Functions ---
95
-
96
- /**
97
- * Print a step in the tree
98
- * @param {string} text - Step text
99
- * @param {string} [icon] - Icon to use
100
- * @param {keyof typeof c} [color] - Color name
101
- */
102
- export function step(text, icon = S.diamond, color = "cyan") {
103
- const colorFn = c[color] || c.cyan;
104
- console.log(`${colorFn(icon)} ${text}`);
105
- }
106
-
107
- /**
108
- * Print an active step (Blue Filled Diamond)
109
- * @param {string} text - Step text
110
- */
111
- export function activeStep(text) {
112
- console.log(`${c.blue(S.diamondFilled)} ${text}`);
113
- }
114
-
115
- /**
116
- * Print empty branch line
117
- */
118
- export function stepLine() {
119
- console.log(`${c.gray(S.branch)}`);
120
- }
121
-
122
- /**
123
- * Print fatal error and exit
124
- * @param {string} msg - Error message
125
- */
126
- export function fatal(msg) {
127
- console.log(`${c.red(S.cross)} ${c.red(msg)}`);
128
- process.exit(1);
129
- }
130
-
131
- /**
132
- * Print success message
133
- * @param {string} msg - Success message
134
- */
135
- export function success(msg) {
136
- console.log(`${c.cyan(S.diamond)} ${c.cyan(msg)}`);
137
- }
138
-
139
- /**
140
- * Output JSON if JSON_OUTPUT mode
141
- * @param {any} data - Data to output
142
- * @param {boolean} jsonMode - Whether to output JSON
143
- */
144
- export function outputJSON(data, jsonMode) {
145
- if (jsonMode) console.log(JSON.stringify(data, null, 2));
146
- }
147
-
148
- /**
149
- * Create a nice box message
150
- * @param {string} message - Message content
151
- * @param {object} options - Box options
152
- */
153
- export function box(message, options = {}) {
154
- return "\n" + boxen(message, {
155
- padding: { top: 0, bottom: 0, left: 1, right: 1 },
156
- margin: { top: 0, bottom: 0, left: 0, right: 0 },
157
- borderStyle: "round",
158
- borderColor: "blue",
159
- ...options
160
- });
161
- }
162
-
163
- /**
164
- * Show branded intro with version (matches agent CLI style)
165
- * @param {string} version - Package version
166
- * @param {string} [status] - Optional status text
167
- */
168
- export function brandedIntro(version, status = "") {
169
- // Split banner and filter to get content lines only
170
- const bannerLines = PIKAKIT_BANNER.split('\n').filter(line => line.trim() !== '');
171
-
172
- // Print all lines except the last with gradient
173
- for (let i = 0; i < bannerLines.length - 1; i++) {
174
- console.log(pikaGradient(bannerLines[i]));
175
- }
176
-
177
- // Last line: gradient ASCII + dim version (aligned at bottom)
178
- const lastLine = bannerLines[bannerLines.length - 1];
179
- console.log(pikaGradient(lastLine) + ` ${c.dim(`v${version}`)}`);
180
-
181
-
182
- if (status) {
183
- console.log(`${c.dim(status)}`);
184
- }
185
- }
186
-
187
- // --- Vercel-Style Installation Prompts ---
188
-
189
- /**
190
- * Prompt user to select which agents to install to
191
- * @param {Array<{name: string, displayName: string, skillsDir: string}>} detectedAgents
192
- * @returns {Promise<Array<{name: string, displayName: string, skillsDir: string}> | null>}
193
- */
194
- export async function selectAgentsPrompt(detectedAgents) {
195
- if (detectedAgents.length === 0) {
196
- return null;
197
- }
198
-
199
- // First ask: All detected or select specific?
200
- const installChoice = await select({
201
- message: "Install to",
202
- options: [
203
- {
204
- value: "all",
205
- label: `All detected agents (Recommended)`,
206
- hint: `Install to all ${detectedAgents.length} detected agents`
207
- },
208
- {
209
- value: "select",
210
- label: "Select specific agents",
211
- hint: "Choose which agents to install to"
212
- }
213
- ]
214
- });
215
-
216
- if (isCancel(installChoice)) {
217
- cancel("Installation cancelled");
218
- return null;
219
- }
220
-
221
- if (installChoice === "all") {
222
- return detectedAgents;
223
- }
224
-
225
- // Let user select specific agents
226
- const selectedAgents = await multiselect({
227
- message: "Select agents to install skills to",
228
- options: detectedAgents.map(agent => ({
229
- value: agent.name,
230
- label: agent.displayName,
231
- hint: agent.skillsDir
232
- })),
233
- required: true
234
- });
235
-
236
- if (isCancel(selectedAgents)) {
237
- cancel("Installation cancelled");
238
- return null;
239
- }
240
-
241
- return detectedAgents.filter(a => selectedAgents.includes(a.name));
242
- }
243
-
244
- /**
245
- * Prompt user to select installation scope (Project or Global)
246
- * @returns {Promise<"project" | "global" | null>}
247
- */
248
- export async function selectScopePrompt() {
249
- const scope = await select({
250
- message: "Installation scope",
251
- options: [
252
- {
253
- value: "project",
254
- label: "Project",
255
- hint: "Install in current directory (committed with your project)"
256
- },
257
- {
258
- value: "global",
259
- label: "Global",
260
- hint: "Install globally (available across all projects)"
261
- }
262
- ]
263
- });
264
-
265
- if (isCancel(scope)) {
266
- cancel("Installation cancelled");
267
- return null;
268
- }
269
-
270
- return scope;
271
- }
272
-
273
- /**
274
- * Prompt user to select installation method (Symlink or Copy)
275
- * @returns {Promise<"symlink" | "copy" | null>}
276
- */
277
- export async function selectMethodPrompt() {
278
- const method = await select({
279
- message: "Installation method",
280
- options: [
281
- {
282
- value: "symlink",
283
- label: "Symlink (Recommended)",
284
- hint: "Single source of truth, easy updates"
285
- },
286
- {
287
- value: "copy",
288
- label: "Copy to all agents",
289
- hint: "Independent copies for each agent"
290
- }
291
- ]
292
- });
293
-
294
- if (isCancel(method)) {
295
- cancel("Installation cancelled");
296
- return null;
297
- }
298
-
299
- return method;
300
- }
301
-
302
- /**
303
- * Prompt user to select skills to install (multiselect with descriptions)
304
- * @param {Array<{name: string, description: string, path: string}>} skills
305
- * @returns {Promise<Array<{name: string, description: string, path: string}> | null>}
306
- */
307
- export async function selectSkillsPrompt(skills) {
308
- if (skills.length === 0) {
309
- return null;
310
- }
311
-
312
- const selectedNames = await multiselect({
313
- message: "Select skills to install",
314
- options: skills.map(skill => ({
315
- value: skill.name,
316
- label: skill.name,
317
- hint: skill.description ? skill.description.substring(0, 60) + "..." : ""
318
- })),
319
- required: true
320
- });
321
-
322
- if (isCancel(selectedNames)) {
323
- cancel("Installation cancelled");
324
- return null;
325
- }
326
-
327
- return skills.filter(s => selectedNames.includes(s.name));
328
- }
329
-
1
+ /**
2
+ * @fileoverview UI components - Install Agent Skill theme
3
+ */
4
+
5
+ import kleur from "kleur";
6
+ import boxen from "boxen";
7
+ import { intro, outro, multiselect, select, confirm, isCancel, cancel, text } from "@clack/prompts";
8
+ import ora from "ora";
9
+ import gradient from "gradient-string";
10
+
11
+ export { intro, outro, multiselect, select, confirm, isCancel, cancel, text };
12
+
13
+ // --- ASCII Art Banner ---
14
+ const PIKAKIT_BANNER = `
15
+ ____ _ _ _ ___ _
16
+ | _ \\(_) | ____ _| |/ (_) |_
17
+ | |_) | | |/ / _\` | ' /| | __|
18
+ | __/| | < (_| | . \\| | |_
19
+ |_| |_|_|\\_\\__,_|_|\\_\\_|\\__|
20
+ `;
21
+
22
+ // Custom gradient: white gray (like vercel style)
23
+ const pikaGradient = gradient(['#ffffff', '#bbbbbb', '#888888', '#555555']);
24
+
25
+ /**
26
+ * Create a spinner
27
+ */
28
+ export function spinner() {
29
+ return {
30
+ _s: null,
31
+ start(msg) {
32
+ this._s = ora({
33
+ text: " " + msg,
34
+ prefixText: "",
35
+ color: "blue",
36
+ spinner: {
37
+ interval: 80,
38
+ frames: ['', '', '', '']
39
+ }
40
+ }).start();
41
+ },
42
+ stop(msg) {
43
+ if (this._s) {
44
+ this._s.stopAndPersist({
45
+ symbol: c.cyan(S.diamond),
46
+ text: " " + msg
47
+ });
48
+ }
49
+ },
50
+ fail(msg) {
51
+ if (this._s) {
52
+ this._s.stopAndPersist({
53
+ symbol: c.red(S.cross),
54
+ text: " " + msg
55
+ });
56
+ }
57
+ },
58
+ message(msg) {
59
+ if (this._s) this._s.text = " " + msg;
60
+ }
61
+ };
62
+ }
63
+
64
+ // --- Symbols ---
65
+
66
+ /** UI symbols for tree structure */
67
+ export const S = {
68
+ branch: "",
69
+ diamond: "",
70
+ diamondFilled: "",
71
+ check: "",
72
+ cross: "x",
73
+ arrow: ""
74
+ };
75
+
76
+ // --- Colors ---
77
+
78
+ /** Color helper functions */
79
+ export const c = {
80
+ cyan: kleur.cyan,
81
+ gray: kleur.gray,
82
+ green: kleur.green,
83
+ red: kleur.red,
84
+ yellow: kleur.yellow,
85
+ magenta: kleur.magenta,
86
+ blue: kleur.blue,
87
+ white: kleur.white,
88
+ bgBlue: kleur.bgBlue,
89
+ bold: kleur.bold,
90
+ dim: kleur.dim,
91
+ inverse: kleur.inverse
92
+ };
93
+
94
+ // --- UI Functions ---
95
+
96
+ /**
97
+ * Print a step in the tree
98
+ * @param {string} text - Step text
99
+ * @param {string} [icon] - Icon to use
100
+ * @param {keyof typeof c} [color] - Color name
101
+ */
102
+ export function step(text, icon = S.diamond, color = "cyan") {
103
+ const colorFn = c[color] || c.cyan;
104
+ console.log(`${colorFn(icon)} ${text}`);
105
+ }
106
+
107
+ /**
108
+ * Print an active step (Blue Filled Diamond)
109
+ * @param {string} text - Step text
110
+ */
111
+ export function activeStep(text) {
112
+ console.log(`${c.blue(S.diamondFilled)} ${text}`);
113
+ }
114
+
115
+ /**
116
+ * Print empty branch line
117
+ */
118
+ export function stepLine() {
119
+ console.log(`${c.gray(S.branch)}`);
120
+ }
121
+
122
+ /**
123
+ * Print fatal error and exit
124
+ * @param {string} msg - Error message
125
+ */
126
+ export function fatal(msg) {
127
+ console.log(`${c.red(S.cross)} ${c.red(msg)}`);
128
+ process.exit(1);
129
+ }
130
+
131
+ /**
132
+ * Print success message
133
+ * @param {string} msg - Success message
134
+ */
135
+ export function success(msg) {
136
+ console.log(`${c.cyan(S.diamond)} ${c.cyan(msg)}`);
137
+ }
138
+
139
+ /**
140
+ * Output JSON if JSON_OUTPUT mode
141
+ * @param {any} data - Data to output
142
+ * @param {boolean} jsonMode - Whether to output JSON
143
+ */
144
+ export function outputJSON(data, jsonMode) {
145
+ if (jsonMode) console.log(JSON.stringify(data, null, 2));
146
+ }
147
+
148
+ /**
149
+ * Create a nice box message
150
+ * @param {string} message - Message content
151
+ * @param {object} options - Box options
152
+ */
153
+ export function box(message, options = {}) {
154
+ return "\n" + boxen(message, {
155
+ padding: { top: 0, bottom: 0, left: 1, right: 1 },
156
+ margin: { top: 0, bottom: 0, left: 0, right: 0 },
157
+ borderStyle: "round",
158
+ borderColor: "blue",
159
+ ...options
160
+ });
161
+ }
162
+
163
+ /**
164
+ * Show branded intro with version (matches agent CLI style)
165
+ * @param {string} version - Package version
166
+ * @param {string} [status] - Optional status text
167
+ */
168
+ export function brandedIntro(version, status = "") {
169
+ // Split banner and filter to get content lines only
170
+ const bannerLines = PIKAKIT_BANNER.split('\n').filter(line => line.trim() !== '');
171
+
172
+ // Print all lines except the last with gradient
173
+ for (let i = 0; i < bannerLines.length - 1; i++) {
174
+ console.log(pikaGradient(bannerLines[i]));
175
+ }
176
+
177
+ // Last line: gradient ASCII + dim version (aligned at bottom)
178
+ const lastLine = bannerLines[bannerLines.length - 1];
179
+ console.log(pikaGradient(lastLine) + ` ${c.dim(`v${version}`)}`);
180
+
181
+
182
+ if (status) {
183
+ console.log(`${c.dim(status)}`);
184
+ }
185
+ }
186
+
187
+ // --- Vercel-Style Installation Prompts ---
188
+
189
+ /**
190
+ * Prompt user to select which agents to install to
191
+ * @param {Array<{name: string, displayName: string, skillsDir: string}>} detectedAgents
192
+ * @returns {Promise<Array<{name: string, displayName: string, skillsDir: string}> | null>}
193
+ */
194
+ export async function selectAgentsPrompt(detectedAgents) {
195
+ if (detectedAgents.length === 0) {
196
+ return null;
197
+ }
198
+
199
+ // First ask: All detected or select specific?
200
+ const installChoice = await select({
201
+ message: "Install to",
202
+ options: [
203
+ {
204
+ value: "all",
205
+ label: `All detected agents (Recommended)`,
206
+ hint: `Install to all ${detectedAgents.length} detected agents`
207
+ },
208
+ {
209
+ value: "select",
210
+ label: "Select specific agents",
211
+ hint: "Choose which agents to install to"
212
+ }
213
+ ]
214
+ });
215
+
216
+ if (isCancel(installChoice)) {
217
+ cancel("Installation cancelled");
218
+ return null;
219
+ }
220
+
221
+ if (installChoice === "all") {
222
+ return detectedAgents;
223
+ }
224
+
225
+ // Let user select specific agents
226
+ const selectedAgents = await multiselect({
227
+ message: "Select agents to install skills to",
228
+ options: detectedAgents.map(agent => ({
229
+ value: agent.name,
230
+ label: agent.displayName,
231
+ hint: agent.skillsDir
232
+ })),
233
+ required: true
234
+ });
235
+
236
+ if (isCancel(selectedAgents)) {
237
+ cancel("Installation cancelled");
238
+ return null;
239
+ }
240
+
241
+ return detectedAgents.filter(a => selectedAgents.includes(a.name));
242
+ }
243
+
244
+ /**
245
+ * Prompt user to select installation scope (Project or Global)
246
+ * @returns {Promise<"project" | "global" | null>}
247
+ */
248
+ export async function selectScopePrompt() {
249
+ const scope = await select({
250
+ message: "Installation scope",
251
+ options: [
252
+ {
253
+ value: "project",
254
+ label: "Project",
255
+ hint: "Install in current directory (committed with your project)"
256
+ },
257
+ {
258
+ value: "global",
259
+ label: "Global",
260
+ hint: "Install globally (available across all projects)"
261
+ }
262
+ ]
263
+ });
264
+
265
+ if (isCancel(scope)) {
266
+ cancel("Installation cancelled");
267
+ return null;
268
+ }
269
+
270
+ return scope;
271
+ }
272
+
273
+ /**
274
+ * Prompt user to select installation method (Symlink or Copy)
275
+ * @returns {Promise<"symlink" | "copy" | null>}
276
+ */
277
+ export async function selectMethodPrompt() {
278
+ const method = await select({
279
+ message: "Installation method",
280
+ options: [
281
+ {
282
+ value: "symlink",
283
+ label: "Symlink (Recommended)",
284
+ hint: "Single source of truth, easy updates"
285
+ },
286
+ {
287
+ value: "copy",
288
+ label: "Copy to all agents",
289
+ hint: "Independent copies for each agent"
290
+ }
291
+ ]
292
+ });
293
+
294
+ if (isCancel(method)) {
295
+ cancel("Installation cancelled");
296
+ return null;
297
+ }
298
+
299
+ return method;
300
+ }
301
+
302
+ /**
303
+ * Prompt user to select skills to install (multiselect with descriptions)
304
+ * @param {Array<{name: string, description: string, path: string}>} skills
305
+ * @returns {Promise<Array<{name: string, description: string, path: string}> | null>}
306
+ */
307
+ export async function selectSkillsPrompt(skills) {
308
+ if (skills.length === 0) {
309
+ return null;
310
+ }
311
+
312
+ const selectedNames = await multiselect({
313
+ message: "Select skills to install",
314
+ options: skills.map(skill => ({
315
+ value: skill.name,
316
+ label: skill.name,
317
+ hint: skill.description ? skill.description.substring(0, 60) + "..." : ""
318
+ })),
319
+ required: true
320
+ });
321
+
322
+ if (isCancel(selectedNames)) {
323
+ cancel("Installation cancelled");
324
+ return null;
325
+ }
326
+
327
+ return skills.filter(s => selectedNames.includes(s.name));
328
+ }
329
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pikakit",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Enterprise-grade Agent Skill Manager with Antigravity Skills support, Progressive Disclosure detection, and semantic routing validation",
5
5
  "license": "MIT",
6
6
  "author": "agentskillkit <agentskillkit@gmail.com>",