Skip to content

Commit 41256e9

Browse files
committed
Merge origin/main into claude/harden-connector-credentials
Claude-Session: https://claude.ai/code/session_017xRBcVy4VXmkQjn2MGeaWk Co-authored-by: Claude <noreply@anthropic.com>
2 parents 88503d9 + 617dcf4 commit 41256e9

208 files changed

Lines changed: 7767 additions & 1063 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.changeset/25921-collaboration-zero-consumer-exports.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ What leaves, and what to write instead:
1515

1616
- FROM `useCommentSearch` TO a `useMemo` over your own comment list that keeps the entries whose `text` or `author` contains the trimmed, lower-cased query.
1717
- FROM `CommentSearchConfig` TO `{ comments: CommentEntry[] }`, with `CommentEntry` from `@object-ui/types`.
18-
- FROM `CommentSearchReturn` TO the shape your own search state returns; the result rows can keep using `CommentSearchResult` from `@object-ui/types`.
18+
- FROM `CommentSearchReturn` TO the shape your own search state returns; type the result rows with a local interface, `{ comment: CommentEntry; objectName: string; recordId: string; highlight?: string }` (`CommentSearchResult` leaves `@object-ui/types` in the same release).
1919
- FROM `createPresenceUpdater` TO a `Map<string, PresenceUser>` keyed by `userId` that you update from your realtime channel, or `PresenceProvider` with `useTenantPresence` / `useRecordPresence`, which the package keeps exporting.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@object-ui/core': patch
3+
---
4+
5+
refactor(core)!: take the test-only `resetActionKeyWarnings` off the package entry
6+
7+
Clause-②: no (narrowing)
8+
Metadata-protocol: none
9+
10+
<!-- adr-0087: not-required (runtime-export-retired @object-ui/core#resetActionKeyWarnings) the retired operand is a test seam that clears a warn-once memo; nothing in the workspace or in hotcrm imported it from the package entry, and no packages/spec schema, registered node type, conversion surface or stored shape names it, so there is nothing for `objectstack migrate meta` to rewrite -->
11+
12+
**BREAKING** for a host that imports `resetActionKeyWarnings` from `@object-ui/core`. It cleared the once-per-key memo behind the unknown-action-key warning and existed for tests; core's own tests reach it through the module that declares it. The other ten names of that module (`ACTION_DEF_KEYS`, `SPEC_ACTION_KEYS`, `NAVIGATION_ALIAS_KEYS`, `HOST_DISPATCH_ACTION_KEYS`, `RETIRED_ACTION_KEYS`, `KNOWN_ACTION_KEYS`, `classifyActionKeys`, `warnOnUnknownActionKeys`, `hasDeprecatedObjectParams`, `warnOnDeprecatedObjectParams`) stay exported unchanged, and the warning itself still fires once per key.
13+
14+
- FROM `resetActionKeyWarnings()` in a test TO a fresh module instance per test (`vi.resetModules()` before importing `@object-ui/core`), or no reset at all when the test asserts the first warning only.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@object-ui/i18n': patch
3+
---
4+
5+
refactor(i18n)!: delete four `publicForm` keys that no screen reads
6+
7+
Clause-②: no (narrowing)
8+
Metadata-protocol: none
9+
10+
<!-- adr-0087: not-required (no-migration-prescription) the four deleted keys are message strings in the built-in locale packs that no t() call site in the workspace or in hotcrm reads (the embeddable form draws its own English literals instead); they are not metadata, no packages/spec schema or stored shape names them, and a host that kept its own text under these keys keeps it in its own resources -->
11+
12+
**BREAKING** only for TypeScript code that names one of the deleted keys through the pack-derived key type (`TranslationKeys`): `publicForm.consentRequired`, `publicForm.rateLimited`, `publicForm.redirectBlocked` and `publicForm.requiredHint` leave all ten packs (ar, de, en, es, fr, ja, ko, pt, ru, zh). No translation call read them. `EmbeddableForm` in `@object-ui/plugin-form` draws the same wording as hard-coded English defaults for `consentRequired`, `rateLimited` and `requiredHint`, and shows `redirectBlocked` only when the form author supplies `texts.redirectBlocked`; those defaults were never localised through these keys and stay un-localised English after this change. An author localises them per form through `config.texts`. The form page's other `publicForm` keys (`submit`, `submitting`, `poweredBy`, `thankYouTitle`, `thankYouMessage`, `redirecting`, `redirectPending`, `loading`, `requiredFields`) are unchanged.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@object-ui/plugin-detail': patch
3+
---
4+
5+
refactor(plugin-detail)!: take the test-only `resetUnknownActivityTypeWarnings` off the package entry
6+
7+
Clause-②: no (narrowing)
8+
Metadata-protocol: none
9+
10+
<!-- adr-0087: not-required (runtime-export-retired @object-ui/plugin-detail#resetUnknownActivityTypeWarnings) the retired operand is a test seam that clears the warn-once bucket of the unmapped activity-type diagnostic; no shipped code in the workspace or in hotcrm called it, and no packages/spec schema, registered node type, conversion surface or stored shape names it, so there is nothing for `objectstack migrate meta` to rewrite -->
11+
12+
**BREAKING** for a host that imports `resetUnknownActivityTypeWarnings` from `@object-ui/plugin-detail`. It existed for tests; the one workspace test outside the package now imports it from the module that declares it. `ACTIVITY_TYPE_TO_FEED_TYPE`, `UNMAPPED_ACTIVITY_FEED_TYPE`, `activityRowToFeedItem` and `isRefusedFeedRead` stay exported unchanged, and the diagnostic still warns once per unmapped type.
13+
14+
- FROM `resetUnknownActivityTypeWarnings()` in a test TO a fresh module instance per test (`vi.resetModules()` before importing `@object-ui/plugin-detail`), or an activity type unique to that test.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@object-ui/react': patch
3+
---
4+
5+
refactor(react)!: take the test-only `__resetVisibilityPredicateWarnings` off the package entry
6+
7+
Clause-②: no (narrowing)
8+
Metadata-protocol: none
9+
10+
<!-- adr-0087: not-required (runtime-export-retired @object-ui/react#__resetVisibilityPredicateWarnings) the retired operand is a test seam that clears the once-per-predicate dedupe of the unresolvable-visibility report; no shipped code in the workspace or in hotcrm called it, and no packages/spec schema, registered node type, conversion surface or stored shape names it, so there is nothing for `objectstack migrate meta` to rewrite -->
11+
12+
**BREAKING** for a host that imports `__resetVisibilityPredicateWarnings` from `@object-ui/react`. The double-underscore name already marked it as a test seam; the workspace tests that used it now import it from the module that declares it. `reportUnresolvableVisibilityPredicate`, `formatUnresolvableVisibilityMessage`, `UNRESOLVABLE_VISIBILITY_PREFIX`, `UNRESOLVABLE_ENABLEMENT_PREFIX` and the `PredicateScopeTier` type stay exported unchanged, and the report still dedupes per predicate.
13+
14+
- FROM `__resetVisibilityPredicateWarnings()` in a test TO a fresh module instance per test (`vi.resetModules()` before importing `@object-ui/react`), or a predicate source string unique to that test so the dedupe cannot hide its line.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@object-ui/types': patch
3+
---
4+
5+
refactor(types)!: retire the zero-consumer `CommentSearchResult` interface
6+
7+
Clause-②: no (narrowing)
8+
Metadata-protocol: none
9+
10+
<!-- adr-0087: not-required (runtime-export-retired @object-ui/types#CommentSearchResult) the retired operand is a TypeScript interface for a cross-record comment search result; its only producer, the `useCommentSearch` hook of `@object-ui/collaboration`, already retired, and nothing in the workspace or in hotcrm reads the type; no packages/spec schema, registered node type, conversion surface or stored shape names it, so there is nothing for `objectstack migrate meta` to rewrite -->
11+
12+
**BREAKING** for a host that imports the type `CommentSearchResult` from `@object-ui/types`. It described the hits of a comment search the packages no longer ship. `CommentEntry`, `MentionNotification` and `ActivityEntry` stay exported unchanged.
13+
14+
- FROM `CommentSearchResult` TO a local interface in your own code: `{ comment: CommentEntry; objectName: string; recordId: string; highlight?: string }`.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@objectstack/service-automation': patch
3+
---
4+
5+
fix(service-automation): a connector instance whose upstream no longer matches its pin is degraded in its own words
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
A provider factory that throws `CONNECTOR_UPSTREAM_CHANGED` (the `mcp` provider does when an instance's `providerConfig.toolsSnapshot` does not match what the server serves) degrades the instance on the same 5 s → 5 min backoff as an unreachable upstream, but its log records now say what happened. The materializer's ERROR reads "… serves a tool definition that differs from its toolsSnapshot — instance registered degraded (no actions); re-checking with backoff, attempt N." instead of "upstream unavailable … retrying with backoff", and the engine's degrade WARN says the instance has no actions "until its upstream serves the definitions its pin names again" instead of "until its upstream is reachable". The instance's reason (`GET /api/v1/automation/connectors`, the `connector_action` refusal) is the factory's message, naming each changed tool, as before.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
feat(spec): `ConnectorUpstreamChangedError`, the marker for an upstream that no longer matches the instance's pin
6+
7+
Clause-②: yes (widening)
8+
Metadata-protocol: none
9+
10+
`@objectstack/spec/integration` exports `CONNECTOR_UPSTREAM_CHANGED`, `ConnectorUpstreamChangedError` and the structural check `isConnectorUpstreamChanged`, beside the upstream-unavailable and credential-rejected markers. A connector provider factory throws it when the upstream it contacted serves a definition that differs from a pin the instance declares. Today that is the `mcp` provider's `providerConfig.toolsSnapshot`: a pinned tool whose description or `inputSchema` changed, or a pinned tool the server no longer serves. The automation materializer degrades the instance with the factory's message as its reason and re-checks it on the same backoff as an outage, so a server that restores the pinned definition recovers it. `CONNECTOR_UPSTREAM_UNAVAILABLE` keeps its meaning: the upstream could not be reached. The code is registered in the error-code ledger under `@objectstack/spec`; no HTTP door answers with it.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@objectstack/connector-mcp': minor
3+
---
4+
5+
feat(connector-mcp): `providerConfig.toolsSnapshot` pins each tool of an `mcp` instance by name
6+
7+
Clause-②: yes (widening)
8+
Metadata-protocol: added
9+
10+
An `mcp` instance's `include` decides which tools it exposes. Until now nothing noticed when the server rewrote one of them, for example a new description that steers an agent or an `inputSchema` that asks for more than it did. `providerConfig.toolsSnapshot` is a record of tool name → the sha256 of that tool's definition. It is keyed by tool name, like `include`, and the two compose.
11+
12+
- **The digest.** sha256, lowercase hex, of the UTF-8 canonical JSON of `{ name, description, inputSchema }` from the tool's `tools/list` entry. A member the server does not send is left out. Canonical JSON sorts object keys in UTF-16 code-unit order at every depth, keeps array order, writes primitives as `JSON.stringify` does and has no whitespace: the RFC 8785 (JCS) form for values read from JSON. `computeMcpToolsSnapshot(tools)` and `mcpToolDigest(tool)` are exported and are the functions the check uses.
13+
- **The check.** On every materialization each pinned tool is hashed and compared on its own. A pinned tool served with a different description or `inputSchema`, or no longer served, degrades the instance: the provider throws `ConnectorUpstreamChangedError` (`CONNECTOR_UPSTREAM_CHANGED`), not the upstream-unavailable marker, so the logs say the pin did not match rather than that the server is down. Its reason names each such tool and the digest the server now serves, and none of the instance's tools are exposed. The instance is re-checked on the retry backoff and recovers once the server serves the pinned definitions again. An edited pin re-materializes it at once. A pinned tool that `include` also lists is reported by the pin when the server stops serving it, not as an `include` typo. When the instance's own credential reached the server (its `auth` over http), a pinned tool the server does not list takes the credential path instead (`ConnectorCredentialRejectedError`, 403, both causes named, a stored credential marked `rejected`), since the server may list only the tools that credential may use; a served pinned tool that hashes differently is still `CONNECTOR_UPSTREAM_CHANGED`.
14+
- **Refused before connecting.** A `toolsSnapshot` that is not a record of tool name → 64 lowercase hex characters fails the boot, and so does a pin on a tool `include` leaves out, since that pin would never be checked.
15+
- Without `toolsSnapshot`, an instance behaves exactly as before. A tool the pin does not name is not checked.
16+
- `McpConnectorOptions.include` now also receives the tool's `tools/list` entry as a second argument. An existing one-argument predicate is unaffected.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@objectstack/platform-objects': patch
3+
---
4+
5+
fix(platform-objects): the Users identity source reads "Local Account" instead of "Env-Native"
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
- **Identity Source.** A user who signed up with email and password, or an app end-user, showed the identity source "Env-Native", a word from the provenance design. The `env_native` option is now labelled "Local Account", beside the federated "IdP-Provisioned": the identity is held by this environment's own sign-in rather than by an identity provider. zh-CN reads 本地账号, ja-JP ローカルアカウント, es-ES Cuenta local.
11+
- The stored value is unchanged: rows, the sign-up hook and the cloud-managed gating keep reading `env_native`.

0 commit comments

Comments
 (0)