@nelsonlongxiang/dsh-open-a2a-net 0.6.33 → 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 (51) hide show
  1. package/README.md +5 -2
  2. package/README_zh.md +5 -2
  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/lib/a2a-client.js +9 -2
  7. package/lib/auth-observer.js +1 -1
  8. package/lib/canvas-store.js +44 -6
  9. package/lib/card.js +2 -1
  10. package/lib/cli-home.js +44 -0
  11. package/lib/client/A2aControl.js +1 -1
  12. package/lib/client.js +65 -65
  13. package/lib/client.js.map +1 -1
  14. package/lib/direct-forward.js +61 -0
  15. package/lib/faces/admin.js +41 -5
  16. package/lib/faces/wire.js +55 -16
  17. package/lib/index.js +110 -64
  18. package/lib/outbound-scope.js +25 -0
  19. package/lib/queue-guard.js +37 -0
  20. package/lib/skill/references/cli.md +5 -4
  21. package/lib/skill/references/pitfalls.md +1 -4
  22. package/lib/task-auth.js +52 -3
  23. package/lib/task-ledger.js +4 -1
  24. package/lib/tools/info.js +19 -3
  25. package/lib/types/a2a-client.d.ts +1 -1
  26. package/lib/types/auth-observer.d.ts +2 -2
  27. package/lib/types/canvas-store.d.ts +10 -1
  28. package/lib/types/cli-home.d.ts +24 -0
  29. package/lib/types/client/A2aControl.d.ts +1 -1
  30. package/lib/types/direct-forward.d.ts +32 -0
  31. package/lib/types/faces/admin.d.ts +8 -1
  32. package/lib/types/faces/wire.d.ts +12 -4
  33. package/lib/types/index.d.ts +4 -0
  34. package/lib/types/outbound-scope.d.ts +21 -0
  35. package/lib/types/queue-guard.d.ts +32 -0
  36. package/lib/types/runtime.d.ts +1 -1
  37. package/lib/types/task-auth.d.ts +17 -2
  38. package/lib/types/task-ledger.d.ts +6 -1
  39. package/lib/types/types.d.ts +8 -0
  40. package/nexus-stage/src/cli-home-picker.ts +42 -0
  41. package/nexus-stage/src/main.ts +9 -2
  42. package/nexus-stage/src/planning-card.ts +61 -0
  43. package/nexus-stage/src/planning-menus.ts +42 -7
  44. package/nexus-stage/src/planning-view.ts +14 -32
  45. package/nexus-stage/src/planning.css +17 -0
  46. package/nexus-stage/src/workbench.css +4 -0
  47. package/nexus-stage/src/workbench.ts +22 -5
  48. package/nexus-stage/src/world.ts +5 -1
  49. package/package.json +2 -1
  50. package/assets/nexusDist/assets/index-BACVZe0j.css +0 -1
  51. package/assets/nexusDist/assets/index-Bbxnpf2p.js +0 -9
@@ -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-Bbxnpf2p.js"></script>
22
- <link rel="stylesheet" crossorigin href="./assets/index-BACVZe0j.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/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,8 +263,10 @@ 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
+ }
241
270
  }
242
271
  }
243
272
  /** One policy predicate for local and signed-remote canvas creation. */
@@ -246,3 +275,12 @@ export function canvasNameReserved(raw, zone, allowlist, roster) {
246
275
  const team = `${zone}/${name}`;
247
276
  return name.startsWith('roster:') || allowlist.includes(team) || roster.membersOf(team).length > 0;
248
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;
285
+ }
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\release-0.6.33-485b362\src\src\client\A2aControl.module.css.mjs
26
- const css = "._9ANQVq_wrap{max-width:100%;display:inline-flex;position:relative}._9ANQVq_trigger{align-items:center;gap:4px;display:inline-flex;position:relative}._9ANQVq_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 _9ANQVq_badgePulse;position:absolute;top:-6px;right:-8px}@keyframes _9ANQVq_badgePulse{0%,to{box-shadow:0 0 #4c8bf573}50%{box-shadow:0 0 0 4px #4c8bf500}}@media (prefers-reduced-motion:reduce){._9ANQVq_unreadBadge{animation:none}}._9ANQVq_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}._9ANQVq_title{font-size:13px;font-weight:600}._9ANQVq_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}._9ANQVq_stageRow{border-top:1px solid var(--dsh-border,#2a2a30);align-items:center;gap:8px;margin-top:4px;padding-top:8px;display:flex}._9ANQVq_stageTitle{text-transform:uppercase;letter-spacing:.04em;opacity:.65;font-size:11px;font-weight:600}._9ANQVq_stageLinks{gap:6px;display:flex}._9ANQVq_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}._9ANQVq_stageLink:hover,._9ANQVq_stageLink:focus-visible{border-color:var(--dsh-accent,#4c8bf5)}._9ANQVq_empty{opacity:.7;font-size:12px}._9ANQVq_row{border:1px solid #0000;border-radius:8px;align-items:center;gap:10px;padding:8px;display:flex}._9ANQVq_joined{border-color:var(--dsh-border,#2a2a30)}._9ANQVq_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}._9ANQVq_facts:hover{background:var(--dsh-surface-hover,#ffffff0f)}._9ANQVq_nameRow{align-items:center;gap:6px;display:flex}._9ANQVq_stateDot{border-radius:50%;flex:none;width:7px;height:7px}._9ANQVq_stateDot._9ANQVq_live{background:var(--dsh-accent,#4c8bf5)}._9ANQVq_stateDot._9ANQVq_live._9ANQVq_joined{background:var(--dsh-success,#3fb96f)}._9ANQVq_stateDot._9ANQVq_cold{background:var(--dsh-warning,#d9a13c)}._9ANQVq_name{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;overflow:hidden}._9ANQVq_description{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}._9ANQVq_team{opacity:.55;font-size:11px;font-family:var(--dsh-mono,monospace)}._9ANQVq_note{opacity:.6;font-size:11px}._9ANQVq_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}._9ANQVq_searchInput:focus{outline:1px solid var(--dsh-accent,#4c8bf5)}._9ANQVq_sessionGroup{flex-direction:column;gap:2px;display:flex}._9ANQVq_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}._9ANQVq_groupChevron{transition:transform .12s;display:inline-block}._9ANQVq_groupChevronClosed{transform:rotate(-90deg)}._9ANQVq_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}._9ANQVq_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}._9ANQVq_groupButton:hover{border-color:var(--dsh-border,#2a2a30);opacity:1}._9ANQVq_groupPicker{border:1px dashed var(--dsh-border,#2a2a30);border-radius:8px;flex-wrap:wrap;gap:6px;width:100%;padding:8px;display:flex;position:relative}._9ANQVq_groupOption{border:1px solid var(--dsh-border,#2a2a30);color:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:2px 8px;font-size:11px}._9ANQVq_groupOptionActive{border-color:var(--dsh-accent,#4c8bf5);color:var(--dsh-accent,#4c8bf5)}._9ANQVq_groupNew{align-items:center;gap:6px;width:100%;margin-top:2px;display:flex}._9ANQVq_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}._9ANQVq_peerGrid{flex-wrap:wrap;gap:6px;display:flex}._9ANQVq_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}._9ANQVq_peerHost{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}._9ANQVq_peerScore{font-family:var(--dsh-mono,monospace);opacity:.6}._9ANQVq_activityList{flex-direction:column;gap:2px;display:flex}._9ANQVq_activityRow{border-radius:4px;align-items:center;gap:8px;padding:2px 4px;font-size:11px;display:flex}._9ANQVq_activityRow[data-ok=false]{opacity:.55}._9ANQVq_activityDir{flex:none;font-weight:600}._9ANQVq_activityDir._9ANQVq_in{color:var(--dsh-success,#3fb96f)}._9ANQVq_activityDir._9ANQVq_out{color:var(--dsh-accent,#4c8bf5)}._9ANQVq_activityTeam{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--dsh-mono,monospace);opacity:.8;flex:1;overflow:hidden}._9ANQVq_activityPeer{text-overflow:ellipsis;white-space:nowrap;opacity:.55;max-width:90px;overflow:hidden}._9ANQVq_activityTime{opacity:.5;font-family:var(--dsh-mono,monospace);flex:none}._9ANQVq_activityRow[data-jump=true]{cursor:pointer}._9ANQVq_activityRow[data-jump=true]:hover{background:var(--dsh-surface-hover,#ffffff0f)}._9ANQVq_fresh{animation:1.2s ease-out 3 _9ANQVq_freshFlash}@keyframes _9ANQVq_freshFlash{0%{background:#4c8bf538}to{background:0 0}}@media (prefers-reduced-motion:reduce){._9ANQVq_fresh{background:#4c8bf51f;animation:none}}._9ANQVq_inFlightList{flex-direction:column;gap:2px;margin-bottom:4px;display:flex}._9ANQVq_inFlightRow{border:1px dashed var(--dsh-border,#2a2a30);border-radius:4px;align-items:center;gap:8px;padding:3px 4px;font-size:11px;display:flex}._9ANQVq_inFlightPulse{background:var(--dsh-accent,#4c8bf5);border-radius:50%;flex:none;width:7px;height:7px;animation:1.1s ease-in-out infinite _9ANQVq_flightPulse}@keyframes _9ANQVq_flightPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(.55)}}@media (prefers-reduced-motion:reduce){._9ANQVq_inFlightPulse{animation:none}}._9ANQVq_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}._9ANQVq_inFlightStale{opacity:.55}._9ANQVq_canvasCreate{align-items:center;gap:6px;margin-bottom:4px;display:flex}._9ANQVq_canvasCreate ._9ANQVq_groupInput{flex:1;min-width:0}._9ANQVq_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}._9ANQVq_canvasChip>span:not([class]){white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._9ANQVq_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}._9ANQVq_canvasChipRemove:hover{color:var(--dsh-color-text-primary,#eee)}._9ANQVq_canvasChipRemove{transition:color .14s ease-out}@media (prefers-reduced-motion:reduce){._9ANQVq_canvasChipRemove{transition:none}}._9ANQVq_canvasChipRemove:focus-visible{outline:2px solid var(--dsh-color-primary,#4f8cff);outline-offset:1px;border-radius:4px}._9ANQVq_canvasActions{gap:6px;margin-top:4px;display:flex}._9ANQVq_inFlightStale ._9ANQVq_inFlightPulse{opacity:.4;animation:none}._9ANQVq_failMark{color:#f87171;flex-shrink:0;font-size:11px}._9ANQVq_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": "_9ANQVq_activityDir",
37
- "activityList": "_9ANQVq_activityList",
38
- "activityPeer": "_9ANQVq_activityPeer",
39
- "activityRow": "_9ANQVq_activityRow",
40
- "activityTeam": "_9ANQVq_activityTeam",
41
- "activityTime": "_9ANQVq_activityTime",
42
- "badgePulse": "_9ANQVq_badgePulse",
43
- "canvasActions": "_9ANQVq_canvasActions",
44
- "canvasChip": "_9ANQVq_canvasChip",
45
- "canvasChipRemove": "_9ANQVq_canvasChipRemove",
46
- "canvasCreate": "_9ANQVq_canvasCreate",
47
- "cold": "_9ANQVq_cold",
48
- "description": "_9ANQVq_description",
49
- "empty": "_9ANQVq_empty",
50
- "facts": "_9ANQVq_facts",
51
- "failMark": "_9ANQVq_failMark",
52
- "flightPulse": "_9ANQVq_flightPulse",
53
- "fresh": "_9ANQVq_fresh",
54
- "freshFlash": "_9ANQVq_freshFlash",
55
- "groupButton": "_9ANQVq_groupButton",
56
- "groupChevron": "_9ANQVq_groupChevron",
57
- "groupChevronClosed": "_9ANQVq_groupChevronClosed",
58
- "groupHead": "_9ANQVq_groupHead",
59
- "groupInput": "_9ANQVq_groupInput",
60
- "groupNew": "_9ANQVq_groupNew",
61
- "groupOption": "_9ANQVq_groupOption",
62
- "groupOptionActive": "_9ANQVq_groupOptionActive",
63
- "groupPicker": "_9ANQVq_groupPicker",
64
- "groupTag": "_9ANQVq_groupTag",
65
- "in": "_9ANQVq_in",
66
- "inFlightList": "_9ANQVq_inFlightList",
67
- "inFlightPulse": "_9ANQVq_inFlightPulse",
68
- "inFlightRow": "_9ANQVq_inFlightRow",
69
- "inFlightStale": "_9ANQVq_inFlightStale",
70
- "joined": "_9ANQVq_joined",
71
- "live": "_9ANQVq_live",
72
- "name": "_9ANQVq_name",
73
- "nameRow": "_9ANQVq_nameRow",
74
- "note": "_9ANQVq_note",
75
- "out": "_9ANQVq_out",
76
- "peerChip": "_9ANQVq_peerChip",
77
- "peerGrid": "_9ANQVq_peerGrid",
78
- "peerHost": "_9ANQVq_peerHost",
79
- "peerScore": "_9ANQVq_peerScore",
80
- "popover": "_9ANQVq_popover",
81
- "row": "_9ANQVq_row",
82
- "searchInput": "_9ANQVq_searchInput",
83
- "sectionTitle": "_9ANQVq_sectionTitle",
84
- "sessionGroup": "_9ANQVq_sessionGroup",
85
- "stageLink": "_9ANQVq_stageLink",
86
- "stageLinks": "_9ANQVq_stageLinks",
87
- "stageRow": "_9ANQVq_stageRow",
88
- "stageTitle": "_9ANQVq_stageTitle",
89
- "staleNote": "_9ANQVq_staleNote",
90
- "stateDot": "_9ANQVq_stateDot",
91
- "team": "_9ANQVq_team",
92
- "title": "_9ANQVq_title",
93
- "trigger": "_9ANQVq_trigger",
94
- "unreadBadge": "_9ANQVq_unreadBadge",
95
- "versionTag": "_9ANQVq_versionTag",
96
- "wrap": "_9ANQVq_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,
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["css","Button","IconGlobeOutlineRegular","_Fragment"],"sources":["../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","client/A2aControl.js","client/locales.js","client/index.js"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\n/**\n * A2A network control: a footer action opening this host's recent network\n * activity feed. The feed is the panel's whole content — in-flight routes,\n * owed receipts, and the routing activity ring. Session/team management\n * lives in the planning view (design: docs/design/panel-activity-feed.md):\n * the stage links row above the feed is the explicit navigation to it.\n * Probes the host's state route at registration time (the seat renders only\n * on a host that serves it). While open, the feed polls so it visibly\n * follows each turn; the closed trigger's unread badge rides a slow poll.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport clsx from 'clsx';\nimport { Button, IconGlobeOutlineRegular } from '@deepseek-ai/dsh-client-ui-primitives';\nimport css from './A2aControl.module.css';\n/** Fetch the host's network state; undefined means the route is absent. */\nasync function fetchState() {\n const response = await fetch('/__dsh_a2a/state', { cache: 'no-store' });\n if (!response.ok)\n return undefined;\n const body = await response.json();\n if (body.nodes !== true || !Array.isArray(body.sessions))\n return undefined;\n return {\n sessions: body.sessions,\n activity: Array.isArray(body.activity) ? body.activity : [],\n inFlight: Array.isArray(body.inFlight) ? body.inFlight : [],\n tasks: Array.isArray(body.tasks) ? body.tasks : [],\n ...(typeof body.tasksStaleCount === 'number' ? { tasksStaleCount: body.tasksStaleCount } : {}),\n ...(typeof body.version === 'string' ? { version: body.version } : {}),\n };\n}\n/** Compact relative time for an activity row. */\nfunction relativeTime(ts) {\n const seconds = Math.max(0, Math.round((Date.now() - ts) / 1000));\n if (seconds < 60)\n return `${String(seconds)}s`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60)\n return `${String(minutes)}m`;\n return `${String(Math.round(minutes / 60))}h`;\n}\n/** One feed row: direction glyph (aria-labelled), team, peer host, age, fail mark. */\nfunction FeedRow({ dir, team, peer, ts, ok, target, openSession, t }) {\n const fresh = Date.now() - ts < 5_000;\n 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)\n 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) })] }));\n}\n/**\n * Render the network toggle and its activity feed.\n * @param props - composed slot props.\n * @returns the control element tree.\n */\nexport function A2aControl({ wide, t, openSession }) {\n const [open, setOpen] = useState(false);\n const [state, setState] = useState({ sessions: [], activity: [], inFlight: [], tasks: [] });\n const [seenActivity, setSeenActivity] = useState(0);\n const stopped = useRef(false);\n useEffect(() => () => { stopped.current = true; }, []);\n const wrap = useRef(null);\n // The popover anchors to the trigger's viewport rect: the sidebar column\n // clips its descendants (the collapse slide), so an in-column absolute\n // popover is cut at the column edge whenever the column is narrower than\n // the popover; fixed positioning escapes the clip at rest (the ui-settings\n // panel precedent). The left edge clamps so a narrow viewport never hides\n // the popover's right side.\n const [anchor, setAnchor] = useState(null);\n // The unread badge counts inbound activity entries that arrived while the\n // panel was closed; opening the panel clears it.\n const unread = Math.max(0, state.activity.filter(entry => entry.dir === 'in').length - seenActivity);\n const toggleOpen = () => {\n if (open) {\n setOpen(false);\n return;\n }\n const rect = wrap.current?.getBoundingClientRect();\n if (rect !== undefined) {\n setAnchor({\n left: Math.max(8, Math.min(rect.left, window.innerWidth - 336)),\n bottom: window.innerHeight - rect.top + 8,\n });\n }\n setSeenActivity(state.activity.filter(entry => entry.dir === 'in').length);\n setOpen(true);\n };\n const refresh = useCallback(() => {\n void fetchState().then((next) => {\n if (!stopped.current && next !== undefined)\n setState(next);\n }).catch(() => { });\n }, []);\n useEffect(() => {\n if (open)\n refresh();\n }, [open, refresh]);\n useEffect(() => {\n // The unread badge lives on the closed trigger, so the state must move\n // even while the panel is closed — a slow poll keeps it fresh; the open\n // panel's faster poll below takes over while visible.\n const slow = setInterval(refresh, 10_000);\n refresh();\n return () => { clearInterval(slow); };\n }, [refresh]);\n useEffect(() => {\n if (!open)\n return;\n // While the feed is open, it polls so the ring visibly follows turns.\n const poll = setInterval(refresh, 2_000);\n return () => { clearInterval(poll); };\n }, [open, refresh]);\n useEffect(() => {\n if (!open)\n return;\n const onPointerDown = (event) => {\n if (event.target.closest(`.${css.wrap}`) === null)\n setOpen(false);\n };\n document.addEventListener('pointerdown', onPointerDown);\n return () => { document.removeEventListener('pointerdown', onPointerDown); };\n }, [open]);\n // 0.6.10: the receive face of click-to-reach (0.6.7 BroadcastChannel,\n // 0.6.8 ?dsh-a2a-open deep link) is removed by ruling — 禁止任何跳转,\n // 全部使用响应式布局. The workbench's 快派 form is the only cross-surface\n // reach primitive and it stays on the workbench page; this panel's\n // FeedRow openSession remains (it switches a conversation in place inside\n // the GUI — no navigation).\n const { sessions, activity, inFlight, tasks } = state;\n return (_jsxs(\"div\", { ref: wrap, className: clsx(css.wrap, wide ? css.wide : css.rail), children: [_jsx(Button, { variant: \"ghost\", size: \"sm\", title: t('a2a.label'), \"aria-label\": t('a2a.label'), \"aria-expanded\": open, onClick: () => { toggleOpen(); }, children: _jsxs(\"span\", { className: css.trigger, children: [_jsx(IconGlobeOutlineRegular, {}), wide ? _jsx(\"span\", { children: t('a2a.label') }) : null, unread > 0 ? _jsx(\"span\", { className: css.unreadBadge, \"aria-label\": String(unread), children: unread > 9 ? '9+' : String(unread) }) : null] }) }), open\n ? (_jsxs(\"div\", { className: css.popover, role: \"dialog\", \"aria-label\": t('a2a.title'), style: anchor === null ? undefined : { left: `${String(anchor.left)}px`, bottom: `${String(anchor.bottom)}px` }, children: [_jsxs(\"div\", { className: css.title, children: [t('a2a.title'), state.version !== undefined ? _jsxs(\"span\", { className: css.versionTag, title: state.version, children: [\"v\", state.version] }) : null] }), _jsxs(\"div\", { className: css.stageRow, children: [_jsx(\"span\", { className: css.stageTitle, children: t('a2a.stageTitle') }), _jsx(\"span\", { className: css.stageLinks, children: _jsx(\"a\", { className: css.stageLink, href: \"/__dsh_a2a_nexus/\", target: \"_blank\", rel: \"noreferrer\", title: t('a2a.stageWorkbench'), children: t('a2a.stageWorkbench') }) })] }), _jsxs(\"div\", { \"aria-live\": \"polite\", children: [inFlight.length > 0 && (_jsx(\"div\", { className: css.inFlightList, \"aria-label\": t('a2a.inFlight'), children: inFlight.map((route) => (_jsxs(\"div\", { className: clsx(css.inFlightRow, Date.now() - route.startedAt > 120_000 && css.inFlightStale), title: Date.now() - route.startedAt > 120_000 ? t('a2a.inFlightStale') : undefined, children: [_jsx(\"span\", { className: css.inFlightPulse, \"aria-hidden\": true }), _jsx(FeedRow, { dir: \"out\", team: route.team, peer: route.peer, ts: route.startedAt, openSession: openSession, t: t })] }, `${route.team}-${String(route.startedAt)}`))) })), (() => {\n // C-ruling: render only settleable debt; the stale tail is a\n // count line, never a row-per-noise listing.\n const settleableTasks = tasks.filter(task => task.settleable !== false);\n const staleCount = state.tasksStaleCount ?? (tasks.length - settleableTasks.length);\n if (settleableTasks.length === 0 && staleCount === 0)\n return null;\n return (_jsxs(_Fragment, { children: [settleableTasks.length > 0 && (_jsxs(_Fragment, { children: [_jsx(\"div\", { className: css.sectionTitle, children: t('a2a.tasks') }), _jsx(\"div\", { className: css.inFlightList, \"aria-label\": t('a2a.tasks'), children: settleableTasks.map((task) => (_jsx(\"div\", { className: css.inFlightRow, title: t('a2a.tasksNote'), children: _jsx(FeedRow, { dir: \"out\", team: task.team, peer: task.peer, ts: task.startedAt, openSession: openSession, t: t }) }, task.taskId))) })] })), staleCount > 0 && (_jsxs(\"div\", { className: css.staleNote, title: t('a2a.tasksNote'), children: [t('a2a.tasksStale'), \" \\u00B7 \", String(staleCount)] }))] }));\n })(), _jsx(\"div\", { className: css.sectionTitle, children: t('a2a.activity') }), activity.length === 0\n ? _jsx(\"div\", { className: css.empty, children: t('a2a.activityEmpty') })\n : (_jsx(\"div\", { className: css.activityList, children: [...activity].reverse().slice(0, 10).map((entry, index) => {\n // A same-host session team resolves to its session row;\n // clicking the activity line jumps there (the linkage\n // into an ongoing collaboration).\n const target = sessions.find(row => row.team === entry.team);\n return (_jsx(FeedRow, { dir: entry.dir, team: entry.team, peer: entry.peer, ts: entry.ts, ok: entry.ok, ...(target !== undefined ? { target } : {}), openSession: openSession, t: t }, `${String(entry.ts)}-${String(index)}`));\n }) }))] })] }))\n : null] }));\n}\n","/** Locale dictionaries for the A2A network sidebar control (namespace `a2aNet`). */\n/** Simplified Chinese dictionary. */\nexport const zh = {\n 'a2a.label': 'A2A 网络',\n 'a2a.title': 'A2A 网络动态',\n 'a2a.activity': '最近动态',\n 'a2a.activityEmpty': '暂无网络动态——加入网络即可开始协作',\n 'a2a.inFlight': '进行中的路由',\n 'a2a.inFlightStale': '等待回执超时(对端处理慢或回执丢失);180 秒后自动解除并按已送达处理',\n 'a2a.tasks': '欠回执的异步任务',\n 'a2a.tasksNote': '异步欠账分三段:未决(等回执)→ 死信(超期自动标注,目标恢复后仍可补回执结算)→ 归档(结算留痕不蒸发)',\n 'a2a.tasksStale': '对话式已送达未答(非欠账,24h 自动死信)',\n 'a2a.jump': '点击跳转到该会话',\n 'a2a.stageTitle': 'A2A 工作台(目录 · 台账 · 活动 · 规划)',\n 'a2a.stageWorkbench': '打开工作台',\n};\n/** English dictionary. */\nexport const en = {\n 'a2a.label': 'A2A network',\n 'a2a.title': 'A2A network activity',\n 'a2a.activity': 'Recent activity',\n 'a2a.activityEmpty': 'No network activity yet — join sessions to the network to start collaborating',\n 'a2a.inFlight': 'Routes in flight',\n 'a2a.inFlightStale': 'Reply wait past 120s (slow or lost receipt); auto-releases as delivered at 180s',\n 'a2a.tasks': 'Owed receipts',\n 'a2a.tasksNote': 'Async debts in three tiers: pending (awaiting receipt) → dead-lettered (auto-flagged past the stale TTL; a revived target can still settle late) → archived (settled records kept for audit)',\n 'a2a.tasksStale': 'Delivered conversationally, no formal receipt (not debt; auto-dead-letters at the TTL)',\n 'a2a.jump': 'Click to open this session',\n 'a2a.stageTitle': 'A2A workbench (directory · ledger · activity · plan)',\n 'a2a.stageWorkbench': 'Open workbench',\n};\n","import { A2aControl } from \"./A2aControl.js\";\nimport { en, zh } from \"./locales.js\";\n/** Dictionary namespace owned by this plugin (network control copy). */\nconst NS = 'a2aNet';\n/** Services required by the browser half: the slot system, the sessions\n * flow used to wake cold rows, and the locale dictionaries. */\nexport const inject = ['slots', 'sessions', 'locale'];\n/** Registers the network control's dictionaries and its sidebar seat.\n * @param ctx - Client root context.\n */\nexport function apply(ctx) {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'a2a-net: dictionaries');\n // The network control renders only on a host that serves the session-node\n // state route (a2a host half + session nodes composed); the probe keeps\n // the seat quiet everywhere else.\n void fetch('/__dsh_a2a/state', { cache: 'no-store' })\n .then(response => (response.ok ? response.json() : undefined))\n .then((info) => {\n if (info?.nodes !== true)\n return;\n ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({\n name: 'sidebar.footer.action',\n id: 'a2a',\n order: 10,\n locale: NS,\n // Wake = the standard session-open flow: the host materializes the\n // session's agent and the a2a host half's persisted intent remounts\n // the node, so the cold row flips live on the next poll.\n inject: () => ({\n openSession: (id) => { ctx.sessions.open(id); },\n }),\n }, A2aControl));\n })\n .catch(() => { });\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["css","Button","IconGlobeOutlineRegular","_Fragment"],"sources":["../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","client/A2aControl.js","client/locales.js","client/index.js"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\n/**\n * A2A network control: a footer action opening this host's recent network\n * activity feed. The feed is the panel's whole content — in-flight routes,\n * owed receipts, and the routing activity ring. Session/team management\n * lives in the planning view (design: docs/design/panel-activity-feed.md):\n * the stage links row above the feed is the explicit navigation to it.\n * Probes the host's state route at registration time (the seat renders only\n * on a host that serves it). While open, the feed polls so it visibly\n * follows each turn; the closed trigger's unread badge rides a slow poll.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport clsx from 'clsx';\nimport { Button, IconGlobeOutlineRegular } from '@deepseek-ai/dsh-client-ui-primitives';\nimport css from './A2aControl.module.css';\n/** Fetch the host's network state; undefined means the route is absent. */\nasync function fetchState() {\n const response = await fetch('/__dsh_a2a/state', { cache: 'no-store' });\n if (!response.ok)\n return undefined;\n const body = await response.json();\n if (body.nodes !== true || !Array.isArray(body.sessions))\n return undefined;\n return {\n sessions: body.sessions,\n activity: Array.isArray(body.activity) ? body.activity : [],\n inFlight: Array.isArray(body.inFlight) ? body.inFlight : [],\n tasks: Array.isArray(body.tasks) ? body.tasks : [],\n ...(typeof body.tasksStaleCount === 'number' ? { tasksStaleCount: body.tasksStaleCount } : {}),\n ...(typeof body.version === 'string' ? { version: body.version } : {}),\n };\n}\n/** Compact relative time for an activity row. */\nfunction relativeTime(ts) {\n const seconds = Math.max(0, Math.round((Date.now() - ts) / 1000));\n if (seconds < 60)\n return `${String(seconds)}s`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60)\n return `${String(minutes)}m`;\n return `${String(Math.round(minutes / 60))}h`;\n}\n/** One feed row: direction glyph (aria-labelled), team, peer host, age, fail mark. */\nfunction FeedRow({ dir, team, peer, ts, ok, target, openSession, t }) {\n const fresh = Date.now() - ts < 5_000;\n 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)\n 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) })] }));\n}\n/**\n * Render the network toggle and its activity feed.\n * @param props - composed slot props.\n * @returns the control element tree.\n */\nexport function A2aControl({ wide, t, openSession }) {\n const [open, setOpen] = useState(false);\n const [state, setState] = useState({ sessions: [], activity: [], inFlight: [], tasks: [] });\n const [seenActivity, setSeenActivity] = useState(0);\n const stopped = useRef(false);\n useEffect(() => () => { stopped.current = true; }, []);\n const wrap = useRef(null);\n // The popover anchors to the trigger's viewport rect: the sidebar column\n // clips its descendants (the collapse slide), so an in-column absolute\n // popover is cut at the column edge whenever the column is narrower than\n // the popover; fixed positioning escapes the clip at rest (the ui-settings\n // panel precedent). The left edge clamps so a narrow viewport never hides\n // the popover's right side.\n const [anchor, setAnchor] = useState(null);\n // The unread badge counts inbound activity entries that arrived while the\n // panel was closed; opening the panel clears it.\n const unread = Math.max(0, state.activity.filter(entry => entry.dir === 'in').length - seenActivity);\n const toggleOpen = () => {\n if (open) {\n setOpen(false);\n return;\n }\n const rect = wrap.current?.getBoundingClientRect();\n if (rect !== undefined) {\n setAnchor({\n left: Math.max(8, Math.min(rect.left, window.innerWidth - 336)),\n bottom: window.innerHeight - rect.top + 8,\n });\n }\n setSeenActivity(state.activity.filter(entry => entry.dir === 'in').length);\n setOpen(true);\n };\n const refresh = useCallback(() => {\n void fetchState().then((next) => {\n if (!stopped.current && next !== undefined)\n setState(next);\n }).catch(() => { });\n }, []);\n useEffect(() => {\n if (open)\n refresh();\n }, [open, refresh]);\n useEffect(() => {\n // The unread badge lives on the closed trigger, so the state must move\n // even while the panel is closed — a slow poll keeps it fresh; the open\n // panel's faster poll below takes over while visible.\n const slow = setInterval(refresh, 10_000);\n refresh();\n return () => { clearInterval(slow); };\n }, [refresh]);\n useEffect(() => {\n if (!open)\n return;\n // While the feed is open, it polls so the ring visibly follows turns.\n const poll = setInterval(refresh, 2_000);\n return () => { clearInterval(poll); };\n }, [open, refresh]);\n useEffect(() => {\n if (!open)\n return;\n const onPointerDown = (event) => {\n if (event.target.closest(`.${css.wrap}`) === null)\n setOpen(false);\n };\n document.addEventListener('pointerdown', onPointerDown);\n return () => { document.removeEventListener('pointerdown', onPointerDown); };\n }, [open]);\n // 0.6.10: the receive face of click-to-reach (0.6.7 BroadcastChannel,\n // 0.6.8 ?dsh-a2a-open deep link) is removed by ruling — 禁止任何跳转,\n // 全部使用响应式布局. The workbench's 快派 form is the only cross-surface\n // reach primitive and it stays on the workbench page; this panel's\n // FeedRow openSession remains (it switches a conversation in place inside\n // the GUI — no navigation).\n const { sessions, activity, inFlight, tasks } = state;\n return (_jsxs(\"div\", { ref: wrap, className: clsx(css.wrap, wide ? css.wide : css.rail), children: [_jsx(Button, { variant: \"ghost\", size: \"sm\", title: t('a2a.label'), \"aria-label\": t('a2a.label'), \"aria-expanded\": open, onClick: () => { toggleOpen(); }, children: _jsxs(\"span\", { className: css.trigger, children: [_jsx(IconGlobeOutlineRegular, {}), wide ? _jsx(\"span\", { children: t('a2a.label') }) : null, unread > 0 ? _jsx(\"span\", { className: css.unreadBadge, \"aria-label\": String(unread), children: unread > 9 ? '9+' : String(unread) }) : null] }) }), open\n ? (_jsxs(\"div\", { className: css.popover, role: \"dialog\", \"aria-label\": t('a2a.title'), style: anchor === null ? undefined : { left: `${String(anchor.left)}px`, bottom: `${String(anchor.bottom)}px` }, children: [_jsxs(\"div\", { className: css.title, children: [t('a2a.title'), state.version !== undefined ? _jsxs(\"span\", { className: css.versionTag, title: state.version, children: [\"v\", state.version] }) : null] }), _jsxs(\"div\", { className: css.stageRow, children: [_jsx(\"span\", { className: css.stageTitle, children: t('a2a.stageTitle') }), _jsx(\"span\", { className: css.stageLinks, children: _jsx(\"a\", { className: css.stageLink, href: \"/__dsh_a2a_nexus/\", target: \"_blank\", rel: \"noreferrer\", title: t('a2a.stageWorkbench'), children: t('a2a.stageWorkbench') }) })] }), _jsxs(\"div\", { \"aria-live\": \"polite\", children: [inFlight.length > 0 && (_jsx(\"div\", { className: css.inFlightList, \"aria-label\": t('a2a.inFlight'), children: inFlight.map((route) => (_jsxs(\"div\", { className: clsx(css.inFlightRow, Date.now() - route.startedAt > 120_000 && css.inFlightStale), title: Date.now() - route.startedAt > 120_000 ? t('a2a.inFlightStale') : undefined, children: [_jsx(\"span\", { className: css.inFlightPulse, \"aria-hidden\": true }), _jsx(FeedRow, { dir: \"out\", team: route.team, peer: route.peer, ts: route.startedAt, openSession: openSession, t: t })] }, `${route.team}-${String(route.startedAt)}`))) })), (() => {\n // C-ruling: render only settleable debt; the stale tail is a\n // count line, never a row-per-noise listing.\n const settleableTasks = tasks.filter(task => task.settleable !== false);\n const staleCount = state.tasksStaleCount ?? (tasks.length - settleableTasks.length);\n if (settleableTasks.length === 0 && staleCount === 0)\n return null;\n return (_jsxs(_Fragment, { children: [settleableTasks.length > 0 && (_jsxs(_Fragment, { children: [_jsx(\"div\", { className: css.sectionTitle, children: t('a2a.tasks') }), _jsx(\"div\", { className: css.inFlightList, \"aria-label\": t('a2a.tasks'), children: settleableTasks.map((task) => (_jsx(\"div\", { className: css.inFlightRow, title: t('a2a.tasksNote'), children: _jsx(FeedRow, { dir: \"out\", team: task.team, peer: task.peer, ts: task.startedAt, openSession: openSession, t: t }) }, task.taskId))) })] })), staleCount > 0 && (_jsxs(\"div\", { className: css.staleNote, title: t('a2a.tasksNote'), children: [t('a2a.tasksStale'), \" \\u00B7 \", String(staleCount)] }))] }));\n })(), _jsx(\"div\", { className: css.sectionTitle, children: t('a2a.activity') }), activity.length === 0\n ? _jsx(\"div\", { className: css.empty, children: t('a2a.activityEmpty') })\n : (_jsx(\"div\", { className: css.activityList, children: [...activity].reverse().slice(0, 10).map((entry, index) => {\n // A same-host session team resolves to its session row;\n // clicking the activity line jumps there (the linkage\n // into an ongoing collaboration).\n const target = sessions.find(row => row.team === entry.team);\n return (_jsx(FeedRow, { dir: entry.dir, team: entry.team, peer: entry.peer, ts: entry.ts, ok: entry.ok, ...(target !== undefined ? { target } : {}), openSession: openSession, t: t }, `${String(entry.ts)}-${String(index)}`));\n }) }))] })] }))\n : null] }));\n}\n","/** Locale dictionaries for the A2A network sidebar control (namespace `a2aNet`). */\n/** Simplified Chinese dictionary. */\nexport const zh = {\n 'a2a.label': 'A2A 网络',\n 'a2a.title': 'A2A 网络动态',\n 'a2a.activity': '最近动态',\n 'a2a.activityEmpty': '暂无网络动态——加入网络即可开始协作',\n 'a2a.inFlight': '进行中的路由',\n 'a2a.inFlightStale': '等待回执超时(对端处理慢或回执丢失);180 秒后自动解除并按已送达处理',\n 'a2a.tasks': '欠回执的异步任务',\n 'a2a.tasksNote': '异步欠账分三段:未决(等回执)→ 死信(超期自动标注,目标恢复后仍可补回执结算)→ 归档(结算留痕不蒸发)',\n 'a2a.tasksStale': '对话式已送达未答(非欠账,24h 自动死信)',\n 'a2a.jump': '点击跳转到该会话',\n 'a2a.stageTitle': 'A2A 工作台(目录 · 台账 · 活动 · 规划)',\n 'a2a.stageWorkbench': '打开工作台',\n};\n/** English dictionary. */\nexport const en = {\n 'a2a.label': 'A2A network',\n 'a2a.title': 'A2A network activity',\n 'a2a.activity': 'Recent activity',\n 'a2a.activityEmpty': 'No network activity yet — join sessions to the network to start collaborating',\n 'a2a.inFlight': 'Routes in flight',\n 'a2a.inFlightStale': 'Reply wait past 120s (slow or lost receipt); auto-releases as delivered at 180s',\n 'a2a.tasks': 'Owed receipts',\n 'a2a.tasksNote': 'Async debts in three tiers: pending (awaiting receipt) → dead-lettered (auto-flagged past the stale TTL; a revived target can still settle late) → archived (settled records kept for audit)',\n 'a2a.tasksStale': 'Delivered conversationally, no formal receipt (not debt; auto-dead-letters at the TTL)',\n 'a2a.jump': 'Click to open this session',\n 'a2a.stageTitle': 'A2A workbench (directory · ledger · activity · plan)',\n 'a2a.stageWorkbench': 'Open workbench',\n};\n","import { A2aControl } from \"./A2aControl.js\";\nimport { en, zh } from \"./locales.js\";\n/** Dictionary namespace owned by this plugin (network control copy). */\nconst NS = 'a2aNet';\n/** Services required by the browser half: the slot system, the sessions\n * flow used to wake cold rows, and the locale dictionaries. */\nexport const inject = ['slots', 'sessions', 'locale'];\n/** Registers the network control's dictionaries and its sidebar seat.\n * @param ctx - Client root context.\n */\nexport function apply(ctx) {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'a2a-net: dictionaries');\n // The network control renders only on a host that serves the session-node\n // state route (a2a host half + session nodes composed); the probe keeps\n // the seat quiet everywhere else.\n void fetch('/__dsh_a2a/state', { cache: 'no-store' })\n .then(response => (response.ok ? response.json() : undefined))\n .then((info) => {\n if (info?.nodes !== true)\n return;\n ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({\n name: 'sidebar.footer.action',\n id: 'a2a',\n order: 10,\n locale: NS,\n // Wake = the standard session-open flow: the host materializes the\n // session's agent and the a2a host half's persisted intent remounts\n // the node, so the cold row flips live on the next poll.\n inject: () => ({\n openSession: (id) => { ctx.sessions.open(id); },\n }),\n }, A2aControl));\n })\n .catch(() => { });\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}