pixelcrew 0.2.2 → 0.2.6

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 (173) hide show
  1. package/README.md +389 -315
  2. package/bin/pixel-agents.js +306 -149
  3. package/package.json +3 -1
  4. package/skill/SKILL.md +185 -0
  5. package/skill/references/anti-ai-rubric.md +30 -0
  6. package/skill/references/anti-ai-slop-encyclopedia.md +181 -0
  7. package/skill/references/commands-reference.md +135 -0
  8. package/skill/references/testing-and-qa-strategy.md +25 -0
  9. package/skill/references/token-efficiency.md +20 -0
  10. package/src/adapters/adapter.interface.js +77 -0
  11. package/src/adapters/antigravity.js +138 -0
  12. package/src/adapters/claude-code.js +149 -0
  13. package/src/adapters/codex.js +131 -0
  14. package/src/adapters/cursor.js +133 -0
  15. package/src/adapters/generic.js +63 -0
  16. package/src/adapters/index.js +15 -0
  17. package/src/adapters/kiro.js +134 -0
  18. package/src/adapters/registry.js +150 -0
  19. package/src/backend/analyzer/complexity-analyzer.js +104 -0
  20. package/src/backend/analyzer/requirement-analyzer.js +213 -0
  21. package/src/backend/analyzer/threat-analyzer.js +122 -0
  22. package/src/backend/api/api-designer.js +90 -0
  23. package/src/backend/api/error-contract.js +132 -0
  24. package/src/backend/api/route-generator.js +92 -0
  25. package/src/backend/api/schema-generator.js +64 -0
  26. package/src/backend/architecture/adr-generator.js +62 -0
  27. package/src/backend/architecture/architecture-reasoner.js +119 -0
  28. package/src/backend/architecture/architecture-selector.js +57 -0
  29. package/src/backend/architecture/tradeoff-analyzer.js +92 -0
  30. package/src/backend/data/data-modeler.js +114 -0
  31. package/src/backend/data/index-analyzer.js +93 -0
  32. package/src/backend/data/query-analyzer.js +41 -0
  33. package/src/backend/data/schema-generator.js +92 -0
  34. package/src/backend/data/transaction-analyzer.js +49 -0
  35. package/src/backend/index.js +67 -0
  36. package/src/backend/observability/logging-engine.js +80 -0
  37. package/src/backend/observability/metrics-engine.js +31 -0
  38. package/src/backend/observability/tracing-engine.js +16 -0
  39. package/src/backend/patterns/pattern-registry.js +74 -0
  40. package/src/backend/patterns/pattern-selector.js +39 -0
  41. package/src/backend/patterns/tradeoff-engine.js +17 -0
  42. package/src/backend/performance/cache-analyzer.js +31 -0
  43. package/src/backend/performance/concurrency-analyzer.js +34 -0
  44. package/src/backend/performance/performance-engine.js +98 -0
  45. package/src/backend/performance/query-optimizer.js +16 -0
  46. package/src/backend/reliability/failure-analyzer.js +22 -0
  47. package/src/backend/reliability/idempotency-engine.js +56 -0
  48. package/src/backend/reliability/resilience-engine.js +141 -0
  49. package/src/backend/reliability/retry-analyzer.js +15 -0
  50. package/src/backend/security/auth-selector.js +33 -0
  51. package/src/backend/security/authorization-engine.js +90 -0
  52. package/src/backend/security/policy-engine.js +49 -0
  53. package/src/backend/security/secret-analyzer.js +39 -0
  54. package/src/backend/security/security-engine.js +122 -0
  55. package/src/backend/security/threat-model.js +59 -0
  56. package/src/backend/synthesis/backend-synthesizer.js +98 -0
  57. package/src/backend/synthesis/infrastructure-synthesizer.js +108 -0
  58. package/src/backend/synthesis/module-synthesizer.js +262 -0
  59. package/src/backend/validation/architecture-validator.js +70 -0
  60. package/src/backend/validation/backend-quality-validator.js +71 -0
  61. package/src/backend/validation/dependency-validator.js +20 -0
  62. package/src/backend/validation/performance-validator.js +38 -0
  63. package/src/backend/validation/security-validator.js +73 -0
  64. package/src/commands/adapt.js +105 -0
  65. package/src/commands/add.js +78 -0
  66. package/src/commands/animate.js +48 -0
  67. package/src/commands/assemble.js +57 -0
  68. package/src/commands/audit.js +93 -0
  69. package/src/commands/backend.js +125 -0
  70. package/src/commands/bento.js +25 -0
  71. package/src/commands/blueprint.js +65 -0
  72. package/src/commands/bolder.js +48 -0
  73. package/src/commands/boss-fight.js +60 -0
  74. package/src/commands/build.js +39 -0
  75. package/src/commands/calibrate.js +25 -0
  76. package/src/commands/chromatic.js +25 -0
  77. package/src/commands/clarify.js +52 -0
  78. package/src/commands/colorize.js +57 -0
  79. package/src/commands/command.interface.js +28 -0
  80. package/src/commands/commands.js +84 -0
  81. package/src/commands/craft.js +57 -0
  82. package/src/commands/crew.js +66 -0
  83. package/src/commands/critique.js +25 -0
  84. package/src/commands/de-slop.js +25 -0
  85. package/src/commands/delight.js +46 -0
  86. package/src/commands/deploy.js +42 -0
  87. package/src/commands/distill.js +48 -0
  88. package/src/commands/doctor.js +89 -0
  89. package/src/commands/document.js +83 -0
  90. package/src/commands/eight-bit.js +25 -0
  91. package/src/commands/extract.js +75 -0
  92. package/src/commands/fix.js +46 -0
  93. package/src/commands/harden.js +85 -0
  94. package/src/commands/index.js +67 -0
  95. package/src/commands/install.js +75 -0
  96. package/src/commands/layout.js +48 -0
  97. package/src/commands/live.js +44 -0
  98. package/src/commands/manifest.js +25 -0
  99. package/src/commands/office.js +25 -0
  100. package/src/commands/onboard.js +46 -0
  101. package/src/commands/oneshot.js +60 -0
  102. package/src/commands/optimize.js +46 -0
  103. package/src/commands/overdrive.js +46 -0
  104. package/src/commands/parser.js +143 -0
  105. package/src/commands/pixelcrew.js +96 -0
  106. package/src/commands/plan.js +66 -0
  107. package/src/commands/polish.js +45 -0
  108. package/src/commands/quieter.js +48 -0
  109. package/src/commands/recap.js +358 -0
  110. package/src/commands/registry.js +353 -0
  111. package/src/commands/render.js +26 -0
  112. package/src/commands/retrofit.js +25 -0
  113. package/src/commands/review.js +118 -0
  114. package/src/commands/roster.js +25 -0
  115. package/src/commands/sentinel.js +25 -0
  116. package/src/commands/shape.js +66 -0
  117. package/src/commands/skills.js +57 -0
  118. package/src/commands/status.js +48 -0
  119. package/src/commands/stop.js +50 -0
  120. package/src/commands/sync.js +58 -0
  121. package/src/commands/typeset.js +58 -0
  122. package/src/commands/warp.js +25 -0
  123. package/src/core/agent-runtime.js +94 -0
  124. package/src/core/event-bus.js +98 -0
  125. package/src/core/index.js +9 -0
  126. package/src/core/orchestrator.js +234 -0
  127. package/src/core/scheduler.js +124 -0
  128. package/src/core/task-graph.js +185 -0
  129. package/src/dashboard/app.js +1172 -30
  130. package/src/dashboard/index.html +223 -23
  131. package/src/dashboard/styles.css +870 -0
  132. package/src/index.js +16 -0
  133. package/src/orchestrator/artifact-graph.js +104 -0
  134. package/src/orchestrator/ast-normalizer.js +147 -0
  135. package/src/orchestrator/code-generator.js +846 -0
  136. package/src/orchestrator/design-engine.js +203 -0
  137. package/src/orchestrator/engine.js +318 -39
  138. package/src/orchestrator/oneshot.js +351 -1561
  139. package/src/orchestrator/ontology.js +394 -0
  140. package/src/orchestrator/planner.js +302 -0
  141. package/src/orchestrator/repair-planner.js +67 -0
  142. package/src/orchestrator/requirement-contract.js +177 -0
  143. package/src/orchestrator/requirement-validator.js +39 -0
  144. package/src/orchestrator/semantic-engine.js +582 -0
  145. package/src/orchestrator/semantic-reviewer.js +179 -0
  146. package/src/orchestrator/skills-registry.js +194 -0
  147. package/src/orchestrator/task-planner.js +111 -0
  148. package/src/orchestrator/task-queue.js +128 -0
  149. package/src/orchestrator/telemetry.js +209 -0
  150. package/src/orchestrator/ui-synthesizer.js +245 -0
  151. package/src/orchestrator/visual-critic.js +106 -0
  152. package/src/policies/architecture/layering.policy.js +14 -0
  153. package/src/policies/performance/indexing.policy.js +13 -0
  154. package/src/policies/reliability/resilience.policy.js +13 -0
  155. package/src/policies/security/auth.policy.js +31 -0
  156. package/src/protocol/agent.js +124 -0
  157. package/src/protocol/event.js +78 -0
  158. package/src/protocol/index.js +8 -0
  159. package/src/protocol/skill.js +54 -0
  160. package/src/protocol/task.js +100 -0
  161. package/src/scaffold/claude-generator.js +60 -0
  162. package/src/scaffold/commands-catalog.js +321 -0
  163. package/src/scaffold/cursor-generator.js +74 -0
  164. package/src/scaffold/ide-rules.js +133 -0
  165. package/src/scaffold/init.js +415 -91
  166. package/src/scaffold/installer.js +571 -0
  167. package/src/scaffold/kiro-generator.js +86 -0
  168. package/src/scaffold/skills-bundle.js +520 -0
  169. package/src/scaffold/templates.js +57 -4
  170. package/src/scaffold/workstations.js +364 -0
  171. package/src/server/server.js +292 -42
  172. package/src/utils/fs-safe.js +168 -0
  173. package/src/utils/markdown-report.js +175 -0
@@ -0,0 +1,571 @@
1
+ /**
2
+ * PIXEL CREW — Multi-Provider Skill Installer & Sync Engine
3
+ *
4
+ * Installs, configures, and synchronizes agent skills across:
5
+ * - .pixel-crew/ (Pixel Crew Swarm Manifest & Local Skills)
6
+ * - .claude/ (Anthropic Claude Code)
7
+ * - .cursor/ (Cursor AI IDE)
8
+ * - .kiro/ (Kiro AI IDE)
9
+ * - .agents/ (Google Antigravity & Agentic IDEs)
10
+ */
11
+
12
+ import fs from 'node:fs/promises';
13
+ import fsSync from 'node:fs';
14
+ import path from 'node:path';
15
+ import os from 'node:os';
16
+ import { fileURLToPath } from 'node:url';
17
+ import { SKILL_DEFINITIONS } from '../orchestrator/skills-registry.js';
18
+ import { SKILL_MARKDOWNS } from './templates.js';
19
+ import { getSkillBundle, sanitizeFrontmatter } from './skills-bundle.js';
20
+ import { generateKiroFiles } from './kiro-generator.js';
21
+ import { generateCursorFiles, generateAntigravityFiles, generateClaudeFiles } from './ide-rules.js';
22
+ import { safeWriteFile, safeMkdir, DryRunReporter } from '../utils/fs-safe.js';
23
+
24
+ export const PROVIDER_PATHS = {
25
+ 'claude-code': (targetDir, skillName) => path.join(targetDir, '.claude', 'skills', skillName, 'SKILL.md'),
26
+ 'cursor': (targetDir, skillName) => path.join(targetDir, '.cursor', 'skills', skillName, 'SKILL.md'),
27
+ 'kiro': (targetDir, skillName) => path.join(targetDir, '.kiro', 'skills', skillName, 'SKILL.md'),
28
+ 'antigravity': (targetDir, skillName) => path.join(targetDir, '.agents', 'skills', skillName, 'SKILL.md'),
29
+ 'codex': (targetDir, skillName) => path.join(targetDir, '.codex', 'skills', skillName, 'SKILL.md'),
30
+ 'pixel-crew': (targetDir, skillName) => path.join(targetDir, '.pixel-crew', 'skills', `${skillName}.md`)
31
+ };
32
+
33
+ export const GLOBAL_PROVIDER_PATHS = {
34
+ 'claude-code': (skillName, home = (process.env.PIXELCREW_HOME || os.homedir())) => path.join(home, '.claude', 'skills', skillName, 'SKILL.md'),
35
+ 'cursor': (skillName, home = (process.env.PIXELCREW_HOME || os.homedir())) => path.join(home, '.cursor', 'skills', skillName, 'SKILL.md'),
36
+ 'kiro': (skillName, home = (process.env.PIXELCREW_HOME || os.homedir())) => path.join(home, '.kiro', 'skills', skillName, 'SKILL.md'),
37
+ 'antigravity': (skillName, home = (process.env.PIXELCREW_HOME || os.homedir())) => path.join(home, '.gemini', 'config', 'skills', skillName, 'SKILL.md'),
38
+ 'codex': (skillName, home = (process.env.PIXELCREW_HOME || os.homedir())) => path.join(home, '.codex', 'skills', skillName, 'SKILL.md'),
39
+ 'pixel-crew': (skillName, home = (process.env.PIXELCREW_HOME || os.homedir())) => path.join(home, '.pixel-crew', 'skills', `${skillName}.md`)
40
+ };
41
+
42
+ /**
43
+ * Detects which IDE / Coding Agent environment the current terminal shell is executing inside
44
+ */
45
+ export function detectActiveIDE(targetDir = process.cwd()) {
46
+ const env = process.env;
47
+
48
+ // 1. Kiro AI
49
+ if (
50
+ env.KIRO === '1' ||
51
+ env.KIRO_AGENT ||
52
+ env.KIRO_SESSION ||
53
+ env.KIRO_APP_DIR ||
54
+ env.TERM_PROGRAM === 'kiro' ||
55
+ env.VSCODE_GIT_ASKPASS_NODE?.toLowerCase().includes('kiro')
56
+ ) {
57
+ return {
58
+ id: 'kiro',
59
+ name: 'Kiro AI',
60
+ globalPath: path.join(os.homedir(), '.kiro', 'skills'),
61
+ detectedVia: 'env'
62
+ };
63
+ }
64
+
65
+ // 2. Cursor AI
66
+ if (
67
+ env.CURSOR === '1' ||
68
+ env.CURSOR_AGENT ||
69
+ env.CURSOR_SESSION ||
70
+ env.CURSOR_APP_DIR ||
71
+ env.TERM_PROGRAM === 'cursor' ||
72
+ env.VSCODE_GIT_ASKPASS_NODE?.toLowerCase().includes('cursor')
73
+ ) {
74
+ return {
75
+ id: 'cursor',
76
+ name: 'Cursor IDE',
77
+ globalPath: path.join(os.homedir(), '.cursor', 'skills'),
78
+ detectedVia: 'env'
79
+ };
80
+ }
81
+
82
+ // 3. Google Antigravity
83
+ if (
84
+ env.ANTIGRAVITY_APP_DIR ||
85
+ env.AGY_SESSION ||
86
+ env.ANTIGRAVITY ||
87
+ env.ANTIGRAVITY_IDE ||
88
+ env.AGY ||
89
+ env.TERM_PROGRAM === 'antigravity' ||
90
+ env.VSCODE_GIT_ASKPASS_NODE?.toLowerCase().includes('antigravity') ||
91
+ (env.CORPUS_NAME && env.CONVERSATION_ID)
92
+ ) {
93
+ return {
94
+ id: 'antigravity',
95
+ name: 'Google Antigravity',
96
+ globalPath: path.join(os.homedir(), '.gemini', 'config', 'skills'),
97
+ detectedVia: 'env'
98
+ };
99
+ }
100
+
101
+ // 4. Claude Code
102
+ if (env.CLAUDE_CODE || env.CLAUDE_SESSION || env.CLAUDE_AGENT) {
103
+ return {
104
+ id: 'claude-code',
105
+ name: 'Claude Code',
106
+ globalPath: path.join(os.homedir(), '.claude', 'skills'),
107
+ detectedVia: 'env'
108
+ };
109
+ }
110
+
111
+ // 5. OpenAI Codex
112
+ if (env.CODEX_SESSION || env.CODEX_AGENT || env.CODEX) {
113
+ return {
114
+ id: 'codex',
115
+ name: 'OpenAI Codex',
116
+ globalPath: path.join(os.homedir(), '.codex', 'skills'),
117
+ detectedVia: 'env'
118
+ };
119
+ }
120
+
121
+ // 6. Check existing workspace markers in targetDir
122
+ try {
123
+ if (
124
+ fsSync.existsSync(path.join(targetDir, '.kiro')) ||
125
+ fsSync.existsSync(path.join(targetDir, '.kirorules')) ||
126
+ fsSync.existsSync(path.join(targetDir, 'kiro.json'))
127
+ ) {
128
+ return {
129
+ id: 'kiro',
130
+ name: 'Kiro AI',
131
+ globalPath: path.join(os.homedir(), '.kiro', 'skills'),
132
+ detectedVia: 'workspace'
133
+ };
134
+ }
135
+ if (
136
+ fsSync.existsSync(path.join(targetDir, '.cursor')) ||
137
+ fsSync.existsSync(path.join(targetDir, '.cursorrules'))
138
+ ) {
139
+ return {
140
+ id: 'cursor',
141
+ name: 'Cursor IDE',
142
+ globalPath: path.join(os.homedir(), '.cursor', 'skills'),
143
+ detectedVia: 'workspace'
144
+ };
145
+ }
146
+ if (
147
+ fsSync.existsSync(path.join(targetDir, '.agents')) ||
148
+ fsSync.existsSync(path.join(targetDir, 'AGENTS.md'))
149
+ ) {
150
+ return {
151
+ id: 'antigravity',
152
+ name: 'Google Antigravity',
153
+ globalPath: path.join(os.homedir(), '.gemini', 'config', 'skills'),
154
+ detectedVia: 'workspace'
155
+ };
156
+ }
157
+ if (
158
+ fsSync.existsSync(path.join(targetDir, '.claude')) ||
159
+ fsSync.existsSync(path.join(targetDir, 'CLAUDE.md'))
160
+ ) {
161
+ return {
162
+ id: 'claude-code',
163
+ name: 'Claude Code',
164
+ globalPath: path.join(os.homedir(), '.claude', 'skills'),
165
+ detectedVia: 'workspace'
166
+ };
167
+ }
168
+ } catch {}
169
+
170
+ return {
171
+ id: 'pixel-crew',
172
+ name: 'Pixel Crew',
173
+ globalPath: path.join(os.homedir(), '.pixel-crew', 'skills'),
174
+ detectedVia: 'default'
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Detects which agent environments exist in the target directory
180
+ */
181
+ export async function detectInstalledProviders(targetDir = process.cwd()) {
182
+ const detected = new Set(['pixel-crew']);
183
+
184
+ const checks = [
185
+ { provider: 'claude-code', paths: [path.join(targetDir, '.claude'), path.join(targetDir, 'CLAUDE.md')] },
186
+ { provider: 'cursor', paths: [path.join(targetDir, '.cursor'), path.join(targetDir, '.cursorrules')] },
187
+ { provider: 'kiro', paths: [path.join(targetDir, '.kiro'), path.join(targetDir, '.kirorules'), path.join(targetDir, 'kiro.json'), path.join(targetDir, '.kiro.json')] },
188
+ { provider: 'antigravity', paths: [path.join(targetDir, '.agents'), path.join(targetDir, 'AGENTS.md'), path.join(targetDir, '.gemini')] },
189
+ { provider: 'pixel-crew', paths: [path.join(targetDir, '.pixel-crew'), path.join(targetDir, '.pixel-agents')] }
190
+ ];
191
+
192
+ for (const check of checks) {
193
+ for (const p of check.paths) {
194
+ try {
195
+ await fs.access(p);
196
+ detected.add(check.provider);
197
+ break;
198
+ } catch {}
199
+ }
200
+ }
201
+
202
+ return Array.from(detected);
203
+ }
204
+
205
+ /**
206
+ * Normalizes skill identifier into standard ID and kebab-case name
207
+ */
208
+ export function normalizeSkillId(rawInput) {
209
+ let cleaned = (rawInput || '').trim();
210
+ // Strip @pixel-crew/ or pixel-crew/
211
+ cleaned = cleaned.replace(/^@?pixel-crew\//, '');
212
+ cleaned = cleaned.replace(/^skills?\//, '');
213
+
214
+ // Check direct match in SKILL_DEFINITIONS
215
+ if (SKILL_DEFINITIONS[cleaned]) {
216
+ const s = SKILL_DEFINITIONS[cleaned];
217
+ const skillName = s.id.includes('/') ? s.id.split('/')[1] : s.id;
218
+ return { id: s.id, name: skillName, definition: s };
219
+ }
220
+
221
+ // Check by suffix or name match
222
+ for (const [id, def] of Object.entries(SKILL_DEFINITIONS)) {
223
+ const subName = id.includes('/') ? id.split('/')[1] : id;
224
+ if (subName.toLowerCase() === cleaned.toLowerCase() || id.toLowerCase() === cleaned.toLowerCase()) {
225
+ return { id, name: subName, definition: def };
226
+ }
227
+ }
228
+
229
+ // Fallback for custom skills or oneshot
230
+ const safeName = cleaned.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase();
231
+ return {
232
+ id: cleaned,
233
+ name: safeName,
234
+ definition: {
235
+ id: cleaned,
236
+ name: safeName.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
237
+ category: 'general',
238
+ description: `Skill capability definition for ${cleaned}`,
239
+ targetAgents: ['frontend', 'backend', 'orchestrator']
240
+ }
241
+ };
242
+ }
243
+
244
+ /**
245
+ * Generates formatted SKILL.md markdown with standard YAML frontmatter
246
+ */
247
+ export function generateSkillMarkdown(skillMeta) {
248
+ const { id, name, definition } = skillMeta;
249
+
250
+ // Check if we have pre-existing detailed markdown in templates
251
+ const markdownKey = `${name}.md`;
252
+ if (SKILL_MARKDOWNS[markdownKey]) {
253
+ const raw = SKILL_MARKDOWNS[markdownKey].trim();
254
+ if (raw.startsWith('---')) {
255
+ return sanitizeFrontmatter(raw + '\n');
256
+ }
257
+ return sanitizeFrontmatter(`---
258
+ name: ${name}
259
+ description: ${definition.description || 'Pixel Crew Agent Skill'}
260
+ category: ${definition.category || 'general'}
261
+ ---
262
+
263
+ ${raw}
264
+ `);
265
+ }
266
+
267
+ return sanitizeFrontmatter(`---
268
+ name: ${name}
269
+ description: ${definition.description || 'Pixel Crew Agent Skill'}
270
+ category: ${definition.category || 'general'}
271
+ ---
272
+
273
+ # ${definition.name || name}
274
+
275
+ ${definition.description || 'Custom capability skill.'}
276
+
277
+ ## Targeted Agents
278
+ ${(definition.targetAgents || ['all']).map(a => `- ${a}`).join('\n')}
279
+
280
+ ## Usage & Guidelines
281
+ - Follow domain-specific best practices and avoid generic anti-patterns.
282
+ - Enforce strict typing, comprehensive testing, and modular architecture.
283
+ `);
284
+ }
285
+
286
+ /**
287
+ * Installs a skill across detected or specified agent providers (project or global scope)
288
+ */
289
+ export async function installSkill(targetDir = process.cwd(), rawSkillInput, options = {}) {
290
+ const {
291
+ dryRun = false,
292
+ provider = null,
293
+ scope = (options.global ? 'global' : (options.scope || 'project')),
294
+ reporter = new DryRunReporter(targetDir)
295
+ } = options;
296
+
297
+ const skillMeta = normalizeSkillId(rawSkillInput);
298
+ const bundle = await getSkillBundle(rawSkillInput);
299
+ const content = (bundle && bundle.content) ? bundle.content : generateSkillMarkdown(skillMeta);
300
+ const activeIDE = detectActiveIDE(targetDir);
301
+
302
+ // Determine target providers
303
+ let targetProviders = [];
304
+ if (provider && provider !== 'auto') {
305
+ if (provider === 'all' || provider === 'multi') {
306
+ targetProviders = Object.keys(PROVIDER_PATHS);
307
+ } else if (provider === 'none' || provider === 'cli' || provider === 'pixel-crew') {
308
+ targetProviders = ['pixel-crew'];
309
+ } else {
310
+ const p = provider.toLowerCase();
311
+ if (PROVIDER_PATHS[p]) targetProviders.push(p);
312
+ else if (p === 'claude') targetProviders.push('claude-code');
313
+ else if (p === 'agents') targetProviders.push('antigravity');
314
+ }
315
+ } else {
316
+ if (scope === 'global') {
317
+ targetProviders = [activeIDE.id];
318
+ } else {
319
+ // Auto-detect environments
320
+ targetProviders = await detectInstalledProviders(targetDir);
321
+ if (activeIDE.id !== 'pixel-crew' && !targetProviders.includes(activeIDE.id)) {
322
+ targetProviders.push(activeIDE.id);
323
+ }
324
+ if (options.allProviders || scope === 'all') {
325
+ targetProviders = Object.keys(PROVIDER_PATHS);
326
+ }
327
+ }
328
+ }
329
+
330
+ // Ensure pixel-crew is included for project-level manifests
331
+ if (scope !== 'global' && (!provider || provider === 'auto') && !targetProviders.includes('pixel-crew')) {
332
+ targetProviders.push('pixel-crew');
333
+ }
334
+
335
+ const writtenPaths = [];
336
+
337
+ // 1. Write Project-Level skills if scope is 'project', 'both', or 'all'
338
+ if (scope !== 'global') {
339
+ for (const p of targetProviders) {
340
+ const pathFn = PROVIDER_PATHS[p];
341
+ if (!pathFn) continue;
342
+
343
+ const fullPath = pathFn(targetDir, skillMeta.name);
344
+ const res = await safeWriteFile(fullPath, content, {
345
+ dryRun,
346
+ reporter,
347
+ targetDir
348
+ });
349
+ writtenPaths.push({ provider: p, scope: 'project', path: fullPath, ...res });
350
+
351
+ // Write attached reference documents for directory-based providers
352
+ if (p !== 'pixel-crew' && bundle?.references && Object.keys(bundle.references).length > 0) {
353
+ const skillDir = path.dirname(fullPath);
354
+ for (const [refName, refContent] of Object.entries(bundle.references)) {
355
+ const refFullPath = path.join(skillDir, 'references', refName);
356
+ await safeWriteFile(refFullPath, refContent, { dryRun, reporter, targetDir });
357
+ }
358
+ }
359
+ }
360
+
361
+ // Keep a manifest only when the PixelCrew provider itself is selected.
362
+ if (targetProviders.includes('pixel-crew')) {
363
+ // Update .pixel-crew/pixel.json manifest
364
+ const manifestPath = path.join(targetDir, '.pixel-crew', 'pixel.json');
365
+ let manifest = {
366
+ name: path.basename(targetDir),
367
+ version: '0.2.5',
368
+ skills: {},
369
+ installedAt: new Date().toISOString()
370
+ };
371
+
372
+ try {
373
+ const raw = await fs.readFile(manifestPath, 'utf-8');
374
+ manifest = JSON.parse(raw);
375
+ } catch {}
376
+
377
+ if (!manifest.skills) manifest.skills = {};
378
+ manifest.skills[skillMeta.id] = {
379
+ name: skillMeta.name,
380
+ category: skillMeta.definition.category || 'general',
381
+ providers: targetProviders,
382
+ installedAt: new Date().toISOString()
383
+ };
384
+
385
+ await safeWriteFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n', {
386
+ dryRun,
387
+ reporter,
388
+ targetDir
389
+ });
390
+ }
391
+ }
392
+
393
+ // 2. Write Global skills if scope is 'global' or 'both'
394
+ if (scope === 'global' || scope === 'both') {
395
+ const globalProviders = provider && provider !== 'auto'
396
+ ? (provider === 'all' ? Object.keys(GLOBAL_PROVIDER_PATHS) : [provider.toLowerCase() === 'claude' ? 'claude-code' : (provider.toLowerCase() === 'agents' ? 'antigravity' : provider.toLowerCase())])
397
+ : [activeIDE.id];
398
+
399
+ for (const gp of globalProviders) {
400
+ const globalPathFn = GLOBAL_PROVIDER_PATHS[gp];
401
+ if (!globalPathFn) continue;
402
+
403
+ const fullGlobalPath = globalPathFn(skillMeta.name);
404
+ const res = await safeWriteFile(fullGlobalPath, content, {
405
+ dryRun,
406
+ reporter,
407
+ targetDir: os.homedir()
408
+ });
409
+ writtenPaths.push({ provider: gp, scope: 'global', path: fullGlobalPath, ...res });
410
+
411
+ // Write attached reference documents globally
412
+ if (gp !== 'pixel-crew' && bundle?.references && Object.keys(bundle.references).length > 0) {
413
+ const skillDir = path.dirname(fullGlobalPath);
414
+ for (const [refName, refContent] of Object.entries(bundle.references)) {
415
+ const refFullPath = path.join(skillDir, 'references', refName);
416
+ await safeWriteFile(refFullPath, refContent, { dryRun, reporter, targetDir: os.homedir() });
417
+ }
418
+ }
419
+ }
420
+ }
421
+
422
+ return {
423
+ success: true,
424
+ skillId: skillMeta.id,
425
+ skillName: skillMeta.name,
426
+ providers: targetProviders,
427
+ scope,
428
+ activeIDE,
429
+ writtenPaths,
430
+ dryRun,
431
+ reporter
432
+ };
433
+ }
434
+
435
+ /**
436
+ * Synchronizes all installed skills across all detected or specified IDE agent directories
437
+ */
438
+ export async function syncSkills(targetDir = process.cwd(), options = {}) {
439
+ const {
440
+ dryRun = false,
441
+ provider = null,
442
+ scope = (options.global ? 'global' : (options.scope || 'project')),
443
+ reporter = new DryRunReporter(targetDir)
444
+ } = options;
445
+
446
+ const manifestPath = path.join(targetDir, '.pixel-crew', 'pixel.json');
447
+ let manifest = null;
448
+
449
+ try {
450
+ const raw = await fs.readFile(manifestPath, 'utf-8');
451
+ manifest = JSON.parse(raw);
452
+ } catch {}
453
+
454
+ // Discover skills from manifest or .pixel-crew/skills directory
455
+ const skillsToSync = new Set();
456
+
457
+ if (manifest?.skills) {
458
+ for (const sId of Object.keys(manifest.skills)) {
459
+ skillsToSync.add(sId);
460
+ }
461
+ }
462
+
463
+ // Check .pixel-crew/skills directory
464
+ const pixelCrewSkillsDir = path.join(targetDir, '.pixel-crew', 'skills');
465
+ try {
466
+ const files = await fs.readdir(pixelCrewSkillsDir);
467
+ for (const f of files) {
468
+ if (f.endsWith('.md')) {
469
+ skillsToSync.add(f.replace(/\.md$/, ''));
470
+ }
471
+ }
472
+ } catch {}
473
+
474
+ // Always ensure all canonical core production skills and domain aliases are synced
475
+ const canonicalSkills = [
476
+ 'pixelcrew',
477
+ 'anti-ai-patterns',
478
+ 'design-director',
479
+ 'frontend-engineering',
480
+ 'backend-engineering',
481
+ 'database-engineering',
482
+ 'performance-engineering',
483
+ 'codebase-intelligence',
484
+ 'token-efficiency',
485
+ 'design/ui-design',
486
+ 'design/typography',
487
+ 'frontend/nextjs',
488
+ 'anti-ai/slop-guardian'
489
+ ];
490
+ for (const s of canonicalSkills) {
491
+ skillsToSync.add(s);
492
+ }
493
+
494
+ const results = [];
495
+ for (const sId of skillsToSync) {
496
+ const res = await installSkill(targetDir, sId, {
497
+ dryRun,
498
+ provider,
499
+ scope,
500
+ reporter
501
+ });
502
+ results.push(res);
503
+ }
504
+
505
+ // Generate IDE-specific workflow definitions and steering rules
506
+ const detected = await detectInstalledProviders(targetDir);
507
+ const activeIDE = detectActiveIDE(targetDir);
508
+
509
+ const shouldGenerate = (ideId) => {
510
+ if (provider && provider !== 'auto') {
511
+ return provider === 'all' || provider === 'multi' || provider.toLowerCase() === ideId || (provider.toLowerCase() === 'claude' && ideId === 'claude-code') || (provider.toLowerCase() === 'agents' && ideId === 'antigravity');
512
+ }
513
+ return activeIDE.id === ideId || (detected.includes(ideId) && ideId !== 'pixel-crew');
514
+ };
515
+
516
+ // 1. Kiro Workflows & Rules
517
+ if (shouldGenerate('kiro')) {
518
+ if (scope !== 'global') {
519
+ const kiroFiles = generateKiroFiles(targetDir, false);
520
+ for (const kf of kiroFiles) {
521
+ await safeWriteFile(kf.path, kf.content, { dryRun, reporter, targetDir });
522
+ }
523
+ }
524
+ if (scope === 'global' || scope === 'both') {
525
+ const kiroGlobalFiles = generateKiroFiles(os.homedir(), true);
526
+ for (const kf of kiroGlobalFiles) {
527
+ await safeWriteFile(kf.path, kf.content, { dryRun, reporter, targetDir: os.homedir() });
528
+ }
529
+ }
530
+ }
531
+
532
+ // 2. Cursor Rules & MDC
533
+ if (shouldGenerate('cursor')) {
534
+ if (scope !== 'global') {
535
+ const cursorFiles = generateCursorFiles(targetDir);
536
+ for (const cf of cursorFiles) {
537
+ await safeWriteFile(cf.path, cf.content, { dryRun, reporter, targetDir });
538
+ }
539
+ }
540
+ }
541
+
542
+ // 3. Antigravity Agent Instructions (AGENTS.md, GEMINI.md, .agents/rules/)
543
+ if (shouldGenerate('antigravity')) {
544
+ if (scope !== 'global') {
545
+ const antigravityFiles = generateAntigravityFiles(targetDir);
546
+ for (const af of antigravityFiles) {
547
+ await safeWriteFile(af.path, af.content, { dryRun, reporter, targetDir });
548
+ }
549
+ }
550
+ }
551
+
552
+ // 4. Claude Code Instructions (CLAUDE.md, .claude-plugin/)
553
+ if (shouldGenerate('claude-code')) {
554
+ if (scope !== 'global') {
555
+ const claudeFiles = generateClaudeFiles(targetDir);
556
+ for (const clf of claudeFiles) {
557
+ await safeWriteFile(clf.path, clf.content, { dryRun, reporter, targetDir });
558
+ }
559
+ }
560
+ }
561
+
562
+ return {
563
+ success: true,
564
+ skillsSynced: Array.from(skillsToSync),
565
+ scope,
566
+ results,
567
+ dryRun,
568
+ reporter
569
+ };
570
+ }
571
+
@@ -0,0 +1,86 @@
1
+ /**
2
+ * PIXEL CREW — Kiro Workflows & Prompts Generator
3
+ *
4
+ * Generates individual .kiro/workflows/*.md, .kiro/prompts/*.md, and .kirorules
5
+ * files so that every PixelCrew slash command (/recap, /assemble, /blueprint, /render, etc.)
6
+ * is natively recognized in the Kiro chat box autocomplete and prompt menu.
7
+ */
8
+
9
+ import path from 'node:path';
10
+ import { FLOOR42_COMMANDS } from './commands-catalog.js';
11
+
12
+ export const KIRO_COMMANDS = FLOOR42_COMMANDS;
13
+
14
+ /**
15
+ * Generates all Kiro workflow, prompt, and rule files
16
+ */
17
+ export function generateKiroFiles(targetDir, isGlobal = false) {
18
+ const baseDir = isGlobal ? targetDir : path.join(targetDir, '.kiro');
19
+ const files = [];
20
+
21
+ // 1. Workflows (.kiro/workflows/*.md)
22
+ for (const cmd of KIRO_COMMANDS) {
23
+ const workflowPath = path.join(baseDir, 'workflows', `${cmd.name}.md`);
24
+ const workflowContent = `---
25
+ name: ${cmd.name}
26
+ description: ${cmd.description}
27
+ ---
28
+
29
+ # /${cmd.name} — PixelCrew Command
30
+
31
+ ${cmd.prompt}
32
+ `;
33
+ files.push({ path: workflowPath, content: workflowContent });
34
+ }
35
+
36
+ // 2. Prompts (.kiro/prompts/*.md)
37
+ for (const cmd of KIRO_COMMANDS) {
38
+ const promptPath = path.join(baseDir, 'prompts', `${cmd.name}.md`);
39
+ const promptContent = `---
40
+ name: ${cmd.name}
41
+ description: ${cmd.description}
42
+ ---
43
+
44
+ ${cmd.prompt}
45
+ `;
46
+ files.push({ path: promptPath, content: promptContent });
47
+ }
48
+
49
+ // 3. Rules (.kirorules and .kiro/rules/pixelcrew.md)
50
+ const rulesContent = `# 🏢 PixelCrew Swarm Rules for Kiro
51
+
52
+ You are integrated with PixelCrew, an autonomous multi-agent engineering swarm (Floor 42, Pixel Corps HQ).
53
+
54
+ ## ⚡ Slash Commands in Kiro Chat:
55
+ ${KIRO_COMMANDS.map(c => `- **\`/${c.name}\`**: ${c.description}`).join('\n')}
56
+
57
+ ## 🛡️ Anti-AI Slop Directive:
58
+ - Enforce intentional asymmetry, mathematical fluid \`clamp()\` typography, and high-contrast surface tiers.
59
+ - Reject generic AI purple/cyan glowing blobs on flat black.
60
+ - Reject cliché copy (*"Elevate your workflow"*, *"Seamlessly innovate"*) and uniform 3-card grids.
61
+ `;
62
+
63
+ if (!isGlobal) {
64
+ files.push({ path: path.join(targetDir, '.kirorules'), content: rulesContent });
65
+ files.push({ path: path.join(baseDir, 'rules', 'pixelcrew.md'), content: rulesContent });
66
+ }
67
+
68
+ // 4. Skills (.kiro/skills/<cmd>/SKILL.md) for direct slash command invocation in Kiro AI chat
69
+ for (const cmd of KIRO_COMMANDS) {
70
+ if (cmd.name === 'pixelcrew') continue;
71
+ const skillPath = path.join(baseDir, 'skills', cmd.name, 'SKILL.md');
72
+ const skillContent = `---
73
+ name: ${cmd.name}
74
+ description: >-
75
+ ${cmd.description}. Triggers Floor 42 command /${cmd.name}.
76
+ ---
77
+
78
+ # /${cmd.name} — PixelCrew Command
79
+
80
+ ${cmd.prompt}
81
+ `;
82
+ files.push({ path: skillPath, content: skillContent });
83
+ }
84
+
85
+ return files;
86
+ }