/** * node-pty が利用可能か確認する */ export declare function isNodePtyAvailable(): boolean; /** * Resume-validation metadata recorded at PTY creation time. * * The API includes `meta` in the `open` message; the session stores it and a * later resume `open` must present an EXACTLY matching meta to reattach to * this PTY (see TerminalSessionManager.resumeSession). This prevents an * API-restart resume from handing an existing PTY to a different tenant / * project / user. */ export interface TerminalSessionMeta { tenantCode: string; projectCode: string; userId: string; } export interface TerminalSessionOptions { cols?: number; rows?: number; cwd?: string; /** * Web 設定(CLAUDE_CODE# / ENV# 由来)から流れてくる env オーバーレイ。 * PTY 環境に最後にマージされ、ユーザーが対話シェルから `claude` を起動した * 際にも Web の `ANTHROPIC_API_KEY` / `CLAUDE_CODE_OAUTH_TOKEN` / * `ANTHROPIC_MODEL` 等が効くようにする。 * 含まれないキーは PTY が継承する process.env をそのまま残す。 */ envVarsOverride?: Record; /** * Resume 検証用メタ(tenantCode / projectCode / userId)。 * open メッセージの meta をそのまま記録し、resume open の meta と完全一致 * した場合のみ既存 PTY への再接続を許可する。 */ meta?: TerminalSessionMeta; /** * アタッチ先の tmux セッション名。 * 指定された場合はこの名前で tmux new-session -A を実行し、既存セッションがあれば * アタッチする。省略時は ais-{sessionId} を自動生成する。 */ tmuxSessionName?: string; } export interface TerminalSessionInfo { sessionId: string; pid: number; cols: number; rows: number; cwd: string; createdAt: number; lastActivity: number; } type DataCallback = (data: string) => void; type ExitCallback = (code: number | null) => void; /** * SSH キーの環境変数名 * * API サーバーが base64 エンコードされた PEM 秘密鍵をこの変数名で送ってくる。 * TerminalSession はこれを検出してファイルに書き出し、GIT_SSH_COMMAND を設定する。 * この変数自体は PTY には渡さない(ファイルパスが GIT_SSH_COMMAND 経由で参照される)。 */ export declare const GIT_SSH_KEY_ENV_NAME = "GIT_SSH_KEY_CONTENT_BASE64"; export declare class TerminalSession { readonly sessionId: string; readonly pid: number; cols: number; rows: number; readonly cwd: string; readonly createdAt: number; private lastActivity; private readonly ptyProcess; private sandboxTmpDir; private sshKeyFile; private tmuxSessionName; private dataCallback; private exitCallback; /** * Internal exit callback owned by the session manager for its own cleanup * (clear grace timer + remove from map). It is kept separate from the public * `exitCallback` so that a later `onExit()` registration by the websocket * handler (which sends the 'exit' frame) does NOT overwrite the manager's * cleanup. Both fire on PTY exit. */ private internalExitCallback; private exited; /** Resume-validation meta recorded at creation (null when the open had no meta). */ private readonly meta; /** * Scrollback ring buffer: PTY output chunks appended alongside the live * stdout relay, capped at SCROLLBACK_BUFFER_MAX_BYTES by dropping the OLDEST * bytes. Replayed to the client on a successful resume. */ private readonly scrollbackChunks; private scrollbackBytes; /** * 過去の terminal-sandbox-* ディレクトリを一括削除する。 * * 通常は session 終了時 (kill / onExit) に `cleanupTmpDir` で削除されるが、 * agent process が SIGKILL / クラッシュした場合は孤立した sandbox dir が * `/tmp` に残る。長期稼働で累積すると ENOSPC を引き起こすため、起動時に * クリーンアップする。 * * デフォルトは 24 時間以上前の sandbox のみ削除。`maxAgeMs=0` で全削除。 * * @param maxAgeMs 削除対象とする経過時間 (ms)。0 で全削除 * @returns 削除した件数 */ static cleanupStaleSandboxes(maxAgeMs?: number): number; constructor(sessionId: string, options?: TerminalSessionOptions); /** * Register the (single) live data relay callback. Registration REPLACES any * previous callback — it does not add a listener — so re-registering on a * resume cannot double-send stdout. */ onData(callback: DataCallback): void; /** Resume-validation meta recorded at creation, or null if none was given. */ getMeta(): TerminalSessionMeta | null; /** * Snapshot of the scrollback ring buffer (oldest → newest), at most * SCROLLBACK_BUFFER_MAX_BYTES bytes. Returns an empty Buffer when no output * has been produced yet. */ getScrollbackBuffer(): Buffer; /** * Append PTY output to the ring buffer, evicting the OLDEST bytes once the * total exceeds SCROLLBACK_BUFFER_MAX_BYTES. Eviction may slice a chunk in * the middle; the cut is then advanced to the next UTF-8 character boundary * (a buffer starting mid-sequence would replay as U+FFFD mojibake at the * top of the restored scrollback), so the kept total may fall a few bytes * under the cap. */ private appendScrollback; onExit(callback: ExitCallback): void; /** * Register the manager-owned exit cleanup. Separate from the public onExit so * it survives the websocket handler re-registering onExit on open/resume. */ setOnExitInternal(callback: () => void): void; write(data: string): void; resize(cols: number, rows: number): void; kill(): void; private cleanupTmpDir; /** * tmux セッションを kill する(fire-and-forget, エラーは無視)。 * tmuxSessionName を null にして二重実行を防ぐ。 */ private killTmuxSession; isAlive(): boolean; getInfo(): TerminalSessionInfo; private touchActivity; } export {}; //# sourceMappingURL=terminal-session.d.ts.map