@nelsonlongxiang/dsh-open-a2a-net 0.6.33 → 0.6.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/README_zh.md +5 -2
- package/assets/nexusDist/assets/index-Du2E6DJL.js +9 -0
- package/assets/nexusDist/assets/index-z33lHtLw.css +1 -0
- package/assets/nexusDist/index.html +2 -2
- package/cli/a2a.mjs +3 -1
- package/lib/a2a-client.js +9 -2
- package/lib/auth-observer.js +1 -1
- package/lib/canvas-store.js +64 -6
- package/lib/card.js +2 -1
- package/lib/cli-home.js +44 -0
- package/lib/client/A2aControl.js +1 -1
- package/lib/client.js +65 -65
- package/lib/client.js.map +1 -1
- package/lib/direct-forward.js +61 -0
- package/lib/faces/admin.js +43 -6
- package/lib/faces/wire.js +57 -40
- package/lib/flood-guard.js +7 -1
- package/lib/index.js +117 -65
- package/lib/outbound-scope.js +25 -0
- package/lib/queue-guard.js +37 -0
- package/lib/response-fields.js +27 -0
- package/lib/skill/references/cli.md +11 -4
- package/lib/skill/references/pitfalls.md +5 -4
- package/lib/skill/references/routing.md +4 -0
- package/lib/task-auth.js +52 -3
- package/lib/task-ledger.js +4 -1
- package/lib/tools/info.js +19 -3
- package/lib/types/a2a-client.d.ts +1 -1
- package/lib/types/auth-observer.d.ts +2 -2
- package/lib/types/canvas-store.d.ts +15 -1
- package/lib/types/cli-home.d.ts +24 -0
- package/lib/types/client/A2aControl.d.ts +1 -1
- package/lib/types/direct-forward.d.ts +32 -0
- package/lib/types/faces/admin.d.ts +8 -1
- package/lib/types/faces/wire.d.ts +12 -4
- package/lib/types/flood-guard.d.ts +5 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/outbound-scope.d.ts +21 -0
- package/lib/types/queue-guard.d.ts +32 -0
- package/lib/types/response-fields.d.ts +3 -0
- package/lib/types/runtime.d.ts +1 -1
- package/lib/types/task-auth.d.ts +17 -2
- package/lib/types/task-ledger.d.ts +6 -1
- package/lib/types/types.d.ts +8 -0
- package/nexus-stage/src/cli-home-picker.ts +42 -0
- package/nexus-stage/src/main.ts +9 -2
- package/nexus-stage/src/planning-card.ts +61 -0
- package/nexus-stage/src/planning-menus.ts +42 -7
- package/nexus-stage/src/planning-view.ts +14 -32
- package/nexus-stage/src/planning.css +17 -0
- package/nexus-stage/src/workbench.css +4 -0
- package/nexus-stage/src/workbench.ts +28 -5
- package/nexus-stage/src/world.ts +5 -1
- package/package.json +2 -1
- package/assets/nexusDist/assets/index-BACVZe0j.css +0 -1
- 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-
|
|
22
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
21
|
+
<script type="module" crossorigin src="./assets/index-Du2E6DJL.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
|
@@ -959,13 +959,15 @@ async function main() {
|
|
|
959
959
|
const pending = s.tasks ?? []
|
|
960
960
|
const dead = s.tasksDead ?? []
|
|
961
961
|
const archived = s.archived ?? []
|
|
962
|
-
if (has('--json')) { console.log(JSON.stringify({ pending, dead, archived }, null, 2)); return }
|
|
962
|
+
if (has('--json')) { console.log(JSON.stringify({ pending, dead, archived, ...(s.settlement === undefined ? {} : { settlement: s.settlement }), ...(s.conservation === undefined ? {} : { conservation: s.conservation }) }, null, 2)); return }
|
|
963
963
|
console.log(`pending (${String(pending.length)}):`)
|
|
964
964
|
listCapped(pending, 20, t => ` ${String(t.taskId)} → ${String(t.team)} ${String(t.direction ?? '')}${senderTail(t)}`)
|
|
965
965
|
console.log(`dead (${String(dead.length)}):`)
|
|
966
966
|
listCapped(dead, 20, t => ` ${String(t.taskId)} → ${String(t.team)} (${String(t.reason ?? '?')})${senderTail(t)}`)
|
|
967
967
|
console.log(`archived (${String(archived.length)}):`)
|
|
968
968
|
listCapped(archived, 20, t => ` ${String(t.taskId)} ${String(t.outcome ?? '?')}${t.endedBy !== undefined && t.endedBy !== 'receipt' ? ` (${String(t.endedBy)})` : ''}${senderTail(t)}`)
|
|
969
|
+
if (s.conservation != null) console.log(`conservation: conserved=${String(s.conservation.conserved)} delta=${String(s.conservation.delta)}`)
|
|
970
|
+
if (s.settlement != null) console.log(`settlement: mode=${String(s.settlement.mode)} refusalsTotal=${String(s.settlement.refusalsTotal)} offChain=${String(s.settlement.offChain)}`)
|
|
969
971
|
return
|
|
970
972
|
}
|
|
971
973
|
if (cmd === 'status') {
|
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
|
}
|
package/lib/auth-observer.js
CHANGED
|
@@ -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)}…`;
|
package/lib/canvas-store.js
CHANGED
|
@@ -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,8 @@ 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 = {};
|
|
67
|
+
cliHomeCleared = new Set();
|
|
65
68
|
path;
|
|
66
69
|
listeners = new Set();
|
|
67
70
|
/**
|
|
@@ -103,6 +106,17 @@ export class CanvasStore {
|
|
|
103
106
|
kept.push({ name: String(entry.name), members });
|
|
104
107
|
}
|
|
105
108
|
this.teams = kept.slice(0, CANVAS_TEAM_CAP);
|
|
109
|
+
if (snapshot.cliHome !== null && typeof snapshot.cliHome === 'object' && !Array.isArray(snapshot.cliHome)) {
|
|
110
|
+
for (const [handle, home] of Object.entries(snapshot.cliHome)) {
|
|
111
|
+
if (CLI_HANDLE_RE.test(handle) && typeof home === 'string' && validHomeOrigin(home) && this.teams.some(t => t.members.includes(handle)))
|
|
112
|
+
this.cliHome[handle] = home;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (Array.isArray(snapshot.cliHomeCleared))
|
|
116
|
+
for (const handle of snapshot.cliHomeCleared) {
|
|
117
|
+
if (typeof handle === 'string' && CLI_HANDLE_RE.test(handle) && this.cliHome[handle] === undefined && this.teams.some(t => t.members.includes(handle)))
|
|
118
|
+
this.cliHomeCleared.add(handle);
|
|
119
|
+
}
|
|
106
120
|
}
|
|
107
121
|
catch {
|
|
108
122
|
// A corrupt store is not fatal: the user re-creates teams; routing
|
|
@@ -124,7 +138,7 @@ export class CanvasStore {
|
|
|
124
138
|
return;
|
|
125
139
|
try {
|
|
126
140
|
mkdirSync(dirname(this.path), { recursive: true });
|
|
127
|
-
const snapshot = { teams: this.teams.map(t => ({ name: t.name, members: [...t.members] })) };
|
|
141
|
+
const snapshot = { teams: this.teams.map(t => ({ name: t.name, members: [...t.members] })), ...(Object.keys(this.cliHome).length > 0 ? { cliHome: { ...this.cliHome } } : {}), ...(this.cliHomeCleared.size > 0 ? { cliHomeCleared: [...this.cliHomeCleared] } : {}) };
|
|
128
142
|
writeFileSync(this.path, JSON.stringify(snapshot), { mode: 0o600 });
|
|
129
143
|
}
|
|
130
144
|
catch {
|
|
@@ -145,6 +159,18 @@ export class CanvasStore {
|
|
|
145
159
|
const entry = this.teams.find(t => t.name === name);
|
|
146
160
|
return entry === undefined ? [] : [...entry.members];
|
|
147
161
|
}
|
|
162
|
+
/** Frozen, operator-linked CLI home; undefined means unknown or ambiguous. */
|
|
163
|
+
cliHomeOf(handle) { return this.cliHome[handle]; }
|
|
164
|
+
pinnedCliHomes() { return Object.entries(this.cliHome); }
|
|
165
|
+
wasCliHomeCleared(handle) { return this.cliHomeCleared.has(handle); }
|
|
166
|
+
clearCliHomeForLocal(handle) {
|
|
167
|
+
if (this.cliHome[handle] === undefined)
|
|
168
|
+
return false;
|
|
169
|
+
delete this.cliHome[handle];
|
|
170
|
+
this.cliHomeCleared.add(handle);
|
|
171
|
+
this.persist();
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
148
174
|
/**
|
|
149
175
|
* The named team's remote member refs (zone-qualified team handles) in
|
|
150
176
|
* routing-priority order — the failover tier after the local live/cold
|
|
@@ -184,7 +210,9 @@ export class CanvasStore {
|
|
|
184
210
|
const index = this.teams.findIndex(t => t.name === name);
|
|
185
211
|
if (index < 0)
|
|
186
212
|
return false;
|
|
187
|
-
this.teams.splice(index, 1);
|
|
213
|
+
const [removed] = this.teams.splice(index, 1);
|
|
214
|
+
for (const id of removed.members)
|
|
215
|
+
this.forgetUnusedHome(id);
|
|
188
216
|
this.persist();
|
|
189
217
|
return true;
|
|
190
218
|
}
|
|
@@ -194,17 +222,29 @@ export class CanvasStore {
|
|
|
194
222
|
* @param name - the existing team name.
|
|
195
223
|
* @param id - the member session id.
|
|
196
224
|
*/
|
|
197
|
-
addMember(name, id) {
|
|
198
|
-
if (id === '')
|
|
225
|
+
addMember(name, id, home, options = {}) {
|
|
226
|
+
if (id === '' || (home !== undefined && (!CLI_HANDLE_RE.test(id) || !validHomeOrigin(home))))
|
|
227
|
+
return false;
|
|
228
|
+
if (home !== undefined && this.cliHome[id] !== undefined && this.cliHome[id] !== home && options.replaceHome !== true)
|
|
199
229
|
return false;
|
|
200
230
|
const entry = this.teams.find(t => t.name === name);
|
|
201
231
|
if (entry === undefined)
|
|
202
232
|
return false;
|
|
203
|
-
if (entry.members.includes(id))
|
|
233
|
+
if (entry.members.includes(id)) {
|
|
234
|
+
if (home !== undefined && this.cliHome[id] !== home) {
|
|
235
|
+
this.cliHome[id] = home;
|
|
236
|
+
this.cliHomeCleared.delete(id);
|
|
237
|
+
this.persist();
|
|
238
|
+
}
|
|
204
239
|
return true;
|
|
240
|
+
}
|
|
205
241
|
if (entry.members.length >= CANVAS_MEMBER_CAP)
|
|
206
242
|
return false;
|
|
207
243
|
entry.members.push(id);
|
|
244
|
+
if (home !== undefined) {
|
|
245
|
+
this.cliHome[id] = home;
|
|
246
|
+
this.cliHomeCleared.delete(id);
|
|
247
|
+
}
|
|
208
248
|
this.persist();
|
|
209
249
|
return true;
|
|
210
250
|
}
|
|
@@ -219,9 +259,16 @@ export class CanvasStore {
|
|
|
219
259
|
if (index < 0)
|
|
220
260
|
return false;
|
|
221
261
|
entry.members.splice(index, 1);
|
|
262
|
+
this.forgetUnusedHome(id);
|
|
222
263
|
this.persist();
|
|
223
264
|
return true;
|
|
224
265
|
}
|
|
266
|
+
forgetUnusedHome(id) {
|
|
267
|
+
if (!this.teams.some(team => team.members.includes(id))) {
|
|
268
|
+
delete this.cliHome[id];
|
|
269
|
+
this.cliHomeCleared.delete(id);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
225
272
|
/**
|
|
226
273
|
* Drop one id from every team — the leave and archive paths: a session
|
|
227
274
|
* leaving the network keeps no canvas membership anywhere.
|
|
@@ -236,8 +283,10 @@ export class CanvasStore {
|
|
|
236
283
|
dirty = true;
|
|
237
284
|
}
|
|
238
285
|
}
|
|
239
|
-
if (dirty)
|
|
286
|
+
if (dirty) {
|
|
287
|
+
this.forgetUnusedHome(id);
|
|
240
288
|
this.persist();
|
|
289
|
+
}
|
|
241
290
|
}
|
|
242
291
|
}
|
|
243
292
|
/** One policy predicate for local and signed-remote canvas creation. */
|
|
@@ -246,3 +295,12 @@ export function canvasNameReserved(raw, zone, allowlist, roster) {
|
|
|
246
295
|
const team = `${zone}/${name}`;
|
|
247
296
|
return name.startsWith('roster:') || allowlist.includes(team) || roster.membersOf(team).length > 0;
|
|
248
297
|
}
|
|
298
|
+
function validHomeOrigin(raw) {
|
|
299
|
+
try {
|
|
300
|
+
const url = new URL(raw);
|
|
301
|
+
return (url.protocol === 'http:' || url.protocol === 'https:') && url.origin === raw;
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
}
|
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
|
}
|
package/lib/cli-home.js
ADDED
|
@@ -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
|
+
}
|
package/lib/client/A2aControl.js
CHANGED
|
@@ -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.
|
|
26
|
-
const css = ".
|
|
25
|
+
//#region \0dsh-css:D:\workspace\dsh-open-a2a-net\tmp\release-0.6.35-d5a66d9\src\src\client\A2aControl.module.css.mjs
|
|
26
|
+
const css = "._9zk42q_wrap{max-width:100%;display:inline-flex;position:relative}._9zk42q_trigger{align-items:center;gap:4px;display:inline-flex;position:relative}._9zk42q_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 _9zk42q_badgePulse;position:absolute;top:-6px;right:-8px}@keyframes _9zk42q_badgePulse{0%,to{box-shadow:0 0 #4c8bf573}50%{box-shadow:0 0 0 4px #4c8bf500}}@media (prefers-reduced-motion:reduce){._9zk42q_unreadBadge{animation:none}}._9zk42q_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}._9zk42q_title{font-size:13px;font-weight:600}._9zk42q_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}._9zk42q_stageRow{border-top:1px solid var(--dsh-border,#2a2a30);align-items:center;gap:8px;margin-top:4px;padding-top:8px;display:flex}._9zk42q_stageTitle{text-transform:uppercase;letter-spacing:.04em;opacity:.65;font-size:11px;font-weight:600}._9zk42q_stageLinks{gap:6px;display:flex}._9zk42q_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}._9zk42q_stageLink:hover,._9zk42q_stageLink:focus-visible{border-color:var(--dsh-accent,#4c8bf5)}._9zk42q_empty{opacity:.7;font-size:12px}._9zk42q_row{border:1px solid #0000;border-radius:8px;align-items:center;gap:10px;padding:8px;display:flex}._9zk42q_joined{border-color:var(--dsh-border,#2a2a30)}._9zk42q_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}._9zk42q_facts:hover{background:var(--dsh-surface-hover,#ffffff0f)}._9zk42q_nameRow{align-items:center;gap:6px;display:flex}._9zk42q_stateDot{border-radius:50%;flex:none;width:7px;height:7px}._9zk42q_stateDot._9zk42q_live{background:var(--dsh-accent,#4c8bf5)}._9zk42q_stateDot._9zk42q_live._9zk42q_joined{background:var(--dsh-success,#3fb96f)}._9zk42q_stateDot._9zk42q_cold{background:var(--dsh-warning,#d9a13c)}._9zk42q_name{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;overflow:hidden}._9zk42q_description{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}._9zk42q_team{opacity:.55;font-size:11px;font-family:var(--dsh-mono,monospace)}._9zk42q_note{opacity:.6;font-size:11px}._9zk42q_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}._9zk42q_searchInput:focus{outline:1px solid var(--dsh-accent,#4c8bf5)}._9zk42q_sessionGroup{flex-direction:column;gap:2px;display:flex}._9zk42q_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}._9zk42q_groupChevron{transition:transform .12s;display:inline-block}._9zk42q_groupChevronClosed{transform:rotate(-90deg)}._9zk42q_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}._9zk42q_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}._9zk42q_groupButton:hover{border-color:var(--dsh-border,#2a2a30);opacity:1}._9zk42q_groupPicker{border:1px dashed var(--dsh-border,#2a2a30);border-radius:8px;flex-wrap:wrap;gap:6px;width:100%;padding:8px;display:flex;position:relative}._9zk42q_groupOption{border:1px solid var(--dsh-border,#2a2a30);color:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:2px 8px;font-size:11px}._9zk42q_groupOptionActive{border-color:var(--dsh-accent,#4c8bf5);color:var(--dsh-accent,#4c8bf5)}._9zk42q_groupNew{align-items:center;gap:6px;width:100%;margin-top:2px;display:flex}._9zk42q_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}._9zk42q_peerGrid{flex-wrap:wrap;gap:6px;display:flex}._9zk42q_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}._9zk42q_peerHost{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}._9zk42q_peerScore{font-family:var(--dsh-mono,monospace);opacity:.6}._9zk42q_activityList{flex-direction:column;gap:2px;display:flex}._9zk42q_activityRow{border-radius:4px;align-items:center;gap:8px;padding:2px 4px;font-size:11px;display:flex}._9zk42q_activityRow[data-ok=false]{opacity:.55}._9zk42q_activityDir{flex:none;font-weight:600}._9zk42q_activityDir._9zk42q_in{color:var(--dsh-success,#3fb96f)}._9zk42q_activityDir._9zk42q_out{color:var(--dsh-accent,#4c8bf5)}._9zk42q_activityTeam{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--dsh-mono,monospace);opacity:.8;flex:1;overflow:hidden}._9zk42q_activityPeer{text-overflow:ellipsis;white-space:nowrap;opacity:.55;max-width:90px;overflow:hidden}._9zk42q_activityTime{opacity:.5;font-family:var(--dsh-mono,monospace);flex:none}._9zk42q_activityRow[data-jump=true]{cursor:pointer}._9zk42q_activityRow[data-jump=true]:hover{background:var(--dsh-surface-hover,#ffffff0f)}._9zk42q_fresh{animation:1.2s ease-out 3 _9zk42q_freshFlash}@keyframes _9zk42q_freshFlash{0%{background:#4c8bf538}to{background:0 0}}@media (prefers-reduced-motion:reduce){._9zk42q_fresh{background:#4c8bf51f;animation:none}}._9zk42q_inFlightList{flex-direction:column;gap:2px;margin-bottom:4px;display:flex}._9zk42q_inFlightRow{border:1px dashed var(--dsh-border,#2a2a30);border-radius:4px;align-items:center;gap:8px;padding:3px 4px;font-size:11px;display:flex}._9zk42q_inFlightPulse{background:var(--dsh-accent,#4c8bf5);border-radius:50%;flex:none;width:7px;height:7px;animation:1.1s ease-in-out infinite _9zk42q_flightPulse}@keyframes _9zk42q_flightPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(.55)}}@media (prefers-reduced-motion:reduce){._9zk42q_inFlightPulse{animation:none}}._9zk42q_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}._9zk42q_inFlightStale{opacity:.55}._9zk42q_canvasCreate{align-items:center;gap:6px;margin-bottom:4px;display:flex}._9zk42q_canvasCreate ._9zk42q_groupInput{flex:1;min-width:0}._9zk42q_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}._9zk42q_canvasChip>span:not([class]){white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._9zk42q_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}._9zk42q_canvasChipRemove:hover{color:var(--dsh-color-text-primary,#eee)}._9zk42q_canvasChipRemove{transition:color .14s ease-out}@media (prefers-reduced-motion:reduce){._9zk42q_canvasChipRemove{transition:none}}._9zk42q_canvasChipRemove:focus-visible{outline:2px solid var(--dsh-color-primary,#4f8cff);outline-offset:1px;border-radius:4px}._9zk42q_canvasActions{gap:6px;margin-top:4px;display:flex}._9zk42q_inFlightStale ._9zk42q_inFlightPulse{opacity:.4;animation:none}._9zk42q_failMark{color:#f87171;flex-shrink:0;font-size:11px}._9zk42q_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": "
|
|
37
|
-
"activityList": "
|
|
38
|
-
"activityPeer": "
|
|
39
|
-
"activityRow": "
|
|
40
|
-
"activityTeam": "
|
|
41
|
-
"activityTime": "
|
|
42
|
-
"badgePulse": "
|
|
43
|
-
"canvasActions": "
|
|
44
|
-
"canvasChip": "
|
|
45
|
-
"canvasChipRemove": "
|
|
46
|
-
"canvasCreate": "
|
|
47
|
-
"cold": "
|
|
48
|
-
"description": "
|
|
49
|
-
"empty": "
|
|
50
|
-
"facts": "
|
|
51
|
-
"failMark": "
|
|
52
|
-
"flightPulse": "
|
|
53
|
-
"fresh": "
|
|
54
|
-
"freshFlash": "
|
|
55
|
-
"groupButton": "
|
|
56
|
-
"groupChevron": "
|
|
57
|
-
"groupChevronClosed": "
|
|
58
|
-
"groupHead": "
|
|
59
|
-
"groupInput": "
|
|
60
|
-
"groupNew": "
|
|
61
|
-
"groupOption": "
|
|
62
|
-
"groupOptionActive": "
|
|
63
|
-
"groupPicker": "
|
|
64
|
-
"groupTag": "
|
|
65
|
-
"in": "
|
|
66
|
-
"inFlightList": "
|
|
67
|
-
"inFlightPulse": "
|
|
68
|
-
"inFlightRow": "
|
|
69
|
-
"inFlightStale": "
|
|
70
|
-
"joined": "
|
|
71
|
-
"live": "
|
|
72
|
-
"name": "
|
|
73
|
-
"nameRow": "
|
|
74
|
-
"note": "
|
|
75
|
-
"out": "
|
|
76
|
-
"peerChip": "
|
|
77
|
-
"peerGrid": "
|
|
78
|
-
"peerHost": "
|
|
79
|
-
"peerScore": "
|
|
80
|
-
"popover": "
|
|
81
|
-
"row": "
|
|
82
|
-
"searchInput": "
|
|
83
|
-
"sectionTitle": "
|
|
84
|
-
"sessionGroup": "
|
|
85
|
-
"stageLink": "
|
|
86
|
-
"stageLinks": "
|
|
87
|
-
"stageRow": "
|
|
88
|
-
"stageTitle": "
|
|
89
|
-
"staleNote": "
|
|
90
|
-
"stateDot": "
|
|
91
|
-
"team": "
|
|
92
|
-
"title": "
|
|
93
|
-
"trigger": "
|
|
94
|
-
"unreadBadge": "
|
|
95
|
-
"versionTag": "
|
|
96
|
-
"wrap": "
|
|
36
|
+
"activityDir": "_9zk42q_activityDir",
|
|
37
|
+
"activityList": "_9zk42q_activityList",
|
|
38
|
+
"activityPeer": "_9zk42q_activityPeer",
|
|
39
|
+
"activityRow": "_9zk42q_activityRow",
|
|
40
|
+
"activityTeam": "_9zk42q_activityTeam",
|
|
41
|
+
"activityTime": "_9zk42q_activityTime",
|
|
42
|
+
"badgePulse": "_9zk42q_badgePulse",
|
|
43
|
+
"canvasActions": "_9zk42q_canvasActions",
|
|
44
|
+
"canvasChip": "_9zk42q_canvasChip",
|
|
45
|
+
"canvasChipRemove": "_9zk42q_canvasChipRemove",
|
|
46
|
+
"canvasCreate": "_9zk42q_canvasCreate",
|
|
47
|
+
"cold": "_9zk42q_cold",
|
|
48
|
+
"description": "_9zk42q_description",
|
|
49
|
+
"empty": "_9zk42q_empty",
|
|
50
|
+
"facts": "_9zk42q_facts",
|
|
51
|
+
"failMark": "_9zk42q_failMark",
|
|
52
|
+
"flightPulse": "_9zk42q_flightPulse",
|
|
53
|
+
"fresh": "_9zk42q_fresh",
|
|
54
|
+
"freshFlash": "_9zk42q_freshFlash",
|
|
55
|
+
"groupButton": "_9zk42q_groupButton",
|
|
56
|
+
"groupChevron": "_9zk42q_groupChevron",
|
|
57
|
+
"groupChevronClosed": "_9zk42q_groupChevronClosed",
|
|
58
|
+
"groupHead": "_9zk42q_groupHead",
|
|
59
|
+
"groupInput": "_9zk42q_groupInput",
|
|
60
|
+
"groupNew": "_9zk42q_groupNew",
|
|
61
|
+
"groupOption": "_9zk42q_groupOption",
|
|
62
|
+
"groupOptionActive": "_9zk42q_groupOptionActive",
|
|
63
|
+
"groupPicker": "_9zk42q_groupPicker",
|
|
64
|
+
"groupTag": "_9zk42q_groupTag",
|
|
65
|
+
"in": "_9zk42q_in",
|
|
66
|
+
"inFlightList": "_9zk42q_inFlightList",
|
|
67
|
+
"inFlightPulse": "_9zk42q_inFlightPulse",
|
|
68
|
+
"inFlightRow": "_9zk42q_inFlightRow",
|
|
69
|
+
"inFlightStale": "_9zk42q_inFlightStale",
|
|
70
|
+
"joined": "_9zk42q_joined",
|
|
71
|
+
"live": "_9zk42q_live",
|
|
72
|
+
"name": "_9zk42q_name",
|
|
73
|
+
"nameRow": "_9zk42q_nameRow",
|
|
74
|
+
"note": "_9zk42q_note",
|
|
75
|
+
"out": "_9zk42q_out",
|
|
76
|
+
"peerChip": "_9zk42q_peerChip",
|
|
77
|
+
"peerGrid": "_9zk42q_peerGrid",
|
|
78
|
+
"peerHost": "_9zk42q_peerHost",
|
|
79
|
+
"peerScore": "_9zk42q_peerScore",
|
|
80
|
+
"popover": "_9zk42q_popover",
|
|
81
|
+
"row": "_9zk42q_row",
|
|
82
|
+
"searchInput": "_9zk42q_searchInput",
|
|
83
|
+
"sectionTitle": "_9zk42q_sectionTitle",
|
|
84
|
+
"sessionGroup": "_9zk42q_sessionGroup",
|
|
85
|
+
"stageLink": "_9zk42q_stageLink",
|
|
86
|
+
"stageLinks": "_9zk42q_stageLinks",
|
|
87
|
+
"stageRow": "_9zk42q_stageRow",
|
|
88
|
+
"stageTitle": "_9zk42q_stageTitle",
|
|
89
|
+
"staleNote": "_9zk42q_staleNote",
|
|
90
|
+
"stateDot": "_9zk42q_stateDot",
|
|
91
|
+
"team": "_9zk42q_team",
|
|
92
|
+
"title": "_9zk42q_title",
|
|
93
|
+
"trigger": "_9zk42q_trigger",
|
|
94
|
+
"unreadBadge": "_9zk42q_unreadBadge",
|
|
95
|
+
"versionTag": "_9zk42q_versionTag",
|
|
96
|
+
"wrap": "_9zk42q_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,
|