@leejungkiin/awkit 1.0.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.
Files changed (139) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +146 -0
  3. package/VERSION +1 -0
  4. package/bin/awf.js +549 -0
  5. package/bin/awk.js +1759 -0
  6. package/core/AGENTS.md +39 -0
  7. package/core/GEMINI.md +202 -0
  8. package/core/GEMINI.md.bak +244 -0
  9. package/core/orchestrator.md +58 -0
  10. package/package.json +46 -0
  11. package/schemas/brain.schema.json +342 -0
  12. package/schemas/preferences.schema.json +95 -0
  13. package/schemas/session.schema.json +112 -0
  14. package/skill-packs/neural-memory/README.md +111 -0
  15. package/skill-packs/neural-memory/pack.json +35 -0
  16. package/skill-packs/neural-memory/schemas/brain-snapshot.json +167 -0
  17. package/skill-packs/neural-memory/skills/nm-memory-audit/SKILL.md +157 -0
  18. package/skill-packs/neural-memory/skills/nm-memory-evolution/SKILL.md +202 -0
  19. package/skill-packs/neural-memory/skills/nm-memory-intake/SKILL.md +135 -0
  20. package/skill-packs/neural-memory/skills/nm-memory-sync/SKILL.md +184 -0
  21. package/skill-packs/neural-memory/workflows/nm-import.md +73 -0
  22. package/skill-packs/neural-memory/workflows/nm-recall.md +67 -0
  23. package/skill-packs/neural-memory/workflows/nm-snapshot.md +69 -0
  24. package/skills/adaptive-language/SKILL.md +189 -0
  25. package/skills/ambient-brain/SKILL.md +314 -0
  26. package/skills/ambient-brain/brain-router.md +185 -0
  27. package/skills/ambient-brain/brain-templates.md +201 -0
  28. package/skills/auto-save/SKILL.md +223 -0
  29. package/skills/awf-adaptive-language/SKILL.md +189 -0
  30. package/skills/awf-context-help/SKILL.md +180 -0
  31. package/skills/awf-error-translator/SKILL.md +153 -0
  32. package/skills/awf-session-restore/SKILL.md +270 -0
  33. package/skills/awf-version-tracker/SKILL.md +32 -0
  34. package/skills/awf-version-tracker/scripts/snapshot.sh +22 -0
  35. package/skills/beads-manager/SKILL.md +323 -0
  36. package/skills/brainstorm-agent/SKILL.md +295 -0
  37. package/skills/context-help/SKILL.md +180 -0
  38. package/skills/error-translator/SKILL.md +153 -0
  39. package/skills/ios-engineer/SKILL.md +101 -0
  40. package/skills/memory-sync/SKILL.md +378 -0
  41. package/skills/memory-sync/memory-router.md +185 -0
  42. package/skills/memory-sync/memory-templates.md +201 -0
  43. package/skills/orchestrator/SKILL.md +193 -0
  44. package/skills/session-restore/SKILL.md +240 -0
  45. package/templates/CODEBASE.md +80 -0
  46. package/templates/brain.example.json +321 -0
  47. package/templates/preferences.example.json +21 -0
  48. package/templates/project-identity/android.json +28 -0
  49. package/templates/project-identity/backend-nestjs.json +24 -0
  50. package/templates/project-identity/expo.json +27 -0
  51. package/templates/project-identity/ios.json +27 -0
  52. package/templates/project-identity/web-nextjs.json +24 -0
  53. package/templates/session.example.json +53 -0
  54. package/templates/specs/design-template.md +166 -0
  55. package/templates/specs/requirements-template.md +65 -0
  56. package/templates/specs/tasks-template.md +132 -0
  57. package/templates/structures/android.txt +10 -0
  58. package/templates/structures/backend-nestjs.txt +6 -0
  59. package/templates/structures/expo.txt +9 -0
  60. package/templates/structures/ios.txt +9 -0
  61. package/templates/structures/web-nextjs.txt +6 -0
  62. package/templates/workflow_dual_mode_template.md +87 -0
  63. package/workflows/_uncategorized/README.md +339 -0
  64. package/workflows/_uncategorized/ads-creative.md +357 -0
  65. package/workflows/_uncategorized/ads-full-optimization.md +308 -0
  66. package/workflows/_uncategorized/ads-plan.md +247 -0
  67. package/workflows/_uncategorized/ads-user-analysis.md +337 -0
  68. package/workflows/_uncategorized/skill-health.md +35 -0
  69. package/workflows/_uncategorized/skill-rollback.md +35 -0
  70. package/workflows/ads/admob.md +62 -0
  71. package/workflows/ads/ads-analyst.md +201 -0
  72. package/workflows/ads/ads-audit.md +106 -0
  73. package/workflows/ads/ads-optimize.md +97 -0
  74. package/workflows/ads/ads-targeting.md +241 -0
  75. package/workflows/ads/adsExpert.md +160 -0
  76. package/workflows/ads/smali-ads-config.md +400 -0
  77. package/workflows/ads/smali-ads-flow.md +331 -0
  78. package/workflows/ads/smali-ads-interstitial.md +377 -0
  79. package/workflows/ads/smali-ads-native.md +382 -0
  80. package/workflows/context/auto-execution-workflow.md +291 -0
  81. package/workflows/context/auto-implement.md +211 -0
  82. package/workflows/context/codebase-sync.md +163 -0
  83. package/workflows/context/logic-reasoning-workflow.md +260 -0
  84. package/workflows/context/next.md +195 -0
  85. package/workflows/context/recap.md +212 -0
  86. package/workflows/context/save-brain.md +285 -0
  87. package/workflows/context/user-intent-analysis-workflow.md +206 -0
  88. package/workflows/expert/codeExpert.md +126 -0
  89. package/workflows/expert/debugExpert.md +136 -0
  90. package/workflows/expert/planExpert.md +112 -0
  91. package/workflows/git/cloudflare-tunnel.md +135 -0
  92. package/workflows/git/git-commit-workflow.md +75 -0
  93. package/workflows/git/hotfix.md +357 -0
  94. package/workflows/git/release-notes.md +160 -0
  95. package/workflows/git/rollback.md +52 -0
  96. package/workflows/git/smart-git-ops.md +103 -0
  97. package/workflows/lifecycle/brainstorm.md +377 -0
  98. package/workflows/lifecycle/code.md +663 -0
  99. package/workflows/lifecycle/debug.md +116 -0
  100. package/workflows/lifecycle/deploy.md +95 -0
  101. package/workflows/lifecycle/init.md +152 -0
  102. package/workflows/lifecycle/master-code-workflow.md +300 -0
  103. package/workflows/lifecycle/migration.md +196 -0
  104. package/workflows/lifecycle/plan.md +91 -0
  105. package/workflows/lifecycle/refactor.md +165 -0
  106. package/workflows/lifecycle/run.md +52 -0
  107. package/workflows/lifecycle/test.md +91 -0
  108. package/workflows/meta/customize.md +346 -0
  109. package/workflows/meta/file-protection-rules.md +129 -0
  110. package/workflows/meta/help.html +350 -0
  111. package/workflows/meta/project-identity-enforcement.md +180 -0
  112. package/workflows/mobile/app-analysis.md +64 -0
  113. package/workflows/mobile/maestro-qa-workflow.md +470 -0
  114. package/workflows/mobile/maestro-test-workflow.md +84 -0
  115. package/workflows/mobile/structure-clean-architect.md +271 -0
  116. package/workflows/mobile/turbo-mobile-build.md +190 -0
  117. package/workflows/quality/accessibility-audit.md +311 -0
  118. package/workflows/quality/audit.md +217 -0
  119. package/workflows/quality/bug-hunter.md +243 -0
  120. package/workflows/quality/code-janitor.md +209 -0
  121. package/workflows/quality/code-quality-rules.md +132 -0
  122. package/workflows/quality/performance-audit.md +343 -0
  123. package/workflows/quality/project-audit.md +61 -0
  124. package/workflows/quality/self-healing-test.md +192 -0
  125. package/workflows/quality/ui-review.md +130 -0
  126. package/workflows/quality/ux-audit.md +213 -0
  127. package/workflows/quality/visual-debug.md +34 -0
  128. package/workflows/roles/oracle.md +267 -0
  129. package/workflows/roles/product-manager-workflow.md +52 -0
  130. package/workflows/roles/qa-engineer-workflow.md +41 -0
  131. package/workflows/roles/tech-lead-workflow.md +45 -0
  132. package/workflows/roles/ui-ux-designer-workflow.md +42 -0
  133. package/workflows/roles/vibe-coding-master-workflow.md +52 -0
  134. package/workflows/ui/app-screen-analyzer.md +152 -0
  135. package/workflows/ui/create-feature.md +332 -0
  136. package/workflows/ui/create-spec-architect.md +184 -0
  137. package/workflows/ui/design-to-ui.md +308 -0
  138. package/workflows/ui/ui-first-methodology.md +279 -0
  139. package/workflows/ui/visualize.md +298 -0
package/bin/awf.js ADDED
@@ -0,0 +1,549 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * AWF v6.0 CLI — Antigravity Workflow Framework
5
+ * Unified installer, updater, and manager for AI agent workflows.
6
+ *
7
+ * Usage:
8
+ * awf install Install AWF into ~/.gemini/antigravity/
9
+ * awf uninstall Remove AWF from system
10
+ * awf update Update to latest version
11
+ * awf doctor Check installation health
12
+ * awf enable-pack Enable a skill pack
13
+ * awf disable-pack Disable a skill pack
14
+ * awf list-packs List available skill packs
15
+ * awf version Show current version
16
+ *
17
+ * Created by Kien AI
18
+ */
19
+
20
+ const fs = require('fs');
21
+ const path = require('path');
22
+ const { execSync } = require('child_process');
23
+
24
+ // ─── Constants ────────────────────────────────────────────────────────────────
25
+
26
+ const AWF_VERSION = fs.readFileSync(path.join(__dirname, '..', 'VERSION'), 'utf8').trim();
27
+ const AWF_ROOT = path.join(__dirname, '..');
28
+ const HOME = process.env.HOME || process.env.USERPROFILE;
29
+
30
+ const TARGETS = {
31
+ antigravity: path.join(HOME, '.gemini', 'antigravity'),
32
+ geminiMd: path.join(HOME, '.gemini', 'GEMINI.md'),
33
+ versionFile: path.join(HOME, '.gemini', 'awf_version'),
34
+ agentsDir: null, // Set per-project
35
+ };
36
+
37
+ // Mapping: source dir in package → target dir in antigravity
38
+ const SYNC_MAP = {
39
+ 'core/GEMINI.md': 'GEMINI.md',
40
+ 'core/AGENTS.md': 'global_workflows/AGENTS.md',
41
+ 'core/orchestrator.md': 'skills/orchestrator/SKILL.md',
42
+ 'workflows': 'global_workflows',
43
+ 'skills': 'skills',
44
+ 'schemas': 'schemas',
45
+ 'templates': 'templates',
46
+ };
47
+
48
+ // ─── Colors ──────────────────────────────────────────────────────────────────
49
+
50
+ const C = {
51
+ reset: '\x1b[0m',
52
+ red: '\x1b[31m',
53
+ green: '\x1b[32m',
54
+ yellow: '\x1b[33m',
55
+ cyan: '\x1b[36m',
56
+ gray: '\x1b[90m',
57
+ bold: '\x1b[1m',
58
+ };
59
+
60
+ function log(msg) { console.log(msg); }
61
+ function ok(msg) { log(`${C.green}✅ ${msg}${C.reset}`); }
62
+ function warn(msg) { log(`${C.yellow}⚠️ ${msg}${C.reset}`); }
63
+ function err(msg) { log(`${C.red}❌ ${msg}${C.reset}`); }
64
+ function info(msg) { log(`${C.cyan}ℹ️ ${msg}${C.reset}`); }
65
+ function dim(msg) { log(`${C.gray} ${msg}${C.reset}`); }
66
+
67
+ // ─── Utility Functions ──────────────────────────────────────────────────────
68
+
69
+ /**
70
+ * Recursively copy directory, preserving structure.
71
+ * Does NOT overwrite files prefixed with `.` (user configs).
72
+ */
73
+ function copyDirRecursive(src, dest, options = {}) {
74
+ const { flatten = false, dryRun = false, overwrite = true } = options;
75
+ let count = 0;
76
+
77
+ if (!fs.existsSync(src)) return count;
78
+ if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
79
+
80
+ const entries = fs.readdirSync(src, { withFileTypes: true });
81
+
82
+ for (const entry of entries) {
83
+ if (entry.name === '.DS_Store') continue;
84
+
85
+ const srcPath = path.join(src, entry.name);
86
+
87
+ if (entry.isDirectory()) {
88
+ if (flatten) {
89
+ // Flatten: copy workflow files from subcategories into single dir
90
+ count += copyDirRecursive(srcPath, dest, options);
91
+ } else {
92
+ const destPath = path.join(dest, entry.name);
93
+ count += copyDirRecursive(srcPath, destPath, options);
94
+ }
95
+ } else {
96
+ const destPath = path.join(dest, entry.name);
97
+
98
+ // Skip user config files if they already exist and overwrite is off
99
+ if (!overwrite && fs.existsSync(destPath)) {
100
+ dim(`Skip (exists): ${entry.name}`);
101
+ continue;
102
+ }
103
+
104
+ if (!dryRun) {
105
+ fs.copyFileSync(srcPath, destPath);
106
+ }
107
+ count++;
108
+ }
109
+ }
110
+
111
+ return count;
112
+ }
113
+
114
+ /**
115
+ * Flatten workflow category dirs into single global_workflows dir.
116
+ * workflows/lifecycle/code.md → global_workflows/code.md
117
+ * workflows/context/recap.md → global_workflows/recap.md
118
+ */
119
+ function flattenWorkflows(srcBase, destDir) {
120
+ let count = 0;
121
+
122
+ if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
123
+
124
+ const categories = fs.readdirSync(srcBase, { withFileTypes: true });
125
+
126
+ for (const cat of categories) {
127
+ if (!cat.isDirectory()) continue;
128
+
129
+ const catPath = path.join(srcBase, cat.name);
130
+ const files = fs.readdirSync(catPath, { withFileTypes: true });
131
+
132
+ for (const file of files) {
133
+ if (file.name === '.DS_Store') continue;
134
+
135
+ if (file.isFile() && file.name.endsWith('.md')) {
136
+ const srcFile = path.join(catPath, file.name);
137
+ const destFile = path.join(destDir, file.name);
138
+ fs.copyFileSync(srcFile, destFile);
139
+ count++;
140
+ }
141
+ }
142
+ }
143
+
144
+ return count;
145
+ }
146
+
147
+ /**
148
+ * Install or update GEMINI.md into ~/.gemini/
149
+ */
150
+ function syncGeminiMd() {
151
+ const srcGemini = path.join(AWF_ROOT, 'core', 'GEMINI.md');
152
+ const destGemini = TARGETS.geminiMd;
153
+
154
+ const destDir = path.dirname(destGemini);
155
+ if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
156
+
157
+ // Read existing GEMINI.md if present
158
+ let existingContent = '';
159
+ if (fs.existsSync(destGemini)) {
160
+ existingContent = fs.readFileSync(destGemini, 'utf8');
161
+
162
+ // Backup existing
163
+ const backupDir = path.join(destDir, 'antigravity', 'backup');
164
+ if (!fs.existsSync(backupDir)) fs.mkdirSync(backupDir, { recursive: true });
165
+
166
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
167
+ const backupPath = path.join(backupDir, `GEMINI_${timestamp}.md.bak`);
168
+ fs.copyFileSync(destGemini, backupPath);
169
+ dim(`Backup: ${backupPath}`);
170
+ }
171
+
172
+ // Copy new GEMINI.md
173
+ fs.copyFileSync(srcGemini, destGemini);
174
+ ok('GEMINI.md updated');
175
+ }
176
+
177
+ // ─── Commands ────────────────────────────────────────────────────────────────
178
+
179
+ function cmdInstall() {
180
+ log('');
181
+ log(`${C.cyan}${C.bold}╔══════════════════════════════════════════════════════════╗${C.reset}`);
182
+ log(`${C.cyan}${C.bold}║ 🚀 AWF v${AWF_VERSION} — Antigravity Workflow Framework ║${C.reset}`);
183
+ log(`${C.cyan}${C.bold}╚══════════════════════════════════════════════════════════╝${C.reset}`);
184
+ log('');
185
+
186
+ const target = TARGETS.antigravity;
187
+
188
+ // 1. Ensure target dirs exist
189
+ info('Creating directories...');
190
+ const dirs = ['global_workflows', 'skills', 'schemas', 'templates'];
191
+ for (const dir of dirs) {
192
+ const fullPath = path.join(target, dir);
193
+ if (!fs.existsSync(fullPath)) {
194
+ fs.mkdirSync(fullPath, { recursive: true });
195
+ }
196
+ }
197
+ ok('Directories ready');
198
+
199
+ // 2. Sync GEMINI.md
200
+ info('Syncing GEMINI.md...');
201
+ syncGeminiMd();
202
+
203
+ // 3. Backup and flatten workflows
204
+ info('Installing workflows...');
205
+ const wfSrc = path.join(AWF_ROOT, 'workflows');
206
+ const wfDest = path.join(target, 'global_workflows');
207
+
208
+ // Backup existing global_workflows to a zip file
209
+ if (fs.existsSync(wfDest)) {
210
+ const backupDir = path.join(target, 'backup');
211
+ if (!fs.existsSync(backupDir)) fs.mkdirSync(backupDir, { recursive: true });
212
+
213
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
214
+ const zipFile = path.join(backupDir, `global_workflows_${timestamp}.bak.zip`);
215
+ try {
216
+ info('Creating zip backup of global_workflows...');
217
+ execSync(`zip -r "${zipFile}" .`, { cwd: wfDest, stdio: 'ignore' });
218
+ ok(`Backup created: ${zipFile}`);
219
+ } catch (e) {
220
+ warn(`Failed to create backup zip: ${e.message}`);
221
+ }
222
+ }
223
+
224
+ const wfCount = flattenWorkflows(wfSrc, wfDest);
225
+ ok(`${wfCount} workflows installed`);
226
+
227
+ // 4. Copy AGENTS.md
228
+ const agentsSrc = path.join(AWF_ROOT, 'core', 'AGENTS.md');
229
+ const agentsDest = path.join(target, 'global_workflows', 'AGENTS.md');
230
+ if (fs.existsSync(agentsSrc)) {
231
+ fs.copyFileSync(agentsSrc, agentsDest);
232
+ ok('AGENTS.md installed');
233
+ }
234
+
235
+ // 5. Copy skills
236
+ info('Installing skills...');
237
+ const skillsSrc = path.join(AWF_ROOT, 'skills');
238
+ const skillsDest = path.join(target, 'skills');
239
+ const skillCount = copyDirRecursive(skillsSrc, skillsDest);
240
+ ok(`${skillCount} skill files installed`);
241
+
242
+ // 6. Copy orchestrator
243
+ const orchSrc = path.join(AWF_ROOT, 'core', 'orchestrator.md');
244
+ const orchDestDir = path.join(target, 'skills', 'orchestrator');
245
+ if (!fs.existsSync(orchDestDir)) fs.mkdirSync(orchDestDir, { recursive: true });
246
+ fs.copyFileSync(orchSrc, path.join(orchDestDir, 'SKILL.md'));
247
+ ok('Orchestrator skill installed');
248
+
249
+ // 7. Copy schemas (always overwrite)
250
+ info('Installing schemas...');
251
+ const schemaSrc = path.join(AWF_ROOT, 'schemas');
252
+ const schemaDest = path.join(target, 'schemas');
253
+ const schemaCount = copyDirRecursive(schemaSrc, schemaDest);
254
+ ok(`${schemaCount} schemas installed`);
255
+
256
+ // 8. Copy templates (don't overwrite existing)
257
+ info('Installing templates...');
258
+ const tmplSrc = path.join(AWF_ROOT, 'templates');
259
+ const tmplDest = path.join(target, 'templates');
260
+ const tmplCount = copyDirRecursive(tmplSrc, tmplDest, { overwrite: false });
261
+ ok(`${tmplCount} templates installed`);
262
+
263
+ // 9. Save version
264
+ fs.writeFileSync(TARGETS.versionFile, AWF_VERSION);
265
+ ok(`Version ${AWF_VERSION} saved`);
266
+
267
+ // 10. Summary
268
+ log('');
269
+ log(`${C.gray}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}`);
270
+ log(`${C.yellow}${C.bold}🎉 AWF v${AWF_VERSION} installed successfully!${C.reset}`);
271
+ log('');
272
+ dim(`Workflows: ${path.join(target, 'global_workflows')}`);
273
+ dim(`Skills: ${path.join(target, 'skills')}`);
274
+ dim(`Schemas: ${path.join(target, 'schemas')}`);
275
+ dim(`Templates: ${path.join(target, 'templates')}`);
276
+ dim(`GEMINI.md: ${TARGETS.geminiMd}`);
277
+ log('');
278
+ log(`${C.cyan}👉 Type '/plan' in your AI chat to get started.${C.reset}`);
279
+ log(`${C.cyan}👉 Run 'awf doctor' to verify installation.${C.reset}`);
280
+ log('');
281
+ }
282
+
283
+ function cmdUninstall() {
284
+ warn('Uninstalling AWF...');
285
+
286
+ // Remove version file
287
+ if (fs.existsSync(TARGETS.versionFile)) {
288
+ fs.unlinkSync(TARGETS.versionFile);
289
+ ok('Version file removed');
290
+ }
291
+
292
+ // Don't remove workflows/skills — user may have custom ones
293
+ warn('Workflow and skill files were NOT removed (may contain custom content).');
294
+ warn('To fully remove, manually delete:');
295
+ dim(TARGETS.antigravity);
296
+
297
+ ok('AWF uninstalled. Custom files preserved.');
298
+ }
299
+
300
+ function cmdUpdate() {
301
+ info(`Updating to AWF v${AWF_VERSION}...`);
302
+
303
+ // Check current version
304
+ let currentVersion = '0.0.0';
305
+ if (fs.existsSync(TARGETS.versionFile)) {
306
+ currentVersion = fs.readFileSync(TARGETS.versionFile, 'utf8').trim();
307
+ }
308
+
309
+ if (currentVersion === AWF_VERSION) {
310
+ ok(`Already on latest version (${AWF_VERSION})`);
311
+ return;
312
+ }
313
+
314
+ info(`Upgrading from ${currentVersion} → ${AWF_VERSION}`);
315
+ cmdInstall();
316
+ }
317
+
318
+ function cmdDoctor() {
319
+ log('');
320
+ log(`${C.cyan}${C.bold}🏥 AWF Health Check${C.reset}`);
321
+ log('');
322
+
323
+ let issues = 0;
324
+
325
+ // 1. Check GEMINI.md
326
+ if (fs.existsSync(TARGETS.geminiMd)) {
327
+ ok('GEMINI.md exists');
328
+ } else {
329
+ err('GEMINI.md missing'); issues++;
330
+ }
331
+
332
+ // 2. Check global_workflows
333
+ const wfDir = path.join(TARGETS.antigravity, 'global_workflows');
334
+ if (fs.existsSync(wfDir)) {
335
+ const wfFiles = fs.readdirSync(wfDir).filter(f => f.endsWith('.md'));
336
+ ok(`${wfFiles.length} workflows found`);
337
+
338
+ // Check essential workflows
339
+ const essential = ['code.md', 'plan.md', 'debug.md', 'save-brain.md', 'recap.md', 'init.md'];
340
+ for (const wf of essential) {
341
+ if (!wfFiles.includes(wf)) {
342
+ warn(`Essential workflow missing: ${wf}`); issues++;
343
+ }
344
+ }
345
+ } else {
346
+ err('global_workflows/ directory missing'); issues++;
347
+ }
348
+
349
+ // 3. Check skills
350
+ const skillsDir = path.join(TARGETS.antigravity, 'skills');
351
+ if (fs.existsSync(skillsDir)) {
352
+ const skills = fs.readdirSync(skillsDir, { withFileTypes: true })
353
+ .filter(d => d.isDirectory())
354
+ .map(d => d.name);
355
+ ok(`${skills.length} skills found`);
356
+
357
+ // Check essential skills
358
+ const essentialSkills = ['orchestrator', 'beads-manager', 'session-restore'];
359
+ for (const s of essentialSkills) {
360
+ if (!skills.includes(s)) {
361
+ warn(`Essential skill missing: ${s}`); issues++;
362
+ }
363
+ }
364
+ } else {
365
+ err('skills/ directory missing'); issues++;
366
+ }
367
+
368
+ // 4. Check schemas
369
+ const schemasDir = path.join(TARGETS.antigravity, 'schemas');
370
+ if (fs.existsSync(schemasDir)) {
371
+ const schemas = fs.readdirSync(schemasDir).filter(f => f.endsWith('.json'));
372
+ ok(`${schemas.length} schemas found`);
373
+ } else {
374
+ warn('schemas/ directory missing'); issues++;
375
+ }
376
+
377
+ // 5. Check version
378
+ if (fs.existsSync(TARGETS.versionFile)) {
379
+ const v = fs.readFileSync(TARGETS.versionFile, 'utf8').trim();
380
+ ok(`AWF version: ${v}`);
381
+ if (v !== AWF_VERSION) {
382
+ warn(`Package version (${AWF_VERSION}) differs from installed (${v}). Run 'awf update'.`);
383
+ }
384
+ } else {
385
+ warn('Version file missing. Run "awf install" first.'); issues++;
386
+ }
387
+
388
+ // Summary
389
+ log('');
390
+ if (issues === 0) {
391
+ log(`${C.green}${C.bold}✅ All checks passed! AWF is healthy.${C.reset}`);
392
+ } else {
393
+ log(`${C.yellow}${C.bold}⚠️ ${issues} issue(s) found. Run 'awf install' to fix.${C.reset}`);
394
+ }
395
+ log('');
396
+ }
397
+
398
+ function cmdEnablePack(packName) {
399
+ if (!packName) {
400
+ err('Usage: awf enable-pack <pack-name>');
401
+ log('');
402
+ cmdListPacks();
403
+ return;
404
+ }
405
+
406
+ const packSrc = path.join(AWF_ROOT, 'skill-packs', packName);
407
+
408
+ if (!fs.existsSync(packSrc)) {
409
+ err(`Skill pack "${packName}" not found.`);
410
+ cmdListPacks();
411
+ return;
412
+ }
413
+
414
+ const target = path.join(TARGETS.antigravity, 'skills');
415
+ info(`Enabling skill pack: ${packName}`);
416
+
417
+ // Copy all skills from pack into skills/
418
+ const count = copyDirRecursive(packSrc, target);
419
+ ok(`${count} files from "${packName}" pack installed`);
420
+ }
421
+
422
+ function cmdDisablePack(packName) {
423
+ if (!packName) {
424
+ err('Usage: awf disable-pack <pack-name>');
425
+ return;
426
+ }
427
+
428
+ const packSrc = path.join(AWF_ROOT, 'skill-packs', packName);
429
+
430
+ if (!fs.existsSync(packSrc)) {
431
+ err(`Skill pack "${packName}" not found.`);
432
+ return;
433
+ }
434
+
435
+ // Get list of skill dirs in this pack
436
+ const skillDirs = fs.readdirSync(packSrc, { withFileTypes: true })
437
+ .filter(d => d.isDirectory())
438
+ .map(d => d.name);
439
+
440
+ const target = path.join(TARGETS.antigravity, 'skills');
441
+
442
+ for (const skillDir of skillDirs) {
443
+ const destPath = path.join(target, skillDir);
444
+ if (fs.existsSync(destPath)) {
445
+ // Move to backup instead of deleting
446
+ const backupDir = path.join(TARGETS.antigravity, 'backup', 'skills');
447
+ if (!fs.existsSync(backupDir)) fs.mkdirSync(backupDir, { recursive: true });
448
+ fs.renameSync(destPath, path.join(backupDir, skillDir));
449
+ dim(`Moved to backup: ${skillDir}`);
450
+ }
451
+ }
452
+
453
+ ok(`Skill pack "${packName}" disabled (backed up)`);
454
+ }
455
+
456
+ function cmdListPacks() {
457
+ const packsDir = path.join(AWF_ROOT, 'skill-packs');
458
+
459
+ log('');
460
+ log(`${C.cyan}${C.bold}📦 Available Skill Packs${C.reset}`);
461
+ log('');
462
+
463
+ if (!fs.existsSync(packsDir)) {
464
+ warn('No skill packs directory found.');
465
+ return;
466
+ }
467
+
468
+ const packs = fs.readdirSync(packsDir, { withFileTypes: true })
469
+ .filter(d => d.isDirectory());
470
+
471
+ if (packs.length === 0) {
472
+ info('No skill packs available yet.');
473
+ return;
474
+ }
475
+
476
+ for (const pack of packs) {
477
+ const readmePath = path.join(packsDir, pack.name, 'README.md');
478
+ let desc = '';
479
+ if (fs.existsSync(readmePath)) {
480
+ const content = fs.readFileSync(readmePath, 'utf8');
481
+ desc = content.split('\n').find(l => l.trim() && !l.startsWith('#')) || '';
482
+ }
483
+ log(` ${C.green}${pack.name}${C.reset} ${C.gray}${desc}${C.reset}`);
484
+ }
485
+
486
+ log('');
487
+ log(`${C.cyan}Usage: awf enable-pack <name>${C.reset}`);
488
+ log('');
489
+ }
490
+
491
+ function cmdVersion() {
492
+ log(`AWF v${AWF_VERSION}`);
493
+ }
494
+
495
+ function cmdHelp() {
496
+ log('');
497
+ log(`${C.cyan}${C.bold}AWF v${AWF_VERSION} — Antigravity Workflow Framework${C.reset}`);
498
+ log('');
499
+ log('Commands:');
500
+ log(` ${C.green}install${C.reset} Install AWF into ~/.gemini/antigravity/`);
501
+ log(` ${C.green}uninstall${C.reset} Remove AWF (preserves custom files)`);
502
+ log(` ${C.green}update${C.reset} Update to latest version`);
503
+ log(` ${C.green}doctor${C.reset} Check installation health`);
504
+ log(` ${C.green}enable-pack${C.reset} Enable a skill pack`);
505
+ log(` ${C.green}disable-pack${C.reset} Disable a skill pack`);
506
+ log(` ${C.green}list-packs${C.reset} List available skill packs`);
507
+ log(` ${C.green}version${C.reset} Show version`);
508
+ log(` ${C.green}help${C.reset} Show this help`);
509
+ log('');
510
+ }
511
+
512
+ // ─── Main ────────────────────────────────────────────────────────────────────
513
+
514
+ const [, , command, ...args] = process.argv;
515
+
516
+ switch (command) {
517
+ case 'install':
518
+ cmdInstall();
519
+ break;
520
+ case 'uninstall':
521
+ cmdUninstall();
522
+ break;
523
+ case 'update':
524
+ cmdUpdate();
525
+ break;
526
+ case 'doctor':
527
+ cmdDoctor();
528
+ break;
529
+ case 'enable-pack':
530
+ cmdEnablePack(args[0]);
531
+ break;
532
+ case 'disable-pack':
533
+ cmdDisablePack(args[0]);
534
+ break;
535
+ case 'list-packs':
536
+ cmdListPacks();
537
+ break;
538
+ case 'version':
539
+ case '--version':
540
+ case '-v':
541
+ cmdVersion();
542
+ break;
543
+ case 'help':
544
+ case '--help':
545
+ case '-h':
546
+ default:
547
+ cmdHelp();
548
+ break;
549
+ }