@nelsonlongxiang/dsh-open-a2a-net 0.6.32 → 0.6.34

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 (64) hide show
  1. package/README.md +12 -3
  2. package/README_zh.md +12 -3
  3. package/assets/nexusDist/assets/index-D2BGWOeU.js +9 -0
  4. package/assets/nexusDist/assets/index-z33lHtLw.css +1 -0
  5. package/assets/nexusDist/index.html +2 -2
  6. package/cli/a2a.mjs +5 -2
  7. package/lib/a2a-client.js +9 -2
  8. package/lib/auth-observer.js +1 -1
  9. package/lib/canvas-store.js +50 -6
  10. package/lib/card.js +2 -1
  11. package/lib/cli-home.js +44 -0
  12. package/lib/client/A2aControl.js +1 -1
  13. package/lib/client.js +65 -65
  14. package/lib/client.js.map +1 -1
  15. package/lib/direct-forward.js +61 -0
  16. package/lib/faces/admin.js +84 -9
  17. package/lib/faces/wire.js +57 -16
  18. package/lib/index.js +118 -67
  19. package/lib/layout-store.js +3 -2
  20. package/lib/outbound-scope.js +25 -0
  21. package/lib/queue-guard.js +37 -0
  22. package/lib/roster-op.js +104 -0
  23. package/lib/skill/references/cli.md +6 -5
  24. package/lib/skill/references/pitfalls.md +1 -4
  25. package/lib/skill/references/router.md +1 -1
  26. package/lib/task-auth.js +52 -3
  27. package/lib/task-ledger.js +4 -1
  28. package/lib/team-store.js +49 -1
  29. package/lib/tools/info.js +19 -3
  30. package/lib/types/a2a-client.d.ts +1 -1
  31. package/lib/types/auth-observer.d.ts +2 -2
  32. package/lib/types/canvas-store.d.ts +14 -1
  33. package/lib/types/cli-home.d.ts +24 -0
  34. package/lib/types/client/A2aControl.d.ts +1 -1
  35. package/lib/types/direct-forward.d.ts +32 -0
  36. package/lib/types/faces/admin.d.ts +9 -1
  37. package/lib/types/faces/wire.d.ts +13 -4
  38. package/lib/types/index.d.ts +4 -0
  39. package/lib/types/outbound-scope.d.ts +21 -0
  40. package/lib/types/queue-guard.d.ts +32 -0
  41. package/lib/types/roster-op.d.ts +21 -0
  42. package/lib/types/runtime.d.ts +1 -1
  43. package/lib/types/task-auth.d.ts +17 -2
  44. package/lib/types/task-ledger.d.ts +6 -1
  45. package/lib/types/team-store.d.ts +7 -0
  46. package/lib/types/types.d.ts +8 -0
  47. package/nexus-stage/src/canvas-ops.ts +2 -1
  48. package/nexus-stage/src/cli-home-picker.ts +42 -0
  49. package/nexus-stage/src/layout-doc.ts +6 -4
  50. package/nexus-stage/src/main.ts +36 -4
  51. package/nexus-stage/src/planning-card.ts +61 -0
  52. package/nexus-stage/src/planning-frame-hue.ts +13 -0
  53. package/nexus-stage/src/planning-legend.ts +1 -0
  54. package/nexus-stage/src/planning-menus.ts +63 -12
  55. package/nexus-stage/src/planning-roster.ts +15 -0
  56. package/nexus-stage/src/planning-types.ts +1 -1
  57. package/nexus-stage/src/planning-view.ts +43 -59
  58. package/nexus-stage/src/planning.css +19 -0
  59. package/nexus-stage/src/workbench.css +4 -0
  60. package/nexus-stage/src/workbench.ts +24 -5
  61. package/nexus-stage/src/world.ts +5 -1
  62. package/package.json +4 -2
  63. package/assets/nexusDist/assets/index-D5H8R8de.js +0 -9
  64. package/assets/nexusDist/assets/index-D9GYZyGZ.css +0 -1
@@ -0,0 +1 @@
1
+ #dsh-plan *,#dsh-plan *:before,#dsh-plan *:after{box-sizing:border-box}#dsh-plan{--uupm-ink-0:var(--n-ink,#dde3f0);--uupm-ink-1:var(--n-ink-muted,#7a86a0);--uupm-bg-0:var(--n-bg,#060a12);--uupm-bg-1:var(--n-panel,#0d1322);--uupm-bg-2:var(--n-raised,#131b2e);--uupm-accent:var(--n-accent,#9673f7);--uupm-live:var(--n-live,#4ade80);--uupm-cold:var(--n-cold,#7a86a0);--uupm-edge-member:var(--n-canvas,#22d3ee);--uupm-warn:var(--n-act,#f59e0b);--uupm-error:var(--n-danger,#f87171);--uupm-indigo:var(--n-federal,#6366f1);--uupm-wash-5:color-mix(in srgb,var(--uupm-accent) 5%,transparent);--uupm-wash-8:color-mix(in srgb,var(--uupm-accent) 8%,transparent);--uupm-wash-12:color-mix(in srgb,var(--uupm-accent) 12%,transparent);--uupm-wash-15:color-mix(in srgb,var(--uupm-accent) 15%,transparent);--uupm-wash-18:color-mix(in srgb,var(--uupm-accent) 18%,transparent);--surface:var(--uupm-bg-1);--ink:var(--uupm-ink-0);--ink-muted:var(--uupm-ink-1);--accent:var(--uupm-accent);--edge-live:var(--uupm-live);--edge-cold:var(--uupm-cold);--federal:var(--uupm-indigo);--card-bg:var(--surface);--card-line:var(--n-card-line,#5c6680);--card-line-hover:var(--uupm-ink-1);--toolbar-bg:color-mix(in srgb,var(--uupm-bg-1) 92%,transparent);--grid-dot:color-mix(in srgb,var(--uupm-ink-1) 22%,transparent);--scrim:color-mix(in srgb,var(--uupm-bg-0) 60%,transparent);--error-ink:var(--n-error-ink,#fecaca);--error-panel:var(--n-error-panel,#2a0d10f2)}#dsh-plan{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;background:var(--uupm-bg-0);color:var(--ink);font-size:13px;line-height:1.5;outline:none}#dsh-plan .mono{font-family:ui-monospace,Cascadia,Consolas,monospace}#dsh-plan:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}#dsh-plan .p-grid{position:absolute;top:0;right:0;bottom:0;left:0;z-index:0;pointer-events:none;background-image:radial-gradient(circle,var(--grid-dot) 1px,transparent 1px);background-size:24px 24px;background-position:0 0}#dsh-plan .p-world{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;transform-origin:0 0}#dsh-plan .p-layer{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}#dsh-plan .p-edges{position:absolute;overflow:visible;width:100%;height:100%;pointer-events:none}#dsh-plan .p-frame{pointer-events:none}#dsh-plan .p-frame-head,#dsh-plan .p-node{pointer-events:auto}#dsh-plan .e-member{stroke:var(--uupm-edge-member);stroke-opacity:.38;stroke-width:1.5}#dsh-plan .e-member.dashed{stroke-dasharray:3 4}#dsh-plan .p-frame{--frame-ink:var(--frame-line,#8B5CF6)}@media (prefers-color-scheme: light){#dsh-plan .p-frame{--frame-ink:color-mix(in srgb,var(--frame-line,#8B5CF6) 72%,black)}}#dsh-plan .p-frame{position:absolute;border:1px solid var(--frame-ink);border-radius:10px;background:var(--frame-bg,var(--uupm-wash-5));min-width:120px;min-height:60px}#dsh-plan .p-frame-head{position:absolute;top:-13px;left:50%;transform:translate(-50%);height:24px;padding:0 10px;border-radius:6px;display:flex;gap:8px;align-items:center;background:var(--uupm-bg-2);border:1px solid var(--frame-ink);font-size:12px;font-weight:600;letter-spacing:.02em;white-space:nowrap;cursor:grab}#dsh-plan .p-frame-head:active{cursor:grabbing}#dsh-plan .p-frame-head:hover{border-color:var(--card-line-hover)}#dsh-plan .p-frame-head .cnt{color:var(--ink-muted);font-weight:400}#dsh-plan .p-frame-head .route{font-size:10.5px;color:var(--ink-muted)}#dsh-plan .p-frame.is-mirror{border-style:dashed}#dsh-plan .p-frame.is-roster{border-style:double;border-width:3px}#dsh-plan .p-frame.is-roster .p-frame-head{border-style:dashed}#dsh-plan .p-frame.is-syncing .p-frame-head .route{color:var(--accent)}#dsh-plan .p-frame.is-unreachable{opacity:.76;border-style:dashed}#dsh-plan .p-frame-unreachable{position:absolute;left:8px;top:20px;max-width:calc(100% - 16px);color:var(--uupm-error);font-size:11px;pointer-events:none}#dsh-plan .p-node.remote.is-unreachable{opacity:.72;border-left-color:var(--uupm-error)}#dsh-plan .p-node.remote.is-unreachable .sub{color:var(--uupm-error)}#dsh-plan .p-node{position:absolute;width:172px;height:56px;padding:8px 26px 8px 14px;background:var(--card-bg);border:1px solid var(--card-line);border-left:3px solid var(--edge-live);border-radius:8px;cursor:grab;-webkit-user-select:none;user-select:none;transition:border-color .12s cubic-bezier(.2,0,0,1),transform .12s cubic-bezier(.2,0,0,1)}#dsh-plan .p-node:hover{border-color:var(--card-line-hover)}#dsh-plan .p-node:active{cursor:grabbing}#dsh-plan .p-node:focus-visible{outline:2px solid var(--accent);outline-offset:2px}#dsh-plan .p-node.selected{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-node.dragging{transform:scale(1.02);border-color:var(--accent)}#dsh-plan .p-node.cold{border-left-color:var(--edge-cold)}#dsh-plan .p-node .nm{font-weight:600;display:flex;align-items:center;gap:7px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#dsh-plan .p-node .nm-text{min-width:0;overflow:hidden;white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.25}#dsh-plan .p-node.remote .nm-text{overflow-wrap:anywhere}#dsh-plan .p-node .dot{width:8px;height:8px;border-radius:50%;background:var(--edge-live);flex:none}#dsh-plan .p-node.cold .dot{background:transparent;border:1.5px solid var(--edge-cold)}#dsh-plan .p-node .sub-row{display:flex;align-items:baseline;gap:6px;margin-top:2px;min-width:0}#dsh-plan .p-node .sub-row .sub{flex:1 1 auto;min-width:0;margin-top:0}#dsh-plan .p-node .work{flex:none;font-size:10.5px;font-weight:500;color:var(--ink-muted);white-space:nowrap}#dsh-plan .p-node .work:empty{display:none}#dsh-plan .p-node.is-working .work{color:var(--edge-live)}#dsh-plan .p-node.is-working .dot{animation:p-working 1.4s ease-in-out infinite}@keyframes p-working{0%,to{box-shadow:0 0 color-mix(in srgb,var(--edge-live) 55%,transparent)}50%{box-shadow:0 0 0 4px transparent}}@media (prefers-reduced-motion: reduce){#dsh-plan .p-node.is-working .dot{animation:none}}#dsh-plan .p-node .sub{font-size:11px;color:var(--ink-muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#dsh-plan .p-node.pulse{box-shadow:0 0 0 2px var(--accent),0 0 14px 4px var(--uupm-wash-15);border-color:var(--accent)}#dsh-plan .p-search{position:relative}#dsh-plan .p-search-input{width:170px;min-height:28px;padding:2px 8px;font-size:12px;background:transparent;color:var(--ink);border:1px solid var(--card-line);border-radius:6px}#dsh-plan .p-search-input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-search-list{position:absolute;top:100%;left:0;margin-top:4px;display:none;min-width:240px;max-height:220px;overflow:auto;z-index:9;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:6px}#dsh-plan .p-search-hit{padding:5px 10px;font-size:12px;color:var(--ink);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#dsh-plan .p-search-hit:hover,#dsh-plan .p-search-hit.active{background:var(--uupm-wash-15)}#dsh-plan .p-node .prio{position:absolute;top:6px;right:8px;font-size:10px;color:var(--ink-muted);border:1px solid var(--card-line);border-radius:4px;padding:0 5px}#dsh-plan .p-marquee{position:absolute;z-index:2;display:none;pointer-events:none;border:1px solid var(--accent);background:var(--uupm-wash-8)}#dsh-plan .p-toolbar{position:absolute;top:16px;left:16px;z-index:3;display:flex;gap:6px;align-items:center;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;padding:6px 8px}#dsh-plan .p-tabs{position:absolute;top:16px;left:50%;transform:translate(-50%);z-index:3;display:flex;gap:4px;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;padding:4px}#dsh-plan .p-tabs [role=tab]{background:transparent;color:var(--ink-muted);border:1px solid transparent;border-radius:6px;padding:4px 12px;font:inherit;cursor:pointer}#dsh-plan .p-tabs [role=tab]:hover{color:var(--ink);border-color:var(--card-line)}#dsh-plan .p-tabs [role=tab][aria-selected=true]{color:var(--ink);border-color:var(--accent);background:var(--uupm-wash-12)}#dsh-plan .p-tabs [role=tab]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-toolbar button{background:transparent;color:var(--ink);border:1px solid var(--card-line);border-radius:6px;padding:4px 10px;font:inherit;cursor:pointer;white-space:nowrap}#dsh-plan .p-toolbar button:hover{border-color:var(--accent)}#dsh-plan .p-toolbar button:active{background:var(--uupm-wash-15)}#dsh-plan .p-toolbar button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-zoom{min-width:44px;text-align:center;font-size:11px;color:var(--ink-muted)}#dsh-plan .p-sep{align-self:stretch;width:1px;margin:2px 4px;background:var(--card-line)}#dsh-plan .p-lamp{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--ink-muted);padding:0 6px}#dsh-plan .p-lamp i{width:7px;height:7px;border-radius:50%;background:var(--ink-muted);transition:background .14s ease}#dsh-plan .p-lamp.saved i{background:var(--edge-live)}#dsh-plan .p-lamp.pending i{background:var(--uupm-warn)}#dsh-plan .p-lamp.error{color:var(--uupm-error);cursor:pointer}#dsh-plan .p-lamp.error i{background:var(--uupm-error)}#dsh-plan .p-lamp.error:hover{border:1px solid var(--uupm-error);border-radius:4px}#dsh-plan .p-status{position:absolute;top:16px;right:16px;z-index:3;display:flex;gap:14px;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;padding:8px 14px;font-size:12px}#dsh-plan .p-status b{font-weight:600}#dsh-plan .ok{color:var(--edge-live)}#dsh-plan .warn{color:var(--uupm-warn)}#dsh-plan .mut{color:var(--ink-muted)}#dsh-plan .p-legend{position:absolute;bottom:16px;left:16px;z-index:3;font-size:11px;color:var(--ink-muted);background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;padding:4px 10px}#dsh-plan .p-legend summary{cursor:pointer;padding:2px 0;-webkit-user-select:none;user-select:none}#dsh-plan .p-legend summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}#dsh-plan .p-legend[open]{padding-bottom:8px}#dsh-plan .p-legend-rows{display:grid;gap:4px;margin-top:4px}#dsh-plan .p-legend i{display:inline-block;width:18px;border-top:2px solid var(--uupm-edge-member);vertical-align:middle;margin-right:6px}#dsh-plan .p-legend i.dashed{border-top-style:dashed}@media (max-width:680px){#dsh-plan .p-toolbar{position:relative;top:auto;left:auto;margin:8px 8px 0;flex-wrap:wrap;row-gap:6px}#dsh-plan .p-toolbar>*{flex:none}#dsh-plan .p-toolbar .p-search{order:-1;flex:1 1 100%}#dsh-plan .p-toolbar .p-sep{display:none}#dsh-plan .p-toolbar .p-search-input{width:100%;box-sizing:border-box}#dsh-plan .p-status{position:relative;top:auto;right:auto;left:auto;width:fit-content;margin:6px 8px 0;padding:6px 10px;gap:10px;flex-wrap:wrap}#dsh-plan .p-legend{display:none}}@media (pointer:coarse){#dsh-plan .p-toolbar button{min-height:36px;min-width:36px}}@media (prefers-reduced-motion: reduce){#dsh-plan *{transition:none!important;animation:none!important}}#dsh-plan .p-frame.drop-target{border-color:var(--accent);border-width:2px;background:var(--uupm-wash-12)}#dsh-plan .p-frame-head:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-node.remote{border-left-color:var(--federal);padding-right:46px}#dsh-plan .p-node.remote .dot{background:var(--federal)}#dsh-plan .p-node.remote .prio{color:var(--ink)}#dsh-plan .p-node .prio.lnk-linked{color:var(--live, #2e9e5b);border-color:var(--live, #2e9e5b)}#dsh-plan .p-node .prio.lnk-stranger{color:var(--ink-muted);border-color:var(--card-line)}#dsh-plan .e-activity{stroke:var(--accent);stroke-width:2;stroke-dasharray:8 6;stroke-opacity:.9}#dsh-plan .e-federal{stroke:var(--federal);stroke-width:1.5;stroke-dasharray:6 5;stroke-opacity:.5}#dsh-plan .edge-label{font-size:10.5px;fill:var(--ink-muted)}@media (prefers-reduced-motion: no-preference){#dsh-plan .e-activity{animation:p-activity-flow 1.1s linear infinite}}@keyframes p-activity-flow{to{stroke-dashoffset:-28}}#dsh-plan .p-status{cursor:pointer}#dsh-plan .p-status:hover{border-color:var(--accent)}#dsh-plan .p-status:active{background:var(--uupm-wash-12)}#dsh-plan .p-status:focus-visible{outline:2px solid var(--accent);outline-offset:2px}#dsh-plan .p-menu{position:fixed;z-index:5;min-width:170px;display:grid;padding:4px;gap:2px;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px}#dsh-plan .p-menu [role=menuitem]{background:transparent;color:var(--ink);border:1px solid transparent;border-radius:6px;padding:6px 10px;font:inherit;text-align:left;cursor:pointer;white-space:nowrap}#dsh-plan .p-menu [role=menuitem]:hover{border-color:var(--card-line);background:var(--uupm-wash-8)}#dsh-plan .p-menu [role=menuitem]:active{background:var(--uupm-wash-18)}#dsh-plan .p-menu [role=menuitem]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-menu [role=menuitem][aria-disabled=true]{color:var(--ink-muted);cursor:not-allowed}#dsh-plan .p-dialog{position:absolute;top:0;right:0;bottom:0;left:0;z-index:6;display:grid;place-items:center;background:var(--scrim)}#dsh-plan .p-dialog-panel{min-width:300px;padding:14px 16px;display:grid;gap:10px;background:var(--uupm-bg-2);border:1px solid var(--card-line);border-radius:10px}#dsh-plan .p-dialog-title{font-weight:600;font-size:12.5px;color:var(--ink)}#dsh-plan .p-dialog-input{font:inherit;color:var(--ink);background:var(--uupm-bg-0);border:1px solid var(--card-line);border-radius:6px;padding:7px 10px}#dsh-plan .p-dialog-input:hover{border-color:color-mix(in srgb,var(--uupm-ink-1) 55%,transparent)}#dsh-plan .p-dialog-input:focus-visible{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}#dsh-plan .p-dialog-err{min-height:1.2em;font-size:11px;color:var(--uupm-error)}#dsh-plan .p-dialog-kind{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:3px;background:var(--uupm-bg-0);border:1px solid var(--card-line);border-radius:8px}#dsh-plan .p-dialog-kind button{font:inherit;color:var(--ink-muted);background:transparent;border:1px solid transparent;border-radius:6px;padding:6px 10px;cursor:pointer}#dsh-plan .p-dialog-kind button:hover{color:var(--ink);background:var(--uupm-wash-8)}#dsh-plan .p-dialog-kind button[aria-checked=true]{color:var(--ink);font-weight:600;background:var(--uupm-wash-15);border-color:var(--accent)}#dsh-plan .p-dialog-kind button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-dialog-hint{font-size:11px;color:var(--ink-muted);max-width:340px}#dsh-plan .p-dialog-row{display:flex;gap:8px;justify-content:flex-end}#dsh-plan .p-dialog-row button{background:transparent;color:var(--ink);border:1px solid var(--card-line);border-radius:6px;padding:5px 12px;font:inherit;cursor:pointer}#dsh-plan .p-dialog-row button:hover{border-color:var(--accent)}#dsh-plan .p-dialog-row button:active{background:var(--uupm-wash-15)}#dsh-plan .p-dialog-row button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-notice-stack{position:absolute;bottom:52px;left:50%;transform:translate(-50%);z-index:5;display:grid;gap:6px;justify-items:center;pointer-events:none}#dsh-plan .p-notice{max-width:60ch;padding:7px 12px;font-size:12px;color:var(--ink);background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#dsh-plan .p-notice.error{color:var(--error-ink);border-color:var(--uupm-error);background:var(--error-panel)}#dsh-plan .p-netbtn{color:var(--ink-muted)}#dsh-plan .p-netbtn:not([disabled]){color:var(--ink)}#dsh-plan .p-netmenu{max-height:240px;overflow:auto}#dsh-plan .p-nodebtn{color:var(--ink)}#dsh-plan .p-nodelist{min-width:300px;max-width:340px;max-height:420px;overflow:auto;padding:6px}#dsh-plan .p-nodelist-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:2px 4px 6px;border-bottom:1px solid var(--card-line)}#dsh-plan .p-nodelist-title{font-size:12px;font-weight:600;color:var(--ink)}#dsh-plan .p-nodesel{font:inherit;font-size:11.5px;color:var(--ink);background:var(--uupm-bg-0);border:1px solid var(--card-line);border-radius:6px;padding:2px 6px;max-width:220px}#dsh-plan .p-nodesel:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-nodelist-group{font-size:11px;color:var(--ink-muted);padding:8px 4px 3px;display:flex;align-items:baseline;gap:8px}#dsh-plan .p-nodelist-note{font-size:10px;color:var(--ink-muted);opacity:.8}#dsh-plan .p-noderow{display:flex;align-items:center;gap:6px;padding:3px 4px;border-radius:6px;font-size:12px;color:var(--ink)}#dsh-plan .p-noderow:hover{background:var(--uupm-wash-8)}#dsh-plan .p-nodedot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--edge-live)}#dsh-plan .p-nodedot.cold{background:var(--ink-muted)}#dsh-plan .p-nodedot.off{background:transparent;border:1px solid var(--ink-muted)}#dsh-plan .p-nodename{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#dsh-plan .p-nonet{flex:none;font-size:10px;color:var(--uupm-warn);border:1px solid var(--uupm-warn);border-radius:4px;padding:0 4px}#dsh-plan .p-teamcount{flex:none;font-size:10px;color:var(--ink-muted);border:1px solid var(--card-line);border-radius:4px;padding:0 4px}#dsh-plan .p-listbtn{flex:none;background:transparent;color:var(--ink);border:1px solid var(--card-line);border-radius:5px;padding:1px 7px;font:inherit;font-size:11px;cursor:pointer}#dsh-plan .p-listbtn:hover{border-color:var(--card-line-hover);background:var(--uupm-wash-8)}#dsh-plan .p-listbtn:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-nodelist-empty{padding:10px 4px;font-size:11.5px;color:var(--ink-muted)}#dsh-plan .p-frame{position:absolute}#dsh-plan .p-frame-handle{position:absolute;pointer-events:auto;width:10px;height:10px;z-index:2;opacity:0;transition:opacity .12s ease}#dsh-plan .p-frame:hover .p-frame-handle{opacity:1}#dsh-plan .p-frame-handle:after{content:"";position:absolute;top:2px;right:2px;bottom:2px;left:2px;background:var(--frame-ink);border-radius:2px}#dsh-plan .p-h-n{top:-5px;left:calc(50% - 12px);width:24px;height:8px;cursor:ns-resize}#dsh-plan .p-h-s{bottom:-5px;left:calc(50% - 12px);width:24px;height:8px;cursor:ns-resize}#dsh-plan .p-h-e{right:-5px;top:calc(50% - 12px);width:8px;height:24px;cursor:ew-resize}#dsh-plan .p-h-w{left:-5px;top:calc(50% - 12px);width:8px;height:24px;cursor:ew-resize}#dsh-plan .p-h-ne{top:-5px;right:-5px;cursor:nesw-resize}#dsh-plan .p-h-nw{top:-5px;left:-5px;cursor:nwse-resize}#dsh-plan .p-h-se{bottom:-5px;right:-5px;cursor:nwse-resize}#dsh-plan .p-h-sw{bottom:-5px;left:-5px;cursor:nesw-resize}#dsh-plan .p-h-ne:after,#dsh-plan .p-h-sw:after{transform:rotate(45deg)}#dsh-plan .p-h-nw:after,#dsh-plan .p-h-se:after{transform:rotate(-45deg)}#dsh-plan .p-frame.selected .p-frame-handle{opacity:1}#dsh-plan .p-frame.selected{outline:1px solid var(--frame-ink)}:root{color-scheme:dark;--n-bg:#060a12;--n-ink:#dde3f0;--n-ink-muted:#7a86a0;--n-panel:#0d1322;--n-live:#4ade80;--n-cold:#7a86a0;--n-border:#223052;--n-act:#f59e0b;--n-danger:#f87171;--n-accent:#9673f7;--n-rail-w:300px;--n-canvas:#22d3ee;--n-line:var(--n-border);--n-raised:#131b2e;--n-federal:#6366f1;--n-card-line:#5c6680;--n-error-ink:#fecaca;--n-error-panel:#2a0d10f2;--n-shadow:rgba(0,0,0,.35)}@media (prefers-color-scheme: light){:root{--n-bg:#eef2fa;--n-ink:#1a2438;--n-ink-muted:#5a6580;--n-panel:#ffffff;--n-live:#157a37;--n-border:#c6d0e6;--n-act:#a84d08;--n-danger:#b91c1c;--n-accent:#6d28d9;--n-cold:#636c81;--n-canvas:#0e7490;--n-raised:#ffffff;--n-federal:#4f46e5;--n-card-line:#8a95ae;--n-error-ink:#b91c1c;--n-error-panel:#fef2f2f2;--n-shadow:rgba(26,36,56,.16)}}@media (min-width:1440px){:root{--n-rail-w:340px }}html,body,#app{height:100%;margin:0}body{background:var(--n-bg);color:var(--n-ink);font:13px/1.45 system-ui,Segoe UI,Roboto,PingFang SC,Microsoft YaHei,sans-serif}.wb{display:flex;flex-direction:column;height:100%}.wb-header{display:flex;align-items:center;gap:12px;padding:8px 14px;border-bottom:1px solid var(--n-border);background:var(--n-panel)}.wb-title{display:flex;align-items:center;gap:10px;font-weight:600;font-size:14px;white-space:nowrap}.wb-badge{font-size:11px;font-weight:400;color:var(--n-ink-muted);border:1px solid var(--n-border);border-radius:99px;padding:1px 8px}.wb-badge[hidden]{display:none}.wb-row-remote{margin-left:6px;padding:0 6px;border:1px solid currentColor;border-radius:99px;font-size:10.5px;color:var(--n-ink-muted);vertical-align:1px}.wb-header-stats{display:flex;gap:16px;font-size:12px;color:var(--n-ink-muted);flex-wrap:wrap;min-width:0}.wb-header-stats .wb-kv{display:flex;gap:6px}.wb-header-stats .wb-kv-k{color:var(--n-ink-muted)}.wb-header-stats .wb-kv-v{color:var(--n-ink)}.wb-header-ok{color:var(--n-ink-muted)}.wb-alert{border:1px solid currentColor;border-radius:99px;padding:0 9px;line-height:20px;white-space:nowrap;cursor:pointer;background:transparent;font:inherit}.wb-alert:hover{background:color-mix(in srgb,currentColor 12%,transparent)}.wb-alert:focus-visible{outline:2px solid currentColor;outline-offset:2px}.wb-alert-danger{color:var(--n-danger)}.wb-alert-warn{color:var(--n-act)}.wb-forensics{font-family:ui-monospace,Consolas,monospace;font-size:11px}.wb-icon-btn{background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:8px;width:30px;height:30px;display:none;align-items:center;justify-content:center;font:inherit;font-size:14px;cursor:pointer;flex:none}.wb-icon-btn:hover{border-color:var(--n-accent)}.wb-menu{margin-left:0}.wb-rail-toggle{margin-left:auto}.wb.is-rail-collapsed .wb-rail{display:none}.wb-body{position:relative;display:grid;grid-template-columns:minmax(0,var(--n-rail-w)) minmax(0,1fr);flex:1;min-height:0}.wb-rail{border-right:1px solid var(--n-border);min-width:0;min-height:0;display:flex;flex-direction:column;overflow:hidden;background:color-mix(in srgb,var(--n-panel) 60%,var(--n-bg))}.wb-side-head{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--n-ink-muted);margin:10px 2px 4px}.wb-item{display:flex;gap:7px;align-items:center;width:100%;text-align:left;background:none;border:none;color:var(--n-ink);font:inherit;padding:3px 6px;border-radius:6px;cursor:pointer}.wb-item:hover{background:color-mix(in srgb,var(--n-accent) 14%,transparent)}.wb-dot{font-size:10px}.wb-dot-live{color:var(--n-live)}.wb-dot-cold{color:var(--n-cold)}.wb-dot-canvas{color:var(--n-canvas)}.wb-dot-remote{color:var(--n-act)}.wb-dir-tools{display:flex;flex-direction:column;gap:6px;padding:8px 6px 4px}.wb-search{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:4px 8px;font:inherit;font-size:12.5px;min-width:0}.wb-search:focus{outline:1px solid var(--n-accent)}.wb-filters{display:flex;flex-wrap:wrap;gap:4px}.wb-filter{background:none;border:1px solid var(--n-border);color:var(--n-ink-muted);border-radius:99px;padding:0 10px;min-height:24px;font:inherit;font-size:11.5px;cursor:pointer}.wb-filter:hover{border-color:var(--n-accent);color:var(--n-ink)}.wb-filter.is-active{border-color:var(--n-accent);color:var(--n-ink);background:color-mix(in srgb,var(--n-accent) 16%,transparent)}.wb-item-badge{flex:none;font-size:10.5px;color:var(--n-canvas);border:1px solid color-mix(in srgb,var(--n-canvas) 45%,transparent);border-radius:99px;padding:0 6px;line-height:17px;white-space:nowrap}.wb-item-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-member-row{display:flex;align-items:center;gap:8px;padding:3px 2px;border-radius:6px}.wb-member-row:hover{background:color-mix(in srgb,var(--n-accent) 10%,transparent)}.wb-member-dot{flex:none;font-size:11px;color:var(--n-ink-muted);min-width:44px}.wb-member-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-member-remove,.wb-member-submit{background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:1px 8px;font:inherit;font-size:11.5px;cursor:pointer;flex:none}.wb-member-remove:hover:not(:disabled),.wb-member-submit:hover:not(:disabled){border-color:var(--n-danger)}.wb-member-submit:hover:not(:disabled){border-color:var(--n-accent)}.wb-member-add{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.wb-cli-home{display:flex;flex-wrap:wrap;gap:6px;padding:8px;margin:4px 0 10px;border:1px solid var(--n-border);border-radius:6px}.wb-cli-home [hidden]{display:none}.wb-cli-home .wb-hint{flex-basis:100%;margin-top:0}.wb-cli-home .wb-member-pick{min-width:0;max-width:100%}.wb-member-pick,.wb-member-manual{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:3px 8px;font:inherit;font-size:12px;min-width:0}.wb-member-pick{flex:1 1 150px}.wb-member-manual{flex:1 1 130px}.wb-member-pick:focus,.wb-member-manual:focus{outline:1px solid var(--n-accent)}.wb-hint{margin-top:10px;font-size:11px;color:var(--n-ink-muted);line-height:1.5}.wb-dispatch{margin-top:12px;border-top:1px dashed var(--n-border);padding-top:8px}.wb-dispatch-form{display:flex;flex-direction:column;gap:6px;margin-top:6px}.wb-dispatch-text{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:5px 8px;font:inherit;font-size:12px;min-height:52px;resize:vertical}.wb-dispatch-text:focus{outline:1px solid var(--n-accent)}.wb-dispatch-submit{align-self:flex-end;background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:2px 14px;font:inherit;font-size:11.5px;cursor:pointer}.wb-dispatch-submit:hover:not(:disabled){border-color:var(--n-accent)}.wb-dispatch-note{font-size:11px;color:var(--n-ink-muted);line-height:1.4;min-height:0}.wb-stage{position:relative;min-width:0;min-height:0;display:flex;flex-direction:column}.wb-stage-board{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden}.wb-stage-board.is-hidden{display:none}.wb-data{display:flex;flex-direction:column;gap:14px;padding:10px 14px;overflow-y:auto;min-height:0}.wb-data.is-hidden{display:none}.wb-pane-head{font-size:12px;color:var(--n-ink-muted);margin:4px 0 8px}.wb-pane-subhead{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--n-ink-muted);margin:12px 0 6px}.wb-table,.wb-row{display:flex;gap:10px;align-items:baseline}.wb-row{font-family:ui-monospace,Consolas,monospace;font-size:12px;background:color-mix(in srgb,var(--n-panel) 55%,transparent);border:1px solid var(--n-border);border-radius:6px;padding:3px 8px;flex-wrap:wrap}.wb-row-team{color:var(--n-accent);min-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-row-meta{color:var(--n-ink-muted)}.wb-row-badges{color:var(--n-live)}.wb-row-dir{min-width:16px}.wb-row-dir.is-fail{color:var(--n-danger)}.wb-btn{background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:2px 10px;font:inherit;font-size:12px;cursor:pointer;margin-left:auto}.wb-btn:hover:not(:disabled){border-color:var(--n-accent)}.wb-btn:disabled{opacity:.5;cursor:default}.wb-btn-primary{border-color:var(--n-accent);color:var(--n-ink)}.wb-action{display:flex;gap:10px;align-items:baseline;font-size:12.5px;padding:5px 8px;border-radius:6px;border:1px solid var(--n-border);margin-bottom:4px}.wb-action-high{border-color:var(--n-danger)}.wb-action-text{flex:1}.wb-draft{display:flex;flex-direction:column;gap:8px;max-width:560px;margin-top:6px}.wb-select,.wb-textarea{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);border-radius:8px;padding:6px 9px;font:inherit}.wb-textarea{resize:vertical}.wb-select:focus,.wb-textarea:focus{outline:1px solid var(--n-accent)}.wb-inspector{position:absolute;top:8px;right:8px;width:280px;max-height:calc(100% - 16px);overflow-y:auto;background:var(--n-panel);border:1px solid var(--n-border);border-radius:10px;padding:10px;z-index:20;box-shadow:0 8px 24px var(--n-shadow);display:none}.wb-inspector.is-open{display:block}.wb-inspector-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px}.wb-inspector-title{font-weight:600;font-size:12.5px}.wb-inspector .wb-icon-btn{display:inline-flex;width:24px;height:24px;font-size:12px}.wb-card{display:flex;flex-direction:column;gap:6px}.wb-kv{display:flex;gap:8px;font-size:12px}.wb-kv-k{color:var(--n-ink-muted);min-width:58px;flex:none}.wb-kv-v{word-break:break-all}.wb-muted{color:var(--n-ink-muted)}.wb-chat{position:absolute;top:8px;right:8px;bottom:8px;width:400px;max-width:calc(100% - 16px);display:flex;flex-direction:column;background:var(--n-panel);border:1px solid var(--n-border);border-radius:12px;z-index:22;box-shadow:0 8px 24px var(--n-shadow);overflow:hidden;transform:translate(calc(100% + 12px));transition:transform .18s ease;pointer-events:none}.wb-chat.is-open{transform:translate(0);pointer-events:auto}.wb-chat-head{display:flex;align-items:center;gap:8px;padding:10px 10px 10px 12px;border-bottom:1px solid var(--n-border);flex:none}.wb-chat-dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--n-ink-muted)}.wb-chat-dot.is-live{background:var(--n-live)}.wb-chat-dot.is-cold{background:transparent;border:1.5px solid var(--n-ink-muted)}.wb-chat-dot.is-peer{background:var(--n-federal)}.wb-chat-titles{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;line-height:1.3}.wb-chat-title{font-weight:600;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-chat-sub{font:11px/1.4 ui-monospace,Consolas,monospace;color:var(--n-ink-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-chat .wb-icon-btn{display:inline-flex;width:28px;height:28px;font-size:13px;flex:none;border-color:transparent}.wb-chat .wb-icon-btn:hover{border-color:var(--n-border)}.wb-chat .wb-icon-btn:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-chat .wb-chat-back[hidden]{display:none}.wb-chat-info-btn[aria-expanded=true]{border-color:var(--n-accent);color:var(--n-accent)}.wb-chat-info{flex:none;display:flex;flex-direction:column;gap:4px;padding:8px 12px;font-size:12px;border-bottom:1px solid var(--n-border);background:color-mix(in srgb,var(--n-bg) 55%,var(--n-panel))}.wb-chat-info[hidden]{display:none}.wb-chat-info .wb-kv-v{font-family:ui-monospace,Consolas,monospace;font-size:11.5px}.wb-chat-thread{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;gap:10px;padding:12px}.wb-chat-thread:focus-visible{outline:2px solid var(--n-accent);outline-offset:-2px}.wb-chat-log,.wb-chat-sent{display:flex;flex-direction:column;gap:10px}.wb-chat-notice{align-self:center;max-width:92%;text-align:center;font-size:11.5px;line-height:1.5;color:var(--n-ink-muted);border:1px dashed var(--n-border);border-radius:8px;padding:6px 10px}.wb-chat-notice[hidden]{display:none}.wb-chat-empty{align-self:center;padding:24px 8px;font-size:12px;color:var(--n-ink-muted);text-align:center}.wb-chat-empty.is-error{color:var(--n-danger)}.wb-msg{display:flex;flex-direction:column;gap:4px;max-width:86%;padding:8px 11px;border-radius:12px;font-size:13px;line-height:1.55}.wb-msg-assistant{align-self:flex-start;background:var(--n-raised);border:1px solid var(--n-border);border-bottom-left-radius:4px}.wb-msg-user{align-self:flex-end;background:color-mix(in srgb,var(--n-accent) 16%,var(--n-panel));border:1px solid color-mix(in srgb,var(--n-accent) 35%,transparent);border-bottom-right-radius:4px}.wb-msg-ledger{align-self:center;max-width:92%;background:transparent;border:1px dashed var(--n-border);font-size:12px}.wb-msg-ledger .wb-msg-text{color:var(--n-ink-muted)}.wb-msg-ledger .wb-msg-meta{justify-content:center}.wb-msg-in .wb-msg-meta{justify-content:flex-start}.wb-msg-who{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.wb-msg-text{color:var(--n-ink);white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.wb-msg-meta{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:6px;font-size:11px}.wb-msg-task{font-family:ui-monospace,Consolas,monospace;color:var(--n-ink-muted)}.wb-msg-status{border:1px solid currentColor;border-radius:99px;padding:0 7px;line-height:18px;white-space:nowrap}.wb-msg-status.is-wait,.wb-msg-status.is-muted{color:var(--n-ink-muted)}.wb-msg-status.is-ok{color:var(--n-live)}.wb-msg-status.is-warn{color:var(--n-act)}.wb-msg-status.is-danger{color:var(--n-danger)}.wb-chat-divider{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--n-ink-muted);margin-top:4px}.wb-chat-divider:before,.wb-chat-divider:after{content:"";flex:1;border-top:1px solid var(--n-border)}.wb-chat-sessions{display:flex;flex-direction:column;gap:6px}.wb-chat-session{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;text-align:left;background:var(--n-raised);border:1px solid var(--n-border);border-radius:8px;padding:7px 10px;color:var(--n-ink);font:inherit;cursor:pointer}.wb-chat-session:hover{border-color:var(--n-accent)}.wb-chat-session:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-chat-session-id{font:12px ui-monospace,Consolas,monospace}.wb-chat-session-meta{font-size:11px;color:var(--n-ink-muted)}.wb-chat-foot{flex:none;border-top:1px solid var(--n-border);padding:8px 10px 10px;background:var(--n-panel)}.wb-chat-composer{display:flex;flex-direction:column;gap:4px}.wb-chat-composer-row{display:flex;align-items:flex-end;gap:8px}.wb-chat-composer .wb-dispatch-text{flex:1 1 auto;min-height:38px;max-height:160px;resize:none;border-radius:10px;padding:8px 10px;font-size:13px;line-height:1.5}.wb-chat-composer .wb-dispatch-submit{align-self:auto;height:38px;padding:0 16px;border-radius:10px;background:var(--n-accent);border-color:var(--n-accent);color:var(--n-bg);font-size:13px;font-weight:600}.wb-chat-composer .wb-dispatch-submit:hover:not(:disabled){border-color:var(--n-accent);filter:brightness(1.08)}.wb-chat-composer .wb-dispatch-submit:disabled{opacity:.45;cursor:default}.wb-chat-composer .wb-dispatch-note{font-size:11px;padding-left:2px}.wb-chat-composer .wb-dispatch-note.is-error{color:var(--n-danger)}.wb-chat-readonly{font-size:12px;color:var(--n-ink-muted);text-align:center;padding:4px 0}.nexus-fault{display:none;position:fixed;top:10px;right:12px;z-index:50;max-width:420px;font:12px/1.5 ui-monospace,Consolas,monospace;color:var(--n-error-ink);background:var(--n-error-panel);border:1px solid var(--n-danger);border-radius:8px;padding:6px 10px;pointer-events:none}@media (max-width:1023px){.wb-menu{display:inline-flex}.wb-rail-toggle{display:none}.wb-body{grid-template-columns:minmax(0,1fr)}.wb-rail{position:fixed;left:0;top:0;bottom:0;width:min(86vw,320px);z-index:40;background:var(--n-panel);border-right:1px solid var(--n-border);transform:translate(-102%);transition:transform .18s ease;box-shadow:8px 0 24px var(--n-shadow)}.wb.is-rail-open .wb-rail{transform:translate(0)}.wb-inspector{left:8px;right:8px;width:auto;top:auto;bottom:8px;max-height:45%}.wb-chat{left:8px;right:8px;width:auto;top:auto;bottom:8px;height:85%;max-height:85%;transform:translateY(102%)}.wb-chat.is-open{transform:translateY(0)}}@media (pointer:coarse){.wb-filter,.wb-item,.wb-tab{min-height:36px}.wb-icon-btn,.wb-inspector .wb-icon-btn,.wb-chat .wb-icon-btn{width:36px;height:36px}}@media (max-width:680px){.wb-header{flex-wrap:wrap;row-gap:4px}.wb-header-stats{order:3;width:100%}.wb-row-team{min-width:0;flex:1 1 auto}.wb-data{padding:8px}}.wb-host-row{display:flex;align-items:center;gap:7px;padding:4px 6px;border:1px solid var(--n-border);border-radius:7px;margin-bottom:4px;cursor:pointer;font-size:12px}.wb-host-row:hover{border-color:var(--n-accent);background:color-mix(in srgb,var(--n-accent) 8%,transparent)}.wb-host-row:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-host-lamp{flex:none;width:8px;height:8px;border-radius:50%;background:var(--n-ink-muted)}.wb-host-lamp.is-live{background:var(--n-live)}.wb-host-lamp.is-warm{background:var(--n-act)}.wb-host-lamp.is-cold{background:var(--n-ink-muted)}.wb-host-lamp.is-fail{background:var(--n-danger)}.wb-host-lamp.is-unknown{background:transparent;border:1px solid var(--n-ink-muted)}.wb-host-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--n-ink)}.wb-host-badge{flex:none;font-size:10.5px;border-radius:99px;padding:0 7px;line-height:17px;border:1px solid var(--n-border)}.wb-host-badge.is-linked{color:var(--n-live);border-color:var(--n-live)}.wb-host-badge.is-stranger{color:var(--n-ink-muted);border-color:var(--n-border)}.wb-host-ver{flex:none;font-size:10px;color:var(--n-ink-muted);border:1px solid var(--n-border);border-radius:4px;padding:0 4px}.wb-host-url{flex:none;max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--n-ink-muted);font-size:10.5px}.wb-tabs{flex:none;display:flex;gap:2px;padding:6px 6px 0;border-bottom:1px solid var(--n-border);overflow-x:auto;scrollbar-width:none}.wb-tab{flex:1 1 auto;display:inline-flex;align-items:center;justify-content:center;gap:5px;min-width:0;background:none;border:none;border-bottom:2px solid transparent;color:var(--n-ink-muted);font:inherit;font-size:12.5px;padding:6px 6px 7px;cursor:pointer;white-space:nowrap}.wb-tab:hover{color:var(--n-ink)}.wb-tab.is-active{color:var(--n-ink);border-bottom-color:var(--n-accent);font-weight:600}.wb-tab:focus-visible{outline:2px solid var(--n-accent);outline-offset:-2px;border-radius:6px 6px 0 0}.wb-tab[hidden]{display:none}.wb-tab-badge{font:10.5px/16px ui-monospace,Consolas,monospace;color:var(--n-ink-muted);font-weight:400}.wb-tab-badge:empty{display:none}.wb-tab-badge.is-danger,.wb-tab-badge.is-warn,.wb-tab-badge.is-accent{padding:0 6px;border-radius:99px;border:1px solid currentColor}.wb-tab-badge.is-danger{color:var(--n-danger)}.wb-tab-badge.is-warn{color:var(--n-act)}.wb-tab-badge.is-accent{color:var(--n-accent)}.wb-tabpanels{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}.wb-tabpanel{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:8px 10px 16px}.wb-tabpanel[hidden]{display:none}.wb-tabpanel:focus-visible{outline:2px solid var(--n-accent);outline-offset:-2px}.wb-tabpanel .wb-pane{display:flex;flex-direction:column;gap:8px}.wb-tabpanel .wb-dir-tools{padding:0 0 6px}.wb-dir-group{display:flex;flex-direction:column;gap:1px;margin-top:10px}.wb-dir-group:first-child{margin-top:2px}.wb-dir-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;padding:0 6px 4px;font-size:11px;letter-spacing:.04em;color:var(--n-ink-muted)}.wb-dir-head-label{font-weight:600;color:var(--n-ink)}.wb-dir-head-note{font-size:10.5px}.wb-dir-day{padding:6px 6px 2px;font-size:10.5px;color:var(--n-ink-muted)}.wb-dir-empty{padding:24px 8px;text-align:center;font-size:12px;color:var(--n-ink-muted)}.wb-directory .wb-item{gap:9px;padding:5px 6px;border-radius:8px}.wb-directory .wb-item:focus-visible{outline:2px solid var(--n-accent);outline-offset:-2px}.wb-item-text{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;line-height:1.35}.wb-item-sub{font:11px/1.35 ui-monospace,Consolas,monospace;color:var(--n-ink-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-item.is-untitled .wb-item-label{color:var(--n-ink-muted);font-family:ui-monospace,Consolas,monospace;font-size:12px}.wb-directory .wb-item.is-unreachable{opacity:.78}.wb-unreachable-note,.wb-node-warning{font-size:11px;line-height:1.35;color:var(--n-danger);white-space:normal;overflow-wrap:anywhere}.wb-dot-log{color:var(--n-ink-muted)}.wb-led-tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}.wb-led-tile{display:flex;flex-direction:column;align-items:flex-start;gap:1px;padding:7px 8px;border-radius:8px;border:1px solid var(--n-border);background:var(--n-raised);cursor:help;min-width:0}.wb-led-tile-v{font:600 17px/1.15 ui-monospace,Consolas,monospace;color:var(--n-ink)}.wb-led-tile-k{font-size:11px;color:var(--n-ink-muted)}.wb-led-tile.is-warn{border-color:var(--n-act)}.wb-led-tile.is-warn .wb-led-tile-v{color:var(--n-act)}.wb-led-tile.is-danger{border-color:var(--n-danger)}.wb-led-tile.is-danger .wb-led-tile-v{color:var(--n-danger)}.wb-led-split{display:flex;flex-direction:column;gap:4px}.wb-led-split-bar{display:flex;height:6px;border-radius:99px;overflow:hidden;background:var(--n-border)}.wb-led-seg{display:block;height:100%}.wb-led-split-legend{display:flex;flex-wrap:wrap;gap:4px 10px;font-size:11px;color:var(--n-ink-muted)}.wb-led-split-item{display:inline-flex;align-items:center;gap:4px}.wb-led-swatch{display:inline-block;width:8px;height:8px;border-radius:2px}.wb-led-seg.is-completed,.wb-led-swatch.is-completed{background:var(--n-live)}.wb-led-seg.is-rejected,.wb-led-swatch.is-rejected{background:var(--n-act)}.wb-led-seg.is-failed,.wb-led-swatch.is-failed{background:var(--n-danger)}.wb-led-seg.is-abandoned,.wb-led-swatch.is-abandoned{background:var(--n-ink-muted)}.wb-led-seg.is-unclassified,.wb-led-swatch.is-unclassified,.wb-led-seg.is-other,.wb-led-swatch.is-other{background:color-mix(in srgb,var(--n-ink-muted) 45%,var(--n-border))}.wb-led-group{display:flex;flex-direction:column;gap:6px;margin-top:4px}.wb-led-group-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;font-size:11.5px;font-weight:600;color:var(--n-ink)}.wb-led-group-hint{font-size:10.5px;font-weight:400;color:var(--n-ink-muted)}.wb-led-group.is-danger .wb-led-group-head{color:var(--n-danger)}.wb-led-group.is-warn .wb-led-group-head{color:var(--n-act)}.wb-led-card{position:relative;display:flex;flex-direction:column;gap:3px;padding:7px 9px;border-radius:8px;border:1px solid var(--n-border);background:var(--n-raised);min-width:0}.wb-led-card.is-danger{border-color:var(--n-danger)}.wb-led-card.is-warn{border-left:3px solid var(--n-act)}.wb-led-card.is-muted,.wb-led-card.is-quiet{background:transparent}.wb-led-card.is-link{cursor:pointer}.wb-led-card.is-link:hover{border-color:var(--n-accent)}.wb-led-card.is-link:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-led-card-head{display:flex;align-items:flex-start;gap:6px;min-width:0}.wb-led-dir{flex:none;font-size:12px;color:var(--n-ink-muted);line-height:1.45}.wb-led-dir.is-in{color:var(--n-federal)}.wb-led-brief{flex:1 1 auto;min-width:0;font-size:12.5px;line-height:1.45;color:var(--n-ink);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}.wb-led-card.is-muted .wb-led-brief,.wb-led-card.is-quiet .wb-led-brief{color:var(--n-ink-muted)}.wb-led-card.is-danger .wb-led-brief{color:var(--n-danger)}.wb-led-brief.is-missing{font-style:italic}.wb-led-meta{display:flex;flex-wrap:wrap;gap:2px 8px;font:11px/1.45 ui-monospace,Consolas,monospace;color:var(--n-ink-muted);min-width:0}.wb-led-meta>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.wb-led-chip{border:1px solid var(--n-border);border-radius:99px;padding:0 6px;font-family:inherit}.wb-led-abandon{position:absolute;top:6px;right:6px;margin-left:0;padding:1px 9px;font-size:11.5px}.wb-led-abandon.is-quiet{border-color:transparent;background:transparent;color:var(--n-ink-muted)}.wb-led-abandon.is-quiet:hover{border-color:var(--n-border);color:var(--n-ink)}.wb-led-card:has(.wb-led-abandon) .wb-led-card-head{padding-right:52px}.wb-led-empty{padding:24px 8px;text-align:center;font-size:12px;color:var(--n-ink-muted)}.wb-led-forensics{font-size:11px;color:var(--n-ink-muted);border-top:1px dashed var(--n-border);padding-top:6px;margin-top:4px}.wb-led-forensics summary{cursor:pointer}.wb-led-forensics summary:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-led-forensics-body{display:flex;flex-direction:column;gap:2px;padding:4px 0 0 12px;font-family:ui-monospace,Consolas,monospace}
@@ -18,8 +18,8 @@ html,body{margin:0;height:100%;background:var(--n-bg);color:var(--n-ink);
18
18
  font-family:"Segoe UI",system-ui,sans-serif;}
19
19
  #app{width:100%;height:100%;position:relative}
20
20
  </style>
21
- <script type="module" crossorigin src="./assets/index-D5H8R8de.js"></script>
22
- <link rel="stylesheet" crossorigin href="./assets/index-D9GYZyGZ.css">
21
+ <script type="module" crossorigin src="./assets/index-D2BGWOeU.js"></script>
22
+ <link rel="stylesheet" crossorigin href="./assets/index-z33lHtLw.css">
23
23
  </head>
24
24
  <body>
25
25
  <div id="app"></div>
package/cli/a2a.mjs CHANGED
@@ -39,7 +39,7 @@ const INBOX_CURSOR = join(IDENTITY_DIR, 'inbox.cursor')
39
39
  const DEFAULT_HOME = 'http://127.0.0.1:3080'
40
40
  const DEFAULT_SKILL_ROOTS = [join(homedir(), '.agents', 'skills')]
41
41
 
42
- const USAGE = `a2a-net CLI — aligned with the plugin's ten model tools ('a2a tools' prints the full map)
42
+ const USAGE = `a2a-net CLI — aligned with the plugin's model tools ('a2a tools' prints the full map)
43
43
 
44
44
  usage: a2a <command> [args] [--home URL] [--key <apiKey>] [--json]
45
45
 
@@ -270,10 +270,12 @@ const TOOL_CATALOG = [
270
270
  ['a2a_tasks', '账本三层对账:pending(欠回执)/dead(超期)/archived(已结算)'],
271
271
  ['a2a_probe', '探活整个 tracked fleet 或单 peer:可达性+往返延迟+失败原因'],
272
272
  ['a2a_exposure', '设本会话的网络可见档:linked(下限)/fleet(自愿上调)'],
273
+ ['a2a_file_send', '把文件暂存在本宿主并授权给目标队,只路由一条引用消息(字节不进消息)'],
274
+ ['a2a_file_fetch', '按引用从暂存宿主拉取文件,核对大小与 sha256 后落到 a2a-inbox/'],
273
275
  ]
274
276
 
275
277
  function printAlignment() {
276
- console.log('插件工具面(十枚)与 CLI 对齐:\n')
278
+ console.log('插件工具面与 CLI 对齐:\n')
277
279
  for (const [tool, desc] of TOOL_CATALOG) console.log(` ${tool.padEnd(16)} ${desc}`)
278
280
  console.log('\nCLI 对齐映射:')
279
281
  const map = [
@@ -284,6 +286,7 @@ function printAlignment() {
284
286
  ['a2a tasks', 'a2a_tasks', '账本三层(pending/dead/archived)'],
285
287
  ['a2a probe', 'a2a_probe', 'peer 可达性(评分/链接/验证,读暖态)'],
286
288
  ['a2a report', 'a2a_report', '离网报告(CLI 形态:投给宿主进程队信箱)'],
289
+ ['a2a file send/fetch', 'a2a_file_send/fetch', '文件通道(CLI 只能从自己的 home 宿主拉取)'],
287
290
  ['(N/A)', 'a2a_exposure', '暴露档是会话面概念——CLI 无会话;户口即其可见性'],
288
291
  ['(拖卡入队)', 'a2a_team_join/leave', '入队是会话手势——等价物:属主把 CLI 成员卡拖进 canvas 队(画布手势=运营者链接)'],
289
292
  ['a2a skills', '(插件无)', '加载本机技能目录输出(CLI 专有)'],
package/lib/a2a-client.js CHANGED
@@ -65,7 +65,7 @@ export class A2aClient {
65
65
  const url = `${baseUrl}${path}`;
66
66
  const response = await this.options.fetch(url, {
67
67
  method: init.method,
68
- headers: this.headers(init.body !== undefined, url, init.method),
68
+ headers: { ...this.headers(init.body !== undefined, url, init.method), ...(init.guard !== undefined ? { 'X-A2A-Guard': init.guard } : {}) },
69
69
  ...(init.body !== undefined ? { body: init.body } : {}),
70
70
  signal: controller.signal,
71
71
  });
@@ -155,7 +155,7 @@ export class A2aClient {
155
155
  * @param callerSession - caller label overriding the node's label (the calling session's node label).
156
156
  * @returns the canonical route result (success or explicit failure).
157
157
  */
158
- async routeDirect(baseUrl, team, message, contextId, signal, callerSession, asyncMode = false, taskIdFromCaller, callbackAddress) {
158
+ async routeDirect(baseUrl, team, message, contextId, signal, callerSession, asyncMode = false, taskIdFromCaller, callbackAddress, guard) {
159
159
  const args = { team, message, caller_session: callerSession ?? this.options.sessionId };
160
160
  if (contextId !== undefined)
161
161
  args.context_id = contextId;
@@ -163,6 +163,8 @@ export class A2aClient {
163
163
  // the async half of the receipt contract for cross-host long tasks.
164
164
  if (asyncMode)
165
165
  args.wait = false;
166
+ else if (guard !== undefined)
167
+ args.wait = true;
166
168
  // The caller-born task id rides the request (idempotency key): a peer
167
169
  // that echoes it keeps the receipt header correlated with this route's
168
170
  // own result; the fallback below stamps it when the peer generated its
@@ -192,6 +194,7 @@ export class A2aClient {
192
194
  raw = await this.http('/a2a/direct', {
193
195
  method: 'POST',
194
196
  body,
197
+ ...(guard !== undefined ? { guard } : {}),
195
198
  ...(signal !== undefined ? { signal } : {}),
196
199
  }, baseUrl);
197
200
  }
@@ -278,7 +281,9 @@ export class A2aClient {
278
281
  context_id: wireText(raw.context_id),
279
282
  task_status: wireText(raw.task_status) === '' ? 'TASK_STATE_DELIVERED' : wireText(raw.task_status),
280
283
  ...(consumed !== undefined ? { consumed } : {}),
284
+ ...(wireText(raw.delivered_to) !== '' ? { deliveredTo: wireText(raw.delivered_to) } : {}),
281
285
  ...(bridge !== undefined ? { bridge } : {}),
286
+ ...(raw.receipt === 'none' || raw.receipt === 'routed' || raw.receipt === 'mailbox' ? { receipt: raw.receipt } : {}),
282
287
  ...(settlementRefused ? { settlementRefused: true } : {}),
283
288
  };
284
289
  }
@@ -288,12 +293,14 @@ export class A2aClient {
288
293
  ok: true,
289
294
  team,
290
295
  reply,
296
+ ...(wireText(raw.delivered_to) !== '' ? { deliveredTo: wireText(raw.delivered_to) } : {}),
291
297
  // Same echo-first rule as the delivered branch: the peer's echo wins,
292
298
  // else the caller-born id, else ''.
293
299
  task_id: wireText(raw.task_id) !== '' ? wireText(raw.task_id) : taskIdFromCaller ?? '',
294
300
  context_id: wireText(raw.context_id),
295
301
  task_status: wireText(raw.task_status),
296
302
  ...(bridge !== undefined ? { bridge } : {}),
303
+ ...(raw.receipt === 'none' || raw.receipt === 'routed' || raw.receipt === 'mailbox' ? { receipt: raw.receipt } : {}),
297
304
  ...(settlementRefused ? { settlementRefused: true } : {}),
298
305
  };
299
306
  }
@@ -52,7 +52,7 @@ function judgeRow(row, version, judge, cacheResting) {
52
52
  if (auth.allowlist_version === version && !cacheResting(row))
53
53
  return undefined;
54
54
  // #142 review P2: a record is re-judged by the rule of the face that admitted it.
55
- const verdict = judge(auth.caller, auth.target, auth.ingress);
55
+ const verdict = judge(auth.caller, auth.target, auth.ingress, auth);
56
56
  const base = { taskId: row.taskId, direction: row.direction ?? 'inbound', caller: auth.caller, target: auth.target };
57
57
  if (!verdict.ok) {
58
58
  const reason = verdict.refusal.length <= AFFECTED_REASON_CAP ? verdict.refusal : `${verdict.refusal.slice(0, AFFECTED_REASON_CAP - 1)}…`;
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
20
20
  import { dirname } from 'node:path';
21
+ import { CLI_HANDLE_RE } from "./cli-deposit.js";
21
22
  /** Upper bounds: a canvas taxonomy, not a database. */
22
23
  export const CANVAS_TEAM_CAP = 64;
23
24
  export const CANVAS_MEMBER_CAP = 32;
@@ -62,6 +63,7 @@ function validName(raw) {
62
63
  export class CanvasStore {
63
64
  /** Team entries in creation order; members in add order (routing priority). */
64
65
  teams = [];
66
+ cliHome = {};
65
67
  path;
66
68
  listeners = new Set();
67
69
  /**
@@ -103,6 +105,12 @@ export class CanvasStore {
103
105
  kept.push({ name: String(entry.name), members });
104
106
  }
105
107
  this.teams = kept.slice(0, CANVAS_TEAM_CAP);
108
+ if (snapshot.cliHome !== null && typeof snapshot.cliHome === 'object' && !Array.isArray(snapshot.cliHome)) {
109
+ for (const [handle, home] of Object.entries(snapshot.cliHome)) {
110
+ if (CLI_HANDLE_RE.test(handle) && typeof home === 'string' && validHomeOrigin(home) && this.teams.some(t => t.members.includes(handle)))
111
+ this.cliHome[handle] = home;
112
+ }
113
+ }
106
114
  }
107
115
  catch {
108
116
  // A corrupt store is not fatal: the user re-creates teams; routing
@@ -124,7 +132,7 @@ export class CanvasStore {
124
132
  return;
125
133
  try {
126
134
  mkdirSync(dirname(this.path), { recursive: true });
127
- const snapshot = { teams: this.teams.map(t => ({ name: t.name, members: [...t.members] })) };
135
+ const snapshot = { teams: this.teams.map(t => ({ name: t.name, members: [...t.members] })), ...(Object.keys(this.cliHome).length > 0 ? { cliHome: { ...this.cliHome } } : {}) };
128
136
  writeFileSync(this.path, JSON.stringify(snapshot), { mode: 0o600 });
129
137
  }
130
138
  catch {
@@ -145,6 +153,9 @@ export class CanvasStore {
145
153
  const entry = this.teams.find(t => t.name === name);
146
154
  return entry === undefined ? [] : [...entry.members];
147
155
  }
156
+ /** Frozen, operator-linked CLI home; undefined means unknown or ambiguous. */
157
+ cliHomeOf(handle) { return this.cliHome[handle]; }
158
+ pinnedCliHomes() { return Object.entries(this.cliHome); }
148
159
  /**
149
160
  * The named team's remote member refs (zone-qualified team handles) in
150
161
  * routing-priority order — the failover tier after the local live/cold
@@ -184,7 +195,9 @@ export class CanvasStore {
184
195
  const index = this.teams.findIndex(t => t.name === name);
185
196
  if (index < 0)
186
197
  return false;
187
- this.teams.splice(index, 1);
198
+ const [removed] = this.teams.splice(index, 1);
199
+ for (const id of removed.members)
200
+ this.forgetUnusedHome(id);
188
201
  this.persist();
189
202
  return true;
190
203
  }
@@ -194,17 +207,26 @@ export class CanvasStore {
194
207
  * @param name - the existing team name.
195
208
  * @param id - the member session id.
196
209
  */
197
- addMember(name, id) {
198
- if (id === '')
210
+ addMember(name, id, home, options = {}) {
211
+ if (id === '' || (home !== undefined && (!CLI_HANDLE_RE.test(id) || !validHomeOrigin(home))))
212
+ return false;
213
+ if (home !== undefined && this.cliHome[id] !== undefined && this.cliHome[id] !== home && options.replaceHome !== true)
199
214
  return false;
200
215
  const entry = this.teams.find(t => t.name === name);
201
216
  if (entry === undefined)
202
217
  return false;
203
- if (entry.members.includes(id))
218
+ if (entry.members.includes(id)) {
219
+ if (home !== undefined && this.cliHome[id] !== home) {
220
+ this.cliHome[id] = home;
221
+ this.persist();
222
+ }
204
223
  return true;
224
+ }
205
225
  if (entry.members.length >= CANVAS_MEMBER_CAP)
206
226
  return false;
207
227
  entry.members.push(id);
228
+ if (home !== undefined)
229
+ this.cliHome[id] = home;
208
230
  this.persist();
209
231
  return true;
210
232
  }
@@ -219,9 +241,14 @@ export class CanvasStore {
219
241
  if (index < 0)
220
242
  return false;
221
243
  entry.members.splice(index, 1);
244
+ this.forgetUnusedHome(id);
222
245
  this.persist();
223
246
  return true;
224
247
  }
248
+ forgetUnusedHome(id) {
249
+ if (!this.teams.some(team => team.members.includes(id)))
250
+ delete this.cliHome[id];
251
+ }
225
252
  /**
226
253
  * Drop one id from every team — the leave and archive paths: a session
227
254
  * leaving the network keeps no canvas membership anywhere.
@@ -236,7 +263,24 @@ export class CanvasStore {
236
263
  dirty = true;
237
264
  }
238
265
  }
239
- if (dirty)
266
+ if (dirty) {
267
+ this.forgetUnusedHome(id);
240
268
  this.persist();
269
+ }
270
+ }
271
+ }
272
+ /** One policy predicate for local and signed-remote canvas creation. */
273
+ export function canvasNameReserved(raw, zone, allowlist, roster) {
274
+ const name = raw.trim();
275
+ const team = `${zone}/${name}`;
276
+ return name.startsWith('roster:') || allowlist.includes(team) || roster.membersOf(team).length > 0;
277
+ }
278
+ function validHomeOrigin(raw) {
279
+ try {
280
+ const url = new URL(raw);
281
+ return (url.protocol === 'http:' || url.protocol === 'https:') && url.origin === raw;
282
+ }
283
+ catch {
284
+ return false;
241
285
  }
242
286
  }
package/lib/card.js CHANGED
@@ -95,12 +95,13 @@ function sessionTeams(wire) {
95
95
  const team = entry;
96
96
  if (typeof team?.team !== 'string' || team.team === '')
97
97
  continue;
98
- if (typeof team.name !== 'string' || (team.description !== undefined && typeof team.description !== 'string'))
98
+ if (typeof team.name !== 'string' || (team.description !== undefined && typeof team.description !== 'string') || (team.offline !== undefined && typeof team.offline !== 'boolean'))
99
99
  continue;
100
100
  entries.push({
101
101
  team: team.team,
102
102
  name: team.name,
103
103
  description: team.description ?? '',
104
+ ...(team.offline !== undefined ? { offline: team.offline } : {}),
104
105
  ...(typeof team.workspace === 'string' && team.workspace !== '' ? { workspace: team.workspace } : {}),
105
106
  });
106
107
  }
@@ -0,0 +1,44 @@
1
+ import { CLI_HANDLE_RE } from "./cli-deposit.js";
2
+ /** Canonical root HTTP(S) origin; address aliases remain distinct trust decisions. */
3
+ export function cliHomeOrigin(value) {
4
+ if (typeof value !== 'string')
5
+ return undefined;
6
+ try {
7
+ const url = new URL(value);
8
+ return (url.protocol === 'http:' || url.protocol === 'https:') && !url.username && !url.password && url.pathname === '/' && !url.search && !url.hash ? url.origin : undefined;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ /** Read-only projection of the same fresh evidence used by explicit home validation. */
15
+ export function cliHomeChoices(handle, candidates, locallyHeld = false) {
16
+ if (locallyHeld)
17
+ return { homes: [], unreadable: 0, held: true };
18
+ const homes = new Set();
19
+ for (const row of candidates) {
20
+ if (!row.linked || !row.card?.sessionTeams?.some(t => t.team === handle))
21
+ continue;
22
+ try {
23
+ homes.add(new URL(row.url).origin);
24
+ }
25
+ catch { /* not a host card URL */ }
26
+ }
27
+ return { homes: [...homes], unreadable: candidates.filter(row => row.card === undefined).length };
28
+ }
29
+ /** Count origins, not URL aliases: two card URLs on one host are one home. */
30
+ export function decideCliHome(handle, requested, candidates, locallyHeld = false) {
31
+ if (!CLI_HANDLE_RE.test(handle))
32
+ return requested === undefined ? { ok: true } : { ok: false, error: 'home is only valid for a CLI handle' };
33
+ if (locallyHeld)
34
+ return requested === undefined ? { ok: true } : { ok: false, error: 'CLI household is held locally; revoke the local household before specifying another home' };
35
+ const homes = new Set(cliHomeChoices(handle, candidates).homes);
36
+ if (requested !== undefined) {
37
+ const origin = cliHomeOrigin(requested);
38
+ if (origin === undefined || !homes.has(origin))
39
+ return { ok: false, error: 'home must be a linked host that currently lists this CLI handle' };
40
+ return { ok: true, home: origin };
41
+ }
42
+ // An unreadable linked host may be another home; lack of evidence is not absence.
43
+ return !candidates.some(row => row.linked && row.card === undefined) && homes.size === 1 ? { ok: true, home: [...homes][0] } : { ok: true };
44
+ }
@@ -44,7 +44,7 @@ function relativeTime(ts) {
44
44
  function FeedRow({ dir, team, peer, ts, ok, target, openSession, t }) {
45
45
  const fresh = Date.now() - ts < 5_000;
46
46
  return (_jsxs("div", { className: clsx(css.activityRow, fresh && css.fresh), "data-ok": ok === undefined ? undefined : String(ok), "data-jump": target !== undefined, title: target !== undefined ? t('a2a.jump') : undefined, onClick: () => { if (target !== undefined)
47
- openSession(target.id); }, role: target !== undefined ? 'button' : undefined, children: [_jsx("span", { className: clsx(css.activityDir, dir), "aria-label": dir === 'in' ? 'inbound' : 'outbound', children: dir === 'in' ? '←' : '→' }), _jsx("span", { className: css.activityTeam, title: team, children: team }), _jsx("span", { className: css.activityPeer, title: peer, children: peer === '' || peer === 'local' ? '' : peer.replace(/^https?:\/\//, '').replace(/\/.*$/, '') }), ok === false ? _jsx("span", { className: css.failMark, "aria-label": "failed", children: "\u2715" }) : null, _jsx("span", { className: css.activityTime, children: relativeTime(ts) })] }));
47
+ openSession(target.id); }, role: target !== undefined ? 'button' : undefined, children: [_jsx("span", { className: clsx(css.activityDir, dir), "aria-label": dir === 'fwd' ? 'forwarded' : dir === 'in' ? 'inbound' : 'outbound', children: dir === 'fwd' ? '⇢' : dir === 'in' ? '←' : '→' }), _jsx("span", { className: css.activityTeam, title: team, children: team }), _jsx("span", { className: css.activityPeer, title: peer, children: peer === '' || peer === 'local' ? '' : peer.replace(/^https?:\/\//, '').replace(/\/.*$/, '') }), ok === false ? _jsx("span", { className: css.failMark, "aria-label": "failed", children: "\u2715" }) : null, _jsx("span", { className: css.activityTime, children: relativeTime(ts) })] }));
48
48
  }
49
49
  /**
50
50
  * Render the network toggle and its activity feed.
package/lib/client.js CHANGED
@@ -22,8 +22,8 @@ window.__ModuleLoader__.load({
22
22
  return n;
23
23
  }
24
24
  //#endregion
25
- //#region \0dsh-css:D:\workspace\dsh-open-a2a-net\tmp\rc-3081-90c7d4c\src\client\A2aControl.module.css.mjs
26
- const css = ".uJ8yTG_wrap{max-width:100%;display:inline-flex;position:relative}.uJ8yTG_trigger{align-items:center;gap:4px;display:inline-flex;position:relative}.uJ8yTG_unreadBadge{text-align:center;color:#fff;background:var(--dsh-accent,#4c8bf5);border-radius:7px;min-width:14px;height:14px;padding:0 3px;font-size:9px;line-height:14px;animation:2s ease-in-out infinite uJ8yTG_badgePulse;position:absolute;top:-6px;right:-8px}@keyframes uJ8yTG_badgePulse{0%,to{box-shadow:0 0 #4c8bf573}50%{box-shadow:0 0 0 4px #4c8bf500}}@media (prefers-reduced-motion:reduce){.uJ8yTG_unreadBadge{animation:none}}.uJ8yTG_popover{z-index:1100;border:1px solid var(--dsh-border,#2a2a30);background:var(--dsh-surface-raised,#1c1c22);border-radius:10px;flex-direction:column;gap:8px;width:320px;max-width:calc(100vw - 16px);max-height:60vh;padding:12px;display:flex;position:fixed;overflow-y:auto;box-shadow:0 8px 24px #00000059}.uJ8yTG_title{font-size:13px;font-weight:600}.uJ8yTG_sectionTitle{border-top:1px solid var(--dsh-border,#2a2a30);text-transform:uppercase;letter-spacing:.04em;opacity:.65;margin-top:4px;padding-top:8px;font-size:11px;font-weight:600}.uJ8yTG_stageRow{border-top:1px solid var(--dsh-border,#2a2a30);align-items:center;gap:8px;margin-top:4px;padding-top:8px;display:flex}.uJ8yTG_stageTitle{text-transform:uppercase;letter-spacing:.04em;opacity:.65;font-size:11px;font-weight:600}.uJ8yTG_stageLinks{gap:6px;display:flex}.uJ8yTG_stageLink{border:1px solid var(--dsh-border,#2a2a30);color:inherit;border-radius:999px;align-items:center;padding:3px 8px;font-size:11px;text-decoration:none;display:inline-flex}.uJ8yTG_stageLink:hover,.uJ8yTG_stageLink:focus-visible{border-color:var(--dsh-accent,#4c8bf5)}.uJ8yTG_empty{opacity:.7;font-size:12px}.uJ8yTG_row{border:1px solid #0000;border-radius:8px;align-items:center;gap:10px;padding:8px;display:flex}.uJ8yTG_joined{border-color:var(--dsh-border,#2a2a30)}.uJ8yTG_facts{text-align:left;min-width:0;color:inherit;font:inherit;cursor:pointer;background:0 0;border:none;border-radius:6px;flex-direction:column;flex:1;gap:2px;padding:2px 4px;display:flex}.uJ8yTG_facts:hover{background:var(--dsh-surface-hover,#ffffff0f)}.uJ8yTG_nameRow{align-items:center;gap:6px;display:flex}.uJ8yTG_stateDot{border-radius:50%;flex:none;width:7px;height:7px}.uJ8yTG_stateDot.uJ8yTG_live{background:var(--dsh-accent,#4c8bf5)}.uJ8yTG_stateDot.uJ8yTG_live.uJ8yTG_joined{background:var(--dsh-success,#3fb96f)}.uJ8yTG_stateDot.uJ8yTG_cold{background:var(--dsh-warning,#d9a13c)}.uJ8yTG_name{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;overflow:hidden}.uJ8yTG_description{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.uJ8yTG_team{opacity:.55;font-size:11px;font-family:var(--dsh-mono,monospace)}.uJ8yTG_note{opacity:.6;font-size:11px}.uJ8yTG_searchInput{box-sizing:border-box;border:1px solid var(--dsh-border,#2a2a30);background:var(--dsh-surface,#141419);width:100%;color:inherit;border-radius:6px;padding:5px 8px;font-size:12px}.uJ8yTG_searchInput:focus{outline:1px solid var(--dsh-accent,#4c8bf5)}.uJ8yTG_sessionGroup{flex-direction:column;gap:2px;display:flex}.uJ8yTG_groupHead{color:inherit;font:inherit;opacity:.75;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:6px;padding:4px 2px;font-size:11px;font-weight:600;display:flex}.uJ8yTG_groupChevron{transition:transform .12s;display:inline-block}.uJ8yTG_groupChevronClosed{transform:rotate(-90deg)}.uJ8yTG_groupTag{text-overflow:ellipsis;white-space:nowrap;border:1px solid var(--dsh-border,#2a2a30);opacity:.8;border-radius:999px;flex:none;max-width:90px;padding:0 6px;font-size:10px;line-height:16px;overflow:hidden}.uJ8yTG_groupButton{width:24px;height:24px;color:inherit;opacity:.55;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;flex:none;font-size:12px;line-height:1}.uJ8yTG_groupButton:hover{border-color:var(--dsh-border,#2a2a30);opacity:1}.uJ8yTG_groupPicker{border:1px dashed var(--dsh-border,#2a2a30);border-radius:8px;flex-wrap:wrap;gap:6px;width:100%;padding:8px;display:flex;position:relative}.uJ8yTG_groupOption{border:1px solid var(--dsh-border,#2a2a30);color:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:2px 8px;font-size:11px}.uJ8yTG_groupOptionActive{border-color:var(--dsh-accent,#4c8bf5);color:var(--dsh-accent,#4c8bf5)}.uJ8yTG_groupNew{align-items:center;gap:6px;width:100%;margin-top:2px;display:flex}.uJ8yTG_groupInput{border:1px solid var(--dsh-border,#2a2a30);background:var(--dsh-surface,#141419);min-width:0;color:inherit;border-radius:6px;flex:1;padding:4px 8px;font-size:12px}.uJ8yTG_peerGrid{flex-wrap:wrap;gap:6px;display:flex}.uJ8yTG_peerChip{border:1px solid var(--dsh-border,#2a2a30);border-radius:999px;align-items:center;gap:6px;padding:3px 8px;font-size:11px;display:inline-flex}.uJ8yTG_peerHost{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.uJ8yTG_peerScore{font-family:var(--dsh-mono,monospace);opacity:.6}.uJ8yTG_activityList{flex-direction:column;gap:2px;display:flex}.uJ8yTG_activityRow{border-radius:4px;align-items:center;gap:8px;padding:2px 4px;font-size:11px;display:flex}.uJ8yTG_activityRow[data-ok=false]{opacity:.55}.uJ8yTG_activityDir{flex:none;font-weight:600}.uJ8yTG_activityDir.uJ8yTG_in{color:var(--dsh-success,#3fb96f)}.uJ8yTG_activityDir.uJ8yTG_out{color:var(--dsh-accent,#4c8bf5)}.uJ8yTG_activityTeam{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--dsh-mono,monospace);opacity:.8;flex:1;overflow:hidden}.uJ8yTG_activityPeer{text-overflow:ellipsis;white-space:nowrap;opacity:.55;max-width:90px;overflow:hidden}.uJ8yTG_activityTime{opacity:.5;font-family:var(--dsh-mono,monospace);flex:none}.uJ8yTG_activityRow[data-jump=true]{cursor:pointer}.uJ8yTG_activityRow[data-jump=true]:hover{background:var(--dsh-surface-hover,#ffffff0f)}.uJ8yTG_fresh{animation:1.2s ease-out 3 uJ8yTG_freshFlash}@keyframes uJ8yTG_freshFlash{0%{background:#4c8bf538}to{background:0 0}}@media (prefers-reduced-motion:reduce){.uJ8yTG_fresh{background:#4c8bf51f;animation:none}}.uJ8yTG_inFlightList{flex-direction:column;gap:2px;margin-bottom:4px;display:flex}.uJ8yTG_inFlightRow{border:1px dashed var(--dsh-border,#2a2a30);border-radius:4px;align-items:center;gap:8px;padding:3px 4px;font-size:11px;display:flex}.uJ8yTG_inFlightPulse{background:var(--dsh-accent,#4c8bf5);border-radius:50%;flex:none;width:7px;height:7px;animation:1.1s ease-in-out infinite uJ8yTG_flightPulse}@keyframes uJ8yTG_flightPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(.55)}}@media (prefers-reduced-motion:reduce){.uJ8yTG_inFlightPulse{animation:none}}.uJ8yTG_versionTag{color:var(--dsh-color-text-tertiary,#888);background:var(--dsh-color-bg-secondary,#8080801f);border-radius:999px;margin-left:auto;padding:1px 6px;font-size:10px;font-weight:500}.uJ8yTG_inFlightStale{opacity:.55}.uJ8yTG_canvasCreate{align-items:center;gap:6px;margin-bottom:4px;display:flex}.uJ8yTG_canvasCreate .uJ8yTG_groupInput{flex:1;min-width:0}.uJ8yTG_canvasChip{max-width:100%;color:var(--dsh-color-text-secondary,#aaa);background:var(--dsh-color-bg-secondary,#8080801f);border-radius:999px;align-items:center;gap:4px;margin:2px 4px 2px 0;padding:1px 6px;font-size:11px;display:inline-flex}.uJ8yTG_canvasChip>span:not([class]){white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}.uJ8yTG_canvasChipRemove{cursor:pointer;min-width:24px;min-height:24px;color:var(--dsh-color-text-tertiary,#888);background:0 0;border:none;padding:2px 5px;font-size:11px;line-height:1}.uJ8yTG_canvasChipRemove:hover{color:var(--dsh-color-text-primary,#eee)}.uJ8yTG_canvasChipRemove{transition:color .14s ease-out}@media (prefers-reduced-motion:reduce){.uJ8yTG_canvasChipRemove{transition:none}}.uJ8yTG_canvasChipRemove:focus-visible{outline:2px solid var(--dsh-color-primary,#4f8cff);outline-offset:1px;border-radius:4px}.uJ8yTG_canvasActions{gap:6px;margin-top:4px;display:flex}.uJ8yTG_inFlightStale .uJ8yTG_inFlightPulse{opacity:.4;animation:none}.uJ8yTG_failMark{color:#f87171;flex-shrink:0;font-size:11px}.uJ8yTG_staleNote{color:var(--dsh-text-muted,#94a3b8b3);padding:4px 8px;font-size:11px}";
25
+ //#region \0dsh-css:D:\workspace\dsh-open-a2a-net\tmp\release-0.6.34-474a60a\src\src\client\A2aControl.module.css.mjs
26
+ const css = ".YPQWgG_wrap{max-width:100%;display:inline-flex;position:relative}.YPQWgG_trigger{align-items:center;gap:4px;display:inline-flex;position:relative}.YPQWgG_unreadBadge{text-align:center;color:#fff;background:var(--dsh-accent,#4c8bf5);border-radius:7px;min-width:14px;height:14px;padding:0 3px;font-size:9px;line-height:14px;animation:2s ease-in-out infinite YPQWgG_badgePulse;position:absolute;top:-6px;right:-8px}@keyframes YPQWgG_badgePulse{0%,to{box-shadow:0 0 #4c8bf573}50%{box-shadow:0 0 0 4px #4c8bf500}}@media (prefers-reduced-motion:reduce){.YPQWgG_unreadBadge{animation:none}}.YPQWgG_popover{z-index:1100;border:1px solid var(--dsh-border,#2a2a30);background:var(--dsh-surface-raised,#1c1c22);border-radius:10px;flex-direction:column;gap:8px;width:320px;max-width:calc(100vw - 16px);max-height:60vh;padding:12px;display:flex;position:fixed;overflow-y:auto;box-shadow:0 8px 24px #00000059}.YPQWgG_title{font-size:13px;font-weight:600}.YPQWgG_sectionTitle{border-top:1px solid var(--dsh-border,#2a2a30);text-transform:uppercase;letter-spacing:.04em;opacity:.65;margin-top:4px;padding-top:8px;font-size:11px;font-weight:600}.YPQWgG_stageRow{border-top:1px solid var(--dsh-border,#2a2a30);align-items:center;gap:8px;margin-top:4px;padding-top:8px;display:flex}.YPQWgG_stageTitle{text-transform:uppercase;letter-spacing:.04em;opacity:.65;font-size:11px;font-weight:600}.YPQWgG_stageLinks{gap:6px;display:flex}.YPQWgG_stageLink{border:1px solid var(--dsh-border,#2a2a30);color:inherit;border-radius:999px;align-items:center;padding:3px 8px;font-size:11px;text-decoration:none;display:inline-flex}.YPQWgG_stageLink:hover,.YPQWgG_stageLink:focus-visible{border-color:var(--dsh-accent,#4c8bf5)}.YPQWgG_empty{opacity:.7;font-size:12px}.YPQWgG_row{border:1px solid #0000;border-radius:8px;align-items:center;gap:10px;padding:8px;display:flex}.YPQWgG_joined{border-color:var(--dsh-border,#2a2a30)}.YPQWgG_facts{text-align:left;min-width:0;color:inherit;font:inherit;cursor:pointer;background:0 0;border:none;border-radius:6px;flex-direction:column;flex:1;gap:2px;padding:2px 4px;display:flex}.YPQWgG_facts:hover{background:var(--dsh-surface-hover,#ffffff0f)}.YPQWgG_nameRow{align-items:center;gap:6px;display:flex}.YPQWgG_stateDot{border-radius:50%;flex:none;width:7px;height:7px}.YPQWgG_stateDot.YPQWgG_live{background:var(--dsh-accent,#4c8bf5)}.YPQWgG_stateDot.YPQWgG_live.YPQWgG_joined{background:var(--dsh-success,#3fb96f)}.YPQWgG_stateDot.YPQWgG_cold{background:var(--dsh-warning,#d9a13c)}.YPQWgG_name{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;overflow:hidden}.YPQWgG_description{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.YPQWgG_team{opacity:.55;font-size:11px;font-family:var(--dsh-mono,monospace)}.YPQWgG_note{opacity:.6;font-size:11px}.YPQWgG_searchInput{box-sizing:border-box;border:1px solid var(--dsh-border,#2a2a30);background:var(--dsh-surface,#141419);width:100%;color:inherit;border-radius:6px;padding:5px 8px;font-size:12px}.YPQWgG_searchInput:focus{outline:1px solid var(--dsh-accent,#4c8bf5)}.YPQWgG_sessionGroup{flex-direction:column;gap:2px;display:flex}.YPQWgG_groupHead{color:inherit;font:inherit;opacity:.75;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:6px;padding:4px 2px;font-size:11px;font-weight:600;display:flex}.YPQWgG_groupChevron{transition:transform .12s;display:inline-block}.YPQWgG_groupChevronClosed{transform:rotate(-90deg)}.YPQWgG_groupTag{text-overflow:ellipsis;white-space:nowrap;border:1px solid var(--dsh-border,#2a2a30);opacity:.8;border-radius:999px;flex:none;max-width:90px;padding:0 6px;font-size:10px;line-height:16px;overflow:hidden}.YPQWgG_groupButton{width:24px;height:24px;color:inherit;opacity:.55;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;flex:none;font-size:12px;line-height:1}.YPQWgG_groupButton:hover{border-color:var(--dsh-border,#2a2a30);opacity:1}.YPQWgG_groupPicker{border:1px dashed var(--dsh-border,#2a2a30);border-radius:8px;flex-wrap:wrap;gap:6px;width:100%;padding:8px;display:flex;position:relative}.YPQWgG_groupOption{border:1px solid var(--dsh-border,#2a2a30);color:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:2px 8px;font-size:11px}.YPQWgG_groupOptionActive{border-color:var(--dsh-accent,#4c8bf5);color:var(--dsh-accent,#4c8bf5)}.YPQWgG_groupNew{align-items:center;gap:6px;width:100%;margin-top:2px;display:flex}.YPQWgG_groupInput{border:1px solid var(--dsh-border,#2a2a30);background:var(--dsh-surface,#141419);min-width:0;color:inherit;border-radius:6px;flex:1;padding:4px 8px;font-size:12px}.YPQWgG_peerGrid{flex-wrap:wrap;gap:6px;display:flex}.YPQWgG_peerChip{border:1px solid var(--dsh-border,#2a2a30);border-radius:999px;align-items:center;gap:6px;padding:3px 8px;font-size:11px;display:inline-flex}.YPQWgG_peerHost{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.YPQWgG_peerScore{font-family:var(--dsh-mono,monospace);opacity:.6}.YPQWgG_activityList{flex-direction:column;gap:2px;display:flex}.YPQWgG_activityRow{border-radius:4px;align-items:center;gap:8px;padding:2px 4px;font-size:11px;display:flex}.YPQWgG_activityRow[data-ok=false]{opacity:.55}.YPQWgG_activityDir{flex:none;font-weight:600}.YPQWgG_activityDir.YPQWgG_in{color:var(--dsh-success,#3fb96f)}.YPQWgG_activityDir.YPQWgG_out{color:var(--dsh-accent,#4c8bf5)}.YPQWgG_activityTeam{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--dsh-mono,monospace);opacity:.8;flex:1;overflow:hidden}.YPQWgG_activityPeer{text-overflow:ellipsis;white-space:nowrap;opacity:.55;max-width:90px;overflow:hidden}.YPQWgG_activityTime{opacity:.5;font-family:var(--dsh-mono,monospace);flex:none}.YPQWgG_activityRow[data-jump=true]{cursor:pointer}.YPQWgG_activityRow[data-jump=true]:hover{background:var(--dsh-surface-hover,#ffffff0f)}.YPQWgG_fresh{animation:1.2s ease-out 3 YPQWgG_freshFlash}@keyframes YPQWgG_freshFlash{0%{background:#4c8bf538}to{background:0 0}}@media (prefers-reduced-motion:reduce){.YPQWgG_fresh{background:#4c8bf51f;animation:none}}.YPQWgG_inFlightList{flex-direction:column;gap:2px;margin-bottom:4px;display:flex}.YPQWgG_inFlightRow{border:1px dashed var(--dsh-border,#2a2a30);border-radius:4px;align-items:center;gap:8px;padding:3px 4px;font-size:11px;display:flex}.YPQWgG_inFlightPulse{background:var(--dsh-accent,#4c8bf5);border-radius:50%;flex:none;width:7px;height:7px;animation:1.1s ease-in-out infinite YPQWgG_flightPulse}@keyframes YPQWgG_flightPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(.55)}}@media (prefers-reduced-motion:reduce){.YPQWgG_inFlightPulse{animation:none}}.YPQWgG_versionTag{color:var(--dsh-color-text-tertiary,#888);background:var(--dsh-color-bg-secondary,#8080801f);border-radius:999px;margin-left:auto;padding:1px 6px;font-size:10px;font-weight:500}.YPQWgG_inFlightStale{opacity:.55}.YPQWgG_canvasCreate{align-items:center;gap:6px;margin-bottom:4px;display:flex}.YPQWgG_canvasCreate .YPQWgG_groupInput{flex:1;min-width:0}.YPQWgG_canvasChip{max-width:100%;color:var(--dsh-color-text-secondary,#aaa);background:var(--dsh-color-bg-secondary,#8080801f);border-radius:999px;align-items:center;gap:4px;margin:2px 4px 2px 0;padding:1px 6px;font-size:11px;display:inline-flex}.YPQWgG_canvasChip>span:not([class]){white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}.YPQWgG_canvasChipRemove{cursor:pointer;min-width:24px;min-height:24px;color:var(--dsh-color-text-tertiary,#888);background:0 0;border:none;padding:2px 5px;font-size:11px;line-height:1}.YPQWgG_canvasChipRemove:hover{color:var(--dsh-color-text-primary,#eee)}.YPQWgG_canvasChipRemove{transition:color .14s ease-out}@media (prefers-reduced-motion:reduce){.YPQWgG_canvasChipRemove{transition:none}}.YPQWgG_canvasChipRemove:focus-visible{outline:2px solid var(--dsh-color-primary,#4f8cff);outline-offset:1px;border-radius:4px}.YPQWgG_canvasActions{gap:6px;margin-top:4px;display:flex}.YPQWgG_inFlightStale .YPQWgG_inFlightPulse{opacity:.4;animation:none}.YPQWgG_failMark{color:#f87171;flex-shrink:0;font-size:11px}.YPQWgG_staleNote{color:var(--dsh-text-muted,#94a3b8b3);padding:4px 8px;font-size:11px}";
27
27
  const tagId = "@nelsonlongxiang/dsh-open-a2a-net/A2aControl.module.css";
28
28
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
29
29
  const tag = document.createElement("style");
@@ -33,67 +33,67 @@ window.__ModuleLoader__.load({
33
33
  document.head.appendChild(tag);
34
34
  }
35
35
  var A2aControl_module_css_default = {
36
- "activityDir": "uJ8yTG_activityDir",
37
- "activityList": "uJ8yTG_activityList",
38
- "activityPeer": "uJ8yTG_activityPeer",
39
- "activityRow": "uJ8yTG_activityRow",
40
- "activityTeam": "uJ8yTG_activityTeam",
41
- "activityTime": "uJ8yTG_activityTime",
42
- "badgePulse": "uJ8yTG_badgePulse",
43
- "canvasActions": "uJ8yTG_canvasActions",
44
- "canvasChip": "uJ8yTG_canvasChip",
45
- "canvasChipRemove": "uJ8yTG_canvasChipRemove",
46
- "canvasCreate": "uJ8yTG_canvasCreate",
47
- "cold": "uJ8yTG_cold",
48
- "description": "uJ8yTG_description",
49
- "empty": "uJ8yTG_empty",
50
- "facts": "uJ8yTG_facts",
51
- "failMark": "uJ8yTG_failMark",
52
- "flightPulse": "uJ8yTG_flightPulse",
53
- "fresh": "uJ8yTG_fresh",
54
- "freshFlash": "uJ8yTG_freshFlash",
55
- "groupButton": "uJ8yTG_groupButton",
56
- "groupChevron": "uJ8yTG_groupChevron",
57
- "groupChevronClosed": "uJ8yTG_groupChevronClosed",
58
- "groupHead": "uJ8yTG_groupHead",
59
- "groupInput": "uJ8yTG_groupInput",
60
- "groupNew": "uJ8yTG_groupNew",
61
- "groupOption": "uJ8yTG_groupOption",
62
- "groupOptionActive": "uJ8yTG_groupOptionActive",
63
- "groupPicker": "uJ8yTG_groupPicker",
64
- "groupTag": "uJ8yTG_groupTag",
65
- "in": "uJ8yTG_in",
66
- "inFlightList": "uJ8yTG_inFlightList",
67
- "inFlightPulse": "uJ8yTG_inFlightPulse",
68
- "inFlightRow": "uJ8yTG_inFlightRow",
69
- "inFlightStale": "uJ8yTG_inFlightStale",
70
- "joined": "uJ8yTG_joined",
71
- "live": "uJ8yTG_live",
72
- "name": "uJ8yTG_name",
73
- "nameRow": "uJ8yTG_nameRow",
74
- "note": "uJ8yTG_note",
75
- "out": "uJ8yTG_out",
76
- "peerChip": "uJ8yTG_peerChip",
77
- "peerGrid": "uJ8yTG_peerGrid",
78
- "peerHost": "uJ8yTG_peerHost",
79
- "peerScore": "uJ8yTG_peerScore",
80
- "popover": "uJ8yTG_popover",
81
- "row": "uJ8yTG_row",
82
- "searchInput": "uJ8yTG_searchInput",
83
- "sectionTitle": "uJ8yTG_sectionTitle",
84
- "sessionGroup": "uJ8yTG_sessionGroup",
85
- "stageLink": "uJ8yTG_stageLink",
86
- "stageLinks": "uJ8yTG_stageLinks",
87
- "stageRow": "uJ8yTG_stageRow",
88
- "stageTitle": "uJ8yTG_stageTitle",
89
- "staleNote": "uJ8yTG_staleNote",
90
- "stateDot": "uJ8yTG_stateDot",
91
- "team": "uJ8yTG_team",
92
- "title": "uJ8yTG_title",
93
- "trigger": "uJ8yTG_trigger",
94
- "unreadBadge": "uJ8yTG_unreadBadge",
95
- "versionTag": "uJ8yTG_versionTag",
96
- "wrap": "uJ8yTG_wrap"
36
+ "activityDir": "YPQWgG_activityDir",
37
+ "activityList": "YPQWgG_activityList",
38
+ "activityPeer": "YPQWgG_activityPeer",
39
+ "activityRow": "YPQWgG_activityRow",
40
+ "activityTeam": "YPQWgG_activityTeam",
41
+ "activityTime": "YPQWgG_activityTime",
42
+ "badgePulse": "YPQWgG_badgePulse",
43
+ "canvasActions": "YPQWgG_canvasActions",
44
+ "canvasChip": "YPQWgG_canvasChip",
45
+ "canvasChipRemove": "YPQWgG_canvasChipRemove",
46
+ "canvasCreate": "YPQWgG_canvasCreate",
47
+ "cold": "YPQWgG_cold",
48
+ "description": "YPQWgG_description",
49
+ "empty": "YPQWgG_empty",
50
+ "facts": "YPQWgG_facts",
51
+ "failMark": "YPQWgG_failMark",
52
+ "flightPulse": "YPQWgG_flightPulse",
53
+ "fresh": "YPQWgG_fresh",
54
+ "freshFlash": "YPQWgG_freshFlash",
55
+ "groupButton": "YPQWgG_groupButton",
56
+ "groupChevron": "YPQWgG_groupChevron",
57
+ "groupChevronClosed": "YPQWgG_groupChevronClosed",
58
+ "groupHead": "YPQWgG_groupHead",
59
+ "groupInput": "YPQWgG_groupInput",
60
+ "groupNew": "YPQWgG_groupNew",
61
+ "groupOption": "YPQWgG_groupOption",
62
+ "groupOptionActive": "YPQWgG_groupOptionActive",
63
+ "groupPicker": "YPQWgG_groupPicker",
64
+ "groupTag": "YPQWgG_groupTag",
65
+ "in": "YPQWgG_in",
66
+ "inFlightList": "YPQWgG_inFlightList",
67
+ "inFlightPulse": "YPQWgG_inFlightPulse",
68
+ "inFlightRow": "YPQWgG_inFlightRow",
69
+ "inFlightStale": "YPQWgG_inFlightStale",
70
+ "joined": "YPQWgG_joined",
71
+ "live": "YPQWgG_live",
72
+ "name": "YPQWgG_name",
73
+ "nameRow": "YPQWgG_nameRow",
74
+ "note": "YPQWgG_note",
75
+ "out": "YPQWgG_out",
76
+ "peerChip": "YPQWgG_peerChip",
77
+ "peerGrid": "YPQWgG_peerGrid",
78
+ "peerHost": "YPQWgG_peerHost",
79
+ "peerScore": "YPQWgG_peerScore",
80
+ "popover": "YPQWgG_popover",
81
+ "row": "YPQWgG_row",
82
+ "searchInput": "YPQWgG_searchInput",
83
+ "sectionTitle": "YPQWgG_sectionTitle",
84
+ "sessionGroup": "YPQWgG_sessionGroup",
85
+ "stageLink": "YPQWgG_stageLink",
86
+ "stageLinks": "YPQWgG_stageLinks",
87
+ "stageRow": "YPQWgG_stageRow",
88
+ "stageTitle": "YPQWgG_stageTitle",
89
+ "staleNote": "YPQWgG_staleNote",
90
+ "stateDot": "YPQWgG_stateDot",
91
+ "team": "YPQWgG_team",
92
+ "title": "YPQWgG_title",
93
+ "trigger": "YPQWgG_trigger",
94
+ "unreadBadge": "YPQWgG_unreadBadge",
95
+ "versionTag": "YPQWgG_versionTag",
96
+ "wrap": "YPQWgG_wrap"
97
97
  };
98
98
  //#endregion
99
99
  //#region lib/client/A2aControl.js
@@ -145,8 +145,8 @@ window.__ModuleLoader__.load({
145
145
  children: [
146
146
  (0, react_jsx_runtime.jsx)("span", {
147
147
  className: clsx(A2aControl_module_css_default.activityDir, dir),
148
- "aria-label": dir === "in" ? "inbound" : "outbound",
149
- children: dir === "in" ? "←" : "→"
148
+ "aria-label": dir === "fwd" ? "forwarded" : dir === "in" ? "inbound" : "outbound",
149
+ children: dir === "fwd" ? "⇢" : dir === "in" ? "←" : "→"
150
150
  }),
151
151
  (0, react_jsx_runtime.jsx)("span", {
152
152
  className: A2aControl_module_css_default.activityTeam,