@north-light/sdk 0.0.0 → 0.3.415

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 (121) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +187 -2
  3. package/dist/client.d.ts +176 -0
  4. package/dist/client.js +582 -0
  5. package/dist/crtr.d.ts +24 -0
  6. package/dist/crtr.js +50 -0
  7. package/dist/env-command.d.ts +15 -0
  8. package/dist/env-command.js +138 -0
  9. package/dist/error-codes.d.ts +7 -0
  10. package/dist/error-codes.js +43 -0
  11. package/dist/errors.d.ts +72 -0
  12. package/dist/errors.js +101 -0
  13. package/dist/index.d.ts +41 -0
  14. package/dist/index.js +17 -0
  15. package/dist/keygen-cli.d.ts +2 -0
  16. package/dist/keygen-cli.js +11 -0
  17. package/dist/keygen-command.d.ts +6 -0
  18. package/dist/keygen-command.js +131 -0
  19. package/dist/oauth/index.d.ts +235 -0
  20. package/dist/oauth/index.js +621 -0
  21. package/dist/oauth/keygen.d.ts +18 -0
  22. package/dist/oauth/keygen.js +46 -0
  23. package/dist/oauth/refusal.d.ts +32 -0
  24. package/dist/oauth/refusal.js +17 -0
  25. package/dist/resources/activity.d.ts +22 -0
  26. package/dist/resources/activity.js +43 -0
  27. package/dist/resources/attachments.d.ts +15 -0
  28. package/dist/resources/attachments.js +13 -0
  29. package/dist/resources/bash.d.ts +9 -0
  30. package/dist/resources/bash.js +15 -0
  31. package/dist/resources/canvas/history.d.ts +11 -0
  32. package/dist/resources/canvas/history.js +20 -0
  33. package/dist/resources/canvas.d.ts +19 -0
  34. package/dist/resources/canvas.js +42 -0
  35. package/dist/resources/crons.d.ts +15 -0
  36. package/dist/resources/crons.js +33 -0
  37. package/dist/resources/custom-objects.d.ts +20 -0
  38. package/dist/resources/custom-objects.js +84 -0
  39. package/dist/resources/files.d.ts +34 -0
  40. package/dist/resources/files.js +34 -0
  41. package/dist/resources/follower.d.ts +71 -0
  42. package/dist/resources/follower.js +202 -0
  43. package/dist/resources/forward.d.ts +7 -0
  44. package/dist/resources/forward.js +67 -0
  45. package/dist/resources/grant-watcher.d.ts +57 -0
  46. package/dist/resources/grant-watcher.js +100 -0
  47. package/dist/resources/human/inbox.d.ts +14 -0
  48. package/dist/resources/human/inbox.js +30 -0
  49. package/dist/resources/human/requests.d.ts +13 -0
  50. package/dist/resources/human/requests.js +26 -0
  51. package/dist/resources/human.d.ts +8 -0
  52. package/dist/resources/human.js +10 -0
  53. package/dist/resources/identifiers.d.ts +8 -0
  54. package/dist/resources/identifiers.js +33 -0
  55. package/dist/resources/memory.d.ts +69 -0
  56. package/dist/resources/memory.js +30 -0
  57. package/dist/resources/models/config.d.ts +8 -0
  58. package/dist/resources/models/config.js +9 -0
  59. package/dist/resources/models/credentials.d.ts +10 -0
  60. package/dist/resources/models/credentials.js +17 -0
  61. package/dist/resources/models.d.ts +8 -0
  62. package/dist/resources/models.js +10 -0
  63. package/dist/resources/node-stream.d.ts +34 -0
  64. package/dist/resources/node-stream.js +176 -0
  65. package/dist/resources/nodes/jobs.d.ts +9 -0
  66. package/dist/resources/nodes/jobs.js +14 -0
  67. package/dist/resources/nodes/result.d.ts +8 -0
  68. package/dist/resources/nodes/result.js +11 -0
  69. package/dist/resources/nodes/worktree.d.ts +9 -0
  70. package/dist/resources/nodes/worktree.js +14 -0
  71. package/dist/resources/nodes.d.ts +23 -0
  72. package/dist/resources/nodes.js +47 -0
  73. package/dist/resources/providers.d.ts +51 -0
  74. package/dist/resources/providers.js +15 -0
  75. package/dist/resources/questions.d.ts +49 -0
  76. package/dist/resources/questions.js +21 -0
  77. package/dist/resources/request.d.ts +12 -0
  78. package/dist/resources/request.js +50 -0
  79. package/dist/resources/run-notice.d.ts +34 -0
  80. package/dist/resources/run-notice.js +67 -0
  81. package/dist/resources/run-reply.d.ts +79 -0
  82. package/dist/resources/run-reply.js +93 -0
  83. package/dist/resources/run-stream.d.ts +65 -0
  84. package/dist/resources/run-stream.js +243 -0
  85. package/dist/resources/run-watcher.d.ts +98 -0
  86. package/dist/resources/run-watcher.js +162 -0
  87. package/dist/resources/runs.d.ts +199 -0
  88. package/dist/resources/runs.js +228 -0
  89. package/dist/resources/shares.d.ts +40 -0
  90. package/dist/resources/shares.js +19 -0
  91. package/dist/resources/structured-requests.d.ts +14 -0
  92. package/dist/resources/structured-requests.js +19 -0
  93. package/dist/resources/uploads.d.ts +27 -0
  94. package/dist/resources/uploads.js +11 -0
  95. package/dist/schema.d.ts +7 -0
  96. package/dist/schema.js +10 -0
  97. package/dist/stores/postgres.d.ts +32 -0
  98. package/dist/stores/postgres.js +92 -0
  99. package/dist/testing/clock.d.ts +7 -0
  100. package/dist/testing/clock.js +12 -0
  101. package/dist/testing/cloud.d.ts +228 -0
  102. package/dist/testing/cloud.js +914 -0
  103. package/dist/testing/conformance/index.d.ts +2 -0
  104. package/dist/testing/conformance/index.js +3 -0
  105. package/dist/testing/conformance/keyed-write.d.ts +43 -0
  106. package/dist/testing/conformance/keyed-write.js +124 -0
  107. package/dist/testing/index.d.ts +7 -0
  108. package/dist/testing/index.js +4 -0
  109. package/dist/testing/notices.d.ts +76 -0
  110. package/dist/testing/notices.js +209 -0
  111. package/dist/testing/run.d.ts +174 -0
  112. package/dist/testing/run.js +429 -0
  113. package/dist/testing/users.d.ts +127 -0
  114. package/dist/testing/users.js +78 -0
  115. package/dist/testing/wire.d.ts +62 -0
  116. package/dist/testing/wire.js +148 -0
  117. package/dist/types.d.ts +88 -0
  118. package/dist/types.js +1 -0
  119. package/dist/version.d.ts +2 -0
  120. package/dist/version.js +3 -0
  121. package/package.json +60 -5
package/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2026 Northlight Systems. All rights reserved.
2
+
3
+ This software and its associated documentation files (the "Software") are the
4
+ proprietary and confidential property of Northlight Systems. No licence or
5
+ right to use, copy, modify, merge, publish, distribute, sublicense, sell,
6
+ reverse engineer, decompile or create derivative works of the Software is
7
+ granted except under a separate written agreement with Northlight Systems.
8
+
9
+ The Software is made available as compiled and minified packages through the
10
+ npm registry solely so that it can be installed and run by those authorised by
11
+ Northlight Systems. Installing a package from the registry does not grant any
12
+ licence to the Software's source code.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
+ NORTHLIGHT SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING
18
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR ITS USE.
package/README.md CHANGED
@@ -1,3 +1,188 @@
1
- # @north-light/sdk
1
+ # @north-light/sdk — a typed Node and browser client for running crouter agents from your application
2
2
 
3
- Placeholder that reserves the name so trusted publishing can be configured. Real releases are published by CI from Northlight-Systems/crouter.
3
+ ![crouter](https://raw.githubusercontent.com/Northlight-Systems/crouter/main/assets/banner.svg)
4
+
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/@north-light/sdk"><img alt="npm" src="https://img.shields.io/npm/v/@north-light/sdk?label=npm"></a>
7
+ </p>
8
+
9
+ `@north-light/sdk` is the application-facing client for a crouter daemon (`crtrd`). Create an agent run, wait for a result checked against a Zod or Standard Schema, stream the run's text and tool calls to a UI, and use the daemon's other APIs: files, bash, documents ("memory"), crons, human requests, and the OAuth connection flow for apps whose users each have their own runtime. It is ESM-only.
10
+
11
+ It is a client, not a runtime. It never runs an agent itself, and it does not bundle a model: the daemon it talks to does, using the provider that daemon is signed in to. In Node, `new Crouter()` connects to the local daemon over its unix socket and starts it on the first request if it is not running. In a browser or from another machine it needs the daemon's TCP URL and a bearer token. The lower-level contract it is built on is [`@north-light/api`](https://www.npmjs.com/package/@north-light/api); most applications should install this package instead.
12
+
13
+ [Docs](https://docs.crouter.ai/docs/sdk) · [Client construction](https://docs.crouter.ai/docs/sdk/client) · [Resource map](https://docs.crouter.ai/docs/sdk/resources) · [Recipes](https://docs.crouter.ai/docs/sdk/guides) · [crouter repository](https://github.com/Northlight-Systems/crouter)
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install @north-light/sdk zod # zod is optional; any Standard Schema works for output_schema
19
+ npm install -g @north-light/cli # the daemon and the crtr CLI
20
+ crtr # first run: the installer signs you in to a model provider
21
+ ```
22
+
23
+ ## Connect
24
+
25
+ In Node, `new Crouter()` uses the local unix socket and starts the daemon on the first request when the socket is cold. In a browser or a remote process, pass the TCP URL and bearer token returned by `crtr sys connect` — the owner token, or a scoped token from `crtr sys connect --scopes` whose list caps what the application and its runs may do. Call `client.auth.status()` before enabling a run button: its `instructions` tells the user what to do when `next_step` is not `null`.
26
+
27
+ ```ts
28
+ import Crouter from '@north-light/sdk';
29
+
30
+ const client = new Crouter();
31
+ const status = await client.auth.status();
32
+
33
+ if (status.next_step !== null) {
34
+ console.log(status.instructions);
35
+ } else {
36
+ console.log('The daemon and selected provider are ready.');
37
+ }
38
+ ```
39
+
40
+ ```ts
41
+ const client = new Crouter({
42
+ baseURL: 'http://127.0.0.1:8787',
43
+ token: 'the-token-from-crtr-sys-connect',
44
+ });
45
+ ```
46
+
47
+ ## Runtime version
48
+
49
+ The SDK talks only to a runtime at or above its own version (`SDK_VERSION`), and has no compatibility mode for older ones: its types, such as `RunObject.activity`, describe what a runtime at its release sends. Every runtime answer carries a `Crouter-Runtime-Version` header. When that version is older than the SDK, or the header is missing (every runtime released before this rule shipped), the call throws `RuntimeVersionError` before the SDK reads the response: `code` is `runtime_version_unsupported`, `status` is 426, `retryable` is false, and `sdkVersion` and `runtimeVersion` name both versions. The SDK also sends its own version on every request except `/healthz` as `Crouter-Minimum-Runtime-Version`; the hosting router and a runtime at this release or later refuse an older runtime with the same 426 *before* any handler runs, so nothing is accepted and no `Idempotency-Key` is recorded (a retry after the roll is a first send). Upgrade the runtime first, then the SDK.
50
+
51
+ Pin `@north-light/sdk` to an exact version. One release is one version set: `@north-light/sdk@X` depends on exactly `@north-light/api@X` and `@north-light/identity@X`, so the pin fixes all three.
52
+
53
+ ```ts
54
+ import { RuntimeVersionError } from '@north-light/sdk';
55
+
56
+ try {
57
+ await client.runs.get(runId);
58
+ } catch (error) {
59
+ if (error instanceof RuntimeVersionError) console.error(`runtime ${error.runtimeVersion ?? '(unnamed)'} is older than SDK ${error.sdkVersion}`);
60
+ else throw error;
61
+ }
62
+ ```
63
+
64
+ ## Run and parse a result
65
+
66
+ `parse()` creates a root run, waits for its outcome, and types `output_parsed` from a Zod or Standard Schema. Pass `scopes` to give a run a per-run allow-list; under a scoped token the list must stay inside the token's ceiling, and omitting it gives the run the ceiling.
67
+
68
+ ```ts
69
+ import Crouter from '@north-light/sdk';
70
+ import { z } from 'zod';
71
+
72
+ const client = new Crouter();
73
+ const run = await client.nodes.parse({
74
+ prompt: 'Read package.json and return its name and version.',
75
+ cwd: '/absolute/path/to/project',
76
+ scopes: ['crtr:llm', 'crtr:files:read:user:.'],
77
+ output_schema: z.object({ name: z.string(), version: z.string() }),
78
+ });
79
+
80
+ if (run.kind === 'result') console.log(run.output_parsed.name, run.output_parsed.version);
81
+ else if (run.reason === 'declined') console.warn(run.declined?.reason);
82
+ else console.error(run.reason, run.detail);
83
+ ```
84
+
85
+ ## Stream a run
86
+
87
+ `nodes.stream()` creates a run and opens its event stream. `followActivity()` turns tool-call events into snapshots for an activity view. Disconnecting or calling `stream.abort()` stops the stream, not the run.
88
+
89
+ ```ts
90
+ import { followActivity } from '@north-light/sdk';
91
+
92
+ const stream = client.nodes.stream({
93
+ prompt: 'Inspect the repository and report the failing tests.',
94
+ cwd: '/absolute/path/to/project',
95
+ });
96
+
97
+ for await (const steps of followActivity(stream)) {
98
+ renderActivity(steps);
99
+ }
100
+
101
+ const outcome = await stream.finalOutcome();
102
+ console.log(outcome.kind);
103
+ ```
104
+
105
+ ## Follow the reply to a message
106
+
107
+ On a run, `runs.reply(runId, sent)` follows the turn that answers one `runs.message` and ends when that turn completes. `turn.completed.error` reports a refused (`content_refused`) or failed (`model_error`) model call.
108
+
109
+ ```ts
110
+ const sent = await client.runs.message(runId, 'Hello');
111
+ const text = await client.runs.reply(runId, sent).text();
112
+ ```
113
+
114
+ To answer a first message in the run's first turn, pass it to `runs.start`: `message` is stored with the run and always joins the first turn as context ahead of `prompt`, and the result's `message` is what `runs.reply` takes. (A `runs.message(id, text, {start_turn: false})` sent after `runs.start` joins the first turn only if it is stored before the run claims that turn's messages.)
115
+
116
+ `runs.message(id, text, {idempotencyKey})` sends an `Idempotency-Key` (a fresh `crypto.randomUUID()` per call, reused across the SDK's own retries). The daemon delivers a key once for 24 hours and returns the original result on replay; the same key with a different body fails with `409 idempotency_conflict`. Pass your own key, derived from your message id, to dedupe across process restarts.
117
+
118
+ ```ts
119
+ const run = await client.runs.start({prompt: instructions, message: 'Hello'});
120
+ const {text, ended, error} = await client.runs.reply(run.run_id, run.message!).collect({onDelta: (delta) => send(delta)});
121
+ // ended: 'completed' | 'error' (see error) | 'waiting_on_user' | 'settled' (see outcome)
122
+ ```
123
+
124
+ `collect` (and `text({onDelta})`) passes each streamed piece to `onDelta`, starting a later assistant message with a blank line, and resolves to the trimmed messages joined by a blank line. The raw `RunReplyEvent` iterator stays available.
125
+
126
+ A run working in the background reports what it is doing on `runs.get(runId).activity` (`starting`, `thinking`, `tool` with `tool.name` and `tool.summary`, `writing`, or `between_turns`; `null` once it is no longer `running`), so a polling page shows progress without reading `runs.trace`.
127
+
128
+ `runs.listAll(filters)` and `memory.listAll(params)` (the person's knowledge and preference documents the caller can read: `public` by default, every privacy level with `crtr:memory:manage:user`) iterate every item across pages with `for await`, fetching the next page only as you go. `runs.delete(runId)` deletes a running run too — it stops the run's turns and sandboxes itself, so there is no need to `cancel` first; deleting a run that is already gone throws `NotFoundError`.
129
+
130
+ ## Read files and run bash
131
+
132
+ File paths and the bash working directory are absolute. `bash.run()` returns non-zero exits as values.
133
+
134
+ ```ts
135
+ const source = await client.files.read('/absolute/path/to/project/package.json');
136
+ const command = await client.bash.run({
137
+ command: 'npm test',
138
+ cwd: '/absolute/path/to/project',
139
+ timeout_s: 60,
140
+ });
141
+
142
+ console.log(source.content, command.exit_code);
143
+ ```
144
+
145
+ ## PostgreSQL connection store (Node)
146
+
147
+ For a multi-process OAuth app, install `pg` in the app (`npm install pg`) and import the optional `@north-light/sdk/stores/postgres` subpath; the SDK's main entry never loads `pg`. `new PostgresConnectionStore(pool, { table: 'connection' })` implements `load`, `save`, `lock`, `remove(userId, refreshToken)`, and `listStale(before: Date)`. Pass it as `new OAuth2Client({..., store})`. Use one shared database and the same table for all workers. The lock keeps one PostgreSQL transaction and client open across the entire refresh callback (including the token request), so provision the pool for concurrent refreshes and avoid a transaction timeout shorter than the request. The table name accepts one or two lowercase SQL identifiers (schema.table), never SQL fragments.
148
+
149
+ Create the table before using the store (or adapt this schema in your migration):
150
+
151
+ ```sql
152
+ CREATE TABLE connection (
153
+ user_id text PRIMARY KEY,
154
+ runtime_url text NOT NULL,
155
+ refresh_token text NOT NULL,
156
+ grant_id text NOT NULL,
157
+ access_token text NOT NULL,
158
+ access_token_expires_at timestamptz NOT NULL,
159
+ id_token text,
160
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
161
+ );
162
+ CREATE INDEX connection_updated_at_idx ON connection (updated_at, user_id);
163
+ ```
164
+
165
+ `save` upserts all fields and sets `updated_at` to the database clock. `listStale(before)` selects connections with `updated_at < before`, oldest first; it is a **last save** timestamp, not necessarily last successful refresh if an app also calls `save` for another reason. For idle-token maintenance, schedule `oauth.refreshIdleConnections({olderThanMs: 30 * 24 * 60 * 60 * 1000})` (for example, daily). It selects stale connections, refreshes under the store lock, reloads there to avoid rotating an already-used token, saves a rotated connection, and reports `{refreshed, refused, failures}`. A connection the directory refuses goes to the client's `onRefusal(refusal)` and is then removed (`remove` deletes the row only while it still holds the refused token); `refusal.kind` is `'removed'` (`grant_removed`: the runtime deleted the app's runs; delete what you store for the person), `'paused'` (`grant_suspended`: nothing was deleted; keep the data until they sign in again), or `'reconnect'` (`refresh_token_expired`, `refresh_token_reused`, `grant_revoked`: nothing was deleted; ask them to sign in again). `refusalOf(error)` returns the same `Refusal` from a refused call's error. Load the signing key `crouter-sdk keygen` wrote with `privateKey: await privateKeyFromFile('local/app-key.json')` (Node), or check one from an environment variable with `parsePrivateJwk(text)`; both refuse anything but a private JWK with a `kid`. The SDK does not start a timer. `listStale` returns connections, not timestamps, so a worker needing a strict cutoff recheck must maintain that policy separately. The table contains credentials: restrict database access, encrypt backups, and delete a row when its user disconnects. PostgreSQL `timestamptz` must be returned as a JavaScript `Date` (the `pg` default parser).
166
+
167
+ ## Example application
168
+
169
+ See the complete [localhost SDK demo](https://github.com/Northlight-Systems/crouter/tree/main/examples/localhost-demo) for streaming, structured output, and an HTTP plugin in one local page.
170
+
171
+ ## Reference
172
+
173
+ The [SDK guide](https://docs.crouter.ai/docs/sdk) covers [client construction](https://docs.crouter.ai/docs/sdk/client), [nodes and scopes](https://docs.crouter.ai/docs/sdk/nodes), [streaming](https://docs.crouter.ai/docs/sdk/streaming), [files](https://docs.crouter.ai/docs/sdk/files), [bash](https://docs.crouter.ai/docs/sdk/bash), [Docker](https://docs.crouter.ai/docs/sdk/docker), [errors](https://docs.crouter.ai/docs/sdk/errors), and the complete [resource map](https://docs.crouter.ai/docs/sdk/resources).
174
+
175
+ `@north-light/sdk/errors` exports `errorCodes`/`ErrorCode` (the daemon's codes), `sdkErrorCodes`/`SdkErrorCode` (the codes the SDK raises itself, such as `oauth_state_mismatch`; `CrouterError.code` is typed with them), and `mapError`, which turns a plain `APIError` into its status class (`NotFoundError`, …) for app tests.
176
+
177
+ The SDK re-exports its public DTO types, so you do not also install `@north-light/api`.
178
+
179
+ ## Related
180
+
181
+ - [`@north-light/api`](https://www.npmjs.com/package/@north-light/api): the `/v1` contract this client is built on.
182
+ - [`@north-light/env-docker`](https://www.npmjs.com/package/@north-light/env-docker): start a `crtrd` container and get a `Connection` to pass to `new Crouter(...)`.
183
+ - [`@north-light/plugin`](https://www.npmjs.com/package/@north-light/plugin): expose your own commands to agents as `crtr` commands.
184
+ - [Main repository](https://github.com/Northlight-Systems/crouter): the `crtr` CLI, the `crtrd` daemon,.
185
+
186
+ ## License
187
+
188
+ Proprietary. Copyright (c) 2026 Northlight Systems. All rights reserved. See `LICENSE`.
@@ -0,0 +1,176 @@
1
+ import { type HealthDTO, type MessageResultDTO, type NodeDetailDTO, type ListNodesQuery, type NodeOutcomeDTO, type NodeOutcomeResponseDTO, type NodeSummaryDTO, type ProfileDTO, type ReportDTO, type ReportsQuery, type StatusDTO } from '@north-light/api';
2
+ import { Bash } from './resources/bash.js';
3
+ import { Canvas } from './resources/canvas.js';
4
+ import { Crons } from './resources/crons.js';
5
+ import { CustomObjects } from './resources/custom-objects.js';
6
+ import { Attachments } from './resources/attachments.js';
7
+ import { Files } from './resources/files.js';
8
+ import { Human } from './resources/human.js';
9
+ import { Models } from './resources/models.js';
10
+ import { NodesResource } from './resources/nodes.js';
11
+ import { NodeStream } from './resources/node-stream.js';
12
+ import { Questions } from './resources/questions.js';
13
+ import { Providers } from './resources/providers.js';
14
+ import { Runs } from './resources/runs.js';
15
+ import { Shares } from './resources/shares.js';
16
+ import { StructuredRequests } from './resources/structured-requests.js';
17
+ import { Memory } from './resources/memory.js';
18
+ import { Uploads } from './resources/uploads.js';
19
+ import type { AuthStatus, AuthStatusParams, CancelParams, EnsureProfileParams, MessageParams, NodeCreateParams, NodeEventsOptions, NodeOutcomeOptions, OutputSchema, ParsedOutcome, RequestOptions, SchemaOutput } from './types.js';
20
+ import type { AppProfile } from './resources/runs.js';
21
+ type CoreNodes = {
22
+ create: (params: NodeCreateParams, options?: RequestOptions) => Promise<NodeDetailDTO>;
23
+ retrieve: (id: string, options?: RequestOptions) => Promise<NodeDetailDTO>;
24
+ list: (query?: ListNodesQuery, options?: RequestOptions) => Promise<NodeSummaryDTO[]>;
25
+ outcome: (id: string, options?: NodeOutcomeOptions) => Promise<NodeOutcomeResponseDTO>;
26
+ waitForOutcome: (id: string, options?: RequestOptions) => Promise<NodeOutcomeDTO>;
27
+ createAndWait: (params: NodeCreateParams, options?: RequestOptions) => Promise<NodeOutcomeDTO>;
28
+ parse: <TSchema extends OutputSchema>(params: NodeCreateParams & {
29
+ output_schema: TSchema;
30
+ }, options?: RequestOptions) => Promise<ParsedOutcome<SchemaOutput<TSchema>>>;
31
+ message: (id: string, body: string | MessageParams, options?: RequestOptions) => Promise<MessageResultDTO>;
32
+ cancel: (id: string, body?: CancelParams, options?: RequestOptions) => Promise<unknown>;
33
+ interrupt: (id: string, options?: RequestOptions) => Promise<unknown>;
34
+ stream: (params: NodeCreateParams, options?: RequestOptions) => NodeStream;
35
+ events: (id: string, options?: NodeEventsOptions) => NodeStream;
36
+ reports: {
37
+ list: (id: string, query?: ReportsQuery, options?: RequestOptions) => Promise<ReportDTO[]>;
38
+ };
39
+ };
40
+ /** Connection settings for a Crouter daemon. `headers` lets a Docker environment's
41
+ * `connection()` result pass directly to this constructor. */
42
+ export interface CrouterOptions {
43
+ /** `http(s)://host:port` of a daemon TCP listener. Defaults to `CRTR_BASE_URL`. */
44
+ baseURL?: string;
45
+ /** Unix socket path. Node only. Defaults to `CRTR_SOCKET`, else `$CRTR_HOME/crtrd.sock`, else `~/.crouter/canvas/crtrd.sock`. */
46
+ socketPath?: string;
47
+ /** Sent as `Authorization: Bearer <token>`. Defaults to `CRTRD_TOKEN`. A unix-socket daemon ignores it. */
48
+ token?: string;
49
+ /** Supplies a directory token per request, including reconnects. Mutually exclusive with token. */
50
+ tokenSource?: () => Promise<string>;
51
+ /** Refreshes a connection-backed token once after a 401. */
52
+ onUnauthorized?: () => Promise<void>;
53
+ /** Per-request wall clock in milliseconds. Defaults to 30000. Does not apply to a stream. */
54
+ timeout?: number;
55
+ /** Transient-failure retries. Defaults to 2. Never applied to `POST` or `PATCH`. */
56
+ maxRetries?: number;
57
+ /** Merged into every request. */
58
+ defaultHeaders?: Record<string, string>;
59
+ /** Merged after `defaultHeaders`; the `Authorization` generated from `token` still wins. */
60
+ headers?: Record<string, string>;
61
+ /** Transport override, for proxies and instrumentation. */
62
+ fetch?: typeof fetch;
63
+ /** On a cold socket, run `crtr sys daemon start` and retry once. Node only. Defaults to true for a socket, false for `baseURL`. */
64
+ autostart?: boolean;
65
+ }
66
+ /**
67
+ * The client, and the only class an application constructs. Each namespace below wraps a
68
+ * family of daemon routes; `request` is the escape hatch for a route with no wrapper.
69
+ */
70
+ export declare class Crouter {
71
+ /** Create, inspect, message, stream, and wait on nodes. */
72
+ readonly nodes: NodesResource & CoreNodes;
73
+ /** Run one command in an absolute working directory. */
74
+ readonly bash: Bash;
75
+ /** Canvas-wide views: attention, snapshot, roster, dashboard, prune, and history. */
76
+ readonly canvas: Canvas;
77
+ /** Scheduled commands. */
78
+ readonly crons: Crons;
79
+ /** Durable structured requests with deadlines and one settlement. */
80
+ readonly structuredRequests: StructuredRequests;
81
+ /** Register, publish, receive, and acknowledge custom canvas objects. */
82
+ readonly customObjects: CustomObjects;
83
+ /** Human requests and the human inbox. */
84
+ readonly human: Human;
85
+ /** Model credentials and model configuration. */
86
+ readonly models: Models;
87
+ /** Agent profiles. */
88
+ readonly profiles: {
89
+ ensure: (name: string, params?: EnsureProfileParams, options?: RequestOptions) => Promise<ProfileDTO>;
90
+ retrieve: (name: string, options?: RequestOptions) => Promise<ProfileDTO>;
91
+ /** The profiles an app may start runs with (app listener only): its own, and those of other apps its grant covers. `default` marks its default profile. */
92
+ list: (options?: RequestOptions) => Promise<{
93
+ profiles: AppProfile[];
94
+ }>;
95
+ };
96
+ /** Daemon status and health. */
97
+ readonly system: {
98
+ status: (options?: RequestOptions) => Promise<StatusDTO>;
99
+ health: (options?: RequestOptions) => Promise<HealthDTO>;
100
+ };
101
+ /** Whether this client can reach a daemon that can run a model. */
102
+ readonly auth: {
103
+ status: (params?: AuthStatusParams, options?: RequestOptions) => Promise<AuthStatus>;
104
+ };
105
+ /** Read, write, and list absolute host paths. */
106
+ readonly files: Files;
107
+ readonly runs: Runs;
108
+ /** Uploads to runtime storage, for files a run prompt or message names (app listener only). */
109
+ readonly uploads: Uploads;
110
+ /** Signed links to files a run received as attachments (app listener only). */
111
+ readonly attachments: Attachments;
112
+ /** Public share links to files (app listener only). */
113
+ readonly shares: Shares;
114
+ /** Questions agents in runs ask the user (app listener only). */
115
+ readonly questions: Questions;
116
+ /** Read the documents the person owns (`store: 'user'`): an app sees their `public` documents, and every privacy level with a `crtr:memory:manage:user` grant. */
117
+ readonly memory: Memory;
118
+ /** Scope-filtered provider tools and daemon-mediated calls. */
119
+ readonly providers: Providers;
120
+ /** The caller's grant. With `wait` (1–25 s) and `since` (a `version` from an earlier answer), the runtime holds the
121
+ * read until the grant's `version` differs from `since` or `wait` seconds pass; the request timeout is extended by
122
+ * `wait`. To follow many people's grants, use `oauth.watchGrants`. */
123
+ readonly grant: {
124
+ get: (options?: RequestOptions & {
125
+ wait?: number;
126
+ since?: string;
127
+ }) => Promise<import('@north-light/api').GrantGetDTO>;
128
+ };
129
+ readonly health: {
130
+ get: (options?: RequestOptions) => Promise<{
131
+ status: 'ok';
132
+ api_version: string;
133
+ }>;
134
+ };
135
+ /** The caller's month-to-date spend (`usage.get`): user-paid model and provider usage, app-paid usage, the grant's
136
+ * `spend_cap`, and `reset_at`. Once user-paid spend reaches `spend_cap`, user-paid model calls answer `cap_exhausted`
137
+ * (a `RateLimitError`, status 402, `userAction: 'raise_cap'`) until `reset_at`. `month` is `YYYY-MM` (UTC; default: current). */
138
+ readonly usage: {
139
+ get: (params?: {
140
+ month?: string;
141
+ }, options?: RequestOptions) => Promise<import('@north-light/api').SpendUsageDTO>;
142
+ };
143
+ private readonly eventFetch;
144
+ private readonly bearerToken;
145
+ private connectionToken;
146
+ private readonly tokenSource;
147
+ private readonly onUnauthorized;
148
+ private readonly client;
149
+ private readonly timeout;
150
+ private readonly baseURL;
151
+ private readonly socketPath;
152
+ constructor(options?: CrouterOptions);
153
+ /** Establish NDJSON through the JSON client's cold-socket/retry transport; leave the live body unread. */
154
+ private openCustomDeliveries;
155
+ private openRunEvents;
156
+ /** `GET /v1/files/download` as a raw fetch: bytes are not JSON, so it bypasses the JSON client but
157
+ * still goes through `call()`, which supplies the connection token and refreshes it once on a 401. */
158
+ private openDownload;
159
+ /** Sends one request to any daemon route, for routes the namespaces above do not wrap. */
160
+ request<T>(method: string, path: string, body?: unknown, options?: RequestOptions): Promise<T>;
161
+ private authStatus;
162
+ private stream;
163
+ private events;
164
+ /** Opening a stream under the call's deadline: the open (token hook included) is abandoned and aborted at
165
+ * `deadlineAt`. Once open, a stream has no deadline: it lives until it ends or `signal` aborts. */
166
+ private openWithin;
167
+ private outcome;
168
+ private waitForOutcome;
169
+ private createAndWait;
170
+ private parse;
171
+ /** Runs `operation` with the connection token, refreshing it once after a 401. `options` carries the call's one
172
+ * deadline (resolved by `deadline`): the token fetch, the refresh and every attempt share it, and `operation`
173
+ * receives the options with the deadline resolved. */
174
+ private call;
175
+ }
176
+ export {};