@north-light/sdk 0.3.485 → 0.3.486
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/README.md +1 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.js +2 -1
- package/dist/oauth/index.d.ts +11 -0
- package/dist/oauth/index.js +21 -0
- package/dist/resources/memory.d.ts +6 -4
- package/dist/resources/memory.js +5 -3
- package/dist/skill/northlight/SKILL.md +2 -2
- package/dist/testing/cloud.d.ts +3 -0
- package/dist/testing/cloud.js +7 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -137,7 +137,7 @@ const {text, ended, error} = await client.runs.reply(run.run_id, run.message!).c
|
|
|
137
137
|
|
|
138
138
|
A run working in the background reports what it is doing on `runs.get(runId).activity` (`starting`, `thinking`, `tool` with `tool.name` and `tool.summary`, `writing`, or `between_turns`; `null` once it is no longer `running`), so a polling page shows progress without reading `runs.trace`.
|
|
139
139
|
|
|
140
|
-
`runs.listAll(filters)` and `memory.listAll(params)` (the person's knowledge and preference documents the caller can read: `public` by default, every privacy level with `crtr:memory:manage:user`) iterate every item across pages with `for await`, fetching the next page only as you go. `runs.delete(runId)` deletes a running run too — it stops the run's turns and sandboxes itself, so there is no need to `cancel` first; deleting a run that is already gone throws `NotFoundError`.
|
|
140
|
+
`runs.listAll(filters)` and `memory.listAll(params)` (the person's knowledge and preference documents the caller can read: `public` by default, `private` too with `crtr:memory:read_private:user`, every privacy level with `crtr:memory:manage:user`) iterate every item across pages with `for await`, fetching the next page only as you go. `runs.delete(runId)` deletes a running run too — it stops the run's turns and sandboxes itself, so there is no need to `cancel` first; deleting a run that is already gone throws `NotFoundError`.
|
|
141
141
|
|
|
142
142
|
## Read files and run bash
|
|
143
143
|
|
package/dist/client.d.ts
CHANGED
|
@@ -124,7 +124,8 @@ export declare class Crouter {
|
|
|
124
124
|
readonly shares: Shares;
|
|
125
125
|
/** Questions agents in runs ask the user (app listener only). */
|
|
126
126
|
readonly questions: Questions;
|
|
127
|
-
/** Read the documents the person owns (`store: 'user'`): an app sees their `public` documents,
|
|
127
|
+
/** Read the documents the person owns (`store: 'user'`): an app sees their `public` documents, `private` ones too while the grant holds
|
|
128
|
+
* `crtr:memory:read_private:user` (read-only; `friends` never), and every privacy level with a `crtr:memory:manage:user` grant. */
|
|
128
129
|
readonly memory: Memory;
|
|
129
130
|
/** Scope-filtered provider tools and daemon-mediated calls. */
|
|
130
131
|
readonly providers: Providers;
|
package/dist/client.js
CHANGED
|
@@ -63,7 +63,8 @@ export class Crouter {
|
|
|
63
63
|
shares;
|
|
64
64
|
/** Questions agents in runs ask the user (app listener only). */
|
|
65
65
|
questions;
|
|
66
|
-
/** Read the documents the person owns (`store: 'user'`): an app sees their `public` documents,
|
|
66
|
+
/** Read the documents the person owns (`store: 'user'`): an app sees their `public` documents, `private` ones too while the grant holds
|
|
67
|
+
* `crtr:memory:read_private:user` (read-only; `friends` never), and every privacy level with a `crtr:memory:manage:user` grant. */
|
|
67
68
|
memory;
|
|
68
69
|
/** Scope-filtered provider tools and daemon-mediated calls. */
|
|
69
70
|
providers;
|
package/dist/oauth/index.d.ts
CHANGED
|
@@ -148,6 +148,17 @@ export declare class OAuth2Client {
|
|
|
148
148
|
* is absent, does not contain `{client_id}` exactly once, or does not expand to a URL on the issuer's origin.
|
|
149
149
|
*/
|
|
150
150
|
accountAppUrl(): Promise<string>;
|
|
151
|
+
/**
|
|
152
|
+
* A link to the app's account page with one optional permission opened first: `accountAppUrl()` plus `permission=<scope>`
|
|
153
|
+
* and, when given, `return_to=<returnTo>`. The directory shows the switch for that scope and, once the person turns it
|
|
154
|
+
* on, a "Back to <app>" button to `returnTo` (accepted only on the origin of one of the app's registered redirect URIs;
|
|
155
|
+
* anything else is ignored). Async because it reads discovery as `accountAppUrl` does. Throws `CrouterError` when `scope`
|
|
156
|
+
* fails `parseScope`, and whatever `accountAppUrl` throws. The person's choice lands in the grant's `resolved_scopes`
|
|
157
|
+
* (read it with `grants.get`, follow it with `watchGrants`).
|
|
158
|
+
*/
|
|
159
|
+
permissionUrl(scope: string, options?: {
|
|
160
|
+
returnTo?: string;
|
|
161
|
+
}): Promise<string>;
|
|
151
162
|
/** Start a sign-in. When `scopes` includes `openid` the result carries the `nonce` to pass to the exchange; with literal scopes its type is `string`.
|
|
152
163
|
* `prompt: 'consent'` makes the directory show its consent screen even when the person already approved these scopes. */
|
|
153
164
|
authorizeUrl<const S extends readonly string[]>({ scopes, state, codeVerifier, prompt }: {
|
package/dist/oauth/index.js
CHANGED
|
@@ -191,6 +191,27 @@ export class OAuth2Client {
|
|
|
191
191
|
throw new CrouterError(`Directory discovery's account_app_uri_template is not a URL on ${origin}`);
|
|
192
192
|
return expanded;
|
|
193
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* A link to the app's account page with one optional permission opened first: `accountAppUrl()` plus `permission=<scope>`
|
|
196
|
+
* and, when given, `return_to=<returnTo>`. The directory shows the switch for that scope and, once the person turns it
|
|
197
|
+
* on, a "Back to <app>" button to `returnTo` (accepted only on the origin of one of the app's registered redirect URIs;
|
|
198
|
+
* anything else is ignored). Async because it reads discovery as `accountAppUrl` does. Throws `CrouterError` when `scope`
|
|
199
|
+
* fails `parseScope`, and whatever `accountAppUrl` throws. The person's choice lands in the grant's `resolved_scopes`
|
|
200
|
+
* (read it with `grants.get`, follow it with `watchGrants`).
|
|
201
|
+
*/
|
|
202
|
+
async permissionUrl(scope, options = {}) {
|
|
203
|
+
try {
|
|
204
|
+
parseScope(scope);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
throw new CrouterError(`Unsupported scope: ${scope}`);
|
|
208
|
+
}
|
|
209
|
+
const url = new URL(await this.accountAppUrl());
|
|
210
|
+
url.searchParams.set('permission', scope);
|
|
211
|
+
if (options.returnTo !== undefined)
|
|
212
|
+
url.searchParams.set('return_to', options.returnTo);
|
|
213
|
+
return url.toString();
|
|
214
|
+
}
|
|
194
215
|
/** Start a sign-in. When `scopes` includes `openid` the result carries the `nonce` to pass to the exchange; with literal scopes its type is `string`.
|
|
195
216
|
* `prompt: 'consent'` makes the directory show its consent screen even when the person already approved these scopes. */
|
|
196
217
|
async authorizeUrl({ scopes, state, codeVerifier, prompt }) {
|
|
@@ -26,7 +26,7 @@ export interface MemoryListItem {
|
|
|
26
26
|
kind: 'knowledge' | 'preference';
|
|
27
27
|
preview: string;
|
|
28
28
|
summary: string | null;
|
|
29
|
-
/**
|
|
29
|
+
/** An app sees `public`; `private` too while its grant holds `crtr:memory:read_private:user`; `friends` only with `crtr:memory:manage:user`. */
|
|
30
30
|
privacy: 'public' | 'friends' | 'private';
|
|
31
31
|
/** The current revision number. */
|
|
32
32
|
revision: number;
|
|
@@ -54,9 +54,11 @@ export interface MemoryDocument extends MemoryListItem {
|
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Reads the documents the person owns. The daemon filters each one by the caller's
|
|
57
|
-
* grant: an app reads `public` documents with no scope,
|
|
58
|
-
* `crtr:memory:
|
|
59
|
-
*
|
|
57
|
+
* grant: an app reads `public` documents with no scope, `private` ones too while the grant
|
|
58
|
+
* holds `crtr:memory:read_private:user` (the person may switch it on and off; `friends` never),
|
|
59
|
+
* and every privacy level with `crtr:memory:manage:user`; a document above the grant's level
|
|
60
|
+
* reads exactly as an absent one (`NotFoundError`). A run started with a `scopes` list sees
|
|
61
|
+
* `private` only if that list covers `crtr:memory:read_private:user` (names it, or `crtr:memory:manage:user`). Reading records nothing.
|
|
60
62
|
*/
|
|
61
63
|
export declare class Memory {
|
|
62
64
|
private readonly request;
|
package/dist/resources/memory.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { withQuery } from './request.js';
|
|
2
2
|
/**
|
|
3
3
|
* Reads the documents the person owns. The daemon filters each one by the caller's
|
|
4
|
-
* grant: an app reads `public` documents with no scope,
|
|
5
|
-
* `crtr:memory:
|
|
6
|
-
*
|
|
4
|
+
* grant: an app reads `public` documents with no scope, `private` ones too while the grant
|
|
5
|
+
* holds `crtr:memory:read_private:user` (the person may switch it on and off; `friends` never),
|
|
6
|
+
* and every privacy level with `crtr:memory:manage:user`; a document above the grant's level
|
|
7
|
+
* reads exactly as an absent one (`NotFoundError`). A run started with a `scopes` list sees
|
|
8
|
+
* `private` only if that list covers `crtr:memory:read_private:user` (names it, or `crtr:memory:manage:user`). Reading records nothing.
|
|
7
9
|
*/
|
|
8
10
|
export class Memory {
|
|
9
11
|
request;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: northlight
|
|
3
3
|
description: "Use when building, debugging or shipping an app that signs people in with Northlight, starts runs on their Northlight runtime, or calls Northlight providers (sms, search, integrations, context, device) with @north-light/sdk."
|
|
4
4
|
metadata:
|
|
5
|
-
sdk-version: "0.3.
|
|
5
|
+
sdk-version: "0.3.486"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Building a Northlight app
|
|
@@ -11,7 +11,7 @@ An app on Northlight signs people in with their Northlight account, then starts
|
|
|
11
11
|
|
|
12
12
|
## First: check this skill matches the SDK
|
|
13
13
|
|
|
14
|
-
This skill is for SDK version `0.3.
|
|
14
|
+
This skill is for SDK version `0.3.486`. If the project has `node_modules/@north-light/sdk/package.json`, compare its `version` with that number. If they differ, run `npx @north-light/sdk skill` in the project, then read the rewritten `.agents/skills/northlight/SKILL.md` (or `.claude/skills/northlight/SKILL.md`) instead of this copy. That command needs no account and no crtr. A project that has no SDK yet starts with `npx @north-light/sdk@latest init <dir>`.
|
|
15
15
|
|
|
16
16
|
## Where things run
|
|
17
17
|
|
package/dist/testing/cloud.d.ts
CHANGED
|
@@ -298,6 +298,9 @@ export declare class FakeCloud {
|
|
|
298
298
|
private runMessage;
|
|
299
299
|
private question;
|
|
300
300
|
private memoryStore;
|
|
301
|
+
/** `public` always; `private` with `crtr:memory:read_private:user`; every level with `crtr:memory:manage:user`; `friends` never
|
|
302
|
+
* below manage. Unlike the real runtime, which narrows a run to the `scopes` it was started with, this reads the user's whole
|
|
303
|
+
* grant (`user.grant.set`): narrowed runs are tested on the real runtime. */
|
|
301
304
|
private memoryVisible;
|
|
302
305
|
private memoryList;
|
|
303
306
|
private providerEntry;
|
package/dist/testing/cloud.js
CHANGED
|
@@ -965,8 +965,14 @@ export class FakeCloud {
|
|
|
965
965
|
if (value !== 'user')
|
|
966
966
|
throw invalid('store must be "user"', 'store');
|
|
967
967
|
}
|
|
968
|
+
/** `public` always; `private` with `crtr:memory:read_private:user`; every level with `crtr:memory:manage:user`; `friends` never
|
|
969
|
+
* below manage. Unlike the real runtime, which narrows a run to the `scopes` it was started with, this reads the user's whole
|
|
970
|
+
* grant (`user.grant.set`): narrowed runs are tested on the real runtime. */
|
|
968
971
|
memoryVisible(user, doc) {
|
|
969
|
-
|
|
972
|
+
const scopes = user.scopeStrings();
|
|
973
|
+
if (doc.privacy === 'public' || scopes.some((scope) => covers(scope, 'crtr:memory:manage:user')))
|
|
974
|
+
return true;
|
|
975
|
+
return doc.privacy === 'private' && scopes.some((scope) => covers(scope, 'crtr:memory:read_private:user'));
|
|
970
976
|
}
|
|
971
977
|
memoryList(user, query) {
|
|
972
978
|
this.memoryStore(query);
|
package/dist/version.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** This SDK's release version. Informational only: compatibility is the contract level, not this number. */
|
|
2
|
-
export declare const SDK_VERSION = "0.3.
|
|
2
|
+
export declare const SDK_VERSION = "0.3.486";
|
|
3
3
|
/** The release sent in `Crouter-Minimum-Runtime-Version` on every request. It is frozen, so a runtime from before the
|
|
4
4
|
* contract level existed (which only knows this header) refuses this SDK, while every later runtime accepts it. */
|
|
5
5
|
export declare const LEGACY_FLOOR = "0.3.423";
|
package/dist/version.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SDK_VERSION is written by scripts/release-version.mjs on every release; do not edit by hand.
|
|
2
2
|
/** This SDK's release version. Informational only: compatibility is the contract level, not this number. */
|
|
3
|
-
export const SDK_VERSION = '0.3.
|
|
3
|
+
export const SDK_VERSION = '0.3.486';
|
|
4
4
|
// LEGACY_FLOOR is written once by `scripts/contract.mjs release`, at the first release that carries the contract level
|
|
5
5
|
// (the `0.0.0` placeholder is replaced there and never again); do not edit by hand.
|
|
6
6
|
/** The release sent in `Crouter-Minimum-Runtime-Version` on every request. It is frozen, so a runtime from before the
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/sdk",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"crouterContract": "1.
|
|
3
|
+
"version": "0.3.486",
|
|
4
|
+
"crouterContract": "1.11",
|
|
5
5
|
"description": "Typed Node and browser client for running crouter agents through the crtrd /v1 API.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"prepublishOnly": "node -e \"if (process.env.npm_config_tag !== 'next') { console.error('@north-light/sdk publishes only with --tag next; scripts/promote-sdk.mjs is the only mover of latest.'); process.exit(1); }\""
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@north-light/api": "0.3.
|
|
48
|
-
"@north-light/identity": "0.3.
|
|
47
|
+
"@north-light/api": "0.3.486",
|
|
48
|
+
"@north-light/identity": "0.3.486",
|
|
49
49
|
"jose": "^6.2.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|