@leejungkiin/awkit 1.7.6 → 1.7.8
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 +213 -92
- package/bin/codex-generators.js +32 -3
- package/core/GEMINI.md +18 -5
- package/core/GEMINI.md.bak +20 -7
- package/core/skill-runtime-manifest.json +1 -0
- package/package.json +1 -1
- package/scripts/exec-progress.js +116 -0
- package/scripts/exec-rtk.js +105 -10
- package/skills/CATALOG.md +1 -1
- package/skills/awf-caveman/SKILL.md +13 -1
- package/skills/code-review/SKILL.md +40 -68
- package/skills/generate-gui-assets/SKILL.md +5 -5
- package/skills/hatch-pet/SKILL.md +2 -2
- package/skills/review/SKILL.md +40 -68
- package/skills/threejs-animation/SKILL.md +86 -0
- package/skills/threejs-animation/examples/workflow-mixer-action.md +20 -0
- package/skills/threejs-animation/references/official-sections.md +19 -0
- package/skills/threejs-audio/SKILL.md +112 -0
- package/skills/threejs-audio/examples/workflow-positional-audio.md +15 -0
- package/skills/threejs-audio/references/official-sections.md +16 -0
- package/skills/threejs-camera/SKILL.md +96 -0
- package/skills/threejs-camera/examples/workflow-perspective-resize.md +13 -0
- package/skills/threejs-controls/SKILL.md +101 -0
- package/skills/threejs-controls/examples/workflow-orbit-damping.md +15 -0
- package/skills/threejs-dev-setup/SKILL.md +102 -0
- package/skills/threejs-dev-setup/examples/workflow-scaffold.md +24 -0
- package/skills/threejs-geometries/SKILL.md +108 -0
- package/skills/threejs-geometries/examples/workflow-extrude-shape.md +13 -0
- package/skills/threejs-helpers/SKILL.md +103 -0
- package/skills/threejs-helpers/examples/workflow-light-camera-helpers.md +13 -0
- package/skills/threejs-lights/SKILL.md +103 -0
- package/skills/threejs-lights/examples/workflow-directional-shadow.md +17 -0
- package/skills/threejs-loaders/SKILL.md +89 -0
- package/skills/threejs-loaders/examples/workflow-gltf-draco.md +22 -0
- package/skills/threejs-loaders/references/official-sections.md +27 -0
- package/skills/threejs-materials/SKILL.md +102 -0
- package/skills/threejs-materials/examples/workflow-pbr-transparent.md +15 -0
- package/skills/threejs-math/SKILL.md +102 -0
- package/skills/threejs-math/examples/workflow-ray-aabb.md +11 -0
- package/skills/threejs-node-tsl/SKILL.md +83 -0
- package/skills/threejs-node-tsl/examples/workflow-tsl-entry.md +13 -0
- package/skills/threejs-node-tsl/references/official-links.md +8 -0
- package/skills/threejs-node-tsl/references/tsl-vs-classic.md +23 -0
- package/skills/threejs-objects/SKILL.md +111 -0
- package/skills/threejs-objects/examples/workflow-raycaster-pick.md +17 -0
- package/skills/threejs-postprocessing/SKILL.md +116 -0
- package/skills/threejs-postprocessing/examples/workflow-composer-bloom.md +15 -0
- package/skills/threejs-renderers/SKILL.md +91 -0
- package/skills/threejs-renderers/examples/workflow-renderer-resize.md +21 -0
- package/skills/threejs-renderers/references/official-sections.md +14 -0
- package/skills/threejs-scenes/SKILL.md +90 -0
- package/skills/threejs-scenes/examples/workflow-fog-background.md +13 -0
- package/skills/threejs-textures/SKILL.md +83 -0
- package/skills/threejs-textures/examples/workflow-pmrem-env.md +19 -0
- package/skills/threejs-webxr/SKILL.md +104 -0
- package/skills/threejs-webxr/examples/workflow-xr-button.md +15 -0
- package/workflows/_uncategorized/generate-gui-assets.md +111 -0
- package/workflows/_uncategorized/goal.md +86 -0
- package/workflows/_uncategorized/hatch-pet.md +116 -0
- package/workflows/_uncategorized/office-hours.md +38 -0
- package/workflows/_uncategorized/plan-ceo-review.md +34 -0
- package/workflows/_uncategorized/plan-design-review.md +38 -0
- package/workflows/_uncategorized/plan-eng-review.md +43 -0
- package/workflows/quality/plan-ceo-review.md +34 -0
- package/workflows/quality/plan-design-review.md +38 -0
- package/workflows/quality/plan-eng-review.md +43 -0
- package/workflows/roles/office-hours.md +38 -0
- package/workflows/ui/generate-gui-assets.md +111 -0
- package/workflows/ui/hatch-pet.md +116 -0
package/bin/awk.js
CHANGED
|
@@ -48,6 +48,7 @@ const { cmdI18n } = require('../scripts/i18n-helper');
|
|
|
48
48
|
const { cmdStorage } = require('../scripts/artifact-storage');
|
|
49
49
|
const { cmdPipeline } = require('../scripts/multi-model-pipeline');
|
|
50
50
|
const depManager = require('../scripts/dependency-manager');
|
|
51
|
+
const rtkRuntime = require('../scripts/exec-rtk');
|
|
51
52
|
|
|
52
53
|
|
|
53
54
|
// ─── Platform Definitions ──────────────────────────────────────────────────
|
|
@@ -67,16 +68,18 @@ const PLATFORMS = {
|
|
|
67
68
|
},
|
|
68
69
|
supportsCustomModes: false,
|
|
69
70
|
supportsSubagents: false,
|
|
71
|
+
isGlobal: true,
|
|
70
72
|
},
|
|
71
73
|
cline: {
|
|
72
74
|
name: 'Cline (VS Code)',
|
|
73
|
-
globalRoot:
|
|
75
|
+
globalRoot: path.join(HOME, '.cline'),
|
|
74
76
|
rulesFile: path.join(HOME, '.cline', 'rules', 'antigravity-rules.md'),
|
|
75
77
|
versionFile: path.join(HOME, '.cline', 'awk_version'),
|
|
76
78
|
dirs: {
|
|
77
|
-
workflows: '
|
|
78
|
-
skills: '
|
|
79
|
+
workflows: 'rules',
|
|
80
|
+
skills: 'rules',
|
|
79
81
|
},
|
|
82
|
+
isGlobal: true,
|
|
80
83
|
},
|
|
81
84
|
codex: {
|
|
82
85
|
name: 'Codex (OpenAI)',
|
|
@@ -87,15 +90,17 @@ const PLATFORMS = {
|
|
|
87
90
|
agents: 'agents',
|
|
88
91
|
skills: '../.agents/skills',
|
|
89
92
|
},
|
|
93
|
+
isGlobal: true,
|
|
90
94
|
},
|
|
91
95
|
claude: {
|
|
92
96
|
name: 'Claude Code',
|
|
93
|
-
globalRoot:
|
|
97
|
+
globalRoot: path.join(HOME, '.claude'),
|
|
94
98
|
rulesFile: 'CLAUDE.md',
|
|
95
|
-
versionFile: '
|
|
99
|
+
versionFile: 'awk_version',
|
|
96
100
|
dirs: {
|
|
97
|
-
skills: '
|
|
101
|
+
skills: 'skills',
|
|
98
102
|
},
|
|
103
|
+
isGlobal: true,
|
|
99
104
|
},
|
|
100
105
|
qwen: {
|
|
101
106
|
name: 'Qwen Code',
|
|
@@ -105,15 +110,17 @@ const PLATFORMS = {
|
|
|
105
110
|
dirs: {
|
|
106
111
|
skills: 'skills',
|
|
107
112
|
},
|
|
113
|
+
isGlobal: true,
|
|
108
114
|
},
|
|
109
115
|
cursor: {
|
|
110
116
|
name: 'Cursor AI',
|
|
111
|
-
globalRoot:
|
|
112
|
-
rulesFile: '.cursor
|
|
113
|
-
versionFile: '.cursor
|
|
117
|
+
globalRoot: path.join(HOME, '.cursor'),
|
|
118
|
+
rulesFile: path.join(HOME, '.cursor', 'rules', 'antigravity-rules.mdc'),
|
|
119
|
+
versionFile: path.join(HOME, '.cursor', 'awk_version'),
|
|
114
120
|
dirs: {
|
|
115
|
-
skills: '
|
|
121
|
+
skills: 'rules',
|
|
116
122
|
},
|
|
123
|
+
isGlobal: true,
|
|
117
124
|
}
|
|
118
125
|
};
|
|
119
126
|
|
|
@@ -482,32 +489,31 @@ function flattenWorkflows(srcBase, destDir) {
|
|
|
482
489
|
}
|
|
483
490
|
|
|
484
491
|
/**
|
|
485
|
-
* Install or update GEMINI.md into
|
|
492
|
+
* Install or update GEMINI.md into Antigravity rule locations.
|
|
486
493
|
*/
|
|
487
494
|
function syncGeminiMd() {
|
|
488
495
|
const srcGemini = path.join(AWK_ROOT, 'core', 'GEMINI.md');
|
|
489
|
-
const
|
|
496
|
+
const primaryDest = TARGETS.geminiMd;
|
|
497
|
+
const legacyDest = path.join(PLATFORMS.antigravity.globalRoot, 'GEMINI.md');
|
|
498
|
+
const destinations = [...new Set([primaryDest, legacyDest])];
|
|
490
499
|
|
|
491
|
-
const
|
|
492
|
-
|
|
500
|
+
for (const destGemini of destinations) {
|
|
501
|
+
const destDir = path.dirname(destGemini);
|
|
502
|
+
if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
|
493
503
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
existingContent = fs.readFileSync(destGemini, 'utf8');
|
|
504
|
+
if (fs.existsSync(destGemini)) {
|
|
505
|
+
const backupDir = path.join(PLATFORMS.antigravity.globalRoot, 'backup');
|
|
506
|
+
if (!fs.existsSync(backupDir)) fs.mkdirSync(backupDir, { recursive: true });
|
|
498
507
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
508
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
509
|
+
const label = destGemini === legacyDest ? 'GEMINI_legacy' : 'GEMINI';
|
|
510
|
+
const backupPath = path.join(backupDir, `${label}_${timestamp}.md.bak`);
|
|
511
|
+
fs.copyFileSync(destGemini, backupPath);
|
|
512
|
+
dim(`Backup: ${backupPath}`);
|
|
513
|
+
}
|
|
502
514
|
|
|
503
|
-
|
|
504
|
-
const backupPath = path.join(backupDir, `GEMINI_${timestamp}.md.bak`);
|
|
505
|
-
fs.copyFileSync(destGemini, backupPath);
|
|
506
|
-
dim(`Backup: ${backupPath}`);
|
|
515
|
+
fs.copyFileSync(srcGemini, destGemini);
|
|
507
516
|
}
|
|
508
|
-
|
|
509
|
-
// Copy new GEMINI.md
|
|
510
|
-
fs.copyFileSync(srcGemini, destGemini);
|
|
511
517
|
ok('GEMINI.md updated');
|
|
512
518
|
}
|
|
513
519
|
|
|
@@ -538,8 +544,19 @@ function cmdInstall(args = []) {
|
|
|
538
544
|
const isUpdate = args.includes('--update');
|
|
539
545
|
let selectedPlatforms = [];
|
|
540
546
|
|
|
541
|
-
|
|
542
|
-
|
|
547
|
+
const hasAll = args.includes('--all') || args.includes('-a') || args.includes('all');
|
|
548
|
+
const hasLocal = args.includes('--local') || args.includes('-l') || args.includes('local');
|
|
549
|
+
|
|
550
|
+
if (hasAll) {
|
|
551
|
+
// Mặc định --all chỉ cài đặt các platform Global
|
|
552
|
+
selectedPlatforms = Object.keys(PLATFORMS).filter(p => PLATFORMS[p].isGlobal);
|
|
553
|
+
if (hasLocal) {
|
|
554
|
+
// Nếu có cả --local thì cài tất cả các platform
|
|
555
|
+
selectedPlatforms = Object.keys(PLATFORMS);
|
|
556
|
+
}
|
|
557
|
+
} else if (hasLocal) {
|
|
558
|
+
// Chỉ cài các platform Local
|
|
559
|
+
selectedPlatforms = Object.keys(PLATFORMS).filter(p => !PLATFORMS[p].isGlobal);
|
|
543
560
|
} else {
|
|
544
561
|
if (args.includes('--gemini') || args.includes('-g') || args.includes('antigravity')) selectedPlatforms.push('antigravity');
|
|
545
562
|
if (args.includes('--cline') || args.includes('cline')) selectedPlatforms.push('cline');
|
|
@@ -552,7 +569,7 @@ function cmdInstall(args = []) {
|
|
|
552
569
|
let legacyArg = null;
|
|
553
570
|
if (pIdx !== -1 && args[pIdx + 1]) {
|
|
554
571
|
legacyArg = args[pIdx + 1];
|
|
555
|
-
} else if (args.length > 0 && !args[0].startsWith('-') && args[0] !== 'all' && args[0] !== '--update') {
|
|
572
|
+
} else if (args.length > 0 && !args[0].startsWith('-') && args[0] !== 'all' && args[0] !== '--update' && args[0] !== 'local') {
|
|
556
573
|
legacyArg = args[0];
|
|
557
574
|
}
|
|
558
575
|
|
|
@@ -569,17 +586,17 @@ function cmdInstall(args = []) {
|
|
|
569
586
|
const defaultPlatform = getActivePlatform();
|
|
570
587
|
const defaultChoice = String(Math.max(platformOrder.indexOf(defaultPlatform), 0) + 1);
|
|
571
588
|
log(`${C.cyan}Select platforms to install (e.g., type "1,2", "all", or "1-6"):${C.reset}`);
|
|
572
|
-
log(` 1. Gemini Code Assist (antigravity)`);
|
|
573
|
-
log(` 2. Cline (VS Code)`);
|
|
574
|
-
log(` 3. Codex CLI (codex)`);
|
|
575
|
-
log(` 4. Claude Code (.claude/)`);
|
|
576
|
-
log(` 5. Qwen Code (~/.qwen/)`);
|
|
577
|
-
log(` 6. Cursor AI (.cursor/rules/)`);
|
|
578
|
-
log(` 7. All
|
|
589
|
+
log(` 1. Gemini Code Assist (antigravity) [Global]`);
|
|
590
|
+
log(` 2. Cline (VS Code) [Global]`);
|
|
591
|
+
log(` 3. Codex CLI (codex) [Global]`);
|
|
592
|
+
log(` 4. Claude Code (.claude/) [Global]`);
|
|
593
|
+
log(` 5. Qwen Code (~/.qwen/) [Global]`);
|
|
594
|
+
log(` 6. Cursor AI (.cursor/rules/) [Global]`);
|
|
595
|
+
log(` 7. All platforms (1-6)`);
|
|
579
596
|
log(`${C.gray}Press Enter to install only the active platform: ${PLATFORMS[defaultPlatform].name}.${C.reset}`);
|
|
580
597
|
const choice = promptChoice('Choice', defaultChoice).trim().toLowerCase();
|
|
581
598
|
|
|
582
|
-
if (choice === '7' || choice === 'all') {
|
|
599
|
+
if (choice === '7' || choice === 'all' || choice === '1-6') {
|
|
583
600
|
selectedPlatforms = Object.keys(PLATFORMS);
|
|
584
601
|
} else {
|
|
585
602
|
if (choice.includes('1')) selectedPlatforms.push('antigravity');
|
|
@@ -704,6 +721,8 @@ function cmdInstall(args = []) {
|
|
|
704
721
|
generateClineSkills(skillsSrc, skillsDest, coreSkills);
|
|
705
722
|
} else if (platform === 'codex') {
|
|
706
723
|
generateCodexSkills(skillsSrc, skillsDest, coreSkills);
|
|
724
|
+
const codexSkillsDest = path.join(target, 'skills');
|
|
725
|
+
generateCodexSkills(skillsSrc, codexSkillsDest, coreSkills);
|
|
707
726
|
const agentsDest = path.join(target, plat.dirs.agents);
|
|
708
727
|
generateCodexAgents(skillsSrc, agentsDest, coreSkills);
|
|
709
728
|
} else if (platform === 'claude') {
|
|
@@ -1011,16 +1030,12 @@ async function cmdDoctor() {
|
|
|
1011
1030
|
warn('schemas/ directory missing'); issues++;
|
|
1012
1031
|
}
|
|
1013
1032
|
|
|
1014
|
-
// 4.5. Check RTK & GitNexus Integration
|
|
1033
|
+
// 4.5. Check optional RTK & GitNexus Integration
|
|
1015
1034
|
if (depManager.checkRtk()) {
|
|
1016
|
-
|
|
1035
|
+
const rtkMode = rtkRuntime.getRtkMode();
|
|
1036
|
+
ok(`RTK (Rust Token Killer) is installed (v${depManager.getRtkVersion() || 'unknown'}, mode: ${rtkMode.mode})`);
|
|
1017
1037
|
} else {
|
|
1018
|
-
warn('RTK (Rust Token Killer) not found.');
|
|
1019
|
-
if (promptYN('Would you like to install RTK automatically now?')) {
|
|
1020
|
-
depManager.installRtk();
|
|
1021
|
-
} else {
|
|
1022
|
-
issues++;
|
|
1023
|
-
}
|
|
1038
|
+
warn('RTK (Rust Token Killer) not found. Optional: run `awkit rtk setup`.');
|
|
1024
1039
|
}
|
|
1025
1040
|
|
|
1026
1041
|
if (depManager.checkGitnexus()) {
|
|
@@ -1054,7 +1069,8 @@ async function cmdDoctor() {
|
|
|
1054
1069
|
ok('AWKit is up-to-date');
|
|
1055
1070
|
}
|
|
1056
1071
|
|
|
1057
|
-
const
|
|
1072
|
+
const currentRtkMode = rtkRuntime.getRtkMode();
|
|
1073
|
+
const currentRtk = currentRtkMode.mode === 'off' ? null : depManager.getRtkVersion();
|
|
1058
1074
|
if (updates.latestRtk && currentRtk && isNewerVersion(updates.latestRtk, currentRtk)) {
|
|
1059
1075
|
warn(`RTK update available: v${updates.latestRtk} (current: v${currentRtk})`);
|
|
1060
1076
|
} else if (currentRtk) {
|
|
@@ -1067,7 +1083,8 @@ async function cmdDoctor() {
|
|
|
1067
1083
|
log('');
|
|
1068
1084
|
log(`${C.bold}Runtime Profile:${C.reset}`);
|
|
1069
1085
|
log(` Profile: ${C.cyan}${installState.profile}${C.reset}`);
|
|
1070
|
-
|
|
1086
|
+
const visiblePacks = (installState.enabledPacks || []).filter(p => p !== 'reverse-engineering');
|
|
1087
|
+
log(` Optional packs: ${visiblePacks.length ? visiblePacks.join(', ') : C.gray + 'none' + C.reset}`);
|
|
1071
1088
|
|
|
1072
1089
|
// Summary
|
|
1073
1090
|
log('');
|
|
@@ -1929,7 +1946,8 @@ function cmdStatus() {
|
|
|
1929
1946
|
}
|
|
1930
1947
|
|
|
1931
1948
|
log(` ${C.gray}Profile:${C.reset} ${installState.profile}`);
|
|
1932
|
-
|
|
1949
|
+
const visiblePacksStatus = (installState.enabledPacks || []).filter(p => p !== 'reverse-engineering');
|
|
1950
|
+
log(` ${C.gray}Optional packs:${C.reset} ${visiblePacksStatus.length ? visiblePacksStatus.join(', ') : 'none'}`);
|
|
1933
1951
|
|
|
1934
1952
|
log('');
|
|
1935
1953
|
|
|
@@ -2318,7 +2336,7 @@ function cmdHelp() {
|
|
|
2318
2336
|
log(` ${C.green}update${C.reset} Pull latest + reinstall`);
|
|
2319
2337
|
log(` ${C.green}lint${C.reset} Run skill & workflow guards (check length, frontmatter)`);
|
|
2320
2338
|
log(` ${C.green}doctor${C.reset} Check installation health`);
|
|
2321
|
-
log(` ${C.green}rtk setup${C.reset}
|
|
2339
|
+
log(` ${C.green}rtk status|setup|off${C.reset} Manage RTK output compression`);
|
|
2322
2340
|
log(` ${C.green}credentials list${C.reset} List stored API keys`);
|
|
2323
2341
|
log(` ${C.green}credentials set${C.reset} <k> <v> Set API key (e.g., gemini_api_key, openrouter_api_key)`);
|
|
2324
2342
|
log(` ${C.green}set-openrouter${C.reset} <key> Shorthand for setting OpenRouter API Key`);
|
|
@@ -4112,7 +4130,8 @@ async function checkAutoUpdate() {
|
|
|
4112
4130
|
log('');
|
|
4113
4131
|
}
|
|
4114
4132
|
|
|
4115
|
-
const
|
|
4133
|
+
const currentRtkMode = rtkRuntime.getRtkMode();
|
|
4134
|
+
const currentRtk = currentRtkMode.mode === 'off' ? null : depManager.getRtkVersion();
|
|
4116
4135
|
if (updates.latestRtk && currentRtk && isNewerVersion(updates.latestRtk, currentRtk)) {
|
|
4117
4136
|
log('');
|
|
4118
4137
|
log(`${C.yellow}${C.bold}🌟 [Thông báo] Có phiên bản mới cho RTK! (v${updates.latestRtk})${C.reset}`);
|
|
@@ -4456,35 +4475,12 @@ function cmdGitnexus(args) {
|
|
|
4456
4475
|
|
|
4457
4476
|
// ─── RTK Integration ──────────────────────────────────────────────────────────
|
|
4458
4477
|
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
log(`${C.cyan}${C.bold}║ ⚙️ RTK Auto-Setup & Configuration ║${C.reset}`);
|
|
4462
|
-
log(`${C.cyan}${C.bold}╚═══════════════════════════════════════════════════════╝${C.reset}`);
|
|
4463
|
-
|
|
4464
|
-
const installed = depManager.installRtk();
|
|
4465
|
-
if (!installed) return;
|
|
4478
|
+
const RTK_SHELL_MARKER = '# RTK Integration for AI Agents (AWKit)';
|
|
4479
|
+
const RTK_SHELL_END_MARKER = '# End RTK Integration for AI Agents (AWKit)';
|
|
4466
4480
|
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
let zshrc = fs.readFileSync(zshrcPath, 'utf8');
|
|
4471
|
-
|
|
4472
|
-
// Clean up old aliases to avoid collision
|
|
4473
|
-
const oldAliases = [
|
|
4474
|
-
'alias git="rtk git"',
|
|
4475
|
-
'alias npm="rtk npm"',
|
|
4476
|
-
'alias pnpm="rtk pnpm"',
|
|
4477
|
-
'alias yarn="rtk yarn"',
|
|
4478
|
-
'alias cargo="rtk cargo"'
|
|
4479
|
-
];
|
|
4480
|
-
for (const oldAlias of oldAliases) {
|
|
4481
|
-
if (zshrc.includes(oldAlias)) {
|
|
4482
|
-
zshrc = zshrc.replace(new RegExp(`\\n?${oldAlias}\\n?`, 'g'), '\n');
|
|
4483
|
-
}
|
|
4484
|
-
}
|
|
4485
|
-
|
|
4486
|
-
const functionBlock = `
|
|
4487
|
-
# RTK Integration for AI Agents (AWKit)
|
|
4481
|
+
function getRtkShellBlock() {
|
|
4482
|
+
return `
|
|
4483
|
+
${RTK_SHELL_MARKER}
|
|
4488
4484
|
unalias npm pnpm yarn cargo git 2>/dev/null
|
|
4489
4485
|
npm() {
|
|
4490
4486
|
if [[ "$1" == "login" || "$1" == "adduser" || "$1" == "publish" ]]; then
|
|
@@ -4521,19 +4517,130 @@ git() {
|
|
|
4521
4517
|
rtk git "$@"
|
|
4522
4518
|
fi
|
|
4523
4519
|
}
|
|
4520
|
+
${RTK_SHELL_END_MARKER}
|
|
4524
4521
|
`;
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4522
|
+
}
|
|
4523
|
+
|
|
4524
|
+
function escapeRegExp(value) {
|
|
4525
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
4526
|
+
}
|
|
4527
|
+
|
|
4528
|
+
function stripRtkShellBlock(content) {
|
|
4529
|
+
const oldAliases = [
|
|
4530
|
+
'alias git="rtk git"',
|
|
4531
|
+
'alias npm="rtk npm"',
|
|
4532
|
+
'alias pnpm="rtk pnpm"',
|
|
4533
|
+
'alias yarn="rtk yarn"',
|
|
4534
|
+
'alias cargo="rtk cargo"'
|
|
4535
|
+
];
|
|
4536
|
+
let updated = content;
|
|
4537
|
+
for (const oldAlias of oldAliases) {
|
|
4538
|
+
updated = updated.replace(new RegExp(`^\\s*${escapeRegExp(oldAlias)}\\s*\\n?`, 'gm'), '');
|
|
4539
|
+
}
|
|
4540
|
+
|
|
4541
|
+
const lines = updated.split('\n');
|
|
4542
|
+
const start = lines.findIndex(line => line.trim() === RTK_SHELL_MARKER);
|
|
4543
|
+
if (start === -1) return { content: updated, removed: updated !== content };
|
|
4544
|
+
|
|
4545
|
+
let end = lines.findIndex((line, index) => index >= start && line.trim() === RTK_SHELL_END_MARKER);
|
|
4546
|
+
if (end === -1) {
|
|
4547
|
+
const gitStart = lines.findIndex((line, index) => index >= start && line.trim() === 'git() {');
|
|
4548
|
+
if (gitStart !== -1) {
|
|
4549
|
+
end = lines.findIndex((line, index) => index > gitStart && line.trim() === '}');
|
|
4529
4550
|
}
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4551
|
+
}
|
|
4552
|
+
if (end === -1) return { content: updated, removed: updated !== content };
|
|
4553
|
+
|
|
4554
|
+
lines.splice(start, end - start + 1);
|
|
4555
|
+
return { content: lines.join('\n').replace(/\n{3,}/g, '\n\n'), removed: true };
|
|
4556
|
+
}
|
|
4557
|
+
|
|
4558
|
+
function hasRtkShellBlock() {
|
|
4559
|
+
const zshrcPath = path.join(HOME, '.zshrc');
|
|
4560
|
+
return fs.existsSync(zshrcPath) && fs.readFileSync(zshrcPath, 'utf8').includes(RTK_SHELL_MARKER);
|
|
4561
|
+
}
|
|
4562
|
+
|
|
4563
|
+
function removeRtkShellBlock({ quiet = false } = {}) {
|
|
4564
|
+
const zshrcPath = path.join(HOME, '.zshrc');
|
|
4565
|
+
if (!fs.existsSync(zshrcPath)) {
|
|
4566
|
+
if (!quiet) warn('~/.zshrc not found. Shell wrappers already absent.');
|
|
4567
|
+
return false;
|
|
4568
|
+
}
|
|
4569
|
+
|
|
4570
|
+
const zshrc = fs.readFileSync(zshrcPath, 'utf8');
|
|
4571
|
+
const stripped = stripRtkShellBlock(zshrc);
|
|
4572
|
+
if (!stripped.removed) {
|
|
4573
|
+
if (!quiet) ok('No AWKit RTK shell wrappers found.');
|
|
4574
|
+
return false;
|
|
4575
|
+
}
|
|
4576
|
+
|
|
4577
|
+
fs.writeFileSync(zshrcPath, stripped.content, 'utf8');
|
|
4578
|
+
if (!quiet) ok('AWKit RTK shell wrappers removed from ~/.zshrc.');
|
|
4579
|
+
return true;
|
|
4580
|
+
}
|
|
4581
|
+
|
|
4582
|
+
function installRtkShellBlock() {
|
|
4583
|
+
if (!depManager.checkRtk()) {
|
|
4584
|
+
err('RTK binary not found. Run `awkit rtk setup` first.');
|
|
4585
|
+
return;
|
|
4586
|
+
}
|
|
4587
|
+
|
|
4588
|
+
const zshrcPath = path.join(HOME, '.zshrc');
|
|
4589
|
+
const zshrc = fs.existsSync(zshrcPath) ? fs.readFileSync(zshrcPath, 'utf8') : '';
|
|
4590
|
+
const stripped = stripRtkShellBlock(zshrc).content.trimEnd();
|
|
4591
|
+
fs.writeFileSync(zshrcPath, `${stripped}\n${getRtkShellBlock()}`, 'utf8');
|
|
4592
|
+
ok('Shell wrappers added to ~/.zshrc.');
|
|
4593
|
+
warn('Reload shell with `source ~/.zshrc` to apply.');
|
|
4594
|
+
}
|
|
4595
|
+
|
|
4596
|
+
function cmdRtkStatus() {
|
|
4597
|
+
const mode = rtkRuntime.getRtkMode();
|
|
4598
|
+
const installed = depManager.checkRtk();
|
|
4599
|
+
const separator = `${C.gray}${'─'.repeat(56)}${C.reset}`;
|
|
4600
|
+
|
|
4601
|
+
log(`${C.cyan}${C.bold}RTK Status${C.reset}`);
|
|
4602
|
+
log(separator);
|
|
4603
|
+
log(` Binary: ${installed ? C.green + 'installed' + C.reset : C.yellow + 'not installed' + C.reset}`);
|
|
4604
|
+
if (installed) log(` Version: ${depManager.getRtkVersion() || 'unknown'}`);
|
|
4605
|
+
log(` Mode: ${C.bold}${mode.mode}${C.reset}`);
|
|
4606
|
+
log(` Mode source: ${mode.source}`);
|
|
4607
|
+
log(` Global config:${rtkRuntime.getRtkConfigPath()}`);
|
|
4608
|
+
log(` Shell wrap: ${hasRtkShellBlock() ? C.yellow + 'enabled in ~/.zshrc' + C.reset : C.green + 'off' + C.reset}`);
|
|
4609
|
+
log('');
|
|
4610
|
+
log(` Modes: off = raw AWKit, safe = low-risk compression, proxy = track raw, aggressive = old broad wrappers`);
|
|
4611
|
+
}
|
|
4612
|
+
|
|
4613
|
+
async function cmdRtkSetup() {
|
|
4614
|
+
log(`${C.cyan}${C.bold}╔═══════════════════════════════════════════════════════╗${C.reset}`);
|
|
4615
|
+
log(`${C.cyan}${C.bold}║ RTK Setup & Safe Configuration ║${C.reset}`);
|
|
4616
|
+
log(`${C.cyan}${C.bold}╚═══════════════════════════════════════════════════════╝${C.reset}`);
|
|
4617
|
+
|
|
4618
|
+
const installed = depManager.checkRtk() || depManager.installRtk();
|
|
4619
|
+
if (!installed) return;
|
|
4620
|
+
|
|
4621
|
+
rtkRuntime.setGlobalRtkMode('safe');
|
|
4622
|
+
ok('RTK mode set to safe.');
|
|
4623
|
+
warn('Shell wrappers are opt-in now. Run `awkit rtk shell-on` only if you want git/npm aliases.');
|
|
4624
|
+
cmdRtkStatus();
|
|
4625
|
+
}
|
|
4626
|
+
|
|
4627
|
+
function cmdRtkOff() {
|
|
4628
|
+
rtkRuntime.setGlobalRtkMode('off');
|
|
4629
|
+
removeRtkShellBlock({ quiet: true });
|
|
4630
|
+
ok('RTK disabled globally for AWKit.');
|
|
4631
|
+
warn('Reload shell with `source ~/.zshrc` if wrappers were active.');
|
|
4632
|
+
}
|
|
4633
|
+
|
|
4634
|
+
function cmdRtkMode(mode) {
|
|
4635
|
+
if (!mode) {
|
|
4636
|
+
err(`Usage: awkit rtk mode <${rtkRuntime.VALID_RTK_MODES.join('|')}>`);
|
|
4637
|
+
return;
|
|
4638
|
+
}
|
|
4639
|
+
try {
|
|
4640
|
+
rtkRuntime.setGlobalRtkMode(mode);
|
|
4641
|
+
ok(`RTK mode set to ${mode}.`);
|
|
4642
|
+
} catch (e) {
|
|
4643
|
+
err(e.message);
|
|
4537
4644
|
}
|
|
4538
4645
|
}
|
|
4539
4646
|
|
|
@@ -4541,9 +4648,23 @@ async function cmdRtk(args) {
|
|
|
4541
4648
|
const action = args[0];
|
|
4542
4649
|
if (action === 'setup') {
|
|
4543
4650
|
await cmdRtkSetup();
|
|
4651
|
+
} else if (!action || action === 'status') {
|
|
4652
|
+
cmdRtkStatus();
|
|
4653
|
+
} else if (action === 'off') {
|
|
4654
|
+
cmdRtkOff();
|
|
4655
|
+
} else if (action === 'on') {
|
|
4656
|
+
cmdRtkMode('safe');
|
|
4657
|
+
} else if (action === 'mode') {
|
|
4658
|
+
cmdRtkMode(args[1]);
|
|
4659
|
+
} else if (rtkRuntime.VALID_RTK_MODES.includes(action)) {
|
|
4660
|
+
cmdRtkMode(action);
|
|
4661
|
+
} else if (action === 'shell-on') {
|
|
4662
|
+
installRtkShellBlock();
|
|
4663
|
+
} else if (action === 'shell-off') {
|
|
4664
|
+
removeRtkShellBlock();
|
|
4544
4665
|
} else {
|
|
4545
4666
|
err(`Unknown rtk command: ${action || ''}`);
|
|
4546
|
-
log(` Available: setup`);
|
|
4667
|
+
log(` Available: status, setup, off, on, mode, shell-on, shell-off`);
|
|
4547
4668
|
}
|
|
4548
4669
|
}
|
|
4549
4670
|
|
package/bin/codex-generators.js
CHANGED
|
@@ -16,9 +16,36 @@ function generateCodexAgentsMd(sourcePath, destPath) {
|
|
|
16
16
|
console.log(`✅ Codex AGENTS.md generated at: ${destPath}`);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Recursively copies a skill directory preserving structure.
|
|
21
|
+
*/
|
|
22
|
+
function copySkillDir(src, dest) {
|
|
23
|
+
if (!fs.existsSync(src)) return 0;
|
|
24
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
25
|
+
|
|
26
|
+
let count = 0;
|
|
27
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
28
|
+
|
|
29
|
+
for (const entry of entries) {
|
|
30
|
+
if (entry.name === '.DS_Store') continue;
|
|
31
|
+
if (entry.name === '__pycache__') continue;
|
|
32
|
+
|
|
33
|
+
const srcPath = path.join(src, entry.name);
|
|
34
|
+
const destPath = path.join(dest, entry.name);
|
|
35
|
+
|
|
36
|
+
if (entry.isDirectory()) {
|
|
37
|
+
count += copySkillDir(srcPath, destPath);
|
|
38
|
+
} else {
|
|
39
|
+
fs.copyFileSync(srcPath, destPath);
|
|
40
|
+
count++;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return count;
|
|
44
|
+
}
|
|
45
|
+
|
|
19
46
|
/**
|
|
20
47
|
* Generates Codex skills directory structure.
|
|
21
|
-
* Copies
|
|
48
|
+
* Copies the entire skill directory and parses/injects frontmatter to SKILL.md.
|
|
22
49
|
*/
|
|
23
50
|
function generateCodexSkills(srcDir, destDir, selectedSkills = null) {
|
|
24
51
|
if (!fs.existsSync(srcDir)) return;
|
|
@@ -37,11 +64,13 @@ function generateCodexSkills(srcDir, destDir, selectedSkills = null) {
|
|
|
37
64
|
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
38
65
|
if (fs.existsSync(skillFile)) {
|
|
39
66
|
const destSkillDir = path.join(destDir, skill);
|
|
40
|
-
|
|
67
|
+
|
|
68
|
+
// Copy the entire directory first
|
|
69
|
+
copySkillDir(skillDir, destSkillDir);
|
|
41
70
|
|
|
42
71
|
const destPath = path.join(destSkillDir, 'SKILL.md');
|
|
43
72
|
|
|
44
|
-
let content = fs.readFileSync(
|
|
73
|
+
let content = fs.readFileSync(destPath, 'utf8');
|
|
45
74
|
|
|
46
75
|
if (content.startsWith('---\n')) {
|
|
47
76
|
if (!content.match(/^name:/m)) {
|
package/core/GEMINI.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GEMINI.md — Antigravity v12.6
|
|
2
2
|
|
|
3
|
-
> Rules only. Updated: 2026-06-
|
|
3
|
+
> Rules only. Updated: 2026-06-23
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -62,11 +62,12 @@ symphony-orchestrator → awf-session-restore (gitnexus state) → nm-memory-syn
|
|
|
62
62
|
- Build: CHỈ dùng `awkit build`. CẤM gọi native (`xcodebuild`, `./gradlew`, `npm run build`).
|
|
63
63
|
- `automation.build.enabled: false` → DỪNG, báo user. KHÔNG fallback native.
|
|
64
64
|
- Thêm params qua `--`: `awkit build -- -destination '...'`. Bypass wrapper = VI PHẠM.
|
|
65
|
+
- **Chạy tác vụ nền (Background Tasks)**: Khi chạy các tác vụ nền hoặc tác vụ dài (>30 giây) như Codex CLI, PHẢI chạy qua wrapper `node scripts/exec-progress.js "<command>"` để hiển thị checklist tiến trình trực quan cho người dùng thay vì để trống màn hình.
|
|
65
66
|
|
|
66
67
|
### 7-Gate System
|
|
67
68
|
- Triage: TRIVIAL (→ Gate 4 thẳng) | MODERATE (→ G3+4+5) | COMPLEX (→ all gates).
|
|
68
69
|
- Gates: G1 brainstorm → G1.5 module-spec (COMPLEX+>3mod) → G2 spec-gate → G2.5 visual (skip nếu backend) → G3 symphony-enforcer → G4 execution → G5 verification.
|
|
69
|
-
- **Goal Mode Override:** Khi đang ở goal mode (`/goal`, active Codex goal, hoặc user nói rõ "goal mode") → gates là checklist nội bộ, KHÔNG dừng chờ user approval ở G2/G2.5/G4 checkpoints. AI tự chọn best-effort, tự verify, ghi
|
|
70
|
+
- **Goal Mode Override (NO-CONFIRM):** Khi đang ở goal mode (`/goal`, active Codex goal, hoặc user nói rõ "goal mode") → gates là checklist nội bộ, KHÔNG dừng chờ user approval ở bất kỳ bước nào (G2/G2.5/G4 checkpoints, prompt audit, style preview, grid configuration, specs approval, v.v.). AI tự động chọn phương án tối ưu (best-effort/recommended default), tự verify, ghi nhận giả định (assumptions) vào logs/walkthrough, rồi tiếp tục cho đến khi goal hoàn thành hoặc bị block thực sự bởi lỗi kỹ thuật/permission. Chỉ dừng lại hỏi ý kiến khi gặp lệnh thực sự nguy hại (destructive) hoặc nhạy cảm bảo mật quy định tại Safety Guardrails.
|
|
70
71
|
- **Gate 4 Three-Phase:**
|
|
71
72
|
- Phase A 🏗️ Infrastructure → B 🎨 UI Shell (mock) → C ⚡ Logic (real data).
|
|
72
73
|
- COMPLEX+UI: 3 phases bắt buộc. MODERATE+UI: A+C gộp, B optional. TRIVIAL: bypass.
|
|
@@ -102,8 +103,11 @@ symphony-orchestrator → awf-session-restore (gitnexus state) → nm-memory-syn
|
|
|
102
103
|
- Sau khi dùng tool sửa code → KHÔNG in lại code trong chat. Tóm tắt bằng bullets.
|
|
103
104
|
- Code block trong chat: tối đa 10 dòng. Show diff → dùng `render_diffs()`.
|
|
104
105
|
|
|
105
|
-
### Image Generation
|
|
106
|
-
-
|
|
106
|
+
### Image Generation & Asset Mandates (BẮT BUỘC)
|
|
107
|
+
- **Cấm tự tạo SVG:** CẤM tự sinh, tự tạo hoặc thiết kế mã SVG cho các UI assets, biểu tượng trang trí, hoặc spritesheet (do chất lượng SVG tự tạo không đảm bảo và không bám sát thiết kế). BẮT BUỘC sử dụng Codex CLI để tạo hình ảnh và spritesheet UI.
|
|
108
|
+
- **Sử dụng Skill bắt buộc:** Tuyệt đối sử dụng các skill `generate-gui-assets` và `hatch-pet` theo tài liệu tương ứng tại `/Users/trungkientn/.agents/skills/generate-gui-assets/SKILL.md` và `/Users/trungkientn/.codex/skills/hatch-pet/SKILL.md`.
|
|
109
|
+
- **Thiết kế dùng Grid để tiết kiệm:** Bắt buộc thiết kế các assets (ngoại trừ background) bằng dạng Grid (spritesheet/atlas) để tối ưu chi phí và tài nguyên.
|
|
110
|
+
- **Quy trình Grid & Tự Động Phê Duyệt:** Luôn ưu tiên tạo và kiểm chứng (verify) theo hướng lưới `8x6` trước. Nếu chất lượng quá xấu, tự động giảm dần số lượng item/kích thước grid xuống các cấu hình nhỏ hơn (ví dụ: 8x5, 6x6, 6x5, v.v.) mà KHÔNG cần hỏi ý kiến hoặc bắt user xác nhận lại (kể cả trong Normal hay Goal Mode).
|
|
107
111
|
|
|
108
112
|
### Proactive UI Asset Generation (MANDATORY)
|
|
109
113
|
- **Asset Audit:** Trong Gate 2.5 (Visual Design) và Gate 4 Phase B (UI Shell), BẮT BUỘC rà soát mã nguồn/thiết kế để phát hiện các UI assets bị thiếu (nút bấm, panel, icon, pet, egg...).
|
|
@@ -112,12 +116,15 @@ symphony-orchestrator → awf-session-restore (gitnexus state) → nm-memory-syn
|
|
|
112
116
|
- **Cấu trúc Lệnh:**
|
|
113
117
|
- Đối với UI assets: `codex exec "Generate GUI asset: [Prompt/Style/Theme] and save it to [path] using the generate-gui-assets skill rules."`
|
|
114
118
|
- Đối với Pet/Egg assets: `codex exec "Generate pet companion asset: [Pet Type/State] and save it to [path] using the hatch-pet skill rules and grid configuration [grid]."`
|
|
115
|
-
- **Chi tiết & Approval:** Tự động thiết lập prompt chi tiết dựa trên Theme của App, tuân thủ tiêu chuẩn Solid Background và hỏi ý kiến user trước khi thực thi lệnh.
|
|
119
|
+
- **Chi tiết & Approval:** Tự động thiết lập prompt chi tiết dựa trên Theme của App, tuân thủ tiêu chuẩn Solid Background và hỏi ý kiến user trước khi thực thi lệnh (Trừ Goal Mode hoặc trường hợp tự động giảm cấu hình lưới grid: Tự động phê duyệt prompt/cấu hình và thực thi lệnh không cần hỏi).
|
|
120
|
+
|
|
116
121
|
|
|
117
122
|
|
|
118
123
|
### Communication (CAVEMAN ULTRA)
|
|
119
124
|
- Chat: Tiếng Việt, tối đa 1-2 câu ngắn. Code/Docs: Tiếng Anh.
|
|
120
125
|
- CẤM giải thích dài, chào hỏi. Chỉ xuất KẾT QUẢ.
|
|
126
|
+
- Caveman chỉ nén prose chat. KHÔNG cắt/mất thông tin kỹ thuật: command output, error, stack trace, diff, JSON/API response, file path, line ref, test evidence.
|
|
127
|
+
- Khi relay output, giữ nguyên dòng quan trọng; chỉ tóm tắt phần nhiễu xung quanh.
|
|
121
128
|
- Planning artifacts (implementation_plan.md, walkthrough.md) VẪN chi tiết theo format chuẩn.
|
|
122
129
|
- Tài liệu thảo luận & brainstorm (Brief, Requirements, Brainstorm) PHẢI dùng tiếng Việt (hoặc ngôn ngữ giao tiếp của User), chỉ Code/Architecture mới bắt buộc dùng tiếng Anh.
|
|
123
130
|
|
|
@@ -145,6 +152,12 @@ symphony-orchestrator → awf-session-restore (gitnexus state) → nm-memory-syn
|
|
|
145
152
|
- Commit: CHỈ qua `awkit gate git auto`. CẤM `git commit` trực tiếp qua bash.
|
|
146
153
|
- Destructive command → double-confirm user. Không chắc → hỏi trước.
|
|
147
154
|
|
|
155
|
+
### GStack Planning & Code Safety
|
|
156
|
+
- **Office Hours & CEO Review**: Chạy `/office-hours` để thử nghiệm ý tưởng dưới góc nhìn startup/YC. Dùng `/plan-ceo-review` để đạt "trải nghiệm sản phẩm 10 sao" và quản lý phạm vi (scope).
|
|
157
|
+
- **Eng Review & Data Safety**: Chốt kiến trúc và thiết kế dữ liệu. Quét an toàn SQL, concurrency/races, và enum completeness trước khi code.
|
|
158
|
+
- **Pass 1 & Pass 2 Review**: Đánh giá code hai lượt (Pass 1: Critical - SQL/data safety, races, LLM boundary, shell injection, enum; Pass 2: Informational - logic/syntax).
|
|
159
|
+
- **Fix-First Heuristic**: Tự động sửa lỗi cơ học (dead code, N+1 queries, stale comments) và hỏi ý kiến user đối với các quyết định rủi ro/kiến trúc.
|
|
160
|
+
|
|
148
161
|
### Subagent Orchestration & Protocol
|
|
149
162
|
- **Định tuyến trước, Tìm kiếm sau:** Tuyệt đối không dùng `grep_search` hoặc `list_dir` diện rộng để định vị subagents (như `critic`). Bắt buộc tra cứu chỉ mục tại `skills/CATALOG.md`, `skills/TRIGGER_INDEX.md` hoặc `skills/review/SKILL.md` trước.
|
|
150
163
|
- **Tận dụng Subagents Cô lập:** Sử dụng built-in subagents (`research` cho tìm kiếm codebase/log thô, `browser` cho các tác vụ UI) để tránh ô nhiễm context trên luồng chat chính.
|