@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
|
@@ -4,6 +4,11 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
4
4
|
import os from 'node:os';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import {
|
|
8
|
+
assessCodexConfigContent,
|
|
9
|
+
assessMcpServerConfig,
|
|
10
|
+
defaultClientConfigPaths,
|
|
11
|
+
} from './lib/client-config.mjs';
|
|
7
12
|
|
|
8
13
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
9
14
|
const rootDir = path.resolve(here, '..');
|
|
@@ -19,6 +24,9 @@ Uso:
|
|
|
19
24
|
|
|
20
25
|
Valida pacote, binarios, skills globais e registro MCP em Codex, Claude,
|
|
21
26
|
Gemini e Antigravity. Nao publica versoes e nao altera configuracoes.
|
|
27
|
+
|
|
28
|
+
O registro recomendado usa Node absoluto + bin/skill-master.mjs absoluto para
|
|
29
|
+
evitar falhas de PATH em apps desktop no Windows, Linux e macOS.
|
|
22
30
|
`);
|
|
23
31
|
process.exit(0);
|
|
24
32
|
}
|
|
@@ -49,25 +57,13 @@ const REQUIRED_BINS = [
|
|
|
49
57
|
'skill-master-doctor',
|
|
50
58
|
];
|
|
51
59
|
|
|
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
60
|
function readJson(filePath) {
|
|
65
|
-
if (!existsSync(filePath)) return null;
|
|
61
|
+
if (!existsSync(filePath)) return { present: false, invalid: false, value: null };
|
|
66
62
|
try {
|
|
67
63
|
const raw = readFileSync(filePath, 'utf8').trim();
|
|
68
|
-
return raw ? JSON.parse(raw) : {};
|
|
64
|
+
return { present: true, invalid: false, value: raw ? JSON.parse(raw) : {} };
|
|
69
65
|
} catch {
|
|
70
|
-
return null;
|
|
66
|
+
return { present: true, invalid: true, value: null };
|
|
71
67
|
}
|
|
72
68
|
}
|
|
73
69
|
|
|
@@ -80,26 +76,40 @@ function commandExists(command) {
|
|
|
80
76
|
|
|
81
77
|
function jsonClientState(filePath) {
|
|
82
78
|
const parsed = readJson(filePath);
|
|
83
|
-
|
|
79
|
+
if (parsed.invalid) {
|
|
80
|
+
return {
|
|
81
|
+
filePath,
|
|
82
|
+
present: true,
|
|
83
|
+
configured: false,
|
|
84
|
+
mode: 'invalid-json',
|
|
85
|
+
command: null,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const server = parsed.value?.mcpServers?.skill_master;
|
|
90
|
+
const assessment = assessMcpServerConfig(server);
|
|
84
91
|
return {
|
|
85
92
|
filePath,
|
|
86
|
-
present:
|
|
87
|
-
configured:
|
|
88
|
-
|
|
93
|
+
present: parsed.present,
|
|
94
|
+
configured: assessment.robust,
|
|
95
|
+
mode: assessment.mode,
|
|
96
|
+
command: assessment.command,
|
|
89
97
|
};
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
function codexState(filePath) {
|
|
93
101
|
if (!existsSync(filePath)) {
|
|
94
|
-
return { filePath, present: false, configured: false, command: null };
|
|
102
|
+
return { filePath, present: false, configured: false, mode: 'missing', command: null };
|
|
95
103
|
}
|
|
96
104
|
|
|
97
105
|
const content = readFileSync(filePath, 'utf8');
|
|
106
|
+
const assessment = assessCodexConfigContent(content);
|
|
98
107
|
return {
|
|
99
108
|
filePath,
|
|
100
109
|
present: true,
|
|
101
|
-
configured:
|
|
102
|
-
|
|
110
|
+
configured: assessment.robust,
|
|
111
|
+
mode: assessment.mode,
|
|
112
|
+
command: assessment.command,
|
|
103
113
|
};
|
|
104
114
|
}
|
|
105
115
|
|
|
@@ -108,16 +118,18 @@ function resultLine(ok, label, detail) {
|
|
|
108
118
|
return `[${marker}] ${label}${detail ? ` - ${detail}` : ''}`;
|
|
109
119
|
}
|
|
110
120
|
|
|
111
|
-
const
|
|
121
|
+
const packageJsonState = readJson(path.join(rootDir, 'package.json'));
|
|
122
|
+
const packageJson = packageJsonState.value;
|
|
112
123
|
const globalSkillsRoot = path.join(process.env.CODEX_HOME ?? path.join(os.homedir(), '.codex'), 'skills');
|
|
113
124
|
const installedSkills = REQUIRED_GLOBAL_SKILLS.filter((skill) => existsSync(path.join(globalSkillsRoot, skill, 'SKILL.md')));
|
|
114
125
|
const missingSkills = REQUIRED_GLOBAL_SKILLS.filter((skill) => !installedSkills.includes(skill));
|
|
115
126
|
|
|
127
|
+
const clientPaths = defaultClientConfigPaths();
|
|
116
128
|
const clients = [
|
|
117
|
-
['Codex', codexState(
|
|
118
|
-
['Claude Desktop', jsonClientState(
|
|
119
|
-
['Gemini CLI', jsonClientState(
|
|
120
|
-
['Antigravity', jsonClientState(
|
|
129
|
+
['Codex', codexState(clientPaths.codex)],
|
|
130
|
+
['Claude Desktop', jsonClientState(clientPaths.claude)],
|
|
131
|
+
['Gemini CLI', jsonClientState(clientPaths.gemini)],
|
|
132
|
+
['Antigravity', jsonClientState(clientPaths.antigravity)],
|
|
121
133
|
];
|
|
122
134
|
|
|
123
135
|
const binResults = REQUIRED_BINS.map((bin) => [bin, commandExists(bin)]);
|
|
@@ -144,9 +156,9 @@ console.log(`- Skills root: ${globalSkillsRoot}`);
|
|
|
144
156
|
console.log('');
|
|
145
157
|
for (const [name, state] of clients) {
|
|
146
158
|
const detail = state.configured
|
|
147
|
-
? state.filePath
|
|
159
|
+
? `${state.mode} em ${state.filePath}`
|
|
148
160
|
: state.present
|
|
149
|
-
? `presente, mas command=${state.command ?? 'nao encontrado'} em ${state.filePath}`
|
|
161
|
+
? `presente, mas mode=${state.mode} command=${state.command ?? 'nao encontrado'} em ${state.filePath}`
|
|
150
162
|
: `ausente em ${state.filePath}`;
|
|
151
163
|
console.log(resultLine(state.configured, `${name} configurado`, detail));
|
|
152
164
|
}
|
|
@@ -158,6 +170,7 @@ console.log(resultLine(ready, 'Readiness global', ready ? 'pronto' : 'requer aca
|
|
|
158
170
|
if (!ready) {
|
|
159
171
|
console.log('');
|
|
160
172
|
console.log('Proximo comando recomendado:');
|
|
173
|
+
console.log(' skill-master-register-clients --apply-all --force');
|
|
161
174
|
console.log(' skill-master-menu --run bootstrap-global --yes');
|
|
162
175
|
console.log('');
|
|
163
176
|
console.log('Depois reinicie Codex, Claude, Gemini e Antigravity.');
|
|
@@ -24,7 +24,7 @@ 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.
|
|
27
|
+
skill-master-install-global-skills --source ./docs/skill-candidates/v0.0.11
|
|
28
28
|
|
|
29
29
|
Instala as skills globais embutidas em CODEX_HOME/skills ou ~/.codex/skills.
|
|
30
30
|
Quando --source aponta para docs/skill-candidates, todas as pastas versionadas v*
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import os from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
4
|
+
import path, { dirname } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import {
|
|
7
|
+
appendCodexServer,
|
|
8
|
+
buildCodexBlock,
|
|
9
|
+
buildJsonMcpSnippet,
|
|
10
|
+
buildSkillMasterServerConfig,
|
|
11
|
+
defaultClientConfigPaths,
|
|
12
|
+
mergeMcpServer,
|
|
13
|
+
writeJson,
|
|
14
|
+
} from './lib/client-config.mjs';
|
|
5
15
|
|
|
6
16
|
const args = process.argv.slice(2);
|
|
7
17
|
const has = (flag) => args.includes(flag);
|
|
@@ -10,6 +20,9 @@ const readValue = (flag, fallback) => {
|
|
|
10
20
|
return index >= 0 ? args[index + 1] : fallback;
|
|
11
21
|
};
|
|
12
22
|
|
|
23
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
const rootDir = dirname(here);
|
|
25
|
+
|
|
13
26
|
if (has('--help')) {
|
|
14
27
|
console.log(`Skill Master client registration
|
|
15
28
|
|
|
@@ -22,27 +35,19 @@ Uso:
|
|
|
22
35
|
skill-master-register-clients --apply-all
|
|
23
36
|
skill-master-register-clients --apply-codex --force
|
|
24
37
|
|
|
25
|
-
Registra o servidor MCP skill_master como stdio usando
|
|
26
|
-
|
|
38
|
+
Registra o servidor MCP skill_master como stdio usando Node absoluto e o
|
|
39
|
+
entrypoint absoluto do pacote. Isso evita falhas de PATH em Windows, Linux,
|
|
40
|
+
macOS e apps desktop que nao herdam o terminal.
|
|
27
41
|
`);
|
|
28
42
|
process.exit(0);
|
|
29
43
|
}
|
|
30
44
|
|
|
31
|
-
const
|
|
32
|
-
const snippetsDir = readValue('--snippets-dir', path.join(
|
|
33
|
-
const codexConfig = readValue('--codex-config',
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
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());
|
|
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'));
|
|
45
|
+
const clientPaths = defaultClientConfigPaths();
|
|
46
|
+
const snippetsDir = readValue('--snippets-dir', path.join(process.env.SKILL_MASTER_HOME ?? path.join(os.homedir(), '.skill-master'), 'client-configs'));
|
|
47
|
+
const codexConfig = readValue('--codex-config', clientPaths.codex);
|
|
48
|
+
const claudeConfig = readValue('--claude-config', clientPaths.claude);
|
|
49
|
+
const geminiConfig = readValue('--gemini-config', clientPaths.gemini);
|
|
50
|
+
const antigravityConfig = readValue('--antigravity-config', clientPaths.antigravity);
|
|
46
51
|
|
|
47
52
|
const applyAll = has('--apply-all');
|
|
48
53
|
const applyCodex = applyAll || has('--apply-codex');
|
|
@@ -51,102 +56,16 @@ const applyGemini = applyAll || has('--apply-gemini');
|
|
|
51
56
|
const applyAntigravity = applyAll || has('--apply-antigravity');
|
|
52
57
|
const writeSnippets = applyAll || has('--write-snippets') || !(applyCodex || applyClaude || applyGemini || applyAntigravity);
|
|
53
58
|
const force = has('--force');
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
args: [],
|
|
58
|
-
env: {
|
|
59
|
-
SKILL_MASTER_UPDATE_CHANNEL: 'stable',
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const codexBlock = `
|
|
64
|
-
[mcp_servers.skill_master]
|
|
65
|
-
command = "skill-master-mcp"
|
|
66
|
-
startup_timeout_sec = 120
|
|
67
|
-
|
|
68
|
-
[mcp_servers.skill_master.env]
|
|
69
|
-
SKILL_MASTER_UPDATE_CHANNEL = "stable"
|
|
70
|
-
`;
|
|
71
|
-
|
|
72
|
-
const claudeSnippet = {
|
|
73
|
-
mcpServers: {
|
|
74
|
-
skill_master: mcpServer,
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const geminiSnippet = {
|
|
79
|
-
mcpServers: {
|
|
80
|
-
skill_master: mcpServer,
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const antigravitySnippet = {
|
|
85
|
-
mcpServers: {
|
|
86
|
-
skill_master: mcpServer,
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const ensureParent = (filePath) => mkdirSync(path.dirname(filePath), { recursive: true });
|
|
91
|
-
|
|
92
|
-
const readJsonOrEmpty = (filePath) => {
|
|
93
|
-
if (!existsSync(filePath)) return {};
|
|
94
|
-
const raw = readFileSync(filePath, 'utf8').trim();
|
|
95
|
-
return raw ? JSON.parse(raw) : {};
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const writeJson = (filePath, value) => {
|
|
99
|
-
ensureParent(filePath);
|
|
100
|
-
writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const mergeMcpServer = (filePath) => {
|
|
104
|
-
const current = readJsonOrEmpty(filePath);
|
|
105
|
-
const next = {
|
|
106
|
-
...current,
|
|
107
|
-
mcpServers: {
|
|
108
|
-
...(current.mcpServers ?? {}),
|
|
109
|
-
skill_master: mcpServer,
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
|
-
writeJson(filePath, next);
|
|
113
|
-
};
|
|
59
|
+
const serverConfig = buildSkillMasterServerConfig({ rootDir });
|
|
60
|
+
const codexBlock = buildCodexBlock(serverConfig);
|
|
61
|
+
const jsonSnippet = buildJsonMcpSnippet(serverConfig);
|
|
114
62
|
|
|
115
63
|
const writeSnippetsFiles = () => {
|
|
116
64
|
mkdirSync(snippetsDir, { recursive: true });
|
|
117
65
|
writeFileSync(path.join(snippetsDir, 'codex.config.toml'), codexBlock.trimStart(), 'utf8');
|
|
118
|
-
writeJson(path.join(snippetsDir, 'claude_desktop_config.skill_master.json'),
|
|
119
|
-
writeJson(path.join(snippetsDir, 'gemini.settings.skill_master.json'),
|
|
120
|
-
writeJson(path.join(snippetsDir, 'antigravity.mcp_config.skill_master.json'),
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const removeCodexBlock = (content) => {
|
|
124
|
-
const lines = content.split('\n');
|
|
125
|
-
const kept = [];
|
|
126
|
-
let skipping = false;
|
|
127
|
-
for (const line of lines) {
|
|
128
|
-
const trimmed = line.trim();
|
|
129
|
-
if (trimmed === '[mcp_servers.skill_master]') {
|
|
130
|
-
skipping = true;
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
if (skipping && trimmed.startsWith('[') && !trimmed.startsWith('[mcp_servers.skill_master')) {
|
|
134
|
-
skipping = false;
|
|
135
|
-
}
|
|
136
|
-
if (!skipping) kept.push(line);
|
|
137
|
-
}
|
|
138
|
-
return kept.join('\n').trimEnd();
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
const appendCodex = () => {
|
|
142
|
-
ensureParent(codexConfig);
|
|
143
|
-
const current = existsSync(codexConfig) ? readFileSync(codexConfig, 'utf8') : '';
|
|
144
|
-
if (current.includes('[mcp_servers.skill_master]') && !force) {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
const base = force ? removeCodexBlock(current) : current.trimEnd();
|
|
148
|
-
writeFileSync(codexConfig, `${base}\n${codexBlock}`, 'utf8');
|
|
149
|
-
return true;
|
|
66
|
+
writeJson(path.join(snippetsDir, 'claude_desktop_config.skill_master.json'), jsonSnippet);
|
|
67
|
+
writeJson(path.join(snippetsDir, 'gemini.settings.skill_master.json'), jsonSnippet);
|
|
68
|
+
writeJson(path.join(snippetsDir, 'antigravity.mcp_config.skill_master.json'), jsonSnippet);
|
|
150
69
|
};
|
|
151
70
|
|
|
152
71
|
const actions = [];
|
|
@@ -155,22 +74,24 @@ if (writeSnippets) {
|
|
|
155
74
|
actions.push(`snippets written to ${snippetsDir}`);
|
|
156
75
|
}
|
|
157
76
|
if (applyCodex) {
|
|
158
|
-
actions.push(
|
|
77
|
+
actions.push(appendCodexServer(codexConfig, serverConfig, { force }) ? `Codex registered at ${codexConfig}` : `Codex already had skill_master at ${codexConfig}`);
|
|
159
78
|
}
|
|
160
79
|
if (applyClaude) {
|
|
161
|
-
mergeMcpServer(claudeConfig);
|
|
80
|
+
mergeMcpServer(claudeConfig, serverConfig, { recoverInvalidJson: force });
|
|
162
81
|
actions.push(`Claude config merged at ${claudeConfig}`);
|
|
163
82
|
}
|
|
164
83
|
if (applyGemini) {
|
|
165
|
-
mergeMcpServer(geminiConfig);
|
|
84
|
+
mergeMcpServer(geminiConfig, serverConfig, { recoverInvalidJson: force });
|
|
166
85
|
actions.push(`Gemini config merged at ${geminiConfig}`);
|
|
167
86
|
}
|
|
168
87
|
if (applyAntigravity) {
|
|
169
|
-
mergeMcpServer(antigravityConfig);
|
|
88
|
+
mergeMcpServer(antigravityConfig, serverConfig, { recoverInvalidJson: force });
|
|
170
89
|
actions.push(`Antigravity config merged at ${antigravityConfig}`);
|
|
171
90
|
}
|
|
172
91
|
|
|
173
92
|
console.log('[skill_master] Client registration');
|
|
93
|
+
console.log(`- Command: ${serverConfig.command}`);
|
|
94
|
+
console.log(`- Args: ${serverConfig.args.join(' ')}`);
|
|
174
95
|
for (const action of actions) {
|
|
175
96
|
console.log(`- ${action}`);
|
|
176
97
|
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# Guia Multi-Computador - Skill Master MCP
|
|
2
|
+
|
|
3
|
+
## 1. Cenario
|
|
4
|
+
|
|
5
|
+
Voce quer usar o mesmo MCP `skill_master` em varios computadores, mantendo todos atualizados e escolhendo o canal de distribuicao mais adequado para cada caso.
|
|
6
|
+
|
|
7
|
+
## 2. Modelos recomendados
|
|
8
|
+
|
|
9
|
+
Hoje existem dois caminhos validos.
|
|
10
|
+
|
|
11
|
+
### Modelo A - npm publico
|
|
12
|
+
|
|
13
|
+
Melhor para:
|
|
14
|
+
|
|
15
|
+
- notebooks novos
|
|
16
|
+
- instalacao rapida
|
|
17
|
+
- ambientes onde o usuario nao deve clonar o repositorio
|
|
18
|
+
- Claude, Codex, Gemini e clientes MCP que aceitam `npx`
|
|
19
|
+
|
|
20
|
+
Base:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx -y @fprad0/skill-master-mcp@latest
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Modelo B - clone + launcher com auto-update
|
|
27
|
+
|
|
28
|
+
Melhor para:
|
|
29
|
+
|
|
30
|
+
- desenvolvimento do MCP
|
|
31
|
+
- testes de `stable` e `beta`
|
|
32
|
+
- controle maior sobre manifests e atualizacao por `git pull --ff-only`
|
|
33
|
+
- ambiente com repo privado
|
|
34
|
+
|
|
35
|
+
Cada computador tera:
|
|
36
|
+
|
|
37
|
+
- clone local do repositorio
|
|
38
|
+
- `git`
|
|
39
|
+
- `node` 18+
|
|
40
|
+
- launcher configurado no cliente MCP
|
|
41
|
+
- configuracao local em `%USERPROFILE%/.skill-master/config.json` no Windows ou `~/.skill-master/config.json` no Linux/macOS
|
|
42
|
+
|
|
43
|
+
Quando o menu detectar que o computador ainda nao esta globalmente pronto, ele vai mostrar o caminho de bootstrap e o atalho unico:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
skill-master-bootstrap-global
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Esse atalho instala as skills globais embutidas e registra Codex, Claude, Gemini e Antigravity para reconhecer `skill_master` como parte do sistema no cliente local.
|
|
50
|
+
|
|
51
|
+
A partir da correcao multi-OS, o registro recomendado nao depende mais de `PATH`. O registrador grava o Node.js absoluto como `command` e o `bin/skill-master.mjs` absoluto como `args`, o que evita falhas comuns em Windows, Linux, macOS e apps desktop que nao herdam o ambiente do terminal.
|
|
52
|
+
|
|
53
|
+
A partir da preparacao `0.0.11`, use o doctor para validar notebooks novos:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
skill-master-menu --run doctor
|
|
57
|
+
skill-master-menu --run bootstrap-global --yes
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
O bootstrap registra Codex, Claude Desktop, Gemini CLI e Antigravity. Depois, reinicie os clientes.
|
|
61
|
+
|
|
62
|
+
## 3. Instalacao em um novo computador
|
|
63
|
+
|
|
64
|
+
### 3.1 Opcao rapida - npm publico
|
|
65
|
+
|
|
66
|
+
#### Windows
|
|
67
|
+
|
|
68
|
+
```powershell
|
|
69
|
+
npm install -g @fprad0/skill-master-mcp
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
ou:
|
|
73
|
+
|
|
74
|
+
```powershell
|
|
75
|
+
npx -y @fprad0/skill-master-mcp@latest
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Linux / macOS
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install -g @fprad0/skill-master-mcp
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
ou:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx -y @fprad0/skill-master-mcp@latest
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 3.2 Opcao controlada - clone local
|
|
91
|
+
|
|
92
|
+
Pre-requisitos:
|
|
93
|
+
|
|
94
|
+
- Git instalado
|
|
95
|
+
- Node.js 18+
|
|
96
|
+
- acesso ao GitHub
|
|
97
|
+
- token read-only se o repositorio for privado
|
|
98
|
+
|
|
99
|
+
Clone:
|
|
100
|
+
|
|
101
|
+
```powershell
|
|
102
|
+
cd C:\Users\CDT\Documents
|
|
103
|
+
git clone https://github.com/FPrad0/skill-master-mcp.git
|
|
104
|
+
cd skill-master-mcp
|
|
105
|
+
npm ci
|
|
106
|
+
npm run build
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3.3 Configuracao local
|
|
110
|
+
|
|
111
|
+
Criar:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
C:\Users\<USER>\.skill-master\config.json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Modelo:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"channel": "stable",
|
|
122
|
+
"autoUpdate": true,
|
|
123
|
+
"updateMode": "on-start",
|
|
124
|
+
"manifestUrl": "https://raw.githubusercontent.com/FPrad0/skill-master-mcp/main/manifests/channels/stable.json",
|
|
125
|
+
"localSkillRoots": [
|
|
126
|
+
"%USERPROFILE%/.codex/skills",
|
|
127
|
+
"%USERPROFILE%/.agents/skills"
|
|
128
|
+
],
|
|
129
|
+
"allowWebSources": false
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 4. Configuracao do cliente MCP
|
|
134
|
+
|
|
135
|
+
No modelo npm global, prefira sempre o registro gerado por `skill-master-register-clients`, porque ele usa caminhos absolutos.
|
|
136
|
+
|
|
137
|
+
No modelo clone + launcher, o launcher ainda e valido para desenvolvimento, mas o doctor vai classificar esse modo como `launcher`, nao como o modo robusto de pacote global.
|
|
138
|
+
|
|
139
|
+
Exemplo robusto para Codex:
|
|
140
|
+
|
|
141
|
+
```toml
|
|
142
|
+
[mcp_servers.skill_master]
|
|
143
|
+
command = "C:\\Program Files\\nodejs\\node.exe"
|
|
144
|
+
args = ["C:\\Users\\CDT\\AppData\\Roaming\\npm\\node_modules\\@fprad0\\skill-master-mcp\\bin\\skill-master.mjs"]
|
|
145
|
+
startup_timeout_sec = 120
|
|
146
|
+
|
|
147
|
+
[mcp_servers.skill_master.env]
|
|
148
|
+
SKILL_MASTER_UPDATE_CHANNEL = "stable"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Para migrar clientes antigos que ainda usam `skill-master-mcp` via PATH, `npx` ou launcher local:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
skill-master-register-clients --apply-all --force
|
|
155
|
+
skill-master-menu --run doctor
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
No modelo clone + launcher, o cliente deve chamar o launcher, nao o `dist/index.js` diretamente.
|
|
159
|
+
|
|
160
|
+
Exemplo conceitual:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"mcpServers": {
|
|
165
|
+
"skill_master": {
|
|
166
|
+
"command": "powershell",
|
|
167
|
+
"args": [
|
|
168
|
+
"-ExecutionPolicy",
|
|
169
|
+
"Bypass",
|
|
170
|
+
"-File",
|
|
171
|
+
"C:/Users/CDT/Documents/skill-master-mcp/scripts/skill-master-launcher.ps1"
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 5. Como as atualizacoes chegam automaticamente
|
|
179
|
+
|
|
180
|
+
### No modelo npm publico
|
|
181
|
+
|
|
182
|
+
1. voce publica uma nova versao no npm publico
|
|
183
|
+
2. a maquina cliente usa `@latest`
|
|
184
|
+
3. no proximo `npx` ou reinstalacao, a nova versao e resolvida
|
|
185
|
+
|
|
186
|
+
### No modelo clone + launcher
|
|
187
|
+
|
|
188
|
+
1. voce faz push no GitHub
|
|
189
|
+
2. voce atualiza o manifesto `stable.json`
|
|
190
|
+
3. o usuario abre o MCP
|
|
191
|
+
4. o launcher verifica o manifesto
|
|
192
|
+
5. se houver versao nova e o clone local estiver limpo, o launcher atualiza
|
|
193
|
+
6. o MCP inicia ja atualizado
|
|
194
|
+
|
|
195
|
+
## 6. Como publicar uma atualizacao
|
|
196
|
+
|
|
197
|
+
### Caminho publico
|
|
198
|
+
|
|
199
|
+
1. subir a nova versao para `main`
|
|
200
|
+
2. publicar pelo workflow `Publish Skill Master to npmjs` somente com autorizacao explicita
|
|
201
|
+
3. validar com `npm view` e `npx`
|
|
202
|
+
|
|
203
|
+
### Caminho clone + launcher
|
|
204
|
+
|
|
205
|
+
1. subir a nova versao para `main`
|
|
206
|
+
2. atualizar `manifests/channels/stable.json`
|
|
207
|
+
3. criar release/tag quando fizer sentido
|
|
208
|
+
4. deixar o launcher puxar com `git pull --ff-only`
|
|
209
|
+
|
|
210
|
+
## 7. Estrategia para varios usuarios
|
|
211
|
+
|
|
212
|
+
### Poucos usuarios tecnicos
|
|
213
|
+
|
|
214
|
+
Use clone privado + launcher. E a rota com mais controle.
|
|
215
|
+
|
|
216
|
+
### Varios usuarios sem perfil tecnico
|
|
217
|
+
|
|
218
|
+
Use npm publico.
|
|
219
|
+
|
|
220
|
+
Se for necessario restringir distribuicao, evolua para:
|
|
221
|
+
|
|
222
|
+
- pacote npm privado
|
|
223
|
+
- instalador/bundle
|
|
224
|
+
- MCP remoto
|
|
225
|
+
|
|
226
|
+
### Equipe ou empresa
|
|
227
|
+
|
|
228
|
+
Evoluir para:
|
|
229
|
+
|
|
230
|
+
- GitHub Packages com permissoes
|
|
231
|
+
- workflow de release
|
|
232
|
+
- canais `stable` e `beta`
|
|
233
|
+
- logs e telemetria minima opcional
|
|
234
|
+
|
|
235
|
+
## 8. Manutencao
|
|
236
|
+
|
|
237
|
+
Recomendacoes:
|
|
238
|
+
|
|
239
|
+
- manter changelog curto
|
|
240
|
+
- nunca quebrar configuracao sem migracao
|
|
241
|
+
- testar update em uma maquina secundaria antes de mover `stable`
|
|
242
|
+
- manter `beta` para validacao
|
|
243
|
+
- documentar breaking changes
|
|
244
|
+
|
|
245
|
+
## 9. Quando nao atualizar automaticamente
|
|
246
|
+
|
|
247
|
+
No modelo clone + launcher, o updater deve recusar atualizacao automatica quando:
|
|
248
|
+
|
|
249
|
+
- houver arquivos locais modificados
|
|
250
|
+
- o GitHub estiver inacessivel
|
|
251
|
+
- o manifesto estiver invalido
|
|
252
|
+
- houver mudanca de versao de Node nao atendida
|
|
253
|
+
- `npm ci` ou build falhar
|
|
254
|
+
|
|
255
|
+
Nesses casos, ele deve iniciar a versao local e mostrar o status pela ferramenta `skill_master_sync_status`.
|