@north-light/cli 0.3.543 → 0.3.544
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/northlight-apps/build-on-your-app.md +47 -0
- package/dist/builtin-memory/northlight-apps/cli.md +3 -3
- package/dist/builtin-memory/northlight-apps/coding-agents.md +16 -7
- package/dist/builtin-memory/northlight-apps/concepts/apps-and-sign-in.md +0 -4
- package/dist/builtin-memory/northlight-apps/concepts/connections.md +0 -4
- package/dist/builtin-memory/northlight-apps/concepts/providers.md +0 -4
- package/dist/builtin-memory/northlight-apps/concepts/runs.md +0 -4
- package/dist/builtin-memory/northlight-apps/concepts/scopes-and-grants.md +0 -4
- package/dist/builtin-memory/northlight-apps/concepts/testing-mode.md +0 -4
- package/dist/builtin-memory/northlight-apps/get-started.md +56 -0
- package/dist/builtin-memory/northlight-apps/guides/go-live.md +1 -1
- package/dist/builtin-memory/northlight-apps/guides/manage-your-app.md +4 -4
- package/dist/builtin-memory/northlight-apps/how-it-fits.md +1 -1
- package/dist/builtin-memory/northlight-apps/know-the-person.md +29 -0
- package/dist/builtin-memory/northlight-apps/let-their-ai-use-your-app.md +67 -0
- package/dist/builtin-memory/northlight-apps/providers/README.md +1 -1
- package/dist/builtin-memory/northlight-apps/providers/context.md +2 -2
- package/dist/builtin-memory/northlight-apps/providers/device.md +3 -3
- package/dist/builtin-memory/northlight-apps/providers/integrations.md +1 -1
- package/dist/builtin-memory/northlight-apps/providers/search.md +1 -1
- package/dist/builtin-memory/northlight-apps/providers/sms.md +3 -3
- package/dist/builtin-memory/northlight-apps/quickstart.md +3 -17
- package/dist/builtin-memory/northlight-apps/reach-people-by-text.md +50 -0
- package/dist/builtin-memory/northlight-apps/use-our-ai.md +55 -0
- package/dist/builtin-memory/northlight-apps/use-our-apps.md +46 -0
- package/dist/core/command-plugins/transport/http-plan.d.ts +2 -0
- package/dist/core/command-plugins/transport/http-plan.js +1 -1
- package/dist/core/providers/call.js +1 -1
- package/dist/daemon/api/app-listener.d.ts +1 -1
- package/dist/daemon/api/app-listener.js +13 -13
- package/dist/daemon/api/handlers/providers.d.ts +3 -1
- package/dist/shared/traceparent.d.ts +6 -0
- package/dist/shared/traceparent.js +1 -0
- package/docs/apps/build-on-your-app.md +44 -0
- package/docs/apps/cli.md +3 -3
- package/docs/apps/coding-agents.md +16 -7
- package/docs/apps/concepts/apps-and-sign-in.md +0 -4
- package/docs/apps/concepts/connections.md +0 -4
- package/docs/apps/concepts/providers.md +0 -4
- package/docs/apps/concepts/runs.md +0 -4
- package/docs/apps/concepts/scopes-and-grants.md +0 -4
- package/docs/apps/concepts/testing-mode.md +0 -4
- package/docs/apps/get-started.md +47 -0
- package/docs/apps/guides/go-live.md +1 -1
- package/docs/apps/guides/manage-your-app.md +4 -4
- package/docs/apps/how-it-fits.md +1 -1
- package/docs/apps/know-the-person.md +27 -0
- package/docs/apps/let-their-ai-use-your-app.md +63 -0
- package/docs/apps/providers/README.md +1 -1
- package/docs/apps/providers/context.md +2 -2
- package/docs/apps/providers/device.md +3 -3
- package/docs/apps/providers/integrations.md +1 -1
- package/docs/apps/providers/search.md +1 -1
- package/docs/apps/providers/sms.md +3 -3
- package/docs/apps/quickstart.md +3 -17
- package/docs/apps/reach-people-by-text.md +47 -0
- package/docs/apps/use-our-ai.md +27 -0
- package/docs/apps/use-our-apps.md +32 -0
- package/docs/cli/join-northlight.md +1 -1
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -117,7 +117,3 @@ It needs the app registered with the `app_token_for_user` operation, and an acti
|
|
|
117
117
|
## Signing in a visitor
|
|
118
118
|
|
|
119
119
|
A person who only needs to be recognized, not connected, signs in with identity only: request `openid`, optionally with `email` and `profile`, and no runtime scope. Finish with `exchangeIdentity`, not `exchangeCode`. An `Identity` is not a connection: no runtime URL, grant or refresh token (if the directory answers with one anyway, `exchangeIdentity` revokes the refresh token), nothing goes in the store, and you keep your own session. To act for that person later, send them through `authorizeUrl` again with the runtime scopes you need.
|
|
120
|
-
|
|
121
|
-
## Checked and not checked
|
|
122
|
-
|
|
123
|
-
From the SDK source and tests. The refresh and refusal paths against `account.northlight.ai` are not yet checked on production.
|
|
@@ -54,7 +54,3 @@ if (context?.state !== 'ready') {
|
|
|
54
54
|
| `unavailable` | The provider does not offer this to the person's account. `message` says so; there is nothing for them to do. |
|
|
55
55
|
|
|
56
56
|
`message` is the provider's own sentence, present for `pending`, `failed` and `unavailable`. `step` is present when the provider reports where things stand (for example `researching`); its values may grow, so ignore one you do not know. `next` is the absolute URL of the setup page for this provider and your app; `setupLink(dependency, {returnTo})` from `@north-light/sdk` adds a `return_to` with your app's registered origin so the person returns to you, and keeps the query `next` already carries. A key can contain a dot (`context.deep`). An entry is missing when the runtime has not synced the grant since the app began requiring the provider: treat that as `not_started`. The runtime does not block your calls for you, so refuse the dependent operation yourself. To act the moment a state turns `ready`, follow it with `oauth.watchGrants`; see [Grant changes](/docs/guides/grant-changes).
|
|
57
|
-
|
|
58
|
-
## Checked and not checked
|
|
59
|
-
|
|
60
|
-
From the SDK source (`providers.tools`, `providers.call`, `grant.get`) and the directory source. The sms limits come from the existing SDK guide. A real `providers.call` for `sms` on production returned a `message_id` for a text to the signed-in person. That the text arrived is not yet checked.
|
|
@@ -88,7 +88,3 @@ try {
|
|
|
88
88
|
## Learn when a background run ends
|
|
89
89
|
|
|
90
90
|
A run you start and do not wait on ends while nobody holds a request. `oauth.watchRuns(...)` follows those runs for you and calls `onEnded` for each one that comes to rest. See [Background runs](/docs/guides/background-runs).
|
|
91
|
-
|
|
92
|
-
## Checked and not checked
|
|
93
|
-
|
|
94
|
-
From the SDK source and its tests. On production, `runs.start` and `runs.wait` ran the quickstart's prompt and settled with status `idle`; the run's reply text and `activity` are not yet checked.
|
|
@@ -56,7 +56,3 @@ A run's list must stay inside the grant, and a child agent never regains a scope
|
|
|
56
56
|
## Your app's own space
|
|
57
57
|
|
|
58
58
|
Your app has its own space on each person's runtime: documents and files owned by your app. Your server and runs started without a `scopes` list read and write it freely. A run started with a `scopes` list needs `crtr:memory:read:app:<your client id>` or `crtr:memory:rw:app:<your client id>` to touch it. Another app's space is reachable only where that app allows it.
|
|
59
|
-
|
|
60
|
-
## Checked and not checked
|
|
61
|
-
|
|
62
|
-
From the SDK source, the directory console source and the existing SDK guide. `403 scope_missing` for a missing `crtr:act` and the consent page's behavior are not yet checked on production.
|
|
@@ -30,7 +30,3 @@ Email support@northlight.ai to have the app verified. Only Northlight staff can
|
|
|
30
30
|
## Test the refusal in code
|
|
31
31
|
|
|
32
32
|
`@north-light/sdk/testing` has a fake directory that can refuse a sign-in as an app in testing, so you can test this path without a second account. See [Test your app](/docs/guides/test-your-app).
|
|
33
|
-
|
|
34
|
-
## Checked and not checked
|
|
35
|
-
|
|
36
|
-
From the SDK source, the console source and the testing-mode specification. Adding a tester, a second person signing in, the `app_in_testing` redirect and removing a tester have not been run on production (not yet checked on production). Those steps need a second account.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Get started
|
|
3
|
+
description: What every Northlight app needs first — an account, a registered app, sign-in with Northlight, a stored connection per person, scopes, and testing mode — and where each is covered.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Get started
|
|
7
|
+
|
|
8
|
+
Every app on Northlight starts the same way: a person signs in with their Northlight account, your server stores a connection for them, and from then on it calls their runtime with `oauth.client(userId)`. The six sections of this site all build on that.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx @north-light/sdk@latest init my-app
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`init` writes a Node server, a signing key and an env file. [Quick setup](/docs/quickstart) takes it from there to a running app in about ten minutes. Using a coding agent? Tell it: *Read https://sdk.docs.northlight.ai/SKILL.md and follow it.* See [Use your coding agent](/docs/coding-agents).
|
|
15
|
+
|
|
16
|
+
Once a person has signed in, this is all it takes to use their runtime:
|
|
17
|
+
|
|
18
|
+
<include lang="ts">../../examples/apps/quickstart-server.ts#run</include>
|
|
19
|
+
|
|
20
|
+
## What to read, in order
|
|
21
|
+
|
|
22
|
+
| Page | What it covers |
|
|
23
|
+
|---|---|
|
|
24
|
+
| [Quick setup](/docs/quickstart) | From no account to an app that signs you in, starts a run and texts your phone |
|
|
25
|
+
| [Use your coding agent](/docs/coding-agents) | The `northlight` skill that `init` installs for Claude Code, Codex, Cursor and Copilot |
|
|
26
|
+
| [Where your app runs](/docs/how-it-fits) | Your server, the directory at `account.northlight.ai`, and each person's runtime |
|
|
27
|
+
| [Apps and sign-in](/docs/concepts/apps-and-sign-in) | What registering creates, the key pair, and the sign-in flow `OAuth2Client` runs |
|
|
28
|
+
| [Connections](/docs/concepts/connections) | What you store per person, token refresh, and refused connections |
|
|
29
|
+
| [Scopes and grants](/docs/concepts/scopes-and-grants) | What your app may ask for, what a person allowed, and a run's own scopes |
|
|
30
|
+
| [Testing mode](/docs/concepts/testing-mode) | You and up to 100 testers can sign in until the app is verified |
|
|
31
|
+
| [Test your app](/docs/guides/test-your-app) | Test your server against `@north-light/sdk/testing` without a network |
|
|
32
|
+
| [Manage your app](/docs/guides/manage-your-app) | The console's tabs: sign-in, scopes, profile, sharing, testers and provider |
|
|
33
|
+
| [Go live](/docs/guides/go-live) | Persistent storage, a real host, verification and the marketplace |
|
|
34
|
+
|
|
35
|
+
Then pick what your app does from the sections in the sidebar: [use our AI](/docs/use-our-ai), [use our apps](/docs/use-our-apps), [know the person](/docs/know-the-person), [reach people by text](/docs/reach-people-by-text), [let the person's AI use your app](/docs/let-their-ai-use-your-app), or [let other apps build on yours](/docs/build-on-your-app).
|
|
36
|
+
|
|
37
|
+
## Run `crtr cloud apps` yourself
|
|
38
|
+
|
|
39
|
+
Everything on this site works with the SDK's own commands and the web console. If you also run crouter, the agent runtime Northlight is built on, you can join your machine to your Northlight account and manage your apps with `crtr cloud apps`, or let your own crouter agents build and manage them.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install -g @north-light/cli
|
|
43
|
+
crtr sys join --directory https://account.northlight.ai --token <token>
|
|
44
|
+
crtr cloud apps mine
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The token comes from **Create join token** at `https://account.northlight.ai/account/machines`. The full steps, and what joining changes on your machine, are in [Join a machine to your Northlight account](https://crouter.docs.northlight.ai/docs/cli/join-northlight). The CLI is [`@north-light/cli`](https://www.npmjs.com/package/@north-light/cli) on npm, and crouter's own docs are at [crouter.docs.northlight.ai](https://crouter.docs.northlight.ai).
|
|
@@ -30,7 +30,7 @@ Four variables configure an app built on the SDK:
|
|
|
30
30
|
|
|
31
31
|
A new app is in testing: only you and up to 100 testers can sign in. To open it to everyone, ask Northlight to verify it by email to support@northlight.ai. Include your app's name and client ID, where it runs, and what it asks for and why. Until then, anyone else is refused with `app_in_testing`. See [Testing mode](/docs/concepts/testing-mode).
|
|
32
32
|
|
|
33
|
-
This site does not state how long verification takes or what Northlight checks beyond that email address
|
|
33
|
+
This site does not state how long verification takes or what Northlight checks beyond that email address.
|
|
34
34
|
|
|
35
35
|
## Rotate the key later
|
|
36
36
|
|
|
@@ -5,7 +5,7 @@ description: What each tab of the Northlight console does for an app you have re
|
|
|
5
5
|
|
|
6
6
|
# Manage your app
|
|
7
7
|
|
|
8
|
-
You manage an app in the console at `https://account.northlight.ai/console`. Choose your app in the list to open its page. The tabs are Sign-in, What it asks for, Profile, Sharing, Testers and Provider.
|
|
8
|
+
You manage an app in the console at `https://account.northlight.ai/console`. Choose your app in the list to open its page. The tabs are Sign-in, What it asks for, Profile, Sharing, Testers and Provider. **Provider** is where an app offers its own tools to people's agents and to other apps: see [Let their AI use your app](/docs/let-their-ai-use-your-app).
|
|
9
9
|
|
|
10
10
|
Your **client ID** is shown on the app's page. `npx @north-light/sdk register` writes it to `local/app.env`; for an app registered in the browser, use `npx @north-light/sdk env --client-id <client id>`.
|
|
11
11
|
|
|
@@ -22,7 +22,7 @@ The login cannot do these, and the CLI refuses them without a request:
|
|
|
22
22
|
- The provider role.
|
|
23
23
|
- On a verified app: signing keys, the JWKS URL, redirect URIs and the run notice URL.
|
|
24
24
|
|
|
25
|
-
Everything below names its `apps` command when there is one.
|
|
25
|
+
Everything below names its `apps` command when there is one.
|
|
26
26
|
|
|
27
27
|
## Sign-in
|
|
28
28
|
|
|
@@ -46,7 +46,7 @@ Until you retire the old key it is your rollback. After you retire it, a sign-in
|
|
|
46
46
|
- **What your app asks for.** The scopes people are asked to approve. **Add permissions** searches the catalog; take scope strings from it and from `providers.tools`, and do not invent them. From the terminal: `apps asks` lists what the app can ask for, and `apps set-scopes --add <scope>` or `--remove <scope>` changes the list. `crtr:act` needs `crtr:llm`. See [Scopes and grants](/docs/concepts/scopes-and-grants).
|
|
47
47
|
- **What your app requires.** Providers the app cannot work without (`apps set-requires`). A person is taken through that provider's setup the first time they sign in. See [Grant changes](/docs/guides/grant-changes#wait-on-a-provider-your-app-requires).
|
|
48
48
|
- **Monthly spend cap.** The most your app may spend of each person's AI subscription per month, in whole US dollars.
|
|
49
|
-
- **Run notice URL.** Where Northlight posts a signed notice when one of your app's background runs ends. Type it in **Notice URL** and choose **Save**; empty it and save to turn notices off. From the terminal: `apps set-run-notice-url` (apps in testing). The URL must be `https`, at most 512 characters, with no `#fragment`. The directory refuses a plain `http` URL with `run_notice_url` as the field. The field's hint says `http://localhost` is accepted while developing, but the production directory refuses it
|
|
49
|
+
- **Run notice URL.** Where Northlight posts a signed notice when one of your app's background runs ends. Type it in **Notice URL** and choose **Save**; empty it and save to turn notices off. From the terminal: `apps set-run-notice-url` (apps in testing). The URL must be `https`, at most 512 characters, with no `#fragment`. The directory refuses a plain `http` URL with `run_notice_url` as the field. The field's hint says `http://localhost` is accepted while developing, but the production directory refuses it, so test notices with a tunnel that gives you an `https` URL. What your app does with a notice is in [Background runs](/docs/guides/background-runs#run-notices).
|
|
50
50
|
|
|
51
51
|
## Profile
|
|
52
52
|
|
|
@@ -75,6 +75,6 @@ Once your app is live you can keep developing on your laptop against production
|
|
|
75
75
|
|
|
76
76
|
On the **Profile** tab, the **Delete this app** card lists what goes: every person's connection to the app, yours included (each person's runtime deletes the app's runs, space and schedules), the app's sign-ins and keys, and its testers and marketplace listing. This cannot be undone, and the client ID is never reused.
|
|
77
77
|
|
|
78
|
-
To delete, type the app's full name in **Type the app's name, *name*, to confirm**. **Delete app** stays disabled until what you typed matches the name (surrounding spaces are ignored), and the directory checks the name again when you submit. After it deletes, the console returns to your app list.
|
|
78
|
+
To delete, type the app's full name in **Type the app's name, *name*, to confirm**. **Delete app** stays disabled until what you typed matches the name (surrounding spaces are ignored), and the directory checks the name again when you submit. After it deletes, the console returns to your app list. After that, `/authorize` with its client ID shows "We couldn't start that sign-in" (HTTP 400).
|
|
79
79
|
|
|
80
80
|
The card is not shown for a provider or a first-party app, and the directory refuses to delete a provider (`app_is_provider`). If you only want a clean slate for tests, changing the app's redirect URIs and keys is often simpler.
|
package/docs/apps/how-it-fits.md
CHANGED
|
@@ -43,4 +43,4 @@ The person's AI subscription pays for model calls, and what your app may do on t
|
|
|
43
43
|
|
|
44
44
|
You operate your server, its sessions, its database and its `ConnectionStore`. You register the app in the console and keep its key pair. Northlight operates the directory and the runtimes; you do not run either, and there is no local Northlight to start. If you run crouter yourself and want a runtime of your own, that is a different path: see [crouter.docs.northlight.ai](https://crouter.docs.northlight.ai).
|
|
45
45
|
|
|
46
|
-
The directory's discovery document at `https://account.northlight.ai/.well-known/openid-configuration` lists the endpoints, the `S256` PKCE method and `private_key_jwt` as the only token authentication method
|
|
46
|
+
The directory's discovery document at `https://account.northlight.ai/.well-known/openid-configuration` lists the endpoints, the `S256` PKCE method and `private_key_jwt` as the only token authentication method.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Let your app know the person
|
|
3
|
+
description: Learn who the person is and what they care about from their first sign-in, with the context provider and their public documents.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Let your app know the person
|
|
7
|
+
|
|
8
|
+
A person who signs in to your app already has a Northlight agent that knows them. Your app can ask it about them from the first sign-in, so onboarding needs fewer questions and the product fits them sooner.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
const runtime = await oauth.client(userId);
|
|
12
|
+
const advice = await runtime.providers.call({
|
|
13
|
+
provider: 'context',
|
|
14
|
+
tool: 'ask informed', // pass the name exactly as providers.tools('context') lists it
|
|
15
|
+
arguments: {request: 'Suggest the first three topics for this person\'s reading list.'},
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`ask informed` (scope `context:ask_informed`) answers from everything their agent knows, private memories included, without handing you private details. `ask public` (scope `context:ask_public`) answers from their public memories only.
|
|
20
|
+
|
|
21
|
+
## Guides
|
|
22
|
+
|
|
23
|
+
| Page | What it covers |
|
|
24
|
+
|---|---|
|
|
25
|
+
| [Context](/docs/providers/context) | The context provider's scopes, setup and tools, including public profile lookups |
|
|
26
|
+
| [Files and documents](/docs/guides/files-and-documents) | Read the documents the person made public with `memory.list` and `memory.get`, with no scope |
|
|
27
|
+
| [Providers](/docs/concepts/providers#providers-your-app-requires) | Require `context` so the person sets it up at first sign-in |
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Let the person's AI use your app
|
|
3
|
+
description: Make your app a provider so its tools show up in the person's chat and terminal agents. Define commands with @north-light/plugin, serve them over HTTP, and add the provider role in the console.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Let the person's AI use your app
|
|
7
|
+
|
|
8
|
+
Your app can be a provider: it offers tools, and once a person connects it, every agent they run (in Northlight chat, in their terminal, and in other apps that ask for it) can call them. You define the tools once with [`@north-light/plugin`](https://www.npmjs.com/package/@north-light/plugin) and serve them from your own server.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import {createFetchHandler, defineLeaf, definePlugin, field, param} from '@north-light/plugin';
|
|
12
|
+
|
|
13
|
+
export const plugin = definePlugin({
|
|
14
|
+
name: 'acme',
|
|
15
|
+
provider: true,
|
|
16
|
+
version: 1,
|
|
17
|
+
description: 'Manage Acme orders.',
|
|
18
|
+
whenToUse: 'you need to look up an Acme order.',
|
|
19
|
+
summary: 'Acme orders',
|
|
20
|
+
rootEntry: {concept: 'an Acme order', description: 'Look up orders.', whenToUse: 'the task is about an Acme order.'},
|
|
21
|
+
groups: {read: {consentLine: 'Read your Acme orders.'}},
|
|
22
|
+
commands: {
|
|
23
|
+
order: defineLeaf({
|
|
24
|
+
group: 'read',
|
|
25
|
+
description: 'Show one order.',
|
|
26
|
+
whenToUse: 'you have an order id.',
|
|
27
|
+
summary: 'show an order',
|
|
28
|
+
params: {id: param.positional('The order id.', {required: true})},
|
|
29
|
+
output: {status: field.string('The order status.')},
|
|
30
|
+
effects: ['Reads one order.'],
|
|
31
|
+
handler: (input, ctx) => ({status: 'shipped'}), // ctx.caller.sub is the person who connected
|
|
32
|
+
}),
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export default createFetchHandler(plugin, {
|
|
37
|
+
auth: {issuer: 'https://account.northlight.ai', audience: 'https://acme.example.com/crtr', providerId: process.env.CROUTER_CLIENT_ID!},
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Each group in `groups` is a scope named `<your client id>:<group>`, and its `consentLine` is what the consent page shows. Every request carries a token the directory minted for one person; the handler checks it and the group's scope before your code runs.
|
|
42
|
+
|
|
43
|
+
## The steps
|
|
44
|
+
|
|
45
|
+
1. **Define the tools** with `definePlugin({provider: true, version, groups, commands})`. Every leaf names its `group`.
|
|
46
|
+
2. **Serve them** at an HTTPS URL. `createFetchHandler` is a standard Fetch handler; `createNodeHandler` serves the same plugin from Node's `http` server.
|
|
47
|
+
3. **Add the provider role.** In the console, open your app's **Provider** tab, fill in **Offer tools to other apps** with your **Endpoint URL** (and an optional **Manage URL**, where people manage their connection), and choose **Add provider role**. The directory fetches your manifest and saves the groups it declares. After a change, choose **Refresh manifest**.
|
|
48
|
+
4. **Set a price**, if you charge, on the same tab: free, a price per unit, or the cost your provider reports, plus a free monthly allowance per person.
|
|
49
|
+
|
|
50
|
+
## Who may use a group
|
|
51
|
+
|
|
52
|
+
A group's `who` says who may be granted it: `own` (only your own app), `user` (the default), `allowlist` (the apps listed in `allowlist`), `any`, or `team:<id>`. The directory applies `own` and `team:<id>`; `user`, `allowlist` and `any` are stored but not yet enforced at consent.
|
|
53
|
+
|
|
54
|
+
## Guides
|
|
55
|
+
|
|
56
|
+
These live on the crouter docs site, because the same package also adds commands to a self-run crouter:
|
|
57
|
+
|
|
58
|
+
| Page | What it covers |
|
|
59
|
+
|---|---|
|
|
60
|
+
| [Plugin docs](https://crouter.docs.northlight.ai/docs/plugin) | What `@north-light/plugin` does and how a plugin is installed |
|
|
61
|
+
| [Commands](https://crouter.docs.northlight.ai/docs/plugin/commands) | Branches, leaves, parameters, outputs, groups and `who` |
|
|
62
|
+
| [Deploying](https://crouter.docs.northlight.ai/docs/plugin/deploying) | `auth: {issuer, audience, providerId}`, `ctx.caller`, versions and breaking changes |
|
|
63
|
+
| [Manage your app](/docs/guides/manage-your-app) | The console's **Provider** tab beside the others |
|
|
@@ -25,4 +25,4 @@ A provider is a service the person's runtime calls for your app. Your app asks t
|
|
|
25
25
|
|
|
26
26
|
<include lang="ts">../../../examples/apps/provider-tools.ts</include>
|
|
27
27
|
|
|
28
|
-
Each provider page below shows the tools of a provider as
|
|
28
|
+
Each provider page below shows the tools of a provider as listed on **2026-10-16** by a person's own Northlight runtime, so it shows the groups that person's own grant holds, not an app's view. What `providers.tools` answers for your app depends on the scopes your app was granted. Tools can change between releases, so treat a table as a starting point and list the tools at run time.
|
|
@@ -9,13 +9,13 @@ The `context` provider answers questions about the person from what their agent
|
|
|
9
9
|
|
|
10
10
|
## Scopes and setup
|
|
11
11
|
|
|
12
|
-
Scopes are `context:<group>`. The console's **Add permissions** list shows `context:ask_informed` and `context:ask_public` on 2026-10-16; the tool list also shows a `research` group (`context:research`)
|
|
12
|
+
Scopes are `context:<group>`. The console's **Add permissions** list shows `context:ask_informed` and `context:ask_public` on 2026-10-16; the tool list also shows a `research` group (`context:research`). It was not in that console list on that date, so check that **Add permissions** offers it before your app depends on it.
|
|
13
13
|
|
|
14
14
|
Context needs setup before it works: the person gives a profile URL on the provider's setup page, and its state stays `pending` for a few minutes afterwards. If your app depends on it, add `context` under **What your app requires** and follow the state with `grant.get().dependencies['context']`. See [Grant changes](/docs/guides/grant-changes#wait-on-a-provider-your-app-requires).
|
|
15
15
|
|
|
16
16
|
## Tools
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Tools as listed on 2026-10-16 (provider major version 1). `*` marks a required parameter. Tool names with a space are written as the provider lists them; pass a multi-word `tool` to `providers.call` exactly as your own `providers.tools` output lists it.
|
|
19
19
|
|
|
20
20
|
| Tool | Group | Parameters | What it does |
|
|
21
21
|
|---|---|---|---|
|
|
@@ -5,7 +5,7 @@ description: "Reach the person's Mac from your app: browser, files, Messages and
|
|
|
5
5
|
|
|
6
6
|
# Device
|
|
7
7
|
|
|
8
|
-
The `device` provider reaches the person's own Mac. Its tools run on the person's machine (the provider's transport is `machine`), and each group is its own scope, so ask only for the groups your app needs.
|
|
8
|
+
The `device` provider reaches the person's own Mac. Its tools run on the person's machine (the provider's transport is `machine`), and each group is its own scope, so ask only for the groups your app needs. When the person has more than one registered Mac, a call must name the one to use with `machine` (`providers.call({provider: 'device', tool, arguments, machine})`); without it the runtime refuses with `machine_required` (except `browser libs`, which uses the most recently seen Mac).
|
|
9
9
|
|
|
10
10
|
## Scopes
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ The `device` provider reaches the person's own Mac. Its tools run on the person'
|
|
|
13
13
|
|
|
14
14
|
## Tools
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Tools as listed on 2026-10-16 (provider major version 2, transport `machine`). `*` marks a required parameter.
|
|
17
17
|
|
|
18
18
|
| Group (scope) | Tools |
|
|
19
19
|
|---|---|
|
|
@@ -23,4 +23,4 @@ Captured 2026-10-16 from `GET /v1/providers/device/tools` on a joined runtime (p
|
|
|
23
23
|
| `messages_send` | `messages send` (`recipient`\*, `text`\*, `file`, `service`) |
|
|
24
24
|
| `shell` | `shell run` (`command`\*, `cwd`, `timeout`, `stdin`) |
|
|
25
25
|
|
|
26
|
-
Tool names with spaces are written as the provider lists them;
|
|
26
|
+
Tool names with spaces are written as the provider lists them; pass them to `providers.call` exactly as your own `providers.tools` output lists them. The table shows a person's own grant, not an app's. Run `runtime.providers.tools('device')` for the list your app can use.
|
|
@@ -16,7 +16,7 @@ Scope strings come from **What it asks for → Add permissions** (provider `inte
|
|
|
16
16
|
|
|
17
17
|
## Find the tool you need
|
|
18
18
|
|
|
19
|
-
The provider has thousands of tools: on 2026-10-16
|
|
19
|
+
The provider has thousands of tools: on 2026-10-16 one runtime listed 3,061 tools across 3,060 groups, one `_read` group and one `_write` group per service, plus `discover` and `link`. This page does not table them. List them from your app:
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
22
|
const integrations = await runtime.providers.tools('integrations');
|
|
@@ -13,7 +13,7 @@ Each scope is `search:<group>`: `search:search`, `search:answer`, `search:conten
|
|
|
13
13
|
|
|
14
14
|
## Tools
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Tools as listed on 2026-10-16 (provider major version 1). `*` marks a required parameter.
|
|
17
17
|
|
|
18
18
|
| Tool | Group (scope) | Parameters | What it does |
|
|
19
19
|
|---|---|---|---|
|
|
@@ -14,7 +14,7 @@ The `sms` provider sends a text from Northlight's number to the verified phone o
|
|
|
14
14
|
| Scope | Consent sentence | Gates |
|
|
15
15
|
|---|---|---|
|
|
16
16
|
| `sms:send` | Send you text messages from Northlight's number | `send`, `react` |
|
|
17
|
-
| `sms:status` | Not
|
|
17
|
+
| `sms:status` | Not listed | `status` |
|
|
18
18
|
|
|
19
19
|
Add them under **What it asks for → Add permissions** (provider `sms`). Without `sms:send` the consent page does not offer it and `providers.call` for `sms` is refused with `scope_missing`.
|
|
20
20
|
|
|
@@ -24,11 +24,11 @@ Add them under **What it asks for → Add permissions** (provider `sms`). Withou
|
|
|
24
24
|
await runtime.providers.call({provider: 'sms', tool: 'send', arguments: {body: 'Your summary is ready.'}});
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
`body` is required. The text goes from Northlight's number to the person's verified phone, and each person can receive at most 50 texts from your app per UTC day.
|
|
27
|
+
`body` is required. The text goes from Northlight's number to the person's verified phone, and each person can receive at most 50 texts from your app per UTC day.
|
|
28
28
|
|
|
29
29
|
## Tools
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Tools as listed on 2026-10-16 (provider major version 1). `*` marks a required parameter.
|
|
32
32
|
|
|
33
33
|
| Tool | Group (scope) | Parameters | What it does |
|
|
34
34
|
|---|---|---|---|
|
package/docs/apps/quickstart.md
CHANGED
|
@@ -9,19 +9,19 @@ description: From no account to a running app that signs a person in with Northl
|
|
|
9
9
|
npx @north-light/sdk@latest init my-app
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
This command creates a small Node server, a signing key and an env file. About ten minutes later you have an app on your laptop that signs you in with Northlight, starts an agent run on your own Northlight runtime, and texts your phone. The app runs on your machine and talks to Northlight's production directory at `https://account.northlight.ai`. There is no local Northlight stack to run
|
|
12
|
+
This command creates a small Node server, a signing key and an env file. About ten minutes later you have an app on your laptop that signs you in with Northlight, starts an agent run on your own Northlight runtime, and texts your phone. The app runs on your machine and talks to Northlight's production directory at `https://account.northlight.ai`. There is no local Northlight stack to run. To run crouter on your own machine as well, see [Get started](/docs/get-started#run-crtr-cloud-apps-yourself).
|
|
13
13
|
|
|
14
14
|
You need Node.js 20.6 or later (the start command uses `--env-file`) and a phone that can receive iMessage. The server was run on Node 20.6, 20.20, 22.14, 22.22 and 26.12.
|
|
15
15
|
|
|
16
16
|
Using a coding agent? Tell it: *Read https://sdk.docs.northlight.ai/SKILL.md and follow it.* It runs every command below; you sign up, then choose **Allow** twice in your browser. See [Use your coding agent](/docs/coding-agents).
|
|
17
17
|
|
|
18
|
-
Each step below ends with what you should see when it worked.
|
|
18
|
+
Each step below ends with what you should see when it worked.
|
|
19
19
|
|
|
20
20
|
## 1. Create an account
|
|
21
21
|
|
|
22
22
|
Open `https://account.northlight.ai/signup` and create your account. Signup texts a confirmation code to your phone, and that text is sent over iMessage. A number that cannot receive iMessage gets "We couldn't send the text", and retrying does not help. One phone number belongs to one account.
|
|
23
23
|
|
|
24
|
-
You should see: your account's page after you enter the code. Opening `https://account.northlight.ai/console` while signed in shows the console, where your apps are listed.
|
|
24
|
+
You should see: your account's page after you enter the code. Opening `https://account.northlight.ai/console` while signed in shows the console, where your apps are listed.
|
|
25
25
|
|
|
26
26
|
## 2. Scaffold the app
|
|
27
27
|
|
|
@@ -49,8 +49,6 @@ You should see, on the terminal: `Created a Northlight app in my-app:` with the
|
|
|
49
49
|
|
|
50
50
|
Only the browser registration below uses that line: `register` reads the public half from `local/app-key.json` itself. If a file already exists, `init` refuses, names it and exits non-zero without writing anything.
|
|
51
51
|
|
|
52
|
-
Checked on production: `npx @north-light/sdk@latest init my-app` (npm `latest` 0.3.476) in an empty directory with no crtr on `PATH` printed this output and wrote these files, the private key has mode `0600`, and `server.ts` is the one listed at the end of this page. Running it again names the skill file and writes nothing.
|
|
53
|
-
|
|
54
52
|
## 3. Log in
|
|
55
53
|
|
|
56
54
|
```bash
|
|
@@ -89,8 +87,6 @@ and "Done. Go back to your terminal." in the browser. The name, id and dates are
|
|
|
89
87
|
|
|
90
88
|
The login is saved outside your project, in `~/.config/northlight/credentials.json` (mode `0600`). Never commit, paste or print it.
|
|
91
89
|
|
|
92
|
-
Checked on production: this whole step, including the confirm page and its wording. The confirm page reads "Let a coding agent manage your Northlight apps?", shows the code, the computer's name and platform and the address it asked from ("The computer named itself; Northlight did not check it"), and lists what the login can and can't do. After **Allow** the page reads "Done / Go back to your terminal." and the terminal prints the output above.
|
|
93
|
-
|
|
94
90
|
If you run `login` again, it does not start over. While a code is pending it prints "Still waiting for the login started at HH:MM." with the same link and code. Once you are logged in it prints "Already logged in as …" and exits 0. If the code expired unapproved it exits 1 and says so: run it again for a new code. See [the CLI reference](/docs/cli#login-logout-whoami).
|
|
95
91
|
|
|
96
92
|
If `login` cannot reach `account.northlight.ai`, or you would rather use the browser, skip to [Register in the browser instead](#register-in-the-browser-instead).
|
|
@@ -118,8 +114,6 @@ Next: npm i && npm start, then open http://localhost:3000/auth/login
|
|
|
118
114
|
|
|
119
115
|
`local/app.env` now has all four settings. The name, client ID and key ID are examples. Change the defaults with `--name`, `--logo`, `--justification` and `--redirect-uri`; the default logo is a placeholder, `https://sdk.docs.northlight.ai/app-logo.png`. `register` refuses when `CROUTER_CLIENT_ID` is already set. A login can register at most 10 apps a day.
|
|
120
116
|
|
|
121
|
-
Checked on production: this step, including that the directory accepts the default logo.
|
|
122
|
-
|
|
123
117
|
## 5. Run it
|
|
124
118
|
|
|
125
119
|
```bash
|
|
@@ -131,8 +125,6 @@ node --env-file=local/app.env --import tsx server.ts
|
|
|
131
125
|
|
|
132
126
|
Open `http://localhost:3000/auth/login`. Your browser goes to `account.northlight.ai`. Sign in if asked, read the consent page, and choose Allow. You land back on `http://localhost:3000/` with "Signed in" and your Northlight user id. Press **Start a run and send me a text**. The page answers "Done", shows the run's status `idle`, the run's reply (`pong`) and the text's `message_id`, and your phone receives "Hello from my first Northlight app." from Northlight's number.
|
|
133
127
|
|
|
134
|
-
Checked on production, as the account that owns the app: the server starts (with `npm start` too), `/` shows the sign-in link, and `/auth/login` answers `303` to `https://account.northlight.ai/authorize?client_id=…&scope=openid+profile+crtr%3Allm+crtr%3Aact+sms%3Asend…&code_challenge_method=S256…`. The consent page listed the four permissions and the monthly cap, **Allow** returned to `http://localhost:3000/` with "Signed in" and the user id, and the button page answered "Done" with status `idle` and a `message_id` for the text. In the console the key then read "Last used just now". Not yet checked on production: that the text reached the phone (the `message_id` is the provider's answer, not a delivery receipt), and the `426` case. The `pong` reply is read through `runs.reply` and has not been run on production since this example changed. Signing in as a second person needs a second account and is not covered here.
|
|
135
|
-
|
|
136
128
|
If `/` shows "One step left", `CROUTER_CLIENT_ID` is empty: run `npx @north-light/sdk register` (or, for an app you registered in the browser, `env --client-id`) and restart. If a call fails with `426 runtime_version_unsupported`, your SDK is newer than the Northlight runtimes. Install the previous version with `npm i --save-exact @north-light/sdk@<version>` and tell support@northlight.ai.
|
|
137
129
|
|
|
138
130
|
## 6. What next
|
|
@@ -163,16 +155,12 @@ Choose **Register app**.
|
|
|
163
155
|
|
|
164
156
|
You should see: a page titled "*your app's name* is registered" with a **Client ID** and, under it, the key ID of the key you pasted. Copy the client ID, then choose **Continue to *your app's name***. If it says "Next: add your app's public key on the Sign-in tab", the key was left out: open the app's **Sign-in** tab and choose **Add key**. The app starts asking for `crtr:llm` and `crtr:act`.
|
|
165
157
|
|
|
166
|
-
Checked on production: these field labels, registering with a pasted key, and the app page opening in testing with that key active and `crtr:llm` and `crtr:act` listed. The "Next: add your app's public key" message, which shows when the key is left out, is not yet checked on production.
|
|
167
|
-
|
|
168
158
|
### Add the permission to text
|
|
169
159
|
|
|
170
160
|
On the app's page, open the **What it asks for** tab and choose **Add permissions**. Choose **Texting**, tick `sms:send` ("Send you text messages from Northlight's number"), and choose **Done**. Then choose **Save** under the list: **Done** only closes the dialog, and the change is not stored until you save.
|
|
171
161
|
|
|
172
162
|
You should see: `sms:send` under what your app asks for after **Save** says "Saved", next to `crtr:llm` and `crtr:act`. The server in this guide asks for all three, so without `sms:send` the consent page does not offer it and the text in step 5 is refused. Take scope strings from this list. Do not invent them. See [Scopes and grants](/docs/concepts/scopes-and-grants).
|
|
173
163
|
|
|
174
|
-
Checked on production: after **Save** and a reload, the tab lists `crtr:llm` and `crtr:act` under Agents and `sms:send` under Texting, and the consent page in step 5 offered the text permission.
|
|
175
|
-
|
|
176
164
|
### Write the client ID into the env file
|
|
177
165
|
|
|
178
166
|
```bash
|
|
@@ -191,8 +179,6 @@ Key file: local/app-key.json (set CROUTER_KEY_FILE to change it).
|
|
|
191
179
|
|
|
192
180
|
`local/app.env` now has all four settings. The command makes no network call and keeps every other line in the file. Add `--origin <url>` if your app does not run on `http://localhost:3000`.
|
|
193
181
|
|
|
194
|
-
Checked on production: this output, and that the command works in a directory with no `local/` yet. `--origin` is not yet checked on production.
|
|
195
|
-
|
|
196
182
|
## The server `init` writes
|
|
197
183
|
|
|
198
184
|
This is `examples/apps/quickstart-server.ts`. The SDK reads no environment: the server passes the values in.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Reach people by text
|
|
3
|
+
description: Give your app its own iMessage number with Comms. People text it, your server answers with an agent run on their runtime, and you can text them again later.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Reach people by text
|
|
7
|
+
|
|
8
|
+
Comms gives your app its own iMessage number, under your app's name and avatar. People text that number, Comms sends each text to your server as a signed webhook, and your server answers with an agent run on the person's own runtime. Once a person has texted you, your app can text them again later, for example from a timer.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import {continueInRuntime, formatReply, verifyWebhook} from '@north-light/comms';
|
|
12
|
+
|
|
13
|
+
const event = verifyWebhook(req.headers, rawBody, [process.env.COMMS_WEBHOOK_SECRET!]);
|
|
14
|
+
if (event.type === 'message.received' && event.data.content.type === 'text') {
|
|
15
|
+
const {contact, content} = event.data;
|
|
16
|
+
if (!contact.user) return; // only a sender texting from an Apple ID email has no user
|
|
17
|
+
const client = await oauth.client(contact.user.id); // their Northlight user id, the same as Connection.userId
|
|
18
|
+
const {runId, reply} = await continueInRuntime({client, message: content.text, runId: runs.get(contact.id), idempotencyKey: event.id});
|
|
19
|
+
runs.set(contact.id, runId); // later texts continue the same run
|
|
20
|
+
const {text} = await reply.collect();
|
|
21
|
+
for (const part of formatReply(text)) {
|
|
22
|
+
await comms.sendMessage({environment: event.environment, to: {contact_id: contact.id}, text: part, idempotency_key: `reply:${event.id}:${part.length}`});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`oauth.client` throws `CrouterError` with code `not_connected` when the person has not signed in to your app yet. Answer that with `sendSignInLink(comms, contact, {environment: event.environment})`: Comms texts them a link that signs them in to your app, which lands on your **Sign-in start URL** (console → **Profile** → **Marketplace**).
|
|
28
|
+
|
|
29
|
+
## The steps
|
|
30
|
+
|
|
31
|
+
The [Comms guide for coding agents](https://comms.northlight.ai/llms.txt) is the whole reference: the webhook events, the send API, its errors, STOP and HELP handling, and the `crtr comms` commands. In short:
|
|
32
|
+
|
|
33
|
+
1. **Build in fake mode.** `npx @north-light/comms fake --webhook http://localhost:3000/hook` runs a local Comms with no account. `npx @north-light/comms fake send --from +15550001 --text "hi"` plays a person texting you.
|
|
34
|
+
2. **Register your app on Northlight.** [Quick setup](/docs/quickstart) steps 1 to 4: sign up, `npx @north-light/sdk login`, `npx @north-light/sdk register`. Comms signs in with the same app key.
|
|
35
|
+
3. **Connect the app to Comms.** At `https://comms.northlight.ai`, sign in and choose **Connect an app**. This is done in a browser only.
|
|
36
|
+
4. **Turn Texting on.** On the app's page there, or with `crtr comms turn-on`: a display name, a square avatar, the HELP text and your test webhook URL. The page shows the test webhook signing secret.
|
|
37
|
+
5. **Text it from your own phone, in test mode.** Add yourself as a tester (`crtr comms testers add --app-id <id> --phone <number> --label <name>`, or the site), then text `JOIN <code>` to the test number. Test mode is free; the [Comms guide](https://comms.northlight.ai/llms.txt) has the tester limit.
|
|
38
|
+
6. **Go to production** when you want your app's own number and anyone to text it. Production is paid: add a card on the billing account, and Comms gets your app its own number.
|
|
39
|
+
|
|
40
|
+
Comms is priced per person your app texts with in production each month; fake mode and testing are free. The SDK is [`@north-light/comms`](https://www.npmjs.com/package/@north-light/comms) on npm. Its 0.3.0 release declares `@north-light/sdk` 0.3.457 as an exact optional peer, so in a project pinned to a newer SDK install it with `npm i @north-light/comms --legacy-peer-deps`.
|
|
41
|
+
|
|
42
|
+
## Rules
|
|
43
|
+
|
|
44
|
+
- **People text first.** Your app can text a person only after they texted your number in that environment, and until they send STOP. A send to anyone else fails `403 not_texted_first`.
|
|
45
|
+
- **Address people by `contact_id` or `user_id`**, never by phone number.
|
|
46
|
+
- **Derive `idempotency_key` from the event you are answering**, so a retried webhook sends nothing twice. Deduplicate deliveries on `event.id`.
|
|
47
|
+
- **Verify the raw body** with `verifyWebhook` before you parse it, and answer `2xx` within 15 seconds.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Let your app use our AI
|
|
3
|
+
description: Start agent runs on each person's own Northlight runtime, with their memory, files and tools, paid by their AI subscription. Typed results, streaming, background runs and documents.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Let your app use our AI
|
|
7
|
+
|
|
8
|
+
Your app starts agents on the person's own Northlight runtime. Each run has their memory, files and tools, works under the scopes they approved, and its model calls are paid by their AI subscription, not by you.
|
|
9
|
+
|
|
10
|
+
<include lang="ts">../../examples/apps/runs-parse.ts</include>
|
|
11
|
+
|
|
12
|
+
`runs.parse` starts a run and returns a value checked against your schema. `runs.start` returns at once and lets you follow the run, reply to it or leave it running.
|
|
13
|
+
|
|
14
|
+
## Guides
|
|
15
|
+
|
|
16
|
+
| Page | What it covers |
|
|
17
|
+
|---|---|
|
|
18
|
+
| [Runs](/docs/concepts/runs) | Start a run, its status and outcome, a run's own scopes, and how to bound one |
|
|
19
|
+
| [Typed results](/docs/guides/typed-results) | Get a value back with `runs.parse` and a schema; never parse the trace |
|
|
20
|
+
| [Stream a run](/docs/guides/stream-a-run) | Show the agent's text and tool calls as they happen |
|
|
21
|
+
| [Background runs](/docs/guides/background-runs) | Learn when a run you did not wait on has ended, with `RunWatcher` or run notices |
|
|
22
|
+
| [Files and documents](/docs/guides/files-and-documents) | Download a file from a run, and read the person's public documents |
|
|
23
|
+
| [Many users](/docs/guides/many-users) | Keep each person's runtime separate when people meet in your app |
|
|
24
|
+
|
|
25
|
+
To schedule work, call `runs.start` from your own timer. A run's agent may also schedule itself with `crtr cron add` when the run holds `crtr:schedule` ([Scopes and grants](/docs/concepts/scopes-and-grants)).
|
|
26
|
+
|
|
27
|
+
An app that pays for its own model calls instead can serve them from its own service with `inferenceEndpoint` from `@north-light/sdk`; see the [release notes](/docs/release-notes) and the [reference](/docs/reference).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Let your app use our apps
|
|
3
|
+
description: Call Northlight's providers from your app on the person's runtime — texting their phone, web search, their connected accounts, their Mac — with providers.tools and providers.call.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Let your app use our apps
|
|
7
|
+
|
|
8
|
+
Northlight's own apps are providers your app can call on the person's runtime: text their phone, place calls, search the web, open a cloud browser, read and act in the accounts they connected, and use their Mac. The person approves each provider's scope once, on your app's consent page.
|
|
9
|
+
|
|
10
|
+
<include lang="ts">../../examples/apps/provider-tools.ts</include>
|
|
11
|
+
|
|
12
|
+
Every provider works the same way: ask for its scope, list its tools with `providers.tools('<provider>')`, then call one with `providers.call`. Scope strings, tool names and arguments come from those lists, never from memory.
|
|
13
|
+
|
|
14
|
+
## Providers
|
|
15
|
+
|
|
16
|
+
| Provider id | What it does | Page |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `sms` | Texts the signed-in person's own verified phone | [Texting (sms)](/docs/providers/sms) |
|
|
19
|
+
| `search` | Web search, sourced answers, page contents and paid data endpoints | [Search](/docs/providers/search) |
|
|
20
|
+
| `integrations` | The person's own accounts at other services | [Integrations](/docs/providers/integrations) |
|
|
21
|
+
| `context` | Ask about the person from their memory, and look up public profiles | [Context](/docs/providers/context) |
|
|
22
|
+
| `device` | The person's Mac: browser, files, Messages and shell | [Device](/docs/providers/device) |
|
|
23
|
+
|
|
24
|
+
These five have pages here. Northlight also runs `phone` (calls from Northlight's number, with an AI voice), `browser` (cloud browser sessions) and `meetings` (the person's meeting notes and transcripts), which have no page yet. For any of them, `providers.tools()` with no argument lists every provider installed on the person's runtime, `providers.tools('<provider>')` lists its tools and arguments, and the console's **Add permissions** list shows every scope your app can ask for.
|
|
25
|
+
|
|
26
|
+
## Guides
|
|
27
|
+
|
|
28
|
+
| Page | What it covers |
|
|
29
|
+
|---|---|
|
|
30
|
+
| [Providers](/docs/concepts/providers) | Scopes, finding and calling tools, and providers your app requires |
|
|
31
|
+
| [Providers index](/docs/providers) | Every first-party provider, its scopes and where names come from |
|
|
32
|
+
| [Grant changes](/docs/guides/grant-changes) | When a person adds or removes a scope, and waiting on a provider's setup |
|
|
@@ -5,7 +5,7 @@ description: Join a laptop to your Northlight account with crtr sys join so crtr
|
|
|
5
5
|
|
|
6
6
|
# Join a machine to your Northlight account
|
|
7
7
|
|
|
8
|
-
Joining makes this machine one of your Northlight account's machines, so `crtr cloud …` commands run as you. Building an app
|
|
8
|
+
Joining makes this machine one of your Northlight account's machines, so `crtr cloud …` commands run as you. Join when you want to run `crtr cloud apps` yourself, or to let your own crtr agents build and manage your Northlight apps. Building an app works without it too: the [SDK docs site](https://sdk.docs.northlight.ai/docs/get-started) uses `npx @north-light/sdk` and the web console.
|
|
9
9
|
|
|
10
10
|
Create your account at `https://account.northlight.ai/signup` first. Then install the CLI (`npm i -g @north-light/cli`). Joining needs `crtr` 0.3.436 or later (older versions need `crtr sys daemon stop` first and fail if a viewer is open); `crtr --version` shows yours.
|
|
11
11
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.544",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
},
|
|
141
141
|
"license": "UNLICENSED",
|
|
142
142
|
"dependencies": {
|
|
143
|
-
"@north-light/identity": "0.3.
|
|
143
|
+
"@north-light/identity": "0.3.544",
|
|
144
144
|
"@earendil-works/pi-agent-core": "1.1.0",
|
|
145
145
|
"@earendil-works/pi-ai": "1.1.0",
|
|
146
146
|
"@earendil-works/pi-coding-agent": "1.1.0",
|