@deerdesign/deertools 1.2.12 → 1.2.13
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/package.json +1 -1
- package/src/commands.js +9 -2
- package/src/login.js +13 -3
- package/src/mcp-stdio.js +22 -1
package/package.json
CHANGED
package/src/commands.js
CHANGED
|
@@ -57,7 +57,14 @@ async function cmdLogin(pos, flags) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
const products = resolveProducts(pos[0]);
|
|
60
|
-
const
|
|
60
|
+
const requestedScope = flags.admin
|
|
61
|
+
? 'admin'
|
|
62
|
+
: (flags.ro || flags['read-only'])
|
|
63
|
+
? 'read'
|
|
64
|
+
: (flags.rw || flags.write)
|
|
65
|
+
? 'read write'
|
|
66
|
+
: (flags.scope || 'read');
|
|
67
|
+
const scope = normalizeScope(requestedScope);
|
|
61
68
|
let failures = 0;
|
|
62
69
|
for (const product of products) {
|
|
63
70
|
out(`\n=== ${product.name} ===`);
|
|
@@ -514,7 +521,7 @@ DeerTools CLI — ekosystem narzędzi dla architektów i agentów AI Deer Design
|
|
|
514
521
|
Produkty: ${ALL_IDS.join(', ')}
|
|
515
522
|
|
|
516
523
|
Dostęp i autoryzacja:
|
|
517
|
-
deertools login <produkt|all> [--
|
|
524
|
+
deertools login <produkt|all> [--ro|--rw|--admin] Logowanie OAuth (RO: tylko odczyt, RW: zapis, Admin).
|
|
518
525
|
deertools logout [produkt|all] Usuwa lokalny klucz.
|
|
519
526
|
deertools whoami [produkt|all] [--json] Status logowania, zakres, ważność.
|
|
520
527
|
deertools profile [list|use <nazwa>|current] Przełączanie profili poświadczeń.
|
package/src/login.js
CHANGED
|
@@ -7,7 +7,7 @@ const credentials = require('./credentials');
|
|
|
7
7
|
|
|
8
8
|
const CLIENT_ID = 'deertools-cli';
|
|
9
9
|
const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
10
|
-
const VALID_SCOPES = ['read', 'write'];
|
|
10
|
+
const VALID_SCOPES = ['read', 'write', 'admin'];
|
|
11
11
|
|
|
12
12
|
const b64url = (buf) => Buffer.from(buf).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
13
13
|
|
|
@@ -21,14 +21,24 @@ function escapeHtml(s) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function normalizeScope(input) {
|
|
24
|
-
|
|
24
|
+
if (!input) return 'read';
|
|
25
|
+
const raw = String(input).toLowerCase().trim();
|
|
26
|
+
if (raw === 'ro' || raw === 'read-only') return 'read';
|
|
27
|
+
if (raw === 'rw' || raw === 'read-write') return 'read write';
|
|
28
|
+
if (raw === 'admin') return 'read write admin';
|
|
29
|
+
|
|
30
|
+
const list = raw.split(/[\s,]+/).filter(Boolean);
|
|
25
31
|
const bad = list.filter((s) => !VALID_SCOPES.includes(s));
|
|
26
32
|
if (bad.length) {
|
|
27
|
-
const err = new Error(`Nieznany zakres: ${bad.join(', ')}. Dozwolone: ${VALID_SCOPES.join(', ')}.`);
|
|
33
|
+
const err = new Error(`Nieznany zakres: ${bad.join(', ')}. Dozwolone: ${VALID_SCOPES.join(', ')} (lub aliasy: ro, rw, admin).`);
|
|
28
34
|
err.exitCode = 2;
|
|
29
35
|
throw err;
|
|
30
36
|
}
|
|
31
37
|
const set = new Set(list.length ? list : ['read']);
|
|
38
|
+
if (set.has('admin')) {
|
|
39
|
+
set.add('write');
|
|
40
|
+
set.add('read');
|
|
41
|
+
}
|
|
32
42
|
if (set.has('write')) set.add('read'); // zapis zakłada odczyt
|
|
33
43
|
return VALID_SCOPES.filter((s) => set.has(s)).join(' ');
|
|
34
44
|
}
|
package/src/mcp-stdio.js
CHANGED
|
@@ -103,12 +103,14 @@ async function cmdMcpServe(pos, flags) {
|
|
|
103
103
|
},
|
|
104
104
|
{
|
|
105
105
|
name: 'deer_update_skills',
|
|
106
|
-
description: 'Autonomiczna aktualizacja skilli Deer Design — pobiera najnowsze wersje paczek z DeerSkills Hub i odświeża plik blokady.',
|
|
106
|
+
description: 'Autonomiczna aktualizacja skilli Deer Design — pobiera najnowsze wersje paczek z DeerSkills Hub i odświeża plik blokady. WYMAGA POTWIERDZENIA CZŁOWIEKA (Human-in-the-Loop) — parametr confirmed=true po zatwierdzeniu przez użytkownika.',
|
|
107
107
|
inputSchema: {
|
|
108
108
|
type: 'object',
|
|
109
109
|
properties: {
|
|
110
110
|
slug: { type: 'string', description: 'Opcjonalny slug konkretnego skilla do zaktualizowania (np. deer-kosztorys). Domyślnie aktualizuje wszystkie przestarzałe skille.' },
|
|
111
|
+
confirmed: { type: 'boolean', description: 'Wymagany bezpiecznik HITL: true tylko po uprzednim zapytaniu człowieka o zgodę w ankiecie (ask_question).' },
|
|
111
112
|
},
|
|
113
|
+
required: ['confirmed'],
|
|
112
114
|
},
|
|
113
115
|
},
|
|
114
116
|
];
|
|
@@ -227,6 +229,25 @@ async function cmdMcpServe(pos, flags) {
|
|
|
227
229
|
}
|
|
228
230
|
|
|
229
231
|
if (toolName === 'deer_update_skills') {
|
|
232
|
+
if (args.confirmed !== true) {
|
|
233
|
+
send({
|
|
234
|
+
jsonrpc: '2.0',
|
|
235
|
+
id,
|
|
236
|
+
result: {
|
|
237
|
+
content: [{
|
|
238
|
+
type: 'text',
|
|
239
|
+
text: JSON.stringify({
|
|
240
|
+
status: 'requires_human_confirmation',
|
|
241
|
+
message: 'BEZPIECZNIK HITL (Human-in-the-Loop): Operacja aktualizacji skilli modyfikuje pliki w środowisku użytkownika. Agent AI NIE MOŻE sam podjąć tej decyzji ani pominąć człowieka.',
|
|
242
|
+
instruction_for_agent: 'Wyświetl użytkownikowi interaktywną ankietę (np. narzędziem ask_question w Antigravity) pytając o zgodę na aktualizację: „Czy zatwierdzasz aktualizację skilli: ' + (args.slug || 'wszystkie przestarzałe skille') + '?”. Dopiero po kliknięciu potwierdzenia przez człowieka wywołaj deer_update_skills ponownie z argumentem confirmed: true.',
|
|
243
|
+
target_skills: args.slug || 'all',
|
|
244
|
+
}, null, 2),
|
|
245
|
+
}],
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
230
251
|
const res = await updateSkills(args.slug || null);
|
|
231
252
|
send({
|
|
232
253
|
jsonrpc: '2.0',
|