Part of #70. See ADR 0021.
Purpose
Export a supported TypeScript client for the local Simlock daemon.
The current client is private. Its generic request method returns Promise<unknown>.
Host must not import files from src/ or start a command process.
Proposed API
The names can change. The public contract must give equivalent typed operations.
export interface ConnectSimlockOptions {
socketPath: string;
startDaemon: boolean;
protocol: { min: number; max: number };
}
export interface ConnectSimlockAdminOptions extends ConnectSimlockOptions {
credential: string;
}
export interface SimlockClient {
protocol: ProtocolInfo;
listCatalog(input?: { platform?: Platform }): Promise<PlatformCatalog[]>;
getStatus(): Promise<DaemonStatus>;
runDoctor(): Promise<DoctorReport>;
renewLease(input: { leaseId: string; ttlMs?: number }): Promise<Lease>;
releaseLease(input: { leaseId: string }): Promise<void>;
close(): Promise<void>;
}
export interface SimlockAdminClient extends SimlockClient {
// Admin operations from later issues extend this interface.
}
export function connectSimlock(
options: ConnectSimlockOptions,
): Promise<SimlockClient>;
export function connectSimlockAdmin(
options: ConnectSimlockAdminOptions,
): Promise<SimlockAdminClient>;
Host will use startDaemon: false. Its supervisor will control the daemon process.
Required behavior
- Export the clients from a supported package entry point.
- Keep the Unix socket as the transport.
- Keep support for an explicit socket path.
- Keep request ID multiplexing on one connection.
- Parse each public result before the client returns it.
- Return typed Simlock errors. Do not expose
unknown payloads.
- Test protocol compatibility during connection.
- Reject an incompatible version before a mutation starts.
- Authenticate the admin client with a daemon-configured credential before it can call an admin method.
- Reject a missing or invalid admin credential before a mutation starts.
- Do not infer admin authority from the socket path or a client-declared role.
- Do not return or log the admin credential.
- Keep private daemon and core types out of the package export.
- Keep existing socket-based frontends on this client implementation.
Use a stable error for protocol mismatch:
interface ProtocolVersionError {
code: "PROTOCOL_VERSION_UNSUPPORTED";
client: { min: number; max: number };
daemon: { min: number; max: number };
}
Use a stable error for an invalid admin credential:
interface AdminAuthenticationError {
code: "ADMIN_AUTHENTICATION_FAILED";
}
Completion conditions
- A Node consumer can use all listed operations from the supported export.
- One connection can renew concurrent leases independently.
- Tests reject invalid result payloads at the client boundary.
- Tests reject protocol mismatch before a mutating request reaches the daemon.
- Tests prove that an ordinary client cannot call an admin operation.
- Tests prove that an invalid admin credential causes zero mutation.
This issue provides the client boundary. Later issues can add methods to the same clients.
Part of #70. See ADR 0021.
Purpose
Export a supported TypeScript client for the local Simlock daemon.
The current client is private. Its generic request method returns
Promise<unknown>.Host must not import files from
src/or start a command process.Proposed API
The names can change. The public contract must give equivalent typed operations.
Host will use
startDaemon: false. Its supervisor will control the daemon process.Required behavior
unknownpayloads.Use a stable error for protocol mismatch:
Use a stable error for an invalid admin credential:
Completion conditions
This issue provides the client boundary. Later issues can add methods to the same clients.