@ryubyte/dsh-a2a 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
2
+ import { homedir, networkInterfaces } from "node:os";
2
3
  import { dirname, join } from "node:path";
3
- import { homedir } from "node:os";
4
4
  //#region src/protocol.ts
5
5
  /**
6
6
  * A2A (Agent2Agent) Protocol v1.0 — TypeScript type definitions.
@@ -575,6 +575,7 @@ var A2AServer = class {
575
575
  options;
576
576
  store;
577
577
  card;
578
+ /** JSON-RPC route path. Mutable: `updateCard` can move it at runtime. */
578
579
  endpointPath;
579
580
  execute;
580
581
  listeners = /* @__PURE__ */ new Set();
@@ -595,6 +596,14 @@ var A2AServer = class {
595
596
  */
596
597
  setBaseUrl(baseUrl) {
597
598
  this.baseUrl = baseUrl.replace(/\/$/, "");
599
+ this.rebuildInterfaceUrls();
600
+ }
601
+ /** The base URL currently advertised in the AgentCard. */
602
+ getBaseUrl() {
603
+ return this.baseUrl;
604
+ }
605
+ /** Rebuild the advertised interface URL(s) from the current baseUrl + path. */
606
+ rebuildInterfaceUrls() {
598
607
  this.card.supportedInterfaces = this.card.supportedInterfaces.map((iface) => ({
599
608
  ...iface,
600
609
  url: `${this.baseUrl}${this.endpointPath}`
@@ -619,6 +628,43 @@ var A2AServer = class {
619
628
  get authConfigured() {
620
629
  return Boolean(this.options.authToken);
621
630
  }
631
+ /**
632
+ * Update the advertised identity (name/description/version/baseUrl/
633
+ * endpointPath/skills) at runtime, in place. Mirrors setBaseUrl/setAuthToken:
634
+ * mutates `this.options` and the existing `this.card` object's properties —
635
+ * never reassigns `this.card`, so the route handler closure that reads
636
+ * `server.card` per request keeps seeing the live card.
637
+ *
638
+ * Returns `{ endpointChanged }`: when the JSON-RPC path moved, the caller
639
+ * (which owns route registration) must re-register routes on the new path —
640
+ * `updateCard` only mutates the advertised URL, not the live HTTP routes.
641
+ */
642
+ updateCard(patch) {
643
+ let endpointChanged = false;
644
+ if (patch.agentName !== void 0) {
645
+ this.options.agentName = patch.agentName;
646
+ this.card.name = patch.agentName;
647
+ }
648
+ if (patch.agentDescription !== void 0) {
649
+ this.options.agentDescription = patch.agentDescription;
650
+ this.card.description = patch.agentDescription;
651
+ }
652
+ if (patch.agentVersion !== void 0) {
653
+ this.options.agentVersion = patch.agentVersion;
654
+ this.card.version = patch.agentVersion;
655
+ }
656
+ if (patch.skills !== void 0) {
657
+ this.options.skills = patch.skills;
658
+ this.card.skills = patch.skills;
659
+ }
660
+ if (patch.endpointPath !== void 0 && patch.endpointPath !== this.endpointPath) {
661
+ this.endpointPath = patch.endpointPath || "/a2a";
662
+ endpointChanged = true;
663
+ }
664
+ if (patch.baseUrl !== void 0) this.baseUrl = patch.baseUrl.replace(/\/$/, "");
665
+ if (patch.baseUrl !== void 0 || endpointChanged) this.rebuildInterfaceUrls();
666
+ return { endpointChanged };
667
+ }
622
668
  buildCard() {
623
669
  const iface = {
624
670
  url: `${this.baseUrl.replace(/\/$/, "")}${this.endpointPath}`,
@@ -1398,6 +1444,29 @@ var DashboardRegistry = class {
1398
1444
  ok: false,
1399
1445
  message: "server-status is not wired (server mode not mounted)"
1400
1446
  };
1447
+ case "set-server-identity":
1448
+ if (!this.hooks.setServerIdentity) return {
1449
+ ok: false,
1450
+ message: "set-server-identity is not wired (server not mounted)"
1451
+ };
1452
+ return this.hooks.setServerIdentity({
1453
+ agentName: payload?.agentName,
1454
+ agentDescription: payload?.agentDescription,
1455
+ agentVersion: payload?.agentVersion,
1456
+ baseUrl: payload?.baseUrl,
1457
+ endpointPath: payload?.endpointPath,
1458
+ skills: payload?.skills
1459
+ });
1460
+ case "update-agent":
1461
+ if (!this.hooks.updateAgent) return {
1462
+ ok: false,
1463
+ message: "update-agent is not wired (client mode not mounted)"
1464
+ };
1465
+ return this.hooks.updateAgent(target, {
1466
+ timeoutMs: typeof payload?.timeoutMs === "number" ? payload.timeoutMs : void 0,
1467
+ mapSkills: typeof payload?.mapSkills === "boolean" ? payload.mapSkills : void 0,
1468
+ bearerToken: payload?.bearerToken || void 0
1469
+ });
1401
1470
  default: return {
1402
1471
  ok: false,
1403
1472
  message: `unknown action ${action}`
@@ -1479,6 +1548,30 @@ function profileNameFromArgv() {
1479
1548
  }
1480
1549
  }
1481
1550
  /**
1551
+ * Best-effort profile-name fallback for launchers that resolve a profile
1552
+ * WITHOUT writing `--profile` back into argv.
1553
+ *
1554
+ * The dsh `web` subcommand is a hardcoded alias for `--profile web`: the
1555
+ * launcher resolves the name internally and boots the web profile, but the
1556
+ * process argv keeps the original tokens (`node …/dsh web [flags]`) — there
1557
+ * is no `--profile` flag and no environment variable naming the profile. So
1558
+ * when {@link profileNameFromArgv} finds nothing, check whether the first
1559
+ * non-flag token after argv[0] is a known dsh subcommand alias:
1560
+ *
1561
+ * - `web` → boot profile `web` (alias, never followed by a name)
1562
+ * - `--profile <n>` → already handled above
1563
+ * - anything else → unknown/not a profile alias (e.g. `plugin`, which
1564
+ * is a management mode, not a boot; returns undefined)
1565
+ *
1566
+ * Returns undefined when argv carries no recognizable alias, letting the
1567
+ * caller fall through to the cwd-based resolution steps.
1568
+ */
1569
+ function profileNameFromDshAlias() {
1570
+ const argv = process.argv ?? [];
1571
+ if (argv.includes("--profile") || argv.some((a) => a.startsWith("--profile="))) return void 0;
1572
+ if (argv[2] === "web") return "web";
1573
+ }
1574
+ /**
1482
1575
  * Resolve the a2a.json path for the current process, without depending on
1483
1576
  * the launch directory. The plugin must work no matter where `dsh` was
1484
1577
  * started from (dsh does NOT chdir into the profile directory), so this
@@ -1488,7 +1581,9 @@ function profileNameFromArgv() {
1488
1581
  *
1489
1582
  * Order:
1490
1583
  * 0. `$DSH_HOME/profiles/<argv --profile>/a2a.json` — the active profile
1491
- * as named on the command line (most authoritative; works from ANY cwd)
1584
+ * as named on the command line (most authoritative; works from ANY cwd).
1585
+ * Also matches the `dsh web` alias, which boots profile `web` without
1586
+ * writing `--profile` into argv.
1492
1587
  * 1. `cwd/a2a.json` — explicit when launched inside a profile dir
1493
1588
  * 2. outward from cwd: the nearest ancestor holding `a2a.json` — covers
1494
1589
  * launching from e.g. a repo checkout whose parent chain includes the
@@ -1506,7 +1601,7 @@ function resolveConfigPath() {
1506
1601
  const cwd = process.cwd();
1507
1602
  const home = process.env.DSH_HOME ?? join(homedir(), ".dsh");
1508
1603
  const base = cwd.split(/[\\/]/).pop() ?? "";
1509
- const profileName = profileNameFromArgv();
1604
+ const profileName = profileNameFromArgv() ?? profileNameFromDshAlias();
1510
1605
  if (profileName && profileName !== "." && profileName !== ".." && !profileName.includes("/") && !profileName.includes("\\")) {
1511
1606
  const argvFile = join(home, "profiles", profileName, A2A_CONFIG_FILENAME);
1512
1607
  if (existsSync(argvFile)) return argvFile;
@@ -1525,6 +1620,7 @@ function resolveConfigPath() {
1525
1620
  if (base && existsSync(profileFile)) return profileFile;
1526
1621
  const globalFile = join(home, A2A_CONFIG_FILENAME);
1527
1622
  if (existsSync(globalFile)) return globalFile;
1623
+ if (profileName && profileName !== "." && profileName !== ".." && !profileName.includes("/") && !profileName.includes("\\")) return join(home, "profiles", profileName, A2A_CONFIG_FILENAME);
1528
1624
  return cwdFile;
1529
1625
  }
1530
1626
  /** Read the persisted config (empty object when absent or unreadable). */
@@ -1976,6 +2072,53 @@ function apply(ctx, config = {}) {
1976
2072
  ok: true,
1977
2073
  message: `agent ${connectionId} removed`
1978
2074
  };
2075
+ },
2076
+ updateAgent: async (connectionId, patch) => {
2077
+ const entry = live.get(connectionId);
2078
+ const snap = dashboard.snapshot().outbound.find((o) => o.connectionId === connectionId);
2079
+ const name = entry?.name ?? snap?.name;
2080
+ const url = entry?.agentCardUrl ?? snap?.agentCardUrl;
2081
+ entry?.configured ?? snap?.configured;
2082
+ if (!name || !url) return {
2083
+ ok: false,
2084
+ message: `connection ${connectionId} not found`
2085
+ };
2086
+ const found = findInitial({
2087
+ name,
2088
+ agentCardUrl: url
2089
+ });
2090
+ if (!found) return {
2091
+ ok: false,
2092
+ message: "only saved (configured) agents can be edited"
2093
+ };
2094
+ if (patch.timeoutMs !== void 0) found.item.timeoutMs = patch.timeoutMs;
2095
+ if (patch.mapSkills !== void 0) found.item.mapSkills = patch.mapSkills;
2096
+ if (patch.bearerToken !== void 0) found.item.bearerToken = patch.bearerToken || void 0;
2097
+ persistAgents();
2098
+ const item = found.item;
2099
+ if (item.enabled === false) return {
2100
+ ok: true,
2101
+ message: `agent ${connectionId} updated (config kept, still disabled)`
2102
+ };
2103
+ if (entry) {
2104
+ entry.disposeAll();
2105
+ live.delete(connectionId);
2106
+ }
2107
+ dashboard.setAgentState(connectionId, "reconnecting");
2108
+ const newId = await connect(item.name, item.agentCardUrl, item.configured, {
2109
+ bearerToken: item.bearerToken,
2110
+ timeoutMs: item.timeoutMs,
2111
+ mapSkills: item.mapSkills
2112
+ });
2113
+ if (!newId) return {
2114
+ ok: false,
2115
+ message: `update of ${connectionId} failed to reconnect`
2116
+ };
2117
+ dashboard.removeAgent(connectionId);
2118
+ return {
2119
+ ok: true,
2120
+ message: `agent ${connectionId} updated as ${newId} (saved to ${configPath})`
2121
+ };
1979
2122
  }
1980
2123
  });
1981
2124
  ctx.effect(() => {
@@ -2008,15 +2151,19 @@ function apply(ctx, config = {}) {
2008
2151
  }, "a2a: client tools");
2009
2152
  });
2010
2153
  }
2011
- if (wantsServer) {
2154
+ {
2012
2155
  const store = new TaskStore();
2013
2156
  const taskPeer = /* @__PURE__ */ new Map();
2014
2157
  const pendingSettled = /* @__PURE__ */ new Set();
2015
2158
  ctx.inject(["webServer"], (ctx) => {
2016
2159
  ctx.effect(() => {
2017
2160
  const webServer = ctx.webServer;
2018
- const baseUrl = mergedConfig.baseUrl ?? `http://${webServer.host === "0.0.0.0" ? "127.0.0.1" : webServer.host}:${webServer.port}`;
2161
+ const baseUrl = mergedConfig.baseUrl ?? inferBaseUrl(webServer.host, webServer.port);
2019
2162
  const endpointPath = mergedConfig.endpointPath ?? DEFAULT_ENDPOINT;
2163
+ if (mergedConfig.baseUrl) try {
2164
+ const pinnedPort = new URL(mergedConfig.baseUrl).port;
2165
+ if (pinnedPort && Number(pinnedPort) !== webServer.port) logger?.warn?.(`[a2a] pinned baseUrl ${mergedConfig.baseUrl} port ${pinnedPort} != listen port ${webServer.port}; remote callers may be unreachable. Clear baseUrl in settings to auto-infer.`);
2166
+ } catch {}
2020
2167
  let execute = mergedConfig.execute;
2021
2168
  let executorKind = execute ? "custom" : "none";
2022
2169
  let disposeExecutor;
@@ -2073,7 +2220,7 @@ function apply(ctx, config = {}) {
2073
2220
  } else pendingSettled.add(taskId);
2074
2221
  }
2075
2222
  }, store);
2076
- let enabled = true;
2223
+ let enabled = wantsServer;
2077
2224
  let disposers = [];
2078
2225
  const registerRoutes = () => {
2079
2226
  disposers.push(webServer.register({
@@ -2126,19 +2273,23 @@ function apply(ctx, config = {}) {
2126
2273
  for (const d of disposers) d();
2127
2274
  disposers = [];
2128
2275
  };
2129
- registerRoutes();
2130
- logger?.info?.(`[a2a] A2A server mounted: AgentCard at ${baseUrl}/.well-known/agent-card.json, JSON-RPC at ${server.endpointPath}`);
2276
+ if (enabled) {
2277
+ registerRoutes();
2278
+ logger?.info?.(`[a2a] A2A server mounted: AgentCard at ${baseUrl}/.well-known/agent-card.json, JSON-RPC at ${server.endpointPath}`);
2279
+ } else logger?.info?.("[a2a] A2A server ready but not serving (enable via settings)");
2131
2280
  const serverCard = () => ({
2132
- baseUrl,
2281
+ baseUrl: server.getBaseUrl(),
2133
2282
  agentName: server.card.name,
2134
2283
  agentDescription: server.card.description,
2135
2284
  agentVersion: server.card.version,
2136
- endpoint: `${baseUrl}${server.endpointPath}`,
2137
- agentCardUrl: `${baseUrl}/.well-known/agent-card.json`,
2285
+ endpointPath: server.endpointPath,
2286
+ endpoint: `${server.getBaseUrl()}${server.endpointPath}`,
2287
+ agentCardUrl: `${server.getBaseUrl()}/.well-known/agent-card.json`,
2138
2288
  skills: (server.card.skills ?? []).map((s) => ({
2139
2289
  id: s.id,
2140
2290
  name: s.name,
2141
- description: s.description
2291
+ description: s.description,
2292
+ tags: s.tags
2142
2293
  })),
2143
2294
  customExecutor: Boolean(mergedConfig.execute),
2144
2295
  executor: executorKind,
@@ -2154,17 +2305,63 @@ function apply(ctx, config = {}) {
2154
2305
  registerRoutes();
2155
2306
  enabled = true;
2156
2307
  logger?.info?.("[a2a] A2A server enabled");
2308
+ } else {
2309
+ unregisterRoutes();
2310
+ enabled = false;
2311
+ logger?.info?.("[a2a] A2A server disabled");
2312
+ }
2313
+ const next = loadConfig();
2314
+ next.server = {
2315
+ ...next.server ?? {},
2316
+ enabled
2317
+ };
2318
+ const res = saveConfig(next);
2319
+ if (!res.ok) {
2320
+ logger?.error?.(`[a2a] failed to persist server.enabled to ${res.path}: ${res.message}`);
2321
+ return {
2322
+ ok: false,
2323
+ message: `applied in-memory but failed to save: ${res.message}`
2324
+ };
2325
+ }
2326
+ return {
2327
+ ok: true,
2328
+ message: enable ? "A2A server enabled" : "A2A server disabled"
2329
+ };
2330
+ },
2331
+ setServerIdentity: async (patch) => {
2332
+ const clearBaseUrl = patch.baseUrl === "";
2333
+ const cardPatch = clearBaseUrl ? {
2334
+ ...patch,
2335
+ baseUrl: void 0
2336
+ } : patch;
2337
+ const { endpointChanged } = server.updateCard(cardPatch);
2338
+ if (clearBaseUrl) server.setBaseUrl(inferBaseUrl(webServer.host, webServer.port));
2339
+ if (endpointChanged && enabled) {
2340
+ unregisterRoutes();
2341
+ registerRoutes();
2342
+ }
2343
+ const next = loadConfig();
2344
+ const s = { ...next.server ?? {} };
2345
+ if (patch.agentName !== void 0) s.agentName = patch.agentName;
2346
+ if (patch.agentDescription !== void 0) s.agentDescription = patch.agentDescription;
2347
+ if (patch.agentVersion !== void 0) s.agentVersion = patch.agentVersion;
2348
+ if (clearBaseUrl) delete s.baseUrl;
2349
+ else if (patch.baseUrl !== void 0) s.baseUrl = patch.baseUrl;
2350
+ if (patch.endpointPath !== void 0) s.endpointPath = patch.endpointPath;
2351
+ if (patch.skills !== void 0) s.skills = patch.skills;
2352
+ next.server = s;
2353
+ const res = saveConfig(next);
2354
+ if (!res.ok) {
2355
+ logger?.error?.(`[a2a] failed to persist server identity to ${res.path}: ${res.message}`);
2157
2356
  return {
2158
- ok: true,
2159
- message: "A2A server enabled"
2357
+ ok: false,
2358
+ message: `applied in-memory but failed to save: ${res.message}`
2160
2359
  };
2161
2360
  }
2162
- unregisterRoutes();
2163
- enabled = false;
2164
- logger?.info?.("[a2a] A2A server disabled");
2361
+ logger?.info?.(`[a2a] server identity updated (saved to ${res.path})`);
2165
2362
  return {
2166
2363
  ok: true,
2167
- message: "A2A server disabled"
2364
+ message: `已更新对外服务 (saved to ${res.path})`
2168
2365
  };
2169
2366
  },
2170
2367
  setServerAuthToken: async (token) => {
@@ -2281,6 +2478,57 @@ function inboundSessionCwd(configPath) {
2281
2478
  return process.cwd();
2282
2479
  }
2283
2480
  }
2481
+ /**
2482
+ * Derive the public base URL advertised in the AgentCard from the real wire
2483
+ * listen address, when the operator did not pin `baseUrl` in config.
2484
+ *
2485
+ * The A2A AgentCard must carry a URL a REMOTE caller can reach. When the web
2486
+ * server binds only loopback (`127.0.0.1`), that address is correct. But when
2487
+ * it binds every interface (`0.0.0.0`), advertising `127.0.0.1` is wrong for
2488
+ * every non-local caller — it points at the caller's own loopback. In that
2489
+ * case pick the machine's best-known LAN address (the primary non-loopback
2490
+ * IPv4 of the interface that routes to the default gateway), and only fall
2491
+ * back to loopback when no such address exists. IPv6 link-local is skipped
2492
+ * (not reachable without a scope id).
2493
+ *
2494
+ * @param host - the web server's configured bind host ('127.0.0.1' | '0.0.0.0').
2495
+ * @param port - the OS-assigned (or configured) listen port.
2496
+ * @returns a scheme+host+port URL for Agents to call back into this DSH.
2497
+ */
2498
+ function inferBaseUrl(host, port) {
2499
+ return `http://${host === "0.0.0.0" ? primaryLanAddress() ?? "127.0.0.1" : host || "127.0.0.1"}:${port}`;
2500
+ }
2501
+ /**
2502
+ * Best single LAN IPv4 for this machine: the address of the non-loopback
2503
+ * interface whose route reaches the default gateway (the address a remote
2504
+ * peer on the same subnet would use to reach us). Returns undefined when the
2505
+ * machine has no non-loopback IPv4 (e.g. offline / containers).
2506
+ *
2507
+ * Prefers IPv4 (A2A URLs here are v4-style), skips link-local (169.254.0.0/16)
2508
+ * and CGNAT (100.64.0.0/10) ranges, which are useless to advertise.
2509
+ */
2510
+ function primaryLanAddress() {
2511
+ try {
2512
+ const ifaces = networkInterfaces();
2513
+ let candidate;
2514
+ for (const name of Object.keys(ifaces)) {
2515
+ const addrs = ifaces[name] ?? [];
2516
+ for (const a of addrs) {
2517
+ if (a.family !== "IPv4" || a.internal) continue;
2518
+ const ip = a.address;
2519
+ if (ip.startsWith("169.254.")) continue;
2520
+ const first = Number(ip.split(".")[0]);
2521
+ const second = Number(ip.split(".")[1]);
2522
+ if (first === 100 && second >= 64 && second <= 127) continue;
2523
+ if (!candidate) candidate = ip;
2524
+ if (name === "en0" || name === "eth0" || name === "ens3" || name === "ens5") return ip;
2525
+ }
2526
+ }
2527
+ return candidate;
2528
+ } catch {
2529
+ return;
2530
+ }
2531
+ }
2284
2532
  /** Drain the request body from a Node IncomingMessage. */
2285
2533
  async function readBody(req) {
2286
2534
  return new Promise((resolve, reject) => {
@@ -2321,4 +2569,4 @@ function toServerReq(req) {
2321
2569
  };
2322
2570
  }
2323
2571
  //#endregion
2324
- export { A2AClient, A2AError, A2AServer, A2A_ERROR_CODES, A2A_METHODS, DashboardRegistry, Role, TaskState, TaskStore, apply, createDshAgentExecutor, defaultExecutor, defaultSkills, fetchAgentCard, getSharedRegistry, inject, isTerminal, name, notConfiguredExecutor, registerAgentTools, shellExecutor };
2572
+ export { A2AClient, A2AError, A2AServer, A2A_ERROR_CODES, A2A_METHODS, DashboardRegistry, Role, TaskState, TaskStore, apply, createDshAgentExecutor, defaultExecutor, defaultSkills, fetchAgentCard, getSharedRegistry, inferBaseUrl, inject, isTerminal, name, notConfiguredExecutor, registerAgentTools, shellExecutor };
@@ -68,6 +68,26 @@ export interface PersistedA2AConfig {
68
68
  * guessing from cwd's basename.
69
69
  */
70
70
  export declare function profileNameFromArgv(): string | undefined;
71
+ /**
72
+ * Best-effort profile-name fallback for launchers that resolve a profile
73
+ * WITHOUT writing `--profile` back into argv.
74
+ *
75
+ * The dsh `web` subcommand is a hardcoded alias for `--profile web`: the
76
+ * launcher resolves the name internally and boots the web profile, but the
77
+ * process argv keeps the original tokens (`node …/dsh web [flags]`) — there
78
+ * is no `--profile` flag and no environment variable naming the profile. So
79
+ * when {@link profileNameFromArgv} finds nothing, check whether the first
80
+ * non-flag token after argv[0] is a known dsh subcommand alias:
81
+ *
82
+ * - `web` → boot profile `web` (alias, never followed by a name)
83
+ * - `--profile <n>` → already handled above
84
+ * - anything else → unknown/not a profile alias (e.g. `plugin`, which
85
+ * is a management mode, not a boot; returns undefined)
86
+ *
87
+ * Returns undefined when argv carries no recognizable alias, letting the
88
+ * caller fall through to the cwd-based resolution steps.
89
+ */
90
+ export declare function profileNameFromDshAlias(): string | undefined;
71
91
  /**
72
92
  * Resolve the a2a.json path for the current process, without depending on
73
93
  * the launch directory. The plugin must work no matter where `dsh` was
@@ -78,7 +98,9 @@ export declare function profileNameFromArgv(): string | undefined;
78
98
  *
79
99
  * Order:
80
100
  * 0. `$DSH_HOME/profiles/<argv --profile>/a2a.json` — the active profile
81
- * as named on the command line (most authoritative; works from ANY cwd)
101
+ * as named on the command line (most authoritative; works from ANY cwd).
102
+ * Also matches the `dsh web` alias, which boots profile `web` without
103
+ * writing `--profile` into argv.
82
104
  * 1. `cwd/a2a.json` — explicit when launched inside a profile dir
83
105
  * 2. outward from cwd: the nearest ancestor holding `a2a.json` — covers
84
106
  * launching from e.g. a repo checkout whose parent chain includes the
@@ -1 +1 @@
1
- {"version":3,"file":"a2a-config.d.ts","sourceRoot":"","sources":["../../src/a2a-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACzG;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAaxD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAqC1C;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,IAAI,kBAAkB,CAW/C;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAatG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAmBpG"}
1
+ {"version":3,"file":"a2a-config.d.ts","sourceRoot":"","sources":["../../src/a2a-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACzG;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAaxD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,SAAS,CAW5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAoD1C;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,IAAI,kBAAkB,CAW/C;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAatG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAmBpG"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * dsh-a2a — dashboard stylesheet.
3
+ *
4
+ * The browser half is a compiled bundle (not a dynamic cordis plugin), so it
5
+ * injects its own stylesheet the same way first-party DSH client UI packages
6
+ * do: a single idempotent <style> tag, styled entirely with the product's
7
+ * `--dsw-alias-*` design tokens (so light/dark themes and future token
8
+ * changes apply automatically), plus `@media` queries for narrow windows.
9
+ *
10
+ * Class names are prefixed with `a2a-` to avoid collisions with product or
11
+ * third-party styles.
12
+ */
13
+ export declare const DASHBOARD_CSS_ID = "@ryubyte/dsh-a2a/dashboard.css";
14
+ /**
15
+ * Idempotently inject the dashboard stylesheet into <head>. Returns a
16
+ * disposer that removes the tag; safe to call repeatedly (a second call is a
17
+ * no-op and returns a no-op disposer).
18
+ */
19
+ export declare function injectDashboardStyles(): () => void;
20
+ //# sourceMappingURL=dashboard.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.css.d.ts","sourceRoot":"","sources":["../../../src/client/dashboard.css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,gBAAgB,mCAAmC,CAAC;AAmQjE;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,IAAI,CAiBlD"}
@@ -8,6 +8,10 @@
8
8
  * The data and the controls live behind the host's `/a2a/api` routes
9
9
  * (served by the node half on the same webserver); the browser half is a
10
10
  * thin read/write client with no protocol knowledge.
11
+ *
12
+ * Styling: a single idempotent stylesheet (dashboard.css.ts) built entirely
13
+ * on the product's `--dsw-alias-*` design tokens, so light/dark themes and
14
+ * narrow-window layouts follow the DSH shell. No inline styles.
11
15
  */
12
16
  import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
13
17
  import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAE5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAE9E,0DAA0D;AAC1D,eAAO,MAAM,MAAM,UAAY,CAAC;AAEhC,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAmB9C;AA6DD,KAAK,YAAY,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC;AAErD,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CA0UnE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAE5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAG9E,0DAA0D;AAC1D,eAAO,MAAM,MAAM,UAAY,CAAC;AAEhC,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAyB9C;AA8DD,KAAK,YAAY,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC;AA+FrD,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CA8UnE"}
@@ -105,6 +105,26 @@ export interface DashboardControlHooks {
105
105
  serverStatus?: () => ControlResult;
106
106
  /** Runtime-remove an outbound agent by its connection id. */
107
107
  removeAgent?: (connectionId: string) => Promise<ControlResult>;
108
+ /** Update the outbound-server identity (AgentCard) at runtime (persisted). */
109
+ setServerIdentity?: (patch: {
110
+ agentName?: string;
111
+ agentDescription?: string;
112
+ agentVersion?: string;
113
+ baseUrl?: string;
114
+ endpointPath?: string;
115
+ skills?: Array<{
116
+ id: string;
117
+ name: string;
118
+ description: string;
119
+ tags?: string[];
120
+ }>;
121
+ }) => Promise<ControlResult>;
122
+ /** Update a saved outbound agent's advanced fields, reconnecting to apply. */
123
+ updateAgent?: (connectionId: string, patch: {
124
+ timeoutMs?: number;
125
+ mapSkills?: boolean;
126
+ bearerToken?: string;
127
+ }) => Promise<ControlResult>;
108
128
  }
109
129
  /** Registry of live A2A connections, both directions. */
110
130
  export declare class DashboardRegistry {
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard.ts"],"names":[],"mappings":"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"}
@@ -125,4 +125,22 @@ export declare const name = "a2a";
125
125
  */
126
126
  export declare const inject: readonly ["webServer", "tools"];
127
127
  export declare function apply(ctx: Context, config?: A2APluginConfig): void;
128
+ /**
129
+ * Derive the public base URL advertised in the AgentCard from the real wire
130
+ * listen address, when the operator did not pin `baseUrl` in config.
131
+ *
132
+ * The A2A AgentCard must carry a URL a REMOTE caller can reach. When the web
133
+ * server binds only loopback (`127.0.0.1`), that address is correct. But when
134
+ * it binds every interface (`0.0.0.0`), advertising `127.0.0.1` is wrong for
135
+ * every non-local caller — it points at the caller's own loopback. In that
136
+ * case pick the machine's best-known LAN address (the primary non-loopback
137
+ * IPv4 of the interface that routes to the default gateway), and only fall
138
+ * back to loopback when no such address exists. IPv6 link-local is skipped
139
+ * (not reachable without a scope id).
140
+ *
141
+ * @param host - the web server's configured bind host ('127.0.0.1' | '0.0.0.0').
142
+ * @param port - the OS-assigned (or configured) listen port.
143
+ * @returns a scheme+host+port URL for Agents to call back into this DSH.
144
+ */
145
+ export declare function inferBaseUrl(host: string, port: number): string;
128
146
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,19 @@ import type { AgentCard, AgentSkill, Message, Part, Task } from './protocol.js';
14
14
  import { TaskState } from './protocol.js';
15
15
  export interface ServerSkill extends AgentSkill {
16
16
  }
17
+ /**
18
+ * Runtime-editable slice of the advertised AgentCard identity. Every field is
19
+ * optional; only the provided ones change. Applied in place by
20
+ * {@link A2AServer.updateCard} (mirrors setBaseUrl/setAuthToken).
21
+ */
22
+ export interface CardIdentityPatch {
23
+ agentName?: string;
24
+ agentDescription?: string;
25
+ agentVersion?: string;
26
+ baseUrl?: string;
27
+ endpointPath?: string;
28
+ skills?: ServerSkill[];
29
+ }
17
30
  export interface ServerOptions {
18
31
  /** Public base URL (scheme + host + optional prefix) where this DSH is exposed. */
19
32
  baseUrl: string;
@@ -94,7 +107,8 @@ export declare class A2AServer {
94
107
  readonly options: ServerOptions;
95
108
  readonly store: TaskStore;
96
109
  readonly card: AgentCard;
97
- readonly endpointPath: string;
110
+ /** JSON-RPC route path. Mutable: `updateCard` can move it at runtime. */
111
+ endpointPath: string;
98
112
  private execute;
99
113
  private listeners;
100
114
  private baseUrl;
@@ -106,6 +120,10 @@ export declare class A2AServer {
106
120
  * address is known (e.g. ephemeral port). Mutates `card` in place.
107
121
  */
108
122
  setBaseUrl(baseUrl: string): void;
123
+ /** The base URL currently advertised in the AgentCard. */
124
+ getBaseUrl(): string;
125
+ /** Rebuild the advertised interface URL(s) from the current baseUrl + path. */
126
+ private rebuildInterfaceUrls;
109
127
  /**
110
128
  * Set or clear the shared bearer token that gates the inbound endpoint at
111
129
  * runtime. Rebuilds the AgentCard so the `bearerAuth` security scheme is
@@ -116,6 +134,20 @@ export declare class A2AServer {
116
134
  setAuthToken(token?: string): void;
117
135
  /** Whether the inbound endpoint is currently token-gated. */
118
136
  get authConfigured(): boolean;
137
+ /**
138
+ * Update the advertised identity (name/description/version/baseUrl/
139
+ * endpointPath/skills) at runtime, in place. Mirrors setBaseUrl/setAuthToken:
140
+ * mutates `this.options` and the existing `this.card` object's properties —
141
+ * never reassigns `this.card`, so the route handler closure that reads
142
+ * `server.card` per request keeps seeing the live card.
143
+ *
144
+ * Returns `{ endpointChanged }`: when the JSON-RPC path moved, the caller
145
+ * (which owns route registration) must re-register routes on the new path —
146
+ * `updateCard` only mutates the advertised URL, not the live HTTP routes.
147
+ */
148
+ updateCard(patch: CardIdentityPatch): {
149
+ endpointChanged: boolean;
150
+ };
119
151
  private buildCard;
120
152
  /** True when the request carries the configured bearer token. */
121
153
  private authorized;