@fprad0/skill-master-mcp 0.0.7 → 0.0.8
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 +9 -0
- package/README.md +86 -6
- package/VERSION.md +2 -2
- package/bin/lib/menu-core.mjs +127 -1
- package/bin/skill-master-activation.mjs +163 -0
- package/bin/skill-master-eval-activation.mjs +32 -0
- package/bin/skill-master-success-skills.mjs +307 -0
- package/dist/activation-evals.d.ts +32 -0
- package/dist/activation-evals.d.ts.map +1 -0
- package/dist/activation-evals.js +116 -0
- package/dist/activation-evals.js.map +1 -0
- package/dist/index.js +326 -1
- package/dist/index.js.map +1 -1
- package/dist/prompt-router.d.ts +43 -0
- package/dist/prompt-router.d.ts.map +1 -0
- package/dist/prompt-router.js +308 -0
- package/dist/prompt-router.js.map +1 -0
- package/dist/success-learning.d.ts +147 -0
- package/dist/success-learning.d.ts.map +1 -0
- package/dist/success-learning.js +444 -0
- package/dist/success-learning.js.map +1 -0
- package/docs/architecture/APRENDIZADO_DE_IMPLEMENTACOES_BEM_SUCEDIDAS.md +125 -0
- package/docs/architecture/ARQUITETURA_AUTO_UPDATE.md +9 -0
- package/docs/architecture/PLANO_MASTER_ACIONAMENTO_AUTOMATICO_E_APRENDIZADO.md +341 -0
- package/docs/architecture/REDE_SEGURA_DE_SKILLS.md +148 -0
- package/manifests/channels/beta.json +6 -5
- package/manifests/channels/stable.json +7 -6
- package/network/approved-skills.json +51 -2
- package/network/unapproved-skill-candidates.json +77 -0
- package/package.json +8 -3
- package/sources.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@ All notable changes to `skill_master` will be tracked here.
|
|
|
7
7
|
- Prepare a public npm publication path with dedicated workflow and operator guide.
|
|
8
8
|
- Upgrade release automation from Node `20` to Node `22`.
|
|
9
9
|
|
|
10
|
+
## [0.0.8] - 2026-06-27
|
|
11
|
+
|
|
12
|
+
- Add `skill_master_prompt_router` with `manual`, `balanced`, and `always-on-assisted` activation modes.
|
|
13
|
+
- Add Dev Senior Master persona routing, safety gates, Notion/update detection, and learned-skill signals.
|
|
14
|
+
- Add success-learning flows for human approval packages, local/global activation, study decisions, and rejection history.
|
|
15
|
+
- Add `skill-master-activation`, `skill-master-success-skills`, and `skill-master-eval-activation` operator CLIs.
|
|
16
|
+
- Expand the terminal menu with activation status, prompt recommendations, learned-skill notifications, study/reject actions, and Notion summaries.
|
|
17
|
+
- Add activation evals with positive, negative, and risk cases plus `npm run eval:activation`.
|
|
18
|
+
|
|
10
19
|
## [0.0.7] - 2026-06-26
|
|
11
20
|
|
|
12
21
|
- Add a visual terminal menu for `skill-master-menu` using `prompts`, with TTY detection and direct action mode.
|
package/README.md
CHANGED
|
@@ -108,18 +108,21 @@ npm install -g @fprad0/skill-master-mcp
|
|
|
108
108
|
npx -y @fprad0/skill-master-mcp@latest
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
Estado atual
|
|
111
|
+
Estado atual preparado em `2026-06-27`:
|
|
112
112
|
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
- `npm install` e `
|
|
113
|
+
- release local preparada: `@fprad0/skill-master-mcp@0.0.8`
|
|
114
|
+
- validacao de pacote por tarball local confirmada
|
|
115
|
+
- publicacao no npmjs aguardando autenticacao npmjs nesta maquina
|
|
116
|
+
- apos publicar, validar `npm install`, `npx` e dist-tag `latest`
|
|
117
117
|
|
|
118
118
|
Comandos globais principais:
|
|
119
119
|
|
|
120
120
|
```bash
|
|
121
|
+
skill-master-activation
|
|
122
|
+
skill-master-eval-activation
|
|
121
123
|
skill-master-mcp
|
|
122
124
|
skill-master-menu
|
|
125
|
+
skill-master-success-skills
|
|
123
126
|
skill-master-update
|
|
124
127
|
skill-master-configure-private-registry
|
|
125
128
|
```
|
|
@@ -136,10 +139,38 @@ O menu agora possui modo visual interativo para terminal com TTY e tambem aceita
|
|
|
136
139
|
skill-master-menu --run status
|
|
137
140
|
skill-master-menu --run check
|
|
138
141
|
skill-master-menu --run update --yes
|
|
142
|
+
skill-master-menu --run notifications
|
|
143
|
+
skill-master-menu --run study-skills
|
|
144
|
+
skill-master-menu --run approval-package
|
|
145
|
+
skill-master-menu --run activation-status
|
|
146
|
+
skill-master-menu --run recommend-prompt
|
|
147
|
+
skill-master-menu --run notion-summary
|
|
139
148
|
```
|
|
140
149
|
|
|
141
150
|
O menu visual usa `prompts` para ficar mais legivel no terminal e manter compatibilidade com `Node 18+`.
|
|
142
151
|
|
|
152
|
+
O menu tambem mostra notificacoes de skills aprendidas pendentes e links externos para estudo. As acoes de ativacao sao:
|
|
153
|
+
|
|
154
|
+
- `skill-master-menu --run activate-learned-local`: instala uma skill aprovada em `.codex/skills` do workspace atual.
|
|
155
|
+
- `skill-master-menu --run activate-learned-global`: instala uma skill aprovada em `${CODEX_HOME:-~/.codex}/skills`.
|
|
156
|
+
- `skill-master-menu --run mark-study`: registra uma skill candidata como material para estudo.
|
|
157
|
+
- `skill-master-menu --run reject-skill`: rejeita uma skill candidata preservando historico.
|
|
158
|
+
|
|
159
|
+
Para modo de ativacao e recomendacao local:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
skill-master-activation --status
|
|
163
|
+
skill-master-activation --set-mode balanced
|
|
164
|
+
skill-master-activation --route-prompt "skill-master, recomende skills para este prompt"
|
|
165
|
+
skill-master-activation --notion-summary
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Para rodar as avaliacoes de ativacao antes de release:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
npm run eval:activation
|
|
172
|
+
```
|
|
173
|
+
|
|
143
174
|
Para atualizar a instalacao global via npm sem iniciar o servidor MCP:
|
|
144
175
|
|
|
145
176
|
```bash
|
|
@@ -200,18 +231,62 @@ O `skill_master` pode aprender com as skills ja existentes em cada maquina insta
|
|
|
200
231
|
Ferramentas MCP principais:
|
|
201
232
|
|
|
202
233
|
- `skill_master_refresh_catalog`
|
|
234
|
+
- `skill_master_prompt_router`
|
|
235
|
+
- `skill_master_activation_check`
|
|
236
|
+
- `skill_master_recommend`
|
|
203
237
|
- `skill_master_prepare_skill_contribution`
|
|
204
238
|
- `skill_master_review_skill_contribution`
|
|
239
|
+
- `skill_master_prepare_success_skill`
|
|
240
|
+
- `skill_master_review_success_skill`
|
|
241
|
+
- `skill_master_list_unapproved_success_skills`
|
|
242
|
+
- `skill_master_prepare_success_skill_approval_package`
|
|
243
|
+
- `skill_master_activate_success_skill`
|
|
205
244
|
|
|
206
245
|
O pacote de contribuicao nao envia arquivos automaticamente, nao executa skills desconhecidas e nao inclui caminhos completos ou corpo bruto por padrao.
|
|
207
246
|
|
|
247
|
+
O fluxo de aprendizado por implementacoes bem-sucedidas cria rascunhos locais em staging, gera pacote de aprovacao humana e permite ativacao explicita em escopo local ou global. Ele exige evidencias, revisa risco/duplicidade e mantem candidatos externos como nao aprovados ate revisao humana. Nenhuma skill aprendida e publicada automaticamente.
|
|
248
|
+
|
|
208
249
|
Leia:
|
|
209
250
|
|
|
210
251
|
- [Rede segura de skills](docs/architecture/REDE_SEGURA_DE_SKILLS.md)
|
|
252
|
+
- [Aprendizado de implementacoes bem-sucedidas](docs/architecture/APRENDIZADO_DE_IMPLEMENTACOES_BEM_SUCEDIDAS.md)
|
|
211
253
|
|
|
212
254
|
## Modos de ativacao em prompts
|
|
213
255
|
|
|
214
|
-
|
|
256
|
+
Clientes e agentes podem usar `skill_master_prompt_router` como camada principal antes de decidir se devem acionar recomendacoes de skills, aplicar persona ou bloquear uma acao sensivel.
|
|
257
|
+
|
|
258
|
+
Modos suportados:
|
|
259
|
+
|
|
260
|
+
- `manual`: ativa apenas com mencao direta ao Skill Master ou gate bloqueante.
|
|
261
|
+
- `balanced`: modo recomendado; ativa por mencao direta, tarefa tecnica com skill relevante, Notion, aprendizado, validacao, MCP ou publicacao.
|
|
262
|
+
- `always-on-assisted`: avalia quase todo prompt, mas retorna `executionMode: no-op` quando nao houver ganho claro.
|
|
263
|
+
|
|
264
|
+
Exemplo de chamada conceitual:
|
|
265
|
+
|
|
266
|
+
```json
|
|
267
|
+
{
|
|
268
|
+
"prompt": "skill-master, veja se existe uma skill para validar este deploy",
|
|
269
|
+
"activationMode": "balanced",
|
|
270
|
+
"riskTolerance": "normal"
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Saida esperada:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"shouldActivate": true,
|
|
279
|
+
"personaOverlay": "Dev Senior Master",
|
|
280
|
+
"executionMode": "assist",
|
|
281
|
+
"safetyGates": [],
|
|
282
|
+
"learningOpportunity": false,
|
|
283
|
+
"notionUpdateNeeded": false
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Use `skill_master_activation_check` quando precisar apenas de uma decisao menor e retrocompativel de ativacao/recomendacao.
|
|
288
|
+
|
|
289
|
+
Restricoes explicitas como `sem publicar`, `nao publicar` ou `nao publique` sao tratadas como execucao local. O router deve registrar `publication_explicitly_disabled` e nao pode transformar essa frase em autorizacao ou intencao de release.
|
|
215
290
|
|
|
216
291
|
Ativacao explicita:
|
|
217
292
|
|
|
@@ -241,6 +316,11 @@ Cliente: chama skill_master_activation_check.
|
|
|
241
316
|
Cliente: se ativar, chama skill_master_recommend ou segue as recomendacoes retornadas.
|
|
242
317
|
```
|
|
243
318
|
|
|
319
|
+
Diagnostico importante:
|
|
320
|
+
|
|
321
|
+
- `skill_master_list_sources` mostra `configPath`, `workspace` e se `workspaceRoots` esta configurado.
|
|
322
|
+
- Se `workspaceRoots` estiver vazio, skills em `.codex/skills` do projeto nao serao catalogadas ate atualizar `sources.json` e reiniciar o processo MCP.
|
|
323
|
+
|
|
244
324
|
## Atualizacao automatica via npm
|
|
245
325
|
|
|
246
326
|
Para instalacoes feitas por `npm install -g`, o caminho seguro de auto-update e executar `skill-master-update` fora do processo MCP.
|
package/VERSION.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Versão funcional planejada: `00.02`
|
|
4
4
|
|
|
5
|
-
Versão técnica para empacotamento semântico: `0.0.
|
|
5
|
+
Versão técnica para empacotamento semântico: `0.0.8`
|
|
6
6
|
|
|
7
7
|
## Observação
|
|
8
8
|
|
|
9
|
-
O nome `00.02` será usado na comunicação e nos documentos. Para ferramentas que exigem SemVer, como npm e alguns fluxos de release, usar `0.0.
|
|
9
|
+
O nome `00.02` será usado na comunicação e nos documentos. Para ferramentas que exigem SemVer, como npm e alguns fluxos de release, usar `0.0.8`.
|
package/bin/lib/menu-core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import process from 'node:process';
|
|
5
5
|
|
|
@@ -39,6 +39,9 @@ export function getMenuStatus(rootDir) {
|
|
|
39
39
|
const packageJson = readJson(rootDir, 'package.json');
|
|
40
40
|
const stableManifest = readJson(rootDir, 'manifests/channels/stable.json');
|
|
41
41
|
const versionText = readText(rootDir, 'VERSION.md');
|
|
42
|
+
const successLearningDir = process.env.SKILL_MASTER_SUCCESS_LEARNING_DIR
|
|
43
|
+
?? join(process.env.SKILL_MASTER_HOME ?? join(process.env.HOME ?? process.env.USERPROFILE ?? '', '.skill-master'), 'data', 'success-learning');
|
|
44
|
+
const studyCandidates = readJson(rootDir, 'network/unapproved-skill-candidates.json');
|
|
42
45
|
|
|
43
46
|
return {
|
|
44
47
|
packageName: packageJson?.name ?? 'nao encontrado',
|
|
@@ -47,9 +50,29 @@ export function getMenuStatus(rootDir) {
|
|
|
47
50
|
manifestSemver: stableManifest?.semver ?? 'nao encontrado',
|
|
48
51
|
versionText,
|
|
49
52
|
rootDir,
|
|
53
|
+
pendingSuccessDrafts: countManifestFiles(successLearningDir),
|
|
54
|
+
studyCandidates: Array.isArray(studyCandidates?.candidates) ? studyCandidates.candidates.length : 0,
|
|
50
55
|
};
|
|
51
56
|
}
|
|
52
57
|
|
|
58
|
+
function countManifestFiles(directory) {
|
|
59
|
+
if (!directory || !existsSync(directory)) {
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let count = 0;
|
|
64
|
+
const visit = (current) => {
|
|
65
|
+
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
66
|
+
const fullPath = join(current, entry.name);
|
|
67
|
+
if (entry.isDirectory()) visit(fullPath);
|
|
68
|
+
else if (entry.isFile() && entry.name === 'manifest.json') count += 1;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
visit(directory);
|
|
73
|
+
return count;
|
|
74
|
+
}
|
|
75
|
+
|
|
53
76
|
export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process.execPath }) {
|
|
54
77
|
return [
|
|
55
78
|
{
|
|
@@ -107,6 +130,106 @@ export function buildMenuCommands({ rootDir, currentFile, nodeExecPath = process
|
|
|
107
130
|
args: ['scripts/configure-private-registry.mjs', '--validate'],
|
|
108
131
|
confirmMessage: 'Rodar a configuracao de registry privado agora?',
|
|
109
132
|
},
|
|
133
|
+
{
|
|
134
|
+
key: 'activationStatus',
|
|
135
|
+
aliases: ['activation-status', 'modo', 'modo-ativacao'],
|
|
136
|
+
label: 'Modo de ativacao atual',
|
|
137
|
+
description: 'Mostra o modo manual, balanced ou always-on-assisted configurado localmente.',
|
|
138
|
+
command: nodeExecPath,
|
|
139
|
+
args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--status'],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
key: 'activationBalanced',
|
|
143
|
+
aliases: ['set-balanced', 'balanced'],
|
|
144
|
+
label: 'Usar modo balanced',
|
|
145
|
+
description: 'Define balanced como modo padrao de ativacao do Skill Master.',
|
|
146
|
+
command: nodeExecPath,
|
|
147
|
+
args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--set-mode', 'balanced'],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
key: 'activationAlwaysOn',
|
|
151
|
+
aliases: ['set-always-on', 'always-on-assisted'],
|
|
152
|
+
label: 'Usar modo always-on-assisted',
|
|
153
|
+
description: 'Define avaliacao assistida quase sempre ativa, mantendo no-op quando nao houver ganho.',
|
|
154
|
+
command: nodeExecPath,
|
|
155
|
+
args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--set-mode', 'always-on-assisted'],
|
|
156
|
+
confirmMessage: 'Alterar o modo local para always-on-assisted?',
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
key: 'promptRecommendation',
|
|
160
|
+
aliases: ['recommend-prompt', 'recomendar-prompt', 'prompt-router'],
|
|
161
|
+
label: 'Ver recomendacao para um prompt',
|
|
162
|
+
description: 'Abre um fluxo interativo para avaliar um prompt pelo router local.',
|
|
163
|
+
command: nodeExecPath,
|
|
164
|
+
args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--route-prompt-interactive'],
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
key: 'successNotifications',
|
|
168
|
+
aliases: ['notifications', 'notificacoes', 'success-notifications'],
|
|
169
|
+
label: 'Notificacoes de skills aprendidas',
|
|
170
|
+
description: 'Mostra drafts pendentes, aprovacoes e skills externas para estudar.',
|
|
171
|
+
command: nodeExecPath,
|
|
172
|
+
args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--notify'],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
key: 'studySkills',
|
|
176
|
+
aliases: ['study-skills', 'skills-estudo', 'estudar'],
|
|
177
|
+
label: 'Skills para estudar',
|
|
178
|
+
description: 'Lista skills externas e links de criadores ainda nao aprovados.',
|
|
179
|
+
command: nodeExecPath,
|
|
180
|
+
args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--study'],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
key: 'approvalPackage',
|
|
184
|
+
aliases: ['approval-package', 'aprovar', 'pacote-aprovacao'],
|
|
185
|
+
label: 'Gerar pacote de aprovacao humana',
|
|
186
|
+
description: 'Cria um relatorio local para revisar e aprovar skills aprendidas.',
|
|
187
|
+
command: nodeExecPath,
|
|
188
|
+
args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--approval-package'],
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
key: 'markLearnedStudy',
|
|
192
|
+
aliases: ['mark-study', 'manter-estudo'],
|
|
193
|
+
label: 'Manter skill candidata para estudo',
|
|
194
|
+
description: 'Seleciona uma candidata e registra decisao de manter para estudo.',
|
|
195
|
+
command: nodeExecPath,
|
|
196
|
+
args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--mark-study-interactive'],
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
key: 'rejectLearnedSkill',
|
|
200
|
+
aliases: ['reject-skill', 'rejeitar-skill'],
|
|
201
|
+
label: 'Rejeitar skill candidata',
|
|
202
|
+
description: 'Seleciona uma candidata, registra rejeicao e preserva historico.',
|
|
203
|
+
command: nodeExecPath,
|
|
204
|
+
args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--reject-interactive'],
|
|
205
|
+
confirmMessage: 'Abrir fluxo para rejeitar uma skill candidata?',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
key: 'activateLearnedLocal',
|
|
209
|
+
aliases: ['activate-learned-local', 'ativar-local', 'skill-local'],
|
|
210
|
+
label: 'Ativar skill aprendida no workspace',
|
|
211
|
+
description: 'Instala uma skill aprendida em .codex/skills do projeto atual.',
|
|
212
|
+
command: nodeExecPath,
|
|
213
|
+
args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--activate-interactive', '--target', 'local'],
|
|
214
|
+
confirmMessage: 'Selecionar e ativar uma skill aprendida no workspace atual?',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
key: 'activateLearnedGlobal',
|
|
218
|
+
aliases: ['activate-learned-global', 'ativar-global', 'skill-global'],
|
|
219
|
+
label: 'Ativar skill aprendida global',
|
|
220
|
+
description: 'Instala uma skill aprendida em CODEX_HOME/skills ou ~/.codex/skills.',
|
|
221
|
+
command: nodeExecPath,
|
|
222
|
+
args: [join(rootDir, 'bin', 'skill-master-success-skills.mjs'), '--activate-interactive', '--target', 'global'],
|
|
223
|
+
confirmMessage: 'Selecionar e ativar uma skill aprendida como skill global deste usuario?',
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
key: 'notionSummary',
|
|
227
|
+
aliases: ['notion-summary', 'resumo-notion'],
|
|
228
|
+
label: 'Abrir resumo para Notion',
|
|
229
|
+
description: 'Mostra um resumo copiavel do estado de ativacao para registrar no ledger Notion.',
|
|
230
|
+
command: nodeExecPath,
|
|
231
|
+
args: [join(rootDir, 'bin', 'skill-master-activation.mjs'), '--notion-summary'],
|
|
232
|
+
},
|
|
110
233
|
];
|
|
111
234
|
}
|
|
112
235
|
|
|
@@ -145,6 +268,8 @@ export function formatStatusReport(status) {
|
|
|
145
268
|
`Semver local: ${status.semver}`,
|
|
146
269
|
`Manifesto stable: ${status.manifestVersion}`,
|
|
147
270
|
`Manifesto semver: ${status.manifestSemver}`,
|
|
271
|
+
`Drafts de skills aprendidas: ${status.pendingSuccessDrafts}`,
|
|
272
|
+
`Skills externas para estudar: ${status.studyCandidates}`,
|
|
148
273
|
];
|
|
149
274
|
|
|
150
275
|
if (status.versionText) {
|
|
@@ -168,6 +293,7 @@ export function formatMenuBanner(status, { useColor = false } = {}) {
|
|
|
168
293
|
colorize('Skill Master MCP', ANSI.bold, useColor),
|
|
169
294
|
'Menu operacional para manutencao local',
|
|
170
295
|
`Versao local ${status.semver} | canal ${status.manifestVersion}`,
|
|
296
|
+
`Pendencias: ${status.pendingSuccessDrafts} drafts | estudo: ${status.studyCandidates} links`,
|
|
171
297
|
colorize('Setas + Enter para navegar', ANSI.dim, useColor),
|
|
172
298
|
];
|
|
173
299
|
return renderPanelLines(lines, { color: ANSI.cyan, useColor });
|
|
@@ -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,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;
|