Skip to content

[comp] Production Deploy#3402

Merged
tofikwest merged 15 commits into
releasefrom
main
Jul 15, 2026
Merged

[comp] Production Deploy#3402
tofikwest merged 15 commits into
releasefrom
main

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

This is an automated pull request to release the candidate branch into production, which will trigger a deployment.
It was created by the [Production PR] action.


Summary by cubic

Fixes org chart refresh after upload/delete/replace/save, sanitizes automation preview URLs, clears stale device-agent auth on uninstall, blocks SSRF in enterprise API calls, hardens dependencies to reduce security findings to 14, and adds an SBOM workflow that submits the resolved Bun tree to GitHub (scans bun.lock via Syft v1.46.0). Also raises framework-editor requirement description limit to 100,000 to support long regulatory text (FRAME-2) and sets least-privileged workflow permissions. Addresses CS-408.

  • Bug Fixes

    • Org chart: adds onChartChange to revalidate SWR after upload/delete/replace/save; isolates refresh failures.
    • Automation preview: only allows http(s) URLs for iframe src/link; drives navigation via state so refresh/external link stay in sync.
    • Enterprise API: prevents SSRF by encoding runId and enforcing a base-origin allowlist in callEnterpriseApi.
    • Device agent: clears app data on uninstall (Windows electron-builder deleteAppDataOnUninstall: true; Debian after-remove.sh) to avoid silent auto-linking after reinstall.
    • Auth types: makes permission merging readonly-compatible with better-auth 1.6.
    • Codegen: escapes backslashes (then quotes) in generate-task-types.ts to avoid broken TS string literals.
    • CI/workflows: adds permissions: contents: read to Trigger.dev deploy and DB migration workflows.
  • Dependencies

    • Security upgrades: better-auth ^1.6.13, next ^16.2.6, axios ^1.16.0; bumps vitest/vite/turbo; updates @browserbasehq/stagehand and @nestjs/swagger.
    • Overrides: adds root overrides for vulnerable transitives (incl. uuid ^11.1.1); apps/mcp-server adds tmp ^0.2.7 and js-yaml ^4.3.0 (npm audit: 0).
    • UI build: removes glob in @trycompai/ui build/exports for deterministic exports and to fix framework-editor builds; skips dotfiles.
    • CI/SBOM: adds .github/workflows/sbom.yml scanning bun.lock via anchore/sbom-action (pinned SHA) with syft-version: v1.46.0 to submit a dependency snapshot.

Written for commit 35487c2. Summary will update on new commits.

Review in cubic

github-actions Bot and others added 3 commits July 14, 2026 03:09
Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com>
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
…r replace (#3362)

* fix(app): refresh SWR cache after upload, delete, and replace

* fix(app): revalidate SWR cache after editor save

* fix(app): isolate SWR refresh failures from upload/delete/save results

---------

Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com>
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
comp-framework-editor (staging) Ready Ready Preview, Comment Jul 15, 2026 6:56pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
app (staging) Skipped Skipped Jul 15, 2026 6:56pm
portal (staging) Skipped Skipped Jul 15, 2026 6:56pm

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 8 files

Confidence score: 3/5

  • In packages/device-agent/assets/linux/after-remove.sh, uninstall cleanup misses the device-linking token when XDG_CONFIG_HOME is set, so reinstall in those environments can incorrectly remain linked and skip sign-in; this can cause account/state leakage across installs—update removal logic to resolve each user’s effective XDG config path (or otherwise clear that token location) before merging.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/device-agent/assets/linux/after-remove.sh">

<violation number="1" location="packages/device-agent/assets/linux/after-remove.sh:10">
P2: Uninstall leaves the device-linking token behind for users who set `XDG_CONFIG_HOME`, so reinstalling in that environment can still skip sign-in. Include each user's effective XDG config location (or otherwise clear the Electron `userData` directory) rather than assuming `~/.config`.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

remove|purge)
for home in /root /home/*; do
[ -d "$home" ] || continue
config_dir="$home/.config/comp-ai-device-agent"

@cubic-dev-ai cubic-dev-ai Bot Jul 14, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Uninstall leaves the device-linking token behind for users who set XDG_CONFIG_HOME, so reinstalling in that environment can still skip sign-in. Include each user's effective XDG config location (or otherwise clear the Electron userData directory) rather than assuming ~/.config.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/device-agent/assets/linux/after-remove.sh, line 10:

<comment>Uninstall leaves the device-linking token behind for users who set `XDG_CONFIG_HOME`, so reinstalling in that environment can still skip sign-in. Include each user's effective XDG config location (or otherwise clear the Electron `userData` directory) rather than assuming `~/.config`.</comment>

<file context>
@@ -0,0 +1,18 @@
+  remove|purge)
+    for home in /root /home/*; do
+      [ -d "$home" ] || continue
+      config_dir="$home/.config/comp-ai-device-agent"
+      if [ -d "$config_dir" ]; then
+        rm -rf "$config_dir"
</file context>
Fix with cubic

Reduce `bun audit` findings from 165 (4 critical / 58 high) to 44
(0 critical / 17 high) by bumping direct deps and adding root overrides
for transitive ones. bun.lock regenerated via `bun install`.

Direct bumps (vulnerable instance was the direct dep):
- better-auth 1.4.22 -> ^1.6.13  (CVE-2026-53512, CVSS 9.1 OAuth
  refresh-token replay; mcp/oidcProvider plugin is enabled in apps/api)
- next ->^16.2.6      (middleware/proxy bypass, SSRF, DoS)
- axios ->^1.16.0     (proxy-auth credential leak, prototype pollution)
- vitest ->^3.2.6, vite ->^6.4.3, turbo ->^2.10.5

Root overrides for transitive vulns (backcompat-safe versions only):
axios, vitest/@vitest/{coverage-v8,ui}, form-data, ws, semver, hono,
@hono/node-server, multer, systeminformation, tmp, dompurify,
ip-address, postcss, prismjs, qs, effect, protobufjs, linkify-it,
mermaid, shell-quote, vite.

undici intentionally NOT overridden: discord.js/@discordjs/rest pin
undici@6 and use its internals; forcing v7 would break them at runtime.

Verified: all production/source code typechecks clean across every
workspace. Remaining typecheck errors are pre-existing .spec.ts test
debt on main (unchanged source + unchanged jest/@types/node/trigger).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ritical→0) (#3406)

* fix(deps): remediate dependency security vulnerabilities (165 -> 16)

Comprehensive dependency-security pass. Reduces `bun audit` from 165
findings (4 critical / 58 high) to 16 (0 critical / 10 high / 3 moderate /
3 low). All changes stay within declared version ranges; bun.lock is a
clean regeneration.

Direct bumps (vulnerable instance was the direct dep):
- better-auth 1.4.22 -> ^1.6.13  (CVE-2026-53512, CVSS 9.1 OAuth
  refresh-token replay; mcp/oidcProvider plugin is enabled in apps/api)
- next -> ^16.2.6 (middleware/proxy bypass, SSRF, DoS)
- axios -> ^1.16.0 (proxy-auth credential leak, prototype pollution)
- vitest -> ^3.2.6, vite -> ^6.4.3, turbo -> ^2.10.5

Dead-dep removal (unused, referenced by no script):
- gitmoji -> cascade-drops request, tough-cookie@2.5.0, tar@2.2.2, node-gyp@3
- semantic-release-discord + -notifier -> drops discord.js/@discordjs/rest
  (which pinned undici@6 and blocked patching it). The real release->Discord
  notification is a separate webhook GitHub Action (no npm deps) - untouched.

Parent bumps (newer parent pulls a patched child):
- @browserbasehq/stagehand -> ^3.7.0 (drops langchain + langsmith)
- @nestjs/swagger -> ^11.4.5 (patched js-yaml 4.3.0)

Overrides for transitive vulns (backcompat-safe, verified):
- axios, form-data, ws, semver, hono, @hono/node-server, multer,
  systeminformation, tmp, dompurify, ip-address, postcss, prismjs, qs,
  effect, protobufjs, linkify-it, mermaid, shell-quote, vite,
  @opentelemetry/core, @sigstore/core, markdown-it, @babel/core
- @tiptap/* pinned 3.22.1 (lockstep; the lockfile regen floated the
  transitive @tiptap/* apart from @tiptap/react@3.22.1)

undici NOT force-overridden across majors (discord.js path removed; the
lockfile regen floats v6->6.27.0 and v7->7.28.0 within ranges instead).

Verified: full `turbo build` (20/20) + typecheck (0 production errors)
across all apps; apps/api Dockerfile.multistage builds clean and boots past
module-load (better-auth 1.6 loads; stops only at the expected SECRET_KEY
env guard). openapi.json intentionally untouched (no API files changed).

Remaining 16 are all dev/build-time or no-upstream-fix: tar
(electron-builder/giget/npm-bundled), minimatch (npm-bundled), esbuild
(dev-server only), uuid (exceljs, no v8 fix), sigstore (release CI), cookie
(disjoint majors), @ai-sdk/provider-utils (low, via stagehand).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(app): make permissions readonly-compatible for better-auth 1.6

better-auth 1.6 types role `statements` as readonly tuples
(ExactRoleStatements = { readonly [P]: readonly [...] }), so casting
`role.statements as Record<string, string[]>` (mutable) is an invalid
conversion and fails `next build`'s TypeScript check on Vercel:

  Type 'readonly ["read"]' cannot be assigned to the mutable type 'string[]'

Widen `mergePermissions`'s `source` param to `Record<string, readonly
string[]>` (it only reads, never mutates) and cast to the readonly type.
Verified against better-auth@1.6.23 dist types; the only `.statements`
cast in the app (other Record<string,string[]> casts are on JSON/any).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…16→15) (#3408)

* chore(deps): bump semantic-release to v25, @semantic-release/github to v12

Clears the sigstore dev/CI-only advisory (16→15). Both are dev-only
release-tooling deps; release.yml already runs Node 22 (satisfies
semantic-release@25 engines). syncpack intentionally left at ^13.0.4 —
v15 silently ignores .syncpackrc.json's lintRules.forbiddenDependencies
(supply-chain guard) and dependencyTypes, so it is not a safe drop-in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): build without the glob package (fixes framework-editor build)

The semantic-release bump perturbed the dependency graph enough to shift
bun's hoisting so that packages/ui's tsup build loaded an ESM
brace-expansion@5 against a CJS balanced-match@1.0.2 (no named 'balanced'
export), crashing @trycompai/ui#build on Vercel (framework-editor).

Root cause is a latent fragility: packages/ui pulled 'glob' into its build
in two places — tsup.config.ts (ESM import evaluated by bundle-require) and
scripts/generate-exports.cjs. glob→minimatch→brace-expansion's balanced-match
resolution is hoisting-dependent, so any dep-graph change can trip it.

Remove glob from the ui build entirely:
- tsup.config.ts: pass entry globs directly; tsup expands them via tinyglobby
  (picomatch/fdir), no brace-expansion.
- generate-exports.cjs: manual recursive fs.readdirSync walk (withFileTypes,
  Node>=10; sorted for deterministic output).

Verified: turbo build 20/20; dist file list + generated exports content
unchanged (exports now alphabetical, deterministic across rebuilds).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): skip dotfiles in generate-exports to match glob semantics

The manual readdirSync walk enumerated every entry, whereas the previous
glob.sync('**/*.js') excluded dotfiles/dot-directories by default (dot:false).
Skip dot-prefixed entries so a stray .something.js or .hidden/ in dist/ can't
leak into package.exports. No change to current output (dist has no dotfiles).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…3411)

Fixes CodeQL js/request-forgery (alert #116, critical). callEnterpriseApi
builds `new URL(endpoint, enterpriseApiUrl)` then fetches it; getAutomationRunStatus
interpolated a user-provided runId straight into the endpoint path
(`/api/tasks-automations/runs/${runId}`), so a crafted runId could inject
path segments into the request URL.

- Encode the user value in the path (encodeURIComponent(runId)).
- Add an origin allowlist guard in callEnterpriseApi: resolve the URL against
  the configured enterprise API base and reject anything whose origin differs,
  so no caller can redirect the request to another host.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… (#3412)

apps/mcp-server is a standalone npm project (excluded from the bun
workspaces). Three open Dependabot alerts, all dev-scope transitives:
- #59 (high) + #58 (low): tmp path traversal / symlink write — tmp@0.0.33
  via external-editor; patched in tmp>=0.2.6
- #71 (moderate): js-yaml quadratic-complexity DoS — js-yaml@4.1.1 via
  @eslint/eslintrc; patched in js-yaml>=4.2.0

Add npm overrides (caret-pinned to stay within the safe major):
- tmp ^0.2.6  -> resolves 0.2.7 (fileSync API is stable, external-editor works)
- js-yaml ^4.2.0 -> resolves 4.3.0 (satisfies eslintrc's ^4.1.1; NOT floated to
  v5, which would be an unvetted breaking major)

Verified: npm audit 0 vulnerabilities; mcp-server build + lint pass.
(bun.lock is gitignored and regenerated from package-lock.json at build.)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts">

<violation number="1" location="apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts:64">
P1: A redirect from an enterprise endpoint still bypasses this origin check because `fetch` follows redirects by default. Disable redirects or validate each redirect target so this helper cannot reach another host after the initial request.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

// SSRF guard: `endpoint` and params can carry user-derived values, so pin the
// request to the configured enterprise API origin — never allow it to be
// redirected to another host.
if (url.origin !== baseUrl.origin) {

@cubic-dev-ai cubic-dev-ai Bot Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: A redirect from an enterprise endpoint still bypasses this origin check because fetch follows redirects by default. Disable redirects or validate each redirect target so this helper cannot reach another host after the initial request.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts, line 64:

<comment>A redirect from an enterprise endpoint still bypasses this origin check because `fetch` follows redirects by default. Disable redirects or validate each redirect target so this helper cannot reach another host after the initial request.</comment>

<file context>
@@ -55,7 +55,15 @@ async function callEnterpriseApi<T>(
+  // SSRF guard: `endpoint` and params can carry user-derived values, so pin the
+  // request to the configured enterprise API origin — never allow it to be
+  // redirected to another host.
+  if (url.origin !== baseUrl.origin) {
+    throw new EnterpriseApiError('Invalid enterprise API endpoint', 400);
+  }
</file context>
Fix with cubic

…M/Dependabot) (#3413)

* ci: submit resolved bun tree to GitHub dependency graph (accurate SBOM)

GitHub does not natively parse bun.lock, so its dependency graph, exported
SBOM, and Dependabot only see declared package.json ranges plus the npm
package-lock.json in apps/mcp-server — they are blind to the bun dependency
tree and to our overrides. Syft parses bun.lock with fully resolved versions,
so this workflow scans the repo with Syft (anchore/sbom-action) and submits
the result via GitHub's Dependency Submission API. After it runs on main,
GitHub's own Export SBOM and Dependabot reflect the real bun tree; the SBOM
is also uploaded as a workflow artifact.

Runs on main (when lockfiles/manifests change), weekly, and on demand.
Needs contents:write for the submission API. No run: steps / no untrusted
input, so no workflow-injection surface.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(security): pin anchore/sbom-action to a commit SHA

The action runs with contents:write (Dependency Submission API), so the
mutable @v0 tag is a supply-chain risk — a retag or repo compromise would
run altered third-party code with our write token. Pin to the full commit
SHA of v0.24.0 (Syft v1.42.3, which parses bun.lock). Bump SHA + comment
together to upgrade.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The merged workflow used path: . (a directory scan). Syft's default
DIRECTORY catalogers don't include the bun cataloger, so it silently skipped
bun.lock and submitted a near-empty snapshot (138 pkgs: just mcp-server's
package-lock.json + GitHub Actions — none of the bun tree). Verified: the
generated artifact had 0 bun deps (axios/better-auth/next all absent).

Scan bun.lock with the file: input instead — a file scan forces the bun
cataloger and yields the full resolved tree (2487 pkgs, axios 1.18.1,
form-data 4.0.6, etc.). apps/mcp-server/package-lock.json is already covered
by GitHub's native npm parsing, so submitting the bun tree completes the graph.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…#3415)

The SBOM run still produced an empty snapshot after switching to file:bun.lock.
Root cause proven: anchore/sbom-action@v0.24.0 bundles Syft 1.42.3, and
'syft scan file:bun.lock' on 1.42.3 yields exactly 1 package (no bun.lock
support). Syft 1.46.0 yields the full tree — verified locally: 2484 packages
(spdx) / 2496 resolved deps in the GitHub snapshot format that gets submitted.

Pin syft-version: v1.46.0 so the action uses a Syft that can read bun.lock.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
uuid <11.1.1 has a missing buffer-bounds check in v3/v5/v6 when a buffer
arg is passed (GHSA, medium). Vulnerable copies were uuid@8.3.2 (via exceljs
in @trycompai/api — prod-reachable) and uuid@9.0.1 (via @trigger.dev/sdk).
Add a flat override to ^11.1.1: uuid's v1/v3/v4/v5 named API is stable across
these majors and v11 keeps a dual CJS/ESM build, so exceljs / @azure/core-http
/ @trigger.dev/sdk remain drop-in compatible. Caret stays in 11.x (12.0.0 is
still vulnerable). Resolves to a single uuid@11.1.1.

Verified: turbo build 20/20; bun audit 15 -> 14 (uuid cleared).

The other 7 open bun.lock alerts (minimatch x3, esbuild x2, cookie,
@ai-sdk/provider-utils) have no safe published fix and are not
prod-runtime-reachable -> handled via dismiss-with-rationale, not overrides.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…w perms) (#3419)

* fix(security): resolve open CodeQL alerts (XSS, sanitization, workflow perms)

- #108 (high, js/xss-through-dom): preview.tsx assigned user-typed input to
  iframe.src / anchor href, allowing javascript:/data: URIs to execute in the
  preview context. Gate every URL sink through an http(s)-only validator.
- #95 (high, js/incomplete-sanitization): generate-task-types.ts escaped single
  quotes but not backslashes when embedding task fields in single-quoted TS
  string literals. Add a helper that escapes backslash-first and apply it to
  id/name/department/frequency.
- #80/#81/#84/#85 (medium, actions/missing-workflow-permissions): the two
  Trigger.dev deploy + two DB-migration workflows had no permissions block.
  Add top-level 'permissions: contents: read' (they only check out to build/
  deploy/migrate — no repo writes).

Verified: app typecheck clean for preview.tsx; codegen script typechecks;
all 4 workflow YAMLs valid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): keep currentUrl state in sync when loading a new preview URL

loadNewUrl navigated the iframe imperatively (iframeRef.current.src) without
updating currentUrl, so the external-link href, refresh, and try-again all
referred to the stale previous URL. Drive navigation through setCurrentUrl
instead (the iframe src prop follows currentUrl/safeUrl), keeping every URL
consumer in sync with what's shown — and avoiding a double-load from setting
both iframe.src and the src prop. Same-URL entries still go through
refreshIframe's cache-bust.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/preview/preview.tsx">

<violation number="1" location="apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/preview/preview.tsx:22">
P3: This XSS hardening never runs: `Preview` has no import or render site, so its iframe and `toSafeUrl` are excluded from every automation route. Wire this component into the live preview path, or remove this dead module rather than maintaining a security fix with no runtime effect.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

* `javascript:...` or `data:text/html,...` would execute in the preview context
* (XSS). Returns the normalized href, or undefined if the value isn't http(s).
*/
function toSafeUrl(value: string | undefined | null): string | undefined {

@cubic-dev-ai cubic-dev-ai Bot Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This XSS hardening never runs: Preview has no import or render site, so its iframe and toSafeUrl are excluded from every automation route. Wire this component into the live preview path, or remove this dead module rather than maintaining a security fix with no runtime effect.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/preview/preview.tsx, line 22:

<comment>This XSS hardening never runs: `Preview` has no import or render site, so its iframe and `toSafeUrl` are excluded from every automation route. Wire this component into the live preview path, or remove this dead module rather than maintaining a security fix with no runtime effect.</comment>

<file context>
@@ -13,6 +13,24 @@ interface Props {
+ * `javascript:...` or `data:text/html,...` would execute in the preview context
+ * (XSS). Returns the normalized href, or undefined if the value isn't http(s).
+ */
+function toSafeUrl(value: string | undefined | null): string | undefined {
+  if (!value) return undefined;
+  try {
</file context>
Fix with cubic

tofikwest and others added 2 commits July 15, 2026 14:48
…0 chars (FRAME-2)

HITRUST CSF build-out is blocked because many requirement descriptions run past 70,000 characters and were rejected by the 10,000-char API validation cap. Raise the requirement description limit to 100,000 across every path that carries it — create, update, batch-update, and framework import — via a shared REQUIREMENT_DESCRIPTION_MAX_LENGTH constant so the four DTOs can no longer drift apart.

The DB column is already unbounded `text` and the editor has no client-side limit, so this lifts the ceiling end-to-end. Control, policy, and task template descriptions keep their existing 10,000 cap (out of scope for this ticket).

Tests updated to assert the new 100,000 boundary.
…cription-100k

feat(framework-editor): raise requirement description limit to 100,000 chars (FRAME-2)
@vercel
vercel Bot temporarily deployed to staging – portal July 15, 2026 18:54 Inactive
@vercel
vercel Bot temporarily deployed to staging – app July 15, 2026 18:54 Inactive
@tofikwest
tofikwest merged commit 600f06b into release Jul 15, 2026
14 checks passed
@claudfuen

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.102.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants