import type { Clock } from '../infra/clock.js';
import type { FileSystem } from '../infra/filesystem.js';
import type { DomainEventBus } from '../shared/domainEvents.js';
import { type DomainError } from '../shared/errors.js';
import { type Result } from '../shared/result.js';
export interface ChatMessage {
    readonly id: string;
    readonly role: 'user' | 'assistant' | 'system' | 'error';
    readonly content: string;
    readonly ts: string;
    readonly blocks?: unknown[];
    /**
     * v0.51.8：用户消息可携带附件（绝对路径数组）。
     * - 上传文件落在 ~/.coral/chat-attachments/<sessionId>/<stamped-name>
     * - 本地挑选文件保留原始路径
     * Worker prompt 拼接时会附在 user 消息末尾，让 Claude 自己 Read。
     */
    readonly attachments?: string[];
}
export interface ChatSession {
    readonly id: string;
    readonly createdAt: string;
    readonly lastMessageAt: string | null;
    readonly title: string;
    readonly project: string | null;
    readonly messageCount: number;
    readonly messages: ChatMessage[];
    /**
     * v0.51.4: Working directory the worker should use for this session. Captured at
     * create time so different sessions can target different repos. Absent (null) =
     * fall back to daemon's startup cwd (legacy behavior).
     */
    readonly cwd?: string | null;
    /** v0.51.12：会话来源（同 ChatSessionSummary） */
    readonly source?: 'console' | 'cli';
    /** v0.51.12：CLI 会话只读 */
    readonly readonly?: boolean;
}
export interface ChatSessionSummary {
    readonly id: string;
    readonly createdAt: string;
    readonly lastMessageAt: string | null;
    readonly title: string;
    readonly project: string | null;
    readonly messageCount: number;
    readonly cwd?: string | null;
    /**
     * v0.51.12：会话来源。
     * - `console`：Console /chat 页创建的会话，持久化在 ~/.coral/chat-sessions/<id>.json
     * - `cli`：`sps agent --chat` / `sps agent --name` 在 daemon 里建的会话，
     *   历史从 Claude CLI 的 ~/.claude/projects/<cwd>/<sessionId>.jsonl 读
     */
    readonly source?: 'console' | 'cli';
    /** v0.51.12：CLI 会话独有的 daemon slot 名（id 也等于此值），用于路由消息 */
    readonly slot?: string;
    /** v0.51.12：CLI 会话当前的 daemon 状态（offline / busy / ready / ...） */
    readonly sessionState?: string | null;
    /** v0.51.12：CLI 会话目前不能从 Console 续聊（只读历史），Console 会话可写 */
    readonly readonly?: boolean;
}
export interface CreateSessionInput {
    title?: string;
    project?: string | null;
    /** v0.51.4: optional working dir; if provided must be absolute and exist. */
    cwd?: string | null;
}
export interface ChatExecutor {
    /** 停止会话对应的 daemon worker（Console 路径：会自动加 chat- 前缀） */
    stopSession(sessionId: string): Promise<void>;
    /** 中断正在进行的 assistant turn */
    cancelRun(sessionId: string): Promise<void>;
    /**
     * v0.51.13：按完整 slot 名停 daemon session（CLI 路径用）。
     * 调用方已知 slot 名形如 `session-default` / `session-foo`，不需要再拼前缀。
     * Slot 不存在或 daemon 未运行时静默 no-op。
     */
    stopExactSlot(slot: string): Promise<void>;
}
export interface ChatServiceDeps {
    readonly fs: FileSystem;
    readonly clock: Clock;
    readonly events: DomainEventBus;
    readonly executor?: ChatExecutor;
}
export declare class ChatService {
    private readonly deps;
    constructor(deps: ChatServiceDeps);
    list(): Promise<Result<ChatSessionSummary[], DomainError>>;
    /** 读 daemon state.json 取 sessions —— 文件不存在或损坏返回空数组 */
    private readDaemonSessions;
    create(input?: CreateSessionInput): Promise<Result<ChatSessionSummary, DomainError>>;
    get(id: string): Promise<Result<ChatSession, DomainError>>;
    /** 返回 since 之后的消息（供 SSE 重连补偿）。since 缺省返回全部。 */
    getMessages(id: string, since?: string): Promise<Result<{
        data: ChatMessage[];
        total: number;
    }, DomainError>>;
    delete(id: string): Promise<Result<void, DomainError>>;
    /**
     * 从 daemon state.json 里把 slot 删掉，让 list() 不再返回。
     * jsonl 文件刻意留着 —— 那是 Claude CLI 自己的存档，跨边界删除越权。
     */
    private removeDaemonSession;
    interrupt(id: string): Promise<Result<void, DomainError>>;
    private sessionPath;
    private summarize;
}
//# sourceMappingURL=ChatService.d.ts.map