@fprad0/skill-master-mcp 0.0.8 → 0.0.10

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 (223) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +61 -8
  3. package/VERSION.md +3 -3
  4. package/bin/lib/menu-core.mjs +798 -7
  5. package/bin/skill-master-bootstrap-global.mjs +48 -0
  6. package/bin/skill-master-doctor.mjs +168 -0
  7. package/bin/skill-master-install-global-skills.mjs +97 -0
  8. package/bin/skill-master-menu.mjs +184 -36
  9. package/bin/skill-master-register-clients.mjs +177 -0
  10. package/dist/domain-router.d.ts +11 -0
  11. package/dist/domain-router.d.ts.map +1 -0
  12. package/dist/domain-router.js +79 -0
  13. package/dist/domain-router.js.map +1 -0
  14. package/dist/index.js +159 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/moral-governance.d.ts +24 -0
  17. package/dist/moral-governance.d.ts.map +1 -0
  18. package/dist/moral-governance.js +143 -0
  19. package/dist/moral-governance.js.map +1 -0
  20. package/dist/prompt-router.d.ts +4 -0
  21. package/dist/prompt-router.d.ts.map +1 -1
  22. package/dist/prompt-router.js +18 -2
  23. package/dist/prompt-router.js.map +1 -1
  24. package/docs/planning/V0_0_9_APROVACAO_CRITICA_MENSAGENS_DE_VENDA.md +85 -0
  25. package/docs/planning/V0_0_9_FONTES_E_CRITERIOS_DE_AUTORIDADE.md +139 -0
  26. package/docs/planning/V0_0_9_MATRIZ_SKILLS_MULTIDISCIPLINARES.md +105 -0
  27. package/docs/planning/V0_0_9_POLITICA_MORAL_CATOLICA_PARA_IA.md +181 -0
  28. package/docs/planning/V0_0_9_PROMPTS_EXECUCAO.md +59 -0
  29. package/docs/planning/V0_0_9_ROADMAP_DISCERNIMENTO_E_CONHECIMENTO_AMPLO.md +181 -0
  30. package/docs/skill-candidates/v0.0.10/cli-creator/LICENSE.txt +201 -0
  31. package/docs/skill-candidates/v0.0.10/cli-creator/SKILL.md +160 -0
  32. package/docs/skill-candidates/v0.0.10/cli-creator/agents/openai.yaml +4 -0
  33. package/docs/skill-candidates/v0.0.10/cli-creator/references/agent-cli-patterns.md +154 -0
  34. package/docs/skill-candidates/v0.0.10/developer-workstation-ops/SKILL.md +32 -0
  35. package/docs/skill-candidates/v0.0.10/figma/LICENSE.txt +2 -0
  36. package/docs/skill-candidates/v0.0.10/figma/SKILL.md +42 -0
  37. package/docs/skill-candidates/v0.0.10/figma/agents/openai.yaml +14 -0
  38. package/docs/skill-candidates/v0.0.10/figma/assets/figma-small.svg +3 -0
  39. package/docs/skill-candidates/v0.0.10/figma/assets/figma.png +0 -0
  40. package/docs/skill-candidates/v0.0.10/figma/assets/icon.svg +28 -0
  41. package/docs/skill-candidates/v0.0.10/figma/references/figma-mcp-config.md +35 -0
  42. package/docs/skill-candidates/v0.0.10/figma/references/figma-tools-and-prompts.md +34 -0
  43. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/LICENSE.TXT +2 -0
  44. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/SKILL.md +349 -0
  45. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/agents/openai.yaml +14 -0
  46. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/assets/figma-small.svg +3 -0
  47. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/assets/figma.png +0 -0
  48. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/assets/icon.svg +28 -0
  49. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/references/mapping-checklist.md +7 -0
  50. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/scripts/normalize_node_id.py +25 -0
  51. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/LICENSE.TXT +2 -0
  52. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/SKILL.md +537 -0
  53. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/agents/openai.yaml +14 -0
  54. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/assets/figma-small.svg +3 -0
  55. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/assets/figma.png +0 -0
  56. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/assets/icon.svg +28 -0
  57. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/references/rule-template.md +15 -0
  58. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/scripts/check_agents_md.sh +9 -0
  59. package/docs/skill-candidates/v0.0.10/figma-generate-design/LICENSE.TXT +2 -0
  60. package/docs/skill-candidates/v0.0.10/figma-generate-design/SKILL.md +341 -0
  61. package/docs/skill-candidates/v0.0.10/figma-generate-design/agents/openai.yaml +14 -0
  62. package/docs/skill-candidates/v0.0.10/figma-generate-design/assets/figma-small.svg +3 -0
  63. package/docs/skill-candidates/v0.0.10/figma-generate-design/assets/figma.png +0 -0
  64. package/docs/skill-candidates/v0.0.10/figma-generate-design/assets/icon.svg +28 -0
  65. package/docs/skill-candidates/v0.0.10/figma-generate-design/maintainers.yml +1 -0
  66. package/docs/skill-candidates/v0.0.10/figma-generate-library/LICENSE.TXT +2 -0
  67. package/docs/skill-candidates/v0.0.10/figma-generate-library/SKILL.md +314 -0
  68. package/docs/skill-candidates/v0.0.10/figma-generate-library/agents/openai.yaml +14 -0
  69. package/docs/skill-candidates/v0.0.10/figma-generate-library/assets/figma-small.svg +3 -0
  70. package/docs/skill-candidates/v0.0.10/figma-generate-library/assets/figma.png +0 -0
  71. package/docs/skill-candidates/v0.0.10/figma-generate-library/assets/icon.svg +28 -0
  72. package/docs/skill-candidates/v0.0.10/figma-generate-library/maintainers.yml +3 -0
  73. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/code-connect-setup.md +260 -0
  74. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/component-creation.md +1014 -0
  75. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/discovery-phase.md +518 -0
  76. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/documentation-creation.md +834 -0
  77. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/error-recovery.md +540 -0
  78. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/naming-conventions.md +527 -0
  79. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/token-creation.md +962 -0
  80. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/bindVariablesToComponent.js +110 -0
  81. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/cleanupOrphans.js +127 -0
  82. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createComponentWithVariants.js +148 -0
  83. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createDocumentationPage.js +139 -0
  84. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createSemanticTokens.js +108 -0
  85. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createVariableCollection.js +49 -0
  86. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/inspectFileStructure.js +121 -0
  87. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/rehydrateState.js +92 -0
  88. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/validateCreation.js +83 -0
  89. package/docs/skill-candidates/v0.0.10/figma-implement-design/LICENSE.txt +2 -0
  90. package/docs/skill-candidates/v0.0.10/figma-implement-design/SKILL.md +258 -0
  91. package/docs/skill-candidates/v0.0.10/figma-implement-design/agents/openai.yaml +14 -0
  92. package/docs/skill-candidates/v0.0.10/figma-implement-design/assets/figma-small.svg +3 -0
  93. package/docs/skill-candidates/v0.0.10/figma-implement-design/assets/figma.png +0 -0
  94. package/docs/skill-candidates/v0.0.10/figma-implement-design/assets/icon.svg +28 -0
  95. package/docs/skill-candidates/v0.0.10/figma-use/LICENSE.TXT +2 -0
  96. package/docs/skill-candidates/v0.0.10/figma-use/SKILL.md +233 -0
  97. package/docs/skill-candidates/v0.0.10/figma-use/agents/openai.yaml +14 -0
  98. package/docs/skill-candidates/v0.0.10/figma-use/assets/figma-small.svg +3 -0
  99. package/docs/skill-candidates/v0.0.10/figma-use/assets/figma.png +0 -0
  100. package/docs/skill-candidates/v0.0.10/figma-use/assets/icon.svg +28 -0
  101. package/docs/skill-candidates/v0.0.10/figma-use/maintainers.yml +1 -0
  102. package/docs/skill-candidates/v0.0.10/figma-use/references/api-reference.md +301 -0
  103. package/docs/skill-candidates/v0.0.10/figma-use/references/common-patterns.md +512 -0
  104. package/docs/skill-candidates/v0.0.10/figma-use/references/component-patterns.md +488 -0
  105. package/docs/skill-candidates/v0.0.10/figma-use/references/effect-style-patterns.md +123 -0
  106. package/docs/skill-candidates/v0.0.10/figma-use/references/gotchas.md +599 -0
  107. package/docs/skill-candidates/v0.0.10/figma-use/references/maintainers.yml +12 -0
  108. package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-patterns.md +513 -0
  109. package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-standalone.d.ts +11293 -0
  110. package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-standalone.index.md +441 -0
  111. package/docs/skill-candidates/v0.0.10/figma-use/references/text-style-patterns.md +203 -0
  112. package/docs/skill-candidates/v0.0.10/figma-use/references/validation-and-recovery.md +109 -0
  113. package/docs/skill-candidates/v0.0.10/figma-use/references/variable-patterns.md +354 -0
  114. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/maintainers.yml +9 -0
  115. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components--creating.md +17 -0
  116. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components--using.md +17 -0
  117. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components.md +50 -0
  118. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-effect-styles.md +52 -0
  119. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-text-styles.md +90 -0
  120. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables--creating.md +13 -0
  121. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables--using.md +13 -0
  122. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables.md +64 -0
  123. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds.md +41 -0
  124. package/docs/skill-candidates/v0.0.10/frontend-design/LICENSE.txt +177 -0
  125. package/docs/skill-candidates/v0.0.10/frontend-design/SKILL.md +55 -0
  126. package/docs/skill-candidates/v0.0.10/frontend-ui-ux-systems/SKILL.md +32 -0
  127. package/docs/skill-candidates/v0.0.10/github/SKILL.md +74 -0
  128. package/docs/skill-candidates/v0.0.10/github/agents/openai.yaml +6 -0
  129. package/docs/skill-candidates/v0.0.10/github/assets/github-small.svg +3 -0
  130. package/docs/skill-candidates/v0.0.10/github/assets/github.png +0 -0
  131. package/docs/skill-candidates/v0.0.10/image-graphic-design-rendering/SKILL.md +28 -0
  132. package/docs/skill-candidates/v0.0.10/language-quality-pt-en-fr-it-ru/SKILL.md +28 -0
  133. package/docs/skill-candidates/v0.0.10/math-physics-reasoning/SKILL.md +28 -0
  134. package/docs/skill-candidates/v0.0.10/mcp-builder/LICENSE.txt +202 -0
  135. package/docs/skill-candidates/v0.0.10/mcp-builder/SKILL.md +236 -0
  136. package/docs/skill-candidates/v0.0.10/mcp-builder/reference/evaluation.md +602 -0
  137. package/docs/skill-candidates/v0.0.10/mcp-builder/reference/mcp_best_practices.md +249 -0
  138. package/docs/skill-candidates/v0.0.10/mcp-builder/reference/node_mcp_server.md +970 -0
  139. package/docs/skill-candidates/v0.0.10/mcp-builder/reference/python_mcp_server.md +719 -0
  140. package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/connections.py +151 -0
  141. package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/evaluation.py +373 -0
  142. package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/example_evaluation.xml +22 -0
  143. package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/requirements.txt +2 -0
  144. package/docs/skill-candidates/v0.0.10/mcp-client-readiness/SKILL.md +31 -0
  145. package/docs/skill-candidates/v0.0.10/openai-docs/LICENSE.txt +201 -0
  146. package/docs/skill-candidates/v0.0.10/openai-docs/SKILL.md +161 -0
  147. package/docs/skill-candidates/v0.0.10/openai-docs/agents/openai.yaml +14 -0
  148. package/docs/skill-candidates/v0.0.10/openai-docs/assets/openai-small.svg +3 -0
  149. package/docs/skill-candidates/v0.0.10/openai-docs/assets/openai.png +0 -0
  150. package/docs/skill-candidates/v0.0.10/openai-docs/references/latest-model.md +37 -0
  151. package/docs/skill-candidates/v0.0.10/openai-docs/references/prompting-guide.md +244 -0
  152. package/docs/skill-candidates/v0.0.10/openai-docs/references/upgrade-guide.md +181 -0
  153. package/docs/skill-candidates/v0.0.10/openai-docs/scripts/fetch-codex-manual.mjs +598 -0
  154. package/docs/skill-candidates/v0.0.10/openai-docs/scripts/resolve-latest-model-info.js +147 -0
  155. package/docs/skill-candidates/v0.0.10/playwright/LICENSE.txt +201 -0
  156. package/docs/skill-candidates/v0.0.10/playwright/NOTICE.txt +14 -0
  157. package/docs/skill-candidates/v0.0.10/playwright/SKILL.md +147 -0
  158. package/docs/skill-candidates/v0.0.10/playwright/agents/openai.yaml +6 -0
  159. package/docs/skill-candidates/v0.0.10/playwright/assets/playwright-small.svg +3 -0
  160. package/docs/skill-candidates/v0.0.10/playwright/assets/playwright.png +0 -0
  161. package/docs/skill-candidates/v0.0.10/playwright/references/cli.md +116 -0
  162. package/docs/skill-candidates/v0.0.10/playwright/references/workflows.md +95 -0
  163. package/docs/skill-candidates/v0.0.10/playwright/scripts/playwright_cli.sh +25 -0
  164. package/docs/skill-candidates/v0.0.10/polyglot-backend-engineering/SKILL.md +32 -0
  165. package/docs/skill-candidates/v0.0.10/screenshot/LICENSE.txt +201 -0
  166. package/docs/skill-candidates/v0.0.10/screenshot/SKILL.md +267 -0
  167. package/docs/skill-candidates/v0.0.10/screenshot/agents/openai.yaml +6 -0
  168. package/docs/skill-candidates/v0.0.10/screenshot/assets/screenshot-small.svg +5 -0
  169. package/docs/skill-candidates/v0.0.10/screenshot/assets/screenshot.png +0 -0
  170. package/docs/skill-candidates/v0.0.10/screenshot/scripts/ensure_macos_permissions.sh +54 -0
  171. package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_display_info.swift +22 -0
  172. package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_permissions.swift +40 -0
  173. package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_window_info.swift +126 -0
  174. package/docs/skill-candidates/v0.0.10/screenshot/scripts/take_screenshot.ps1 +163 -0
  175. package/docs/skill-candidates/v0.0.10/screenshot/scripts/take_screenshot.py +585 -0
  176. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/SKILL.md +62 -0
  177. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/agents/openai.yaml +4 -0
  178. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/activation-policy.md +77 -0
  179. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/human-approval-policy.md +83 -0
  180. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/persona-dev-senior-master.md +46 -0
  181. package/docs/skill-candidates/v0.0.10/terminal-menu-operations/SKILL.md +30 -0
  182. package/docs/skill-candidates/v0.0.10/terminal-pixel-art-tui/SKILL.md +43 -0
  183. package/docs/skill-candidates/v0.0.10/webapp-testing/LICENSE.txt +202 -0
  184. package/docs/skill-candidates/v0.0.10/webapp-testing/SKILL.md +96 -0
  185. package/docs/skill-candidates/v0.0.10/webapp-testing/examples/console_logging.py +35 -0
  186. package/docs/skill-candidates/v0.0.10/webapp-testing/examples/element_discovery.py +40 -0
  187. package/docs/skill-candidates/v0.0.10/webapp-testing/examples/static_html_automation.py +33 -0
  188. package/docs/skill-candidates/v0.0.10/webapp-testing/scripts/with_server.py +106 -0
  189. package/docs/skill-candidates/v0.0.10/winui-app/LICENSE.txt +202 -0
  190. package/docs/skill-candidates/v0.0.10/winui-app/SKILL.md +94 -0
  191. package/docs/skill-candidates/v0.0.10/winui-app/agents/openai.yaml +5 -0
  192. package/docs/skill-candidates/v0.0.10/winui-app/assets/winui.png +0 -0
  193. package/docs/skill-candidates/v0.0.10/winui-app/config.yaml +50 -0
  194. package/docs/skill-candidates/v0.0.10/winui-app/references/_sections.md +96 -0
  195. package/docs/skill-candidates/v0.0.10/winui-app/references/accessibility-input-and-localization.md +51 -0
  196. package/docs/skill-candidates/v0.0.10/winui-app/references/build-run-and-launch-verification.md +72 -0
  197. package/docs/skill-candidates/v0.0.10/winui-app/references/community-toolkit-controls-and-helpers.md +57 -0
  198. package/docs/skill-candidates/v0.0.10/winui-app/references/controls-layout-and-adaptive-ui.md +84 -0
  199. package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-environment-audit-and-remediation.md +82 -0
  200. package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-setup-and-project-selection.md +67 -0
  201. package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-template-first-recovery.md +62 -0
  202. package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-winui-app-structure.md +62 -0
  203. package/docs/skill-candidates/v0.0.10/winui-app/references/motion-animations-and-polish.md +45 -0
  204. package/docs/skill-candidates/v0.0.10/winui-app/references/performance-diagnostics-and-responsiveness.md +46 -0
  205. package/docs/skill-candidates/v0.0.10/winui-app/references/sample-source-map.md +37 -0
  206. package/docs/skill-candidates/v0.0.10/winui-app/references/shell-navigation-and-windowing.md +67 -0
  207. package/docs/skill-candidates/v0.0.10/winui-app/references/styling-theming-materials-and-icons.md +71 -0
  208. package/docs/skill-candidates/v0.0.10/winui-app/references/testing-debugging-and-review-checklists.md +77 -0
  209. package/docs/skill-candidates/v0.0.10/winui-app/references/windows-app-sdk-lifecycle-notifications-and-deployment.md +52 -0
  210. package/docs/skill-candidates/v0.0.9/ai-ethics-human-dignity/SKILL.md +32 -0
  211. package/docs/skill-candidates/v0.0.9/broad-domain-router/SKILL.md +41 -0
  212. package/docs/skill-candidates/v0.0.9/catholic-moral-discernment/SKILL.md +31 -0
  213. package/docs/skill-candidates/v0.0.9/engineering-systems-master/SKILL.md +31 -0
  214. package/docs/skill-candidates/v0.0.9/language-quality-pt-en-fr/SKILL.md +28 -0
  215. package/docs/skill-candidates/v0.0.9/math-science-reasoning/SKILL.md +29 -0
  216. package/docs/skill-candidates/v0.0.9/philosophy-sociology-discernment/SKILL.md +28 -0
  217. package/docs/skill-candidates/v0.0.9/professional-boundary-triage/SKILL.md +40 -0
  218. package/docs/skill-candidates/v0.0.9/release-ethics-gate/SKILL.md +32 -0
  219. package/docs/skill-candidates/v0.0.9/source-authority-reviewer/SKILL.md +31 -0
  220. package/manifests/channels/beta.json +7 -7
  221. package/manifests/channels/stable.json +8 -8
  222. package/network/unapproved-skill-candidates.json +34 -1
  223. package/package.json +7 -1
@@ -1,5 +1,6 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { existsSync, readFileSync, readdirSync } from 'node:fs';
3
+ import os from 'node:os';
3
4
  import { join } from 'node:path';
4
5
  import process from 'node:process';
5
6
 
@@ -11,12 +12,245 @@ const ANSI = {
11
12
  green: '\x1b[32m',
12
13
  yellow: '\x1b[33m',
13
14
  red: '\x1b[31m',
15
+ white: '\x1b[37m',
16
+ gray: '\x1b[90m',
17
+ teal: '\x1b[38;5;80m',
18
+ amber: '\x1b[38;5;179m',
19
+ blue: '\x1b[38;5;75m',
20
+ };
21
+
22
+ const REQUIRED_GLOBAL_SKILLS = [
23
+ 'catholic-moral-discernment',
24
+ 'ai-ethics-human-dignity',
25
+ 'professional-boundary-triage',
26
+ 'broad-domain-router',
27
+ 'language-quality-pt-en-fr',
28
+ 'math-science-reasoning',
29
+ 'philosophy-sociology-discernment',
30
+ 'engineering-systems-master',
31
+ 'source-authority-reviewer',
32
+ 'release-ethics-gate',
33
+ 'mcp-client-readiness',
34
+ 'terminal-menu-operations',
35
+ 'terminal-pixel-art-tui',
36
+ ];
37
+
38
+ const BUNDLED_SKILL_DOMAIN_GROUPS = [
39
+ {
40
+ key: 'moral',
41
+ label: 'moral-core',
42
+ skills: [
43
+ 'ai-ethics-human-dignity',
44
+ 'broad-domain-router',
45
+ 'catholic-moral-discernment',
46
+ 'engineering-systems-master',
47
+ 'language-quality-pt-en-fr',
48
+ 'math-science-reasoning',
49
+ 'philosophy-sociology-discernment',
50
+ 'professional-boundary-triage',
51
+ 'release-ethics-gate',
52
+ 'source-authority-reviewer',
53
+ ],
54
+ },
55
+ {
56
+ key: 'frontend',
57
+ label: 'frontend-ui',
58
+ skills: [
59
+ 'figma',
60
+ 'figma-code-connect-components',
61
+ 'figma-create-design-system-rules',
62
+ 'figma-generate-design',
63
+ 'figma-generate-library',
64
+ 'figma-implement-design',
65
+ 'figma-use',
66
+ 'frontend-design',
67
+ 'frontend-ui-ux-systems',
68
+ 'playwright',
69
+ 'screenshot',
70
+ 'webapp-testing',
71
+ 'winui-app',
72
+ ],
73
+ },
74
+ {
75
+ key: 'backend',
76
+ label: 'backend-data',
77
+ skills: [
78
+ 'mcp-builder',
79
+ 'polyglot-backend-engineering',
80
+ ],
81
+ },
82
+ {
83
+ key: 'ops',
84
+ label: 'ops-clients',
85
+ skills: [
86
+ 'cli-creator',
87
+ 'developer-workstation-ops',
88
+ 'github',
89
+ 'mcp-client-readiness',
90
+ 'openai-docs',
91
+ 'skill-master-orchestrator',
92
+ 'terminal-menu-operations',
93
+ 'terminal-pixel-art-tui',
94
+ ],
95
+ },
96
+ {
97
+ key: 'knowledge',
98
+ label: 'knowledge',
99
+ skills: [
100
+ 'language-quality-pt-en-fr-it-ru',
101
+ 'math-physics-reasoning',
102
+ ],
103
+ },
104
+ ];
105
+
106
+ const COMMAND_AREA_LABELS = {
107
+ status: 'diagnostico',
108
+ doctor: 'diagnostico',
109
+ check: 'desenvolvimento',
110
+ build: 'desenvolvimento',
111
+ publicNpm: 'distribuicao',
112
+ updateGlobal: 'distribuicao',
113
+ privateRegistry: 'registry',
114
+ activationStatus: 'ativacao',
115
+ activationBalanced: 'ativacao',
116
+ activationAlwaysOn: 'ativacao',
117
+ installGlobalSkills: 'skills-globais',
118
+ bootstrapGlobal: 'bootstrap-global',
119
+ registerClients: 'clientes-mcp',
120
+ promptRecommendation: 'roteamento',
121
+ successNotifications: 'aprendizado',
122
+ studySkills: 'aprendizado',
123
+ approvalPackage: 'aprovacao',
124
+ markLearnedStudy: 'aprovacao',
125
+ rejectLearnedSkill: 'aprovacao',
126
+ activateLearnedLocal: 'ativacao-skill',
127
+ activateLearnedGlobal: 'ativacao-skill',
128
+ notionSummary: 'documentacao',
14
129
  };
15
130
 
16
131
  function colorize(text, color, enabled) {
17
132
  return enabled ? `${color}${text}${ANSI.reset}` : text;
18
133
  }
19
134
 
135
+ function visibleLength(text) {
136
+ return String(text).replace(/\x1b\[[0-9;]*m/g, '').length;
137
+ }
138
+
139
+ function fitText(text, width) {
140
+ const value = String(text ?? '');
141
+ if (visibleLength(value) <= width) {
142
+ return `${value}${' '.repeat(width - visibleLength(value))}`;
143
+ }
144
+
145
+ return `${value.slice(0, Math.max(0, width - 1))}~`;
146
+ }
147
+
148
+ function splitText(text, width, maxLines = 3) {
149
+ const words = String(text ?? '').split(/\s+/).filter(Boolean);
150
+ const lines = [];
151
+ let current = '';
152
+
153
+ for (const word of words) {
154
+ const next = current ? `${current} ${word}` : word;
155
+ if (next.length <= width) {
156
+ current = next;
157
+ continue;
158
+ }
159
+ if (current) lines.push(current);
160
+ current = word.length > width ? word.slice(0, width - 1) + '~' : word;
161
+ if (lines.length >= maxLines) break;
162
+ }
163
+ if (current && lines.length < maxLines) lines.push(current);
164
+ return lines.length ? lines : [''];
165
+ }
166
+
167
+ function globalSkillsRoot() {
168
+ return join(process.env.CODEX_HOME ?? join(os.homedir(), '.codex'), 'skills');
169
+ }
170
+
171
+ function readClientConfigState(filePath) {
172
+ if (!existsSync(filePath)) {
173
+ return { present: false, kind: 'missing', globalCommand: false };
174
+ }
175
+
176
+ const content = readFileSync(filePath, 'utf8');
177
+ const hasSkillMaster = content.includes('skill_master');
178
+ const hasGlobalCommand = content.includes('command = "skill-master-mcp"') || content.includes("command = 'skill-master-mcp'");
179
+ const hasLauncher = content.includes('skill-master-launcher');
180
+
181
+ return {
182
+ present: true,
183
+ kind: hasGlobalCommand ? 'global' : hasLauncher ? 'launcher' : hasSkillMaster ? 'custom' : 'unknown',
184
+ globalCommand: hasGlobalCommand,
185
+ };
186
+ }
187
+
188
+ function readJsonState(filePath) {
189
+ if (!existsSync(filePath)) {
190
+ return { present: false, globalCommand: false };
191
+ }
192
+
193
+ try {
194
+ const parsed = JSON.parse(readFileSync(filePath, 'utf8'));
195
+ const server = parsed?.mcpServers?.skill_master;
196
+ return {
197
+ present: true,
198
+ globalCommand: server?.command === 'skill-master-mcp',
199
+ };
200
+ } catch {
201
+ return { present: true, globalCommand: false };
202
+ }
203
+ }
204
+
205
+ function defaultClaudeConfigPath() {
206
+ if (process.platform === 'win32') {
207
+ return join(process.env.APPDATA ?? join(os.homedir(), 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
208
+ }
209
+
210
+ if (process.platform === 'darwin') {
211
+ return join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
212
+ }
213
+
214
+ return join(os.homedir(), '.config', 'Claude', 'claude_desktop_config.json');
215
+ }
216
+
217
+ function inspectGlobalReadiness() {
218
+ const root = globalSkillsRoot();
219
+ const installed = REQUIRED_GLOBAL_SKILLS.filter((name) => existsSync(join(root, name, 'SKILL.md')));
220
+ const missing = REQUIRED_GLOBAL_SKILLS.filter((name) => !installed.includes(name));
221
+ const codexConfigPath = join(process.env.CODEX_HOME ?? join(os.homedir(), '.codex'), 'config.toml');
222
+ const claudeConfigPath = defaultClaudeConfigPath();
223
+ const geminiConfigPath = join(os.homedir(), '.gemini', 'settings.json');
224
+ const antigravityConfigPath = join(os.homedir(), '.gemini', 'config', 'mcp_config.json');
225
+ const codex = readClientConfigState(codexConfigPath);
226
+ const claude = readJsonState(claudeConfigPath);
227
+ const gemini = readJsonState(geminiConfigPath);
228
+ const antigravity = readJsonState(antigravityConfigPath);
229
+ const ready = missing.length === 0
230
+ && codex.globalCommand
231
+ && claude.globalCommand
232
+ && gemini.globalCommand
233
+ && antigravity.globalCommand;
234
+ const mode = ready
235
+ ? 'ready'
236
+ : codex.kind === 'launcher' || claude.present || gemini.present || antigravity.present
237
+ ? 'partial'
238
+ : 'missing';
239
+
240
+ return {
241
+ root,
242
+ required: REQUIRED_GLOBAL_SKILLS.length,
243
+ installed,
244
+ missing,
245
+ ready,
246
+ mode,
247
+ codex,
248
+ claude,
249
+ gemini,
250
+ antigravity,
251
+ };
252
+ }
253
+
20
254
  export function readJson(rootDir, relativePath) {
21
255
  const target = join(rootDir, relativePath);
22
256
  if (!existsSync(target)) {
@@ -42,6 +276,8 @@ export function getMenuStatus(rootDir) {
42
276
  const successLearningDir = process.env.SKILL_MASTER_SUCCESS_LEARNING_DIR
43
277
  ?? join(process.env.SKILL_MASTER_HOME ?? join(process.env.HOME ?? process.env.USERPROFILE ?? '', '.skill-master'), 'data', 'success-learning');
44
278
  const studyCandidates = readJson(rootDir, 'network/unapproved-skill-candidates.json');
279
+ const globalReadiness = inspectGlobalReadiness();
280
+ const bundledCatalog = inspectBundledSkillCatalog(rootDir);
45
281
 
46
282
  return {
47
283
  packageName: packageJson?.name ?? 'nao encontrado',
@@ -52,6 +288,8 @@ export function getMenuStatus(rootDir) {
52
288
  rootDir,
53
289
  pendingSuccessDrafts: countManifestFiles(successLearningDir),
54
290
  studyCandidates: Array.isArray(studyCandidates?.candidates) ? studyCandidates.candidates.length : 0,
291
+ globalReadiness,
292
+ bundledCatalog,
55
293
  };
56
294
  }
57
295
 
@@ -73,21 +311,108 @@ function countManifestFiles(directory) {
73
311
  return count;
74
312
  }
75
313
 
314
+ function listBundledSkillNames(rootDir) {
315
+ const source = join(rootDir, 'docs', 'skill-candidates');
316
+ if (!existsSync(source)) {
317
+ return [];
318
+ }
319
+
320
+ const entries = readdirSync(source, { withFileTypes: true });
321
+ const directSkills = entries
322
+ .filter((entry) => entry.isDirectory() && existsSync(join(source, entry.name, 'SKILL.md')))
323
+ .map((entry) => entry.name);
324
+
325
+ if (directSkills.length) {
326
+ return Array.from(new Set(directSkills)).sort();
327
+ }
328
+
329
+ return Array.from(new Set(
330
+ entries
331
+ .filter((entry) => entry.isDirectory())
332
+ .flatMap((entry) => {
333
+ const versionPath = join(source, entry.name);
334
+ return readdirSync(versionPath, { withFileTypes: true })
335
+ .filter((skillEntry) => skillEntry.isDirectory() && existsSync(join(versionPath, skillEntry.name, 'SKILL.md')))
336
+ .map((skillEntry) => skillEntry.name);
337
+ }),
338
+ )).sort();
339
+ }
340
+
341
+ function inspectBundledSkillCatalog(rootDir) {
342
+ const names = listBundledSkillNames(rootDir);
343
+ const categories = BUNDLED_SKILL_DOMAIN_GROUPS.map((group) => ({
344
+ key: group.key,
345
+ label: group.label,
346
+ count: group.skills.filter((skill) => names.includes(skill)).length,
347
+ }));
348
+
349
+ return {
350
+ total: names.length,
351
+ names,
352
+ categories,
353
+ };
354
+ }
355
+
356
+ function formatBundledCategoryLine(catalog) {
357
+ if (!catalog?.categories?.length) {
358
+ return 'bundled skills: 0';
359
+ }
360
+
361
+ return catalog.categories
362
+ .filter((category) => category.count > 0)
363
+ .map((category) => `${category.label} ${category.count}`)
364
+ .join(' | ');
365
+ }
366
+
367
+ function resolveCommandArea(action) {
368
+ if (!action) {
369
+ return 'geral';
370
+ }
371
+
372
+ return COMMAND_AREA_LABELS[action.key] ?? 'geral';
373
+ }
374
+
375
+ function formatActionCommand(action) {
376
+ if (!action?.command) {
377
+ return '';
378
+ }
379
+
380
+ return [action.command, ...(action.args ?? [])].join(' ');
381
+ }
382
+
76
383
  export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process.execPath }) {
384
+ const isDevCheckout = existsSync(join(rootDir, 'tsconfig.json')) && existsSync(join(rootDir, 'src'));
385
+ const repoOnlyReason = 'Disponivel apenas no clone de desenvolvimento; no pacote npm use Doctor ou Status.';
386
+
77
387
  return [
78
388
  {
79
389
  key: 'status',
80
390
  aliases: ['status'],
81
391
  label: 'Status local',
82
392
  description: 'Mostra versao local, manifesto e informacoes do pacote.',
393
+ details: ['Nao altera arquivos.', 'Use para confirmar se o menu esta lendo a instalacao correta.'],
394
+ success: 'Relatorio impresso com versao, canal, skills globais e clientes configurados.',
83
395
  command: nodeExecPath,
84
396
  args: [currentFile, '--status'],
85
397
  },
398
+ {
399
+ key: 'doctor',
400
+ aliases: ['doctor', 'diagnostico', 'verificar-menu', 'validar-menu'],
401
+ label: 'Doctor do menu e clientes MCP',
402
+ description: 'Valida pacote, binarios, skills globais e registros em Codex, Claude, Gemini e Antigravity.',
403
+ details: ['Seguro para outros notebooks.', 'Nao publica versao e nao mexe em configuracoes sem uma acao separada.'],
404
+ success: 'Mostra um relatorio GO/NO-GO com proximos comandos recomendados.',
405
+ command: nodeExecPath,
406
+ args: [join(rootDir, 'bin', 'skill-master-doctor.mjs')],
407
+ },
86
408
  {
87
409
  key: 'check',
88
410
  aliases: ['check', 'gate'],
89
411
  label: 'Rodar gate completo',
90
412
  description: 'Executa build, testes e validacao de manifestos.',
413
+ details: ['Exige clone do repositorio com src, testes e tsconfig.', 'Nao e uma acao indicada para instalacao global via npm.'],
414
+ success: 'Build, testes e manifestos passam no checkout de desenvolvimento.',
415
+ disabledReason: isDevCheckout ? null : repoOnlyReason,
91
416
  command: 'npm',
92
417
  args: ['run', 'check'],
93
418
  },
@@ -96,6 +421,9 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
96
421
  aliases: ['build'],
97
422
  label: 'Rodar build',
98
423
  description: 'Compila o projeto localmente.',
424
+ details: ['Exige clone do repositorio com tsconfig.', 'Pacotes npm publicados ja usam dist precompilado.'],
425
+ success: 'dist atualizado no checkout de desenvolvimento.',
426
+ disabledReason: isDevCheckout ? null : repoOnlyReason,
99
427
  command: 'npm',
100
428
  args: ['run', 'build'],
101
429
  },
@@ -104,6 +432,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
104
432
  aliases: ['public-npm', 'npm', 'registry'],
105
433
  label: 'Validar pacote no npm publico',
106
434
  description: 'Consulta a versao publicada em registry.npmjs.org.',
435
+ details: ['Usa somente leitura no registry publico.', 'Bom para confirmar se outro notebook consegue instalar por npm.'],
436
+ success: 'Retorna a versao publicada atualmente no npmjs.',
107
437
  command: 'npm',
108
438
  args: [
109
439
  'view',
@@ -117,6 +447,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
117
447
  aliases: ['update', 'update-global'],
118
448
  label: 'Atualizar pacote global via npm',
119
449
  description: 'Atualiza a instalacao global e exige reinicio do cliente MCP.',
450
+ details: ['Roda npm install -g fora do processo MCP stdio.', 'Use antes de abrir Codex, Claude, Gemini ou Antigravity.'],
451
+ success: 'Pacote global atualizado para a versao latest do npm publico.',
120
452
  command: nodeExecPath,
121
453
  args: [join(rootDir, 'bin', 'skill-master-update.mjs')],
122
454
  confirmMessage: 'Atualizar o pacote global agora?',
@@ -126,6 +458,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
126
458
  aliases: ['private-registry', 'private', 'github-packages'],
127
459
  label: 'Configurar registry privado GitHub Packages',
128
460
  description: 'Prepara o .npmrc e valida o acesso ao pacote privado.',
461
+ details: ['Uso avancado para ambientes privados.', 'Nao e necessario para o pacote publico do npmjs.'],
462
+ success: '.npmrc configurado e validacao npm view executada.',
129
463
  command: nodeExecPath,
130
464
  args: ['scripts/configure-private-registry.mjs', '--validate'],
131
465
  confirmMessage: 'Rodar a configuracao de registry privado agora?',
@@ -135,6 +469,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
135
469
  aliases: ['activation-status', 'modo', 'modo-ativacao'],
136
470
  label: 'Modo de ativacao atual',
137
471
  description: 'Mostra o modo manual, balanced ou always-on-assisted configurado localmente.',
472
+ details: ['Nao altera configuracao.', 'Ajuda a entender quando o Skill Master deve sugerir skills.'],
473
+ success: 'Modo atual e caminho da configuracao impressos no terminal.',
138
474
  command: nodeExecPath,
139
475
  args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--status'],
140
476
  },
@@ -143,6 +479,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
143
479
  aliases: ['set-balanced', 'balanced'],
144
480
  label: 'Usar modo balanced',
145
481
  description: 'Define balanced como modo padrao de ativacao do Skill Master.',
482
+ details: ['Recomendado para uso diario.', 'Ativa o MCP quando ha ganho claro para o prompt.'],
483
+ success: 'Modo balanced salvo localmente.',
146
484
  command: nodeExecPath,
147
485
  args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--set-mode', 'balanced'],
148
486
  },
@@ -151,15 +489,52 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
151
489
  aliases: ['set-always-on', 'always-on-assisted'],
152
490
  label: 'Usar modo always-on-assisted',
153
491
  description: 'Define avaliacao assistida quase sempre ativa, mantendo no-op quando nao houver ganho.',
492
+ details: ['Mais agressivo que balanced.', 'Indicado para usuarios que querem o Skill Master avaliando quase todos os prompts.'],
493
+ success: 'Modo always-on-assisted salvo localmente.',
154
494
  command: nodeExecPath,
155
495
  args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--set-mode', 'always-on-assisted'],
156
496
  confirmMessage: 'Alterar o modo local para always-on-assisted?',
157
497
  },
498
+ {
499
+ key: 'installGlobalSkills',
500
+ aliases: ['install-global-skills', 'skills-globais', 'global-skills'],
501
+ label: 'Instalar skills globais do Skill Master',
502
+ description: 'Copia as skills amplas e morais embutidas para CODEX_HOME/skills ou ~/.codex/skills.',
503
+ details: ['Necessario para Codex descobrir as skills globais.', 'Pode ser reexecutado com seguranca pelo bootstrap.'],
504
+ success: 'Skills globais copiadas para a pasta global do usuario.',
505
+ command: nodeExecPath,
506
+ args: [join(rootDir, 'bin', 'skill-master-install-global-skills.mjs')],
507
+ confirmMessage: 'Instalar as skills globais embutidas neste usuario?',
508
+ },
509
+ {
510
+ key: 'bootstrapGlobal',
511
+ aliases: ['bootstrap-global', 'global-bootstrap', 'ativar-global-completo'],
512
+ label: 'Ativar MCP global neste computador',
513
+ description: 'Instala skills globais e registra Codex, Claude, Gemini e Antigravity no mesmo passo.',
514
+ details: ['Acao principal para notebooks novos.', 'Depois reinicie os clientes para eles recarregarem MCP e skills.'],
515
+ success: 'Skills instaladas e configuracoes MCP aplicadas nos clientes encontrados.',
516
+ command: nodeExecPath,
517
+ args: [join(rootDir, 'bin', 'skill-master-bootstrap-global.mjs')],
518
+ confirmMessage: 'Executar o bootstrap global do Skill Master neste computador?',
519
+ },
520
+ {
521
+ key: 'registerClients',
522
+ aliases: ['register-clients', 'registrar-clientes', 'codex-claude-gemini', 'antigravity'],
523
+ label: 'Registrar clientes MCP',
524
+ description: 'Gera/aplica configuracoes MCP para Codex, Claude, Gemini e Antigravity reconhecerem skill_master.',
525
+ details: ['Usa o binario global skill-master-mcp.', 'Preserva outros servidores MCP ja existentes nos JSONs.'],
526
+ success: 'Arquivos de configuracao mesclados com o servidor skill_master.',
527
+ command: nodeExecPath,
528
+ args: [join(rootDir, 'bin', 'skill-master-register-clients.mjs'), '--apply-all'],
529
+ confirmMessage: 'Aplicar registro do skill_master em Codex, Claude, Gemini e Antigravity?',
530
+ },
158
531
  {
159
532
  key: 'promptRecommendation',
160
533
  aliases: ['recommend-prompt', 'recomendar-prompt', 'prompt-router'],
161
534
  label: 'Ver recomendacao para um prompt',
162
535
  description: 'Abre um fluxo interativo para avaliar um prompt pelo router local.',
536
+ details: ['Ajuda a decidir se skill-master, skill_master ou skill-master-mcp deve agir.', 'Nao publica nem altera skills.'],
537
+ success: 'Router imprime recomendacao, modo de ativacao e gates aplicaveis.',
163
538
  command: nodeExecPath,
164
539
  args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--route-prompt-interactive'],
165
540
  },
@@ -168,6 +543,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
168
543
  aliases: ['notifications', 'notificacoes', 'success-notifications'],
169
544
  label: 'Notificacoes de skills aprendidas',
170
545
  description: 'Mostra drafts pendentes, aprovacoes e skills externas para estudar.',
546
+ details: ['Use para decidir o que aprovar, estudar ou rejeitar.', 'Nao ativa skill automaticamente.'],
547
+ success: 'Lista de pendencias e proximas acoes exibida.',
171
548
  command: nodeExecPath,
172
549
  args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--notify'],
173
550
  },
@@ -176,6 +553,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
176
553
  aliases: ['study-skills', 'skills-estudo', 'estudar'],
177
554
  label: 'Skills para estudar',
178
555
  description: 'Lista skills externas e links de criadores ainda nao aprovados.',
556
+ details: ['Material de estudo, nao ativacao operacional.', 'Bom para revisao humana antes de virar skill local/global.'],
557
+ success: 'Links e motivos de estudo exibidos.',
179
558
  command: nodeExecPath,
180
559
  args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--study'],
181
560
  },
@@ -184,6 +563,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
184
563
  aliases: ['approval-package', 'aprovar', 'pacote-aprovacao'],
185
564
  label: 'Gerar pacote de aprovacao humana',
186
565
  description: 'Cria um relatorio local para revisar e aprovar skills aprendidas.',
566
+ details: ['Exige decisao humana antes de ativacao.', 'Inclui riscos, evidencias e recomendacao.'],
567
+ success: 'Pacote local de aprovacao gerado.',
187
568
  command: nodeExecPath,
188
569
  args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--approval-package'],
189
570
  },
@@ -192,6 +573,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
192
573
  aliases: ['mark-study', 'manter-estudo'],
193
574
  label: 'Manter skill candidata para estudo',
194
575
  description: 'Seleciona uma candidata e registra decisao de manter para estudo.',
576
+ details: ['Preserva historico sem ativar a skill.', 'Use quando a fonte ainda precisa revisao.'],
577
+ success: 'Decisao registrada no historico local.',
195
578
  command: nodeExecPath,
196
579
  args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--mark-study-interactive'],
197
580
  },
@@ -200,6 +583,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
200
583
  aliases: ['reject-skill', 'rejeitar-skill'],
201
584
  label: 'Rejeitar skill candidata',
202
585
  description: 'Seleciona uma candidata, registra rejeicao e preserva historico.',
586
+ details: ['Nao apaga evidencias.', 'Use quando risco, fonte ou utilidade nao passam no gate.'],
587
+ success: 'Rejeicao registrada com motivo.',
203
588
  command: nodeExecPath,
204
589
  args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--reject-interactive'],
205
590
  confirmMessage: 'Abrir fluxo para rejeitar uma skill candidata?',
@@ -209,6 +594,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
209
594
  aliases: ['activate-learned-local', 'ativar-local', 'skill-local'],
210
595
  label: 'Ativar skill aprendida no workspace',
211
596
  description: 'Instala uma skill aprendida em .codex/skills do projeto atual.',
597
+ details: ['Escopo limitado ao workspace.', 'Mais conservador que ativar globalmente.'],
598
+ success: 'Skill copiada para .codex/skills do projeto.',
212
599
  command: nodeExecPath,
213
600
  args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--activate-interactive', '--target', 'local'],
214
601
  confirmMessage: 'Selecionar e ativar uma skill aprendida no workspace atual?',
@@ -218,6 +605,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
218
605
  aliases: ['activate-learned-global', 'ativar-global', 'skill-global'],
219
606
  label: 'Ativar skill aprendida global',
220
607
  description: 'Instala uma skill aprendida em CODEX_HOME/skills ou ~/.codex/skills.',
608
+ details: ['Afeta todos os projetos deste usuario.', 'Use apenas depois de aprovacao humana.'],
609
+ success: 'Skill instalada no diretorio global de skills.',
221
610
  command: nodeExecPath,
222
611
  args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--activate-interactive', '--target', 'global'],
223
612
  confirmMessage: 'Selecionar e ativar uma skill aprendida como skill global deste usuario?',
@@ -227,6 +616,8 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
227
616
  aliases: ['notion-summary', 'resumo-notion'],
228
617
  label: 'Abrir resumo para Notion',
229
618
  description: 'Mostra um resumo copiavel do estado de ativacao para registrar no ledger Notion.',
619
+ details: ['Nao escreve no Notion sozinho.', 'Gera texto de continuidade para documentacao.'],
620
+ success: 'Resumo pronto para registro exibido.',
230
621
  command: nodeExecPath,
231
622
  args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--notion-summary'],
232
623
  },
@@ -236,8 +627,9 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
236
627
  export function buildMenuChoices(commands) {
237
628
  return commands.map((command) => ({
238
629
  title: command.label,
239
- description: command.description,
630
+ description: [command.description, command.success ? `Resultado: ${command.success}` : null].filter(Boolean).join(' '),
240
631
  value: command.key,
632
+ disabled: command.disabledReason ?? false,
241
633
  })).concat({
242
634
  title: 'Sair',
243
635
  description: 'Fecha o menu operacional.',
@@ -261,6 +653,8 @@ export function isInteractiveTerminal() {
261
653
  }
262
654
 
263
655
  export function formatStatusReport(status) {
656
+ const readiness = status.globalReadiness;
657
+ const bundledCatalog = status.bundledCatalog ?? { total: 0, categories: [] };
264
658
  const lines = [
265
659
  'Skill Master MCP - status local',
266
660
  `Diretorio: ${status.rootDir}`,
@@ -270,6 +664,14 @@ export function formatStatusReport(status) {
270
664
  `Manifesto semver: ${status.manifestSemver}`,
271
665
  `Drafts de skills aprendidas: ${status.pendingSuccessDrafts}`,
272
666
  `Skills externas para estudar: ${status.studyCandidates}`,
667
+ `Global readiness: ${readiness.ready ? 'pronto' : readiness.mode}`,
668
+ `Global skills instaladas: ${readiness.installed.length}/${readiness.required}`,
669
+ `Bundle de skills embutidas: ${bundledCatalog.total}`,
670
+ `Dominios do bundle: ${formatBundledCategoryLine(bundledCatalog)}`,
671
+ `Codex global: ${readiness.codex.globalCommand ? 'sim' : readiness.codex.kind}`,
672
+ `Claude global: ${readiness.claude.globalCommand ? 'sim' : readiness.claude.present ? 'nao-global' : 'ausente'}`,
673
+ `Gemini global: ${readiness.gemini.globalCommand ? 'sim' : readiness.gemini.present ? 'nao-global' : 'ausente'}`,
674
+ `Antigravity global: ${readiness.antigravity.globalCommand ? 'sim' : readiness.antigravity.present ? 'nao-global' : 'ausente'}`,
273
675
  ];
274
676
 
275
677
  if (status.versionText) {
@@ -280,6 +682,41 @@ export function formatStatusReport(status) {
280
682
  return lines.join('\n');
281
683
  }
282
684
 
685
+ function formatGlobalAlert(status, { useColor = false } = {}) {
686
+ const readiness = status.globalReadiness;
687
+ if (readiness.ready) {
688
+ return renderPanelLines(
689
+ [
690
+ colorize('GLOBAL READY', ANSI.bold, useColor),
691
+ 'O MCP esta reconhecido como comando global neste computador.',
692
+ 'Codex, Claude, Gemini e Antigravity podem ser apontados para skill-master-mcp.',
693
+ 'A instalacao global e as skills embutidas ja estao prontas para uso.',
694
+ ],
695
+ { color: ANSI.green, useColor },
696
+ );
697
+ }
698
+
699
+ return [
700
+ renderPanelLines(
701
+ [
702
+ colorize('ALERTA GLOBAL', ANSI.bold, useColor),
703
+ 'Este computador ainda nao esta pronto para uso global do Skill Master.',
704
+ 'Execute agora: skill-master-menu --run bootstrap-global --yes',
705
+ 'Isso instala as skills globais e registra Codex, Claude, Gemini e Antigravity.',
706
+ ],
707
+ { color: ANSI.red, useColor },
708
+ ),
709
+ renderPanelLines(
710
+ [
711
+ colorize('AVISO SUTIL', ANSI.dim, useColor),
712
+ 'Sem instalacao global, o MCP continua util localmente, mas nao fica integrado como parte do sistema em todos os clientes.',
713
+ `Skills globais detectadas: ${readiness.installed.length}/${readiness.required}`,
714
+ ],
715
+ { color: ANSI.yellow, useColor },
716
+ ),
717
+ ].join('\n\n');
718
+ }
719
+
283
720
  function renderPanelLines(lines, { color = ANSI.cyan, useColor = false } = {}) {
284
721
  const width = Math.max(...lines.map((line) => line.length), 24);
285
722
  const border = `+${'-'.repeat(width + 2)}+`;
@@ -289,22 +726,372 @@ function renderPanelLines(lines, { color = ANSI.cyan, useColor = false } = {}) {
289
726
  }
290
727
 
291
728
  export function formatMenuBanner(status, { useColor = false } = {}) {
729
+ const bundledCatalog = status.bundledCatalog ?? { total: 0, categories: [] };
292
730
  const lines = [
293
731
  colorize('Skill Master MCP', ANSI.bold, useColor),
294
732
  'Menu operacional para manutencao local',
295
733
  `Versao local ${status.semver} | canal ${status.manifestVersion}`,
296
734
  `Pendencias: ${status.pendingSuccessDrafts} drafts | estudo: ${status.studyCandidates} links`,
735
+ `Global: ${status.globalReadiness.ready ? 'pronto' : 'requer instalacao global'}`,
736
+ `Bundle: ${bundledCatalog.total} skills | ${formatBundledCategoryLine(bundledCatalog)}`,
297
737
  colorize('Setas + Enter para navegar', ANSI.dim, useColor),
298
738
  ];
299
- return renderPanelLines(lines, { color: ANSI.cyan, useColor });
739
+ return [
740
+ renderPanelLines(lines, { color: ANSI.cyan, useColor }),
741
+ formatGlobalAlert(status, { useColor }),
742
+ ].join('\n\n');
743
+ }
744
+
745
+ function dnaPanelLines(tick, width, height, status, { useColor = false, compact = false } = {}) {
746
+ const lines = [];
747
+ const center = Math.floor(width / 2);
748
+ const graphLeft = 2;
749
+ const graphRight = Math.max(graphLeft + 8, width - 3);
750
+ const graphWidth = Math.max(10, graphRight - graphLeft + 1);
751
+ const radius = Math.max(3, Math.floor((graphWidth - 4) / 3.35));
752
+ const phase = tick / 6;
753
+ const bodyHeight = Math.max(compact ? 6 : 8, height - (compact ? 5 : 6));
754
+ const scanRow = bodyHeight > 0 ? tick % bodyHeight : 0;
755
+
756
+ lines.push(fitText(colorize('GENOME MATRIX', ANSI.bold, useColor), width));
757
+ lines.push(fitText(colorize(compact ? 'lab helix / scan stable' : 'procedural intelligence helix', ANSI.dim, useColor), width));
758
+ if (!compact) {
759
+ lines.push(fitText(colorize('signal map / sync locked / low flicker', ANSI.gray, useColor), width));
760
+ }
761
+
762
+ const place = (cells, col, char, color) => {
763
+ if (col >= 0 && col < width) cells[col] = colorize(char, color, useColor);
764
+ };
765
+
766
+ for (let row = 0; row < bodyHeight; row += 1) {
767
+ const angle = row * 0.49 + phase;
768
+ const left = Math.round(center + Math.sin(angle) * radius);
769
+ const right = Math.round(center + Math.sin(angle + Math.PI) * radius);
770
+ const min = Math.min(left, right);
771
+ const max = Math.max(left, right);
772
+ const chars = Array.from({ length: width }, () => ' ');
773
+ const front = Math.cos(angle) >= 0;
774
+ const leftColor = front ? ANSI.teal : ANSI.blue;
775
+ const rightColor = front ? ANSI.amber : ANSI.gray;
776
+ const bondColor = front ? ANSI.gray : ANSI.blue;
777
+ const scanActive = row === scanRow;
778
+
779
+ place(chars, graphLeft, row === 0 ? '┌' : row === bodyHeight - 1 ? '└' : '│', ANSI.gray);
780
+ place(chars, graphRight, row === 0 ? '┐' : row === bodyHeight - 1 ? '┘' : '│', ANSI.gray);
781
+
782
+ if (row === 0 || row === bodyHeight - 1) {
783
+ for (let col = graphLeft + 1; col < graphRight; col += 1) {
784
+ place(chars, col, '─', ANSI.gray);
785
+ }
786
+ }
787
+
788
+ for (let col = min + 2; col < max - 1; col += 1) {
789
+ const rungChar = row % 4 < 2 ? '═' : '─';
790
+ place(chars, col, scanActive ? '█' : rungChar, scanActive ? ANSI.white : bondColor);
791
+ }
792
+
793
+ place(chars, left - 1, '▓', leftColor);
794
+ place(chars, left, scanActive ? '█' : row % 2 === 0 ? '█' : '▓', scanActive ? ANSI.white : leftColor);
795
+ place(chars, left + 1, '▓', leftColor);
796
+ place(chars, right - 1, '▓', rightColor);
797
+ place(chars, right, scanActive ? '█' : row % 2 === 0 ? '█' : '▓', scanActive ? ANSI.white : rightColor);
798
+ place(chars, right + 1, '▓', rightColor);
799
+
800
+ if (row % 4 === 1 || row % 4 === 2) {
801
+ place(chars, center, scanActive ? '◆' : '◆', scanActive ? ANSI.white : ANSI.gray);
802
+ }
803
+
804
+ lines.push(chars.join(''));
805
+ }
806
+
807
+ lines.push(fitText('', width));
808
+ lines.push(fitText(colorize(compact ? 'helix stable' : 'helix stable lattice aligned', ANSI.gray, useColor), width));
809
+ lines.push(fitText(colorize(compact ? `global ${status.globalReadiness.installed.length}/${status.globalReadiness.required}` : `global ${status.globalReadiness.installed.length}/${status.globalReadiness.required} clients linked`, ANSI.amber, useColor), width));
810
+
811
+ return lines.slice(0, height).map((line) => fitText(line, width));
812
+ }
813
+
814
+ function renderMeterBar(value, total, width, { useColor = false, color = ANSI.teal } = {}) {
815
+ const safeTotal = Math.max(1, total);
816
+ const safeValue = Math.max(0, Math.min(value, safeTotal));
817
+ const fill = Math.round((safeValue / safeTotal) * width);
818
+ const filled = '█'.repeat(fill);
819
+ const empty = '░'.repeat(Math.max(0, width - fill));
820
+ return `${colorize(filled, color, useColor)}${colorize(empty, ANSI.gray, useColor)}`;
821
+ }
822
+
823
+ function renderSparkline(series, { useColor = false, color = ANSI.teal } = {}) {
824
+ const blocks = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
825
+ return series.map((value) => colorize(blocks[Math.max(0, Math.min(blocks.length - 1, value))], color, useColor)).join('');
826
+ }
827
+
828
+ function buildTelemetrySeries(seed, length, tick) {
829
+ return Array.from({ length }, (_, index) => {
830
+ const raw = Math.sin((index + 1 + seed) * 0.72 + tick * 0.18) + Math.cos((index + seed) * 0.33 + tick * 0.11);
831
+ const normalized = Math.max(0, Math.min(1, (raw + 2) / 4));
832
+ return Math.round(normalized * 7);
833
+ });
834
+ }
835
+
836
+ function buildOverviewSignalLine(status, width, tick, { useColor = false, compact = false } = {}) {
837
+ const signalWidth = Math.max(6, Math.min(compact ? 8 : 12, Math.floor(width / (compact ? 10 : 8))));
838
+ const healthWidth = Math.max(6, Math.min(compact ? 8 : 12, Math.floor(width / (compact ? 10 : 8))));
839
+ const signal = renderSparkline(
840
+ buildTelemetrySeries(status.globalReadiness.installed.length + status.pendingSuccessDrafts, signalWidth, tick),
841
+ { useColor, color: ANSI.teal },
842
+ );
843
+ const health = renderSparkline(
844
+ buildTelemetrySeries(status.studyCandidates + (status.globalReadiness.ready ? 7 : 3), healthWidth, tick + 3),
845
+ { useColor, color: ANSI.amber },
846
+ );
847
+ return compact
848
+ ? `signal ${signal} health ${health}`
849
+ : `signal ${signal} health ${health}`;
850
+ }
851
+
852
+ function telemetryPanelLines(status, selected, width, height, { useColor = false, tick = 0, compact = false } = {}) {
853
+ const commandArea = resolveCommandArea(selected);
854
+ const bundledCatalog = status.bundledCatalog ?? { total: 0, categories: [] };
855
+ const categoryLead = bundledCatalog.categories
856
+ ?.filter((category) => category.count > 0)
857
+ .sort((left, right) => right.count - left.count)[0];
858
+ const categoryName = categoryLead?.label ?? 'none';
859
+ const categoryCount = categoryLead?.count ?? 0;
860
+ const meterWidth = Math.max(8, Math.min(16, width - 14));
861
+ const sparkWidth = Math.max(8, Math.min(compact ? 8 : 12, width - 18));
862
+ const skillsSpark = renderSparkline(buildTelemetrySeries(status.globalReadiness.installed.length + categoryCount, sparkWidth, tick), { useColor, color: ANSI.amber });
863
+ const draftsSpark = renderSparkline(buildTelemetrySeries(status.pendingSuccessDrafts + 2, sparkWidth, tick + 2), { useColor, color: ANSI.teal });
864
+ const studySpark = renderSparkline(buildTelemetrySeries(status.studyCandidates + 4, sparkWidth, tick + 4), { useColor, color: ANSI.blue });
865
+ const lines = [
866
+ fitText(colorize('SYSTEM WINDOWS', ANSI.bold, useColor), width),
867
+ fitText(colorize(`selected area ${commandArea}`, ANSI.gray, useColor), width),
868
+ fitText(colorize(`dominant skill ${categoryName} ${categoryCount}`, ANSI.gray, useColor), width),
869
+ fitText(`bundle ${String(bundledCatalog.total).padStart(2, '0')} ${renderMeterBar(bundledCatalog.total, Math.max(36, bundledCatalog.total), meterWidth, { useColor, color: ANSI.white })}`, width),
870
+ fitText(`global ${status.globalReadiness.installed.length}/${status.globalReadiness.required} ${renderMeterBar(status.globalReadiness.installed.length, status.globalReadiness.required, meterWidth, { useColor, color: ANSI.amber })}`, width),
871
+ fitText(`skills ${skillsSpark}`, width),
872
+ fitText(`drafts ${String(status.pendingSuccessDrafts).padStart(2, '0')} ${renderMeterBar(status.pendingSuccessDrafts, Math.max(6, status.pendingSuccessDrafts || 1), meterWidth, { useColor, color: ANSI.teal })}`, width),
873
+ fitText(`queue ${draftsSpark}`, width),
874
+ fitText(`study ${String(status.studyCandidates).padStart(2, '0')} ${renderMeterBar(status.studyCandidates, Math.max(8, status.studyCandidates || 1), meterWidth, { useColor, color: ANSI.blue })}`, width),
875
+ fitText(`links ${studySpark}`, width),
876
+ fitText(colorize(compact ? 'codex / claude / gemini' : 'codex / claude / gemini / antigravity', ANSI.dim, useColor), width),
877
+ ];
878
+
879
+ return lines.slice(0, height).map((line) => fitText(line, width));
880
+ }
881
+
882
+ function renderBox(lines, width, title, { useColor = false, color = ANSI.cyan, style = 'normal' } = {}) {
883
+ const innerWidth = Math.max(10, width - 4);
884
+ const titleText = title ? ` ${title.toUpperCase()} ` : '';
885
+ const topLeft = style === 'focus' ? '╭' : style === 'hud' ? '┏' : '┌';
886
+ const topRight = style === 'focus' ? '╮' : style === 'hud' ? '┓' : '┐';
887
+ const bottomLeft = style === 'focus' ? '╰' : style === 'hud' ? '┗' : '└';
888
+ const bottomRight = style === 'focus' ? '╯' : style === 'hud' ? '┛' : '┘';
889
+ const topFill = style === 'focus' ? '═' : '─';
890
+ const bottomTail = style === 'focus' ? '══' : '┄┄';
891
+ const top = `${topLeft}${titleText}${topFill.repeat(Math.max(0, width - 2 - titleText.length))}${topRight}`;
892
+ const bottom = `${bottomLeft}${topFill.repeat(Math.max(0, width - 4))}${bottomTail}${bottomRight}`;
893
+ const body = lines.map((line, index) => {
894
+ const left = index === 0
895
+ ? (style === 'focus' ? '╞' : '├')
896
+ : index === lines.length - 1
897
+ ? (style === 'focus' ? '╘' : '╰')
898
+ : '│';
899
+ const right = index === 0
900
+ ? (style === 'focus' ? '╡' : '┤')
901
+ : index === lines.length - 1
902
+ ? (style === 'focus' ? '╛' : '╯')
903
+ : '│';
904
+ return `${colorize(left, color, useColor)} ${fitText(line, innerWidth)} ${colorize(right, color, useColor)}`;
905
+ });
906
+ return [
907
+ colorize(top, color, useColor),
908
+ ...body,
909
+ colorize(bottom, color, useColor),
910
+ ];
911
+ }
912
+
913
+ function joinHorizontalBoxes(boxes, gutter = 2) {
914
+ const height = Math.max(...boxes.map((box) => box.lines.length));
915
+ const gap = ' '.repeat(gutter);
916
+ const rows = [];
917
+
918
+ for (let index = 0; index < height; index += 1) {
919
+ rows.push(boxes.map((box) => box.lines[index] ?? ' '.repeat(box.width)).join(gap));
920
+ }
921
+
922
+ return rows;
923
+ }
924
+
925
+ export function formatCyberMenuFrame(status, commands, selectedIndex, tick = 0, {
926
+ columns = 120,
927
+ rows = 32,
928
+ useColor = false,
929
+ } = {}) {
930
+ const width = Math.max(72, Math.min(columns, 150));
931
+ const height = Math.max(22, Math.min(rows - 1, 42));
932
+ const compactMode = width < 104 || height < 27;
933
+ const rightWidth = compactMode ? (width >= 92 ? 28 : 26) : width >= 132 ? 44 : width >= 108 ? 38 : 30;
934
+ const gutter = 2;
935
+ const leftWidth = width - rightWidth - gutter;
936
+ const selected = commands[selectedIndex] ?? commands[0];
937
+ const actionArea = resolveCommandArea(selected);
938
+ const bundledCatalog = status.bundledCatalog ?? { total: 0, categories: [] };
939
+ const summaryOuterHeight = compactMode ? 7 : 8;
940
+ const bodyOuterHeight = Math.max(12, height - summaryOuterHeight - 1);
941
+ const detailOuterHeight = compactMode
942
+ ? Math.min(8, Math.max(7, Math.floor(bodyOuterHeight * 0.46)))
943
+ : Math.min(10, Math.max(8, Math.floor(bodyOuterHeight * 0.42)));
944
+ const actionOuterHeight = compactMode
945
+ ? Math.max(8, bodyOuterHeight - detailOuterHeight)
946
+ : Math.max(8, bodyOuterHeight - detailOuterHeight);
947
+ const rightBottomOuterHeight = compactMode
948
+ ? Math.min(8, Math.max(7, Math.floor(bodyOuterHeight * 0.4)))
949
+ : Math.min(10, Math.max(8, Math.floor(bodyOuterHeight * 0.34)));
950
+ const rightTopOuterHeight = Math.max(8, bodyOuterHeight - rightBottomOuterHeight);
951
+ const summaryInnerWidth = width - 4;
952
+ const actionInnerWidth = leftWidth - 4;
953
+ const detailInnerWidth = leftWidth - 4;
954
+ const rightInnerWidth = rightWidth - 4;
955
+ const summaryInnerHeight = summaryOuterHeight - 2;
956
+ const actionInnerHeight = actionOuterHeight - 2;
957
+ const detailInnerHeight = detailOuterHeight - 2;
958
+ const rightTopInnerHeight = rightTopOuterHeight - 2;
959
+ const rightBottomInnerHeight = rightBottomOuterHeight - 2;
960
+ const visibleActionRows = Math.max(compactMode ? 2 : 3, actionInnerHeight - (compactMode ? 2 : 3));
961
+ const scrollStart = Math.min(
962
+ Math.max(0, selectedIndex - Math.floor(visibleActionRows / 2)),
963
+ Math.max(0, commands.length - visibleActionRows),
964
+ );
965
+ const visibleCommands = commands.slice(scrollStart, scrollStart + visibleActionRows);
966
+
967
+ const summaryLines = compactMode
968
+ ? [
969
+ colorize('SKILL MASTER MENU', ANSI.bold, useColor),
970
+ `version ${status.semver} | channel ${status.manifestVersion} | readiness ${status.globalReadiness.ready ? 'ready' : status.globalReadiness.mode}`,
971
+ colorize(`GLOBAL SKILLS ${status.globalReadiness.installed.length}/${status.globalReadiness.required}`, ANSI.amber, useColor),
972
+ `bundle ${bundledCatalog.total} | drafts ${status.pendingSuccessDrafts} | study ${status.studyCandidates}`,
973
+ buildOverviewSignalLine(status, summaryInnerWidth, tick, { useColor, compact: true }),
974
+ colorize('compact cyberpunk hud / operator safe', ANSI.dim, useColor),
975
+ ]
976
+ : [
977
+ colorize('SKILL MASTER MENU', ANSI.bold, useColor),
978
+ `version ${status.semver} | channel ${status.manifestVersion} | readiness ${status.globalReadiness.ready ? 'ready' : status.globalReadiness.mode}`,
979
+ colorize(`GLOBAL SKILLS ${status.globalReadiness.installed.length}/${status.globalReadiness.required}`, ANSI.amber, useColor),
980
+ `bundle ${bundledCatalog.total} | drafts ${status.pendingSuccessDrafts} | study ${status.studyCandidates}`,
981
+ buildOverviewSignalLine(status, summaryInnerWidth, tick, { useColor, compact: false }),
982
+ formatBundledCategoryLine(bundledCatalog),
983
+ colorize('workflow windows / cyberpunk terminal / operator safe', ANSI.dim, useColor),
984
+ ];
985
+
986
+ const actionLines = [
987
+ colorize('ACTION GRID', ANSI.gray, useColor),
988
+ colorize('up/down move enter run q exit', ANSI.dim, useColor),
989
+ ...visibleCommands.map((command, offset) => {
990
+ const index = scrollStart + offset;
991
+ const marker = index === selectedIndex ? '▸' : '·';
992
+ const disabled = command.disabledReason ? ' [off]' : '';
993
+ const label = `${marker} ${command.label}${disabled}`;
994
+ return index === selectedIndex
995
+ ? colorize(fitText(label, actionInnerWidth), ANSI.teal, useColor)
996
+ : fitText(label, actionInnerWidth);
997
+ }),
998
+ ];
999
+
1000
+ while (actionLines.length < actionInnerHeight) {
1001
+ actionLines.push(fitText('', actionInnerWidth));
1002
+ }
1003
+
1004
+ const descriptionLines = [
1005
+ colorize('DETAIL FOCUS', ANSI.amber, useColor),
1006
+ colorize(selected?.label ?? 'Nenhuma acao', ANSI.bold, useColor),
1007
+ fitText(colorize(`area ${actionArea} | action ${Math.min(selectedIndex + 1, commands.length)}/${commands.length}`, ANSI.gray, useColor), detailInnerWidth),
1008
+ fitText(colorize('────────────────────────────────', ANSI.amber, useColor), detailInnerWidth),
1009
+ ...splitText(selected?.description, detailInnerWidth, 1),
1010
+ ...splitText(selected?.success ? `resultado: ${selected.success}` : '', detailInnerWidth, 1),
1011
+ ...splitText(`exec: ${formatActionCommand(selected)}`, detailInnerWidth, 1),
1012
+ ...(selected?.confirmMessage ? splitText(`confirmacao: ${selected.confirmMessage}`, detailInnerWidth, 2) : []),
1013
+ ...(selected?.disabledReason ? splitText(`Indisponivel: ${selected.disabledReason}`, detailInnerWidth, 2) : []),
1014
+ ];
1015
+
1016
+ while (descriptionLines.length < detailInnerHeight) {
1017
+ descriptionLines.push(fitText('', detailInnerWidth));
1018
+ }
1019
+
1020
+ const rightTopLines = dnaPanelLines(tick, rightInnerWidth, rightTopInnerHeight, status, { useColor, compact: compactMode });
1021
+ const rightBottomLines = telemetryPanelLines(status, selected, rightInnerWidth, rightBottomInnerHeight, { useColor, tick, compact: compactMode });
1022
+ const summaryBox = renderBox(
1023
+ summaryLines.slice(0, summaryInnerHeight).map((line) => fitText(line, summaryInnerWidth)),
1024
+ width,
1025
+ 'overview',
1026
+ { useColor, color: ANSI.white, style: 'hud' },
1027
+ );
1028
+ const actionBox = renderBox(
1029
+ actionLines.slice(0, actionInnerHeight).map((line) => fitText(line, actionInnerWidth)),
1030
+ leftWidth,
1031
+ 'actions',
1032
+ { useColor, color: ANSI.gray, style: 'normal' },
1033
+ );
1034
+ const detailBox = renderBox(
1035
+ descriptionLines.slice(0, detailInnerHeight).map((line) => fitText(line, detailInnerWidth)),
1036
+ leftWidth,
1037
+ 'details',
1038
+ { useColor, color: ANSI.amber, style: 'focus' },
1039
+ );
1040
+ const dnaBox = renderBox(rightTopLines, rightWidth, 'dna-core', { useColor, color: ANSI.white, style: 'hud' });
1041
+ const telemetryBox = renderBox(rightBottomLines, rightWidth, 'telemetry', { useColor, color: ANSI.blue, style: 'normal' });
1042
+ const bodyRows = joinHorizontalBoxes([
1043
+ { lines: [...actionBox, ...detailBox], width: leftWidth },
1044
+ { lines: [...dnaBox, ...telemetryBox], width: rightWidth },
1045
+ ], gutter);
1046
+
1047
+ return [...summaryBox, '', ...bodyRows].join('\n');
1048
+ }
1049
+
1050
+ export function formatRunningActionFrame(status, action, tick = 0, {
1051
+ columns = 120,
1052
+ rows = 32,
1053
+ useColor = false,
1054
+ } = {}) {
1055
+ const width = Math.max(72, Math.min(columns, 150));
1056
+ const height = Math.max(18, Math.min(rows - 1, 30));
1057
+ const innerWidth = width - 4;
1058
+ const commandArea = resolveCommandArea(action);
1059
+ const pulse = renderSparkline(buildTelemetrySeries((status.globalReadiness.installed.length || 1) + tick, Math.max(8, Math.min(18, Math.floor(innerWidth / 5))), tick), { useColor, color: ANSI.teal });
1060
+ const lines = [
1061
+ colorize('EXECUTION TRANSFER', ANSI.bold, useColor),
1062
+ fitText(colorize(`area ${commandArea} | launching ${action?.label ?? 'acao'}`, ANSI.amber, useColor), innerWidth),
1063
+ fitText(colorize(`pulse ${pulse}`, ANSI.gray, useColor), innerWidth),
1064
+ fitText('', innerWidth),
1065
+ ...splitText(action?.description ?? '', innerWidth, 2),
1066
+ ...splitText(action?.success ? `resultado esperado: ${action.success}` : '', innerWidth, 2),
1067
+ ...splitText(`exec: ${formatActionCommand(action)}`, innerWidth, 2),
1068
+ fitText('', innerWidth),
1069
+ fitText(colorize('alternando do HUD para o stream real do comando...', ANSI.dim, useColor), innerWidth),
1070
+ ];
1071
+
1072
+ while (lines.length < Math.max(8, height - 2)) {
1073
+ lines.push(fitText('', innerWidth));
1074
+ }
1075
+
1076
+ return renderBox(
1077
+ lines.slice(0, Math.max(8, height - 2)).map((line) => fitText(line, innerWidth)),
1078
+ width,
1079
+ 'running',
1080
+ { useColor, color: ANSI.teal, style: 'focus' },
1081
+ ).join('\n');
300
1082
  }
301
1083
 
302
1084
  export function formatActionHeader(action, { useColor = false } = {}) {
1085
+ const lines = [
1086
+ colorize(action.label, ANSI.bold, useColor),
1087
+ action.description,
1088
+ ...(action.details ?? []),
1089
+ action.success ? `Resultado esperado: ${action.success}` : null,
1090
+ action.disabledReason ? `Indisponivel: ${action.disabledReason}` : null,
1091
+ ].filter(Boolean);
1092
+
303
1093
  return renderPanelLines(
304
- [
305
- colorize(action.label, ANSI.bold, useColor),
306
- action.description,
307
- ],
1094
+ lines,
308
1095
  { color: ANSI.green, useColor },
309
1096
  );
310
1097
  }
@@ -318,7 +1105,11 @@ export function formatResultMessage(code, { useColor = false } = {}) {
318
1105
  }
319
1106
 
320
1107
  export function formatHelp(commands) {
321
- const actionList = commands.map((command) => ` - ${command.key}: ${command.label}`).join('\n');
1108
+ const actionList = commands.map((command) => {
1109
+ const aliases = command.aliases.length ? ` aliases: ${command.aliases.join(', ')}` : '';
1110
+ const disabled = command.disabledReason ? ` indisponivel: ${command.disabledReason}` : '';
1111
+ return ` - ${command.key}: ${command.label}\n ${command.description}${aliases}${disabled}`;
1112
+ }).join('\n');
322
1113
 
323
1114
  return `Skill Master Menu
324
1115