You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(connector-openapi): resolve providerConfig.spec from a package-relative file path (#3016) (#3024)
* feat(connector-openapi): resolve providerConfig.spec from a package-relative file path (#3016)
ADR-0096 follow-up: complete the spec union (inline object | file path |
remote URL) for the declarative openapi provider.
- spec: ConnectorProviderContext gains an optional host-injected
loadPackageFile capability (pure type)
- service-automation: packageRoot option + createPackageFileLoader with a
root-confinement guard (rejects absolute and ..-escaping paths; lazy
node:fs/node:path imports); capability injected into every provider ctx;
failures follow the reconcile policy (fatal at boot, soft on reload)
- connector-openapi: non-URL string specs are read via ctx.loadPackageFile
and parsed as OpenAPI JSON with clear errors
- cli: serve/dev anchor packageRoot to the objectstack.config.ts directory
- tests: file-path happy path, missing file (fatal at boot / skipped on
reload), traversal rejection; ADR-0096 scope-boundary note updated
Closes#3016
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016eY7byWABTUPtJG7R2AEFU
* docs(spec) + showcase: demo the openapi file-path spec (#3016)
- spec: providerConfig describe/TSDoc now documents the spec union
(inline object | package-relative file path | http(s) URL) so the
auto-generated references pick it up
- showcase: StatusOpenApiConnector — a provider: 'openapi' declarative
instance whose OpenAPI document is referenced as a package-relative
file path (src/system/connectors/status-openapi.json), materialized at
boot by an option-less ConnectorOpenApiPlugin; getHealth dispatches
GET /api/v1/health against the running server itself
- coverage notes + stale connectors: comment updated (the collection has
held provider-bound instances since ADR-0096, not only descriptors)
Verified: booted the showcase (--fresh, random port); GET
/api/v1/automation/connectors lists showcase_status_openapi
(origin: declarative) with the getHealth action.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016eY7byWABTUPtJG7R2AEFU
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/adr/0096-declarative-connector-instances.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -134,6 +134,6 @@ keeps serving until its replacement materializes successfully. Boot keeps the
134
134
135
135
### Deliberate scope boundaries
136
136
137
-
-**`providerConfig.spec` (openapi)** accepts an inline document or an http(s) URL; resolving a `./file.json` ref relative to the stack is the stack loader's job, not the connector's.
137
+
-**`providerConfig.spec` (openapi)** accepts an inline document, an http(s) URL, **or a package-relative file path** (#3016 follow-up). The connector still owns no filesystem access: the automation service injects a `loadPackageFile` capability into `ConnectorProviderContext` that resolves the ref against the declaring stack/package root (`packageRoot`, CLI default: the `objectstack.config.ts` directory) and **confines reads to that root** — absolute and `..`-escaping paths are rejected. Read/parse failures follow the reconcile policy above: fatal at boot, skipped on reload.
138
138
-**MCP credentials** ride the transport (ADR-0024); for an http transport a resolved `auth` is folded into the request headers.
139
139
-**MCP at boot** connects during materialization, so an unreachable server fails boot; a fail-soft "optional" marker for boot-time materialization is a possible future refinement (runtime reloads are already soft).
'Both connector kinds are demonstrated. (1) Provider-bound INSTANCE (ADR-0096 / #2977): StatusApiConnector declares `provider: rest` and is materialized into a live, dispatchable connector at boot by ConnectorRestPlugin\'s provider factory — ShowcaseDeclarativeConnectorPingFlow calls it via connector_action and it appears in GET /connectors. (2) Catalog DESCRIPTOR (#2612): ErpCatalogConnector has no provider, so it stays inert metadata; enabled:false marks the deliberate catalog entry and silences the boot audit. Plugin-registered connectors (ConnectorRestPlugin/ConnectorSlackPlugin in objectstack.config.ts) are also exercised by the connector flows.',
182
+
'Both connector kinds are demonstrated. (1) Provider-bound INSTANCES (ADR-0096 / #2977): StatusApiConnector declares `provider: rest` (inline config) and StatusOpenApiConnector declares `provider: openapi` with its OpenAPI document referenced as a package-relative FILE PATH (#3016, read at boot and confined to the package root) — both are materialized into live, dispatchable connectors at boot; ShowcaseDeclarativeConnectorPingFlow calls the rest instance via connector_action and both appear in GET /connectors. (2) Catalog DESCRIPTOR (#2612): ErpCatalogConnector has no provider, so it stays inert metadata; enabled:false marks the deliberate catalog entry and silences the boot audit. Plugin-registered connectors (ConnectorRestPlugin/ConnectorSlackPlugin in objectstack.config.ts) are also exercised by the connector flows.',
"description": "Minimal OpenAPI document for the showcase's own health probe. Referenced by the StatusOpenApiConnector declarative instance (src/system/connectors/index.ts) as a package-relative file path — the #3016 / ADR-0096 spec form resolved and confined to this package's root at boot."
7
+
},
8
+
"servers": [{ "url": "http://127.0.0.1:3000" }],
9
+
"paths": {
10
+
"/api/v1/health": {
11
+
"get": {
12
+
"operationId": "getHealth",
13
+
"summary": "Server health probe",
14
+
"description": "Returns the running server's health status.",
0 commit comments