Cloud Agents do not show in Agents' recent Agents sidebar

The mismatch today
Cursor’s workbench.html says:


workbench.html
Lines 58-87
				require-trusted-types-for
					'script'
				;
				trusted-types
					amdLoader
					...
					anysphereUiPolicy
					...
				;
But some workbench code still does things like:

new Function(...) / dynamic eval
element.innerHTML = plainString
trustedTypes.createPolicy(...) without a singleton guard
With require-trusted-types-for 'script' on, 'unsafe-eval' in script-src is not enough. You also need either:

trusted-types-eval in CSP, or
Every script sink to go through a createScript policy, or
Stop using Function / raw-string DOM sinks entirely
Right now Cursor has (1) enforcement ON, (2) partially implemented, (3) not done everywhere.

Fix type A — CSP one-liner (broad, fast, less ideal)
File: out/vs/code/electron-sandbox/workbench/workbench.html

				script-src
					'self'
					'unsafe-eval'
					trusted-types-eval
					blob:
				;
Effect: new Function("...") and eval("...") work again with plain strings even under Trusted Types.

Tradeoff: Weakens the exact protection require-trusted-types-for is trying to provide for code compilation sinks. Fine as a temporary unblock; not a great long-term security posture.

Fix type B — Add createScript policies (proper fix for Function)
Most Cursor/VS Code policies only define createHTML or createScriptURL. Your failing case needs createScript.

Example of what they already do for HTML (good pattern):

// anysphereUiPolicy — only createHTML today
window.trustedTypes.createPolicy("anysphereUiPolicy", {
  createHTML: (html) => html
});
What they’d add for code that compiles strings:

window.trustedTypes.createPolicy("anysphereUiPolicy", {
  createHTML: (html) => html,
  createScript: (script) => script,
});
And at call sites that currently do raw compilation:

 const fn = new Function("return " + expr);
 const policy = getOrCreatePolicy("anysphereUiPolicy", {
   createHTML: s => s,
   createScript: s => s,
 });
 const body = policy.createScript("return " + expr);
 const fn = globalThis.eval(body); // or a shared trustedFunction(...args, body) helper
VS Code already has a central helper (createTrustedTypesPolicy in vs/base/browser/trustedTypes.js) — the diff on Cursor’s side is route new code through it instead of ad-hoc createPolicy / raw sinks.

Angular/VS Code-style helper they’d ideally centralize:

function trustedFunction(...args: string[]): Function {
  const policy = createTrustedTypesPolicy('cursorScript', {
    createScript: (s) => s,
  });
  const paramList = args.slice(0, -1);
  const body = args[args.length - 1];
  const script = policy!.createScript(body);
  const fn = globalThis.eval(script) as Function;
  fn.toString = () => body;
  return fn.bind(globalThis);
}
That’s the “real” fix for the error you reproduced manually.

Fix type C — Stop unsafe fallbacks (subtle bug)
In the bundle, Cursor UI code looks like:

// If policy exists, use it; else write raw string anyway
Tqr ? n.innerHTML = Tqr.createHTML(e) : n.innerHTML = e
Under enforcement, that else branch always throws if policy creation failed — and silently “worked” before TT was strict.

 Tqr ? n.innerHTML = Tqr.createHTML(e) : n.innerHTML = e
 if (!Tqr) throw new Error("anysphereUiPolicy unavailable under Trusted Types enforcement");
 n.innerHTML = Tqr.createHTML(e);
Same idea anywhere they fallback to raw strings “just in case.”

Fix type D — Duplicate policy names (separate known crash)
Forum reports: Policy with name "tokenizeToString" already exists.

They already guard anysphereUiPolicy with a singleton:

if (window.__anysphereUiTrustedTypesPolicy) return window.__anysphereUiTrustedTypesPolicy;
window.__anysphereUiTrustedTypesPolicy = window.trustedTypes.createPolicy(...);
The diff is to apply that everywhere policies are created, especially tokenizeToString (listed twice in CSP already):

 let _tokenizePolicy;
 function getTokenizePolicy() {
   return trustedTypes.createPolicy('tokenizeToString', ...); // throws on 2nd call
   if (_tokenizePolicy) return _tokenizePolicy;
   _tokenizePolicy = createTrustedTypesPolicy('tokenizeToString', { createHTML: s => s });
   return _tokenizePolicy;
 }
Or use 'allow-duplicates' in CSP — worse than singletons.

Fix type E — New Cursor features need CSP allowlist entries
When Background Composer / Cloud Agent / Zod schemas init, any new policy name must be added to workbench.html:

				trusted-types
					...
					shikiWorkerFactory
					cursorComposerScript
					backgroundComposerPolicy
				;
Missing name → createPolicy() throws before any code runs.

What the actual “diff” looks like in practice
For Cursor engineers, it’s not one line — it’s a matrix:

Violation you saw	Cursor-side fix
Function constructor / TrustedScript
Add trusted-types-eval or createScript policy + trustedFunction helper
TrustedHTML on innerHTML
Use existing createHTML policies; remove raw-string fallbacks
createPolicy throws “already exists”
Singleton cache per policy name
createPolicy throws “not allowed”
Add policy name to trusted-types in workbench.html
Third-party lib uses Function internally
Wrap at boundary, swap lib, or trusted-types-eval
Your manual test points to the Function / createScript bucket — very likely in newer Cursor modules (composer, background agent, Zod validation) that VS Code’s upstream workbench didn’t have when the CSP was designed.

What they should not do
Assume 'unsafe-eval' fixes it (you proved it doesn’t)
Disable Trusted Types entirely (big security regression vs VS Code baseline)
Patch only in DevTools/console (user workaround, not a product fix)
Minimal fix vs correct fix
Minimal unblock:

Correct fix:

Add shared trustedFunction / createScript policy
Fix composer/background-agent call sites to use it
Singleton all createPolicy calls
Keep require-trusted-types-for 'script' without trusted-types-eval
If you grab __cspViolations[0].source after reload, we can map it to which of A–E applies first in your build — but from your new Function test, the top item on their fix list is almost certainly B (+ maybe E for a new policy name).

Composer 2.5 proposed the fix :wink:

@stewartmcgown thanks for the detailed write-up, and for testing with --disable-extensions. Since the error still happens with extensions disabled, that confirms it’s not caused by an extension, but by how the build behaves under Trusted Types on a managed device.

It matches what @harryfear is seeing. On a managed Mac, a Trusted Types policy is applied require-trusted-types-for 'script', and it blocks the script sink Function or createScript during composer init. Because of that, init crashes, and the listBackgroundComposers request never gets sent. That’s why the web and mobile agents don’t show up in the sidebar. On unmanaged machines, this policy isn’t applied, so we can’t reproduce the issue there.

We’ve already logged this internally, and I’ll pass your notes about the createScript policy, trusted-types-eval, and the singleton behavior to the team. The specifics really help. I can’t share an ETA yet, but I’ll update the thread as soon as I have news.

From the user side, there’s unfortunately no full workaround here, since the enforcement level is set by MDM. If you can manage the device profile, you can check which policy is forcing Trusted Types enforcement, and loosening it might temporarily unblock the list. But the proper fix still needs to come from our side.