@plurnk/plurnk-schemes 0.8.0 → 0.10.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/README.md CHANGED
@@ -7,11 +7,70 @@ Framework + contract for `@plurnk/plurnk-schemes-*` URI handler packages. Consum
7
7
  - [`SPEC.md`](./SPEC.md) — author-facing contract.
8
8
  - Constellation: [plurnk-grammar](https://github.com/plurnk/plurnk-grammar), [plurnk-mimetypes](https://github.com/plurnk/plurnk-mimetypes), [plurnk-providers](https://github.com/plurnk/plurnk-providers), [plurnk-execs](https://github.com/plurnk/plurnk-execs).
9
9
 
10
+ ## Write a scheme
11
+
12
+ Ship a scheme by publishing a package — **under any scope** (`@acme/whatever`; discovery keys on `plurnk.kind`, not the `@plurnk` scope) — that declares itself and default-exports a `SchemeHandler`. Install it and it lights up; there is no first-party allow-list (scope-agnostic discovery, SPEC §6).
13
+
14
+ ### 1. Declare in `package.json`
15
+
16
+ ```json
17
+ {
18
+ "plurnk": { "kind": "scheme", "name": "foo" }
19
+ }
20
+ ```
21
+
22
+ `plurnk.name` is the URI prefix you claim (`foo://…`). The consumer's scope-agnostic `node_modules` scan registers you by it; two packages claiming one prefix fail-hard.
23
+
24
+ ### 2. Default-export a `SchemeHandler`
25
+
26
+ ```ts
27
+ import type {
28
+ SchemeHandler, SchemeManifest, SchemeCtx, SchemeResult, ReadStatement,
29
+ } from "@plurnk/plurnk-schemes";
30
+
31
+ export default class Foo implements SchemeHandler {
32
+ static manifest: SchemeManifest = { /* step 3 */ };
33
+
34
+ async read(statement: ReadStatement, ctx: SchemeCtx): Promise<SchemeResult> {
35
+ /* … reach the substrate ONLY through ctx capabilities (SPEC §3.bis, §5) … */
36
+ }
37
+ }
38
+ ```
39
+
40
+ Implement only the op methods you support — `read` / `find` / `edit` / `copy` / `move` / `send` / … — all optional; the engine calls `handler[op.toLowerCase()](statement, ctx)` and returns **501** for any op you omit. `implements SchemeHandler` gives you compile-time signature checking. The statement + path types (`ReadStatement`, `SendStatement`, `UrlPath`, …) are **re-exported from this package**, so you depend on and exact-pin **only `@plurnk/plurnk-schemes`** — grammar rides underneath.
41
+
42
+ ### 3. Declare the manifest — including self-doc
43
+
44
+ ```ts
45
+ static manifest: SchemeManifest = {
46
+ name: "foo",
47
+ channels: { body: "text/markdown" },
48
+ defaultChannel: "body",
49
+ category: "data",
50
+ scope: "session",
51
+ writableBy: ["model", "client"],
52
+ volatile: false,
53
+ modelVisible: true,
54
+ glyph: "🦊", // display icon; omit → the name is shown
55
+ example: "READ(foo://thing/42)" // one-line usage, shown verbatim in the model's listing
56
+ };
57
+ ```
58
+
59
+ - **`example`** — a single self-documenting usage line, surfaced **verbatim** in the model's tools listing (like an execs runtime's `example`). Omit it and your scheme isn't advertised with a usage line.
60
+ - **`glyph`** — a display icon (emoji / nerdfont). Omit it and the scheme `name` is rendered in its place.
61
+
62
+ ### 4. Ship deep docs (beyond the one-liner)
63
+
64
+ The `example` is the teaser. For real documentation — every op, channel, status code, and gotcha — author a **markdown doc the model reads on demand at `plurnk://schemes/<name>.md`**, which the consumer serves. Keep it model-facing prose; the manifest stays a one-liner, the doc carries the depth. (See plurnk-service for where to place the file in your package.)
65
+
66
+ That's the whole contract: declare, `implements SchemeHandler`, manifest with self-doc, optional deep doc. Publish, install, discovered.
67
+
10
68
  ## Exports
11
69
 
12
70
  ### Types
13
71
 
14
- - Manifest/flags: `SchemeManifest`, `SchemeFlagAffinity`, `WriterTier`, `LoopFlags`, `DEFAULT_LOOP_FLAGS`.
72
+ - Manifest/flags: `SchemeManifest` (incl. `example` / `glyph` self-doc), `SchemeFlagAffinity`, `WriterTier`, `LoopFlags`, `DEFAULT_LOOP_FLAGS`.
73
+ - Behavior contract: `SchemeHandler` + the re-exported scheme-facing grammar types (`PlurnkStatement` + per-op statements + `ParsedPath` / `LocalPath` / `UrlPath`).
15
74
  - Result families: `SchemeResult` / `EntryResult` / `ProposalResult` / `PassthroughResult` / `SchemeResultBase` / `TelemetryEvent`.
16
75
  - Capability ctx: `SchemeCtx` + `EntryCaps` / `ChannelCaps` / `TagCaps` / `NotifyCaps` / `SubscriptionCaps` / `CrossSchemeCaps`, plus `EntryData` / `ChannelState` / `SubscriptionHandle` / `ProposalAware`.
17
76
 
@@ -23,6 +82,7 @@ Framework + contract for `@plurnk/plurnk-schemes-*` URI handler packages. Consum
23
82
  - `PathMimetype.resolve(pathname, default, mimetypes)` — path-extension mimetype resolver.
24
83
  - `Matcher.matchAgainstContent(body, content, mimetype, mimetypes, baseLine?)` — body-matcher dispatch over `Mimetypes.query` (glob/regex/jsonpath/xpath).
25
84
  - `Results.error` / `.logCoordinate` / `.isEntry` / `.isProposal` / `.isPassthrough` / `.isErrorStatus` — result builders + guards.
85
+ - `SchemeDiscovery.discover({ cwd? })` — scope-agnostic `node_modules` scan for `plurnk.kind:"scheme"` packages (trust-gated, fail-hard on prefix collision); returns descriptors for the consumer to register (SPEC §6).
26
86
 
27
87
  The **capability ctx** (`SchemeCtx`) is the DB-free authoring surface for siblings — interfaces only; plurnk-service injects the db-backed impl (see SPEC §3.bis). The db-backed implementations themselves (CRUD primitives, entry-op handlers, channel writes, subscription registry) stay in plurnk-service.
28
88
 
package/SPEC.md CHANGED
@@ -42,8 +42,12 @@ class Known {
42
42
  | `volatile` | Boolean. |
43
43
  | `modelVisible` | Boolean. |
44
44
  | `flags?` | Optional `SchemeFlagAffinity`. |
45
+ | `example?` | One self-documenting usage line (e.g. `"READ(foo://thing/42)"`), surfaced verbatim in the model's packet listing. Omit → not advertised with a usage line. Deep docs do NOT live here — see below. |
46
+ | `glyph?` | Display icon (emoji / nerdfont). Omit → consumer renders the `name` (`glyph ?? name`). |
45
47
  | `storedScheme?` | Value persisted to `entries.scheme`, which may differ from the addressing `name`. Resolution: `storedScheme === undefined ? name : storedScheme`. Absent → defaults to `name` (additive; existing manifests unchanged). Explicit `null` → persists BARE (e.g. File: bare paths, `entries.scheme` NULL, routing name `"file"`). |
46
48
 
49
+ **Self-doc split.** The manifest carries only the terse listing (`example` + `glyph`). Detailed documentation — every op, channel, status code, gotcha — is a markdown the model reads on demand at **`plurnk://schemes/<name>.md`** (the consumer serves it), bypassing the manifest. Keep the manifest a one-liner; the deep doc carries the prose.
50
+
47
51
  ## §2 Interface
48
52
 
49
53
  Sister scheme handlers implement op methods consumed by plurnk-service via dispatch: the engine calls `handler[statement.op.toLowerCase()](statement, ctx)` and returns **501** for any op whose method is absent. The op-dispatch surface is the exported **`SchemeHandler`** interface — every method optional, each `(statement, ctx) => Promise<SchemeResult>`, the per-op statement type from grammar:
@@ -74,6 +78,7 @@ Two surfaces are NOT yet in `SchemeHandler`, pending their result types migratin
74
78
 
75
79
  - Manifest/flags: `SchemeManifest`, `SchemeFlagAffinity`, `WriterTier`, `LoopFlags`, `DEFAULT_LOOP_FLAGS`.
76
80
  - Behavior contract: `SchemeHandler` (§2). Scheme-facing grammar types re-exported here so siblings pin only this package: `PlurnkStatement` + the per-op statement types (`ReadStatement`, `FindStatement`, `ShowStatement`, `HideStatement`, `EditStatement`, `CopyStatement`, `MoveStatement`, `SendStatement`, `ExecStatement`) and path types (`ParsedPath`, `LocalPath`, `UrlPath`).
81
+ - Discovery: `SchemeDiscovery` (behavior class) with `SchemeInfo` / `SchemeDiscoveryResult` / `DiscoverOptions` (§6).
77
82
  - Result families: `SchemeResult` (`EntryResult` | `ProposalResult` | `PassthroughResult`), `SchemeResultBase`, `TelemetryEvent`. Keyed on scheme-shape, not op. `error` is a grammar `TelemetryEvent`, present iff `status >= 400`. Guards `isEntryResult` / `isProposalResult` / `isPassthroughResult` / `isErrorStatus`; builders `schemeError(scheme, kind, message?, position?)`, `logCoordinate(coordinate, op?)`.
78
83
  - Capability ctx (PR-2, see §3.bis): `SchemeCtx` + `EntryCaps` / `ChannelCaps` / `TagCaps` / `NotifyCaps` / `SubscriptionCaps` / `CrossSchemeCaps`, plus `EntryData`, `ChannelState`, `SubscriptionHandle`, `ProposalAware`.
79
84
 
@@ -172,7 +177,7 @@ These migrate when the v1 namespaced ctx API lands (entries / channels / visibil
172
177
  A scheme handler is discovered and registered with **zero first-party involvement** — install it, it lights up. The contract:
173
178
 
174
179
  - **Declare** `plurnk.kind: "scheme"` and `plurnk.name: "<scheme>"` in `package.json`, and `export default` the handler class.
175
- - **Service scans scope-agnostically.** `SchemeRegistry.discoverExternal` walks *all* of `node_modules` — scoped (`@acme/foo`) and unscoped — registering every package with `plurnk.kind === "scheme"` by its declared `plurnk.name`. A third party publishes under their own scope and is found by the same scan; there is no first-party allow-list (plurnk-service#227). A name collision with an in-tree scheme fail-hards.
180
+ - **`SchemeDiscovery` owns the scan (this package).** `SchemeDiscovery.discover({ cwd? })` walks *all* of `node_modules` — scoped (`@acme/foo`) and unscoped — and returns `{ schemes: {name, packageName}[], skipped }` for every package declaring `plurnk.kind === "scheme"` + `plurnk.name`. Scope-agnostic, so a third party under their own scope is found with no first-party allow-list (plurnk-service#227); two externals claiming one prefix fail-hard. It returns **descriptors, not handlers** — contract-only, it never imports a scheme package; the consumer imports each `packageName` and registers `new mod.default()`, applying in-tree precedence. Co-located with its tests here, parallel to `plurnk-execs`/`plurnk-mimetypes`/`plurnk-providers` discover().
176
181
  - **The framework stays contract-only.** `@plurnk/plurnk-schemes` never depends on a scheme package — that would nest daughters under it and the top-level scan would miss them. Daughters peer-pin the framework (exact); it arrives transitively and is itself ignored by the scan (no `plurnk.kind`).
177
182
  - **`@plurnk/plurnk-schemes-all`** is the first-party convenience bundle: it deps the first-party siblings flat so one install surfaces them all. It is never a gate — operators install individual packages or third-party ones identically.
178
183
  - **Trust.** An operator can require host-level trust before a discovered plugin registers (`PLURNK_PLUGINS_TRUSTED_ONLY`, plurnk-service#229) — the scope-agnostic scan widens reach, the trust gate bounds it.
@@ -0,0 +1,17 @@
1
+ export interface SchemeInfo {
2
+ readonly name: string;
3
+ readonly packageName: string;
4
+ }
5
+ export interface SchemeDiscoveryResult {
6
+ readonly schemes: ReadonlyArray<SchemeInfo>;
7
+ readonly skipped: ReadonlyArray<string>;
8
+ }
9
+ export interface DiscoverOptions {
10
+ readonly cwd?: string;
11
+ readonly packageDirs?: ReadonlyArray<string>;
12
+ }
13
+ export default class SchemeDiscovery {
14
+ #private;
15
+ static discover(options?: DiscoverOptions): Promise<SchemeDiscoveryResult>;
16
+ }
17
+ //# sourceMappingURL=SchemeDiscovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemeDiscovery.d.ts","sourceRoot":"","sources":["../src/SchemeDiscovery.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IAClC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAChD;AAED,MAAM,CAAC,OAAO,OAAO,eAAe;;WACnB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAgFvF"}
@@ -0,0 +1,111 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export default class SchemeDiscovery {
4
+ static async discover(options = {}) {
5
+ const dirs = options.packageDirs ?? await SchemeDiscovery.#defaultPackageDirs(options.cwd ?? process.cwd());
6
+ const byName = new Map();
7
+ const skipped = new Set();
8
+ for (const dir of dirs) {
9
+ const info = await SchemeDiscovery.#readSchemeInfo(dir);
10
+ if (info === null)
11
+ continue;
12
+ // Host plugin-trust gate: an untrusted third-party package is
13
+ // discovered but not surfaced for registration — recorded, never crashed on.
14
+ if (!SchemeDiscovery.#isTrusted(info.packageName)) {
15
+ skipped.add(info.packageName);
16
+ continue;
17
+ }
18
+ const existing = byName.get(info.name);
19
+ // Two EXTERNAL packages claiming one scheme prefix is an unresolvable
20
+ // ambiguity — fail-hard, mirroring execs' runtime-collision rule.
21
+ // (In-tree precedence is the consumer's concern; it sees its own set.)
22
+ if (existing !== undefined) {
23
+ throw new Error(`scheme name collision: '${info.name}' claimed by both `
24
+ + `${existing.packageName} and ${info.packageName}`);
25
+ }
26
+ byName.set(info.name, info);
27
+ }
28
+ return { schemes: [...byName.values()], skipped: [...skipped].sort() };
29
+ }
30
+ // Host plugin-trust gate, read from PLURNK_PLUGINS_TRUSTED_ONLY — the SAME
31
+ // env var plurnk-service decides once and every scope-agnostic discovery
32
+ // surface enforces (plurnk-service#229). The ~5-line policy is duplicated,
33
+ // not shared (can't import across the package boundary), matching execs:
34
+ // unset / "" / "0" → OFF: every installed package trusted (no regression).
35
+ // any value → ON: `@plurnk/*` always trusted, plus a comma-separated
36
+ // allowlist of additionally-trusted package names.
37
+ static #isTrusted(packageName) {
38
+ const gate = process.env.PLURNK_PLUGINS_TRUSTED_ONLY;
39
+ if (gate === undefined || gate === "" || gate === "0")
40
+ return true;
41
+ if (packageName.startsWith("@plurnk/"))
42
+ return true;
43
+ return gate.split(",").map((s) => s.trim()).includes(packageName);
44
+ }
45
+ // Enumerate every installed package directory — scoped (`@scope/name`) and
46
+ // unscoped (`name`) — under `<cwd>/node_modules`. Unreadable dirs are the
47
+ // legitimate scan boundary (not-a-package, missing manifest), skipped — not
48
+ // a masked contract violation (cf. the matcher's sanctioned node_modules tolerance).
49
+ static async #defaultPackageDirs(cwd) {
50
+ const nm = path.join(cwd, "node_modules");
51
+ let entries;
52
+ try {
53
+ entries = await fs.readdir(nm, { withFileTypes: true });
54
+ }
55
+ catch {
56
+ return [];
57
+ }
58
+ const dirs = [];
59
+ for (const entry of entries) {
60
+ if (!entry.isDirectory() || entry.name === ".bin" || entry.name === ".cache")
61
+ continue;
62
+ if (entry.name.startsWith("@")) {
63
+ const scopeDir = path.join(nm, entry.name);
64
+ try {
65
+ const scoped = await fs.readdir(scopeDir, { withFileTypes: true });
66
+ for (const s of scoped)
67
+ if (s.isDirectory())
68
+ dirs.push(path.join(scopeDir, s.name));
69
+ }
70
+ catch { /* unreadable scope dir — skip */ }
71
+ }
72
+ else {
73
+ dirs.push(path.join(nm, entry.name));
74
+ }
75
+ }
76
+ return dirs;
77
+ }
78
+ // One SchemeInfo for a package declaring plurnk.kind:"scheme" + plurnk.name;
79
+ // null for anything else (non-package dir, non-scheme, invalid declaration).
80
+ static async #readSchemeInfo(dir) {
81
+ let raw;
82
+ try {
83
+ raw = await fs.readFile(path.join(dir, "package.json"), "utf-8");
84
+ }
85
+ catch {
86
+ return null;
87
+ }
88
+ let pkg;
89
+ try {
90
+ pkg = JSON.parse(raw);
91
+ }
92
+ catch {
93
+ return null;
94
+ }
95
+ if (typeof pkg !== "object" || pkg === null)
96
+ return null;
97
+ const record = pkg;
98
+ const plurnk = record.plurnk;
99
+ if (typeof plurnk !== "object" || plurnk === null)
100
+ return null;
101
+ const plurnkRec = plurnk;
102
+ if (plurnkRec.kind !== "scheme")
103
+ return null;
104
+ if (typeof plurnkRec.name !== "string" || plurnkRec.name === "")
105
+ return null;
106
+ if (typeof record.name !== "string" || record.name === "")
107
+ return null;
108
+ return { name: plurnkRec.name, packageName: record.name };
109
+ }
110
+ }
111
+ //# sourceMappingURL=SchemeDiscovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemeDiscovery.js","sourceRoot":"","sources":["../src/SchemeDiscovery.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export type { EditResult as LineEditResult, JsonSliceResult, SliceResult } from
7
7
  export { default as PathMimetype } from "./path-mimetype.ts";
8
8
  export { default as Matcher } from "./matcher.ts";
9
9
  export type { MatchResult } from "./matcher.ts";
10
+ export { default as SchemeDiscovery } from "./SchemeDiscovery.ts";
11
+ export type { SchemeInfo, SchemeDiscoveryResult, DiscoverOptions } from "./SchemeDiscovery.ts";
10
12
  export { default as Results } from "./results.ts";
11
13
  export type { EntryResult, PassthroughResult, ProposalResult, SchemeResult, SchemeResultBase, TelemetryEvent, } from "./results.ts";
12
14
  export type { ChannelCaps, ChannelState, CrossSchemeCaps, EntryCaps, EntryData, NotifyCaps, ProposalAware, SchemeCtx, SubscriptionCaps, SubscriptionHandle, TagCaps, } from "./ctx.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,YAAY,EACR,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,UAAU,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,UAAU,IAAI,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EACR,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,GACjB,MAAM,cAAc,CAAC;AAItB,YAAY,EACR,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,SAAS,EACT,UAAU,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,OAAO,GACV,MAAM,UAAU,CAAC;AAOlB,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EACR,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,SAAS,EACT,OAAO,GACV,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,YAAY,EACR,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,UAAU,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,UAAU,IAAI,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EAAE,UAAU,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EACR,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,GACjB,MAAM,cAAc,CAAC;AAItB,YAAY,EACR,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,SAAS,EACT,UAAU,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,OAAO,GACV,MAAM,UAAU,CAAC;AAOlB,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EACR,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,SAAS,EACT,OAAO,GACV,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -11,5 +11,6 @@ export { default as MimetypeClassifier, TEXT_PRIMITIVE_MIMETYPE } from "./mimety
11
11
  export { default as Slicer } from "./line-marker.js";
12
12
  export { default as PathMimetype } from "./path-mimetype.js";
13
13
  export { default as Matcher } from "./matcher.js";
14
+ export { default as SchemeDiscovery } from "./SchemeDiscovery.js";
14
15
  export { default as Results } from "./results.js";
15
16
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,yEAAyE;AACzE,4BAA4B;AAS5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,4EAA4E;AAC5E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,yEAAyE;AACzE,4BAA4B;AAS5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,4EAA4E;AAC5E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC"}
package/dist/types.d.ts CHANGED
@@ -15,6 +15,8 @@ export interface SchemeManifest {
15
15
  readonly volatile: boolean;
16
16
  readonly modelVisible: boolean;
17
17
  readonly flags?: SchemeFlagAffinity;
18
+ readonly example?: string;
19
+ readonly glyph?: string;
18
20
  readonly storedScheme?: string | null;
19
21
  }
20
22
  export interface LoopFlags {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAElE,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAUpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CACjC;AAED,eAAO,MAAM,kBAAkB,EAAE,SAM/B,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAElE,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAUpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAUxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CACjC;AAED,eAAO,MAAM,kBAAkB,EAAE,SAM/B,CAAC"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,qCAAqC;AACrC,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,sEAAsE;AACtE,uEAAuE;AACvE,+CAA+C;AAyC/C,MAAM,CAAC,MAAM,kBAAkB,GAAc,MAAM,CAAC,MAAM,CAAC;IACvD,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,KAAK;IACZ,aAAa,EAAE,KAAK;IACpB,WAAW,EAAE,KAAK;CACrB,CAAC,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,qCAAqC;AACrC,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,sEAAsE;AACtE,uEAAuE;AACvE,+CAA+C;AAoD/C,MAAM,CAAC,MAAM,kBAAkB,GAAc,MAAM,CAAC,MAAM,CAAC;IACvD,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,KAAK;IACZ,aAAa,EAAE,KAAK;IACpB,WAAW,EAAE,KAAK;CACrB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plurnk/plurnk-schemes",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "Framework + contract for the @plurnk/plurnk-schemes-* URI handler family.",
5
5
  "keywords": [
6
6
  "plurnk",