fix(vscode-companion): align package eslint config with root and style cleanup (#3782)
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run

* fix(vscode-companion): fix ESLint curly and eqeqeq violations

Fix pre-existing lint errors in vscode-ide-companion that cause all 8
CI test matrix jobs to fail (ubuntu/macos/windows × Node 20/22/24).

- extension.ts:221 — add braces to single-line if (curly rule)
- WebViewProvider.ts:1740,1742 — add braces to single-line if (curly)
- App.tsx:179 — replace == with === (eqeqeq) and add braces (curly)
- App.tsx:215 — add braces to single-line if (curly rule)
- App.tsx:1210 — add braces to single-line if return (curly rule)
- App.tsx:1241 — add braces to single-line if continue (curly rule)
- App.tsx:1258 — add braces to single-line if continue (curly rule)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(vscode-companion): revert === null to == null and align package eslint config

- Revert `child === null` back to `child == null` in App.tsx:179.
  The == null idiom catches both null and undefined, which is the
  defensive pattern needed here. A future case that forgets to assign
  `child` would let undefined slip through with === null, desyncing
  childIndexMap from the rendered DOM and breaking findMessageIndex.

- Align package-level eslint eqeqeq with root config by adding
  { null: 'ignore' }, so == null is allowed as a warning-level rule
  matching the project-wide ESLint policy.

The curly brace additions from the prior commit are retained as
style improvements (curly: 'warn' in the package config), though
they were not CI-blocking violations — CI runs from root which uses
curly: ['error', 'multi-line'] and permits single-line if statements.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
John London 2026-05-01 23:35:24 -05:00 committed by GitHub
parent 5d1052a358
commit ad12bf84cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 25 additions and 9 deletions

View file

@ -67,7 +67,7 @@ export default [
],
curly: 'warn',
eqeqeq: 'warn',
eqeqeq: ['warn', 'always', { null: 'ignore' }],
'no-throw-literal': 'warn',
semi: 'warn',
},

View file

@ -218,7 +218,9 @@ export async function activate(context: vscode.ExtensionContext) {
const sendCopyToActive = (action: string) => {
for (const provider of chatProviderRegistry?.getPermissionAwareProviders() ??
[]) {
if (provider.sendCopyCommand(action)) break;
if (provider.sendCopyCommand(action)) {
break;
}
}
};
context.subscriptions.push(

View file

@ -177,7 +177,9 @@ const MessageList = React.memo<MessageListProps>(
}
// No wrapper div — message components render directly as children
// of the scroll container, preserving the original CSS layout.
if (child == null) return null;
if (child == null) {
return null;
}
mapping.push(index);
return <React.Fragment key={`msg-${index}`}>{child}</React.Fragment>;
});
@ -213,7 +215,9 @@ function findMessageIndex(
while (directChild && directChild.parentElement !== container) {
directChild = directChild.parentElement;
}
if (!directChild) return -1;
if (!directChild) {
return -1;
}
// Find DOM child position among container's children
const children = container.children;
@ -1211,7 +1215,9 @@ export const App: React.FC = () => {
useEffect(() => {
const handler = (event: MessageEvent) => {
const message = event.data;
if (message?.type !== 'copyCommand') return;
if (message?.type !== 'copyCommand') {
return;
}
const { action } = message.data as { action: string };
@ -1242,7 +1248,9 @@ export const App: React.FC = () => {
msg.kind === 'image' && msg.imagePath
? `![image](${msg.imagePath})`
: (msg.content || '').trim();
if (!content) continue;
if (!content) {
continue;
}
if (msg.role === 'user') {
parts.push(`**User:** ${content}`);
} else if (msg.role === 'thinking') {
@ -1255,7 +1263,9 @@ export const App: React.FC = () => {
item.type === 'in-progress-tool-call'
) {
const tc = item.data as ToolCallData;
if (!shouldShowToolCall(tc.kind)) continue;
if (!shouldShowToolCall(tc.kind)) {
continue;
}
const text = formatToolCallForCopy(tc, true);
if (text) {
parts.push(`**[Tool: ${tc.kind}]**\n\n${text}`);

View file

@ -1737,9 +1737,13 @@ export class WebViewProvider {
* The webview resolves the content and posts back a 'copyToClipboard' message.
*/
sendCopyCommand(action: string): boolean {
if (WebViewProvider.lastContextMenuProvider !== this) return false;
if (WebViewProvider.lastContextMenuProvider !== this) {
return false;
}
const webview = this.getActiveWebview();
if (!webview) return false;
if (!webview) {
return false;
}
webview.postMessage({ type: 'copyCommand', data: { action } });
return true;
}