Skip to content

Library + cross-cutting typing debt - #507

Merged
2witstudios merged 9 commits into
masterfrom
typing/lib
Feb 9, 2026
Merged

2witstudios merged 9 commits into
masterfrom
typing/lib

Conversation

@2witstudios

@2witstudios 2witstudios commented Feb 9, 2026 •

Copy link
Copy Markdown
Owner

Summary

Closes #439, #443, #444, #445, #446, #447, #466

Test plan

  • pnpm typecheck passes across monorepo
  • pnpm test — all existing tests pass
  • pnpm --filter web build — web app builds, public/pdf.worker.min.mjs exists
  • PDF viewer loads worker from local path (no network request to unpkg.com)
  • Desktop app builds with pnpm build:desktop
  • AI tool approval states render correctly (approval-requested, approval-responded, output-denied)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • PDF viewer now uses local worker file for improved offline support and performance.
  • Bug Fixes

    • Enhanced error handling in desktop app with consistent, user-friendly error messages across multiple operations.
  • Improvements

    • Strengthened type safety and validation throughout the logging system and file processing pipelines.

2witstudios and others added 7 commits February 8, 2026 19:15
Dead code — only consumed by its own test file. The AI system uses
read_page tool to access page content directly from the database.

Fixes #439

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce JsonValue, LogMetadata (strict), LogInput (caller-facing),
and HttpMethod types. Replace all `any` in logger.ts, logger-browser.ts,
logger-config.ts, logger-database.ts, and activity-tracker.ts.
Type request params with LoggableRequest union (Next.js + Express).
sanitizeData now uses unknown throughout.

Fixes #443

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Page.content: any → string | null (all page content stored as text).
Page.fileMetadata: Record<string, any> → Record<string, JsonValue>.
Validator data params: any → Record<string, unknown>.
PageTypeConfig.defaultContent: () => any → () => string | Record<string, unknown>.
storage-limits existingTx: any → Drizzle transaction type.

Fixes #444

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ntent-store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Viewer imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Feb 9, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@2witstudios has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 19 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This PR comprehensively hardens TypeScript typing across the codebase by replacing permissive any types with unknown, structured type definitions (LogInput, ExtendedToolState, extraction metadata interfaces), implementing centralized error utilities for consistent error handling in desktop IPC, configuring local PDF.js worker delivery, removing unused page content parser functionality, and refining content and file processing signatures.

Changes

Cohort / File(s) Summary
Desktop Error Utilities & Handling
apps/desktop/src/main/error-utils.ts, apps/desktop/src/main/auth-storage.ts, apps/desktop/src/main/index.ts, apps/desktop/src/main/mcp-manager.ts
New centralized error utility module with isNodeError, getErrorMessage, and hasErrorCode helpers; integrated across auth-storage and IPC handlers to replace any error catches with unknown and standardized error message extraction.
Desktop IPC Type Safety
apps/desktop/src/main/ws-client.ts, apps/desktop/src/preload/index.ts
Tightened WebSocket message dynamic property typing from any to unknown; narrowed IPC listener event type from any to Electron.IpcRendererEvent.
Logging Infrastructure & Types
packages/lib/src/logging/logger-types.ts, packages/lib/src/logging/logger-browser.ts, packages/lib/src/logging/logger-config.ts, packages/lib/src/logging/logger-database.ts, packages/lib/src/logging/logger.ts, packages/lib/src/logging/index.ts
New centralized logging types (LogInput, LogMetadata, HttpMethod); updated all logging method signatures and logging helpers from Record<string, any> to LogInput; introduced LoggableRequest union type for Next.js/Express requests; added initializeLogging function.
Activity Tracking
packages/lib/src/monitoring/activity-tracker.ts
Updated all public activity-tracking function signatures to use LogInput instead of any for metadata and context parameters.
File Processing Metadata Types
packages/lib/src/file-processing/file-processor.ts
Introduced structured metadata interfaces (PdfExtractionMetadata, VisionExtractionMetadata, ExtractionContentMetadata) and vision API response types; replaced any metadata typing with the new union types across extractContent, extractPDF, and extractWithAIVision methods.
Processor Type Refinement
apps/processor/src/cache/content-store.ts, apps/processor/src/utils/security.ts
Strengthened type safety in cache metadata normalization by replacing any with unknown and Record<string, unknown>; tightened MIME type checking cast from any to readonly string[].
File & Type Utilities
packages/lib/src/utils/file-security.ts, types/pdf-parse.d.ts
Narrowed type casts in MIME type checking and updated pdf-parse definitions to use Record<string, unknown> instead of any for metadata and callback parameters.
PDF Viewer & Configuration
apps/web/src/components/layout/middle-content/page-views/file/viewers/PDFViewer.tsx, apps/web/next.config.ts, apps/web/.gitignore, apps/web/package.json
Introduced ReactPdfModule typing for dynamically imported react-pdf; switched PDF.js worker configuration from remote unpkg URL to local air-gapped path /pdf.worker.min.mjs; added copy-webpack-plugin and CopyPlugin configuration to bundle the worker file.
AI Tool State Typing
apps/web/src/types/ai-sdk-extensions.ts, apps/web/src/components/ai/ui/confirmation.tsx, apps/web/src/components/ai/ui/tool.tsx
New ExtendedToolState type combining ToolUIPart['state'] with forward-compatible states for AI SDK v6; updated confirmation and tool UI components to use the extended state type; removed associated @ts-expect-error suppressions.
Page & Content Type Deprecation
packages/lib/src/content/page-content-parser.ts, packages/lib/src/__tests__/page-content-parser.test.ts, packages/lib/src/client-safe.ts, packages/lib/src/client.ts, packages/lib/src/content/index.ts
Removed unused getPageContentForAI module and entire test suite (479 lines); removed re-exports from public API surfaces.
Page Validation & Type Refinement
packages/lib/src/content/page-type-validators.ts, packages/lib/src/content/page-types.config.ts, packages/lib/src/types.ts
Updated validation and config function signatures from any to Record<string, unknown> and string | Record<string, unknown>; introduced JsonPrimitive and JsonValue types; refined Page.content type from any to string | null.
Storage Type Precision
packages/lib/src/services/storage-limits.ts
Tightened updateStorageUsage transaction parameter typing from any to constrained transaction type derived from db.transaction.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Poem

A rabbit hops through code so fine,
Replacing any with types divine,
Where unknown flows and types align,
The PDF worker hops offline—
No more errors—tests gone—just ExtendedToolState to align! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Library + cross-cutting typing debt' directly reflects the PR's main objective to reduce TypeScript typing debt across multiple packages and files.
Linked Issues check ✅ Passed The PR fully addresses issue #439 by removing the unused getPageContentForAI parser, its tests, and related exports, aligning with the objective to deprecate/remove the function when it lacks owned runtime usage.
Out of Scope Changes check ✅ Passed All changes are in-scope with PR objectives: type debt reduction, dead code removal, error-utils helpers, file-processing typing, and PDF.js worker bundling are all documented goals.
Docstring Coverage ✅ Passed Docstring coverage is 82.14% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch typing/lib

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
packages/lib/src/content/page-type-validators.ts (1)

117-123: ⚠️ Potential issue | 🔴 Critical

Fix type error: unknown cannot be passed to string parameter without type narrowing.

Line 119 passes data.content (type unknown) to isValidSheetContent(content: string) without checking the type first. With strict: true enabled in tsconfig, this fails TypeScript type checking. The validatePageUpdate function (lines 193–196) shows the correct pattern: use a typeof check to narrow the type to string before calling isValidSheetContent.

🔧 Proposed fix
     case PageType.SHEET:
-      if (data.content) {
-        if (!isValidSheetContent(data.content)) {
+      if (typeof data.content === 'string' && data.content) {
+        if (!isValidSheetContent(data.content)) {
           errors.push('Invalid sheet content');
         }
       }
🤖 Fix all issues with AI agents
In `@apps/web/package.json`:
- Line 132: The package.json entry for "copy-webpack-plugin" is causing CI
failures because the lockfile is out of sync; run pnpm install to regenerate
pnpm-lock.yaml and commit the updated lockfile, and ensure the dependency is
present in the lockfile. Also reorder the "copy-webpack-plugin" key in
apps/web/package.json so it is alphabetically before the eslint* entries to
match the repo's sort convention (i.e., move the "copy-webpack-plugin" line to
the correct spot in the dependencies/devDependencies list).

In `@packages/lib/src/content/page-types.config.ts`:
- Line 25: getDefaultContent's declared return is string but it currently
returns a value typed string | Record<string, unknown> (the local variable
content); add a runtime type check in getDefaultContent to ensure you only
return a string: if typeof content === 'string' return it, otherwise convert the
object branch to a string (e.g. JSON.stringify(content) or otherwise serialize)
or throw an explicit error—modify the return so the function always returns a
string and update any early returns to use the same check for the content
variable.
🧹 Nitpick comments (17)
apps/processor/src/utils/security.ts (1)

101-107: Consider importing DANGEROUS_MIME_TYPES from the shared lib instead of redeclaring.

An identical DANGEROUS_MIME_TYPES constant exists in packages/lib/src/utils/file-security.ts (lines 38-44). Re-exporting from the lib package would eliminate the duplication and ensure both stay in sync if the list ever changes.

packages/lib/src/utils/file-security.ts (1)

39-45: Nit: DANGEROUS_MIME_TYPES is duplicated in apps/processor/src/utils/security.ts.

The same constant (identical values and as const) exists in apps/processor/src/utils/security.ts (lines 100-106). Since this file already lives in the shared @pagespace/lib package, the processor could import from here to avoid drift.

packages/lib/src/services/storage-limits.ts (1)

186-188: Good: eliminates any for the transaction parameter. Consider extracting a type alias to reduce repetition and improve readability.

♻️ Optional: extract a type alias
+type DbTransaction = Parameters<Parameters<typeof db.transaction>[0]>[0];
+
 export async function updateStorageUsage(
   userId: string,
   deltaBytes: number,
   context?: {
     pageId?: string;
     driveId?: string;
     eventType?: 'upload' | 'delete' | 'update' | 'reconcile';
   },
-  existingTx?: Parameters<Parameters<typeof db.transaction>[0]>[0]
+  existingTx?: DbTransaction
 ): Promise<void> {
-  const executeUpdate = async (tx: Parameters<Parameters<typeof db.transaction>[0]>[0]) => {
+  const executeUpdate = async (tx: DbTransaction) => {

If this transaction type is used elsewhere in the codebase (e.g., other files accepting an optional tx), consider exporting it from @pagespace/db for reuse.

packages/lib/src/file-processing/file-processor.ts (3)

8-23: Record<string, unknown> in the union neutralises the discriminated union.

Because every object is assignable to Record<string, unknown>, including it in ExtractionContentMetadata means the compiler can never narrow to PdfExtractionMetadata or VisionExtractionMetadata via the method discriminant. This limits the value of the new interfaces for any downstream consumer.

Consider replacing the catch-all with a small TextExtractionMetadata (or similar) that covers the remaining method literals ('mammoth' | 'direct' | 'text-by-extension'), plus an UnsupportedTypeMetadata for the default branch. That way the union is fully discriminated on method and callers get exhaustive narrowing.

♻️ Sketch
+interface TextExtractionMetadata {
+  method: 'mammoth' | 'direct' | 'text-by-extension';
+}
+
+interface UnsupportedTypeMetadata {
+  unsupportedType: string;
+}
+
-type ExtractionContentMetadata = PdfExtractionMetadata | VisionExtractionMetadata | Record<string, unknown>;
+type ExtractionContentMetadata =
+  | PdfExtractionMetadata
+  | VisionExtractionMetadata
+  | TextExtractionMetadata
+  | UnsupportedTypeMetadata;

25-27: OpenAI response interface doesn't cover error shapes.

OpenAIVisionResponse assumes choices always exists, but a 200-with-error body (rate-limit soft errors, content-filter refusals) can return { error: { message, type, code } } instead. The optional chaining on line 418 prevents a crash, but the as assertion silently hides the mismatch.

A lightweight guard (e.g. checking 'choices' in data) before accessing the field would make this more robust.


170-175: Local metadata variable widens specific metadata types back to Record<string, unknown>.

On line 184 (metadata = pdfResult.metadata) and line 243 (metadata = ocrResult.metadata), the precisely-typed PdfExtractionMetadata / VisionExtractionMetadata values are immediately widened to Record<string, unknown>, losing the type information the new interfaces provide.

If the union is tightened per the earlier suggestion, this variable's type can become ExtractionContentMetadata directly, preserving specificity through the function body.

apps/processor/src/cache/content-store.ts (2)

349-358: Typing improvement looks correct, but raw entries are not validated as objects.

Line 350's change to Record<string, Record<string, unknown>> is more honest about the parsed JSON shape. However, rawParsed[key] (line 353) is assigned without verifying it's actually an object — if a corrupt metadata file has a primitive value for a preset key, metadata[preset].lastAccessed = … on line 357 would silently fail or produce unexpected serialization.

This is a pre-existing concern, not introduced by this PR, so flagging as optional.

Suggested guard (optional)
         for (const key of Object.keys(rawParsed)) {
           if (isSafePropertyKey(key) && isValidPreset(key)) {
-            metadata[key] = rawParsed[key];
+            const val: unknown = rawParsed[key];
+            if (typeof val === 'object' && val !== null) {
+              metadata[key] = val as Record<string, unknown>;
+            }
           }
         }

504-505: Date fields use a truthy check + as string instead of a typeof guard.

Lines 504–505 check truthiness of entry.createdAt / entry.lastAccessed and then cast as string, but unlike every other field in this method (and in normalizeOriginalMetadata), they skip the typeof check. If a corrupted file has a non-string truthy value (e.g., a number or boolean), new Date(...) may produce an unexpected result.

For consistency with the rest of the file, prefer typeof guards:

Suggested fix
-          createdAt: entry.createdAt ? new Date(entry.createdAt as string) : new Date(0),
-          lastAccessed: entry.lastAccessed ? new Date(entry.lastAccessed as string) : new Date(0)
+          createdAt: typeof entry.createdAt === 'string' ? new Date(entry.createdAt) : new Date(0),
+          lastAccessed: typeof entry.lastAccessed === 'string' ? new Date(entry.lastAccessed) : new Date(0)
apps/web/src/components/ai/ui/confirmation.tsx (1)

15-41: Duplicate union variant in ToolUIPartApproval.

Lines 26-30 and 31-35 define the same variant { id: string; approved: true; reason?: string } twice. One can be removed without any behavioral change.

♻️ Suggested diff
 type ToolUIPartApproval =
   | {
       id: string;
       approved?: never;
       reason?: never;
     }
   | {
       id: string;
       approved: boolean;
       reason?: string;
     }
   | {
       id: string;
       approved: true;
       reason?: string;
     }
-  | {
-      id: string;
-      approved: true;
-      reason?: string;
-    }
   | {
       id: string;
       approved: false;
       reason?: string;
     }
   | undefined;
apps/web/src/components/ai/ui/tool.tsx (1)

38-49: Use Record<ExtendedToolState, ReactNode> for exhaustive key checking.

Record<string, ReactNode> accepts any string and won't flag if a new ExtendedToolState variant is added without a corresponding icon. All seven current variants (input-streaming, input-available, approval-requested, approval-responded, output-available, output-error, output-denied) are covered in the icon map. Switching to Record<ExtendedToolState, ReactNode> ensures TypeScript enforces exhaustive coverage when the union grows, preventing future omissions at compile-time.

Note: With the stricter type, the fallback on line 49 becomes unreachable code and can be simplified to just return icons[status];

♻️ Suggested diff
-  const icons: Record<string, ReactNode> = {
+  const icons: Record<ExtendedToolState, ReactNode> = {
     "input-streaming": <CircleIcon className="size-4 text-muted-foreground" />,
     "input-available": <ClockIcon className="size-4 text-primary animate-pulse" />,
     "approval-requested": <ClockIcon className="size-4 text-yellow-600" />,
     "approval-responded": <CheckCircleIcon className="size-4 text-blue-600" />,
     "output-available": <CheckCircleIcon className="size-4 text-green-600" />,
     "output-error": <XCircleIcon className="size-4 text-red-600" />,
     "output-denied": <XCircleIcon className="size-4 text-orange-600" />,
   };

-  return icons[status] || <CircleIcon className="size-4 text-muted-foreground" />;
+  return icons[status];
apps/desktop/src/main/mcp-manager.ts (1)

172-183: LGTM on the error typing change. The catch (error: unknown) with hasErrorCode is correct.

However, note that getErrorMessage(error) is used here (line 180) but other catch blocks in this same file (e.g., saveConfig at line 206, startServer at line 395, executeTool at line 1056) still inline the same error instanceof Error ? error.message : String(error) pattern. Consider using getErrorMessage consistently throughout the file.

apps/desktop/src/main/index.ts (1)

28-28: Pre-existing as any on electron-store.

Line 28 has as any which conflicts with the coding guideline "Never use any types." This isn't introduced by this PR, but since the PR is specifically about removing any types, it might be worth addressing here. The comment says it works around electron-store v10 type definitions.

apps/desktop/src/main/error-utils.ts (1)

9-11: Redundant cast in hasErrorCode.

After isNodeError(error) narrows the type to Error & { code?: string }, the explicit (error as Error & { code?: string }) cast is unnecessary — error.code is already valid.

♻️ Suggested simplification
 export function hasErrorCode(error: unknown, code: string): boolean {
-  return isNodeError(error) && (error as Error & { code?: string }).code === code;
+  return isNodeError(error) && error.code === code;
 }
packages/lib/src/logging/logger-database.ts (2)

120-142: Unsafe cast: narrow the parameter type instead of casting.

metrics.method is typed as string (line 122) but cast to HttpMethod on line 142. This defeats the purpose of introducing the HttpMethod type — callers can still pass arbitrary strings. Consider typing the parameter as HttpMethod directly.

♻️ Suggested fix
 export async function writeApiMetrics(metrics: {
   endpoint: string;
-  method: string;
+  method: HttpMethod;
   statusCode: number;
   ...

264-291: Same unsafe cast pattern in writeError.

error.method is string? (line 272) but cast to HttpMethod on line 291. Same recommendation: type the parameter as HttpMethod to get compile-time safety at call sites.

packages/lib/src/logging/logger-browser.ts (2)

190-194: Type assertions after sanitizeData are a pragmatic trade-off — consider a brief inline comment.

sanitizeData returns unknown, so the as LogContext (line 190) and as LogInput (line 194) casts are required to satisfy the typed fields. These are safe in practice because sanitizeData preserves the top-level object structure (it only truncates strings and caps nesting depth), but technically the assertion could mask a shape mismatch if sanitization ever replaces a top-level object with a string (e.g., '[Object: max depth exceeded]'). Since context and metadata are always passed at depth=0, this cannot happen today.

A one-line // safe: top-level objects are always preserved by sanitizeData would document the invariant for future readers.


304-320: error and fatal methods: identical discrimination logic — consider extracting a helper.

The error and fatal methods share the exact same instanceof Error discrimination block (lines 307–316 vs 325–334). This is a minor DRY opportunity — a small private helper could deduplicate it. Low priority since there are only two occurrences.

♻️ Optional: extract shared discrimination
+ private splitErrorAndMeta(
+   errorOrMetadata?: Error | LogInput,
+   metadata?: LogInput
+ ): { error: Error | undefined; meta: LogInput | undefined } {
+   if (errorOrMetadata instanceof Error) {
+     return { error: errorOrMetadata, meta: metadata };
+   }
+   return { error: undefined, meta: errorOrMetadata };
+ }
+
  public error(message: string, errorOrMetadata?: Error | LogInput, metadata?: LogInput): void {
    if (!this.shouldLog(LogLevel.ERROR)) return;
-   let error: Error | undefined;
-   let meta: LogInput | undefined;
-   if (errorOrMetadata instanceof Error) {
-     error = errorOrMetadata;
-     meta = metadata;
-   } else {
-     error = undefined;
-     meta = errorOrMetadata;
-   }
-   const entry = this.createLogEntry(LogLevel.ERROR, message, meta, error);
+   const { error, meta } = this.splitErrorAndMeta(errorOrMetadata, metadata);
+   const entry = this.createLogEntry(LogLevel.ERROR, message, meta, error);
    this.output(entry);
  }

Apply the same pattern to fatal.

Also applies to: 322-338

Comment thread apps/web/package.json Outdated
Comment thread packages/lib/src/content/page-types.config.ts
- Reorder copy-webpack-plugin alphabetically in devDependencies and
  regenerate pnpm-lock.yaml (CodeRabbit #1)
- Add runtime typeof guard in getDefaultContent return (CodeRabbit #2)
- Fix WebSocketMessage cast via unknown for ToolExecutionRequest
- Add index signatures to PdfExtractionMetadata/VisionExtractionMetadata
- Guard sheet content validation with typeof string check
- Cast logger-database category field to string | undefined
- Wrap ZodError/Error/MetricsSummary at logger call sites instead of
  passing incompatible types to LogInput (Record<string, unknown>)
- Remove unused ToolUIPart import from confirmation.tsx
- Include root types/ directory in lib, processor, and web tsconfigs
  so pdf-parse-debugging-disabled ambient module resolves in all builds
- Spread PDFInfo to satisfy Record<string, unknown> constraint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@2witstudios

Copy link
Copy Markdown
Owner Author

Addressing Review Feedback (b6f50c5)

CodeRabbit Comment 1 — Lockfile sync + alphabetical ordering (apps/web/package.json)

  • Lockfile: Ran pnpm install — pnpm-lock.yaml now includes copy-webpack-plugin (56 lines added).
  • Alphabetical ordering: Moved copy-webpack-plugin before the eslint* entries in apps/web/package.json:129.

CodeRabbit Comment 2 — getDefaultContent return type (page-types.config.ts:195)

  • Added runtime typeof check: return typeof content === 'string' ? content : JSON.stringify(content); — ensures the function always returns string regardless of which defaultContent() implementation is used.

Additional build fixes

These were surfaced by the lockfile sync enabling full typecheck/build passes:

  • Added root types/ directory to lib, processor, and web tsconfig include arrays so the pdf-parse-debugging-disabled ambient module declaration resolves in all build targets
  • Fixed WebSocketMessage cast via unknown for ToolExecutionRequest in desktop
  • Added index signatures to PdfExtractionMetadata/VisionExtractionMetadata
  • Guarded sheet content validation with typeof string check
  • Cast logger-database category field to string | undefined (from unknown index signature)
  • Wrapped ZodError/Error/MetricsSummary at logger call sites (auth/google/*, model-capabilities, monitoring)
  • Removed unused ToolUIPart import from confirmation.tsx (lint error)
  • Spread PDFInfo to satisfy Record<string, unknown> constraint

Local validation

  • pnpm typecheck: 10/10 tasks pass (db, desktop, lib build+typecheck, processor, realtime, marketing, web build+typecheck)
  • pnpm test (web): 208 files, 3623 tests pass
  • pnpm test (lib): 63/74 pass; 11 failures are all ECONNREFUSED :5432 (no local PostgreSQL) — these are pre-existing integration tests that require a database, not related to our changes

Resolve modify/delete conflict on page-content-parser.ts (keep deleted per #439).
Auto-merged CODE page type additions with our typing improvements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@2witstudios
2witstudios merged commit 7c29371 into master Feb 9, 2026
10 checks passed
@2witstudios
2witstudios deleted the typing/lib branch February 9, 2026 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tech debt: Wire up or deprecate unused getPageContentForAI parser

1 participant