@leejungkiin/awkit 1.1.1 → 1.1.3
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/awk.js +215 -72
- package/bin/cline-generators.js +73 -0
- package/bin/codex-generators.js +108 -0
- package/core/GEMINI.md +14 -17
- package/package.json +2 -2
- package/skill-packs/superpowers/README.md +59 -0
- package/skill-packs/superpowers/pack.json +15 -0
- package/skill-packs/superpowers/skills/brainstorming/SKILL.md +96 -0
- package/skill-packs/superpowers/skills/executing-plans/SKILL.md +100 -0
- package/skill-packs/superpowers/skills/finishing-a-development-branch/SKILL.md +213 -0
- package/skill-packs/superpowers/skills/receiving-code-review/SKILL.md +213 -0
- package/skill-packs/superpowers/skills/requesting-code-review/SKILL.md +115 -0
- package/skill-packs/superpowers/skills/requesting-code-review/code-reviewer.md +146 -0
- package/skill-packs/superpowers/skills/single-flow-task-execution/SKILL.md +359 -0
- package/skill-packs/superpowers/skills/single-flow-task-execution/code-quality-reviewer-prompt.md +20 -0
- package/skill-packs/superpowers/skills/single-flow-task-execution/implementer-prompt.md +78 -0
- package/skill-packs/superpowers/skills/single-flow-task-execution/spec-reviewer-prompt.md +61 -0
- package/skill-packs/superpowers/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/skill-packs/superpowers/skills/systematic-debugging/SKILL.md +296 -0
- package/skill-packs/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/skill-packs/superpowers/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/skill-packs/superpowers/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/skill-packs/superpowers/skills/systematic-debugging/find-polluter.sh +63 -0
- package/skill-packs/superpowers/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/skill-packs/superpowers/skills/systematic-debugging/test-academic.md +14 -0
- package/skill-packs/superpowers/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/skill-packs/superpowers/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/skill-packs/superpowers/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/skill-packs/superpowers/skills/test-driven-development/SKILL.md +371 -0
- package/skill-packs/superpowers/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/skill-packs/superpowers/skills/using-git-worktrees/SKILL.md +223 -0
- package/skill-packs/superpowers/skills/using-superpowers/SKILL.md +97 -0
- package/skill-packs/superpowers/skills/verification-before-completion/SKILL.md +139 -0
- package/skill-packs/superpowers/skills/writing-plans/SKILL.md +108 -0
- package/skill-packs/superpowers/skills/writing-skills/SKILL.md +716 -0
- package/skill-packs/superpowers/skills/writing-skills/antigravity-best-practices.md +1173 -0
- package/skill-packs/superpowers/skills/writing-skills/examples/AGENTS_MD_TESTING.md +189 -0
- package/skill-packs/superpowers/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/skill-packs/superpowers/skills/writing-skills/persuasion-principles.md +187 -0
- package/skill-packs/superpowers/skills/writing-skills/render-graphs.js +175 -0
- package/skill-packs/superpowers/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/skills/CATALOG.md +7 -0
- package/skills/orchestrator/SKILL.md +0 -4
- package/skills/symphony-enforcer/SKILL.md +188 -53
- package/templates/specs/PROJECT.md +50 -0
- package/templates/specs/ROADMAP.md +79 -0
- package/templates/specs/TECH-SPEC.md +81 -0
- package/templates/specs/task-spec-template.xml +65 -0
- package/workflows/lifecycle/init.md +103 -91
- package/core/AGENTS.md +0 -38
- package/skills/beads-manager/SKILL.md +0 -459
- package/workflows/_uncategorized/AGENTS.md +0 -38
package/bin/awk.js
CHANGED
|
@@ -28,17 +28,75 @@ const path = require('path');
|
|
|
28
28
|
const https = require('https');
|
|
29
29
|
const { execSync, spawnSync } = require('child_process');
|
|
30
30
|
|
|
31
|
-
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
32
|
-
|
|
33
31
|
const AWK_VERSION = fs.readFileSync(path.join(__dirname, '..', 'VERSION'), 'utf8').trim();
|
|
34
32
|
const AWK_ROOT = path.join(__dirname, '..');
|
|
35
33
|
const HOME = process.env.HOME || process.env.USERPROFILE;
|
|
36
34
|
|
|
35
|
+
const { generateClineRules, generateClineWorkflows, generateClineSkills } = require('./cline-generators');
|
|
36
|
+
const { generateCodexAgentsMd, generateCodexSkills, generateCodexAgents } = require('./codex-generators');
|
|
37
|
+
|
|
38
|
+
// ─── Platform Definitions ──────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
const PLATFORMS = {
|
|
41
|
+
antigravity: {
|
|
42
|
+
name: 'Antigravity (Gemini Code Assist)',
|
|
43
|
+
globalRoot: path.join(HOME, '.gemini', 'antigravity'),
|
|
44
|
+
rulesFile: path.join(HOME, '.gemini', 'GEMINI.md'),
|
|
45
|
+
versionFile: path.join(HOME, '.gemini', 'awk_version'),
|
|
46
|
+
dirs: {
|
|
47
|
+
workflows: 'global_workflows',
|
|
48
|
+
skills: 'skills',
|
|
49
|
+
schemas: 'schemas',
|
|
50
|
+
templates: 'templates',
|
|
51
|
+
},
|
|
52
|
+
supportsCustomModes: false,
|
|
53
|
+
supportsSubagents: false,
|
|
54
|
+
},
|
|
55
|
+
cline: {
|
|
56
|
+
name: 'Cline (VS Code)',
|
|
57
|
+
globalRoot: process.cwd(), // Local to project
|
|
58
|
+
rulesFile: path.join(HOME, '.cline', 'rules', 'antigravity-rules.md'),
|
|
59
|
+
versionFile: path.join(HOME, '.cline', 'awk_version'),
|
|
60
|
+
dirs: {
|
|
61
|
+
workflows: '.clinerules',
|
|
62
|
+
skills: '.clinerules/skills',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
codex: {
|
|
66
|
+
name: 'Codex (OpenAI)',
|
|
67
|
+
globalRoot: path.join(HOME, '.codex'),
|
|
68
|
+
rulesFile: path.join(HOME, '.codex', 'AGENTS.md'),
|
|
69
|
+
versionFile: path.join(HOME, '.codex', 'awk_version'),
|
|
70
|
+
dirs: {
|
|
71
|
+
agents: 'agents',
|
|
72
|
+
skills: '../.agents/skills',
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const PLATFORM_FILE = path.join(HOME, '.awkit_platform');
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get the currently configured platform.
|
|
81
|
+
* Reads from ~/.awkit_platform, defaults to 'antigravity'.
|
|
82
|
+
*/
|
|
83
|
+
function getActivePlatform() {
|
|
84
|
+
return 'antigravity';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function savePlatform(platform) {
|
|
88
|
+
fs.writeFileSync(PLATFORM_FILE, platform, 'utf8');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Active platform — resolved at install time or from saved config
|
|
92
|
+
let activePlatform = 'antigravity';
|
|
93
|
+
|
|
94
|
+
// Legacy compat: TARGETS object derived from active platform
|
|
37
95
|
const TARGETS = {
|
|
38
|
-
antigravity
|
|
39
|
-
geminiMd
|
|
40
|
-
versionFile
|
|
41
|
-
agentsDir: null,
|
|
96
|
+
get antigravity() { return PLATFORMS[activePlatform].globalRoot; },
|
|
97
|
+
get geminiMd() { return PLATFORMS[activePlatform].rulesFile || path.join(HOME, '.gemini', 'GEMINI.md'); },
|
|
98
|
+
get versionFile() { return PLATFORMS[activePlatform].versionFile; },
|
|
99
|
+
agentsDir: null,
|
|
42
100
|
};
|
|
43
101
|
|
|
44
102
|
// Mapping: source dir in package → target dir in antigravity
|
|
@@ -87,6 +145,22 @@ function promptYN(question) {
|
|
|
87
145
|
}
|
|
88
146
|
}
|
|
89
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Prompt user for a choice, returning the raw answer string.
|
|
150
|
+
* Returns defaultVal if user presses Enter without input.
|
|
151
|
+
*/
|
|
152
|
+
function promptChoice(question, defaultVal = '') {
|
|
153
|
+
try {
|
|
154
|
+
const answer = execSync(
|
|
155
|
+
`bash -c 'read -p "${question} (default: ${defaultVal}): " ans; echo $ans'`,
|
|
156
|
+
{ stdio: ['inherit', 'pipe', 'inherit'] }
|
|
157
|
+
).toString().trim();
|
|
158
|
+
return answer || defaultVal;
|
|
159
|
+
} catch (e) {
|
|
160
|
+
return defaultVal;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
90
164
|
// ─── Utility Functions ──────────────────────────────────────────────────────
|
|
91
165
|
|
|
92
166
|
/**
|
|
@@ -238,24 +312,38 @@ function installSymphony({ silent = false } = {}) {
|
|
|
238
312
|
}
|
|
239
313
|
}
|
|
240
314
|
|
|
241
|
-
function cmdInstall() {
|
|
315
|
+
function cmdInstall(platformArg) {
|
|
242
316
|
log('');
|
|
243
317
|
log(`${C.cyan}${C.bold}╔══════════════════════════════════════════════════════════╗${C.reset}`);
|
|
244
318
|
log(`${C.cyan}${C.bold}║ 🚀 AWK v${AWK_VERSION} — Antigravity Workflow Kit ║${C.reset}`);
|
|
245
319
|
log(`${C.cyan}${C.bold}╚══════════════════════════════════════════════════════════╝${C.reset}`);
|
|
246
320
|
log('');
|
|
247
321
|
|
|
248
|
-
|
|
322
|
+
// Platform selection
|
|
323
|
+
let platform = platformArg || getActivePlatform();
|
|
324
|
+
|
|
325
|
+
if (!PLATFORMS[platform]) {
|
|
326
|
+
err(`Unknown platform: ${platform}.`);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
activePlatform = platform;
|
|
331
|
+
savePlatform(platform);
|
|
249
332
|
|
|
250
|
-
|
|
333
|
+
const plat = PLATFORMS[platform];
|
|
334
|
+
const target = plat.globalRoot;
|
|
335
|
+
|
|
336
|
+
info(`Installing for ${C.bold}${plat.name}${C.reset}...`);
|
|
251
337
|
log('');
|
|
338
|
+
|
|
339
|
+
// 0. Install Symphony if missing (shared dependency)
|
|
252
340
|
info('Checking dependencies...');
|
|
253
341
|
installSymphony();
|
|
254
342
|
|
|
255
343
|
// 1. Ensure target dirs exist
|
|
256
344
|
info('Creating directories...');
|
|
257
|
-
const
|
|
258
|
-
for (const dir of
|
|
345
|
+
const dirKeys = Object.values(plat.dirs);
|
|
346
|
+
for (const dir of dirKeys) {
|
|
259
347
|
const fullPath = path.join(target, dir);
|
|
260
348
|
if (!fs.existsSync(fullPath)) {
|
|
261
349
|
fs.mkdirSync(fullPath, { recursive: true });
|
|
@@ -263,72 +351,104 @@ function cmdInstall() {
|
|
|
263
351
|
}
|
|
264
352
|
ok('Directories ready');
|
|
265
353
|
|
|
266
|
-
// 2. Sync
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
354
|
+
// 2. Sync rules (platform-specific)
|
|
355
|
+
if (platform === 'antigravity') {
|
|
356
|
+
info('Syncing GEMINI.md...');
|
|
357
|
+
syncGeminiMd();
|
|
358
|
+
} else if (platform === 'cline') {
|
|
359
|
+
info('Generating Cline global rules...');
|
|
360
|
+
generateClineRules(path.join(AWK_ROOT, 'core', 'GEMINI.md'), plat.rulesFile);
|
|
361
|
+
} else if (platform === 'codex') {
|
|
362
|
+
info('Generating Codex AGENTS.md...');
|
|
363
|
+
generateCodexAgentsMd(path.join(AWK_ROOT, 'core', 'GEMINI.md'), plat.rulesFile);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// 3. Backup and install workflows
|
|
367
|
+
if (plat.dirs.workflows) {
|
|
368
|
+
info('Installing workflows...');
|
|
369
|
+
const wfSrc = path.join(AWK_ROOT, 'workflows');
|
|
370
|
+
const wfDest = path.join(target, plat.dirs.workflows);
|
|
371
|
+
|
|
372
|
+
// Backup existing workflows
|
|
373
|
+
if (fs.existsSync(wfDest)) {
|
|
374
|
+
const backupDir = path.join(target, 'backup');
|
|
375
|
+
if (!fs.existsSync(backupDir)) fs.mkdirSync(backupDir, { recursive: true });
|
|
376
|
+
|
|
377
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
378
|
+
const zipFile = path.join(backupDir, `workflows_${timestamp}.bak.zip`);
|
|
379
|
+
try {
|
|
380
|
+
execSync(`zip -r "${zipFile}" .`, { cwd: wfDest, stdio: 'ignore' });
|
|
381
|
+
dim(`Backup: ${zipFile}`);
|
|
382
|
+
} catch (e) {
|
|
383
|
+
warn(`Failed to create backup: ${e.message}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
279
386
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
ok(`Backup created: ${zipFile}`);
|
|
286
|
-
} catch (e) {
|
|
287
|
-
warn(`Failed to create backup zip: ${e.message}`);
|
|
387
|
+
if (platform === 'cline') {
|
|
388
|
+
generateClineWorkflows(wfSrc, wfDest);
|
|
389
|
+
} else if (platform !== 'codex') {
|
|
390
|
+
const wfCount = flattenWorkflows(wfSrc, wfDest);
|
|
391
|
+
ok(`${wfCount} workflows installed`);
|
|
288
392
|
}
|
|
289
393
|
}
|
|
290
394
|
|
|
291
|
-
const wfCount = flattenWorkflows(wfSrc, wfDest);
|
|
292
|
-
ok(`${wfCount} workflows installed`);
|
|
293
|
-
|
|
294
395
|
// 4. Copy AGENTS.md
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
fs.
|
|
299
|
-
|
|
396
|
+
if (platform === 'antigravity' && plat.dirs.workflows) {
|
|
397
|
+
const agentsSrc = path.join(AWK_ROOT, 'core', 'AGENTS.md');
|
|
398
|
+
const agentsDest = path.join(target, plat.dirs.workflows, 'AGENTS.md');
|
|
399
|
+
if (fs.existsSync(agentsSrc)) {
|
|
400
|
+
fs.copyFileSync(agentsSrc, agentsDest);
|
|
401
|
+
ok('AGENTS.md installed');
|
|
402
|
+
}
|
|
300
403
|
}
|
|
301
404
|
|
|
302
405
|
// 5. Copy skills
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
406
|
+
if (plat.dirs.skills) {
|
|
407
|
+
info('Installing skills...');
|
|
408
|
+
const skillsSrc = path.join(AWK_ROOT, 'skills');
|
|
409
|
+
const skillsDest = path.join(target, plat.dirs.skills);
|
|
410
|
+
|
|
411
|
+
if (platform === 'cline') {
|
|
412
|
+
generateClineSkills(skillsSrc, skillsDest);
|
|
413
|
+
} else if (platform === 'codex') {
|
|
414
|
+
generateCodexSkills(skillsSrc, skillsDest);
|
|
415
|
+
const agentsDest = path.join(target, plat.dirs.agents);
|
|
416
|
+
generateCodexAgents(skillsSrc, agentsDest);
|
|
417
|
+
} else {
|
|
418
|
+
const skillCount = copyDirRecursive(skillsSrc, skillsDest);
|
|
419
|
+
ok(`${skillCount} skill files installed`);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
308
422
|
|
|
309
423
|
// 6. Copy orchestrator
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
424
|
+
if (platform === 'antigravity') {
|
|
425
|
+
const orchSrc = path.join(AWK_ROOT, 'core', 'orchestrator.md');
|
|
426
|
+
const orchDestDir = path.join(target, plat.dirs.skills, 'orchestrator');
|
|
427
|
+
if (!fs.existsSync(orchDestDir)) fs.mkdirSync(orchDestDir, { recursive: true });
|
|
428
|
+
fs.copyFileSync(orchSrc, path.join(orchDestDir, 'SKILL.md'));
|
|
429
|
+
ok('Orchestrator skill installed');
|
|
430
|
+
}
|
|
315
431
|
|
|
316
432
|
// 7. Copy schemas (always overwrite)
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
433
|
+
if (plat.dirs.schemas) {
|
|
434
|
+
info('Installing schemas...');
|
|
435
|
+
const schemaSrc = path.join(AWK_ROOT, 'schemas');
|
|
436
|
+
const schemaDest = path.join(target, plat.dirs.schemas);
|
|
437
|
+
const schemaCount = copyDirRecursive(schemaSrc, schemaDest);
|
|
438
|
+
ok(`${schemaCount} schemas installed`);
|
|
439
|
+
}
|
|
322
440
|
|
|
323
441
|
// 8. Copy templates (don't overwrite existing)
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
442
|
+
if (plat.dirs.templates) {
|
|
443
|
+
info('Installing templates...');
|
|
444
|
+
const tmplSrc = path.join(AWK_ROOT, 'templates');
|
|
445
|
+
const tmplDest = path.join(target, plat.dirs.templates);
|
|
446
|
+
const tmplCount = copyDirRecursive(tmplSrc, tmplDest, { overwrite: false });
|
|
447
|
+
ok(`${tmplCount} templates installed`);
|
|
448
|
+
}
|
|
329
449
|
|
|
330
450
|
// 9. Save version
|
|
331
|
-
fs.writeFileSync(
|
|
451
|
+
fs.writeFileSync(plat.versionFile, AWK_VERSION);
|
|
332
452
|
ok(`Version ${AWK_VERSION} saved`);
|
|
333
453
|
|
|
334
454
|
// 10. Install default skill packs
|
|
@@ -337,21 +457,34 @@ function cmdInstall() {
|
|
|
337
457
|
// 11. Summary
|
|
338
458
|
log('');
|
|
339
459
|
log(`${C.gray}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}`);
|
|
340
|
-
log(`${C.yellow}${C.bold}🎉 AWK v${AWK_VERSION} installed
|
|
460
|
+
log(`${C.yellow}${C.bold}🎉 AWK v${AWK_VERSION} installed for ${plat.name}!${C.reset}`);
|
|
341
461
|
log('');
|
|
342
|
-
dim(`
|
|
343
|
-
dim(`
|
|
344
|
-
dim(`
|
|
345
|
-
dim(`
|
|
346
|
-
dim(`
|
|
462
|
+
dim(`Platform: ${plat.name}`);
|
|
463
|
+
if (plat.dirs.workflows) dim(`Workflows: ${path.join(target, plat.dirs.workflows)}`);
|
|
464
|
+
if (plat.dirs.skills) dim(`Skills: ${path.join(target, plat.dirs.skills)}`);
|
|
465
|
+
if (plat.dirs.schemas) dim(`Schemas: ${path.join(target, plat.dirs.schemas)}`);
|
|
466
|
+
if (plat.dirs.templates) dim(`Templates: ${path.join(target, plat.dirs.templates)}`);
|
|
467
|
+
if (plat.dirs.agents) dim(`Agents: ${path.join(target, plat.dirs.agents)}`);
|
|
468
|
+
|
|
469
|
+
if (plat.rulesFile) {
|
|
470
|
+
dim(`Global Rules: ${plat.rulesFile}`);
|
|
471
|
+
}
|
|
347
472
|
if (defaultPacks.length > 0) {
|
|
348
473
|
dim(`Packs: ${defaultPacks.join(', ')} (auto-enabled)`);
|
|
349
474
|
}
|
|
350
|
-
|
|
351
|
-
|
|
475
|
+
if (platform === 'antigravity') {
|
|
476
|
+
dim(`Symphony: task tracking ready`);
|
|
477
|
+
}
|
|
352
478
|
log('');
|
|
353
|
-
|
|
354
|
-
|
|
479
|
+
|
|
480
|
+
if (platform === 'antigravity') {
|
|
481
|
+
log(`${C.cyan}👉 Type '/plan' in your AI chat to get started.${C.reset}`);
|
|
482
|
+
log(`${C.cyan}👉 Run 'awkit init' in any project to initialize it.${C.reset}`);
|
|
483
|
+
} else if (platform === 'cline') {
|
|
484
|
+
log(`${C.cyan}👉 Type '/plan' in Cline chat to get started.${C.reset}`);
|
|
485
|
+
} else if (platform === 'codex') {
|
|
486
|
+
log(`${C.cyan}👉 Type '$skill' in Codex to invoke skills.${C.reset}`);
|
|
487
|
+
}
|
|
355
488
|
log(`${C.cyan}👉 Run 'awkit doctor' to verify installation.${C.reset}`);
|
|
356
489
|
log('');
|
|
357
490
|
}
|
|
@@ -1962,7 +2095,17 @@ switch (command) {
|
|
|
1962
2095
|
cmdInit(args.includes('--force'));
|
|
1963
2096
|
break;
|
|
1964
2097
|
case 'install':
|
|
1965
|
-
|
|
2098
|
+
// Parse platform from either first arg or --platform flag
|
|
2099
|
+
{
|
|
2100
|
+
const pIdx = args.indexOf('--platform');
|
|
2101
|
+
let platformArg = null;
|
|
2102
|
+
if (pIdx !== -1 && args[pIdx + 1]) {
|
|
2103
|
+
platformArg = args[pIdx + 1];
|
|
2104
|
+
} else if (args[0] && !args[0].startsWith('-')) {
|
|
2105
|
+
platformArg = args[0];
|
|
2106
|
+
}
|
|
2107
|
+
cmdInstall(platformArg);
|
|
2108
|
+
}
|
|
1966
2109
|
break;
|
|
1967
2110
|
case 'uninstall':
|
|
1968
2111
|
cmdUninstall();
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generates Cline global rules from GEMINI.md
|
|
6
|
+
* @param {string} sourcePath Path to core/GEMINI.md
|
|
7
|
+
* @param {string} destPath Destination path (e.g. ~/.cline/rules/antigravity.md)
|
|
8
|
+
*/
|
|
9
|
+
function generateClineRules(sourcePath, destPath) {
|
|
10
|
+
if (!fs.existsSync(sourcePath)) return;
|
|
11
|
+
|
|
12
|
+
let content = fs.readFileSync(sourcePath, 'utf8');
|
|
13
|
+
const preamble = `
|
|
14
|
+
# Antigravity Rules for Cline
|
|
15
|
+
|
|
16
|
+
${content}
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
20
|
+
fs.writeFileSync(destPath, preamble.trim() + '\n');
|
|
21
|
+
console.log(`✅ Cline global rules generated at: ${destPath}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Copies workflow markdown files to the given directory.
|
|
26
|
+
*/
|
|
27
|
+
function generateClineWorkflows(srcDir, destDir) {
|
|
28
|
+
if (!fs.existsSync(srcDir)) return;
|
|
29
|
+
|
|
30
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
31
|
+
const items = fs.readdirSync(srcDir);
|
|
32
|
+
|
|
33
|
+
let count = 0;
|
|
34
|
+
for (const item of items) {
|
|
35
|
+
if (!item.endsWith('.md')) continue;
|
|
36
|
+
const srcPath = path.join(srcDir, item);
|
|
37
|
+
const destPath = path.join(destDir, item);
|
|
38
|
+
fs.copyFileSync(srcPath, destPath);
|
|
39
|
+
count++;
|
|
40
|
+
}
|
|
41
|
+
console.log(`✅ Copied ${count} workflows to ${destDir}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Copies SKILL.md from each skill directory to the given directory.
|
|
46
|
+
*/
|
|
47
|
+
function generateClineSkills(srcDir, destDir) {
|
|
48
|
+
if (!fs.existsSync(srcDir)) return;
|
|
49
|
+
|
|
50
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
51
|
+
const skills = fs.readdirSync(srcDir);
|
|
52
|
+
|
|
53
|
+
let count = 0;
|
|
54
|
+
for (const skill of skills) {
|
|
55
|
+
const skillDir = path.join(srcDir, skill);
|
|
56
|
+
if (!fs.statSync(skillDir).isDirectory()) continue;
|
|
57
|
+
|
|
58
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
59
|
+
if (fs.existsSync(skillFile)) {
|
|
60
|
+
// Copy SKILL.md as <skillname>.md
|
|
61
|
+
const destPath = path.join(destDir, `${skill}.md`);
|
|
62
|
+
fs.copyFileSync(skillFile, destPath);
|
|
63
|
+
count++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
console.log(`✅ Copied ${count} skills to ${destDir}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = {
|
|
70
|
+
generateClineRules,
|
|
71
|
+
generateClineWorkflows,
|
|
72
|
+
generateClineSkills
|
|
73
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generates Codex global agents.md from GEMINI.md
|
|
6
|
+
* @param {string} sourcePath Path to core/GEMINI.md
|
|
7
|
+
* @param {string} destPath Destination path (e.g. ~/.codex/AGENTS.md)
|
|
8
|
+
*/
|
|
9
|
+
function generateCodexAgentsMd(sourcePath, destPath) {
|
|
10
|
+
if (!fs.existsSync(sourcePath)) return;
|
|
11
|
+
|
|
12
|
+
let content = fs.readFileSync(sourcePath, 'utf8');
|
|
13
|
+
|
|
14
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
15
|
+
fs.writeFileSync(destPath, content.trim() + '\n');
|
|
16
|
+
console.log(`✅ Codex AGENTS.md generated at: ${destPath}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Generates Codex skills directory structure.
|
|
21
|
+
* Copies SKILL.md and parses it.
|
|
22
|
+
*/
|
|
23
|
+
function generateCodexSkills(srcDir, destDir) {
|
|
24
|
+
if (!fs.existsSync(srcDir)) return;
|
|
25
|
+
|
|
26
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
27
|
+
const skills = fs.readdirSync(srcDir);
|
|
28
|
+
|
|
29
|
+
let count = 0;
|
|
30
|
+
for (const skill of skills) {
|
|
31
|
+
const skillDir = path.join(srcDir, skill);
|
|
32
|
+
if (!fs.statSync(skillDir).isDirectory()) continue;
|
|
33
|
+
|
|
34
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
35
|
+
if (fs.existsSync(skillFile)) {
|
|
36
|
+
const destSkillDir = path.join(destDir, skill);
|
|
37
|
+
fs.mkdirSync(destSkillDir, { recursive: true });
|
|
38
|
+
|
|
39
|
+
const destPath = path.join(destSkillDir, 'SKILL.md');
|
|
40
|
+
|
|
41
|
+
let content = fs.readFileSync(skillFile, 'utf8');
|
|
42
|
+
|
|
43
|
+
if (content.startsWith('---\n')) {
|
|
44
|
+
if (!content.match(/^name:/m)) {
|
|
45
|
+
content = content.replace('---\n', `---\nname: ${skill}\n`);
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
const preamble = `---\nname: ${skill}\ndescription: Antigravity skill ${skill}\n---\n`;
|
|
49
|
+
content = preamble + content;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fs.writeFileSync(destPath, content);
|
|
53
|
+
count++;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
console.log(`✅ Generated ${count} Codex skills in ${destDir}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Generates Codex custom agents (.toml) for specific skills.
|
|
61
|
+
*/
|
|
62
|
+
function generateCodexAgents(srcDir, destDir) {
|
|
63
|
+
if (!fs.existsSync(srcDir)) return;
|
|
64
|
+
|
|
65
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
66
|
+
const skills = fs.readdirSync(srcDir);
|
|
67
|
+
|
|
68
|
+
const SPECIALIST_SKILLS = [
|
|
69
|
+
'ios-engineer',
|
|
70
|
+
'smali-to-kotlin',
|
|
71
|
+
'smali-to-swift',
|
|
72
|
+
'problem-solving-pro',
|
|
73
|
+
'swiftui-pro',
|
|
74
|
+
'android-re-analyzer',
|
|
75
|
+
'brainstorm-agent'
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
let count = 0;
|
|
79
|
+
for (const skill of skills) {
|
|
80
|
+
if (!SPECIALIST_SKILLS.includes(skill)) continue;
|
|
81
|
+
|
|
82
|
+
const skillDir = path.join(srcDir, skill);
|
|
83
|
+
if (!fs.statSync(skillDir).isDirectory()) continue;
|
|
84
|
+
|
|
85
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
86
|
+
if (fs.existsSync(skillFile)) {
|
|
87
|
+
const content = fs.readFileSync(skillFile, 'utf8');
|
|
88
|
+
|
|
89
|
+
const tomlContent = `name = "${skill}"
|
|
90
|
+
description = "Antigravity specialist ${skill}"
|
|
91
|
+
developer_instructions = """
|
|
92
|
+
${content.replace(/"""/g, '\\"\\"\\"')}
|
|
93
|
+
"""
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
const destPath = path.join(destDir, `${skill}.toml`);
|
|
97
|
+
fs.writeFileSync(destPath, tomlContent);
|
|
98
|
+
count++;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
console.log(`✅ Generated ${count} Codex custom agents in ${destDir}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
module.exports = {
|
|
105
|
+
generateCodexAgentsMd,
|
|
106
|
+
generateCodexSkills,
|
|
107
|
+
generateCodexAgents
|
|
108
|
+
};
|
package/core/GEMINI.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# GEMINI.md — Antigravity
|
|
1
|
+
# GEMINI.md — Antigravity v11.0
|
|
2
2
|
|
|
3
|
-
> Rules + routing only. Gate details → skills. Updated: 2026-03-
|
|
3
|
+
> Rules + routing only. Gate details → skills. Updated: 2026-03-18
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
|
|
9
9
|
- Bạn là **Antigravity Orchestrator**.
|
|
10
10
|
- Pragmatic. Regression-averse. Symphony-first. Multi-project.
|
|
11
|
-
- Luôn khai báo mô hình trước mỗi câu trả lời
|
|
12
11
|
|
|
13
12
|
---
|
|
14
13
|
|
|
@@ -33,8 +32,9 @@ Mỗi skill tự xử lý gate logic riêng — xem SKILL.md của từng skill.
|
|
|
33
32
|
|
|
34
33
|
### Exit Protocol
|
|
35
34
|
|
|
36
|
-
- Task done →
|
|
37
|
-
-
|
|
35
|
+
- Task done → auto-complete Symphony → **BẮT BUỘC** `symphony next` + present gợi ý.
|
|
36
|
+
- Kết thúc message → **LUÔN** kèm "Next steps" section.
|
|
37
|
+
- `nm-memory-sync` auto-save (W1–W4 triggers).
|
|
38
38
|
- Deploy/push → kiểm tra in-progress tasks trước, confirm với user.
|
|
39
39
|
|
|
40
40
|
---
|
|
@@ -50,6 +50,11 @@ Mỗi skill tự xử lý gate logic riêng — xem SKILL.md của từng skill.
|
|
|
50
50
|
- AI models: Gemini 2.5+ only.
|
|
51
51
|
- Firebase: Firebase AI Logic SDK.
|
|
52
52
|
|
|
53
|
+
### Spec-First (NEW v11.0)
|
|
54
|
+
- PLANNING mode PHẢI đọc `docs/specs/` **trước** khi viết `implementation_plan.md`.
|
|
55
|
+
- Mỗi task trong plan NÊN có format XML `<task>` (xem `templates/specs/task-spec-template.xml`).
|
|
56
|
+
- `implementation_plan.md` PHẢI reference `TECH-SPEC.md` constraints khi relevant.
|
|
57
|
+
|
|
53
58
|
### NeuralMemory
|
|
54
59
|
- Brain = projectId. Switch trước mọi nmem call.
|
|
55
60
|
- Mọi `nmem_remember()` PHẢI tag projectId.
|
|
@@ -62,16 +67,8 @@ Mỗi skill tự xử lý gate logic riêng — xem SKILL.md của từng skill.
|
|
|
62
67
|
- Kết thúc task: Tóm tắt + Test + Next steps.
|
|
63
68
|
- Không rõ: Hỏi lại, tối đa 2 lần.
|
|
64
69
|
|
|
65
|
-
### Project Context
|
|
66
|
-
|
|
67
|
-
> [!CAUTION]
|
|
68
|
-
> TRƯỚC KHI dùng `grep_search` / `codebase_search` / `list_dir` → **PHẢI đọc CODEBASE.md** của project đó.
|
|
69
|
-
> Bỏ qua = vi phạm. KHÔNG CÓ NGOẠI LỆ.
|
|
70
|
-
|
|
71
|
-
- **Quy trình bắt buộc:** Đọc CODEBASE.md → xác định file/layer target → search cụ thể.
|
|
72
|
-
- **KHÔNG search "mù"** (search mà chưa biết project structure).
|
|
73
|
-
- CODEBASE.md là **bản đồ project** — dạng compact (path + purpose). Đọc nhanh, tốn ít context.
|
|
74
|
-
- KHÔNG scan raw directory (`list_dir`, `find_by_name`) nếu đã có CODEBASE.md.
|
|
70
|
+
### Project Context
|
|
71
|
+
- CODEBASE.md tồn tại → KHÔNG scan raw directory.
|
|
75
72
|
- KHÔNG hỏi user về project structure.
|
|
76
73
|
- CODEBASE.md outdated → ghi chú "⚠️ dùng /codebase-sync".
|
|
77
74
|
|
|
@@ -88,9 +85,9 @@ Mỗi skill tự xử lý gate logic riêng — xem SKILL.md của từng skill.
|
|
|
88
85
|
|
|
89
86
|
## Routing
|
|
90
87
|
|
|
91
|
-
- **Execution order:** `symphony-orchestrator` → `awf-session-restore` → `nm-memory-sync` → `orchestrator` → action
|
|
88
|
+
- **Execution order:** `symphony-orchestrator` → `awf-session-restore` → `nm-memory-sync` → `symphony-enforcer` → `orchestrator` → action
|
|
92
89
|
- **Skill catalog:** xem `orchestrator/SKILL.md`
|
|
93
|
-
- **Workflows:** 75+ (`/xxx`). Core: `/
|
|
90
|
+
- **Workflows:** 75+ (`/xxx`). Core: `/init` `/code` `/debug` `/recap` `/next` `/todo`
|
|
94
91
|
- **Shortcuts:** `/todo` `/done` `/next`
|
|
95
92
|
|
|
96
93
|
---
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leejungkiin/awkit",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.3",
|
|
4
|
+
"description": "Antigravity Workflow Kit. Unified AI agent orchestration system.",
|
|
5
5
|
"main": "bin/awk.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"awkit": "bin/awk.js",
|