@north-light/cli 0.3.414 → 0.3.415
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +20 -0
- package/dist/api/client.js +3 -3
- package/dist/api/dto/common.d.ts +1 -1
- package/dist/api/dto/crons.d.ts +7 -1
- package/dist/api/dto/human-requests.d.ts +1 -1
- package/dist/api/dto/run-events.d.ts +1 -1
- package/dist/api/dto/usage.d.ts +27 -0
- package/dist/api/dto/usage.js +0 -0
- package/dist/api/errors.js +1 -1
- package/dist/api/index.d.ts +3 -2
- package/dist/api/index.js +1 -1
- package/dist/builtin-memory/crouter-sdk/README.md +22 -4
- package/dist/builtin-memory/crouter-sdk/client.md +32 -1
- package/dist/builtin-memory/crouter-sdk/errors.md +3 -0
- package/dist/builtin-memory/crouter-sdk/getting-started.md +26 -4
- package/dist/builtin-memory/crouter-sdk/release-notes.md +23 -0
- package/dist/builtin-memory/crouter-sdk/testing.md +9 -3
- package/dist/builtin-memory/internal/nodes-and-canvas.md +4 -0
- package/dist/clients/attach/viewer.js +606 -606
- package/dist/commands/cron.js +1 -1
- package/dist/commands/node/create.js +1 -1
- package/dist/core/canvas/crons.d.ts +15 -1
- package/dist/core/canvas/crons.js +13 -13
- package/dist/core/canvas/delivery-contract.d.ts +1 -1
- package/dist/core/canvas/migrations.js +73 -66
- package/dist/core/canvas/types.d.ts +1 -1
- package/dist/core/command.d.ts +7 -0
- package/dist/core/command.js +9 -9
- package/dist/core/grants/mirror.d.ts +4 -0
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/layout.d.ts +2 -0
- package/dist/core/layout.js +2 -2
- package/dist/core/llm/run.d.ts +5 -1
- package/dist/core/llm/run.js +3 -3
- package/dist/core/providers/call.d.ts +2 -0
- package/dist/core/providers/call.js +1 -1
- package/dist/core/providers/errors.js +1 -1
- package/dist/core/providers/receipts.d.ts +2 -0
- package/dist/core/providers/receipts.js +2 -3
- package/dist/core/runs/operations.d.ts +2 -0
- package/dist/core/runs/operations.js +4 -4
- package/dist/core/runtime/broker/model-adapter.js +2 -2
- package/dist/core/runtime/run-command.d.ts +6 -0
- package/dist/core/runtime/run-command.js +1 -1
- package/dist/core/spaces/mounts.d.ts +2 -0
- package/dist/core/spaces/mounts.js +1 -1
- package/dist/core/spaces/process.d.ts +14 -2
- package/dist/core/spaces/process.js +1 -1
- package/dist/core/usage/ledger.d.ts +49 -0
- package/dist/core/usage/ledger.js +10 -0
- package/dist/daemon/api/app-listener.js +12 -12
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/llm.d.ts +8 -0
- package/dist/daemon/api/handlers/llm.js +3 -3
- package/dist/daemon/api/map.d.ts +1 -1
- package/dist/daemon/api/map.js +1 -1
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/cron/armed-context.d.ts +21 -4
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/authority.d.ts +27 -0
- package/dist/daemon/cron/authority.js +1 -0
- package/dist/daemon/cron/disposition.d.ts +2 -0
- package/dist/daemon/cron/disposition.js +1 -1
- package/dist/daemon/cron/escalation.js +3 -3
- package/dist/daemon/cron/folders.d.ts +5 -0
- package/dist/daemon/cron/folders.js +1 -0
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/settle.d.ts +10 -0
- package/dist/daemon/cron/settle.js +1 -1
- package/dist/daemon/cron/sinks.d.ts +2 -1
- package/dist/daemon/cron/sinks.js +2 -2
- package/dist/daemon/cron-run.js +1 -1
- package/dist/daemon/reconcilers/action-lane.js +1 -1
- package/dist/daemon/reconcilers/broker-supervision.d.ts +10 -0
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/cron-lane.d.ts +1 -0
- package/dist/daemon/reconcilers/cron-lane.js +1 -1
- package/docs/sdk/README.md +22 -4
- package/docs/sdk/client.md +32 -1
- package/docs/sdk/errors.md +3 -0
- package/docs/sdk/getting-started.md +26 -4
- package/docs/sdk/release-notes.md +23 -0
- package/docs/sdk/testing.md +9 -3
- package/package.json +2 -2
- package/packages/crouter-identity/dist/index.d.ts +29 -2
- package/packages/crouter-identity/dist/index.js +81 -12
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -71,7 +71,70 @@ export function covers(held, requested) {
|
|
|
71
71
|
}
|
|
72
72
|
return held === requested;
|
|
73
73
|
}
|
|
74
|
-
/**
|
|
74
|
+
/** A directory fetch ran past its deadline (or was aborted by its caller before that). `code` is `deadline_exceeded`;
|
|
75
|
+
* `deadlineAt` is the instant (epoch ms) the operation had to finish by. The `@north-light/sdk` maps it to its
|
|
76
|
+
* `DeadlineExceededError`. */
|
|
77
|
+
export class FetchDeadlineError extends Error {
|
|
78
|
+
deadlineAt;
|
|
79
|
+
url;
|
|
80
|
+
code = 'deadline_exceeded';
|
|
81
|
+
constructor(deadlineAt, url) {
|
|
82
|
+
super(`${url} did not answer by the deadline (${new Date(deadlineAt).toISOString()})`);
|
|
83
|
+
this.deadlineAt = deadlineAt;
|
|
84
|
+
this.url = url;
|
|
85
|
+
this.name = 'FetchDeadlineError';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** The default deadline for one `JwksCache.load`, covering its discovery read and its key-set read together. */
|
|
89
|
+
export const DEFAULT_JWKS_TIMEOUT_MS = 10_000;
|
|
90
|
+
/**
|
|
91
|
+
* One `fetch` plus the reading of its answer (`read`, e.g. `response.json()`), bounded by one absolute deadline. The
|
|
92
|
+
* request is aborted when the deadline passes or `signal` fires, and the returned promise rejects at that moment
|
|
93
|
+
* even when `fetcher` ignores its signal, so a directory that accepts the connection and never answers cannot hold a
|
|
94
|
+
* caller (or a lock the caller holds) past `deadlineAt`. Rejects `FetchDeadlineError` at the deadline and the signal's
|
|
95
|
+
* reason when `signal` fired first.
|
|
96
|
+
*/
|
|
97
|
+
export async function boundedFetch(fetcher, url, init, bounds, read) {
|
|
98
|
+
const { deadlineAt, signal } = bounds;
|
|
99
|
+
if (signal?.aborted)
|
|
100
|
+
throw signal.reason;
|
|
101
|
+
const remaining = deadlineAt - Date.now();
|
|
102
|
+
if (remaining <= 0)
|
|
103
|
+
throw new FetchDeadlineError(deadlineAt, url);
|
|
104
|
+
const controller = new AbortController();
|
|
105
|
+
let timer;
|
|
106
|
+
let onAbort;
|
|
107
|
+
const stop = new Promise((_resolve, reject) => {
|
|
108
|
+
timer = setTimeout(() => { const error = new FetchDeadlineError(deadlineAt, url); controller.abort(error); reject(error); }, remaining);
|
|
109
|
+
if (signal) {
|
|
110
|
+
onAbort = () => { controller.abort(signal.reason); reject(signal.reason); };
|
|
111
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
const work = (async () => {
|
|
115
|
+
const response = await fetcher(url, { ...init, signal: controller.signal });
|
|
116
|
+
// A response that arrives after the deadline won is discarded: close it so its connection is not retained.
|
|
117
|
+
if (controller.signal.aborted) {
|
|
118
|
+
void response.body?.cancel().catch(() => { });
|
|
119
|
+
throw controller.signal.reason;
|
|
120
|
+
}
|
|
121
|
+
return read(response);
|
|
122
|
+
})();
|
|
123
|
+
// The loser of the race must not surface as an unhandled rejection.
|
|
124
|
+
work.catch(() => { });
|
|
125
|
+
stop.catch(() => { });
|
|
126
|
+
try {
|
|
127
|
+
return await Promise.race([work, stop]);
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
clearTimeout(timer);
|
|
131
|
+
if (onAbort)
|
|
132
|
+
signal?.removeEventListener('abort', onAbort);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** Keys are scoped to one configured issuer; failed refreshes keep the last successful set. Every `load` is bounded by
|
|
136
|
+
* one deadline (`timeoutMs`, default `DEFAULT_JWKS_TIMEOUT_MS`) over its discovery read and its key-set read together;
|
|
137
|
+
* callers that join an in-flight load share that load's deadline. */
|
|
75
138
|
export class JwksCache {
|
|
76
139
|
issuer;
|
|
77
140
|
fetcher;
|
|
@@ -79,16 +142,20 @@ export class JwksCache {
|
|
|
79
142
|
lastUnknownRefresh = -Infinity;
|
|
80
143
|
loading;
|
|
81
144
|
discovery;
|
|
82
|
-
|
|
145
|
+
timeoutMs;
|
|
146
|
+
constructor(issuer, fetcher = fetch, jwksUri, options = {}) {
|
|
83
147
|
this.issuer = issuer;
|
|
84
148
|
this.fetcher = fetcher;
|
|
85
149
|
if (jwksUri)
|
|
86
150
|
this.discovery = { jwks_uri: jwksUri };
|
|
151
|
+
this.timeoutMs = options.timeoutMs ?? DEFAULT_JWKS_TIMEOUT_MS;
|
|
152
|
+
if (!Number.isFinite(this.timeoutMs) || this.timeoutMs <= 0 || this.timeoutMs > 2_147_483_647)
|
|
153
|
+
throw new RangeError('JwksCache timeoutMs must be a positive finite number of at most 2147483647');
|
|
87
154
|
}
|
|
88
155
|
async load() {
|
|
89
156
|
if (this.loading)
|
|
90
157
|
return this.loading;
|
|
91
|
-
const loading = this.fetchKeys();
|
|
158
|
+
const loading = this.fetchKeys(Date.now() + this.timeoutMs);
|
|
92
159
|
this.loading = loading;
|
|
93
160
|
try {
|
|
94
161
|
return await loading;
|
|
@@ -97,20 +164,22 @@ export class JwksCache {
|
|
|
97
164
|
this.loading = undefined;
|
|
98
165
|
}
|
|
99
166
|
}
|
|
100
|
-
async fetchKeys() {
|
|
167
|
+
async fetchKeys(deadlineAt) {
|
|
101
168
|
if (!this.discovery) {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
169
|
+
const value = await boundedFetch(this.fetcher, `${this.issuer.replace(/\/$/, '')}/.well-known/openid-configuration`, {}, { deadlineAt }, async (response) => {
|
|
170
|
+
if (!response.ok)
|
|
171
|
+
throw new Error(`Directory discovery failed: ${response.status}`);
|
|
172
|
+
return await response.json();
|
|
173
|
+
});
|
|
106
174
|
if (!value || typeof value !== 'object' || !('jwks_uri' in value) || typeof value.jwks_uri !== 'string')
|
|
107
175
|
throw new Error('Directory discovery has no jwks_uri');
|
|
108
176
|
this.discovery = { jwks_uri: value.jwks_uri };
|
|
109
177
|
}
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
178
|
+
const keys = await boundedFetch(this.fetcher, this.discovery.jwks_uri, {}, { deadlineAt }, async (response) => {
|
|
179
|
+
if (!response.ok)
|
|
180
|
+
throw new Error(`Directory JWKS failed: ${response.status}`);
|
|
181
|
+
return await response.json();
|
|
182
|
+
});
|
|
114
183
|
if (!keys || typeof keys !== 'object' || !('keys' in keys) || !Array.isArray(keys.keys))
|
|
115
184
|
throw new Error('Invalid directory JWKS');
|
|
116
185
|
this.keys = keys;
|
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.415",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/cli",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.415",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "UNLICENSED",
|
|
12
12
|
"workspaces": [
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@earendil-works/pi-ai": "0.99.1",
|
|
19
19
|
"@earendil-works/pi-coding-agent": "0.99.1",
|
|
20
20
|
"@earendil-works/pi-tui": "0.99.1",
|
|
21
|
-
"@north-light/identity": "0.3.
|
|
21
|
+
"@north-light/identity": "0.3.415",
|
|
22
22
|
"cron-parser": "^5.6.0",
|
|
23
23
|
"esbuild": "^0.27.7",
|
|
24
24
|
"jose": "^6.2.12",
|
|
@@ -13814,17 +13814,17 @@
|
|
|
13814
13814
|
},
|
|
13815
13815
|
"packages/crouter-api": {
|
|
13816
13816
|
"name": "@north-light/api",
|
|
13817
|
-
"version": "0.3.
|
|
13817
|
+
"version": "0.3.415",
|
|
13818
13818
|
"license": "UNLICENSED"
|
|
13819
13819
|
},
|
|
13820
13820
|
"packages/crouter-env-docker": {
|
|
13821
13821
|
"name": "@north-light/env-docker",
|
|
13822
|
-
"version": "0.3.
|
|
13822
|
+
"version": "0.3.415",
|
|
13823
13823
|
"license": "UNLICENSED"
|
|
13824
13824
|
},
|
|
13825
13825
|
"packages/crouter-identity": {
|
|
13826
13826
|
"name": "@north-light/identity",
|
|
13827
|
-
"version": "0.3.
|
|
13827
|
+
"version": "0.3.415",
|
|
13828
13828
|
"license": "UNLICENSED",
|
|
13829
13829
|
"dependencies": {
|
|
13830
13830
|
"jose": "^6.2.1"
|
|
@@ -13832,20 +13832,20 @@
|
|
|
13832
13832
|
},
|
|
13833
13833
|
"packages/crouter-plugin": {
|
|
13834
13834
|
"name": "@north-light/plugin",
|
|
13835
|
-
"version": "0.3.
|
|
13835
|
+
"version": "0.3.415",
|
|
13836
13836
|
"license": "UNLICENSED",
|
|
13837
13837
|
"dependencies": {
|
|
13838
|
-
"@north-light/api": "0.3.
|
|
13839
|
-
"@north-light/identity": "0.3.
|
|
13838
|
+
"@north-light/api": "0.3.415",
|
|
13839
|
+
"@north-light/identity": "0.3.415"
|
|
13840
13840
|
}
|
|
13841
13841
|
},
|
|
13842
13842
|
"packages/crouter-sdk": {
|
|
13843
13843
|
"name": "@north-light/sdk",
|
|
13844
|
-
"version": "0.3.
|
|
13844
|
+
"version": "0.3.415",
|
|
13845
13845
|
"license": "UNLICENSED",
|
|
13846
13846
|
"dependencies": {
|
|
13847
|
-
"@north-light/api": "0.3.
|
|
13848
|
-
"@north-light/identity": "0.3.
|
|
13847
|
+
"@north-light/api": "0.3.415",
|
|
13848
|
+
"@north-light/identity": "0.3.415",
|
|
13849
13849
|
"jose": "^6.2.1"
|
|
13850
13850
|
},
|
|
13851
13851
|
"bin": {
|