- Updated error message in `runHeadlessClaudeAgent` to be more concise.
- Removed unnecessary comments in `config-file.test.ts` and `hexclave-config-file.ts` to enhance readability.
- Refactored `runHeadlessClaudeAgent` to streamline the handling of the `onPreToolUse` option.
- Adjusted import statements in `index.ts` for better clarity.
These changes improve the maintainability and clarity of the codebase, particularly in the configuration management components.
- Updated `next.config.mjs` to include dynamic path resolution for the `@anthropic-ai/claude-agent-sdk`, improving output file tracing.
- Refactored tests in `config-file.test.ts` to clarify the shared agent updater's functionality and ensure it can handle updates to both config and imported files in a single run.
- Modified `manager.ts` to utilize `updateConfigObject` for applying configuration updates, enhancing the reliability of remote environment updates.
- Improved the `updateConfigObject` function in `local-config-updater` to include baseline configuration in the update prompt, ensuring expected outcomes are clearly defined.
These changes enhance the configuration management and testing capabilities within the Hexclave ecosystem.
- Removed "allowImportingTsExtensions" from tsconfig.json in dashboard, local-config-updater, and stack-cli to streamline TypeScript configurations.
- Updated import statement in local-config-updater to use a more explicit path for better clarity.
These changes simplify TypeScript settings and improve code maintainability across the project.
- Added "allowImportingTsExtensions" to tsconfig.json files in dashboard, local-config-updater, and stack-cli for enhanced TypeScript module handling.
- Refactored the AppDetailsPageClient component to simplify the enable/disable functionality by removing asynchronous alert wrappers.
- Updated the configuration update function to enable waiting for sync, improving the reliability of remote environment updates.
These changes enhance TypeScript support and improve the user experience in the dashboard application.
- Added outputFileTracingIncludes to next.config.mjs for better handling of the @anthropic-ai/claude-agent-sdk files.
- Updated import statements in local-config-updater to use TypeScript type imports for improved clarity and maintainability.
These changes improve the configuration management and build process within the Hexclave ecosystem.
The merge auto-resolved manager.ts by keeping the updateConfigObject import,
but dev switched to the simpler replaceConfigObject + override approach. The
transitive import chain through updateConfigObject pulled the Claude agent SDK
into the Edge Runtime bundle, causing Turbopack build failures (crypto, fs,
path, process.exit are not available in Edge Runtime).
Co-Authored-By: mantra <mantra@stack-auth.com>
## What
Continues the **Stack Auth → Hexclave** rename for a set of safe,
internal-only surfaces. This intentionally avoids public-contract names.
### Changes
- **Examples** — renamed the user-facing config module
`stack.ts`/`stack.tsx` (and the `convex` / `lovable` `stack/`
directories) to `hexclave`, and updated every importer across
`.ts`/`.tsx`/`.jsx`. The public `app/handler/[...stack]/` route segment
is left unchanged.
- **apps/{dashboard,backend,internal-tool}** — renamed app-local
SDK-init symbols `stackClientApp → hexclaveClientApp` and
`getStackServerApp → getHexclaveServerApp`, and the dashboard
`StackCompanion` component → `HexclaveCompanion` (incl.
`useStackCompanion`, context types). The public
`StackClientApp`/`StackServerApp` SDK classes are **unchanged**.
- **packages/stack-shared** — added comments to the crypto / JWT / vault
`stack-*` literals documenting that they must **not** be renamed (key
derivation / JWKS / KMS-alias stability). The literals are
byte-identical.
### Deliberately excluded
- **`STACK_*` → `HEXCLAVE_*` env-var rename** — `HEXCLAVE_*` already
resolves via the dual-read layers (SDK env, dashboard `_inlineEnvVars`,
`getEnvVariable`). The remaining holdout is the docker post-build
sentinel path, which the codebase authors explicitly deferred and which
is tightly coupled to `entrypoint.sh` + untestable here. A blind rename
there risks silently breaking self-host/emulator bootstrap for ~zero
functional gain.
- **All public-contract names** — SDK class names, env vars, HTTP
headers (`x-stack-*`), and the `/handler` route convention.
## Verification
- `pnpm lint` — **29/29 passing**.
- `pnpm typecheck` — **28/29 passing**; the only failure is
`@hexclave/docs` (pre-existing missing fumadocs `.source` codegen,
untouched by this PR).
- Two rounds of adversarial multi-agent review; findings fixed:
string-literal collateral from the symbol sweep (CLI test fixtures + an
AI-prompt template) reverted, and a missed `.jsx` importer in
`examples/cjs-test` corrected.
## Notes
- Based on a `dev` snapshot from when the branch was cut (a couple
commits behind tip); the diff contains only the changes above.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Complete the internal “Stack” → “Hexclave” rename across examples,
app-local code, config tooling, and setup docs, and standardize env
output to HEXCLAVE_* with correct default API URL handling. Public SDK
classes, handler routes, and legacy env names keep working.
- **Refactors**
- Examples/config: `stack.*` files and `stack/` dirs →
`hexclave.*`/`hexclave/`; imports updated; keep `app/handler/[...stack]`
route.
- Apps: backend/dashboard/internal-tool now use `getHexclaveServerApp`
and `hexclaveClientApp`; dashboard `StackCompanion` →
`HexclaveCompanion`. Public `StackClientApp`/`StackServerApp` unchanged.
- Env/setup: Next.js and CLI generators write HEXCLAVE_* and omit API
URL when using https://api.stack-auth.com; CLI `doctor` and auth
resolution prefer HEXCLAVE_* (e.g. `HEXCLAVE_SECRET_SERVER_KEY`,
`HEXCLAVE_PROJECT_ID`) with `STACK_*` fallback.
- Config tooling: `stack-config-file` → `hexclave-config-file`, emitting
`HexclaveConfig`; imports updated across backend/dashboard/tooling.
- Shared/docs: added “do not rename” notes for crypto/JWT/vault
`stack-*` literals; regenerated setup prompt/docs to use
`hexclave.config.ts`, `hexclave dev`, and `src/hexclave/`.
- Tests: updated snapshots/assertions to expect `HexclaveConfig` and
HEXCLAVE_* env names.
- **Migration**
- No action required. SDK and CLI read both HEXCLAVE_* and STACK_*.
<sup>Written for commit 8a891b4f6c.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1534?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Renamed internal app/client/server instances and companion/provider
components to the new product name across backend, dashboard, examples,
and tooling; imports updated accordingly.
* Updated generated environment variable names and CLI init/doctor
outputs to prefer the new product prefix.
* **Documentation**
* Added clarifying notes about vault/encryption and JWT/key labels to
avoid breaking existing encrypted data.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Added a new package `@hexclave/local-config-updater` to manage configuration updates.
- Implemented core functionality for reading and updating configuration files using a headless agent.
- Integrated with the `@anthropic-ai/claude-agent-sdk` for AI-assisted updates.
- Updated the pnpm-lock file to reflect new dependencies and removed the deprecated `@anthropic-ai/claude-agent-sdk` from the dashboard app.
- Added tests to ensure the correct behavior of the local config updater.
This change enhances the configuration management capabilities within the Hexclave ecosystem.
## Summary
Four Mintlify doc pages threw runtime console errors and rendered
broken/empty content. Two distinct root causes:
1. **`HexclaveAgentReminders` snippet** — broke Setup, "Using Hexclave
with AI", and Stack CLI pages (and home). The component referenced a
sibling module-level export (`<pre>{hexclaveReminders}</pre>`), but
Mintlify evaluates an imported snippet component in an isolated scope
that does not include sibling exports, throwing `hexclaveReminders is
not defined`. Fixed by inlining the value into the component (matching
the self-contained pattern of every other working snippet). The snippet
is generated, so the generator `scripts/generate-setup-prompt-docs.ts`
was updated too.
2. **`connected-account.mdx`** — SDK ConnectedAccount page rendered
empty because it used `CollapsibleTypesSection`/`MethodLayout`/etc. but
was missing the `/snippets/sdk-type-components.jsx` import that all
other SDK type pages have (`Expected component CollapsibleTypesSection
to be defined`). Added the import.
## Validation
- All 4 pages render fully with clean browser consoles (verified locally
via the `mint` dev server).
- `mint validate` passes.
- Re-running the generator produces no diff (snippet stays in sync with
the generator).
Link to Devin session:
https://app.devin.ai/sessions/6ef551840f104808937c325d3f105e7a
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes console errors and empty renders in Mintlify Hexclave docs by
making the `HexclaveAgentReminders` snippet self-contained and adding
missing SDK type component imports in `connected-account.mdx`. Also
removes an unused export to avoid duplication.
- **Bug Fixes**
- Inlined content in `HexclaveAgentReminders` and updated
`scripts/generate-setup-prompt-docs.ts` to emit it, resolving
ReferenceError on Setup, Using Hexclave with AI, Stack CLI, and home
pages.
- Added missing `/snippets/sdk-type-components.jsx` import and the
`ContentSection`/`MethodReturns` named imports in
`sdk/types/connected-account.mdx` so type components render.
- **Refactors**
- Removed the unused `hexclaveReminders` export from the snippet.
<sup>Written for commit b5f2f7a28e.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1541?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: aman <aman@stack-auth.com>
## Summary
Three related fixes, surfaced while investigating a production error on
managed email onboarding.
### 1. DNSimple managed-email zone deletion (the reported production
error)
`deleteDnsimpleZoneByName` issued `DELETE /v2/{account}/zones/{zone}`,
but **DNSimple's v2 API has no DELETE endpoint for zones**. Zones are
created here by creating a *domain* (`POST /domains`), so the symmetric
teardown is `DELETE /domains/{name}`, which also removes the hosted
zone. The old call returned a non-OK status, throwing:
> `HexclaveAssertionError: DNSimple returned non-OK status when deleting
managed email zone`
on every managed-domain deletion (the Resend domain was already deleted
by then, so the request 500s and the DNSimple zone leaks). Now deletes
the owning domain.
### 2. `applyManagedEmailProvider` left configs in an invalid state
The apply early-returned on `domain.status === "applied"` **without
rewriting config**. If the config had since drifted (e.g. the user
switched to a shared/other provider and back), re-applying never
restored `password`/`senderName`, so the *rendered* config was invalid
and **every `GET /internal/projects` 500'd** with `Result admin
validation failed in CRUD handler` (dashboard then loops/refreshes). Now
it only short-circuits when the config actually uses the domain
(`isManagedEmailDomainInUseForTenancy`); otherwise it re-provisions and
writes the full valid config.
### 3. Email-settings dashboard: managed domain now uses the staged save
flow
Clicking "Use this domain" fired an immediate API call and only
refreshed the domains *list* — never the project config the UI derives
"active" from — so nothing visibly changed and it appeared not to
persist. Applying a managed domain now matches the other providers:
selecting a domain stages a draft and shows the standard **"Unsaved
changes → Save"** card; **Save** calls `applyManagedEmailProvider`
(which owns the full config write) and then refreshes the reactive
config cache so the UI flips to **Active**.
### 4. Build unblock: `@stackframe/stack-shared` → `@hexclave/shared`
The `@hexclave/*` rename (#1482) missed `createGlobal`'s import in two
template providers, and PR 3 deleted the compat alias — so `pnpm
build:packages` couldn't resolve
`@stackframe/stack-shared/dist/utils/globals` when building the
dashboard. Fixed in the template (generated SDKs follow). *(Independent
of the email fixes, but required to build the branch.)*
## Files
- `apps/backend/src/lib/managed-email-onboarding.tsx` — DNSimple domain
delete + apply re-provision-on-drift
- `apps/dashboard/.../email-settings/domain-settings.tsx` — staged
managed-domain apply
-
`packages/template/src/providers/{stack-context,translation-provider-client}.tsx`
— globals import rename
## Testing
- `tsc --noEmit` and `eslint` clean on `@hexclave/backend` and
`@hexclave/dashboard`.
- `pnpm build:packages` + `pnpm codegen` succeed; dashboard
email-settings route compiles and serves `200`.
- Reproduced the 500 loop locally, root-caused it to a partial managed
config override, and reset the affected project's `emails.server`
override to recover.
## Notes
- Applying a managed domain still calls the API once (to mint the scoped
Resend sending key) — that call now happens on **Save** rather than on
click.
- The older `apps/dashboard/.../emails/page-client.tsx` has the same
immediate-apply pattern; left untouched pending confirmation that screen
is still in use.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes managed email onboarding: deletes DNSimple domains correctly,
restores a valid managed config on re-apply, and moves managed-domain
apply to a staged Save that waits for the domain list and shows
selection state. Also updates imports to `@hexclave/shared` to unblock
builds.
- **Bug Fixes**
- DNSimple teardown: use DELETE `/domains/{name}` (zones have no
DELETE). Stops errors and zone leaks when removing managed domains.
- `applyManagedEmailProvider`: only short-circuits when the rendered
config already uses the domain; otherwise re-provisions and writes the
full managed config to prevent invalid renders and 500s.
- Dashboard: managed domain selection now stages a draft; Save calls
`applyManagedEmailProvider`, refreshes the config cache, and the UI
updates. Shows “Selected — save to apply,” supports deselecting,
requires a selection, and disables Save until the domains list finishes
loading.
- **Dependencies**
- Renamed globals import from `@stackframe/stack-shared` to
`@hexclave/shared` to restore `pnpm build:packages`.
<sup>Written for commit 6ecb6a1ff8.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1527?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved detection and recovery for managed email configuration drift
scenarios
* Fixed teardown behavior to avoid leaving inconsistent managed domain
state
* **New Features**
* Managed domain selection now requires explicit save confirmation
before applying
* Added status labels showing current vs staged domain and pending
changes
* Added ability to deselect staged managed domains; deleting a domain
clears any draft
* Save now shows applied sender identity via toast after applying
managed domain
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The merge with dev left the apps/dashboard importer without its
@anthropic-ai/claude-agent-sdk entry (so frozen install failed) and kept
stale duplicate @img/sharp platform packages. Regenerated the lockfile so
it matches every package.json again.
Co-Authored-By: mantra <mantra@stack-auth.com>
The PreToolUse hook now denies any Write/Edit whose resolved target lands
outside the agent's cwd (absolute paths or ../ escapes from imports) and
fails the run loudly afterwards, so cwd is a real boundary rather than
just where relative paths resolve. Adds unit tests covering the
allow/deny/absolute-path cases.
Co-Authored-By: mantra <mantra@stack-auth.com>
JSON-encode configFileName in buildConfigUpdatePrompt, matching the
existing treatment of config paths/values, so a file name containing a
backtick can't break out of the prompt's code span.
Co-Authored-By: mantra <mantra@stack-auth.com>
Make restoreConfigFiles best-effort (restore every file, aggregate
per-file failures) and guard the rollback call site so a restore
exception is logged but the original update error is always re-thrown.
Co-Authored-By: mantra <mantra@stack-auth.com>
- Short-circuit updateConfigObject when flattenConfigUpdate yields no leaf changes
(avoids wasting an AI call on empty/undefined-only updates)
- Add settingSources: [], strictMcpConfig: true, CLAUDE_CODE_DISABLE_AUTO_MEMORY
to the agent runner so it doesn't inherit user/project Claude settings
- Reject relative imports that escape the config directory (../ traversal) to
prevent out-of-workspace read/write during snapshot/restore
Co-Authored-By: mantra <mantra@stack-auth.com>
Uses the previously-unused filePath param as Babel's sourceFilename so parse
diagnostics reference the real file. Addresses Copilot review note.
Co-Authored-By: mantra <mantra@stack-auth.com>
When the config can't be evaluated (e.g. it imports external text files) we
can't do a semantic check, so a wrong agent result could previously pass the
structural `export config` check. Now a non-empty update that leaves every
snapshotted file byte-for-byte unchanged is treated as a failure (and rolled
back), so the agent doing nothing is no longer reported as success.
Addresses cubic P1: fallback validation too weak for non-evaluable configs.
Co-Authored-By: mantra <mantra@stack-auth.com>
- Roll back the config file and its referenced files if the agent fails or
its result doesn't validate, so no half-applied update is left behind
- Validate the rendered fast-path config in memory before writing to disk
- Only schedule a background sync after a successful update (manager.ts)
- Treat empty-object update values as leaves and skip undefined values so the
agent prompt matches override() semantics
- Detect agent completion via "result" in message (matches the CLI)
- Accept the export { config } specifier form in the structural check
- Add importAttributes to parseStackConfigFileContent for parser consistency
- Drop the unsafe Record<string,string> cast in stripClaudeCodeEnv
- Add a bounded, configurable timeout to the agent run
Co-Authored-By: mantra <mantra@stack-auth.com>
The previous regeneration re-resolved the whole tree and downgraded the
dashboard's @types/react from 19.2.7 to 18.3.29, which made useRef().current
read-only and broke the dashboard build (page-client.tsx). dev's lockfile
already satisfies this branch's package.json (including the agent SDK), so
restoring it keeps the dependency graph unchanged and fixes the build.
Co-Authored-By: mantra <mantra@stack-auth.com>
dev moved pnpm.overrides from package.json into pnpm-workspace.yaml (commit 82f470e56), which pnpm 11.5.0 reads. Regenerated the lockfile so its overrides block matches, fixing ERR_PNPM_LOCKFILE_CONFIG_MISMATCH on frozen install.
Co-Authored-By: mantra <mantra@stack-auth.com>
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/hexclave/hexclave/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Improve ClickHouse readiness check for local startup and make it
non-blocking with clearer logs. Also tighten workspace build
permissions.
- **Bug Fixes**
- Updated `wait-until-clickhouse-is-ready` to log status, use `wait-on`
with `http-get://`, verbose output, and a 10s timeout; continue with a
warning if ClickHouse isn’t ready.
- **Dependencies**
- Set `@quetzallabs/i18n` to `false` in `pnpm-workspace.yaml`
`allowBuilds` to prevent building that package.
<sup>Written for commit f24cf668b9.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1535?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Improved dependency readiness checks with enhanced error handling and
logging during system initialization.
* Updated build configuration to optimize package dependency management
and build processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Apply RDE config updates in place instead of overwriting the whole file.
Plain static configs keep the deterministic render (fast path, no AI). Configs
with custom structure (imports, helper wrappers, external text refs) are edited
by a headless Claude agent so user-authored structure is preserved and
externally-referenced files are updated rather than inlined. Every edit is
validated (semantic when the config is evaluable, structural fallback
otherwise) and hard-fails on mismatch.
Co-Authored-By: mantra <mantra@stack-auth.com>