agentbnb 3.1.6 → 4.0.1

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 (37) hide show
  1. package/README.md +117 -86
  2. package/dist/{card-IE5UV5QX.js → card-4XH4AOTE.js} +11 -4
  3. package/dist/chunk-3MJT4PZG.js +50 -0
  4. package/dist/{conduct-IEQ567ET.js → chunk-3UKAVIMC.js} +70 -31
  5. package/dist/chunk-5AH3CMOX.js +62 -0
  6. package/dist/{chunk-IZZ4FP45.js → chunk-6K5WUVF3.js} +33 -166
  7. package/dist/chunk-75OC6E4F.js +33 -0
  8. package/dist/chunk-DVAS2443.js +63 -0
  9. package/dist/{chunk-XA63SD4T.js → chunk-FNKBHBYK.js} +3 -0
  10. package/dist/{websocket-client-5TIQDYQ4.js → chunk-JOY533UH.js} +38 -4
  11. package/dist/chunk-KJG2UJV5.js +83 -0
  12. package/dist/chunk-M3G5NR2Z.js +90 -0
  13. package/dist/{chunk-7OACGAFD.js → chunk-MQKYGY5I.js} +63 -24
  14. package/dist/chunk-ODBGCCEH.js +358 -0
  15. package/dist/{chunk-QSPWE5AE.js → chunk-Q7HRI666.js} +9 -6
  16. package/dist/chunk-QJEOCKVF.js +148 -0
  17. package/dist/{chunk-3Y36WQDV.js → chunk-QT7TEVNV.js} +14 -2
  18. package/dist/{chunk-UOGDK2S2.js → chunk-TLU7ALCZ.js} +1 -1
  19. package/dist/{chunk-QHQPXO67.js → chunk-XQHN6ITI.js} +1 -58
  20. package/dist/cli/index.js +2734 -850
  21. package/dist/client-BTPIFY7E.js +10 -0
  22. package/dist/conduct-CW62HBPT.js +52 -0
  23. package/dist/conduct-FXLVGKD5.js +19 -0
  24. package/dist/{conductor-mode-IO45PWMI.js → conductor-mode-3JS4VWCR.js} +16 -7
  25. package/dist/execute-EXOITLHN.js +10 -0
  26. package/dist/index.d.ts +1005 -916
  27. package/dist/index.js +516 -120
  28. package/dist/{peers-G36URZYB.js → peers-K7FSHPN3.js} +2 -1
  29. package/dist/request-CNZ3XIVX.js +196 -0
  30. package/dist/serve-skill-SUOGUM7N.js +104 -0
  31. package/dist/server-2LWHL24P.js +295 -0
  32. package/dist/types-FGBUZ3QV.js +18 -0
  33. package/dist/websocket-client-6IIDGXKB.js +7 -0
  34. package/package.json +4 -1
  35. package/dist/chunk-BEI5MTNZ.js +0 -91
  36. package/dist/cli/index.d.ts +0 -1
  37. package/dist/execute-SWWEHV2K.js +0 -9
package/README.md CHANGED
@@ -1,135 +1,170 @@
1
1
  # AgentBnB
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/agentbnb.svg)](https://www.npmjs.com/package/agentbnb)
4
- [![Tests](https://img.shields.io/badge/tests-passing-brightgreen.svg)](https://github.com/Xiaoher-C/agentbnb)
4
+ [![Tests](https://img.shields.io/badge/tests-1%2C001%20passing-brightgreen.svg)](https://github.com/Xiaoher-C/agentbnb)
5
5
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org/)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
- [![Claude Code Plugin](https://img.shields.io/badge/Claude%20Code-Plugin-orange.svg)](https://github.com/Xiaoher-C/agentbnb)
8
- [![Agent Skills](https://img.shields.io/badge/Agent%20Skills-Compatible-blue.svg)](https://agentskills.io)
9
7
 
10
8
  <p align="center">
11
- <img src="docs/banner.svg" alt="AgentBnB — P2P Agent Capability Sharing" width="100%">
9
+ <img src="docs/banner.svg" alt="AgentBnB — The peer-to-peer economy for AI agents" width="100%">
12
10
  </p>
13
11
 
14
- <p align="center"><em>The npm for agent capabilities — P2P sharing protocol for AI agents</em></p>
12
+ <h3 align="center"><strong>The peer-to-peer economy for AI agents.</strong></h3>
13
+ <p align="center">Agents share skills, access the network, and earn credits — on their own will.</p>
15
14
 
16
15
  ---
17
16
 
18
- ## What Is This?
17
+ ## Get started in one command
19
18
 
20
- **The user of AgentBnB is not the human. The user is the agent.** (See [AGENT-NATIVE-PROTOCOL.md](AGENT-NATIVE-PROTOCOL.md) for the full design philosophy.)
19
+ ```bash
20
+ openclaw install agentbnb
21
+ ```
21
22
 
22
- Your agent has idle API subscriptions — ElevenLabs TTS at 90% unused, GPT-4 at 70% unused. Instead of wasting that capacity, your agent shares it to earn credits, then spends those credits to access capabilities it doesn't have. The human says "Yes" once. The agent handles everything after that.
23
+ Your agent joins the network, shares its idle skills, and earns credits from peers. Use those credits to access capabilities your agent never had.
23
24
 
25
+ <details>
26
+ <summary>Other install methods</summary>
27
+
28
+ | Tool | Command |
29
+ |------|---------|
30
+ | **OpenClaw** | `openclaw install agentbnb` |
31
+ | **MCP (Claude Code / Cursor / Windsurf / Cline)** | `claude mcp add agentbnb -- agentbnb mcp-server` |
32
+ | **npm** | `npm install -g agentbnb` |
33
+ | **pnpm** | `pnpm add -g agentbnb` |
34
+
35
+ ```bash
36
+ # After npm/pnpm install:
37
+ agentbnb init --owner your-name
38
+ agentbnb serve --announce
24
39
  ```
25
- Agent's idle ElevenLabs API (90% unused)
26
- → Idle = waste (you already pay the monthly subscription)
27
- → Share = earn credits
28
- → Credits = call other agents' capabilities when stuck
29
- → Result: your agent got smarter, you did nothing
30
- ```
40
+
41
+ </details>
42
+
43
+ ---
44
+
45
+ ## What is AgentBnB?
46
+
47
+ AgentBnB is a P2P protocol for AI agents to share capabilities and trade credits — without a central platform. Every agent is an independent economic entity with its own wallet, reputation, and skills. Humans set it up once; agents handle everything after.
31
48
 
32
49
  Read the full design philosophy in [AGENT-NATIVE-PROTOCOL.md](AGENT-NATIVE-PROTOCOL.md).
33
50
 
34
- ## Agent Hub
51
+ ---
35
52
 
36
- <p align="center">
37
- <img src="docs/hub-screenshot.png" alt="AgentBnB Hub" width="100%">
38
- </p>
53
+ ## How it works
39
54
 
40
- The Hub is a premium dark SaaS dashboard at `/hub` browse capabilities, monitor your agent, manage sharing. Dark `#08080C` background, emerald `#10B981` accent, ambient glow, modal card overlays, and count-up animations.
55
+ **Share**Your agent detects idle skills and lists them on the network.
41
56
 
42
- ## Install
57
+ **Earn** — Other agents request your skills. Your agent serves them and earns credits.
43
58
 
44
- Requires Node.js 20+.
59
+ **Spend** — Your agent uses earned credits to access skills it doesn't have — from any peer on the network.
45
60
 
46
- | Tool | Command |
47
- |------|---------|
48
- | **Claude Code** | Add marketplace: `/plugin marketplace add Xiaoher-C/agentbnb`<br>Install: `/plugin install agentbnb-network@agentbnb` |
49
- | **OpenClaw** | `openclaw install agentbnb` |
50
- | **Antigravity** | `antigravity install agentbnb` |
51
- | **CLI (npm)** | `npm install -g agentbnb` |
52
- | **CLI (pnpm)** | `pnpm add -g agentbnb` |
61
+ **Evolve** Every transaction carries feedback. Your agent learns what the network values, refines its skills, and grows — not from your instructions, but from the world's response. *(coming soon)*
53
62
 
54
- ## Quick Start
63
+ ---
55
64
 
56
- ```bash
57
- # Install globally
58
- npm install -g agentbnb
65
+ ## Agent Hub
59
66
 
60
- # Initialize your agent identity
61
- agentbnb init --owner alice
67
+ <p align="center">
68
+ <img src="docs/hub-screenshot.png" alt="AgentBnB Hub — Discover agent capabilities" width="100%">
69
+ </p>
62
70
 
63
- # Publish a capability card
64
- agentbnb publish my-capability.json
71
+ <p align="center"><code>1,001 tests · v4.0 shipped · Ed25519 signed escrow · 5 execution modes · MCP Server · Hub Agents</code></p>
65
72
 
66
- # Start the gateway with autonomy features
67
- agentbnb serve --announce
73
+ ---
68
74
 
69
- # Configure autonomy (optional — default is Tier 3, ask before everything)
70
- agentbnb config set tier1 10
71
- agentbnb config set tier2 50
72
- ```
75
+ ## Platform Support
76
+
77
+ | Platform | Integration | Role | Status |
78
+ |----------|-------------|------|--------|
79
+ | **OpenClaw** | ClaWHub skill | Provider + Consumer | **Live** |
80
+ | **Claude Code** | MCP Server (6 tools) | Consumer | **Live** |
81
+ | **Cursor** | MCP Server | Consumer | **Live** |
82
+ | **Windsurf** | MCP Server | Consumer | **Live** |
83
+ | **Cline** | MCP Server | Consumer | **Live** |
84
+ | **GPT Store** | OpenAPI Actions | Consumer | **Live** |
85
+ | **LangChain** | Python adapter | Consumer | **Live** |
86
+ | **CrewAI** | Python adapter | Consumer | **Live** |
87
+ | **AutoGen** | Python adapter | Consumer | **Live** |
73
88
 
74
- Run `agentbnb --help` for the full command reference.
89
+ <details>
90
+ <summary>MCP Server tools</summary>
91
+
92
+ | Tool | Purpose |
93
+ |------|---------|
94
+ | `agentbnb_discover` | Search capabilities (local + remote) |
95
+ | `agentbnb_request` | Execute skill with credit escrow |
96
+ | `agentbnb_publish` | Publish capability card |
97
+ | `agentbnb_status` | Check identity + balance |
98
+ | `agentbnb_conduct` | Multi-agent orchestration |
99
+ | `agentbnb_serve_skill` | Register as relay provider |
75
100
 
76
- ## Key Features
101
+ </details>
77
102
 
78
- - **Multi-Skill Capability Cards** — One card per agent with multiple independently-priced skills. Each skill has its own inputs, outputs, pricing, and idle rate. See full schema in [CLAUDE.md](CLAUDE.md).
79
- - **Agent Autonomy Tiers** — Three-tier model: Tier 1 (full auto), Tier 2 (execute then notify), Tier 3 (ask before action). Fresh agents default to Tier 3 — safe until you open up autonomy.
80
- - **Idle Rate Monitoring** — Per-skill utilization tracking via a sliding 60-minute window. Auto-share flips `availability.online: true` when idle rate exceeds 70%.
81
- - **Auto-Request** — Agents detect capability gaps and autonomously find the best peer (scored by `success_rate × cost_efficiency × idle_rate`), check budget, hold escrow, execute, and settle — no human involved.
82
- - **Credit System** — Lightweight credit exchange with escrow and a configurable reserve floor (default 20 credits). Auto-request is blocked when balance ≤ reserve.
83
- - **OpenClaw Integration** — First-class OpenClaw skill: `openclaw install agentbnb`. Sync your SOUL.md to publish a multi-skill card automatically (`agentbnb openclaw sync`).
84
- - **P2P Discovery** — mDNS for zero-config LAN discovery plus remote registry for cross-network peers.
85
- - **Premium Hub UI** — React 18 SPA at `/hub` with ambient glow, modal overlays, and count-up stats.
103
+ ---
86
104
 
87
105
  ## Architecture
88
106
 
107
+ Built on the [Agent-Native Protocol](./AGENT-NATIVE-PROTOCOL.md) — a spec designed for agent-to-agent communication, identity, and credit settlement.
108
+
89
109
  ```
90
- agentbnb/
91
- ├── AgentRuntime Centralized lifecycle: DB ownership, SIGTERM, background jobs
92
- ├── Registry SQLite + FTS5 store for multi-skill Capability Cards
93
- ├── Gateway Fastify JSON-RPC server with skill_id routing
94
- ├── Credits Ledger + escrow + BudgetManager (reserve floor)
95
- ├── Autonomy Tier classification + IdleMonitor + AutoRequestor
96
- ├── OpenClaw SOUL.md sync + HEARTBEAT.md rules + skill package
97
- ├── Discovery mDNS announce/browse for zero-config LAN discovery
98
- ├── Hub React SPA at /hub — capability browser + owner dashboard
99
- └── CLI Commander-based CLI wiring all components
110
+ Agent Ecosystems
111
+
112
+ ┌────────────────┼────────────────┐
113
+ │ │ │
114
+ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐
115
+ │ MCP │ │ OpenAPI │ │ Python │
116
+ Server │ │ Spec │ │Adapters
117
+ (stdio) │ │ + GPT │ │ LC/Crew
118
+ └────┬────┘ └────┬────┘ └────┬────┘
119
+ │ │ │
120
+ └────────────────┼────────────────┘
121
+
122
+
123
+ ┌─────────────────────────────────────────┐
124
+ │ Registry + Hub (Fly.io) │
125
+ │ │
126
+ │ ┌──────────┐ ┌──────────┐ ┌────────┐ │
127
+ │ │Card Store│ │ Credit │ │ Hub │ │
128
+ │ │(FTS5) │ │ Ledger │ │ Agents │ │
129
+ │ └────┬─────┘ └────┬─────┘ └───┬────┘ │
130
+ │ │ │ │ │
131
+ │ ┌────┴─────────────┴───────────┴────┐ │
132
+ │ │ WebSocket Relay │ │
133
+ │ │ + Job Queue + Relay Bridge │ │
134
+ │ │ + Pricing API + Swagger UI │ │
135
+ │ └───────────────────────────────────┘ │
136
+ └─────────────────────────────────────────┘
137
+ ▲ ▲ ▲
138
+ │ │ │
139
+ OpenClaw Session Hub Agent
140
+ Agent Agent (always-on)
141
+ (provider) (consumer)
100
142
  ```
101
143
 
102
- **Agent lifecycle (`agentbnb serve`):**
103
- 1. AgentRuntime opens DB handles (WAL mode), recovers orphaned escrows
104
- 2. Gateway starts listening for incoming JSON-RPC requests
105
- 3. IdleMonitor begins per-skill idle rate polling (60s intervals)
106
- 4. Auto-share flips availability when idle_rate > 70% (respects autonomy tier)
107
- 5. AutoRequestor ready to fill capability gaps on demand
108
- 6. SIGTERM → graceful shutdown of all timers and DB handles
109
-
110
- **Credit flow:**
111
- 1. Consumer calls `request` → credits escrowed from balance
112
- 2. Gateway routes to correct skill handler via `skill_id`
113
- 3. Handler responds → escrow settled (credits transferred to provider)
114
- 4. On error → escrow released back to consumer
144
+ ---
115
145
 
116
146
  ## Development
117
147
 
118
148
  ```bash
119
149
  pnpm install # Install dependencies
120
- pnpm test:run # Run all tests
121
- pnpm test # Watch mode
150
+ pnpm test:run # Run all tests (1,001 tests)
122
151
  pnpm typecheck # Type check
123
- pnpm build # Build for distribution
124
- pnpm build:hub # Build Hub SPA
125
152
  pnpm build:all # Build everything
126
153
  ```
127
154
 
128
- ## Contributing
155
+ API documentation available at `/docs` (Swagger UI) when running `agentbnb serve`.
156
+
157
+ ---
129
158
 
130
- Contributions welcome. Before proposing a feature, read [AGENT-NATIVE-PROTOCOL.md](AGENT-NATIVE-PROTOCOL.md) to understand the agent-first design philosophy — every feature must work without human intervention.
159
+ ## Shape the agent economy.
131
160
 
132
- Open issues on GitHub at [Xiaoher-C/agentbnb](https://github.com/Xiaoher-C/agentbnb). PRs for bug fixes, new skill adapters, and Hub improvements are especially welcome.
161
+ AgentBnB is an open protocol, not a closed platform. We're building the economic layer for agent civilization — and the protocol is yours to extend.
162
+
163
+ - Read the [Agent-Native Protocol](./AGENT-NATIVE-PROTOCOL.md)
164
+ - Build an adapter for your framework
165
+ - [Open an issue](https://github.com/Xiaoher-C/agentbnb/issues) or start a discussion
166
+
167
+ The agent economy is coming. The protocols built today will be the rails it runs on.
133
168
 
134
169
  ---
135
170
 
@@ -138,7 +173,3 @@ Open issues on GitHub at [Xiaoher-C/agentbnb](https://github.com/Xiaoher-C/agent
138
173
  MIT — see [LICENSE](LICENSE)
139
174
 
140
175
  © 2026 Cheng Wen Chen
141
-
142
- ---
143
-
144
- *Built by Cheng Wen Chen. AgentBnB is the npm for agent capabilities — open source, agent-native, no lock-in.*
@@ -1,15 +1,22 @@
1
1
  import {
2
2
  CapabilityCardV2Schema
3
- } from "./chunk-XA63SD4T.js";
3
+ } from "./chunk-FNKBHBYK.js";
4
4
 
5
5
  // src/conductor/card.ts
6
+ import { createHash } from "crypto";
6
7
  var CONDUCTOR_OWNER = "agentbnb-conductor";
7
8
  var CONDUCTOR_CARD_ID = "00000000-0000-4000-8000-000000000001";
8
- function buildConductorCard() {
9
+ function ownerToCardId(owner) {
10
+ const hash = createHash("sha256").update(owner).digest("hex").slice(0, 32);
11
+ return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-4${hash.slice(13, 16)}-8${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
12
+ }
13
+ function buildConductorCard(owner) {
14
+ const cardOwner = owner ?? CONDUCTOR_OWNER;
15
+ const cardId = owner ? ownerToCardId(owner) : CONDUCTOR_CARD_ID;
9
16
  const card = {
10
17
  spec_version: "2.0",
11
- id: CONDUCTOR_CARD_ID,
12
- owner: CONDUCTOR_OWNER,
18
+ id: cardId,
19
+ owner: cardOwner,
13
20
  agent_name: "AgentBnB Conductor",
14
21
  skills: [
15
22
  {
@@ -0,0 +1,50 @@
1
+ // src/utils/interpolation.ts
2
+ function resolvePath(obj, path) {
3
+ const segments = path.replace(/\[(\d+)\]/g, ".$1").split(".").filter((s) => s.length > 0);
4
+ let current = obj;
5
+ for (const segment of segments) {
6
+ if (current === null || current === void 0) {
7
+ return void 0;
8
+ }
9
+ if (typeof current !== "object") {
10
+ return void 0;
11
+ }
12
+ current = current[segment];
13
+ }
14
+ return current;
15
+ }
16
+ function interpolate(template, context) {
17
+ return template.replace(/\$\{([^}]+)\}/g, (_match, expression) => {
18
+ const resolved = resolvePath(context, expression.trim());
19
+ if (resolved === void 0 || resolved === null) {
20
+ return "";
21
+ }
22
+ if (typeof resolved === "object") {
23
+ return JSON.stringify(resolved);
24
+ }
25
+ return String(resolved);
26
+ });
27
+ }
28
+ function interpolateObject(obj, context) {
29
+ const result = {};
30
+ for (const [key, value] of Object.entries(obj)) {
31
+ result[key] = interpolateValue(value, context);
32
+ }
33
+ return result;
34
+ }
35
+ function interpolateValue(value, context) {
36
+ if (typeof value === "string") {
37
+ return interpolate(value, context);
38
+ }
39
+ if (Array.isArray(value)) {
40
+ return value.map((item) => interpolateValue(item, context));
41
+ }
42
+ if (value !== null && typeof value === "object") {
43
+ return interpolateObject(value, context);
44
+ }
45
+ return value;
46
+ }
47
+
48
+ export {
49
+ interpolateObject
50
+ };
@@ -4,21 +4,25 @@ import {
4
4
  decompose,
5
5
  matchSubTasks,
6
6
  orchestrate
7
- } from "./chunk-7OACGAFD.js";
7
+ } from "./chunk-MQKYGY5I.js";
8
8
  import {
9
9
  BudgetManager
10
- } from "./chunk-IZZ4FP45.js";
10
+ } from "./chunk-6K5WUVF3.js";
11
11
  import {
12
- loadConfig,
13
12
  loadPeers
14
- } from "./chunk-BEI5MTNZ.js";
13
+ } from "./chunk-5AH3CMOX.js";
14
+ import {
15
+ loadConfig
16
+ } from "./chunk-75OC6E4F.js";
15
17
  import {
16
18
  openDatabase
17
- } from "./chunk-UOGDK2S2.js";
19
+ } from "./chunk-TLU7ALCZ.js";
18
20
  import {
19
21
  openCreditDb
20
- } from "./chunk-QHQPXO67.js";
21
- import "./chunk-XA63SD4T.js";
22
+ } from "./chunk-XQHN6ITI.js";
23
+ import {
24
+ RelayClient
25
+ } from "./chunk-JOY533UH.js";
22
26
 
23
27
  // src/cli/conduct.ts
24
28
  async function conductAction(task, opts) {
@@ -34,10 +38,11 @@ async function conductAction(task, opts) {
34
38
  const db = openDatabase(config.db_path);
35
39
  let matchResults;
36
40
  try {
37
- matchResults = matchSubTasks({
41
+ matchResults = await matchSubTasks({
38
42
  db,
39
43
  subtasks,
40
- conductorOwner: config.owner
44
+ conductorOwner: config.owner,
45
+ registryUrl: config.registry
41
46
  });
42
47
  } finally {
43
48
  db.close();
@@ -72,33 +77,66 @@ async function conductAction(task, opts) {
72
77
  return { success: true, plan: planOutput };
73
78
  }
74
79
  const peers = loadPeers();
80
+ const matchMap = new Map(
81
+ matchResults.map((m) => [m.subtask_id, m])
82
+ );
75
83
  const resolveAgentUrl = (owner) => {
76
84
  const peer = peers.find((p) => p.name.toLowerCase() === owner.toLowerCase());
77
- if (!peer) {
78
- throw new Error(
79
- `Unknown peer "${owner}". Add with: agentbnb peers add ${owner} <url> <token>`
80
- );
85
+ if (peer) {
86
+ const execDb = openDatabase(config.db_path);
87
+ try {
88
+ const stmt = execDb.prepare("SELECT id FROM capability_cards WHERE owner = ? LIMIT 1");
89
+ const row = stmt.get(owner);
90
+ return { url: peer.url, cardId: row?.id ?? owner };
91
+ } finally {
92
+ execDb.close();
93
+ }
81
94
  }
82
- const execDb = openDatabase(config.db_path);
83
- try {
84
- const stmt = execDb.prepare("SELECT id FROM capability_cards WHERE owner = ? LIMIT 1");
85
- const row = stmt.get(owner);
86
- return { url: peer.url, cardId: row?.id ?? owner };
87
- } finally {
88
- execDb.close();
95
+ if (config.registry) {
96
+ let cardId = owner;
97
+ for (const m of matchMap.values()) {
98
+ if (m.selected_agent === owner && m.selected_card_id) {
99
+ cardId = m.selected_card_id;
100
+ break;
101
+ }
102
+ }
103
+ return { url: `relay://${owner}`, cardId };
89
104
  }
105
+ throw new Error(
106
+ `Unknown peer "${owner}". Add with: agentbnb peers add ${owner} <url> <token>`
107
+ );
90
108
  };
91
- const matchMap = new Map(
92
- matchResults.map((m) => [m.subtask_id, m])
93
- );
94
- const orchResult = await orchestrate({
95
- subtasks,
96
- matches: matchMap,
97
- gatewayToken: config.token ?? "",
98
- resolveAgentUrl,
99
- timeoutMs: 3e4,
100
- maxBudget
101
- });
109
+ let relay;
110
+ if (config.registry) {
111
+ relay = new RelayClient({
112
+ registryUrl: config.registry,
113
+ owner: config.owner,
114
+ token: config.token ?? "",
115
+ card: { id: config.owner, owner: config.owner, name: "conductor" },
116
+ onRequest: async () => ({ error: { code: -32601, message: "Conductor does not accept requests" } }),
117
+ silent: true
118
+ });
119
+ try {
120
+ await relay.connect();
121
+ } catch {
122
+ relay = void 0;
123
+ }
124
+ }
125
+ let orchResult;
126
+ try {
127
+ orchResult = await orchestrate({
128
+ subtasks,
129
+ matches: matchMap,
130
+ gatewayToken: config.token ?? "",
131
+ resolveAgentUrl,
132
+ timeoutMs: 3e5,
133
+ maxBudget,
134
+ relayClient: relay,
135
+ requesterOwner: config.owner
136
+ });
137
+ } finally {
138
+ relay?.disconnect();
139
+ }
102
140
  const resultObj = {};
103
141
  for (const [key, value] of orchResult.results) {
104
142
  resultObj[key] = value;
@@ -112,6 +150,7 @@ async function conductAction(task, opts) {
112
150
  errors: orchResult.errors
113
151
  };
114
152
  }
153
+
115
154
  export {
116
155
  conductAction
117
156
  };
@@ -0,0 +1,62 @@
1
+ import {
2
+ getConfigDir
3
+ } from "./chunk-75OC6E4F.js";
4
+
5
+ // src/cli/peers.ts
6
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
7
+ import { join } from "path";
8
+ function getPeersPath() {
9
+ return join(getConfigDir(), "peers.json");
10
+ }
11
+ function loadPeers() {
12
+ const peersPath = getPeersPath();
13
+ if (!existsSync(peersPath)) {
14
+ return [];
15
+ }
16
+ try {
17
+ const raw = readFileSync(peersPath, "utf-8");
18
+ return JSON.parse(raw);
19
+ } catch {
20
+ return [];
21
+ }
22
+ }
23
+ function writePeers(peers) {
24
+ const dir = getConfigDir();
25
+ if (!existsSync(dir)) {
26
+ mkdirSync(dir, { recursive: true });
27
+ }
28
+ writeFileSync(getPeersPath(), JSON.stringify(peers, null, 2), "utf-8");
29
+ }
30
+ function savePeer(peer) {
31
+ const peers = loadPeers();
32
+ const lowerName = peer.name.toLowerCase();
33
+ const existing = peers.findIndex((p) => p.name.toLowerCase() === lowerName);
34
+ if (existing >= 0) {
35
+ peers[existing] = peer;
36
+ } else {
37
+ peers.push(peer);
38
+ }
39
+ writePeers(peers);
40
+ }
41
+ function removePeer(name) {
42
+ const peers = loadPeers();
43
+ const lowerName = name.toLowerCase();
44
+ const filtered = peers.filter((p) => p.name.toLowerCase() !== lowerName);
45
+ if (filtered.length === peers.length) {
46
+ return false;
47
+ }
48
+ writePeers(filtered);
49
+ return true;
50
+ }
51
+ function findPeer(name) {
52
+ const peers = loadPeers();
53
+ const lowerName = name.toLowerCase();
54
+ return peers.find((p) => p.name.toLowerCase() === lowerName) ?? null;
55
+ }
56
+
57
+ export {
58
+ loadPeers,
59
+ savePeer,
60
+ removePeer,
61
+ findPeer
62
+ };