@fprad0/skill-master-mcp 0.0.9 → 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.
- package/CHANGELOG.md +11 -0
- package/README.md +16 -2
- package/VERSION.md +3 -3
- package/bin/lib/menu-core.mjs +651 -16
- package/bin/skill-master-bootstrap-global.mjs +14 -1
- package/bin/skill-master-doctor.mjs +168 -0
- package/bin/skill-master-install-global-skills.mjs +30 -10
- package/bin/skill-master-menu.mjs +184 -36
- package/bin/skill-master-register-clients.mjs +26 -3
- package/dist/index.js +30 -5
- package/dist/index.js.map +1 -1
- package/docs/skill-candidates/v0.0.10/cli-creator/LICENSE.txt +201 -0
- package/docs/skill-candidates/v0.0.10/cli-creator/SKILL.md +160 -0
- package/docs/skill-candidates/v0.0.10/cli-creator/agents/openai.yaml +4 -0
- package/docs/skill-candidates/v0.0.10/cli-creator/references/agent-cli-patterns.md +154 -0
- package/docs/skill-candidates/v0.0.10/developer-workstation-ops/SKILL.md +32 -0
- package/docs/skill-candidates/v0.0.10/figma/LICENSE.txt +2 -0
- package/docs/skill-candidates/v0.0.10/figma/SKILL.md +42 -0
- package/docs/skill-candidates/v0.0.10/figma/agents/openai.yaml +14 -0
- package/docs/skill-candidates/v0.0.10/figma/assets/figma-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/figma/assets/figma.png +0 -0
- package/docs/skill-candidates/v0.0.10/figma/assets/icon.svg +28 -0
- package/docs/skill-candidates/v0.0.10/figma/references/figma-mcp-config.md +35 -0
- package/docs/skill-candidates/v0.0.10/figma/references/figma-tools-and-prompts.md +34 -0
- package/docs/skill-candidates/v0.0.10/figma-code-connect-components/LICENSE.TXT +2 -0
- package/docs/skill-candidates/v0.0.10/figma-code-connect-components/SKILL.md +349 -0
- package/docs/skill-candidates/v0.0.10/figma-code-connect-components/agents/openai.yaml +14 -0
- package/docs/skill-candidates/v0.0.10/figma-code-connect-components/assets/figma-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/figma-code-connect-components/assets/figma.png +0 -0
- package/docs/skill-candidates/v0.0.10/figma-code-connect-components/assets/icon.svg +28 -0
- package/docs/skill-candidates/v0.0.10/figma-code-connect-components/references/mapping-checklist.md +7 -0
- package/docs/skill-candidates/v0.0.10/figma-code-connect-components/scripts/normalize_node_id.py +25 -0
- package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/LICENSE.TXT +2 -0
- package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/SKILL.md +537 -0
- package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/agents/openai.yaml +14 -0
- package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/assets/figma-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/assets/figma.png +0 -0
- package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/assets/icon.svg +28 -0
- package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/references/rule-template.md +15 -0
- package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/scripts/check_agents_md.sh +9 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-design/LICENSE.TXT +2 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-design/SKILL.md +341 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-design/agents/openai.yaml +14 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-design/assets/figma-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-design/assets/figma.png +0 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-design/assets/icon.svg +28 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-design/maintainers.yml +1 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/LICENSE.TXT +2 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/SKILL.md +314 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/agents/openai.yaml +14 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/assets/figma-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/assets/figma.png +0 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/assets/icon.svg +28 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/maintainers.yml +3 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/references/code-connect-setup.md +260 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/references/component-creation.md +1014 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/references/discovery-phase.md +518 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/references/documentation-creation.md +834 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/references/error-recovery.md +540 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/references/naming-conventions.md +527 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/references/token-creation.md +962 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/bindVariablesToComponent.js +110 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/cleanupOrphans.js +127 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createComponentWithVariants.js +148 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createDocumentationPage.js +139 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createSemanticTokens.js +108 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createVariableCollection.js +49 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/inspectFileStructure.js +121 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/rehydrateState.js +92 -0
- package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/validateCreation.js +83 -0
- package/docs/skill-candidates/v0.0.10/figma-implement-design/LICENSE.txt +2 -0
- package/docs/skill-candidates/v0.0.10/figma-implement-design/SKILL.md +258 -0
- package/docs/skill-candidates/v0.0.10/figma-implement-design/agents/openai.yaml +14 -0
- package/docs/skill-candidates/v0.0.10/figma-implement-design/assets/figma-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/figma-implement-design/assets/figma.png +0 -0
- package/docs/skill-candidates/v0.0.10/figma-implement-design/assets/icon.svg +28 -0
- package/docs/skill-candidates/v0.0.10/figma-use/LICENSE.TXT +2 -0
- package/docs/skill-candidates/v0.0.10/figma-use/SKILL.md +233 -0
- package/docs/skill-candidates/v0.0.10/figma-use/agents/openai.yaml +14 -0
- package/docs/skill-candidates/v0.0.10/figma-use/assets/figma-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/figma-use/assets/figma.png +0 -0
- package/docs/skill-candidates/v0.0.10/figma-use/assets/icon.svg +28 -0
- package/docs/skill-candidates/v0.0.10/figma-use/maintainers.yml +1 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/api-reference.md +301 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/common-patterns.md +512 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/component-patterns.md +488 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/effect-style-patterns.md +123 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/gotchas.md +599 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/maintainers.yml +12 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-patterns.md +513 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-standalone.d.ts +11293 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-standalone.index.md +441 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/text-style-patterns.md +203 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/validation-and-recovery.md +109 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/variable-patterns.md +354 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/maintainers.yml +9 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components--creating.md +17 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components--using.md +17 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components.md +50 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-effect-styles.md +52 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-text-styles.md +90 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables--creating.md +13 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables--using.md +13 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables.md +64 -0
- package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds.md +41 -0
- package/docs/skill-candidates/v0.0.10/frontend-design/LICENSE.txt +177 -0
- package/docs/skill-candidates/v0.0.10/frontend-design/SKILL.md +55 -0
- package/docs/skill-candidates/v0.0.10/frontend-ui-ux-systems/SKILL.md +32 -0
- package/docs/skill-candidates/v0.0.10/github/SKILL.md +74 -0
- package/docs/skill-candidates/v0.0.10/github/agents/openai.yaml +6 -0
- package/docs/skill-candidates/v0.0.10/github/assets/github-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/github/assets/github.png +0 -0
- package/docs/skill-candidates/v0.0.10/image-graphic-design-rendering/SKILL.md +28 -0
- package/docs/skill-candidates/v0.0.10/language-quality-pt-en-fr-it-ru/SKILL.md +28 -0
- package/docs/skill-candidates/v0.0.10/math-physics-reasoning/SKILL.md +28 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/LICENSE.txt +202 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/SKILL.md +236 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/reference/evaluation.md +602 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/reference/node_mcp_server.md +970 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/reference/python_mcp_server.md +719 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/connections.py +151 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/evaluation.py +373 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/requirements.txt +2 -0
- package/docs/skill-candidates/v0.0.10/mcp-client-readiness/SKILL.md +31 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/LICENSE.txt +201 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/SKILL.md +161 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/agents/openai.yaml +14 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/assets/openai-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/assets/openai.png +0 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/references/latest-model.md +37 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/references/prompting-guide.md +244 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/references/upgrade-guide.md +181 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/scripts/fetch-codex-manual.mjs +598 -0
- package/docs/skill-candidates/v0.0.10/openai-docs/scripts/resolve-latest-model-info.js +147 -0
- package/docs/skill-candidates/v0.0.10/playwright/LICENSE.txt +201 -0
- package/docs/skill-candidates/v0.0.10/playwright/NOTICE.txt +14 -0
- package/docs/skill-candidates/v0.0.10/playwright/SKILL.md +147 -0
- package/docs/skill-candidates/v0.0.10/playwright/agents/openai.yaml +6 -0
- package/docs/skill-candidates/v0.0.10/playwright/assets/playwright-small.svg +3 -0
- package/docs/skill-candidates/v0.0.10/playwright/assets/playwright.png +0 -0
- package/docs/skill-candidates/v0.0.10/playwright/references/cli.md +116 -0
- package/docs/skill-candidates/v0.0.10/playwright/references/workflows.md +95 -0
- package/docs/skill-candidates/v0.0.10/playwright/scripts/playwright_cli.sh +25 -0
- package/docs/skill-candidates/v0.0.10/polyglot-backend-engineering/SKILL.md +32 -0
- package/docs/skill-candidates/v0.0.10/screenshot/LICENSE.txt +201 -0
- package/docs/skill-candidates/v0.0.10/screenshot/SKILL.md +267 -0
- package/docs/skill-candidates/v0.0.10/screenshot/agents/openai.yaml +6 -0
- package/docs/skill-candidates/v0.0.10/screenshot/assets/screenshot-small.svg +5 -0
- package/docs/skill-candidates/v0.0.10/screenshot/assets/screenshot.png +0 -0
- package/docs/skill-candidates/v0.0.10/screenshot/scripts/ensure_macos_permissions.sh +54 -0
- package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_display_info.swift +22 -0
- package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_permissions.swift +40 -0
- package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_window_info.swift +126 -0
- package/docs/skill-candidates/v0.0.10/screenshot/scripts/take_screenshot.ps1 +163 -0
- package/docs/skill-candidates/v0.0.10/screenshot/scripts/take_screenshot.py +585 -0
- package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/SKILL.md +62 -0
- package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/agents/openai.yaml +4 -0
- package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/activation-policy.md +77 -0
- package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/human-approval-policy.md +83 -0
- package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/persona-dev-senior-master.md +46 -0
- package/docs/skill-candidates/v0.0.10/terminal-menu-operations/SKILL.md +30 -0
- package/docs/skill-candidates/v0.0.10/terminal-pixel-art-tui/SKILL.md +43 -0
- package/docs/skill-candidates/v0.0.10/webapp-testing/LICENSE.txt +202 -0
- package/docs/skill-candidates/v0.0.10/webapp-testing/SKILL.md +96 -0
- package/docs/skill-candidates/v0.0.10/webapp-testing/examples/console_logging.py +35 -0
- package/docs/skill-candidates/v0.0.10/webapp-testing/examples/element_discovery.py +40 -0
- package/docs/skill-candidates/v0.0.10/webapp-testing/examples/static_html_automation.py +33 -0
- package/docs/skill-candidates/v0.0.10/webapp-testing/scripts/with_server.py +106 -0
- package/docs/skill-candidates/v0.0.10/winui-app/LICENSE.txt +202 -0
- package/docs/skill-candidates/v0.0.10/winui-app/SKILL.md +94 -0
- package/docs/skill-candidates/v0.0.10/winui-app/agents/openai.yaml +5 -0
- package/docs/skill-candidates/v0.0.10/winui-app/assets/winui.png +0 -0
- package/docs/skill-candidates/v0.0.10/winui-app/config.yaml +50 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/_sections.md +96 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/accessibility-input-and-localization.md +51 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/build-run-and-launch-verification.md +72 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/community-toolkit-controls-and-helpers.md +57 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/controls-layout-and-adaptive-ui.md +84 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-environment-audit-and-remediation.md +82 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-setup-and-project-selection.md +67 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-template-first-recovery.md +62 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-winui-app-structure.md +62 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/motion-animations-and-polish.md +45 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/performance-diagnostics-and-responsiveness.md +46 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/sample-source-map.md +37 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/shell-navigation-and-windowing.md +67 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/styling-theming-materials-and-icons.md +71 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/testing-debugging-and-review-checklists.md +77 -0
- package/docs/skill-candidates/v0.0.10/winui-app/references/windows-app-sdk-lifecycle-notifications-and-deployment.md +52 -0
- package/manifests/channels/beta.json +7 -7
- package/manifests/channels/stable.json +8 -8
- package/network/unapproved-skill-candidates.json +34 -1
- package/package.json +2 -1
|
@@ -6,6 +6,20 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
|
|
7
7
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
const rootDir = dirname(here);
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
|
|
11
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
12
|
+
console.log(`Skill Master global bootstrap
|
|
13
|
+
|
|
14
|
+
Uso:
|
|
15
|
+
skill-master-bootstrap-global
|
|
16
|
+
|
|
17
|
+
Instala as skills globais embutidas e registra o MCP skill_master em Codex,
|
|
18
|
+
Claude Desktop, Gemini e Antigravity usando o binario global skill-master-mcp.
|
|
19
|
+
Reinicie os clientes depois da execucao.
|
|
20
|
+
`);
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
9
23
|
|
|
10
24
|
const steps = [
|
|
11
25
|
{
|
|
@@ -32,4 +46,3 @@ for (const step of steps) {
|
|
|
32
46
|
if ((process.exitCode ?? 0) === 0) {
|
|
33
47
|
console.log('[skill_master] Global bootstrap complete.');
|
|
34
48
|
}
|
|
35
|
-
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const rootDir = path.resolve(here, '..');
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const has = (flag) => args.includes(flag);
|
|
12
|
+
|
|
13
|
+
if (has('--help') || has('-h')) {
|
|
14
|
+
console.log(`Skill Master Doctor
|
|
15
|
+
|
|
16
|
+
Uso:
|
|
17
|
+
skill-master-doctor
|
|
18
|
+
skill-master-doctor --strict
|
|
19
|
+
|
|
20
|
+
Valida pacote, binarios, skills globais e registro MCP em Codex, Claude,
|
|
21
|
+
Gemini e Antigravity. Nao publica versoes e nao altera configuracoes.
|
|
22
|
+
`);
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const REQUIRED_GLOBAL_SKILLS = [
|
|
27
|
+
'catholic-moral-discernment',
|
|
28
|
+
'ai-ethics-human-dignity',
|
|
29
|
+
'professional-boundary-triage',
|
|
30
|
+
'broad-domain-router',
|
|
31
|
+
'language-quality-pt-en-fr',
|
|
32
|
+
'math-science-reasoning',
|
|
33
|
+
'philosophy-sociology-discernment',
|
|
34
|
+
'engineering-systems-master',
|
|
35
|
+
'source-authority-reviewer',
|
|
36
|
+
'release-ethics-gate',
|
|
37
|
+
'mcp-client-readiness',
|
|
38
|
+
'terminal-menu-operations',
|
|
39
|
+
'terminal-pixel-art-tui',
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
const REQUIRED_BINS = [
|
|
43
|
+
'skill-master-menu',
|
|
44
|
+
'skill-master-mcp',
|
|
45
|
+
'skill-master-update',
|
|
46
|
+
'skill-master-bootstrap-global',
|
|
47
|
+
'skill-master-install-global-skills',
|
|
48
|
+
'skill-master-register-clients',
|
|
49
|
+
'skill-master-doctor',
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
function defaultClaudeConfigPath() {
|
|
53
|
+
if (process.platform === 'win32') {
|
|
54
|
+
return path.join(process.env.APPDATA ?? path.join(os.homedir(), 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (process.platform === 'darwin') {
|
|
58
|
+
return path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return path.join(os.homedir(), '.config', 'Claude', 'claude_desktop_config.json');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function readJson(filePath) {
|
|
65
|
+
if (!existsSync(filePath)) return null;
|
|
66
|
+
try {
|
|
67
|
+
const raw = readFileSync(filePath, 'utf8').trim();
|
|
68
|
+
return raw ? JSON.parse(raw) : {};
|
|
69
|
+
} catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function commandExists(command) {
|
|
75
|
+
const lookup = process.platform === 'win32' ? 'where' : 'command';
|
|
76
|
+
const lookupArgs = process.platform === 'win32' ? [command] : ['-v', command];
|
|
77
|
+
const result = spawnSync(lookup, lookupArgs, { shell: process.platform !== 'win32', stdio: 'ignore' });
|
|
78
|
+
return result.status === 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function jsonClientState(filePath) {
|
|
82
|
+
const parsed = readJson(filePath);
|
|
83
|
+
const server = parsed?.mcpServers?.skill_master;
|
|
84
|
+
return {
|
|
85
|
+
filePath,
|
|
86
|
+
present: Boolean(parsed),
|
|
87
|
+
configured: server?.command === 'skill-master-mcp',
|
|
88
|
+
command: server?.command ?? null,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function codexState(filePath) {
|
|
93
|
+
if (!existsSync(filePath)) {
|
|
94
|
+
return { filePath, present: false, configured: false, command: null };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const content = readFileSync(filePath, 'utf8');
|
|
98
|
+
return {
|
|
99
|
+
filePath,
|
|
100
|
+
present: true,
|
|
101
|
+
configured: content.includes('[mcp_servers.skill_master]') && content.includes('command = "skill-master-mcp"'),
|
|
102
|
+
command: content.includes('skill-master-mcp') ? 'skill-master-mcp' : null,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function resultLine(ok, label, detail) {
|
|
107
|
+
const marker = ok ? 'OK' : 'NO';
|
|
108
|
+
return `[${marker}] ${label}${detail ? ` - ${detail}` : ''}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const packageJson = readJson(path.join(rootDir, 'package.json'));
|
|
112
|
+
const globalSkillsRoot = path.join(process.env.CODEX_HOME ?? path.join(os.homedir(), '.codex'), 'skills');
|
|
113
|
+
const installedSkills = REQUIRED_GLOBAL_SKILLS.filter((skill) => existsSync(path.join(globalSkillsRoot, skill, 'SKILL.md')));
|
|
114
|
+
const missingSkills = REQUIRED_GLOBAL_SKILLS.filter((skill) => !installedSkills.includes(skill));
|
|
115
|
+
|
|
116
|
+
const clients = [
|
|
117
|
+
['Codex', codexState(path.join(process.env.CODEX_HOME ?? path.join(os.homedir(), '.codex'), 'config.toml'))],
|
|
118
|
+
['Claude Desktop', jsonClientState(defaultClaudeConfigPath())],
|
|
119
|
+
['Gemini CLI', jsonClientState(path.join(os.homedir(), '.gemini', 'settings.json'))],
|
|
120
|
+
['Antigravity', jsonClientState(path.join(os.homedir(), '.gemini', 'config', 'mcp_config.json'))],
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
const binResults = REQUIRED_BINS.map((bin) => [bin, commandExists(bin)]);
|
|
124
|
+
const allBinsOk = binResults.every(([, ok]) => ok);
|
|
125
|
+
const allSkillsOk = missingSkills.length === 0;
|
|
126
|
+
const allClientsOk = clients.every(([, state]) => state.configured);
|
|
127
|
+
const packageOk = packageJson?.name === '@fprad0/skill-master-mcp';
|
|
128
|
+
|
|
129
|
+
console.log('Skill Master Doctor');
|
|
130
|
+
console.log(`- Root: ${rootDir}`);
|
|
131
|
+
console.log(`- Package: ${packageJson?.name ?? 'unknown'}@${packageJson?.version ?? 'unknown'}`);
|
|
132
|
+
console.log('');
|
|
133
|
+
|
|
134
|
+
console.log(resultLine(packageOk, 'Pacote local reconhecido', packageOk ? packageJson.version : 'package.json inesperado'));
|
|
135
|
+
console.log(resultLine(allBinsOk, 'Binarios globais no PATH', binResults.filter(([, ok]) => !ok).map(([bin]) => bin).join(', ') || 'todos encontrados'));
|
|
136
|
+
for (const [bin, ok] of binResults) {
|
|
137
|
+
console.log(` ${resultLine(ok, bin)}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.log('');
|
|
141
|
+
console.log(resultLine(allSkillsOk, `Skills globais ${installedSkills.length}/${REQUIRED_GLOBAL_SKILLS.length}`, missingSkills.join(', ') || 'todas instaladas'));
|
|
142
|
+
console.log(`- Skills root: ${globalSkillsRoot}`);
|
|
143
|
+
|
|
144
|
+
console.log('');
|
|
145
|
+
for (const [name, state] of clients) {
|
|
146
|
+
const detail = state.configured
|
|
147
|
+
? state.filePath
|
|
148
|
+
: state.present
|
|
149
|
+
? `presente, mas command=${state.command ?? 'nao encontrado'} em ${state.filePath}`
|
|
150
|
+
: `ausente em ${state.filePath}`;
|
|
151
|
+
console.log(resultLine(state.configured, `${name} configurado`, detail));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const ready = packageOk && allBinsOk && allSkillsOk && allClientsOk;
|
|
155
|
+
console.log('');
|
|
156
|
+
console.log(resultLine(ready, 'Readiness global', ready ? 'pronto' : 'requer acao'));
|
|
157
|
+
|
|
158
|
+
if (!ready) {
|
|
159
|
+
console.log('');
|
|
160
|
+
console.log('Proximo comando recomendado:');
|
|
161
|
+
console.log(' skill-master-menu --run bootstrap-global --yes');
|
|
162
|
+
console.log('');
|
|
163
|
+
console.log('Depois reinicie Codex, Claude, Gemini e Antigravity.');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (has('--strict') && !ready) {
|
|
167
|
+
process.exitCode = 1;
|
|
168
|
+
}
|
|
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
|
|
7
7
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
const rootDir = path.resolve(here, '..');
|
|
9
|
-
const defaultSource = path.join(rootDir, 'docs', 'skill-candidates'
|
|
9
|
+
const defaultSource = path.join(rootDir, 'docs', 'skill-candidates');
|
|
10
10
|
const defaultTarget = path.join(process.env.CODEX_HOME ?? path.join(os.homedir(), '.codex'), 'skills');
|
|
11
11
|
|
|
12
12
|
const args = process.argv.slice(2);
|
|
@@ -24,8 +24,11 @@ Uso:
|
|
|
24
24
|
skill-master-install-global-skills --overwrite
|
|
25
25
|
skill-master-install-global-skills --dry-run
|
|
26
26
|
skill-master-install-global-skills --target ~/.codex/skills
|
|
27
|
+
skill-master-install-global-skills --source ./docs/skill-candidates/v0.0.10
|
|
27
28
|
|
|
28
29
|
Instala as skills globais embutidas em CODEX_HOME/skills ou ~/.codex/skills.
|
|
30
|
+
Quando --source aponta para docs/skill-candidates, todas as pastas versionadas v*
|
|
31
|
+
sao lidas.
|
|
29
32
|
`);
|
|
30
33
|
process.exit(0);
|
|
31
34
|
}
|
|
@@ -40,10 +43,28 @@ if (!existsSync(source)) {
|
|
|
40
43
|
process.exit(1);
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
const listSkillSources = (sourcePath) => {
|
|
47
|
+
const entries = readdirSync(sourcePath, { withFileTypes: true });
|
|
48
|
+
const directSkills = entries
|
|
49
|
+
.filter((entry) => entry.isDirectory() && existsSync(path.join(sourcePath, entry.name, 'SKILL.md')))
|
|
50
|
+
.map((entry) => ({ name: entry.name, path: path.join(sourcePath, entry.name) }));
|
|
51
|
+
|
|
52
|
+
if (directSkills.length) {
|
|
53
|
+
return directSkills;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return entries
|
|
57
|
+
.filter((entry) => entry.isDirectory())
|
|
58
|
+
.flatMap((entry) => {
|
|
59
|
+
const versionPath = path.join(sourcePath, entry.name);
|
|
60
|
+
return readdirSync(versionPath, { withFileTypes: true })
|
|
61
|
+
.filter((skillEntry) => skillEntry.isDirectory() && existsSync(path.join(versionPath, skillEntry.name, 'SKILL.md')))
|
|
62
|
+
.map((skillEntry) => ({ name: skillEntry.name, path: path.join(versionPath, skillEntry.name) }));
|
|
63
|
+
})
|
|
64
|
+
.sort((left, right) => left.name.localeCompare(right.name));
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const skills = listSkillSources(source);
|
|
47
68
|
|
|
48
69
|
if (!dryRun) {
|
|
49
70
|
mkdirSync(target, { recursive: true });
|
|
@@ -53,16 +74,16 @@ const installed = [];
|
|
|
53
74
|
const skipped = [];
|
|
54
75
|
|
|
55
76
|
for (const skill of skills) {
|
|
56
|
-
const from = path
|
|
57
|
-
const to = path.join(target, skill);
|
|
77
|
+
const from = skill.path;
|
|
78
|
+
const to = path.join(target, skill.name);
|
|
58
79
|
if (existsSync(to) && !overwrite) {
|
|
59
|
-
skipped.push(skill);
|
|
80
|
+
skipped.push(skill.name);
|
|
60
81
|
continue;
|
|
61
82
|
}
|
|
62
83
|
if (!dryRun) {
|
|
63
84
|
cpSync(from, to, { recursive: true, force: overwrite });
|
|
64
85
|
}
|
|
65
|
-
installed.push(skill);
|
|
86
|
+
installed.push(skill.name);
|
|
66
87
|
}
|
|
67
88
|
|
|
68
89
|
console.log('[skill_master] Global skills installer');
|
|
@@ -74,4 +95,3 @@ if (dryRun) console.log('- Dry run: no files were written.');
|
|
|
74
95
|
if (installed.length) console.log(`- Installed skills: ${installed.join(', ')}`);
|
|
75
96
|
if (skipped.length) console.log(`- Skipped skills: ${skipped.join(', ')}`);
|
|
76
97
|
console.log('[skill_master] Restart or rescan Codex to load new global skills.');
|
|
77
|
-
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import prompts from 'prompts';
|
|
4
|
+
import readline from 'node:readline';
|
|
4
5
|
import { dirname } from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
7
|
import {
|
|
7
|
-
buildMenuChoices,
|
|
8
8
|
buildMenuCommands,
|
|
9
9
|
formatActionHeader,
|
|
10
|
+
formatCyberMenuFrame,
|
|
10
11
|
formatHelp,
|
|
11
|
-
|
|
12
|
+
formatRunningActionFrame,
|
|
12
13
|
formatResultMessage,
|
|
13
14
|
formatStatusReport,
|
|
14
15
|
getMenuStatus,
|
|
@@ -20,6 +21,19 @@ import {
|
|
|
20
21
|
const currentFile = fileURLToPath(import.meta.url);
|
|
21
22
|
const rootDir = dirname(dirname(currentFile));
|
|
22
23
|
const commands = buildMenuCommands({ rootDir, currentFile });
|
|
24
|
+
readline.emitKeypressEvents(process.stdin);
|
|
25
|
+
const CONTROL = {
|
|
26
|
+
alternateScreenIn: '\x1b[?1049h',
|
|
27
|
+
alternateScreenOut: '\x1b[?1049l',
|
|
28
|
+
hideCursor: '\x1b[?25l',
|
|
29
|
+
showCursor: '\x1b[?25h',
|
|
30
|
+
cursorHome: '\x1b[H',
|
|
31
|
+
clearScreen: '\x1b[2J',
|
|
32
|
+
clearToEnd: '\x1b[0J',
|
|
33
|
+
reset: '\x1b[0m',
|
|
34
|
+
syncStart: '\x1b[?2026h',
|
|
35
|
+
syncEnd: '\x1b[?2026l',
|
|
36
|
+
};
|
|
23
37
|
|
|
24
38
|
function parseArgs(argv) {
|
|
25
39
|
const parsed = {
|
|
@@ -62,6 +76,10 @@ function printStatus() {
|
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
async function runSelectedAction(action, { yes = false, useColor = false } = {}) {
|
|
79
|
+
if (action.disabledReason) {
|
|
80
|
+
throw new Error(`Action ${action.key} is unavailable here: ${action.disabledReason}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
65
83
|
if (action.confirmMessage && !yes) {
|
|
66
84
|
if (!isInteractiveTerminal()) {
|
|
67
85
|
throw new Error(`Action ${action.key} requires --yes outside an interactive terminal.`);
|
|
@@ -88,47 +106,177 @@ async function runSelectedAction(action, { yes = false, useColor = false } = {})
|
|
|
88
106
|
return { cancelled: false, code };
|
|
89
107
|
}
|
|
90
108
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const status = getMenuStatus(rootDir);
|
|
95
|
-
console.log(formatMenuBanner(status, { useColor: true }));
|
|
96
|
-
console.log('');
|
|
97
|
-
|
|
98
|
-
const selection = await prompts({
|
|
99
|
-
type: 'select',
|
|
100
|
-
name: 'action',
|
|
101
|
-
message: 'Escolha uma acao',
|
|
102
|
-
choices: buildMenuChoices(commands),
|
|
103
|
-
initial: 0,
|
|
104
|
-
});
|
|
109
|
+
const readKey = () => new Promise((resolve) => {
|
|
110
|
+
process.stdin.once('keypress', (_str, key) => resolve(key));
|
|
111
|
+
});
|
|
105
112
|
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
function createKeyReader() {
|
|
114
|
+
const queue = [];
|
|
115
|
+
const waiters = [];
|
|
116
|
+
const onKeypress = (_str, key) => {
|
|
117
|
+
const waiter = waiters.shift();
|
|
118
|
+
if (waiter) {
|
|
119
|
+
clearTimeout(waiter.timer);
|
|
120
|
+
waiter.resolve(key);
|
|
121
|
+
return;
|
|
108
122
|
}
|
|
123
|
+
queue.push(key);
|
|
124
|
+
};
|
|
109
125
|
|
|
110
|
-
|
|
111
|
-
if (!action) {
|
|
112
|
-
return 1;
|
|
113
|
-
}
|
|
126
|
+
process.stdin.on('keypress', onKeypress);
|
|
114
127
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
128
|
+
return {
|
|
129
|
+
read(timeoutMs) {
|
|
130
|
+
if (queue.length) return Promise.resolve(queue.shift());
|
|
131
|
+
return new Promise((resolve) => {
|
|
132
|
+
const waiter = {
|
|
133
|
+
resolve,
|
|
134
|
+
timer: setTimeout(() => {
|
|
135
|
+
const index = waiters.indexOf(waiter);
|
|
136
|
+
if (index >= 0) waiters.splice(index, 1);
|
|
137
|
+
resolve(null);
|
|
138
|
+
}, timeoutMs),
|
|
139
|
+
};
|
|
140
|
+
waiters.push(waiter);
|
|
141
|
+
});
|
|
142
|
+
},
|
|
143
|
+
close() {
|
|
144
|
+
for (const waiter of waiters.splice(0)) {
|
|
145
|
+
clearTimeout(waiter.timer);
|
|
146
|
+
waiter.resolve(null);
|
|
147
|
+
}
|
|
148
|
+
process.stdin.off('keypress', onKeypress);
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
119
152
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
153
|
+
function setRawInput(enabled) {
|
|
154
|
+
if (typeof process.stdin.setRawMode === 'function') {
|
|
155
|
+
process.stdin.setRawMode(enabled);
|
|
156
|
+
}
|
|
157
|
+
if (enabled) process.stdin.resume();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function restoreMenuInput() {
|
|
161
|
+
setRawInput(true);
|
|
162
|
+
process.stdin.resume();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function enterVisualScreen() {
|
|
166
|
+
process.stdout.write(`${CONTROL.alternateScreenIn}${CONTROL.hideCursor}${CONTROL.clearScreen}${CONTROL.cursorHome}`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function leaveVisualScreen() {
|
|
170
|
+
process.stdout.write(`${CONTROL.reset}${CONTROL.showCursor}${CONTROL.alternateScreenOut}`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function writeStableFrame(frame, { clear = false } = {}) {
|
|
174
|
+
const prefix = clear ? CONTROL.clearScreen : '';
|
|
175
|
+
process.stdout.write([
|
|
176
|
+
CONTROL.syncStart,
|
|
177
|
+
CONTROL.cursorHome,
|
|
178
|
+
prefix,
|
|
179
|
+
frame,
|
|
180
|
+
'\n',
|
|
181
|
+
CONTROL.clearToEnd,
|
|
182
|
+
CONTROL.syncEnd,
|
|
183
|
+
].join(''));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function renderCyberMenu(selectedIndex, tick, { clear = false } = {}) {
|
|
187
|
+
const status = getMenuStatus(rootDir);
|
|
188
|
+
const frame = formatCyberMenuFrame(status, commands, selectedIndex, tick, {
|
|
189
|
+
columns: process.stdout.columns ?? 120,
|
|
190
|
+
rows: process.stdout.rows ?? 32,
|
|
191
|
+
useColor: true,
|
|
192
|
+
});
|
|
193
|
+
writeStableFrame(frame, { clear });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function renderRunningAction(action, tick) {
|
|
197
|
+
const status = getMenuStatus(rootDir);
|
|
198
|
+
const frame = formatRunningActionFrame(status, action, tick, {
|
|
199
|
+
columns: process.stdout.columns ?? 120,
|
|
200
|
+
rows: process.stdout.rows ?? 32,
|
|
201
|
+
useColor: true,
|
|
202
|
+
});
|
|
203
|
+
writeStableFrame(frame, { clear: true });
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
207
|
+
|
|
208
|
+
async function waitForAnyKey(message = 'Pressione qualquer tecla para voltar ao menu...') {
|
|
209
|
+
process.stdout.write(`\n${message}`);
|
|
210
|
+
setRawInput(true);
|
|
211
|
+
await readKey();
|
|
212
|
+
setRawInput(false);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function runVisualMenu() {
|
|
216
|
+
let selectedIndex = 0;
|
|
217
|
+
let tick = 0;
|
|
218
|
+
let lastCode = 0;
|
|
219
|
+
let keyReader = createKeyReader();
|
|
220
|
+
let previousColumns = process.stdout.columns ?? 120;
|
|
221
|
+
let previousRows = process.stdout.rows ?? 32;
|
|
222
|
+
let needsClear = true;
|
|
223
|
+
|
|
224
|
+
enterVisualScreen();
|
|
225
|
+
restoreMenuInput();
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
while (true) {
|
|
229
|
+
const columns = process.stdout.columns ?? 120;
|
|
230
|
+
const rows = process.stdout.rows ?? 32;
|
|
231
|
+
const resized = columns !== previousColumns || rows !== previousRows;
|
|
232
|
+
previousColumns = columns;
|
|
233
|
+
previousRows = rows;
|
|
234
|
+
renderCyberMenu(selectedIndex, tick, { clear: needsClear || resized });
|
|
235
|
+
needsClear = false;
|
|
236
|
+
const key = await keyReader.read(240);
|
|
237
|
+
|
|
238
|
+
if (!key) {
|
|
239
|
+
tick += 1;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
128
242
|
|
|
129
|
-
|
|
130
|
-
return
|
|
243
|
+
if (key.ctrl && key.name === 'c') return 130;
|
|
244
|
+
if (key.name === 'escape' || key.name === 'q') return lastCode;
|
|
245
|
+
if (key.name === 'up' || key.name === 'k') {
|
|
246
|
+
selectedIndex = selectedIndex === 0 ? commands.length - 1 : selectedIndex - 1;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (key.name === 'down' || key.name === 'j') {
|
|
250
|
+
selectedIndex = selectedIndex === commands.length - 1 ? 0 : selectedIndex + 1;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
if (key.name === 'return' || key.name === 'enter') {
|
|
254
|
+
const action = commands[selectedIndex];
|
|
255
|
+
keyReader.close();
|
|
256
|
+
renderRunningAction(action, tick);
|
|
257
|
+
await sleep(180);
|
|
258
|
+
setRawInput(false);
|
|
259
|
+
leaveVisualScreen();
|
|
260
|
+
try {
|
|
261
|
+
const result = await runSelectedAction(action, { useColor: true });
|
|
262
|
+
lastCode = result.code;
|
|
263
|
+
} catch (error) {
|
|
264
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
265
|
+
process.stderr.write(`[skill_master] ${message}\n`);
|
|
266
|
+
lastCode = 1;
|
|
267
|
+
}
|
|
268
|
+
await waitForAnyKey();
|
|
269
|
+
keyReader = createKeyReader();
|
|
270
|
+
restoreMenuInput();
|
|
271
|
+
enterVisualScreen();
|
|
272
|
+
needsClear = true;
|
|
273
|
+
}
|
|
131
274
|
}
|
|
275
|
+
} finally {
|
|
276
|
+
keyReader.close();
|
|
277
|
+
setRawInput(false);
|
|
278
|
+
process.stdin.pause();
|
|
279
|
+
leaveVisualScreen();
|
|
132
280
|
}
|
|
133
281
|
}
|
|
134
282
|
|
|
@@ -18,6 +18,7 @@ Uso:
|
|
|
18
18
|
skill-master-register-clients --apply-codex
|
|
19
19
|
skill-master-register-clients --apply-claude
|
|
20
20
|
skill-master-register-clients --apply-gemini
|
|
21
|
+
skill-master-register-clients --apply-antigravity
|
|
21
22
|
skill-master-register-clients --apply-all
|
|
22
23
|
skill-master-register-clients --apply-codex --force
|
|
23
24
|
|
|
@@ -30,14 +31,25 @@ Registra o servidor MCP skill_master como stdio usando o binario global:
|
|
|
30
31
|
const home = os.homedir();
|
|
31
32
|
const snippetsDir = readValue('--snippets-dir', path.join(home, '.skill-master', 'client-configs'));
|
|
32
33
|
const codexConfig = readValue('--codex-config', path.join(process.env.CODEX_HOME ?? path.join(home, '.codex'), 'config.toml'));
|
|
33
|
-
const
|
|
34
|
+
const defaultClaudeConfig = () => {
|
|
35
|
+
if (process.platform === 'win32') {
|
|
36
|
+
return path.join(process.env.APPDATA ?? path.join(home, 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
|
|
37
|
+
}
|
|
38
|
+
if (process.platform === 'darwin') {
|
|
39
|
+
return path.join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
40
|
+
}
|
|
41
|
+
return path.join(home, '.config', 'Claude', 'claude_desktop_config.json');
|
|
42
|
+
};
|
|
43
|
+
const claudeConfig = readValue('--claude-config', defaultClaudeConfig());
|
|
34
44
|
const geminiConfig = readValue('--gemini-config', path.join(home, '.gemini', 'settings.json'));
|
|
45
|
+
const antigravityConfig = readValue('--antigravity-config', path.join(home, '.gemini', 'config', 'mcp_config.json'));
|
|
35
46
|
|
|
36
47
|
const applyAll = has('--apply-all');
|
|
37
48
|
const applyCodex = applyAll || has('--apply-codex');
|
|
38
49
|
const applyClaude = applyAll || has('--apply-claude');
|
|
39
50
|
const applyGemini = applyAll || has('--apply-gemini');
|
|
40
|
-
const
|
|
51
|
+
const applyAntigravity = applyAll || has('--apply-antigravity');
|
|
52
|
+
const writeSnippets = applyAll || has('--write-snippets') || !(applyCodex || applyClaude || applyGemini || applyAntigravity);
|
|
41
53
|
const force = has('--force');
|
|
42
54
|
|
|
43
55
|
const mcpServer = {
|
|
@@ -69,6 +81,12 @@ const geminiSnippet = {
|
|
|
69
81
|
},
|
|
70
82
|
};
|
|
71
83
|
|
|
84
|
+
const antigravitySnippet = {
|
|
85
|
+
mcpServers: {
|
|
86
|
+
skill_master: mcpServer,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
72
90
|
const ensureParent = (filePath) => mkdirSync(path.dirname(filePath), { recursive: true });
|
|
73
91
|
|
|
74
92
|
const readJsonOrEmpty = (filePath) => {
|
|
@@ -99,6 +117,7 @@ const writeSnippetsFiles = () => {
|
|
|
99
117
|
writeFileSync(path.join(snippetsDir, 'codex.config.toml'), codexBlock.trimStart(), 'utf8');
|
|
100
118
|
writeJson(path.join(snippetsDir, 'claude_desktop_config.skill_master.json'), claudeSnippet);
|
|
101
119
|
writeJson(path.join(snippetsDir, 'gemini.settings.skill_master.json'), geminiSnippet);
|
|
120
|
+
writeJson(path.join(snippetsDir, 'antigravity.mcp_config.skill_master.json'), antigravitySnippet);
|
|
102
121
|
};
|
|
103
122
|
|
|
104
123
|
const removeCodexBlock = (content) => {
|
|
@@ -146,9 +165,13 @@ if (applyGemini) {
|
|
|
146
165
|
mergeMcpServer(geminiConfig);
|
|
147
166
|
actions.push(`Gemini config merged at ${geminiConfig}`);
|
|
148
167
|
}
|
|
168
|
+
if (applyAntigravity) {
|
|
169
|
+
mergeMcpServer(antigravityConfig);
|
|
170
|
+
actions.push(`Antigravity config merged at ${antigravityConfig}`);
|
|
171
|
+
}
|
|
149
172
|
|
|
150
173
|
console.log('[skill_master] Client registration');
|
|
151
174
|
for (const action of actions) {
|
|
152
175
|
console.log(`- ${action}`);
|
|
153
176
|
}
|
|
154
|
-
console.log('- Restart Codex, Claude or
|
|
177
|
+
console.log('- Restart Codex, Claude, Gemini or Antigravity after registration.');
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,7 @@ const contributionsDir = process.env.SKILL_MASTER_CONTRIBUTIONS_DIR
|
|
|
28
28
|
?? path.join(skillMasterHome, 'data', 'contributions');
|
|
29
29
|
const successLearningDir = process.env.SKILL_MASTER_SUCCESS_LEARNING_DIR
|
|
30
30
|
?? path.join(skillMasterHome, 'data', 'success-learning');
|
|
31
|
-
const bundledGlobalSkillsDir = path.join(projectRoot, 'docs', 'skill-candidates'
|
|
31
|
+
const bundledGlobalSkillsDir = path.join(projectRoot, 'docs', 'skill-candidates');
|
|
32
32
|
const workspace = process.env.SKILL_MASTER_WORKSPACE ?? process.cwd();
|
|
33
33
|
const userGlobalSkillsDir = path.join(process.env.CODEX_HOME ?? path.join(os.homedir(), '.codex'), 'skills');
|
|
34
34
|
const workspaceLocalSkillsDir = path.join(workspace, '.codex', 'skills');
|
|
@@ -58,6 +58,31 @@ const refresh = async (includeWeb) => {
|
|
|
58
58
|
await saveSnapshot(updated);
|
|
59
59
|
return updated;
|
|
60
60
|
};
|
|
61
|
+
const listBundledGlobalSkillSources = async (sourceRoot) => {
|
|
62
|
+
const entries = await fs.readdir(sourceRoot, { withFileTypes: true }).catch(() => []);
|
|
63
|
+
const directSkills = [];
|
|
64
|
+
for (const entry of entries.filter((item) => item.isDirectory())) {
|
|
65
|
+
const skillPath = path.join(sourceRoot, entry.name);
|
|
66
|
+
const hasSkill = await fs.access(path.join(skillPath, 'SKILL.md')).then(() => true).catch(() => false);
|
|
67
|
+
if (hasSkill)
|
|
68
|
+
directSkills.push({ name: entry.name, path: skillPath });
|
|
69
|
+
}
|
|
70
|
+
if (directSkills.length) {
|
|
71
|
+
return directSkills.sort((left, right) => left.name.localeCompare(right.name));
|
|
72
|
+
}
|
|
73
|
+
const versionedSkills = [];
|
|
74
|
+
for (const versionEntry of entries.filter((item) => item.isDirectory())) {
|
|
75
|
+
const versionPath = path.join(sourceRoot, versionEntry.name);
|
|
76
|
+
const skillEntries = await fs.readdir(versionPath, { withFileTypes: true }).catch(() => []);
|
|
77
|
+
for (const skillEntry of skillEntries.filter((item) => item.isDirectory())) {
|
|
78
|
+
const skillPath = path.join(versionPath, skillEntry.name);
|
|
79
|
+
const hasSkill = await fs.access(path.join(skillPath, 'SKILL.md')).then(() => true).catch(() => false);
|
|
80
|
+
if (hasSkill)
|
|
81
|
+
versionedSkills.push({ name: skillEntry.name, path: skillPath });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return versionedSkills.sort((left, right) => left.name.localeCompare(right.name));
|
|
85
|
+
};
|
|
61
86
|
await refresh(false).catch(() => snapshot);
|
|
62
87
|
const response = (data, markdown) => ({
|
|
63
88
|
content: [{ type: 'text', text: markdown.slice(0, CHARACTER_LIMIT) }],
|
|
@@ -363,7 +388,7 @@ server.registerTool('skill_master_domain_router', {
|
|
|
363
388
|
});
|
|
364
389
|
server.registerTool('skill_master_install_global_skills', {
|
|
365
390
|
title: 'Install bundled Skill Master global skills',
|
|
366
|
-
description: 'Install the bundled Skill Master
|
|
391
|
+
description: 'Install the bundled versioned Skill Master skills into the user-global Codex skills directory. This makes them available to Codex after restart/rescan.',
|
|
367
392
|
inputSchema: {
|
|
368
393
|
overwrite: z.boolean().default(false),
|
|
369
394
|
confirm_install: z.boolean().default(false),
|
|
@@ -386,12 +411,12 @@ server.registerTool('skill_master_install_global_skills', {
|
|
|
386
411
|
`Target: ${userGlobalSkillsDir}`,
|
|
387
412
|
].join('\n'));
|
|
388
413
|
}
|
|
389
|
-
const entries = await
|
|
414
|
+
const entries = await listBundledGlobalSkillSources(bundledGlobalSkillsDir);
|
|
390
415
|
await fs.mkdir(userGlobalSkillsDir, { recursive: true });
|
|
391
416
|
const installed = [];
|
|
392
417
|
const skipped = [];
|
|
393
|
-
for (const entry of entries
|
|
394
|
-
const source =
|
|
418
|
+
for (const entry of entries) {
|
|
419
|
+
const source = entry.path;
|
|
395
420
|
const target = path.join(userGlobalSkillsDir, entry.name);
|
|
396
421
|
const targetExists = await fs.access(target).then(() => true).catch(() => false);
|
|
397
422
|
if (targetExists && !overwrite) {
|