How Magnitude Handles Client Imports and Package Dependencies Between Client and Daemon
Magnitude enforces a strict layered architecture where clients (CLI/web) only import from @magnitudedev/client-common and @magnitudedev/sdk, while all daemon internals remain accessible only via RPC through the SDK.
This article explains how the Magnitude monorepo isolates client-side code from daemon-side processes using import rules, package boundaries, and a single RPC bridge. Understanding this architecture is essential for contributing to the codebase or extending Magnitude with custom clients.
Package Layering Architecture
Magnitude's dependency flow follows a unidirectional hierarchy documented in AGENTS.md:
clients (cli/web) → client-common → sdk → acn (daemon)
This design guarantees that client code cannot accidentally depend on daemon implementation details. The client remains lightweight, portable, and independently testable.
Allowed Client Dependencies
Clients may only import from two packages:
@magnitudedev/client-common— shared UI state, React hooks, and display synchronization@magnitudedev/sdk— the portable Effect-TS RPC client that communicates with the daemon
Prohibited Client Dependencies
The following packages are never imported directly by client code:
acnagentacn-protocolaiproviders
Attempting to import these triggers linting errors and violates the architectural contract.
Dependency Flow by Layer
| Layer | Responsibility | Visible To |
|---|---|---|
| client-common | Maintains shared UI state; defines queries/mutations over the SDK | Clients, SDK |
| sdk | Implements Effect-TS-native RPC client; handles endpoint admission/recovery; optionally starts services | client-common, Clients |
| acn | Hosts agent runtime, session handling, file operations, display streams; implements ACN protocol RPCs | SDK (via RPC only) |
| acn-protocol | Pure wire contracts: RPC signatures, schemas; shared by SDK and ACN but never imported by clients | SDK, ACN |
| providers / agent / internals | Concrete provider implementations, worker projections, tools, storage | Internal daemon only |
The SDK is the sole bridge across the client-daemon boundary. All RPCs are declared once in packages/acn-protocol/src/boundary/ and consumed through the SDK's generated methods.
Enforcing Import Boundaries
Magnitude employs multiple mechanisms to prevent architectural violations:
Static Analysis
Linting rules flag prohibited imports during development. Importing from @magnitudedev/acn or @magnitudedev/providers in client code fails the build.
Runtime Validation
The SDK verifies RPC version compatibility before establishing daemon connections, preventing mismatched client-daemon deployments.
Design Documentation
The cross-boundary ownership model is detailed in design/cross-boundary/client-acn-icn-ownership.md, explaining why only the SDK should handle cross-process communication.
Code Examples: Correct and Incorrect Import Patterns
✅ Correct: Client code using allowed packages
// Client-side code (CLI or web)
import { useDisplayView } from '@magnitudedev/client-common';
import { AgentClient } from '@magnitudedev/sdk';
export const SessionManager = () => {
const display = useDisplayView(); // From client-common
const listSessions = async () => {
const client = await AgentClient.make(); // From sdk
return client.session.list();
};
// ...
};
❌ Incorrect: Client code attempting daemon imports
// These imports would trigger lint errors and architectural violations:
// import { ACNService } from '@magnitudedev/acn';
// import { ProviderRegistry } from '@magnitudedev/providers';
// import { AgentRuntime } from '@magnitudedev/agent';
The SDK abstracts all RPC details. The client calls methods; the SDK handles serialization, transport, and error recovery.
RPC Declaration and Consumption
RPC contracts live in packages/acn-protocol/src/boundary/ and provide single source of truth for remote operations:
// packages/acn-protocol/src/boundary/session.ts (conceptual)
export interface SessionBoundary {
list: Rpc<[], Session[]>;
create: Rpc<[CreateSessionInput], Session>;
// ...
}
The SDK consumes these contracts to generate typed client methods, while packages/acn/ implements the handlers.
Key Files and Their Roles
| Path | Purpose |
|---|---|
AGENTS.md |
High-level package layering and import rules |
design/cross-boundary/client-acn-icn-ownership.md |
Ownership model rationale |
packages/client-common/src/operations/* |
Client-side query/mutation wrappers around SDK |
packages/sdk/src/* |
Effect-TS RPC client implementation |
packages/acn-protocol/src/boundary/* |
Wire contracts (RPC signatures, schemas) |
packages/acn/* |
Daemon RPC handler implementation |
Summary
- Layered architecture (
clients → client-common → sdk → acn) enforces unidirectional dependencies - Two-package rule: clients import only from
@magnitudedev/client-commonand@magnitudedev/sdk - SDK-only bridge: all client-daemon communication routes through the SDK's RPC layer
- Static and runtime enforcement: lint rules and version checks prevent boundary violations
- Single source of truth: RPC contracts in
acn-protocolare shared between SDK and daemon, never directly imported by clients
Frequently Asked Questions
What happens if client code imports from @magnitudedev/acn directly?
The build fails due to linting rules that prohibit cross-boundary imports. Even if bypassed, runtime errors would occur because the client lacks the daemon's execution context and environment dependencies.
Why does the SDK use Effect-TS for its RPC implementation?
Effect-TS provides structured concurrency, built-in error handling, and type-safe composition that Magnitude leverages for reliable client-daemon communication, admission control, and automatic recovery from connection failures.
Can third-party clients interact with the Magnitude daemon?
Yes—any client importing @magnitudedev/sdk can communicate with a running daemon, as the SDK encapsulates all protocol details. The daemon's RPC surface in acn-protocol serves as the stable public API.
How does this architecture support testing?
Clients unit-test with mocked SDK calls without daemon dependencies. The SDK itself tests against stubbed ACN protocols. Integration tests exercise the full stack, but each layer remains independently verifiable.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →