* fix(security): distinguish webhooks from internal hooks in audit summary
The attack surface summary reported a single 'hooks: disabled/enabled' line
that only checked the external webhook endpoint (hooks.enabled), ignoring
internal hooks (hooks.internal.enabled). Users who enabled internal hooks
(session-memory, command-logger, etc.) saw 'hooks: disabled' and thought
something was broken.
Split into two separate lines:
- hooks.webhooks: disabled/enabled
- hooks.internal: disabled/enabled
Fixes#13466
* test(security): move attack surface tests to focused test file
Move the 3 new hook-distinction tests from the monolithic audit.test.ts
(1,511 lines) into a dedicated audit-extra.sync.test.ts that tests
collectAttackSurfaceSummaryFindings directly. Avoids growing the
already-large test file and keeps tests focused on the changed unit.
* fix: add changelog entry for security audit hook split (#13474) (thanks @mcaxtr)
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The newly added 'resolved' field contains secrets after ${ENV}
substitution. This commit ensures redactConfigSnapshot also redacts
the resolved field to prevent credential leaks in config.get responses.
The initial fix using snapshot.parsed broke configs with $include directives.
This commit adds a new 'resolved' field to ConfigFileSnapshot that contains
the config after $include and ${ENV} substitution but BEFORE runtime defaults
are applied. This is now used by config set/unset to avoid:
1. Breaking configs with $include directives
2. Leaking runtime defaults into the written config file
Also removes applyModelDefaults from writeConfigFile since runtime defaults
should only be applied when loading, not when writing.
Fixes#6070
The config set/unset commands were using snapshot.config (which contains
runtime-merged defaults) instead of snapshot.parsed (the raw user config).
This caused runtime defaults like agents.defaults to leak into the written
config file when any value was set or unset.
Changed both set and unset commands to use structuredClone(snapshot.parsed)
to preserve only user-specified config values.
* fix(security): prevent String(undefined) coercion in credential inputs
When a prompter returns undefined (due to cancel, timeout, or bug),
String(undefined).trim() produces the literal string "undefined" instead
of "". This truthy string prevents secure fallbacks from triggering,
allowing predictable credential values (e.g., gateway password = "undefined").
Fix all 8 occurrences by using String(value ?? "").trim(), which correctly
yields "" for null/undefined inputs and triggers downstream validation or
fallback logic.
Fixes#8054
* fix(security): also fix String(undefined) in api-provider credential inputs
Address codex review feedback: 4 additional occurrences of the unsafe
String(variable).trim() pattern in auth-choice.apply.api-providers.ts
(Cloudflare Account ID, Gateway ID, synthetic API key inputs + validators).
* fix(test): strengthen password coercion test per review feedback
* fix(security): harden credential prompt coercion
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Ship a self-contained standalone server with the npm package so
`npm i -g ironclaw` can serve the web UI without runtime `npm install`
or `next build`. This eliminates the fragile first-boot build step
and cuts the cold-start time for the gateway web app.
Changes:
- next.config.ts: enable `output: "standalone"` and set
`outputFileTracingRoot` to the monorepo root so pnpm workspace
deps are traced correctly. Remove the now-unnecessary manual
webpack externals for Node.js built-ins.
- package.json: update `files` to ship only the standalone build
output, static assets, and public dir (instead of the entire
`apps/web/` tree). Add `web:build` and `web:prepack` to the
`prepack` script so the standalone server is built and its
static/public assets are copied into place before publish. Bump
version to 2026.2.10-1.5.
- server-web-app.ts: rewrite the web app lifecycle to prefer the
pre-built standalone `server.js` in production. Add
`resolveStandaloneServerJs`, `hasStandaloneBuild`,
`hasLegacyNextBuild`, and `isInWorkspace` helpers. In dev
workspaces, fall back to building on-the-fly or legacy
`next start`. Export key functions for testability.
- server-web-app.test.ts: add comprehensive unit tests covering
path resolution, standalone/legacy build detection,
ensureWebAppBuilt scenarios (skip, disabled, dev, standalone,
legacy, missing), startWebAppIfEnabled (skip, disabled, null
config, missing dir, standalone start, missing build error,
default port, graceful stop).
- workspace-sidebar.tsx: update sidebar branding to "Ironclaw".
Published as ironclaw@2026.2.10-1.5.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Introduced a new RelationSelect component for managing relations in forms.
- Updated EntryDetailModal and ObjectTable components to utilize RelationSelect for relation fields, allowing for inline editing and improved user experience.
- Enhanced API route for fetching relation options based on user input.
- Refactored EditableCell to support relation editing with dropdowns, improving data entry efficiency.
- Added new API endpoint for fetching lightweight options for relation dropdowns.
This update streamlines the handling of relational data within the workspace, enhancing the overall functionality and user interface.