@deerdesign/deertools 1.2.27 → 1.2.32
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/README.md +55 -63
- package/package.json +4 -3
- package/src/baselinker-commands.js +21 -94
- package/src/cli.js +20 -6
- package/src/commands.js +167 -137
- package/src/completion.js +24 -18
- package/src/embedding.js +59 -0
- package/src/rendermind/cli-commands.js +31 -0
- package/src/rendermind/client.js +393 -0
- package/src/rendermind/mcp-server.js +305 -0
- package/src/skill-commands.js +157 -15
- package/src/skills-hub.js +66 -0
- package/src/supplier/cli-commands.js +32 -0
- package/src/supplier/mcp-server.js +360 -0
- package/src/tui.js +24 -39
package/src/commands.js
CHANGED
|
@@ -5,8 +5,6 @@ const path = require('path');
|
|
|
5
5
|
const credentials = require('./credentials');
|
|
6
6
|
const { getProduct, resolveProducts, ALL_IDS } = require('./registry');
|
|
7
7
|
const { login, normalizeScope } = require('./login');
|
|
8
|
-
const { discover, fetchText, apiRequest, explain } = require('./http');
|
|
9
|
-
const { listOperations, parseFrontmatterName } = require('./openapi');
|
|
10
8
|
|
|
11
9
|
const out = (s = '') => process.stdout.write(`${s}\n`);
|
|
12
10
|
const err = (s = '') => process.stderr.write(`${s}\n`);
|
|
@@ -17,9 +15,30 @@ function fail(message, exitCode = 1) {
|
|
|
17
15
|
throw e;
|
|
18
16
|
}
|
|
19
17
|
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
function parseQuery(list) {
|
|
19
|
+
const q = {};
|
|
20
|
+
for (const item of [].concat(list || [])) {
|
|
21
|
+
const i = String(item).indexOf('=');
|
|
22
|
+
if (i < 1) fail(`Zły parametr zapytania „${item}” — użyj --query klucz=wartość`, 2);
|
|
23
|
+
q[item.slice(0, i)] = item.slice(i + 1);
|
|
24
|
+
}
|
|
25
|
+
return q;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function cmdBlockedDomain(cmdName) {
|
|
29
|
+
fail(
|
|
30
|
+
`Komenda „deertools ${cmdName}” jest wyłączona zgodnie ze standardem architektonicznym DeerTools CLI.\n` +
|
|
31
|
+
`DeerTools CLI służy wyłącznie do zarządzania logowaniem (login/logout/whoami), konfiguracją MCP (mcp install) oraz skillami (skill/team/agent).\n` +
|
|
32
|
+
`Operacje na systemach domenowych wykonuj bezpośrednio przez natywne narzędzia serwerów MCP:\n` +
|
|
33
|
+
` • deer-estimate (Kosztorys)\n` +
|
|
34
|
+
` • deer-catalog (Katalog Connect)\n` +
|
|
35
|
+
` • deer-deliveries (Dostawy)\n` +
|
|
36
|
+
` • deer-supplier (Supplier Hub)\n` +
|
|
37
|
+
` • deer-rendermind (RenderMind)\n` +
|
|
38
|
+
` • deer-baselinker (BaseLinker)\n` +
|
|
39
|
+
` • deer-skills (DeerSkills Hub)`,
|
|
40
|
+
2
|
|
41
|
+
);
|
|
23
42
|
}
|
|
24
43
|
|
|
25
44
|
async function cmdLogin(pos, flags) {
|
|
@@ -27,13 +46,13 @@ async function cmdLogin(pos, flags) {
|
|
|
27
46
|
out(`\n=== BaseLinker ===`);
|
|
28
47
|
try {
|
|
29
48
|
const { loginBaseLinkerBrowser } = require('./baselinker');
|
|
30
|
-
|
|
49
|
+
await loginBaseLinkerBrowser({
|
|
31
50
|
port: flags.port ? Number(flags.port) : 0,
|
|
32
51
|
openBrowser: flags['no-open'] ? null : undefined,
|
|
33
52
|
log: out
|
|
34
53
|
});
|
|
35
54
|
out(`✓ Zalogowano do BaseLinker. Token zapisany w credentials.json.`);
|
|
36
|
-
out(`
|
|
55
|
+
out(` Serwer MCP: deertools mcp install | Test połączenia: deertools baselinker test`);
|
|
37
56
|
return;
|
|
38
57
|
} catch (e) {
|
|
39
58
|
err(`✗ BaseLinker: ${e.message}`);
|
|
@@ -48,7 +67,7 @@ async function cmdLogin(pos, flags) {
|
|
|
48
67
|
const token = pos[1] || flags.token;
|
|
49
68
|
await loginSkillsDirect(token);
|
|
50
69
|
out(`✓ Zalogowano do DeerSkills Hub. Klucz zapisany w credentials.json.`);
|
|
51
|
-
out(` Przegląd umiejętności: deertools skill list |
|
|
70
|
+
out(` Przegląd umiejętności: deertools skill list | Synchronizacja: deertools skill sync`);
|
|
52
71
|
return;
|
|
53
72
|
} catch (e) {
|
|
54
73
|
err(`✗ DeerSkills: ${e.message}`);
|
|
@@ -57,9 +76,10 @@ async function cmdLogin(pos, flags) {
|
|
|
57
76
|
}
|
|
58
77
|
|
|
59
78
|
const products = resolveProducts(pos[0]);
|
|
79
|
+
const explicitRo = Boolean(flags.ro || flags['read-only']);
|
|
60
80
|
const requestedScope = flags.admin
|
|
61
81
|
? 'admin'
|
|
62
|
-
:
|
|
82
|
+
: explicitRo
|
|
63
83
|
? 'read'
|
|
64
84
|
: (flags.rw || flags.write)
|
|
65
85
|
? 'read write'
|
|
@@ -69,9 +89,23 @@ async function cmdLogin(pos, flags) {
|
|
|
69
89
|
for (const product of products) {
|
|
70
90
|
out(`\n=== ${product.name} ===`);
|
|
71
91
|
try {
|
|
72
|
-
|
|
92
|
+
if (product.id === 'skills') {
|
|
93
|
+
const { loginSkillsBrowser } = require('./skills-login');
|
|
94
|
+
const entry = await loginSkillsBrowser({
|
|
95
|
+
port: flags.port ? Number(flags.port) : 0,
|
|
96
|
+
openBrowser: flags['no-open'] ? null : undefined,
|
|
97
|
+
log: out,
|
|
98
|
+
});
|
|
99
|
+
out(`✓ Zalogowano do DeerSkills Hub. Zakres: ${entry.scope}.`);
|
|
100
|
+
out(` Przegląd umiejętności: deertools skill list | Synchronizacja: deertools skill sync`);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const productScope = (product.id === 'rendermind' && !explicitRo && !flags.scope && !flags.admin)
|
|
104
|
+
? 'read write'
|
|
105
|
+
: scope;
|
|
106
|
+
const entry = await login(product, { scope: productScope, port: flags.port ? Number(flags.port) : 0, clientName: flags.name, openBrowser: flags['no-open'] ? null : undefined, log: out });
|
|
73
107
|
out(`✓ Zalogowano${entry.email ? ` jako ${entry.email}` : ''}. Zakres: ${entry.scope}${entry.expires_at ? `, ważny do ${entry.expires_at.slice(0, 10)}` : ''}.`);
|
|
74
|
-
out(`
|
|
108
|
+
out(` Konfiguracja MCP: deertools mcp install | Synchronizacja skilli: deertools skill sync`);
|
|
75
109
|
} catch (e) {
|
|
76
110
|
failures += 1;
|
|
77
111
|
err(`✗ ${product.name}: ${e.message}`);
|
|
@@ -80,7 +114,6 @@ async function cmdLogin(pos, flags) {
|
|
|
80
114
|
if (failures) fail(`Nie udało się zalogować do ${failures} z ${products.length} produktów.`, 1);
|
|
81
115
|
}
|
|
82
116
|
|
|
83
|
-
|
|
84
117
|
async function cmdLogout(pos) {
|
|
85
118
|
if (pos[0] === 'baselinker' || pos[0] === 'bl') {
|
|
86
119
|
out(credentials.removeProduct('baselinker') ? `✓ Wylogowano z BaseLinker (token usunięty lokalnie).` : `– BaseLinker: nie byłeś zalogowany.`);
|
|
@@ -154,67 +187,6 @@ async function cmdWhoami(pos, flags) {
|
|
|
154
187
|
}
|
|
155
188
|
}
|
|
156
189
|
|
|
157
|
-
async function cmdDocs(pos, flags) {
|
|
158
|
-
const product = needProduct(flags, pos);
|
|
159
|
-
const what = (pos[1] || 'llms').toLowerCase();
|
|
160
|
-
if (what === 'llms') {
|
|
161
|
-
const r = await fetchText(`${product.site}/llms.txt`);
|
|
162
|
-
if (!r.ok) fail(`Brak dokumentacji dla agenta (${product.site}/llms.txt zwraca ${r.status}). Produkt jeszcze jej nie opublikował.`, 4);
|
|
163
|
-
out(r.text);
|
|
164
|
-
} else if (what === 'openapi') {
|
|
165
|
-
const d = await discover(product);
|
|
166
|
-
if (!d.openapi) fail(`Brak openapi.json produktu ${product.name}.`, 4);
|
|
167
|
-
out(JSON.stringify(d.openapi, null, 2));
|
|
168
|
-
} else if (what === 'skill') {
|
|
169
|
-
const r = await fetchText(`${product.site}/skill/SKILL.md`);
|
|
170
|
-
if (!r.ok) fail(`Brak skilla (${product.site}/skill/SKILL.md zwraca ${r.status}).`, 4);
|
|
171
|
-
out(r.text);
|
|
172
|
-
} else {
|
|
173
|
-
fail('Użycie: deertools docs <produkt> [llms|openapi|skill]', 2);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
async function cmdEndpoints(pos, flags) {
|
|
178
|
-
const product = needProduct(flags, pos);
|
|
179
|
-
const d = await discover(product);
|
|
180
|
-
if (!d.openapi) fail(`Produkt ${product.name} nie udostępnia jeszcze openapi.json (sprawdź: deertools docs ${product.id}).`, 4);
|
|
181
|
-
const ops = listOperations(d.openapi);
|
|
182
|
-
if (flags.json) { out(JSON.stringify({ apiBase: d.apiBase, operations: ops }, null, 2)); return; }
|
|
183
|
-
out(`${product.name} — ${d.apiBase}`);
|
|
184
|
-
for (const o of ops) out(` ${o.method.padEnd(6)} ${o.path.padEnd(48)} [${o.scope}] ${o.summary}`.trimEnd());
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function parseQuery(list) {
|
|
188
|
-
const q = {};
|
|
189
|
-
for (const item of [].concat(list || [])) {
|
|
190
|
-
const i = String(item).indexOf('=');
|
|
191
|
-
if (i < 1) fail(`Zły parametr zapytania „${item}” — użyj --query klucz=wartość`, 2);
|
|
192
|
-
q[item.slice(0, i)] = item.slice(i + 1);
|
|
193
|
-
}
|
|
194
|
-
return q;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
async function cmdApi(pos, flags) {
|
|
198
|
-
const product = needProduct(flags, pos);
|
|
199
|
-
const method = String(pos[1] || '').toUpperCase();
|
|
200
|
-
const p = pos[2];
|
|
201
|
-
if (!['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(method) || !p) fail('Użycie: deertools api <produkt> <GET|POST|PUT|PATCH|DELETE> </ścieżka> [--query k=v] [--data \'{"a":1}\' | --data-file plik.json]', 2);
|
|
202
|
-
let body;
|
|
203
|
-
if (flags['data-file']) body = fs.readFileSync(flags['data-file'], 'utf8');
|
|
204
|
-
else if (flags.data !== undefined && flags.data !== true) body = String(flags.data);
|
|
205
|
-
const res = await apiRequest(product, { method, path: p, query: parseQuery(flags.query), body });
|
|
206
|
-
if (!res.ok) {
|
|
207
|
-
err(explain(res.status, res.json, product) + (res.retryAfter ? ` Spróbuj za ${res.retryAfter} s.` : ''));
|
|
208
|
-
if (res.text) err(res.text.slice(0, 1000));
|
|
209
|
-
const e = new Error('');
|
|
210
|
-
e.exitCode = res.status === 401 ? 3 : 1;
|
|
211
|
-
e.silent = true;
|
|
212
|
-
throw e;
|
|
213
|
-
}
|
|
214
|
-
out(res.json ? JSON.stringify(res.json, null, flags.raw ? 0 : 2) : res.text);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const { detectAgents, installSkillContent } = require('./agent-detector');
|
|
218
190
|
const skillCommands = require('./skill-commands');
|
|
219
191
|
|
|
220
192
|
const BUNDLES = {
|
|
@@ -324,43 +296,96 @@ async function cmdSkill(pos, flags) {
|
|
|
324
296
|
const target = pos[1] || (flags.all ? '--all' : null);
|
|
325
297
|
return skillCommands.cmdSkillInstall(target, flags, out, err);
|
|
326
298
|
}
|
|
327
|
-
fail('Użycie:\n deertools skill login [token]\n deertools skill sync [--force]\n deertools skill bundle <architekci|kosztorysy|logistyka|sprzedaz|it>\n deertools skill list [--tag <tag>]\n deertools skill search <fraza>\n deertools skill install [--all|<slug[@version]>]\n deertools skill check\n deertools skill update [slug]\n deertools skill versions <slug>\n deertools skill diff <slug> [wersjaA] [wersjaB]\n deertools skill push [katalog] [--team <zespół>] [--own|--global] [--bump patch|minor|major]\n deertools skill share <slug> --team <zespół>\n deertools skill review [list|approve|reject|submit]\n deertools skill promote <slug>', 2);
|
|
299
|
+
fail('Użycie:\n deertools skill login [token]\n deertools skill sync [--push] [--force]\n deertools skill bundle <architekci|kosztorysy|logistyka|sprzedaz|it>\n deertools skill list [--tag <tag>]\n deertools skill search <fraza>\n deertools skill install [--all|<slug[@version]>]\n deertools skill check\n deertools skill update [slug]\n deertools skill versions <slug>\n deertools skill diff <slug> [wersjaA] [wersjaB]\n deertools skill push [katalog] [--team <zespół>] [--own|--global] [--bump patch|minor|major]\n deertools skill share <slug> --team <zespół>\n deertools skill review [list|approve|reject|submit]\n deertools skill promote <slug>', 2);
|
|
328
300
|
}
|
|
329
301
|
|
|
302
|
+
function resolveDeertoolsBin() {
|
|
303
|
+
const localBin = path.join(os.homedir(), '.local', 'bin', 'deertools');
|
|
304
|
+
if (fs.existsSync(localBin)) return localBin;
|
|
305
|
+
return 'deertools';
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function buildMcpServersConfig(products, useFullBinPath = false) {
|
|
309
|
+
const servers = {};
|
|
310
|
+
const binCmd = useFullBinPath ? resolveDeertoolsBin() : 'deertools';
|
|
311
|
+
|
|
312
|
+
// Produkty z natywnym Remote MCP w chmurze obsługującym x-api-key
|
|
313
|
+
const remoteApiKeyProducts = new Set(['estimate', 'catalog', 'deliveries']);
|
|
314
|
+
|
|
315
|
+
for (const p of products) {
|
|
316
|
+
if (remoteApiKeyProducts.has(p.id) && p.mcpEndpoint) {
|
|
317
|
+
const cred = credentials.getKey(p);
|
|
318
|
+
const key = cred ? cred.key : `${p.keyPrefix}<twój_klucz_api>`;
|
|
319
|
+
const srvKey = `deer-${p.id}`;
|
|
320
|
+
servers[srvKey] = {
|
|
321
|
+
url: p.mcpEndpoint,
|
|
322
|
+
headers: {
|
|
323
|
+
'x-api-key': key,
|
|
324
|
+
'Authorization': `Bearer ${key}`,
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Serwery MCP stdio obsługujące klucze API z ~/.deertools/credentials.json
|
|
331
|
+
servers['deer-supplier'] = {
|
|
332
|
+
command: binCmd,
|
|
333
|
+
args: ['supplier', 'mcp'],
|
|
334
|
+
};
|
|
335
|
+
servers['deer-rendermind'] = {
|
|
336
|
+
command: binCmd,
|
|
337
|
+
args: ['rendermind', 'mcp'],
|
|
338
|
+
};
|
|
339
|
+
servers['deer-baselinker'] = {
|
|
340
|
+
command: binCmd,
|
|
341
|
+
args: ['baselinker', 'mcp'],
|
|
342
|
+
};
|
|
343
|
+
servers['deer-skills'] = {
|
|
344
|
+
command: binCmd,
|
|
345
|
+
args: ['mcp', 'serve'],
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
return servers;
|
|
349
|
+
}
|
|
330
350
|
|
|
331
351
|
async function cmdMcp(pos, flags) {
|
|
332
352
|
const sub = pos[0] || 'config';
|
|
333
353
|
const products = resolveProducts(pos[1]);
|
|
334
|
-
const servers = {};
|
|
335
354
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
355
|
+
if (sub === 'list') {
|
|
356
|
+
const servers = buildMcpServersConfig(products, false);
|
|
357
|
+
if (flags.json) {
|
|
358
|
+
out(JSON.stringify(servers, null, 2));
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
out('\n=== Zarejestrowane Serwery MCP Ekosystemu DeerTools ===\n');
|
|
362
|
+
for (const [name, cfg] of Object.entries(servers)) {
|
|
363
|
+
if (cfg.url) {
|
|
364
|
+
out(` • ${name.padEnd(18)} [Remote HTTP] ${cfg.url}`);
|
|
365
|
+
} else {
|
|
366
|
+
out(` • ${name.padEnd(18)} [Local stdio] ${cfg.command} ${(cfg.args || []).join(' ')}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
out('\nAby zainstalować w Cursor i Antigravity: deertools mcp install\n');
|
|
370
|
+
return;
|
|
348
371
|
}
|
|
349
372
|
|
|
350
373
|
if (sub === 'config') {
|
|
374
|
+
const servers = buildMcpServersConfig(products, false);
|
|
351
375
|
const config = { mcpServers: servers };
|
|
352
376
|
if (flags.json) {
|
|
353
377
|
out(JSON.stringify(config, null, 2));
|
|
354
378
|
} else {
|
|
355
|
-
out('\nKonfiguracja
|
|
379
|
+
out('\nKonfiguracja MCP dla DeerTools (Cursor IDE, Claude Desktop, Antigravity):');
|
|
356
380
|
out(JSON.stringify(config, null, 2));
|
|
357
|
-
out('\nAby zainstalować automatycznie w Cursorze i
|
|
381
|
+
out('\nAby zainstalować automatycznie w Cursorze i Antigravity, uruchom:');
|
|
358
382
|
out(' deertools mcp install\n');
|
|
359
383
|
}
|
|
360
384
|
return;
|
|
361
385
|
}
|
|
362
386
|
|
|
363
387
|
if (sub === 'install') {
|
|
388
|
+
const servers = buildMcpServersConfig(products, true);
|
|
364
389
|
let touched = 0;
|
|
365
390
|
// 1. Cursor global (~/.cursor/mcp.json)
|
|
366
391
|
const cursorGlobal = path.join(os.homedir(), '.cursor', 'mcp.json');
|
|
@@ -396,7 +421,7 @@ async function cmdMcp(pos, flags) {
|
|
|
396
421
|
}
|
|
397
422
|
}
|
|
398
423
|
|
|
399
|
-
// 3. Antigravity / Gemini (.agents/mcp_config.json)
|
|
424
|
+
// 3. Antigravity / Gemini Workspace (.agents/mcp_config.json)
|
|
400
425
|
const agentsConfig = path.join(process.cwd(), '.agents', 'mcp_config.json');
|
|
401
426
|
if (fs.existsSync(path.dirname(agentsConfig))) {
|
|
402
427
|
try {
|
|
@@ -413,8 +438,25 @@ async function cmdMcp(pos, flags) {
|
|
|
413
438
|
}
|
|
414
439
|
}
|
|
415
440
|
|
|
441
|
+
// 4. Antigravity Global (~/.gemini/config/mcp_config.json)
|
|
442
|
+
const geminiGlobal = path.join(os.homedir(), '.gemini', 'config', 'mcp_config.json');
|
|
443
|
+
if (fs.existsSync(path.dirname(geminiGlobal))) {
|
|
444
|
+
try {
|
|
445
|
+
let cur = { mcpServers: {} };
|
|
446
|
+
if (fs.existsSync(geminiGlobal)) {
|
|
447
|
+
try { cur = JSON.parse(fs.readFileSync(geminiGlobal, 'utf8')); } catch (_) {}
|
|
448
|
+
}
|
|
449
|
+
cur.mcpServers = Object.assign({}, cur.mcpServers, servers);
|
|
450
|
+
fs.writeFileSync(geminiGlobal, JSON.stringify(cur, null, 2));
|
|
451
|
+
out(`✓ Antigravity Global: ${geminiGlobal}`);
|
|
452
|
+
touched++;
|
|
453
|
+
} catch (e) {
|
|
454
|
+
err(`✗ Antigravity Global (${geminiGlobal}): ${e.message}`);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
416
458
|
if (!touched) fail('Nie znaleziono środowiska agenta do instalacji MCP.', 4);
|
|
417
|
-
out(`\nPomyślnie
|
|
459
|
+
out(`\nPomyślnie skonfigurowano wszystkie 7 serwerów MCP dla produktów DeerTools!`);
|
|
418
460
|
return;
|
|
419
461
|
}
|
|
420
462
|
|
|
@@ -423,7 +465,7 @@ async function cmdMcp(pos, flags) {
|
|
|
423
465
|
return cmdMcpServe(pos, flags);
|
|
424
466
|
}
|
|
425
467
|
|
|
426
|
-
fail('Użycie: deertools mcp [config|install|serve] [produkt|all] [--json]', 2);
|
|
468
|
+
fail('Użycie: deertools mcp [list|config|install|serve] [produkt|all] [--json]', 2);
|
|
427
469
|
}
|
|
428
470
|
|
|
429
471
|
async function cmdAgent(pos, flags) {
|
|
@@ -521,70 +563,58 @@ const { cmdAudit } = require('./audit');
|
|
|
521
563
|
const { cmdProfile } = require('./profiles');
|
|
522
564
|
const { cmdCompletion } = require('./completion');
|
|
523
565
|
const { cmdBaseLinker } = require('./baselinker-commands');
|
|
566
|
+
const { cmdRenderMind } = require('./rendermind/cli-commands');
|
|
567
|
+
const { cmdSupplier } = require('./supplier/cli-commands');
|
|
524
568
|
|
|
525
569
|
const HELP = `
|
|
526
|
-
DeerTools CLI —
|
|
570
|
+
DeerTools CLI — Identity, MCP & Skills Hub Manager dla ekosystemu Deer Design
|
|
527
571
|
|
|
528
|
-
|
|
572
|
+
Systemy: ${ALL_IDS.join(', ')}, baselinker
|
|
529
573
|
|
|
530
|
-
|
|
531
|
-
deertools login <
|
|
532
|
-
deertools logout [
|
|
533
|
-
deertools whoami [
|
|
574
|
+
1. Tożsamość i autoryzacja (OAuth 2.1 + PKCE):
|
|
575
|
+
deertools login <system|all> [--ro|--rw|--admin] Logowanie OAuth (RO: odczyt, RW: zapis, Admin).
|
|
576
|
+
deertools logout [system|all] Usuwa lokalny klucz z ~/.deertools/credentials.json.
|
|
577
|
+
deertools whoami [system|all] [--json] Status logowania, zakres uprawnień i ważność kluczy.
|
|
534
578
|
deertools profile [list|use <nazwa>|current] Przełączanie profili poświadczeń.
|
|
535
579
|
|
|
536
|
-
Zarządzanie skillami i zespołami (DeerSkills Hub):
|
|
580
|
+
2. Zarządzanie skillami i zespołami (DeerSkills Hub):
|
|
537
581
|
deertools agent [list|select <agenty>|reset] Wykrywanie i konfiguracja platform agentów AI na PC.
|
|
538
582
|
deertools skill list [--tag <tag>] Przegląda skille w Hubie wraz ze statusem zainstalowania.
|
|
539
583
|
deertools skill sync [--push] [--force] Instaluje skille zespołu (--push wypycha lokalne nowości do Hubu).
|
|
540
584
|
deertools sync [--push] Krótki alias dla deertools skill sync (sync dwukierunkowy).
|
|
585
|
+
deertools skill bundle <architekci|kosztorysy|...> Instaluje pakiet startowy skilli dla wybranego działu.
|
|
541
586
|
deertools skill install [--all|<slug[@wersja]>] Instaluje wszystkie skille (--all) lub wskazany skill.
|
|
542
|
-
deertools skill search <fraza>
|
|
543
|
-
deertools skill versions <slug> Historia wydań z changelogami
|
|
587
|
+
deertools skill search <fraza> Hybrydowe wyszukiwanie umiejętności (wektory + tekst).
|
|
588
|
+
deertools skill versions <slug> Historia wydań z changelogami i datami.
|
|
544
589
|
deertools skill diff <slug> [wersjaA] [wersjaB] Porównanie zmian w plikach paczki i treści SKILL.md.
|
|
545
590
|
deertools skill push [katalog] [--team <zespół>] Publikuje do własnej przestrzeni, zespołu lub globalnie.
|
|
546
591
|
deertools skill share <slug> --team <zespół> Udostępnia skill prywatny wskazanemu zespołowi.
|
|
547
|
-
deertools skill review [list|approve|reject|submit] Zarządzanie procesem Peer Review
|
|
592
|
+
deertools skill review [list|approve|reject|submit] Zarządzanie procesem Peer Review skilli zespołu.
|
|
548
593
|
deertools skill update [slug] Aktualizuje zainstalowane skille do najnowszej wersji.
|
|
549
594
|
deertools skill promote <slug> Zgłasza nominację skilla do oficjalnego katalogu globalnego.
|
|
550
|
-
deertools team [list]
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
deertools
|
|
554
|
-
deertools
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
deertools
|
|
559
|
-
deertools
|
|
560
|
-
deertools
|
|
561
|
-
deertools
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
deertools baselinker test Testuje autoryzację i listuje katalogi.
|
|
568
|
-
deertools baselinker serve [--port 3456] Lokalny serwer Web UI z dashboardem i MCP SSE.
|
|
569
|
-
deertools baselinker mcp [--all] Mostek MCP stdio (Cursor / Claude Desktop).
|
|
570
|
-
deertools baselinker sync-schema Pobiera i aktualizuje bazę 204 metod z api.baselinker.com.
|
|
571
|
-
deertools baselinker search <fraza> Przeszukuje bazę metod i schematów parametrów.
|
|
572
|
-
deertools baselinker call <metoda> [json] Wywołuje dowolną metodę BaseLinkera z CLI.
|
|
573
|
-
deertools baselinker catalog <search|get> Operacje katalogowe z poziomu terminala.
|
|
574
|
-
|
|
575
|
-
Narzędzia systemowe:
|
|
576
|
-
deertools update Sprawdza i podpowiada aktualizację CLI.
|
|
577
|
-
deertools doctor [--json] Pełna diagnostyka połączeń, portów i kluczy.
|
|
578
|
-
deertools audit [--limit 25] [--clear] [--json] Historia operacji i wywołań API.
|
|
579
|
-
deertools completion [install|zsh|bash] Autouzupełnianie w powłoce po wciśnięciu Tab.
|
|
580
|
-
|
|
581
|
-
Zmienne środowiskowe: DEERTOOLS_<PRODUKT>_KEY, BASELINKER_TOKEN, DEERTOOLS_HOME, DEERTOOLS_PROFILE, DEERTOOLS_AGENTS.
|
|
595
|
+
deertools team [list|members|add|remove|create] Zarządzanie zespołami i rolami w DeerSkills Hub.
|
|
596
|
+
|
|
597
|
+
3. Integracja serwerów MCP dla Agentów AI (Cursor / Antigravity / Claude):
|
|
598
|
+
deertools mcp list [--json] Lista wszystkich 7 serwerów MCP ekosystemu DeerTools.
|
|
599
|
+
deertools mcp config [--json] Generuje konfigurację JSON serwerów MCP.
|
|
600
|
+
deertools mcp install Automatycznie instaluje serwery MCP w Cursor i Antigravity.
|
|
601
|
+
|
|
602
|
+
4. Diagnostyka i utrzymanie środowiska:
|
|
603
|
+
deertools doctor [--json] Pełna diagnostyka połączeń, portów, kluczy i serwerów MCP.
|
|
604
|
+
deertools audit [--limit 25] [--clear] [--json] Historia operacji.
|
|
605
|
+
deertools update Sprawdza i instaluje aktualizację CLI z npm.
|
|
606
|
+
deertools completion [install|zsh|bash] Autouzupełnianie komend w powłoce po wciśnięciu Tab.
|
|
607
|
+
|
|
608
|
+
Zasada architektoniczna:
|
|
609
|
+
Operacje biznesowe (wyszukiwanie produktów, kosztorysowanie, wizualizacje, dostawy, rabaty)
|
|
610
|
+
wykonywane są przez Agenta AI wyłącznie za pośrednictwem serwerów MCP (deer-estimate,
|
|
611
|
+
deer-catalog, deer-deliveries, deer-supplier, deer-rendermind, deer-baselinker, deer-skills).
|
|
582
612
|
`;
|
|
583
613
|
|
|
584
614
|
module.exports = {
|
|
585
|
-
cmdLogin, cmdLogout, cmdWhoami,
|
|
615
|
+
cmdLogin, cmdLogout, cmdWhoami, cmdSkill, cmdMcp,
|
|
586
616
|
cmdDoctor, cmdAudit, cmdProfile, cmdCompletion,
|
|
587
|
-
cmdBaseLinker,
|
|
617
|
+
cmdBaseLinker, cmdRenderMind, cmdSupplier,
|
|
618
|
+
cmdAgent, cmdTeam, cmdBlockedDomain,
|
|
588
619
|
HELP, parseQuery,
|
|
589
620
|
};
|
|
590
|
-
|
package/src/completion.js
CHANGED
|
@@ -16,22 +16,23 @@ _deertools() {
|
|
|
16
16
|
'login:Logowanie do produktów przez przeglądarkę i OAuth'
|
|
17
17
|
'logout:Wylogowanie i usunięcie lokalnych kluczy'
|
|
18
18
|
'whoami:Status zalogowania, ważność tokenów i zakresy'
|
|
19
|
-
'docs:Pobranie dokumentacji produktu dla agentów AI'
|
|
20
|
-
'endpoints:Lista endpointów REST z openapi.json'
|
|
21
|
-
'api:Wywołanie API z automatycznym nagłówkiem autoryzacji'
|
|
22
19
|
'skill:Zarządzanie skillami, pakietami i synchronizacją'
|
|
20
|
+
'sync:Synchronizacja skilli z DeerSkills Hub'
|
|
23
21
|
'team:Zarządzanie zespołami i uprawnieniami w DeerSkills Hub'
|
|
24
22
|
'agent:Wykrywanie i konfiguracja platform agentów AI'
|
|
25
|
-
'mcp:Konfiguracja i instalacja serwerów
|
|
23
|
+
'mcp:Konfiguracja i instalacja serwerów MCP'
|
|
26
24
|
'doctor:Diagnostyka środowiska, połączeń i uprawnień'
|
|
27
|
-
'audit:Historia
|
|
25
|
+
'audit:Historia operacji'
|
|
28
26
|
'profile:Przełączanie profili użytkownika / środowisk'
|
|
27
|
+
'update:Aktualizacja pakietu deertools'
|
|
29
28
|
'completion:Generowanie skryptu autouzupełniania powłoki'
|
|
30
|
-
'baselinker:
|
|
29
|
+
'baselinker:Autoryzacja i mostek MCP BaseLinkera'
|
|
30
|
+
'rendermind:Mostek MCP RenderMind'
|
|
31
|
+
'supplier:Mostek MCP Supplier Hub'
|
|
31
32
|
)
|
|
32
33
|
|
|
33
34
|
local -a products
|
|
34
|
-
products=( ${ALL_IDS.map(p => `'${p}'`).join(' ')} 'all' )
|
|
35
|
+
products=( ${ALL_IDS.map(p => `'${p}'`).join(' ')} 'baselinker' 'all' )
|
|
35
36
|
|
|
36
37
|
_arguments -C \\
|
|
37
38
|
'--help[Pokaż pomoc]' \\
|
|
@@ -47,18 +48,19 @@ _deertools() {
|
|
|
47
48
|
;;
|
|
48
49
|
args)
|
|
49
50
|
case $line[1] in
|
|
50
|
-
login|logout|
|
|
51
|
-
_values 'produkty' ${ALL_IDS.map(p => `'${p}'`).join(' ')} 'all'
|
|
51
|
+
login|logout|whoami)
|
|
52
|
+
_values 'produkty' ${ALL_IDS.map(p => `'${p}'`).join(' ')} 'baselinker' 'all'
|
|
52
53
|
;;
|
|
53
54
|
baselinker)
|
|
54
|
-
local -a sub=( 'auth:Zapisz token X-BLToken' 'test:Testuj połączenie' '
|
|
55
|
+
local -a sub=( 'auth:Zapisz token X-BLToken' 'test:Testuj połączenie' 'mcp:Uruchom mostek MCP stdio' 'sync-schema:Synchronizuj bazę metod' )
|
|
55
56
|
_describe -t sub 'baselinker podkomendy' sub
|
|
56
57
|
;;
|
|
57
58
|
skill)
|
|
58
|
-
|
|
59
|
+
local -a sub=( 'list:Lista skilli w Hubie' 'sync:Synchronizuj skille' 'install:Zainstaluj skill' 'bundle:Pakiety stanowiskowe' 'search:Wyszukaj skill' 'push:Opublikuj skill' 'check:Sprawdź aktualizacje' 'update:Aktualizuj skille' 'versions:Historia wydań' 'diff:Porównaj wersje' 'review:Peer Review' 'share:Udostępnij zespołowi' 'promote:Nominuj do katalogu globalnego' )
|
|
60
|
+
_describe -t sub 'skill podkomendy' sub
|
|
59
61
|
;;
|
|
60
62
|
mcp)
|
|
61
|
-
local -a sub=( 'config:Wyświetl JSON konfiguracji MCP' 'install:Zainstaluj w Cursor i Antigravity' 'serve:Uruchom lokalny mostek MCP stdio' )
|
|
63
|
+
local -a sub=( 'list:Lista serwerów MCP' 'config:Wyświetl JSON konfiguracji MCP' 'install:Zainstaluj w Cursor i Antigravity' 'serve:Uruchom lokalny mostek MCP stdio' )
|
|
62
64
|
_describe -t sub 'mcp podkomendy' sub
|
|
63
65
|
;;
|
|
64
66
|
esac
|
|
@@ -78,25 +80,29 @@ _deertools_completions() {
|
|
|
78
80
|
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
79
81
|
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
80
82
|
|
|
81
|
-
opts="login logout whoami
|
|
83
|
+
opts="login logout whoami skill sync team agent mcp doctor audit profile update completion baselinker rendermind supplier --help --version --json"
|
|
82
84
|
|
|
83
85
|
case "$prev" in
|
|
84
|
-
login|logout|
|
|
85
|
-
COMPREPLY=( $(compgen -W "${ALL_IDS.join(' ')} all" -- "$cur") )
|
|
86
|
+
login|logout|whoami)
|
|
87
|
+
COMPREPLY=( $(compgen -W "${ALL_IDS.join(' ')} baselinker all" -- "$cur") )
|
|
86
88
|
return 0
|
|
87
89
|
;;
|
|
88
90
|
baselinker)
|
|
89
|
-
COMPREPLY=( $(compgen -W "auth test
|
|
91
|
+
COMPREPLY=( $(compgen -W "auth test mcp sync-schema" -- "$cur") )
|
|
92
|
+
return 0
|
|
93
|
+
;;
|
|
94
|
+
skill)
|
|
95
|
+
COMPREPLY=( $(compgen -W "list sync install bundle search push check update versions diff review share promote" -- "$cur") )
|
|
90
96
|
return 0
|
|
91
97
|
;;
|
|
92
98
|
mcp)
|
|
93
|
-
COMPREPLY=( $(compgen -W "config install serve" -- "$cur") )
|
|
99
|
+
COMPREPLY=( $(compgen -W "list config install serve" -- "$cur") )
|
|
94
100
|
return 0
|
|
95
101
|
;;
|
|
96
102
|
esac
|
|
97
103
|
|
|
98
104
|
if [[ "\$cur" == -* ]]; then
|
|
99
|
-
COMPREPLY=( $(compgen -W "--help --version --json --
|
|
105
|
+
COMPREPLY=( $(compgen -W "--help --version --json --ro --rw --admin --profile" -- "$cur") )
|
|
100
106
|
return 0
|
|
101
107
|
fi
|
|
102
108
|
|
package/src/embedding.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { spawnSync } = require('child_process');
|
|
3
|
+
|
|
4
|
+
let checked = false;
|
|
5
|
+
let available = false;
|
|
6
|
+
let pythonBin = null;
|
|
7
|
+
|
|
8
|
+
function findPythonBinary() {
|
|
9
|
+
if (pythonBin) return pythonBin;
|
|
10
|
+
const candidates = process.platform === 'win32' ? ['python', 'py', 'python3'] : ['python3', 'python'];
|
|
11
|
+
for (const bin of candidates) {
|
|
12
|
+
try {
|
|
13
|
+
const res = spawnSync(bin, ['-c', 'import sentence_transformers'], { timeout: 8000 });
|
|
14
|
+
if (res.status === 0) {
|
|
15
|
+
pythonBin = bin;
|
|
16
|
+
available = true;
|
|
17
|
+
checked = true;
|
|
18
|
+
return bin;
|
|
19
|
+
}
|
|
20
|
+
} catch (_) {}
|
|
21
|
+
}
|
|
22
|
+
checked = true;
|
|
23
|
+
available = false;
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function isEmbeddingAvailable() {
|
|
28
|
+
if (checked) return available;
|
|
29
|
+
return Boolean(findPythonBinary());
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function computeEmbedding(text) {
|
|
33
|
+
const bin = findPythonBinary();
|
|
34
|
+
if (!text || !bin) return null;
|
|
35
|
+
try {
|
|
36
|
+
const script = `
|
|
37
|
+
import json, sys
|
|
38
|
+
from sentence_transformers import SentenceTransformer
|
|
39
|
+
m = SentenceTransformer('all-MiniLM-L6-v2')
|
|
40
|
+
vec = m.encode(sys.argv[1]).tolist()
|
|
41
|
+
print(json.dumps(vec))
|
|
42
|
+
`;
|
|
43
|
+
const res = spawnSync('python3', ['-c', script, String(text)], { timeout: 20000, encoding: 'utf8' });
|
|
44
|
+
if (res.status === 0) {
|
|
45
|
+
const lines = res.stdout.trim().split('\n');
|
|
46
|
+
const lastLine = lines[lines.length - 1];
|
|
47
|
+
const parsed = JSON.parse(lastLine);
|
|
48
|
+
if (Array.isArray(parsed) && parsed.length === 384) {
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} catch (_) {}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
57
|
+
isEmbeddingAvailable,
|
|
58
|
+
computeEmbedding,
|
|
59
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { runRenderMindMcpServer } = require('./mcp-server');
|
|
3
|
+
|
|
4
|
+
function out(msg) { process.stdout.write(msg + '\n'); }
|
|
5
|
+
|
|
6
|
+
async function cmdRenderMind(pos, flags) {
|
|
7
|
+
const sub = pos[0];
|
|
8
|
+
|
|
9
|
+
if (sub === 'mcp') {
|
|
10
|
+
return runRenderMindMcpServer();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
out(`Użycie: deertools rendermind mcp
|
|
14
|
+
|
|
15
|
+
Zgodnie ze standardem architektonicznym DeerTools CLI:
|
|
16
|
+
- Operacje biznesowe i generowanie wizualizacji wykonuje Agent AI za pośrednictwem serwera MCP (deer-rendermind).
|
|
17
|
+
- Dostępne narzędzia MCP:
|
|
18
|
+
* rendermind_create_visualization
|
|
19
|
+
* rendermind_upload_image
|
|
20
|
+
* rendermind_get_visualization
|
|
21
|
+
* rendermind_floor_plan_estimate
|
|
22
|
+
|
|
23
|
+
Aby zainstalować serwer MCP w Cursor / Antigravity, uruchom:
|
|
24
|
+
deertools mcp install
|
|
25
|
+
|
|
26
|
+
Dokumentacja:
|
|
27
|
+
deertools docs rendermind
|
|
28
|
+
`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = { cmdRenderMind };
|