@north-light/cli 0.3.429 → 0.3.431
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.
- package/dist/builtin-memory/crouter-sdk/README.md +2 -2
- package/dist/builtin-memory/crouter-sdk/client.md +4 -4
- package/dist/builtin-memory/crouter-sdk/error-envelope.md +3 -3
- package/dist/builtin-memory/crouter-sdk/getting-started.md +2 -2
- package/dist/builtin-memory/crouter-sdk/guides/README.md +1 -1
- package/dist/builtin-memory/crouter-sdk/guides/{apps-on-crouter-cloud.md → apps-on-northlight.md} +1 -1
- package/dist/builtin-memory/crouter-sdk/guides/apps-with-many-users.md +3 -3
- package/dist/builtin-memory/crouter-sdk/guides/typed-extraction.md +1 -1
- package/dist/builtin-memory/crouter-sdk/release-notes.md +2 -2
- package/dist/builtin-memory/crouter-sdk/resources.md +1 -1
- package/dist/builtin-memory/crouter-sdk/testing.md +3 -3
- package/dist/builtin-memory/internal/plugins.md +1 -1
- package/dist/clients/attach/viewer.js +4 -4
- package/dist/clients/inbox/tui/input.js +1 -1
- package/dist/clients/inbox/tui/page-body.js +1 -1
- package/dist/clients/inbox/tui/render.js +2 -2
- package/dist/commands/node/lifecycle.js +1 -1
- package/dist/commands/sys/setup-core.d.ts +1 -1
- package/dist/commands/sys/setup-core.js +3 -3
- package/dist/core/command.d.ts +1 -1
- package/dist/core/command.js +1 -1
- package/dist/core/model-auth/flows.d.ts +1 -1
- package/dist/core/providers/call.js +1 -1
- package/dist/core/runtime/broker-protocol.d.ts +2 -2
- package/dist/daemon/api/bridge.d.ts +1 -1
- package/dist/daemon/reconcilers/live-obligation.d.ts +1 -1
- package/dist/launcher/users.js +4 -4
- package/dist/pi-extensions/canvas-review-boundary.d.ts +1 -1
- package/docs/release-local.md +1 -1
- package/docs/sdk/README.md +2 -2
- package/docs/sdk/client.md +4 -4
- package/docs/sdk/error-envelope.md +2 -2
- package/docs/sdk/getting-started.md +2 -2
- package/docs/sdk/guides/README.md +1 -1
- package/docs/sdk/guides/{apps-on-crouter-cloud.md → apps-on-northlight.md} +2 -2
- package/docs/sdk/guides/apps-with-many-users.md +3 -3
- package/docs/sdk/guides/typed-extraction.md +1 -1
- package/docs/sdk/release-notes.md +2 -2
- package/docs/sdk/resources.md +1 -1
- package/docs/sdk/testing.md +3 -3
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +2 -2
- package/runtime.lock.json +12 -12
|
@@ -28,7 +28,7 @@ if (run.kind === 'result') console.log(run.output_parsed.root_cause);
|
|
|
28
28
|
|
|
29
29
|
## Go live with an app key
|
|
30
30
|
|
|
31
|
-
Once you have installed the SDK and tried the local flow in [[crouter-sdk/getting-started]], build against production: [[crouter-sdk/guides/apps-on-
|
|
31
|
+
Once you have installed the SDK and tried the local flow in [[crouter-sdk/getting-started]], build against production: [[crouter-sdk/guides/apps-on-northlight]] takes you from signing up at `https://account.northlight.ai` and joining your laptop (`crtr sys join`) to a running app on your laptop, registered with `crtr cloud apps register`. Generate the key and pull the settings with:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
npx @north-light/sdk keygen --app <client id>
|
|
@@ -85,7 +85,7 @@ The directory rejects the key until its public JWK is added to the app. To chang
|
|
|
85
85
|
| [[crouter-sdk/docker]] | `start()`, `attach()`, `connection()` from `@north-light/env-docker` |
|
|
86
86
|
| [[crouter-sdk/testing]] | `FakeCloud` from `@north-light/sdk/testing`: a fake directory and runtime your real `OAuth2Client` and `Crouter` talk to through `fetch` |
|
|
87
87
|
| [[crouter-sdk/release-notes]] | Behavior changes an existing app must act on, newest first |
|
|
88
|
-
| [[crouter-sdk/guides/apps-on-
|
|
88
|
+
| [[crouter-sdk/guides/apps-on-northlight]] | Building and registering an app against production (joining a laptop, `crtr cloud apps` registration, keys, env file, scopes, running locally, the `crtr cloud apps` commands); typed results from app runs with `runs.parse`, declines, bounding a run, `run_idle`, and waiting on a provider your app requires |
|
|
89
89
|
| [[crouter-sdk/guides/apps-with-many-users]] | Per-person runtime connections, app-owned user access, privacy, and spending |
|
|
90
90
|
|
|
91
91
|
## Phases
|
|
@@ -210,7 +210,7 @@ watcher.nudge();
|
|
|
210
210
|
await watcher.stop();
|
|
211
211
|
```
|
|
212
212
|
|
|
213
|
-
- **`users()`** returns the
|
|
213
|
+
- **`users()`** returns the Northlight user ids whose grant the app follows, read from its own rows. The watcher calls it at `start()`, every `sweepMs` (default 30 000), after each delivery, and on `nudge()`. A user it no longer returns is forgotten: no further reads, and a user who comes back is delivered their current grant again. Each followed person holds one request on their runtime per turn, so return only people whose change the app will act on.
|
|
214
214
|
- **Each turn** is one `grant.get` on `oauth.client(userId)`; then the user goes to the back of the queue, so with more followed users than `concurrency` (default 50) every user still gets a turn in round-robin order. A user whose last reading was delivered reads `grant.get({wait, since: version})` (`wait` integer 1–25, default 25): the runtime holds the read until the grant's `version` changes or `wait` seconds pass. A user with nothing delivered yet (their first turn, or after `onChanged` threw) reads at once.
|
|
215
215
|
- **`onChanged({userId, grant, previous})`** is level-triggered. The first event for a user in a process carries the current grant and `previous: null`, so a restart delivers current state again; later events carry the grant last delivered as `previous`. Delivery is at least once per `(userId, version)` and never repeated for an unchanged `version`; make the handler idempotent (guard the write on the row still waiting).
|
|
216
216
|
- **If `onChanged` throws**, the same version is delivered again after 5 s, doubling to 5 min, and the error goes to `onError`. A transient runtime error (5xx, `runtime_starting`, a router 504, a network failure), or a runtime 401 `grant_revoked` the client's one forced refresh did not clear, backs off the same way. An answer without `version` (a runtime older than 0.3.400) is reported and backs off. A missing connection (`not_connected`) or a refused one (which `onRefusal` already handled, once) drops that user and reports to `onError`; the next sweep decides again from `users()`.
|
|
@@ -219,7 +219,7 @@ await watcher.stop();
|
|
|
219
219
|
|
|
220
220
|
### Show what a person's month has cost
|
|
221
221
|
|
|
222
|
-
A person's grant caps what your app may spend of their AI subscription each UTC month (`grant.spend_cap`;
|
|
222
|
+
A person's grant caps what your app may spend of their AI subscription each UTC month (`grant.spend_cap`; Northlight sets $50). `usage.get()` answers where the month stands:
|
|
223
223
|
|
|
224
224
|
```ts
|
|
225
225
|
const usage = await runtime.usage.get(); // or {month: '2026-09'}
|
|
@@ -231,9 +231,9 @@ const usage = await runtime.usage.get(); // or {month: '2026-09'}
|
|
|
231
231
|
- **At the cap.** Once `usd_equivalent` reaches `spend_cap`, user-paid model and provider calls answer 402 `cap_exhausted` (a `RateLimitError` with `retryable: false`, `userAction: 'raise_cap'` and `resetAt`) until `reset_at`, the first instant of the next UTC month. A run whose model call is refused ends with outcome reason `cap_exhausted`. The check runs before each call, so the call that crosses the cap completes and the next one is refused. Do not retry; tell the person when the count resets.
|
|
232
232
|
- `spend_cap: null` means the grant is not capped.
|
|
233
233
|
|
|
234
|
-
### Link to the app's settings on
|
|
234
|
+
### Link to the app's settings on Northlight
|
|
235
235
|
|
|
236
|
-
Each person who uses your app has a page on their
|
|
236
|
+
Each person who uses your app has a page on their Northlight account where they change or remove what the app may do. Link to it with the URL the directory advertises; never compose the path yourself:
|
|
237
237
|
|
|
238
238
|
```ts
|
|
239
239
|
const href = await oauth.accountAppUrl(); // e.g. https://<directory>/account/apps/<your client id>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
kind: knowledge
|
|
3
3
|
when-and-why-to-read: When you need App-facing error envelope, this knowledge
|
|
4
|
-
should be read because Contract 2 codes and the HTTP refusal body for
|
|
5
|
-
|
|
4
|
+
should be read because Contract 2 codes and the HTTP refusal body for
|
|
5
|
+
Northlight apps.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# App-facing error envelope
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Northlight's app-facing HTTP endpoints use contract 2's error body. An app's **own** endpoints can use the same shape with `origin: 'app'`. The SDK publishes the fixed code tuples:
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
13
|
import { errorCodes, type ErrorEnvelope } from '@north-light/sdk/errors';
|
|
@@ -176,7 +176,7 @@ An outcome is returned, never thrown — including a decline and a failure. Only
|
|
|
176
176
|
|
|
177
177
|
## Go live with an app key
|
|
178
178
|
|
|
179
|
-
Build against production from your laptop: [[crouter-sdk/guides/apps-on-
|
|
179
|
+
Build against production from your laptop: [[crouter-sdk/guides/apps-on-northlight]] walks the whole path. In short, sign up at `https://account.northlight.ai`, create a join token at `https://account.northlight.ai/account/machines` and run `crtr sys join --directory https://account.northlight.ai --token <token>` on your laptop, register the app with `crtr cloud apps register` using a `http://localhost:<port>` origin and a `http://localhost:<port>/auth/callback` redirect URI while you develop, then generate the key and pull its settings with:
|
|
180
180
|
|
|
181
181
|
```bash
|
|
182
182
|
npx @north-light/sdk keygen --app <client id>
|
|
@@ -187,7 +187,7 @@ npx @north-light/sdk env --app <client id>
|
|
|
187
187
|
|
|
188
188
|
`env` runs `crtr cloud apps get --app-id <client id>` and writes `CROUTER_ISSUER`, `CROUTER_CLIENT_ID`, and `APP_ORIGIN` into `local/app.env` (`--out <path>` writes another file). It updates those three lines in place, keeps every other line and comment, and creates the file with mode `0600` when it doesn't exist. It never writes `CROUTER_KEY_FILE` or anything secret. It prints the values it set and the key file your app will read.
|
|
189
189
|
|
|
190
|
-
Both commands reach your app through this machine's `crtr`, so the machine must be joined to your Northlight account. On one that isn't, they say so, print a join step and exit 2. Against production, [[crouter-sdk/guides/apps-on-
|
|
190
|
+
Both commands reach your app through this machine's `crtr`, so the machine must be joined to your Northlight account. On one that isn't, they say so, print a join step and exit 2. Against production, [[crouter-sdk/guides/apps-on-northlight]] first.
|
|
191
191
|
|
|
192
192
|
An app built on the SDK is configured from four variables:
|
|
193
193
|
|
|
@@ -14,7 +14,7 @@ These recipes turn the SDK namespaces into complete applications: a bounded extr
|
|
|
14
14
|
| [[crouter-sdk/guides/event-driven-assistant]] | Events arrive over time from a webhook, queue, or watcher. | A resident node that wakes for each event. |
|
|
15
15
|
| [[crouter-sdk/guides/fan-out-pipeline]] | One task needs independent research before a synthesis. | An orchestrator's final report. |
|
|
16
16
|
| [[crouter-sdk/guides/human-approval]] | A person must decide before work continues. | A node resumed by an inbox answer. |
|
|
17
|
-
| [[crouter-sdk/guides/apps-on-
|
|
17
|
+
| [[crouter-sdk/guides/apps-on-northlight]] | You are building and registering an app, or it starts runs on a person's runtime and needs typed data back. | A validated result from `runs.parse`, or an explicit decline or `run_idle`. |
|
|
18
18
|
| [[crouter-sdk/guides/apps-with-many-users]] | People interact using separate runtime connections. | App-owned access controls, attribution, and per-person spending. |
|
|
19
19
|
|
|
20
20
|
Start with typed extraction for a request/response job. Use a resident node when the same assistant should react again later. Use an orchestrator only when child work can proceed independently; otherwise keep the composition in your application.
|
package/dist/builtin-memory/crouter-sdk/guides/{apps-on-crouter-cloud.md → apps-on-northlight.md}
RENAMED
|
@@ -7,7 +7,7 @@ when-and-why-to-read: When you are building and registering an app on
|
|
|
7
7
|
transcript is not a data channel.
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Apps on
|
|
10
|
+
# Apps on Northlight
|
|
11
11
|
|
|
12
12
|
This page first walks through [building and registering an app](#build-and-register-an-app) against production with `crtr cloud apps`, then covers [managing it](#manage-an-app-with-crtr-cloud-apps), then runs.
|
|
13
13
|
|
|
@@ -7,13 +7,13 @@ when-and-why-to-read: When you need Apps with many users, this knowledge should
|
|
|
7
7
|
|
|
8
8
|
# Apps with many users
|
|
9
9
|
|
|
10
|
-
An app can bring people together without putting all of their agents or data on one runtime. **Each person's runtime holds that person's agents, memory, files, conversations, AI subscription, phone, and device.** Your app's server holds its user table keyed by the
|
|
10
|
+
An app can bring people together without putting all of their agents or data on one runtime. **Each person's runtime holds that person's agents, memory, files, conversations, AI subscription, phone, and device.** Your app's server holds its user table keyed by the Northlight `sub`, one stored `Connection` per person in a `ConnectionStore` (runtime URL, rotating refresh token, grant id), in-app roles and settings, and data shared between users. Sign in with Northlight is the initial sign-in for every app user, including a visitor. Request the app's grants during sign-in from a person whose runtime your app will use. A visitor who only needs to be recognized signs in with identity only (see [Signing in a visitor](#signing-in-a-visitor)). Northlight permissions decide what your app can do on each person's runtime. Your app decides what its users can do to each other.
|
|
11
11
|
|
|
12
12
|
Keep the connection and refresh token on the server, not in a visitor's browser. The server can call `providers.call` on a stored connection outside any run, even when nobody is present and the person is offline. Access tokens last 10 minutes; refresh tokens rotate on each use and expire after 90 days unused. Give `OAuth2Client` a persistent `ConnectionStore` with a cross-process lock as `store`, reach each person's runtime with `await oauth.client(userId)`, and schedule `oauth.refreshIdleConnections({ olderThanMs: 30 * 24 * 60 * 60 * 1000 })` on a timer. Act on a dead connection in one place, `onRefusal`, as [[crouter-sdk/client]] describes, and delete a person's data only on `grant_removed` (`kind: 'removed'`). Learn when a background run ends with `oauth.watchRuns(...)` instead of a poll loop: see [[crouter-sdk/client]]. See [[crouter-sdk/client]].
|
|
13
13
|
|
|
14
14
|
## Signing in a visitor
|
|
15
15
|
|
|
16
|
-
A visitor who only needs to be recognized, not connected, signs in with identity only. Request `openid`, adding `email` for their email and `profile` for their name and photo, and no runtime scope. The directory shows one line ("Know who you are on
|
|
16
|
+
A visitor who only needs to be recognized, not connected, signs in with identity only. Request `openid`, adding `email` for their email and `profile` for their name and photo, and no runtime scope. The directory shows one line ("Know who you are on Northlight"), writes no grant, and answers with an ID token and an access token usable only at `/userinfo`: no refresh token, grant, or runtime URL. Finish that sign-in with `exchangeIdentity`, not `exchangeCode`:
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
const {url, codeVerifier, state, nonce} = await oauth.authorizeUrl({scopes: ['openid', 'email', 'profile'], state: sessionState});
|
|
@@ -35,7 +35,7 @@ An `Identity` is not a connection. It has no runtime URL, grant, or refresh toke
|
|
|
35
35
|
|
|
36
36
|
When visitor A causes your server to call person B's runtime using **B's connection**, the runtime records the app as `grantee` and B as `sub`. It does not know or record that A caused the call. Even a request outside a run, with nobody present, has this attribution. Keep your own record of the app user and action when you need it; do not send an app-user identity as a runtime principal.
|
|
37
37
|
|
|
38
|
-
A visitor chatting with B's clone starts an app run on **B's runtime and B's AI subscription**, using the app's grant from B. The app rate-limits visitors; B's per-app spend cap is the platform backstop.
|
|
38
|
+
A visitor chatting with B's clone starts an app run on **B's runtime and B's AI subscription**, using the app's grant from B. The app rate-limits visitors; B's per-app spend cap is the platform backstop. Northlight's developer terms allow spending B's connection because of another user's action **only for what B turned on in your app, limited per person**. Northlight records nothing about the other user. B can control the app's spend cap or remove the app.
|
|
39
39
|
|
|
40
40
|
## The app's agent and documents
|
|
41
41
|
|
|
@@ -50,6 +50,6 @@ package @north-light/cli@0.3.332
|
|
|
50
50
|
|
|
51
51
|
Handle every outcome arm. A result contains `output_parsed`; a decline says the agent could not honestly meet the schema; another failure carries its reason and detail. Transport and daemon failures still throw, so let those reach your normal application error handling.
|
|
52
52
|
|
|
53
|
-
**From an app.** An app holding a person's connection does the same thing with `runs.parse({prompt, output_schema})`, which returns the run outcome union (`finalized` with `output_parsed` typed from the schema, `declined` with `details`, `canceled`, `deadline_exceeded`, `runtime_error`). It also covers `run_idle` and questions. See [[crouter-sdk/guides/apps-on-
|
|
53
|
+
**From an app.** An app holding a person's connection does the same thing with `runs.parse({prompt, output_schema})`, which returns the run outcome union (`finalized` with `output_parsed` typed from the schema, `declined` with `details`, `canceled`, `deadline_exceeded`, `runtime_error`). It also covers `run_idle` and questions. See [[crouter-sdk/guides/apps-on-northlight]].
|
|
54
54
|
|
|
55
55
|
This is the right shape for bounded work: one prompt, one answer, and no future message. If a user or external event must return to the same agent later, use a resident node instead. See [[crouter-concepts/nodes-and-the-canvas]] for why an SDK node has durable identity, and [[crouter-concepts/lifecycle-and-wakes]] for the terminal-versus-resident decision.
|
|
@@ -173,7 +173,7 @@ The SDK now sends `Crouter-Minimum-Runtime-Version: <SDK_VERSION>` on every requ
|
|
|
173
173
|
|
|
174
174
|
### `grant.get` dependencies are one `{ state, message?, next }` entry per provider (breaking)
|
|
175
175
|
|
|
176
|
-
`GrantGetDTO.dependencies[provider]` was a bare `SetupState` string; it is now a `ProviderDependency` (exported from `@north-light/sdk` and `@north-light/api`): `{ state, message?, next }`. `state` is the setup state the string used to be. `message` is the provider's own sentence for `pending` and `failed` (its `message_pending` / `message_failed`), so delete any copy of a provider's prose your app hard-codes and show `message` instead. `next` is the absolute URL of the directory's setup page for that provider and your app; link the person there (append `return_to` with your registered redirect origin) instead of building the URL yourself. **Change every read of `dependencies[p]` to `dependencies[p].state`** (or `dependencies[p]?.state` where the entry may be missing), and carry `message` and `next` into your `provider_setup_pending` details. The runtime reads only this shape from the directory's grant sync: a runtime on this release paired with a directory that still sends bare strings reports `dependencies` as `{}`, so roll the directory change with it. See [[crouter-sdk/guides/apps-on-
|
|
176
|
+
`GrantGetDTO.dependencies[provider]` was a bare `SetupState` string; it is now a `ProviderDependency` (exported from `@north-light/sdk` and `@north-light/api`): `{ state, message?, next }`. `state` is the setup state the string used to be. `message` is the provider's own sentence for `pending` and `failed` (its `message_pending` / `message_failed`), so delete any copy of a provider's prose your app hard-codes and show `message` instead. `next` is the absolute URL of the directory's setup page for that provider and your app; link the person there (append `return_to` with your registered redirect origin) instead of building the URL yourself. **Change every read of `dependencies[p]` to `dependencies[p].state`** (or `dependencies[p]?.state` where the entry may be missing), and carry `message` and `next` into your `provider_setup_pending` details. The runtime reads only this shape from the directory's grant sync: a runtime on this release paired with a directory that still sends bare strings reports `dependencies` as `{}`, so roll the directory change with it. See [[crouter-sdk/guides/apps-on-northlight]].
|
|
177
177
|
|
|
178
178
|
## 0.3.393
|
|
179
179
|
|
|
@@ -213,7 +213,7 @@ A runtime on this release requires the `rev` claim in every app access token, so
|
|
|
213
213
|
|
|
214
214
|
### `runs.get` reports what a running run is doing (additive)
|
|
215
215
|
|
|
216
|
-
`RunObject.activity` is `{phase: 'starting' | 'thinking' | 'writing' | 'between_turns'}` or `{phase: 'tool', tool: {name, summary}}` while the run is `running`, and `null` otherwise, so a polling app can show progress from `runs.get` without reading `runs.trace`. `runs.list` entries carry it too. See [[crouter-sdk/guides/apps-on-
|
|
216
|
+
`RunObject.activity` is `{phase: 'starting' | 'thinking' | 'writing' | 'between_turns'}` or `{phase: 'tool', tool: {name, summary}}` while the run is `running`, and `null` otherwise, so a polling app can show progress from `runs.get` without reading `runs.trace`. `runs.list` entries carry it too. See [[crouter-sdk/guides/apps-on-northlight]]. A test double that builds a `RunObject` literal must add `activity`.
|
|
217
217
|
|
|
218
218
|
## 0.3.374
|
|
219
219
|
|
|
@@ -39,7 +39,7 @@ Every namespace exported by the client. Namespaces are camelCase. Verbs are `cre
|
|
|
39
39
|
| `grant` | `get` (`wait`, `since`: hold until `version` changes) | `GET /v1/grant` |
|
|
40
40
|
| `health` | `get` | `GET /v1/health` |
|
|
41
41
|
|
|
42
|
-
`runs`, `uploads`, `attachments`, `shares`, `questions` and the app side of `grant` and `providers` are the application-facing API an app reaches through the app listener; see [[crouter-sdk/guides/apps-on-
|
|
42
|
+
`runs`, `uploads`, `attachments`, `shares`, `questions` and the app side of `grant` and `providers` are the application-facing API an app reaches through the app listener; see [[crouter-sdk/guides/apps-on-northlight]] and [[crouter-sdk/guides/apps-with-many-users]]. `memory` is the person's `public` documents ([[crouter-sdk/memory]]). `system.health` (`/healthz`) is the daemon's liveness check; `health.get` is the app listener's.
|
|
43
43
|
|
|
44
44
|
Action methods keep the product's literal name (`fork`, `revive`, `promote`, `yield`) rather than being renamed into a generic verb. Every request-capable method takes `RequestOptions` as its final argument after its path, body, or query arguments. `RequestOptions` is `{ headers?, signal?, timeout?, maxRetries? }`; stream event options exclude `timeout` and add `after`.
|
|
45
45
|
|
|
@@ -7,7 +7,7 @@ when-and-why-to-read: When you need Testing your app, this knowledge should be
|
|
|
7
7
|
|
|
8
8
|
# Testing your app
|
|
9
9
|
|
|
10
|
-
`@north-light/sdk/testing` exports `FakeCloud`, a fake
|
|
10
|
+
`@north-light/sdk/testing` exports `FakeCloud`, a fake Northlight: the directory (discovery, token refresh, JWKS) and each person's runtime (grant, runs, memory, providers, run notices). It answers through `fetch`. Your app's production path — `new OAuth2Client(...)`, `oauth.client(userId)`, `runs`, `memory`, `grant`, `providers`, `watchRuns`, `watchGrants`, `onRefusal`, `forwardRunEvents`, `verifyRunNotice` — runs against it unchanged. The only differences from production are the `fetch` and `issuer` you pass in.
|
|
11
11
|
|
|
12
12
|
There is no mock `Crouter`. An object typed as `Crouter` would re-implement `RunReply`, `RunStream`, the watchers, retries and error mapping, so your tests would check a copy of the SDK instead of the SDK. FakeCloud fakes only the wire, so every SDK behaviour under test is the one you ship.
|
|
13
13
|
|
|
@@ -42,7 +42,7 @@ Options: `new FakeCloud({clientId, issuer = 'https://directory.test', runtimeUrl
|
|
|
42
42
|
|
|
43
43
|
### Isolated runs
|
|
44
44
|
|
|
45
|
-
The fake stands in for a
|
|
45
|
+
The fake stands in for a Northlight guest, where the Linux root launcher always exists, so `runs.start({isolated: true})` starts a run by default and `run.params.isolated` is `true`. The checks `startRun` makes without the launcher are mirrored: `isolated` must be a boolean, `cwd` is accepted only with `isolated: true` and must be an absolute path inside the run's root folder, `/apps/<clientId>/nodes/<run id>` (else 400 `invalid_request`, `param: cwd`), and `worktree` is refused. Nothing in the fake enforces the sandbox itself (no network, no `files/` mount).
|
|
46
46
|
|
|
47
47
|
`isolatedRuns: 'unavailable'` models a runtime without the launcher, such as a local daemon on a Mac: every isolated start answers 503 `isolated_unavailable` (`param: isolated`, retryable, so `runs.start` sends it three times before throwing). Use it to test your app's handling of that refusal.
|
|
48
48
|
|
|
@@ -97,7 +97,7 @@ The real `OAuth2Client` handles all of it: your `onRefusal` runs with the refusa
|
|
|
97
97
|
|
|
98
98
|
## Testing mode
|
|
99
99
|
|
|
100
|
-
An unverified third-party app is *in testing* on
|
|
100
|
+
An unverified third-party app is *in testing* on Northlight: only its admin and up to 100 named testers can sign in, and anyone else is refused. `cloud.testing` puts the fake's app in that state so your app can test the refusal.
|
|
101
101
|
|
|
102
102
|
```ts
|
|
103
103
|
cloud.user('user:tess').setAccount({ email: 'tess@example.com' }); // the identifiers the account holds
|
|
@@ -96,7 +96,7 @@ The `<plugin-name>` directory IS the plugin. The manifest's `name` field must ma
|
|
|
96
96
|
|
|
97
97
|
## Plugin credentials
|
|
98
98
|
|
|
99
|
-
A local plugin runs as its caller's app, with no plugin identity or home of its own. Its credentials belong in that app's daemon-managed env store (`/runtime/secrets/env/<app>/_app`), not a file under `HOME`; the app home is for dotfiles and tool configuration. Model vendor credentials belong only to the daemon's `/runtime/secrets/auth.json`, and a
|
|
99
|
+
A local plugin runs as its caller's app, with no plugin identity or home of its own. Its credentials belong in that app's daemon-managed env store (`/runtime/secrets/env/<app>/_app`), not a file under `HOME`; the app home is for dotfiles and tool configuration. Model vendor credentials belong only to the daemon's `/runtime/secrets/auth.json`, and a Northlight provider's vendor keys belong to its deployment config. A profile's env store overlays the app layer when that profile belongs to the launched app. Crtr-constructed launch values win last.
|
|
100
100
|
|
|
101
101
|
```json
|
|
102
102
|
"env": {
|
|
@@ -1631,7 +1631,7 @@ ${n}`),this.name="DaemonExitedBeforeReadyError",this.stderrTail=n}},vF=class ext
|
|
|
1631
1631
|
${s}`}catch{return}finally{if(t!==void 0)try{Xai(t)}catch{}}}function Vt(t){return process.env.CRTR_API_SOCKET?z0({autostart:!1,...t?.timeoutMs!==void 0?{timeoutMs:t.timeoutMs}:{}}):WKe()?z0({autostart:!1,...t?.timeoutMs!==void 0?{timeoutMs:t.timeoutMs}:{}}):z0({...t?.timeoutMs!==void 0?{timeoutMs:t.timeoutMs}:{},onColdSocket:async()=>{r0n()},coldStartDiagnostic:sci,coldStartFailure:n0n,coldStartPollWindowMs:3e5})}function l0n(t,e=qS()){let n=t?.scope??"user";if(e){if(t?.canvasName!==void 0)throw ywe("--canvas selects the person's remote canvas targets, which an app's node cannot reach","Omit --canvas; this node reads its own runtime's canvas.");return new SF}let r=t?.canvasName??jxe(n).activeCanvas??null;if(!r)return new SF;let{previewEndpoint:i,relayToken:o}=z3(r,n);return new $x(i,o)}var ici,oci,aci,SF,cc=h(()=>{"use strict";Xfe();LQ();Bx();i0n();NKe();qo();ame();V3();Fr();as();Ss();ici=4096,oci=20;aci=2e3,SF=class{client;rosterCache=null;rosterInFlight=null;constructor(e=Vt()){this.client=e}async roster(){let e=Date.now();return this.rosterCache!==null&&e-this.rosterCache.at<aci?this.rosterCache.index:this.rosterInFlight!==null?this.rosterInFlight:(this.rosterInFlight=this.client.canvasRoster().then(n=>{let r={snapshot:n,subscriptions:new Map,subscribers:new Map};for(let i of n.edges){let o={node_id:i.to_id,active:i.active,created:i.created},s={node_id:i.from_id,active:i.active,created:i.created},a=r.subscriptions.get(i.from_id);a===void 0?r.subscriptions.set(i.from_id,[o]):a.push(o);let c=r.subscribers.get(i.to_id);c===void 0?r.subscribers.set(i.to_id,[s]):c.push(s)}return this.rosterCache={at:Date.now(),index:r},r}).finally(()=>{this.rosterInFlight=null}),this.rosterInFlight)}async orNull(e){try{return await e()}catch(n){if(n instanceof fn&&n.status===404)return null;throw n}}async getNode(e){let n=await this.orNull(()=>this.client.getNode(e));return n===null?null:ume(n)}async getRow(e){let n=await this.orNull(()=>this.client.getNode(e));return n===null?null:ume(n)}async listNodes(e){let n=e?.status,r;if(Array.isArray(n)){let i=new Set(n);r=(await this.client.listNodes()).filter(s=>i.has(s.status))}else n!==void 0?r=await this.client.listNodes({status:n}):r=await this.client.listNodes();return r.map(i=>ume(i))}async browseSnapshot(){let e=await this.client.canvasBrowseCompressed(),n=JSON.parse(rci(e).toString("utf8")),r={subscriptions:new Map,subscribers:new Map};for(let i of n.edges){let o=r.subscriptions.get(i.from_id)??[];o.push({node_id:i.to_id,active:i.active,created:i.created}),r.subscriptions.set(i.from_id,o);let s=r.subscribers.get(i.to_id)??[];s.push({node_id:i.from_id,active:i.active,created:i.created}),r.subscribers.set(i.to_id,s)}return this.rosterCache={at:Date.now(),index:r},n.nodes.map(i=>ume(i))}async panelRoster(){let e=await this.roster();return e.snapshot!==void 0?e.snapshot:(this.rosterCache=null,(await this.roster()).snapshot)}async subscriptionsOf(e){return this.roster().then(n=>n.subscriptions.get(e)??[])}async subscribersOf(e){return this.roster().then(n=>n.subscribers.get(e)??[])}async view(e){let n=new Set([e]),r=[],i=(await this.subscriptionsOf(e)).map(o=>o.node_id);for(;i.length>0;){let o=i.shift();if(!n.has(o)){n.add(o),r.push(o);for(let s of await this.subscriptionsOf(o))n.has(s.node_id)||i.push(s.node_id)}}return r}async ticketCountsForNodes(e){return(await this.client.attentionCounts([...e])).counts}async ticketCountsForView(e){return this.ticketCountsForNodes([e,...await this.view(e)])}async newestReport(e){return(await this.client.getReports(e,{limit:1}))[0]??null}async hasActiveLiveSubscription(e){let n=(await this.subscriptionsOf(e)).filter(r=>r.active);for(let r of n){let i=await this.getRow(r.node_id);if(i&&(i.status==="active"||i.status==="idle"))return!0}return!1}}});function cci(t){return{dir:t.request_dir,id:t.request_id,inboxTicketId:t.ticket_id,kind:"page",title:t.title,subtitle:t.subtitle??"",dialect:t.dialect,placement:t.placement,inbox:t.inbox,steps:t.steps,slotKinds:t.slot_kinds,awaitsResponse:t.awaits_response,source:t.source,emittedAt:t.emitted_at,recommendedOptions:(t.recommended_options??[]).map(e=>({slotId:e.slot_id,optionId:e.option_id,label:e.label})),...t.fast_action===void 0?{}:{fastAction:{kind:t.fast_action.kind,responses:t.fast_action.responses}},state:t.state,...t.answer_digest===void 0?{}:{answerDigest:t.answer_digest}}}function uci(t){return{dir:t.request_dir,id:t.request_id,inboxTicketId:t.ticket_id,kind:"review",title:t.title,subtitle:t.subtitle,blockedSince:t.blocked_since,source:t.source}}function h0(t){return t.kind==="page"?cci(t):uci(t)}function cD(t){return{manifest:hS(t.page),document:t.source_document,progress:t.progress===null?null:t.progress.responses,state:t.state,revision:t.revision}}function d0n(t){let e=t.result;if(!(e===null||e.kind!=="page"))return e.summary.replace(/\s+/g," ").trim()}function CF(t){let e=t.result;return e!==null&&e.kind==="canceled"?"ticket was already canceled":e!==null&&e.kind==="page"?"ticket was already resolved: page submitted":"ticket was already resolved"}function gS(t,e){let n=r=>r.kind==="page"?r.emittedAt:r.blockedSince;return n(e).localeCompare(n(t))||t.id.localeCompare(e.id)}var uD=h(()=>{"use strict";f0()});function IF(t){let e=t.config.label;return typeof e=="string"&&e!==""?e:t.unvalidated===!0?t.kind:t.kind==="options"?"Options":t.kind==="text"?"Text":t.kind==="table"?"Table":t.kind==="cards"?"Cards":t.kind==="chart"?"Chart":t.kind}function cf(t){return!(t.unvalidated===!0||t.kind==="cards"&&t.config.cards===void 0)}function lme(t){if(!cf(t))return[];let e=[];if(t.kind==="options"){let r=t.config;e=r.options.map(i=>({kind:"select",group:"option",id:i.id,label:i.label,...i.description===void 0?{}:{description:i.description},mode:r.mode})),r.allowFreetext===!0&&e.push({kind:"freetext",label:r.freetextLabel??"Something else"})}else if(t.kind==="cards"){let r=t.config;e=(r.cards??[]).map(i=>({kind:"select",group:"card",id:i.id,label:i.subtitle===void 0?i.title:`${i.title} \u2014 ${i.subtitle}`,...i.body===void 0?{}:{description:i.body},mode:r.mode}))}else if(t.kind==="text")e.push({kind:"edit",label:"Edit"}),e.push({kind:"accept",label:"Accept as-is"});else if(t.kind==="table"){let r=t.config;if(r.rowSelect!=="none"){let i=r.columns[0];e.push(...(r.rows??[]).map(o=>({kind:"select",group:"row",id:o.id,label:i===void 0?o.id:String(o.cells[i.id]??o.id),mode:r.rowSelect})))}r.columnSelect!=="none"&&e.push(...r.columns.map(i=>({kind:"select",group:"column",id:i.id,label:i.label,mode:r.columnSelect})))}let n=new Set;return e.map(r=>{if(r.kind!=="select")return r;let i;for(let o of[...r.label.toLowerCase()].filter(s=>/[a-z]/.test(s)))if(!n.has(o)&&!lci.has(o)){i=o;break}if(i===void 0){for(let o=1;o<=9;o++)if(!n.has(String(o))){i=String(o);break}}return i!==void 0&&n.add(i),{...r,...i===void 0?{}:{shortcut:i}}})}function p0n(t,e=!1){if(t==null)return"";let n=String(t).replaceAll("|","\\|").replaceAll(`
|
|
1632
1632
|
`,"<br>");return e&&n!==""?`\`${n.replaceAll("`","\\`")}\``:n}function dme(t){let e=`| ${t.columns.map(r=>p0n(r.label)).join(" | ")} |`,n=`| ${t.columns.map(r=>r.align==="right"?"---:":"---").join(" | ")} |`;return[e,n,...(t.rows??[]).map(r=>`| ${t.columns.map(i=>p0n(r.cells[i.id],i.mono===!0)).join(" | ")} |`)].join(`
|
|
1633
1633
|
`)}function jKe(t,e,n){if(e.id===void 0)return!1;try{return Gyn(t.manifest,{[e.id]:n}),!0}catch{return!1}}function Fx(t,e){return!cf(e)||e.id===void 0||!t.responses.has(e.id)?!1:jKe(t,e,t.responses.get(e.id))}function yS(t){if(t.manifest.slots.some(e=>Qc(e)&&!cf(e)))return!1;try{return qyn(t.manifest,Object.fromEntries(t.responses)),!0}catch{return!1}}function TF(t){switch(t.kind){case"option":return`option:${t.optionId}`;case"row":return`row:${t.rowId}`}}function kF(t){return cf(t)?t.kind==="options"?t.config.options.map(e=>({kind:"option",optionId:e.id})):t.kind==="table"?(t.config.rows??[]).map(e=>({kind:"row",rowId:e.id})):[]:[]}var lci,K3=h(()=>{"use strict";f0();lci=new Set(["c","r","e","a","n","p","q","j","k","u","d"," "])});function Tr(t){return typeof t!="string"?"":t.replace(dci,"")}function Ux(t){return Tr(t).replace(/\s+/g," ").trim()}function Qx(t,e="\u2500"){return t<1?"":e.repeat(t)}function np(t,e){if(e<1)return"";if(Da(t)<=e)return t;let n=[...t],r=0,i="";for(let o of n){let s=Da(o);if(r+s+1>e)break;i+=o,r+=s}return i+"\u2026"}function fme(t,e){let n=t.replace(/\n/g," ").replace(/✅/g,"\u2713").replace(/❌/g,"\u2717").replace(new RegExp("\\p{Emoji_Presentation}","gu"),"");if(e<4)return n.slice(0,e);if(Da(n)<=e)return n;let i=n;for(;Da(i)>e-1&&i.length>0;){let o=i.lastIndexOf(" ",i.length-2);o>e*.4?i=i.slice(0,o):i=i.slice(0,i.length-1)}return i+"\u2026"}function pci(t,e){let n=0,r="";for(let i of t){let o=Da(i);if(n+o>e)break;r+=i,n+=o}return r===""&&t.length>0&&(r=[...t][0]),r}function qg(t,e){if(e<1)return[t];let n=[],r=t.split(`
|
|
1634
|
-
`);for(let i=0;i<r.length;i++){let o=r[i];if(o===""){n.push("");continue}let s=o.split(/[ \t]+/).filter(Boolean),a="";for(let c of s){for(;Da(c)>e;){a&&(n.push(a),a="");let l=pci(c,e);n.push(l),c=c.slice(l.length)}let u=a?`${a} ${c}`:c;Da(u)<=e?a=u:(a&&n.push(a),a=c)}a&&n.push(a)}return n.length>0?n:[""]}function g0(t,e,n){let r=Math.max(0,Math.floor((e-n)/2));if(r===0)return t;let i=" ".repeat(r);return t.map(o=>o===""?"":i+o)}function os(t){return Ie(t)}function fci(t){let e=[],n=0;qKe.lastIndex=0;for(let r=qKe.exec(t);r!==null;r=qKe.exec(t)){for(let i of f0n.segment(t.slice(n,r.index)))e.push({ansi:!1,text:i.segment,width:os(i.segment)});e.push({ansi:!0,text:r[0]}),n=r.index+r[0].length}for(let r of f0n.segment(t.slice(n)))e.push({ansi:!1,text:r.segment,width:os(r.segment)});return e}function g0n(t,e,n){if(n<1)return"";let r=Math.max(0,e),i=r+n,o="",s="",a=!1,c=0;for(let l of fci(t)){if(l.ansi){c<r?o+=l.text:(s+=l.text,a=!0);continue}if(c>=i)break;let d=l.width;if(d===0){c>=r&&(s+=l.text);continue}if(c+d<=r){c+=d;continue}if(c<r){s+=" ".repeat(c+d-r),c+=d;continue}if(c+d>i){s+=" ".repeat(i-c),c=i;break}s+=l.text,c+=d}if(s==="")return"";o!==""&&(s=o+s,a=!0);let u=mci(s);return a?s+u+Pe:s}function mci(t){let e="";GKe.lastIndex=0;for(let n=GKe.exec(t);n!==null;n=GKe.exec(t))e=n[1]===""?"":`\x1B]8;;${n[2]}`;return e}function Ma(t,e){return e<1?"":os(t)<=e?t:g0n(t,0,e)}function mme(t,e,n){if(n<1)return"";let r=os(t);if(r<=n)return t;let i=r-n,o=Math.max(0,Math.min(e,i)),s=o>0,a=o<i,c=n-(s?1:0)-(a?1:0),u=c>0?g0n(t,o+(s?1:0),c):"";return`${s?`${lt}\u2039${Pe}`:""}${u}${a?`${lt}\u203A${Pe}`:""}`}var uf,Pe,Es,lt,m0n,h0n,lD,ra,_s,pme,Y3,dci,qKe,GKe,f0n,y0=h(()=>{"use strict";T$();et();uf="\x1B[",Pe=`${uf}0m`,Es=`${uf}1m`,lt=`${uf}2m`,m0n=`${uf}3m`,h0n=`${uf}31m`,lD=`${uf}32m`,ra=`${uf}33m`,_s=`${uf}36m`,pme=`${uf}90m`,Y3=`${uf}7m`,dci=/\x1b\[[0-9;?]*[a-zA-Z]|\x1b[@-_]|[\x00-\x08\x0B\x0E-\x1F\x7F-\x9F]/g;qKe=/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b_[^\x07\x1b]*(?:\x07|\x1b\\)|\x1b\[[0-9;?]*[a-zA-Z]|\x1b[@-^]/g,GKe=/\x1b\]8;[^;\x07\x1b]*;([^\x07\x1b]*)(\x07|\x1b\\)/g,f0n=new Intl.Segmenter(void 0,{granularity:"grapheme"})});function hme(t,e,n,r){let i=a=>Mde(a,n,r);if(t.dialect==="html")return e===""?[`${lt}HTML page \u2014 open in
|
|
1634
|
+
`);for(let i=0;i<r.length;i++){let o=r[i];if(o===""){n.push("");continue}let s=o.split(/[ \t]+/).filter(Boolean),a="";for(let c of s){for(;Da(c)>e;){a&&(n.push(a),a="");let l=pci(c,e);n.push(l),c=c.slice(l.length)}let u=a?`${a} ${c}`:c;Da(u)<=e?a=u:(a&&n.push(a),a=c)}a&&n.push(a)}return n.length>0?n:[""]}function g0(t,e,n){let r=Math.max(0,Math.floor((e-n)/2));if(r===0)return t;let i=" ".repeat(r);return t.map(o=>o===""?"":i+o)}function os(t){return Ie(t)}function fci(t){let e=[],n=0;qKe.lastIndex=0;for(let r=qKe.exec(t);r!==null;r=qKe.exec(t)){for(let i of f0n.segment(t.slice(n,r.index)))e.push({ansi:!1,text:i.segment,width:os(i.segment)});e.push({ansi:!0,text:r[0]}),n=r.index+r[0].length}for(let r of f0n.segment(t.slice(n)))e.push({ansi:!1,text:r.segment,width:os(r.segment)});return e}function g0n(t,e,n){if(n<1)return"";let r=Math.max(0,e),i=r+n,o="",s="",a=!1,c=0;for(let l of fci(t)){if(l.ansi){c<r?o+=l.text:(s+=l.text,a=!0);continue}if(c>=i)break;let d=l.width;if(d===0){c>=r&&(s+=l.text);continue}if(c+d<=r){c+=d;continue}if(c<r){s+=" ".repeat(c+d-r),c+=d;continue}if(c+d>i){s+=" ".repeat(i-c),c=i;break}s+=l.text,c+=d}if(s==="")return"";o!==""&&(s=o+s,a=!0);let u=mci(s);return a?s+u+Pe:s}function mci(t){let e="";GKe.lastIndex=0;for(let n=GKe.exec(t);n!==null;n=GKe.exec(t))e=n[1]===""?"":`\x1B]8;;${n[2]}`;return e}function Ma(t,e){return e<1?"":os(t)<=e?t:g0n(t,0,e)}function mme(t,e,n){if(n<1)return"";let r=os(t);if(r<=n)return t;let i=r-n,o=Math.max(0,Math.min(e,i)),s=o>0,a=o<i,c=n-(s?1:0)-(a?1:0),u=c>0?g0n(t,o+(s?1:0),c):"";return`${s?`${lt}\u2039${Pe}`:""}${u}${a?`${lt}\u203A${Pe}`:""}`}var uf,Pe,Es,lt,m0n,h0n,lD,ra,_s,pme,Y3,dci,qKe,GKe,f0n,y0=h(()=>{"use strict";T$();et();uf="\x1B[",Pe=`${uf}0m`,Es=`${uf}1m`,lt=`${uf}2m`,m0n=`${uf}3m`,h0n=`${uf}31m`,lD=`${uf}32m`,ra=`${uf}33m`,_s=`${uf}36m`,pme=`${uf}90m`,Y3=`${uf}7m`,dci=/\x1b\[[0-9;?]*[a-zA-Z]|\x1b[@-_]|[\x00-\x08\x0B\x0E-\x1F\x7F-\x9F]/g;qKe=/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b_[^\x07\x1b]*(?:\x07|\x1b\\)|\x1b\[[0-9;?]*[a-zA-Z]|\x1b[@-^]/g,GKe=/\x1b\]8;[^;\x07\x1b]*;([^\x07\x1b]*)(\x07|\x1b\\)/g,f0n=new Intl.Segmenter(void 0,{granularity:"grapheme"})});function hme(t,e,n,r){let i=a=>Mde(a,n,r);if(t.dialect==="html")return e===""?[`${lt}HTML page \u2014 open in Northlight to read this${Pe}`]:i(e);let o=e===""?[]:i(e),s=-1;for(let a of t.slots){t.steps>1&&a.step!==s&&(o.length>0&&o.push(""),o.push(`${Es}Step ${a.step+1}/${t.steps}${Pe}`),s=a.step),o.length>0&&o.push(""),o.push(`${Es}${np(Tr(Ux(IF(a))),n)}${Pe}`);let c=a.config.body;if(typeof c=="string"&&c!==""&&o.push(...i(c)),!cf(a)){o.push(`${lt}${Tr(a.kind)} \u2014 open in Northlight to answer this${Pe}`);continue}if(a.kind==="text")o.push(...i(a.config.initialText));else if(a.kind==="table")o.push(...i(dme(a.config)));else if(a.kind==="cards"){for(let u of a.config.cards??[])if(o.push(` \u2022 ${np(Tr(Ux(u.subtitle===void 0?u.title:`${u.title} \u2014 ${u.subtitle}`)),Math.max(10,n-4))}`),u.body!==void 0)for(let l of qg(Tr(u.body),Math.max(10,n-6)))o.push(` ${lt}${l}${Pe}`)}else if(a.kind==="options"){for(let u of a.config.options)if(o.push(` \u2022 ${np(Tr(Ux(u.label)),Math.max(10,n-4))}`),u.description!==void 0)for(let l of qg(Tr(u.description),Math.max(10,n-6)))o.push(` ${lt}${l}${Pe}`)}else if(a.kind==="chart"){let u=a.config,l=u.title??`${u.x??""} vs ${(u.y??[]).map(d=>d.label??d.field).join(", ")}`;o.push(`${lt}chart \u2014 ${Tr(u.kind??"chart")}: ${Tr(l)}${Pe}`)}}return o}var zKe=h(()=>{"use strict";eS();K3();y0()});function A0n(t){if(t===null||typeof t!="object")return;let e=t.details;if(e===null||typeof e!="object")return;let n=e.crtrPreview;if(n===null||typeof n!="object")return;let r=n;if(r.path!=="human send")return;let i=r.result;if(i===null||typeof i!="object")return;let o=i,s=o.page_id;if(typeof s=="string"&&o.placement==="inline")return{pageId:s}}function hci(t){return t.document_media_type==="text/html"?xF(t.source_document):wF(t.source_document,t.page)}function gci(t){return t===void 0?{}:{answerDigest:t}}var y0n,gme,w0n=h(()=>{"use strict";f0();Yfe();Jfe();cc();uD();zKe();y0();y0n=16;gme=class{constructor(e,n){this.pageId=e;this.openHint=n}pageId;openHint;expanded=!1;generation=0;stamp;snapshot;status="loading";cache;async refresh(){let e;try{e=(await Vt().getHumanRequest(this.pageId)).page}catch{e=void 0}if(e===void 0)return this.settle("unavailable",void 0,void 0);let n=`${e.revision}|${e.state}`;if(this.status==="ready"&&n===this.stamp)return!1;let r;try{r={manifest:e.page,displayMarkdown:hci(e),state:e.state,...e.state==="resolved"?gci(d0n(e)):{}}}catch{return this.settle("unavailable",void 0,n)}return this.settle("ready",r,n)}setExpanded(e){e!==this.expanded&&(this.expanded=e,this.cache=void 0)}render(e){let n=e>0?e:80,r=this.cache;if(r!==void 0&&r.width===n&&r.generation===this.generation&&r.expanded===this.expanded)return r.lines;let i=this.compose(n);return this.cache={width:n,generation:this.generation,expanded:this.expanded,lines:i},i}invalidate(){this.cache=void 0}settle(e,n,r){return e===this.status&&e==="unavailable"?!1:(this.status=e,this.snapshot=n,this.stamp=r,this.generation++,this.cache=void 0,!0)}compose(e){let n=this.snapshot;if(n===void 0){let a=this.status==="loading"?"[page] loading\u2026":"[page] no longer available";return["",` ${lt}${a}${Pe}`,""]}let r=Math.min(Math.max(20,e-4),100),i=["",` ${Es}${_s}${np(Tr(Ux(n.manifest.title)),r)}${Pe}`];if(n.manifest.subtitle)for(let a of qg(Tr(n.manifest.subtitle),r))i.push(` ${lt}${a}${Pe}`);let o=hme(n.manifest,n.displayMarkdown,r,Math.max(20,e-4));if(o.length>0){i.push("");let a=this.expanded||o.length<=y0n?o:o.slice(0,y0n);for(let c of a)i.push(` ${c}`);a.length<o.length&&i.push(` ${lt}\u2026 +${o.length-a.length} lines \u2014 ctrl+o to expand${Pe}`)}let s=this.footerLine(n,r);return s!==void 0&&i.push("",` ${s}`),i.push(""),i}footerLine(e,n){switch(e.state){case"pending":return zfe(e.manifest)?`${ra}\u25B8 awaiting your answer${Pe} ${lt}\u2014 ${Tr(this.openHint())}${Pe}`:`${lt}\u25E6 queued in your inbox \u2014 ${Tr(this.openHint())}${Pe}`;case"resolved":return e.answerDigest===void 0?`${lD}\u2713 answered${Pe}`:`${lD}\u2713 answered${Pe} ${lt}\u2014 ${np(Tr(e.answerDigest),Math.max(10,n-12))}${Pe}`;case"canceled":return`${lt}\u2298 canceled${Pe}`;case"passive":return}}}});function b0n(t){for(let e of yci){let n=e.split(" ");if(n.length<=t.length&&n.every((r,i)=>t[i]===r))return!0}return!1}function _0n(t){let e;for(let[r,i]of Object.entries(xci)){let o=r.split(" ");o.length<=t.length&&o.every((s,a)=>t[a]===s)&&(e===void 0||o.length>e.words)&&(e={words:o.length,cp:i})}if(e!==void 0)return String.fromCodePoint(e.cp);let n=t.length>0?wci[t[0]]:void 0;return n!==void 0?String.fromCodePoint(n):"\u25C6"}function RF(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function yme(t){let e=RF(RF(t)?.details);if(e===void 0)return[];let n=e.crtrPreviews;return(Array.isArray(n)?n:[e.crtrPreview]).flatMap(i=>{let o=RF(i);if(o===void 0||typeof o.path!="string")return[];let s=o.jsonl;return[{path:o.path,result:RF(o.result),jsonl:Array.isArray(s)?s.flatMap(a=>{let c=RF(a);return c===void 0?[]:[c]}):void 0,error:RF(o.error)}]})}function AS(t){return t.result}function eh(t,e){let n=t[e];return typeof n=="string"&&n!==""?n:void 0}function KKe(t,e){return typeof t[e]=="boolean"?t[e]:void 0}function dD(t,e){return typeof t[e]=="number"&&Number.isFinite(t[e])?t[e]:void 0}function Eci(t,e){let n=t[e];return Array.isArray(n)&&n.every(r=>r!==null&&typeof r=="object"&&!Array.isArray(r))?n:void 0}function _ci(t,e){return t.length>e?`${t.slice(0,e).trimEnd()}\u2026`:t}function vci(t,e,n=5){let r=t.map(s=>eh(s,e));if(r.some(s=>s===void 0))return;let i=r.slice(0,n),o=r.length-i.length;return o>0?`${i.join(", ")}, \u2026 ${o} more`:i.join(", ")}function Sci(t){let e=t.error;if(e===void 0)return null;let n=eh(e,"error"),r=eh(e,"message");return n===void 0||r===void 0?null:[{text:n,tone:"error"},{text:_ci(r,160),tone:"muted"}]}function Cci(t){let e=AS(t);if(e===void 0)return null;let n=eh(e,"deleted")??eh(e,"remote");if(n!==void 0)return[{text:n.trim().split(`
|
|
1635
1635
|
`)[0]??"",tone:"warning"}];let r=eh(e,"readMetadata")??eh(e,"object");if(r===void 0)return null;let i=r.split(`
|
|
1636
1636
|
`).filter(o=>o.trim()!==""&&!o.startsWith("<auto-loaded-context")&&!o.startsWith("</auto-loaded-context"));return i.length===0?null:[{text:i[0]},...i.slice(1,bci).map(o=>({text:o,tone:"muted"}))]}function Ici(t,e=!1){return n=>{let r=AS(n),i=r===void 0?void 0:dD(r,"count")??dD(r,"total");return i===void 0?null:i===0&&e?[{text:`PASS \xB7 no ${t}`,tone:"success"}]:[{text:`${i} ${t}`,tone:i===0?"muted":"plain"}]}}function Wx(t,e="items"){return n=>{let r=AS(n);if(r===void 0)return null;let i=Eci(r,e),o=dD(r,"total")??i?.length;if(i===void 0||o===void 0)return null;let s=[{text:`${o} ${t}`,tone:o===0?"muted":"plain"}],a=vci(i,"name");return a!==void 0&&a!==""&&s.push({text:a,tone:"muted"}),s}}function Tci(t){let n=AS(t)?.counts;if(n===null||typeof n!="object"||Array.isArray(n))return null;let r=Object.entries(n);if(r.some(([,s])=>typeof s!="number"))return null;let i=r.reduce((s,[,a])=>s+a,0);if(i===0)return[{text:"PASS \xB7 no pending asks",tone:"success"}];let o=r.filter(([,s])=>s>0).sort((s,a)=>a[1]-s[1])[0];return o===void 0?null:[{text:`${i} asks`,tone:"warning"},{text:`hottest: ${o[0]} (${o[1]})`,tone:"muted"}]}function VKe(t,e,n){return r=>{let i=AS(r);if(i===void 0)return null;let o=KKe(i,t);if(o===void 0)return null;let s=dD(i,"pid")??dD(i,"existing_pid");return[{text:o?`${e}${s===void 0?"":` \xB7 pid ${s}`}`:n,tone:o?"success":"muted"}]}}function kci(t){let e=AS(t);if(e===void 0||eh(e,"page_id")===void 0)return null;let n=KKe(e,"reply");return n===void 0?null:[{text:n?"page sent \u2192 waiting on human":"announcement sent",tone:n?"accent":"success"}]}function Rci(t){let e=AS(t);if(e===void 0)return null;let n=KKe(e,"resolved"),r=eh(e,"job_id");return n===void 0||r===void 0?null:[{text:`${n?"resolved":"not resolved"} ${r}`,tone:n?"success":"warning"}]}function x0n(t){let e=AS(t);if(e===void 0)return null;let n=eh(e,"status");return n===void 0?null:[{text:n,tone:["done","success","submitted","filed"].includes(n)?"success":n==="failed"?"error":"plain"}]}function Dci(t){let e=t.jsonl;if(e===void 0)return null;let n=e.filter(r=>eh(r,"name")!==void 0&&dD(r,"projects_count")!==void 0);return n.length===0&&e.length>0?null:[{text:`${n.length} profile${n.length===1?"":"s"}`},...n.slice(0,5).map(r=>({text:`${eh(r,"name")} \xB7 ${dD(r,"projects_count")} projects`,tone:"muted"}))]}function v0n(t,e=[]){let n=Sci(t);return n!==null?n:Mci.find(({path:i})=>i===t.path)?.run(t,e)??null}var yci,Aci,E0n,th,wci,xci,bci,Mci,J3=h(()=>{"use strict";yci=new Set(["canvas roster","canvas snapshot","node inspect snapshot","node inspect show","sys context sysprompt"]);Aci=61529,E0n=String.fromCodePoint(Aci),th={bash:String.fromCodePoint(61728),read:String.fromCodePoint(61788),write:String.fromCodePoint(61639),edit:String.fromCodePoint(61508)},wci={canvas:61672,capture:61501,device:61705,doc:61485,human:61447,node:61842,pkg:61874,profile:62141,push:61678,"exa-search":61442,surface:61704,sys:61459},xci={"canvas dashboard":61668,"canvas snapshot":61488,"canvas browse":61774,"canvas attention count":62098,"canvas attention list":61498,"canvas attention map":62073,"canvas revive":61473,"node lifecycle revive":61473,"canvas list":61498,"canvas read":61485,"canvas search":61442,"canvas history search":61442,"canvas history grep":61616,"sys daemon start":61515,"sys daemon status":61713,"sys daemon stop":61517,"canvas chord":61441,"surface tmux-spread":61449,"canvas issue new":61832,"canvas prune":61636,"human send":61529,"human review":61508,"human show":61704,"human cancel":61453,"human list":61498,"human resolve":61452,"doc write":61504,"doc edit":61508,"doc history":61914,"doc lint":61770,"node new":61543,"node message send":61664,"node message request":61664,"cron add":61463,"node wait deadline":61463,"node subscription add":61683,"node subscription remove":61942,"node promote":61698,"node yield":62093,"surface node focus":61531,"surface node cycle":61473,"node inspect list":61498,"node inspect show":61550,"node inspect snapshot":61488,"node inspect context":61564,"node lifecycle recycle":61880,"node lifecycle close":61453,"node lifecycle demote":61699,"node config":61459,"cron list":61463,"cron cancel":61534,"pkg plugin install":61465,"pkg plugin remove":61460,"pkg plugin enable":61452,"pkg plugin disable":61534,"pkg plugin update":61473,"pkg plugin list":61498,"pkg plugin show":61550,"pkg market add":61543,"pkg market remove":61460,"pkg market update":61473,"pkg market list":61498,"pkg market browse":61774,"push update":61587,"push final":61726,"exa-search web":61612,"exa-search answer":61557,"exa-search contents":61686,"surface attach to":61926,"sys config get":61465,"sys config set":61504,"sys config path":61563,"sys settings":61459,"sys setup":61613,"sys doctor":61681,"sys context sysprompt":61788,"sys context prompt-review":61442,"sys feedback":61557,"sys update":61473,"sys version":61483,"sys sync":61561};bci=4;Mci=[{path:"canvas read",run:Cci},{path:"canvas list",run:Wx("objects")},{path:"canvas search",run:Wx("hits")},{path:"canvas attention count",run:Ici("pending asks",!0)},{path:"canvas attention list",run:Wx("pending asks")},{path:"canvas attention map",run:Tci},{path:"human send",run:kci},{path:"human list",run:Wx("pending")},{path:"human resolve",run:Rci},{path:"pkg plugin list",run:Wx("plugins")},{path:"pkg market list",run:Wx("marketplaces")},{path:"pkg market browse",run:Wx("plugins")},{path:"canvas dashboard",run:Wx("nodes","rows")},{path:"node inspect list",run:Wx("nodes","nodes")},{path:"sys daemon start",run:VKe("started","started","already running")},{path:"sys daemon status",run:VKe("running","running","not running")},{path:"sys daemon stop",run:VKe("stopped","stopped","was not running")},{path:"sys update",run:x0n},{path:"sys feedback",run:x0n},{path:"profile list",run:Dci}]});var pD,X3,wS=h(()=>{"use strict";pD="/run/crtr/launcher.sock",X3=class extends Error{constructor(n,r){super(r);this.refusal=n}refusal}});import{connect as Oci}from"node:net";async function Ame(t,e=[],n=pD){if(!S0n)throw new Error("Linux launcher client requires the native addon");let r=Oci(n);try{await new Promise((a,c)=>{r.once("connect",a),r.once("error",c)});let i=r._handle?.fd;if(i===void 0||i<0)throw new Error("launcher socket fd unavailable");S0n.sendFds(i,JSON.stringify(t),e);let o=await new Promise((a,c)=>{let u="";r.on("data",l=>{u+=l.toString(),u.includes(`
|
|
1637
1637
|
`)&&a(u.slice(0,u.indexOf(`
|
|
@@ -1705,8 +1705,8 @@ ${e.message}`,["Yes","No"],l=>c({type:"extension_ui_response",id:e.id,confirmed:
|
|
|
1705
1705
|
`)?t.slice(0,-1):t;return`${r}${e}
|
|
1706
1706
|
${i}
|
|
1707
1707
|
${r}
|
|
1708
|
-
`}function Tpi(t,e){let n=e+2,r=o=>Math.max(1,Math.min(o-1,e)),i=t.spans.map(o=>o!==null&&(o[0]<=1||o[1]>=n));return{lines:t.lines,rows:t.rows.map((o,s)=>i[s]===!0?null:o),spans:t.spans.map((o,s)=>o===null||i[s]===!0?null:[r(o[0]),r(o[1])]),blocks:t.blocks.map(o=>({type:o.type,start:r(o.start),end:r(o.end)}))}}function fbn(t,e,n){let r=Hx(t).length;return Tpi(Tde(Ipi(t,e),n),r)}var Spi,Cpi,zYe=h(()=>{"use strict";s6();eS();Spi={".ts":"typescript",".mts":"typescript",".cts":"typescript",".tsx":"tsx",".js":"javascript",".mjs":"javascript",".cjs":"javascript",".jsx":"jsx",".py":"python",".rb":"ruby",".go":"go",".rs":"rust",".java":"java",".c":"c",".h":"c",".cc":"cpp",".cpp":"cpp",".hpp":"cpp",".cs":"csharp",".swift":"swift",".kt":"kotlin",".php":"php",".lua":"lua",".pl":"perl",".sh":"bash",".bash":"bash",".zsh":"bash",".fish":"fish",".sql":"sql",".json":"json",".jsonc":"json",".yaml":"yaml",".yml":"yaml",".toml":"toml",".ini":"ini",".xml":"xml",".html":"html",".htm":"html",".css":"css",".scss":"scss",".less":"less",".vim":"vim",".el":"lisp",".ex":"elixir",".exs":"elixir",".erl":"erlang",".hs":"haskell",".scala":"scala",".dart":"dart",".r":"r",".jl":"julia",".zig":"zig",".tf":"terraform",".proto":"protobuf",".graphql":"graphql",".gql":"graphql",".dockerfile":"dockerfile",".diff":"diff",".patch":"diff",".csv":"text",".txt":"text",".log":"text",".env":"bash",".mk":"makefile"},Cpi=new Set([".md",".markdown",".mdown",".mkd"])});function rhe(t){let e=[],n=new Array(t.lines.length).fill(null);for(let r=0;r<t.lines.length;r++){let i=t.spans[r]??null;if(i===null){let s=t.rows[r]??null,a=s!==null?t.blocks[s]:void 0;if(a===void 0)continue;i=[a.start,a.end]}let o=e[e.length-1];o!==void 0&&o.lastRow===r-1&&o.start===i[0]&&o.end===i[1]?o.lastRow=r:e.push({start:i[0],end:i[1],firstRow:r,lastRow:r}),n[r]=e.length-1}if(e.length===0){e.push({start:t.blocks[0]?.start??1,end:t.blocks[t.blocks.length-1]?.end??1,firstRow:0,lastRow:Math.max(0,t.lines.length-1)});for(let r=0;r<n.length;r++)n[r]=0}return{units:e,rowUnits:n}}function wD(t,e){let n=-1;for(let r=0;r<t.length;r++){let i=t[r];i.start<=e&&i.end>=e&&(n===-1||i.end-i.start<t[n].end-t[n].start)&&(n=r)}if(n!==-1)return n;for(let r=0;r<t.length;r++)if(t[r].start>e)return r;return Math.max(0,t.length-1)}function VYe(t,e){for(let n=0;n<t.length;n++)if(t[n].start===e.start&&t[n].end===e.end)return n;return wD(t,e.start)}function m6(t,e,n){let r=-1,i=-1;if(t.forEach((o,s)=>{o.start<=n&&o.end>=e&&(r===-1&&(r=s),i=s)}),r===-1){let o=wD(t,e);return{lo:o,hi:o}}return{lo:r,hi:i}}var KYe=h(()=>{"use strict"});import{basename as kpi,dirname as mbn,join as Rpi}from"node:path";import{mkdirSync as Dpi,watch as Mpi,writeFileSync as IGs}from"node:fs";function YYe(t){return Rpi(Cs(),"signals",t)}function ihe(t,e){let n=YYe(t);try{Dpi(mbn(n),{recursive:!0,mode:448});let r=Mpi(mbn(n),(i,o)=>{String(o)===kpi(n)&&e()});return()=>r.close()}catch(r){return console.error(`activity-signal: failed to watch "${t}": ${r instanceof Error?r.message:String(r)}`),()=>{}}}var JYe=h(()=>{"use strict";Fr()});function hbn(t){return ihe("review-activity",t)}var gbn=h(()=>{"use strict";JYe()});function ybn(t,e){return{async anchorBase(){let n=await e(()=>Vt().getReviewDocumentBase(t));return{file:n.file,text:n.anchor_base_text,docHash:n.anchor_base_sha256}},async list(){return(await e(()=>Vt().listReviewComments(t,{status:"all"}))).comments.map(Npi)},async create(n){return(await FF(()=>e(()=>Vt().createReviewComment(t,{text:n.text,anchor:{line:n.line,end_line:n.endLine},doc_hash:n.docHash,actor_node_id:null})))).comment.comment_id},async edit(n){await FF(()=>e(()=>Vt().editReviewComment(n.id,{text:n.text,if_revision:n.ifRevision,actor_node_id:null})))},async resolve(n){await FF(()=>e(()=>Vt().resolveReviewComment(n,{actor_node_id:null})))},async reopen(n){await FF(()=>e(()=>Vt().reopenReviewComment(n,{actor_node_id:null})))},async remove(n){await FF(()=>e(()=>Vt().deleteReviewComment(n,{actor_node_id:null})))},async remapRanges(n){await FF(()=>e(()=>Vt().updateReviewCommentRanges(t,{from_doc_hash:n.fromDocHash,to_doc_hash:n.toDocHash,entries:n.entries.map(r=>"detached"in r?{comment_id:r.id,detached:!0}:{comment_id:r.id,anchor:{line:r.anchor.line,end_line:r.anchor.endLine}})})))},async fork(n){let r=await e(()=>Vt().forkReviewComment(n));return{nodeId:r.node_id,cwd:r.cwd}},onChanged(n){return hbn(n)}}}function Npi(t){let e={line:t.anchor.line,endLine:t.anchor.end_line};return{id:t.comment_id,revision:t.revision,...e,lineText:t.anchor_line_text,comment:t.text,status:t.status,authorKind:t.author.kind,createdAt:t.created_at,anchorStatus:t.anchor_state==="detached"?"detached":"live",...t.anchor_state==="detached"?{originalRange:e}:{}}}async function FF(t){try{return await t()}catch(e){throw e instanceof fn&&Ppi(e.code)?new h6(e.code,e.message,e.details):e}}function Ppi(t){return t==="stale_document"||t==="stale_comment"||t==="range_batch_incomplete"||t==="range_batch_stale"}var h6,XYe=h(()=>{"use strict";hp();cc();gbn();h6=class extends Error{code;details;constructor(e,n,r){super(n),this.name="ReviewDocumentError",this.code=e,this.details=r}}});function ohe(t){switch(t){case"active":return 0;case"idle":return 1;case"done":return 2;case"canceled":return 3;case"dead":return 4;default:return 5}}function Abn(t){return t==="active"||t==="idle"}function wbn(t){return t.lifecycle!=="resident"||t.finalized}var she=h(()=>{"use strict"});function g6(){let t=O0();return t!==void 0?{CRTR_HOME:t}:{}}function ZYe(){return{...g6(),CRTR_ATTACH_WAKE_PARKED:"0"}}function ahe(t){let e=dbe();if(e!==null){for(let n of e)if(Rh(n,"@crtr_node")===t)return n}}function xbn(t,e,n,r,i){let o=IC(t,{cwd:n,env:ZYe(),command:`crtr surface attach to ${e}`});if(o===null)return{focused:!1,session:null,inPlace:!1,revived:i};let s=Nb(o);return s!==null&&lK(s.window,"even-horizontal"),tW(o),{focused:!0,session:s?.session??r,inPlace:!1,revived:i}}async function che(t,e,n){let r=n.pane??process.env.TMUX_PANE??my()?.pane;if(r===void 0||r==="")return{focused:!1,session:null,inPlace:!1,revived:!1};let o=(await t.ensureAttach(e,{resume:!0,revive:!0,wakeParked:!1})).revived,s=Nb(r)?.session??null;if(n.inPlace===!0){let c=Rh(r,"@crtr_node"),u=ahe(e);u!==void 0&&u!==r&&Pb(u)&&J0(u);try{hy(r,"@crtr_node","")}catch{}let l=lbe(r),d=c!==void 0&&c!==""?{...ZYe(),CRTR_ATTACH_ROSTER:c}:ZYe(),p=uK({pane:r,cwd:n.cwd,env:d,command:`crtr surface attach to ${e}`});return p&&l!==null&&cbe(l,n.name),{focused:p,session:s,inPlace:!0,revived:o}}if(n.newPane===!0){let c=ahe(e);return c!==void 0&&Pb(c)&&J0(c),xbn(r,e,n.cwd,s,o)}let a=ahe(e);if(a!==void 0){let c=Nb(a);if(c!==null)return gbe(c.session),p1(c.session,c.window),tW(a),{focused:!0,session:c.session,inPlace:!0,revived:o}}return xbn(r,e,n.cwd,s,o)}async function uhe(t,e,n){let r=e.node_id;if(e.kind==="human")throw new af({error:"not_focusable",message:`node ${r} is a human-ask (kind:human), not a conversation \u2014 it has no pi session to focus.`,next:`The pending question is queued for the user; see it with \`crtr human list\`, or retract it with \`crtr human cancel ${r}\`.`});return!Abn(e.status)&&wbn({lifecycle:e.lifecycle,finalized:e.final_report!=null})?{focused:await ube(n.pane,e.cwd,`crtr node inspect transcript ${kn(r)}`),session:null,revived:!1,inPlace:!1}:che(t,r,{cwd:e.cwd,name:e.name,pane:n.pane,...n.newPane===!0?{newPane:!0}:{},...n.inPlace===!0?{inPlace:!0}:{}})}var y6=h(()=>{"use strict";as();she();Bx();Ap()});var bbn=h(()=>{"use strict";Ap();y6();cc()});function Ebn(t){let{companionNodeId:e,cwd:n,callerPane:r}=t;if(!ua())return{ok:!1,reason:"no_tmux"};let o=mbe().filter(l=>l.nodeId===e&&aK(l.pane)).sort((l,d)=>d.stampMs-l.stampMs);if(o.length>0)return{ok:!0,paneId:o[0].pane,origin:"adopted"};if(r===void 0||r==="")return{ok:!1,reason:"no_caller_pane"};let s=cK(r);if(s===null)return{ok:!1,reason:"split_refused"};let a,c;s.cols>=Lpi?(a=!1,c=Math.max(Bpi,Math.round(s.cols*Fpi))):(a=!0,c=Math.max($pi,Math.round(s.rows*Upi)));let u=IC(r,{cwd:n,env:g6(),command:`crtr surface attach to ${e}`,vertical:a,size:c});return u===null?{ok:!1,reason:"split_refused"}:{ok:!0,paneId:u,origin:"opened"}}function _bn(t){let{nodeId:e,cwd:n,splitFrom:r}=t;if(!ua())return{ok:!1,reason:"no_tmux"};if(r===void 0||r==="")return{ok:!1,reason:"no_caller_pane"};let i=cK(r);if(i===null)return{ok:!1,reason:"split_refused"};if(Math.floor(i.cols/2)<Qpi)return{ok:!1,reason:"no_room"};let o=IC(r,{cwd:n,env:g6(),command:`crtr surface attach to ${e}`,vertical:!1,size:Math.floor(i.cols/2)});return o===null?{ok:!1,reason:"split_refused"}:{ok:!0,paneId:o}}function lhe(t){return Pb(t)&&aK(t)}function eJe(t,e){!Pb(t)||Rh(t,"@crtr_node")!==e||J0(t)}var Lpi,Bpi,$pi,Fpi,Upi,Qpi,vbn=h(()=>{"use strict";Ap();bbn();Lpi=99,Bpi=40,$pi=12,Fpi=.42,Upi=.4,Qpi=52});function Cbn(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function Wpi(t){return t!==null&&typeof t=="object"?t:{}}function dhe(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function Hpi(t){return Array.isArray(t)?t.filter(e=>e!==null&&typeof e=="object"&&"anchor"in e&&"text"in e):[]}function tJe(t,e){let n=new Map(e.map(r=>[r.id,r.label]));return t.map(r=>({id:r,label:n.get(r)??r}))}function Ibn(t,e){let n=t.rows?.find(i=>i.id===e),r=t.columns[0];return n===void 0||r===void 0||!Cbn(n.cells,r.id)?e:String(n.cells[r.id])}function jpi(t){let e=t.config.label;return typeof e=="string"&&e!==""?e:t.id??t.kind}function nJe(t,e){return e.kind==="whole"?jpi(t):e.kind==="option"?t.config.options.find(n=>n.id===e.optionId)?.label??e.optionId:Ibn(t.config,e.rowId)}function Sbn(t,e){return Hpi(e.comments).map(n=>({anchor:n.anchor,anchorLabel:nJe(t,n.anchor),text:n.text}))}function qpi(t,e){let n=e===void 0?"unanswered":"answered",r=Wpi(e),i=t.config.label,o={id:t.id,kind:t.kind,...typeof i=="string"&&i!==""?{label:i}:{},state:n};if(t.unvalidated===!0)return{...o,blank:e===void 0,groups:[],comments:[],...e===void 0?{}:{raw:r}};if(t.kind==="options"){let s=t.config,a=typeof r.freetext=="string"&&r.freetext!==""?r.freetext:void 0,c={group:"option",mode:s.mode,total:s.options.length,picked:tJe(dhe(r.selectedOptionIds),s.options)};return{...o,blank:c.picked.length===0&&a===void 0,groups:[c],...a===void 0?{}:{freetext:a},comments:Sbn(t,r)}}if(t.kind==="text"){let s=r,a=typeof s.text=="string"?s.text:"",c=t.config.singleLine===!0;return{...o,blank:c&&a==="",groups:[],text:{value:a,edited:s.edited===!0,...c?{singleLine:!0}:{}},comments:[]}}if(t.kind==="table"){let s=t.config,a=[];return(s.rowSelect==="single"||s.rowSelect==="multi")&&a.push({group:"row",mode:s.rowSelect,total:s.rows?.length??0,picked:dhe(r.selectedRowIds).map(c=>({id:c,label:Ibn(s,c)}))}),(s.columnSelect==="single"||s.columnSelect==="multi")&&a.push({group:"column",mode:s.columnSelect,total:s.columns.length,picked:tJe(dhe(r.selectedColumnIds),s.columns)}),{...o,blank:a.every(c=>c.picked.length===0),groups:a,comments:Sbn(t,r)}}if(t.kind==="cards"){let s=t.config,a=(s.cards??[]).map(u=>({id:u.id,label:u.title})),c={group:"card",mode:s.mode,total:a.length,picked:tJe(dhe(r.selectedCardIds),a)};return{...o,blank:c.picked.length===0,groups:[c],comments:[]}}throw new Error(`slot "${t.id}" kind "${t.kind}" does not accept a response`)}function Tbn(t,e,n){let r=hS(t),i=r.slots.filter(Qc).map(s=>qpi(s,Cbn(e,s.id)?e[s.id]:void 0)),o=i.filter(s=>s.state==="answered");return{title:r.title,...r.subtitle===void 0?{}:{subtitle:r.subtitle},completedAt:n.completedAt,kind:i.length===0?"acknowledgement":"answer",digest:zpi(o),slots:i}}function Gpi(t){return t.picked.length===0?"no selection":t.group==="option"||t.group==="card"?t.picked.map(e=>e.label).join(", "):t.total>0?`${t.picked.length} of ${t.total} ${t.group}s`:`${t.picked.length} ${t.group}${t.picked.length===1?"":"s"}`}function zpi(t){return t.map(e=>{if(e.raw!==void 0)return`${e.kind} response`;if(e.text!==void 0)return e.text.singleLine===!0?e.text.value===""?"empty":e.text.value:e.text.edited?"edited":"unchanged";let n=e.groups.map(Gpi);return e.freetext!==void 0&&n.push(e.freetext),n.join(", ")||"no selection"}).join(" \xB7 ")}var kbn=h(()=>{"use strict";f0()});function Dbn(t){return Tbn(t.manifest,Object.fromEntries(t.responses),{completedAt:""})}function Kpi(t,e){return e.id===void 0?void 0:t.slots.find(n=>n.id===e.id)}function Mbn(t){if(t===void 0||t.state==="unanswered")return"unanswered";if(t.raw!==void 0)return"custom response";let e=t.text!==void 0?[t.text.edited?"edited":"accepted"]:t.groups.map(n=>n.picked.length===0?"none":n.picked.map(r=>r.label).join(", "));return t.freetext!==void 0&&e.push(t.freetext),t.comments.length>0&&e.push(`${t.comments.length} comment${t.comments.length===1?"":"s"}`),e.join("; ")||"answered"}function Rbn(t,e){return nJe(t,e)}function Obn(t,e,n){let r=Math.min(Math.max(20,e-4),120),i=Math.max(20,e-4),o=["",` ${Es}${_s}${Tr(t.manifest.title)}${Pe}`];if(t.manifest.subtitle)for(let p of qg(Tr(t.manifest.subtitle),r))o.push(` ${lt}${p}${Pe}`);if(t.displayMarkdown!==""){o.push("");for(let p of phe(t.displayMarkdown,r,i))o.push(` ${p}`)}else t.manifest.dialect==="html"&&o.push("",` ${lt}HTML page \u2014 open in crouter cloud to read this${Pe}`);let s=t.slots.length>0;s&&o.push(` ${lt}${Qx(r)}${Pe}`,"");let a=Dbn(t),c=-1,u;for(let p=0;p<t.slots.length;p++){let f=t.slots[p];t.manifest.steps>1&&f.step!==c&&(c!==-1&&o.push(""),o.push(` ${Es}Step ${f.step+1}/${t.manifest.steps}${Pe}`),c=f.step);let m=f.id===void 0?void 0:t.responses.get(f.id),g=Qc(f)?Fx(t,f)?`${lD}\u2713${Pe}`:`${lt}\u25CB${Pe}`:`${lt}\xB7${Pe}`,y=p===t.currentIndex?`${_s}\u25B8${Pe} `:" ";p===t.currentIndex&&(u=o.length),o.push(` ${y}${g} ${np(Ux(IF(f)),Math.max(10,e-16))}`),m!==void 0&&o.push(` ${lt}${np(Ux(Mbn(Kpi(a,f))),Math.max(10,e-10))}${Pe}`)}if(t.manifest.slots.some(p=>Qc(p)&&!cf(p))){o.push("");for(let p of qg("This page must be answered in crouter cloud. Leaving it here keeps it in your inbox; x on the list cancels it.",r-2))o.push(` ${ra}${p}${Pe}`)}s&&o.push(""),o.push(` ${lt}${Qx(r)}${Pe}`);let d=!t.manifest.slots.some(Qc)?` ${lt}u/d${Pe} scroll ${lt}q${Pe} dismiss`:` ${lt}enter${Pe} review ${lt}\u2191\u2193/jk${Pe} navigate ${lt}u/d${Pe} scroll ${lt}q${Pe} close`;return Wbn(o,d,t,e,n,r+2,t.followSelection?u:void 0)}function UF(t,e,n){let r=[...t],i=Math.max(0,Math.min(e,r.length)),o=Nbn(t,n),s=0;for(let u=0;u<o.length;u++)o[u].start<=i&&(s=u);let a=o.map((u,l)=>{if(l!==s)return r.slice(u.start,u.end).join("");let d=r.slice(u.start,i).join(""),p=i<u.end?r[i]:" ",f=i<u.end?r.slice(i+1,u.end).join(""):"";return`${d}${Y3}${p}${Pe}${f}`}),c=o[s];return i===c.end&&Da(r.slice(c.start,c.end).join(""))>=n&&(a[s]=r.slice(c.start,c.end).join(""),a.splice(s+1,0,`${Y3} ${Pe}`)),a}function A6(t,e){let n=[...t],r=Math.max(0,Math.min(e,n.length));for(;r>0&&/\s/.test(n[r-1]);)r--;for(;r>0&&!/\s/.test(n[r-1]);)r--;return r}function fhe(t,e){let n=[...t],r=Math.max(0,Math.min(e,n.length));for(;r<n.length&&/\s/.test(n[r]);)r++;for(;r<n.length&&!/\s/.test(n[r]);)r++;return r}function Nbn(t,e){let n=[...t],r=Math.max(1,e),i=[],o=0,s=0;for(let a=0;a<n.length;a++){let c=n[a];if(c===`
|
|
1709
|
-
`){i.push({start:o,end:a}),o=a+1,s=0;continue}let u=Da(c);s+u>r?(i.push({start:o,end:a}),o=a,s=u):s+=u}return i.push({start:o,end:n.length}),i}function w6(t,e,n,r){let i=Nbn(t,r),o=Math.max(0,Math.min(e,[...t].length)),s=0;for(let c=0;c<i.length;c++)i[c].start<=o&&(s=c);let a=i[s+n];return a===void 0?o:Math.min(a.start+(o-i[s].start),a.end)}function Ypi(t,e){return e.id===void 0?[]:t.responses.get(e.id)?.comments??[]}function Jpi(t,e,n,r){if(e.id===void 0)return!1;let i=t.responses.get(e.id);return n==="option"?i?.selectedOptionIds?.includes(r)===!0:n==="card"?i?.selectedCardIds?.includes(r)===!0:n==="row"?i?.selectedRowIds?.includes(r)===!0:i?.selectedColumnIds?.includes(r)===!0}function Pbn(t,e){let n=t.slots[t.currentIndex],r=Math.min(Math.max(20,e-4),120),i=Math.max(20,e-4),o=["",` ${Es}${_s}[${t.currentIndex+1}/${t.slots.length}]${Pe} ${lt}${Tr(t.manifest.title)}${Pe}`,` ${lt}${Qx(r)}${Pe}`,"",` ${Es}${Tr(IF(n))}${Pe}`],s=n.config.body;if(typeof s=="string"&&s.length>0){o.push("");for(let u of phe(s,r,i))o.push(` ${u}`)}if(cf(n)){if(n.kind==="chart"){let u=n.config,l=u.title??`${u.x} vs ${(u.y??[]).map(d=>d.label??d.field).join(", ")}`;o.push("",` ${lt}chart \u2014 ${Tr(u.kind)}: ${Tr(l)}${Pe}`)}else if(n.kind==="table"){o.push("");for(let l of phe(dme(n.config),r,i))o.push(` ${l}`);let u=n.config.label;u&&o.push(` ${lt}${Tr(u)}${Pe}`)}else if(n.kind==="text"){let l=(n.id===void 0?void 0:t.responses.get(n.id))?.text??n.config.initialText;o.push("");for(let d of phe(l,r,i))o.push(` ${d}`)}}else{o.push("");for(let u of qg(`${Tr(n.kind)} \u2014 must be answered in
|
|
1708
|
+
`}function Tpi(t,e){let n=e+2,r=o=>Math.max(1,Math.min(o-1,e)),i=t.spans.map(o=>o!==null&&(o[0]<=1||o[1]>=n));return{lines:t.lines,rows:t.rows.map((o,s)=>i[s]===!0?null:o),spans:t.spans.map((o,s)=>o===null||i[s]===!0?null:[r(o[0]),r(o[1])]),blocks:t.blocks.map(o=>({type:o.type,start:r(o.start),end:r(o.end)}))}}function fbn(t,e,n){let r=Hx(t).length;return Tpi(Tde(Ipi(t,e),n),r)}var Spi,Cpi,zYe=h(()=>{"use strict";s6();eS();Spi={".ts":"typescript",".mts":"typescript",".cts":"typescript",".tsx":"tsx",".js":"javascript",".mjs":"javascript",".cjs":"javascript",".jsx":"jsx",".py":"python",".rb":"ruby",".go":"go",".rs":"rust",".java":"java",".c":"c",".h":"c",".cc":"cpp",".cpp":"cpp",".hpp":"cpp",".cs":"csharp",".swift":"swift",".kt":"kotlin",".php":"php",".lua":"lua",".pl":"perl",".sh":"bash",".bash":"bash",".zsh":"bash",".fish":"fish",".sql":"sql",".json":"json",".jsonc":"json",".yaml":"yaml",".yml":"yaml",".toml":"toml",".ini":"ini",".xml":"xml",".html":"html",".htm":"html",".css":"css",".scss":"scss",".less":"less",".vim":"vim",".el":"lisp",".ex":"elixir",".exs":"elixir",".erl":"erlang",".hs":"haskell",".scala":"scala",".dart":"dart",".r":"r",".jl":"julia",".zig":"zig",".tf":"terraform",".proto":"protobuf",".graphql":"graphql",".gql":"graphql",".dockerfile":"dockerfile",".diff":"diff",".patch":"diff",".csv":"text",".txt":"text",".log":"text",".env":"bash",".mk":"makefile"},Cpi=new Set([".md",".markdown",".mdown",".mkd"])});function rhe(t){let e=[],n=new Array(t.lines.length).fill(null);for(let r=0;r<t.lines.length;r++){let i=t.spans[r]??null;if(i===null){let s=t.rows[r]??null,a=s!==null?t.blocks[s]:void 0;if(a===void 0)continue;i=[a.start,a.end]}let o=e[e.length-1];o!==void 0&&o.lastRow===r-1&&o.start===i[0]&&o.end===i[1]?o.lastRow=r:e.push({start:i[0],end:i[1],firstRow:r,lastRow:r}),n[r]=e.length-1}if(e.length===0){e.push({start:t.blocks[0]?.start??1,end:t.blocks[t.blocks.length-1]?.end??1,firstRow:0,lastRow:Math.max(0,t.lines.length-1)});for(let r=0;r<n.length;r++)n[r]=0}return{units:e,rowUnits:n}}function wD(t,e){let n=-1;for(let r=0;r<t.length;r++){let i=t[r];i.start<=e&&i.end>=e&&(n===-1||i.end-i.start<t[n].end-t[n].start)&&(n=r)}if(n!==-1)return n;for(let r=0;r<t.length;r++)if(t[r].start>e)return r;return Math.max(0,t.length-1)}function VYe(t,e){for(let n=0;n<t.length;n++)if(t[n].start===e.start&&t[n].end===e.end)return n;return wD(t,e.start)}function m6(t,e,n){let r=-1,i=-1;if(t.forEach((o,s)=>{o.start<=n&&o.end>=e&&(r===-1&&(r=s),i=s)}),r===-1){let o=wD(t,e);return{lo:o,hi:o}}return{lo:r,hi:i}}var KYe=h(()=>{"use strict"});import{basename as kpi,dirname as mbn,join as Rpi}from"node:path";import{mkdirSync as Dpi,watch as Mpi,writeFileSync as IGs}from"node:fs";function YYe(t){return Rpi(Cs(),"signals",t)}function ihe(t,e){let n=YYe(t);try{Dpi(mbn(n),{recursive:!0,mode:448});let r=Mpi(mbn(n),(i,o)=>{String(o)===kpi(n)&&e()});return()=>r.close()}catch(r){return console.error(`activity-signal: failed to watch "${t}": ${r instanceof Error?r.message:String(r)}`),()=>{}}}var JYe=h(()=>{"use strict";Fr()});function hbn(t){return ihe("review-activity",t)}var gbn=h(()=>{"use strict";JYe()});function ybn(t,e){return{async anchorBase(){let n=await e(()=>Vt().getReviewDocumentBase(t));return{file:n.file,text:n.anchor_base_text,docHash:n.anchor_base_sha256}},async list(){return(await e(()=>Vt().listReviewComments(t,{status:"all"}))).comments.map(Npi)},async create(n){return(await FF(()=>e(()=>Vt().createReviewComment(t,{text:n.text,anchor:{line:n.line,end_line:n.endLine},doc_hash:n.docHash,actor_node_id:null})))).comment.comment_id},async edit(n){await FF(()=>e(()=>Vt().editReviewComment(n.id,{text:n.text,if_revision:n.ifRevision,actor_node_id:null})))},async resolve(n){await FF(()=>e(()=>Vt().resolveReviewComment(n,{actor_node_id:null})))},async reopen(n){await FF(()=>e(()=>Vt().reopenReviewComment(n,{actor_node_id:null})))},async remove(n){await FF(()=>e(()=>Vt().deleteReviewComment(n,{actor_node_id:null})))},async remapRanges(n){await FF(()=>e(()=>Vt().updateReviewCommentRanges(t,{from_doc_hash:n.fromDocHash,to_doc_hash:n.toDocHash,entries:n.entries.map(r=>"detached"in r?{comment_id:r.id,detached:!0}:{comment_id:r.id,anchor:{line:r.anchor.line,end_line:r.anchor.endLine}})})))},async fork(n){let r=await e(()=>Vt().forkReviewComment(n));return{nodeId:r.node_id,cwd:r.cwd}},onChanged(n){return hbn(n)}}}function Npi(t){let e={line:t.anchor.line,endLine:t.anchor.end_line};return{id:t.comment_id,revision:t.revision,...e,lineText:t.anchor_line_text,comment:t.text,status:t.status,authorKind:t.author.kind,createdAt:t.created_at,anchorStatus:t.anchor_state==="detached"?"detached":"live",...t.anchor_state==="detached"?{originalRange:e}:{}}}async function FF(t){try{return await t()}catch(e){throw e instanceof fn&&Ppi(e.code)?new h6(e.code,e.message,e.details):e}}function Ppi(t){return t==="stale_document"||t==="stale_comment"||t==="range_batch_incomplete"||t==="range_batch_stale"}var h6,XYe=h(()=>{"use strict";hp();cc();gbn();h6=class extends Error{code;details;constructor(e,n,r){super(n),this.name="ReviewDocumentError",this.code=e,this.details=r}}});function ohe(t){switch(t){case"active":return 0;case"idle":return 1;case"done":return 2;case"canceled":return 3;case"dead":return 4;default:return 5}}function Abn(t){return t==="active"||t==="idle"}function wbn(t){return t.lifecycle!=="resident"||t.finalized}var she=h(()=>{"use strict"});function g6(){let t=O0();return t!==void 0?{CRTR_HOME:t}:{}}function ZYe(){return{...g6(),CRTR_ATTACH_WAKE_PARKED:"0"}}function ahe(t){let e=dbe();if(e!==null){for(let n of e)if(Rh(n,"@crtr_node")===t)return n}}function xbn(t,e,n,r,i){let o=IC(t,{cwd:n,env:ZYe(),command:`crtr surface attach to ${e}`});if(o===null)return{focused:!1,session:null,inPlace:!1,revived:i};let s=Nb(o);return s!==null&&lK(s.window,"even-horizontal"),tW(o),{focused:!0,session:s?.session??r,inPlace:!1,revived:i}}async function che(t,e,n){let r=n.pane??process.env.TMUX_PANE??my()?.pane;if(r===void 0||r==="")return{focused:!1,session:null,inPlace:!1,revived:!1};let o=(await t.ensureAttach(e,{resume:!0,revive:!0,wakeParked:!1})).revived,s=Nb(r)?.session??null;if(n.inPlace===!0){let c=Rh(r,"@crtr_node"),u=ahe(e);u!==void 0&&u!==r&&Pb(u)&&J0(u);try{hy(r,"@crtr_node","")}catch{}let l=lbe(r),d=c!==void 0&&c!==""?{...ZYe(),CRTR_ATTACH_ROSTER:c}:ZYe(),p=uK({pane:r,cwd:n.cwd,env:d,command:`crtr surface attach to ${e}`});return p&&l!==null&&cbe(l,n.name),{focused:p,session:s,inPlace:!0,revived:o}}if(n.newPane===!0){let c=ahe(e);return c!==void 0&&Pb(c)&&J0(c),xbn(r,e,n.cwd,s,o)}let a=ahe(e);if(a!==void 0){let c=Nb(a);if(c!==null)return gbe(c.session),p1(c.session,c.window),tW(a),{focused:!0,session:c.session,inPlace:!0,revived:o}}return xbn(r,e,n.cwd,s,o)}async function uhe(t,e,n){let r=e.node_id;if(e.kind==="human")throw new af({error:"not_focusable",message:`node ${r} is a human-ask (kind:human), not a conversation \u2014 it has no pi session to focus.`,next:`The pending question is queued for the user; see it with \`crtr human list\`, or retract it with \`crtr human cancel ${r}\`.`});return!Abn(e.status)&&wbn({lifecycle:e.lifecycle,finalized:e.final_report!=null})?{focused:await ube(n.pane,e.cwd,`crtr node inspect transcript ${kn(r)}`),session:null,revived:!1,inPlace:!1}:che(t,r,{cwd:e.cwd,name:e.name,pane:n.pane,...n.newPane===!0?{newPane:!0}:{},...n.inPlace===!0?{inPlace:!0}:{}})}var y6=h(()=>{"use strict";as();she();Bx();Ap()});var bbn=h(()=>{"use strict";Ap();y6();cc()});function Ebn(t){let{companionNodeId:e,cwd:n,callerPane:r}=t;if(!ua())return{ok:!1,reason:"no_tmux"};let o=mbe().filter(l=>l.nodeId===e&&aK(l.pane)).sort((l,d)=>d.stampMs-l.stampMs);if(o.length>0)return{ok:!0,paneId:o[0].pane,origin:"adopted"};if(r===void 0||r==="")return{ok:!1,reason:"no_caller_pane"};let s=cK(r);if(s===null)return{ok:!1,reason:"split_refused"};let a,c;s.cols>=Lpi?(a=!1,c=Math.max(Bpi,Math.round(s.cols*Fpi))):(a=!0,c=Math.max($pi,Math.round(s.rows*Upi)));let u=IC(r,{cwd:n,env:g6(),command:`crtr surface attach to ${e}`,vertical:a,size:c});return u===null?{ok:!1,reason:"split_refused"}:{ok:!0,paneId:u,origin:"opened"}}function _bn(t){let{nodeId:e,cwd:n,splitFrom:r}=t;if(!ua())return{ok:!1,reason:"no_tmux"};if(r===void 0||r==="")return{ok:!1,reason:"no_caller_pane"};let i=cK(r);if(i===null)return{ok:!1,reason:"split_refused"};if(Math.floor(i.cols/2)<Qpi)return{ok:!1,reason:"no_room"};let o=IC(r,{cwd:n,env:g6(),command:`crtr surface attach to ${e}`,vertical:!1,size:Math.floor(i.cols/2)});return o===null?{ok:!1,reason:"split_refused"}:{ok:!0,paneId:o}}function lhe(t){return Pb(t)&&aK(t)}function eJe(t,e){!Pb(t)||Rh(t,"@crtr_node")!==e||J0(t)}var Lpi,Bpi,$pi,Fpi,Upi,Qpi,vbn=h(()=>{"use strict";Ap();bbn();Lpi=99,Bpi=40,$pi=12,Fpi=.42,Upi=.4,Qpi=52});function Cbn(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function Wpi(t){return t!==null&&typeof t=="object"?t:{}}function dhe(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function Hpi(t){return Array.isArray(t)?t.filter(e=>e!==null&&typeof e=="object"&&"anchor"in e&&"text"in e):[]}function tJe(t,e){let n=new Map(e.map(r=>[r.id,r.label]));return t.map(r=>({id:r,label:n.get(r)??r}))}function Ibn(t,e){let n=t.rows?.find(i=>i.id===e),r=t.columns[0];return n===void 0||r===void 0||!Cbn(n.cells,r.id)?e:String(n.cells[r.id])}function jpi(t){let e=t.config.label;return typeof e=="string"&&e!==""?e:t.id??t.kind}function nJe(t,e){return e.kind==="whole"?jpi(t):e.kind==="option"?t.config.options.find(n=>n.id===e.optionId)?.label??e.optionId:Ibn(t.config,e.rowId)}function Sbn(t,e){return Hpi(e.comments).map(n=>({anchor:n.anchor,anchorLabel:nJe(t,n.anchor),text:n.text}))}function qpi(t,e){let n=e===void 0?"unanswered":"answered",r=Wpi(e),i=t.config.label,o={id:t.id,kind:t.kind,...typeof i=="string"&&i!==""?{label:i}:{},state:n};if(t.unvalidated===!0)return{...o,blank:e===void 0,groups:[],comments:[],...e===void 0?{}:{raw:r}};if(t.kind==="options"){let s=t.config,a=typeof r.freetext=="string"&&r.freetext!==""?r.freetext:void 0,c={group:"option",mode:s.mode,total:s.options.length,picked:tJe(dhe(r.selectedOptionIds),s.options)};return{...o,blank:c.picked.length===0&&a===void 0,groups:[c],...a===void 0?{}:{freetext:a},comments:Sbn(t,r)}}if(t.kind==="text"){let s=r,a=typeof s.text=="string"?s.text:"",c=t.config.singleLine===!0;return{...o,blank:c&&a==="",groups:[],text:{value:a,edited:s.edited===!0,...c?{singleLine:!0}:{}},comments:[]}}if(t.kind==="table"){let s=t.config,a=[];return(s.rowSelect==="single"||s.rowSelect==="multi")&&a.push({group:"row",mode:s.rowSelect,total:s.rows?.length??0,picked:dhe(r.selectedRowIds).map(c=>({id:c,label:Ibn(s,c)}))}),(s.columnSelect==="single"||s.columnSelect==="multi")&&a.push({group:"column",mode:s.columnSelect,total:s.columns.length,picked:tJe(dhe(r.selectedColumnIds),s.columns)}),{...o,blank:a.every(c=>c.picked.length===0),groups:a,comments:Sbn(t,r)}}if(t.kind==="cards"){let s=t.config,a=(s.cards??[]).map(u=>({id:u.id,label:u.title})),c={group:"card",mode:s.mode,total:a.length,picked:tJe(dhe(r.selectedCardIds),a)};return{...o,blank:c.picked.length===0,groups:[c],comments:[]}}throw new Error(`slot "${t.id}" kind "${t.kind}" does not accept a response`)}function Tbn(t,e,n){let r=hS(t),i=r.slots.filter(Qc).map(s=>qpi(s,Cbn(e,s.id)?e[s.id]:void 0)),o=i.filter(s=>s.state==="answered");return{title:r.title,...r.subtitle===void 0?{}:{subtitle:r.subtitle},completedAt:n.completedAt,kind:i.length===0?"acknowledgement":"answer",digest:zpi(o),slots:i}}function Gpi(t){return t.picked.length===0?"no selection":t.group==="option"||t.group==="card"?t.picked.map(e=>e.label).join(", "):t.total>0?`${t.picked.length} of ${t.total} ${t.group}s`:`${t.picked.length} ${t.group}${t.picked.length===1?"":"s"}`}function zpi(t){return t.map(e=>{if(e.raw!==void 0)return`${e.kind} response`;if(e.text!==void 0)return e.text.singleLine===!0?e.text.value===""?"empty":e.text.value:e.text.edited?"edited":"unchanged";let n=e.groups.map(Gpi);return e.freetext!==void 0&&n.push(e.freetext),n.join(", ")||"no selection"}).join(" \xB7 ")}var kbn=h(()=>{"use strict";f0()});function Dbn(t){return Tbn(t.manifest,Object.fromEntries(t.responses),{completedAt:""})}function Kpi(t,e){return e.id===void 0?void 0:t.slots.find(n=>n.id===e.id)}function Mbn(t){if(t===void 0||t.state==="unanswered")return"unanswered";if(t.raw!==void 0)return"custom response";let e=t.text!==void 0?[t.text.edited?"edited":"accepted"]:t.groups.map(n=>n.picked.length===0?"none":n.picked.map(r=>r.label).join(", "));return t.freetext!==void 0&&e.push(t.freetext),t.comments.length>0&&e.push(`${t.comments.length} comment${t.comments.length===1?"":"s"}`),e.join("; ")||"answered"}function Rbn(t,e){return nJe(t,e)}function Obn(t,e,n){let r=Math.min(Math.max(20,e-4),120),i=Math.max(20,e-4),o=["",` ${Es}${_s}${Tr(t.manifest.title)}${Pe}`];if(t.manifest.subtitle)for(let p of qg(Tr(t.manifest.subtitle),r))o.push(` ${lt}${p}${Pe}`);if(t.displayMarkdown!==""){o.push("");for(let p of phe(t.displayMarkdown,r,i))o.push(` ${p}`)}else t.manifest.dialect==="html"&&o.push("",` ${lt}HTML page \u2014 open in Northlight to read this${Pe}`);let s=t.slots.length>0;s&&o.push(` ${lt}${Qx(r)}${Pe}`,"");let a=Dbn(t),c=-1,u;for(let p=0;p<t.slots.length;p++){let f=t.slots[p];t.manifest.steps>1&&f.step!==c&&(c!==-1&&o.push(""),o.push(` ${Es}Step ${f.step+1}/${t.manifest.steps}${Pe}`),c=f.step);let m=f.id===void 0?void 0:t.responses.get(f.id),g=Qc(f)?Fx(t,f)?`${lD}\u2713${Pe}`:`${lt}\u25CB${Pe}`:`${lt}\xB7${Pe}`,y=p===t.currentIndex?`${_s}\u25B8${Pe} `:" ";p===t.currentIndex&&(u=o.length),o.push(` ${y}${g} ${np(Ux(IF(f)),Math.max(10,e-16))}`),m!==void 0&&o.push(` ${lt}${np(Ux(Mbn(Kpi(a,f))),Math.max(10,e-10))}${Pe}`)}if(t.manifest.slots.some(p=>Qc(p)&&!cf(p))){o.push("");for(let p of qg("This page must be answered in Northlight. Leaving it here keeps it in your inbox; x on the list cancels it.",r-2))o.push(` ${ra}${p}${Pe}`)}s&&o.push(""),o.push(` ${lt}${Qx(r)}${Pe}`);let d=!t.manifest.slots.some(Qc)?` ${lt}u/d${Pe} scroll ${lt}q${Pe} dismiss`:` ${lt}enter${Pe} review ${lt}\u2191\u2193/jk${Pe} navigate ${lt}u/d${Pe} scroll ${lt}q${Pe} close`;return Wbn(o,d,t,e,n,r+2,t.followSelection?u:void 0)}function UF(t,e,n){let r=[...t],i=Math.max(0,Math.min(e,r.length)),o=Nbn(t,n),s=0;for(let u=0;u<o.length;u++)o[u].start<=i&&(s=u);let a=o.map((u,l)=>{if(l!==s)return r.slice(u.start,u.end).join("");let d=r.slice(u.start,i).join(""),p=i<u.end?r[i]:" ",f=i<u.end?r.slice(i+1,u.end).join(""):"";return`${d}${Y3}${p}${Pe}${f}`}),c=o[s];return i===c.end&&Da(r.slice(c.start,c.end).join(""))>=n&&(a[s]=r.slice(c.start,c.end).join(""),a.splice(s+1,0,`${Y3} ${Pe}`)),a}function A6(t,e){let n=[...t],r=Math.max(0,Math.min(e,n.length));for(;r>0&&/\s/.test(n[r-1]);)r--;for(;r>0&&!/\s/.test(n[r-1]);)r--;return r}function fhe(t,e){let n=[...t],r=Math.max(0,Math.min(e,n.length));for(;r<n.length&&/\s/.test(n[r]);)r++;for(;r<n.length&&!/\s/.test(n[r]);)r++;return r}function Nbn(t,e){let n=[...t],r=Math.max(1,e),i=[],o=0,s=0;for(let a=0;a<n.length;a++){let c=n[a];if(c===`
|
|
1709
|
+
`){i.push({start:o,end:a}),o=a+1,s=0;continue}let u=Da(c);s+u>r?(i.push({start:o,end:a}),o=a,s=u):s+=u}return i.push({start:o,end:n.length}),i}function w6(t,e,n,r){let i=Nbn(t,r),o=Math.max(0,Math.min(e,[...t].length)),s=0;for(let c=0;c<i.length;c++)i[c].start<=o&&(s=c);let a=i[s+n];return a===void 0?o:Math.min(a.start+(o-i[s].start),a.end)}function Ypi(t,e){return e.id===void 0?[]:t.responses.get(e.id)?.comments??[]}function Jpi(t,e,n,r){if(e.id===void 0)return!1;let i=t.responses.get(e.id);return n==="option"?i?.selectedOptionIds?.includes(r)===!0:n==="card"?i?.selectedCardIds?.includes(r)===!0:n==="row"?i?.selectedRowIds?.includes(r)===!0:i?.selectedColumnIds?.includes(r)===!0}function Pbn(t,e){let n=t.slots[t.currentIndex],r=Math.min(Math.max(20,e-4),120),i=Math.max(20,e-4),o=["",` ${Es}${_s}[${t.currentIndex+1}/${t.slots.length}]${Pe} ${lt}${Tr(t.manifest.title)}${Pe}`,` ${lt}${Qx(r)}${Pe}`,"",` ${Es}${Tr(IF(n))}${Pe}`],s=n.config.body;if(typeof s=="string"&&s.length>0){o.push("");for(let u of phe(s,r,i))o.push(` ${u}`)}if(cf(n)){if(n.kind==="chart"){let u=n.config,l=u.title??`${u.x} vs ${(u.y??[]).map(d=>d.label??d.field).join(", ")}`;o.push("",` ${lt}chart \u2014 ${Tr(u.kind)}: ${Tr(l)}${Pe}`)}else if(n.kind==="table"){o.push("");for(let l of phe(dme(n.config),r,i))o.push(` ${l}`);let u=n.config.label;u&&o.push(` ${lt}${Tr(u)}${Pe}`)}else if(n.kind==="text"){let l=(n.id===void 0?void 0:t.responses.get(n.id))?.text??n.config.initialText;o.push("");for(let d of phe(l,r,i))o.push(` ${d}`)}}else{o.push("");for(let u of qg(`${Tr(n.kind)} \u2014 must be answered in Northlight; the terminal cannot submit this page`,Math.max(10,r-2)))o.push(` ${ra}${u}${Pe}`);o.push(` ${lt}q leaves it in your inbox; x on the list cancels it${Pe}`)}o.push("",` ${lt}${Qx(r)}${Pe}`);let a;if(t.inputMode!==null){let u=t.inputMode.kind==="comment"?`Comment on ${Rbn(n,t.inputMode.anchor)}`:t.inputMode.kind==="text"?"Edit text":"Other response";o.push(` ${Es}${u}${Pe}`);for(let l of UF(t.inputMode.buffer,t.inputMode.cursor,Math.max(10,r-4)))o.push(` ${l}`);a=` ${lt}enter save esc cancel${t.editorAvailable?" ^o editor":""}${Pe}`}else{lme(n).forEach((l,d)=>{let p=d===t.selectedAction?`${_s}\u25B8${Pe}`:" ";if(l.kind==="select"){let f=Jpi(t,n,l.group,l.id)?`${lD}\u2713${Pe}`:" ";if(o.push(` ${p} [${f}] ${l.shortcut?`[${l.shortcut}] `:""}${Tr(l.label)}`),l.description)for(let m of qg(Tr(l.description),Math.max(10,r-6)))o.push(` ${lt}${m}${Pe}`)}else{let f=l.kind==="freetext"?"r":l.kind==="edit"?"e":"a";o.push(` ${p} [${f}] ${Tr(l.label)}`)}});for(let l of Ypi(t,n))for(let d of qg(`attached: ${Rbn(n,l.anchor)} \u2014 ${Tr(l.text)}`,Math.max(10,r-2)))o.push(` ${lt}${d}${Pe}`);t.hint&&o.push(` ${ra}${Tr(t.hint)}${Pe}`),a=` ${lt}n/p next/previous \u2191\u2193/jk actions${kF(n).length>0?" c comment":""} u/d scroll \u2190\u2192/hl pan q close${Pe}`}let c=Math.max(0,...o.map(os));return{lines:o,footer:a,maxW:r,maxH:Math.max(0,c-Math.max(1,e))}}function Lbn(t,e,n){if(t.slots[t.currentIndex]===void 0){t.scrollOffset=0,t.hscrollOffset=0,t.hscrollMax=0;return}let r=Pbn(t,e);t.hscrollMax=r.maxH,t.hscrollOffset=Math.max(0,Math.min(t.hscrollOffset,t.hscrollMax)),t.scrollOffset=Math.max(0,Math.min(t.scrollOffset,Math.max(0,r.lines.length-rJe(n))))}function Bbn(t,e){t.hscrollOffset=Math.max(0,Math.min(t.hscrollMax,t.hscrollOffset+e*Vpi))}function $bn(t,e,n){let r=Pbn(t,e),i=rJe(n),o=t.scrollOffset,s=r.lines.slice(o,o+i);for(;s.length<i;)s.push("");let a=t.hscrollOffset>0?s.map(u=>mme(u,t.hscrollOffset,e)):s,c=Math.min(e,r.maxW+2);return i<n&&a.push(Qbn(r.footer,Ubn(o,i,r.lines.length),r.maxW+2)),g0(a.map(u=>Ma(u,e)),e,c)}function Fbn(t,e,n){let r=Math.min(Math.max(20,e-4),120),i=["",` ${Es}${_s}${Tr(t.manifest.title)} \u2014 Summary${Pe}`,` ${lt}${Qx(r)}${Pe}`,""],o=Dbn(t);for(let c of o.slots){let u=t.manifest.slots.find(p=>p.id===c.id),d=u!==void 0&&Fx(t,u)?`${lD}\u2713${Pe}`:`${ra}\u25CB${Pe}`;i.push(` ${d} ${Es}${Tr(u===void 0?c.kind:IF(u))}${Pe} ${lt}${Tr(Mbn(c))}${Pe}`)}let s=yS(t);if(!s){i.push("",` ${ra}Cannot submit yet.${Pe}`);for(let c of t.slots.filter(Qc))Fx(t,c)||(i.push(` ${lt}${c.id??c.kind} is unanswered${Pe}`),cf(c)||i.push(` ${lt}${c.id} must be answered in Northlight${Pe}`))}i.push("",` ${lt}${Qx(r)}${Pe}`);let a=s?` ${lt}enter${Pe} submit ${lt}u/d${Pe} scroll ${lt}q${Pe} back`:` ${lt}u/d${Pe} scroll ${lt}q${Pe} back`;return Wbn(i,a,t,e,n,r+2)}function rJe(t){return t>=2?t-1:t}function Ubn(t,e,n){if(e<=0||n<=e)return{marks:"",full:""};let r=Math.min(n,t+e),i=`${t>0?"\u25B4":" "}${r<n?"\u25BE":" "}`;return{marks:`${lt}${i}${Pe}`,full:`${lt}${i} ${t+1}\u2013${r}/${n}${Pe}`}}function Qbn(t,e,n){if(e.full==="")return t;let r=i=>n-os(t)-os(i)-2;for(let i of[e.full,e.marks])if(r(i)>=2)return`${t}${" ".repeat(r(i))}${i}`;return` ${e.marks} ${t.trimStart()}`}function Wbn(t,e,n,r,i,o,s){let a=rJe(i),c=Math.max(0,t.length-a);n.scrollOffset=Math.max(0,Math.min(n.scrollOffset,c)),s!==void 0&&a>0&&(s<n.scrollOffset?n.scrollOffset=s:s>=n.scrollOffset+a&&(n.scrollOffset=Math.min(c,s-a+1)));let u=t.slice(n.scrollOffset,n.scrollOffset+a);for(;u.length<a;)u.push("");return a<i&&u.push(Qbn(e,Ubn(n.scrollOffset,a,t.length),o)),g0(u.map(l=>Ma(l,r)),r,Math.min(r,o))}var Vpi,phe,QF=h(()=>{"use strict";T$();f0();kbn();eS();K3();y0();Vpi=8,phe=(t,e,n)=>Mde(t,e,n)});function Hbn(t,e,n,r){let i=e.units.length>0?e:{units:[{start:1,end:Math.max(1,t.length),firstRow:0,lastRow:0}],rowUnits:e.rowUnits};return{sourceLines:t,units:i.units,rowUnits:i.rowUnits,comments:[...n],sourceRevision:r,detached:Object.fromEntries(n.flatMap(o=>o.anchorStatus==="detached"?[[o.id,o.originalRange??{line:o.line,endLine:o.endLine}]]:[])),activeUnit:n.length>0?wD(i.units,n[0].line):0,selectionAnchor:null,scroll:0,hscroll:0,mode:"view",compose:null,listIndex:0}}function iJe(t){let e=t.selectionAnchor??t.activeUnit;return{lo:Math.min(t.activeUnit,e),hi:Math.max(t.activeUnit,e)}}function Xpi(t){let{lo:e,hi:n}=iJe(t),r=Number.POSITIVE_INFINITY,i=0;for(let o=e;o<=n;o++){let s=t.units[o];s!==void 0&&(r=Math.min(r,s.start),i=Math.max(i,s.end))}return Number.isFinite(r)?{line:r,endLine:Math.max(r,i)}:{line:1,endLine:Math.max(1,t.sourceLines.length)}}function oJe(t,e,n){let r=Math.max(0,t.units.length-1),i=Math.max(0,Math.min(r,t.activeUnit+e));return n?{...t,activeUnit:i,selectionAnchor:t.selectionAnchor??t.activeUnit}:{...t,activeUnit:i,selectionAnchor:null}}function jbn(t){let e=new Set;for(let n of t.comments){if(n.status==="deleted"||n.anchorStatus==="detached")continue;let r=!1;t.units.forEach((i,o)=>{i.start<=n.endLine&&i.end>=n.line&&(e.add(o),r=!0)}),r||e.add(wD(t.units,n.line))}return e}function Zpi(t,e,n){let r=t[e],i=t[n];return r===void 0||i===void 0?null:{first:r.firstRow,last:i.lastRow}}function efi(t,e,n,r,i,o=2){let s=Math.max(0,i-r),a=Math.max(0,Math.min(t,s));return n-e+1>=r?Math.max(0,Math.min(Math.max(0,e-1),s)):(e-o<a?a=Math.max(e-o,n-(r-1)):n+o>a+r-1&&(a=Math.min(n+o-(r-1),e)),Math.max(0,Math.min(a,s)))}function vS(t,e,n){let r=Zpi(t.units,t.activeUnit,t.activeUnit);if(r===null)return t;let i=efi(t.scroll,r.first,r.last,n,e.lines.length);return i===t.scroll?t:{...t,scroll:i}}function qbn(t,e,n,r){let i=Math.max(0,r-n);return{...t,scroll:Math.max(0,Math.min(t.scroll+e,i))}}function Gbn(t){return Math.max(1,Math.floor(t/2))}function zbn(t,e,n,r){if(e===0)return t;let i=e>0?1:-1,o=Math.max(0,r-n),s=Math.max(0,Math.min(t.scroll+e,o)),a=s+(s>0?1:0),c=Math.max(a,s+n-1-(s+n<r?1:0)),u=t.units[t.activeUnit]?.firstRow??t.scroll,l=Math.max(a,Math.min(u+e,c)),d=tfi(t,l,a,c,i)??t.activeUnit;return s===t.scroll&&d===t.activeUnit?t:{...t,scroll:s,activeUnit:d,selectionAnchor:null}}function tfi(t,e,n,r,i){let o=Math.max(0,t.units.length-1);for(let s=0;s<=r-n;s++)for(let a of[e+s*i,e-s*i]){if(a<n||a>r)continue;let c=t.rowUnits[a];if(c!=null)return Math.max(0,Math.min(o,c))}return null}function Vbn(t){return{...t,mode:"compose",compose:{buffer:"",cursor:0,editingId:null,returnMode:"view",anchor:Xpi(t)}}}function Kbn(t,e){let n=t.comments[e];if(n===void 0)return t;let r=n.comment,{lo:i,hi:o}=m6(t.units,n.line,n.endLine);return{...t,activeUnit:o,selectionAnchor:i===o?null:i,mode:"compose",compose:{buffer:r,cursor:[...r].length,editingId:n.id,returnMode:"list",anchor:{line:n.line,endLine:n.endLine}}}}function mhe(t){let e=t.compose?.returnMode??"view";return{...t,mode:e,compose:null}}function Ybn(t){let e=t.compose;if(e==null)return{state:t,commit:null};let n=e.buffer.trim();return n.length===0?{state:mhe(t),commit:null}:{state:mhe(t),commit:{editingId:e.editingId,anchor:e.anchor,text:n}}}function Jbn(t){return{...t,mode:"list",listIndex:Math.max(0,Math.min(t.listIndex,t.comments.length-1))}}function sJe(t){return{...t,mode:"view"}}function aJe(t,e){if(t.comments.length===0)return t;let n=Math.max(0,Math.min(t.comments.length-1,t.listIndex+e));return{...t,listIndex:n}}function Xbn(t){let e=t.comments[t.listIndex];return{state:t,id:e?.id??null}}function Zbn(t){return{state:t,id:t.comments.at(-1)?.id??null}}function eEn(t){return{...t,mode:"help"}}function cJe(t){return{...t,mode:"view"}}function _S(t){return[...t]}function tEn(t){return t.replace(/\x1b\[20[01]~/g,"").replace(/\x1b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\r\n?/g,`
|
|
1710
1710
|
`).replace(/[\x00-\x09\x0B-\x1F\x7F]/g,"")}function hhe(t,e,n){let r=_S(t),i=Math.max(0,Math.min(e,r.length));return{buffer:[...r.slice(0,i),..._S(n),...r.slice(i)].join(""),cursor:i+_S(n).length}}function nEn(t,e){if(e<=0)return{buffer:t,cursor:e};let n=_S(t);return{buffer:[...n.slice(0,e-1),...n.slice(e)].join(""),cursor:e-1}}function rEn(t,e){let n=_S(t);return e>=n.length?{buffer:t,cursor:e}:{buffer:[...n.slice(0,e),...n.slice(e+1)].join(""),cursor:e}}function iEn(t,e){let n=e;for(;n>0&&t[n-1]!==`
|
|
1711
1711
|
`;)n--;let r=e;for(;r<t.length&&t[r]!==`
|
|
1712
1712
|
`;)r++;return{start:n,end:r}}function oEn(t,e){return iEn(_S(t),e).start}function sEn(t,e){return iEn(_S(t),e).end}function aEn(t,e,n,r){return w6(t,e,n,r)}function uJe(t,e){return A6(t,e)}function cEn(t,e){return fhe(t,e)}function uEn(t,e){let n=_S(t),r=Math.max(0,Math.min(e,n.length)),i=uJe(t,r);return i===r?{buffer:t,cursor:r}:{buffer:[...n.slice(0,i),...n.slice(r)].join(""),cursor:i}}var lJe=h(()=>{"use strict";QF();KYe()});function yhe(t){return Math.min(Math.max(20,t-6),120)}function pEn(t){return Math.max(20,t-4)}function fEn(t,e=0){return Math.max(1,pEn(t)-(e>0?e+1:0))}function mEn(t,e){return Ize(t,yhe(e),pEn(e))}function hEn(t,e,n){let r=[];for(let o=0;o<n;o++){let s=e+o;r.push(s<t.lines.length?{abs:s,line:t.lines[s]}:{abs:null,line:""})}e>0&&r.length>0&&(r[0]={abs:null,line:` ${lt}\u2191 ${e} more above${Pe}`});let i=t.lines.length-(e+n);return i>0&&r.length>0&&(r[r.length-1]={abs:null,line:` ${lt}\u2193 ${i} more below${Pe}`}),r}function gEn(t,e,n){let r=0;for(let i of hEn(t,e,n))r=Math.max(r,os(i.line));return r}function dJe(t,e,n,r,i=0){let o=Math.max(1,r-Ahe(t,n)),s=Math.max(0,e.lines.length-o),a=Math.max(0,Math.min(t.scroll,s));return Math.max(0,gEn(e,a,o)-fEn(n,i))}function yEn(t,e,n,r,i,o=0){let s=dJe(t,n,r,i,o),a=Math.max(0,Math.min(t.hscroll+e,s));return a===t.hscroll?t:{...t,hscroll:a}}function nfi(t,e){let n=Math.max(0,e-Da(Tr(t)));return lEn+t.replaceAll(Pe,Pe+lEn)+" ".repeat(n)+Pe}function WF(t,e){let n=Ma(t,e),r=Math.max(0,e-os(n));return` ${dEn}${n.replaceAll(Pe,Pe+dEn)}${" ".repeat(r)}${Pe}`}function ofi(t){return`${Es}${_s}${t.key}${Pe} ${t.label}`}function sfi(t,e){let r=s=>1+s.reduce((a,c,u)=>a+os(`${c.key} ${c.label}`)+(u===0?0:3),0),i=[...t],o=[...t].sort((s,a)=>a.priority-s.priority);for(let s of o){if(r(i)<=e)break;i=i.filter(a=>a!==s)}return i}function ghe(t,e){let n=sfi(t,e);return WF(` ${n.map(ofi).join(` ${lt}\xB7${Pe} `)}`,e)}function xEn(t){return ghe(wEn,t)}function cfi(t){let e=[WF(` ${Es}Keys${Pe} ${lt}? or esc closes this${Pe}`,t)];for(let n of bEn){e.push(WF("",t)),e.push(WF(` ${ra}${n.title}${Pe}`,t));for(let[r,i]of n.rows)e.push(WF(` ${Es}${_s}${r.padEnd(afi)}${Pe}${i}`,t))}return e}function Ahe(t,e){if(t.mode==="view")return 4;if(t.mode==="compose"){let r=t.compose,i=Math.min(Math.max(20,e-4),120);return 6+(r?UF(r.buffer,r.cursor,Math.max(10,i-2)).length:1)}return t.mode==="list"?3+Math.max(1,t.comments.length)+2:3+ufi}function EEn(t,e,n,r,i,o){let s=Math.min(Math.max(20,r-4),120),a=yhe(r),c=["",` ${Es}${_s}Review \u2014 ${e}${Pe} ${lt}${t.comments.length} comment${t.comments.length===1?"":"s"}${Pe}`,` ${lt}${Qx(s)}${Pe}`],u=[];if(t.mode==="compose"&&t.compose){let P=t.compose,U=P.anchor.line===P.anchor.endLine?`L${P.anchor.line}`:`L${P.anchor.line}-${P.anchor.endLine}`;u.push(` ${ra}${P.editingId!==null?"Edit comment":"Comment"} on ${U}:${Pe}`);for(let q of UF(P.buffer,P.cursor,Math.max(10,s-2)))u.push(` ${q}`);u.push(""),u.push(ghe(ifi,s))}else t.mode==="list"?(t.comments.length===0?u.push(` ${lt}(no comments yet \u2014 press c to comment on the highlighted block)${Pe}`):t.comments.forEach((P,U)=>{let q=P.line===P.endLine?`L${P.line}`:`L${P.line}-${P.endLine}`,G=U===t.listIndex?`${_s}\u25B8${Pe}`:" ",W=np(P.comment.replace(/\n/g," / "),Math.max(10,s-14));u.push(` ${G} ${lt}[${q}]${Pe} ${W}`)}),u.push(""),u.push(ghe(wEn,s))):t.mode==="help"?u.push(...cfi(s)):u.push(ghe(rfi,s));o?.notice!==void 0&&u.length>0&&(u[u.length-1]=WF(` ${ra}${o.notice}${Pe}`,s));let l=c.length+u.length,d=Math.max(1,i-l),p=Math.max(0,n.lines.length-d),f=Math.max(0,Math.min(t.scroll,p)),m=o?.lineNumbers===!0?String(n.lines.length).length:0,g=fEn(r,m),y=gEn(n,f,d),w=Math.max(0,y-g),x=Math.max(0,Math.min(t.hscroll,w)),{lo:E,hi:_}=iJe(t),C=jbn(t),I=[];for(let P of hEn(n,f,d)){if(P.abs===null){I.push(` ${" ".repeat(m>0?m+1:0)}${P.line}`);continue}let U=mme(P.line,x,g),q=t.rowUnits[P.abs]??null,G=n.spans[P.abs]?.[0],W=m>0?G===void 0?" ".repeat(m+1):`${lt}${String(G).padStart(m)}${Pe} `:"",fe=Math.min(g,Math.max(a,os(U)));q!==null&&q>=E&&q<=_?I.push(` ${_s}\u258C${Pe} ${W}${nfi(U,fe)}`):q!==null&&C.has(q)?I.push(` ${ra}\u258E${Pe} ${W}${U}`):I.push(` ${W}${U}`)}for(;I.length<d;)I.push("");let D=Math.min(r,Math.max(s+2,a+4+(m>0?m+1:0))),O=I.map(P=>{let U=os(P)>D?r:D;return g0([P],r,U)[0]??""}),k=[...g0(c,r,D),...O,...g0(u,r,D)];for(;k.length<i;)k.push("");return k.slice(0,i).map(P=>Ma(P,r))}function _En(t){return dbn(t)?{doc:"markdown"}:{doc:"code",language:pbn(t)}}var AEn,lEn,dEn,rfi,ifi,wEn,bEn,afi,ufi,vEn=h(()=>{"use strict";T$();eS();zYe();QF();y0();lJe();AEn=8,lEn=`${uf}48;5;236m`;dEn=`${uf}48;5;237m`;rfi=[{key:"c",label:"comment",priority:0},{key:"C",label:"all comments",priority:2},{key:"U",label:"undo",priority:6},{key:"a",label:"agent pane",priority:3},{key:"e",label:"$EDITOR",priority:7},{key:"s",label:"submit",priority:4},{key:"x",label:"cancel",priority:8},{key:"?",label:"all keys",priority:1},{key:"esc",label:"close",priority:5}],ifi=[{key:"enter",label:"save",priority:0},{key:"^\u23CE/^F",label:"save + hand to its own agent",priority:2},{key:"^J/\u2325\u23CE",label:"newline",priority:3},{key:"esc",label:"discard",priority:1}],wEn=[{key:"\u2191\u2193/jk",label:"move",priority:1},{key:"enter/e",label:"edit",priority:0},{key:"d",label:"delete",priority:2},{key:"c",label:"new comment",priority:3},{key:"esc",label:"back",priority:0}];bEn=[{title:"Comment",rows:[["c / enter","comment on the highlighted block (J/K widens it)"],["C","all comments \u2014 edit or delete them there"],["U","undo your last comment"],["^\u23CE / ^F","while writing: save + hand to its own agent"]]},{title:"Read",rows:[["\u2191\u2193 / j k","next / previous block"],["J / K","extend the highlight down / up"],["u / d","half a page up / down"],["\u2190\u2192 / h l","pan a diagram wider than the pane"]]},{title:"Finish",rows:[["a","open the agent pane beside the document"],["e","edit the document yourself in $EDITOR"],["s s","approve and submit the review"],["x x","cancel the review"],["esc","leave \u2014 the review stays open in the inbox"]]}],afi=12;ufi=1+bEn.reduce((t,e)=>t+2+e.rows.length,0)});function x6(t){switch(t.type){case"moveUnit":case"extendUnit":case"space":case"help":case"listEdit":case"printable":case"paste":return t.text;case"scrollPage":case"pan":case"cancel":return t.text;default:return}}function whe(t){let e=SC(t);if(nt(e,hr.ctrl("j"))||nt(e,hr.alt("enter")))return{type:"composeNewline"};if(nt(e,hr.alt("backspace"))||nt(e,hr.ctrl("w")))return{type:"composeWordBackspace"};if(nt(e,hr.backspace))return{type:"composeBackspace"};if(nt(e,hr.delete))return{type:"composeDelete"};if(nt(e,hr.alt("left"))||nt(e,hr.ctrl("left"))||nt(e,hr.super("left"))||nt(e,hr.alt("b")))return{type:"composeMove",direction:"wordLeft"};if(nt(e,hr.alt("right"))||nt(e,hr.ctrl("right"))||nt(e,hr.super("right"))||nt(e,hr.alt("f")))return{type:"composeMove",direction:"wordRight"};if(nt(e,hr.home)||nt(e,hr.ctrl("a")))return{type:"composeHome"};if(nt(e,hr.end)||nt(e,hr.ctrl("e")))return{type:"composeEnd"};if(nt(e,hr.shift("tab")))return{type:"tab",reverse:!0};if(nt(e,hr.tab))return{type:"tab",reverse:!1};if(nt(e,hr.ctrl("enter"))||nt(e,hr.ctrl("f")))return{type:"confirmFork"};if(nt(e,hr.enter))return{type:"confirm"};if(nt(e,hr.escape))return{type:"cancel"};if(nt(e,hr.up))return{type:"arrow",direction:"up"};if(nt(e,hr.down))return{type:"arrow",direction:"down"};if(nt(e,hr.left))return{type:"arrow",direction:"left"};if(nt(e,hr.right))return{type:"arrow",direction:"right"};if(nt(e,hr.pageUp))return{type:"scrollPage",delta:-1};if(nt(e,hr.pageDown))return{type:"scrollPage",delta:1};if(nt(e,hr.shift("j")))return{type:"extendUnit",delta:1,text:"J"};if(nt(e,hr.shift("k")))return{type:"extendUnit",delta:-1,text:"K"};if(nt(e,hr.shift("c")))return{type:"printable",text:"C"};if(nt(e,hr.shift("u")))return{type:"printable",text:"U"};if(nt(e,"j"))return{type:"moveUnit",delta:1,text:"j"};if(nt(e,"k"))return{type:"moveUnit",delta:-1,text:"k"};if(nt(e,"u"))return{type:"scrollPage",delta:-1,text:"u"};if(nt(e,"d"))return{type:"scrollPage",delta:1,text:"d"};if(nt(e,"h"))return{type:"pan",delta:-1,text:"h"};if(nt(e,"l"))return{type:"pan",delta:1,text:"l"};if(nt(e,hr.space))return{type:"space",text:" "};if(nt(e,hr.question))return{type:"help",text:"?"};if(nt(e,"e"))return{type:"listEdit",text:"e"};if(nt(e,"q"))return{type:"cancel",text:"q"};let n=oQ(e),r=lfi(t,n);return r==="?"?{type:"help",text:r}:r!==void 0?{type:"printable",text:r}:n!==void 0?null:[...t].length>1?{type:"paste",text:t}:null}function lfi(t,e){let n=_f(t);if(n!==void 0&&pJe(n))return n;if(e!==void 0){let r=e.startsWith("shift+"),i=r?e.slice(6):e;if([...i].length===1&&pJe(i))return r&&/^[a-z]$/.test(i)?i.toUpperCase():i}return[...t].length===1&&pJe(t)?t:void 0}function pJe(t){return!new RegExp("\\p{C}","u").test(t)}var SEn=h(()=>{"use strict";et();ol()});import{accessSync as dfi,constants as pfi,readSync as ffi,statSync as mfi}from"node:fs";import{delimiter as hfi,join as gfi}from"node:path";function xhe(t){let e=t.trim().split(/\s+/)[0]??"";return e.split("/").pop()||e}function IEn(t){return CEn.has(xhe(t))}function Afi(t,e=process.env.PATH){for(let n of(e??"").split(hfi))if(n!=="")try{let r=gfi(n,t);if(!mfi(r).isFile())continue;return dfi(r,pfi.X_OK),!0}catch{}return!1}function jF(t=process.env,e=n=>Afi(n,t.PATH)){let n=(t.VISUAL??"").trim()||(t.EDITOR??"").trim();if(n!=="")return{command:n,source:"env"};for(let r of yfi){if(!e(r))continue;let i=CEn.has(r)?" \u2014 :wq saves and quits, :q! quits without saving":"";return{command:r,source:"fallback",hint:`Used ${r}; set $EDITOR to choose another${i}`}}return null}function wfi(){let t=Buffer.alloc(256);try{for(;;){let e=ffi(0,t,0,t.length,null);if(e===0||t.subarray(0,e).includes(10))return}}catch{}}function qF(t,e=r=>{process.stdout.write(r)},n=wfi){t.source!=="fallback"||t.hint===void 0||(e(`
|
|
@@ -1842,7 +1842,7 @@ Dropped: ${u.dropped}`}}}}var LIn=h(()=>{"use strict";Gt();BD();$D();LD();wU()})
|
|
|
1842
1842
|
`)[0]}`),e.requestChromeRefresh()}))};n.onCursorDownAtBottom=s?void 0:()=>{d!==void 0||l.length===0||(d=l[0].key,g())};let D=()=>{let k=l.find(q=>q.key===d);if(k===void 0||s)return;if(k.kind==="crons"){x(),e.openInspector("schedule");return}if(k.kind==="review"){if(a!=="controller"){e.setNotice("Read-only observer attach \u2014 cannot open the review companion");return}x();let q=process.env.TMUX_PANE;if(q===void 0||q===""){e.setNotice("Could not open the companion: no tmux pane");return}(async()=>{let G=Vt(),W=await G.getNode(k.companionNodeId);(await uhe(G,W,{pane:q})).focused||e.setNotice("Could not open the companion")})().catch(G=>e.setNotice(`Could not open the companion: ${Au(G).split(`
|
|
1843
1843
|
`)[0]}`));return}if(k.kind==="bash"){if(DF(tb(o)).length===0){e.setNotice("Background job already finished"),e.requestChromeRefresh();return}x(),e.openInspector("jobs");return}let P=k.nodeId;if(P===o){x();return}if(a!=="controller"){e.setNotice("Read-only observer attach \u2014 cannot focus nodes");return}let U=process.env.TMUX_PANE;if(U===void 0||U===""){e.setNotice("cannot swap \u2014 no tmux pane");return}MTn("tmux",["run-shell","-b",`crtr surface node focus ${P} --pane ${U} --in-place >/dev/null 2>&1`],()=>{})};return{refresh:y,handleKey:k=>{if(s)return!1;let P=nt(k,"down"),U=nt(k,"up");if(d===void 0)return!1;let q=l.findIndex(W=>W.key===d),G=l[q];if(f!==void 0){if(E(k)==="y")return I(),!0;w(!0)}return G?.kind==="bash"&&E(k)==="x"?(C(),!0):U?(q<=0?x():(d=l[q-1].key,g()),!0):P?(q>=0&&q<l.length-1&&(d=l[q+1].key,g()),!0):nt(k,"enter")?(D(),!0):nt(k,"escape")?(x(),!0):(x(),!1)},active:()=>d!==void 0,exit:x}}var Bwi,NTn=h(()=>{"use strict";et();cc();y6();KF();MF();PD();Gx();DTn();Bwi=15e3});function $wi(t){return t.kind==="page"?t.emittedAt:t.blockedSince}function Fwi(t){let e=Date.now()-Date.parse(t);if(!Number.isFinite(e)||e<0)return"now";let n=Math.floor(e/6e4);if(n<1)return"now";if(n<60)return`${n}m`;let r=Math.floor(n/60);return r<24?`${r}h`:`${Math.floor(r/24)}d`}function PTn(t,e){let{nodeId:n,remote:r,canvasSource:i,tui:o,pal:s}=t,a=new Ze,c=[],u=new Map,l,d=0,p=_=>{let C=_.source.nodeId,I=C!==void 0&&C!==n?` \xB7 ${yD(u.get(C)??null,C)}`:"";return jx(` ${l6}\u2691${Jr} ${_.title}${s.faint(` \xB7 ${Fwi($wi(_))}${I}`)}`)},f=()=>{if(e.syncCursor(),a.clear(),c.length>0&&!e.suppressed()){let _=l===void 0?-1:c.findIndex(I=>I.dir===l);_>=0&&(d=Math.min(Math.max(d,_-dye+1),_)),d=Math.max(0,Math.min(d,Math.max(0,c.length-dye)));for(let I of c.slice(d,d+dye)){let D=p(I);a.addChild(new ve(I.dir===l?qx(gD(D),zg(),ES):D,1,0))}let C=c.length-Math.min(dye,c.length-d);C>0&&a.addChild(new ve(s.faint(` +${C} more`),1,0)),a.addChild(new sn(s.border))}o.requestRender()},m=async()=>{let _=new Map((await i.listNodes()).map(D=>[D.node_id,D])),C=new Map,I=async D=>{if(C.has(D))return;let O=_.get(D)??null;if(D!==n&&O?.kind==="human")return;C.set(D,O);let k=await i.subscriptionsOf(D).catch(()=>[]);for(let P of k)await I(P.node_id)};return await I(n),C},g=async()=>{if(r)return;u=await m();let _=Vt(),[C,I]=await Promise.all([_.listHumanInbox(),_.getInboxHistory()]),D=new Map;for(let O of C.tickets){let k=h0(O);D.set(k.dir,k)}for(let O of I.tickets){let k=h0(O);k.kind==="page"&&(k.source.nodeId===void 0||!u.has(k.source.nodeId)||k.state!=="pending"||!k.awaitsResponse||k.inbox||D.has(k.dir)||D.set(k.dir,k))}c=[...D.values()].filter(O=>O.source.nodeId!==void 0&&u.has(O.source.nodeId)).sort(gS),l!==void 0&&!c.some(O=>O.dir===l)&&(l=void 0),f()},y=()=>{l!==void 0&&(l=void 0,f())},w=()=>{if(!r){if(l!==void 0){y();return}if(c.length===0){e.setNotice("No pending human requests in this subtree");return}e.exitRoster(),l=c[0].dir,d=0,f()}},x=()=>{let _=c.find(C=>C.dir===l);_!==void 0&&(y(),e.openTicket(_))};return{component:a,refresh:g,handleKey:_=>{if(l===void 0)return!1;let C=c.findIndex(D=>D.dir===l),I=_f(_)??(_.length===1?_:void 0);return nt(_,"up")||I==="k"?(C>0&&(l=c[C-1].dir,f()),!0):nt(_,"down")||I==="j"?(C>=0&&C<c.length-1?(l=c[C+1].dir,f()):y(),!0):nt(_,"enter")?(x(),!0):nt(_,"escape")?(y(),!0):(y(),!1)},toggle:w,active:()=>l!==void 0,pendingTickets:()=>[...c]}}var dye,LTn=h(()=>{"use strict";et();Ws();uD();cc();Gx();dye=3});import{existsSync as Uwi,renameSync as Qwi,unlinkSync as BTn,writeFileSync as $Tn}from"node:fs";import{hostname as tet}from"node:os";import{randomUUID as Wwi}from"node:crypto";function jwi(t){if(typeof t!="object"||t===null)return null;let e=t;return typeof e.token!="string"||typeof e.host!="string"||!Number.isInteger(e.pid)||typeof e.claimedAt!="string"||typeof e.heartbeatAt!="string"?null:{token:e.token,host:e.host,pid:e.pid,claimedAt:e.claimedAt,heartbeatAt:e.heartbeatAt,...typeof e.tmuxClient=="string"?{tmuxClient:e.tmuxClient}:{}}}function net(t){return jwi(KM(PS(t)))}function qwi(t){try{return process.kill(t,0),!0}catch{return!1}}function Gwi(t,e=Date.now(),n=tet()){if(t.host===n)return!qwi(t.pid);let r=Date.parse(t.heartbeatAt);return!Number.isFinite(r)||e-r>Hwi}function eV(t,e={}){return fc(`${t}/.ticket-lock`,()=>{let n=PS(t),r=net(t);if(r!==null&&!Gwi(r,Date.now(),e.host??tet()))return null;Uwi(n)&&BTn(n);let i=e.host??tet(),o=e.pid??process.pid,s=(e.now??new Date).toISOString(),a={token:Wwi(),host:i,pid:o,claimedAt:s,heartbeatAt:s,...e.tmuxClient?{tmuxClient:e.tmuxClient}:{}};return $Tn(n,`${JSON.stringify(a)}
|
|
1844
1844
|
`,{flag:"wx",mode:384}),a})}function pye(t,e,n=new Date){return fc(`${t}/.ticket-lock`,()=>{let r=net(t);if(r===null||r.token!==e)return!1;let i=`${PS(t)}.${e}.heartbeat`;return $Tn(i,`${JSON.stringify({...r,heartbeatAt:n.toISOString()})}
|
|
1845
|
-
`,{flag:"wx",mode:384}),Qwi(i,PS(t)),!0})}function zwi(t,e){let n=net(t);return n===null||n.token!==e?!1:(BTn(PS(t)),!0)}function ty(t,e){return fc(`${t}/.ticket-lock`,()=>zwi(t,e))}var Hwi,ret=h(()=>{"use strict";lye();Gs();Mf();Hwi=3e4});function bU(t){return ihe("inbox-activity",t)}var fye=h(()=>{"use strict";JYe()});function QTn(t,e,n,r,i){if(e.ctrl&&t==="c"){i(!1);return}if(n.hint=void 0,n.inputMode!==null){exi(t,e,n,r);return}n.phase==="overview"?Vwi(t,e,n,r,i):n.phase==="item-review"?Kwi(t,e,n,r,i):Ywi(t,e,n,r,i)}function oet(t,e,n){return t==="d"||e.pageDown||e.ctrl&&(t==="d"||t==="e")?(n.scrollOffset+=t==="e"?1:10,n.followSelection=!1,!0):t==="u"||e.pageUp||e.ctrl&&(t==="u"||t==="y")?(n.scrollOffset=Math.max(0,n.scrollOffset-(t==="y"?1:10)),n.followSelection=!1,!0):!1}function Vwi(t,e,n,r,i){if(oet(t,e,n)){r();return}if(t==="j"||e.downArrow)n.currentIndex=Math.min(n.currentIndex+1,Math.max(0,n.slots.length-1)),n.followSelection=!0;else if(t==="k"||e.upArrow)n.currentIndex=Math.max(n.currentIndex-1,0),n.followSelection=!0;else if((e.return||t===" ")&&n.slots.length>0)n.phase="item-review",set(n);else if(t==="q"||e.escape){i(!n.manifest.slots.some(Qc));return}else return;r()}function Kwi(t,e,n,r,i){let o=n.slots[n.currentIndex];if(o===void 0){n.phase="overview",r();return}let s=lme(o);if(t==="n"){iet(n,1),r();return}if(t==="p"){iet(n,-1),r();return}if(t==="q"||e.escape){i(!1);return}if(oet(t,e,n)){r();return}if((t==="h"||t==="l"||e.leftArrow||e.rightArrow)&&n.hscrollMax>0&&!s.some(c=>c.kind==="select"&&c.shortcut===t)){Bbn(n,t==="h"||e.leftArrow?-1:1),r();return}if(t==="j"||e.downArrow){n.selectedAction=Math.min(n.selectedAction+1,Math.max(0,s.length-1)),r();return}if(t==="k"||e.upArrow){n.selectedAction=Math.max(0,n.selectedAction-1),r();return}if(t==="c"&&kF(o).length>0){Xwi(n,o,s),r();return}let a=s.find(c=>c.kind==="select"&&c.shortcut===t);if(a?.kind==="select"){FTn(n,o,a,mye(o,a.mode)),r(),mye(o,a.mode)&&n.phase==="final"&&yS(n)&&i(!0);return}if(t===" "&&s[n.selectedAction]?.kind==="select"){let c=s[n.selectedAction];FTn(n,o,c,mye(o,c.mode)),r(),mye(o,c.mode)&&n.phase==="final"&&yS(n)&&i(!0);return}if(t==="r"&&s.some(c=>c.kind==="freetext")){let c=FD(o,n.responses.get(o.id));n.inputMode={kind:"freetext",buffer:c.freetext??"",cursor:[...c.freetext??""].length},r();return}if(t==="e"&&s.some(c=>c.kind==="edit")){let c=FD(o,n.responses.get(o.id));n.inputMode={kind:"text",buffer:c.text,cursor:[...c.text].length},r();return}if(t==="a"&&s.some(c=>c.kind==="accept")){C0(n,o,{text:o.config.initialText,edited:!1}),UD(n),r();return}if(e.return){let c=s[n.selectedAction];if(c?.kind==="freetext"){let u=FD(o,n.responses.get(o.id));n.inputMode={kind:"freetext",buffer:u.freetext??"",cursor:[...u.freetext??""].length},r();return}if(c?.kind==="edit"){let u=FD(o,n.responses.get(o.id));n.inputMode={kind:"text",buffer:u.text,cursor:[...u.text].length},r();return}if(c?.kind==="accept"){C0(n,o,{text:o.config.initialText,edited:!1}),UD(n),r();return}if(Fx(n,o)){UD(n),r();return}if(cf(o)){let u=FD(o,n.responses.get(o.id));if(jKe(n,o,u)){C0(n,o,u),UD(n),r();return}}if(Qc(o)){n.hint=cf(o)?"Select at least one option (space to toggle), or q to go back":"This must be answered in
|
|
1845
|
+
`,{flag:"wx",mode:384}),Qwi(i,PS(t)),!0})}function zwi(t,e){let n=net(t);return n===null||n.token!==e?!1:(BTn(PS(t)),!0)}function ty(t,e){return fc(`${t}/.ticket-lock`,()=>zwi(t,e))}var Hwi,ret=h(()=>{"use strict";lye();Gs();Mf();Hwi=3e4});function bU(t){return ihe("inbox-activity",t)}var fye=h(()=>{"use strict";JYe()});function QTn(t,e,n,r,i){if(e.ctrl&&t==="c"){i(!1);return}if(n.hint=void 0,n.inputMode!==null){exi(t,e,n,r);return}n.phase==="overview"?Vwi(t,e,n,r,i):n.phase==="item-review"?Kwi(t,e,n,r,i):Ywi(t,e,n,r,i)}function oet(t,e,n){return t==="d"||e.pageDown||e.ctrl&&(t==="d"||t==="e")?(n.scrollOffset+=t==="e"?1:10,n.followSelection=!1,!0):t==="u"||e.pageUp||e.ctrl&&(t==="u"||t==="y")?(n.scrollOffset=Math.max(0,n.scrollOffset-(t==="y"?1:10)),n.followSelection=!1,!0):!1}function Vwi(t,e,n,r,i){if(oet(t,e,n)){r();return}if(t==="j"||e.downArrow)n.currentIndex=Math.min(n.currentIndex+1,Math.max(0,n.slots.length-1)),n.followSelection=!0;else if(t==="k"||e.upArrow)n.currentIndex=Math.max(n.currentIndex-1,0),n.followSelection=!0;else if((e.return||t===" ")&&n.slots.length>0)n.phase="item-review",set(n);else if(t==="q"||e.escape){i(!n.manifest.slots.some(Qc));return}else return;r()}function Kwi(t,e,n,r,i){let o=n.slots[n.currentIndex];if(o===void 0){n.phase="overview",r();return}let s=lme(o);if(t==="n"){iet(n,1),r();return}if(t==="p"){iet(n,-1),r();return}if(t==="q"||e.escape){i(!1);return}if(oet(t,e,n)){r();return}if((t==="h"||t==="l"||e.leftArrow||e.rightArrow)&&n.hscrollMax>0&&!s.some(c=>c.kind==="select"&&c.shortcut===t)){Bbn(n,t==="h"||e.leftArrow?-1:1),r();return}if(t==="j"||e.downArrow){n.selectedAction=Math.min(n.selectedAction+1,Math.max(0,s.length-1)),r();return}if(t==="k"||e.upArrow){n.selectedAction=Math.max(0,n.selectedAction-1),r();return}if(t==="c"&&kF(o).length>0){Xwi(n,o,s),r();return}let a=s.find(c=>c.kind==="select"&&c.shortcut===t);if(a?.kind==="select"){FTn(n,o,a,mye(o,a.mode)),r(),mye(o,a.mode)&&n.phase==="final"&&yS(n)&&i(!0);return}if(t===" "&&s[n.selectedAction]?.kind==="select"){let c=s[n.selectedAction];FTn(n,o,c,mye(o,c.mode)),r(),mye(o,c.mode)&&n.phase==="final"&&yS(n)&&i(!0);return}if(t==="r"&&s.some(c=>c.kind==="freetext")){let c=FD(o,n.responses.get(o.id));n.inputMode={kind:"freetext",buffer:c.freetext??"",cursor:[...c.freetext??""].length},r();return}if(t==="e"&&s.some(c=>c.kind==="edit")){let c=FD(o,n.responses.get(o.id));n.inputMode={kind:"text",buffer:c.text,cursor:[...c.text].length},r();return}if(t==="a"&&s.some(c=>c.kind==="accept")){C0(n,o,{text:o.config.initialText,edited:!1}),UD(n),r();return}if(e.return){let c=s[n.selectedAction];if(c?.kind==="freetext"){let u=FD(o,n.responses.get(o.id));n.inputMode={kind:"freetext",buffer:u.freetext??"",cursor:[...u.freetext??""].length},r();return}if(c?.kind==="edit"){let u=FD(o,n.responses.get(o.id));n.inputMode={kind:"text",buffer:u.text,cursor:[...u.text].length},r();return}if(c?.kind==="accept"){C0(n,o,{text:o.config.initialText,edited:!1}),UD(n),r();return}if(Fx(n,o)){UD(n),r();return}if(cf(o)){let u=FD(o,n.responses.get(o.id));if(jKe(n,o,u)){C0(n,o,u),UD(n),r();return}}if(Qc(o)){n.hint=cf(o)?"Select at least one option (space to toggle), or q to go back":"This must be answered in Northlight",r();return}iet(n,1),r()}}function Ywi(t,e,n,r,i){if(t==="q"||e.escape){n.phase=n.slots.length===1?"item-review":"overview",n.scrollOffset=0,r();return}if(oet(t,e,n)){r();return}e.return&&(yS(n)||!n.manifest.slots.some(Qc))&&i(!0)}function set(t){t.selectedAction=0,t.scrollOffset=0,t.followSelection=!0,t.hscrollOffset=0,t.hscrollMax=0}function iet(t,e){let n=t.currentIndex+e;if(n<0){t.phase=t.slots.length>1?"overview":"item-review",t.scrollOffset=0,t.followSelection=!0;return}if(n>=t.slots.length){t.phase="final",t.scrollOffset=0,t.followSelection=!0;return}t.currentIndex=n,set(t)}function UD(t){for(let e=t.currentIndex+1;e<t.slots.length;e++){let n=t.slots[e];if(Qc(n)&&!Fx(t,n)){t.currentIndex=e,set(t);return}}t.phase="final",t.scrollOffset=0}function FD(t,e){return e!==void 0?e:t.kind==="options"?{selectedOptionIds:[],comments:[]}:t.kind==="cards"?{selectedCardIds:[]}:t.kind==="table"?{selectedRowIds:[],selectedColumnIds:[],comments:[]}:t.kind==="text"?{text:t.config.initialText,edited:!1}:{}}function aet(t){return[...t?.comments??[]]}function C0(t,e,n){e.id!==void 0&&(t.responses.set(e.id,n),t.persist?.())}function FTn(t,e,n,r){let i=FD(e,t.responses.get(e.id));if(e.kind==="options"){let o=i,s=hye(o.selectedOptionIds,n.id,n.mode);C0(t,e,{...o,selectedOptionIds:s})}else if(e.kind==="cards"){let o=i;C0(t,e,{...o,selectedCardIds:hye(o.selectedCardIds,n.id,n.mode)})}else if(e.kind==="table"){let o=i;n.group==="row"?C0(t,e,{...o,selectedRowIds:hye(o.selectedRowIds,n.id,n.mode)}):C0(t,e,{...o,selectedColumnIds:hye(o.selectedColumnIds,n.id,n.mode)})}r&&UD(t)}function hye(t,e,n){return n==="single"?[e]:t.includes(e)?t.filter(r=>r!==e):[...t,e]}function Jwi(t){if(t?.kind==="select"){if(t.group==="option")return{kind:"option",optionId:t.id};if(t.group==="row")return{kind:"row",rowId:t.id}}}function Xwi(t,e,n){let r=Jwi(n[t.selectedAction])??kF(e)[0],o=aet(e.id===void 0?void 0:t.responses.get(e.id)).find(s=>s.id===TF(r))?.text??"";t.inputMode={kind:"comment",buffer:o,cursor:[...o].length,anchor:r}}function Zwi(t){if(t.inputMode?.kind!=="comment")return;let e=t.slots[t.currentIndex],n=kF(e);if(n.length===0)return;let r=TF(t.inputMode.anchor),i=n.findIndex(a=>TF(a)===r),o=n[(i+1)%n.length],s=aet(e.id===void 0?void 0:t.responses.get(e.id)).find(a=>a.id===TF(o))?.text??"";t.inputMode={kind:"comment",anchor:o,buffer:s,cursor:[...s].length}}function exi(t,e,n,r){let i=n.inputMode;if(e.escape){n.inputMode=null,r();return}if(e.tab&&i.kind==="comment"){Zwi(n),r();return}if(e.return){txi(n),r();return}if(e.newline){WTn(i,`
|
|
1846
1846
|
`),r();return}e.wordLeft?i.cursor=A6(i.buffer,i.cursor):e.wordRight?i.cursor=fhe(i.buffer,i.cursor):e.leftArrow?i.cursor=Math.max(0,i.cursor-1):e.rightArrow?i.cursor=Math.min([...i.buffer].length,i.cursor+1):e.upArrow?i.cursor=w6(i.buffer,i.cursor,-1,UTn(n)):e.downArrow?i.cursor=w6(i.buffer,i.cursor,1,UTn(n)):e.home||e.ctrl&&t==="a"?i.cursor=sxi(i.buffer,i.cursor):e.end||e.ctrl&&t==="e"?i.cursor=axi(i.buffer,i.cursor):e.meta&&e.backspace?rxi(i):e.backspace||t==="\x7F"?nxi(i):e.del||e.ctrl&&t==="d"?oxi(i):!e.ctrl&&!e.meta&&ixi(i,t),r()}function txi(t){let e=t.inputMode,n=t.slots[t.currentIndex],r=FD(n,n.id===void 0?void 0:t.responses.get(n.id));if(e.kind==="comment"){let i=e.anchor,o=TF(i),s=aet(r).filter(a=>a.id!==o);e.buffer.trim()!==""&&s.push({id:o,anchor:i,text:e.buffer}),C0(t,n,{...r,comments:s})}else e.kind==="freetext"?(C0(t,n,{...r,freetext:e.buffer}),UD(t)):(C0(t,n,{text:e.buffer,edited:e.buffer!==n.config.initialText}),UD(t));t.inputMode=null}function WTn(t,e){let n=[...t.buffer];n.splice(t.cursor,0,...e),t.buffer=n.join(""),t.cursor+=[...e].length}function nxi(t){if(t.cursor===0)return;let e=[...t.buffer];e.splice(t.cursor-1,1),t.buffer=e.join(""),t.cursor--}function rxi(t){let e=A6(t.buffer,t.cursor);if(e===t.cursor)return;let n=[...t.buffer];n.splice(e,t.cursor-e),t.buffer=n.join(""),t.cursor=e}function ixi(t,e){let n=e.replace(/\x1b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\r\n?/g,`
|
|
1847
1847
|
`).replace(/[\x00-\x09\x0B-\x1F\x7F]/g,"");n.length>0&&WTn(t,n)}function oxi(t){let e=[...t.buffer];t.cursor>=e.length||(e.splice(t.cursor,1),t.buffer=e.join(""))}function sxi(t,e){let n=[...t].slice(0,e).join(""),r=n.lastIndexOf(`
|
|
1848
1848
|
`);return r<0?0:[...n.slice(0,r+1)].length}function axi(t,e){let n=[...t],r=n.slice(e).indexOf(`
|