@hanzo/build 0.2.10 → 0.2.12

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 (136) hide show
  1. package/README.md +98 -25
  2. package/lib/api/agents.d.ts +80 -0
  3. package/lib/api/agents.js +148 -0
  4. package/lib/api/billing.d.ts +205 -0
  5. package/lib/api/billing.js +300 -0
  6. package/lib/api/call.d.ts +6 -0
  7. package/lib/api/call.js +11 -0
  8. package/lib/api/capabilities.d.ts +25 -0
  9. package/lib/api/capabilities.js +40 -0
  10. package/lib/api/coding.d.ts +31 -1
  11. package/lib/api/coding.js +50 -1
  12. package/lib/api/connectors.d.ts +90 -0
  13. package/lib/api/connectors.js +109 -0
  14. package/lib/api/consent.d.ts +22 -0
  15. package/lib/api/consent.js +28 -0
  16. package/lib/api/github.d.ts +13 -0
  17. package/lib/api/github.js +9 -0
  18. package/lib/api/harness.d.ts +44 -0
  19. package/lib/api/harness.js +348 -0
  20. package/lib/api/keys.d.ts +41 -0
  21. package/lib/api/keys.js +55 -0
  22. package/lib/api/machines.d.ts +56 -0
  23. package/lib/api/machines.js +84 -0
  24. package/lib/api/members.d.ts +47 -0
  25. package/lib/api/members.js +88 -0
  26. package/lib/api/memory.d.ts +25 -0
  27. package/lib/api/memory.js +34 -0
  28. package/lib/api/places.d.ts +2 -2
  29. package/lib/api/places.js +3 -26
  30. package/lib/api/plugins.d.ts +55 -0
  31. package/lib/api/plugins.js +62 -0
  32. package/lib/api/pref.d.ts +49 -0
  33. package/lib/api/pref.js +68 -0
  34. package/lib/api/profile.d.ts +21 -0
  35. package/lib/api/profile.js +40 -0
  36. package/lib/api/projects.d.ts +19 -2
  37. package/lib/api/projects.js +29 -4
  38. package/lib/api/provider.d.ts +42 -0
  39. package/lib/api/provider.js +58 -0
  40. package/lib/api/sessions.d.ts +32 -4
  41. package/lib/api/sessions.js +42 -6
  42. package/lib/api/skills.d.ts +70 -0
  43. package/lib/api/skills.js +90 -0
  44. package/lib/api/tools.d.ts +34 -0
  45. package/lib/api/tools.js +37 -0
  46. package/lib/api/turn.d.ts +84 -16
  47. package/lib/api/turn.js +221 -4
  48. package/lib/api/webhooks.d.ts +60 -0
  49. package/lib/api/webhooks.js +81 -0
  50. package/lib/ask.d.ts +18 -0
  51. package/lib/ask.js +69 -0
  52. package/lib/builder.js +39 -19
  53. package/lib/customize/agents.d.ts +2 -0
  54. package/lib/customize/agents.js +125 -0
  55. package/lib/customize/connectors.d.ts +2 -0
  56. package/lib/customize/connectors.js +199 -0
  57. package/lib/customize/index.d.ts +6 -0
  58. package/lib/customize/index.js +52 -0
  59. package/lib/customize/plugins.d.ts +2 -0
  60. package/lib/customize/plugins.js +93 -0
  61. package/lib/customize/skills.d.ts +2 -0
  62. package/lib/customize/skills.js +127 -0
  63. package/lib/customize/ui.d.ts +110 -0
  64. package/lib/customize/ui.js +99 -0
  65. package/lib/desk.d.ts +4 -1
  66. package/lib/desk.js +3 -16
  67. package/lib/find.d.ts +7 -0
  68. package/lib/find.js +77 -0
  69. package/lib/foot.d.ts +16 -0
  70. package/lib/foot.js +36 -0
  71. package/lib/forge.js +4 -4
  72. package/lib/git.d.ts +4 -0
  73. package/lib/git.js +6 -2
  74. package/lib/host.d.ts +5 -0
  75. package/lib/landing.d.ts +10 -0
  76. package/lib/landing.js +30 -14
  77. package/lib/markdown.d.ts +49 -0
  78. package/lib/markdown.js +123 -0
  79. package/lib/plans.d.ts +1 -0
  80. package/lib/plans.js +113 -0
  81. package/lib/prefs.d.ts +30 -0
  82. package/lib/prefs.js +83 -0
  83. package/lib/prose.d.ts +4 -0
  84. package/lib/prose.js +53 -0
  85. package/lib/route.d.ts +16 -1
  86. package/lib/route.js +32 -1
  87. package/lib/run.js +184 -32
  88. package/lib/section.js +2 -2
  89. package/lib/settings/account.d.ts +5 -0
  90. package/lib/settings/account.js +111 -0
  91. package/lib/settings/billing.d.ts +1 -0
  92. package/lib/settings/billing.js +104 -0
  93. package/lib/settings/capabilities.d.ts +1 -0
  94. package/lib/settings/capabilities.js +55 -0
  95. package/lib/settings/card.d.ts +31 -0
  96. package/lib/settings/card.js +105 -0
  97. package/lib/settings/code.d.ts +1 -0
  98. package/lib/settings/code.js +51 -0
  99. package/lib/settings/environments.d.ts +1 -0
  100. package/lib/settings/environments.js +53 -0
  101. package/lib/settings/general.d.ts +1 -0
  102. package/lib/settings/general.js +44 -0
  103. package/lib/settings/index.d.ts +4 -0
  104. package/lib/settings/index.js +22 -0
  105. package/lib/settings/integrations.d.ts +1 -0
  106. package/lib/settings/integrations.js +81 -0
  107. package/lib/settings/keys.d.ts +1 -0
  108. package/lib/settings/keys.js +102 -0
  109. package/lib/settings/machines.d.ts +1 -0
  110. package/lib/settings/machines.js +118 -0
  111. package/lib/settings/members.d.ts +1 -0
  112. package/lib/settings/members.js +67 -0
  113. package/lib/settings/memory.d.ts +1 -0
  114. package/lib/settings/memory.js +56 -0
  115. package/lib/settings/notifications.d.ts +1 -0
  116. package/lib/settings/notifications.js +97 -0
  117. package/lib/settings/privacy.d.ts +1 -0
  118. package/lib/settings/privacy.js +63 -0
  119. package/lib/settings/sections.d.ts +16 -0
  120. package/lib/settings/sections.js +32 -0
  121. package/lib/settings/ui.d.ts +49 -0
  122. package/lib/settings/ui.js +47 -0
  123. package/lib/settings/usage.d.ts +1 -0
  124. package/lib/settings/usage.js +114 -0
  125. package/lib/shelf.d.ts +6 -0
  126. package/lib/shelf.js +86 -16
  127. package/lib/switch.js +1 -2
  128. package/lib/transcript.d.ts +12 -0
  129. package/lib/transcript.js +56 -0
  130. package/lib/voice.d.ts +3 -1
  131. package/lib/voice.js +10 -4
  132. package/package.json +1 -1
  133. package/lib/account.d.ts +0 -14
  134. package/lib/account.js +0 -38
  135. package/lib/mcp.d.ts +0 -1
  136. package/lib/mcp.js +0 -28
package/README.md CHANGED
@@ -42,9 +42,10 @@ import { Builder, type Host } from '@hanzo/build'
42
42
  `Host` is everything that differs between hosts: where the platform is
43
43
  (`api`), the bearer (`token()`, read at call time), the org (`org`), who is
44
44
  signed in (`person`), whether they administer the org (`admin`), the address
45
- under the mount (`path`) and how to move (`go`), and where to link out
46
- (`links`, `open`). Peers: `@hanzo/ui`, `@hanzo/gui`, `@hanzogui/lucide-icons-2`,
47
- `react`.
45
+ under the mount (`path`) and how to move (`go`), where to link out
46
+ (`links`, `open`), and — for a host that can repaint itself — the theme
47
+ (`theme`, `chooseTheme`), which follows the person's saved choice. Peers:
48
+ `@hanzo/ui`, `@hanzo/gui`, `@hanzogui/lucide-icons-2`, `react`.
48
49
 
49
50
  ### In a host that has its own rail
50
51
 
@@ -72,13 +73,16 @@ hanzo.id token for `Host.admin`. One left column, never two.
72
73
  | `''` | New — the empty state and the composer |
73
74
  | `sess_<32 hex>` | one run, live |
74
75
  | `-/automations` | repeating work, read from `/v1/auto/flows` |
75
- | `-/mcp` | the fleet's native MCP servers, from `POST /v1/mcp` `tools/list` |
76
+ | `-/customize` · `-/customize/connectors` · `/plugins` · `/agents` | Customize: skills, connectors, plugins, agents |
77
+ | `-/mcp` | Connectors → Discover, where the fleet's native MCP servers now live |
76
78
  | `-/codebases` | the forge's repositories |
77
79
  | `-/sync` | bring granted repositories onto the forge |
78
80
  | `-/projects` | the forge's boards |
79
81
  | `-/issues` | the forge's issues |
80
82
  | `-/artifacts` | what the org has built |
81
83
  | `-/templates` | the public starters |
84
+ | `-/plans` | the plans this brand sells, and the move to another |
85
+ | `-/settings/<section>` | Billing, Usage, Members, Integrations, Notifications, … |
82
86
  | `<slug>` | a project's workspace |
83
87
 
84
88
  A project slug holds no `_` and never starts with `-`, so the forms cannot
@@ -88,25 +92,65 @@ collide.
88
92
 
89
93
  **The rail** (hanzo.build). At the top, the mark. Signed in to an organization,
90
94
  that spot is the organization switcher: the org, and the projects under it.
91
- New, then Automations, then the forge — Codebase, Projects, Issues — then MCP,
92
- Artifacts, More (Templates, Machines, Docs), then the org's coding runs newest
93
- first with a live status dot. The account stays at the foot. Settings opens
94
- that account on this page. Collapse is an explicit toggle kept in this browser.
95
- A host with its own rail draws `DevSection` there instead.
96
-
97
- **MCP.** The native servers `POST /v1/mcp` lists, each with the operations it
98
- names. A run starts a server when it calls it, and the server stays up afterwards.
95
+ New, Projects, Artifacts, Customize, Automations, then More (Codebase, Issues,
96
+ Templates, Machines, Docs), then the org's coding runs newest first with a live
97
+ status dot. At the foot, a card offering Hanzo in Slack (dismissed once, gone in
98
+ this browser) and the account, whose menu holds the email, Settings, Usage, View
99
+ all plans, Get help (the docs, in a new tab) and Log out. Collapse is an explicit
100
+ toggle kept in this browser. A host with its own rail draws `DevSection` there
101
+ instead.
102
+
103
+ **Artifacts.** A few starters to make something new from, each copied into a
104
+ project as Templates does, then every project under the month it was last
105
+ edited, public or private, with rename, visibility and delete. A project belongs
106
+ to the org and names no author, so there is no Yours or Shared with you.
107
+
108
+ **Settings, Code.** Environments: every codebase that has one, opened in the
109
+ same editor a run shows, forgotten by an org admin. Machines: `hanzo login` and
110
+ `hanzo link` to link one, registering one by hand, and each machine's rename,
111
+ drain, claim key (shown once) and removal. API keys: your secret and publishable
112
+ key, a new one shown once, rotated or revoked.
113
+
114
+ **Customize.** What the agent brings to a run, a tab each — Skills, Connectors,
115
+ Plugins, Agents — and in each, Yours (what the org has) and Discover (what it
116
+ can add), one search and one Add. Skills and connectors ride into every run in
117
+ the org, so they are an org admin's to add, switch and remove, and a member reads
118
+ them; plugins and agents are any member's.
119
+
120
+ - Skills: the org's own SKILL.md skills, written, revised and deleted here, and
121
+ the brand's catalogue (`/.well-known/agent-skills/`) to read and add. Adding is
122
+ switching `skill_<name>` on, and a switch per skill turns it off again.
123
+ - Connectors: the MCP servers the org added — by URL or off the shelf, a secret
124
+ sealed in KMS — each with a switch per tool. Adding one switches its tools on.
125
+ Discover is the shelf (featured first; a listing that ships only a package has
126
+ no plus) and the fleet's native servers `POST /v1/mcp` lists, which every run
127
+ can call and nothing adds.
128
+ - Plugins: TypeScript connectors built on the platform, from source or from a
129
+ description of an API; a failed build says why. Discover lists what the
130
+ deployment mounts.
131
+ - Agents: the org's own — model, instructions, tools, budget — created, edited
132
+ (only what changed is sent) and deleted; Discover is the platform's presets
133
+ whose tool calls run on the platform.
99
134
 
100
135
  **New.** "What's up next?", and at the foot the composer: where the run runs
101
- (Default is the platform's sandbox; the org's machines follow), the codebase
102
- and the branch — the forge's repositories, filtered as you type — then the
103
- ask. Under it: attach (files ride the prompt as text), dictate, Build or Plan,
104
- and the model and effort. A codebase can be added to a project. Opening a
105
- codebase or an issue from its own screen lands here with that choice already
106
- made.
107
-
108
- **A run.** The transcript as it streams, steering while it works, Stop, and
109
- the pull request once it pushes one. Beside it:
136
+ (Cloud is the platform's sandbox with the codebase's environment; the org's
137
+ machines follow under remote control, each linked with `hanzo link`), the
138
+ codebase and the branch — the forge's repositories, filtered as you type, read
139
+ again with Refresh list, and a way to Sync for a GitHub repository that is not
140
+ there yet — then the ask. Under it: attach (files ride the prompt as text),
141
+ dictate, Build or Plan, and the model and effort. A codebase can be added to a
142
+ project. Opening a codebase or an issue from its own screen lands here with
143
+ that choice already made.
144
+
145
+ **A run.** The transcript as it streams, drawn by what each part is: what the
146
+ agent says as markdown, each command it runs as a card that opens onto its
147
+ output, the files it edits with their diff, the files it reads as chips, and the
148
+ run's own steps. Steering while it works; Pause, Resume and Stop; the pull
149
+ request once it pushes one. Once it has finished, a follow-up starts a new run
150
+ from the branch it pushed — the same codebase, place and mode — and opens it; a
151
+ paused sandbox run goes on the same way. A plan run ends with its plan and
152
+ Approve and build. Rename it, share a project run's story publicly, and find any
153
+ run by status in Find. Beside it:
110
154
 
111
155
  - Environment: the codebase's environment, and the run's facts.
112
156
  - Git: what it pushed, read from the forge — Diff, Review, Commits.
@@ -142,8 +186,11 @@ picker and open-in-tab; Share and Publish; the console dock under it.
142
186
  | `POST /v1/agent/coding` | start a run → 202 `{sessionId, …}` |
143
187
  | `GET /v1/agent/sessions?kind=coding` | Recents, and a project's runs |
144
188
  | `GET /v1/agent/sessions/{id}` · `GET /v1/agent/sessions/stream?root=` | a run, and its live feed (SSE over fetch) |
145
- | `POST /v1/agent/sessions/{id}/message` · `/stop` | steer, stop |
146
- | `GET /v1/agent/targets` | the org's machines |
189
+ | `POST /v1/agent/sessions/{id}/message` · `/pause` · `/resume` · `/stop` | steer, pause, resume a machine's run, stop |
190
+ | `PATCH /v1/agent/sessions/{id}` `{title}` · `{published}` | rename a run, share its story at `GET /v1/agent/builds/{org}/{project}` |
191
+ | `GET /v1/agent/sessions?kind=coding&status=&after=` | Find, by status, paged |
192
+ | `GET`/`POST /v1/agent/targets` · `PATCH`/`DELETE …/{id}` · `POST …/{id}/key` | the org's machines, and a machine's claim key |
193
+ | `GET`/`POST`/`DELETE /v1/account/keys` | your API keys |
147
194
  | `GET /v1/auto/flows` · `POST /v1/auto/flows` · `POST /v1/auto/flows/{id}/enable` | automations |
148
195
  | `GET /v1/environment` · `GET`/`PUT`/`DELETE /v1/environment/{repo}` · `PUT`/`DELETE …/secrets/{name}` | a codebase's environment |
149
196
  | `GET /v1/agent/coding/{session}/changes` · `/tree` · `/blob` | what a run pushed, and its branch's files, from the forge |
@@ -154,11 +201,31 @@ picker and open-in-tab; Share and Publish; the console dock under it.
154
201
  | `GET /v1/task/projects` · `GET /v1/task/board` · `GET /v1/task/projects/{key}/issues` | boards and issues, read from the forge |
155
202
  | `GET /v1/provider/github/repos` · `…/{owner}/{repo}/branches` | kept for a host that still asks GitHub |
156
203
  | `POST /v1/provider/github/user/connect` | connect a person's GitHub |
157
- | `GET /v1/projects` · `POST /v1/projects/fork` · `GET /v1/templates` | artifacts, templates |
204
+ | `GET /v1/projects` · `PATCH`/`DELETE /v1/projects/{slug}` · `POST /v1/projects/fork` · `GET /v1/templates` | artifacts, templates |
158
205
  | `GET /v1/git/repos/{name}/tree` · `/blob` | Files and Code |
159
206
  | `POST /v1/platform/apps` · `GET /v1/platform/builds` | Add to project, Publish |
160
207
  | `POST /v1/mcp` | the native MCP servers, `tools/list` |
208
+ | `GET /v1/tool?source=` · `GET`/`PUT /v1/tool/activation` | the org's tools, and which are on |
209
+ | `GET /v1/tool/skills?activated=true` · `GET /v1/tool/skills/authored` · `POST /v1/tool/skills` · `DELETE /v1/tool/skills/{id}` | skills |
210
+ | `GET /.well-known/agent-skills/index.json` · `…/{skill}/SKILL.md` | the brand's skills catalogue, public |
211
+ | `GET`/`POST /v1/tool/mcp/servers` · `DELETE …/{id}` · `GET /v1/tool/catalog` · `…/{id}` | connectors, and the shelf |
212
+ | `GET /v1/tool/plugins/authored` · `POST /v1/tool/plugins/build` · `DELETE …/authored/{id}` · `GET /v1/tool/plugins` | plugins, and what is mounted |
213
+ | `GET`/`POST /v1/agent` · `GET`/`PATCH`/`DELETE /v1/agent/{ref}` · `GET /v1/agent/chat/presets` | agents, and presets |
161
214
  | `GET /v1/models` · `POST /v1/event` | the model list, a verdict |
215
+ | `GET`/`PATCH /v1/pref` | the person's own settings: theme, text size, motion, dictation language, what to call them, their instructions, the coding defaults |
216
+ | `PUT /v1/iam/account` · `POST /v1/account/avatar` | the person's name and photo |
217
+ | `GET`/`PUT /v1/iam/consent` | whether Hanzo may train on their data, and usage insights |
218
+ | `GET /v1/tool` · `PUT /v1/tool/activation` | what the agent may use, per kind of tool |
219
+ | `GET /v1/ai/memory/list` · `POST /v1/ai/memory/remember` · `…/delete` | what Hanzo remembers |
220
+ | `PATCH /v1/projects/{slug}` | a project public or private |
221
+ | `GET /v1/billing/plans` · `…/subscriptions` · `POST …/subscribe/card` · `…/subscriptions/{id}/cancel`·`/reactivate` | Plans, and the plan in Billing |
222
+ | `GET`/`POST`/`DELETE /v1/billing/methods` · `GET /v1/billing/settings` | saved cards; a card is added from the processor's own field |
223
+ | `GET /v1/billing/invoices` · `…/invoices/{id}/pdf` | invoices |
224
+ | `GET /v1/billing/balance` · `…/credit-balance` · `…/usage/rollup` · `POST …/topup` · `GET /v1/usage/summary` | Usage |
225
+ | `GET`/`POST`/`PATCH`/`DELETE /v1/billing/alerts` | the monthly limit (org admin) |
226
+ | `GET /v1/iam/memberships?org=` · `GET`/`POST`/`DELETE /v1/iam/invitations` | Members |
227
+ | `GET /v1/provider/{slack,github}` · `POST …/connect`·`/disconnect` · `GET /v1/provider/slack/channels` · `GET /v1/provider/github/installations` | Integrations |
228
+ | `GET`/`POST /v1/webhook` · `DELETE /v1/webhook/{id}` · `POST …/test` · `GET …/deliveries` | Notifications |
162
229
 
163
230
  `mode`, `model` and `effort` are sent with a run as asked; the platform
164
231
  honours them where it does and nothing here simulates them.
@@ -172,6 +239,8 @@ src/
172
239
  landing.tsx New
173
240
  forge.tsx Codebase, Automations, Projects, Issues
174
241
  run.tsx one run
242
+ transcript.tsx a run's transcript, as cards
243
+ prose.tsx markdown, drawn as text (markdown.ts reads it)
175
244
  desk.tsx the pane beside a run
176
245
  door.tsx a run's desktop or shell, framed
177
246
  git.tsx what a run pushed
@@ -179,8 +248,12 @@ src/
179
248
  environment.tsx a codebase's environment
180
249
  project.tsx a project's workspace
181
250
  shelf.tsx Artifacts and Templates
251
+ customize/ Customize: the shell, then one file per tab
182
252
  publish.tsx Add to project / Publish
183
- account.tsx the account and find-a-run dialogs
253
+ find.tsx finding a run, by status, paged
254
+ foot.tsx the rail's foot: the Slack card and the account menu
255
+ ask.tsx confirming an act, or naming something, in a dialog
256
+ settings/ Settings, one file per section
184
257
  data.ts reads as hooks
185
258
  host.tsx what a host provides
186
259
  route.ts the address grammar
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Agents: the org's own — a model, instructions, the tools it may call and a
3
+ * budget — and the presets one can start from.
4
+ *
5
+ * GET /v1/agent {agents: [agent]}, without instructions
6
+ * POST /v1/agent create → 201 agent
7
+ * GET /v1/agent/{ref} one, with its instructions
8
+ * PATCH /v1/agent/{ref} the fields sent change, the rest stay → agent
9
+ * DELETE /v1/agent/{ref} removes it and every run recorded against it → 204
10
+ * GET /v1/agent/chat/presets {presets: [{id, title, systemPrompt, serverExecuted}]}
11
+ *
12
+ * A ref is the agent's id or its name. A budget is required: the most it may
13
+ * spend in a period and in one run, in micro-USD, and the period — day, week or
14
+ * month. Tools are names from the tool plane; none grants none, and `*` is
15
+ * whatever the fleet's MCP server serves when it runs. An omitted model is the
16
+ * deployment's default. A preset whose tool calls run on the platform
17
+ * (`serverExecuted`) makes a working agent; the others hand their calls back to
18
+ * the client that asked, so they are not offered here.
19
+ */
20
+ import { type Target } from './call.ts';
21
+ export type Period = 'day' | 'week' | 'month';
22
+ export declare const PERIODS: readonly Period[];
23
+ export interface Agent {
24
+ id: string;
25
+ name: string;
26
+ model: string;
27
+ description: string;
28
+ /** Only a single agent's read carries it; the list withholds it. */
29
+ instructions: string;
30
+ tools: string[];
31
+ status: string;
32
+ runs: number;
33
+ /** Micro-USD per period, per run, and spent this period. */
34
+ cap: number;
35
+ task: number;
36
+ spent: number;
37
+ period: Period | '';
38
+ emoji: string;
39
+ }
40
+ export interface Preset {
41
+ id: string;
42
+ title: string;
43
+ prompt: string;
44
+ }
45
+ /** The fields a person edits. Money is in dollars here and micro-USD on the wire. */
46
+ export interface Draft {
47
+ name: string;
48
+ description: string;
49
+ model: string;
50
+ instructions: string;
51
+ tools: string[];
52
+ cap: string;
53
+ task: string;
54
+ period: Period;
55
+ }
56
+ /** An agent's name, as the handler takes it. */
57
+ export declare const NAME: RegExp;
58
+ /** The most instructions the handler keeps. */
59
+ export declare const MAX: number;
60
+ /** Every tool the fleet's MCP server serves. */
61
+ export declare const ALL = "*";
62
+ export declare const micros: (dollars: string) => number;
63
+ export declare const dollars: (m: number) => string;
64
+ export declare function agent(raw: unknown): Agent;
65
+ /** A draft of an agent as it stands, to edit. */
66
+ export declare function draft(a: Agent): Draft;
67
+ export declare const EMPTY: Draft;
68
+ /** Why a draft cannot be saved as it stands, or '' when it can. */
69
+ export declare function refuse(d: Draft): string;
70
+ export declare function agents(t: Target): Promise<Agent[]>;
71
+ export declare function one(t: Target, ref: string): Promise<Agent>;
72
+ export declare function create(t: Target, d: Draft): Promise<Agent>;
73
+ /** The fields that differ from `was`, and nothing else: an omitted field keeps its value. */
74
+ export declare function changes(was: Agent, d: Draft): Record<string, unknown>;
75
+ export declare function update(t: Target, was: Agent, d: Draft): Promise<Agent>;
76
+ export declare function remove(t: Target, ref: string): Promise<void>;
77
+ /** The presets that make a working agent. */
78
+ export declare function presets(t: Target): Promise<Preset[]>;
79
+ /** A new agent's draft from a preset. */
80
+ export declare function fromPreset(p: Preset): Draft;
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Agents: the org's own — a model, instructions, the tools it may call and a
3
+ * budget — and the presets one can start from.
4
+ *
5
+ * GET /v1/agent {agents: [agent]}, without instructions
6
+ * POST /v1/agent create → 201 agent
7
+ * GET /v1/agent/{ref} one, with its instructions
8
+ * PATCH /v1/agent/{ref} the fields sent change, the rest stay → agent
9
+ * DELETE /v1/agent/{ref} removes it and every run recorded against it → 204
10
+ * GET /v1/agent/chat/presets {presets: [{id, title, systemPrompt, serverExecuted}]}
11
+ *
12
+ * A ref is the agent's id or its name. A budget is required: the most it may
13
+ * spend in a period and in one run, in micro-USD, and the period — day, week or
14
+ * month. Tools are names from the tool plane; none grants none, and `*` is
15
+ * whatever the fleet's MCP server serves when it runs. An omitted model is the
16
+ * deployment's default. A preset whose tool calls run on the platform
17
+ * (`serverExecuted`) makes a working agent; the others hand their calls back to
18
+ * the client that asked, so they are not offered here.
19
+ */
20
+ import { call, seg } from './call.js';
21
+ export const PERIODS = ['day', 'week', 'month'];
22
+ /** An agent's name, as the handler takes it. */
23
+ export const NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
24
+ /** The most instructions the handler keeps. */
25
+ export const MAX = 32 << 10;
26
+ /** Every tool the fleet's MCP server serves. */
27
+ export const ALL = '*';
28
+ const str = (v) => (typeof v === 'string' ? v : '');
29
+ const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0);
30
+ const obj = (v) => (v && typeof v === 'object' ? v : {});
31
+ const rows = (v) => (Array.isArray(v) ? v : []);
32
+ export const micros = (dollars) => Math.round(Number(dollars) * 1_000_000);
33
+ export const dollars = (m) => (m ? String(m / 1_000_000) : '');
34
+ export function agent(raw) {
35
+ const o = obj(raw);
36
+ const period = str(o.period);
37
+ return {
38
+ id: str(o.id),
39
+ name: str(o.name),
40
+ model: str(o.model),
41
+ description: str(o.description),
42
+ instructions: str(o.instructions),
43
+ tools: rows(o.tools).map(str).filter(Boolean),
44
+ status: str(o.status),
45
+ runs: num(o.runs),
46
+ cap: num(o.cap_micro_usd),
47
+ task: num(o.max_task_micro_usd),
48
+ spent: num(o.consumed_micro_usd),
49
+ period: PERIODS.includes(period) ? period : '',
50
+ emoji: str(o.emoji),
51
+ };
52
+ }
53
+ /** A draft of an agent as it stands, to edit. */
54
+ export function draft(a) {
55
+ return {
56
+ name: a.name,
57
+ description: a.description,
58
+ model: a.model,
59
+ instructions: a.instructions,
60
+ tools: a.tools,
61
+ cap: dollars(a.cap),
62
+ task: dollars(a.task),
63
+ period: a.period || 'month',
64
+ };
65
+ }
66
+ export const EMPTY = { name: '', description: '', model: '', instructions: '', tools: [], cap: '', task: '', period: 'month' };
67
+ /** Why a draft cannot be saved as it stands, or '' when it can. */
68
+ export function refuse(d) {
69
+ if (!NAME.test(d.name))
70
+ return 'A name is letters, digits, . _ or -, starting with a letter or digit';
71
+ if (new TextEncoder().encode(d.instructions).length > MAX)
72
+ return 'Instructions are at most 32 KB';
73
+ const cap = micros(d.cap);
74
+ const task = micros(d.task);
75
+ if (!(cap > 0))
76
+ return 'Set what it may spend each ' + d.period;
77
+ if (!(task > 0))
78
+ return 'Set what one run may spend';
79
+ if (task > cap)
80
+ return 'One run cannot spend more than the whole ' + d.period;
81
+ return '';
82
+ }
83
+ export async function agents(t) {
84
+ return rows(obj(await call(t, 'GET', '/v1/agent')).agents).map(agent).filter((a) => a.name);
85
+ }
86
+ export async function one(t, ref) {
87
+ return agent(await call(t, 'GET', `/v1/agent/${seg(ref)}`));
88
+ }
89
+ export async function create(t, d) {
90
+ const why = refuse(d);
91
+ if (why)
92
+ throw new Error(why);
93
+ const body = {
94
+ name: d.name.trim(),
95
+ description: d.description.trim(),
96
+ instructions: d.instructions,
97
+ tools: d.tools,
98
+ cap_micro_usd: micros(d.cap),
99
+ max_task_micro_usd: micros(d.task),
100
+ period: d.period,
101
+ };
102
+ if (d.model)
103
+ body.model = d.model;
104
+ return agent(await call(t, 'POST', '/v1/agent', body));
105
+ }
106
+ /** The fields that differ from `was`, and nothing else: an omitted field keeps its value. */
107
+ export function changes(was, d) {
108
+ const out = {};
109
+ if (d.model && d.model !== was.model)
110
+ out.model = d.model;
111
+ if (d.description.trim() !== was.description)
112
+ out.description = d.description.trim();
113
+ if (d.instructions !== was.instructions)
114
+ out.instructions = d.instructions;
115
+ if (d.tools.join('\n') !== was.tools.join('\n'))
116
+ out.tools = d.tools;
117
+ if (micros(d.cap) !== was.cap)
118
+ out.cap_micro_usd = micros(d.cap);
119
+ if (micros(d.task) !== was.task)
120
+ out.max_task_micro_usd = micros(d.task);
121
+ if (d.period !== was.period)
122
+ out.period = d.period;
123
+ return out;
124
+ }
125
+ export async function update(t, was, d) {
126
+ const why = refuse({ ...d, name: was.name });
127
+ if (why)
128
+ throw new Error(why);
129
+ const body = changes(was, d);
130
+ if (!Object.keys(body).length)
131
+ return was;
132
+ return agent(await call(t, 'PATCH', `/v1/agent/${seg(was.id || was.name)}`, body));
133
+ }
134
+ export async function remove(t, ref) {
135
+ await call(t, 'DELETE', `/v1/agent/${seg(ref)}`);
136
+ }
137
+ /** The presets that make a working agent. */
138
+ export async function presets(t) {
139
+ return rows(obj(await call(t, 'GET', '/v1/agent/chat/presets')).presets)
140
+ .map(obj)
141
+ .filter((p) => p.serverExecuted === true)
142
+ .map((p) => ({ id: str(p.id), title: str(p.title), prompt: str(p.systemPrompt) }))
143
+ .filter((p) => p.id);
144
+ }
145
+ /** A new agent's draft from a preset. */
146
+ export function fromPreset(p) {
147
+ return { ...EMPTY, name: p.id, description: p.title, instructions: p.prompt };
148
+ }
@@ -0,0 +1,205 @@
1
+ /**
2
+ * The organization's money: its plan, the cards it pays with, its invoices, its
3
+ * balance and credits, what it has spent this month, and the caps on that spend.
4
+ *
5
+ * GET /v1/billing/plans the catalog the serving brand sells (public)
6
+ * GET /v1/billing/subscriptions {count, subscriptions}
7
+ * POST /v1/billing/subscribe/card buy a plan with a saved card; one paid plan at a time (409)
8
+ * POST /v1/billing/subscriptions/{id}/cancel at the end of the paid period
9
+ * POST /v1/billing/subscriptions/{id}/reactivate
10
+ * GET /v1/billing/methods saved cards, newest first
11
+ * POST /v1/billing/methods save a card from the processor's single-use token
12
+ * DELETE /v1/billing/methods/{id}
13
+ * GET /v1/billing/settings the processor a browser tokenizes a card against
14
+ * GET /v1/billing/invoices {count, cursor, invoices}
15
+ * GET /v1/billing/invoices/{id}/pdf the invoice as a PDF
16
+ * GET /v1/billing/balance prepaid balance, whole cents
17
+ * GET /v1/billing/credit-balance granted credit, per currency
18
+ * POST /v1/billing/topup charge a saved card into the balance
19
+ * GET /v1/billing/usage/rollup the plan's month: included spend and request windows
20
+ * GET /v1/usage/summary?range=month this month's spend, by category
21
+ * GET /v1/billing/alerts spend caps (bare array)
22
+ * POST /v1/billing/alerts open a cap (org admin)
23
+ * PATCH /v1/billing/alerts/{id} change one (org admin)
24
+ * DELETE /v1/billing/alerts/{id} lift one (org admin)
25
+ *
26
+ * Every figure is whole cents. The wallet, the caps and the cards are the
27
+ * caller's own, resolved by the platform from the credential; nothing here names
28
+ * an org or a subject. No card number passes through this file: a card is saved
29
+ * from the token the processor's own form returns.
30
+ */
31
+ import { type Target } from './call.ts';
32
+ /** `$1,234.56` from whole cents; whole dollars drop the cents. */
33
+ export declare function money(cents: number, currency?: string): string;
34
+ /** Whole cents from what a person typed as dollars — `25`, `$25.50` — or null. */
35
+ export declare function cents(typed: string): number | null;
36
+ export interface Plan {
37
+ id: string;
38
+ name: string;
39
+ description: string;
40
+ /** personal, team, enterprise, … */
41
+ category: string;
42
+ /** Per month, billed monthly. 0 is free. */
43
+ monthly: number;
44
+ /** Per month, billed yearly; 0 when the plan has no yearly price. */
45
+ yearly: number;
46
+ currency: string;
47
+ perSeat: boolean;
48
+ /** Priced by talking to sales; nothing to buy here. */
49
+ sales: boolean;
50
+ popular: boolean;
51
+ features: string[];
52
+ }
53
+ export declare function plan(raw: unknown): Plan;
54
+ export declare function plans(t: Target): Promise<Plan[]>;
55
+ export interface Subscription {
56
+ id: string;
57
+ plan: string;
58
+ name: string;
59
+ /** Per period, per seat. */
60
+ price: number;
61
+ interval: string;
62
+ currency: string;
63
+ seats: number;
64
+ /** trialing, active, past_due, canceled, unpaid. */
65
+ status: string;
66
+ /** RFC 3339: paid through, and renews or ends then. */
67
+ ends: string;
68
+ /** Ends at `ends` rather than renewing. */
69
+ ending: boolean;
70
+ /** The saved card a renewal charges, or ''. */
71
+ method: string;
72
+ }
73
+ export declare function subscription(raw: unknown): Subscription;
74
+ /** The plan the org is on, or null for none (the free tier). */
75
+ export declare function current(list: Subscription[]): Subscription | null;
76
+ export declare function subscriptions(t: Target): Promise<Subscription[]>;
77
+ export interface Purchase {
78
+ plan: string;
79
+ /** month | year */
80
+ interval: 'month' | 'year';
81
+ /** The saved card that pays. */
82
+ method: string;
83
+ }
84
+ /** Buy a plan. No amount is sent: the catalog prices it, and the platform charges that. */
85
+ export declare function subscribe(t: Target, p: Purchase): Promise<{
86
+ subscription: string;
87
+ charged: number;
88
+ }>;
89
+ /** End a plan when its paid period does, not before. */
90
+ export declare function cancel(t: Target, id: string): Promise<Subscription>;
91
+ export declare function reactivate(t: Target, id: string): Promise<Subscription>;
92
+ export interface Method {
93
+ id: string;
94
+ type: string;
95
+ brand: string;
96
+ last4: string;
97
+ /** `MM/YY`, or ''. */
98
+ expires: string;
99
+ default: boolean;
100
+ /** What the platform calls it when it is not a card. */
101
+ name: string;
102
+ }
103
+ export declare function method(raw: unknown): Method;
104
+ /** How a saved method reads in a row: `Visa •••• 4242`. */
105
+ export declare function label(m: Method): string;
106
+ export declare function methods(t: Target): Promise<Method[]>;
107
+ /** The card a charge uses: the default, or the newest. */
108
+ export declare function chosen(list: Method[]): Method | null;
109
+ /** Save a card from the single-use token the processor's form returned. */
110
+ export declare function save(t: Target, token: string): Promise<Method>;
111
+ export declare function detach(t: Target, id: string): Promise<void>;
112
+ export interface Processor {
113
+ /** `square`, or '' where none is configured. */
114
+ provider: string;
115
+ application: string;
116
+ location: string;
117
+ /** `production` charges real cards; anything else is the sandbox. */
118
+ environment: string;
119
+ live: boolean;
120
+ }
121
+ export declare function processor(t: Target): Promise<Processor>;
122
+ export interface Line {
123
+ description: string;
124
+ amount: number;
125
+ }
126
+ export interface Invoice {
127
+ id: string;
128
+ /** `INV-0042`, or '' for a draft. */
129
+ number: string;
130
+ date: string;
131
+ status: string;
132
+ currency: string;
133
+ subtotal: number;
134
+ tax: number;
135
+ discount: number;
136
+ credit: number;
137
+ paid: number;
138
+ due: number;
139
+ /** What the invoice comes to before credit is applied. */
140
+ total: number;
141
+ start: string;
142
+ end: string;
143
+ lines: Line[];
144
+ }
145
+ export declare function invoice(raw: unknown): Invoice;
146
+ export declare function invoices(t: Target): Promise<Invoice[]>;
147
+ /** The invoice as a PDF, read with the caller's bearer. */
148
+ export declare function pdf(t: Target, id: string): Promise<Blob>;
149
+ /** What the org can still spend from its prepaid balance, in cents. */
150
+ export declare function balance(t: Target): Promise<number>;
151
+ /** Granted credit the org can spend, in US cents. */
152
+ export declare function credit(t: Target): Promise<number>;
153
+ /** Charge a saved card and add the amount to the balance; answers the balance after. */
154
+ export declare function topup(t: Target, amount: number, card: string): Promise<number>;
155
+ export interface Window {
156
+ /** hour, day, week or month. */
157
+ span: string;
158
+ /** Requests the plan includes in this span; 0 is no bound. */
159
+ limit: number;
160
+ used: number;
161
+ /** RFC 3339. */
162
+ resets: string;
163
+ }
164
+ export interface Month {
165
+ plan: string;
166
+ /** `2026-09`. */
167
+ period: string;
168
+ /** Spend the plan includes this month, and how much of it is used. */
169
+ included: number;
170
+ used: number;
171
+ overage: number;
172
+ windows: Window[];
173
+ }
174
+ export declare function month(t: Target): Promise<Month>;
175
+ export interface Spend {
176
+ /** Whether the ledger answered; false means the zeros are not measurements. */
177
+ known: boolean;
178
+ /** Month to date. */
179
+ total: number;
180
+ categories: {
181
+ name: string;
182
+ cents: number;
183
+ }[];
184
+ }
185
+ export declare function spend(t: Target): Promise<Spend>;
186
+ export interface Cap {
187
+ id: string;
188
+ title: string;
189
+ /** The ceiling for the calendar month, in cents; 0 bounds no spend. */
190
+ threshold: number;
191
+ /** Refuses spend past the ceiling, rather than only warning. */
192
+ enforce: boolean;
193
+ project: string;
194
+ service: string;
195
+ /** Spent this month against it, or null when the platform could not read it. */
196
+ spent: number | null;
197
+ resets: string;
198
+ }
199
+ export declare function cap(raw: unknown): Cap;
200
+ export declare function caps(t: Target): Promise<Cap[]>;
201
+ /** The org-wide monthly cap: no project, no service, a ceiling. */
202
+ export declare function monthly(list: Cap[]): Cap | null;
203
+ /** Set the org's monthly cap: change the one there is, or open one that refuses spend past it. */
204
+ export declare function limit(t: Target, list: Cap[], threshold: number): Promise<Cap>;
205
+ export declare function lift(t: Target, id: string): Promise<void>;