GitHub check
256 KB of 597 KB loaded Download the full log (597 KB)
341 KB of earlier output not loaded
15.5757298Z β react(purity): Cannot call impure function during render
ββ[apps/web/src/components/CustomSnoozeDialog.tsx:140:58]
139 β {...(weekStartsOn === undefined ? {} : { weekStartsOn })}
140 β disabled={{ before: new Date(new Date().setHours(0, 0, 0, 0)) }}
Β· ββββββ¬ββββ
Β· β°ββ Cannot call impure function
141 β onSelect={(selected) => {
β°ββββ
help: `Date` is an impure function. Calling an impure function can produce unstable results that update unpredictably when the component re-renders
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/purity
β react(no-array-index-key): Usage of Array index in keys is not allowed
ββ[apps/web/src/components/pullRequest/PullRequestChecksPopover.tsx:88:15]
87 β <li
88 β key={`${index}:${check.name}`}
Β· ββββββββββββββββββββββββββββββ
89 β className="col-span-full grid grid-cols-subgrid items-center text-xs"
β°ββββ
help: Use a unique data-dependent key to avoid unnecessary rerenders
β t3code(no-inline-schema-compile): Hoist Schema.encodeEffect(...) to module scope: both the inline schema literal and the compiled function are rebuilt on every call. Move the compiled function to a module-level const.
ββ[apps/server/src/serverSettings.test.ts:1741:32]
1740 β const model = createModelSelection(ProviderInstanceId.make("codex"), "gpt-5.5");
1741 β const modelJson = yield* Schema.encodeEffect(Schema.fromJsonString(ModelSelection))(model);
Β· βββββββββββββββββββ
1742 β const scriptsJson = yield* Schema.encodeEffect(
β°ββββ
β t3code(no-inline-schema-compile): Hoist Schema.encodeEffect(...) to module scope: both the inline schema literal and the compiled function are rebuilt on every call. Move the compiled function to a module-level const.
ββ[apps/server/src/serverSettings.test.ts:1742:34]
1741 β const modelJson = yield* Schema.encodeEffect(Schema.fromJsonString(ModelSelection))(model);
1742 β const scriptsJson = yield* Schema.encodeEffect(
Β· βββββββββββββββββββ
1743 β Schema.fromJsonString(Schema.Array(ProjectScript)),
β°ββββ
β eslint(no-unused-vars): Variable 'layerTest' is declared but never used. Unused variables should start with a '_'.
ββ[apps/server/src/telemetry/AnalyticsService.ts:340:7]
339 β
340 β const layerTest = AnalyticsService.layerTest;
Β· βββββ¬ββββ
Β· β°ββ 'layerTest' is declared here
β°ββββ
help: Consider removing this declaration.
β eslint(no-unused-vars): Variable 'layer' is declared but never used. Unused variables should start with a '_'.
ββ[apps/server/src/orchestration-v2/ThreadPullRequestService.ts:413:7]
412 β
413 β const layer = Layer.effect(ThreadPullRequestServiceV2, make);
Β· βββ¬ββ
Β· β°ββ 'layer' is declared here
β°ββββ
help: Consider removing this declaration.
β unicorn(no-array-reverse): Use `Array#toReversed()` instead of `Array#reverse()`.
ββ[apps/web/src/lib/composerContextReferences.ts:90:40]
89 β let cursor = prompt.length;
90 β for (const occurrence of occurrences.reverse()) {
Β· βββββββ
91 β let { start, end } = occurrence;
β°ββββ
help: `Array#reverse()` mutates the original array. Use `Array#toReversed()` to return a new reversed array without modifying the original.
β eslint(no-unused-vars): Variable 'layerUnavailable' is declared but never used. Unused variables should start with a '_'.
ββ[apps/server/src/orchestration-v2/Orchestrator.ts:12340:7]
12339 β
12340 β const layerUnavailable: Layer.Layer<OrchestratorV2> = Layer.succeed(
Β· βββββββββ¬βββββββ
Β· β°ββ 'layerUnavailable' is declared here
12341 β OrchestratorV2,
β°ββββ
help: Consider removing this declaration.
β eslint(no-unused-vars): Parameter '_' is declared but never used.
ββ[apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts:555:70]
554 β assert.deepStrictEqual(
555 β (yield* Ref.get(fixture.syncCommands)).map(({ commandId: _, ...rest }) => rest),
Β· β¬
Β· β°ββ '_' is declared here
556 β [
β°ββββ
help: Consider removing this parameter.
β eslint(no-unused-vars): Parameter '_' is declared but never used.
ββ[apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts:1155:70]
1154 β assert.deepStrictEqual(
1155 β (yield* Ref.get(fixture.linkCommands)).map(({ commandId: _, ...rest }) => rest),
Β· β¬
Β· β°ββ '_' is declared here
1156 β [
β°ββββ
help: Consider removing this parameter.
β eslint(no-unused-vars): Variable 'layerDaemon' is declared but never used. Unused variables should start with a '_'.
ββ[apps/server/src/orchestration-v2/EffectWorker.ts:914:7]
913 β
914 β const layerDaemon: Layer.Layer<never, never, OrchestrationEffectWorkerV2> = Layer.effectDiscard(
Β· ββββββ¬βββββ
Β· β°ββ 'layerDaemon' is declared here
915 β runDaemon.pipe(Effect.forkScoped),
β°ββββ
help: Consider removing this declaration.
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/thread-work-log.tsx:174:5]
170 β const expandedAngle = props.collapsedDirection === "right" ? 90 : 180;
171 β const rotation = useSharedValue(props.expanded ? expandedAngle : 0);
Β· βββββ¬βββ
Β· β°ββ `rotation` originates here
172 β
173 β useLayoutEffect(() => {
174 β rotation.value = withTiming(props.expanded ? expandedAngle : 0, {
Β· βββββ¬βββ
Β· β°ββ `rotation` cannot be modified
175 β duration: THREAD_DISCLOSURE_TRANSITION_MS,
β°ββββ
help: Modifying a value returned from a hook is not allowed. Consider moving the modification into the hook where the value is constructed
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(no-array-index-key): Usage of Array index in keys is not allowed
ββ[apps/mobile/src/features/threads/thread-work-log.tsx:1246:23]
1245 β <Text
1246 β key={`${index}:${line}`}
Β· ββββββββββββββββββββββββ
1247 β selectable
β°ββββ
help: Use a unique data-dependent key to avoid unnecessary rerenders
β react(purity): Cannot call impure function during render
ββ[apps/mobile/src/features/threads/thread-list-v2-items.tsx:697:76]
696 β const [snoozeGateClock, setSnoozeGateClock] = useState(() => ({ thread, now: Date.now() }));
697 β if (snoozeGateClock.thread !== thread) setSnoozeGateClock({ thread, now: Date.now() });
Β· ββββββ¬ββββ
Β· β°ββ Cannot call impure function
698 β const snoozeGateNow = new Date(snoozeGateClock.now).toISOString();
β°ββββ
help: `Date.now` is an impure function. Calling an impure function can produce unstable results that update unpredictably when the component re-renders
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/purity
β react(purity): Cannot call impure function during render
ββ[apps/mobile/src/features/threads/thread-list-v2-items.tsx:718:71]
717 β const snoozePresets = useMemo(
718 β () => (swipeActions.secondary === "snooze" ? resolveSnoozePresets(new Date()) : ([] as const)),
Β· ββββββ¬ββββ
Β· β°ββ Cannot call impure function
719 β [props.snoozePresetMinute, swipeActions.secondary],
β°ββββ
help: `Date` is an impure function. Calling an impure function can produce unstable results that update unpredictably when the component re-renders
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/purity
β react(memo-dependencies): Found extra memoization dependencies
ββ[apps/mobile/src/features/threads/thread-list-v2-items.tsx:719:6]
718 β () => (swipeActions.secondary === "snooze" ? resolveSnoozePresets(new Date()) : ([] as const)),
719 β [props.snoozePresetMinute, swipeActions.secondary],
Β· βββββββββββββ¬βββββββββββ
Β· β°ββ Unnecessary dependency `props.snoozePresetMinute`
720 β );
β°ββββ
help: Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(memo-dependencies): Found extra memoization dependencies
ββ[apps/mobile/src/features/threads/thread-list-v2-items.tsx:765:7]
764 β thread.pinnedAt,
765 β variant,
Β· ββββ¬βββ
Β· β°ββ Unnecessary dependency `variant`
766 β ],
β°ββββ
help: Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(no-array-index-key): Usage of Array index in keys is not allowed
ββ[apps/mobile/src/features/threads/thread-list-v2-items.tsx:1215:21]
1214 β {providerDrivers.slice(0, -1).map((driver, index) => (
1215 β <View key={`${driver}:${index}`} className="-mr-1 opacity-30">
Β· ββββββββββββββββββββββββββ
1216 β <ProviderIcon provider={driver} size={12} />
β°ββββ
help: Use a unique data-dependent key to avoid unnecessary rerenders
β t3code(no-polling-loop-in-tests): Polling loop in a test. Spinning on `yieldNow`/`sleep` is scheduler- and load-dependent. Await the `Deferred`, `Queue.take`, `Stream` element, `drain()`, or `expect.poll` that marks the milestone.
ββ[apps/server/src/orchestration-v2/FoundationPersistence.test.ts:566:7]
565 β let afterSequence = created[0]!.sequence;
566 β βββΆ for (let index = 1; index <= 32; index += 1) {
567 β β const nextEvent = {
568 β β id: EventId.make(`event:foundation-stream-race:${index}`),
569 β β type: "thread.metadata-updated" as const,
570 β β threadId,
571 β β providerInstanceId,
572 β β occurredAt: now,
573 β β payload: { ...thread, title: `Race update ${index}` },
574 β β } satisfies OrchestrationV2DomainEvent;
575 β β const reader = yield* eventSink
576 β β .stream({ threadId, afterSequence })
577 β β .pipe(Stream.runHead, Effect.forkChild);
578 β β yield* Effect.yieldNow;
579 β β const written = yield* eventSink.write({ events: [nextEvent] });
580 β β const received = yield* Fiber.join(reader);
581 β β if (Option.isNone(received)) {
582 β β return yield* Effect.die("The event stream ended before delivering the live event.");
583 β β }
584 β β assert.equal(received.value.sequence, written[0]?.sequence);
585 β β assert.equal(received.value.event.id, nextEvent.id);
586 β β afterSequence = received.value.sequence;
587 β β°ββΆ }
588 β }),
β°ββββ
β t3code(no-polling-loop-in-tests): Polling loop in a test. Spinning on `yieldNow`/`sleep` is scheduler- and load-dependent. Await the `Deferred`, `Queue.take`, `Stream` element, `drain()`, or `expect.poll` that marks the milestone.
ββ[apps/server/src/orchestration-v2/FoundationPersistence.test.ts:2327:9]
2326 β let settled = false;
2327 β βββΆ while (!settled) {
2328 β β settled = (yield* outbox.listByCommandId(commandId)).every(
2329 β β (effect) => effect.status === "succeeded",
2330 β β );
2331 β β if (!settled) yield* Effect.yieldNow;
2332 β β°ββΆ }
2333 β }).pipe(Effect.provide(layerWorker), Effect.scoped);
β°ββββ
β t3code(no-inline-schema-compile): Hoist Schema.decodeUnknownSync(...) to module scope: the compiled function is rebuilt on every call. Move it to a module-level const.
ββ[packages/contracts/src/auth.test.ts:17:12]
16 β it("decodes legacy review credentials without offering them in new grants", () => {
17 β expect(Schema.decodeUnknownSync(AuthEnvironmentScopes)(["review:write"])).toEqual([
Β· ββββββββββββββββββββββββ
18 β "review:write",
β°ββββ
β t3code(no-inline-schema-compile): Hoist Schema.decodeUnknownSync(...) to module scope: the compiled function is rebuilt on every call. Move it to a module-level const.
ββ[packages/contracts/src/auth.test.ts:20:18]
19 β ]);
20 β expect(() => Schema.decodeUnknownSync(AuthGrantScopes)(["review:write"])).toThrow();
Β· ββββββββββββββββββββββββ
21 β expect(AuthStandardClientScopes).not.toContain("review:write");
β°ββββ
β t3code(no-inline-schema-compile): Hoist Schema.decodeUnknownSync(...) to module scope: the compiled function is rebuilt on every call. Move it to a module-level const.
ββ[packages/contracts/src/auth.test.ts:58:21]
57 β it("ignores unknown response permissions without falling back to broader scopes", () => {
58 β const session = Schema.decodeUnknownSync(AuthSessionState)({
Β· ββββββββββββββββββββββββ
59 β authenticated: true,
β°ββββ
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:2109:5]
2107 β );
2108 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
2109 β setExpandedVideo(null);
Β· βββββββββ¬βββββββ
Β· β°ββ Avoid calling setState() directly within an effect
2110 β setExpandedFile(null);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β eslint(no-unused-vars): Identifier 'isMarkdownFileLinkLabel' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:62:10]
61 β import { resolveAssetUrl } from "@t3tools/client-runtime/state/assets";
62 β import { isMarkdownFileLinkLabel } from "@t3tools/shared/markdownLinks";
Β· ββββββββββββ¬βββββββββββ
Β· β°ββ 'isMarkdownFileLinkLabel' is imported here
63 β import { formatAttachmentSize } from "@t3tools/client-runtime/state/attachments";
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'createContext' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:88:3]
87 β import {
88 β createContext,
Β· βββββββ¬ββββββ
Β· β°ββ 'createContext' is imported here
89 β memo,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'ActivityIndicator' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:103:3]
102 β import {
103 β ActivityIndicator,
Β· βββββββββ¬ββββββββ
Β· β°ββ 'ActivityIndicator' is imported here
104 β Image,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'ScrollView' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:110:3]
109 β Pressable,
110 β ScrollView,
Β· ββββββ¬ββββ
Β· β°ββ 'ScrollView' is imported here
111 β StyleSheet,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'NativeText' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:112:11]
111 β StyleSheet,
112 β Text as NativeText,
Β· ββββββ¬ββββ
Β· β°ββ 'NativeText' is imported here
113 β type ColorValue,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'tryOpenExternalUrl' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:134:10]
133 β import { copyTextWithHaptic } from "../../lib/copyTextWithHaptic";
134 β import { tryOpenExternalUrl } from "../../lib/openExternalUrl";
Β· ββββββββββ¬ββββββββ
Β· β°ββ 'tryOpenExternalUrl' is imported here
135 β import { downloadAndShareAttachment } from "../../lib/attachmentDownload";
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'faviconUrlForOrigin' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:137:10]
136 β import { hasWideMarkdownBlock } from "../../lib/wideMarkdownBlocks";
137 β import { faviconUrlForOrigin } from "@t3tools/shared/favicon";
Β· ββββββββββ¬βββββββββ
Β· β°ββ 'faviconUrlForOrigin' is imported here
138 β import {
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'MediaVideoPlayer' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:151:10]
150 β import { VideoAttachmentTile } from "../../components/VideoAttachmentTile";
151 β import { MediaVideoPlayer } from "../../components/MediaVideoPlayer";
Β· βββββββββ¬βββββββ
Β· β°ββ 'MediaVideoPlayer' is imported here
152 β import { resolveMarkdownMediaPreview } from "../../lib/markdownMedia";
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'mediaVideoPreviewUri' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:155:3]
154 β attachmentVideoPreviewSource,
155 β mediaVideoPreviewUri,
Β· βββββββββββ¬βββββββββ
Β· β°ββ 'mediaVideoPreviewUri' is imported here
156 β mediaVideoThumbnailKey,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'mediaVideoThumbnailKey' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:156:3]
155 β mediaVideoPreviewUri,
156 β mediaVideoThumbnailKey,
Β· ββββββββββββ¬ββββββββββ
Β· β°ββ 'mediaVideoThumbnailKey' is imported here
157 β type MediaVideoPreviewSource,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Type 'MediaVideoPreviewSource' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:157:8]
156 β mediaVideoThumbnailKey,
157 β type MediaVideoPreviewSource,
Β· ββββββββββββ¬βββββββββββ
Β· β°ββ 'MediaVideoPreviewSource' is imported here
158 β } from "../../lib/videoPreviewSource";
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Type 'ReviewDiffTheme' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:165:15]
164 β import { parseReviewCommentMessageSegments } from "../review/reviewCommentSelection";
165 β import type { ReviewDiffTheme } from "../review/shikiReviewHighlighter";
Β· ββββββββ¬βββββββ
Β· β°ββ 'ReviewDiffTheme' is imported here
166 β import {
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'resolveMarkdownFontSizes' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:180:3]
179 β import {
180 β resolveMarkdownFontSizes,
Β· βββββββββββββ¬βββββββββββ
Β· β°ββ 'resolveMarkdownFontSizes' is imported here
181 β resolveNativeMarkdownTypography,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'markdownLinkIconSource' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:185:10]
184 β import { PierreEntryIcon } from "../../components/PierreEntryIcon";
185 β import { markdownLinkIconSource } from "../../lib/markdownLinkIcons";
Β· ββββββββββββ¬ββββββββββ
Β· β°ββ 'markdownLinkIconSource' is imported here
186 β import {
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'resolveMarkdownInlineCodePresentation' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:188:3]
187 β normalizeNativeMarkdownUrl,
188 β resolveMarkdownInlineCodePresentation,
Β· βββββββββββββββββββ¬ββββββββββββββββββ
Β· β°ββ 'resolveMarkdownInlineCodePresentation' is imported here
189 β resolveMarkdownLinkIcon,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'resolveMarkdownLinkIcon' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:189:3]
188 β resolveMarkdownInlineCodePresentation,
189 β resolveMarkdownLinkIcon,
Β· ββββββββββββ¬βββββββββββ
Β· β°ββ 'resolveMarkdownLinkIcon' is imported here
190 β resolveMarkdownLinkPresentation,
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'useMarkdownCodeHighlight' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:228:10]
227 β import { ThreadMcpApp } from "./McpAppWebView";
228 β import { useMarkdownCodeHighlight } from "./markdownCodeHighlightState";
Β· βββββββββββββ¬βββββββββββ
Β· β°ββ 'useMarkdownCodeHighlight' is imported here
229 β import {
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'useAssetUrlState' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:232:3]
231 β useAssetUrl,
232 β useAssetUrlState,
Β· βββββββββ¬βββββββ
Β· β°ββ 'useAssetUrlState' is imported here
233 β useRefreshAssetUrl,
β°ββββ
help: Consider removing this import.
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:2111:7]
2110 β setExpandedFile(null);
2111 β }, [props.environmentId, props.threadId, props.contentPresentation.kind]);
Β· ββββββββββ¬βββββββββ ββββββββ¬ββββββ ββββββββββββββββ¬ββββββββββββββ
Β· β β β°ββ Unnecessary dependency `props.contentPresentation.kind`
Β· β β°ββ Unnecessary dependency `props.threadId`
Β· β°ββ Unnecessary dependency `props.environmentId`
2112 β const horizontalPadding = props.layoutVariant === "split" ? 20 : 16;
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:2578:7]
2577 β reportHeaderMaterialVisibility(false);
2578 β }, [feedThreadKey, reportHeaderMaterialVisibility]);
Β· βββββββ¬ββββββ
Β· β°ββ Unnecessary dependency `feedThreadKey`
2579 β
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:2594:7]
2593 β }
2594 β }, [listMountKey, props.contentInsetEndAdjustment, listRef]);
Β· βββββββ¬βββββ
Β· β°ββ Unnecessary dependency `listMountKey`
2595 β
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:2751:7]
2750 β }
2751 β }, [expandedTurnIds, expandedWorkGroups, expandedWorkRows, settleDisclosureAfterLayout]);
Β· ββββββββ¬βββββββ ββββββββββ¬ββββββββ βββββββββ¬βββββββ
Β· β β β°ββ Unnecessary dependency `expandedWorkRows`
Β· β β°ββ Unnecessary dependency `expandedWorkGroups`
Β· β°ββ Unnecessary dependency `expandedTurnIds`
2752 β
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(memo-dependencies): Found extra memoization dependencies
ββ[apps/mobile/src/features/threads/ThreadFeed.tsx:603:9]
602 β };
603 β }, [props.environmentId, attachment.id, httpBaseUrl]),
Β· ββββββββββ¬βββββββββ βββββββ¬ββββββ ββββββ¬βββββ
Β· β β β°ββ Unnecessary dependency `httpBaseUrl`
Β· β β°ββ Unnecessary dependency `attachment.id`
Β· β°ββ Unnecessary dependency `props.environmentId`
604 β );
β°ββββ
help: Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/NewTaskDraftScreen.tsx:361:7]
355 β }, [cancelledIncomingShareId, navigation, props.incomingShareId]);
356 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
357 β if (!isReturningToProjectPicker) {
358 β return;
359 β }
360 β if (requestedInitialProjectAvailable) {
361 β setIsReturningToProjectPicker(false);
Β· βββββββββββββββ¬ββββββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
362 β return;
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/NewTaskDraftScreen.tsx:504:9]
447 β
448 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
449 β if (props.pendingTaskId || props.draftId) {
450 β return;
451 β }
452 β if (lastInitialProjectRefRef.current !== props.initialProjectRef) {
453 β lastInitialProjectRefRef.current = props.initialProjectRef;
454 β appliedInitialProjectKeyRef.current = null;
455 β }
456 β const initialEnvironmentId = props.initialProjectRef?.environmentId;
457 β const initialProjectId = props.initialProjectRef?.projectId;
458 β if (initialEnvironmentId && initialProjectId) {
459 β const directProject =
460 β projects.find(
461 β (project) =>
462 β project.environmentId === initialEnvironmentId && project.id === initialProjectId,
463 β ) ?? null;
464 β
465 β if (directProject) {
466 β // Apply the route's project once. Re-applying on every change would
467 β // instantly revert environment/project switches made in the picker.
468 β const directProjectKey = `${directProject.environmentId}:${directProject.id}`;
469 β if (appliedInitialProjectKeyRef.current === directProjectKey) {
470 β return;
471 β }
472 β if (props.initialProjectRef?.branch) {
473 β if (
474 β selectedProject?.environmentId !== directProject.environmentId ||
475 β selectedProject.id !== directProject.id
476 β ) {
477 β setProject(directProject);
478 β return;
479 β }
480 β if (!flow.draftKey) return;
481 β // The route completes checkout before mounting this composer. Local
482 β // mode reuses an existing worktree; worktree mode would create another.
483 β updateComposerDraftSettings(flow.draftKey, {
484 β workspaceSelection: {
485 β mode: "local",
486 β branch: props.initialProjectRef.branch,
487 β worktreePath: props.initialProjectRef.worktreePath ?? null,
488 β startFromOrigin: false,
489 β },
490 β });
491 β }
492 β appliedInitialProjectKeyRef.current = directProjectKey;
493 β if (
494 β selectedProject?.environmentId === directProject.environmentId &&
495 β selectedProject.id === directProject.id
496 β ) {
497 β return;
498 β }
499 β setProject(directProject);
500 β return;
501 β }
502 β
503 β if (projects.length > 0) {
504 β setIsReturningToProjectPicker(true);
Β· βββββββββββββββ¬ββββββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
505 β }
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/NewTaskDraftScreen.tsx:604:5]
545 β
546 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
547 β const shareId = props.incomingShareId;
548 β const draftKey = flow.draftKey;
549 β const destinationProject = selectedProject;
550 β const initialEnvironmentId = props.initialProjectRef?.environmentId;
551 β const initialProjectId = props.initialProjectRef?.projectId;
552 β const selectedProjectMatchesRoute =
553 β !initialEnvironmentId ||
554 β !initialProjectId ||
555 β (destinationProject?.environmentId === initialEnvironmentId &&
556 β destinationProject.id === initialProjectId);
557 β if (
558 β !shareId ||
559 β !draftKey ||
560 β !destinationProject ||
561 β !selectedProjectMatchesRoute ||
562 β cancelledIncomingShareId === shareId
563 β ) {
564 β return;
565 β }
566 β const importKey = `${shareId}:${draftKey}`;
567 β if (
568 β startedShareImportKeyRef.current === importKey ||
569 β cancellingShareImportKeyRef.current === importKey
570 β ) {
571 β return;
572 β }
573 β
574 β if (!incomingShare) {
575 β if (isIncomingShareUnavailable && alertedUnavailableIncomingShareIdRef.current !== shareId) {
576 β alertedUnavailableIncomingShareIdRef.current = shareId;
577 β Dialog.alert(
578 β "Shared content unavailable",
579 β "The shared content is no longer in the inbox. You can continue editing this task draft.",
580 β );
581 β }
582 β return;
583 β }
584 β
585 β if (
586 β incomingShare.attachments.some((attachment) => attachment.type === "file") &&
587 β selectedEnvironmentServerConfig === null
588 β ) {
589 β return;
590 β }
591 β
592 β if (alertedUnavailableIncomingShareIdRef.current === shareId) {
593 β alertedUnavailableIncomingShareIdRef.current = null;
594 β }
595 β startedShareImportKeyRef.current = importKey;
596 β const draftBackup =
597 β shareImportDraftBackupRef.current.get(importKey) ?? getComposerDraftSnapshot(draftKey);
598 β shareImportDraftBackupRef.current.set(importKey, draftBackup);
599 β const importToken = Symbol(importKey);
600 β let didReserveShare = false;
601 β let didConsumeShare = false;
602 β let needsDraftRestore = false;
603 β activeShareImportTokenRef.current = importToken;
604 β setImportingShareKey(importKey);
Β· βββββββββββ¬βββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
605 β void (async () => {
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/NewTaskDraftScreen.tsx:524:5]
523 β props.initialProjectRef,
524 β props.incomingShareId,
Β· βββββββββββ¬ββββββββββ
Β· β°ββ Unnecessary dependency `props.incomingShareId`
525 β props.pendingTaskId,
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found missing/extra effect dependencies
ββ[apps/mobile/src/features/threads/NewTaskDraftScreen.tsx:543:5]
542 β loadedBranchesProjectKeyRef.current = projectKey;
543 β flow.loadBranches();
Β· βββ¬β
Β· β°ββ Missing dependency `flow`
544 β }, [flow.loadBranches, selectedProject]);
Β· βββββββββ¬ββββββββ
Β· β°ββ Overly precise dependency `flow.loadBranches`, use `flow` instead
545 β
β°ββββ
help: Missing dependencies can cause an effect to fire less often than it should. Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/NewTaskDraftScreen.tsx:766:5]
765 β flow.draftKey,
766 β hasImportedIncomingShare,
Β· βββββββββββββ¬βββββββββββ
Β· β°ββ Unnecessary dependency `hasImportedIncomingShare`
767 β incomingShare,
768 β isIncomingShareInboxLoading,
Β· ββββββββββββββ¬βββββββββββββ
Β· β°ββ Unnecessary dependency `isIncomingShareInboxLoading`
769 β isIncomingShareUnavailable,
770 β props.incomingShareId,
771 β props.initialProjectRef?.environmentId,
772 β props.initialProjectRef?.projectId,
773 β releaseShareReservation,
774 β reserveShare,
775 β selectedEnvironmentServerConfig,
776 β selectedProject,
777 β shareImportAttempt,
Β· ββββββββββ¬ββββββββ
Β· β°ββ Unnecessary dependency `shareImportAttempt`
778 β ]);
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found missing/extra effect dependencies
ββ[apps/mobile/src/features/threads/NewTaskContextPickerScreens.tsx:370:7]
369 β mountedRef.current = false;
370 β flow.setBranchQuery("");
Β· βββ¬β
Β· β°ββ Missing dependency `flow`
371 β };
372 β }, [flow.setBranchQuery]);
Β· ββββββββββ¬βββββββββ
Β· β°ββ Overly precise dependency `flow.setBranchQuery`, use `flow` instead
373 β
β°ββββ
help: Missing dependencies can cause an effect to fire less often than it should. Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β eslint(no-unused-vars): Variable 'layer' is declared but never used. Unused variables should start with a '_'.
ββ[packages/provider-opencode/src/server/adapter.ts:3755:7]
3754 β
3755 β const layer: Layer.Layer<ProviderAdapter.ProviderAdapterV2, never, OpenCodeAdapterV2DriverEnv> =
Β· βββ¬ββ
Β· β°ββ 'layer' is declared here
3756 β Layer.effect(
β°ββββ
help: Consider removing this declaration.
β t3code(no-inline-schema-compile): Hoist Schema.encodeUnknownSync(...) to module scope: both the inline schema literal and the compiled function are rebuilt on every call. Move the compiled function to a module-level const.
ββ[packages/contracts/src/composerContext.test.ts:181:18]
180 β it("sends a message without the records the wire cannot carry", () => {
181 β const wire = Schema.encodeUnknownSync(Schema.toCodecJson(OrchestrationMessageContext))({
Β· ββββββββββββββββββββββββ
182 β version: 1,
β°ββββ
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/review/ReviewCommentComposerSheet.tsx:103:7]
100 β
101 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
102 β if (!target || selectedLines.length === 0) {
103 β setHighlightedLinesById({});
Β· ββββββββββββ¬βββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
104 β return;
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β eslint(no-empty-pattern): Empty object binding pattern
ββ[packages/provider-opencode/src/server/OpenCodeRuntime.environment.test.ts:53:14]
52 β
53 β for (const {} of [
Β· ββ
54 β { healthy: true },
β°ββββ
help: Passing `null` or `undefined` will result in runtime error because `null` and `undefined` cannot be destructured.
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/new-task-flow-provider.tsx:444:5]
434 β : null;
435 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
436 β if (
437 β props.active === false ||
438 β activeDraftKey !== null ||
439 β editingPendingTask !== null ||
440 β selectedProject === null
441 β ) {
442 β return;
443 β }
444 β setActiveDraftKey(
Β· βββββββββ¬ββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
445 β createNewTaskDraft({
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(jsx-no-constructed-context-values): The Context `value` prop should not be constructed.
ββ[apps/mobile/src/features/threads/new-task-flow-provider.tsx:1244:36]
1243 β <ActiveNewTaskContext value={activeNewTask}>
1244 β <NewTaskFlowContext.Provider value={value}>{props.children}</NewTaskFlowContext.Provider>
Β· βββββββββββββ
1245 β </ActiveNewTaskContext>
β°ββββ
help: Wrap the `value` prop in useMemo() or useCallback(), or use a constant value to prevent unnecessary re-renders.
Alternatively, move the value outside the render function if it doesn't depend on props or state.
β eslint(no-unused-vars): Function 'summarizePayload' is declared but never used.
ββ[packages/provider-acp/src/server/nativeLogging.ts:22:10]
21 β
22 β function summarizePayload(payload: unknown): Readonly<Record<string, unknown>> {
Β· βββββββββ¬βββββββ
Β· β°ββ 'summarizePayload' is declared here
23 β if (payload === null) return { valueType: "null" };
β°ββββ
help: Consider removing this declaration.
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/review/useNativeReviewDiffHighlighting.ts:60:5]
55 β
56 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
57 β scheduler.reset();
58 β highlightedRowIdsRef.current = new Set();
59 β visibleChunkIndexRef.current = 0;
60 β setVisibleRange({ firstRowIndex: 0, lastRowIndex: 80 });
Β· ββββββββ¬βββββββ
Β· β°ββ Avoid calling setState() directly within an effect
61 β setTokensPatchJson(createEmptyTokenPatch(resetKey));
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/review/useNativeReviewDiffHighlighting.ts:63:7]
62 β return () => scheduler.cancel();
63 β }, [enabled, resetKey, rows.length, scheduler]);
Β· ββββ¬βββ ββββββ¬βββββ
Β· β β°ββ Unnecessary dependency `rows.length`
Β· β°ββ Unnecessary dependency `enabled`
64 β
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/review/useReviewCommentSelectionController.ts:107:5]
104 β
105 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
106 β clearReviewCommentTarget();
107 β setPendingNativeCommentSelection(null);
Β· βββββββββββββββββ¬βββββββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
108 β }, [selectedSection?.id]);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/review/useReviewCommentSelectionController.ts:112:7]
109 β
110 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
111 β if (activeCommentTarget === null) {
112 β setPendingNativeCommentSelection(null);
Β· βββββββββββββββββ¬βββββββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
113 β }
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/review/useReviewCommentSelectionController.ts:108:7]
107 β setPendingNativeCommentSelection(null);
108 β }, [selectedSection?.id]);
Β· ββββββββββ¬βββββββββ
Β· β°ββ Unnecessary dependency `selectedSection?.id`
109 β
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β unicorn(prefer-array-find): Prefer `find` over filtering and accessing the first result.
ββ[packages/client-runtime/src/operations/projects.ts:228:51]
227 β ): string {
228 β const folderName = workspaceRoot.split(/[\\/]/).filter(Boolean).at(-1) ?? "";
Β· ββββββ
229 β return target.owner ? `${target.owner}/${folderName}` : folderName;
β°ββββ
help: Use `find(predicate)` instead of `filter(predicate)[0]` or similar patterns.
β unicorn(require-module-specifiers): Empty import specifier is not allowed
ββ[packages/contracts/src/rpc.ts:295:8]
294 β } from "./device.ts";
295 β import {} from "./previewAutomation.ts";
Β· ββ
296 β import {
β°ββββ
help: Remove empty braces
β t3code(no-polling-loop-in-tests): Polling loop in a test. Spinning on `yieldNow`/`sleep` is scheduler- and load-dependent. Await the `Deferred`, `Queue.take`, `Stream` element, `drain()`, or `expect.poll` that marks the milestone.
ββ[packages/client-runtime/src/state/threads-sync.test.ts:1228:7]
1227 β yield* harness.replaceSession;
1228 β βββΆ for (let attempt = 0; attempt < 100; attempt += 1) {
1229 β β if ((yield* Ref.get(harness.subscriptionCount)) >= 2) {
1230 β β break;
1231 β β }
1232 β β yield* Effect.yieldNow;
1233 β β°ββΆ }
1234 β yield* Queue.offer(
β°ββββ
β t3code(no-polling-loop-in-tests): Polling loop in a test. Spinning on `yieldNow`/`sleep` is scheduler- and load-dependent. Await the `Deferred`, `Queue.take`, `Stream` element, `drain()`, or `expect.poll` that marks the milestone.
ββ[packages/client-runtime/src/state/threads-sync.test.ts:1337:7]
1336 β yield* harness.replaceSession;
1337 β βββΆ for (let attempt = 0; attempt < 100; attempt += 1) {
1338 β β if ((yield* Ref.get(harness.subscriptionCount)) >= 2) break;
1339 β β yield* Effect.yieldNow;
1340 β β°ββΆ }
1341 β expect(yield* Ref.get(harness.subscriptionCount)).toBe(2);
β°ββββ
β eslint(require-yield): This generator function does not have `yield`
ββ[packages/provider-acp/src/server/mcpOverAcpBridge.ts:81:78]
80 β
81 β βββΆ export const makeAcpMcpOverAcpBridge = Effect.fn("AcpMcpOverAcpBridge.make")(function* (
82 β β options: AcpMcpOverAcpBridgeOptions,
83 β β ): Effect.fn.Return<AcpMcpOverAcpBridge> {
84 β β const fetchImplementation = options.fetchImplementation ?? fetch;
85 β β const connections = new Map<string, Connection>();
86 β β
87 β β const connectionFor = (connectionId: string): Effect.Effect<Connection, AcpMcpOverAcpError> =>
88 β β Effect.suspend(() => {
89 β β const connection = connections.get(connectionId);
90 β β return connection === undefined
91 β β ? Effect.fail(new AcpMcpOverAcpError(`Unknown MCP-over-ACP connection "${connectionId}".`))
92 β β : Effect.succeed(connection);
93 β β });
94 β β
95 β β const send = (
96 β β connection: Connection,
97 β β message: unknown,
98 β β ): Effect.Effect<ReadonlyArray<unknown>, AcpMcpOverAcpError> =>
99 β β connection.mutex.withPermits(1)(
100 β β Effect.gen(function* () {
101 β β const body = JSON.stringify(message);
102 β β if (Buffer.byteLength(body) > MAX_MESSAGE_BYTES) {
103 β β return yield* Effect.fail(new AcpMcpOverAcpError("MCP-over-ACP message exceeds 8 MiB."));
104 β β }
105 β β const response = yield* Effect.tryPromise({
106 β β try: (signal) =>
107 β β fetchImplementation(options.endpoint, {
108 β β method: "POST",
109 β β signal,
110 β β headers: {
111 β β "content-type": "application/json",
112 β β accept: "application/json, text/event-stream",
113 β β authorization: options.authorization,
114 β β ...(connection.sessionId === null
115 β β ? {}
116 β β : { "mcp-session-id": connection.sessionId }),
117 β β ...(connection.protocolVersion === null
118 β β ? {}
119 β β : { "mcp-protocol-version": connection.protocolVersion }),
120 β β },
121 β β body,
122 β β }),
123 β β catch: bridgeError,
124 β β });
125 β β connection.sessionId = response.headers.get("mcp-session-id") ?? connection.sessionId;
126 β β if (!response.ok) {
127 β β yield* Effect.promise(
128 β β () => response.body?.cancel().catch(() => undefined) ?? Promise.resolve(),
129 β β );
130 β β return yield* Effect.fail(
131 β β new AcpMcpOverAcpError(`T3 Code MCP endpoint responded with HTTP ${response.status}.`),
132 β β );
133 β β }
134 β β const payloads = [...(yield* Stream.runCollect(responsePayloads(response, bridgeError)))];
135 β β for (const payload of payloads) {
136 β β connection.protocolVersion = protocolVersionOf(payload) ?? connection.protocolVersion;
137 β β }
138 β β return payloads;
139 β β }).pipe(Effect.mapError(bridgeError)),
140 β β );
141 β β
142 β β const disconnect = Effect.fn("mcpOverAcpBridge.disconnect")(function* (
143 β β request: AcpSchema.DisconnectMcpRequest,
144 β β ): Effect.fn.Return<AcpSchema.DisconnectMcpResponse, AcpMcpOverAcpError> {
145 β β const connection = yield* connectionFor(request.connectionId);
146 β β connections.delete(request.connectionId);
147 β β const sessionId = connection.sessionId;
148 β β if (sessionId !== null) {
149 β β const response = yield* Effect.tryPromise({
150 β β try: (signal) =>
151 β β fetchImplementation(options.endpoint, {
152 β β method: "DELETE",
153 β β signal,
154 β β headers: {
155 β β authorization: options.authorization,
156 β β "mcp-session-id": sessionId,
157 β β ...(connection.protocolVersion === null
158 β β ? {}
159 β β : { "mcp-protocol-version": connection.protocolVersion }),
160 β β },
161 β β }),
162 β β catch: bridgeError,
163 β β });
164 β β if (!response.ok && response.status !== 404) {
165 β β return yield* Effect.fail(
166 β β new AcpMcpOverAcpError(
167 β β `T3 Code MCP endpoint rejected disconnect with HTTP ${response.status}.`,
168 β β ),
169 β β );
170 β β }
171 β β yield* Effect.promise(
172 β β () => response.body?.cancel().catch(() => undefined) ?? Promise.resolve(),
173 β β );
174 β β }
175 β β return {};
176 β β });
177 β β
178 β β return {
179 β β connect: Effect.fn("mcpOverAcpBridge.connect")(function* (request) {
180 β β if (request.serverId !== "t3-code") {
181 β β return yield* Effect.fail(
182 β β new AcpMcpOverAcpError(`Unknown ACP MCP server "${request.serverId}".`),
183 β β );
184 β β }
185 β β if (connections.size >= MAX_CONNECTIONS) {
186 β β return yield* Effect.fail(new AcpMcpOverAcpError("Too many MCP-over-ACP connections."));
187 β β }
188 β β const connectionId = yield* options.allocateConnectionId;
189 β β connections.set(connectionId, {
190 β β mutex: yield* Semaphore.make(1),
191 β β sessionId: null,
192 β β protocolVersion: null,
193 β β nextRequestId: 0,
194 β β });
195 β β return { connectionId };
196 β β }),
197 β β message: Effect.fn("mcpOverAcpBridge.message")(function* (request) {
198 β β const connection = yield* connectionFor(request.connectionId);
199 β β const id = ++connection.nextRequestId;
200 β β const payloads = yield* send(connection, {
201 β β jsonrpc: "2.0",
202 β β id,
203 β β method: request.method,
204 β β ...(request.params == null ? {} : { params: request.params }),
205 β β });
206 β β const response = payloads.find((payload) => asEnvelope(payload)?.id === id);
207 β β const envelope = asEnvelope(response);
208 β β if (envelope === null) {
209 β β return yield* Effect.fail(
210 β β new AcpMcpOverAcpError("MCP server did not return a matching response."),
211 β β );
212 β β }
213 β β if (envelope.error !== undefined) {
214 β β return yield* Effect.fail(new AcpMcpOverAcpError(errorMessage(envelope.error)));
215 β β }
216 β β return (envelope.result ?? null) as AcpSchema.MessageMcpResponse;
217 β β }),
218 β β notification: Effect.fn("mcpOverAcpBridge.notification")(function* (request) {
219 β β const connection = yield* connectionFor(request.connectionId);
220 β β yield* send(connection, {
221 β β jsonrpc: "2.0",
222 β β method: request.method,
223 β β ...(request.params == null ? {} : { params: request.params }),
224 β β });
225 β β }),
226 β β disconnect,
227 β β dispose: Effect.suspend(() =>
228 β β Effect.forEach(
229 β β [...connections.keys()],
230 β β (connectionId) => disconnect({ connectionId }).pipe(Effect.ignore),
231 β β { discard: true },
232 β β ),
233 β β ),
234 β β };
235 β β°ββΆ });
β°ββββ
help: Add a `yield` expression inside the generator body, or convert it to a regular function if iteration behavior is not needed.
β eslint(no-unused-vars): Function 'normalizeTerminalContextSelection' is declared but never used.
ββ[apps/web/src/lib/terminalContext.ts:56:10]
55 β
56 β function normalizeTerminalContextSelection(
Β· βββββββββββββββββ¬ββββββββββββββββ
Β· β°ββ 'normalizeTerminalContextSelection' is declared here
57 β selection: TerminalContextSelection,
β°ββββ
help: Consider removing this declaration.
β eslint(no-unused-vars): Type 'AuthSessionState' is imported but never used.
ββ[packages/client-runtime/src/state/usageAccess.ts:3:8]
2 β AuthDiagnosticsReadScope,
3 β type AuthSessionState,
Β· βββββββββ¬βββββββ
Β· β°ββ 'AuthSessionState' is imported here
4 β sessionGrantsScope,
β°ββββ
help: Consider removing this import.
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx:285:5]
283 β const [snoozeWakeTick, bumpSnoozeWakeTick] = useState(0);
284 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
285 β setNow(new Date().toISOString());
Β· ββββ¬ββ
Β· β°ββ Avoid calling setState() directly within an effect
286 β const id = setInterval(() => setNow(new Date().toISOString()), 60_000);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx:365:25]
364 β // range) the boundary string is identical and the chain would die.
365 β }, [nextSnoozeWakeAt, snoozeWakeTick]);
Β· ββββββββ¬ββββββ
Β· β°ββ Unnecessary dependency `snoozeWakeTick`
366 β const listItems = ((): readonly SidebarListItem[] => {
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(purity): Cannot call impure function during render
ββ[apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx:356:53]
355 β if (Number.isNaN(wakeAtMs)) return;
356 β const delayMs = Math.min(Math.max(0, wakeAtMs - Date.now()) + 50, 2_147_483_647);
Β· ββββββ¬ββββ
Β· β°ββ Cannot call impure function
357 β const id = setTimeout(() => {
β°ββββ
help: `Date.now` is an impure function. Calling an impure function can produce unstable results that update unpredictably when the component re-renders
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/purity
β eslint(no-unused-vars): Identifier 'Arr' is imported but never used.
ββ[packages/client-runtime/src/state/threadSort.ts:4:13]
3 β import type { EnvironmentThreadShell } from "./models.ts";
4 β import * as Arr from "effect/Array";
Β· ββ¬β
Β· β°ββ 'Arr' is imported here
5 β import * as Order from "effect/Order";
β°ββββ
help: Consider removing this import.
β eslint(no-unused-vars): Identifier 'Order' is imported but never used.
ββ[packages/client-runtime/src/state/threadSort.ts:5:13]
4 β import * as Arr from "effect/Array";
5 β import * as Order from "effect/Order";
Β· βββ¬ββ
Β· β°ββ 'Order' is imported here
6 β
β°ββββ
help: Consider removing this import.
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/thread-inspector-content-stack.tsx:60:5]
58 β
59 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
60 β setMountedModes((current) => {
Β· ββββββββ¬βββββββ
Β· β°ββ Avoid calling setState() directly within an effect
61 β if (current.has(props.mode)) {
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/use-worktree-setup.ts:30:40]
28 β const snapshot = resolveWorktreeSetupSnapshot(input.threadId, query.data, live);
29 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
30 β if (snapshot && snapshot !== live) setHeld({ key, snapshot });
Β· ββββ¬βββ
Β· β°ββ Avoid calling setState() directly within an effect
31 β }, [key, live, snapshot]);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β unicorn(no-array-reverse): Use `Array#toReversed()` instead of `Array#reverse()`.
ββ[apps/mobile/src/lib/markdownDocument.ts:138:28]
137 β visit(parser.parse(markdown));
138 β for (const edit of edits.reverse())
Β· βββββββ
139 β markdown = markdown.slice(0, edit.start) + edit.content + markdown.slice(edit.end);
β°ββββ
help: `Array#reverse()` mutates the original array. Use `Array#toReversed()` to return a new reversed array without modifying the original.
β unicorn(no-array-reverse): Use `Array#toReversed()` instead of `Array#reverse()`.
ββ[apps/mobile/src/lib/markdownDocument.ts:169:28]
168 β visit(parser.parse(markdown));
169 β for (const edit of edits.reverse())
Β· βββββββ
170 β markdown = markdown.slice(0, edit.start) + edit.content + markdown.slice(edit.end);
β°ββββ
help: `Array#reverse()` mutates the original array. Use `Array#toReversed()` to return a new reversed array without modifying the original.
β unicorn(no-array-reverse): Use `Array#toReversed()` instead of `Array#reverse()`.
ββ[apps/mobile/src/lib/markdownDocument.ts:223:38]
222 β visit(parser.parse(markdown));
223 β for (const lineStart of lineStarts.reverse()) {
Β· βββββββ
224 β // The header row may be a lazy line without its container markers (`>` or list indent),
β°ββββ
help: `Array#reverse()` mutates the original array. Use `Array#toReversed()` to return a new reversed array without modifying the original.
β eslint(no-unused-vars): Type 'EnvironmentId' is imported but never used.
ββ[packages/client-runtime/src/state/sharedSettings.ts:2:3]
1 β import type {
2 β EnvironmentId,
Β· βββββββ¬ββββββ
Β· β°ββ 'EnvironmentId' is imported here
3 β ExecutionEnvironmentCapabilities,
β°ββββ
help: Consider removing this import.
β unicorn(no-new-array): Do not use `new Array(singleArgument)`.
ββ[apps/web/src/terminal/ghostty/core.ts:194:19]
193 β const count = Math.min(CHUNK_SIZE, graphemeLength - start);
194 β const codes = new Array<number>(count);
Β· ββββββββββββββββββββββββ
195 β for (let index = 0; index < count; index += 1) {
β°ββββ
help: It's not clear whether the argument is meant to be the length of the array or the only element. If the argument is the array's length, consider using `Array.from({ length: n })`. If the argument is the only element, use `[element]`.
β react(capitalized-calls): Capitalized function called without JSX
ββ[apps/mobile/src/lib/useHoverGesture.ts:8:15]
7 β () =>
8 β Gesture.Hover()
Β· βββ¬ββ
Β· β°ββ `Hover` may be a component
9 β .manualActivation(true)
β°ββββ
help: Render `Hover` with JSX if it is a component; otherwise rename it to start with a lowercase letter or allowlist it in the compiler configuration
note: `Hover` is treated as a component because it begins with an uppercase letter; React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/static-components
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadMarkdownImage.tsx:57:5]
55 β
56 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
57 β setDecodedSize(null);
Β· ββββββββ¬ββββββ
Β· β°ββ Avoid calling setState() directly within an effect
58 β }, [props.sourceKey]);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadMarkdownImage.tsx:61:5]
59 β
60 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
61 β setFailedUri(null);
Β· βββββββ¬βββββ
Β· β°ββ Avoid calling setState() directly within an effect
62 β }, [props.uri]);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β eslint(no-unused-vars): Identifier 'ActivityIndicator' is imported but never used.
ββ[apps/mobile/src/features/threads/ThreadMarkdownImage.tsx:7:10]
6 β import { parse, SvgAst, type JsxAST } from "react-native-svg";
7 β import { ActivityIndicator, Pressable, StyleSheet, View, type ViewStyle } from "react-native";
Β· βββββββββ¬ββββββββ
Β· β°ββ 'ActivityIndicator' is imported here
8 β
β°ββββ
help: Consider removing this import.
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadMarkdownImage.tsx:58:7]
57 β setDecodedSize(null);
58 β }, [props.sourceKey]);
Β· ββββββββ¬βββββββ
Β· β°ββ Unnecessary dependency `props.sourceKey`
59 β
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadMarkdownImage.tsx:62:7]
61 β setFailedUri(null);
62 β }, [props.uri]);
Β· βββββ¬ββββ
Β· β°ββ Unnecessary dependency `props.uri`
63 β
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(capitalized-calls): Capitalized function called without JSX
ββ[apps/mobile/src/features/threads/ThreadQueueControl.tsx:602:27]
601 β const onEnd = useEffectEvent((y: number, success: boolean) => props.onEnd(y, success));
602 β const gesture = Gesture.Pan()
Β· ββ¬β
Β· β°ββ `Pan` may be a component
603 β .enabled(!props.disabled)
β°ββββ
help: Render `Pan` with JSX if it is a component; otherwise rename it to start with a lowercase letter or allowlist it in the compiler configuration
note: `Pan` is treated as a component because it begins with an uppercase letter; React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/static-components
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:261:5]
259 β .join("|");
260 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
261 β stop();
Β· βββ¬β
Β· β°ββ Avoid calling setState() directly within an effect
262 β }, [orderVersion]);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(exhaustive-effect-dependencies): Found missing/extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:261:5]
260 β useEffect(() => {
261 β stop();
Β· βββ¬β
Β· β°ββ Missing dependency `stop`
262 β }, [orderVersion]);
Β· βββββββ¬βββββ
Β· β°ββ Unnecessary dependency `orderVersion`
263 β useEffect(
β°ββββ
help: Missing dependencies can cause an effect to fire less often than it should. Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(refs): Cannot access refs during render
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:96:9]
95 β const latest = useRef(props);
96 β latest.current = props;
Β· ββββ¬βββββββ¬βββ
Β· β β°ββ Cannot update ref value during render
Β· β°ββ This value is a ref
97 β const gesture = useMemo(
β°ββββ
help: React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/refs
β react(refs): Cannot access refs during render
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:104:18]
103 β .runOnJS(true)
104 β .onStart(() => latest.current.onStart())
Β· ββββββββββββββββ¬ββββββββββββββ
Β· β°ββ Passing a ref to a function may read its value during render
105 β .onUpdate((event) => latest.current.onMove(event.translationY))
β°ββββ
help: React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/refs
β react(refs): Cannot access refs during render
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:105:19]
104 β .onStart(() => latest.current.onStart())
105 β .onUpdate((event) => latest.current.onMove(event.translationY))
Β· βββββββββββββββββββββββββββ¬βββββββββββββββββββββββββ
Β· β°ββ Passing a ref to a function may read its value during render
106 β .onEnd((event) => latest.current.onMove(event.translationY))
β°ββββ
help: React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/refs
β react(refs): Cannot access refs during render
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:106:16]
105 β .onUpdate((event) => latest.current.onMove(event.translationY))
106 β .onEnd((event) => latest.current.onMove(event.translationY))
Β· βββββββββββββββββββββββββββ¬βββββββββββββββββββββββββ
Β· β°ββ Passing a ref to a function may read its value during render
107 β .onFinalize((_, success) => latest.current.onEnd(!success)),
β°ββββ
help: React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/refs
β react(refs): Cannot access refs during render
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:107:21]
106 β .onEnd((event) => latest.current.onMove(event.translationY))
107 β .onFinalize((_, success) => latest.current.onEnd(!success)),
Β· ββββββββββββββββββββββββ¬ββββββββββββββββββββββ
Β· β°ββ Passing a ref to a function may read its value during render
108 β [props.disabled],
β°ββββ
help: React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/refs
β react(refs): Cannot access refs during render
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:249:9]
248 β const latest = useRef({ rows, planners, moveThread });
249 β latest.current = { rows, planners, moveThread };
Β· ββββ¬βββββββ¬βββ
Β· β β°ββ Cannot update ref value during render
Β· β°ββ This value is a ref
250 β
β°ββββ
help: React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/refs
β react(refs): Cannot access refs during render
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:247:22]
246 β const [preview, setPreview] = useState<Drag | null>(null);
247 β const translateY = useRef(new Animated.Value(0)).current;
Β· βββββββββββββββββββ¬ββββββββββββββββββ
Β· β°ββ Cannot access ref value during render
248 β const latest = useRef({ rows, planners, moveThread });
β°ββββ
help: React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/refs
β react(purity): Cannot call impure function during render
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:324:16]
323 β update(0);
324 β let last = performance.now();
Β· βββββββββ¬ββββββββ
Β· β°ββ Cannot call impure function
325 β const tick = () => {
β°ββββ
help: `performance.now` is an impure function. Calling an impure function can produce unstable results that update unpredictably when the component re-renders
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/purity
β react(capitalized-calls): Capitalized function called without JSX
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:99:15]
98 β () =>
99 β Gesture.Pan()
Β· ββ¬β
Β· β°ββ `Pan` may be a component
100 β .enabled(!props.disabled)
β°ββββ
help: Render `Pan` with JSX if it is a component; otherwise rename it to start with a lowercase letter or allowlist it in the compiler configuration
note: `Pan` is treated as a component because it begins with an uppercase letter; React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/static-components
β react(memo-dependencies): Found missing memoization dependencies
ββ[apps/mobile/src/features/threads/ThreadArrangementSheet.tsx:108:5]
103 β .runOnJS(true)
104 β .onStart(() => latest.current.onStart())
Β· ββββ¬ββ
Β· β°ββ Missing dependency `latest`. Refs, setState functions, and other "stable" values generally do not need to be added as dependencies, but this variable may change over time to point to different values
105 β .onUpdate((event) => latest.current.onMove(event.translationY))
106 β .onEnd((event) => latest.current.onMove(event.translationY))
107 β .onFinalize((_, success) => latest.current.onEnd(!success)),
108 β [props.disabled],
Β· βββββββββ¬βββββββ
Β· β°ββ This dependency list is missing values used by the callback
109 β );
β°ββββ
help: Missing dependencies can cause a value to update less often than it should, resulting in stale UI
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β t3code(no-polling-loop-in-tests): Polling loop in a test. Spinning on `yieldNow`/`sleep` is scheduler- and load-dependent. Await the `Deferred`, `Queue.take`, `Stream` element, `drain()`, or `expect.poll` that marks the milestone.
ββ[packages/client-runtime/src/state/shell-sync.test.ts:169:7]
168 β });
169 β βββΆ for (let index = 0; index < 100; index += 1) {
170 β β if ((yield* SubscriptionRef.get(shellState)).status === "synchronizing") break;
171 β β yield* Effect.yieldNow;
172 β β°ββΆ }
173 β
β°ββββ
β t3code(no-polling-loop-in-tests): Polling loop in a test. Spinning on `yieldNow`/`sleep` is scheduler- and load-dependent. Await the `Deferred`, `Queue.take`, `Stream` element, `drain()`, or `expect.poll` that marks the milestone.
ββ[packages/client-runtime/src/state/shell-sync.test.ts:178:7]
177 β yield* Deferred.succeed(releaseSave, undefined);
178 β βββΆ for (let index = 0; index < 100; index += 1) {
179 β β if ((yield* Ref.get(saved)).length > 0) break;
180 β β yield* Effect.yieldNow;
181 β β°ββΆ }
182 β
β°ββββ
β t3code(no-polling-loop-in-tests): Polling loop in a test. Spinning on `yieldNow`/`sleep` is scheduler- and load-dependent. Await the `Deferred`, `Queue.take`, `Stream` element, `drain()`, or `expect.poll` that marks the milestone.
ββ[packages/client-runtime/src/state/shell-sync.test.ts:307:7]
306 β yield* Deferred.succeed(releaseUnenrichedSave, undefined);
307 β βββΆ for (let index = 0; index < 100; index += 1) {
308 β β const values = yield* Ref.get(saved);
309 β β if (values.length > 0 && values.at(-1)?.projects[0]?.repositoryIdentity != null) {
310 β β break;
311 β β }
312 β β yield* Effect.yieldNow;
313 β β°ββΆ }
314 β
β°ββββ
β oxc(no-accumulating-spread): Do not spread accumulators in loops
ββ[packages/client-runtime/src/state/shell.ts:189:5]
186 β let waiting = yield* Ref.get(awaitingCompletion);
187 β let next = initial;
Β· βββ¬β
Β· β°ββ From this accumulator
188 β let receivedSnapshot = false;
189 β for (const item of items) {
Β· ββ¬β
Β· β°ββ For this loop
190 β if (item.kind === "synchronized") {
191 β waiting = false;
192 β if (Option.isSome(next.snapshot)) {
193 β next = { ...next, status: "live", error: Option.none() };
Β· ββββ¬βββ
Β· β°ββ From this spread
194 β }
β°ββββ
help: Consider using `Object.assign()` to mutate the accumulator instead.
note: Using spreads within accumulators leads to `O(n^2)` time complexity.
β eslint(no-unused-vars): Type 'AuthSessionState' is imported but never used.
ββ[apps/web/src/components/settings/ProviderSettingsPanel.logic.ts:4:8]
3 β AuthProvidersManageScope,
4 β type AuthSessionState,
Β· βββββββββ¬βββββββ
Β· β°ββ 'AuthSessionState' is imported here
5 β type EnvironmentId,
β°ββββ
help: Consider removing this import.
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadDetailScreen.tsx:512:5]
510 β }, []);
511 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
512 β setKeyboardStateSuspect(false);
Β· ββββββββββββ¬βββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
513 β }, [isKeyboardVisible, liveKeyboardHeight]);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadDetailScreen.tsx:872:7]
869 β const [lastKnownKeyboardHeight, setLastKnownKeyboardHeight] = useState(0);
870 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
871 β if (liveKeyboardHeight > 0 && liveKeyboardHeight !== lastKnownKeyboardHeight) {
872 β setLastKnownKeyboardHeight(liveKeyboardHeight);
Β· ββββββββββββββ¬ββββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
873 β }
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadDetailScreen.tsx:1119:5]
1117 β
1118 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
1119 β setAnchorMessageId(null);
Β· ββββββββββ¬ββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
1120 β setSubmittedMessageId(null);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadDetailScreen.tsx:513:7]
512 β setKeyboardStateSuspect(false);
513 β }, [isKeyboardVisible, liveKeyboardHeight]);
Β· βββββββββ¬ββββββββ ββββββββββ¬ββββββββ
Β· β β°ββ Unnecessary dependency `liveKeyboardHeight`
Β· β°ββ Unnecessary dependency `isKeyboardVisible`
514 β const handleOwnedInputFocusChange = (focused: boolean) => {
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadDetailScreen.tsx:1067:7]
1066 β userInputInsetProgress.set(1);
1067 β }, [activeUserInputRequestId, userInputCardProgress, userInputInsetProgress]);
Β· βββββββββββββ¬βββββββββββ
Β· β°ββ Unnecessary dependency `activeUserInputRequestId`
1068 β const showContent = props.showContent ?? true;
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadDetailScreen.tsx:1125:15]
1124 β freeze.set(false);
1125 β }, [freeze, selectedThreadKey]);
Β· βββββββββ¬ββββββββ
Β· β°ββ Unnecessary dependency `selectedThreadKey`
1126 β
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/ThreadDetailScreen.tsx:955:5]
950 β const composerPopoverHeight = useSharedValue(0);
951 β const floatingControlCoverage = useSharedValue(
Β· ββββββββββββ¬βββββββββββ
Β· β°ββ `floatingControlCoverage` originates here
952 β showFloatingStatus ? FLOATING_WORKING_CONTROL_COVERAGE : 0,
953 β );
954 β useEffect(() => {
955 β floatingControlCoverage.value = withTiming(
Β· ββββββββββββ¬βββββββββββ
Β· β°ββ `floatingControlCoverage` cannot be modified
956 β showFloatingStatus ? FLOATING_WORKING_CONTROL_COVERAGE : 0,
β°ββββ
help: Modifying a value returned from a hook is not allowed. Consider moving the modification into the hook where the value is constructed
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/ThreadDetailScreen.tsx:973:7]
963 β const userInputCoverageApplies = Platform.OS === "ios" && activeUserInputRequestId !== null;
964 β const combinedContentInsetEndAdjustment = useSharedValue(
Β· βββββββββββββββββ¬ββββββββββββββββ
Β· β°ββ `combinedContentInsetEndAdjustment` originates here
965 β Math.max(0, estimatedOverlayHeight - nativeInsetOvercount),
966 β );
967 β useAnimatedReaction(
968 β () =>
969 β contentInsetEndAdjustment.value +
970 β floatingControlCoverage.value +
971 β (userInputCoverageApplies ? userInputInsetProgress.value * userInputCardCoverage.value : 0),
972 β (value) => {
973 β combinedContentInsetEndAdjustment.value = value;
Β· βββββββββββββββββ¬ββββββββββββββββ
Β· β°ββ `combinedContentInsetEndAdjustment` cannot be modified
974 β },
β°ββββ
help: Modifying a value returned from a hook is not allowed. Consider moving the modification into the hook where the value is constructed
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/use-composer-command-menu.ts:215:7]
211 β };
212 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
213 β const inserted = ownerKey ? readComposerDraftSelection(ownerKey, draftMessage) : null;
214 β if (inserted) {
215 β setSelection((current) =>
Β· βββββββ¬βββββ
Β· β°ββ Avoid calling setState() directly within an effect
216 β current.start === inserted.start && current.end === inserted.end ? current : inserted,
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/use-composer-command-menu.ts:296:7]
284 β }, [hasWorkspaceSnapshot]);
285 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
286 β if (!environmentId || !projectCwd || !selectedProviderInstanceId) return;
287 β const key = `${environmentId}:${selectedProviderInstanceId}:${projectCwd}`;
288 β const now = Date.now();
289 β const lastRequest = workspaceRefreshKeyRef.current;
290 β if (
291 β lastRequest?.key === key &&
292 β now - lastRequest.requestedAt < PROVIDER_WORKSPACE_SNAPSHOT_TTL_MS
293 β )
294 β return;
295 β if (hasCurrentProviderWorkspaceSnapshot(selectedProviderStatus, projectCwd, now)) {
296 β setWorkspaceRefreshRetry(null);
Β· βββββββββββββ¬βββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
297 β return;
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/threads/use-composer-command-menu.ts:326:5]
325 β }, [
326 β draftMessage,
Β· βββββββ¬βββββ
Β· β°ββ Unnecessary dependency `draftMessage`
327 β environmentId,
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(no-object-type-as-default-prop): Do not use an array literal as default prop value. Use a stable reference instead.
ββ[apps/web/src/components/settings/SettingInheritance.tsx:163:24]
162 β keys,
163 β overridingProjects = [],
Β· ββ
164 β onClearOverrides,
β°ββββ
help: Default values are re-created on every render and break referential equality, causing unnecessary re-renders. Move the value out of the component or memoize it.
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/ThreadRouteScreen.tsx:400:5]
398 β
399 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
400 β setInspectorSelection((current) => {
Β· βββββββββββ¬ββββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
401 β if (props.renderInspector === undefined) {
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(no-unstable-nested-components): Do not define components during render.
ββ[apps/mobile/src/features/threads/ThreadRouteScreen.tsx:528:24]
527 β const inspectorHeaderInset = Platform.OS === "ios" ? 0 : safeAreaInsets.top;
528 β βββΆ const GitInspector = () => (
529 β β <GitOverviewSheet
530 β β headerInset={inspectorHeaderInset}
531 β β presentation="inspector"
532 β β route={{ params: { environmentId: environmentId!, threadId: threadId! } }}
533 β β />
534 β β°ββΆ );
535 β const FilesInspector = () =>
β°ββββ
help: Move this component definition out of the parent component `ThreadRouteContent` and pass data as props.
β react(no-unstable-nested-components): Do not define components during render.
ββ[apps/mobile/src/features/threads/ThreadRouteScreen.tsx:535:26]
534 β );
535 β βββΆ const FilesInspector = () =>
536 β β selectedThread !== null && selectedThreadCwd !== null ? (
537 β β <ThreadFileNavigatorPane
538 β β cwd={selectedThreadCwd}
539 β β environmentId={selectedThread.environmentId}
540 β β headerInset={inspectorHeaderInset}
541 β β projectName={selectedThreadProject?.title ?? "Files"}
542 β β selectedPath={null}
543 β β onSelectFile={handleSelectInspectorFile}
544 β β />
545 β β°ββΆ ) : null;
546 β const RouteInspector = () => props.renderInspector?.(inspectorHeaderInset);
β°ββββ
help: Move this component definition out of the parent component `ThreadRouteContent` and pass data as props.
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/PendingUserInputCard.tsx:100:7]
86 β
87 β const cardCoverage = props.cardCoverage;
Β· βββββββ¬βββββ
Β· β°ββ `cardCoverage` originates here
88 β const barHeightRef = useRef(0);
89 β const cardHeightRef = useRef(0);
90 β const cardHeight = useSharedValue(0);
91 β const notifyCoverage = useCallback(() => {
92 β if (!cardCoverage) {
93 β return;
94 β }
95 β const coverage = Math.max(0, cardHeightRef.current - barHeightRef.current);
96 β if (coverage === cardCoverage.value) {
97 β return;
98 β }
99 β if (cardCoverage.value === 0) {
100 β cardCoverage.value = coverage;
Β· βββββββ¬βββββ
Β· β°ββ `cardCoverage` cannot be modified
101 β return;
β°ββββ
help: Do not mutate component props or hook arguments. If the value should change, update it where it is owned and pass an update callback, or use local state
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/PendingUserInputCard.tsx:118:7]
89 β const cardHeightRef = useRef(0);
90 β const cardHeight = useSharedValue(0);
Β· ββββββ¬ββββ
Β· β°ββ `cardHeight` originates here
91 β const notifyCoverage = useCallback(() => {
92 β if (!cardCoverage) {
93 β return;
94 β }
95 β const coverage = Math.max(0, cardHeightRef.current - barHeightRef.current);
96 β if (coverage === cardCoverage.value) {
97 β return;
98 β }
99 β if (cardCoverage.value === 0) {
100 β cardCoverage.value = coverage;
101 β return;
102 β }
103 β cardCoverage.value = withTiming(coverage, {
104 β duration: USER_INPUT_TOGGLE_DURATION_MS,
105 β easing: Easing.out(Easing.cubic),
106 β });
107 β }, [cardCoverage]);
108 β const handleBarLayout = useCallback(
109 β (event: LayoutChangeEvent) => {
110 β barHeightRef.current = event.nativeEvent.layout.height;
111 β notifyCoverage();
112 β },
113 β [notifyCoverage],
114 β );
115 β const handleCardLayout = useCallback(
116 β (event: LayoutChangeEvent) => {
117 β cardHeightRef.current = event.nativeEvent.layout.height;
118 β cardHeight.value = event.nativeEvent.layout.height;
Β· ββββββ¬ββββ
Β· β°ββ `cardHeight` cannot be modified
119 β notifyCoverage();
β°ββββ
help: Modifying a value returned from a hook is not allowed. Consider moving the modification into the hook where the value is constructed
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): Cannot modify local variables after render completes
ββ[apps/mobile/src/features/threads/PendingUserInputCard.tsx:100:7]
90 β const cardHeight = useSharedValue(0);
91 β const notifyCoverage = useCallback(() => {
Β· ββββ¬βββ
Β· β°ββ This function may (indirectly) reassign or modify `cardCoverage` after render
92 β if (!cardCoverage) {
93 β return;
94 β }
95 β const coverage = Math.max(0, cardHeightRef.current - barHeightRef.current);
96 β if (coverage === cardCoverage.value) {
97 β return;
98 β }
99 β if (cardCoverage.value === 0) {
100 β cardCoverage.value = coverage;
Β· βββββββ¬βββββ
Β· β°ββ This modifies `cardCoverage`
101 β return;
β°ββββ
help: This argument is a function which may reassign or mutate `cardCoverage` after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): Cannot modify local variables after render completes
ββ[apps/mobile/src/features/threads/PendingUserInputCard.tsx:100:7]
99 β if (cardCoverage.value === 0) {
100 β cardCoverage.value = coverage;
Β· βββββββ¬βββββ
Β· β°ββ This modifies `cardCoverage`
101 β return;
102 β }
103 β cardCoverage.value = withTiming(coverage, {
104 β duration: USER_INPUT_TOGGLE_DURATION_MS,
105 β easing: Easing.out(Easing.cubic),
106 β });
107 β }, [cardCoverage]);
108 β const handleBarLayout = useCallback(
109 β (event: LayoutChangeEvent) => {
Β· ββββββββββββββββ¬βββββββββββββββ
Β· β°ββ This function may (indirectly) reassign or modify `cardCoverage` after render
110 β barHeightRef.current = event.nativeEvent.layout.height;
β°ββββ
help: This argument is a function which may reassign or mutate `cardCoverage` after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): Cannot modify local variables after render completes
ββ[apps/mobile/src/features/threads/PendingUserInputCard.tsx:118:7]
115 β const handleCardLayout = useCallback(
116 β (event: LayoutChangeEvent) => {
Β· ββββββββββββββββ¬βββββββββββββββ
Β· β°ββ This function may (indirectly) reassign or modify `cardHeight` after render
117 β cardHeightRef.current = event.nativeEvent.layout.height;
118 β cardHeight.value = event.nativeEvent.layout.height;
Β· ββββββ¬ββββ
Β· β°ββ This modifies `cardHeight`
119 β notifyCoverage();
β°ββββ
help: This argument is a function which may reassign or mutate `cardHeight` after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β eslint(no-unused-vars): Type 'AuthSessionState' is imported but never used.
ββ[packages/client-runtime/src/state/filesystem.ts:3:8]
2 β AuthFilesystemReadScope,
3 β type AuthSessionState,
Β· βββββββββ¬βββββββ
Β· β°ββ 'AuthSessionState' is imported here
4 β type FilesystemBrowseEntry,
β°ββββ
help: Consider removing this import.
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/NewTaskDraftRouteScreen.tsx:40:5]
37 β const [initialized, setInitialized] = useState(false);
38 β useLayoutEffect(() => {
Β· ββββββββ¬βββββββ
Β· β°ββ This is the containing effect
39 β reset();
40 β setInitialized(true);
Β· ββββββββ¬ββββββ
Β· β°ββ Avoid calling setState() directly within an effect
41 β }, [reset]);
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(set-state-in-effect): Calling setState synchronously within an effect can trigger cascading renders
ββ[apps/mobile/src/features/threads/NewTaskDraftRouteScreen.tsx:93:5]
88 β
89 β useEffect(() => {
Β· βββββ¬ββββ
Β· β°ββ This is the containing effect
90 β if (!needsPreparation || !initialProjectRef.branch || waitingForProject) return;
91 β const branchName = initialProjectRef.branch;
92 β let active = true;
93 β setPendingCheckouts((count) => count + 1);
Β· ββββββββββ¬βββββββββ
Β· β°ββ Avoid calling setState() directly within an effect
94 β // Serialize replacements: ignoring a stale result cannot undo its Git mutation.
β°ββββ
help: Effects should synchronize React with external systems. Calling setState synchronously inside an effect starts another render and is usually unnecessary. Derive the value during render, initialize state directly, or update it from the event that caused the change. Use an effect only when synchronizing with an external system.
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/floating-working-control.tsx:111:5]
107 β );
108 β const separationProgress = useSharedValue(props.showScrollToEnd ? 1 : 0);
Β· ββββββββββ¬ββββββββ
Β· β°ββ `separationProgress` originates here
109 β
110 β useEffect(() => {
111 β separationProgress.value = withTiming(props.showScrollToEnd ? 1 : 0, CONTROL_TIMING);
Β· ββββββββββ¬ββββββββ
Β· β°ββ `separationProgress` cannot be modified
112 β }, [props.showScrollToEnd, separationProgress]);
β°ββββ
help: Modifying a value returned from a hook is not allowed. Consider moving the modification into the hook where the value is constructed
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/floating-working-control.tsx:138:5]
128 β // and repeatedly retargets the animation as it grows.
129 β const capsuleWidth = useSharedValue<number | null>(null);
Β· βββββββ¬βββββ
Β· β°ββ `capsuleWidth` originates here
130 β const measuredWidthRef = useRef<number | null>(null);
131 β const handleLabelLayout = (event: LayoutChangeEvent) => {
132 β const width = event.nativeEvent.layout.width;
133 β if (width === measuredWidthRef.current) {
134 β return;
135 β }
136 β const first = measuredWidthRef.current === null;
137 β measuredWidthRef.current = width;
138 β capsuleWidth.value = first ? width : withTiming(width, CONTROL_TIMING);
Β· βββββββ¬βββββ
Β· β°ββ `capsuleWidth` cannot be modified
139 β };
β°ββββ
help: Modifying a value returned from a hook is not allowed. Consider moving the modification into the hook where the value is constructed
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/floating-working-control.tsx:145:7]
128 β // and repeatedly retargets the animation as it grows.
129 β const capsuleWidth = useSharedValue<number | null>(null);
Β· βββββββ¬βββββ
Β· β°ββ `capsuleWidth` originates here
130 β const measuredWidthRef = useRef<number | null>(null);
131 β const handleLabelLayout = (event: LayoutChangeEvent) => {
132 β const width = event.nativeEvent.layout.width;
133 β if (width === measuredWidthRef.current) {
134 β return;
135 β }
136 β const first = measuredWidthRef.current === null;
137 β measuredWidthRef.current = width;
138 β capsuleWidth.value = first ? width : withTiming(width, CONTROL_TIMING);
139 β };
140 β const hasStatus = props.status !== null;
141 β const hasCapsule = hasStatus || hasQueue || hasAgents || hasPreview;
142 β useEffect(() => {
143 β if (!hasStatus) {
144 β measuredWidthRef.current = null;
145 β capsuleWidth.value = null;
Β· βββββββ¬βββββ
Β· β°ββ `capsuleWidth` cannot be modified
146 β }
β°ββββ
help: Modifying a value returned from a hook is not allowed. Consider moving the modification into the hook where the value is constructed
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): Cannot modify local variables after render completes
ββ[apps/mobile/src/features/threads/floating-working-control.tsx:145:7]
141 β const hasCapsule = hasStatus || hasQueue || hasAgents || hasPreview;
142 β useEffect(() => {
Β· ββββ¬βββ
Β· β°ββ This function may (indirectly) reassign or modify `capsuleWidth` after render
143 β if (!hasStatus) {
144 β measuredWidthRef.current = null;
145 β capsuleWidth.value = null;
Β· βββββββ¬βββββ
Β· β°ββ This modifies `capsuleWidth`
146 β }
β°ββββ
help: This argument is a function which may reassign or mutate `capsuleWidth` after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(immutability): Cannot modify local variables after render completes
ββ[apps/mobile/src/features/threads/floating-working-control.tsx:138:5]
130 β const measuredWidthRef = useRef<number | null>(null);
131 β const handleLabelLayout = (event: LayoutChangeEvent) => {
Β· ββββββββββββββββ¬βββββββββββββββ
Β· β°ββ This function may (indirectly) reassign or modify `capsuleWidth` after render
132 β const width = event.nativeEvent.layout.width;
133 β if (width === measuredWidthRef.current) {
134 β return;
135 β }
136 β const first = measuredWidthRef.current === null;
137 β measuredWidthRef.current = width;
138 β capsuleWidth.value = first ? width : withTiming(width, CONTROL_TIMING);
Β· βββββββ¬βββββ
Β· β°ββ This modifies `capsuleWidth`
139 β };
β°ββββ
help: This argument is a function which may reassign or mutate `capsuleWidth` after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(exhaustive-effect-dependencies): Found missing/extra effect dependencies
ββ[apps/mobile/src/features/threads/ThreadComposer.tsx:772:7]
771 β if (settingsSheetPresentation.isActive) {
772 β settingsRoutePresentation.present(settingsRouteSession);
Β· βββββββββββββ¬ββββββββββββ
Β· β°ββ Missing dependency `settingsRoutePresentation`
773 β }
774 β }, [settingsRoutePresentation.present, settingsRouteSession, settingsSheetPresentation.isActive]);
Β· βββββββββββββββββ¬ββββββββββββββββ
Β· β°ββ Overly precise dependency `settingsRoutePresentation.present`, use `settingsRoutePresentation` instead
775 β
β°ββββ
help: Missing dependencies can cause an effect to fire less often than it should. Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(immutability): This value cannot be modified
ββ[apps/mobile/src/features/threads/ThreadComposer.tsx:390:5]
386 β typeof props.style.borderRadius === "number" ? props.style.borderRadius : 0;
387 β const animatedBorderRadius = useSharedValue(targetBorderRadius);
Β· βββββββββββ¬βββββββββ
Β· β°ββ `animatedBorderRadius` originates here
388 β const shouldAnimate = props.animateLayout !== false && Platform.OS !== "android";
389 β useLayoutEffect(() => {
390 β animatedBorderRadius.value = shouldAnimate
Β· βββββββββββ¬βββββββββ
Β· β°ββ `animatedBorderRadius` cannot be modified
391 β ? withTiming(targetBorderRadius, {
β°ββββ
help: Modifying a value returned from a hook is not allowed. Consider moving the modification into the hook where the value is constructed
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
β react(memo-dependencies): Found extra memoization dependencies
ββ[apps/mobile/src/features/keyboard/HardwareKeyboardCommandProvider.tsx:116:34]
115 β return [...commands];
116 β }, [activeThreadRef, pathname, registrationVersion, navigation]);
Β· ββββββββββ¬βββββββββ
Β· β°ββ Unnecessary dependency `registrationVersion`
117 β
β°ββββ
help: Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(jsx-no-constructed-context-values): The Context `value` prop should not be constructed.
ββ[apps/mobile/src/features/threads/ThreadSettingsSheet.tsx:290:50]
289 β return (
290 β <ExistingThreadSettingsRouteContext.Provider value={value}>
Β· βββββββββββββ
291 β {props.children}
β°ββββ
help: Wrap the `value` prop in useMemo() or useCallback(), or use a constant value to prevent unnecessary re-renders.
Alternatively, move the value outside the render function if it doesn't depend on props or state.
β react(jsx-no-constructed-context-values): The Context `value` prop should not be constructed.
ββ[apps/mobile/src/features/threads/ThreadSettingsSheet.tsx:654:44]
653 β return (
654 β <ThreadSettingsSessionContext.Provider value={value}>
Β· βββββββββββββ
655 β {props.children}
β°ββββ
help: Wrap the `value` prop in useMemo() or useCallback(), or use a constant value to prevent unnecessary re-renders.
Alternatively, move the value outside the render function if it doesn't depend on props or state.
β react(jsx-no-constructed-context-values): The Context `value` prop should not be constructed.
ββ[apps/mobile/src/features/threads/ThreadSettingsSheet.tsx:1462:55]
1461 β return (
1462 β <ThreadSettingsPickerPresentationContext.Provider value={presentation}>
Β· ββββββββββββββββββββ
1463 β <ThreadSettingsPickerStack.Navigator
β°ββββ
help: Wrap the `value` prop in useMemo() or useCallback(), or use a constant value to prevent unnecessary re-renders.
Alternatively, move the value outside the render function if it doesn't depend on props or state.
β react(no-array-index-key): Usage of Array index in keys is not allowed
ββ[apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx:814:17]
813 β <div
814 β key={`${index}:${check.name}:${check.url ?? ""}`}
Β· βββββββββββββββββββββββββββββββββββββββββββββββββ
815 β className="group flex items-center gap-2 rounded-md pr-1 hover:bg-accent/60"
β°ββββ
help: Use a unique data-dependent key to avoid unnecessary rerenders
β react(exhaustive-effect-dependencies): Found extra effect dependencies
ββ[apps/mobile/src/features/review/ReviewSheet.tsx:454:7]
453 β showAuxiliaryPane("inspector");
454 β }, [environmentId, showAuxiliaryPane, threadId]);
Β· βββββββ¬ββββββ βββββ¬βββ
Β· β β°ββ Unnecessary dependency `threadId`
Β· β°ββ Unnecessary dependency `environmentId`
455 β const {
β°ββββ
help: Extra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
β react(static-components): Cannot create components during render
ββ[apps/mobile/src/features/review/ReviewSheet.tsx:725:20]
492 β // same check.
493 β const NativeReviewDiffView = resolveNativeReviewDiffView();
Β· ββββββββββββββ¬βββββββββββββ
Β· β°ββ The component is created during render here
494 β const nativeReviewDiffViewRef = useRef<NativeReviewDiffViewHandle>(null);
495 β const showcasedReviewDrawRef = useRef<string | null>(null);
496 β const [isPullRefreshing, setIsPullRefreshing] = useState(false);
497 β const handlePullToRefresh = async () => {
498 β setIsPullRefreshing(true);
499 β await refreshSelectedSection();
500 β setIsPullRefreshing(false);
501 β };
502 β const reviewFileNavigatorRef = useRef<ReviewFileNavigatorHandle>(null);
503 β const reviewFiles = parsedDiff.kind === "files" ? parsedDiff.files : [];
504 β const fileVisibility = useReviewFileVisibility({
505 β threadKey: reviewCache.threadKey,
506 β sectionId: selectedSection?.id ?? null,
507 β files: reviewFiles,
508 β cachedExpandedFileIds: selectedSection?.id
509 β ? reviewCache.expandedFileIdsBySection[selectedSection.id]
510 β : undefined,
511 β cachedViewedFileIds: selectedSection?.id
512 β ? reviewCache.viewedFileIdsBySection[selectedSection.id]
513 β : undefined,
514 β });
515 β const { collapsedFileIds, toggleExpandedFile, toggleViewedFile, viewedFileIds } = fileVisibility;
516 β const commentSelection = useReviewCommentSelectionController({
517 β environmentId,
518 β threadId,
519 β selectedSection,
520 β nativeReviewDiffData,
521 β });
522 β const nativeBridge = useNativeReviewDiffBridge({
523 β threadKey: reviewCache.threadKey,
524 β sectionId: selectedSection?.id ?? null,
525 β diff: selectedSection?.diff,
526 β data: nativeReviewDiffData,
527 β collapsedFileIds,
528 β viewedFileIds,
529 β selectedRowIds: commentSelection.selectedRowIds,
530 β canHighlight: parsedDiff.kind === "files",
531 β });
532 β const showcaseReviewKey =
533 β SHOWCASE_ENABLED && parsedDiff.kind === "files" && selectedSection
534 β ? `${reviewCache.threadKey}:${selectedSection.id}:${nativeBridge.tokensResetKey}:${nativeBridge.themeId}`
535 β : null;
536 β const handleNativeDebug = (event: NativeSyntheticEvent<Record<string, unknown>>) => {
537 β nativeBridge.onDebug(event);
538 β if (
539 β showcaseReviewKey === null ||
540 β showcasedReviewDrawRef.current === showcaseReviewKey ||
541 β !isNativeReviewDiffDrawEvent(event.nativeEvent)
542 β ) {
543 β return;
544 β }
545 β showcasedReviewDrawRef.current = showcaseReviewKey;
546 β reportShowcaseSceneRendered({ scene: "review", themeId: nativeBridge.themeId });
547 β };
548 β
549 β const handleSelectFile = async (fileId: string | null) => {
550 β loadVisibleFile(fileId, true);
551 β commentSelection.clearSelection();
552 β if (fileId !== null && collapsedFileIds.includes(fileId)) {
553 β toggleExpandedFile(fileId);
554 β }
555 β const nativeView = nativeReviewDiffViewRef.current;
556 β if (!nativeView) return;
557 β const result = await settlePromise(() =>
558 β fileId === null ? nativeView.scrollToTop(true) : nativeView.scrollToFile(fileId, true),
559 β );
560 β if (AsyncResult.isFailure(result)) {
561 β console.error("[review] Failed to navigate to diff file", squashAtomCommandFailure(result));
562 β }
563 β };
564 β const handleVisibleFileChange = (
565 β event: NativeSyntheticEvent<{ readonly fileId?: string | null }>,
566 β ) => {
567 β loadVisibleFile(event.nativeEvent.fileId ?? null);
568 β reviewFileNavigatorRef.current?.setVisibleFile(event.nativeEvent.fileId ?? null);
569 β };
570 β const renderInspector = () => (
571 β <ReviewFileNavigator
572 β ref={reviewFileNavigatorRef}
573 β files={nativeReviewDiffData.files}
574 β headerInset={insets.top}
575 β sectionId={selectedSection?.id ?? null}
576 β onSelectFile={(fileId) => void handleSelectFile(fileId)}
577 β />
578 β );
579 β
580 β const handleNativeToggleFile = (event: NativeSyntheticEvent<{ readonly fileId?: string }>) => {
581 β const { fileId } = event.nativeEvent;
582 β if (fileId) {
583 β loadVisibleFile(fileId, true);
584 β toggleExpandedFile(fileId);
585 β }
586 β };
587 β
588 β const handleNativeToggleViewedFile = (
589 β event: NativeSyntheticEvent<{ readonly fileId?: string }>,
590 β ) => {
591 β const { fileId } = event.nativeEvent;
592 β if (fileId) {
593 β toggleViewedFile(fileId);
594 β }
595 β };
596 β
597 β const parsedDiffNotice =
598 β parsedDiff.kind === "files" || parsedDiff.kind === "raw" ? parsedDiff.notice : null;
599 β const hasCachedSelectedDiff = selectedSection?.diff != null;
600 β const hasAnyCachedDiff = reviewSections.some((section) => section.diff != null);
601 β const sectionMenu = buildReviewSectionMenu(reviewSections);
602 β const { showConnectionNotice, showSectionToolbar } = resolveReviewAvailability({
603 β hasEnvironmentPresentation: environment.isReady,
604 β isEnvironmentConnected: isEnvironmentReady,
605 β hasCachedSelectedDiff,
606 β hasAnyCachedDiff,
607 β });
608 β const handleRetryEnvironment = () => {
609 β void retryEnvironment(environmentId);
610 β };
611 β const handleReturnToThread = () => {
612 β if (navigation.canGoBack()) {
613 β navigation.goBack();
614 β return;
615 β }
616 β navigation.navigate("Thread", {
617 β environmentId: String(environmentId),
618 β threadId: String(threadId),
619 β });
620 β };
621 β const androidHeaderSubtitle = [
622 β selectedSection?.title,
623 β headerDiffSummary.additions,
624 β headerDiffSummary.deletions,
625 β ]
626 β .filter((part): part is string => Boolean(part))
627 β .join(" Β· ");
628 β
629 β const showChangedFilesPane =
630 β !showConnectionNotice &&
631 β selectedSection !== null &&
632 β parsedDiff.kind === "files" &&
633 β NativeReviewDiffView !== null;
634 β useRegisterWorkspaceInspector(showChangedFilesPane ? renderInspector : undefined);
635 β const showChangedFilesToggle = panes.supportsAuxiliaryPane && showChangedFilesPane;
636 β
637 β const listHeader = (() => {
638 β const children: ReactElement[] = [];
639 β
640 β if (error) {
641 β children.push(
642 β <View
643 β key="review-error"
644 β className={cn(
645 β "bg-card px-4 py-3",
646 β Platform.OS === "android" ? "m-2 rounded-[20px]" : "border-b border-border",
647 β )}
648 β >
649 β <Text className="text-sm font-t3-bold text-foreground">Review unavailable</Text>
650 β <Text className="text-xs leading-normal text-foreground-muted">{error}</Text>
651 β </View>,
652 β );
653 β }
654 β
655 β if (parsedDiffNotice) {
656 β children.push(<ReviewNotice key="review-notice" notice={parsedDiffNotice} />);
657 β }
658 β
659 β if (children.length === 0) {
660 β return null;
661 β }
662 β
663 β return <>{children}</>;
664 β })();
665 β const headerSubtitle = [
666 β headerDiffSummary.additions,
667 β headerDiffSummary.deletions,
668 β pendingReviewCommentCount > 0
669 β ? `${pendingReviewCommentCount} comment${pendingReviewCommentCount === 1 ? "" : "s"}`
670 β : null,
671 β ]
672 β .filter(Boolean)
673 β .join(" Β· ");
674 β const headerTitleText = selectedSection?.title ?? "Review changes";
675 β
676 β return (
677 β <>
678 β <ReviewHeader
679 β environmentId={environmentId}
680 β threadId={threadId}
681 β title={headerTitleText}
682 β subtitle={headerSubtitle}
683 β androidSubtitle={androidHeaderSubtitle}
684 β iconColor={headerIcon}
685 β selectedThreadCwd={selectedThreadCwd}
686 β sectionMenu={sectionMenu}
687 β selectedSection={selectedSection}
688 β showSectionToolbar={showSectionToolbar}
689 β showChangedFilesToggle={showChangedFilesToggle}
690 β onRefresh={handlePullToRefresh}
691 β onSelectSection={selectSection}
692 β onReturnToThread={handleReturnToThread}
693 β />
694 β
695 β <ScreenContent>
696 β <View className="flex-1 bg-sheet android:bg-sheet-solid">
697 β {showConnectionNotice ? (
698 β <View className="flex-1" style={{ paddingTop: topContentInset }}>
699 β <EnvironmentConnectionNotice
700 β environmentLabel={environment.presentation?.entry.target.label ?? "Environment"}
701 β connection={
702 β environment.presentation?.connection ?? {
703 β phase: "available",
704 β error: null,
705 β traceId: null,
706 β }
707 β }
708 β resourceName="review"
709 β onRetry={handleRetryEnvironment}
710 β />
711 β </View>
712 β ) : selectedSection && parsedDiff.kind === "files" && NativeReviewDiffView ? (
713 β <View
714 β className="flex-1"
715 β style={{
716 β backgroundColor: nativeBridge.theme.background,
717 β }}
718 β >
719 β <View
720 β className="min-w-0 flex-1"
721 β style={listHeader ? { paddingTop: topContentInset } : undefined}
722 β >
723 β {listHeader}
724 β <View className="min-w-0 flex-1" collapsable={false}>
725 β <NativeReviewDiffView
Β· βββββββββββ¬βββββββββ
Β· β°ββ This component is created during render
726 β collapsable={false}
β°ββββ
help: Components created during render will reset their state each time they are created. Declare components outside of render
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/static-components
β react(no-array-index-key): Usage of Array index in keys is not allowed
ββ[apps/mobile/src/features/review/ReviewCommentCard.tsx:223:31]
222 β ? snippetTokens.map((line, lineIndex) => (
223 β <NativeText key={lineIndex}>
Β· βββββββββββββββ
224 β {lineIndex > 0 ? "\n" : ""}
β°ββββ
help: Use a unique data-dependent key to avoid unnecessary rerenders
β react(no-array-index-key): Usage of Array index in keys is not allowed
ββ[apps/mobile/src/features/review/ReviewCommentCard.tsx:227:25]
226 β <NativeText
227 β key={tokenIndex}
Β· ββββββββββββββββ
228 β style={{
β°ββββ
help: Use a unique data-dependent key to avoid unnecessary rerenders
Found 0 errors and 362 warnings in 5400 files (4.9s, 8 threads)
Post job cleanup.
Cache hit occurred on the primary key electron-Linux-X64-854e11ddd491bd4f350eebb67a74265df119376a3984c8e153cfe5fc8ced6309, not saving cache.
Post job cleanup.
##[start-action display=Cache full pnpm store;id=__ef49962b-d743-402a-801a-c282124e8eb9.__actions_cache]
Post job cleanup.
Cache hit occurred on the primary key pnpm-full-v1-Linux-X64-2baa264059789b1dde4bbc8fdc5b8342f31f2fc8e6176e5c5e486efdd242b36c, not saving cache.
##[end-action id=__ef49962b-d743-402a-801a-c282124e8eb9.__actions_cache;outcome=success;conclusion=success;duration_ms=92]
##[start-action display=Cache Vite+;id=__ef49962b-d743-402a-801a-c282124e8eb9.vp_cache]
Post job cleanup.
Cache hit occurred on the primary key vite-plus-home-v2-Linux-X64-1.3.0-node26.12.1-pnpm@12.14.0, not saving cache.
##[end-action id=__ef49962b-d743-402a-801a-c282124e8eb9.vp_cache;outcome=success;conclusion=success;duration_ms=64]
Post job cleanup.
[command]/usr/local/bin/git version
git version 2.55.0
Temporarily overriding HOME='/home/runner/_work/_temp/13f9f1ab-2abe-4cc5-8960-2f101b305a0d' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
[command]/usr/local/bin/git config --global --add safe.directory /home/runner/_work/t3code/t3code
Removing SSH command configuration
[command]/usr/local/bin/git config --local --name-only --get-regexp core\.sshCommand
[command]/usr/local/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
fatal: No url found for submodule path '.repos/alchemy-effect/submodules/distilled' in .gitmodules
Warning: The process '/usr/local/bin/git' failed with exit code 128
A job completed hook has been configured by the self-hosted runner administrator
βΈ Run '/job_completed.sh'
shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
env:
BLACKSMITH_RUNNER_MESSAGE_WAIT_MS: 285
BLACKSMITH_RUNNER_ACQUIRE_JOB_MS: 408
BLACKSMITH_CHECK_RUN_ID: 120647473462
BLACKSMITH_JOB_DISPLAY_NAME: Lint
GITHUB_ACTIONS_CACHE_MODE: write
Docker container cache not activated, skipping hash computation.
No active SSH sessions detected. Proceeding with shutdown immediately.
Cleaning up orphan processes