@fprad0/skill-master-mcp 0.0.10 → 0.0.11
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 +5 -1
- package/README.md +29 -9
- package/VERSION.md +3 -3
- package/bin/lib/client-config.mjs +268 -0
- package/bin/lib/menu-core.mjs +47 -37
- package/bin/skill-master-bootstrap-global.mjs +2 -1
- package/bin/skill-master-doctor.mjs +42 -29
- package/bin/skill-master-install-global-skills.mjs +1 -1
- package/bin/skill-master-register-clients.mjs +36 -115
- package/docs/operations/GUIA_MULTI_COMPUTADOR.md +255 -0
- package/docs/operations/GUIA_NPM_PUBLICO.md +147 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/SKILL.md +399 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/common-patterns.md +331 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/complete-examples.md +872 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/component-patterns.md +502 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/data-fetching.md +767 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/file-organization.md +502 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/loading-and-error-states.md +501 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/performance.md +406 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/routing-guide.md +364 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/styling-guide.md +428 -0
- package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/typescript-standards.md +418 -0
- package/docs/skill-candidates/v0.0.11/git-version-control-ops/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/go-engineering/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/java-engineering/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/javascript-engineering/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/json-contract-design/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/multi-client-mcp-ops/SKILL.md +36 -0
- package/docs/skill-candidates/v0.0.11/nextjs/SKILL.md +745 -0
- package/docs/skill-candidates/v0.0.11/nextjs/agents/openai.yaml +3 -0
- package/docs/skill-candidates/v0.0.11/nextjs/references/app-router-files.md +94 -0
- package/docs/skill-candidates/v0.0.11/python-engineering/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/ruby-engineering/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/senior-fullstack/SKILL.md +209 -0
- package/docs/skill-candidates/v0.0.11/senior-fullstack/references/architecture_patterns.md +103 -0
- package/docs/skill-candidates/v0.0.11/senior-fullstack/references/development_workflows.md +103 -0
- package/docs/skill-candidates/v0.0.11/senior-fullstack/references/tech_stack_guide.md +103 -0
- package/docs/skill-candidates/v0.0.11/senior-fullstack/scripts/code_quality_analyzer.py +114 -0
- package/docs/skill-candidates/v0.0.11/senior-fullstack/scripts/fullstack_scaffolder.py +114 -0
- package/docs/skill-candidates/v0.0.11/senior-fullstack/scripts/project_scaffolder.py +114 -0
- package/docs/skill-candidates/v0.0.11/shadcn/SKILL.md +573 -0
- package/docs/skill-candidates/v0.0.11/shadcn/agents/openai.yaml +3 -0
- package/docs/skill-candidates/v0.0.11/sql-postgresql-engineering/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/terminal-shell-ops/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/typescript-expert/SKILL.md +429 -0
- package/docs/skill-candidates/v0.0.11/typescript-expert/references/tsconfig-strict.json +92 -0
- package/docs/skill-candidates/v0.0.11/typescript-expert/references/typescript-cheatsheet.md +383 -0
- package/docs/skill-candidates/v0.0.11/typescript-expert/references/utility-types.ts +335 -0
- package/docs/skill-candidates/v0.0.11/typescript-expert/scripts/ts_diagnostic.py +203 -0
- package/docs/skill-candidates/v0.0.11/ui-component-primitives/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/web-mobile-design-systems/SKILL.md +34 -0
- package/docs/skill-candidates/v0.0.11/windows-linux-platform-ops/SKILL.md +34 -0
- package/manifests/channels/beta.json +7 -7
- package/manifests/channels/stable.json +8 -8
- package/package.json +6 -2
- package/scripts/verify-menu-actions.mjs +115 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,11 @@ All notable changes to `skill_master` will be tracked here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## [0.0.11] - 2026-06-28
|
|
8
|
+
|
|
9
|
+
- Register MCP clients with an absolute Node.js executable plus the absolute `bin/skill-master.mjs` entrypoint, avoiding PATH-dependent startup failures in Windows, Linux, macOS, and desktop MCP clients.
|
|
10
|
+
- Add shared client-config helpers, Codex/JSON config assessment, doctor reporting for robust vs legacy registration modes, and a menu action matrix verifier.
|
|
11
|
+
- Add a second bundled global skill pack `v0.0.11` with more granular language, data, terminal, Git, OS, MCP client and UI/design skills for global installation.
|
|
8
12
|
|
|
9
13
|
## [0.0.10] - 2026-06-28
|
|
10
14
|
|
package/README.md
CHANGED
|
@@ -108,13 +108,12 @@ npm install -g @fprad0/skill-master-mcp
|
|
|
108
108
|
npx -y @fprad0/skill-master-mcp@latest
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
Fluxo atual:
|
|
112
112
|
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
- validacao
|
|
116
|
-
-
|
|
117
|
-
- preparacao local seguinte: `0.0.10`, focada em confiabilidade do menu, doctor, Antigravity e separacao entre acoes globais e acoes de desenvolvimento
|
|
113
|
+
- instalacao publica simples por `npm install -g @fprad0/skill-master-mcp`
|
|
114
|
+
- execucao sem install global por `npx -y @fprad0/skill-master-mcp@latest`
|
|
115
|
+
- validacao rapida da versao publicada por `npm view @fprad0/skill-master-mcp version --registry=https://registry.npmjs.org`
|
|
116
|
+
- esta linha de release amplia o bundle global para `v0.0.11` e endurece o registro MCP multi-cliente com Node absoluto
|
|
118
117
|
|
|
119
118
|
Comandos globais principais:
|
|
120
119
|
|
|
@@ -157,7 +156,7 @@ skill-master-menu --run notion-summary
|
|
|
157
156
|
|
|
158
157
|
O menu visual usa `prompts` para ficar mais legivel no terminal e manter compatibilidade com `Node 18+`.
|
|
159
158
|
|
|
160
|
-
Quando o menu detectar que o MCP ainda nao esta globalmente pronto neste computador, ele mostra um alerta forte e um aviso sutil explicando que a instalacao global e o registro dos clientes sao necessarios para o `skill_master` parecer parte do sistema em Codex, Claude e
|
|
159
|
+
Quando o menu detectar que o MCP ainda nao esta globalmente pronto neste computador, ele mostra um alerta forte e um aviso sutil explicando que a instalacao global e o registro dos clientes sao necessarios para o `skill_master` parecer parte do sistema em Codex, Claude, Gemini e Antigravity.
|
|
161
160
|
|
|
162
161
|
Em instalacoes globais via npm, o menu tambem separa acoes operacionais de acoes de desenvolvimento. Acoes como `check` e `build` dependem do clone completo do repositorio; quando o pacote estiver instalado globalmente, use:
|
|
163
162
|
|
|
@@ -173,7 +172,9 @@ Para instalar as skills globais embutidas de discernimento, conhecimento amplo,
|
|
|
173
172
|
skill-master-install-global-skills
|
|
174
173
|
```
|
|
175
174
|
|
|
176
|
-
No estado atual do pacote, esse bundle global tambem inclui cobertura para frontend, backend, CLI, terminal, GitHub, Windows/Linux, clientes MCP, design, Figma, Playwright, idiomas e raciocinio tecnico, usando uma combinacao de skills locais aprovadas e skills oficiais empacotadas em `docs/skill-candidates/v0.0.10`.
|
|
175
|
+
No estado atual do pacote, esse bundle global tambem inclui cobertura para frontend, backend, CLI, terminal, GitHub, Windows/Linux, clientes MCP, design, Figma, Playwright, idiomas e raciocinio tecnico, usando uma combinacao de skills locais aprovadas e skills oficiais empacotadas em `docs/skill-candidates/v0.0.10` e `docs/skill-candidates/v0.0.11`.
|
|
176
|
+
|
|
177
|
+
O pacote `v0.0.11` amplia a granularidade com skills dedicadas para TypeScript, Python, JavaScript, Java, Ruby, Go, SQL/PostgreSQL, contratos JSON, Git, shell/terminal, Windows/Linux, operacao multi-cliente MCP, componentes UI e sistemas web/mobile.
|
|
177
178
|
|
|
178
179
|
Para fazer o bootstrap global completo em um passo:
|
|
179
180
|
|
|
@@ -181,7 +182,7 @@ Para fazer o bootstrap global completo em um passo:
|
|
|
181
182
|
skill-master-bootstrap-global
|
|
182
183
|
```
|
|
183
184
|
|
|
184
|
-
Para registrar o MCP nos clientes principais
|
|
185
|
+
Para registrar o MCP nos clientes principais, use o registrador. Ele grava `command` com o Node.js absoluto e `args` com o caminho absoluto de `bin/skill-master.mjs`, evitando falhas de `PATH` em Windows, Linux, macOS e apps desktop que nao herdam o terminal:
|
|
185
186
|
|
|
186
187
|
```bash
|
|
187
188
|
skill-master-register-clients --apply-codex
|
|
@@ -198,6 +199,25 @@ skill-master-register-clients --apply-all
|
|
|
198
199
|
|
|
199
200
|
Isso configura o servidor MCP `skill_master` em Codex, Claude Desktop, Gemini e Antigravity quando os arquivos de configuracao locais estiverem disponiveis. Reinicie o cliente depois do registro.
|
|
200
201
|
|
|
202
|
+
Se um cliente ja tiver uma configuracao antiga por `skill-master-mcp`, `npx` ou launcher local e nao estiver iniciando, force a migracao para o modo robusto:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
skill-master-register-clients --apply-all --force
|
|
206
|
+
skill-master-menu --run doctor
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
No Codex, o bloco recomendado fica no formato:
|
|
210
|
+
|
|
211
|
+
```toml
|
|
212
|
+
[mcp_servers.skill_master]
|
|
213
|
+
command = "/caminho/absoluto/para/node"
|
|
214
|
+
args = ["/caminho/absoluto/para/bin/skill-master.mjs"]
|
|
215
|
+
startup_timeout_sec = 120
|
|
216
|
+
|
|
217
|
+
[mcp_servers.skill_master.env]
|
|
218
|
+
SKILL_MASTER_UPDATE_CHANNEL = "stable"
|
|
219
|
+
```
|
|
220
|
+
|
|
201
221
|
O menu tambem mostra notificacoes de skills aprendidas pendentes e links externos para estudo. As acoes de ativacao sao:
|
|
202
222
|
|
|
203
223
|
- `skill-master-menu --run activate-learned-local`: instala uma skill aprovada em `.codex/skills` do workspace atual.
|
package/VERSION.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Versão
|
|
2
2
|
|
|
3
|
-
Versão funcional planejada: `00.
|
|
3
|
+
Versão funcional planejada: `00.05`
|
|
4
4
|
|
|
5
|
-
Versão técnica para empacotamento semântico: `0.0.
|
|
5
|
+
Versão técnica para empacotamento semântico: `0.0.11`
|
|
6
6
|
|
|
7
7
|
## Observação
|
|
8
8
|
|
|
9
|
-
O nome `00.
|
|
9
|
+
O nome `00.05` será usado na comunicação e nos documentos. Para ferramentas que exigem SemVer, como npm e alguns fluxos de release, usar `0.0.11`.
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_SERVER_ENV = {
|
|
8
|
+
SKILL_MASTER_UPDATE_CHANNEL: 'stable',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function defaultClaudeConfigPath(home = os.homedir(), platform = process.platform) {
|
|
12
|
+
if (platform === 'win32') {
|
|
13
|
+
return path.join(process.env.APPDATA ?? path.join(home, 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (platform === 'darwin') {
|
|
17
|
+
return path.join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return path.join(home, '.config', 'Claude', 'claude_desktop_config.json');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function defaultClientConfigPaths({
|
|
24
|
+
home = os.homedir(),
|
|
25
|
+
env = process.env,
|
|
26
|
+
platform = process.platform,
|
|
27
|
+
} = {}) {
|
|
28
|
+
return {
|
|
29
|
+
codex: path.join(env.CODEX_HOME ?? path.join(home, '.codex'), 'config.toml'),
|
|
30
|
+
claude: defaultClaudeConfigPath(home, platform),
|
|
31
|
+
gemini: path.join(home, '.gemini', 'settings.json'),
|
|
32
|
+
antigravity: path.join(home, '.gemini', 'config', 'mcp_config.json'),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function buildSkillMasterServerConfig({
|
|
37
|
+
rootDir,
|
|
38
|
+
nodeExecPath = process.execPath,
|
|
39
|
+
env = DEFAULT_SERVER_ENV,
|
|
40
|
+
} = {}) {
|
|
41
|
+
const packageRoot = rootDir ?? path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
42
|
+
const serverEntry = path.join(packageRoot, 'bin', 'skill-master.mjs');
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
command: nodeExecPath,
|
|
46
|
+
args: [serverEntry],
|
|
47
|
+
env: { ...env },
|
|
48
|
+
metadata: {
|
|
49
|
+
mode: 'absolute-node',
|
|
50
|
+
packageRoot,
|
|
51
|
+
serverEntry,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function tomlString(value) {
|
|
57
|
+
return JSON.stringify(String(value));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function tomlStringArray(values) {
|
|
61
|
+
return `[${values.map((value) => tomlString(value)).join(', ')}]`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function buildCodexBlock(serverConfig) {
|
|
65
|
+
const envEntries = Object.entries(serverConfig.env ?? {});
|
|
66
|
+
const envBlock = envEntries.length
|
|
67
|
+
? `\n[mcp_servers.skill_master.env]\n${envEntries.map(([key, value]) => `${key} = ${tomlString(value)}`).join('\n')}\n`
|
|
68
|
+
: '';
|
|
69
|
+
|
|
70
|
+
return `
|
|
71
|
+
[mcp_servers.skill_master]
|
|
72
|
+
command = ${tomlString(serverConfig.command)}
|
|
73
|
+
args = ${tomlStringArray(serverConfig.args ?? [])}
|
|
74
|
+
startup_timeout_sec = 120
|
|
75
|
+
${envBlock}`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function buildJsonMcpSnippet(serverConfig) {
|
|
79
|
+
return {
|
|
80
|
+
mcpServers: {
|
|
81
|
+
skill_master: {
|
|
82
|
+
command: serverConfig.command,
|
|
83
|
+
args: serverConfig.args ?? [],
|
|
84
|
+
env: serverConfig.env ?? {},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function ensureParent(filePath) {
|
|
91
|
+
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function backupPath(filePath) {
|
|
95
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
96
|
+
return `${filePath}.invalid-${stamp}.bak`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function readJsonOrEmpty(filePath, { recoverInvalidJson = false } = {}) {
|
|
100
|
+
if (!existsSync(filePath)) return {};
|
|
101
|
+
const raw = readFileSync(filePath, 'utf8').trim();
|
|
102
|
+
if (!raw) return {};
|
|
103
|
+
try {
|
|
104
|
+
return JSON.parse(raw);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
if (recoverInvalidJson) {
|
|
107
|
+
copyFileSync(filePath, backupPath(filePath));
|
|
108
|
+
return {};
|
|
109
|
+
}
|
|
110
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
111
|
+
throw new Error(`Invalid JSON at ${filePath}: ${message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function writeJson(filePath, value) {
|
|
116
|
+
ensureParent(filePath);
|
|
117
|
+
writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function mergeMcpServer(filePath, serverConfig, options = {}) {
|
|
121
|
+
const current = readJsonOrEmpty(filePath, options);
|
|
122
|
+
const next = {
|
|
123
|
+
...current,
|
|
124
|
+
mcpServers: {
|
|
125
|
+
...(current.mcpServers ?? {}),
|
|
126
|
+
skill_master: buildJsonMcpSnippet(serverConfig).mcpServers.skill_master,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
writeJson(filePath, next);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function removeCodexSkillMasterBlock(content) {
|
|
133
|
+
const lines = String(content ?? '').split('\n');
|
|
134
|
+
const kept = [];
|
|
135
|
+
let skipping = false;
|
|
136
|
+
for (const line of lines) {
|
|
137
|
+
const trimmed = line.trim();
|
|
138
|
+
if (trimmed === '[mcp_servers.skill_master]') {
|
|
139
|
+
skipping = true;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (skipping && trimmed.startsWith('[') && !trimmed.startsWith('[mcp_servers.skill_master')) {
|
|
143
|
+
skipping = false;
|
|
144
|
+
}
|
|
145
|
+
if (!skipping) kept.push(line);
|
|
146
|
+
}
|
|
147
|
+
return kept.join('\n').trimEnd();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function appendCodexServer(filePath, serverConfig, { force = false } = {}) {
|
|
151
|
+
ensureParent(filePath);
|
|
152
|
+
const current = existsSync(filePath) ? readFileSync(filePath, 'utf8') : '';
|
|
153
|
+
if (current.includes('[mcp_servers.skill_master]') && !force) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const base = force ? removeCodexSkillMasterBlock(current) : current.trimEnd();
|
|
157
|
+
writeFileSync(filePath, `${base}\n${buildCodexBlock(serverConfig)}`, 'utf8');
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function normalizeSlashes(value) {
|
|
162
|
+
return String(value ?? '').replace(/\\/g, '/').toLowerCase();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function basename(value) {
|
|
166
|
+
const normalized = normalizeSlashes(value);
|
|
167
|
+
return normalized.split('/').pop() ?? '';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function isNodeCommand(command) {
|
|
171
|
+
const name = basename(command);
|
|
172
|
+
return name === 'node' || name === 'node.exe';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function hasSkillMasterEntryArg(args = []) {
|
|
176
|
+
return args.some((arg) => normalizeSlashes(arg).endsWith('/bin/skill-master.mjs'));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function hasLauncherArg(args = []) {
|
|
180
|
+
return args.some((arg) => {
|
|
181
|
+
const normalized = normalizeSlashes(arg);
|
|
182
|
+
return normalized.endsWith('/scripts/skill-master-launcher.ps1')
|
|
183
|
+
|| normalized.endsWith('/scripts/skill-master-launcher.sh');
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function assessMcpServerConfig(server) {
|
|
188
|
+
if (!server?.command) {
|
|
189
|
+
return {
|
|
190
|
+
present: Boolean(server),
|
|
191
|
+
robust: false,
|
|
192
|
+
mode: server ? 'missing-command' : 'missing',
|
|
193
|
+
command: server?.command ?? null,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const command = String(server.command);
|
|
198
|
+
const args = Array.isArray(server.args) ? server.args : [];
|
|
199
|
+
const commandName = basename(command);
|
|
200
|
+
const normalizedCommand = normalizeSlashes(command);
|
|
201
|
+
|
|
202
|
+
if (isNodeCommand(command) && hasSkillMasterEntryArg(args)) {
|
|
203
|
+
return { present: true, robust: true, mode: 'absolute-node', command };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (commandName === 'skill-master-mcp' || commandName === 'skill-master-mcp.cmd') {
|
|
207
|
+
return { present: true, robust: false, mode: 'path-bin', command };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if ((normalizedCommand.includes('powershell') || commandName === 'bash' || commandName === 'env') && hasLauncherArg(args)) {
|
|
211
|
+
return { present: true, robust: false, mode: 'launcher', command };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return { present: true, robust: false, mode: 'custom', command };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function parseTomlStringToken(token) {
|
|
218
|
+
const value = String(token ?? '').trim();
|
|
219
|
+
if (!value) return '';
|
|
220
|
+
if (value.startsWith('"')) {
|
|
221
|
+
try {
|
|
222
|
+
return JSON.parse(value);
|
|
223
|
+
} catch {
|
|
224
|
+
return value.slice(1, -1);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (value.startsWith("'")) {
|
|
228
|
+
return value.slice(1, -1);
|
|
229
|
+
}
|
|
230
|
+
return value;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function parseTomlStringArray(value) {
|
|
234
|
+
const matches = [...String(value ?? '').matchAll(/"(?:\\.|[^"])*"|'[^']*'/g)];
|
|
235
|
+
return matches.map((match) => parseTomlStringToken(match[0]));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function extractCodexSkillMasterServer(content) {
|
|
239
|
+
const lines = String(content ?? '').split('\n');
|
|
240
|
+
const block = [];
|
|
241
|
+
let collecting = false;
|
|
242
|
+
|
|
243
|
+
for (const line of lines) {
|
|
244
|
+
const trimmed = line.trim();
|
|
245
|
+
if (trimmed === '[mcp_servers.skill_master]') {
|
|
246
|
+
collecting = true;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (collecting && trimmed.startsWith('[')) {
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
if (collecting) block.push(line);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (!block.length) return null;
|
|
256
|
+
|
|
257
|
+
const commandLine = block.find((line) => line.trim().startsWith('command'));
|
|
258
|
+
const argsLine = block.find((line) => line.trim().startsWith('args'));
|
|
259
|
+
const commandToken = commandLine?.match(/=\s*("(?:\\.|[^"])*"|'[^']*')/)?.[1] ?? null;
|
|
260
|
+
const command = commandToken ? parseTomlStringToken(commandToken) : null;
|
|
261
|
+
const args = argsLine ? parseTomlStringArray(argsLine.split('=').slice(1).join('=')) : [];
|
|
262
|
+
|
|
263
|
+
return command ? { command, args } : null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export function assessCodexConfigContent(content) {
|
|
267
|
+
return assessMcpServerConfig(extractCodexSkillMasterServer(content));
|
|
268
|
+
}
|
package/bin/lib/menu-core.mjs
CHANGED
|
@@ -3,6 +3,11 @@ import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import process from 'node:process';
|
|
6
|
+
import {
|
|
7
|
+
assessCodexConfigContent,
|
|
8
|
+
assessMcpServerConfig,
|
|
9
|
+
defaultClientConfigPaths,
|
|
10
|
+
} from './client-config.mjs';
|
|
6
11
|
|
|
7
12
|
const ANSI = {
|
|
8
13
|
reset: '\x1b[0m',
|
|
@@ -63,11 +68,17 @@ const BUNDLED_SKILL_DOMAIN_GROUPS = [
|
|
|
63
68
|
'figma-generate-library',
|
|
64
69
|
'figma-implement-design',
|
|
65
70
|
'figma-use',
|
|
71
|
+
'frontend-dev-guidelines',
|
|
66
72
|
'frontend-design',
|
|
67
73
|
'frontend-ui-ux-systems',
|
|
74
|
+
'nextjs',
|
|
68
75
|
'playwright',
|
|
69
76
|
'screenshot',
|
|
77
|
+
'senior-fullstack',
|
|
78
|
+
'shadcn',
|
|
79
|
+
'ui-component-primitives',
|
|
70
80
|
'webapp-testing',
|
|
81
|
+
'web-mobile-design-systems',
|
|
71
82
|
'winui-app',
|
|
72
83
|
],
|
|
73
84
|
},
|
|
@@ -75,8 +86,16 @@ const BUNDLED_SKILL_DOMAIN_GROUPS = [
|
|
|
75
86
|
key: 'backend',
|
|
76
87
|
label: 'backend-data',
|
|
77
88
|
skills: [
|
|
89
|
+
'go-engineering',
|
|
90
|
+
'java-engineering',
|
|
91
|
+
'javascript-engineering',
|
|
92
|
+
'json-contract-design',
|
|
78
93
|
'mcp-builder',
|
|
79
94
|
'polyglot-backend-engineering',
|
|
95
|
+
'python-engineering',
|
|
96
|
+
'ruby-engineering',
|
|
97
|
+
'sql-postgresql-engineering',
|
|
98
|
+
'typescript-expert',
|
|
80
99
|
],
|
|
81
100
|
},
|
|
82
101
|
{
|
|
@@ -85,12 +104,16 @@ const BUNDLED_SKILL_DOMAIN_GROUPS = [
|
|
|
85
104
|
skills: [
|
|
86
105
|
'cli-creator',
|
|
87
106
|
'developer-workstation-ops',
|
|
107
|
+
'git-version-control-ops',
|
|
88
108
|
'github',
|
|
89
109
|
'mcp-client-readiness',
|
|
110
|
+
'multi-client-mcp-ops',
|
|
90
111
|
'openai-docs',
|
|
91
112
|
'skill-master-orchestrator',
|
|
113
|
+
'terminal-shell-ops',
|
|
92
114
|
'terminal-menu-operations',
|
|
93
115
|
'terminal-pixel-art-tui',
|
|
116
|
+
'windows-linux-platform-ops',
|
|
94
117
|
],
|
|
95
118
|
},
|
|
96
119
|
{
|
|
@@ -174,58 +197,45 @@ function readClientConfigState(filePath) {
|
|
|
174
197
|
}
|
|
175
198
|
|
|
176
199
|
const content = readFileSync(filePath, 'utf8');
|
|
177
|
-
const
|
|
178
|
-
const hasGlobalCommand = content.includes('command = "skill-master-mcp"') || content.includes("command = 'skill-master-mcp'");
|
|
179
|
-
const hasLauncher = content.includes('skill-master-launcher');
|
|
200
|
+
const assessment = assessCodexConfigContent(content);
|
|
180
201
|
|
|
181
202
|
return {
|
|
182
203
|
present: true,
|
|
183
|
-
kind:
|
|
184
|
-
globalCommand:
|
|
204
|
+
kind: assessment.mode,
|
|
205
|
+
globalCommand: assessment.robust,
|
|
206
|
+
command: assessment.command,
|
|
185
207
|
};
|
|
186
208
|
}
|
|
187
209
|
|
|
188
210
|
function readJsonState(filePath) {
|
|
189
211
|
if (!existsSync(filePath)) {
|
|
190
|
-
return { present: false, globalCommand: false };
|
|
212
|
+
return { present: false, kind: 'missing', globalCommand: false };
|
|
191
213
|
}
|
|
192
214
|
|
|
193
215
|
try {
|
|
194
216
|
const parsed = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
195
217
|
const server = parsed?.mcpServers?.skill_master;
|
|
218
|
+
const assessment = assessMcpServerConfig(server);
|
|
196
219
|
return {
|
|
197
220
|
present: true,
|
|
198
|
-
|
|
221
|
+
kind: assessment.mode,
|
|
222
|
+
globalCommand: assessment.robust,
|
|
223
|
+
command: assessment.command,
|
|
199
224
|
};
|
|
200
225
|
} 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');
|
|
226
|
+
return { present: true, kind: 'invalid-json', globalCommand: false };
|
|
208
227
|
}
|
|
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
228
|
}
|
|
216
229
|
|
|
217
230
|
function inspectGlobalReadiness() {
|
|
218
231
|
const root = globalSkillsRoot();
|
|
219
232
|
const installed = REQUIRED_GLOBAL_SKILLS.filter((name) => existsSync(join(root, name, 'SKILL.md')));
|
|
220
233
|
const missing = REQUIRED_GLOBAL_SKILLS.filter((name) => !installed.includes(name));
|
|
221
|
-
const
|
|
222
|
-
const
|
|
223
|
-
const
|
|
224
|
-
const
|
|
225
|
-
const
|
|
226
|
-
const claude = readJsonState(claudeConfigPath);
|
|
227
|
-
const gemini = readJsonState(geminiConfigPath);
|
|
228
|
-
const antigravity = readJsonState(antigravityConfigPath);
|
|
234
|
+
const clientPaths = defaultClientConfigPaths();
|
|
235
|
+
const codex = readClientConfigState(clientPaths.codex);
|
|
236
|
+
const claude = readJsonState(clientPaths.claude);
|
|
237
|
+
const gemini = readJsonState(clientPaths.gemini);
|
|
238
|
+
const antigravity = readJsonState(clientPaths.antigravity);
|
|
229
239
|
const ready = missing.length === 0
|
|
230
240
|
&& codex.globalCommand
|
|
231
241
|
&& claude.globalCommand
|
|
@@ -233,7 +243,7 @@ function inspectGlobalReadiness() {
|
|
|
233
243
|
&& antigravity.globalCommand;
|
|
234
244
|
const mode = ready
|
|
235
245
|
? 'ready'
|
|
236
|
-
: codex.
|
|
246
|
+
: codex.present || claude.present || gemini.present || antigravity.present
|
|
237
247
|
? 'partial'
|
|
238
248
|
: 'missing';
|
|
239
249
|
|
|
@@ -522,7 +532,7 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
|
|
|
522
532
|
aliases: ['register-clients', 'registrar-clientes', 'codex-claude-gemini', 'antigravity'],
|
|
523
533
|
label: 'Registrar clientes MCP',
|
|
524
534
|
description: 'Gera/aplica configuracoes MCP para Codex, Claude, Gemini e Antigravity reconhecerem skill_master.',
|
|
525
|
-
details: ['Usa
|
|
535
|
+
details: ['Usa Node absoluto + bin/skill-master.mjs absoluto.', 'Preserva outros servidores MCP ja existentes nos JSONs.'],
|
|
526
536
|
success: 'Arquivos de configuracao mesclados com o servidor skill_master.',
|
|
527
537
|
command: nodeExecPath,
|
|
528
538
|
args: [join(rootDir, 'bin', 'skill-master-register-clients.mjs'), '--apply-all'],
|
|
@@ -668,10 +678,10 @@ export function formatStatusReport(status) {
|
|
|
668
678
|
`Global skills instaladas: ${readiness.installed.length}/${readiness.required}`,
|
|
669
679
|
`Bundle de skills embutidas: ${bundledCatalog.total}`,
|
|
670
680
|
`Dominios do bundle: ${formatBundledCategoryLine(bundledCatalog)}`,
|
|
671
|
-
`Codex
|
|
672
|
-
`Claude
|
|
673
|
-
`Gemini
|
|
674
|
-
`Antigravity
|
|
681
|
+
`Codex MCP robusto: ${readiness.codex.globalCommand ? 'sim' : readiness.codex.kind}`,
|
|
682
|
+
`Claude MCP robusto: ${readiness.claude.globalCommand ? 'sim' : readiness.claude.kind}`,
|
|
683
|
+
`Gemini MCP robusto: ${readiness.gemini.globalCommand ? 'sim' : readiness.gemini.kind}`,
|
|
684
|
+
`Antigravity MCP robusto: ${readiness.antigravity.globalCommand ? 'sim' : readiness.antigravity.kind}`,
|
|
675
685
|
];
|
|
676
686
|
|
|
677
687
|
if (status.versionText) {
|
|
@@ -688,8 +698,8 @@ function formatGlobalAlert(status, { useColor = false } = {}) {
|
|
|
688
698
|
return renderPanelLines(
|
|
689
699
|
[
|
|
690
700
|
colorize('GLOBAL READY', ANSI.bold, useColor),
|
|
691
|
-
'O MCP esta
|
|
692
|
-
'Codex, Claude, Gemini e Antigravity podem
|
|
701
|
+
'O MCP esta registrado de forma robusta neste computador.',
|
|
702
|
+
'Codex, Claude, Gemini e Antigravity podem iniciar com Node absoluto.',
|
|
693
703
|
'A instalacao global e as skills embutidas ja estao prontas para uso.',
|
|
694
704
|
],
|
|
695
705
|
{ color: ANSI.green, useColor },
|
|
@@ -702,7 +712,7 @@ function formatGlobalAlert(status, { useColor = false } = {}) {
|
|
|
702
712
|
colorize('ALERTA GLOBAL', ANSI.bold, useColor),
|
|
703
713
|
'Este computador ainda nao esta pronto para uso global do Skill Master.',
|
|
704
714
|
'Execute agora: skill-master-menu --run bootstrap-global --yes',
|
|
705
|
-
'Isso instala as skills globais e registra Codex, Claude, Gemini e Antigravity.',
|
|
715
|
+
'Isso instala as skills globais e registra Codex, Claude, Gemini e Antigravity com Node absoluto.',
|
|
706
716
|
],
|
|
707
717
|
{ color: ANSI.red, useColor },
|
|
708
718
|
),
|
|
@@ -15,7 +15,8 @@ Uso:
|
|
|
15
15
|
skill-master-bootstrap-global
|
|
16
16
|
|
|
17
17
|
Instala as skills globais embutidas e registra o MCP skill_master em Codex,
|
|
18
|
-
Claude Desktop, Gemini e Antigravity usando
|
|
18
|
+
Claude Desktop, Gemini e Antigravity usando Node absoluto e o entrypoint
|
|
19
|
+
absoluto do pacote, sem depender do PATH do app desktop.
|
|
19
20
|
Reinicie os clientes depois da execucao.
|
|
20
21
|
`);
|
|
21
22
|
process.exit(0);
|