Skip to content

Conversation

@Baz00k
Copy link
Owner

@Baz00k Baz00k commented Jan 15, 2026

No description provided.

Copy link

Copilot AI left a comment

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 introduces a major architectural change to the agent system, replacing the draft-based workflow with a Virtual File System (VFS) that stages changes before applying them. The agent now works with file diffs instead of text drafts, and the reviewer provides feedback through structured comments.

Changes:

  • Introduced VFS service for staging file modifications and generating diffs
  • Refactored agent workflow to use writer/reviewer tools with VFS integration
  • Added theme system with multiple UI themes and diff viewer
  • Implemented session resume/retry functionality
  • Enhanced web fetch with PDF support and binary content detection

Reviewed changes

Copilot reviewed 54 out of 55 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/services/vfs.ts New VFS service for staging file changes and generating diffs
src/services/agent.ts Refactored agent to use VFS-based workflow with session resume
src/tui/hooks/useAgent.ts Changed to global state with useSyncExternalStore
src/tui/theme/index.ts New theme system with GitHub Dark, Monokai, and Dracula themes
src/tui/components/* New DiffReviewModal, DiffView, Sidebar, and updated components
src/tools/vfs.ts New VFS-based file manipulation tools
src/tools/review.ts New reviewer tools for commenting and approving/rejecting
src/services/prompts.ts Updated prompts for VFS-based workflow
src/services/web.ts Added PDF extraction and binary content detection

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

Comment on lines 233 to 242
let globalState: AgentState = { ...initialAgentState };
const listeners = new Set<() => void>();

let globalSession: {
submitUserAction: (action: UserAction) => Effect.Effect<void, unknown>;
cancel: () => Effect.Effect<void>;
fiber: Fiber.RuntimeFiber<void, unknown> | null;
} | null = null;

let globalLastRunOptions: RunOptions | null = null;
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

Using global mutable state in React hooks creates race conditions when multiple instances exist or components unmount/remount. This violates React's rules of hooks and can lead to memory leaks. Consider using React Context or a proper state management solution instead of module-level globals.

Copilot uses AI. Check for mistakes.
Comment on lines +382 to +384
const step = Effect.fn("step")(function* (
currentCycle: number,
): Effect.fn.Return<
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

The step function is recursive (line 578: return yield* step(cycle) and line 608) without a clear base case at the function signature level. While there is an iteration limit check at line 409, the recursive pattern makes the code harder to follow. Consider refactoring to use an iterative loop with explicit continuation conditions.

Copilot uses AI. Check for mistakes.
}

return yield* Effect.fail(new UserDirError({ message: "Could not determine config directory" }));
return yield* new UserDirError({ message: "Could not determine config directory" });
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

This changed from Effect.fail(new UserDirError(...)) to yield* new UserDirError(...). The new syntax is incorrect - you cannot yield from a Data.TaggedError instance. This will cause a runtime error. Should be return yield* Effect.fail(new UserDirError(...)).

Copilot uses AI. Check for mistakes.
}

return yield* Effect.fail(new UserDirError({ message: "Could not determine data directory" }));
return yield* new UserDirError({ message: "Could not determine data directory" });
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

Same issue as line 27 - incorrect Effect error handling syntax. Should be return yield* Effect.fail(new UserDirError(...)).

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +55
return yield* new FileReadError({
cause: "Access denied",
message: `Access denied: ${resolved} is outside of ${cwd}`,
});
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

Incorrect Effect error handling syntax - cannot yield from error constructor. Should be return yield* Effect.fail(new FileReadError(...)).

Suggested change
return yield* new FileReadError({
cause: "Access denied",
message: `Access denied: ${resolved} is outside of ${cwd}`,
});
return yield* Effect.fail(
new FileReadError({
cause: "Access denied",
message: `Access denied: ${resolved} is outside of ${cwd}`,
}),
);

Copilot uses AI. Check for mistakes.
Comment on lines +289 to +292
return yield* new AgentStreamError({
message: "Prompt is required for new sessions",
cause: new Error("Missing prompt"),
});
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

Incorrect Effect error handling - yielding from error constructor instead of Effect.fail. Should be return yield* Effect.fail(new AgentStreamError(...)).

Suggested change
return yield* new AgentStreamError({
message: "Prompt is required for new sessions",
cause: new Error("Missing prompt"),
});
return yield* Effect.fail(
new AgentStreamError({
message: "Prompt is required for new sessions",
cause: new Error("Missing prompt"),
}),
);

Copilot uses AI. Check for mistakes.
export const ANTIGRAVITY_ENDPOINT_SANDBOX = "https://daily-cloudcode-pa.sandbox.googleapis.com";

export const ANTIGRAVITY_DEFAULT_ENDPOINT = ANTIGRAVITY_ENDPOINT_DAILY;
export const ANTIGRAVITY_DEFAULT_ENDPOINT = ANTIGRAVITY_ENDPOINT_SANDBOX;
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

Changed from DAILY to SANDBOX endpoint. This appears to be a configuration change that should not be committed to the main branch as it affects the production behavior. Consider using environment variables for endpoint selection.

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +19
const command = Command.make("jot", {}, () =>
Effect.tryPromise({
try: () => startTUI(),
catch: (error) => new TUIStartupError({ cause: error, message: `Failed to start TUI: ${error}` }),
}),
).pipe(
Command.withSubcommands([writeCommand, configCommand, antigravityCommand]),
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

The default command now always starts the TUI. The removed auth command is no longer accessible. If this is intentional, ensure users have an alternative way to authenticate.

Copilot uses AI. Check for mistakes.
Baz00k added 26 commits January 17, 2026 12:24
This commit fixes a bug where resuming a session would reset the VFS
because the agent loop started from cycle 0 instead of the saved cycle
count. It also refactors the Session service to reuse logic and adds a
regression test.
@Baz00k Baz00k force-pushed the feat/improved-agent branch from 1f44609 to 7c21a85 Compare January 17, 2026 11:24
@Baz00k Baz00k marked this pull request as ready for review January 17, 2026 12:01
@Baz00k Baz00k merged commit 53f6ce5 into master Jan 17, 2026
1 check passed
@Baz00k Baz00k deleted the feat/improved-agent branch January 17, 2026 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants