Skip to content

v0.9.11: managed mcp optimizations, instrumentation improvements, mammoth parser bump - #8569

Merged
waleedlatif1 merged 6 commits into
mainfrom
staging
Oct 2, 2026
Merged

waleedlatif1 merged 6 commits into
mainfrom
staging

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

…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
@waleedlatif1
waleedlatif1 requested a review from a team as a code owner October 2, 2026 15:47
@vercel

vercel Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
docs Ready Ready Preview Oct 2, 2026 3:49pm UTC

Request Review

Comment thread scripts/check-guidance-refs.ts Dismissed
@greptile-apps

greptile-apps Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

[Medium risk] Documentation and configuration updates across agent skills and rules.

The PR should not merge until normalized chat-upload names resolve unambiguously.

Findings

  1. P1 Upload references can select wrong file ▶

Summary

The PR refreshes agent guidance and audit checks, reuses managed MCP sessions within Search operations, improves chat-upload name resolution and logging, and bumps mammoth. One upload-resolution collision can cause a chat file reference to return the wrong file.

Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A["Two distinct stored chat names"] --> B["Same normalized uploads path"]
  B --> C["Normalized name lookup"]
  C --> D["Newest matching upload returned"]
Loading

Reviews (1) · Last reviewed commit: "fix(deps): bump mammoth to 1.12.3 (#8568..."

Comment thread apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.ts

@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.

15 issues found across 211 files

Confidence score: 3/5

  • managed-mcp.integration.ts returns SECOND_DOCUMENT from search and metadata but fetches a manifest identified as DOCUMENT, so the Lucid reader rejects the second-document integration cases. Make the fetched manifest identity match the searched document.
  • check-zustand-v5-selectors.ts can miss persist calls without a partialize callback and whole-state persistence through destructured rest parameters. Check the persist options for partialize and reject rest-based whole-state selectors.
  • check-application-graph.ts treats 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.ts misses namespace members read through destructuring, such as const { 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 =

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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: 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>
Fix with cubic

Comment on lines +91 to +93
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.

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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: 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>
Suggested change
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.
Fix with cubic

// ✓ Good — omit from deps, mutate is stable
const handler = useCallback(() => {
createEntity.mutate(data)
// eslint-disable-next-line react-hooks/exhaustive-deps

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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: 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>

Comment thread apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.ts
Comment on lines +218 to +221
for (let i = args.length - 1; i >= 0; i--) {
const arg = args[i]
if (arg instanceof Error) return arg
}

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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: 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.)

View Feedback

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>
Suggested change
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
}
Fix with cubic

- **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.

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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: 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>
Suggested change
- **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.
Fix with cubic

- **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`.

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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: 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>
Suggested change
- **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).
Fix with cubic

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

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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: 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>
Fix with cubic


`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`

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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: 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>
Suggested change
`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`
Fix with cubic

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.

@cubic-dev-ai cubic-dev-ai Bot Oct 2, 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 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>
Fix with cubic

@waleedlatif1
waleedlatif1 merged commit bd8be70 into main Oct 2, 2026
76 checks passed

This branch was successfully deployed

1 active deployment
Preview — d00a1d87 Deployed Oct 2, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants