@leejungkiin/awkit 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -7
- package/bin/awk.js +215 -72
- package/bin/cline-generators.js +73 -0
- package/bin/codex-generators.js +108 -0
- 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/core/AGENTS.md +0 -38
- package/skills/beads-manager/SKILL.md +0 -459
- package/workflows/_uncategorized/AGENTS.md +0 -38
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# AWKit — Antigravity Workflow Kit v1
|
|
1
|
+
# AWKit — Antigravity Workflow Kit v1
|
|
2
2
|
|
|
3
|
-
> **v1.
|
|
3
|
+
> **v1.1.4** · Single Source of Truth · Symphony-First · Ambient Memory
|
|
4
4
|
|
|
5
5
|
AWKit là framework điều phối AI agent chuyên nghiệp. Đây là **nơi duy nhất** chứa toàn bộ workflows, skills, GEMINI.md và cấu hình — không còn phân tán giữa nhiều repo.
|
|
6
6
|
|
|
@@ -22,6 +22,7 @@ awkit doctor
|
|
|
22
22
|
|---------|-------------|
|
|
23
23
|
| `awkit install` | Deploy AWKit vào `~/.gemini/antigravity/` |
|
|
24
24
|
| `awkit update` | Update lên version mới nhất |
|
|
25
|
+
| `awkit init` | Khởi tạo project mới (tạo .project-identity, CODEBASE.md, etc.) |
|
|
25
26
|
| `awkit sync` | Full sync: harvest + install (one shot) |
|
|
26
27
|
| `awkit status` | So sánh repo vs installed (diff view) |
|
|
27
28
|
| `awkit harvest` | Pull từ `~/.gemini/antigravity/` về repo |
|
|
@@ -29,6 +30,8 @@ awkit doctor
|
|
|
29
30
|
| `awkit enable-pack <name>` | Kích hoạt skill pack |
|
|
30
31
|
| `awkit disable-pack <name>` | Vô hiệu skill pack |
|
|
31
32
|
| `awkit list-packs` | Xem danh sách skill packs |
|
|
33
|
+
| `awkit tg setup` | Cài đặt Telegram Bot Token, Chat ID & Topic |
|
|
34
|
+
| `awkit tg send <msg>` | Gửi tin nhắn qua Telegram |
|
|
32
35
|
| `awkit version` | Show version |
|
|
33
36
|
|
|
34
37
|
### Typical Workflow
|
|
@@ -47,13 +50,13 @@ awkit install
|
|
|
47
50
|
awkit sync
|
|
48
51
|
|
|
49
52
|
# 3. Commit the snapshot
|
|
50
|
-
git add -A && git commit -m "chore: sync AWKit
|
|
53
|
+
git add -A && git commit -m "chore: sync AWKit v1.1.3"
|
|
51
54
|
```
|
|
52
55
|
|
|
53
56
|
|
|
54
57
|
|
|
55
58
|
```
|
|
56
|
-
main-awf/ (AWKit
|
|
59
|
+
main-awf/ (AWKit v1.1.x — Source of Truth)
|
|
57
60
|
├── bin/
|
|
58
61
|
│ ├── awk.js ← CLI entry point
|
|
59
62
|
│ └── awf.js ← (legacy, kept for reference)
|
|
@@ -86,7 +89,7 @@ main-awf/ (AWKit v7.0 — Source of Truth)
|
|
|
86
89
|
├── templates/ ← Project templates
|
|
87
90
|
├── scripts/
|
|
88
91
|
│ └── harvest.js ← Migration: pull from ~/.gemini/
|
|
89
|
-
├── VERSION → 1.
|
|
92
|
+
├── VERSION → 1.1.3
|
|
90
93
|
└── package.json (@leejungkiin/awkit)
|
|
91
94
|
```
|
|
92
95
|
|
|
@@ -114,6 +117,21 @@ main-awf/ (edit here)
|
|
|
114
117
|
Gemini / Claude / Any AI
|
|
115
118
|
```
|
|
116
119
|
|
|
120
|
+
## 📨 Telegram Integration
|
|
121
|
+
|
|
122
|
+
Bạn có thể cấu hình AWKit gửi thông báo tự động (deploy xong, test pass...) qua Telegram:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# 1. Setup Bot Token, Chat ID và Message Thread ID (Topic)
|
|
126
|
+
awkit tg setup
|
|
127
|
+
|
|
128
|
+
# 2. Gửi thử tin nhắn kiểm tra
|
|
129
|
+
awkit tg send "Hello from AWKit!"
|
|
130
|
+
|
|
131
|
+
# 3. Gửi đến chat/topic cụ thể
|
|
132
|
+
awkit tg send "Hello" --chat -100123456789 --topic 1234
|
|
133
|
+
```
|
|
134
|
+
|
|
117
135
|
## 📦 Skill Packs
|
|
118
136
|
|
|
119
137
|
```bash
|
|
@@ -129,8 +147,8 @@ awkit enable-pack ios-dev
|
|
|
129
147
|
| 4.x | AWF v4 | Shell-based, `awf-` prefix skills |
|
|
130
148
|
| 5.x | Antigravity v5 | Node.js, Symphony integration |
|
|
131
149
|
| 6.x | AWF v6 | main-awf, multiple sources |
|
|
132
|
-
| **1.
|
|
150
|
+
| **1.1.x** | **AWKit v1.1** | **Single source of truth, Native CLI, Telegram Integration** |
|
|
133
151
|
|
|
134
152
|
---
|
|
135
153
|
|
|
136
|
-
*AWKit v1.
|
|
154
|
+
*AWKit v1.1.x — Antigravity Workflow Kit · Created by Kien AI*
|
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leejungkiin/awkit",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.4",
|
|
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",
|