@north-light/cli 0.3.483 → 0.3.484

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 (92) hide show
  1. package/dist/api/client.d.ts +6 -0
  2. package/dist/api/client.js +3 -3
  3. package/dist/api/contract.d.ts +1 -1
  4. package/dist/api/contract.js +1 -1
  5. package/dist/api/dto/custom-objects.d.ts +5 -1
  6. package/dist/api/dto/docs.d.ts +26 -0
  7. package/dist/api/dto/objects.d.ts +21 -1
  8. package/dist/api/dto/plugins.d.ts +22 -0
  9. package/dist/api/dto/plugins.js +0 -0
  10. package/dist/api/index.d.ts +1 -0
  11. package/dist/api/index.js +1 -1
  12. package/dist/api/routes.d.ts +2 -0
  13. package/dist/api/routes.js +1 -1
  14. package/dist/builtin-memory/crouter-plugin/deploying.md +107 -0
  15. package/dist/builtin-memory/crouter-sdk/release-notes.md +69 -0
  16. package/dist/clients/attach/viewer.js +579 -578
  17. package/dist/commands/pkg/plugin-manage.d.ts +4 -0
  18. package/dist/commands/pkg/plugin-manage.js +18 -16
  19. package/dist/core/canvas/migrations.js +27 -18
  20. package/dist/core/command-plugins/bundle.d.ts +4 -1
  21. package/dist/core/command-plugins/bundle.js +1 -1
  22. package/dist/core/command-plugins/caller-header.d.ts +10 -0
  23. package/dist/core/command-plugins/caller-header.js +1 -0
  24. package/dist/core/command-plugins/compose.js +1 -1
  25. package/dist/core/command-plugins/endpoint.d.ts +4 -0
  26. package/dist/core/command-plugins/endpoint.js +1 -1
  27. package/dist/core/command-plugins/transport/exec-invoke-async.d.ts +11 -0
  28. package/dist/core/command-plugins/transport/exec-invoke-async.js +1 -0
  29. package/dist/core/command-plugins/transport/exec-invoke.d.ts +14 -0
  30. package/dist/core/command-plugins/transport/exec-invoke.js +1 -1
  31. package/dist/core/command-plugins/transport/http-invoke.d.ts +9 -2
  32. package/dist/core/command-plugins/transport/http-invoke.js +3 -3
  33. package/dist/core/command-plugins/transport/http-plan.js +1 -1
  34. package/dist/core/command-plugins/transport/sign.d.ts +55 -0
  35. package/dist/core/command-plugins/transport/sign.js +3 -0
  36. package/dist/core/graph/access.d.ts +19 -0
  37. package/dist/core/graph/access.js +3 -3
  38. package/dist/core/graph/custom.d.ts +29 -9
  39. package/dist/core/graph/custom.js +9 -8
  40. package/dist/core/graph/events.js +8 -8
  41. package/dist/core/graph/package-kinds.d.ts +25 -0
  42. package/dist/core/graph/package-kinds.js +1 -0
  43. package/dist/core/graph/package-reconcile.d.ts +20 -0
  44. package/dist/core/graph/package-reconcile.js +1 -0
  45. package/dist/core/graph/reader.d.ts +5 -0
  46. package/dist/core/graph/reader.js +3 -3
  47. package/dist/core/graph/receivers.d.ts +2 -1
  48. package/dist/core/graph/types.d.ts +2 -0
  49. package/dist/core/graph/watches.d.ts +4 -0
  50. package/dist/core/graph/watches.js +9 -8
  51. package/dist/core/peer/directory.d.ts +2 -1
  52. package/dist/core/peer/directory.js +1 -1
  53. package/dist/core/peer/ingest.d.ts +6 -1
  54. package/dist/core/peer/ingest.js +1 -1
  55. package/dist/core/peer/names.d.ts +2 -0
  56. package/dist/core/peer/names.js +1 -1
  57. package/dist/core/peer/outbox-store.d.ts +2 -0
  58. package/dist/core/peer/receiver.js +1 -1
  59. package/dist/core/peer/stubs.d.ts +26 -1
  60. package/dist/core/peer/stubs.js +1 -1
  61. package/dist/core/plugin-app.d.ts +31 -0
  62. package/dist/core/plugin-app.js +1 -0
  63. package/dist/core/plugin-objects-manifest.d.ts +35 -0
  64. package/dist/core/plugin-objects-manifest.js +1 -0
  65. package/dist/core/providers/bundles.js +2 -2
  66. package/dist/core/providers/call.d.ts +3 -0
  67. package/dist/core/providers/call.js +1 -1
  68. package/dist/core/secrets.d.ts +11 -0
  69. package/dist/core/secrets.js +1 -1
  70. package/dist/daemon/api/app-listener.js +13 -13
  71. package/dist/daemon/api/handlers/custom-objects.js +3 -3
  72. package/dist/daemon/api/handlers/objects.js +3 -2
  73. package/dist/daemon/api/handlers/package-docs.js +1 -1
  74. package/dist/daemon/api/handlers/plugin-app-token.d.ts +6 -0
  75. package/dist/daemon/api/handlers/plugin-app-token.js +1 -0
  76. package/dist/daemon/api/handlers/providers.d.ts +7 -0
  77. package/dist/daemon/api/handlers/providers.js +1 -1
  78. package/dist/daemon/api/operations.js +1 -1
  79. package/dist/daemon/api/server.js +1 -1
  80. package/dist/daemon/crtrd.js +7 -5
  81. package/dist/daemon/peer/forward.d.ts +4 -1
  82. package/dist/daemon/peer/forward.js +1 -1
  83. package/dist/daemon/plugin-objects/read-leaf.d.ts +20 -0
  84. package/dist/daemon/plugin-objects/read-leaf.js +2 -0
  85. package/dist/types.d.ts +16 -0
  86. package/docs/plugin/deploying.md +107 -0
  87. package/docs/sdk/release-notes.md +69 -0
  88. package/package.json +2 -2
  89. package/packages/crouter-identity/dist/index.d.ts +1 -1
  90. package/packages/crouter-identity/dist/index.js +6 -2
  91. package/packages/crouter-identity/package.json +1 -1
  92. package/runtime.lock.json +12 -12
@@ -9,6 +9,75 @@ when-and-why-to-read: When you need Release notes, this knowledge should be read
9
9
 
10
10
  Changes to `@north-light/sdk` that can change what an existing app sees. Newest first.
11
11
 
12
+ ## 0.3.484
13
+
14
+ Plugins can now declare canvas object kinds and act on the canvas, and an app token can be granted canvas scopes. Everything below is additive: no request or response an existing app sends or reads changes, with one runtime-side exception under [Unknown bearers](#unknown-bearers-are-refused).
15
+
16
+ ### Plugin manifests declare `object_kinds` and `scopes` (additive)
17
+
18
+ `plugin.json` and `bundle.json` take two optional top-level blocks. `object_kinds` maps a kind name (`<plugin>.<name>`, so the first segment is the plugin's own name) to `{ description, events, read? }`: `events` holds up to 64 entries `{ level: 1-10, supersedes?: boolean }`, and `read.command` is a leaf path below the plugin's root command. That leaf must answer once: a leaf declared `rest.streaming: true` is refused as a `read.command`. `scopes` lists the canvas scopes the plugin asks for. A provider bundle may not declare `scopes`: a cloud app's scopes come from directory consent. Install, update and enable refuse an invalid block and keep the installed version; a kind another owner already holds is reported as `kind_owned` and the plugin's other kinds still apply. `crtr pkg plugin install|update|enable` print these as `warnings`, plus `appScopes` (the scopes the plugin's token now carries). Plugin authors: see [[crouter-plugin/deploying]].
19
+
20
+ `ReconcilePackagesDTO` (the answer of `POST /v1/documents/reconcile-packages`) gains two optional fields: `kinds` (`applied` with `outcome` of `inserted`, `updated` or `unchanged`; `refused` with code `kind_owned`; `invalid` plugins with the reason) and `tokens` (`granted` plugins with their scopes, and `revoked` plugin names).
21
+
22
+ ### Canvas object scopes `crtr:objects:<verb>:<target>` (additive)
23
+
24
+ `@north-light/identity` accepts `crtr:objects:<read|watch|link|write>:<user|node|profile:<id>|app:<x>>`. Each scope is its own grant: `covers` is exact equality, so `crtr:objects:write:user` does not imply `read`. The target is where the object lives:
25
+
26
+ - `user`: objects in the person's space.
27
+ - `profile:<id>`: objects below that profile.
28
+ - `app:<x>`: nodes and custom objects of another app `x`. An app never needs a scope for its own objects, and a plugin may not declare its own `app:<plugin>` space.
29
+ - `node`: any node, including the stub of a node on another of the account's machines.
30
+
31
+ `read` lets the holder read objects of the target, `write` change them, and `link` (below) make a node watch an object the holder owns. `watch` lets a custom object that watches an object of the target read it. Holding a scope never lifts run confinement inside the owning app, and a revoked grant holds nothing. A public custom object is readable by any app that may use the owning app's tools, with no scope. The app listener now serves the canvas operations (`objects.*`, `custom-objects.*`, `docs.*`) to an app grant token under its resolved scopes; those rows answered `unknown operation` there before.
32
+
33
+ ### The `crtr_app_` credential and its socket fetch (additive)
34
+
35
+ Each enabled local plugin that declares `object_kinds` or `scopes`, or serves over HTTP, holds one `crtr_app_…` token carrying its manifest's `scopes`. It is issued when the plugin is installed or enabled, reissued on update (the scopes can change), and revoked on uninstall or disable. crtrd accepts it as a bearer on its unix socket and TCP listener, looks it up on every request (a revoked token stops working on the next one), and treats the holder as app `app:<plugin>`.
36
+
37
+ - `GET /v1/plugins/:name/app-token` (new operation `plugins.app-token`, person and broker callers) answers `{ token, socket }`, or `404 not_found` when the plugin is not installed, enabled, valid and holding a token. A service fetches it once at startup over the socket as the user who runs it. A node whose uid is not the daemon's gets `403 forbidden`.
38
+ - An exec plugin receives the token as `CRTR_APP_TOKEN` and the socket as `CRTR_DAEMON_SOCKET` in its leaf's environment. crtr never sends the token to a plugin's HTTP port.
39
+ - SDK: `CrtrClient.plugins.appToken(name)` and the DTO `PluginAppTokenDTO`; route helper `routes.pluginAppToken(name)`.
40
+
41
+ ### `Crtr-Caller` and `Crtr-Signature` on local HTTP calls (additive)
42
+
43
+ Every HTTP call to a plugin carries `Crtr-Caller: node=<id>; machine=<id>; profile=<id>; run=<id>` (fields in that order, empty ones left out, header omitted when none). Calls to a local plugin's endpoint origin also carry `Crtr-Signature: v1,t=<unix seconds>,h=<signed header names>,sig=<base64url HMAC-SHA256 keyed by the plugin's token>` plus a fresh `Crtr-Request-Id`. A manifest cannot set these three header names. Provider calls carry `Crtr-Caller` too. Plugin authors: the canonical string and a reference verifier are in [[crouter-plugin/deploying]].
44
+
45
+ crtrd signs the call; the CLI never holds the token. `POST /v1/plugins/:name/call-headers` (new operation `plugins.call-headers`, person and broker callers) takes only digests, `{ method, url, body_sha256, header_names, headers_sha256 }`, and answers `{ headers }` (`Crtr-Caller`, and `Crtr-Signature` when the URL is on the installed endpoint's origin and that endpoint is loopback). Any other URL gets `Crtr-Caller` only. An unknown or disabled plugin and a provider plugin answer `404 not_found`; malformed digests answer `400 invalid_request`. SDK: `CrtrClient.plugins.callHeaders(name, request)`, `PluginCallHeadersRequestDTO`, `PluginCallHeadersDTO`, `routes.pluginCallHeaders(name)`.
46
+
47
+ ### Unknown bearers are refused
48
+
49
+ A bearer that crtrd does not recognize is now `401` on the TCP listener as well. A runtime with no owner token used to treat a request with a bearer it did not know as the owner; now only a request with no bearer is, and a live `crtr_app_` token is that app. `crtr_pub_` and the owner token behave as before.
50
+
51
+ ### `custom-objects.register` takes `privacy`, and `events` is optional (additive)
52
+
53
+ `RegisterCustomObjectRequestDTO.privacy?` is `public` (the default), `friends` or `private`; setting it on an existing instance changes it and publishes `configured` with `privacy` in `changed`. `events` is now optional: omit it to create or return an instance of a kind an installed plugin declares, which leaves the kind's catalog alone. Omitting it for any other kind is still `400 invalid_request`. `kind_owned` now guards only the kind catalog: registering an instance of a plugin's kind never conflicts with it.
54
+
55
+ ### Publishing a plugin-declared kind has new refusals
56
+
57
+ `custom-objects.publish` on an instance of a kind that an installed plugin declares (or that crossed from another machine):
58
+
59
+ - `404 not_here` when this machine holds only a stub of the object. Details are `{ id, home_machine }`; ask the home machine.
60
+ - `409 kind_inert` when the kind's plugin is no longer installed and enabled.
61
+ - `403 forbidden` unless the caller is the kind's owning app or holds the instance's publish token.
62
+
63
+ Instances of kinds an app registered itself publish as before.
64
+
65
+ ### Watching with `link` and `watcher_machine` (additive)
66
+
67
+ `POST /v1/objects/:ref/watch` and `DELETE …/watch` take an optional `watcher` ref naming a node or a custom object. A non-person app caller can name a node as the `watcher` when the object is one it owns and it holds `crtr:objects:link:<target of the watcher>`: the node then watches the object. Any miss, whatever the cause, is `404 not_found`. `watcher_machine` (body field; query parameter on DELETE) names the machine of an account's other node as the watcher; crtrd keeps a local stand-in for that node, and an event for a node that never watched the stand-in locally still reaches the node. A `watcher_machine` that is not one of the account's machines is `404`; an unreachable directory is `503 runtime_unreachable`. Custom-object watchers behave as before.
68
+
69
+ A linked node receives the object's events even when it could not read the object by its own access. crtrd keeps the linking app on the watch and checks its scope and ownership again at each publish, so a revoked scope or token stops new deliveries. Across machines, both the object's home machine and the node's machine need this release.
70
+
71
+ ### Reading: `kind_decl`, privacy and plugin read text (additive)
72
+
73
+ `ObjectDTO` gains an optional `kind_decl` (`{ name, description, events, owner }`). The runtime fills it on the object of an `objects.read` answer and of an `objects.watch` answer when the object is an instance of a custom kind, so another machine can hold a stub of it. It grants nothing. `ObjectListItemDTO` extends `ObjectDTO`, so its type carries the field, but list and search answers do not fill it. `privacy` is the field `ObjectDTO` already had: a read answered by another machine now carries the home object's `kind_decl` and `privacy` into the reader's stub, so a stub is never more readable than its home object.
74
+
75
+ A read of an instance of a plugin kind whose manifest sets `read.command` runs that leaf on the home machine (15 s deadline for exec and provider plugins alike), outside the canvas transaction, and returns its `markdown` as `text`. The `read` event and the read watch are recorded once. Access is checked again after the leaf returns, and a reader who lost it gets `not_found`; an object deleted while the leaf ran answers `state: "deleted"`, and one that vanished answers `not_found`. If the leaf cannot answer (plugin not installed or disabled, timeout, no string `markdown`), `text` is the last announcement followed by `\ncontent unavailable: <reason>`. Such a read adds `data.content`: `"live"` or `"unavailable"`. A kind that is no longer declared by an installed plugin, a kind without `read.command`, and every other object read as before, with no `data.content`.
76
+
77
+ ### Migrations v89–v91
78
+
79
+ The canvas database gains `object_kinds.read_json`, `object_kinds.source` (`register`, `manifest` or `peer`) and `object_kinds.declared` (v89), a `peer_ingested_destinations` table recording each event destination already ingested from another machine (v90), and `watches.link_app`, the app that made a watch through `link` (v91). No app action; an older runtime cannot open a database migrated by this release.
80
+
12
81
  ## 0.3.483
13
82
 
14
83
  ### `unavailable`, `step` and `setupLink` on `grant.get` dependencies (additive for the SDK; a type change for exhaustive switches)