@openparachute/hub 0.7.6-rc.3 → 0.7.6
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/package.json +1 -1
- package/src/__tests__/hub-server.test.ts +1 -1
- package/src/__tests__/scope-explanations.test.ts +1 -1
- package/src/admin-clients.ts +1 -1
- package/src/admin-module-token.ts +1 -1
- package/src/brand.ts +1 -1
- package/src/chrome-strip.ts +2 -2
- package/src/commands/install.ts +2 -2
- package/src/commands/status.ts +2 -2
- package/src/commands/upgrade.ts +4 -2
- package/src/help.ts +1 -1
- package/src/hub-server.ts +1 -1
- package/src/hub.ts +3 -3
- package/src/module-manifest.ts +3 -3
- package/src/resource-binding.ts +1 -1
- package/src/scope-explanations.ts +1 -1
- package/src/scope-registry.ts +1 -1
- package/src/services-manifest.ts +3 -3
- package/src/well-known.ts +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
The hub coordinates the modules running on your machine: it installs them, supervises them as child processes (the hub itself runs under your platform's process manager — launchd / systemd / the container runtime), exposes them over Tailscale, serves the discovery document at `/.well-known/parachute.json`, and (soon) issues OAuth tokens. Each module (vault, surface, scribe, …) stays a standalone package; the hub stitches them together.
|
|
6
6
|
|
|
7
|
-
> Previously published as `@openparachute/cli`. Renamed 2026-04-26 to better reflect the role — see [
|
|
7
|
+
> Previously published as `@openparachute/cli`. Renamed 2026-04-26 to better reflect the role — see [docs/contracts/hub-as-issuer.md](https://github.com/ParachuteComputer/parachute-hub/blob/main/docs/contracts/hub-as-issuer.md). The `parachute` binary name is unchanged.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
package/package.json
CHANGED
|
@@ -4606,7 +4606,7 @@ describe("parseArgs — issuer env precedence (hub#365)", () => {
|
|
|
4606
4606
|
|
|
4607
4607
|
describe("hubFetch persistent chrome strip injection (workstream G)", () => {
|
|
4608
4608
|
// Pins the proxy-side wiring of the chrome strip from
|
|
4609
|
-
// `
|
|
4609
|
+
// `docs/contracts/design-system.md` §7 — every proxied
|
|
4610
4610
|
// text/html response gets the strip injected after the first `<body>`,
|
|
4611
4611
|
// with opt-outs for `/surface/notes/*` (the Notes PWA owns its own chrome).
|
|
4612
4612
|
// The pure rewrite + opt-out logic is covered in chrome-strip.test.ts;
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
|
|
13
13
|
describe("SCOPE_EXPLANATIONS", () => {
|
|
14
14
|
test("covers every canonical first-party scope from oauth-scopes.md", () => {
|
|
15
|
-
// Source of truth:
|
|
15
|
+
// Source of truth: docs/contracts/oauth-scopes.md.
|
|
16
16
|
const expected = [
|
|
17
17
|
"vault:read",
|
|
18
18
|
"vault:write",
|
package/src/admin-clients.ts
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
* UX is preserved.
|
|
40
40
|
*
|
|
41
41
|
* Two cases, one route — `return_to` is the discriminator. The pattern
|
|
42
|
-
* doc is `
|
|
42
|
+
* doc is `docs/contracts/oauth-dcr-approval.md` §"SPA
|
|
43
43
|
* approve page (two cases, one route)".
|
|
44
44
|
*
|
|
45
45
|
* Validation reuses `isSafeAuthorizeReturnTo` from oauth-handlers.ts so
|
|
@@ -132,7 +132,7 @@ export async function handleModuleToken(
|
|
|
132
132
|
// installDir carries a readable module.json. This is the canonical
|
|
133
133
|
// gate — any module (first- or third-party) that completed
|
|
134
134
|
// self-registration mints with zero hub code changes, per
|
|
135
|
-
// `
|
|
135
|
+
// `docs/contracts/hub-module-boundary.md` (the seam,
|
|
136
136
|
// mechanism 1).
|
|
137
137
|
// 2. KNOWN bootstrap short (KNOWN_MODULES ∪ FIRST_PARTY_FALLBACKS): kept
|
|
138
138
|
// as a fallback so a first-party module mid-install (row not yet
|
package/src/brand.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* mark or the tagline copy happens in ONE place; every consumer follows.
|
|
8
8
|
*
|
|
9
9
|
* Source of truth for the brand mark + tagline lives in the design-system
|
|
10
|
-
*
|
|
10
|
+
* contract doc (`docs/contracts/design-system.md` §2). This file
|
|
11
11
|
* is the hub's vendored copy of that mark so the chrome injector + the
|
|
12
12
|
* server-rendered surfaces can render without fetching anything at runtime.
|
|
13
13
|
* Keep this file's SVG path corpus in sync with the design-system doc; the
|
package/src/chrome-strip.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* so an operator always knows where they are and how to navigate back to the
|
|
7
7
|
* hub root. The structural fix to the "where-am-I confusion" called out in
|
|
8
8
|
* `AUDIT-UI-UX.md` §2.5 + §5 row G, with the HTML + CSS shape pinned in
|
|
9
|
-
* `
|
|
9
|
+
* `docs/contracts/design-system.md` §7.
|
|
10
10
|
*
|
|
11
11
|
* Injection mechanism: buffer-and-replace on the first `<body...>` tag.
|
|
12
12
|
* Responses larger than `MAX_INJECT_SIZE_BYTES` are passed through unchanged
|
|
@@ -90,7 +90,7 @@ const BRAND_MARK_SVG = brandMarkSvg(16, "chrome-1");
|
|
|
90
90
|
* hasn't yet adopted the canonical palette tokens. Once a surface declares
|
|
91
91
|
* `:root { --bg-soft: ...; }` of its own, those win via cascade.
|
|
92
92
|
*
|
|
93
|
-
* Sourced from `
|
|
93
|
+
* Sourced from `docs/contracts/design-system.md` §7 verbatim,
|
|
94
94
|
* with the `:host` token shim added for cross-surface portability.
|
|
95
95
|
*/
|
|
96
96
|
const CHROME_STYLE = `
|
package/src/commands/install.ts
CHANGED
|
@@ -955,7 +955,7 @@ export async function install(input: string, opts: InstallOpts = {}): Promise<nu
|
|
|
955
955
|
// first-party we fall back to the vendored manifest when absent; for
|
|
956
956
|
// third-party (npm / local-path) the manifest is the contract — its
|
|
957
957
|
// absence hard-errors here. See
|
|
958
|
-
// `
|
|
958
|
+
// `docs/contracts/module-json-extensibility.md`.
|
|
959
959
|
const installDir = resolveInstallDir(target, findGlobalInstall);
|
|
960
960
|
const installedManifest = await readInstalledManifest(target, installDir, {
|
|
961
961
|
readManifest,
|
|
@@ -990,7 +990,7 @@ export async function install(input: string, opts: InstallOpts = {}): Promise<nu
|
|
|
990
990
|
if (!installedManifest) {
|
|
991
991
|
log(`✗ ${target.packageName} does not ship .parachute/module.json — not a Parachute module.`);
|
|
992
992
|
log(
|
|
993
|
-
" Authors: see parachute-
|
|
993
|
+
" Authors: see parachute-hub/docs/contracts/module-json-extensibility.md for the contract.",
|
|
994
994
|
);
|
|
995
995
|
return 1;
|
|
996
996
|
}
|
package/src/commands/status.ts
CHANGED
|
@@ -112,8 +112,8 @@ function formatRow(cells: string[], widths: number[]): string {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
|
-
* Canonical user-facing state vocabulary, per [
|
|
116
|
-
* design-system.md §6](
|
|
115
|
+
* Canonical user-facing state vocabulary, per [docs/contracts/
|
|
116
|
+
* design-system.md §6](../../docs/contracts/design-system.md)
|
|
117
117
|
* (workstream F). Replaces the pre-F two-column `PROCESS` (running/stopped)
|
|
118
118
|
* + `HEALTH` (ok/down/http <code>) split with a single rollup column the
|
|
119
119
|
* SPA, well-known doc, and CLI all share.
|
package/src/commands/upgrade.ts
CHANGED
|
@@ -206,7 +206,8 @@ export interface UpgradeOpts {
|
|
|
206
206
|
* `@latest` otherwise.
|
|
207
207
|
*
|
|
208
208
|
* Per governance rule 2 (pre-1.0 RC versioning,
|
|
209
|
-
*
|
|
209
|
+
* https://github.com/ParachuteComputer/parachute-workspace/blob/main/docs/process/governance.md),
|
|
210
|
+
* operators on the dev
|
|
210
211
|
* chain run `@rc`; `@latest` is the explicit-stable channel. The default
|
|
211
212
|
* `parachute upgrade` (pre hub#332) hard-coded `@latest`, which silently
|
|
212
213
|
* downgraded rc operators when `@latest` pointed at a prior stable.
|
|
@@ -324,7 +325,8 @@ function resolveUpgradeSupervisor(opts: UpgradeOpts["supervisor"]): {
|
|
|
324
325
|
|
|
325
326
|
/**
|
|
326
327
|
* Channel detection from a semver-ish version string. Pre-1.0 governance
|
|
327
|
-
* (parachute-
|
|
328
|
+
* (https://github.com/ParachuteComputer/parachute-workspace/blob/main/docs/process/governance.md
|
|
329
|
+
* rule 2) ships rc chains as
|
|
328
330
|
* `<x>.<y>.<z>-rc.<N>` (or sometimes `-rc` with no N). Anything matching that
|
|
329
331
|
* trailing suffix is the rc channel; everything else is the stable channel.
|
|
330
332
|
*/
|
package/src/help.ts
CHANGED
|
@@ -332,7 +332,7 @@ What it does:
|
|
|
332
332
|
modules installed.
|
|
333
333
|
|
|
334
334
|
The STATE column rolls process state + probe result into one of four
|
|
335
|
-
canonical labels (per parachute-
|
|
335
|
+
canonical labels (per parachute-hub/docs/contracts/design-system.md §6):
|
|
336
336
|
active supervised, running, last probe ok
|
|
337
337
|
pending supervised, needs operator action (OAuth / config) —
|
|
338
338
|
not reachable from \`parachute status\` today; surfaces in
|
package/src/hub-server.ts
CHANGED
|
@@ -1419,7 +1419,7 @@ async function loadManagementUrls(
|
|
|
1419
1419
|
* earlier "vaults browse via Notes — no tile" rule retired with PR 1 of
|
|
1420
1420
|
* workstream C; operators administer per-vault tokens / config / MCP via
|
|
1421
1421
|
* the vault admin SPA, which is a different audience from Notes' content
|
|
1422
|
-
* browse. See [`module-ui-declaration.md` §"Use vs admin"](https://github.com/ParachuteComputer/parachute-
|
|
1422
|
+
* browse. See [`module-ui-declaration.md` §"Use vs admin"](https://github.com/ParachuteComputer/parachute-hub/blob/main/docs/contracts/module-ui-declaration.md#use-vs-admin--both-can-be-true).
|
|
1423
1423
|
*
|
|
1424
1424
|
* `loadManagementUrls` continues to handle vault's `managementUrl` for
|
|
1425
1425
|
* the hub admin SPA's vault-list "Manage" link — a different surface
|
package/src/hub.ts
CHANGED
|
@@ -484,7 +484,7 @@ const DISCOVERY_SCRIPT = `<script>
|
|
|
484
484
|
// The previous SERVICE_LABELS / SERVICE_ORDER / isVaultName hardcoding
|
|
485
485
|
// is retired: vault has no uiUrl, so the "skip vault" rule emerges
|
|
486
486
|
// from data rather than a name check; ordering is alphabetical-by-
|
|
487
|
-
// displayName per
|
|
487
|
+
// displayName per docs/contracts/module-json-extensibility.md.
|
|
488
488
|
|
|
489
489
|
// Admin entries: always visible. Even a fresh hub with zero vaults wants
|
|
490
490
|
// the operator to find /admin/vaults. Hardcoded — they live in the
|
|
@@ -617,7 +617,7 @@ const DISCOVERY_SCRIPT = `<script>
|
|
|
617
617
|
});
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
-
// Alphabetical-by-displayName per
|
|
620
|
+
// Alphabetical-by-displayName per docs/contracts/module-json-extensibility.md.
|
|
621
621
|
// Stable for shared-prefix labels (Notes, Notes-Lite would sort that way).
|
|
622
622
|
const tiles = Array.from(byShort.values()).sort((a, b) =>
|
|
623
623
|
a.title.localeCompare(b.title),
|
|
@@ -630,7 +630,7 @@ const DISCOVERY_SCRIPT = `<script>
|
|
|
630
630
|
empty.innerHTML =
|
|
631
631
|
'No services with a UI declared yet. Modules surface their UIs by ' +
|
|
632
632
|
'declaring <code>uiUrl</code> in <code>module.json</code> ' +
|
|
633
|
-
'(see
|
|
633
|
+
'(see parachute-hub/docs/contracts/module-json-extensibility.md).';
|
|
634
634
|
servicesGrid.appendChild(empty);
|
|
635
635
|
return;
|
|
636
636
|
}
|
package/src/module-manifest.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* module. Author-controlled, shipped in the published artifact, read by the
|
|
4
4
|
* CLI on `parachute install <package>`.
|
|
5
5
|
*
|
|
6
|
-
* The shape mirrors `
|
|
6
|
+
* The shape mirrors `docs/contracts/module-json-extensibility.md`.
|
|
7
7
|
* Third-party modules are first-class: no `@openparachute/` scope or
|
|
8
8
|
* `parachute-*` prefix required — `module.json` is what makes a package a
|
|
9
9
|
* module. First-party modules will eventually ship their own `module.json`
|
|
@@ -271,7 +271,7 @@ export interface ModuleManifest {
|
|
|
271
271
|
readonly configSchema?: ConfigSchema;
|
|
272
272
|
/**
|
|
273
273
|
* Where the module's admin UI lives. Hub renders a "Manage" link when set
|
|
274
|
-
* (see `
|
|
274
|
+
* (see `docs/contracts/module-json-extensibility.md`).
|
|
275
275
|
*
|
|
276
276
|
* Three shapes (unified URL-resolution semantics — B4 of the 2026-06-09
|
|
277
277
|
* hub-module-boundary migration):
|
|
@@ -293,7 +293,7 @@ export interface ModuleManifest {
|
|
|
293
293
|
/**
|
|
294
294
|
* Where the module's primary user-facing UI lives. Hub renders a tile on
|
|
295
295
|
* the discovery page (`/`) Services section when set (see
|
|
296
|
-
* `
|
|
296
|
+
* `docs/contracts/module-json-extensibility.md` and the
|
|
297
297
|
* `loadUiUrls` resolver in `hub-server.ts`).
|
|
298
298
|
*
|
|
299
299
|
* Two shapes — same rules as `managementUrl`:
|
package/src/resource-binding.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* vault's named scopes, lock the picker to `<name>`, and mint named scopes so
|
|
26
26
|
* `inferAudience` stamps `aud=vault.<name>`.
|
|
27
27
|
*
|
|
28
|
-
* Source of truth for scope shape: `
|
|
28
|
+
* Source of truth for scope shape: `docs/contracts/oauth-scopes.md`.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
import { VAULT_VERBS } from "./jwt-audience.ts";
|
package/src/scope-registry.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* downstream service should be rejected, but defense-in-depth says don't
|
|
8
8
|
* sign claims you don't understand. This module is the gate.
|
|
9
9
|
*
|
|
10
|
-
* Source of truth for scope shape: `
|
|
10
|
+
* Source of truth for scope shape: `docs/contracts/oauth-scopes.md`.
|
|
11
11
|
*
|
|
12
12
|
* Declared scopes come from two places:
|
|
13
13
|
* 1. `FIRST_PARTY_SCOPES` — the canonical Parachute scopes hardcoded in
|
package/src/services-manifest.ts
CHANGED
|
@@ -25,8 +25,8 @@ export type PublicExposure = "allowed" | "loopback" | "auth-required";
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Visible-to-discovery state of a UI sub-unit. Aligns with the four-state
|
|
28
|
-
* supervisor vocabulary in [
|
|
29
|
-
* §6](../
|
|
28
|
+
* supervisor vocabulary in [docs/contracts/design-system.md
|
|
29
|
+
* §6](../docs/contracts/design-system.md) (workstream F).
|
|
30
30
|
* Absent → hub treats the sub-unit as "active" (the discovery default).
|
|
31
31
|
*
|
|
32
32
|
* "active" — UI is installed, OAuth client is approved, ready to serve.
|
|
@@ -827,7 +827,7 @@ function dropLegacyShortNameRows(raw: unknown, where: string): { raw: unknown; c
|
|
|
827
827
|
});
|
|
828
828
|
|
|
829
829
|
console.error(
|
|
830
|
-
`${where}: dropped legacy short-name row(s) [${dropped.join(", ")}] in favor of same-port manifestName row(s). This is the parachute-app#13 / parachute-runner#4 self-register fixup. See parachute-
|
|
830
|
+
`${where}: dropped legacy short-name row(s) [${dropped.join(", ")}] in favor of same-port manifestName row(s). This is the parachute-app#13 / parachute-runner#4 self-register fixup. See parachute-hub/docs/contracts/services-json-row-conventions.md.`,
|
|
831
831
|
);
|
|
832
832
|
|
|
833
833
|
return {
|
package/src/well-known.ts
CHANGED
|
@@ -47,7 +47,7 @@ export interface WellKnownVaultEntry {
|
|
|
47
47
|
version: string;
|
|
48
48
|
/**
|
|
49
49
|
* Where the vault's admin SPA lives. Path-or-URL per
|
|
50
|
-
* `
|
|
50
|
+
* `docs/contracts/module-json-extensibility.md`. Hub renders
|
|
51
51
|
* a "Manage" link when present. Sourced from the vault module's
|
|
52
52
|
* `.parachute/module.json:managementUrl`.
|
|
53
53
|
*/
|