v0.9.11: managed mcp optimizations, instrumentation improvements, mammoth parser bump - #8569
Conversation
waleedlatif1
commented
Oct 2, 2026
- improvement(audits): enforce console, helper, render-path, persist, and deployment-flag rules (improvement(audits): enforce console, helper, render-path, persist, and deployment-flag rules #8559)
- docs(agents): accurate guidance, guardrail map, and check:guidance-refs (docs(agents): accurate guidance, guardrail map, and check:guidance-refs #8557)
- fix(search): reuse managed MCP sessions within operations (fix(search): reuse managed MCP sessions within operations #8567)
- fix(files): resolve chat uploads whose names are not in VFS form (fix(files): resolve chat uploads whose names are not in VFS form #8566)
- fix(logging): name the driver cause and redact bound params in logged errors (fix(logging): name the driver cause and redact bound params in logged errors #8565)
- fix(deps): bump mammoth to 1.12.3 (fix(deps): bump mammoth to 1.12.3 #8568)
…nd deployment-flag rules (#8559) * chore(lint): ban console in runtime code with Biome noConsole Runtime code logs through createLogger from @sim/logger. Scripts, CLIs, script-migrations, the logger itself, SDK examples, and tests keep console as their interface. Autofix is disabled so lint --unsafe never silently deletes a console call. * refactor(utils): replace inline toError, isRecordLike, omit, and truncate idioms with @sim/utils helpers * refactor(ui): lazy-init object refs and use size-* for equal height and width useRef(new X()) built a throwaway X on every render; the refs now lazy-init through ??= as sim-react-performance.md prescribes. Equal h-N w-N pairs become size-N per sim-styling.md. * improvement(audits): extend check:utils to the remaining written idioms Adds toError, isRecordLike, filterUndefined, omit, truncate, and escapeRegExp idioms from CLAUDE.md, plus render-path rules: ES2023 array methods in browser code, useRef(new X()), and h-N w-N pairs. * improvement(audits): require an explicit partialize on every zustand persist sim-stores.md requires persist to whitelist durable fields; check:zustand-v5 now fails on a persist with no partialize or one that spreads the whole state. canvas-mode was the one store without it. * improvement(audits): flag deployment-shape env-flags imports in client settings surfaces check:client-boundary now fails when a 'use client' module under the workspace, organization, or standalone settings surfaces imports isHosted, isBillingEnabled, isChatEnabled, or an enterprise feature flag from env-flags instead of reading the seeded deployment shape. * docs(agents): name the check that enforces the common-utilities list * docs(agents): scope the check:utils note to the forms it bans * perf(audits): gate backreference patterns in check:utils behind literal prefilters The h-N/w-N, toError, and truncate patterns backtrack from every word boundary; a cheap literal test per file keeps the scan at ~1s of CPU. * refactor(ui): lazy-init useRef containers the nested-generic pattern missed Allocate Map/Set ref containers once instead of on every render, and drop the redundant processedRemovalIds alias in the toast provider. * improvement(audits): close detector gaps in check:utils and the deployment-shape rule - check:utils: match useRef(new X()) with nested generics, honor utils-lint-allow above formatter-wrapped statements, drop h-screen/w-screen from the size-N rule, and skip server-only App Router files in the ES2023 rule - deployment-shape rule: cover stores/, hooks/, blocks/ and surface hooks, read namespace imports, derive the flag list from deployment-shape.ts, parse long import clauses whole, and allowlist the panel store's module-init isChatEnabled - zustand persist message names the hoisted-options escape - biome: allow console in *.integration.ts, *.spec.ts, and desktop e2e * improvement(audits): share the directive classifier and simplify check:utils - move leadingDirective/directiveOn into scripts/source-kind.ts; check:utils uses it instead of its own 'use client' regex, and multi-line block-comment headers now parse - replace the deployment-shape allowlist with a client-boundary-allow annotation on the panel store's isChatEnabled import - exempt all of packages/utils/src by prefix (drops the stale retry.test.ts entry) - build both truncate patterns from one shared fragment and prefilter - add literal prefilters to isRecordLike, fromEntries, and useRef patterns and memoize prefilter results per file - trim the deployment-shape rationale to a CLAUDE.md pointer * refactor: drop isRecordLike pass-through wrappers and return audioLevels directly useSpeechToText returns its stable, in-place-filled Float32Array instead of a nullable ref; MicButton and the composer, search, and user-input props follow. * improvement(audits): ban ES2023 array methods repo-wide, catch whole-state partialize, strip inline directive comments * improvement(audits): follow aliased persist imports, require strict !== for filterUndefined, state the .with scope
…fs (#8557) * fix(audits): guard the route wrapper against lib/mothership, not the removed lib/copilot The Copilot modules moved to lib/mothership in the v1.0.0 rename, so the route-wrapper graph guard was banning a directory that no longer exists. * improvement(audits): add check:guidance-refs and fix the stale references it found Agent guidance (CLAUDE.md, every AGENTS.md, .claude/rules, .agents/skills) names paths, scripts, skills, and import specifiers that agents follow literally. The new audit resolves each one and fails on any that no longer exists. Fixes the references it found: lib/copilot -> lib/mothership, stores/workflows/store -> stores/workflows/workflow/store, a relative landing path, deleted selector-provider and legacy landing mentions, and illustrative example imports rewritten as placeholders. * improvement(audits): check rule frontmatter globs in check:guidance-refs A paths glob that matches nothing silently stops the rule from loading. sim-api-contracts still targeted the removed apps/sim/hooks/selectors; drop it, and name check:api-validation:strict as the gate the rule describes. * docs(agents): consolidate guidance and add the local gate to CLAUDE.md - CLAUDE.md: "How your work is checked" (the local gate and a rule-to-check map), sharper comment rules (no narration, restated names, or change history), drop filler, fix the type-check command description. - Rules: one source for the text scale (sim-styling), use-client boundary (sim-queries), testing principles (CLAUDE.md); fix an in-place sort in a list-ordering example and an ESLint directive the repo does not use; drop change-history narration and rotting line-number references. * docs(agents): fix stale facts in connector, model, column-type, and selector skills Verified against the code: fetchWithRetry moved to secure-fetch.server, deletion reconciliation is checkpoint.unsafe (shouldReconcileDeletions is gone), the legacy Search toggle is removed, inline-content connectors may hash content, reasoningEffort/thinking provider lists, column-type metadata update path, check:api-validation:strict as the gate. CLAUDE.md now names the coerceValue switch and relative barrel re-exports as the documented exceptions the code relies on. Selector rules in connector skills point at validate-selector instead of restating it. * docs(agents): fix contradictions and stale facts in platform skills tool-registry-boundary told tests to re-mock a global (check:test-patterns fails that); db-migrate listed a nonexistent annotate rule and omitted the pending-drop-tables contract; permission-group skills cited a removed descriptions record, a nonexistent key-order test, and a single principal-wide capability where there are two; v2-api-conventions cited a removed helper; memory-load-check called a pattern the connectors use cargo-culting. Gates now name check:api-validation:strict / check:audits, ship runs CI's schema/migration sync step, test-audit points at CLAUDE.md instead of copying it, and incident narration became current-state rules. * docs(agents): align UI skills with the settings, emcn, and state rules add-settings-page's audit greps used a pathspec that matches nothing, and its registration steps named types that no longer exist (SETTINGS_SECTION_REGISTRY and SECTION_MODULES are the mechanism). The emcn review taught the legacy Button variants and a destructive Delete chip that sim-settings-pages forbids. The design skills now carry repo precedence notes (no global styles, emcn owns chrome, framer-motion, hover-hover:, fixed fonts and weights). The you-might-not-need-* skills recognize URL state, the list-preference exception, and the Map memo the component rule prescribes. * docs(agents): fix contradictions and stale facts in integration skills Verified against the code: tags live on BlockMeta, not BlockConfig; check-block-registry requires required user-only params to be filled by a subBlock of the same id, so remapping them in tools.config.params fails CI; subblock ids are unique per condition; matchEvent may return a NextResponse; createHmacVerifier needs requireSecret to fail closed; FileToolProcessor is executor-side; provider scopes live in lib/auth/connectors/providers.ts; BYOK needs PROVIDER_SECTIONS; polling crons need the matching docker/crontab line. Duplicated option-list and regenerate sections now point at one copy. * docs(agents): map the new ratchets and lint rules in the guardrail table * docs(agents): correct audit findings in guidance and gate docs Restore the connector byte-cap rule's skip list, list every CI gate step, name the real baseline flags and generated-artifact checks, make api-validation strict-only guidance explicit, pass a base ref to check-block-registry, and teach check:guidance-refs about bun run --cwd. * docs(agents): drop the hand-kept rule-to-check table from CLAUDE.md Name the enforcing check on the rule's own bullet instead, and tighten the Comments bullet. * improvement(audits): share rule frontmatter parsing and fail on dead graph guards check:guidance-refs reuses sync-skills' parseRule, reads workspace manifests once from the root workspaces globs, and matches rule globs against one git listing instead of a filesystem scan per glob (~2.5s to ~0.2s). Markdown links now go through the shared path check. check:application-graph fails when a forbidden prefix matches nothing under apps/sim. * fix(audits): resolve wildcard and root package exports, ignore deleted files and test-only guards check:guidance-refs now requires a bare @sim/<pkg> import to have a '.' export, checks that a wildcard export match maps to an existing file, and drops index entries missing from the working tree before matching rule path globs. check:application-graph no longer counts a leftover test file as keeping a non-directory forbidden prefix alive. * docs(agents): correct review findings in skills and rules Scope SSRF, client-boundary, forcedToolUse, canonicalParamId, integration metadata, and HEAD claims to what the code does; fix the ship migration pathspec, the babysit conflict path, enrichment folder placeholders, framer-motion samples, and stale connector and column-type references. * fix(audits): resolve import specifiers to module files only; tighten review-flagged guidance * docs(agents): keep the repo-wide ES2023 ban in sim-components after rebase * fix(audits): require exact export targets to exist and resolve markdown links strictly * fix(audits): check require() specifiers and keep path resolution inside the repo
* fix(search): reuse managed MCP sessions within operations * fix(search): close acceptance sessions and verify concurrency
* fix(files): resolve chat uploads whose names are not in VFS form * fix(files): match chat upload names exactly in SQL with one bounded row
… errors (#8565) * fix(logging): name the driver cause and redact bound params in logged errors * fix(logging): redact bound params in colorized, nested, and exported errors * fix(logging): report the cause of the error the line reports
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
There was a problem hiding this comment.
15 issues found across 211 files
Confidence score: 3/5
managed-mcp.integration.tsreturnsSECOND_DOCUMENTfrom search and metadata but fetches a manifest identified asDOCUMENT, so the Lucid reader rejects the second-document integration cases. Make the fetched manifest identity match the searched document.check-zustand-v5-selectors.tscan miss persist calls without apartializecallback and whole-state persistence through destructured rest parameters. Check the persist options forpartializeand reject rest-based whole-state selectors.check-application-graph.tstreats integration tests and declaration files as live modules, so they can mask a deleted or renamed guarded runtime module. Exclude those files from the live-module match.check-client-boundary-imports.tsmisses namespace members read through destructuring, such asconst { isHosted } = flags. Detect destructured members so this boundary check cannot be bypassed.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/sim/lib/sim-search/live/managed-mcp.integration.ts">
<violation number="1" location="apps/sim/lib/sim-search/live/managed-mcp.integration.ts:120">
P2: The fixture returns `SECOND_DOCUMENT` from search and metadata but identifies every fetched manifest as `DOCUMENT`; the Lucid reader rejects that identity mismatch, causing the second-document integration cases to fail. Derive the fetch manifest identity from the requested `id`.</violation>
</file>
<file name=".claude/rules/sim-url-state.md">
<violation number="1" location=".claude/rules/sim-url-state.md:17">
P3: Condensing the decision bullets into the table dropped the only reference to `.claude/rules/sim-queries.md` in this file (the removed "React Query → server/remote data. Unchanged; see sim-queries.md" bullet). The doc set keeps reciprocal pointers between these rules (sim-queries.md:11 points back to sim-url-state.md, sim-api-contracts.md and sim-hooks.md point at sim-queries.md), so readers/agents now lose the route to the authoritative React Query rule. Re-add the cross-reference, e.g. in the React Query row or the intro sentence.</violation>
</file>
<file name=".agents/skills/add-block-preview/SKILL.md">
<violation number="1" location=".agents/skills/add-block-preview/SKILL.md:56">
P3: `lib/integrations/tool-catalog.ts` is not resolvable from the repo root where this doc lives; the file is at `apps/sim/lib/integrations/tool-catalog.ts` (imported in code as `@/lib/integrations/tool-catalog.ts`). Every sibling reference in this file uses the full `apps/sim/...` prefix — align the path so an agent following the guidance can find the file.</violation>
</file>
<file name=".cursor/rules/sim-styling.mdc">
<violation number="1" location=".cursor/rules/sim-styling.mdc:98">
P3: The `See .../usage-limit-field.tsx` reference no longer demonstrates the `inputClassName` example: the file uses `<ChipInput inputMode='numeric' />` and contains no `inputClassName`, `font-mono`, or number-spinner reset (also true at pr-base). Drop the pointer or update it to a file that actually uses the prop, otherwise the example it is meant to illustrate is not there.</violation>
</file>
<file name=".agents/skills/babysit/SKILL.md">
<violation number="1" location=".agents/skills/babysit/SKILL.md:91">
P2: Step 6's sync check only rebases when `git log origin/staging..HEAD` shows unrecognized commits (`/ship` step 2: "If it shows commits you don't recognize, fix it now... Try `git rebase origin/staging` first"). A PR that conflicts purely because staging advanced carries only this session's recognizable commits, so following this pointer to step 6 runs no rebase and the conflict is never resolved — step 7 then has nothing new to push and step 8 re-triggers reviewers on a still-`CONFLICTING` branch, repeating until step 10's two-round stop condition surfaces it to the user. State the resolution action explicitly: rebase onto `origin/staging`, resolve, and `git rebase --continue` before running the gates.</violation>
</file>
<file name=".cursor/rules/sim-queries.mdc">
<violation number="1" location=".cursor/rules/sim-queries.mdc:144">
P2: Removing this `eslint-disable-next-line react-hooks/exhaustive-deps` leaves the "✓ Good" example failing the lint rule it documents: `useCallback` referencing `createEntity` with deps `[data]` reports a missing dependency. The repo's own usage of this exact pattern (e.g. `apps/sim/app/workspace/[workspaceId]/tables/tables.tsx` uses `// eslint-disable-next-line react-hooks/exhaustive-deps -- mutation objects are unstable; mutate is stable in v5`) shows the disable comment is required, so the doc now presents code that cannot be committed verbatim cleanly. Restore the comment (with the explanatory annotation) or address the lint trigger explicitly.</violation>
</file>
<file name=".agents/skills/add-settings-page/SKILL.md">
<violation number="1" location=".agents/skills/add-settings-page/SKILL.md:50">
P3: The listed expected match `CredentialDetailLayout` can never appear in this grep's results: credential-detail-layout.tsx lives at workspace `components/credential-detail/...`, outside both `'apps/sim/**/settings/**'` and `'apps/sim/ee/'`. Drop it from the expected-match list (or widen the pathspec to actually include it), and rephrase so it doesn't clash with 'A detail sub-view is never a match' — the point is that it is exempt because it hand-rolls the shell, not because it is a grep match.</violation>
</file>
<file name=".claude/rules/sim-settings-pages.md">
<violation number="1" location=".claude/rules/sim-settings-pages.md:96">
P3: Not every `SETTINGS_SECTION_REGISTRY` entry carries a `description`: the field lives on the optional `unified` projection (`SettingsSectionRegistryEntry` only declares `label`, `icon`, `docsLink`, `unified?`, `planes?`), and two entries (`Chat keys`, `Recently deleted`) have no `unified` at all. The next hunk of this same change already uses the correct contract (`label` and `unified.description`); align this sentence with it so agents don't force a `unified.description` onto standalone-plane entries.</violation>
</file>
<file name="packages/logger/src/index.ts">
<violation number="1" location="packages/logger/src/index.ts:218">
P2: The reverse scan makes OTel attributes select the last bare error, so calls with multiple errors export the wrong primary exception. Iterate `args` in order while retaining the existing `{ error }` fallback.
(Based on your team's feedback about OTel primary-error selection.)</violation>
</file>
<file name="scripts/check-application-graph.ts">
<violation number="1" location="scripts/check-application-graph.ts:298">
P2: `prefixMatchesAnything` treats `*.integration.ts` and declaration files as live modules. A renamed or deleted guarded runtime module can therefore leave only test or type files and still bypass the dead-prefix failure; exclude those suffixes alongside `.test.ts`.</violation>
</file>
<file name="scripts/check-zustand-v5-selectors.ts">
<violation number="1" location="scripts/check-zustand-v5-selectors.ts:319">
P2: `hasPartialize` can be satisfied by a state member or storage name, allowing a persist call without a `partialize` callback to bypass the audit. Check the second/options argument for the `partialize` property before treating the call as compliant.</violation>
<violation number="2" location="scripts/check-zustand-v5-selectors.ts:322">
P2: The whole-state check misses destructured rest parameters, so `partialize: ({ ...state }) => ({ ...state })` and its block-body equivalent pass despite persisting every field and action. Extend the check to reject destructured-rest callbacks that return the rest object.
(Based on your team's feedback about rejecting whole-state partializers.)</violation>
</file>
<file name="scripts/check-client-boundary-imports.ts">
<violation number="1" location="scripts/check-client-boundary-imports.ts:106">
P2: Namespace destructuring bypasses this check: `envFlagReads` only recognizes `flags.name`, so `const { isHosted } = flags` is never reported. Detect destructured namespace members too.</violation>
</file>
<file name="scripts/check-utils-enforcement.ts">
<violation number="1" location="scripts/check-utils-enforcement.ts:149">
P2: The `.with` check only matches numeric literal indexes, so `items.with(index, nextValue)` bypasses this array-method ban. Detect variable-index array calls without flagging non-array `context.with()` methods.</violation>
</file>
<file name=".agents/skills/add-integration/SKILL.md">
<violation number="1" location=".agents/skills/add-integration/SKILL.md:135">
P3: This points authors to conflicting canonical-ID rules: the `add-block` skill forbids matching any subblock ID, while this guidance and `sim-integrations.md` allow a group member to share it. Synchronize the referenced `add-block` rule so authors do not reject valid pairs or follow the wrong constraint.</violation>
</file>
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Tip: instead of fixing issues one by one fix them all with cubic
Re-trigger cubic
| protocol.setRequestHandler(CallToolRequestSchema, async ({ params }) => { | ||
| events.push({ method: params.name, actor, at: performance.now() }) | ||
| await onTool?.(params.name, params.arguments ?? {}) | ||
| const documentId = |
There was a problem hiding this comment.
P2: The fixture returns SECOND_DOCUMENT from search and metadata but identifies every fetched manifest as DOCUMENT; the Lucid reader rejects that identity mismatch, causing the second-document integration cases to fail. Derive the fetch manifest identity from the requested id.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At apps/sim/lib/sim-search/live/managed-mcp.integration.ts, line 120:
<comment>The fixture returns `SECOND_DOCUMENT` from search and metadata but identifies every fetched manifest as `DOCUMENT`; the Lucid reader rejects that identity mismatch, causing the second-document integration cases to fail. Derive the fetch manifest identity from the requested `id`.</comment>
<file context>
@@ -0,0 +1,677 @@
+ protocol.setRequestHandler(CallToolRequestSchema, async ({ params }) => {
+ events.push({ method: params.name, actor, at: performance.now() })
+ await onTool?.(params.name, params.arguments ?? {})
+ const documentId =
+ params.arguments?.query === 'second topology' ||
+ params.arguments?.document_id === SECOND_DOCUMENT
</file context>
| 2. **If the PR has a merge conflict**, resolve it with step 6 (its rebase-based sync flow and | ||
| the `/ship` gates; a merge commit would be discarded by that rebase), then steps 7–8: push | ||
| with `--force-with-lease` and re-trigger review. |
There was a problem hiding this comment.
P2: Step 6's sync check only rebases when git log origin/staging..HEAD shows unrecognized commits (/ship step 2: "If it shows commits you don't recognize, fix it now... Try git rebase origin/staging first"). A PR that conflicts purely because staging advanced carries only this session's recognizable commits, so following this pointer to step 6 runs no rebase and the conflict is never resolved — step 7 then has nothing new to push and step 8 re-triggers reviewers on a still-CONFLICTING branch, repeating until step 10's two-round stop condition surfaces it to the user. State the resolution action explicitly: rebase onto origin/staging, resolve, and git rebase --continue before running the gates.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .agents/skills/babysit/SKILL.md, line 91:
<comment>Step 6's sync check only rebases when `git log origin/staging..HEAD` shows unrecognized commits (`/ship` step 2: "If it shows commits you don't recognize, fix it now... Try `git rebase origin/staging` first"). A PR that conflicts purely because staging advanced carries only this session's recognizable commits, so following this pointer to step 6 runs no rebase and the conflict is never resolved — step 7 then has nothing new to push and step 8 re-triggers reviewers on a still-`CONFLICTING` branch, repeating until step 10's two-round stop condition surfaces it to the user. State the resolution action explicitly: rebase onto `origin/staging`, resolve, and `git rebase --continue` before running the gates.</comment>
<file context>
@@ -88,8 +88,9 @@ conditions freshly after every push.
-2. **If the PR has a merge conflict**, merge `origin/staging`, resolve the conflicts, run the
- usual pre-push checks, push, and go to step 8 to re-trigger review.
+2. **If the PR has a merge conflict**, resolve it with step 6 (its rebase-based sync flow and
+ the `/ship` gates; a merge commit would be discarded by that rebase), then steps 7–8: push
+ with `--force-with-lease` and re-trigger review.
</file context>
| 2. **If the PR has a merge conflict**, resolve it with step 6 (its rebase-based sync flow and | |
| the `/ship` gates; a merge commit would be discarded by that rebase), then steps 7–8: push | |
| with `--force-with-lease` and re-trigger review. | |
| 2. **If the PR has a merge conflict**, run `git rebase origin/staging`, resolve the conflicts, and | |
| `git rebase --continue` (this is step 6's rebase-based sync flow — a merge commit would be | |
| discarded by that rebase), then run step 6's `/ship` gates and steps 7–8: push with | |
| `--force-with-lease` and re-trigger review. |
| // ✓ Good — omit from deps, mutate is stable | ||
| const handler = useCallback(() => { | ||
| createEntity.mutate(data) | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps |
There was a problem hiding this comment.
P2: Removing this eslint-disable-next-line react-hooks/exhaustive-deps leaves the "✓ Good" example failing the lint rule it documents: useCallback referencing createEntity with deps [data] reports a missing dependency. The repo's own usage of this exact pattern (e.g. apps/sim/app/workspace/[workspaceId]/tables/tables.tsx uses // eslint-disable-next-line react-hooks/exhaustive-deps -- mutation objects are unstable; mutate is stable in v5) shows the disable comment is required, so the doc now presents code that cannot be committed verbatim cleanly. Restore the comment (with the explanatory annotation) or address the lint trigger explicitly.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .cursor/rules/sim-queries.mdc, line 144:
<comment>Removing this `eslint-disable-next-line react-hooks/exhaustive-deps` leaves the "✓ Good" example failing the lint rule it documents: `useCallback` referencing `createEntity` with deps `[data]` reports a missing dependency. The repo's own usage of this exact pattern (e.g. `apps/sim/app/workspace/[workspaceId]/tables/tables.tsx` uses `// eslint-disable-next-line react-hooks/exhaustive-deps -- mutation objects are unstable; mutate is stable in v5`) shows the disable comment is required, so the doc now presents code that cannot be committed verbatim cleanly. Restore the comment (with the explanatory annotation) or address the lint trigger explicitly.</comment>
<file context>
@@ -141,7 +141,6 @@ const handler = useCallback(() => {
const handler = useCallback(() => {
createEntity.mutate(data)
- // eslint-disable-next-line react-hooks/exhaustive-deps
}, [data])
</file context>
</details>
<a href="https://www.cubic.dev/action/fix/violation/5a275cb7-1503-4197-8c7c-5c672cc85d35" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://cubic.dev/buttons/fix-with-cubic-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://cubic.dev/buttons/fix-with-cubic-light.svg">
<img alt="Fix with cubic" src="https://cubic.dev/buttons/fix-with-cubic-dark.svg">
</picture>
</a>
| for (let i = args.length - 1; i >= 0; i--) { | ||
| const arg = args[i] | ||
| if (arg instanceof Error) return arg | ||
| } |
There was a problem hiding this comment.
P2: The reverse scan makes OTel attributes select the last bare error, so calls with multiple errors export the wrong primary exception. Iterate args in order while retaining the existing { error } fallback.
(Based on your team's feedback about OTel primary-error selection.)
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/logger/src/index.ts, line 218:
<comment>The reverse scan makes OTel attributes select the last bare error, so calls with multiple errors export the wrong primary exception. Iterate `args` in order while retaining the existing `{ error }` fallback.
(Based on your team's feedback about OTel primary-error selection.) </comment>
<file context>
@@ -131,55 +132,105 @@ const getLogConfig = () => {
+ * `Error` argument, else the first `{ error }` field.
+ */
+const primaryError = (args: unknown[]): Error | undefined => {
+ for (let i = args.length - 1; i >= 0; i--) {
+ const arg = args[i]
+ if (arg instanceof Error) return arg
</file context>
| for (let i = args.length - 1; i >= 0; i--) { | |
| const arg = args[i] | |
| if (arg instanceof Error) return arg | |
| } | |
| for (const arg of args) { | |
| if (arg instanceof Error) return arg | |
| } |
| - **Keys are registry block types.** Never `custom_block_*` (parse drops them — custom blocks have their own enabled/disabled lifecycle). | ||
| - **The shared hidden-predicate is `isHiddenUnder`** (`apps/sim/blocks/visibility/context.ts`). Never restate the preview/disabled rule inline at a new consumer. | ||
| - **Process-global caches stay ungated.** `getStaticComponentFiles` (VFS) and `getExposedIntegrationTools` build the ungated universe; per-viewer filtering happens at stamp/consumer time. Never move gating into a shared builder. | ||
| - **Process-global caches stay ungated.** Shared builders such as `getExposedIntegrationTools` (`lib/integrations/tool-catalog.ts`) build the ungated universe; per-viewer filtering happens at consumer time via `isHiddenUnder`. Never move gating into a shared builder. |
There was a problem hiding this comment.
P3: lib/integrations/tool-catalog.ts is not resolvable from the repo root where this doc lives; the file is at apps/sim/lib/integrations/tool-catalog.ts (imported in code as @/lib/integrations/tool-catalog.ts). Every sibling reference in this file uses the full apps/sim/... prefix — align the path so an agent following the guidance can find the file.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .agents/skills/add-block-preview/SKILL.md, line 56:
<comment>`lib/integrations/tool-catalog.ts` is not resolvable from the repo root where this doc lives; the file is at `apps/sim/lib/integrations/tool-catalog.ts` (imported in code as `@/lib/integrations/tool-catalog.ts`). Every sibling reference in this file uses the full `apps/sim/...` prefix — align the path so an agent following the guidance can find the file.</comment>
<file context>
@@ -53,7 +53,7 @@ To pull an already-GA block from discovery surfaces on hosted (incident, depreca
- **Keys are registry block types.** Never `custom_block_*` (parse drops them — custom blocks have their own enabled/disabled lifecycle).
- **The shared hidden-predicate is `isHiddenUnder`** (`apps/sim/blocks/visibility/context.ts`). Never restate the preview/disabled rule inline at a new consumer.
-- **Process-global caches stay ungated.** `getStaticComponentFiles` (VFS) and `getExposedIntegrationTools` build the ungated universe; per-viewer filtering happens at stamp/consumer time. Never move gating into a shared builder.
+- **Process-global caches stay ungated.** Shared builders such as `getExposedIntegrationTools` (`lib/integrations/tool-catalog.ts`) build the ungated universe; per-viewer filtering happens at consumer time via `isHiddenUnder`. Never move gating into a shared builder.
- Gating is **surface hiding, not secrecy** — the full config ships in the client JS bundle. Anything truly secret cannot be a registered block.
</file context>
| - **Process-global caches stay ungated.** Shared builders such as `getExposedIntegrationTools` (`lib/integrations/tool-catalog.ts`) build the ungated universe; per-viewer filtering happens at consumer time via `isHiddenUnder`. Never move gating into a shared builder. | |
| **Process-global caches stay ungated.** Shared builders such as `getExposedIntegrationTools` (`apps/sim/lib/integrations/tool-catalog.ts`) build the ungated universe; per-viewer filtering happens at consumer time via `isHiddenUnder`. Never move gating into a shared builder. |
| - **Trailing buttons** (reveal/copy/fetch) → `endAdornment`. | ||
| - **Inner-input styling** (e.g. `font-mono`, number-spinner reset) → `inputClassName` (ChipInput only). See `app/workspace/[workspaceId]/settings/components/billing/components/usage-limit-field/usage-limit-field.tsx:117`. | ||
| - **`ChipModalField` controls take NO className.** Pass `title`/`value`/`onChange`/`error`/`hint`/`required`/`flush`. The field owns label, control, and error/hint rendering. See `app/workspace/[workspaceId]/skills/components/skill-modal/skill-modal.tsx:170`. | ||
| - **Inner-input styling** (e.g. `font-mono`, number-spinner reset) → `inputClassName` (ChipInput only). See `app/workspace/[workspaceId]/settings/components/billing/components/usage-limit-field/usage-limit-field.tsx`. |
There was a problem hiding this comment.
P3: The See .../usage-limit-field.tsx reference no longer demonstrates the inputClassName example: the file uses <ChipInput inputMode='numeric' /> and contains no inputClassName, font-mono, or number-spinner reset (also true at pr-base). Drop the pointer or update it to a file that actually uses the prop, otherwise the example it is meant to illustrate is not there.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .cursor/rules/sim-styling.mdc, line 98:
<comment>The `See .../usage-limit-field.tsx` reference no longer demonstrates the `inputClassName` example: the file uses `<ChipInput inputMode='numeric' />` and contains no `inputClassName`, `font-mono`, or number-spinner reset (also true at pr-base). Drop the pointer or update it to a file that actually uses the prop, otherwise the example it is meant to illustrate is not there.</comment>
<file context>
@@ -95,19 +95,19 @@ Draw a line with a real `border-*` utility. Never hand-roll one as `shadow-[inse
- **Trailing buttons** (reveal/copy/fetch) → `endAdornment`.
-- **Inner-input styling** (e.g. `font-mono`, number-spinner reset) → `inputClassName` (ChipInput only). See `app/workspace/[workspaceId]/settings/components/billing/components/usage-limit-field/usage-limit-field.tsx:117`.
-- **`ChipModalField` controls take NO className.** Pass `title`/`value`/`onChange`/`error`/`hint`/`required`/`flush`. The field owns label, control, and error/hint rendering. See `app/workspace/[workspaceId]/skills/components/skill-modal/skill-modal.tsx:170`.
+- **Inner-input styling** (e.g. `font-mono`, number-spinner reset) → `inputClassName` (ChipInput only). See `app/workspace/[workspaceId]/settings/components/billing/components/usage-limit-field/usage-limit-field.tsx`.
+- **`ChipModalField` controls take NO className.** Pass `title`/`value`/`onChange`/`error`/`hint`/`required`/`flush`. The field owns label, control, and error/hint rendering. See `app/workspace/[workspaceId]/skills/components/skill-modal/skill-modal.tsx`.
</file context>
| - **Inner-input styling** (e.g. `font-mono`, number-spinner reset) → `inputClassName` (ChipInput only). See `app/workspace/[workspaceId]/settings/components/billing/components/usage-limit-field/usage-limit-field.tsx`. | |
| - **Inner-input styling** (e.g. `font-mono`, number-spinner reset) → `inputClassName` (ChipInput only). |
| 4. Confirm each page imports `SettingsPanel` and that its `NavigationItem` has an | ||
| `git grep -n "flex h-full flex-col bg-\[var(--bg)\]" -- 'apps/sim/**/settings/**' 'apps/sim/ee/'` | ||
| — expected matches: the workspace and organization `settings/layout.tsx` shells, the shared | ||
| header shell (`components/settings/settings-header.tsx`), `CredentialDetailLayout` (the |
There was a problem hiding this comment.
P3: The listed expected match CredentialDetailLayout can never appear in this grep's results: credential-detail-layout.tsx lives at workspace components/credential-detail/..., outside both 'apps/sim/**/settings/**' and 'apps/sim/ee/'. Drop it from the expected-match list (or widen the pathspec to actually include it), and rephrase so it doesn't clash with 'A detail sub-view is never a match' — the point is that it is exempt because it hand-rolls the shell, not because it is a grep match.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .agents/skills/add-settings-page/SKILL.md, line 50:
<comment>The listed expected match `CredentialDetailLayout` can never appear in this grep's results: credential-detail-layout.tsx lives at workspace `components/credential-detail/...`, outside both `'apps/sim/**/settings/**'` and `'apps/sim/ee/'`. Drop it from the expected-match list (or widen the pathspec to actually include it), and rephrase so it doesn't clash with 'A detail sub-view is never a match' — the point is that it is exempt because it hand-rolls the shell, not because it is a grep match.</comment>
<file context>
@@ -21,65 +21,58 @@ Key paths:
-4. Confirm each page imports `SettingsPanel` and that its `NavigationItem` has an
+ `git grep -n "flex h-full flex-col bg-\[var(--bg)\]" -- 'apps/sim/**/settings/**' 'apps/sim/ee/'`
+ — expected matches: the workspace and organization `settings/layout.tsx` shells, the shared
+ header shell (`components/settings/settings-header.tsx`), `CredentialDetailLayout` (the
+ `settings/secrets/[credentialId]` exception), or an entitlement/loading gate. A detail
+ sub-view is never a match: it passes `back={{ text, icon: ArrowLeft, onSelect }}` to
</file context>
|
|
||
| `apps/sim/components/settings/navigation.ts` is the single source of truth (the | ||
| `settings/navigation.ts` in the route tree is only a re-export shim). Every `NavigationItem` carries a one-line `description`; `SettingsPanel` | ||
| `settings/navigation.ts` in the route tree is only a re-export shim). Every `SETTINGS_SECTION_REGISTRY` entry carries a one-line `description`; `SettingsPanel` |
There was a problem hiding this comment.
P3: Not every SETTINGS_SECTION_REGISTRY entry carries a description: the field lives on the optional unified projection (SettingsSectionRegistryEntry only declares label, icon, docsLink, unified?, planes?), and two entries (Chat keys, Recently deleted) have no unified at all. The next hunk of this same change already uses the correct contract (label and unified.description); align this sentence with it so agents don't force a unified.description onto standalone-plane entries.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .claude/rules/sim-settings-pages.md, line 96:
<comment>Not every `SETTINGS_SECTION_REGISTRY` entry carries a `description`: the field lives on the optional `unified` projection (`SettingsSectionRegistryEntry` only declares `label`, `icon`, `docsLink`, `unified?`, `planes?`), and two entries (`Chat keys`, `Recently deleted`) have no `unified` at all. The next hunk of this same change already uses the correct contract (`label` and `unified.description`); align this sentence with it so agents don't force a `unified.description` onto standalone-plane entries.</comment>
<file context>
@@ -93,17 +93,17 @@ return (
`apps/sim/components/settings/navigation.ts` is the single source of truth (the
-`settings/navigation.ts` in the route tree is only a re-export shim). Every `NavigationItem` carries a one-line `description`; `SettingsPanel`
+`settings/navigation.ts` in the route tree is only a re-export shim). Every `SETTINGS_SECTION_REGISTRY` entry carries a one-line `description`; `SettingsPanel`
resolves both via `getSettingsSectionMeta(plane, section)` and the
`SettingsSectionProvider` the settings shell wraps around the active section.
</file context>
| `settings/navigation.ts` in the route tree is only a re-export shim). Every `SETTINGS_SECTION_REGISTRY` entry carries a one-line `description`; `SettingsPanel` | |
| `settings/navigation.ts` in the route tree is only a re-export shim). Every `SETTINGS_SECTION_REGISTRY` entry with a `unified` projection carries a one-line `unified.description`; `SettingsPanel` |
| survives serialization, so `inputs` and `tools.config.params` reference the canonical id, never the | ||
| subblock ids. It is unique block-wide, and every member of a group shares the same `required` value. | ||
| - Basic/advanced pairs use a `canonicalParamId`; its constraints are in | ||
| `.claude/rules/sim-integrations.md` and the `add-block` skill → canonicalParamId Pattern. |
There was a problem hiding this comment.
P3: This points authors to conflicting canonical-ID rules: the add-block skill forbids matching any subblock ID, while this guidance and sim-integrations.md allow a group member to share it. Synchronize the referenced add-block rule so authors do not reject valid pairs or follow the wrong constraint.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .agents/skills/add-integration/SKILL.md, line 135:
<comment>This points authors to conflicting canonical-ID rules: the `add-block` skill forbids matching any subblock ID, while this guidance and `sim-integrations.md` allow a group member to share it. Synchronize the referenced `add-block` rule so authors do not reject valid pairs or follow the wrong constraint.</comment>
<file context>
@@ -128,13 +128,11 @@ Three rules that are easy to get wrong when copying from existing blocks:
- survives serialization, so `inputs` and `tools.config.params` reference the canonical id, never the
- subblock ids. It is unique block-wide, and every member of a group shares the same `required` value.
+- Basic/advanced pairs use a `canonicalParamId`; its constraints are in
+ `.claude/rules/sim-integrations.md` and the `add-block` skill → canonicalParamId Pattern.
- Every text-entry subBlock (`short-input`, `long-input`, `code`) and every selector declares a
`placeholder`; an empty box tells the user nothing. Secrets read `Enter your {thing}` (e.g.
</file context>