@coltonkirsten/a12s 0.6.0 → 0.7.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.
@@ -1,5 +1,5 @@
1
- import type { A12sEvent, ApiErrorBody, ComputerStatus, EnqueueRequest, EnqueueResponse, GapData, InboxListOptions, InboxListResponse, Message, PutFleetRequest, PutFleetResponse, ServiceStatus, StatusResponse, Token, TokenRequest, Turn } from "./types.js";
2
- export interface A12sClientOptions {
1
+ import type { A12sEvent, ApiErrorBody, ComputerStatus, EnqueueResponse, GapData, InboxListOptions, InboxListResponse, Message, PutFleetRequest, PutFleetResponse, SendRequest, ServiceStatus, StatusResponse, Token, TokenRequest, Turn } from "./types.js";
2
+ export interface ConnectOptions {
3
3
  /**
4
4
  * The Controller's API, e.g. http://127.0.0.1:52011. Default "": the page's own origin, which is what a browser
5
5
  * app served by `a12s gateway` uses.
@@ -58,18 +58,14 @@ export interface WaitOptions {
58
58
  export interface Reply extends Turn {
59
59
  message: EnqueueResponse;
60
60
  }
61
- /**
62
- * @deprecated Use {@link Fleet}: `fleet.agentComputers.get(name)` returns an {@link AgentComputer} with these
63
- * methods. Kept for one release.
64
- */
65
- export declare class A12sClient {
61
+ /** The HTTP transport behind {@link Fleet} and its handles; the package doesn't export it. */
62
+ export declare class Client {
66
63
  readonly url: string;
67
64
  private readonly token?;
68
65
  private readonly fetchImpl;
69
66
  private shared?;
70
- constructor(opts?: A12sClientOptions);
67
+ constructor(opts?: ConnectOptions);
71
68
  private headers;
72
- /** @internal */
73
69
  request<T>(method: string, path: string, body?: unknown, opts?: {
74
70
  headers?: Record<string, string>;
75
71
  signal?: AbortSignal;
@@ -81,9 +77,9 @@ export declare class A12sClient {
81
77
  * Puts a Message in a Computer's inbox and returns at once. It is delivered at the Computer's next idle moment,
82
78
  * batched with anything else pending. Works while the Computer is busy or asleep.
83
79
  */
84
- send(computer: string, msg: EnqueueRequest | string): Promise<EnqueueResponse>;
80
+ send(computer: string, msg: SendRequest | string): Promise<EnqueueResponse>;
85
81
  /** Sends a Message, waits for the Turn that delivers it and resolves when that Turn ends. */
86
- prompt(computer: string, body: string, opts?: Omit<EnqueueRequest, "body"> & WaitOptions): Promise<Reply>;
82
+ prompt(computer: string, body: string, opts?: Omit<SendRequest, "body"> & WaitOptions): Promise<Reply>;
87
83
  /**
88
84
  * @internal Waits for the Turn that delivers the Message and resolves when it ends. Delivery is read from the
89
85
  * Message's own snapshot and the Turn is replayed from its start, so it works however late it is called.
@@ -91,7 +87,7 @@ export declare class A12sClient {
91
87
  reply(computer: string, message: EnqueueResponse, opts?: WaitOptions): Promise<Reply>;
92
88
  /**
93
89
  * Live events of one Computer, several, or (no argument) every Computer in the Fleet, merged. Each event carries
94
- * its `computer`. Reconnects after a network drop without losing or repeating events. Call `await stream.ready()`
90
+ * its `agentComputer`. Reconnects after a network drop without losing or repeating events. Call `await stream.ready()`
95
91
  * before sending work you want to see from the start; `close()` (or `break`) ends it.
96
92
  */
97
93
  events(computers?: string | string[], opts?: EventsOptions): EventStream;
@@ -118,10 +114,8 @@ export declare class A12sClient {
118
114
  sleep(computer: string, opts?: {
119
115
  hold?: boolean;
120
116
  }): Promise<void>;
121
- /** Starts a sleeping agent computer; its session resumes on the next Turn. `clearInbox` discards pending Messages. */
122
- wake(computer: string, opts?: {
123
- clearInbox?: boolean;
124
- }): Promise<void>;
117
+ /** Starts a sleeping agent computer; its session resumes on the next Turn. */
118
+ wake(computer: string): Promise<void>;
125
119
  /** Holds the inbox: Messages still queue, none is delivered until resume(). */
126
120
  hold(computer: string, opts?: {
127
121
  reason?: string;
@@ -1,4 +1,4 @@
1
- // Runs in Node, Deno, Bun and browsers: no node: imports here (`npm run dashboard` bundles it for the browser).
1
+ // Runs in Node, Deno, Bun and browsers: no node: imports here (`npm run browser` bundles it for the browser).
2
2
  import { readSSE } from "./sse.js";
3
3
  /** A refused call: the HTTP status and the Controller's error, including its fix line. */
4
4
  export class A12sError extends Error {
@@ -45,11 +45,8 @@ export class A12sStreamError extends Error {
45
45
  }
46
46
  }
47
47
  const enc = encodeURIComponent;
48
- /**
49
- * @deprecated Use {@link Fleet}: `fleet.agentComputers.get(name)` returns an {@link AgentComputer} with these
50
- * methods. Kept for one release.
51
- */
52
- export class A12sClient {
48
+ /** The HTTP transport behind {@link Fleet} and its handles; the package doesn't export it. */
49
+ export class Client {
53
50
  url;
54
51
  token;
55
52
  fetchImpl;
@@ -62,7 +59,6 @@ export class A12sClient {
62
59
  headers(extra = {}) {
63
60
  return this.token ? { authorization: `Bearer ${this.token}`, ...extra } : extra;
64
61
  }
65
- /** @internal */
66
62
  async request(method, path, body, opts = {}) {
67
63
  const res = await this.fetchImpl(this.url + path, {
68
64
  method,
@@ -90,8 +86,7 @@ export class A12sClient {
90
86
  * batched with anything else pending. Works while the Computer is busy or asleep.
91
87
  */
92
88
  send(computer, msg) {
93
- const m = typeof msg === "string" ? { body: msg } : { ...msg };
94
- m.idempotencyKey ??= globalThis.crypto.randomUUID();
89
+ const m = { ...(typeof msg === "string" ? { body: msg } : msg), idempotencyKey: globalThis.crypto.randomUUID() };
95
90
  return this.request("POST", `/v1/agent-computers/${enc(computer)}/inbox`, m);
96
91
  }
97
92
  /** Sends a Message, waits for the Turn that delivers it and resolves when that Turn ends. */
@@ -118,7 +113,7 @@ export class A12sClient {
118
113
  }
119
114
  /**
120
115
  * Live events of one Computer, several, or (no argument) every Computer in the Fleet, merged. Each event carries
121
- * its `computer`. Reconnects after a network drop without losing or repeating events. Call `await stream.ready()`
116
+ * its `agentComputer`. Reconnects after a network drop without losing or repeating events. Call `await stream.ready()`
122
117
  * before sending work you want to see from the start; `close()` (or `break`) ends it.
123
118
  */
124
119
  events(computers, opts = {}) {
@@ -186,12 +181,9 @@ export class A12sClient {
186
181
  ...(opts.hold ? { hold: true } : {}),
187
182
  });
188
183
  }
189
- /** Starts a sleeping agent computer; its session resumes on the next Turn. `clearInbox` discards pending Messages. */
190
- async wake(computer, opts = {}) {
191
- await this.request("POST", `/v1/agent-computers/${enc(computer)}/power`, {
192
- state: "awake",
193
- ...(opts.clearInbox ? { clearInbox: true, requestId: crypto.randomUUID() } : {}),
194
- });
184
+ /** Starts a sleeping agent computer; its session resumes on the next Turn. */
185
+ async wake(computer) {
186
+ await this.request("POST", `/v1/agent-computers/${enc(computer)}/power`, { state: "awake" });
195
187
  }
196
188
  /** Holds the inbox: Messages still queue, none is delivered until resume(). */
197
189
  hold(computer, opts = {}) {
@@ -307,7 +299,7 @@ export class A12sClient {
307
299
  cursor = undefined; // the stream goes live; a reconnect starts live too
308
300
  if (opts.onGap === "throw")
309
301
  throw new A12sGapError(data);
310
- const gap = { v: 1, computer, session: "", turn: "", seq: 0, ts: new Date().toISOString(), type: "gap", data };
302
+ const gap = { v: 1, agentComputer: computer, session: "", turn: "", seq: 0, ts: new Date().toISOString(), type: "gap", data };
311
303
  yield gap;
312
304
  continue;
313
305
  }
@@ -478,7 +470,7 @@ class SharedEvents {
478
470
  }
479
471
  if (f.event === "gap") {
480
472
  const data = cursor !== undefined ? { lastEventId: cursor } : {};
481
- const gap = { v: 1, computer: "", session: "", turn: "", seq: 0, ts: new Date().toISOString(), type: "gap", data };
473
+ const gap = { v: 1, session: "", turn: "", seq: 0, ts: new Date().toISOString(), type: "gap", data };
482
474
  for (const s of this.subs) {
483
475
  if (s.onGap === "throw")
484
476
  s.fail(new A12sGapError(data));
@@ -510,7 +502,7 @@ class SharedEvents {
510
502
  }
511
503
  }
512
504
  function agentComputerOf(ev) {
513
- return ev.agentComputer || ev.computer;
505
+ return ev.agentComputer ?? "";
514
506
  }
515
507
  function wanted(names, ev) {
516
508
  if (!names)
@@ -721,7 +713,6 @@ class TurnBuilder {
721
713
  this.open.delete(key);
722
714
  return {
723
715
  agentComputer: name,
724
- computer: name,
725
716
  id: ev.turn,
726
717
  session: ev.session,
727
718
  status: ev.data.status,
@@ -1,5 +1,5 @@
1
- import { A12sClient, type A12sClientOptions, type EventsOptions, TurnStream, type EventStream, type Reply, type SharedEventsOptions, type WaitOptions } from "./client.js";
2
- import type { AgentComputerData, AgentComputerSpec, ComputerStatus, CredentialInfo, EnqueueRequest, EnqueueResponse, FleetSpec, InboxListOptions, InboxListResponse, MergePatch, Message, ServiceStatus, StatusResponse, Token, TokenAction, Turn } from "./types.js";
1
+ import { Client, type ConnectOptions, type EventsOptions, TurnStream, type EventStream, type Reply, type SharedEventsOptions, type WaitOptions } from "./client.js";
2
+ import type { AgentComputerData, AgentComputerSpec, ComputerStatus, CredentialInfo, EnqueueResponse, FleetSpec, InboxListOptions, InboxListResponse, MergePatch, Message, SendRequest, ServiceStatus, StatusResponse, Token, TokenAction, Turn } from "./types.js";
3
3
  /** The Fleet as written, and its version for a conditional write. */
4
4
  export interface FleetState {
5
5
  version: number;
@@ -21,19 +21,21 @@ export interface CreateOptions {
21
21
  * ```
22
22
  */
23
23
  export declare class Fleet {
24
- /** The lower-level client the handles use, for API calls that have no method here. */
25
- readonly client: A12sClient;
24
+ /** For API calls that have no method here: `request(method, path, body?, { headers, signal })`. */
25
+ readonly client: Pick<Client, "url" | "request">;
26
26
  readonly agentComputers: AgentComputers;
27
27
  readonly services: Services;
28
28
  readonly tokens: Tokens;
29
29
  readonly credentials: Credentials;
30
+ private readonly transport;
30
31
  /** No discovery: `url` and `token` as given, by default the page's own origin. */
31
- constructor(opts?: A12sClientOptions);
32
+ constructor(opts?: ConnectOptions);
32
33
  /**
33
34
  * In a browser: the Fleet behind the page's own origin, which is `a12s gateway` serving the page (no token
34
- * needed). In Node: found like {@link connect} finds it. Pass `url` and `token` to reach anything else.
35
+ * needed). In Node: a running Fleet found from the files `a12s up` writes. Pass `url` and `token` to reach anything
36
+ * else.
35
37
  */
36
- static connect(opts?: A12sClientOptions): Promise<Fleet>;
38
+ static connect(opts?: ConnectOptions): Promise<Fleet>;
37
39
  get url(): string;
38
40
  get(): Promise<FleetState>;
39
41
  /**
@@ -55,7 +57,7 @@ export declare class Fleet {
55
57
  }
56
58
  export declare class AgentComputers {
57
59
  private readonly client;
58
- constructor(client: A12sClient);
60
+ constructor(client: Client);
59
61
  /**
60
62
  * Adds an agent computer to the Fleet and starts it. One that names a credential with no value yet resolves at once,
61
63
  * waiting in Provisioning (`status.waiting`, and a console warning); it starts when the value is set. Fails with
@@ -74,7 +76,7 @@ export declare class AgentComputer {
74
76
  /** The spec with the Fleet's defaults merged in. */
75
77
  effective: AgentComputerSpec;
76
78
  status: ComputerStatus;
77
- constructor(client: A12sClient, data: AgentComputerData);
79
+ constructor(client: Client, data: AgentComputerData);
78
80
  private set;
79
81
  private get path();
80
82
  reload(): Promise<this>;
@@ -86,7 +88,7 @@ export declare class AgentComputer {
86
88
  * Puts a Message in the inbox; it is delivered at the next idle moment. Await it for the queued Message, or call
87
89
  * `wait()` on it (or on the awaited Message, at any time later) for the Turn that delivers it.
88
90
  */
89
- send(text: string, opts?: Omit<EnqueueRequest, "body">): Sending;
91
+ send(text: string, opts?: Omit<SendRequest, "body">): Sending;
90
92
  /** Its events, live, from the Fleet's shared connection; `turn` replays one Turn from its start instead. */
91
93
  events(opts?: EventsOptions): EventStream;
92
94
  /** Its last `limit` finished Turns, newest first. */
@@ -102,10 +104,8 @@ export declare class AgentComputer {
102
104
  sleep(opts?: {
103
105
  hold?: boolean;
104
106
  }): Promise<void>;
105
- /** Wakes it; `clearInbox` discards the pending Messages first. */
106
- wake(opts?: {
107
- clearInbox?: boolean;
108
- }): Promise<void>;
107
+ /** Wakes it; its session resumes on the next Turn. */
108
+ wake(): Promise<void>;
109
109
  /** Holds its inbox: Messages still queue, none is delivered until resume(). */
110
110
  hold(opts?: {
111
111
  reason?: string;
@@ -140,7 +140,7 @@ export declare class Sending implements Promise<SentMessage> {
140
140
  }
141
141
  export declare class Services {
142
142
  private readonly client;
143
- constructor(client: A12sClient);
143
+ constructor(client: Client);
144
144
  /** Adds a Service to the Fleet. Fails with code `exists` if the name is taken. */
145
145
  create(name: string, spec?: Record<string, unknown> & CreateOptions): Promise<Service>;
146
146
  /** Throws {@link NotFound} if there is none. */
@@ -152,7 +152,7 @@ export declare class Service {
152
152
  private readonly client;
153
153
  readonly name: string;
154
154
  status: ServiceStatus;
155
- constructor(client: A12sClient, status: ServiceStatus);
155
+ constructor(client: Client, status: ServiceStatus);
156
156
  /** As written in the Fleet. */
157
157
  get spec(): Record<string, unknown>;
158
158
  private get path();
@@ -167,10 +167,11 @@ export declare class Service {
167
167
  }
168
168
  export declare class Tokens {
169
169
  private readonly client;
170
- constructor(client: A12sClient);
170
+ constructor(client: Client);
171
171
  /**
172
172
  * A token for another program; owner only. The secret is in the result once. With `prefix` it may do everything
173
- * the owner can for names that start with it, and nothing outside; otherwise `actions` on `agentComputers`.
173
+ * the owner can for names that start with it except set `security.seccomp`, and nothing outside; otherwise
174
+ * `actions` on `agentComputers`.
174
175
  */
175
176
  create(name: string, opts: {
176
177
  prefix: string;
@@ -184,7 +185,7 @@ export declare class Tokens {
184
185
  /** Credentials by name: set once, then name them in a spec's `credentials`. Values are never read back. */
185
186
  export declare class Credentials {
186
187
  private readonly client;
187
- constructor(client: A12sClient);
188
+ constructor(client: Client);
188
189
  /** Stores the value on the Controller; agent computers that use it get the new value at once. */
189
190
  set(name: string, value: string): Promise<CredentialInfo>;
190
191
  list(): Promise<CredentialInfo[]>;
package/dist/src/fleet.js CHANGED
@@ -1,5 +1,5 @@
1
- // Runs in Node, Deno, Bun and browsers: no node: imports here (`npm run dashboard` bundles it for the browser).
2
- import { A12sClient, A12sError, TurnStream, } from "./client.js";
1
+ // Runs in Node, Deno, Bun and browsers: no node: imports here (`npm run browser` bundles it for the browser).
2
+ import { A12sError, Client, TurnStream, } from "./client.js";
3
3
  const enc = encodeURIComponent;
4
4
  const maxReplaceTries = 5;
5
5
  /**
@@ -14,23 +14,25 @@ const maxReplaceTries = 5;
14
14
  * ```
15
15
  */
16
16
  export class Fleet {
17
- /** The lower-level client the handles use, for API calls that have no method here. */
17
+ /** For API calls that have no method here: `request(method, path, body?, { headers, signal })`. */
18
18
  client;
19
19
  agentComputers;
20
20
  services;
21
21
  tokens;
22
22
  credentials;
23
+ transport;
23
24
  /** No discovery: `url` and `token` as given, by default the page's own origin. */
24
25
  constructor(opts = {}) {
25
- this.client = new A12sClient(opts);
26
- this.agentComputers = new AgentComputers(this.client);
27
- this.services = new Services(this.client);
28
- this.tokens = new Tokens(this.client);
29
- this.credentials = new Credentials(this.client);
26
+ this.client = this.transport = new Client(opts);
27
+ this.agentComputers = new AgentComputers(this.transport);
28
+ this.services = new Services(this.transport);
29
+ this.tokens = new Tokens(this.transport);
30
+ this.credentials = new Credentials(this.transport);
30
31
  }
31
32
  /**
32
33
  * In a browser: the Fleet behind the page's own origin, which is `a12s gateway` serving the page (no token
33
- * needed). In Node: found like {@link connect} finds it. Pass `url` and `token` to reach anything else.
34
+ * needed). In Node: a running Fleet found from the files `a12s up` writes. Pass `url` and `token` to reach anything
35
+ * else.
34
36
  */
35
37
  static async connect(opts = {}) {
36
38
  return new Fleet(opts);
@@ -72,16 +74,16 @@ export class Fleet {
72
74
  */
73
75
  events(agentComputers, opts = {}) {
74
76
  if (opts.turn !== undefined || opts.after !== undefined)
75
- return this.client.events(agentComputers, opts);
76
- return this.client.sharedEvents(namesOf(agentComputers), opts);
77
+ return this.transport.events(agentComputers, opts);
78
+ return this.transport.sharedEvents(namesOf(agentComputers), opts);
77
79
  }
78
80
  /** Finished Turns of the named agent computers, or all of them, as they end. */
79
81
  turns(agentComputers, opts = {}) {
80
- return new TurnStream(this.client.sharedEvents(namesOf(agentComputers), opts));
82
+ return new TurnStream(this.transport.sharedEvents(namesOf(agentComputers), opts));
81
83
  }
82
84
  /** Every agent computer and Service: phase, session, active Turn, inbox, power. */
83
85
  status() {
84
- return this.client.status();
86
+ return this.transport.status();
85
87
  }
86
88
  }
87
89
  function namesOf(names) {
@@ -189,9 +191,9 @@ export class AgentComputer {
189
191
  sleep(opts = {}) {
190
192
  return this.client.sleep(this.name, opts);
191
193
  }
192
- /** Wakes it; `clearInbox` discards the pending Messages first. */
193
- wake(opts = {}) {
194
- return this.client.wake(this.name, opts);
194
+ /** Wakes it; its session resumes on the next Turn. */
195
+ wake() {
196
+ return this.client.wake(this.name);
195
197
  }
196
198
  /** Holds its inbox: Messages still queue, none is delivered until resume(). */
197
199
  hold(opts = {}) {
@@ -311,7 +313,8 @@ export class Tokens {
311
313
  }
312
314
  /**
313
315
  * A token for another program; owner only. The secret is in the result once. With `prefix` it may do everything
314
- * the owner can for names that start with it, and nothing outside; otherwise `actions` on `agentComputers`.
316
+ * the owner can for names that start with it except set `security.seccomp`, and nothing outside; otherwise
317
+ * `actions` on `agentComputers`.
315
318
  */
316
319
  create(name, opts) {
317
320
  if ("prefix" in opts) {
@@ -1,12 +1,3 @@
1
- import { A12sClient, type A12sClientOptions } from "./client.js";
2
- export * from "./client.js";
1
+ export { A12sError, A12sGapError, A12sStreamError, EventStream, NotFound, TurnStream, type ConnectOptions, type EventsOptions, type Reply, type SharedEventsOptions, type WaitOptions, } from "./client.js";
3
2
  export * from "./fleet.js";
4
3
  export * from "./types.js";
5
- export type ConnectOptions = A12sClientOptions;
6
- /**
7
- * @deprecated Use `Fleet.connect()`. Kept for one release.
8
- *
9
- * In a browser: a client for the page's own origin, which is `a12s gateway` serving the page (no token needed).
10
- * Pass `url` and `token` to reach anything else.
11
- */
12
- export declare function connect(opts?: ConnectOptions): Promise<A12sClient>;
package/dist/src/index.js CHANGED
@@ -1,15 +1,5 @@
1
1
  // The default entry (browsers, Deno, workers): no node: imports. Node resolves "@coltonkirsten/a12s" to ./node.ts instead, through
2
2
  // the "node" export condition, so `import { Fleet } from "@coltonkirsten/a12s"` works everywhere.
3
- import { A12sClient } from "./client.js";
4
- export * from "./client.js";
3
+ export { A12sError, A12sGapError, A12sStreamError, EventStream, NotFound, TurnStream, } from "./client.js";
5
4
  export * from "./fleet.js";
6
5
  export * from "./types.js";
7
- /**
8
- * @deprecated Use `Fleet.connect()`. Kept for one release.
9
- *
10
- * In a browser: a client for the page's own origin, which is `a12s gateway` serving the page (no token needed).
11
- * Pass `url` and `token` to reach anything else.
12
- */
13
- export async function connect(opts = {}) {
14
- return new A12sClient(opts);
15
- }
@@ -1,31 +1,25 @@
1
- import { A12sClient, type A12sClientOptions } from "./client.js";
1
+ import type { ConnectOptions as PageConnectOptions } from "./client.js";
2
2
  import { Fleet as PageFleet } from "./fleet.js";
3
- export * from "./client.js";
4
- export * from "./fleet.js";
5
- export * from "./types.js";
3
+ export * from "./index.js";
6
4
  export declare class Fleet extends PageFleet {
7
- /** A running Fleet, as its owner, found like {@link connect} finds it. */
5
+ /**
6
+ * A running Fleet, as its owner. It uses the first of:
7
+ * 1. `url` (and `token`), or `$A12S_URL` (and `$A12S_TOKEN`);
8
+ * 2. the Fleet named by `fleet`;
9
+ * 3. the Fleet file in `$A12S_FLEET`, else the nearest `fleet.yaml` in the current directory or a parent;
10
+ * 4. the only Fleet with a running Controller on this machine.
11
+ * For 2–4 it reads `~/.a12s/<fleet>/controller.json`, which `a12s up` writes: its URL always, and its owner token
12
+ * unless `token` is given (a prefix or narrow token on this machine).
13
+ */
8
14
  static connect(opts?: ConnectOptions): Promise<Fleet>;
9
15
  }
10
- export interface ConnectOptions extends A12sClientOptions {
11
- /** The Fleet's name (`metadata.name`). Default: found as described on {@link connect}. */
16
+ export interface ConnectOptions extends PageConnectOptions {
17
+ /** The Fleet's name (`metadata.name`). Default: found as described on {@link Fleet.connect}. */
12
18
  fleet?: string;
13
19
  /** Where `.a12s/` lives. Default: the home directory. */
14
20
  home?: string;
15
21
  /** Where to start looking for fleet.yaml. Default: the current directory. */
16
22
  cwd?: string;
17
23
  }
18
- /**
19
- * @deprecated Use `Fleet.connect()`, which finds the Fleet the same way. Kept for one release.
20
- *
21
- * A client for a running Fleet, as its owner. It uses the first of:
22
- * 1. `url` (and `token`), or `$A12S_URL` (and `$A12S_TOKEN`);
23
- * 2. the Fleet named by `fleet`;
24
- * 3. the Fleet file in `$A12S_FLEET`, else the nearest `fleet.yaml` in the current directory or a parent;
25
- * 4. the only Fleet with a running Controller on this machine.
26
- * For 2–4 it reads `~/.a12s/<fleet>/controller.json`, which `a12s up` writes: its URL always, and its owner token
27
- * unless `token` is given (a prefix or narrow token on this machine).
28
- */
29
- export declare function connect(opts?: ConnectOptions): Promise<A12sClient>;
30
24
  /** metadata.name from a Fleet file, in either `metadata: { name: x }` or block form. */
31
25
  export declare function fleetName(yaml: string): string | undefined;
package/dist/src/node.js CHANGED
@@ -1,32 +1,23 @@
1
- // The Node entry ("node" export condition): connect() finds a running Fleet from the files `a12s up` writes.
1
+ // The Node entry ("node" export condition): Fleet.connect() finds a running Fleet from the files `a12s up` writes.
2
2
  import { readdir, readFile } from "node:fs/promises";
3
3
  import { homedir } from "node:os";
4
4
  import { dirname, join, resolve } from "node:path";
5
- import { A12sClient } from "./client.js";
6
5
  import { Fleet as PageFleet } from "./fleet.js";
7
- export * from "./client.js";
8
- export * from "./fleet.js";
9
- export * from "./types.js";
6
+ export * from "./index.js";
10
7
  export class Fleet extends PageFleet {
11
- /** A running Fleet, as its owner, found like {@link connect} finds it. */
8
+ /**
9
+ * A running Fleet, as its owner. It uses the first of:
10
+ * 1. `url` (and `token`), or `$A12S_URL` (and `$A12S_TOKEN`);
11
+ * 2. the Fleet named by `fleet`;
12
+ * 3. the Fleet file in `$A12S_FLEET`, else the nearest `fleet.yaml` in the current directory or a parent;
13
+ * 4. the only Fleet with a running Controller on this machine.
14
+ * For 2–4 it reads `~/.a12s/<fleet>/controller.json`, which `a12s up` writes: its URL always, and its owner token
15
+ * unless `token` is given (a prefix or narrow token on this machine).
16
+ */
12
17
  static async connect(opts = {}) {
13
18
  return new Fleet(await discover(opts));
14
19
  }
15
20
  }
16
- /**
17
- * @deprecated Use `Fleet.connect()`, which finds the Fleet the same way. Kept for one release.
18
- *
19
- * A client for a running Fleet, as its owner. It uses the first of:
20
- * 1. `url` (and `token`), or `$A12S_URL` (and `$A12S_TOKEN`);
21
- * 2. the Fleet named by `fleet`;
22
- * 3. the Fleet file in `$A12S_FLEET`, else the nearest `fleet.yaml` in the current directory or a parent;
23
- * 4. the only Fleet with a running Controller on this machine.
24
- * For 2–4 it reads `~/.a12s/<fleet>/controller.json`, which `a12s up` writes: its URL always, and its owner token
25
- * unless `token` is given (a prefix or narrow token on this machine).
26
- */
27
- export async function connect(opts = {}) {
28
- return new A12sClient(await discover(opts));
29
- }
30
21
  async function discover(opts) {
31
22
  const url = opts.url ?? process.env.A12S_URL;
32
23
  if (url)
@@ -93,6 +84,6 @@ async function onlyRunningFleet(home) {
93
84
  if (running.length === 1)
94
85
  return running[0];
95
86
  throw new Error(running.length === 0
96
- ? "no running Fleet found: run a12s up in your Fleet's directory, or pass connect({ url, token })"
97
- : `several Fleets are running (${running.join(", ")}): pass connect({ fleet: "<name>" }) or run from the Fleet's directory`);
87
+ ? "no running Fleet found: run a12s up in your Fleet's directory, or pass Fleet.connect({ url, token })"
88
+ : `several Fleets are running (${running.join(", ")}): pass Fleet.connect({ fleet: "<name>" }) or run from the Fleet's directory`);
98
89
  }
@@ -28,18 +28,8 @@ export interface AgentComputerSpec {
28
28
  cpu?: string | number;
29
29
  memory?: string | number;
30
30
  };
31
- home?: {
32
- size?: string | number;
33
- preset?: string;
34
- };
35
- autonomy?: "full" | "restricted";
36
- /** Credential names; their values come from `a12s up` or the credentials API. */
31
+ /** Credential names, added to the defaults' list; their values come from `a12s creds set` or the credentials API. */
37
32
  credentials?: string[];
38
- drives?: Array<{
39
- name: string;
40
- at: string;
41
- readOnly?: boolean;
42
- }>;
43
33
  egress?: {
44
34
  allow?: string[];
45
35
  };
@@ -50,7 +40,6 @@ export interface AgentComputerSpec {
50
40
  inbox?: {
51
41
  maxMessages?: number;
52
42
  maxBytes?: string;
53
- intro?: string;
54
43
  };
55
44
  power?: {
56
45
  sleepAfterIdle?: string;
@@ -78,15 +67,7 @@ export interface FleetSpec {
78
67
  metadata: {
79
68
  name: string;
80
69
  };
81
- egress?: {
82
- enforcement?: string;
83
- allowPrivate?: string[];
84
- };
85
70
  defaults?: AgentComputerSpec;
86
- drives?: Record<string, {
87
- size?: string | number;
88
- access: string;
89
- }>;
90
71
  agent_computers: Record<string, AgentComputerSpec>;
91
72
  services?: Record<string, Record<string, unknown>>;
92
73
  }
@@ -124,9 +105,8 @@ export interface AgentComputersResponse {
124
105
  }
125
106
  export interface PutFleetRequest {
126
107
  fleet: FleetSpec;
127
- /** Credential values by name, base64-encoded (Go []byte). Kept in the Controller's memory only. */
108
+ /** Credential values by name, base64-encoded (Go []byte). */
128
109
  credentials?: Record<string, string>;
129
- asleep?: boolean;
130
110
  }
131
111
  export interface ServiceChanges {
132
112
  created: string[] | null;
@@ -204,28 +184,21 @@ export interface ComputerStatus {
204
184
  image: string;
205
185
  /** The Fleet's security.seccomp path, when the Computer runs with a custom seccomp profile. */
206
186
  seccomp?: string;
207
- autonomy: string;
208
187
  generation: number;
209
188
  stagedGeneration?: number;
210
189
  credentialGeneration?: number;
211
- /** A quantity such as "10Gi". */
212
- homeSize?: string;
213
- drives?: string[];
214
190
  egressMode?: string;
215
191
  warnings?: string[];
216
192
  inbox?: InboxSummary;
217
- /** Set only on a wake --clear-inbox answer: how many Messages were discarded. */
218
- inboxCleared?: number;
219
193
  power?: PowerStatus;
220
194
  }
221
195
  export interface DriveRow {
222
196
  name: string;
223
- kind: "home" | "work" | "state";
197
+ kind: "home" | "state";
224
198
  computer?: string;
225
199
  service?: string;
226
200
  /** A quantity such as "10Gi". */
227
201
  size?: string;
228
- access?: string;
229
202
  attachedTo?: string[];
230
203
  orphaned?: boolean;
231
204
  }
@@ -243,7 +216,6 @@ export interface ServiceStatus {
243
216
  send?: string[];
244
217
  uses?: string[];
245
218
  usedBy?: string[];
246
- publish?: string[];
247
219
  ports?: string[];
248
220
  stateDrive?: string;
249
221
  egressMode?: string;
@@ -253,12 +225,8 @@ export interface ServiceStatus {
253
225
  }
254
226
  export interface StatusResponse {
255
227
  fleet: string;
256
- egressEnforcement: string;
257
228
  agentComputers: ComputerStatus[];
258
- /** @deprecated `agentComputers` under its old name. */
259
- computers: ComputerStatus[];
260
229
  orphanedDrives?: DriveRow[];
261
- credentialsLoaded: boolean;
262
230
  warnings?: string[];
263
231
  orphanedInboxes?: InboxSummary[];
264
232
  services?: ServiceStatus[];
@@ -270,12 +238,14 @@ export interface EnqueueRequest {
270
238
  sender?: string;
271
239
  metadata?: Record<string, string>;
272
240
  fresh?: boolean;
273
- /** A retry with the same key returns the original Message. The client sends a random one if unset. */
241
+ /** Set by the client on every send: a request repeated with the same key returns the original Message. */
274
242
  idempotencyKey?: string;
275
243
  /** Seconds; 0 means now or never. */
276
244
  expires?: number;
277
245
  replaceKey?: string;
278
246
  }
247
+ /** What send() takes: the client sets the idempotencyKey itself. */
248
+ export type SendRequest = Omit<EnqueueRequest, "idempotencyKey">;
279
249
  export interface EnqueueResponse {
280
250
  id: string;
281
251
  seq: number;
@@ -322,10 +292,8 @@ export interface InboxListOptions {
322
292
  /** The fields every event has. `seq` is the agent computer's journal position (0 for the Controller's own events). */
323
293
  export interface EventEnvelope {
324
294
  v: number;
325
- /** The agent computer it is about; absent on `fleet.changed` and in journals older than the field. */
295
+ /** The agent computer it is about; absent on `fleet.changed` and `service.phase`. */
326
296
  agentComputer?: string;
327
- /** `agentComputer` under its old name, for one release. */
328
- computer: string;
329
297
  session: string;
330
298
  /** The Turn it belongs to; "" for events outside a Turn. */
331
299
  turn: string;
@@ -501,8 +469,6 @@ export interface ToolCall {
501
469
  /** A finished Turn: what `turns()` yields and `wait()` returns. */
502
470
  export interface Turn {
503
471
  agentComputer: string;
504
- /** `agentComputer` under its old name, for one release. */
505
- computer: string;
506
472
  /** The Turn id. */
507
473
  id: string;
508
474
  session: string;
@@ -539,7 +505,7 @@ export interface TokenRequest {
539
505
  name: string;
540
506
  actions?: TokenAction[];
541
507
  computers?: string[];
542
- /** Every power over agent computers, Services and credentials whose names start with it; none outside. */
508
+ /** Every power over agent computers, Services and credentials whose names start with it but seccomp; none outside. */
543
509
  prefix?: string;
544
510
  }
545
511
  /** A credential's name, whether it has a value, and who uses it. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coltonkirsten/a12s",
3
- "version": "0.6.0",
3
+ "version": "0.7.1",
4
4
  "description": "TypeScript client for a12s: send work to agent Computers, stream their events and Turns, in Node or the browser",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -35,10 +35,10 @@
35
35
  "provenance": true
36
36
  },
37
37
  "scripts": {
38
- "build": "rm -rf dist && tsc -p tsconfig.json && npm run dashboard",
38
+ "build": "rm -rf dist && tsc -p tsconfig.json && npm run browser",
39
39
  "lint": "tsc -p tsconfig.json --noEmit",
40
40
  "test": "npm run build && node --test 'dist/test/*.test.js'",
41
- "dashboard": "esbuild ../../internal/gateway/dashboard/main.js --bundle --platform=browser --format=esm --alias:@coltonkirsten/a12s=./src/index.ts --log-level=warning --outfile=dist/dashboard.js"
41
+ "browser": "esbuild src/index.ts --bundle --platform=browser --format=esm --log-level=warning --outfile=dist/browser.js"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^24.19.1",