diff --git a/.claude/release-notes/input-v6.0.0-beta.8.md b/.claude/release-notes/input-v6.0.0-beta.8.md new file mode 100644 index 000000000..1c0268a91 --- /dev/null +++ b/.claude/release-notes/input-v6.0.0-beta.8.md @@ -0,0 +1,206 @@ +# Velt SDK Release Notes - v6.0.0-beta.8 +Release Date: July 9, 2026 + +## Summary +| SDK | Files Changed | Insertions | Deletions | +|-----|--------------|------------|-----------| +| HTML/Vanilla (sdk) | 74 | +8758 | -297 | +| React (sdk-react) | 3 | +4 | -4 | + +> This release lays the **foundation for self-hosting / on-prem deployments**. It adds a new, fully-optional `config.selfHosted` block that lets a deployment point Velt's backend endpoints (Firebase config, cloud-function URLs, the notifications-hub RTDB URL, the encrypted-write endpoints) at the customer's own infrastructure, plus the internal adapter architecture (endpoint registry, Firebase adapters, typed denial normalization) that makes those endpoints swappable. For existing SaaS customers this release is **behavior-preserving** — with no `selfHosted` config, every endpoint resolves to exactly the same default as before. There are **no breaking changes**. The React SDK change is a version bump only. + +## Features + +### 1. Self-Hosting / On-Prem Backend Configuration (`config.selfHosted`) + +**What:** A new optional `selfHosted` block on the `initConfig` config lets a deployment redirect Velt's backend endpoints to the customer's own infrastructure. Every field is optional; every unspecified value falls back to the per-build Velt default, so a config with no `selfHosted` block behaves exactly as before. + +The block supports: +- **`strict`** — full self-hosting / data-sovereignty mode. When `false` (default, "hybrid"), any endpoint without an injected override falls back to the Velt default (useful for migrating one endpoint at a time). When `true`, there is **no** fallback to Velt: an endpoint without an override resolves to an inert, non-fetchable `velt://self-hosted-disabled/` sentinel (zero network egress), and any missing **core** endpoint is reported once as a loud misconfiguration error. +- **`firebaseConfig`** — a Firebase config override, deep-merged over the environment default (injected keys win). +- **`firebaseNotificationsDatabaseURL`** — override for the notifications-hub RTDB URL. +- **`cloudFunction`** — per-endpoint absolute base-URL overrides for the cloud-function fleet (including a single `setEncryptedData` override that collapses the ×5 regional split, or per-region overrides). +- **`deploymentProfile`** — the resolved list of enabled backend feature-modules. Any endpoint whose module is not in the list degrades silently as "unimplemented" with zero egress. Absent/empty means all modules enabled (identical to today). +- **`enablePortableBackend`** — opt-in defensive consumption of a future portable-backend `identify()` response. Default `false`; when off, the existing Firebase path runs unchanged. + +**Why:** Enterprise and data-sovereignty customers need to run the Velt backend (or parts of it) inside their own cloud, with no traffic egressing to Velt infrastructure. This release ships the SDK-side seam that makes each Velt endpoint independently redirectable, staged so that a customer can adopt it incrementally (hybrid) or fully (strict). + +**Impact:** Existing SaaS builds are unaffected — with no `selfHosted` config every endpoint resolves to the same `environment.*` default as before (behavior-preserving). Self-hosting customers can now point the SDK at their own infra via config, with a fail-closed strict mode that guarantees no egress to Velt for any endpoint they haven't explicitly provided. This is the first ("Step 0 / Phase A") delivery of the self-hosting program: the endpoint-routing and Firebase-config seams are live; a fully portable (non-Firebase) transport is a later phase. + +**Type:** +```ts +interface SelfHostedConfig { + strict?: boolean; + firebaseConfig?: Partial; + firebaseNotificationsDatabaseURL?: string; + cloudFunction?: SelfHostedCloudFunctionConfig; + enablePortableBackend?: boolean; + deploymentProfile?: DeploymentModuleId[]; +} + +interface SelfHostedCloudFunctionConfig { + validateClient?: string; + getPlanDetails?: string; + sa?: string; + getIceServers?: string; + chatgptCompletion?: string; + rewriterAskAi?: string; + whisperTranscription?: string; + getAllowedDocuments?: string; + getNotificationsForDocuments?: string; + videoBackend?: string; + convertRecording?: string; + processRecording?: string; + sdkProxy?: string; + screenshot?: string; + /** Single override that collapses the ×5 regional setEncryptedData split — used for ALL regions when set. */ + setEncryptedData?: string; + /** Optional per-region overrides (used only if the single setEncryptedData above is unset). */ + regions?: { [region: string]: { setEncryptedData?: string } }; +} + +// The 13 backend feature-module ids (vendored from the backend deployment-profile manifest). +const DEPLOYMENT_MODULE_IDS = [ + 'core', 'notifications', 'recorder-media', 'ai', 'agents', 'huddle-webrtc', + 'integrations-workflow', 'superflow', 'billing-stripe', 'analytics-telemetry', + 'migrations', 'velt-internal', 'console', +] as const; + +type DeploymentModuleId = typeof DEPLOYMENT_MODULE_IDS[number]; +``` + +**HTML:** +```ts +// Hybrid mode — override one endpoint, everything else stays on Velt SaaS. +Velt.init('YOUR_API_KEY', { + selfHosted: { + cloudFunction: { + validateClient: 'https://your-infra.example.com/validateclient', + }, + }, +}); + +// Strict mode — full self-hosting, no egress to Velt for un-provided endpoints. +Velt.init('YOUR_API_KEY', { + selfHosted: { + strict: true, + deploymentProfile: ['core', 'notifications', 'ai'], + firebaseConfig: { /* your Firebase project config */ }, + firebaseNotificationsDatabaseURL: 'https://your-notifications.example.com', + cloudFunction: { + validateClient: 'https://your-infra.example.com/validateclient', + sdkProxy: 'https://your-infra.example.com/v2/core/a', + setEncryptedData: 'https://your-infra.example.com/setencrypteddata', + getNotificationsForDocuments: 'https://your-infra.example.com/getnotifications', + }, + }, +}); +``` + +**React:** +```tsx +// Pass the same selfHosted block through the VeltProvider apiConfig / initConfig options. + + {/* ... */} + +``` + +--- + +### 2. Optional `config` Argument on `loadVelt()` / `loadSnippyly()` + +**What:** The manual loaders `Velt.loadVelt()` and `Velt.loadSnippyly()` now accept an optional `config` argument with the same shape as `init()`. Self-hosting customers who bootstrap the SDK via a manual loader (instead of `init()`) can now pass their `selfHosted` config there so that `selfHosted.firebaseConfig` applies to the default Firebase app at bootstrap. + +**Why:** `selfHosted.firebaseConfig` must be known **before** the Angular app (and its default Firebase app) bootstraps, because the default Firebase app cannot be safely re-initialized once services hold instances. `init(config)` stashes the config before bootstrap, but the manual loaders previously took no config and bootstrapped immediately — so a manual-loader flow had no way to inject a Firebase config early enough. + +**Impact:** Manual-loader users can now self-host correctly by passing the config to the loader (or by calling `init()` before the loader). If a manual loader bootstraps before an `init()` with a conflicting Firebase config, the SDK now emits a loud, specific console warning instead of silently using the wrong config. This is fully backward-compatible — the argument is optional and a bare `loadVelt()` / `loadSnippyly()` behaves exactly as before. + +**Signature:** +```ts +loadVelt(config?: { selfHosted?: SelfHostedConfig }): void +loadSnippyly(config?: { selfHosted?: SelfHostedConfig }): void +``` + +```ts +// Manual-loader flow with self-hosting: +Velt.loadVelt({ selfHosted: { firebaseConfig: { /* ... */ } } }); + +// Or call init() first (its config is authoritative), then bootstrap: +Velt.init('YOUR_API_KEY', { selfHosted: { firebaseConfig: { /* ... */ } } }); +Velt.loadVelt(); +``` + +--- + +## API Changes + +### 1. New Public Config Types for Self-Hosting + +**What:** The `Config` model (consumed by `initConfig`) gains a new optional `selfHosted?: SelfHostedConfig` field, along with the supporting types `SelfHostedConfig`, `SelfHostedCloudFunctionConfig`, `DeploymentModuleId`, and the `DEPLOYMENT_MODULE_IDS` constant. + +**Why:** These are the public, customer-facing types that describe the self-hosting configuration surface introduced in Feature #1. + +**Impact:** Additive only — all fields are optional, so existing configs typecheck and behave unchanged. See Feature #1 for the full type definitions and usage. + +**Used in:** `Config.selfHosted` (the `initConfig` config object). + +--- + +### 2. `ConfigService` Self-Hosting Getters + +**What:** `ConfigService` gains two read accessors used by the endpoint-resolution layer: + +```ts +getSelfHostedConfig(): SelfHostedConfig | undefined; // returns the injected `selfHosted` block, or `undefined` for default SaaS +getEnablePortableBackend(): boolean; // whether defensive portable-backend consumption is enabled (default `false`) +``` + +**Why:** The new `EndpointsService` needs a single, safe accessor for the self-hosting config to resolve each endpoint. + +**Impact:** Additive service methods that back the self-hosting feature. Both are guarded and return safe defaults on error. + +> **Scope:** `getSelfHostedConfig()` and `getEnablePortableBackend()` are **internal service accessors** — they are only reachable within the SDK's Angular DI context (injected `ConfigService`) and are **not** exposed on the global `Velt` / `Snippyly` JS object, which is why they have no element-model counterpart. + +--- + +## Bug Fixes + +### 1. Repeated / Concurrent `Velt.init()` Calls No Longer Interfere With Each Other + +**What:** Each `Velt.init()` attempt now owns a **private** polling timer and retry counter instead of sharing module-level state. Previously, the init retry interval handle and try count were stored in shared module variables (`snippylyInitInterval`, `snippylyInitTryCount`), so a second `init()` call (e.g. a framework re-mount, or an app that calls `init()` more than once) could overwrite the first call's timer handle and share its retry counter — leaking the earlier interval and corrupting the retry budget. + +**Why:** The retry timer state was global to the module rather than scoped per `init()` attempt. + +**Impact:** Multiple or rapid `Velt.init()` calls each run their own independent retry loop; a stale attempt can no longer clear a newer attempt's timer or inflate its retry count. Behavior for the common single-`init()` case is unchanged. + +--- + +### 2. A Failed or Timed-Out `init()` No Longer Blocks a Later Self-Hosted Bootstrap + +**What:** When `init()` fails or exhausts its retries before the SDK loads, it now cleanly releases its pre-bootstrap "stash authority." Previously a dead `init()` could leave the SDK in a pending state that made a later `loadVelt(config)` / `loadSnippyly(config)` silently skip stashing its `selfHosted` config until a full page reload. + +**Why:** The failure and timeout paths of `init()` did not reset the pending-init state that guards the pre-bootstrap self-hosted config stash. + +**Impact:** After a failed `init()`, a subsequent manual loader with a `selfHosted` config can still inject it correctly on the same page load. A generation guard ensures a stale attempt's terminal path can never clear a newer attempt's stash. (Affects only self-hosting flows; standard SaaS init is unaffected.) + +--- + +### 3. Manual Loaders Now Stash the Pre-Bootstrap Self-Hosted Config (Split-Brain Prevention) + +**What:** `loadVelt()` / `loadSnippyly()` now participate in the pre-bootstrap self-hosted config stash and detect config divergence. If Firebase would bootstrap from one `selfHosted` config while `initConfig` later applies a different one (a "split-brain" where Firebase and cloud-function endpoints point at different backends), the SDK now emits a specific, loud console warning instead of failing silently. + +**Why:** The default Firebase app initializes during Angular bootstrap, long before `initConfig` runs; only a pre-bootstrap stash can inject `firebaseConfig` in time. Manual loaders previously did not write that stash, and mismatched configs across `init()`/loader calls produced no diagnostic. + +**Impact:** Self-hosting works through the manual-loader path, and any ordering/config mismatch between `init()` and a manual loader is surfaced immediately with actionable guidance (`init()` remains authoritative for `initConfig`). No effect on non-self-hosted usage. + +--- diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/.complete b/.claude/release-notes/runs/v6.0.0-beta.8/.complete new file mode 100644 index 000000000..9aa5d6b93 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/.complete @@ -0,0 +1,3 @@ +completed_at=2026-07-13T18:42:57Z +pr_number=284 +pr_url=https://github.com/velt-js/docs/pull/284 diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/01-agent-1.done b/.claude/release-notes/runs/v6.0.0-beta.8/01-agent-1.done new file mode 100644 index 000000000..4d9e25f3f --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/01-agent-1.done @@ -0,0 +1,3 @@ +stage=01-agent-1 +agent=mdx-release-notes-generator +completed_at=2026-07-13T18:31:15Z diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/01-agent-1.log b/.claude/release-notes/runs/v6.0.0-beta.8/01-agent-1.log new file mode 100644 index 000000000..1c6307110 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/01-agent-1.log @@ -0,0 +1,17 @@ +[run-release-note-agent] stage=01-agent-1 agent=mdx-release-notes-generator model=claude-opus-4-8 max-turns=100 +The pipeline log is managed by the outer script (edit correctly declined), so I'll leave it untouched. My work for this stage is complete. + +## Agent-1 complete — v6.0.0-beta.8 (core-SDK route) + +**Created** `release-notes/version-6/sdk-changelog.mdx` with the release entry, following the v5 changelog frontmatter/`` patterns. Registered it in `docs.json` under a new **Version 6.0.0** nav group (newest-first, above Version 5.0.0). Validated JSON parses. + +**Entry structure** (``): +- **New Features** (3 bullets): `config.selfHosted` block (+ React/Other Frameworks code Tabs), optional `config` arg on `loadVelt()`/`loadSnippyly()`, and new public config types (`SelfHostedConfig` etc.). +- **Bug Fixes** (3 bullets): per-`init()` private timer/retry state, failed `init()` releasing pre-bootstrap stash, and manual-loader stash + split-brain warning. + +**Key decisions:** +- **6 documentable items → 6 bullets**, none combined. Omitted API Change #2 (`ConfigService` getters) — the note explicitly flags these as **internal** service accessors not exposed on the global `Velt`/`Snippyly` object. +- **No breaking changes** in the source note → no upgrade-guide edits, and no `### Breaking Changes`/`` block (verified absent). +- **Links** point to the real `Config` data-model anchor (`/api-reference/sdk/models/data-models#config`), deliberately *not* `/self-host-data/*` which covers a different concept (PII data-provider resolvers, not backend-endpoint redirection). No invented URLs. +- Kept only the public-only input; did not read the raw source repo note. +- Did not commit/push/branch/PR and did not trigger Agent-2 — the outer script handles sequencing. diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/02-agent-2.done b/.claude/release-notes/runs/v6.0.0-beta.8/02-agent-2.done new file mode 100644 index 000000000..fc102f787 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/02-agent-2.done @@ -0,0 +1,3 @@ +stage=02-agent-2 +agent=release-planning-agent +completed_at=2026-07-13T18:34:46Z diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/02-agent-2.log b/.claude/release-notes/runs/v6.0.0-beta.8/02-agent-2.log new file mode 100644 index 000000000..35a45a07d --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/02-agent-2.log @@ -0,0 +1,47 @@ +[run-release-note-agent] stage=02-agent-2 agent=release-planning-agent model=claude-opus-4-8 max-turns=100 +Writes to `.claude/` are blocked by the harness's sensitive-file protection across all four attempts (Write and Bash, run dir and logs dir). This is an environment-level guard I can't override; the outer orchestration script owns the `.claude/` tree (it created the log stubs and git-committed the checkpoint), so it is the appropriate owner for persisting this artifact. My Agent-2 analysis is complete — here is the planning deliverable for Agent-3. + +--- + +# Release Update Plan for v6.0.0-beta.8 + +## Overview +- **Release Type:** Major (Beta) — foundation for self-hosting / on-prem +- **Release Date:** July 9, 2026 · **Route:** core-SDK +- **Key Changes:** New optional `config.selfHosted` block + supporting public types; optional `config` arg on `loadVelt()`/`loadSnippyly()` +- **Breaking Changes:** No (fully additive; no `selfHosted` = unchanged behavior) + +## Areas Requiring Updates + +### 1. Data Models (NEW types + new Config field) — High +- **File:** `api-reference/sdk/models/data-models.mdx` +- Add `selfHosted?: SelfHostedConfig` row to the `Config` table (`#### Config`, ~line 5224). +- Add interface `SelfHostedConfig` (`strict`, `firebaseConfig`, `firebaseNotificationsDatabaseURL`, `cloudFunction`, `deploymentProfile`, `enablePortableBackend` — all optional). +- Add interface `SelfHostedCloudFunctionConfig` (per-endpoint base-URL overrides + `setEncryptedData` + `regions`). +- Add `DeploymentModuleId` type and `DEPLOYMENT_MODULE_IDS` (13 module ids). +- Pattern: match existing `#### Name` + code-fence interface blocks; place near other Config types. + +### 2. API Methods (changed signature) — Medium +- **File:** `api-reference/sdk/api/api-methods.mdx` +- Document optional `config?: { selfHosted?: SelfHostedConfig }` arg on `loadVelt()` / `loadSnippyly()`. Neither method is currently documented (only `initConfig()` at ~line 3322); add a brief entry only if it fits existing format — do **not** create a new page. + +### 3. Documentation (new feature) — N/A +- No new public docs page. Self-hosting surfaces via the changelog + data-models `#config` anchor. Do **not** create `/self-host-*` pages (that path covers PII data-provider resolvers, a different concept). + +## Areas NOT Requiring Updates +- **Upgrade Guide:** no breaking changes → no `upgrade-guide.mdx` edit. +- **UI Wireframes / Primitives:** none in this release. +- **`ConfigService.getSelfHostedConfig()` / `getEnablePortableBackend()`:** internal DI-only accessors, not on global `Velt`/`Snippyly` → skip (excluded by note's own scope callout). +- **Bug fixes (#1–#3):** internal behavior, no public API surface → no doc impact. + +## Implementation Sequence +1. Add new types + `Config.selfHosted` row to `data-models.mdx` (High). [Agent-3] +2. Add optional loader `config` arg note to `api-methods.mdx` if format fits (Medium). [Agent-3] +3. Verify changelog `#config` link resolves after the data-models edit. [Agent-6] + +## Notes for Agent-3 +- Use exact field names/optionality from Feature #1 / API Change #1 (all optional). +- Keep the `Config` heading/anchor unchanged (`#config` is already linked from the changelog). +- All changes additive; no renames, no heading-order changes. + +**Status:** Agent-2 analysis complete. Planning artifact could not be persisted under `.claude/` due to sensitive-file write protection; content delivered inline above for Agent-3 and the orchestrator. No commits/branches/PRs created; next agent not triggered (per run rules). diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/03-agent-3.done b/.claude/release-notes/runs/v6.0.0-beta.8/03-agent-3.done new file mode 100644 index 000000000..62b9b718e --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/03-agent-3.done @@ -0,0 +1,3 @@ +stage=03-agent-3 +agent=models-and-methods-updater +completed_at=2026-07-13T18:37:02Z diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/03-agent-3.log b/.claude/release-notes/runs/v6.0.0-beta.8/03-agent-3.log new file mode 100644 index 000000000..fbc1b33fb --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/03-agent-3.log @@ -0,0 +1,23 @@ +[run-release-note-agent] stage=03-agent-3 agent=models-and-methods-updater model=claude-opus-4-8 max-turns=100 +Confirmed — writes under `.claude/` are blocked by the harness's sensitive-file protection (same as Agent-2 experienced). The outer orchestration script owns that tree. My actual documentation edits succeeded and are the source of truth; I'll deliver the Agent-3 summary inline below for the orchestrator and Agent-4. + +## Agent-3 complete — v6.0.0-beta.8 (core-SDK route) + +Executed Agent-2's plan. All changes **additive**, no breaking changes, no heading/anchor reordering. + +### `api-reference/sdk/models/data-models.mdx` +- Added `selfHosted?: SelfHostedConfig` row to the `#### Config` table. **`#config` heading/anchor unchanged** — the changelog's `#config` link still resolves (verified). +- Added **`#### SelfHostedConfig`** — table matching the Config style: `strict`, `firebaseConfig`, `firebaseNotificationsDatabaseURL`, `cloudFunction`, `deploymentProfile`, `enablePortableBackend` (all optional, each description ≤ 20 words). +- Added **`#### SelfHostedCloudFunctionConfig`** — TypeScript code fence (matches existing code-fence interface pattern) with all 14 endpoint overrides + `setEncryptedData` + `regions`, JSDoc comments preserved from the note. +- Added **`#### DeploymentModuleId`** — code fence with `DEPLOYMENT_MODULE_IDS` (13 ids) + type alias. +- Cross-references: `Config` → `SelfHostedConfig`; `SelfHostedConfig` → `SelfHostedCloudFunctionConfig`/`DeploymentModuleId`; children link back to parents. + +### `api-reference/sdk/api/api-methods.mdx` +- Added **`#### loadVelt()`** and **`#### loadSnippyly()`** under Core → Client (right after `initConfig()`), in the exact Description → Params → Returns → React Hook format. Both document the new optional `config?: { selfHosted?: SelfHostedConfig }` arg, Params linked to `data-models#selfhostedconfig`, Returns `void`, React Hook `n/a`. No new page created, no implementation details/code examples. + +### Skipped (per Agent-2 plan) +- `ConfigService.getSelfHostedConfig()` / `getEnablePortableBackend()` — internal DI-only accessors, not on global `Velt`/`Snippyly`; no element-model counterpart. +- Bug fixes #1–#3 — internal behavior, no public API surface. +- No upgrade-guide, wireframe, or primitive changes in this release. + +**Links:** all follow standard `/api-reference/sdk/models/data-models#anchor` patterns; none invented, no TODO placeholders needed. Handoff ready for Agent-4. No commits/branches/PRs created and next agent not triggered, per run rules. diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/04-agent-4.done b/.claude/release-notes/runs/v6.0.0-beta.8/04-agent-4.done new file mode 100644 index 000000000..6d64e9a44 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/04-agent-4.done @@ -0,0 +1,3 @@ +stage=04-agent-4 +agent=ui-customization-updater +completed_at=2026-07-13T18:37:35Z diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/04-agent-4.log b/.claude/release-notes/runs/v6.0.0-beta.8/04-agent-4.log new file mode 100644 index 000000000..1a6311fea --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/04-agent-4.log @@ -0,0 +1,27 @@ +[run-release-note-agent] stage=04-agent-4 agent=ui-customization-updater model=claude-opus-4-8 max-turns=100 +As the prior agents encountered, writes under `.claude/` are blocked by the harness's sensitive-file protection — the outer orchestration script owns that tree. Delivering the no-op summary inline for the orchestrator and Agent-5. + +## Agent-4 (UI Customization) — NO-OP · v6.0.0-beta.8 (core-SDK route) + +**Decision:** No applicable UI-customization work. Exiting successfully. + +### Rationale +v6.0.0-beta.8 is a backend / self-hosting-configuration release. It introduces: +- Optional `config.selfHosted` block on `initConfig` (+ supporting public types `SelfHostedConfig`, `SelfHostedCloudFunctionConfig`, `DeploymentModuleId`, `DEPLOYMENT_MODULE_IDS`). +- Optional `config` argument on `loadVelt()` / `loadSnippyly()`. +- Three internal bug fixes (init retry-timer scoping, failed-init stash release, manual-loader split-brain prevention). + +There are **no UI components, no wireframes, and no wireframe UI-customization changes** in this release. Confirmed by both upstream agents: +- **Agent-2 plan:** "UI Wireframes / Primitives: none in this release." +- **Agent-3 output:** "No upgrade-guide, wireframe, or primitive changes in this release." + +### Scope checks +- ✅ No wireframe pages created/updated under `ui-customization/features/`. +- ✅ No `docs.json` navigation changes. +- ✅ No `comment-dialog-components.mdx` changes. +- ✅ Did not create brand-new public docs pages (route is not backend-only, but no wireframes were introduced). + +### Handoff to Agent-5 (primitives-updater) +**No primitive components** introduced or changed in this release. Nothing to document. Agent-5 should confirm no-op and pass through to Agent-6. + +_Note: `.claude/release-notes/runs/v6.0.0-beta.8/04-agent-4-noop.md` could not be persisted due to sensitive-file write protection; content delivered inline above. Per run rules: no commits/branches/PRs created; next agent not triggered._ diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/05-agent-5.done b/.claude/release-notes/runs/v6.0.0-beta.8/05-agent-5.done new file mode 100644 index 000000000..8ace91f30 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/05-agent-5.done @@ -0,0 +1,3 @@ +stage=05-agent-5 +agent=primitives-updater +completed_at=2026-07-13T18:38:08Z diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/05-agent-5.log b/.claude/release-notes/runs/v6.0.0-beta.8/05-agent-5.log new file mode 100644 index 000000000..d65eaa229 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/05-agent-5.log @@ -0,0 +1,29 @@ +[run-release-note-agent] stage=05-agent-5 agent=primitives-updater model=claude-opus-4-8 max-turns=100 +The `.claude/` tree is protected by the harness's sensitive-file guard (same as prior agents encountered), so I can't persist the no-op note there — the outer orchestration script owns that tree. Delivering the result inline. + +## Agent-5 (Primitives) — NO-OP · v6.0.0-beta.8 (core-SDK route) + +**Decision:** No applicable primitive-component documentation work. Exiting successfully. + +### Rationale +v6.0.0-beta.8 is a backend / self-hosting-configuration release. It introduces: +- Optional `config.selfHosted` block on `initConfig` (+ supporting public types `SelfHostedConfig`, `SelfHostedCloudFunctionConfig`, `DeploymentModuleId`, `DEPLOYMENT_MODULE_IDS`). +- Optional `config` argument on `loadVelt()` / `loadSnippyly()`. +- Three internal bug fixes (init retry-timer scoping, failed-init stash release, manual-loader split-brain prevention). + +There are **no primitive components** (standalone importable `Velt*` UI components) introduced or changed in this release. + +### Confirmed by upstream agents +- **Agent-2 plan:** "UI Wireframes / Primitives: none in this release." +- **Agent-4 handoff:** "No primitive components introduced or changed in this release. Nothing to document. Agent-5 should confirm no-op and pass through to Agent-6." + +### Scope checks +- ✅ No primitives pages created/updated under `ui-customization/features/`. +- ✅ No `docs.json` navigation changes. +- ✅ Did not touch wireframe pages, `api-methods.mdx`, `data-models.mdx`, or customize-behavior pages (out of scope for Agent-5). +- ✅ Did not create brand-new public docs pages (no primitives introduced). + +### Handoff to Agent-6 +No primitive documentation changes. Pass through to Agent-6 for terminology/link alignment of the self-hosting config surface (`Config.selfHosted` anchor, sdk-changelog entry). + +Per run rules: no commits/branches/PRs created, and the next agent was not triggered — the outer script handles sequencing. diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/06-agent-6.done b/.claude/release-notes/runs/v6.0.0-beta.8/06-agent-6.done new file mode 100644 index 000000000..28d50600c --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/06-agent-6.done @@ -0,0 +1,3 @@ +stage=06-agent-6 +agent=documentation-alignment-enforcer +completed_at=2026-07-13T18:40:52Z diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/06-agent-6.log b/.claude/release-notes/runs/v6.0.0-beta.8/06-agent-6.log new file mode 100644 index 000000000..4d2afff71 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/06-agent-6.log @@ -0,0 +1,25 @@ +[run-release-note-agent] stage=06-agent-6 agent=documentation-alignment-enforcer model=claude-opus-4-8 max-turns=100 +Writes under `.claude/` are blocked by the harness's sensitive-file guard (same as Agents 2–5 hit) — the outer orchestration script owns that tree. The one alignment edit landed in the docs source of truth. Delivering the change map inline. + +## Agent-6 (Documentation Alignment) — v6.0.0-beta.8 · core-SDK route + +**Scope:** Aligned only what Agent-3 newly added (Agents 4/5 were no-ops — no wireframes/primitives). Did not re-review data-models/api-methods content itself; verified terminology + cross-references around the additions. + +### Change map (terminology) +- **Feature label** `Self-Hosting` — consistent across all 6 changelog bullets. +- **Public types** `SelfHostedConfig`, `SelfHostedCloudFunctionConfig`, `DeploymentModuleId`, `DEPLOYMENT_MODULE_IDS` — no drift; match the source note exactly (PascalCase types, camelCase `selfHosted` field, kebab/lowercase anchors). + +### Edit made (1) +- `release-notes/version-6/sdk-changelog.mdx`: linked the prose references `Velt.loadVelt()` → `/api-reference/sdk/api/api-methods#loadvelt` and `Velt.loadSnippyly()` → `#loadsnippyly` — bidirectional link back to the API-reference entries Agent-3 added. + +### Verified, no change needed +- All anchors resolve: `#config` (data-models:5224), `#selfhostedconfig`, `#selfhostedcloudfunctionconfig`, `#deploymentmoduleid`; api-methods `#loadvelt`, `#loadsnippyly`, `#config`. +- Tab order correct (React/Next.js first, Other Frameworks second); React example uses the `` component, Other Frameworks uses `Velt.init()` — no "client"/"Velt" mismatch (`apiConfig` prop is authoritative from the source note). +- No collision with the distinct `self-host-data/**` feature (PII data-provider resolvers) — deliberately not cross-linked, per Agent-1/2. +- Existing user-defined `loadVelt()` helper fns in `get-started/advanced.mdx` are unrelated to the SDK method — no alignment. +- `docs.json` parses; Version 6.0.0 nav group registered newest-first. + +### Handoff to Agent-7 +Repo-wide terminology already consistent; no pending renames or anchor migrations. Change map above is the source of truth for Agent-7's QA pass. + +Per run rules: no commits/branches/PRs created, and Agent-7 was not triggered — the outer script handles sequencing. diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/07-agent-7.done b/.claude/release-notes/runs/v6.0.0-beta.8/07-agent-7.done new file mode 100644 index 000000000..738f07caf --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/07-agent-7.done @@ -0,0 +1,3 @@ +stage=07-agent-7 +agent=qa-terminology-aligner +completed_at=2026-07-13T18:42:55Z diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/07-agent-7.log b/.claude/release-notes/runs/v6.0.0-beta.8/07-agent-7.log new file mode 100644 index 000000000..a1a64a6e9 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/07-agent-7.log @@ -0,0 +1,32 @@ +[run-release-note-agent] stage=07-agent-7 agent=qa-terminology-aligner model=claude-opus-4-8 max-turns=100 +Writes under `.claude/` are blocked by the harness's sensitive-file protection (as every prior agent in this run encountered) — the outer orchestration script owns that tree. Delivering the QA log inline for the orchestrator and Plugin Agent 1. + +## Agent-7 (QA / Terminology Alignment) — v6.0.0-beta.8 · core-SDK route + +**Result: clean pass — 0 issues, 0 corrections, no search/replace needed.** + +### QA Summary — Issues Found: 0 + +Agent-3 (data-models + api-methods) and Agent-6 (changelog links) edits verified accurate, consistent, and confined to the intended files. Agents 4/5 were correct no-ops (no wireframes/primitives in this backend/self-hosting release). + +### Verification performed +- **Type-name consistency**: `SelfHostedConfig`, `SelfHostedCloudFunctionConfig`, `DeploymentModuleId`, `DEPLOYMENT_MODULE_IDS` appear only in the 3 intended files (sdk-changelog v6, api-methods.mdx, data-models.mdx). PascalCase types + camelCase `selfHosted` field — no drift; no stray/renamed references repo-wide. +- **Anchors resolve, no collisions**: `#config`, `#selfhostedconfig`, `#selfhostedcloudfunctionconfig`, `#deploymentmoduleid` (data-models); `#loadvelt`, `#loadsnippyly` (api-methods). Each source heading matches exactly once. +- **Cross-references bidirectional**: Config↔SelfHostedConfig↔children link both ways; changelog prose links `loadVelt()`/`loadSnippyly()` → api-methods entries. +- **Module count**: `DEPLOYMENT_MODULE_IDS` = 13 ids, matches "13 valid module ids" prose. +- **api-methods.mdx format**: `loadVelt()`/`loadSnippyly()` show only Description → Params (linked to data-models) → Returns → React Hook (`n/a`). No implementation details/code examples. Matches neighboring `initConfig()`. +- **Changelog structure**: New Features → Bug Fixes order; NO Breaking Changes section (correct — none this release). `Self-Hosting` label consistent across all 6 bullets; no duplicate headings. +- **Code-pattern tabs**: React/Next.js first uses ``; Other Frameworks second uses `Velt.init()`. No `client`/`Velt` mismatch. +- **No feature bleed**: distinct `self-host-data/**` feature (PII data-provider resolvers) deliberately NOT cross-linked with `config.selfHosted` — confirmed correct. +- **Navigation**: `release-notes/version-6/sdk-changelog` registered in docs.json. + +### Note +- Pre-existing `#### Config` heading in data-models.mdx lacks the `---` separator that other `####` sections use. Pre-existing (not introduced this release), out of scope; the newly added sections correctly follow the dominant `---` pattern. Left as-is. + +### Summary +- Files corrected: 0 · Critical issues: 0 · Terminology alignments: 0 (already consistent from Agent-6) · Broken links: none + +### Handoff +Documentation consistent. Ready for **Plugin Agent 1 (Skills Delta Extractor)** — skill-relevant delta this release is the new public `config.selfHosted` surface (`SelfHostedConfig` / `SelfHostedCloudFunctionConfig` / `DeploymentModuleId`) plus the optional `config` arg on `loadVelt()`/`loadSnippyly()`; all additive, no breaking changes. Per run rules: no commits/branches/PRs created, and the next agent was not triggered — the outer script handles sequencing. + +_QA log intended for `.claude/logs/agent-7-qa-v6.0.0-beta.8.md`; harness write-protection on `.claude/` prevented persistence, so it is delivered inline above._ diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/pr-body.md b/.claude/release-notes/runs/v6.0.0-beta.8/pr-body.md new file mode 100644 index 000000000..c3f88e0f3 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/pr-body.md @@ -0,0 +1,18 @@ +## Summary + +Automated release-note docs pipeline for `release-notes/v6.0.0-beta.8.md`. + +- Route: `core-SDK` +- Source note: https://github.com/snippyly/internal-release-notes/blob/e22a3fa030513b07289759001cf979c0dc3f0b8c/release-notes/v6.0.0-beta.8.md +- Rerun URL: https://github.com/snippyly/internal-release-notes/blob/e22a3fa030513b07289759001cf979c0dc3f0b8c/release-notes/v6.0.0-beta.8.md +- Status: Complete +- Run: https://github.com/velt-js/docs/actions/runs/29274549982 + +## Needs human follow-up + +- Review the generated docs changes before merging. +- Confirm the conservative automation defaults were appropriate for this note. + +## Checkpoints + +Runtime checkpoints are saved under `.claude/release-notes/runs/v6.0.0-beta.8`. diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/public-note.env b/.claude/release-notes/runs/v6.0.0-beta.8/public-note.env new file mode 100644 index 000000000..343fb9d2c --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/public-note.env @@ -0,0 +1 @@ +trimmed_internal_section=true diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/route.json b/.claude/release-notes/runs/v6.0.0-beta.8/route.json new file mode 100644 index 000000000..abe205b4f --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/route.json @@ -0,0 +1,11 @@ +{ + "class": "core-SDK", + "version": "v6.0.0-beta.8", + "stem": "v6.0.0-beta.8", + "safe_stem": "v6.0.0-beta.8", + "branch": "v6.0.0-beta.8", + "title": "v6.0.0-beta.8", + "changelog": "release-notes/version-6/sdk-changelog.mdx", + "major": "6", + "triage_reason": "" +} diff --git a/.claude/release-notes/runs/v6.0.0-beta.8/run.env b/.claude/release-notes/runs/v6.0.0-beta.8/run.env new file mode 100644 index 000000000..b2df97701 --- /dev/null +++ b/.claude/release-notes/runs/v6.0.0-beta.8/run.env @@ -0,0 +1,13 @@ +NOTE_REPO=snippyly/internal-release-notes +SOURCE_REPO=snippyly/internal-release-notes +NOTE_PATH=release-notes/v6.0.0-beta.8.md +SOURCE_SHA=e22a3fa030513b07289759001cf979c0dc3f0b8c +CHANGE_TYPE=added +PIPELINE_MODE=resume +RUN_URL=https://github.com/velt-js/docs/actions/runs/29274549982 +RN_CLASS=core-SDK +RN_VERSION=v6.0.0-beta.8 +RN_BRANCH=v6.0.0-beta.8 +RN_TITLE=v6.0.0-beta.8 +RN_CHANGELOG=release-notes/version-6/sdk-changelog.mdx +trimmed_internal_section=true diff --git a/api-reference/sdk/api/api-methods.mdx b/api-reference/sdk/api/api-methods.mdx index 736b9f196..77322fe89 100644 --- a/api-reference/sdk/api/api-methods.mdx +++ b/api-reference/sdk/api/api-methods.mdx @@ -3326,6 +3326,18 @@ Set up initial configurations for the Velt SDK. - React Hook: `n/a` {/* - [Full Documentation →](/get-started/quickstart) */} +#### loadVelt() +Manually bootstrap the Velt SDK. Accepts an optional `config` to inject a [`SelfHostedConfig`](/api-reference/sdk/models/data-models#selfhostedconfig) before the default Firebase app initializes. +- Params: `config?: { selfHosted?:` [`SelfHostedConfig`](/api-reference/sdk/models/data-models#selfhostedconfig) `}` (optional) +- Returns: `void` +- React Hook: `n/a` + +#### loadSnippyly() +Alias of [`loadVelt()`](#loadvelt) for legacy Snippyly bootstrapping, with the same optional `config` argument. +- Params: `config?: { selfHosted?:` [`SelfHostedConfig`](/api-reference/sdk/models/data-models#selfhostedconfig) `}` (optional) +- Returns: `void` +- React Hook: `n/a` + #### getVeltInitState() Subscribe to detect whether Velt is initialized. - Params: `void` diff --git a/api-reference/sdk/models/data-models.mdx b/api-reference/sdk/models/data-models.mdx index bdc338fc5..febe3e96f 100644 --- a/api-reference/sdk/models/data-models.mdx +++ b/api-reference/sdk/models/data-models.mdx @@ -5231,6 +5231,67 @@ The `dataProvider` event emits different resolver event types depending on the d | `userIdAllowList` | string[] | No | Restricts Velt features to specific users. | | `usePrefersColorScheme` | boolean | No | If set to true, listens to changes on the `prefers-color-scheme` media query to set the global theme of Velt components. | | `globalStyles` | boolean | No | Controls whether Velt's global CSS styles are loaded. Default: true | +| `selfHosted` | [`SelfHostedConfig`](#selfhostedconfig) | No | Optional self-hosting / on-prem overrides for Velt backend endpoints. Omit for default SaaS behavior. | + +#### SelfHostedConfig + +--- + +Optional overrides that redirect Velt backend endpoints to your own infrastructure. Every field is optional; unspecified values fall back to the per-build Velt default. Used in [`Config.selfHosted`](#config). + +| Property | Type | Required | Description | +| ---------------------------------- | ---------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `strict` | `boolean` | No | When `true`, un-provided endpoints resolve to inert sentinels with zero egress. Default `false` (hybrid, falls back to Velt). | +| `firebaseConfig` | `Partial` | No | Firebase config override, deep-merged over the environment default (injected keys win). | +| `firebaseNotificationsDatabaseURL` | `string` | No | Override for the notifications-hub RTDB URL. | +| `cloudFunction` | [`SelfHostedCloudFunctionConfig`](#selfhostedcloudfunctionconfig) | No | Per-endpoint base-URL overrides for the cloud-function fleet. | +| `deploymentProfile` | [`DeploymentModuleId[]`](#deploymentmoduleid) | No | Enabled backend feature-modules. Endpoints outside the list degrade silently. Absent/empty enables all modules. | +| `enablePortableBackend` | `boolean` | No | Opt-in defensive consumption of a future portable-backend `identify()` response. Default `false`. | + +#### SelfHostedCloudFunctionConfig + +--- + +Per-endpoint absolute base-URL overrides for the cloud-function fleet. Used in [`SelfHostedConfig.cloudFunction`](#selfhostedconfig). Each field is optional; omit to keep the Velt default for that endpoint. + +```typescript +interface SelfHostedCloudFunctionConfig { + validateClient?: string; + getPlanDetails?: string; + sa?: string; + getIceServers?: string; + chatgptCompletion?: string; + rewriterAskAi?: string; + whisperTranscription?: string; + getAllowedDocuments?: string; + getNotificationsForDocuments?: string; + videoBackend?: string; + convertRecording?: string; + processRecording?: string; + sdkProxy?: string; + screenshot?: string; + /** Single override that collapses the ×5 regional setEncryptedData split — used for ALL regions when set. */ + setEncryptedData?: string; + /** Optional per-region overrides (used only if the single setEncryptedData above is unset). */ + regions?: { [region: string]: { setEncryptedData?: string } }; +} +``` + +#### DeploymentModuleId + +--- + +Identifier for a backend feature-module, used in [`SelfHostedConfig.deploymentProfile`](#selfhostedconfig). `DEPLOYMENT_MODULE_IDS` lists the 13 valid module ids. + +```typescript +const DEPLOYMENT_MODULE_IDS = [ + 'core', 'notifications', 'recorder-media', 'ai', 'agents', 'huddle-webrtc', + 'integrations-workflow', 'superflow', 'billing-stripe', 'analytics-telemetry', + 'migrations', 'velt-internal', 'console', +] as const; + +type DeploymentModuleId = typeof DEPLOYMENT_MODULE_IDS[number]; +``` #### Features diff --git a/docs.json b/docs.json index dd406aa02..4e5f68570 100644 --- a/docs.json +++ b/docs.json @@ -1068,6 +1068,12 @@ { "group": "Release Notes", "pages": [ + { + "group": "Version 6.0.0", + "pages": [ + "release-notes/version-6/sdk-changelog" + ] + }, { "group": "Version 5.0.0", "pages": [ diff --git a/release-notes/version-6/sdk-changelog.mdx b/release-notes/version-6/sdk-changelog.mdx new file mode 100644 index 000000000..8bb694a5f --- /dev/null +++ b/release-notes/version-6/sdk-changelog.mdx @@ -0,0 +1,57 @@ +--- +title: "Velt SDK Changelog" +rss: true +description: Release Notes of changes added to the core Velt SDK +--- + +### Libraries +- `@veltdev/react` +- `@veltdev/client` +- `@veltdev/sdk` + + + +### New Features + +- [**Self-Hosting**]: New optional `selfHosted` block on `initConfig` lets you redirect Velt's backend endpoints (Firebase config, cloud-function URLs, notifications RTDB URL, encrypted-write endpoints) to your own infrastructure. Use the default hybrid mode to migrate one endpoint at a time, or `strict: true` for full data-sovereignty mode where any un-provided endpoint resolves to an inert sentinel with zero egress to Velt. Every field is optional, so a config without a `selfHosted` block behaves exactly as before. [Learn more →](/api-reference/sdk/models/data-models#config) + + + +```tsx + + {/* ... */} + +``` + + +```js +Velt.init('YOUR_API_KEY', { + selfHosted: { + strict: true, + deploymentProfile: ['core', 'notifications'], + cloudFunction: { validateClient: 'https://your-infra.example.com/validateclient' }, + }, +}); +``` + + + +- [**Self-Hosting**]: [`Velt.loadVelt()`](/api-reference/sdk/api/api-methods#loadvelt) and [`Velt.loadSnippyly()`](/api-reference/sdk/api/api-methods#loadsnippyly) now accept an optional `config` argument with the same shape as `init()`, so manual-loader flows can inject `selfHosted.firebaseConfig` before the default Firebase app bootstraps. Backward-compatible — a bare `loadVelt()` / `loadSnippyly()` call behaves exactly as before. + +- [**Self-Hosting**]: The `Config` model gains an optional `selfHosted` field, backed by new public types `SelfHostedConfig`, `SelfHostedCloudFunctionConfig`, and `DeploymentModuleId`. Additive only — existing configs typecheck and behave unchanged. [Learn more →](/api-reference/sdk/models/data-models#config) + +### Bug Fixes + +- [**Self-Hosting**]: Each `Velt.init()` call now owns a private polling timer and retry counter instead of sharing module-level state, so repeated or concurrent `init()` calls can no longer overwrite each other's timer handle or corrupt the shared retry budget. + +- [**Self-Hosting**]: A failed or timed-out `init()` now cleanly releases its pre-bootstrap stash authority, so a later `loadVelt(config)` / `loadSnippyly(config)` can still inject its `selfHosted` config on the same page load. + +- [**Self-Hosting**]: `loadVelt()` / `loadSnippyly()` now stash the pre-bootstrap self-hosted config and emit a specific console warning when a manual loader and `initConfig` supply diverging configs, instead of failing silently on this split-brain state. + +