@avow-finance/sdk 0.0.0-stage → 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.
Files changed (267) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +122 -2
  3. package/dist/agent-entry.d.ts +15 -0
  4. package/dist/agent-entry.d.ts.map +1 -0
  5. package/dist/agent-entry.js +11 -0
  6. package/dist/agent-entry.js.map +1 -0
  7. package/dist/agent-key.d.ts +34 -0
  8. package/dist/agent-key.d.ts.map +1 -0
  9. package/dist/agent-key.js +33 -0
  10. package/dist/agent-key.js.map +1 -0
  11. package/dist/agent.d.ts +261 -0
  12. package/dist/agent.d.ts.map +1 -0
  13. package/dist/agent.js +493 -0
  14. package/dist/agent.js.map +1 -0
  15. package/dist/avow-api.d.ts +78 -0
  16. package/dist/avow-api.d.ts.map +1 -0
  17. package/dist/avow-api.js +2 -0
  18. package/dist/avow-api.js.map +1 -0
  19. package/dist/contest.d.ts +135 -0
  20. package/dist/contest.d.ts.map +1 -0
  21. package/dist/contest.js +186 -0
  22. package/dist/contest.js.map +1 -0
  23. package/dist/http.d.ts +161 -0
  24. package/dist/http.d.ts.map +1 -0
  25. package/dist/http.js +311 -0
  26. package/dist/http.js.map +1 -0
  27. package/dist/index.d.ts +38 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +38 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/job/accept.d.ts +84 -0
  32. package/dist/job/accept.d.ts.map +1 -0
  33. package/dist/job/accept.js +136 -0
  34. package/dist/job/accept.js.map +1 -0
  35. package/dist/job/customer.d.ts +43 -0
  36. package/dist/job/customer.d.ts.map +1 -0
  37. package/dist/job/customer.js +83 -0
  38. package/dist/job/customer.js.map +1 -0
  39. package/dist/job/quote.d.ts +34 -0
  40. package/dist/job/quote.d.ts.map +1 -0
  41. package/dist/job/quote.js +37 -0
  42. package/dist/job/quote.js.map +1 -0
  43. package/dist/lock.d.ts +269 -0
  44. package/dist/lock.d.ts.map +1 -0
  45. package/dist/lock.js +283 -0
  46. package/dist/lock.js.map +1 -0
  47. package/dist/moderato.d.ts +27 -0
  48. package/dist/moderato.d.ts.map +1 -0
  49. package/dist/moderato.js +34 -0
  50. package/dist/moderato.js.map +1 -0
  51. package/dist/node/cli.d.ts +3 -0
  52. package/dist/node/cli.d.ts.map +1 -0
  53. package/dist/node/cli.js +346 -0
  54. package/dist/node/cli.js.map +1 -0
  55. package/dist/node/connect.d.ts +15 -0
  56. package/dist/node/connect.d.ts.map +1 -0
  57. package/dist/node/connect.js +91 -0
  58. package/dist/node/connect.js.map +1 -0
  59. package/dist/node/eval.d.ts +3 -0
  60. package/dist/node/eval.d.ts.map +1 -0
  61. package/dist/node/eval.js +67 -0
  62. package/dist/node/eval.js.map +1 -0
  63. package/dist/node/first-run.d.ts +50 -0
  64. package/dist/node/first-run.d.ts.map +1 -0
  65. package/dist/node/first-run.js +149 -0
  66. package/dist/node/first-run.js.map +1 -0
  67. package/dist/node/job.d.ts +50 -0
  68. package/dist/node/job.d.ts.map +1 -0
  69. package/dist/node/job.js +176 -0
  70. package/dist/node/job.js.map +1 -0
  71. package/dist/node/mailbox.d.ts +19 -0
  72. package/dist/node/mailbox.d.ts.map +1 -0
  73. package/dist/node/mailbox.js +81 -0
  74. package/dist/node/mailbox.js.map +1 -0
  75. package/dist/node/mcp.d.ts +74 -0
  76. package/dist/node/mcp.d.ts.map +1 -0
  77. package/dist/node/mcp.js +367 -0
  78. package/dist/node/mcp.js.map +1 -0
  79. package/dist/node/platform.d.ts +35 -0
  80. package/dist/node/platform.d.ts.map +1 -0
  81. package/dist/node/platform.js +102 -0
  82. package/dist/node/platform.js.map +1 -0
  83. package/dist/node/runner-session.d.ts +41 -0
  84. package/dist/node/runner-session.d.ts.map +1 -0
  85. package/dist/node/runner-session.js +100 -0
  86. package/dist/node/runner-session.js.map +1 -0
  87. package/dist/node/runner.d.ts +63 -0
  88. package/dist/node/runner.d.ts.map +1 -0
  89. package/dist/node/runner.js +341 -0
  90. package/dist/node/runner.js.map +1 -0
  91. package/dist/node/service-child.d.ts +2 -0
  92. package/dist/node/service-child.d.ts.map +1 -0
  93. package/dist/node/service-child.js +40 -0
  94. package/dist/node/service-child.js.map +1 -0
  95. package/dist/node/service-excerpt.d.ts +21 -0
  96. package/dist/node/service-excerpt.d.ts.map +1 -0
  97. package/dist/node/service-excerpt.js +32 -0
  98. package/dist/node/service-excerpt.js.map +1 -0
  99. package/dist/node/service-process.d.ts +12 -0
  100. package/dist/node/service-process.d.ts.map +1 -0
  101. package/dist/node/service-process.js +132 -0
  102. package/dist/node/service-process.js.map +1 -0
  103. package/dist/node/session-input.d.ts +12 -0
  104. package/dist/node/session-input.d.ts.map +1 -0
  105. package/dist/node/session-input.js +42 -0
  106. package/dist/node/session-input.js.map +1 -0
  107. package/dist/node/session-view.d.ts +20 -0
  108. package/dist/node/session-view.d.ts.map +1 -0
  109. package/dist/node/session-view.js +198 -0
  110. package/dist/node/session-view.js.map +1 -0
  111. package/dist/node-agent.d.ts +2 -0
  112. package/dist/node-agent.d.ts.map +1 -0
  113. package/dist/node-agent.js +6 -0
  114. package/dist/node-agent.js.map +1 -0
  115. package/dist/node.d.ts +2 -0
  116. package/dist/node.d.ts.map +1 -0
  117. package/dist/node.js +9 -0
  118. package/dist/node.js.map +1 -0
  119. package/dist/sandbox/agent.d.ts +187 -0
  120. package/dist/sandbox/agent.d.ts.map +1 -0
  121. package/dist/sandbox/agent.js +468 -0
  122. package/dist/sandbox/agent.js.map +1 -0
  123. package/dist/sandbox/business-store.d.ts +19 -0
  124. package/dist/sandbox/business-store.d.ts.map +1 -0
  125. package/dist/sandbox/business-store.js +19 -0
  126. package/dist/sandbox/business-store.js.map +1 -0
  127. package/dist/sandbox/business.d.ts +70 -0
  128. package/dist/sandbox/business.d.ts.map +1 -0
  129. package/dist/sandbox/business.js +115 -0
  130. package/dist/sandbox/business.js.map +1 -0
  131. package/dist/sandbox/connect.d.ts +64 -0
  132. package/dist/sandbox/connect.d.ts.map +1 -0
  133. package/dist/sandbox/connect.js +182 -0
  134. package/dist/sandbox/connect.js.map +1 -0
  135. package/dist/sandbox/deployment.d.ts +14 -0
  136. package/dist/sandbox/deployment.d.ts.map +1 -0
  137. package/dist/sandbox/deployment.js +38 -0
  138. package/dist/sandbox/deployment.js.map +1 -0
  139. package/dist/sandbox/keys.d.ts +45 -0
  140. package/dist/sandbox/keys.d.ts.map +1 -0
  141. package/dist/sandbox/keys.js +132 -0
  142. package/dist/sandbox/keys.js.map +1 -0
  143. package/dist/sandbox/mailbox.d.ts +90 -0
  144. package/dist/sandbox/mailbox.d.ts.map +1 -0
  145. package/dist/sandbox/mailbox.js +400 -0
  146. package/dist/sandbox/mailbox.js.map +1 -0
  147. package/dist/sandbox/mandate.d.ts +84 -0
  148. package/dist/sandbox/mandate.d.ts.map +1 -0
  149. package/dist/sandbox/mandate.js +107 -0
  150. package/dist/sandbox/mandate.js.map +1 -0
  151. package/dist/sandbox/namespace.d.ts +16 -0
  152. package/dist/sandbox/namespace.d.ts.map +1 -0
  153. package/dist/sandbox/namespace.js +16 -0
  154. package/dist/sandbox/namespace.js.map +1 -0
  155. package/dist/sandbox/session.d.ts +60 -0
  156. package/dist/sandbox/session.d.ts.map +1 -0
  157. package/dist/sandbox/session.js +94 -0
  158. package/dist/sandbox/session.js.map +1 -0
  159. package/dist/sandbox/setup.d.ts +136 -0
  160. package/dist/sandbox/setup.d.ts.map +1 -0
  161. package/dist/sandbox/setup.js +490 -0
  162. package/dist/sandbox/setup.js.map +1 -0
  163. package/dist/sandbox/store.d.ts +69 -0
  164. package/dist/sandbox/store.d.ts.map +1 -0
  165. package/dist/sandbox/store.js +115 -0
  166. package/dist/sandbox/store.js.map +1 -0
  167. package/dist/sandbox/supplier-key.d.ts +73 -0
  168. package/dist/sandbox/supplier-key.d.ts.map +1 -0
  169. package/dist/sandbox/supplier-key.js +180 -0
  170. package/dist/sandbox/supplier-key.js.map +1 -0
  171. package/dist/sandbox/suppliers.d.ts +7 -0
  172. package/dist/sandbox/suppliers.d.ts.map +1 -0
  173. package/dist/sandbox/suppliers.js +29 -0
  174. package/dist/sandbox/suppliers.js.map +1 -0
  175. package/dist/sandbox/terms.d.ts +32 -0
  176. package/dist/sandbox/terms.d.ts.map +1 -0
  177. package/dist/sandbox/terms.js +58 -0
  178. package/dist/sandbox/terms.js.map +1 -0
  179. package/dist/sandbox/vault.d.ts +24 -0
  180. package/dist/sandbox/vault.d.ts.map +1 -0
  181. package/dist/sandbox/vault.js +54 -0
  182. package/dist/sandbox/vault.js.map +1 -0
  183. package/dist/send.d.ts +122 -0
  184. package/dist/send.d.ts.map +1 -0
  185. package/dist/send.js +328 -0
  186. package/dist/send.js.map +1 -0
  187. package/dist/service-entry.d.ts +6 -0
  188. package/dist/service-entry.d.ts.map +1 -0
  189. package/dist/service-entry.js +6 -0
  190. package/dist/service-entry.js.map +1 -0
  191. package/dist/session/anthropic.d.ts +17 -0
  192. package/dist/session/anthropic.d.ts.map +1 -0
  193. package/dist/session/anthropic.js +215 -0
  194. package/dist/session/anthropic.js.map +1 -0
  195. package/dist/session/charge.d.ts +13 -0
  196. package/dist/session/charge.d.ts.map +1 -0
  197. package/dist/session/charge.js +33 -0
  198. package/dist/session/charge.js.map +1 -0
  199. package/dist/session/data.d.ts +8 -0
  200. package/dist/session/data.d.ts.map +1 -0
  201. package/dist/session/data.js +20 -0
  202. package/dist/session/data.js.map +1 -0
  203. package/dist/session/eval.d.ts +41 -0
  204. package/dist/session/eval.d.ts.map +1 -0
  205. package/dist/session/eval.js +281 -0
  206. package/dist/session/eval.js.map +1 -0
  207. package/dist/session/executor.d.ts +80 -0
  208. package/dist/session/executor.d.ts.map +1 -0
  209. package/dist/session/executor.js +381 -0
  210. package/dist/session/executor.js.map +1 -0
  211. package/dist/session/fixture-world.d.ts +29 -0
  212. package/dist/session/fixture-world.d.ts.map +1 -0
  213. package/dist/session/fixture-world.js +708 -0
  214. package/dist/session/fixture-world.js.map +1 -0
  215. package/dist/session/live-world.d.ts +22 -0
  216. package/dist/session/live-world.d.ts.map +1 -0
  217. package/dist/session/live-world.js +329 -0
  218. package/dist/session/live-world.js.map +1 -0
  219. package/dist/session/ollama.d.ts +29 -0
  220. package/dist/session/ollama.d.ts.map +1 -0
  221. package/dist/session/ollama.js +177 -0
  222. package/dist/session/ollama.js.map +1 -0
  223. package/dist/session/provider.d.ts +79 -0
  224. package/dist/session/provider.d.ts.map +1 -0
  225. package/dist/session/provider.js +19 -0
  226. package/dist/session/provider.js.map +1 -0
  227. package/dist/session/scripted.d.ts +45 -0
  228. package/dist/session/scripted.d.ts.map +1 -0
  229. package/dist/session/scripted.js +236 -0
  230. package/dist/session/scripted.js.map +1 -0
  231. package/dist/session/selection.d.ts +37 -0
  232. package/dist/session/selection.d.ts.map +1 -0
  233. package/dist/session/selection.js +104 -0
  234. package/dist/session/selection.js.map +1 -0
  235. package/dist/session/service-check.d.ts +48 -0
  236. package/dist/session/service-check.d.ts.map +1 -0
  237. package/dist/session/service-check.js +86 -0
  238. package/dist/session/service-check.js.map +1 -0
  239. package/dist/session/service.d.ts +128 -0
  240. package/dist/session/service.d.ts.map +1 -0
  241. package/dist/session/service.js +150 -0
  242. package/dist/session/service.js.map +1 -0
  243. package/dist/session/session.d.ts +95 -0
  244. package/dist/session/session.d.ts.map +1 -0
  245. package/dist/session/session.js +312 -0
  246. package/dist/session/session.js.map +1 -0
  247. package/dist/session/toolbox.d.ts +69 -0
  248. package/dist/session/toolbox.d.ts.map +1 -0
  249. package/dist/session/toolbox.js +391 -0
  250. package/dist/session/toolbox.js.map +1 -0
  251. package/dist/session/tools.d.ts +45 -0
  252. package/dist/session/tools.d.ts.map +1 -0
  253. package/dist/session/tools.js +137 -0
  254. package/dist/session/tools.js.map +1 -0
  255. package/dist/session/world.d.ts +188 -0
  256. package/dist/session/world.d.ts.map +1 -0
  257. package/dist/session/world.js +2 -0
  258. package/dist/session/world.js.map +1 -0
  259. package/dist/sign.d.ts +19 -0
  260. package/dist/sign.d.ts.map +1 -0
  261. package/dist/sign.js +33 -0
  262. package/dist/sign.js.map +1 -0
  263. package/dist/supplier.d.ts +41 -0
  264. package/dist/supplier.d.ts.map +1 -0
  265. package/dist/supplier.js +57 -0
  266. package/dist/supplier.js.map +1 -0
  267. package/package.json +56 -3
@@ -0,0 +1,367 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync, } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { dirname, join, resolve } from 'node:path';
6
+ import { createInterface } from 'node:readline';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { formatUsd, isSessionId, SANDBOX_TOOLS, toWire, whenRetryPasses, } from '@avow-finance/spec';
9
+ import { Refusal, sandboxAgent } from '../sandbox/agent.js';
10
+ import { sessionUrl } from '../sandbox/session.js';
11
+ import { fileStore, SANDBOX_DIR, takeRun } from './platform.js';
12
+ /**
13
+ * `avow-sandbox-mcp` gives a model in Claude Code, Claude Desktop or any other MCP client the
14
+ * starter's agent, with three tools. It runs as the agent, with only the agent's key, through the
15
+ * same SDK calls agent.ts makes, and it never opens the business's key. Each tool call reports to
16
+ * the screen the runner opened, marked as the MCP agent's.
17
+ *
18
+ * avow-sandbox-mcp [--dir <folder>] serves MCP over stdio for the agent in <folder>
19
+ * avow-sandbox-mcp add claude-code adds the server to Claude Code for this folder
20
+ * avow-sandbox-mcp add claude-desktop adds the server to Claude Desktop
21
+ */
22
+ const SERVER = { name: 'avow-sandbox', version: '0.0.0' };
23
+ const PROTOCOL = '2025-06-18';
24
+ /** How long a booking waits for the supplier's acceptance before it answers. */
25
+ const ACCEPTANCE_WAIT_MS = 45_000;
26
+ const usd = (dollars) => dollars === null ? 'no limit' : formatUsd(BigInt(Math.round(dollars * 1_000_000)));
27
+ const noInput = { type: 'object', properties: {}, additionalProperties: false };
28
+ /** The tools, kept to what shows the authority model and nothing more. */
29
+ export const MCP_TOOLS = [
30
+ {
31
+ name: 'authority',
32
+ description: "What your agent can commit right now. It has two limits. It holds at most so much in bookings at once, which Avow refuses past and the lock checks against Avow's approval. Its key moves at most so much a day, a limit the business set on chain. It names the suppliers the agent may book too.",
33
+ inputSchema: noInput,
34
+ },
35
+ {
36
+ name: 'book',
37
+ description: "Books GPU capacity with one of your agent's suppliers, backed by a reserve in your business's own lock. Avow checks the booking against the mandate and what the lock holds before any money moves, the agent's machine runs the open verifier, and the supplier accepts on the lock. A refusal comes back with its reason code, the layer that refused it, the amounts and when the same booking could pass. A reserve that never landed with no reason given comes back as a failure. Held reserves come back as bookings end or are cancelled, the key's daily limit starts again each day, Avow's relay can be limiting how much it takes for now, and anything else in the mandate changes only when the business signs a new one.",
38
+ inputSchema: {
39
+ type: 'object',
40
+ properties: {
41
+ reserve: { type: 'number', description: 'The reserve in dollars, such as 200' },
42
+ gpu: { type: 'string', description: 'The GPU model, H100 when left out' },
43
+ count: { type: 'integer', description: 'How many GPUs, 8 when left out' },
44
+ hours: { type: 'number', description: 'How many hours, 1 when left out' },
45
+ supplier: {
46
+ type: 'string',
47
+ description: "The supplier's business id, the agent's first supplier when left out",
48
+ },
49
+ },
50
+ required: ['reserve'],
51
+ additionalProperties: false,
52
+ },
53
+ },
54
+ {
55
+ name: 'commitments',
56
+ description: 'Lists every commitment your agent made, with its state on the lock, whether the current authority made it, and a link anyone can open to check it.',
57
+ inputSchema: noInput,
58
+ },
59
+ ];
60
+ /** The session the runner opened in this folder, while the runner still runs. */
61
+ function runnerSession(dir) {
62
+ try {
63
+ const { id, pid } = JSON.parse(readFileSync(join(dir, SANDBOX_DIR, 'session.json'), 'utf8'));
64
+ if (typeof id !== 'string' || !isSessionId(id) || typeof pid !== 'number')
65
+ return null;
66
+ process.kill(pid, 0);
67
+ return id;
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ }
73
+ /** The MCP agent for one folder, answering each tool call through the SDK's agent. */
74
+ export function mcpAgent(dir, options = {}) {
75
+ const store = fileStore(join(dir, SANDBOX_DIR));
76
+ const log = (line) => process.stderr.write(`${line}\n`);
77
+ async function open(tool) {
78
+ const id = runnerSession(dir);
79
+ return sandboxAgent({
80
+ store,
81
+ session: id ? { id, run: takeRun(join(dir, SANDBOX_DIR), id) } : null,
82
+ source: 'mcp',
83
+ tool,
84
+ log,
85
+ ...(options.fetch ? { fetch: options.fetch } : {}),
86
+ });
87
+ }
88
+ const screen = () => {
89
+ const id = runnerSession(dir);
90
+ return id ? sessionUrl(id) : null;
91
+ };
92
+ async function authority() {
93
+ const agent = await open('authority');
94
+ const left = await agent.left();
95
+ const dailyLeft = await agent.dailyLeft();
96
+ const now = dailyLeft === null ? left : Math.min(left, dailyLeft);
97
+ return {
98
+ text: [
99
+ `Your agent can commit up to ${usd(now)} more right now.`,
100
+ `It holds at most ${usd(agent.authority)} in bookings at once, which Avow refuses past and the lock checks against Avow's approval, and ${usd(left)} of that is free.`,
101
+ `Its key moves at most ${usd(agent.dailyLimit)} a day, a limit your business set on chain, and ${usd(dailyLeft)} of today's is left.`,
102
+ `It may book with ${agent.suppliers.map((s) => s.id).join(', ')} only.`,
103
+ ].join(' '),
104
+ structured: {
105
+ canCommitNow: now,
106
+ heldAtOnce: { limit: agent.authority, left },
107
+ movedPerDay: { limit: agent.dailyLimit, left: dailyLeft },
108
+ suppliers: agent.suppliers,
109
+ business: agent.business,
110
+ mandateHash: agent.mandateHash,
111
+ screen: screen(),
112
+ },
113
+ isError: false,
114
+ };
115
+ }
116
+ async function book(args) {
117
+ const reserve = args.reserve;
118
+ if (typeof reserve !== 'number')
119
+ throw new RangeError('The booking needs a reserve in dollars');
120
+ const agent = await open('book');
121
+ const gpu = typeof args.gpu === 'string' ? args.gpu : 'H100';
122
+ const count = typeof args.count === 'number' ? args.count : 8;
123
+ const hours = typeof args.hours === 'number' ? args.hours : 1;
124
+ const supplier = typeof args.supplier === 'string' ? args.supplier : (agent.suppliers[0]?.id ?? '');
125
+ try {
126
+ const c = await agent.book({ supplier, resource: { gpu, count, hours }, reserve });
127
+ const checks = await c.verify();
128
+ const accepted = await Promise.race([
129
+ c.accepted(),
130
+ new Promise((done) => setTimeout(() => done(null), ACCEPTANCE_WAIT_MS).unref()),
131
+ ]);
132
+ const passed = checks.filter((k) => k.passed).length;
133
+ return {
134
+ text: [
135
+ `Committed ${usd(c.amount)} with ${supplier} for ${count} ${gpu} for ${hours} hour${hours === 1 ? '' : 's'}.`,
136
+ accepted === true
137
+ ? 'The supplier checked the commitment and accepted it on the lock.'
138
+ : accepted === false
139
+ ? "The supplier didn't accept it in time, so the reserve goes back to the business."
140
+ : "The supplier hasn't accepted it yet, and the commitments tool shows when it does.",
141
+ `On this machine the open verifier passed ${passed} of ${checks.length} checks.`,
142
+ `Your agent has ${usd(c.left)} left of its ${usd(agent.authority)} held at once.`,
143
+ `Anyone can check the commitment at ${c.link}`,
144
+ ].join(' '),
145
+ structured: {
146
+ status: 'committed',
147
+ reserve: c.amount,
148
+ supplier,
149
+ resource: { gpu, count, hours },
150
+ accepted,
151
+ checks,
152
+ reference: toWire(c.reference),
153
+ link: c.link,
154
+ left: c.left,
155
+ screen: screen(),
156
+ },
157
+ isError: false,
158
+ };
159
+ }
160
+ catch (error) {
161
+ if (!(error instanceof Refusal))
162
+ throw error;
163
+ const dollars = (micros) => micros === null ? null : Number(micros) / 1_000_000;
164
+ // A reserve that never landed with no reason given is a failure, and nothing refused it.
165
+ const failed = error.layer === 'unknown';
166
+ return {
167
+ text: failed
168
+ ? `The booking failed, with reason code ${error.code}. ${error.message}`
169
+ : `Refused by ${error.layer === 'sdk' ? 'the SDK' : error.layer}, with reason code ${error.code}. ${error.message}`,
170
+ structured: {
171
+ status: failed ? 'failed' : 'refused',
172
+ code: error.code,
173
+ layer: error.layer,
174
+ sentence: error.message,
175
+ retry: whenRetryPasses(error),
176
+ amounts: {
177
+ needed: dollars(error.amounts.needed),
178
+ left: dollars(error.amounts.left),
179
+ heldAtOnce: dollars(error.amounts.authority),
180
+ perCommitment: dollars(error.amounts.capPerCommitment),
181
+ movedPerDay: dollars(error.amounts.dailyLimit),
182
+ movedToday: dollars(error.amounts.dailyLeft),
183
+ },
184
+ screen: screen(),
185
+ },
186
+ isError: false,
187
+ };
188
+ }
189
+ }
190
+ async function commitments() {
191
+ const agent = await open('commitments');
192
+ const list = await agent.commitments();
193
+ return {
194
+ text: list.length === 0
195
+ ? 'Your agent has made no commitments yet.'
196
+ : list
197
+ .map((c) => `${usd(c.amount)} with ${c.supplier}, ${c.state}${c.current ? '' : ', made under an earlier authority'}, at ${new Date(Number(c.madeAt) * 1000).toISOString()}. Check it at ${c.link}`)
198
+ .join('\n'),
199
+ structured: {
200
+ commitments: list.map((c) => ({
201
+ amount: c.amount,
202
+ supplier: c.supplier,
203
+ state: c.state,
204
+ current: c.current,
205
+ madeAt: Number(c.madeAt),
206
+ releaseDate: c.releaseDate === null ? null : Number(c.releaseDate),
207
+ reference: toWire(c.reference),
208
+ link: c.link,
209
+ })),
210
+ },
211
+ isError: false,
212
+ };
213
+ }
214
+ return {
215
+ async call(name, args) {
216
+ try {
217
+ if (name === 'authority')
218
+ return await authority();
219
+ if (name === 'book')
220
+ return await book(args);
221
+ if (name === 'commitments')
222
+ return await commitments();
223
+ return { text: `There's no tool named ${name}.`, structured: {}, isError: true };
224
+ }
225
+ catch (error) {
226
+ return {
227
+ text: error instanceof Error ? error.message : String(error),
228
+ structured: {},
229
+ isError: true,
230
+ };
231
+ }
232
+ },
233
+ };
234
+ }
235
+ /** Serves MCP over stdio, a JSON-RPC message per line, for the agent in `dir`. */
236
+ export function serve(dir, io = { input: process.stdin, output: process.stdout }) {
237
+ const agent = mcpAgent(dir);
238
+ const write = (message) => io.output.write(`${JSON.stringify({ jsonrpc: '2.0', ...message })}\n`);
239
+ const lines = createInterface({ input: io.input });
240
+ lines.on('line', async (line) => {
241
+ if (line.trim() === '')
242
+ return;
243
+ let message;
244
+ try {
245
+ message = JSON.parse(line);
246
+ }
247
+ catch {
248
+ write({ id: null, error: { code: -32700, message: 'Parse error' } });
249
+ return;
250
+ }
251
+ const { id, method } = message;
252
+ // A notification, which has no id, gets no answer.
253
+ if (id === undefined || id === null)
254
+ return;
255
+ const params = (message.params ?? {});
256
+ switch (method) {
257
+ case 'initialize': {
258
+ const asked = params.protocolVersion;
259
+ write({
260
+ id,
261
+ result: {
262
+ protocolVersion: typeof asked === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(asked) ? asked : PROTOCOL,
263
+ capabilities: { tools: { listChanged: false } },
264
+ serverInfo: SERVER,
265
+ instructions: "These tools act as one business's agent on Avow's sandbox, on Tempo's testnet, with test dollars. The agent commits the business only within the mandate the business signed. A refusal comes from the SDK checking the mandate on this machine, from Avow, from Avow's relay, from the lock or from the account's keychain. It names which, gives the reason code and the amounts, and says when the same booking could pass. A reserve that never landed with no reason given comes back as a failure, and the same booking might pass on another try.",
266
+ },
267
+ });
268
+ return;
269
+ }
270
+ case 'ping':
271
+ write({ id, result: {} });
272
+ return;
273
+ case 'tools/list':
274
+ write({ id, result: { tools: MCP_TOOLS } });
275
+ return;
276
+ case 'tools/call': {
277
+ const name = typeof params.name === 'string' ? params.name : '';
278
+ const args = (params.arguments ?? {});
279
+ const answer = await agent.call(name, args);
280
+ write({
281
+ id,
282
+ result: {
283
+ content: [{ type: 'text', text: answer.text }],
284
+ structuredContent: answer.structured,
285
+ isError: answer.isError,
286
+ },
287
+ });
288
+ return;
289
+ }
290
+ default:
291
+ write({ id, error: { code: -32601, message: `Method not found: ${method}` } });
292
+ }
293
+ });
294
+ }
295
+ /** Where Claude Desktop keeps its MCP servers on this platform. */
296
+ export function claudeDesktopConfig() {
297
+ if (process.platform === 'darwin') {
298
+ return join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
299
+ }
300
+ if (process.platform === 'win32') {
301
+ return join(process.env.APPDATA ?? join(homedir(), 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
302
+ }
303
+ return join(homedir(), '.config', 'Claude', 'claude_desktop_config.json');
304
+ }
305
+ /** Adds the server to Claude Code for this folder, or to Claude Desktop, against this folder's agent. */
306
+ function add(client, dir) {
307
+ const server = realpathSync(fileURLToPath(import.meta.url));
308
+ const args = [server, '--dir', dir];
309
+ if (!existsSync(join(dir, SANDBOX_DIR, 'agent.json'))) {
310
+ console.log('This folder has no agent yet. Run npm start first, then add the server.');
311
+ }
312
+ if (client === 'claude-code') {
313
+ const line = ['claude', 'mcp', 'add', SERVER.name, '--', process.execPath, ...args];
314
+ const result = spawnSync(line[0], line.slice(1), {
315
+ stdio: 'inherit',
316
+ shell: process.platform === 'win32',
317
+ });
318
+ if (result.error || result.status !== 0) {
319
+ console.log(`\nClaude Code didn't take it. Run this in this folder yourself:\n\n ${line.map((a) => JSON.stringify(a)).join(' ')}\n`);
320
+ return 1;
321
+ }
322
+ console.log('\nAdded. Run claude in this folder and ask it to book $200 of GPU compute.');
323
+ return 0;
324
+ }
325
+ if (client === 'claude-desktop') {
326
+ const file = claudeDesktopConfig();
327
+ let config = {};
328
+ if (existsSync(file)) {
329
+ config = JSON.parse(readFileSync(file, 'utf8'));
330
+ copyFileSync(file, `${file}.bak`);
331
+ }
332
+ config.mcpServers = {
333
+ ...(config.mcpServers ?? {}),
334
+ [SERVER.name]: { command: process.execPath, args },
335
+ };
336
+ mkdirSync(dirname(file), { recursive: true });
337
+ writeFileSync(file, `${JSON.stringify(config, null, 2)}\n`);
338
+ console.log(`Added to ${file}. Restart Claude Desktop and ask it to book $200 of GPU compute.`);
339
+ return 0;
340
+ }
341
+ console.error('Use avow-sandbox-mcp add claude-code, or avow-sandbox-mcp add claude-desktop.');
342
+ return 1;
343
+ }
344
+ /** Runs only as the command, so a test can import the server. */
345
+ const isMain = (() => {
346
+ try {
347
+ return realpathSync(process.argv[1] ?? '') === realpathSync(fileURLToPath(import.meta.url));
348
+ }
349
+ catch {
350
+ return false;
351
+ }
352
+ })();
353
+ if (isMain) {
354
+ const argv = process.argv.slice(2);
355
+ if (argv[0] === 'add') {
356
+ process.exitCode = add(argv[1], process.cwd());
357
+ }
358
+ else {
359
+ const at = argv.indexOf('--dir');
360
+ const dir = resolve(at >= 0 ? (argv[at + 1] ?? '.') : '.');
361
+ // Standard output carries the protocol, so anything the SDK prints goes to standard error.
362
+ console.log = (...items) => console.error(...items);
363
+ serve(dir);
364
+ }
365
+ }
366
+ export { SANDBOX_TOOLS };
367
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/node/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { SandboxPlatform } from '../sandbox/agent.js';
2
+ import type { SandboxStore } from '../sandbox/store.js';
3
+ /** The folder in the working directory where the sandbox keeps its keys and its setup. */
4
+ export declare const SANDBOX_DIR = ".avow";
5
+ /**
6
+ * A sandbox store in a folder on this machine. Each item is a JSON file only its owner can read,
7
+ * written whole through a temporary file, and the folder ignores itself in git. The business's
8
+ * root key in it is sealed under the passphrase, so reading the folder doesn't give the key.
9
+ */
10
+ export declare function fileStore(dir?: string): SandboxStore;
11
+ /** What the runner sets for each run of the agent it starts, and nothing else of its own. */
12
+ export declare const RUNNER_ENV: {
13
+ readonly session: 'AVOW_SANDBOX_SESSION';
14
+ readonly run: 'AVOW_SANDBOX_RUN';
15
+ };
16
+ /** The highest run number taken in a session so far, or 0 when none is. */
17
+ export declare function latestRun(dir: string, session: string): number;
18
+ /**
19
+ * Marks every run number up to `run` as taken in a session, so a session kept across a restart
20
+ * goes on from the last run Avow's relay holds, even when this folder lost its own count.
21
+ */
22
+ export declare function takenUpTo(dir: string, session: string, run: number): void;
23
+ /**
24
+ * Takes the next run number in a session, in the sandbox folder `dir`. The runner and the MCP
25
+ * server both start runs, and the screen tells runs apart by number, so each claims its number by
26
+ * creating a file named for it, which only one process can create. A restarted MCP server goes on
27
+ * from the numbers already taken.
28
+ */
29
+ export declare function takeRun(dir: string, session: string): number;
30
+ /**
31
+ * The sandbox's defaults in Node. Everything goes in the working directory's `.avow` folder, and a
32
+ * run the runner started reports to the session it opened.
33
+ */
34
+ export declare const nodePlatform: SandboxPlatform;
35
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/node/platform.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAEvD,0FAA0F;AAC1F,eAAO,MAAM,WAAW,UAAU,CAAA;AAKlC;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,GAAE,MAAyC,GAAG,YAAY,CAuBtF;AAED,6FAA6F;AAC7F,eAAO,MAAM,UAAU;aACrB,OAAO,EAAE,sBAAsB;aAC/B,GAAG,EAAE,kBAAkB;CACf,CAAA;AAOV,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAO9D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAKzE;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,eAO1B,CAAA"}
@@ -0,0 +1,102 @@
1
+ import { mkdirSync, readdirSync, writeFileSync } from 'node:fs';
2
+ import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { isSessionId } from '@avow-finance/spec';
5
+ /** The folder in the working directory where the sandbox keeps its keys and its setup. */
6
+ export const SANDBOX_DIR = '.avow';
7
+ /** What the sandbox's folder tells git, so nothing in it ever reaches a commit. */
8
+ const IGNORE_ALL = '# The sandbox keeps its keys here. Never commit them.\n*\n';
9
+ /**
10
+ * A sandbox store in a folder on this machine. Each item is a JSON file only its owner can read,
11
+ * written whole through a temporary file, and the folder ignores itself in git. The business's
12
+ * root key in it is sealed under the passphrase, so reading the folder doesn't give the key.
13
+ */
14
+ export function fileStore(dir = join(process.cwd(), SANDBOX_DIR)) {
15
+ const file = (item) => join(dir, `${item}.json`);
16
+ return {
17
+ async read(item) {
18
+ try {
19
+ return await readFile(file(item), 'utf8');
20
+ }
21
+ catch (error) {
22
+ if (error.code === 'ENOENT')
23
+ return null;
24
+ throw error;
25
+ }
26
+ },
27
+ async write(item, text) {
28
+ await mkdir(dir, { recursive: true, mode: 0o700 });
29
+ await writeFile(join(dir, '.gitignore'), IGNORE_ALL, { flag: 'wx' }).catch((error) => {
30
+ if (error.code !== 'EEXIST')
31
+ throw error;
32
+ });
33
+ const temporary = `${file(item)}.${process.pid}.tmp`;
34
+ await writeFile(temporary, text, { mode: 0o600 });
35
+ await rename(temporary, file(item));
36
+ },
37
+ };
38
+ }
39
+ /** What the runner sets for each run of the agent it starts, and nothing else of its own. */
40
+ export const RUNNER_ENV = {
41
+ session: 'AVOW_SANDBOX_SESSION',
42
+ run: 'AVOW_SANDBOX_RUN',
43
+ };
44
+ function runsDir(dir, session) {
45
+ if (!isSessionId(session))
46
+ throw new RangeError(`${session} isn't a session id`);
47
+ return join(dir, 'runs', session);
48
+ }
49
+ /** The highest run number taken in a session so far, or 0 when none is. */
50
+ export function latestRun(dir, session) {
51
+ try {
52
+ const taken = readdirSync(runsDir(dir, session)).map(Number).filter(Number.isSafeInteger);
53
+ return Math.max(0, ...taken);
54
+ }
55
+ catch {
56
+ return 0;
57
+ }
58
+ }
59
+ /**
60
+ * Marks every run number up to `run` as taken in a session, so a session kept across a restart
61
+ * goes on from the last run Avow's relay holds, even when this folder lost its own count.
62
+ */
63
+ export function takenUpTo(dir, session, run) {
64
+ if (run < 1 || latestRun(dir, session) >= run)
65
+ return;
66
+ const runs = runsDir(dir, session);
67
+ mkdirSync(runs, { recursive: true, mode: 0o700 });
68
+ writeFileSync(join(runs, String(run)), '', { mode: 0o600 });
69
+ }
70
+ /**
71
+ * Takes the next run number in a session, in the sandbox folder `dir`. The runner and the MCP
72
+ * server both start runs, and the screen tells runs apart by number, so each claims its number by
73
+ * creating a file named for it, which only one process can create. A restarted MCP server goes on
74
+ * from the numbers already taken.
75
+ */
76
+ export function takeRun(dir, session) {
77
+ const runs = runsDir(dir, session);
78
+ mkdirSync(runs, { recursive: true, mode: 0o700 });
79
+ for (let run = latestRun(dir, session) + 1;; run += 1) {
80
+ try {
81
+ writeFileSync(join(runs, String(run)), '', { flag: 'wx', mode: 0o600 });
82
+ return run;
83
+ }
84
+ catch (error) {
85
+ if (error.code !== 'EEXIST')
86
+ throw error;
87
+ }
88
+ }
89
+ }
90
+ /**
91
+ * The sandbox's defaults in Node. Everything goes in the working directory's `.avow` folder, and a
92
+ * run the runner started reports to the session it opened.
93
+ */
94
+ export const nodePlatform = {
95
+ store: () => fileStore(),
96
+ session: () => {
97
+ const id = process.env[RUNNER_ENV.session];
98
+ const run = Number(process.env[RUNNER_ENV.run]);
99
+ return id && isSessionId(id) && Number.isInteger(run) && run > 0 ? { id, run } : null;
100
+ },
101
+ };
102
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/node/platform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { type Address } from 'viem';
2
+ /** How long before Avow's relay closes a session the runner moves to a new one, in seconds. */
3
+ export declare const SESSION_MARGIN = 600n;
4
+ /** The session the runner reports to. */
5
+ export interface RunnerSession {
6
+ id: string;
7
+ /** Whether the session hasn't had the agent's authority yet, so the runner announces it. */
8
+ fresh: boolean;
9
+ /** When Avow's relay stops taking the session's events, in unix seconds, or null while unknown. */
10
+ endsAt: bigint | null;
11
+ }
12
+ interface SessionOptions {
13
+ /** The sandbox folder, `.avow` in the working directory. */
14
+ dir: string;
15
+ apiUrl: string;
16
+ fetch?: typeof fetch;
17
+ now?: () => bigint;
18
+ log?: (line: string) => void;
19
+ }
20
+ /**
21
+ * The session the runner reports to, kept in the sandbox folder with the business, so the screen
22
+ * a developer has open keeps working across restarts. A restart keeps it while Avow's relay holds
23
+ * it for the business's account and takes its events for more than `SESSION_MARGIN`. On a first
24
+ * run, after `npm run fresh`, or once a session has closed, it's a new session, and the runner
25
+ * announces the agent's authority to it.
26
+ *
27
+ * The account comes from business.json, and nothing checks it here, since that takes the
28
+ * passphrase. The sealed key opens only for the account it was sealed for, so a file that names
29
+ * another business's account can make the runner keep that business's session, but nothing the
30
+ * runner signs can reach it, and Avow's relay refuses this business's agent's events there.
31
+ */
32
+ export declare function keepSession(m: SessionOptions & {
33
+ account: Address | null;
34
+ }): Promise<RunnerSession>;
35
+ /**
36
+ * The session for the next run, the same one until Avow's relay is about to stop taking its
37
+ * events. Then it's a new one, which the runner announces the authority to again.
38
+ */
39
+ export declare function sessionForNextRun(session: RunnerSession, m: SessionOptions): Promise<RunnerSession>;
40
+ export {};
41
+ //# sourceMappingURL=runner-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-session.d.ts","sourceRoot":"","sources":["../../src/node/runner-session.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,OAAO,EAAkB,MAAM,MAAM,CAAA;AAInD,+FAA+F;AAC/F,eAAO,MAAM,cAAc,OAAO,CAAA;AAElC,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,4FAA4F;IAC5F,KAAK,EAAE,OAAO,CAAA;IACd,mGAAmG;IACnG,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,UAAU,cAAc;IACtB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7B;AAuCD;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,CAAC,EAAE,cAAc,GAAG;IAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,GAC9C,OAAO,CAAC,aAAa,CAAC,CAsBxB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,aAAa,EACtB,CAAC,EAAE,cAAc,GAChB,OAAO,CAAC,aAAa,CAAC,CAaxB"}