Skip to content

chore: fix build and test setup in shadow-agent#43

Merged
Coldaine merged 1 commit into
mainfrom
jules-8219488336156373328-7a643538
May 8, 2026
Merged

chore: fix build and test setup in shadow-agent#43
Coldaine merged 1 commit into
mainfrom
jules-8219488336156373328-7a643538

Conversation

@Coldaine

@Coldaine Coldaine commented Apr 26, 2026

Copy link
Copy Markdown
Owner

User description

This fixes the build and test setup by running tsc type check alongside vitest in the test npm script. Also fixes all existing typescript type check errors on main.

PR created automatically by Jules for task 8219488336156373328 started by @Coldaine

Overview

This PR updates the build and test setup for the shadow-agent package to enforce TypeScript type-checking during tests, and fixes all associated type-check errors that were preventing compilation.

Changes

Test Configuration

File Change
package.json Updated test script to run tsc --noEmit before vitest run to enforce TypeScript type-checking alongside unit tests
tsconfig.json Enabled JavaScript file inclusion (allowJs: true) and expanded compilation scope to include scripts directory alongside src and tests

Type-Check Error Fixes

File Issue & Fix
src/electron/start-main-process.ts Async handling: Changed getState to treat currentSessionManager.getBuffer().getAll() as a thenable via events.then(...) instead of synchronous derivation
src/inference/direct-api.ts Type suppression: Switched from // @ts-expect-error to // @ts-ignore in loadAnthropicSdk to suppress type-checking errors
src/inference/shadow-inference-engine.ts Null safety: Added non-null assertions (!) to buffer.readPending(), buffer.commitCheckpoint(), and buffer.registerConsumer() method calls
tests/prompt-generation.test.ts Import suppression: Added // @ts-ignore directive to suppress type-checking errors for import from ../scripts/prompt-generation.mjs

Summary

The PR establishes TypeScript type-checking as a required part of the test pipeline and resolves the blocking type errors across the codebase through targeted fixes: handling Promise-based flows, enabling JavaScript compilation support, adjusting null-handling assertions, and selectively suppressing unavoidable type errors.


CodeAnt-AI Description

Enforce type checks during tests and fix the blocking build errors

What Changed

  • Test runs now stop if TypeScript errors are present, so broken code is caught before tests finish
  • Type checking now includes the scripts folder and JavaScript files used by the project
  • Fixed the code paths that were preventing the project from compiling and running tests cleanly
  • Kept prompt-generation tests and optional SDK loading compatible with type checking

Impact

✅ Fewer broken test runs
✅ Earlier build failures for type errors
✅ Cleaner setup for scripts and prompt tests

🔄 Retrigger CodeAnt AI Review

Details

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings April 26, 2026 10:42
@codeant-ai

codeant-ai Bot commented Apr 26, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.

@coderabbitai

coderabbitai Bot commented Apr 26, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The pull request adds TypeScript type-checking to the test pipeline, updates tsconfig to include JavaScript files and the scripts directory, modifies type suppression directives, adds non-null assertions to buffer method calls, and shifts getState to handle promise-based values asynchronously.

Changes

Cohort / File(s) Summary
Build & TypeScript Configuration
package.json, tsconfig.json
Test script now runs tsc --noEmit before Vitest. TypeScript configured to allow JavaScript sources and include scripts directory in compilation scope.
Type Suppression Updates
src/inference/direct-api.ts, tests/prompt-generation.test.ts
Changed TypeScript suppression directives from @ts-expect-error to @ts-ignore and added suppression for module import type-checking.
Async Flow & Buffer Safety
src/electron/start-main-process.ts
getState now handles promise-based values from buffer via .then(), shifting from synchronous to asynchronous control flow.
Non-null Assertions
src/inference/shadow-inference-engine.ts
Added non-null assertions to buffer.readPending, buffer.commitCheckpoint, and buffer.registerConsumer method calls for type safety.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

A rabbit hops through types with care, ✨
Adding checks to keep it fair,
Promises now flow with grace,
TypeScript runs the testing race,
Scripts included in the compile,
Safer code that makes us smile! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: fix build and test setup in shadow-agent' accurately summarizes the main changes: updating the test npm script to run TypeScript type-checking before vitest and fixing TypeScript type-check errors throughout the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jules-8219488336156373328-7a643538

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codeant-ai codeant-ai Bot added the size:XS This PR changes 0-9 lines, ignoring generated files label Apr 26, 2026
@codeant-ai

codeant-ai Bot commented Apr 26, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shadow-agent/src/inference/shadow-inference-engine.ts (1)

52-55: 🧹 Nitpick | 🔵 Trivial

Non-null assertions are safe given the runtime guard, but capturing typed references would be cleaner and more refactor-resilient.

The supportsBufferedDrain boolean (L52-55) gates each ! assertion, so behavior is correct today. The risk is fragility: if anyone later modifies the guard or invokes these paths outside start()/drainPendingEvents, the assertions silently lie to the type system. Capturing the methods after the narrow guard removes the need for ! and lets TypeScript verify the contract.

♻️ Optional refactor — narrow once, reuse the typed refs
-  const supportsBufferedDrain =
-    typeof buffer.registerConsumer === 'function' &&
-    typeof buffer.readPending === 'function' &&
-    typeof buffer.commitCheckpoint === 'function';
+  const bufferedDrain =
+    buffer.registerConsumer && buffer.readPending && buffer.commitCheckpoint
+      ? {
+          registerConsumer: buffer.registerConsumer.bind(buffer),
+          readPending: buffer.readPending.bind(buffer),
+          commitCheckpoint: buffer.commitCheckpoint.bind(buffer),
+        }
+      : null;
@@
-        const pending = await buffer.readPending!(INFERENCE_CONSUMER_ID);
+        const pending = await bufferedDrain!.readPending(INFERENCE_CONSUMER_ID);
@@
-        await buffer.commitCheckpoint!(INFERENCE_CONSUMER_ID, pending.events.at(-1)!.id);
+        await bufferedDrain!.commitCheckpoint(INFERENCE_CONSUMER_ID, pending.events.at(-1)!.id);
@@
-        await buffer.registerConsumer!(INFERENCE_CONSUMER_ID, { startAt: 'latest' });
+        await bufferedDrain.registerConsumer(INFERENCE_CONSUMER_ID, { startAt: 'latest' });

(Then check if (bufferedDrain) { ... } instead of supportsBufferedDrain.)

Also applies to: 112-112, 118-118, 148-148

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shadow-agent/src/inference/shadow-inference-engine.ts` around lines 52 - 55,
The boolean guard supportsBufferedDrain should be replaced with captured, typed
references to the buffer methods to avoid non-null assertions: after confirming
typeof buffer.registerConsumer/readPending/commitCheckpoint === 'function',
assign them to local constants (eg. const registerConsumer =
buffer.registerConsumer; const readPending = buffer.readPending; const
commitCheckpoint = buffer.commitCheckpoint;) and use those locals in start(),
drainPendingEvents and any other places (instead of buffer.registerConsumer!
etc.) and check the presence of the grouped ref (e.g., if (readPending) { ... })
so TypeScript enforces the contract without `!`; update the usages referenced in
the review (lines around the current supportsBufferedDrain and the occurrences
at the other noted sites) to use these captured refs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shadow-agent/package.json`:
- Line 15: The coverage script currently bypasses the TypeScript gate; update
the package.json "test:coverage" script to run the same type-check guard as
"test" by prefixing it with tsc --noEmit && so that it runs the type check
before invoking Vitest's coverage (i.e., ensure the "test:coverage" script
composes tsc --noEmit && <existing vitest coverage command>), keeping the
existing coverage arguments intact.

In `@shadow-agent/src/inference/direct-api.ts`:
- Around line 45-46: The current suppression uses `@ts-ignore` for the dynamic
import cast; change it to `@ts-expect-error` and add a short explanatory comment
explaining that we're suppressing a TS error specifically for the return-type
cast of the dynamic import of '@anthropic-ai/sdk' (a required runtime
dependency), referencing the cast to Promise<{ default: AnthropicSdkConstructor
}>; update the comment near the import expression in direct-api.ts so future
reviewers know this is intentionally scoped to the cast rather than silencing
all TypeScript errors.

In `@shadow-agent/tests/prompt-generation.test.ts`:
- Line 6: Replace the "// `@ts-ignore`" directive in prompt-generation.test.ts
with an "@ts-expect-error" plus a short reason explaining that the imported .mjs
lacks type declarations (following the pattern used in
shadow-agent/src/mcp/shadow-mcp-server.ts); this will document the expected
error and allow TypeScript to alert if the underlying type issue is later fixed.

In `@shadow-agent/tsconfig.json`:
- Line 6: The tsconfig currently enables "allowJs": true which pulls scripts/ JS
files into the project but leaves "checkJs" implicit; explicitly set "checkJs"
in tsconfig.json to document the intended behavior—add "checkJs": false if you
want only syntax/parse validation for .js/.mjs files, or set "checkJs": true if
you want full type-checking of those script files (adjust accordingly alongside
"allowJs" and the existing include patterns).

---

Outside diff comments:
In `@shadow-agent/src/inference/shadow-inference-engine.ts`:
- Around line 52-55: The boolean guard supportsBufferedDrain should be replaced
with captured, typed references to the buffer methods to avoid non-null
assertions: after confirming typeof
buffer.registerConsumer/readPending/commitCheckpoint === 'function', assign them
to local constants (eg. const registerConsumer = buffer.registerConsumer; const
readPending = buffer.readPending; const commitCheckpoint =
buffer.commitCheckpoint;) and use those locals in start(), drainPendingEvents
and any other places (instead of buffer.registerConsumer! etc.) and check the
presence of the grouped ref (e.g., if (readPending) { ... }) so TypeScript
enforces the contract without `!`; update the usages referenced in the review
(lines around the current supportsBufferedDrain and the occurrences at the other
noted sites) to use these captured refs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4b6ccbb7-aa0c-4ddd-b2d9-6aa415b92590

📥 Commits

Reviewing files that changed from the base of the PR and between 353b55b and 95bf905.

📒 Files selected for processing (6)
  • shadow-agent/package.json
  • shadow-agent/src/electron/start-main-process.ts
  • shadow-agent/src/inference/direct-api.ts
  • shadow-agent/src/inference/shadow-inference-engine.ts
  • shadow-agent/tests/prompt-generation.test.ts
  • shadow-agent/tsconfig.json

Comment thread shadow-agent/package.json
"prepare": "npm --prefix .. run hooks:install",
"start": "electron dist-electron/main.cjs",
"test": "vitest run",
"test": "tsc --noEmit && vitest run",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

LGTM — gating tests on tsc --noEmit is a sensible safeguard.

The short-circuit behavior of && ensures Vitest only runs after a clean type check, matching the PR objective. Note that test:coverage (line 16) still bypasses the type check; consider mirroring the gate there too if coverage runs are expected to validate the same correctness baseline.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shadow-agent/package.json` at line 15, The coverage script currently bypasses
the TypeScript gate; update the package.json "test:coverage" script to run the
same type-check guard as "test" by prefixing it with tsc --noEmit && so that it
runs the type check before invoking Vitest's coverage (i.e., ensure the
"test:coverage" script composes tsc --noEmit && <existing vitest coverage
command>), keeping the existing coverage arguments intact.

Comment on lines +45 to 46
// @ts-ignore
return import('@anthropic-ai/sdk') as Promise<{ default: AnthropicSdkConstructor }>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the SDK's published export shape to see if the cast/suppression is still warranted.
fd -e json package.json shadow-agent --max-depth 2
rg -nP '"@anthropic-ai/sdk"' shadow-agent/package.json
# Look for type declarations
fd -t f -e d.ts . node_modules/@anthropic-ai/sdk 2>/dev/null | head
rg -nP '\bexport\s+(default|=)' -g '*.d.ts' --max-count 3 node_modules/@anthropic-ai/sdk 2>/dev/null

Repository: Coldaine/AgentVisualCrazy

Length of output: 134


🏁 Script executed:

# Read the full context of the function and surrounding code in direct-api.ts
cat -n shadow-agent/src/inference/direct-api.ts | head -60

Repository: Coldaine/AgentVisualCrazy

Length of output: 2287


🏁 Script executed:

# Check the cited convention in shadow-mcp-server.ts around lines 38-44
cat -n shadow-agent/src/mcp/shadow-mcp-server.ts | sed -n '30,50p'

Repository: Coldaine/AgentVisualCrazy

Length of output: 1234


🏁 Script executed:

# Search for `@ts-expect-error` patterns in the codebase to confirm convention
rg -n '@ts-expect-error' shadow-agent/src/ -A 1

Repository: Coldaine/AgentVisualCrazy

Length of output: 677


🏁 Script executed:

# Search for `@ts-ignore` patterns to see if both are used
rg -n '@ts-ignore' shadow-agent/src/ -A 1

Repository: Coldaine/AgentVisualCrazy

Length of output: 260


🏁 Script executed:

# Check what AnthropicSdkConstructor is and where it's defined
rg -n 'AnthropicSdkConstructor' shadow-agent/src/ -B 2 -A 2

Repository: Coldaine/AgentVisualCrazy

Length of output: 1508


Avoid downgrading @ts-expect-error to @ts-ignore; restore consistency with codebase convention.

This change weakens type-check coverage rather than strengthening it. Two concerns:

  1. @ts-ignore silently suppresses any error, including ones introduced later. The established codebase convention is @ts-expect-error with an explanatory comment — see shadow-agent/src/mcp/shadow-mcp-server.ts:41–44, which uses the same pattern for optional dependency imports.
  2. @anthropic-ai/sdk is a declared runtime dependency (package.json L21), so this suppression is unusual. The cast itself (dynamic import return shape) is likely the source of the error rather than module resolution.

Replace @ts-ignore with @ts-expect-error and add an explanatory comment. Since this is a required (not optional) dependency, adjust the comment accordingly:

♻️ Suggested change
 async function loadAnthropicSdk(): Promise<{ default: AnthropicSdkConstructor }> {
-  // `@ts-ignore`
-  return import('@anthropic-ai/sdk') as Promise<{ default: AnthropicSdkConstructor }>;
+  // `@ts-expect-error` — dynamic import return shape requires cast to expected interface
+  return import('@anthropic-ai/sdk') as Promise<{ default: AnthropicSdkConstructor }>;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// @ts-ignore
return import('@anthropic-ai/sdk') as Promise<{ default: AnthropicSdkConstructor }>;
// `@ts-expect-error` — dynamic import return shape requires cast to expected interface
return import('@anthropic-ai/sdk') as Promise<{ default: AnthropicSdkConstructor }>;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shadow-agent/src/inference/direct-api.ts` around lines 45 - 46, The current
suppression uses `@ts-ignore` for the dynamic import cast; change it to
`@ts-expect-error` and add a short explanatory comment explaining that we're
suppressing a TS error specifically for the return-type cast of the dynamic
import of '@anthropic-ai/sdk' (a required runtime dependency), referencing the
cast to Promise<{ default: AnthropicSdkConstructor }>; update the comment near
the import expression in direct-api.ts so future reviewers know this is
intentionally scoped to the cast rather than silencing all TypeScript errors.

import path from 'node:path';
import { describe, expect, it } from 'vitest';

// @ts-ignore

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm whether the suppression is still required after the tsconfig changes.
fd -e mjs prompt-generation
cat shadow-agent/tsconfig.json
# Try a dry parse: list any .d.ts adjacent to the .mjs source
fd -e d.ts prompt-generation

Repository: Coldaine/AgentVisualCrazy

Length of output: 741


🏁 Script executed:

# 1. Read the test file to see the import and context
cat -n shadow-agent/tests/prompt-generation.test.ts | head -20

Repository: Coldaine/AgentVisualCrazy

Length of output: 826


🏁 Script executed:

# 2. Check the shadow-mcp-server.ts file for the `@ts-expect-error` convention reference
cat -n shadow-agent/src/mcp/shadow-mcp-server.ts | sed -n '35,50p'

Repository: Coldaine/AgentVisualCrazy

Length of output: 1095


🏁 Script executed:

# 3. Search for other uses of `@ts-ignore` vs `@ts-expect-error` in the codebase
rg '@ts-ignore|@ts-expect-error' shadow-agent/src shadow-agent/tests --type ts --type tsx -n

Repository: Coldaine/AgentVisualCrazy

Length of output: 97


🏁 Script executed:

# Fix the rg search - avoid problematic file type flags
rg '@ts-ignore|@ts-expect-error' shadow-agent/src shadow-agent/tests -n --no-heading

Repository: Coldaine/AgentVisualCrazy

Length of output: 452


🏁 Script executed:

# Check if there are TypeScript declaration files or type definitions for the prompt-generation module
find shadow-agent/scripts -type f -name "*prompt*" | head -20

Repository: Coldaine/AgentVisualCrazy

Length of output: 193


🏁 Script executed:

# Check if prompt-generation.mjs is a build/generated file
head -10 shadow-agent/scripts/prompt-generation.mjs

# Also check direct-api.ts context around line 45 to see the pattern
cat -n shadow-agent/src/inference/direct-api.ts | sed -n '40,50p'

Repository: Coldaine/AgentVisualCrazy

Length of output: 900


🏁 Script executed:

# Check if these .mjs files are in .gitignore (indicating they're generated)
cat shadow-agent/.gitignore 2>/dev/null | grep -E '\.mjs|scripts' || echo "No .gitignore entries found for .mjs files"

Repository: Coldaine/AgentVisualCrazy

Length of output: 85


Use @ts-expect-error with a brief reason instead of @ts-ignore.

The .mjs file has no type declarations (as reflected in the .gitignore policy for scripts/*.d.mts). Using @ts-expect-error with a documented reason follows the project convention established in shadow-agent/src/mcp/shadow-mcp-server.ts and allows TypeScript to flag the directive if the underlying error is ever resolved.

♻️ Suggested change
-// `@ts-ignore`
+// `@ts-expect-error` — .mjs has no .d.ts; checked at runtime only
 import {
   buildFullPrompt,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// @ts-ignore
// `@ts-expect-error` — .mjs has no .d.ts; checked at runtime only
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shadow-agent/tests/prompt-generation.test.ts` at line 6, Replace the "//
`@ts-ignore`" directive in prompt-generation.test.ts with an "@ts-expect-error"
plus a short reason explaining that the imported .mjs lacks type declarations
(following the pattern used in shadow-agent/src/mcp/shadow-mcp-server.ts); this
will document the expected error and allow TypeScript to alert if the underlying
type issue is later fixed.

"useDefineForClassFields": true,
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"allowJs": false,
"allowJs": true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Scope expansion is reasonable; consider whether checkJs should be explicit.

allowJs: true plus include: ["src", "tests", "scripts"] will pull every .js/.mjs under scripts/ into the type-check graph. With checkJs left at its default (false), JS files get only syntax/parse validation, which is likely the intent here. If you ever want type-checking of the scripts (they look like the source of truth for prompt generation), set "checkJs": true explicitly so the behavior is documented. Otherwise the current setup is fine.

Also applies to: 24-24

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shadow-agent/tsconfig.json` at line 6, The tsconfig currently enables
"allowJs": true which pulls scripts/ JS files into the project but leaves
"checkJs" implicit; explicitly set "checkJs" in tsconfig.json to document the
intended behavior—add "checkJs": false if you want only syntax/parse validation
for .js/.mjs files, or set "checkJs": true if you want full type-checking of
those script files (adjust accordingly alongside "allowJs" and the existing
include patterns).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the shadow-agent project’s build/test workflow to include a TypeScript type-check step and resolves existing type errors uncovered by running tsc alongside the test suite.

Changes:

  • Run tsc --noEmit as part of npm test before vitest run.
  • Adjust TypeScript config to include scripts/ in the typecheck scope (and allow JS inputs).
  • Fix type errors in inference + main process wiring (buffer optional methods; async event retrieval).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
shadow-agent/tsconfig.json Expands compilation scope to scripts/ and allows JS so tsc can cover tooling files.
shadow-agent/package.json Updates test script to run tsc --noEmit before vitest.
shadow-agent/tests/prompt-generation.test.ts Adds suppression to import prompt-generation script from .mjs.
shadow-agent/src/inference/shadow-inference-engine.ts Addresses TS optional-method typing for buffered drain APIs via non-null assertions.
shadow-agent/src/inference/direct-api.ts Changes TS suppression on dynamic import of Anthropic SDK.
shadow-agent/src/electron/start-main-process.ts Fixes getState to derive state after getAll() promise resolves.
Comments suppressed due to low confidence (1)

shadow-agent/tests/prompt-generation.test.ts:13

  • Avoid using // @ts-ignore on the import here; it suppresses all TS errors on the next line and can mask real regressions. Prefer adding a small .d.ts module declaration for ../scripts/prompt-generation.mjs (or converting the script to TS / .mts) so the test can type-check without suppression; if suppression is unavoidable, use // @ts-expect-error with a short reason so the build fails if the underlying issue disappears.
// @ts-ignore
import {
  buildFullPrompt,
  checkPromptArtifacts,
  loadPromptDefinitions,
  renderPromptDocs,
  renderRuntimePrompt,
} from '../scripts/prompt-generation.mjs';

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


async function loadAnthropicSdk(): Promise<{ default: AnthropicSdkConstructor }> {
// @ts-expect-error — @anthropic-ai/sdk is an optional runtime dependency
// @ts-ignore

Copilot AI Apr 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// @ts-ignore is overly broad and also breaks the repo’s established pattern of using // @ts-expect-error — … for optional runtime dependencies (see e.g. src/mcp/shadow-mcp-server.ts). If this import is still expected to error in some environments, switch back to @ts-expect-error with the reason; if it no longer errors, remove the suppression entirely so TypeScript can catch real issues on this line.

Suggested change
// @ts-ignore
// @ts-expect-error — Optional runtime dependency may not be installed in all environments.

Copilot uses AI. Check for mistakes.
Comment on lines +112 to +118
const pending = await buffer.readPending!(INFERENCE_CONSUMER_ID);
if (pending.events.length === 0) {
continue;
}

trigger.onEvents(pending.events);
await buffer.commitCheckpoint(INFERENCE_CONSUMER_ID, pending.events.at(-1)!.id);
await buffer.commitCheckpoint!(INFERENCE_CONSUMER_ID, pending.events.at(-1)!.id);

Copilot AI Apr 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using non-null assertions on readPending/commitCheckpoint/registerConsumer works, but it spreads ! throughout the control flow and weakens type safety. Since you already compute supportsBufferedDrain, consider introducing a small type guard (or a locally narrowed const buffered = buffer as Required<Pick<EventBufferLike, ...>>) inside the supportsBufferedDrain path so these calls don’t need ! and future edits can’t accidentally bypass the runtime check.

Copilot uses AI. Check for mistakes.
@kilo-code-bot

kilo-code-bot Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (6 files)
  • shadow-agent/package.json - Added TypeScript check to test script
  • shadow-agent/src/electron/start-main-process.ts - Fixed async handling in getState
  • shadow-agent/src/inference/direct-api.ts - Changed type suppression directive
  • shadow-agent/src/inference/shadow-inference-engine.ts - Added non-null assertions for buffer methods
  • shadow-agent/tests/prompt-generation.test.ts - Added type ignore for import
  • shadow-agent/tsconfig.json - Enabled JS files and included scripts in compilation

Reviewed by grok-code-fast-1:optimized:free · 104,596 tokens

@Coldaine
Coldaine merged commit 8f2e3a4 into main May 8, 2026
8 checks passed
@Coldaine
Coldaine deleted the jules-8219488336156373328-7a643538 branch May 8, 2026 13:27
@codeant-ai

codeant-ai Bot commented May 10, 2026

Copy link
Copy Markdown

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:XS This PR changes 0-9 lines, ignoring generated files and removed size:XS This PR changes 0-9 lines, ignoring generated files labels May 10, 2026
@codeant-ai

codeant-ai Bot commented May 10, 2026

Copy link
Copy Markdown

Sequence Diagram

This PR updates the shadow-agent test script so that running tests first performs a TypeScript type check over source, tests, and scripts, and only then runs the Vitest test suite.

sequenceDiagram
    participant Dev as Developer
    participant Npm as NPM test script
    participant Tsc as TypeScript compiler
    participant Vitest as Test runner

    Dev->>Npm: Run test
    Npm->>Tsc: Type check project sources
    Tsc-->>Npm: Type check success
    Npm->>Vitest: Run unit tests
    Vitest-->>Dev: Report test results
Loading

Generated by CodeAnt AI


if (supportsBufferedDrain) {
await buffer.registerConsumer(INFERENCE_CONSUMER_ID, { startAt: 'latest' });
await buffer.registerConsumer!(INFERENCE_CONSUMER_ID, { startAt: 'latest' });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This awaited call can reject (e.g., checkpoint persistence/read errors), but start() is invoked fire-and-forget from the main process (void inferenceEngine.start()), so the rejection becomes unhandled. Add local error handling around consumer registration (or handle the returned promise at the call site) so startup failures don't surface as unhandled promise rejections. [possible bug]

Severity Level: Critical 🚨
- ❌ Shadow inference engine startup can fail on checkpoint I/O errors.
- ⚠️ Electron main process experiences unhandled promise rejections.
- ⚠️ Shadow insights feature may silently remain disabled after launch.
Steps of Reproduction ✅
1. Launch the Electron main process so `whenReady()` in
`shadow-agent/src/electron/start-main-process.ts:1-33` runs. In the `ready` handler at
`shadow-agent/src/electron/start-main-process.ts:11-24`, the code constructs an inference
engine via `createInferenceEngine({ buffer: currentSessionManager.getBuffer(), ... })` at
lines 13-22, then calls `void inferenceEngine.start()` at line 23, explicitly discarding
the returned `Promise<void>`.

2. `createInferenceEngine()` in
`shadow-agent/src/inference/shadow-inference-engine.ts:43-170` builds the engine and
defines `start()` at lines 125-168. In `start()`, after loading credentials and creating
the client, it checks `supportsBufferedDrain` at lines 52-55 and, when true, executes
`await buffer.registerConsumer!(INFERENCE_CONSUMER_ID, { startAt: 'latest' });` at line
148.

3. The concrete `buffer` implementation is `EventBuffer` from
`shadow-agent/src/capture/event-buffer.ts:9-23`. Its `registerConsumer()` implementation
at `shadow-agent/src/capture/event-buffer.ts:24-25` delegates to `enqueueMutation(async ()
=> ensureCheckpoint(consumerId, options))`. `ensureCheckpoint()` at
`shadow-agent/src/capture/event-buffer.ts:11-39,300-8` performs filesystem I/O via
`readCheckpointFile(checkpointPath())` and `persistCheckpoints()` (which calls
`writeCheckpointFile` at lines 7-9), any of which can reject on real systems (e.g.,
unreadable or unwritable `persistenceRoot`).

4. When such an error occurs, `buffer.registerConsumer()` rejects its promise, causing
`InferenceEngine.start()`'s returned `Promise<void>` to reject. Because
`start-main-process.ts` invokes `void inferenceEngine.start();` at line 23 without `await`
or `.catch()`, and there is no global `process.on('unhandledRejection', ...)` handler in
the codebase (confirmed by Grep across `**/*.ts`), this rejection surfaces as an unhandled
promise rejection in the Electron main process. In this failure mode, the shadow inference
engine never completes startup (no `engine.started` log at
`shadow-agent/src/inference/shadow-inference-engine.ts:145`), shadow insights remain
disabled, and the runtime logs an unhandled rejection originating from
`buffer.registerConsumer`.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** shadow-agent/src/inference/shadow-inference-engine.ts
**Line:** 148:148
**Comment:**
	*Possible Bug: This awaited call can reject (e.g., checkpoint persistence/read errors), but `start()` is invoked fire-and-forget from the main process (`void inferenceEngine.start()`), so the rejection becomes unhandled. Add local error handling around consumer registration (or handle the returned promise at the call site) so startup failures don't surface as unhandled promise rejections.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai

codeant-ai Bot commented May 10, 2026

Copy link
Copy Markdown

CodeAnt AI finished running the review.

@codeant-ai

codeant-ai Bot commented May 10, 2026

Copy link
Copy Markdown

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:XS This PR changes 0-9 lines, ignoring generated files and removed size:XS This PR changes 0-9 lines, ignoring generated files labels May 10, 2026
@codeant-ai

codeant-ai Bot commented May 10, 2026

Copy link
Copy Markdown

Sequence Diagram

This PR updates the shadow-agent npm test script so that TypeScript type checking (including the scripts directory) runs before Vitest, and tests only execute when the type check succeeds.

sequenceDiagram
    participant Developer
    participant Npm
    participant TypeScript
    participant TestRunner

    Developer->>Npm: Run npm test
    Npm->>TypeScript: Run type check with no emit

    alt Type check fails
        TypeScript-->>Developer: Report type errors and stop
    else Type check passes
        TypeScript-->>Npm: Type check passed
        Npm->>TestRunner: Run unit tests
        TestRunner-->>Developer: Test results
    end
Loading

Generated by CodeAnt AI

@codeant-ai

codeant-ai Bot commented May 10, 2026

Copy link
Copy Markdown

CodeAnt AI finished running the review.

@codeant-ai

codeant-ai Bot commented May 11, 2026

Copy link
Copy Markdown

CodeAnt AI is running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XS This PR changes 0-9 lines, ignoring generated files and removed size:XS This PR changes 0-9 lines, ignoring generated files labels May 11, 2026
@codeant-ai

codeant-ai Bot commented May 11, 2026

Copy link
Copy Markdown

Sequence Diagram

This PR updates the shadow-agent test pipeline so that TypeScript type checking runs before unit tests, including scripts, ensuring tests only run on type-correct code.

sequenceDiagram
    participant Developer
    participant NpmTest
    participant TypeScript
    participant Vitest

    Developer->>NpmTest: Run npm test
    NpmTest->>TypeScript: Type check src tests scripts
    TypeScript-->>NpmTest: Type check success
    NpmTest->>Vitest: Run unit tests
    Vitest-->>Developer: Report test results
Loading

Generated by CodeAnt AI

@codeant-ai

codeant-ai Bot commented May 11, 2026

Copy link
Copy Markdown

CodeAnt AI finished running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai

codeant-ai Bot commented May 11, 2026

Copy link
Copy Markdown

CodeAnt AI is running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XS This PR changes 0-9 lines, ignoring generated files and removed size:XS This PR changes 0-9 lines, ignoring generated files labels May 11, 2026
@codeant-ai

codeant-ai Bot commented May 11, 2026

Copy link
Copy Markdown

Sequence Diagram

This diagram shows how the updated test script now runs TypeScript type checking across source, tests, and scripts before executing unit tests, including tests that import the prompt generation module.

sequenceDiagram
    participant Developer
    participant Npm
    participant TypeScript
    participant TestRunner
    participant PromptScripts

    Developer->>Npm: Run test script
    Npm->>TypeScript: Type check src tests and scripts
    TypeScript-->>Npm: Type check passes
    Npm->>TestRunner: Run unit tests
    TestRunner->>PromptScripts: Import prompt generation module
    TestRunner-->>Developer: Report test results
Loading

Generated by CodeAnt AI

@codeant-ai

codeant-ai Bot commented May 11, 2026

Copy link
Copy Markdown

CodeAnt AI finished running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS This PR changes 0-9 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants