@baize-ai/core 0.2.0 → 0.3.0

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.
Files changed (44) hide show
  1. package/.dockerignore +8 -18
  2. package/CHANGELOG.md +19 -1
  3. package/Dockerfile +66 -12
  4. package/README.md +85 -6
  5. package/README.zh-CN.md +63 -3
  6. package/assets/logo.png +0 -0
  7. package/cli/baize.js +6 -0
  8. package/cli/commands/a2a.js +124 -0
  9. package/cli/commands/add.js +126 -86
  10. package/cli/commands/component.js +27 -4
  11. package/cli/commands/doctor.js +2 -2
  12. package/cli/commands/init.js +28 -0
  13. package/cli/commands/self-uninstall.js +1 -1
  14. package/cli/lib/__tests__/instruction-split.test.js +1 -1
  15. package/cli/lib/a2a.js +235 -0
  16. package/cli/lib/lock.js +3 -3
  17. package/cli/lib/self-upgrade.js +1 -1
  18. package/docker-compose.yml +1 -1
  19. package/docs/docker.md +18 -4
  20. package/docs/release.md +150 -0
  21. package/package.json +1 -1
  22. package/scripts/docker-publish.sh +70 -0
  23. package/scripts/install.sh +4 -4
  24. package/scripts/pack-release.sh +361 -0
  25. package/skills/comm-bridge/package.json +7 -3
  26. package/skills/comm-bridge/scripts/c4-receive.js +23 -2
  27. package/skills/scheduler/package.json +2 -2
  28. package/skills/web-console/SKILL.md +34 -0
  29. package/skills/web-console/package.json +2 -2
  30. package/skills/web-console/public/app.js +900 -4
  31. package/skills/web-console/public/index.html +126 -0
  32. package/skills/web-console/public/styles.css +130 -0
  33. package/skills/web-console/scripts/a2a-admin.js +506 -0
  34. package/skills/web-console/scripts/channel-admin.js +99 -16
  35. package/skills/web-console/scripts/server.js +386 -1
  36. package/skills/web-console/scripts/skill-catalog.js +179 -0
  37. package/templates/claude-system.md +22 -0
  38. package/templates/pm2/ecosystem.config.cjs +4 -1
  39. package/test/a2a-cli.test.js +180 -0
  40. package/test/agent-card-api.test.js +261 -0
  41. package/test/channel-admin.test.js +87 -0
  42. package/test/component-lock.test.js +216 -0
  43. package/test/skill-catalog.test.js +118 -0
  44. package/test/web-console-routes.test.js +488 -1
@@ -35,6 +35,7 @@
35
35
  <button type="button" class="app-nav-item" id="nav-chat">聊天</button>
36
36
  <button type="button" class="app-nav-item" id="nav-model">模型设置</button>
37
37
  <button type="button" class="app-nav-item" id="nav-channels">渠道设置</button>
38
+ <button type="button" class="app-nav-item" id="nav-a2a">A2A 互联</button>
38
39
  </nav>
39
40
  <div class="header-right">
40
41
  <div class="status" id="status">
@@ -252,6 +253,131 @@
252
253
 
253
254
 
254
255
 
256
+ </div>
257
+ </main>
258
+
259
+ <!-- A2A View (Agent-to-Agent) -->
260
+ <main class="settings-view" id="a2a-view" hidden>
261
+ <div class="settings-container">
262
+
263
+ <!-- Section: install + mode + config + health (D25 U3) -->
264
+ <section class="settings-section">
265
+ <div class="settings-section-head">
266
+ <h2>A2A 智能体互联</h2>
267
+ <p>Agent-to-Agent:模块安装、运行模式(单机/集群)、peer 目录、任务看板与消息记录。数据由本机 baize-a2a 组件提供。</p>
268
+ </div>
269
+ <div class="settings-grid">
270
+ <div class="settings-card">
271
+ <div class="card-title">模块安装 <span class="channel-state" id="a2a-install-state"></span></div>
272
+ <div class="cred-state" id="a2a-install-status" role="status" aria-live="polite">加载中...</div>
273
+ <form id="form-a2a-install" class="settings-form">
274
+ <input type="file" id="a2a-install-file" accept=".tgz,.tar.gz,.zip" aria-label="选择 baize-a2a 模块包">
275
+ <button type="submit" class="btn btn-primary" id="btn-a2a-install">上传安装</button>
276
+ </form>
277
+ <div class="cred-state" id="a2a-install-feedback" role="status" aria-live="polite"></div>
278
+ </div>
279
+ <div class="settings-card">
280
+ <div class="card-title">运行模式 <span class="channel-state" id="a2a-mode-state"></span></div>
281
+ <div class="cred-state" id="a2a-mode-badge" role="status" aria-live="polite">加载中...</div>
282
+ <div class="admin-actions">
283
+ <button type="button" class="btn btn-primary" id="btn-a2a-switch-mode" disabled>切换集群模式</button>
284
+ </div>
285
+ <div class="cred-state" id="a2a-mode-feedback" role="status" aria-live="polite"></div>
286
+ </div>
287
+ <div class="settings-card">
288
+ <div class="card-title">连接配置 <span class="channel-state" id="a2a-config-state"></span></div>
289
+ <form id="form-a2a-config" class="settings-form settings-form-stack">
290
+ <input type="text" id="a2a-config-admin-url" placeholder="Admin 服务地址(如 https://admin.example.com)" autocomplete="off" spellcheck="false" aria-label="Admin 服务地址">
291
+ <input type="text" id="a2a-config-advertise-url" placeholder="对外宣告地址(如 https://a2a.example.com)" autocomplete="off" spellcheck="false" aria-label="对外宣告地址">
292
+ <button type="submit" class="btn btn-primary">保存配置</button>
293
+ </form>
294
+ <div class="cred-state" id="a2a-config-feedback" role="status" aria-live="polite"></div>
295
+ </div>
296
+ <div class="settings-card">
297
+ <div class="card-title">健康状态 <span class="channel-state" id="a2a-health-state"></span></div>
298
+ <div class="cred-state" id="a2a-health" role="status" aria-live="polite">加载中...</div>
299
+ </div>
300
+ </div>
301
+ <div class="settings-card">
302
+ <div class="card-title">身份与注册状态 <span class="channel-state" id="a2a-status-state"></span></div>
303
+ <div class="cred-state" id="a2a-status" role="status" aria-live="polite">加载中...</div>
304
+ <div class="card-title" style="margin-top: var(--s-3);">Agent 名片 <span class="channel-state" id="a2a-card-state"></span></div>
305
+ <div class="cred-state" id="a2a-card" role="status" aria-live="polite">名片加载中...</div>
306
+ <div class="card-title" style="margin-top: var(--s-3);">调用授权 <span class="channel-state" id="a2a-authz-state"></span></div>
307
+ <div class="cred-state" id="a2a-authz" role="status" aria-live="polite">授权策略加载中...</div>
308
+ <div class="admin-actions">
309
+ <button type="button" class="btn btn-outline" id="btn-a2a-edit-card">编辑名片</button>
310
+ </div>
311
+ </div>
312
+ </section>
313
+
314
+ <!-- Section: peer directory + search -->
315
+ <section class="settings-section">
316
+ <div class="settings-section-head">
317
+ <h2>Peer 目录</h2>
318
+ <p>已缓存的可达 agent;可在 admin Directory 中搜索更多。</p>
319
+ </div>
320
+ <div class="settings-card">
321
+ <div class="card-title">Peers <span class="channel-state" id="a2a-peers-state"></span></div>
322
+ <div id="a2a-peers" role="list" aria-live="polite">加载中...</div>
323
+ <form id="form-a2a-search" class="settings-form">
324
+ <input type="text" id="a2a-search-query" placeholder="在 Directory 中搜索 agent(如 doccraft)" autocomplete="off" spellcheck="false" aria-label="搜索 agent">
325
+ <button type="submit" class="btn btn-outline">搜索</button>
326
+ </form>
327
+ <div class="cred-state" id="a2a-search-results" role="status" aria-live="polite"></div>
328
+ </div>
329
+ </section>
330
+
331
+ <!-- Section: task board -->
332
+ <section class="settings-section">
333
+ <div class="settings-section-head">
334
+ <h2>任务看板</h2>
335
+ <p>本机 A2A 任务(task_runs,source=a2a)状态一览。</p>
336
+ </div>
337
+ <div class="settings-card">
338
+ <div class="card-title">Tasks <span class="channel-state" id="a2a-tasks-state"></span></div>
339
+ <div id="a2a-tasks" aria-live="polite">加载中...</div>
340
+ </div>
341
+ </section>
342
+
343
+ <!-- Section: message log -->
344
+ <section class="settings-section">
345
+ <div class="settings-section-head">
346
+ <h2>消息记录</h2>
347
+ <p>本机 A2A inbox / outbox 最近消息。</p>
348
+ </div>
349
+ <div class="settings-card">
350
+ <div class="card-title">Messages <span class="channel-state" id="a2a-messages-state"></span></div>
351
+ <div id="a2a-messages" aria-live="polite">加载中...</div>
352
+ </div>
353
+ </section>
354
+
355
+ <!-- Section: delegation -->
356
+ <section class="settings-section">
357
+ <div class="settings-section-head">
358
+ <h2>委托</h2>
359
+ <p>向 peer 发送消息或派发任务。</p>
360
+ </div>
361
+ <div class="settings-card">
362
+ <div class="card-title">发送消息</div>
363
+ <form id="form-a2a-send" class="settings-form settings-form-stack">
364
+ <input type="text" id="a2a-send-peer" placeholder="peer agent ID" autocomplete="off" spellcheck="false" aria-label="peer agent ID">
365
+ <textarea id="a2a-send-text" placeholder="消息内容" rows="2" aria-label="消息内容"></textarea>
366
+ <button type="submit" class="btn btn-primary">发送</button>
367
+ </form>
368
+ </div>
369
+ <div class="settings-card">
370
+ <div class="card-title">派发任务</div>
371
+ <form id="form-a2a-task" class="settings-form settings-form-stack">
372
+ <input type="text" id="a2a-task-peer" placeholder="peer agent ID" autocomplete="off" spellcheck="false" aria-label="peer agent ID">
373
+ <input type="text" id="a2a-task-skill" placeholder="skill ID(可选)" autocomplete="off" spellcheck="false" aria-label="skill ID">
374
+ <textarea id="a2a-task-instruction" placeholder="指令" rows="2" aria-label="指令"></textarea>
375
+ <label class="remember-me"><input type="checkbox" id="a2a-task-async"> 异步派发(立即返回 taskId)</label>
376
+ <button type="submit" class="btn btn-primary">派发任务</button>
377
+ </form>
378
+ </div>
379
+ </section>
380
+
255
381
  </div>
256
382
  </main>
257
383
  </div>
@@ -717,6 +717,32 @@ input, textarea { font-family: inherit; color: inherit; }
717
717
  .channel-state.ok { color: var(--success-green); }
718
718
  .channel-state.warn { color: var(--warning); }
719
719
 
720
+ /* ── D25 U3: A2A mode card / install / config / health ───────── */
721
+ .a2a-mode-badge {
722
+ display: inline-block;
723
+ padding: 3px 12px;
724
+ border-radius: var(--r-full);
725
+ background: var(--bg-hover);
726
+ border: 1px solid var(--border-strong);
727
+ color: var(--text-secondary);
728
+ font-size: var(--fs-sm);
729
+ font-weight: 600;
730
+ white-space: nowrap;
731
+ }
732
+ .a2a-mode-badge.ok {
733
+ background: var(--success-green-soft);
734
+ border-color: rgba(87, 201, 135, 0.4);
735
+ color: var(--success-green);
736
+ }
737
+ .a2a-mode-badge.err {
738
+ background: rgba(239, 106, 106, 0.12);
739
+ border-color: rgba(239, 106, 106, 0.4);
740
+ color: var(--danger);
741
+ }
742
+ .a2a-mode-detail { font-size: var(--fs-sm); color: var(--text-secondary); }
743
+ .a2a-feedback-ok { color: var(--success-green); }
744
+ .a2a-feedback-error { color: var(--danger); }
745
+
720
746
  /* Official channel catalogue */
721
747
  .channel-item {
722
748
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
@@ -738,3 +764,107 @@ input, textarea { font-family: inherit; color: inherit; }
738
764
  }
739
765
  .btn-danger { color: var(--danger); border-color: rgba(239, 106, 106, 0.4); }
740
766
  .btn-danger:hover { background: rgba(239, 106, 106, 0.12); }
767
+
768
+ /* ── Agent card editor modal (D21) ───────────────────────────── */
769
+ .agent-card-modal-overlay {
770
+ position: fixed; inset: 0; z-index: 1000;
771
+ background: rgba(8, 12, 16, 0.6);
772
+ display: flex; align-items: center; justify-content: center;
773
+ padding: var(--s-4);
774
+ }
775
+ .agent-card-modal {
776
+ background: var(--bg-surface);
777
+ border: 1px solid var(--border-strong);
778
+ border-radius: var(--r-lg);
779
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
780
+ width: min(640px, 100%);
781
+ max-height: 85vh;
782
+ display: flex; flex-direction: column;
783
+ }
784
+ .agent-card-modal-head {
785
+ display: flex; align-items: center; justify-content: space-between;
786
+ padding: var(--s-4) var(--s-5); border-bottom: 1px solid var(--border);
787
+ }
788
+ .agent-card-modal-head .card-title { margin-bottom: 0; }
789
+ .agent-card-modal-close {
790
+ background: transparent; border: none; color: var(--text-secondary);
791
+ font-size: 22px; line-height: 1; cursor: pointer; padding: 2px 6px;
792
+ border-radius: var(--r-sm);
793
+ }
794
+ .agent-card-modal-close:hover { background: var(--bg-hover); color: var(--text-primary); }
795
+ .agent-card-modal-body { padding: var(--s-4) var(--s-5); overflow-y: auto; display: flex; flex-direction: column; gap: var(--s-2); }
796
+ .agent-card-field-label {
797
+ font-size: var(--fs-xs); color: var(--text-secondary);
798
+ margin-top: var(--s-2); display: flex; align-items: center; gap: var(--s-2);
799
+ }
800
+ .agent-card-input {
801
+ width: 100%; padding: 9px 12px;
802
+ border: 1px solid var(--border-strong); border-radius: var(--r-md);
803
+ background: var(--bg-input); color: var(--text-primary);
804
+ font-size: var(--fs-sm); outline: none; box-sizing: border-box;
805
+ transition: border-color 0.15s, box-shadow 0.15s;
806
+ }
807
+ .agent-card-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
808
+ .agent-card-textarea { resize: vertical; min-height: 64px; font-family: inherit; }
809
+ .agent-card-selected-count { font-size: var(--fs-xs); color: var(--accent); }
810
+ .agent-card-skill-list {
811
+ border: 1px solid var(--border); border-radius: var(--r-md);
812
+ max-height: 260px; overflow-y: auto; padding: var(--s-1);
813
+ display: flex; flex-direction: column; gap: 2px;
814
+ }
815
+ .agent-card-skill-row {
816
+ display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
817
+ padding: 8px 10px; border-radius: var(--r-md); cursor: pointer;
818
+ border: 1px solid transparent;
819
+ }
820
+ .agent-card-skill-row:hover { background: var(--bg-hover); }
821
+ .agent-card-skill-row.selected { background: var(--accent-soft); border-color: rgba(77, 217, 208, 0.35); }
822
+ .agent-card-skill-main { min-width: 0; }
823
+ .agent-card-skill-title { display: flex; align-items: center; gap: var(--s-2); margin-bottom: 2px; }
824
+ .agent-card-skill-id { font-size: 11px; color: var(--text-muted); }
825
+ .agent-card-skill-row .conn-block-desc { margin-bottom: 0; }
826
+ .agent-card-skill-check { color: var(--accent); font-weight: 700; flex-shrink: 0; }
827
+ .agent-card-modal-foot {
828
+ display: flex; justify-content: flex-end; gap: var(--s-2);
829
+ padding: var(--s-3) var(--s-5); border-top: 1px solid var(--border);
830
+ }
831
+
832
+ /* Agent card editor tabs (D22 单元 C) */
833
+ .agent-card-modal-tabs {
834
+ display: flex; gap: var(--s-1);
835
+ padding: var(--s-2) var(--s-5) 0;
836
+ border-bottom: 1px solid var(--border);
837
+ }
838
+ .agent-card-tab {
839
+ background: transparent; border: none;
840
+ border-bottom: 2px solid transparent;
841
+ color: var(--text-secondary);
842
+ font-size: var(--fs-sm);
843
+ padding: var(--s-2) var(--s-3);
844
+ cursor: pointer;
845
+ margin-bottom: -1px;
846
+ }
847
+ .agent-card-tab:hover { color: var(--text-primary); }
848
+ .agent-card-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
849
+
850
+ /* Call authorization tab */
851
+ .authz-mode-row { display: flex; gap: var(--s-4); padding: var(--s-1) 0; }
852
+ .authz-mode-option { display: flex; align-items: center; gap: 6px; font-size: var(--fs-sm); cursor: pointer; }
853
+ .authz-tags { display: flex; flex-wrap: wrap; gap: var(--s-2); min-height: 28px; }
854
+ .authz-tag {
855
+ display: inline-flex; align-items: center; gap: 6px;
856
+ background: var(--bg-hover);
857
+ border: 1px solid var(--border);
858
+ border-radius: var(--r-full);
859
+ padding: 3px 8px 3px 10px;
860
+ font-size: var(--fs-xs);
861
+ max-width: 100%;
862
+ }
863
+ .authz-tag-x {
864
+ background: transparent; border: none; cursor: pointer;
865
+ color: var(--text-secondary); font-size: 14px; line-height: 1;
866
+ padding: 0 2px; border-radius: 50%;
867
+ }
868
+ .authz-tag-x:hover { color: var(--danger); }
869
+ .authz-add-row { display: flex; gap: var(--s-2); }
870
+ .authz-add-row .agent-card-input { flex: 1; }