@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.
Files changed (241) hide show
  1. package/bin/awk.js +576 -84
  2. package/core/CLAUDE.md +1 -1
  3. package/core/GEMINI.md +148 -167
  4. package/core/GEMINI.md.bak +149 -116
  5. package/core/skill-runtime-manifest.json +3 -0
  6. package/docs/Claude Fable 5.md +3826 -0
  7. package/docs/android_kotlin_system_instruction.md +210 -0
  8. package/docs/brainstorm_ponytail_integration.md +146 -0
  9. package/docs/brainstorm_smart_setup.md +113 -0
  10. package/docs/deep-research-report (1).md +293 -0
  11. package/docs/history/GEMINI.v1.md +135 -0
  12. package/docs/history/brainstorm_antigravity_unified_architecture.v1.md +105 -0
  13. package/docs/history/implementation_plan.v1.md +58 -0
  14. package/package.json +4 -1
  15. package/scripts/artifact-storage.js +130 -0
  16. package/scripts/automation-gate.js +40 -7
  17. package/scripts/claude-plan.js +76 -0
  18. package/scripts/dependency-manager.js +210 -0
  19. package/scripts/exec-rtk.js +11 -5
  20. package/scripts/i18n-helper.js +381 -0
  21. package/scripts/multi-model-pipeline.js +144 -0
  22. package/skill-packs/mobile-ios/pack.json +4 -2
  23. package/skill-packs/reverse-engineering/pack.json +1 -0
  24. package/skills/CATALOG.md +20 -0
  25. package/skills/GEMINI.md +9 -1
  26. package/skills/TRIGGER_INDEX.md +10 -0
  27. package/skills/ai-music/SKILL.md +275 -0
  28. package/skills/android-re-analyzer/SKILL.md +238 -0
  29. package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
  30. package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
  31. package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
  32. package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
  33. package/skills/android-re-analyzer/references/setup-guide.md +221 -0
  34. package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
  35. package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
  36. package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
  37. package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
  38. package/skills/animal-island-ui-style/SKILL.md +1450 -0
  39. package/skills/app-store-review-agent/SKILL.md +164 -0
  40. package/skills/app-store-review-agent/references/guidelines/README.md +154 -0
  41. package/skills/app-store-review-agent/references/guidelines/by-app-type/ai_apps.md +37 -0
  42. package/skills/app-store-review-agent/references/guidelines/by-app-type/all_apps.md +50 -0
  43. package/skills/app-store-review-agent/references/guidelines/by-app-type/crypto_finance.md +31 -0
  44. package/skills/app-store-review-agent/references/guidelines/by-app-type/games.md +31 -0
  45. package/skills/app-store-review-agent/references/guidelines/by-app-type/health_fitness.md +31 -0
  46. package/skills/app-store-review-agent/references/guidelines/by-app-type/kids.md +27 -0
  47. package/skills/app-store-review-agent/references/guidelines/by-app-type/macos.md +38 -0
  48. package/skills/app-store-review-agent/references/guidelines/by-app-type/social_ugc.md +32 -0
  49. package/skills/app-store-review-agent/references/guidelines/by-app-type/subscription_iap.md +34 -0
  50. package/skills/app-store-review-agent/references/guidelines/by-app-type/vpn.md +18 -0
  51. package/skills/app-store-review-agent/references/rules/design/minimum_functionality.md +96 -0
  52. package/skills/app-store-review-agent/references/rules/design/sign_in_with_apple.md +54 -0
  53. package/skills/app-store-review-agent/references/rules/entitlements/unused_entitlements.md +83 -0
  54. package/skills/app-store-review-agent/references/rules/metadata/accurate_metadata.md +54 -0
  55. package/skills/app-store-review-agent/references/rules/metadata/apple_trademark.md +99 -0
  56. package/skills/app-store-review-agent/references/rules/metadata/china_storefront.md +72 -0
  57. package/skills/app-store-review-agent/references/rules/metadata/competitor_terms.md +56 -0
  58. package/skills/app-store-review-agent/references/rules/metadata/subscription_metadata.md +81 -0
  59. package/skills/app-store-review-agent/references/rules/privacy/privacy_manifest.md +84 -0
  60. package/skills/app-store-review-agent/references/rules/privacy/unnecessary_data.md +60 -0
  61. package/skills/app-store-review-agent/references/rules/subscription/misleading_pricing.md +63 -0
  62. package/skills/app-store-review-agent/references/rules/subscription/missing_tos_pp.md +54 -0
  63. package/skills/awf-ponytail/SKILL.md +91 -0
  64. package/skills/awf-ponytail-review/SKILL.md +67 -0
  65. package/skills/awf-session-restore/SKILL.md +3 -3
  66. package/skills/brainstorm-agent/SKILL.md +11 -2
  67. package/skills/brainstorm-agent/templates/brief-template.md +8 -0
  68. package/skills/claude-planner/SKILL.md +47 -0
  69. package/skills/code-review/SKILL.md +87 -0
  70. package/skills/expo-game-development/SKILL.md +163 -0
  71. package/skills/flutter/LICENSE.txt +202 -0
  72. package/skills/flutter/SKILL.md +127 -0
  73. package/skills/flutter-project-creater/LICENSE.txt +202 -0
  74. package/skills/flutter-project-creater/SKILL.md +106 -0
  75. package/skills/game-developer/SKILL.md +163 -0
  76. package/skills/game-developer/references/ecs-patterns.md +501 -0
  77. package/skills/game-developer/references/multiplayer-networking.md +475 -0
  78. package/skills/game-developer/references/performance-optimization.md +422 -0
  79. package/skills/game-developer/references/unity-patterns.md +271 -0
  80. package/skills/game-developer/references/unreal-cpp.md +352 -0
  81. package/skills/generate-gui-assets/SKILL.md +305 -0
  82. package/skills/generate-gui-assets/agents/openai.yaml +4 -0
  83. package/skills/generate-gui-assets/references/catalog-schema.md +58 -0
  84. package/skills/generate-gui-assets/references/extraction-techniques.md +21 -0
  85. package/skills/generate-gui-assets/references/prompt-patterns.md +58 -0
  86. package/skills/generate-gui-assets/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
  87. package/skills/generate-gui-assets/scripts/build_gui_contact_sheet.py +51 -0
  88. package/skills/generate-gui-assets/scripts/clean_chroma_edges.py +262 -0
  89. package/skills/generate-gui-assets/scripts/copy_approved_icons.py +64 -0
  90. package/skills/generate-gui-assets/scripts/prepare_gui_asset_run.py +91 -0
  91. package/skills/generate-gui-assets/scripts/suggest_grid_options.py +63 -0
  92. package/skills/generate-gui-assets/scripts/validate_gui_catalog.py +50 -0
  93. package/skills/godot-game-development/SKILL.md +142 -0
  94. package/skills/hatch-pet/LICENSE.txt +201 -0
  95. package/skills/hatch-pet/SKILL.md +420 -0
  96. package/skills/hatch-pet/agents/openai.yaml +4 -0
  97. package/skills/hatch-pet/references/animation-rows.md +29 -0
  98. package/skills/hatch-pet/references/codex-pet-contract.md +35 -0
  99. package/skills/hatch-pet/references/qa-rubric.md +60 -0
  100. package/skills/hatch-pet/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
  101. package/skills/hatch-pet/scripts/clean_chroma_edges.py +262 -0
  102. package/skills/hatch-pet/scripts/compose_atlas.py +150 -0
  103. package/skills/hatch-pet/scripts/derive_running_left_from_running_right.py +143 -0
  104. package/skills/hatch-pet/scripts/extract_strip_frames.py +323 -0
  105. package/skills/hatch-pet/scripts/finalize_pet_run.py +382 -0
  106. package/skills/hatch-pet/scripts/generate_pet_images.py +287 -0
  107. package/skills/hatch-pet/scripts/inspect_frames.py +246 -0
  108. package/skills/hatch-pet/scripts/make_contact_sheet.py +96 -0
  109. package/skills/hatch-pet/scripts/package_custom_pet.py +108 -0
  110. package/skills/hatch-pet/scripts/pet_job_status.py +117 -0
  111. package/skills/hatch-pet/scripts/prepare_pet_run.py +673 -0
  112. package/skills/hatch-pet/scripts/queue_pet_repairs.py +172 -0
  113. package/skills/hatch-pet/scripts/record_imagegen_result.py +250 -0
  114. package/skills/hatch-pet/scripts/render_animation_videos.py +134 -0
  115. package/skills/hatch-pet/scripts/render_animation_videos.sh +5 -0
  116. package/skills/hatch-pet/scripts/validate_atlas.py +139 -0
  117. package/skills/i18n-orchestrator/SKILL.md +37 -0
  118. package/skills/ios-simulator-skill/SKILL.md +390 -0
  119. package/skills/ios-simulator-skill/scripts/accessibility_audit.py +300 -0
  120. package/skills/ios-simulator-skill/scripts/app_launcher.py +326 -0
  121. package/skills/ios-simulator-skill/scripts/app_state_capture.py +400 -0
  122. package/skills/ios-simulator-skill/scripts/appearance.py +385 -0
  123. package/skills/ios-simulator-skill/scripts/build_and_test.py +348 -0
  124. package/skills/ios-simulator-skill/scripts/clipboard.py +103 -0
  125. package/skills/ios-simulator-skill/scripts/common/__init__.py +61 -0
  126. package/skills/ios-simulator-skill/scripts/common/cache_utils.py +289 -0
  127. package/skills/ios-simulator-skill/scripts/common/device_utils.py +462 -0
  128. package/skills/ios-simulator-skill/scripts/common/env_config.py +35 -0
  129. package/skills/ios-simulator-skill/scripts/common/hang_pipeline.py +862 -0
  130. package/skills/ios-simulator-skill/scripts/common/hang_sessions.py +490 -0
  131. package/skills/ios-simulator-skill/scripts/common/idb_utils.py +180 -0
  132. package/skills/ios-simulator-skill/scripts/common/screenshot_utils.py +338 -0
  133. package/skills/ios-simulator-skill/scripts/container.py +668 -0
  134. package/skills/ios-simulator-skill/scripts/gesture.py +394 -0
  135. package/skills/ios-simulator-skill/scripts/hang_watcher.py +1533 -0
  136. package/skills/ios-simulator-skill/scripts/keyboard.py +391 -0
  137. package/skills/ios-simulator-skill/scripts/localization_audit.py +483 -0
  138. package/skills/ios-simulator-skill/scripts/location.py +467 -0
  139. package/skills/ios-simulator-skill/scripts/log_monitor.py +493 -0
  140. package/skills/ios-simulator-skill/scripts/model_inspector.py +645 -0
  141. package/skills/ios-simulator-skill/scripts/navigator.py +461 -0
  142. package/skills/ios-simulator-skill/scripts/privacy_manager.py +310 -0
  143. package/skills/ios-simulator-skill/scripts/push_notification.py +240 -0
  144. package/skills/ios-simulator-skill/scripts/screen_mapper.py +296 -0
  145. package/skills/ios-simulator-skill/scripts/sim_health_check.sh +245 -0
  146. package/skills/ios-simulator-skill/scripts/sim_list.py +299 -0
  147. package/skills/ios-simulator-skill/scripts/simctl_boot.py +312 -0
  148. package/skills/ios-simulator-skill/scripts/simctl_create.py +316 -0
  149. package/skills/ios-simulator-skill/scripts/simctl_delete.py +357 -0
  150. package/skills/ios-simulator-skill/scripts/simctl_erase.py +351 -0
  151. package/skills/ios-simulator-skill/scripts/simctl_shutdown.py +290 -0
  152. package/skills/ios-simulator-skill/scripts/simulator_selector.py +375 -0
  153. package/skills/ios-simulator-skill/scripts/status_bar.py +250 -0
  154. package/skills/ios-simulator-skill/scripts/test_recorder.py +323 -0
  155. package/skills/ios-simulator-skill/scripts/visual_diff.py +235 -0
  156. package/skills/ios-simulator-skill/scripts/xcode/__init__.py +13 -0
  157. package/skills/ios-simulator-skill/scripts/xcode/builder.py +397 -0
  158. package/skills/ios-simulator-skill/scripts/xcode/cache.py +204 -0
  159. package/skills/ios-simulator-skill/scripts/xcode/config.py +178 -0
  160. package/skills/ios-simulator-skill/scripts/xcode/reporter.py +343 -0
  161. package/skills/ios-simulator-skill/scripts/xcode/xcresult.py +451 -0
  162. package/skills/ios-visual-qa-strategist/SKILL.md +111 -0
  163. package/skills/ios-visual-qa-strategist/agents/openai.yaml +4 -0
  164. package/skills/ios-visual-qa-strategist/references/ios-tool-selection.md +61 -0
  165. package/skills/ios-visual-qa-strategist/references/minimal-capture-policy.md +56 -0
  166. package/skills/ios-visual-qa-strategist/references/visual-reasoning-heuristics.md +53 -0
  167. package/skills/orchestrator/SKILL.md +0 -20
  168. package/skills/persistent-storage/SKILL.md +55 -0
  169. package/skills/short-maker/SKILL.md +23 -0
  170. package/skills/short-maker/scripts/effects.js +56 -0
  171. package/skills/short-maker/scripts/shortmaker-bridge.js +332 -0
  172. package/skills/short-maker/scripts/videomix.js +601 -0
  173. package/skills/short-maker/templates/hyperframes/cinematic-character.template.html +172 -0
  174. package/skills/short-maker/templates/hyperframes/index.template.html +194 -0
  175. package/skills/smali-to-kotlin/SKILL.md +128 -0
  176. package/skills/smali-to-kotlin/examples/getting-started/tech-stack.md +58 -0
  177. package/skills/smali-to-kotlin/examples/pipeline/data-ui-parity.md +118 -0
  178. package/skills/smali-to-kotlin/examples/pipeline/scanner-and-bootstrap.md +106 -0
  179. package/skills/smali-to-kotlin/library-patterns.md +189 -0
  180. package/skills/smali-to-kotlin/phase-0-discovery.md +128 -0
  181. package/skills/smali-to-kotlin/phase-1-architecture.md +166 -0
  182. package/skills/smali-to-kotlin/phase-2-blueprint-ui.md +347 -0
  183. package/skills/smali-to-kotlin/phase-2-blueprint.md +228 -0
  184. package/skills/smali-to-kotlin/phase-3-build.md +248 -0
  185. package/skills/smali-to-kotlin/phase-3-logic-build.md +268 -0
  186. package/skills/smali-to-kotlin/smali-reading-guide.md +310 -0
  187. package/skills/smali-to-kotlin/templates/app-map.md +101 -0
  188. package/skills/smali-to-kotlin/templates/architecture.md +142 -0
  189. package/skills/smali-to-kotlin/templates/blueprint.md +145 -0
  190. package/skills/spec-gate/SKILL.md +6 -2
  191. package/skills/symphony-enforcer/SKILL.md +8 -0
  192. package/skills/symphony-enforcer/examples/mindful-stop.md +2 -0
  193. package/skills/symphony-enforcer/examples/three-phase.md +16 -0
  194. package/skills/symphony-enforcer/examples/trigger-points.md +7 -1
  195. package/skills/unity-game-development/SKILL.md +231 -0
  196. package/skills/verification-gate/SKILL.md +4 -2
  197. package/skills/video-edit/SKILL.md +36 -0
  198. package/skills/video-edit/scripts/video_edit.py +324 -0
  199. package/templates/setup-mapping.json +48 -0
  200. package/templates/specs/design-template.md +161 -71
  201. package/templates/specs/requirements-template.md +65 -133
  202. package/templates/specs/task-spec-template.xml +3 -0
  203. package/workflows/_uncategorized/critic.md +40 -0
  204. package/workflows/_uncategorized/git-rebase-flow.md +81 -0
  205. package/workflows/_uncategorized/image-gen.md +118 -0
  206. package/workflows/_uncategorized/multi-model-pipeline.md +60 -0
  207. package/workflows/_uncategorized/pixel-gen.md +86 -0
  208. package/workflows/_uncategorized/pixel-setup.md +90 -0
  209. package/workflows/_uncategorized/ponytail-review.md +59 -0
  210. package/workflows/_uncategorized/reverse-android-build.md +222 -0
  211. package/workflows/_uncategorized/reverse-android-design.md +139 -0
  212. package/workflows/_uncategorized/reverse-android-discover.md +150 -0
  213. package/workflows/_uncategorized/reverse-android-scan.md +158 -0
  214. package/workflows/_uncategorized/reverse-android.md +143 -0
  215. package/workflows/_uncategorized/reverse-ios-build.md +240 -0
  216. package/workflows/_uncategorized/reverse-ios-design.md +112 -0
  217. package/workflows/_uncategorized/reverse-ios-discover.md +120 -0
  218. package/workflows/_uncategorized/reverse-ios-scan.md +155 -0
  219. package/workflows/_uncategorized/reverse-ios.md +152 -0
  220. package/workflows/_uncategorized/safety-router.md +34 -0
  221. package/workflows/_uncategorized/teach.md +89 -0
  222. package/workflows/_uncategorized/verify-ui.md +53 -0
  223. package/workflows/_uncategorized/visualize-screenshots.md +34 -0
  224. package/workflows/ads/ads-analyst.md +201 -0
  225. package/workflows/ads/ads-audit.md +106 -0
  226. package/workflows/ads/ads-optimize.md +97 -0
  227. package/workflows/ads/ads-targeting.md +241 -0
  228. package/workflows/ads/adsExpert.md +160 -0
  229. package/workflows/ads/smali-ads-config.md +400 -0
  230. package/workflows/ads/smali-ads-flow.md +331 -0
  231. package/workflows/ads/smali-ads-interstitial.md +377 -0
  232. package/workflows/ads/smali-ads-native.md +382 -0
  233. package/workflows/context/teach.md +89 -0
  234. package/workflows/gitnexus.md +8 -8
  235. package/workflows/lifecycle/brainstorm.md +43 -0
  236. package/workflows/lifecycle/code.md +5 -0
  237. package/workflows/lifecycle/init.md +23 -5
  238. package/workflows/lifecycle/multi-model-pipeline.md +60 -0
  239. package/workflows/quality/ponytail-review.md +59 -0
  240. package/workflows/roles/critic.md +40 -0
  241. package/workflows/roles/safety-router.md +34 -0
package/bin/awk.js CHANGED
@@ -19,6 +19,7 @@
19
19
  * awkit list-packs List available skill packs
20
20
  * awkit tg setup Setup Telegram Bot API credentials
21
21
  * awkit tg send Send a message via Telegram Bot API
22
+ * awkit build Run project build command securely based on configuration
22
23
  * awkit version Show current version
23
24
  *
24
25
  * Created by Kien AI
@@ -43,6 +44,11 @@ const { cmdGate } = require('../scripts/automation-gate');
43
44
  const { cmdObsidian } = require('../scripts/obsidian-sync');
44
45
  const { cmdQuota } = require('../scripts/cockpit-quota');
45
46
  const { cmdVideo } = require('../scripts/video-analyzer');
47
+ const { cmdI18n } = require('../scripts/i18n-helper');
48
+ const { cmdStorage } = require('../scripts/artifact-storage');
49
+ const { cmdPipeline } = require('../scripts/multi-model-pipeline');
50
+ const depManager = require('../scripts/dependency-manager');
51
+
46
52
 
47
53
  // ─── Platform Definitions ──────────────────────────────────────────────────
48
54
 
@@ -368,7 +374,7 @@ function copyDirRecursive(src, dest, options = {}) {
368
374
  const entries = fs.readdirSync(src, { withFileTypes: true });
369
375
 
370
376
  for (const entry of entries) {
371
- if (entry.name === '.DS_Store') continue;
377
+ if (entry.name === '.DS_Store' || entry.name === '.git' || entry.name === '.venv' || entry.name === 'node_modules') continue;
372
378
 
373
379
  const srcPath = path.join(src, entry.name);
374
380
 
@@ -898,14 +904,19 @@ function cmdUpdate() {
898
904
  log(`${C.gray} local repo: v${AWK_VERSION}${C.reset}`);
899
905
  log('');
900
906
 
901
- // 3. Already up-to-date?
902
- if (npmLatest && npmLatest === installedVersion) {
903
- ok(`Already on the latest version (v${installedVersion}) 🎉`);
904
- return;
907
+ // 3. Already up-to-date or newer?
908
+ if (npmLatest) {
909
+ if (npmLatest === installedVersion) {
910
+ ok(`Already on the latest version (v${installedVersion}) 🎉`);
911
+ return;
912
+ } else if (isNewerVersion(installedVersion, npmLatest)) {
913
+ ok(`Your installed version (v${installedVersion}) is newer than the npm registry version (v${npmLatest}) 🎉`);
914
+ return;
915
+ }
905
916
  }
906
917
 
907
918
  // 4. New version available on npm → install from registry
908
- if (npmLatest && npmLatest !== installedVersion) {
919
+ if (npmLatest && isNewerVersion(npmLatest, installedVersion)) {
909
920
  info(`Upgrading: v${installedVersion} → v${npmLatest}`);
910
921
  info('Running: npm install -g @leejungkiin/awkit');
911
922
  try {
@@ -924,13 +935,15 @@ function cmdUpdate() {
924
935
  // 5. Offline fallback: compare AWK_VERSION (local repo) vs installed
925
936
  if (installedVersion === AWK_VERSION) {
926
937
  ok(`Already on latest version (v${AWK_VERSION}) — could not verify with npm`);
927
- } else {
938
+ } else if (isNewerVersion(AWK_VERSION, installedVersion)) {
928
939
  info(`Upgrading from v${installedVersion} → v${AWK_VERSION} (local only, npm unreachable)`);
929
940
  cmdInstall(['--update']);
941
+ } else {
942
+ ok(`Your installed version (v${installedVersion}) is newer than or equal to local repo version (v${AWK_VERSION})`);
930
943
  }
931
944
  }
932
945
 
933
- function cmdDoctor() {
946
+ async function cmdDoctor() {
934
947
  log('');
935
948
  log(`${C.cyan}${C.bold}🏥 AWK Health Check${C.reset}`);
936
949
  log('');
@@ -998,16 +1011,27 @@ function cmdDoctor() {
998
1011
  warn('schemas/ directory missing'); issues++;
999
1012
  }
1000
1013
 
1001
- // 4.5. Check RTK Integration
1002
- try {
1003
- const { checkRtk } = require('../scripts/exec-rtk');
1004
- if (checkRtk()) {
1005
- ok('RTK (Rust Token Killer) is installed and active');
1014
+ // 4.5. Check RTK & GitNexus Integration
1015
+ if (depManager.checkRtk()) {
1016
+ ok(`RTK (Rust Token Killer) is installed (v${depManager.getRtkVersion() || 'unknown'})`);
1017
+ } else {
1018
+ warn('RTK (Rust Token Killer) not found.');
1019
+ if (promptYN('Would you like to install RTK automatically now?')) {
1020
+ depManager.installRtk();
1006
1021
  } else {
1007
- warn('RTK (Rust Token Killer) not found. Run "awkit rtk setup" to optimize token usage.');
1022
+ issues++;
1023
+ }
1024
+ }
1025
+
1026
+ if (depManager.checkGitnexus()) {
1027
+ ok('GitNexus (Code Intelligence Indexer) is installed and active');
1028
+ } else {
1029
+ warn('GitNexus (Code Intelligence Indexer) not found.');
1030
+ if (promptYN('Would you like to install GitNexus globally now?')) {
1031
+ depManager.installGitnexus();
1032
+ } else {
1033
+ issues++;
1008
1034
  }
1009
- } catch (e) {
1010
- warn(`RTK check failed: ${e.message}`);
1011
1035
  }
1012
1036
 
1013
1037
  // 5. Check version
@@ -1021,6 +1045,25 @@ function cmdDoctor() {
1021
1045
  warn('Version file missing. Run "awkit install" first.'); issues++;
1022
1046
  }
1023
1047
 
1048
+ // 5.5. Check Updates
1049
+ try {
1050
+ const updates = await depManager.checkUpdates(AWK_VERSION);
1051
+ if (updates.latestAwkit && isNewerVersion(updates.latestAwkit, AWK_VERSION)) {
1052
+ warn(`AWKit update available: v${updates.latestAwkit} (current: v${AWK_VERSION})`);
1053
+ } else {
1054
+ ok('AWKit is up-to-date');
1055
+ }
1056
+
1057
+ const currentRtk = depManager.getRtkVersion();
1058
+ if (updates.latestRtk && currentRtk && isNewerVersion(updates.latestRtk, currentRtk)) {
1059
+ warn(`RTK update available: v${updates.latestRtk} (current: v${currentRtk})`);
1060
+ } else if (currentRtk) {
1061
+ ok('RTK is up-to-date');
1062
+ }
1063
+ } catch (e) {
1064
+ warn(`Update check failed: ${e.message}`);
1065
+ }
1066
+
1024
1067
  log('');
1025
1068
  log(`${C.bold}Runtime Profile:${C.reset}`);
1026
1069
  log(` Profile: ${C.cyan}${installState.profile}${C.reset}`);
@@ -1710,15 +1753,19 @@ function cmdListPacks() {
1710
1753
  }
1711
1754
 
1712
1755
  for (const pack of packs) {
1713
- const readmePath = path.join(packsDir, pack.name, 'README.md');
1714
1756
  const configPath = path.join(packsDir, pack.name, 'pack.json');
1757
+ const config = fs.existsSync(configPath) ? readJsonFile(configPath, {}) : {};
1758
+ if (config.hidden === true) {
1759
+ continue;
1760
+ }
1761
+
1762
+ const readmePath = path.join(packsDir, pack.name, 'README.md');
1715
1763
  let desc = '';
1716
1764
  if (fs.existsSync(readmePath)) {
1717
1765
  const content = fs.readFileSync(readmePath, 'utf8');
1718
1766
  desc = content.split('\n').find(l => l.trim() && !l.startsWith('#')) || '';
1719
1767
  }
1720
- if (!desc && fs.existsSync(configPath)) {
1721
- const config = readJsonFile(configPath, {});
1768
+ if (!desc) {
1722
1769
  desc = config.description || '';
1723
1770
  }
1724
1771
  log(` ${C.green}${pack.name}${C.reset} ${C.gray}${desc}${C.reset}`);
@@ -1938,6 +1985,47 @@ function cmdSync() {
1938
1985
  log('');
1939
1986
  }
1940
1987
 
1988
+ // ─── Build: Safe project-specific compilation ────────────────────────────────
1989
+
1990
+ function cmdBuild() {
1991
+ log('');
1992
+ log(`${C.cyan}${C.bold}🔨 AWK Build Control${C.reset}`);
1993
+ log('');
1994
+
1995
+ const pjPath = path.join(process.cwd(), '.project-identity');
1996
+ const pj = readJsonFile(pjPath, {});
1997
+
1998
+ if (!pj.automation || !pj.automation.build) {
1999
+ warn('No build configuration found in .project-identity under "automation.build".');
2000
+ log('Skipping build...');
2001
+ return;
2002
+ }
2003
+
2004
+ const { enabled, command } = pj.automation.build;
2005
+
2006
+ if (!enabled) {
2007
+ warn('Build is disabled for this project (automation.build.enabled is false).');
2008
+ log('Skipping build...');
2009
+ return;
2010
+ }
2011
+
2012
+ if (!command) {
2013
+ err('Build command is not configured in .project-identity (automation.build.command is empty).');
2014
+ return;
2015
+ }
2016
+
2017
+ info(`Running build command: ${C.bold}${command}${C.reset}`);
2018
+ try {
2019
+ execSync(command, { stdio: 'inherit' });
2020
+ log('');
2021
+ ok('Build successful!');
2022
+ } catch (e) {
2023
+ log('');
2024
+ err(`Build failed: ${e.message}`);
2025
+ process.exit(1);
2026
+ }
2027
+ }
2028
+
1941
2029
  async function cmdAdmin() {
1942
2030
  info('Mở Symphony Dashboard...');
1943
2031
  try {
@@ -2035,6 +2123,29 @@ function cmdHelp() {
2035
2123
  log(`${C.cyan}${C.bold}╚═══════════════════════════════════════════════════════╝${C.reset}`);
2036
2124
  log('');
2037
2125
 
2126
+ // Project Context Detector
2127
+ const cwd = process.cwd();
2128
+ const identityPath = path.join(cwd, '.project-identity');
2129
+ if (fs.existsSync(identityPath)) {
2130
+ try {
2131
+ const raw = fs.readFileSync(identityPath, 'utf8');
2132
+ const identity = JSON.parse(raw);
2133
+ const icon = identity.icon || '⚡';
2134
+ const name = identity.projectName || 'Unnamed Project';
2135
+ const pType = identity.projectType ? `Type: ${identity.projectType}` : 'Type: Generic';
2136
+
2137
+ let bCmd = 'Disabled';
2138
+ if (identity.automation && identity.automation.build && identity.automation.build.enabled) {
2139
+ bCmd = identity.automation.build.command || 'Enabled';
2140
+ }
2141
+
2142
+ log(`${C.cyan}👉 Active Project: ${icon} ${C.bold}${name}${C.reset}`);
2143
+ log(` [${pType} | Build Control: ${bCmd === 'Disabled' ? C.yellow + 'Manual' : C.green + bCmd}${C.reset}]`);
2144
+ log(` Run ${C.green}awkit identity${C.reset} for full configuration details.`);
2145
+ log('');
2146
+ } catch (_) {}
2147
+ }
2148
+
2038
2149
  // Install
2039
2150
  log(`${C.bold}⚙️ Setup${C.reset}`);
2040
2151
  log(line);
@@ -2056,6 +2167,8 @@ function cmdHelp() {
2056
2167
  log(` ${C.gray} --force${C.reset} Overwrite existing files`);
2057
2168
  log(` ${C.gray} Generates: .project-identity, <Name>.code-workspace,${C.reset}`);
2058
2169
  log(` ${C.gray} CODEBASE.md, thiết lập router (AGENTS.md, CLAUDE.md)${C.reset}`);
2170
+ log(` ${C.green}identity${C.reset} Show project identity & active configurations (alias: config)`);
2171
+ log(` ${C.green}build${C.reset} Run project build based on .project-identity config`);
2059
2172
  log('');
2060
2173
 
2061
2174
  // Maintenance
@@ -2098,6 +2211,24 @@ function cmdHelp() {
2098
2211
  log(` ${C.green}disable-pack${C.reset} <name> Uninstall a skill pack (backed up)`);
2099
2212
  log('');
2100
2213
 
2214
+ // Storage
2215
+ log(`${C.bold}🗄️ Storage${C.reset}`);
2216
+ log(line);
2217
+ log(` ${C.green}storage set${C.reset} <key> <val> Save key-value pair`);
2218
+ log(` ${C.green}storage get${C.reset} <key> Retrieve value by key`);
2219
+ log(` ${C.green}storage delete${C.reset} <key> Delete key`);
2220
+ log(` ${C.green}storage list${C.reset} [prefix] List keys with optional prefix`);
2221
+ log(` ${C.gray} --shared Access shared storage space${C.reset}`);
2222
+ log('');
2223
+
2224
+ // Pipeline
2225
+ log(`${C.bold}🔗 Pipeline${C.reset}`);
2226
+ log(line);
2227
+ log(` ${C.green}pipeline plan${C.reset} <Feature> Lập kế hoạch kiến trúc (Opus 4.6 via agy)`);
2228
+ log(` ${C.green}pipeline ui${C.reset} <Feature> Thiết kế shell & GUI assets (Codex)`);
2229
+ log(` ${C.green}pipeline code${C.reset} <Feature> Thực thi viết code & review (Gemini + Critic)`);
2230
+ log('');
2231
+
2101
2232
  // Trello
2102
2233
  log(`${C.bold}📋 Trello${C.reset}`);
2103
2234
  log(line);
@@ -2139,6 +2270,11 @@ function cmdHelp() {
2139
2270
  if (packs.length) {
2140
2271
  log(` Available packs:`);
2141
2272
  for (const p of packs) {
2273
+ const configPath = path.join(packsDir, p.name, 'pack.json');
2274
+ const config = fs.existsSync(configPath) ? readJsonFile(configPath, {}) : {};
2275
+ if (config.hidden === true) {
2276
+ continue;
2277
+ }
2142
2278
  const readmePath = path.join(packsDir, p.name, 'README.md');
2143
2279
  let tagline = '';
2144
2280
  if (fs.existsSync(readmePath)) {
@@ -2212,10 +2348,55 @@ function detectProjectType(cwd) {
2212
2348
  if (entries.includes('pubspec.yaml')) {
2213
2349
  return 'flutter';
2214
2350
  }
2351
+
2352
+ // JS/Node project check
2353
+ if (entries.includes('package.json')) {
2354
+ try {
2355
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
2356
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
2357
+ if (pkg.bin) {
2358
+ return 'cli';
2359
+ }
2360
+ if (deps['next']) {
2361
+ return 'web-nextjs';
2362
+ }
2363
+ if (deps['@nestjs/core']) {
2364
+ return 'backend-nestjs';
2365
+ }
2366
+ return 'node';
2367
+ } catch (_) { /* continue */ }
2368
+ }
2369
+
2215
2370
  // Default: generic mobile-firebase
2216
2371
  return 'mobile-firebase';
2217
2372
  }
2218
2373
 
2374
+ /**
2375
+ * Get the default safe build command based on projectType.
2376
+ */
2377
+ function getDefaultBuildCommand(projectType) {
2378
+ switch (projectType) {
2379
+ case 'ios':
2380
+ return 'xcodebuild -scheme YourScheme -sdk iphonesimulator -configuration Debug';
2381
+ case 'android':
2382
+ return './gradlew assembleDebug';
2383
+ case 'expo':
2384
+ return 'npx expo prebuild';
2385
+ case 'flutter':
2386
+ return 'flutter build apk --debug';
2387
+ case 'web-nextjs':
2388
+ return 'npm run build';
2389
+ case 'backend-nestjs':
2390
+ return 'npm run build';
2391
+ case 'cli':
2392
+ case 'node':
2393
+ return 'npm test';
2394
+ case 'mobile-firebase':
2395
+ default:
2396
+ return 'npm run build';
2397
+ }
2398
+ }
2399
+
2219
2400
  /**
2220
2401
  * Build .project-identity object from detected type + project name.
2221
2402
  */
@@ -2326,6 +2507,70 @@ function buildProjectIdentity(projectName, projectType, cwd, date) {
2326
2507
  servicesDir: 'lib/shared/services',
2327
2508
  modelsDir: 'lib/shared/models',
2328
2509
  },
2510
+ cli: {
2511
+ projectType: 'cli',
2512
+ techStack: {
2513
+ platform: 'CLI',
2514
+ language: 'JavaScript / TypeScript',
2515
+ runtime: 'Node.js',
2516
+ framework: 'Vanilla NodeJS',
2517
+ testing: 'Jest / doctor',
2518
+ },
2519
+ codingStandards: { language: 'en', namingConvention: 'camelCase', indentation: 'spaces-4', lineLength: 120 },
2520
+ architecture: 'Modular',
2521
+ featuresDir: 'src/commands',
2522
+ sharedUIDir: 'src/ui',
2523
+ servicesDir: 'src/services',
2524
+ modelsDir: 'src/models',
2525
+ },
2526
+ node: {
2527
+ projectType: 'node',
2528
+ techStack: {
2529
+ platform: 'NodeJS Backend/App',
2530
+ language: 'JavaScript / TypeScript',
2531
+ runtime: 'Node.js',
2532
+ testing: 'Jest',
2533
+ },
2534
+ codingStandards: { language: 'en', namingConvention: 'camelCase', indentation: 'spaces-4', lineLength: 120 },
2535
+ architecture: 'Modular',
2536
+ featuresDir: 'src/features',
2537
+ sharedUIDir: 'src/views',
2538
+ servicesDir: 'src/services',
2539
+ modelsDir: 'src/models',
2540
+ },
2541
+ 'web-nextjs': {
2542
+ projectType: 'web-nextjs',
2543
+ techStack: {
2544
+ platform: 'Web',
2545
+ language: 'TypeScript / JavaScript',
2546
+ framework: 'Next.js',
2547
+ styling: 'Tailwind CSS / CSS Modules',
2548
+ stateManagement: 'Zustand / Redux Toolkit / React Context',
2549
+ networking: 'Axios / Fetch',
2550
+ },
2551
+ codingStandards: { language: 'en', namingConvention: 'camelCase', indentation: 'spaces-2', lineLength: 100 },
2552
+ architecture: 'App Router / Pages Router',
2553
+ featuresDir: 'src/app',
2554
+ sharedUIDir: 'src/components',
2555
+ servicesDir: 'src/services',
2556
+ modelsDir: 'src/models',
2557
+ },
2558
+ 'backend-nestjs': {
2559
+ projectType: 'backend-nestjs',
2560
+ techStack: {
2561
+ platform: 'Backend',
2562
+ language: 'TypeScript',
2563
+ framework: 'NestJS',
2564
+ database: 'PostgreSQL / MySQL / MongoDB',
2565
+ orm: 'Prisma / TypeORM / Mongoose',
2566
+ },
2567
+ codingStandards: { language: 'en', namingConvention: 'camelCase', indentation: 'spaces-2', lineLength: 100 },
2568
+ architecture: 'Controller-Service-Repository',
2569
+ featuresDir: 'src/modules',
2570
+ sharedUIDir: 'src/common',
2571
+ servicesDir: 'src/services',
2572
+ modelsDir: 'src/models',
2573
+ },
2329
2574
  };
2330
2575
 
2331
2576
  // Fallback: generic mobile-firebase
@@ -2394,6 +2639,10 @@ function buildProjectIdentity(projectName, projectType, cwd, date) {
2394
2639
  "pixel-mcp": {
2395
2640
  enabled: false
2396
2641
  }
2642
+ },
2643
+ build: {
2644
+ enabled: false,
2645
+ command: getDefaultBuildCommand(projectType)
2397
2646
  }
2398
2647
  },
2399
2648
  modelPolicy: {
@@ -2637,6 +2886,10 @@ async function cmdInit(forceFlag = false) {
2637
2886
  "pixel-mcp": {
2638
2887
  enabled: false
2639
2888
  }
2889
+ },
2890
+ build: {
2891
+ enabled: false,
2892
+ command: getDefaultBuildCommand(projectType)
2640
2893
  }
2641
2894
  };
2642
2895
  fs.writeFileSync(identityPath, JSON.stringify(currentIdentity, null, 2) + '\n');
@@ -2657,6 +2910,18 @@ async function cmdInit(forceFlag = false) {
2657
2910
  currentIdentity.automation.mcp = { "pixel-mcp": { enabled: false } };
2658
2911
  changed = true;
2659
2912
  }
2913
+ if (!currentIdentity.projectType) {
2914
+ currentIdentity.projectType = projectType;
2915
+ changed = true;
2916
+ }
2917
+ if (!currentIdentity.automation.build) {
2918
+ const detectedType = currentIdentity.projectType || projectType || 'mobile-firebase';
2919
+ currentIdentity.automation.build = {
2920
+ enabled: false,
2921
+ command: getDefaultBuildCommand(detectedType)
2922
+ };
2923
+ changed = true;
2924
+ }
2660
2925
  if (!currentIdentity.modelPolicy) {
2661
2926
  currentIdentity.modelPolicy = {
2662
2927
  mode: "auto",
@@ -2841,17 +3106,20 @@ Additional project context can be found in:
2841
3106
  ).trim();
2842
3107
 
2843
3108
  if (hasSource) {
2844
- execSync('npx -y gitnexus analyze', {
3109
+ const usePnpm = fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'));
3110
+ const indexCmd = usePnpm ? 'pnpm dlx gitnexus analyze' : 'npx -y gitnexus analyze';
3111
+ info(`Running index with: ${indexCmd}...`);
3112
+ execSync(indexCmd, {
2845
3113
  cwd,
2846
3114
  stdio: 'ignore',
2847
3115
  });
2848
3116
  ok('GitNexus index created (.gitnexus/)');
2849
3117
  } else {
2850
- dim('No source files found — skipping GitNexus index (run later: npx gitnexus analyze)');
3118
+ dim('No source files found — skipping GitNexus index (run later: pnpm dlx gitnexus analyze or npx gitnexus analyze)');
2851
3119
  }
2852
3120
  } catch (e) {
2853
3121
  warn(`GitNexus indexing failed: ${e.message}`);
2854
- dim('Run manually later: npx gitnexus analyze');
3122
+ dim('Run manually later: pnpm dlx gitnexus analyze or npx gitnexus analyze');
2855
3123
  }
2856
3124
 
2857
3125
  // ── 6. Summary ─────────────────────────────────────────────────────────────
@@ -2866,9 +3134,10 @@ Additional project context can be found in:
2866
3134
  dim(`GitNexus: code intelligence index`);
2867
3135
  log('');
2868
3136
  log(`${C.cyan}👉 Open ${workspaceName} in VS Code to get started.${C.reset}`);
3137
+ log(`${C.cyan}👉 Run '/init' in AI chat to activate Smart Ecosystem Setup (SAEE) & recommendations.${C.reset}`);
2869
3138
  log(`${C.cyan}👉 Run '/codebase-sync' in AI chat to keep CODEBASE.md updated.${C.reset}`);
2870
3139
  log(`${C.cyan}👉 Run 'symphony task list' to manage tasks.${C.reset}`);
2871
- log(`${C.cyan}👉 Run 'npx gitnexus analyze' after major changes to refresh index.${C.reset}`);
3140
+ log(`${C.cyan}👉 Run 'pnpm dlx gitnexus analyze' (or 'npx gitnexus analyze') after major changes to refresh index.${C.reset}`);
2872
3141
  log('');
2873
3142
 
2874
3143
  // ── 7. Open Documentation ───────────────────────────────────────────────────
@@ -3520,41 +3789,90 @@ function cmdTrello(args) {
3520
3789
  }
3521
3790
  }
3522
3791
 
3523
- // ─── Auto-Update Checker ──────────────────────────────────────────────────────
3524
-
3525
- function checkAutoUpdate() {
3526
- const checkFile = path.join(TARGETS.antigravity, '.awk_update_check');
3527
- const now = Date.now();
3528
- const ONEDAY = 24 * 60 * 60 * 1000;
3792
+ /**
3793
+ * Helper to check if semantic version `latest` is newer than `current`.
3794
+ */
3795
+ function isNewerVersion(latest, current) {
3796
+ if (!latest || !current) return false;
3797
+ const clean = v => v.replace(/^v/, '');
3798
+ const lClean = clean(latest);
3799
+ const cClean = clean(current);
3800
+ if (lClean === cClean) return false;
3801
+
3802
+ const parse = v => {
3803
+ const parts = v.split('-');
3804
+ const numbers = parts[0].split('.').map(Number);
3805
+ const prerelease = parts[1] ? parts[1].split('.') : [];
3806
+ return { numbers, prerelease };
3807
+ };
3529
3808
 
3530
- if (fs.existsSync(checkFile)) {
3531
- try {
3532
- const lastCheck = parseInt(fs.readFileSync(checkFile, 'utf8'), 10);
3533
- if (!isNaN(lastCheck) && (now - lastCheck < ONEDAY)) {
3534
- return; // already checked recently
3535
- }
3536
- } catch (_) { }
3809
+ const l = parse(lClean);
3810
+ const c = parse(cClean);
3811
+
3812
+ // Compare main version numbers
3813
+ for (let i = 0; i < 3; i++) {
3814
+ const ln = l.numbers[i] || 0;
3815
+ const cn = c.numbers[i] || 0;
3816
+ if (ln > cn) return true;
3817
+ if (ln < cn) return false;
3818
+ }
3819
+
3820
+ const lIsPrerelease = l.prerelease.length > 0;
3821
+ const cIsPrerelease = c.prerelease.length > 0;
3822
+
3823
+ if (lIsPrerelease && !cIsPrerelease) return false;
3824
+ if (!lIsPrerelease && cIsPrerelease) return true;
3825
+
3826
+ const maxLength = Math.max(l.prerelease.length, c.prerelease.length);
3827
+ for (let i = 0; i < maxLength; i++) {
3828
+ const lp = l.prerelease[i];
3829
+ const cp = c.prerelease[i];
3830
+ if (lp === undefined) return false;
3831
+ if (cp === undefined) return true;
3832
+ const lpNum = parseInt(lp, 10);
3833
+ const cpNum = parseInt(cp, 10);
3834
+ const lpIsNum = !isNaN(lpNum);
3835
+ const cpIsNum = !isNaN(cpNum);
3836
+ if (lpIsNum && cpIsNum) {
3837
+ if (lpNum > cpNum) return true;
3838
+ if (lpNum < cpNum) return false;
3839
+ } else if (lpIsNum) {
3840
+ return false;
3841
+ } else if (cpIsNum) {
3842
+ return true;
3843
+ } else {
3844
+ if (lp > cp) return true;
3845
+ if (lp < cp) return false;
3846
+ }
3537
3847
  }
3848
+ return false;
3849
+ }
3538
3850
 
3539
- // Touch the file so we don't retry immediately on failure
3540
- try { fs.writeFileSync(checkFile, now.toString()); } catch (_) { }
3851
+ // ─── Auto-Update Checker ──────────────────────────────────────────────────────
3541
3852
 
3542
- // Check for update using npm registry
3853
+ async function checkAutoUpdate() {
3543
3854
  try {
3544
- const output = execSync('npm view @leejungkiin/awkit version', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 3000 });
3545
- const npmVersion = output.trim();
3546
-
3547
- // Simple string comparison for versions like "1.0.0" (Assumes SemVer)
3548
- if (npmVersion && npmVersion !== AWK_VERSION) {
3855
+ const updates = await depManager.checkUpdates(AWK_VERSION);
3856
+ if (updates.latestAwkit && isNewerVersion(updates.latestAwkit, AWK_VERSION)) {
3549
3857
  log('');
3550
- log(`${C.yellow}${C.bold}🌟 [Thông báo] Có phiên bản mới cho AWKit! (v${npmVersion})${C.reset}`);
3858
+ log(`${C.yellow}${C.bold}🌟 [Thông báo] Có phiên bản mới cho AWKit! (v${updates.latestAwkit})${C.reset}`);
3551
3859
  log(`${C.gray} Phiên bản hiện tại: v${AWK_VERSION}${C.reset}`);
3552
3860
  log(`${C.gray} Chạy lệnh sau để nâng cấp:${C.reset}`);
3553
3861
  log(`${C.cyan} npm i -g @leejungkiin/awkit && awkit install${C.reset}`);
3554
3862
  log('');
3555
3863
  }
3864
+
3865
+ const currentRtk = depManager.getRtkVersion();
3866
+ if (updates.latestRtk && currentRtk && isNewerVersion(updates.latestRtk, currentRtk)) {
3867
+ log('');
3868
+ log(`${C.yellow}${C.bold}🌟 [Thông báo] Có phiên bản mới cho RTK! (v${updates.latestRtk})${C.reset}`);
3869
+ log(`${C.gray} Phiên bản hiện tại: v${currentRtk}${C.reset}`);
3870
+ log(`${C.gray} Chạy lệnh sau để nâng cấp:${C.reset}`);
3871
+ log(`${C.cyan} awkit rtk setup${C.reset}`);
3872
+ log('');
3873
+ }
3556
3874
  } catch (_) {
3557
- // Fail silently (offline, npm not installed, package not published yet)
3875
+ // Fail silently in auto check
3558
3876
  }
3559
3877
  }
3560
3878
 
@@ -3585,7 +3903,7 @@ function cmdGitnexus(args) {
3585
3903
  const registry = readGitnexusRegistry();
3586
3904
  if (registry.length === 0) {
3587
3905
  info('No GitNexus indexed repositories found.');
3588
- dim('Run `npx gitnexus analyze` in a project to index it.');
3906
+ dim('Run `pnpm dlx gitnexus analyze` or `npx gitnexus analyze` in a project to index it.');
3589
3907
  return;
3590
3908
  }
3591
3909
 
@@ -3618,7 +3936,7 @@ function cmdGitnexus(args) {
3618
3936
 
3619
3937
  if (!match) {
3620
3938
  warn('Current directory is not indexed by GitNexus.');
3621
- dim('Run `npx gitnexus analyze` to index this project.');
3939
+ dim('Run `pnpm dlx gitnexus analyze` or `npx gitnexus analyze` to index this project.');
3622
3940
  return;
3623
3941
  }
3624
3942
 
@@ -3644,7 +3962,7 @@ function cmdGitnexus(args) {
3644
3962
  if (stale) {
3645
3963
  log('');
3646
3964
  warn(`Index is ${ageDays} days old. Consider refreshing:`);
3647
- dim(' npx gitnexus analyze');
3965
+ dim(' pnpm dlx gitnexus analyze (or npx gitnexus analyze)');
3648
3966
  }
3649
3967
 
3650
3968
  // Show projectId from .project-identity if available
@@ -3868,43 +4186,77 @@ async function cmdRtkSetup() {
3868
4186
  log(`${C.cyan}${C.bold}║ ⚙️ RTK Auto-Setup & Configuration ║${C.reset}`);
3869
4187
  log(`${C.cyan}${C.bold}╚═══════════════════════════════════════════════════════╝${C.reset}`);
3870
4188
 
3871
- log(`\nChecking dependencies...`);
3872
- try {
3873
- execSync('which cargo', { stdio: 'ignore' });
3874
- ok('Cargo is installed.');
3875
- } catch (_) {
3876
- err('Cargo/Rust not found. Please install Rust (https://rustup.rs/) and retry.');
3877
- return;
3878
- }
3879
-
3880
- log(`\nInstalling RTK (Rust Token Killer) via Cargo...`);
3881
- try {
3882
- execSync('cargo install --git https://github.com/rtk-ai/rtk', { stdio: 'inherit' });
3883
- ok('RTK successfully installed/updated via Cargo.');
3884
- } catch (e) {
3885
- err(`Failed to install RTK: ${e.message}`);
3886
- return;
3887
- }
4189
+ const installed = depManager.installRtk();
4190
+ if (!installed) return;
3888
4191
 
3889
4192
  const zshrcPath = path.join(HOME, '.zshrc');
3890
4193
  log(`\nConfiguring Shell Aliases in ~/.zshrc...`);
3891
4194
  if (fs.existsSync(zshrcPath)) {
3892
- const zshrc = fs.readFileSync(zshrcPath, 'utf8');
3893
- const aliasBlock = `
3894
- # RTK Alias for AI Agents (AWKit)
3895
- alias git="rtk git"
3896
- alias npm="rtk npm"
3897
- alias pnpm="rtk pnpm"
3898
- alias yarn="rtk yarn"
3899
- alias cargo="rtk cargo"
4195
+ let zshrc = fs.readFileSync(zshrcPath, 'utf8');
4196
+
4197
+ // Clean up old aliases to avoid collision
4198
+ const oldAliases = [
4199
+ 'alias git="rtk git"',
4200
+ 'alias npm="rtk npm"',
4201
+ 'alias pnpm="rtk pnpm"',
4202
+ 'alias yarn="rtk yarn"',
4203
+ 'alias cargo="rtk cargo"'
4204
+ ];
4205
+ for (const oldAlias of oldAliases) {
4206
+ if (zshrc.includes(oldAlias)) {
4207
+ zshrc = zshrc.replace(new RegExp(`\\n?${oldAlias}\\n?`, 'g'), '\n');
4208
+ }
4209
+ }
4210
+
4211
+ const functionBlock = `
4212
+ # RTK Integration for AI Agents (AWKit)
4213
+ unalias npm pnpm yarn cargo git 2>/dev/null
4214
+ npm() {
4215
+ if [[ "$1" == "login" || "$1" == "adduser" || "$1" == "publish" ]]; then
4216
+ command npm "$@"
4217
+ else
4218
+ rtk npm "$@"
4219
+ fi
4220
+ }
4221
+ pnpm() {
4222
+ if [[ "$1" == "login" || "$1" == "publish" ]]; then
4223
+ command pnpm "$@"
4224
+ else
4225
+ rtk pnpm "$@"
4226
+ fi
4227
+ }
4228
+ yarn() {
4229
+ if [[ "$1" == "login" || "$1" == "publish" ]]; then
4230
+ command yarn "$@"
4231
+ else
4232
+ rtk yarn "$@"
4233
+ fi
4234
+ }
4235
+ cargo() {
4236
+ if [[ "$1" == "login" || "$1" == "publish" ]]; then
4237
+ command cargo "$@"
4238
+ else
4239
+ rtk cargo "$@"
4240
+ fi
4241
+ }
4242
+ git() {
4243
+ if [[ "$1" == "rebase" ]]; then
4244
+ command git "$@"
4245
+ else
4246
+ rtk git "$@"
4247
+ fi
4248
+ }
3900
4249
  `;
3901
- if (zshrc.includes('alias git="rtk git"')) {
3902
- ok('Aliases already present in ~/.zshrc.');
3903
- } else {
3904
- fs.appendFileSync(zshrcPath, aliasBlock, 'utf8');
3905
- ok('Shell aliases successfully added to ~/.zshrc.');
3906
- log(`\n${C.cyan}Please reload your shell (source ~/.zshrc) to apply shifts.${C.reset}`);
4250
+ // Clean up old RTK integration block if exists to allow updating
4251
+ if (zshrc.includes('# RTK Integration for AI Agents (AWKit)')) {
4252
+ const startIdx = zshrc.indexOf('# RTK Integration for AI Agents (AWKit)');
4253
+ zshrc = zshrc.substring(0, startIdx);
3907
4254
  }
4255
+
4256
+ zshrc += functionBlock;
4257
+ fs.writeFileSync(zshrcPath, zshrc, 'utf8');
4258
+ ok('Shell wrappers successfully added/updated in ~/.zshrc.');
4259
+ log(`\n${C.cyan}Please reload your shell (source ~/.zshrc) to apply shifts.${C.reset}`);
3908
4260
  } else {
3909
4261
  warn('~/.zshrc not found. Skipping alias setup.');
3910
4262
  }
@@ -3920,6 +4272,130 @@ async function cmdRtk(args) {
3920
4272
  }
3921
4273
  }
3922
4274
 
4275
+ // ─── Project Identity CLI View ───────────────────────────────────────────────
4276
+
4277
+ function cmdIdentity(args = []) {
4278
+ const cwd = process.cwd();
4279
+ const identityPath = path.join(cwd, '.project-identity');
4280
+
4281
+ if (!fs.existsSync(identityPath)) {
4282
+ err('No .project-identity found in the current directory.');
4283
+ log(` Run ${C.cyan}awkit init${C.reset} to create one for this project.`);
4284
+ return;
4285
+ }
4286
+
4287
+ try {
4288
+ const raw = fs.readFileSync(identityPath, 'utf8');
4289
+ const identity = JSON.parse(raw);
4290
+
4291
+ // Handle specific field querying
4292
+ if (args.length > 0) {
4293
+ const query = args[0];
4294
+
4295
+ if (query === '--keys') {
4296
+ console.log(Object.keys(identity).join('\n'));
4297
+ return;
4298
+ }
4299
+
4300
+ if (query === '--json') {
4301
+ console.log(JSON.stringify(identity, null, 2));
4302
+ return;
4303
+ }
4304
+
4305
+ // Helper to get nested value by dot notation (e.g., automation.build.enabled)
4306
+ const getNested = (obj, path) => {
4307
+ return path.split('.').reduce((acc, part) => acc && acc[part], obj);
4308
+ };
4309
+
4310
+ const val = getNested(identity, query);
4311
+ if (val !== undefined) {
4312
+ if (typeof val === 'object') {
4313
+ console.log(JSON.stringify(val));
4314
+ } else {
4315
+ console.log(val);
4316
+ }
4317
+ }
4318
+ return; // Exit silently if undefined, ideal for bash scripts
4319
+ }
4320
+
4321
+ const border = `${C.cyan}${C.bold}╔═══════════════════════════════════════════════════════╗${C.reset}`;
4322
+ const bottom = `${C.cyan}${C.bold}╚═══════════════════════════════════════════════════════╝${C.reset}`;
4323
+ const line = `${C.gray}${'─'.repeat(56)}${C.reset}`;
4324
+
4325
+ log('');
4326
+ log(border);
4327
+ log(`${C.cyan}${C.bold}║ 🆔 PROJECT IDENTITY: ${C.green}${C.bold}${String(identity.projectName || 'Unnamed Project').padEnd(30)}${C.cyan}${C.bold} ║${C.reset}`);
4328
+ log(bottom);
4329
+ log('');
4330
+
4331
+ // Basic Info
4332
+ log(`${C.bold}ℹ️ Basic Information${C.reset}`);
4333
+ log(line);
4334
+ log(` ${C.bold}Project Stage:${C.reset} ${identity.projectStage || 'development'}`);
4335
+ log(` ${C.bold}Project Type:${C.reset} ${identity.projectType ? C.green + identity.projectType + C.reset : C.yellow + 'Not configured' + C.reset}`);
4336
+ log(` ${C.bold}Primary Lang:${C.reset} ${identity.primaryLanguage || 'en'}`);
4337
+ if (identity.techStack) {
4338
+ const rt = Array.isArray(identity.techStack.runtime) ? identity.techStack.runtime.join(', ') : 'N/A';
4339
+ const lang = Array.isArray(identity.techStack.languages) ? identity.techStack.languages.join(', ') : 'N/A';
4340
+ log(` ${C.bold}Runtime/Lang:${C.reset} ${rt} / ${lang}`);
4341
+ }
4342
+ log('');
4343
+
4344
+ // Build Configuration
4345
+ log(`${C.bold}🛠️ Build & Run Control${C.reset}`);
4346
+ log(line);
4347
+ if (identity.automation && identity.automation.build) {
4348
+ const b = identity.automation.build;
4349
+ const statusStr = b.enabled ? `${C.green}Enabled (Safe Auto-Run via awkit build)${C.reset}` : `${C.yellow}Disabled / Manual Only${C.reset}`;
4350
+ log(` ${C.bold}Build Control:${C.reset} ${statusStr}`);
4351
+ log(` ${C.bold}Build Command:${C.reset} ${C.cyan}${b.command || 'N/A'}${C.reset}`);
4352
+ } else {
4353
+ log(` ${C.bold}Build Control:${C.reset} ${C.yellow}Not Configured (Manual Mode)${C.reset}`);
4354
+ }
4355
+ log('');
4356
+
4357
+ // Automation Gates
4358
+ log(`${C.bold}🔒 Automation & Sync Gates${C.reset}`);
4359
+ log(line);
4360
+ if (identity.automation) {
4361
+ const git = identity.automation.git || {};
4362
+ log(` ${C.bold}Git AutoCommit:${C.reset} ${git.autoCommit ? C.green + 'true' : C.red + 'false'}${C.reset}`);
4363
+ log(` ${C.bold}Git AutoPush:${C.reset} ${git.autoPush ? C.green + 'true' : C.red + 'false'}${C.reset}`);
4364
+
4365
+ const trello = identity.automation.trello || {};
4366
+ const syncStr = trello.enabled
4367
+ ? `${C.green}Enabled${C.reset} (AutoSync: ${trello.autoSync ? C.green + 'true' : C.red + 'false'}${C.reset})`
4368
+ : `${C.red}Disabled${C.reset}`;
4369
+ log(` ${C.bold}Trello Sync:${C.reset} ${syncStr}`);
4370
+ if (identity.trello) {
4371
+ log(` ${C.bold}Trello Board:${C.reset} ${identity.trello.board || 'N/A'}`);
4372
+ log(` ${C.bold}Trello Card:${C.reset} ${identity.trello.card || 'N/A'}`);
4373
+ }
4374
+
4375
+ const tg = identity.automation.telegram || {};
4376
+ const tgStr = tg.enabled ? `${C.green}Enabled${C.reset}` : `${C.red}Disabled${C.reset}`;
4377
+ log(` ${C.bold}Telegram Alerts:${C.reset} ${tgStr}`);
4378
+ if (tg.triggers) {
4379
+ const trigs = Object.keys(tg.triggers).filter(k => tg.triggers[k]).join(', ');
4380
+ log(` ${C.bold}Alert Triggers:${C.reset} ${C.gray}${trigs || 'None'}${C.reset}`);
4381
+ }
4382
+ }
4383
+ log('');
4384
+
4385
+ // Caveman Mode
4386
+ if (identity.communication && identity.communication.cavemanMode) {
4387
+ const cm = identity.communication.cavemanMode;
4388
+ log(`${C.bold}💬 Communication Mode${C.reset}`);
4389
+ log(line);
4390
+ log(` ${C.bold}Caveman Mode:${C.reset} ${cm.enabled ? C.green + 'Enabled (' + cm.level + ')' : C.red + 'Disabled'}${C.reset}`);
4391
+ log('');
4392
+ }
4393
+
4394
+ } catch (e) {
4395
+ err(`Failed to parse .project-identity: ${e.message}`);
4396
+ }
4397
+ }
4398
+
3923
4399
  // ─── Native HTTP Server ───────────────────────────────────────────────────────
3924
4400
 
3925
4401
  function cmdServe(args) {
@@ -4014,13 +4490,14 @@ function cmdServe(args) {
4014
4490
 
4015
4491
  // ─── Main ────────────────────────────────────────────────────────────────────
4016
4492
 
4017
- // Check for updates (max once per day) before continuing
4018
- checkAutoUpdate();
4019
-
4020
4493
  const [, , command, ...args] = process.argv;
4021
4494
 
4022
4495
  (async () => {
4496
+ await checkAutoUpdate();
4023
4497
  switch (command) {
4498
+ case 'build':
4499
+ cmdBuild();
4500
+ break;
4024
4501
  case 'init':
4025
4502
  await cmdInit(args.includes('--force'));
4026
4503
  break;
@@ -4043,7 +4520,13 @@ const [, , command, ...args] = process.argv;
4043
4520
  cmdHarvest(args.includes('--dry-run'));
4044
4521
  break;
4045
4522
  case 'doctor':
4046
- cmdDoctor();
4523
+ await cmdDoctor();
4524
+ break;
4525
+ case 'storage':
4526
+ cmdStorage(args);
4527
+ break;
4528
+ case 'pipeline':
4529
+ cmdPipeline(args);
4047
4530
  break;
4048
4531
  case 'browser':
4049
4532
  cmdBrowser(args);
@@ -4094,6 +4577,10 @@ const [, , command, ...args] = process.argv;
4094
4577
  case 'rtk':
4095
4578
  await cmdRtk(args);
4096
4579
  break;
4580
+ case 'i18n':
4581
+ await cmdI18n(args);
4582
+ break;
4583
+
4097
4584
  case 'gitnexus':
4098
4585
  case 'gn':
4099
4586
  cmdGitnexus(args);
@@ -4116,6 +4603,11 @@ const [, , command, ...args] = process.argv;
4116
4603
  case 'restart':
4117
4604
  await cmdRestart();
4118
4605
  break;
4606
+ case 'identity':
4607
+ case 'config':
4608
+ case 'project':
4609
+ cmdIdentity(args);
4610
+ break;
4119
4611
  case 'help':
4120
4612
  case '--help':
4121
4613
  case '-h':