blob: f27b7a7e6d16c6a93f55cb4875adfe46c23efc54 [file]
import type { StoredMessage } from './session.js';
/** Stable identifier for one external Agent integration, for example `codex`. */
export type ExternalAgentId = string;
export interface ExternalSessionQuery {
cwd?: string;
includeArchived?: boolean;
}
/** Lightweight source-native identity used by session pickers and import commands. */
export interface ExternalSessionSummary {
id: string;
name: string;
cwd: string;
createdAt?: number;
updatedAt?: number;
archived?: boolean;
}
/**
* An external session after its source-specific format has been converted to
* Maka's existing raw Session representation.
*
* There is intentionally no intermediate external-message model here. Each
* adapter owns its source format and emits canonical Maka StoredMessages.
*/
export interface ExternalMakaSession {
sourceSessionId: string;
metadata: {
name: string;
cwd: string;
};
messages: readonly StoredMessage[];
}
/** Read-only, source-specific conversion boundary for one external Agent. */
export interface ExternalSessionAdapter {
readonly id: ExternalAgentId;
detect(): Promise<boolean>;
listSessions(query?: ExternalSessionQuery): Promise<readonly ExternalSessionSummary[]>;
readSession(sessionId: string): Promise<ExternalMakaSession>;
}
export class ExternalSessionAdapterRegistry {
private readonly adapters = new Map<ExternalAgentId, ExternalSessionAdapter>();
constructor(adapters: readonly ExternalSessionAdapter[] = []) {
for (const adapter of adapters) this.register(adapter);
}
register(adapter: ExternalSessionAdapter): void {
if (adapter.id.trim().length === 0) {
throw new Error('External Session adapter id must not be empty');
}
if (this.adapters.has(adapter.id)) {
throw new Error(`External Session adapter is already registered: ${adapter.id}`);
}
this.adapters.set(adapter.id, adapter);
}
get(adapterId: ExternalAgentId): ExternalSessionAdapter | undefined {
return this.adapters.get(adapterId);
}
require(adapterId: ExternalAgentId): ExternalSessionAdapter {
const adapter = this.get(adapterId);
if (!adapter) throw new Error(`External Session adapter is not registered: ${adapterId}`);
return adapter;
}
list(): readonly ExternalSessionAdapter[] {
return [...this.adapters.values()];
}
}