harness-dispatch 0.7.9 → 0.8.0
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/CHANGELOG.md +657 -1
- package/README.md +25 -4
- package/config.default.yaml +30 -2
- package/dist/auth.d.ts +29 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +58 -5
- package/dist/auth.js.map +1 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +404 -20
- package/dist/bin.js.map +1 -1
- package/dist/breaker-store.d.ts +25 -1
- package/dist/breaker-store.d.ts.map +1 -1
- package/dist/breaker-store.js +193 -25
- package/dist/breaker-store.js.map +1 -1
- package/dist/client-register.d.ts +147 -0
- package/dist/client-register.d.ts.map +1 -0
- package/dist/client-register.js +380 -0
- package/dist/client-register.js.map +1 -0
- package/dist/config/validation.d.ts +29 -0
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +88 -0
- package/dist/config/validation.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +55 -2
- package/dist/config.js.map +1 -1
- package/dist/dispatch-log.d.ts +14 -0
- package/dist/dispatch-log.d.ts.map +1 -1
- package/dist/dispatch-log.js +3 -0
- package/dist/dispatch-log.js.map +1 -1
- package/dist/dispatchers/openai-compatible.d.ts +20 -4
- package/dist/dispatchers/openai-compatible.d.ts.map +1 -1
- package/dist/dispatchers/openai-compatible.js +145 -17
- package/dist/dispatchers/openai-compatible.js.map +1 -1
- package/dist/http/answer-stream.d.ts +52 -0
- package/dist/http/answer-stream.d.ts.map +1 -0
- package/dist/http/answer-stream.js +47 -0
- package/dist/http/answer-stream.js.map +1 -0
- package/dist/http/parse.d.ts.map +1 -1
- package/dist/http/parse.js +41 -0
- package/dist/http/parse.js.map +1 -1
- package/dist/http/server.d.ts.map +1 -1
- package/dist/http/server.js +102 -9
- package/dist/http/server.js.map +1 -1
- package/dist/jobs/store.d.ts.map +1 -1
- package/dist/jobs/store.js +45 -4
- package/dist/jobs/store.js.map +1 -1
- package/dist/jobs.d.ts +24 -0
- package/dist/jobs.d.ts.map +1 -1
- package/dist/jobs.js +101 -1
- package/dist/jobs.js.map +1 -1
- package/dist/mcp/config-hot-reload.d.ts.map +1 -1
- package/dist/mcp/config-hot-reload.js +10 -0
- package/dist/mcp/config-hot-reload.js.map +1 -1
- package/dist/mcp/near-miss-guard.d.ts +45 -0
- package/dist/mcp/near-miss-guard.d.ts.map +1 -0
- package/dist/mcp/near-miss-guard.js +98 -0
- package/dist/mcp/near-miss-guard.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +36 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-schemas.d.ts.map +1 -1
- package/dist/mcp/tool-schemas.js +21 -4
- package/dist/mcp/tool-schemas.js.map +1 -1
- package/dist/mcp/tools.d.ts +22 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +38 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp-clients.d.ts +63 -0
- package/dist/mcp-clients.d.ts.map +1 -0
- package/dist/mcp-clients.js +117 -0
- package/dist/mcp-clients.js.map +1 -0
- package/dist/near-miss.d.ts +63 -0
- package/dist/near-miss.d.ts.map +1 -0
- package/dist/near-miss.js +132 -0
- package/dist/near-miss.js.map +1 -0
- package/dist/quota.d.ts +31 -1
- package/dist/quota.d.ts.map +1 -1
- package/dist/quota.js +68 -6
- package/dist/quota.js.map +1 -1
- package/dist/route-policy.d.ts +10 -0
- package/dist/route-policy.d.ts.map +1 -1
- package/dist/route-policy.js +20 -2
- package/dist/route-policy.js.map +1 -1
- package/dist/router.d.ts +61 -2
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +156 -29
- package/dist/router.js.map +1 -1
- package/dist/safety.d.ts.map +1 -1
- package/dist/safety.js +31 -1
- package/dist/safety.js.map +1 -1
- package/dist/status.d.ts +30 -21
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +152 -8
- package/dist/status.js.map +1 -1
- package/dist/types.d.ts +25 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/working-dir.d.ts.map +1 -1
- package/dist/working-dir.js +16 -0
- package/dist/working-dir.js.map +1 -1
- package/dist/workspace-resolve.d.ts.map +1 -1
- package/dist/workspace-resolve.js +119 -15
- package/dist/workspace-resolve.js.map +1 -1
- package/dist/workspaces.d.ts +83 -0
- package/dist/workspaces.d.ts.map +1 -1
- package/dist/workspaces.js +288 -15
- package/dist/workspaces.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,8 +66,13 @@ harness-dispatch configure --yes
|
|
|
66
66
|
harness-dispatch doctor --live
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
`configure --yes` detects installed harnesses
|
|
70
|
-
|
|
69
|
+
`configure --yes` detects installed harnesses, writes `config.yaml`, and then
|
|
70
|
+
offers to register this server with each MCP client it finds (Claude Code,
|
|
71
|
+
Cursor) — showing you what it would write, and what is already there, before
|
|
72
|
+
changing anything. `--no-clients` skips the offer and prints a snippet to paste
|
|
73
|
+
instead; `harness-dispatch connect` does the same registration later on its own,
|
|
74
|
+
and `connect --remove` undoes it. Without
|
|
75
|
+
`--yes` configure previews and writes nothing. `doctor` then checks the whole chain:
|
|
71
76
|
binary, config load, harness detection, auth and billing classification, route
|
|
72
77
|
readiness. `--live` goes further and routes one tiny real prompt, so you see a
|
|
73
78
|
completion before wiring anything into your agent. The live probe never touches paid or
|
|
@@ -348,6 +353,10 @@ set `billing_kind:` / `paid_usage_possible:` explicitly once you know it.
|
|
|
348
353
|
harness-dispatch # stdio MCP
|
|
349
354
|
harness-dispatch configure # detect harnesses and prepare config
|
|
350
355
|
harness-dispatch configure --print # inspect generated config YAML
|
|
356
|
+
harness-dispatch connect # register with the MCP clients you have
|
|
357
|
+
harness-dispatch connect --clients cursor # no prompt; ids from the listing it prints
|
|
358
|
+
harness-dispatch connect --dev # point clients at THIS checkout's build
|
|
359
|
+
harness-dispatch connect --remove # take the entry back out
|
|
351
360
|
harness-dispatch doctor # validate install, auth, config, and routes
|
|
352
361
|
harness-dispatch doctor --live # run one eligible live routed probe
|
|
353
362
|
harness-dispatch doctor --live --allow-paid
|
|
@@ -376,7 +385,7 @@ version bump.
|
|
|
376
385
|
| `dispatch` | Always starts new routed coding work — one task to the best-fit harness, or a fanout to several for independent opinions. Every call runs as a background job from the first moment: a fast task returns its full result inline (`completed: true`), a slow one returns `completed: false` plus a `jobId` to check on. Nothing is ever lost to a timeout — including the MCP call's own. |
|
|
377
386
|
| `job_status` | Checks work started by `dispatch`. Pass the `jobId` it returned to get a `partialOutput` tail while running and the full `result` once done; omit `jobId` to list recent background dispatches (compact, newest first). |
|
|
378
387
|
| `cancel_job` | Stops work started by `dispatch` — a wrong turn, a wrong directory, a superseded run. A job still waiting for a slot stops outright; a running one tears down within about a second (poll `job_status` to see it land), killing the agent CLI and its children. Files it already changed are **not** reverted, and a cancelled run is not counted as a route failure. |
|
|
379
|
-
| `retry_job` | Re-runs a finished job's task from its own record — same prompt (as the delegate saw it), files, working directory, hints and workspace policy. Pass `service` to send the retry to a different route, which is the usual reason to retry: the task was fine and the route was not
|
|
388
|
+
| `retry_job` | Re-runs a finished job's task from its own record — same prompt (as the delegate saw it), files, working directory, hints and workspace policy. Pass `service` to send the retry to a different route, which is the usual reason to retry: the task was fine and the route was not — the original's model is left behind when the new route does not declare it, reported as `droppedModel`. Returns a new jobId; the original is untouched. |
|
|
380
389
|
| `workspace` | For a job that ran with `workspacePolicy: "copy"` or `"git_worktree"`, the agent's changes live in an isolated workspace and were **never** applied to your project. `action: "diff"` returns the real patch; `"apply"` applies it (refusing when your project has uncommitted changes, since the patch was built against a clean base — `force: true` overrides); `"discard"` deletes the workspace. The full patch is always written to the job directory, so `git apply` by hand is available either way. |
|
|
381
390
|
| `usage` | Per-route call counts, quota, billing kind, and breaker state — check this before passing an unfamiliar `hints.model`/`service`/`models` value, since those are not validated. Pass `listModels: <route id>` to fetch that `openai_compatible` route's live `GET /models` catalog instead of (or alongside) the summary. |
|
|
382
391
|
|
|
@@ -449,9 +458,21 @@ Status is exposed as resources:
|
|
|
449
458
|
|
|
450
459
|
Endpoints:
|
|
451
460
|
|
|
461
|
+
- `GET /health` — liveness, and the **only** route served without a token, so a
|
|
462
|
+
deploy gate or container probe can ask without being handed a credential. It
|
|
463
|
+
answers `{"status","service","version"}` and nothing else: no routes, no
|
|
464
|
+
endpoints, no quota, no config.
|
|
452
465
|
- `POST /mcp` for streamable HTTP MCP
|
|
466
|
+
- `POST /v1/chat/completions` with `stream: true` sends the answer as SSE
|
|
467
|
+
deltas. An endpoint route streams its text as it arrives; a CLI harness emits
|
|
468
|
+
protocol on stdout, so its answer is sent once, at completion — the deltas
|
|
469
|
+
never carry harness protocol either way. **Streaming creates no job record**,
|
|
470
|
+
so unlike the non-streaming call there is no `jobId` to poll and an
|
|
471
|
+
interrupted stream cannot be recovered. Use the non-streaming form for work
|
|
472
|
+
you would mind losing.
|
|
453
473
|
- `GET /v1/status` — full route/quota/billing/breaker detail (same shape as
|
|
454
|
-
`harness-dispatch://status.json`)
|
|
474
|
+
`harness-dispatch://status.json`). Authenticated, because that answer is not
|
|
475
|
+
for strangers.
|
|
455
476
|
- `GET /v1/usage` — per-route call counts, quota, billing kind, and breaker state only
|
|
456
477
|
- `GET /v1/models` — OpenAI-style model list; each entry's `id` is a route id you can
|
|
457
478
|
pass as `model` in `/v1/chat/completions`
|
package/config.default.yaml
CHANGED
|
@@ -47,7 +47,23 @@ clis:
|
|
|
47
47
|
# line; {{tokens}} are substituted at dispatch time (see the reference at
|
|
48
48
|
# the bottom of this file).
|
|
49
49
|
protocol:
|
|
50
|
-
|
|
50
|
+
# The prompt goes on STDIN, not in argv.
|
|
51
|
+
#
|
|
52
|
+
# `claude -p` accepts either; argv was the original choice and it is the
|
|
53
|
+
# one that carries every command-line defect this project has fixed. On
|
|
54
|
+
# Windows a .CMD/.bat target is re-spawned through cmd.exe, which caps
|
|
55
|
+
# the whole command line at 8,191 characters — so a long prompt was
|
|
56
|
+
# refused before it reached the harness at all, and the machinery
|
|
57
|
+
# deciding where that boundary sits had to replicate cross-spawn's own
|
|
58
|
+
# escaping to know. generic-cli.ts skips that check entirely when
|
|
59
|
+
# `stdin: true` (the guard is `if (!protocol.stdin)`), because a prompt
|
|
60
|
+
# on stdin has no such limit. codex_cli has always worked this way.
|
|
61
|
+
#
|
|
62
|
+
# Verified live: a 21,670-character prompt — 2.65x the 8,191-character ceiling, and
|
|
63
|
+
# measured at 20,064 characters as argv, which the old form refused
|
|
64
|
+
# outright — dispatched and answered.
|
|
65
|
+
stdin: true
|
|
66
|
+
args: ["-p", "--output-format", "json", "{{safety}}", "{{model}}"]
|
|
51
67
|
model: { flag: "--model" }
|
|
52
68
|
safety:
|
|
53
69
|
read_only: ["--allowedTools", "Read", "--permission-mode", "plan"]
|
|
@@ -206,7 +222,19 @@ clis:
|
|
|
206
222
|
protocol:
|
|
207
223
|
# -p is Cursor's boolean "print mode" flag; the prompt itself is the
|
|
208
224
|
# trailing positional {{prompt}}.
|
|
209
|
-
|
|
225
|
+
# Prompt on STDIN, for the same reason as claude_code_cli above: a
|
|
226
|
+
# prompt in argv is measured against cmd.exe's 8,191-character ceiling
|
|
227
|
+
# and escaped to get there, and this route is a `cursor-agent.CMD`
|
|
228
|
+
# PowerShell wrapper — the one that failed at ~9k characters and drove
|
|
229
|
+
# two releases of escaping work. generic-cli.ts skips the check
|
|
230
|
+
# entirely when `stdin: true`.
|
|
231
|
+
#
|
|
232
|
+
# Verified live before changing: `cursor-agent -p --trust
|
|
233
|
+
# --output-format json` with the prompt piped in returns
|
|
234
|
+
# {"type":"result","subtype":"success","is_error":false,...,"result":"pong"}.
|
|
235
|
+
# --trust is required or it refuses with a workspace-trust prompt.
|
|
236
|
+
stdin: true
|
|
237
|
+
args: ["-p", "--trust", "{{safety}}", "{{working_dir}}", "--output-format", "json", "{{model}}"]
|
|
210
238
|
# Only read_only gets extra flags; the other profiles run print mode as
|
|
211
239
|
# before. --trust is unrelated to capability — it just suppresses the
|
|
212
240
|
# workspace-trust prompt, which would hang a non-interactive run.
|
package/dist/auth.d.ts
CHANGED
|
@@ -2,8 +2,37 @@ export declare function authDir(): string;
|
|
|
2
2
|
export declare function tokenPath(): string;
|
|
3
3
|
export declare function generateHttpToken(): string;
|
|
4
4
|
export declare function readHttpToken(): Promise<string | null>;
|
|
5
|
+
/**
|
|
6
|
+
* The token as it is on disk RIGHT NOW, for a running server to consult.
|
|
7
|
+
*
|
|
8
|
+
* A server read the token once at startup and held it forever, so `auth
|
|
9
|
+
* rotate` was a lie in both directions: an acceptance pass measured the old
|
|
10
|
+
* token still returning 200 after rotation, and the newly issued one being
|
|
11
|
+
* rejected with 401. Invalidating the old token is the entire reason anyone
|
|
12
|
+
* rotates a credential, so telling the user it rotated while the leaked value
|
|
13
|
+
* kept working is the worst possible outcome.
|
|
14
|
+
*
|
|
15
|
+
* Synchronous because it is consulted on the authorization path of every
|
|
16
|
+
* request, which is not async. The file is a few dozen bytes on local disk and
|
|
17
|
+
* the read is guarded by an mtime check in the caller.
|
|
18
|
+
*/
|
|
19
|
+
export declare function readHttpTokenSync(): string | null;
|
|
20
|
+
/** Modification time of the token file, or 0 when there isn't one. */
|
|
21
|
+
export declare function httpTokenMtimeMs(): number;
|
|
5
22
|
export declare function ensureHttpToken(): Promise<string>;
|
|
6
23
|
export declare function rotateHttpToken(): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Whether a request carries the expected bearer token.
|
|
26
|
+
*
|
|
27
|
+
* A `token` of null means NO AUTH IS CONFIGURED, and every request is
|
|
28
|
+
* authorized — this function fails open, deliberately, and a caller that
|
|
29
|
+
* cannot guarantee a token must not rely on it to deny anything. The HTTP
|
|
30
|
+
* server can: it calls `ensureHttpToken()` at startup and falls back to the
|
|
31
|
+
* token it read from disk on refresh, so null never reaches here from there.
|
|
32
|
+
*
|
|
33
|
+
* Spelled out because the fail-open branch is one line and reads like a
|
|
34
|
+
* guard clause rather than the policy decision it is.
|
|
35
|
+
*/
|
|
7
36
|
export declare function isAuthorized(authorizationHeader: string | string[] | undefined, token: string | null): boolean;
|
|
8
37
|
export declare function maskToken(token: string): string;
|
|
9
38
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AASA,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS5D;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAOvD;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAKvD;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AASA,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CASjD;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAOvD;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAKvD;AAyBD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,mBAAmB,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,EAClD,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAOT;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/C"}
|
package/dist/auth.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
-
import { promises as fs } from "node:fs";
|
|
2
|
+
import { promises as fs, readFileSync, statSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { stateRoot } from "./state-dir.js";
|
|
5
5
|
const TOKEN_ENV = "HARNESS_DISPATCH_HTTP_TOKEN";
|
|
@@ -24,6 +24,41 @@ export async function readHttpToken() {
|
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* The token as it is on disk RIGHT NOW, for a running server to consult.
|
|
29
|
+
*
|
|
30
|
+
* A server read the token once at startup and held it forever, so `auth
|
|
31
|
+
* rotate` was a lie in both directions: an acceptance pass measured the old
|
|
32
|
+
* token still returning 200 after rotation, and the newly issued one being
|
|
33
|
+
* rejected with 401. Invalidating the old token is the entire reason anyone
|
|
34
|
+
* rotates a credential, so telling the user it rotated while the leaked value
|
|
35
|
+
* kept working is the worst possible outcome.
|
|
36
|
+
*
|
|
37
|
+
* Synchronous because it is consulted on the authorization path of every
|
|
38
|
+
* request, which is not async. The file is a few dozen bytes on local disk and
|
|
39
|
+
* the read is guarded by an mtime check in the caller.
|
|
40
|
+
*/
|
|
41
|
+
export function readHttpTokenSync() {
|
|
42
|
+
const fromEnv = process.env[TOKEN_ENV];
|
|
43
|
+
if (fromEnv)
|
|
44
|
+
return fromEnv;
|
|
45
|
+
try {
|
|
46
|
+
const token = readFileSync(tokenPath(), "utf-8").trim();
|
|
47
|
+
return token || null;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Modification time of the token file, or 0 when there isn't one. */
|
|
54
|
+
export function httpTokenMtimeMs() {
|
|
55
|
+
try {
|
|
56
|
+
return statSync(tokenPath()).mtimeMs;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
27
62
|
export async function ensureHttpToken() {
|
|
28
63
|
const existing = await readHttpToken();
|
|
29
64
|
if (existing)
|
|
@@ -42,19 +77,37 @@ export async function rotateHttpToken() {
|
|
|
42
77
|
/**
|
|
43
78
|
* Constant-time string compare. `value === expected` short-circuits on the
|
|
44
79
|
* first mismatching byte — a textbook timing side channel for guessing a
|
|
45
|
-
* bearer token one byte at a time.
|
|
46
|
-
*
|
|
47
|
-
*
|
|
80
|
+
* bearer token one byte at a time.
|
|
81
|
+
*
|
|
82
|
+
* On a length mismatch it still does comparison work rather than returning
|
|
83
|
+
* early. That work is now sized by `expected`, not by `value`: the previous
|
|
84
|
+
* version compared the caller-supplied buffer against ITSELF, so its cost
|
|
85
|
+
* scaled with the length an attacker chose, and the comment claiming "a length
|
|
86
|
+
* mismatch alone doesn't leak timing info either" asserted a property the code
|
|
87
|
+
* did not have. The remaining signal is the same for every wrong length, which
|
|
88
|
+
* is what that sentence was meant to say.
|
|
48
89
|
*/
|
|
49
90
|
function safeEqual(value, expected) {
|
|
50
91
|
const valueBuf = Buffer.from(value, "utf8");
|
|
51
92
|
const expectedBuf = Buffer.from(expected, "utf8");
|
|
52
93
|
if (valueBuf.length !== expectedBuf.length) {
|
|
53
|
-
timingSafeEqual(
|
|
94
|
+
timingSafeEqual(expectedBuf, expectedBuf);
|
|
54
95
|
return false;
|
|
55
96
|
}
|
|
56
97
|
return timingSafeEqual(valueBuf, expectedBuf);
|
|
57
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Whether a request carries the expected bearer token.
|
|
101
|
+
*
|
|
102
|
+
* A `token` of null means NO AUTH IS CONFIGURED, and every request is
|
|
103
|
+
* authorized — this function fails open, deliberately, and a caller that
|
|
104
|
+
* cannot guarantee a token must not rely on it to deny anything. The HTTP
|
|
105
|
+
* server can: it calls `ensureHttpToken()` at startup and falls back to the
|
|
106
|
+
* token it read from disk on refresh, so null never reaches here from there.
|
|
107
|
+
*
|
|
108
|
+
* Spelled out because the fail-open branch is one line and reads like a
|
|
109
|
+
* guard clause rather than the policy decision it is.
|
|
110
|
+
*/
|
|
58
111
|
export function isAuthorized(authorizationHeader, token) {
|
|
59
112
|
if (token === null)
|
|
60
113
|
return true;
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/bin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;GAEG;
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;GAEG;AAg8BH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgK1D"}
|