@leejungkiin/awkit 1.7.0 → 1.7.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/bin/awk.js +576 -84
- package/core/CLAUDE.md +1 -1
- package/core/GEMINI.md +148 -167
- package/core/GEMINI.md.bak +149 -116
- package/core/skill-runtime-manifest.json +3 -0
- package/docs/Claude Fable 5.md +3826 -0
- package/docs/android_kotlin_system_instruction.md +210 -0
- package/docs/brainstorm_ponytail_integration.md +146 -0
- package/docs/brainstorm_smart_setup.md +113 -0
- package/docs/deep-research-report (1).md +293 -0
- package/docs/history/GEMINI.v1.md +135 -0
- package/docs/history/brainstorm_antigravity_unified_architecture.v1.md +105 -0
- package/docs/history/implementation_plan.v1.md +58 -0
- package/package.json +4 -1
- package/scripts/artifact-storage.js +130 -0
- package/scripts/automation-gate.js +40 -7
- package/scripts/claude-plan.js +76 -0
- package/scripts/dependency-manager.js +210 -0
- package/scripts/exec-rtk.js +11 -5
- package/scripts/i18n-helper.js +381 -0
- package/scripts/multi-model-pipeline.js +144 -0
- package/skill-packs/mobile-ios/pack.json +4 -2
- package/skill-packs/reverse-engineering/pack.json +1 -0
- package/skills/CATALOG.md +20 -0
- package/skills/GEMINI.md +9 -1
- package/skills/TRIGGER_INDEX.md +10 -0
- package/skills/ai-music/SKILL.md +275 -0
- package/skills/android-re-analyzer/SKILL.md +238 -0
- package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
- package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
- package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
- package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
- package/skills/android-re-analyzer/references/setup-guide.md +221 -0
- package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
- package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
- package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
- package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
- package/skills/animal-island-ui-style/SKILL.md +1450 -0
- package/skills/app-store-review-agent/SKILL.md +164 -0
- package/skills/app-store-review-agent/references/guidelines/README.md +154 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/ai_apps.md +37 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/all_apps.md +50 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/crypto_finance.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/games.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/health_fitness.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/kids.md +27 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/macos.md +38 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/social_ugc.md +32 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/subscription_iap.md +34 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/vpn.md +18 -0
- package/skills/app-store-review-agent/references/rules/design/minimum_functionality.md +96 -0
- package/skills/app-store-review-agent/references/rules/design/sign_in_with_apple.md +54 -0
- package/skills/app-store-review-agent/references/rules/entitlements/unused_entitlements.md +83 -0
- package/skills/app-store-review-agent/references/rules/metadata/accurate_metadata.md +54 -0
- package/skills/app-store-review-agent/references/rules/metadata/apple_trademark.md +99 -0
- package/skills/app-store-review-agent/references/rules/metadata/china_storefront.md +72 -0
- package/skills/app-store-review-agent/references/rules/metadata/competitor_terms.md +56 -0
- package/skills/app-store-review-agent/references/rules/metadata/subscription_metadata.md +81 -0
- package/skills/app-store-review-agent/references/rules/privacy/privacy_manifest.md +84 -0
- package/skills/app-store-review-agent/references/rules/privacy/unnecessary_data.md +60 -0
- package/skills/app-store-review-agent/references/rules/subscription/misleading_pricing.md +63 -0
- package/skills/app-store-review-agent/references/rules/subscription/missing_tos_pp.md +54 -0
- package/skills/awf-ponytail/SKILL.md +91 -0
- package/skills/awf-ponytail-review/SKILL.md +67 -0
- package/skills/awf-session-restore/SKILL.md +3 -3
- package/skills/brainstorm-agent/SKILL.md +11 -2
- package/skills/brainstorm-agent/templates/brief-template.md +8 -0
- package/skills/claude-planner/SKILL.md +47 -0
- package/skills/code-review/SKILL.md +87 -0
- package/skills/expo-game-development/SKILL.md +163 -0
- package/skills/flutter/LICENSE.txt +202 -0
- package/skills/flutter/SKILL.md +127 -0
- package/skills/flutter-project-creater/LICENSE.txt +202 -0
- package/skills/flutter-project-creater/SKILL.md +106 -0
- package/skills/game-developer/SKILL.md +163 -0
- package/skills/game-developer/references/ecs-patterns.md +501 -0
- package/skills/game-developer/references/multiplayer-networking.md +475 -0
- package/skills/game-developer/references/performance-optimization.md +422 -0
- package/skills/game-developer/references/unity-patterns.md +271 -0
- package/skills/game-developer/references/unreal-cpp.md +352 -0
- package/skills/generate-gui-assets/SKILL.md +305 -0
- package/skills/generate-gui-assets/agents/openai.yaml +4 -0
- package/skills/generate-gui-assets/references/catalog-schema.md +58 -0
- package/skills/generate-gui-assets/references/extraction-techniques.md +21 -0
- package/skills/generate-gui-assets/references/prompt-patterns.md +58 -0
- package/skills/generate-gui-assets/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/generate-gui-assets/scripts/build_gui_contact_sheet.py +51 -0
- package/skills/generate-gui-assets/scripts/clean_chroma_edges.py +262 -0
- package/skills/generate-gui-assets/scripts/copy_approved_icons.py +64 -0
- package/skills/generate-gui-assets/scripts/prepare_gui_asset_run.py +91 -0
- package/skills/generate-gui-assets/scripts/suggest_grid_options.py +63 -0
- package/skills/generate-gui-assets/scripts/validate_gui_catalog.py +50 -0
- package/skills/godot-game-development/SKILL.md +142 -0
- package/skills/hatch-pet/LICENSE.txt +201 -0
- package/skills/hatch-pet/SKILL.md +420 -0
- package/skills/hatch-pet/agents/openai.yaml +4 -0
- package/skills/hatch-pet/references/animation-rows.md +29 -0
- package/skills/hatch-pet/references/codex-pet-contract.md +35 -0
- package/skills/hatch-pet/references/qa-rubric.md +60 -0
- package/skills/hatch-pet/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/hatch-pet/scripts/clean_chroma_edges.py +262 -0
- package/skills/hatch-pet/scripts/compose_atlas.py +150 -0
- package/skills/hatch-pet/scripts/derive_running_left_from_running_right.py +143 -0
- package/skills/hatch-pet/scripts/extract_strip_frames.py +323 -0
- package/skills/hatch-pet/scripts/finalize_pet_run.py +382 -0
- package/skills/hatch-pet/scripts/generate_pet_images.py +287 -0
- package/skills/hatch-pet/scripts/inspect_frames.py +246 -0
- package/skills/hatch-pet/scripts/make_contact_sheet.py +96 -0
- package/skills/hatch-pet/scripts/package_custom_pet.py +108 -0
- package/skills/hatch-pet/scripts/pet_job_status.py +117 -0
- package/skills/hatch-pet/scripts/prepare_pet_run.py +673 -0
- package/skills/hatch-pet/scripts/queue_pet_repairs.py +172 -0
- package/skills/hatch-pet/scripts/record_imagegen_result.py +250 -0
- package/skills/hatch-pet/scripts/render_animation_videos.py +134 -0
- package/skills/hatch-pet/scripts/render_animation_videos.sh +5 -0
- package/skills/hatch-pet/scripts/validate_atlas.py +139 -0
- package/skills/i18n-orchestrator/SKILL.md +37 -0
- package/skills/ios-simulator-skill/SKILL.md +390 -0
- package/skills/ios-simulator-skill/scripts/accessibility_audit.py +300 -0
- package/skills/ios-simulator-skill/scripts/app_launcher.py +326 -0
- package/skills/ios-simulator-skill/scripts/app_state_capture.py +400 -0
- package/skills/ios-simulator-skill/scripts/appearance.py +385 -0
- package/skills/ios-simulator-skill/scripts/build_and_test.py +348 -0
- package/skills/ios-simulator-skill/scripts/clipboard.py +103 -0
- package/skills/ios-simulator-skill/scripts/common/__init__.py +61 -0
- package/skills/ios-simulator-skill/scripts/common/cache_utils.py +289 -0
- package/skills/ios-simulator-skill/scripts/common/device_utils.py +462 -0
- package/skills/ios-simulator-skill/scripts/common/env_config.py +35 -0
- package/skills/ios-simulator-skill/scripts/common/hang_pipeline.py +862 -0
- package/skills/ios-simulator-skill/scripts/common/hang_sessions.py +490 -0
- package/skills/ios-simulator-skill/scripts/common/idb_utils.py +180 -0
- package/skills/ios-simulator-skill/scripts/common/screenshot_utils.py +338 -0
- package/skills/ios-simulator-skill/scripts/container.py +668 -0
- package/skills/ios-simulator-skill/scripts/gesture.py +394 -0
- package/skills/ios-simulator-skill/scripts/hang_watcher.py +1533 -0
- package/skills/ios-simulator-skill/scripts/keyboard.py +391 -0
- package/skills/ios-simulator-skill/scripts/localization_audit.py +483 -0
- package/skills/ios-simulator-skill/scripts/location.py +467 -0
- package/skills/ios-simulator-skill/scripts/log_monitor.py +493 -0
- package/skills/ios-simulator-skill/scripts/model_inspector.py +645 -0
- package/skills/ios-simulator-skill/scripts/navigator.py +461 -0
- package/skills/ios-simulator-skill/scripts/privacy_manager.py +310 -0
- package/skills/ios-simulator-skill/scripts/push_notification.py +240 -0
- package/skills/ios-simulator-skill/scripts/screen_mapper.py +296 -0
- package/skills/ios-simulator-skill/scripts/sim_health_check.sh +245 -0
- package/skills/ios-simulator-skill/scripts/sim_list.py +299 -0
- package/skills/ios-simulator-skill/scripts/simctl_boot.py +312 -0
- package/skills/ios-simulator-skill/scripts/simctl_create.py +316 -0
- package/skills/ios-simulator-skill/scripts/simctl_delete.py +357 -0
- package/skills/ios-simulator-skill/scripts/simctl_erase.py +351 -0
- package/skills/ios-simulator-skill/scripts/simctl_shutdown.py +290 -0
- package/skills/ios-simulator-skill/scripts/simulator_selector.py +375 -0
- package/skills/ios-simulator-skill/scripts/status_bar.py +250 -0
- package/skills/ios-simulator-skill/scripts/test_recorder.py +323 -0
- package/skills/ios-simulator-skill/scripts/visual_diff.py +235 -0
- package/skills/ios-simulator-skill/scripts/xcode/__init__.py +13 -0
- package/skills/ios-simulator-skill/scripts/xcode/builder.py +397 -0
- package/skills/ios-simulator-skill/scripts/xcode/cache.py +204 -0
- package/skills/ios-simulator-skill/scripts/xcode/config.py +178 -0
- package/skills/ios-simulator-skill/scripts/xcode/reporter.py +343 -0
- package/skills/ios-simulator-skill/scripts/xcode/xcresult.py +451 -0
- package/skills/ios-visual-qa-strategist/SKILL.md +111 -0
- package/skills/ios-visual-qa-strategist/agents/openai.yaml +4 -0
- package/skills/ios-visual-qa-strategist/references/ios-tool-selection.md +61 -0
- package/skills/ios-visual-qa-strategist/references/minimal-capture-policy.md +56 -0
- package/skills/ios-visual-qa-strategist/references/visual-reasoning-heuristics.md +53 -0
- package/skills/orchestrator/SKILL.md +0 -20
- package/skills/persistent-storage/SKILL.md +55 -0
- package/skills/short-maker/SKILL.md +23 -0
- package/skills/short-maker/scripts/effects.js +56 -0
- package/skills/short-maker/scripts/shortmaker-bridge.js +332 -0
- package/skills/short-maker/scripts/videomix.js +601 -0
- package/skills/short-maker/templates/hyperframes/cinematic-character.template.html +172 -0
- package/skills/short-maker/templates/hyperframes/index.template.html +194 -0
- package/skills/smali-to-kotlin/SKILL.md +128 -0
- package/skills/smali-to-kotlin/examples/getting-started/tech-stack.md +58 -0
- package/skills/smali-to-kotlin/examples/pipeline/data-ui-parity.md +118 -0
- package/skills/smali-to-kotlin/examples/pipeline/scanner-and-bootstrap.md +106 -0
- package/skills/smali-to-kotlin/library-patterns.md +189 -0
- package/skills/smali-to-kotlin/phase-0-discovery.md +128 -0
- package/skills/smali-to-kotlin/phase-1-architecture.md +166 -0
- package/skills/smali-to-kotlin/phase-2-blueprint-ui.md +347 -0
- package/skills/smali-to-kotlin/phase-2-blueprint.md +228 -0
- package/skills/smali-to-kotlin/phase-3-build.md +248 -0
- package/skills/smali-to-kotlin/phase-3-logic-build.md +268 -0
- package/skills/smali-to-kotlin/smali-reading-guide.md +310 -0
- package/skills/smali-to-kotlin/templates/app-map.md +101 -0
- package/skills/smali-to-kotlin/templates/architecture.md +142 -0
- package/skills/smali-to-kotlin/templates/blueprint.md +145 -0
- package/skills/spec-gate/SKILL.md +6 -2
- package/skills/symphony-enforcer/SKILL.md +8 -0
- package/skills/symphony-enforcer/examples/mindful-stop.md +2 -0
- package/skills/symphony-enforcer/examples/three-phase.md +16 -0
- package/skills/symphony-enforcer/examples/trigger-points.md +7 -1
- package/skills/unity-game-development/SKILL.md +231 -0
- package/skills/verification-gate/SKILL.md +4 -2
- package/skills/video-edit/SKILL.md +36 -0
- package/skills/video-edit/scripts/video_edit.py +324 -0
- package/templates/setup-mapping.json +48 -0
- package/templates/specs/design-template.md +161 -71
- package/templates/specs/requirements-template.md +65 -133
- package/templates/specs/task-spec-template.xml +3 -0
- package/workflows/_uncategorized/critic.md +40 -0
- package/workflows/_uncategorized/git-rebase-flow.md +81 -0
- package/workflows/_uncategorized/image-gen.md +118 -0
- package/workflows/_uncategorized/multi-model-pipeline.md +60 -0
- package/workflows/_uncategorized/pixel-gen.md +86 -0
- package/workflows/_uncategorized/pixel-setup.md +90 -0
- package/workflows/_uncategorized/ponytail-review.md +59 -0
- package/workflows/_uncategorized/reverse-android-build.md +222 -0
- package/workflows/_uncategorized/reverse-android-design.md +139 -0
- package/workflows/_uncategorized/reverse-android-discover.md +150 -0
- package/workflows/_uncategorized/reverse-android-scan.md +158 -0
- package/workflows/_uncategorized/reverse-android.md +143 -0
- package/workflows/_uncategorized/reverse-ios-build.md +240 -0
- package/workflows/_uncategorized/reverse-ios-design.md +112 -0
- package/workflows/_uncategorized/reverse-ios-discover.md +120 -0
- package/workflows/_uncategorized/reverse-ios-scan.md +155 -0
- package/workflows/_uncategorized/reverse-ios.md +152 -0
- package/workflows/_uncategorized/safety-router.md +34 -0
- package/workflows/_uncategorized/teach.md +89 -0
- package/workflows/_uncategorized/verify-ui.md +53 -0
- package/workflows/_uncategorized/visualize-screenshots.md +34 -0
- package/workflows/ads/ads-analyst.md +201 -0
- package/workflows/ads/ads-audit.md +106 -0
- package/workflows/ads/ads-optimize.md +97 -0
- package/workflows/ads/ads-targeting.md +241 -0
- package/workflows/ads/adsExpert.md +160 -0
- package/workflows/ads/smali-ads-config.md +400 -0
- package/workflows/ads/smali-ads-flow.md +331 -0
- package/workflows/ads/smali-ads-interstitial.md +377 -0
- package/workflows/ads/smali-ads-native.md +382 -0
- package/workflows/context/teach.md +89 -0
- package/workflows/gitnexus.md +8 -8
- package/workflows/lifecycle/brainstorm.md +43 -0
- package/workflows/lifecycle/code.md +5 -0
- package/workflows/lifecycle/init.md +23 -5
- package/workflows/lifecycle/multi-model-pipeline.md +60 -0
- package/workflows/quality/ponytail-review.md +59 -0
- package/workflows/roles/critic.md +40 -0
- package/workflows/roles/safety-router.md +34 -0
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leejungkiin/awkit",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.4",
|
|
4
4
|
"description": "Antigravity Workflow Kit v1.6 Unified AI agent orchestration system with Mindful Checkpoints.",
|
|
5
5
|
"main": "bin/awk.js",
|
|
6
6
|
"private": false,
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
7
10
|
"bin": {
|
|
8
11
|
"awkit": "bin/awk.js",
|
|
9
12
|
"ag": "bin/awk.js"
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact Storage Engine for AWKit
|
|
3
|
+
* Manages persistent key-value data for interactive artifacts.
|
|
4
|
+
* Saves data locally to .brain/storage.json.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const STORAGE_DIR = path.join(process.cwd(), '.brain');
|
|
11
|
+
const STORAGE_FILE = path.join(STORAGE_DIR, 'storage.json');
|
|
12
|
+
|
|
13
|
+
function ensureStorageDir() {
|
|
14
|
+
if (!fs.existsSync(STORAGE_DIR)) {
|
|
15
|
+
fs.mkdirSync(STORAGE_DIR, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function loadStorage() {
|
|
20
|
+
ensureStorageDir();
|
|
21
|
+
if (!fs.existsSync(STORAGE_FILE)) {
|
|
22
|
+
return { personal: {}, shared: {} };
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const content = fs.readFileSync(STORAGE_FILE, 'utf8');
|
|
26
|
+
return JSON.parse(content);
|
|
27
|
+
} catch (_) {
|
|
28
|
+
return { personal: {}, shared: {} };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function saveStorage(data) {
|
|
33
|
+
ensureStorageDir();
|
|
34
|
+
fs.writeFileSync(STORAGE_FILE, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function validateKey(key) {
|
|
38
|
+
if (!key || typeof key !== 'string') return 'Key must be a non-empty string.';
|
|
39
|
+
if (key.length > 200) return 'Key must be under 200 characters.';
|
|
40
|
+
if (/\s/.test(key)) return 'Key cannot contain whitespace.';
|
|
41
|
+
if (/[\/\\'"\s]/.test(key)) return 'Key cannot contain path separators or quotes.';
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function cmdStorage(args) {
|
|
46
|
+
const action = args[0];
|
|
47
|
+
const key = args[1];
|
|
48
|
+
const value = args[2];
|
|
49
|
+
const isShared = args.includes('--shared');
|
|
50
|
+
|
|
51
|
+
const type = isShared ? 'shared' : 'personal';
|
|
52
|
+
|
|
53
|
+
if (!action) {
|
|
54
|
+
console.error('Usage: awkit storage <get|set|delete|list> [key] [value] [--shared]');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const storage = loadStorage();
|
|
59
|
+
|
|
60
|
+
switch (action.toLowerCase()) {
|
|
61
|
+
case 'set': {
|
|
62
|
+
const err = validateKey(key);
|
|
63
|
+
if (err) {
|
|
64
|
+
console.error(`Error: ${err}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
if (value === undefined) {
|
|
68
|
+
console.error('Error: Value is required for set action.');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let parsedValue = value;
|
|
73
|
+
try {
|
|
74
|
+
// Try to parse if it is valid JSON
|
|
75
|
+
parsedValue = JSON.parse(value);
|
|
76
|
+
} catch (_) {
|
|
77
|
+
// Keep as raw string if parsing fails
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
storage[type][key] = parsedValue;
|
|
81
|
+
saveStorage(storage);
|
|
82
|
+
console.log(JSON.stringify({ key, value: parsedValue, shared: isShared }, null, 2));
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
case 'get': {
|
|
87
|
+
if (!key) {
|
|
88
|
+
console.error('Error: Key is required for get action.');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
const found = storage[type][key];
|
|
92
|
+
if (found === undefined) {
|
|
93
|
+
console.error(`Error: Key "${key}" not found in ${type} storage.`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
console.log(JSON.stringify({ key, value: found, shared: isShared }, null, 2));
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
case 'delete': {
|
|
101
|
+
if (!key) {
|
|
102
|
+
console.error('Error: Key is required for delete action.');
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
if (storage[type][key] === undefined) {
|
|
106
|
+
console.error(`Error: Key "${key}" not found in ${type} storage.`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
delete storage[type][key];
|
|
110
|
+
saveStorage(storage);
|
|
111
|
+
console.log(JSON.stringify({ key, deleted: true, shared: isShared }, null, 2));
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
case 'list': {
|
|
116
|
+
const prefix = key || '';
|
|
117
|
+
const keys = Object.keys(storage[type]).filter(k => k.startsWith(prefix));
|
|
118
|
+
console.log(JSON.stringify({ keys, prefix: prefix || null, shared: isShared }, null, 2));
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
default:
|
|
123
|
+
console.error(`Unknown action: ${action}`);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
module.exports = {
|
|
129
|
+
cmdStorage
|
|
130
|
+
};
|
|
@@ -102,13 +102,13 @@ function checkGate(domain, action) {
|
|
|
102
102
|
case 'git': {
|
|
103
103
|
const gitConfig = automation.git;
|
|
104
104
|
if (!gitConfig) {
|
|
105
|
-
return { allowed:
|
|
105
|
+
return { allowed: false, config: null, reason: 'No automation.git config — default block' };
|
|
106
106
|
}
|
|
107
|
-
if (action === 'commit' && gitConfig.autoCommit
|
|
108
|
-
return { allowed: false, config: gitConfig, reason: 'automation.git.autoCommit is
|
|
107
|
+
if (action === 'commit' && gitConfig.autoCommit !== true) {
|
|
108
|
+
return { allowed: false, config: gitConfig, reason: 'automation.git.autoCommit is not true (default off)' };
|
|
109
109
|
}
|
|
110
|
-
if (action === 'push' && gitConfig.autoPush
|
|
111
|
-
return { allowed: false, config: gitConfig, reason: 'automation.git.autoPush is
|
|
110
|
+
if (action === 'push' && gitConfig.autoPush !== true) {
|
|
111
|
+
return { allowed: false, config: gitConfig, reason: 'automation.git.autoPush is not true (default off)' };
|
|
112
112
|
}
|
|
113
113
|
return { allowed: true, config: gitConfig, reason: 'automation.git allows this action' };
|
|
114
114
|
}
|
|
@@ -166,6 +166,12 @@ function checkGate(domain, action) {
|
|
|
166
166
|
|
|
167
167
|
// ─── Git executors ────────────────────────────────────────────────────────────
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* List of generic commit messages that should be rejected.
|
|
171
|
+
* AI agents MUST provide descriptive conventional commit messages.
|
|
172
|
+
*/
|
|
173
|
+
const GENERIC_MSG_PATTERNS = /^(chore: update|update|wip|changes|fix|feat|chore|save|commit|auto commit|update files|chore: update files|feat\([^)]*\): update \w+)$/i;
|
|
174
|
+
|
|
169
175
|
function execGitCommit(message) {
|
|
170
176
|
const gate = checkGate('git', 'commit');
|
|
171
177
|
if (!gate.allowed) {
|
|
@@ -174,6 +180,22 @@ function execGitCommit(message) {
|
|
|
174
180
|
return false;
|
|
175
181
|
}
|
|
176
182
|
|
|
183
|
+
// BLOCK commits without descriptive messages
|
|
184
|
+
if (!message || !message.trim()) {
|
|
185
|
+
err('🚫 COMMIT BLOCKED: No commit message provided.');
|
|
186
|
+
err(' AI MUST provide a descriptive conventional commit message.');
|
|
187
|
+
err(' Example: awkit gate git auto "feat(auth): add Google sign-in flow"');
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (GENERIC_MSG_PATTERNS.test(message.trim())) {
|
|
192
|
+
err(`🚫 COMMIT BLOCKED: Generic message detected — "${message}"`);
|
|
193
|
+
err(' AI MUST describe WHAT was changed and WHY.');
|
|
194
|
+
err(' ✅ Good: "feat(home): add hero banner with parallax effect"');
|
|
195
|
+
err(' ❌ Bad: "chore: update", "feat(app): update development"');
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
|
|
177
199
|
try {
|
|
178
200
|
execRtkSync('git add -A', { stdio: 'inherit' });
|
|
179
201
|
execRtkSync(`git commit -m "${message.replace(/"/g, '\\"')}"`, { stdio: 'inherit' });
|
|
@@ -221,6 +243,17 @@ function execGitAuto(message) {
|
|
|
221
243
|
log(`${C.cyan}${C.bold}🔒 Automation Gate — Git Auto${C.reset}`);
|
|
222
244
|
dim(` Checking .project-identity...`);
|
|
223
245
|
|
|
246
|
+
// Early exit if working tree is clean to prevent infinite recursion/loops
|
|
247
|
+
try {
|
|
248
|
+
const gitStatus = execSync('git status --porcelain', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
249
|
+
if (!gitStatus) {
|
|
250
|
+
ok('Working tree clean. No changes to commit or push.');
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
} catch (_) {
|
|
254
|
+
// Ignore errors if not in a git repo, fallback to standard execution
|
|
255
|
+
}
|
|
256
|
+
|
|
224
257
|
const committed = execGitCommit(message);
|
|
225
258
|
if (!committed) return false;
|
|
226
259
|
|
|
@@ -353,13 +386,13 @@ function cmdGate(args) {
|
|
|
353
386
|
case 'git':
|
|
354
387
|
switch (action) {
|
|
355
388
|
case 'commit':
|
|
356
|
-
execGitCommit(rest.join(' ') ||
|
|
389
|
+
execGitCommit(rest.join(' ') || null);
|
|
357
390
|
break;
|
|
358
391
|
case 'push':
|
|
359
392
|
execGitPush();
|
|
360
393
|
break;
|
|
361
394
|
case 'auto':
|
|
362
|
-
execGitAuto(rest.join(' ') ||
|
|
395
|
+
execGitAuto(rest.join(' ') || null);
|
|
363
396
|
break;
|
|
364
397
|
default:
|
|
365
398
|
err(`Unknown git action: ${action}`);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync, spawnSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
// Parse arguments
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
let promptFile = '';
|
|
10
|
+
let outputFile = '';
|
|
11
|
+
|
|
12
|
+
for (let i = 0; i < args.length; i++) {
|
|
13
|
+
if (args[i] === '--prompt-file' && args[i + 1]) {
|
|
14
|
+
promptFile = args[i + 1];
|
|
15
|
+
i++;
|
|
16
|
+
} else if (args[i] === '--output' && args[i + 1]) {
|
|
17
|
+
outputFile = args[i + 1];
|
|
18
|
+
i++;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!promptFile || !outputFile) {
|
|
23
|
+
console.error('Usage: node scripts/claude-plan.js --prompt-file <file> --output <file>');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 1. Check if claude command is available
|
|
28
|
+
try {
|
|
29
|
+
execSync('which claude', { stdio: 'ignore' });
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.warn('⚠️ claude CLI not found in PATH');
|
|
32
|
+
process.exit(127);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 2. Check if authenticated (quick test with timeout to avoid hang)
|
|
36
|
+
try {
|
|
37
|
+
execSync('claude -p "echo OK" --max-turns 1 --bare', { stdio: 'ignore', timeout: 5000 });
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.warn('⚠️ claude CLI is installed but not authenticated or timed out');
|
|
40
|
+
process.exit(2);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 3. Read prompt
|
|
44
|
+
if (!fs.existsSync(promptFile)) {
|
|
45
|
+
console.error(`Error: Prompt file not found: ${promptFile}`);
|
|
46
|
+
process.exit(3);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const promptContent = fs.readFileSync(promptFile, 'utf8');
|
|
50
|
+
|
|
51
|
+
// 4. Run Claude CLI
|
|
52
|
+
console.log('🚀 Running planning via Claude CLI...');
|
|
53
|
+
try {
|
|
54
|
+
const result = spawnSync('claude', [
|
|
55
|
+
'-p', promptContent,
|
|
56
|
+
'--model', 'claude-opus-4-8',
|
|
57
|
+
'--max-turns', '3',
|
|
58
|
+
'--output-format', 'text',
|
|
59
|
+
'--bare'
|
|
60
|
+
], { encoding: 'utf8', timeout: 300000 }); // 5 minutes timeout
|
|
61
|
+
|
|
62
|
+
if (result.status !== 0) {
|
|
63
|
+
console.error('❌ Claude CLI exited with status:', result.status);
|
|
64
|
+
console.error(result.stderr || result.stdout);
|
|
65
|
+
process.exit(result.status || 4);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
fs.mkdirSync(path.dirname(outputFile), { recursive: true });
|
|
69
|
+
fs.writeFileSync(outputFile, result.stdout);
|
|
70
|
+
console.log(`✅ Plan successfully written to ${outputFile}`);
|
|
71
|
+
process.exit(0);
|
|
72
|
+
|
|
73
|
+
} catch (err) {
|
|
74
|
+
console.error('❌ Exception during Claude execution:', err.message);
|
|
75
|
+
process.exit(5);
|
|
76
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
const https = require('https');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
const HOME = os.homedir();
|
|
8
|
+
const CACHE_DIR = path.join(HOME, '.gemini', 'antigravity');
|
|
9
|
+
const CACHE_FILE = path.join(CACHE_DIR, '.awkit-update-cache.json');
|
|
10
|
+
const CACHE_DURATION_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
11
|
+
|
|
12
|
+
// Helper colors matching AWKit style
|
|
13
|
+
const C = {
|
|
14
|
+
reset: '\x1b[0m',
|
|
15
|
+
red: '\x1b[31m',
|
|
16
|
+
green: '\x1b[32m',
|
|
17
|
+
yellow: '\x1b[33m',
|
|
18
|
+
cyan: '\x1b[36m',
|
|
19
|
+
gray: '\x1b[90m',
|
|
20
|
+
bold: '\x1b[1m'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function logOk(msg) { console.log(`${C.green}✅ ${msg}${C.reset}`); }
|
|
24
|
+
function logWarn(msg) { console.log(`${C.yellow}⚠️ ${msg}${C.reset}`); }
|
|
25
|
+
function logErr(msg) { console.log(`${C.red}❌ ${msg}${C.reset}`); }
|
|
26
|
+
function logInfo(msg) { console.log(`${C.cyan}ℹ️ ${msg}${C.reset}`); }
|
|
27
|
+
function logDim(msg) { console.log(`${C.gray} ${msg}${C.reset}`); }
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Check if rtk is installed.
|
|
31
|
+
*/
|
|
32
|
+
function checkRtk() {
|
|
33
|
+
try {
|
|
34
|
+
execSync('which rtk', { stdio: 'ignore' });
|
|
35
|
+
return true;
|
|
36
|
+
} catch (_) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get installed rtk version.
|
|
43
|
+
*/
|
|
44
|
+
function getRtkVersion() {
|
|
45
|
+
try {
|
|
46
|
+
return execSync('rtk --version', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim().replace(/^rtk\s+/, '');
|
|
47
|
+
} catch (_) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Check if gitnexus is installed globally or locally.
|
|
54
|
+
*/
|
|
55
|
+
function checkGitnexus() {
|
|
56
|
+
try {
|
|
57
|
+
execSync('which gitnexus', { stdio: 'ignore' });
|
|
58
|
+
return true;
|
|
59
|
+
} catch (_) {
|
|
60
|
+
try {
|
|
61
|
+
// Check if npx can resolve it without installing it
|
|
62
|
+
execSync('npx --no-install gitnexus --version', { stdio: 'ignore' });
|
|
63
|
+
return true;
|
|
64
|
+
} catch (_) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Install RTK using optimal pathways.
|
|
72
|
+
*/
|
|
73
|
+
function installRtk() {
|
|
74
|
+
logInfo('Installing RTK (Rust Token Killer)...');
|
|
75
|
+
|
|
76
|
+
// 1. Try Homebrew if on macOS
|
|
77
|
+
if (process.platform === 'darwin') {
|
|
78
|
+
try {
|
|
79
|
+
execSync('which brew', { stdio: 'ignore' });
|
|
80
|
+
logInfo('Homebrew detected, trying brew install...');
|
|
81
|
+
execSync('brew install rtk', { stdio: 'inherit' });
|
|
82
|
+
logOk('RTK installed via Homebrew.');
|
|
83
|
+
return true;
|
|
84
|
+
} catch (_) {
|
|
85
|
+
logDim('Homebrew not available or failed. Trying pre-built script installer.');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 2. Try official curl pre-built installer
|
|
90
|
+
try {
|
|
91
|
+
logInfo('Downloading pre-built RTK binary...');
|
|
92
|
+
execSync('curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh', { stdio: 'inherit' });
|
|
93
|
+
logOk('RTK pre-built binary installed to ~/.local/bin.');
|
|
94
|
+
return true;
|
|
95
|
+
} catch (e) {
|
|
96
|
+
logDim(`Pre-built installer failed: ${e.message}. Trying Cargo compile fallback.`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 3. Fallback to Cargo compile
|
|
100
|
+
try {
|
|
101
|
+
execSync('which cargo', { stdio: 'ignore' });
|
|
102
|
+
logInfo('Cargo detected, compiling RTK from source...');
|
|
103
|
+
execSync('cargo install --git https://github.com/rtk-ai/rtk', { stdio: 'inherit' });
|
|
104
|
+
logOk('RTK successfully compiled and installed via Cargo.');
|
|
105
|
+
return true;
|
|
106
|
+
} catch (_) {
|
|
107
|
+
logErr('Cargo/Rust not found. Could not compile RTK.');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
logErr('Failed to install RTK. Please install it manually (see https://www.rtk-ai.app/guide/getting-started/installation).');
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Install GitNexus globally.
|
|
116
|
+
*/
|
|
117
|
+
function installGitnexus() {
|
|
118
|
+
logInfo('Installing GitNexus globally via npm...');
|
|
119
|
+
try {
|
|
120
|
+
execSync('npm install -g @duytransipher/gitnexus', { stdio: 'inherit' });
|
|
121
|
+
logOk('GitNexus successfully installed globally.');
|
|
122
|
+
return true;
|
|
123
|
+
} catch (e) {
|
|
124
|
+
logErr(`Failed to install GitNexus globally: ${e.message}`);
|
|
125
|
+
logDim('Try running manually: npm install -g @duytransipher/gitnexus');
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Perform HTTPS GET request returning parsed JSON.
|
|
132
|
+
*/
|
|
133
|
+
function fetchJson(url) {
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
const options = {
|
|
136
|
+
headers: { 'User-Agent': 'awkit-dependency-manager' },
|
|
137
|
+
timeout: 4000
|
|
138
|
+
};
|
|
139
|
+
https.get(url, options, (res) => {
|
|
140
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
141
|
+
return reject(new Error(`HTTP ${res.statusCode}`));
|
|
142
|
+
}
|
|
143
|
+
let data = '';
|
|
144
|
+
res.on('data', chunk => { data += chunk; });
|
|
145
|
+
res.on('end', () => {
|
|
146
|
+
try { resolve(JSON.parse(data)); } catch (e) { reject(e); }
|
|
147
|
+
});
|
|
148
|
+
}).on('error', reject).on('timeout', () => reject(new Error('Request timeout')));
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Check updates with 24h caching.
|
|
154
|
+
*/
|
|
155
|
+
async function checkUpdates(currentAwkitVersion) {
|
|
156
|
+
let cache = { lastChecked: 0, latestAwkit: null, latestRtk: null };
|
|
157
|
+
|
|
158
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
159
|
+
try {
|
|
160
|
+
cache = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
|
|
161
|
+
} catch (_) {}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const now = Date.now();
|
|
165
|
+
if (now - cache.lastChecked < CACHE_DURATION_MS && cache.latestAwkit && cache.latestRtk) {
|
|
166
|
+
return { latestAwkit: cache.latestAwkit, latestRtk: cache.latestRtk, cached: true };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
logInfo('Checking for updates...');
|
|
170
|
+
let latestAwkit = cache.latestAwkit;
|
|
171
|
+
let latestRtk = cache.latestRtk;
|
|
172
|
+
|
|
173
|
+
// Check AWKit
|
|
174
|
+
try {
|
|
175
|
+
const npmData = await fetchJson('https://registry.npmjs.org/@leejungkiin/awkit/latest');
|
|
176
|
+
if (npmData && npmData.version) {
|
|
177
|
+
latestAwkit = npmData.version;
|
|
178
|
+
}
|
|
179
|
+
} catch (e) {
|
|
180
|
+
logDim(`AWKit update check failed: ${e.message}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Check RTK
|
|
184
|
+
try {
|
|
185
|
+
const githubData = await fetchJson('https://api.github.com/repos/rtk-ai/rtk/releases/latest');
|
|
186
|
+
if (githubData && githubData.tag_name) {
|
|
187
|
+
latestRtk = githubData.tag_name.replace(/^v/, '');
|
|
188
|
+
}
|
|
189
|
+
} catch (e) {
|
|
190
|
+
logDim(`RTK update check failed: ${e.message}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Save cache
|
|
194
|
+
cache = { lastChecked: now, latestAwkit, latestRtk };
|
|
195
|
+
try {
|
|
196
|
+
fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
197
|
+
fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2) + '\n');
|
|
198
|
+
} catch (_) {}
|
|
199
|
+
|
|
200
|
+
return { latestAwkit, latestRtk, cached: false };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
module.exports = {
|
|
204
|
+
checkRtk,
|
|
205
|
+
getRtkVersion,
|
|
206
|
+
checkGitnexus,
|
|
207
|
+
installRtk,
|
|
208
|
+
installGitnexus,
|
|
209
|
+
checkUpdates
|
|
210
|
+
};
|
package/scripts/exec-rtk.js
CHANGED
|
@@ -24,19 +24,25 @@ function checkRtk() {
|
|
|
24
24
|
* @returns {Buffer|string}
|
|
25
25
|
*/
|
|
26
26
|
function execRtkSync(command, options = {}) {
|
|
27
|
+
const trimmed = command.trim();
|
|
28
|
+
|
|
29
|
+
// Only compress developer commands known to be verbose
|
|
30
|
+
const eligiblePrefixes = ['git ', 'npm ', 'cargo ', 'yarn ', 'pnpm ', 'grep ', 'find ', 'awkit trello '];
|
|
31
|
+
const extendedPrefixes = ['cat ', 'curl ', 'xcodebuild ', './gradlew ', 'swift ', 'flutter ', 'dart ', 'pod ', 'brew '];
|
|
32
|
+
const allEligible = [...eligiblePrefixes, ...extendedPrefixes];
|
|
33
|
+
const isEligible = allEligible.some(prefix => trimmed.startsWith(prefix));
|
|
34
|
+
|
|
27
35
|
if (!checkRtk()) {
|
|
36
|
+
if (isEligible && !options.stdio) {
|
|
37
|
+
return execSync(`${command} 2>&1 | tail -c 8000`, { ...options, shell: true });
|
|
38
|
+
}
|
|
28
39
|
return execSync(command, options);
|
|
29
40
|
}
|
|
30
41
|
|
|
31
|
-
const trimmed = command.trim();
|
|
32
42
|
if (trimmed.startsWith('rtk ')) {
|
|
33
43
|
return execSync(command, options);
|
|
34
44
|
}
|
|
35
45
|
|
|
36
|
-
// Only compress developer commands known to be verbose
|
|
37
|
-
const eligiblePrefixes = ['git ', 'npm ', 'cargo ', 'yarn ', 'pnpm ', 'grep ', 'find ', 'awkit trello '];
|
|
38
|
-
const isEligible = eligiblePrefixes.some(prefix => trimmed.startsWith(prefix));
|
|
39
|
-
|
|
40
46
|
if (isEligible) {
|
|
41
47
|
return execSync(`rtk ${command}`, options);
|
|
42
48
|
}
|