@fprad0/skill-master-mcp 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +129 -10
  3. package/VERSION.md +3 -3
  4. package/bin/lib/menu-core.mjs +284 -2
  5. package/bin/skill-master-activation.mjs +163 -0
  6. package/bin/skill-master-bootstrap-global.mjs +35 -0
  7. package/bin/skill-master-eval-activation.mjs +32 -0
  8. package/bin/skill-master-install-global-skills.mjs +77 -0
  9. package/bin/skill-master-register-clients.mjs +154 -0
  10. package/bin/skill-master-success-skills.mjs +307 -0
  11. package/dist/activation-evals.d.ts +32 -0
  12. package/dist/activation-evals.d.ts.map +1 -0
  13. package/dist/activation-evals.js +116 -0
  14. package/dist/activation-evals.js.map +1 -0
  15. package/dist/domain-router.d.ts +11 -0
  16. package/dist/domain-router.d.ts.map +1 -0
  17. package/dist/domain-router.js +79 -0
  18. package/dist/domain-router.js.map +1 -0
  19. package/dist/index.js +460 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/moral-governance.d.ts +24 -0
  22. package/dist/moral-governance.d.ts.map +1 -0
  23. package/dist/moral-governance.js +143 -0
  24. package/dist/moral-governance.js.map +1 -0
  25. package/dist/prompt-router.d.ts +47 -0
  26. package/dist/prompt-router.d.ts.map +1 -0
  27. package/dist/prompt-router.js +324 -0
  28. package/dist/prompt-router.js.map +1 -0
  29. package/dist/success-learning.d.ts +147 -0
  30. package/dist/success-learning.d.ts.map +1 -0
  31. package/dist/success-learning.js +444 -0
  32. package/dist/success-learning.js.map +1 -0
  33. package/docs/architecture/APRENDIZADO_DE_IMPLEMENTACOES_BEM_SUCEDIDAS.md +125 -0
  34. package/docs/architecture/ARQUITETURA_AUTO_UPDATE.md +9 -0
  35. package/docs/architecture/PLANO_MASTER_ACIONAMENTO_AUTOMATICO_E_APRENDIZADO.md +341 -0
  36. package/docs/architecture/REDE_SEGURA_DE_SKILLS.md +148 -0
  37. package/docs/planning/V0_0_9_APROVACAO_CRITICA_MENSAGENS_DE_VENDA.md +85 -0
  38. package/docs/planning/V0_0_9_FONTES_E_CRITERIOS_DE_AUTORIDADE.md +139 -0
  39. package/docs/planning/V0_0_9_MATRIZ_SKILLS_MULTIDISCIPLINARES.md +105 -0
  40. package/docs/planning/V0_0_9_POLITICA_MORAL_CATOLICA_PARA_IA.md +181 -0
  41. package/docs/planning/V0_0_9_PROMPTS_EXECUCAO.md +59 -0
  42. package/docs/planning/V0_0_9_ROADMAP_DISCERNIMENTO_E_CONHECIMENTO_AMPLO.md +181 -0
  43. package/docs/skill-candidates/v0.0.9/ai-ethics-human-dignity/SKILL.md +32 -0
  44. package/docs/skill-candidates/v0.0.9/broad-domain-router/SKILL.md +41 -0
  45. package/docs/skill-candidates/v0.0.9/catholic-moral-discernment/SKILL.md +31 -0
  46. package/docs/skill-candidates/v0.0.9/engineering-systems-master/SKILL.md +31 -0
  47. package/docs/skill-candidates/v0.0.9/language-quality-pt-en-fr/SKILL.md +28 -0
  48. package/docs/skill-candidates/v0.0.9/math-science-reasoning/SKILL.md +29 -0
  49. package/docs/skill-candidates/v0.0.9/philosophy-sociology-discernment/SKILL.md +28 -0
  50. package/docs/skill-candidates/v0.0.9/professional-boundary-triage/SKILL.md +40 -0
  51. package/docs/skill-candidates/v0.0.9/release-ethics-gate/SKILL.md +32 -0
  52. package/docs/skill-candidates/v0.0.9/source-authority-reviewer/SKILL.md +31 -0
  53. package/manifests/channels/beta.json +7 -6
  54. package/manifests/channels/stable.json +8 -7
  55. package/network/approved-skills.json +51 -2
  56. package/network/unapproved-skill-candidates.json +77 -0
  57. package/package.json +13 -3
  58. package/sources.json +4 -1
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import process from 'node:process';
7
+ import { fileURLToPath } from 'node:url';
8
+ import prompts from 'prompts';
9
+ import { buildCatalog, loadConfig } from '../dist/catalog.js';
10
+ import { routeSkillMasterPrompt } from '../dist/prompt-router.js';
11
+
12
+ const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
13
+ const skillMasterHome = process.env.SKILL_MASTER_HOME ?? path.join(os.homedir(), '.skill-master');
14
+ const activationConfigPath = process.env.SKILL_MASTER_ACTIVATION_CONFIG
15
+ ?? path.join(skillMasterHome, 'activation.json');
16
+ const sourcesConfigPath = process.env.SKILL_MASTER_CONFIG ?? path.join(rootDir, 'sources.json');
17
+ const workspace = process.env.SKILL_MASTER_WORKSPACE ?? process.cwd();
18
+
19
+ const defaultConfig = {
20
+ activationMode: 'balanced',
21
+ riskTolerance: 'normal',
22
+ };
23
+
24
+ const isTty = () => Boolean(process.stdin.isTTY && process.stdout.isTTY);
25
+
26
+ const readActivationConfig = () => {
27
+ if (!existsSync(activationConfigPath)) return defaultConfig;
28
+ return { ...defaultConfig, ...JSON.parse(readFileSync(activationConfigPath, 'utf8')) };
29
+ };
30
+
31
+ const writeActivationConfig = (config) => {
32
+ mkdirSync(path.dirname(activationConfigPath), { recursive: true });
33
+ writeFileSync(activationConfigPath, JSON.stringify(config, null, 2), 'utf8');
34
+ };
35
+
36
+ const parseArgs = (argv) => {
37
+ const parsed = {
38
+ command: 'status',
39
+ mode: null,
40
+ prompt: null,
41
+ format: 'markdown',
42
+ };
43
+
44
+ for (let index = 0; index < argv.length; index += 1) {
45
+ const arg = argv[index];
46
+ if (arg === '--status') parsed.command = 'status';
47
+ else if (arg === '--set-mode') {
48
+ parsed.command = 'set-mode';
49
+ parsed.mode = argv[++index] ?? null;
50
+ } else if (arg === '--route-prompt') {
51
+ parsed.command = 'route-prompt';
52
+ parsed.prompt = argv[++index] ?? null;
53
+ } else if (arg === '--route-prompt-interactive') parsed.command = 'route-prompt-interactive';
54
+ else if (arg === '--notion-summary') parsed.command = 'notion-summary';
55
+ else if (arg === '--json') parsed.format = 'json';
56
+ else if (arg === '--help' || arg === '-h') parsed.command = 'help';
57
+ else throw new Error(`Unknown argument: ${arg}`);
58
+ }
59
+
60
+ return parsed;
61
+ };
62
+
63
+ const loadSkills = async () => {
64
+ const config = await loadConfig(sourcesConfigPath);
65
+ const catalog = await buildCatalog(config, { cwd: workspace, includeWeb: false });
66
+ return catalog.skills;
67
+ };
68
+
69
+ const routePrompt = async (prompt, { format }) => {
70
+ if (!prompt) throw new Error('Missing prompt.');
71
+ const config = readActivationConfig();
72
+ const skills = await loadSkills();
73
+ const decision = routeSkillMasterPrompt(skills, prompt, {
74
+ activationMode: config.activationMode,
75
+ riskTolerance: config.riskTolerance,
76
+ limit: 8,
77
+ sourceKinds: ['workspace', 'local', 'plugin'],
78
+ });
79
+
80
+ if (format === 'json') {
81
+ console.log(JSON.stringify(decision, null, 2));
82
+ return;
83
+ }
84
+
85
+ console.log('Skill Master - prompt router');
86
+ console.log(`- Ativar: ${decision.shouldActivate ? 'sim' : 'nao'}`);
87
+ console.log(`- Modo: ${decision.activationMode}`);
88
+ console.log(`- Execucao: ${decision.executionMode}`);
89
+ console.log(`- Persona: ${decision.personaOverlay}`);
90
+ console.log(`- Proxima acao: ${decision.nextAction}`);
91
+ if (decision.recommendedSkills.length > 0) {
92
+ console.log('- Skills:');
93
+ for (const skill of decision.recommendedSkills.slice(0, 5)) {
94
+ console.log(` - ${skill.name} (${skill.source})`);
95
+ }
96
+ }
97
+ };
98
+
99
+ const printStatus = () => {
100
+ const config = readActivationConfig();
101
+ console.log('Skill Master - modo de ativacao');
102
+ console.log(`- Config: ${activationConfigPath}`);
103
+ console.log(`- Modo: ${config.activationMode}`);
104
+ console.log(`- Tolerancia de risco: ${config.riskTolerance}`);
105
+ console.log(`- Workspace: ${workspace}`);
106
+ };
107
+
108
+ const setMode = (mode) => {
109
+ if (!['manual', 'balanced', 'always-on-assisted'].includes(mode)) {
110
+ throw new Error('Mode must be manual, balanced, or always-on-assisted.');
111
+ }
112
+ const config = { ...readActivationConfig(), activationMode: mode };
113
+ writeActivationConfig(config);
114
+ console.log(`Modo de ativacao atualizado para: ${mode}`);
115
+ };
116
+
117
+ const routePromptInteractive = async (format) => {
118
+ if (!isTty()) throw new Error('Interactive prompt routing requires a TTY.');
119
+ const response = await prompts({
120
+ type: 'text',
121
+ name: 'prompt',
122
+ message: 'Qual prompt voce quer avaliar?',
123
+ validate: (value) => value.trim().length >= 3 || 'Informe ao menos 3 caracteres.',
124
+ });
125
+ await routePrompt(response.prompt, { format });
126
+ };
127
+
128
+ const printNotionSummary = () => {
129
+ const config = readActivationConfig();
130
+ console.log('## Resumo para Notion - Skill Master Activation');
131
+ console.log('');
132
+ console.log(`- Modo atual: ${config.activationMode}`);
133
+ console.log(`- Tolerancia de risco: ${config.riskTolerance}`);
134
+ console.log(`- Workspace: ${workspace}`);
135
+ console.log('- Politica: nenhuma publicacao sem autorizacao explicita.');
136
+ console.log('- Recomendacao: registrar mudancas de modo, decisoes de skills aprendidas e releases pendentes no ledger do Skill Master.');
137
+ };
138
+
139
+ const printHelp = () => {
140
+ console.log(`Skill Master Activation
141
+
142
+ Usage:
143
+ skill-master-activation --status
144
+ skill-master-activation --set-mode manual|balanced|always-on-assisted
145
+ skill-master-activation --route-prompt "prompt" [--json]
146
+ skill-master-activation --route-prompt-interactive
147
+ skill-master-activation --notion-summary
148
+ `);
149
+ };
150
+
151
+ try {
152
+ const args = parseArgs(process.argv.slice(2));
153
+ if (args.command === 'help') printHelp();
154
+ else if (args.command === 'status') printStatus();
155
+ else if (args.command === 'set-mode') setMode(args.mode);
156
+ else if (args.command === 'route-prompt') await routePrompt(args.prompt, { format: args.format });
157
+ else if (args.command === 'route-prompt-interactive') await routePromptInteractive(args.format);
158
+ else if (args.command === 'notion-summary') printNotionSummary();
159
+ else throw new Error(`Unsupported command: ${args.command}`);
160
+ } catch (error) {
161
+ process.stderr.write(`[skill_master] ${error instanceof Error ? error.message : String(error)}\n`);
162
+ process.exitCode = 1;
163
+ }
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from 'node:child_process';
4
+ import { dirname, join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const here = dirname(fileURLToPath(import.meta.url));
8
+ const rootDir = dirname(here);
9
+
10
+ const steps = [
11
+ {
12
+ label: 'install-global-skills',
13
+ command: process.execPath,
14
+ args: [join(rootDir, 'bin', 'skill-master-install-global-skills.mjs'), '--overwrite'],
15
+ },
16
+ {
17
+ label: 'register-clients',
18
+ command: process.execPath,
19
+ args: [join(rootDir, 'bin', 'skill-master-register-clients.mjs'), '--apply-all', '--force'],
20
+ },
21
+ ];
22
+
23
+ for (const step of steps) {
24
+ console.log(`[skill_master] Running ${step.label}...`);
25
+ const result = spawnSync(step.command, step.args, { stdio: 'inherit' });
26
+ if (result.status !== 0) {
27
+ process.exitCode = result.status ?? 1;
28
+ break;
29
+ }
30
+ }
31
+
32
+ if ((process.exitCode ?? 0) === 0) {
33
+ console.log('[skill_master] Global bootstrap complete.');
34
+ }
35
+
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { runActivationEvals } from '../dist/activation-evals.js';
4
+
5
+ const report = runActivationEvals();
6
+ const asJson = process.argv.includes('--json');
7
+
8
+ if (asJson) {
9
+ console.log(JSON.stringify(report, null, 2));
10
+ } else {
11
+ console.log('Skill Master Activation Evals');
12
+ console.log(`- Generated at: ${report.generatedAt}`);
13
+ console.log(`- Total: ${report.total}`);
14
+ console.log(`- Passed: ${report.passed}`);
15
+ console.log(`- Failed: ${report.failed}`);
16
+ console.log(`- Accuracy: ${(report.accuracy * 100).toFixed(1)}%`);
17
+ console.log(`- False positives: ${report.falsePositives}`);
18
+ console.log(`- False negatives: ${report.falseNegatives}`);
19
+ console.log(`- Correct blocks: ${report.correctBlocks}`);
20
+ console.log(`- Recommendation: ${report.recommendation}`);
21
+
22
+ const failed = report.results.filter((result) => !result.passed);
23
+ if (failed.length > 0) {
24
+ console.log('');
25
+ console.log('Failed cases:');
26
+ for (const result of failed) {
27
+ console.log(`- ${result.case.id}: ${result.findings.join('; ')}`);
28
+ }
29
+ }
30
+ }
31
+
32
+ process.exitCode = report.recommendation === 'balanced-ready' ? 0 : 1;
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readdirSync, cpSync, mkdirSync } from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const here = path.dirname(fileURLToPath(import.meta.url));
8
+ const rootDir = path.resolve(here, '..');
9
+ const defaultSource = path.join(rootDir, 'docs', 'skill-candidates', 'v0.0.9');
10
+ const defaultTarget = path.join(process.env.CODEX_HOME ?? path.join(os.homedir(), '.codex'), 'skills');
11
+
12
+ const args = process.argv.slice(2);
13
+ const has = (flag) => args.includes(flag);
14
+ const readValue = (flag, fallback) => {
15
+ const index = args.indexOf(flag);
16
+ return index >= 0 ? args[index + 1] : fallback;
17
+ };
18
+
19
+ if (has('--help')) {
20
+ console.log(`Skill Master global skills installer
21
+
22
+ Uso:
23
+ skill-master-install-global-skills
24
+ skill-master-install-global-skills --overwrite
25
+ skill-master-install-global-skills --dry-run
26
+ skill-master-install-global-skills --target ~/.codex/skills
27
+
28
+ Instala as skills globais embutidas em CODEX_HOME/skills ou ~/.codex/skills.
29
+ `);
30
+ process.exit(0);
31
+ }
32
+
33
+ const source = readValue('--source', defaultSource);
34
+ const target = readValue('--target', defaultTarget);
35
+ const overwrite = has('--overwrite');
36
+ const dryRun = has('--dry-run');
37
+
38
+ if (!existsSync(source)) {
39
+ console.error(`[skill_master] Source not found: ${source}`);
40
+ process.exit(1);
41
+ }
42
+
43
+ const skills = readdirSync(source, { withFileTypes: true })
44
+ .filter((entry) => entry.isDirectory())
45
+ .map((entry) => entry.name)
46
+ .sort();
47
+
48
+ if (!dryRun) {
49
+ mkdirSync(target, { recursive: true });
50
+ }
51
+
52
+ const installed = [];
53
+ const skipped = [];
54
+
55
+ for (const skill of skills) {
56
+ const from = path.join(source, skill);
57
+ const to = path.join(target, skill);
58
+ if (existsSync(to) && !overwrite) {
59
+ skipped.push(skill);
60
+ continue;
61
+ }
62
+ if (!dryRun) {
63
+ cpSync(from, to, { recursive: true, force: overwrite });
64
+ }
65
+ installed.push(skill);
66
+ }
67
+
68
+ console.log('[skill_master] Global skills installer');
69
+ console.log(`- Source: ${source}`);
70
+ console.log(`- Target: ${target}`);
71
+ console.log(`- Installed: ${installed.length}`);
72
+ console.log(`- Skipped: ${skipped.length}`);
73
+ if (dryRun) console.log('- Dry run: no files were written.');
74
+ if (installed.length) console.log(`- Installed skills: ${installed.join(', ')}`);
75
+ if (skipped.length) console.log(`- Skipped skills: ${skipped.join(', ')}`);
76
+ console.log('[skill_master] Restart or rescan Codex to load new global skills.');
77
+
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+
6
+ const args = process.argv.slice(2);
7
+ const has = (flag) => args.includes(flag);
8
+ const readValue = (flag, fallback) => {
9
+ const index = args.indexOf(flag);
10
+ return index >= 0 ? args[index + 1] : fallback;
11
+ };
12
+
13
+ if (has('--help')) {
14
+ console.log(`Skill Master client registration
15
+
16
+ Uso:
17
+ skill-master-register-clients --write-snippets
18
+ skill-master-register-clients --apply-codex
19
+ skill-master-register-clients --apply-claude
20
+ skill-master-register-clients --apply-gemini
21
+ skill-master-register-clients --apply-all
22
+ skill-master-register-clients --apply-codex --force
23
+
24
+ Registra o servidor MCP skill_master como stdio usando o binario global:
25
+ skill-master-mcp
26
+ `);
27
+ process.exit(0);
28
+ }
29
+
30
+ const home = os.homedir();
31
+ const snippetsDir = readValue('--snippets-dir', path.join(home, '.skill-master', 'client-configs'));
32
+ const codexConfig = readValue('--codex-config', path.join(process.env.CODEX_HOME ?? path.join(home, '.codex'), 'config.toml'));
33
+ const claudeConfig = readValue('--claude-config', path.join(home, '.config', 'Claude', 'claude_desktop_config.json'));
34
+ const geminiConfig = readValue('--gemini-config', path.join(home, '.gemini', 'settings.json'));
35
+
36
+ const applyAll = has('--apply-all');
37
+ const applyCodex = applyAll || has('--apply-codex');
38
+ const applyClaude = applyAll || has('--apply-claude');
39
+ const applyGemini = applyAll || has('--apply-gemini');
40
+ const writeSnippets = applyAll || has('--write-snippets') || !(applyCodex || applyClaude || applyGemini);
41
+ const force = has('--force');
42
+
43
+ const mcpServer = {
44
+ command: 'skill-master-mcp',
45
+ args: [],
46
+ env: {
47
+ SKILL_MASTER_UPDATE_CHANNEL: 'stable',
48
+ },
49
+ };
50
+
51
+ const codexBlock = `
52
+ [mcp_servers.skill_master]
53
+ command = "skill-master-mcp"
54
+ startup_timeout_sec = 120
55
+
56
+ [mcp_servers.skill_master.env]
57
+ SKILL_MASTER_UPDATE_CHANNEL = "stable"
58
+ `;
59
+
60
+ const claudeSnippet = {
61
+ mcpServers: {
62
+ skill_master: mcpServer,
63
+ },
64
+ };
65
+
66
+ const geminiSnippet = {
67
+ mcpServers: {
68
+ skill_master: mcpServer,
69
+ },
70
+ };
71
+
72
+ const ensureParent = (filePath) => mkdirSync(path.dirname(filePath), { recursive: true });
73
+
74
+ const readJsonOrEmpty = (filePath) => {
75
+ if (!existsSync(filePath)) return {};
76
+ const raw = readFileSync(filePath, 'utf8').trim();
77
+ return raw ? JSON.parse(raw) : {};
78
+ };
79
+
80
+ const writeJson = (filePath, value) => {
81
+ ensureParent(filePath);
82
+ writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
83
+ };
84
+
85
+ const mergeMcpServer = (filePath) => {
86
+ const current = readJsonOrEmpty(filePath);
87
+ const next = {
88
+ ...current,
89
+ mcpServers: {
90
+ ...(current.mcpServers ?? {}),
91
+ skill_master: mcpServer,
92
+ },
93
+ };
94
+ writeJson(filePath, next);
95
+ };
96
+
97
+ const writeSnippetsFiles = () => {
98
+ mkdirSync(snippetsDir, { recursive: true });
99
+ writeFileSync(path.join(snippetsDir, 'codex.config.toml'), codexBlock.trimStart(), 'utf8');
100
+ writeJson(path.join(snippetsDir, 'claude_desktop_config.skill_master.json'), claudeSnippet);
101
+ writeJson(path.join(snippetsDir, 'gemini.settings.skill_master.json'), geminiSnippet);
102
+ };
103
+
104
+ const removeCodexBlock = (content) => {
105
+ const lines = content.split('\n');
106
+ const kept = [];
107
+ let skipping = false;
108
+ for (const line of lines) {
109
+ const trimmed = line.trim();
110
+ if (trimmed === '[mcp_servers.skill_master]') {
111
+ skipping = true;
112
+ continue;
113
+ }
114
+ if (skipping && trimmed.startsWith('[') && !trimmed.startsWith('[mcp_servers.skill_master')) {
115
+ skipping = false;
116
+ }
117
+ if (!skipping) kept.push(line);
118
+ }
119
+ return kept.join('\n').trimEnd();
120
+ };
121
+
122
+ const appendCodex = () => {
123
+ ensureParent(codexConfig);
124
+ const current = existsSync(codexConfig) ? readFileSync(codexConfig, 'utf8') : '';
125
+ if (current.includes('[mcp_servers.skill_master]') && !force) {
126
+ return false;
127
+ }
128
+ const base = force ? removeCodexBlock(current) : current.trimEnd();
129
+ writeFileSync(codexConfig, `${base}\n${codexBlock}`, 'utf8');
130
+ return true;
131
+ };
132
+
133
+ const actions = [];
134
+ if (writeSnippets) {
135
+ writeSnippetsFiles();
136
+ actions.push(`snippets written to ${snippetsDir}`);
137
+ }
138
+ if (applyCodex) {
139
+ actions.push(appendCodex() ? `Codex registered at ${codexConfig}` : `Codex already had skill_master at ${codexConfig}`);
140
+ }
141
+ if (applyClaude) {
142
+ mergeMcpServer(claudeConfig);
143
+ actions.push(`Claude config merged at ${claudeConfig}`);
144
+ }
145
+ if (applyGemini) {
146
+ mergeMcpServer(geminiConfig);
147
+ actions.push(`Gemini config merged at ${geminiConfig}`);
148
+ }
149
+
150
+ console.log('[skill_master] Client registration');
151
+ for (const action of actions) {
152
+ console.log(`- ${action}`);
153
+ }
154
+ console.log('- Restart Codex, Claude or Gemini after registration.');