2026-02-27 04:29:51 +00:00
|
|
|
import { useCallback } from "react";
|
2026-02-28 20:42:40 +00:00
|
|
|
import { useShallow } from "zustand/react/shallow";
|
2026-02-27 04:29:51 +00:00
|
|
|
import { listen } from "@tauri-apps/api/event";
|
|
|
|
|
import { useAppState } from "../store/appState";
|
|
|
|
|
import * as commands from "../lib/tauri-commands";
|
|
|
|
|
|
|
|
|
|
export function useTerminal() {
|
|
|
|
|
const { sessions, activeSessionId, addSession, removeSession, setActiveSession } =
|
2026-02-28 20:42:40 +00:00
|
|
|
useAppState(
|
|
|
|
|
useShallow(s => ({
|
|
|
|
|
sessions: s.sessions,
|
|
|
|
|
activeSessionId: s.activeSessionId,
|
|
|
|
|
addSession: s.addSession,
|
|
|
|
|
removeSession: s.removeSession,
|
|
|
|
|
setActiveSession: s.setActiveSession,
|
|
|
|
|
}))
|
|
|
|
|
);
|
2026-02-27 04:29:51 +00:00
|
|
|
|
|
|
|
|
const open = useCallback(
|
Add Claude Code settings infrastructure, TUI mode, session naming, and global defaults
Adds first-class support for Claude Code CLI features (2.1.71-2.1.110):
- New ClaudeCodeSettings struct with per-project and global defaults for
TUI mode, effort level, focus mode, thinking summaries, session recap,
auto-scroll, env scrub, and 1-hour prompt caching
- Settings injected as env vars (CLAUDE_CODE_NO_FLICKER, etc.) and
~/.claude/settings.json entries via entrypoint.sh merge block
- New ClaudeCodeSettingsModal component for configuring settings
- Session naming support (-n flag passed to claude CLI, shown in tabs)
- Relaxed reserved prefix filter: CLAUDE_CODE_* env vars now allowed in
custom env vars UI for power users
- Global SSH key path, git name, and git email now used as fallbacks
when per-project values are not set, with UI in SettingsPanel
- Fingerprint-based change detection triggers container recreation when
Claude Code settings change
- Updated README, HOW-TO-USE, and CLAUDE.md documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 08:46:03 -07:00
|
|
|
async (projectId: string, projectName: string, sessionType: "claude" | "bash" = "claude", sessionName?: string) => {
|
2026-02-27 04:29:51 +00:00
|
|
|
const sessionId = crypto.randomUUID();
|
Add Claude Code settings infrastructure, TUI mode, session naming, and global defaults
Adds first-class support for Claude Code CLI features (2.1.71-2.1.110):
- New ClaudeCodeSettings struct with per-project and global defaults for
TUI mode, effort level, focus mode, thinking summaries, session recap,
auto-scroll, env scrub, and 1-hour prompt caching
- Settings injected as env vars (CLAUDE_CODE_NO_FLICKER, etc.) and
~/.claude/settings.json entries via entrypoint.sh merge block
- New ClaudeCodeSettingsModal component for configuring settings
- Session naming support (-n flag passed to claude CLI, shown in tabs)
- Relaxed reserved prefix filter: CLAUDE_CODE_* env vars now allowed in
custom env vars UI for power users
- Global SSH key path, git name, and git email now used as fallbacks
when per-project values are not set, with UI in SettingsPanel
- Fingerprint-based change detection triggers container recreation when
Claude Code settings change
- Updated README, HOW-TO-USE, and CLAUDE.md documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 08:46:03 -07:00
|
|
|
await commands.openTerminalSession(projectId, sessionId, sessionType, sessionName);
|
|
|
|
|
addSession({ id: sessionId, projectId, projectName, sessionType, sessionName: sessionName ?? null });
|
2026-02-27 04:29:51 +00:00
|
|
|
return sessionId;
|
|
|
|
|
},
|
|
|
|
|
[addSession],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const close = useCallback(
|
|
|
|
|
async (sessionId: string) => {
|
|
|
|
|
await commands.closeTerminalSession(sessionId);
|
|
|
|
|
removeSession(sessionId);
|
|
|
|
|
},
|
|
|
|
|
[removeSession],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const sendInput = useCallback(
|
|
|
|
|
async (sessionId: string, data: string) => {
|
|
|
|
|
const bytes = Array.from(new TextEncoder().encode(data));
|
|
|
|
|
await commands.terminalInput(sessionId, bytes);
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const resize = useCallback(
|
|
|
|
|
async (sessionId: string, cols: number, rows: number) => {
|
|
|
|
|
await commands.terminalResize(sessionId, cols, rows);
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-01 10:52:08 -08:00
|
|
|
const pasteImage = useCallback(
|
|
|
|
|
async (sessionId: string, imageData: Uint8Array) => {
|
|
|
|
|
const bytes = Array.from(imageData);
|
|
|
|
|
return commands.pasteImageToTerminal(sessionId, bytes);
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
2026-02-27 04:29:51 +00:00
|
|
|
const onOutput = useCallback(
|
|
|
|
|
(sessionId: string, callback: (data: Uint8Array) => void) => {
|
|
|
|
|
const eventName = `terminal-output-${sessionId}`;
|
|
|
|
|
return listen<number[]>(eventName, (event) => {
|
|
|
|
|
callback(new Uint8Array(event.payload));
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const onExit = useCallback(
|
|
|
|
|
(sessionId: string, callback: () => void) => {
|
|
|
|
|
const eventName = `terminal-exit-${sessionId}`;
|
|
|
|
|
return listen<void>(eventName, () => {
|
|
|
|
|
callback();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
sessions,
|
|
|
|
|
activeSessionId,
|
|
|
|
|
setActiveSession,
|
|
|
|
|
open,
|
|
|
|
|
close,
|
|
|
|
|
sendInput,
|
2026-03-01 10:52:08 -08:00
|
|
|
pasteImage,
|
2026-02-27 04:29:51 +00:00
|
|
|
resize,
|
|
|
|
|
onOutput,
|
|
|
|
|
onExit,
|
|
|
|
|
};
|
|
|
|
|
}
|