@deerdesign/deertools 1.2.26 → 1.2.31

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/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 needProduct(flags, pos) {
21
- if (!pos[0]) fail(`Podaj produkt: ${ALL_IDS.join(' | ')}`, 2);
22
- return getProduct(pos[0]);
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
- const entry = await loginBaseLinkerBrowser({
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(` Narzędzia katalogu: deertools baselinker catalog search <id> | MCP: deertools baselinker mcp`);
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 | Katalog: https://skill-garden-vault.lovable.app`);
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
- : (flags.ro || flags['read-only'])
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
- const entry = await login(product, { scope, port: flags.port ? Number(flags.port) : 0, clientName: flags.name, openBrowser: flags['no-open'] ? null : undefined, log: out });
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(` Dokumentacja dla agenta: deertools docs ${product.id} | skill: deertools skill install ${product.id}`);
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
- for (const p of products) {
337
- if (!p.mcpEndpoint) continue;
338
- const cred = credentials.getKey(p);
339
- const key = cred ? cred.key : `${p.keyPrefix}<twój_klucz_api>`;
340
- const srvKey = `deer-${p.id}`;
341
- servers[srvKey] = {
342
- url: p.mcpEndpoint,
343
- headers: {
344
- 'x-api-key': key,
345
- 'Authorization': `Bearer ${key}`,
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 Remote MCP dla DeerTools (np. Cursor IDE, Claude Desktop, Antigravity):');
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 projektach, uruchom:');
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 zintegrowano serwery MCP dla produktów DeerTools!`);
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,69 +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 — ekosystem narzędzi dla architektów i agentów AI Deer Design
570
+ DeerTools CLI — Identity, MCP & Skills Hub Manager dla ekosystemu Deer Design
527
571
 
528
- Produkty: ${ALL_IDS.join(', ')}
572
+ Systemy: ${ALL_IDS.join(', ')}, baselinker
529
573
 
530
- Dostęp i autoryzacja:
531
- deertools login <produkt|all> [--ro|--rw|--admin] Logowanie OAuth (RO: tylko odczyt, RW: zapis, Admin).
532
- deertools logout [produkt|all] Usuwa lokalny klucz.
533
- deertools whoami [produkt|all] [--json] Status logowania, zakres, ważność.
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
- deertools skill sync [--agent <id>|-i|--force] Instaluje brakujące i aktualizuje obecne skille zespołu.
583
+ deertools skill sync [--push] [--force] Instaluje skille zespołu (--push wypycha lokalne nowości do Hubu).
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.
540
586
  deertools skill install [--all|<slug[@wersja]>] Instaluje wszystkie skille (--all) lub wskazany skill.
541
- deertools skill search <fraza> Wyszukuje umiejętności po słowach kluczowych.
542
- deertools skill versions <slug> Historia wydań z changelogami z commitów i datami.
587
+ deertools skill search <fraza> Hybrydowe wyszukiwanie umiejętności (wektory + tekst).
588
+ deertools skill versions <slug> Historia wydań z changelogami i datami.
543
589
  deertools skill diff <slug> [wersjaA] [wersjaB] Porównanie zmian w plikach paczki i treści SKILL.md.
544
590
  deertools skill push [katalog] [--team <zespół>] Publikuje do własnej przestrzeni, zespołu lub globalnie.
545
591
  deertools skill share <slug> --team <zespół> Udostępnia skill prywatny wskazanemu zespołowi.
546
- deertools skill review [list|approve|reject|submit] Zarządzanie procesem Peer Review i weryfikacją skilli zespołu.
592
+ deertools skill review [list|approve|reject|submit] Zarządzanie procesem Peer Review skilli zespołu.
547
593
  deertools skill update [slug] Aktualizuje zainstalowane skille do najnowszej wersji.
548
594
  deertools skill promote <slug> Zgłasza nominację skilla do oficjalnego katalogu globalnego.
549
- deertools team [list] Przegląda listę zespołów, liczbę członków i przypisanych skilli.
550
- deertools team members [zespół] Lista członków zespołów i ich ról (Lider / Członek).
551
- deertools team add <zespół> <email> [--role lead] Dodaje lub aktualizuje rolę pracownika w zespole.
552
- deertools team remove <zespół> <email> Usuwa pracownika ze wskazanego zespołu.
553
- deertools team create <nazwa> [--slug <s>] [--desc] Tworzy nowy zespół w organizacji Deer Design.
554
-
555
- Integracja MCP i inspekcja API produktów:
556
- deertools mcp list Lista dostępnych serwerów MCP w chmurze.
557
- deertools mcp config [--json] Generuje konfigurację Remote MCP dla Cursor i Antigravity.
558
- deertools mcp install Instaluje serwery MCP w Cursor i Antigravity.
559
- deertools mcp serve Lokalny mostek MCP stdio (Claude Desktop / Ollama).
560
- deertools docs <produkt> [llms|openapi|skill] Pobiera dokumentację dla agentów.
561
- deertools endpoints <produkt> [--json] Lista endpointów REST z openapi.json.
562
- deertools api <produkt> <METODA> </ścieżka> Wywołuje bezpośrednio API produktu.
563
-
564
- BaseLinker Hub & Proxy:
565
- deertools baselinker auth [token] Zapisuje klucz API BaseLinkera w credentials.json.
566
- deertools baselinker test Testuje autoryzację i listuje katalogi.
567
- deertools baselinker serve [--port 3456] Lokalny serwer Web UI z dashboardem i MCP SSE.
568
- deertools baselinker mcp [--all] Mostek MCP stdio (Cursor / Claude Desktop).
569
- deertools baselinker sync-schema Pobiera i aktualizuje bazę 204 metod z api.baselinker.com.
570
- deertools baselinker search <fraza> Przeszukuje bazę metod i schematów parametrów.
571
- deertools baselinker call <metoda> [json] Wywołuje dowolną metodę BaseLinkera z CLI.
572
- deertools baselinker catalog <search|get> Operacje katalogowe z poziomu terminala.
573
-
574
- Narzędzia systemowe:
575
- deertools update Sprawdza i podpowiada aktualizację CLI.
576
- deertools doctor [--json] Pełna diagnostyka połączeń, portów i kluczy.
577
- deertools audit [--limit 25] [--clear] [--json] Historia operacji i wywołań API.
578
- deertools completion [install|zsh|bash] Autouzupełnianie w powłoce po wciśnięciu Tab.
579
-
580
- 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).
581
612
  `;
582
613
 
583
614
  module.exports = {
584
- cmdLogin, cmdLogout, cmdWhoami, cmdDocs, cmdEndpoints, cmdApi, cmdSkill, cmdMcp,
615
+ cmdLogin, cmdLogout, cmdWhoami, cmdSkill, cmdMcp,
585
616
  cmdDoctor, cmdAudit, cmdProfile, cmdCompletion,
586
- cmdBaseLinker, cmdAgent, cmdTeam,
617
+ cmdBaseLinker, cmdRenderMind, cmdSupplier,
618
+ cmdAgent, cmdTeam, cmdBlockedDomain,
587
619
  HELP, parseQuery,
588
620
  };
589
-
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 Remote MCP'
23
+ 'mcp:Konfiguracja i instalacja serwerów MCP'
26
24
  'doctor:Diagnostyka środowiska, połączeń i uprawnień'
27
- 'audit:Historia wywołań API i log operacji'
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:Lokalny mostek MCP, Web UI i katalog BaseLinkera'
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|docs|endpoints)
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' 'serve:Uruchom lokalny serwer Web UI' 'mcp:Uruchom mostek MCP stdio' 'sync-schema:Synchronizuj bazę metod' 'search:Wyszukaj metodę' 'call:Wywołaj metodę' 'catalog:Operacje katalogowe' )
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
- _values 'akcja' 'install'
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 docs endpoints api baselinker skill team agent mcp doctor audit profile completion --help --version --json"
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|docs|endpoints)
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 serve mcp sync-schema search call catalog" -- "$cur") )
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 --write --scope --profile" -- "$cur") )
105
+ COMPREPLY=( $(compgen -W "--help --version --json --ro --rw --admin --profile" -- "$cur") )
100
106
  return 0
101
107
  fi
102
108
 
@@ -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 };