@intentic/extension-manifest 1.310.0 → 1.311.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.
Files changed (2) hide show
  1. package/README.md +29 -65
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -1,74 +1,38 @@
1
- # @intentic/extension-manifest
1
+ # extension-manifest
2
2
 
3
- What an extension **declares**: as opposed to what it programs against.
3
+ The schema of `intentic-extension.json`: what an extension declares it contributes and may reach, which the install dialog shows and the host holds every registration to.
4
4
 
5
- This package holds the `intentic-extension.json` schema and the rule that matches a daemon call against the
6
- manifest's `permissions.sandbox` allowlist. Nothing else: no host API, no Vue, no runtime behaviour. It imports
7
- zod and nothing more.
8
-
9
- ## Why it is its own package
10
-
11
- It exists to break a cycle. The daemon's wire contract (`@intentic/sandbox-contract`) has to validate manifests,
12
- because the daemon serves extension listings and gates installs: so it needs the schema. The host API
13
- (`@intentic/extension-api`) has to name the daemon's typed client, because that is what an extension calls the
14
- sandbox through: so it needs the contract. With the schema living in `extension-api`, those two requirements
15
- formed a loop, and the loop is why `api.sandbox` could only ever offer `request(path)` and `json<T>(path)`: a
16
- string-shaped door to a fully typed surface, with every extension re-writing the URL, the method and the
17
- response shape by hand.
18
-
19
- Splitting the declaration vocabulary out settles it in one direction:
20
-
21
- ```
22
- extension-manifest ← sandbox-contract ← extension-api
5
+ ```mermaid
6
+ flowchart LR
7
+ points["src/points/<br/>one file per contribution point"] --> manifest(["ExtensionManifestSchema"])
8
+ manifest -- "manifestJsonSchema" --> schema["intentic-extension.schema.json<br/>author's editor hover text"]
9
+ manifest --> daemon["Daemon<br/>install · updates · route gate"]
10
+ manifest --> web["Editor<br/>install dialog · extension host"]
11
+ manifest --> scan["registry-scan<br/>readiness checks"]
23
12
  ```
24
13
 
25
- Both of the other packages depend on this one; this one depends on neither. `extension-api` may now name
26
- contract types, which is what lets `api.sandbox.rpc` be typed.
27
-
28
- ## One point, one file
29
-
30
- What a manifest may declare is not one schema: it is thirteen independent ones, and they used to share a file
31
- every feature had to edit to add anything, in two places at once. Each now lives alone under
32
- [src/points/](src/points), as its key, its shape and **the sentence that explains it to the author**, and
33
- `contributes` is assembled from the set. Adding a contribution point is a file plus a line.
34
-
35
- Binding the description to the schema is the part that pays. It used to sit in a `//` comment: read by
36
- maintainers, never by the one person it was written for: so a manifest was written by copying another
37
- extension's and guessing. Worse, zod *strips* what it does not declare rather than refusing it, at every level:
38
- a misspelt `viewers` was not an error, it was a viewer that never appeared, found at install, with the manifest
39
- parsing perfectly. The descriptions now generate out to `intentic-extension.schema.json`, which an editor reads
40
- to give completion, hover documentation and a red squiggle on a key nothing declares.
41
-
42
- That schema is **strict where the runtime is lenient**, deliberately. Authoring is where an unknown key is a
43
- typo worth shouting about; runtime is where one is a manifest written for a newer host, which an older daemon
44
- must go on installing with the point it does not understand ignored: otherwise every addition to that list
45
- would be a breaking change.
14
+ - `manifest.ts` is the envelope. Each contribution point (views, commands, capabilities, listener, processes and the
15
+ rest) is a `ContributionPoint` in `src/points/`, carrying the sentence an author sees as hover text.
16
+ - The runtime parse is lenient and the authoring schema strict, since an unknown key in an author's file is a typo.
17
+ The generated schema is committed twice, here and in the site's `public/` behind `MANIFEST_SCHEMA_URL`, and the
18
+ editor's `manifest-schema.test.ts` fails when either copy is stale.
19
+ - `sandboxRouteAllowed` is the permission rule: an entry is `"<METHOD> <path-glob>"`, and each `*` matches one path
20
+ segment.
21
+ - `diffPowers` folds two manifests into the powers an owner approved, so an update re-asks only when it adds one.
22
+ - `HOST_PUBLISHED_SPECIFIERS` lists the only bare imports a published bundle may use: the modules the shell's import
23
+ map provides.
46
24
 
47
25
  ## Key files
48
26
 
49
- - [src/points/](src/points): one contribution point per file, and the index that collects them into
50
- `CONTRIBUTION_POINTS` and assembles `contributes` from it.
51
- - [src/contribution-point.ts](src/contribution-point.ts), what a point *is*: name, description, schema. The
52
- reasoning for why the description travels with the schema rather than sitting in a comment.
53
- - [src/manifest.ts](src/manifest.ts), the envelope: who the extension is, which host it needs, what code it
54
- ships, how far it may reach. The manifest is the **approval + gating surface**: the install dialog shows
55
- exactly the declared contribution points, and the host refuses any runtime registration the approved manifest
56
- never declared.
57
- - [src/json-schema.ts](src/json-schema.ts): the authoring schema, emitted from those points.
58
- - [src/permissions.ts](src/permissions.ts): `sandboxRouteAllowed`, the `"<METHOD> <path-glob>"` matcher behind
59
- `permissions.sandbox`. Kept beside the schema because it is the rule for one of the schema's own fields.
27
+ - [src/manifest.ts](src/manifest.ts) — `ExtensionManifestSchema`, the envelope.
28
+ - [src/points/index.ts](src/points/index.ts) — every contribution point, assembled into `contributes`.
29
+ - [src/permissions.ts](src/permissions.ts) — the sandbox-route allowlist rule.
30
+ - [src/powers-diff.ts](src/powers-diff.ts) — what an update asks for, as set arithmetic over powers.
31
+ - [src/bundle.ts](src/bundle.ts) — which imports a published bundle may name.
32
+ - [intentic-extension.schema.json](intentic-extension.schema.json) — the generated authoring schema.
60
33
 
61
- ## Conventions & gotchas
34
+ ## Commands
62
35
 
63
- - **Declaration only.** If something here needed to know how the host behaves, it would belong in
64
- `extension-api` instead. The test is whether the daemon (which has no host and no browser) still needs it.
65
- - The contribution-point list is read back by the host's surface guard, which compares it against
66
- `extension-api`'s recorded surface and its README: so adding a contribution point here without bumping the
67
- SDK version there fails that test rather than shipping a version number that lies about what it supports.
68
- - **The generated schema is committed, in two copies**: the one shipped in this package and the one the site
69
- serves at the `$schema` URL. Run `pnpm --filter @intentic/extension-manifest schema` after touching a point
70
- and commit both; `manifest-schema.test.ts` regenerates and compares, the way `contract.lock.json` is guarded.
71
- A generated document only guards anything if a diff shows it moving.
72
- - Points are collected in an explicit list rather than by a module-load side effect. Two committed documents
73
- are generated from them (that schema and the wire contract's lock) and a registry that filled itself as
74
- modules happened to load would make both depend on import order.
36
+ ```sh
37
+ pnpm --filter @intentic/extension-manifest schema # regenerate both copies of the authoring schema
38
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentic/extension-manifest",
3
- "version": "1.310.0",
3
+ "version": "1.311.0",
4
4
  "description": "What an intentic extension DECLARES, the intentic-extension.json schema and the sandbox-route allowlist rule",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  }
33
33
  },
34
34
  "dependencies": {
35
- "@intentic/base": "1.310.0",
35
+ "@intentic/base": "1.311.0",
36
36
  "tslib": "2.8.1",
37
37
  "zod": "4.5.4"
38
38
  },