@seeed-studio/solution-cli 0.4.0 → 0.4.1

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 CHANGED
@@ -4,22 +4,25 @@ Install the signed Rust deployment engine and the `solution-cli` AI Agent Skill
4
4
 
5
5
  ## 1. Quick Start: Install to Your Agent (快速安装与宿主配置)
6
6
 
7
- **按需安装到当前使用的 AI Agent**(避免全量污染)。直接复制对应命令发给你的 AI 助手,或在终端执行:
7
+ **推荐方式:npm 全局安装并挂载到指定 Agent**
8
+ (将 `solution-cli` 注册到系统全局 PATH,Agent 在对话中调用方案/硬件查询毫秒级响应,避免因 PATH 缺失导致的报错重试):
8
9
 
9
- | 目标 AI 宿主 | 专属一键安装命令(直接复制发给 AI 或在终端运行) | 技能挂载路径 |
10
+ | 目标 AI 宿主 | 专属安装命令(直接复制发给 AI 或在终端运行) | 技能挂载路径 |
10
11
  |---|---|---|
11
- | **豆包工作 (Doubao Work)** | `npx -y @seeed-studio/solution-cli install --agent doubao` | `~/.doubao/skills` |
12
- | **WorkBuddy** | `npx -y @seeed-studio/solution-cli install --agent workbuddy` | `~/.workbuddy/skills` |
13
- | **Claude Code** | `npx -y @seeed-studio/solution-cli install --agent claude` | `~/.claude/skills` |
14
- | **OpenAI Codex** | `npx -y @seeed-studio/solution-cli install --agent codex` | `~/.agents/skills` 或 `~/.codex/skills` |
15
- | **Google Antigravity** | `npx -y @seeed-studio/solution-cli install --agent antigravity` | `~/.gemini/config/skills` |
16
- | **CodeBuddy** | `npx -y @seeed-studio/solution-cli install --agent codebuddy` | `~/.codebuddy/skills` |
17
- | **全部 Agent (全量检测)** | `npx -y @seeed-studio/solution-cli install --agent all` | 上述全部已检测目录 |
18
- | **自定义路径 (如 Cursor)** | `npx -y @seeed-studio/solution-cli install --skills-dir <路径>` | `<自定义路径>/solution-cli` |
12
+ | **豆包工作 (Doubao Work)** | `npm install -g @seeed-studio/solution-cli && solution-cli install --agent doubao` | `~/.doubao/skills` |
13
+ | **Claude Code** | `npm install -g @seeed-studio/solution-cli && solution-cli install --agent claude` | `~/.claude/skills` |
14
+ | **OpenAI Codex** | `npm install -g @seeed-studio/solution-cli && solution-cli install --agent codex` | `~/.agents/skills` 或 `~/.codex/skills` |
15
+ | **Google Antigravity** | `npm install -g @seeed-studio/solution-cli && solution-cli install --agent antigravity` | `~/.gemini/config/skills` |
16
+ | **WorkBuddy** | `npm install -g @seeed-studio/solution-cli && solution-cli install --agent workbuddy` | `~/.workbuddy/skills` |
17
+ | **CodeBuddy** | `npm install -g @seeed-studio/solution-cli && solution-cli install --agent codebuddy` | `~/.codebuddy/skills` |
18
+ | **Hermes Agent** | `npm install -g @seeed-studio/solution-cli && solution-cli install --agent hermes` | `$HERMES_HOME/skills` (默认 `~/.hermes/skills`) |
19
+ | **全部 Agent (全量检测)** | `npm install -g @seeed-studio/solution-cli && solution-cli install --agent all` | 上述全部已检测目录 |
20
+ | **自定义路径 (如 Cursor)** | `npm install -g @seeed-studio/solution-cli && solution-cli install --skills-dir <路径>` | `<自定义路径>/solution-cli` |
19
21
 
20
22
  > [!TIP]
21
- > - **发给 AI 助手**:直接复制上表中对应的专属命令发给你的 AI(例如对豆包说:*“请帮我运行:`npx -y @seeed-studio/solution-cli install --agent doubao`”*),AI 即可在后台全自动执行完成。
22
- > - **精准隔离**:指定 `--agent <id>` 时,安装器仅写入该 Agent 对应的目录,绝不修改或触碰其他 Agent 环境。
23
+ > - **为什么使用 `npm install -g`?** 全局安装后,系统内已有 `solution-cli` 命令。AI Agent 在后续对话中调用方案与硬件查询无需每次通过网络重新下载包,避免产生 `command not found: solution-cli` 报错。
24
+ > - **发给 AI 助手**:直接复制上表中对应的专属命令发给你的 AI 助手(例如对豆包说:*“请帮我运行:`npm install -g @seeed-studio/solution-cli && solution-cli install --agent doubao`”*)。
25
+ > - **免全局安装(npx 备选)**:若无系统全局 npm 写入权限,仍可使用 npx 免全局安装:`npx -y @seeed-studio/solution-cli install --agent <id>`。
23
26
  > - **国内镜像延迟排查**:若遇 npm 同步延迟,可在命令末尾加上 `--registry=https://registry.npmjs.org/`。
24
27
 
25
28
  ### 开发者本地源码部署
package/bin/cli.js CHANGED
@@ -4,7 +4,7 @@ import path from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { runInstall, runUpdate, listAgents, runStatus, runUninstall } from '../lib/installer.js';
6
6
  import { runDoctor } from '../lib/doctor.js';
7
- import { searchHub, listHub, getHubRecord, loadKnowledgeCore, queryProductFamily, queryAccessories, createDeploymentLockfile } from '../lib/knowledge.js';
7
+ import { searchHub, listHub, getHubRecord, loadKnowledgeCore, queryProductFamily, searchProducts, queryAccessories, createDeploymentLockfile } from '../lib/knowledge.js';
8
8
  import { assertCompatibility } from '../lib/compatibility.js';
9
9
  import { searchGotchas } from '../lib/gotchas.js';
10
10
 
@@ -34,8 +34,9 @@ Commands:
34
34
  Usage: solution-cli hub search <keyword> [--limit 5] [--locale zh|en|ja] [--json]
35
35
  solution-cli hub list [--type scenario|tech|reference_design] [--page N] [--limit 50] [--locale zh|en|ja] [--json]
36
36
  solution-cli hub get <id> [--type ...] [--section overview|links|description|architecture|products|deployment|playbook|integration] [--preset <id>] [--locale zh|en|ja] [--json]
37
- product Query product families, SKUs, and verified accessories
38
- Usage: solution-cli product query <family_id> [--locale zh|en] [--json]
37
+ product Query product families, SKUs, physical interfaces, box contents, and verified accessories
38
+ Usage: solution-cli product search <keyword|model|sku> [--limit 5] [--locale zh|en|ja] [--json]
39
+ solution-cli product query <family_id> [--locale zh|en|ja] [--json]
39
40
  solution-cli product accessories <family_id> [--sku <sku>] [--category <cats>] [--compact] [--json]
40
41
  solution-cli product verify-compatibility --host <family_id> [--json]
41
42
  gotchas Search edge hardware and chip troubleshooting knowledge (RK3588, reCamera, Jetson, Hailo)
@@ -45,7 +46,7 @@ Commands:
45
46
  help Show this help message
46
47
 
47
48
  Options:
48
- --agent <name|all> Target agent(s): workbuddy, doubao, claude, codex, codebuddy, antigravity, or all
49
+ --agent <name|all> Target agent(s): workbuddy, doubao, claude, codex, codebuddy, antigravity, hermes, hermes:<profile>, or all
49
50
  --skills-dir <path> Install skill directly to custom directory (supports any third-party or proprietary Agent)
50
51
  -y, --yes Accept default detected selections non-interactively
51
52
  --dry-run Simulate operations without making changes to filesystem
@@ -209,7 +210,7 @@ function validateCommandFlags(command, flags) {
209
210
  doctor: ['--json'],
210
211
  agent: ['--json'],
211
212
  hub: ['--json', '--compact', '--locale', '--limit', '--page', '--type', '--section', '--sections', '--preset'],
212
- product: ['--json', '--compact', '--locale', '--sku', '--host', '--accessory', '--category'],
213
+ product: ['--json', '--compact', '--locale', '--sku', '--host', '--accessory', '--category', '--limit'],
213
214
  gotchas: ['--json', '--chip'],
214
215
  lockfile: ['--json', '--solution', '--version', '--hardware'],
215
216
  help: [],
@@ -495,10 +496,102 @@ async function main() {
495
496
  }
496
497
 
497
498
  case 'product': {
498
- const sub = flags.positionals[0] || 'query';
499
- const familyId = flags.positionals[1] || flags.host;
499
+ const rawFirst = flags.positionals[0];
500
+ const core = loadKnowledgeCore();
501
+ let sub = rawFirst;
502
+ let queryTarget = flags.positionals[1] || flags.host;
503
+
504
+ // Auto routing: if first argument is not a known subcommand keyword
505
+ if (rawFirst !== 'search' && rawFirst !== 'query' && rawFirst !== 'accessories' && rawFirst !== 'verify-compatibility') {
506
+ if (rawFirst && core.product_families?.[rawFirst]) {
507
+ sub = 'query';
508
+ queryTarget = rawFirst;
509
+ } else if (rawFirst) {
510
+ sub = 'search';
511
+ queryTarget = flags.positionals.join(' ');
512
+ } else {
513
+ sub = 'query';
514
+ }
515
+ }
516
+ const familyId = queryTarget;
517
+
518
+ if (sub === 'search') {
519
+ const q = (rawFirst === 'search' ? flags.positionals.slice(1).join(' ') : queryTarget) || '';
520
+ if (!q.trim()) {
521
+ console.error('Please specify a search query (e.g. "solution-cli product search J4012 Super")');
522
+ process.exit(1);
523
+ }
524
+ const dto = searchProducts({ query: q, locale: flags.locale, limit: flags.limit ? parseInt(flags.limit, 10) : 5 });
525
+ if (flags.json) {
526
+ console.log(JSON.stringify(dto, null, 2));
527
+ } else {
528
+ if (dto.records.length === 0) {
529
+ console.log(`未找到与 "${q}" 匹配的硬件产品。`);
530
+ } else {
531
+ console.log(`\n🔍 找到 ${dto.records.length} 个匹配的硬件产品族:`);
532
+ dto.records.forEach((fam) => {
533
+ console.log(`\n======================================================================`);
534
+ console.log(`📦 \x1b[1m${fam.title}\x1b[0m (Family ID: \x1b[36m${fam.family_id}\x1b[0m)`);
535
+ if (fam.summary) console.log(` 💡 简介: ${fam.summary}`);
536
+ if (fam.interfaces?.length) console.log(` 🔌 板载接口 (Interfaces): ${fam.interfaces.join(', ')}`);
537
+ if (fam.protocols?.length) console.log(` 📡 通信协议 (Protocols): ${fam.protocols.join(', ')}`);
538
+
539
+ if (fam.supported_scenarios?.length) {
540
+ console.log(` 🚀 官方落地方案 (该设备可以干嘛):`);
541
+ fam.supported_scenarios.slice(0, 5).forEach((sc) => {
542
+ const scTitle = sc.title?.[flags.locale] || sc.title?.zh || sc.title?.en || sc.id;
543
+ console.log(` - \x1b[32m${scTitle}\x1b[0m (ID: ${sc.id})`);
544
+ });
545
+ }
500
546
 
501
- if (sub === 'query') {
547
+ if (fam.matched_skus?.length) {
548
+ console.log(` 🎯 具体型号 (SKU) & 开箱配置:`);
549
+ fam.matched_skus.forEach((s) => {
550
+ console.log(` --------------------------------------------------`);
551
+ console.log(` SKU: \x1b[1m${s.sku}\x1b[0m | 型号: ${s.model || '标准款'} | 名称: ${s.name}`);
552
+ if (s.ai_performance) console.log(` ⚡ 算力: ${s.ai_performance}`);
553
+
554
+ // Power & Readiness summary
555
+ if (s.package_profile?.readiness_summary) {
556
+ const icon = s.package_profile.out_of_the_box_ready ? '\x1b[32m✔ 开箱即用\x1b[0m' : '\x1b[33m⚠️ 无法直接开机/需配件\x1b[0m';
557
+ console.log(` ⚡ 开箱状态: ${icon}`);
558
+ console.log(` ${s.package_profile.readiness_summary}`);
559
+ } else if (s.power.adapter_included === true) {
560
+ console.log(` 🔌 电源适配器: \x1b[32m✔ 随附\x1b[0m (${s.power.adapter_spec || s.power.input_voltage || '标配适配器'})`);
561
+ } else if (s.power.adapter_included === false) {
562
+ console.log(` 🔌 电源适配器: \x1b[31m✖ 不随附\x1b[0m (需要自备或加配: ${s.power.adapter_spec || s.power.input_voltage || '需外接电源'})`);
563
+ } else if (s.power.input_voltage) {
564
+ console.log(` 🔌 供电要求: ${s.power.input_voltage} ${s.power.input_connector || ''}`);
565
+ }
566
+
567
+ // Required accessories if any
568
+ if (s.required_accessories?.length) {
569
+ console.log(` 🔌 必需加配配件:`);
570
+ s.required_accessories.forEach((acc) => {
571
+ console.log(` • \x1b[1m${acc.name}\x1b[0m (SKU: ${acc.sku || 'N/A'})${acc.reason ? ` - ${acc.reason}` : ''}`);
572
+ });
573
+ }
574
+
575
+ // Package contents
576
+ if (s.package_contents?.length) {
577
+ console.log(` 📦 包装清单 (Box Contents):`);
578
+ s.package_contents.forEach((item) => console.log(` • ${item}`));
579
+ }
580
+
581
+ // I/O ports
582
+ if (s.io_ports?.length) {
583
+ const portSummary = s.io_ports.map((p) => `${p.count}x ${p.type}${p.notes ? ` (${p.notes})` : ''}`).join(', ');
584
+ console.log(` 🖥️ 外设端口 (I/O Ports): ${portSummary}`);
585
+ }
586
+
587
+ if (s.url) console.log(` 🔗 购买链接: ${s.url}`);
588
+ });
589
+ }
590
+ });
591
+ console.log(`\n💡 提示: 查看该设备必需与推荐配件请使用: solution-cli product accessories <family_id>`);
592
+ }
593
+ }
594
+ } else if (sub === 'query') {
502
595
  if (!familyId) {
503
596
  console.error('Please specify a product family ID (e.g. "solution-cli product query recomputer_j40")');
504
597
  process.exit(1);
@@ -512,9 +605,23 @@ async function main() {
512
605
  console.log(`Product family "${familyId}" not found.`);
513
606
  } else {
514
607
  console.log(`\n📦 Product Family: \x1b[1m${fam.title}\x1b[0m (${fam.family_id})`);
608
+ if (fam.summary) console.log(` Summary: ${fam.summary}`);
515
609
  console.log(` Default SKU: ${fam.default_sku || 'N/A'}`);
516
610
  console.log(` Regions: ${(fam.regions || []).join(', ') || 'Global'}`);
517
611
  console.log(` SKUs Available: ${fam.skus_count}`);
612
+ if (fam.interfaces?.length) {
613
+ console.log(` Interfaces: ${fam.interfaces.join(', ')}`);
614
+ }
615
+ if (fam.protocols?.length) {
616
+ console.log(` Protocols: ${fam.protocols.join(', ')}`);
617
+ }
618
+ if (fam.supported_scenarios?.length) {
619
+ console.log(` Supported Scenarios:`);
620
+ fam.supported_scenarios.slice(0, 5).forEach((sc) => {
621
+ const scTitle = sc.title?.[flags.locale] || sc.title?.zh || sc.title?.en || sc.id;
622
+ console.log(` - ${scTitle} (${sc.id})`);
623
+ });
624
+ }
518
625
  if (fam.physical_spec?.power_input) {
519
626
  const p = fam.physical_spec.power_input;
520
627
  console.log(` Power Spec: ${p.voltage_v || ''}V ${p.min_current_a || ''}A (${p.connector}) ${p.polarity || ''}`);