@halfwhey/claudraband-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/claude/claude.d.ts +70 -0
- package/dist/claude/index.d.ts +9 -0
- package/dist/claude/inspect.d.ts +14 -0
- package/dist/claude/parser.d.ts +17 -0
- package/dist/claude/resolve.d.ts +4 -0
- package/dist/index.d.ts +207 -0
- package/dist/index.js +2491 -0
- package/dist/session-registry.d.ts +46 -0
- package/dist/terminal/activity.d.ts +23 -0
- package/dist/terminal/index.d.ts +82 -0
- package/dist/tmuxctl/index.d.ts +2 -0
- package/dist/tmuxctl/tmux.d.ts +39 -0
- package/dist/wrap/event.d.ts +24 -0
- package/dist/wrap/index.d.ts +3 -0
- package/dist/wrap/wrapper.d.ts +11 -0
- package/package.json +52 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Event } from "../wrap/event";
|
|
2
|
+
import type { Wrapper } from "../wrap/wrapper";
|
|
3
|
+
import { type TerminalBackend } from "../terminal";
|
|
4
|
+
export interface ClaudeConfig {
|
|
5
|
+
claudeArgs: string[];
|
|
6
|
+
claudeExecutable?: string;
|
|
7
|
+
model: string;
|
|
8
|
+
permissionMode: string;
|
|
9
|
+
workingDir: string;
|
|
10
|
+
terminalBackend: TerminalBackend;
|
|
11
|
+
tmuxSession: string;
|
|
12
|
+
paneWidth: number;
|
|
13
|
+
paneHeight: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function sessionPath(cwd: string, sessionID: string): string;
|
|
16
|
+
export declare class ClaudeWrapper implements Wrapper {
|
|
17
|
+
private cfg;
|
|
18
|
+
private terminal;
|
|
19
|
+
private tailer;
|
|
20
|
+
private _claudeSessionId;
|
|
21
|
+
private _signal;
|
|
22
|
+
private abortController;
|
|
23
|
+
private eventIterable;
|
|
24
|
+
constructor(cfg: ClaudeConfig);
|
|
25
|
+
name(): string;
|
|
26
|
+
model(): string;
|
|
27
|
+
setModel(model: string): void;
|
|
28
|
+
setPermissionMode(mode: string): void;
|
|
29
|
+
/** The Claude Code session UUID used for the JSONL file. */
|
|
30
|
+
get claudeSessionId(): string;
|
|
31
|
+
start(signal: AbortSignal): Promise<void>;
|
|
32
|
+
/** Resume an existing Claude Code session by its UUID. */
|
|
33
|
+
startResume(claudeSessionId: string, signal: AbortSignal): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Restart Claude Code with updated config (e.g. after a permission mode
|
|
36
|
+
* change). Stops the current terminal host and re-spawns with --resume.
|
|
37
|
+
*/
|
|
38
|
+
restart(): Promise<void>;
|
|
39
|
+
private buildCmd;
|
|
40
|
+
private spawnAndTail;
|
|
41
|
+
/**
|
|
42
|
+
* Poll the terminal until Claude Code is ready to accept input.
|
|
43
|
+
* Looks for "INSERT" in the status bar, which indicates the TUI has loaded.
|
|
44
|
+
*/
|
|
45
|
+
private waitForReady;
|
|
46
|
+
stop(): Promise<void>;
|
|
47
|
+
/** Disconnect without killing the process. The terminal stays alive. */
|
|
48
|
+
detach(): Promise<void>;
|
|
49
|
+
/** Check if the underlying terminal process is still running. */
|
|
50
|
+
isProcessAlive(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Check if a Claude Code session has a live process without attaching.
|
|
53
|
+
* Only meaningful for tmux backend -- xterm processes can't outlive the CLI.
|
|
54
|
+
*/
|
|
55
|
+
static hasLiveProcess(tmuxSessionName: string, claudeSessionId: string): Promise<boolean>;
|
|
56
|
+
static stopLiveProcess(tmuxSessionName: string, claudeSessionId: string): Promise<boolean>;
|
|
57
|
+
send(input: string): Promise<void>;
|
|
58
|
+
interrupt(): Promise<void>;
|
|
59
|
+
/** Capture the current visible content of the terminal. */
|
|
60
|
+
capturePane(): Promise<string>;
|
|
61
|
+
processId(): Promise<number | undefined>;
|
|
62
|
+
alive(): boolean;
|
|
63
|
+
events(): AsyncGenerator<Event>;
|
|
64
|
+
}
|
|
65
|
+
export interface ParsedClaudeArgs {
|
|
66
|
+
passthroughArgs: string[];
|
|
67
|
+
model?: string;
|
|
68
|
+
permissionMode?: string;
|
|
69
|
+
}
|
|
70
|
+
export declare function parseClaudeArgs(args: string[]): ParsedClaudeArgs;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ClaudeWrapper } from "./claude";
|
|
2
|
+
export { sessionPath } from "./claude";
|
|
3
|
+
export { parseClaudeArgs } from "./claude";
|
|
4
|
+
export type { ClaudeConfig } from "./claude";
|
|
5
|
+
export { resolveClaudeExecutable } from "./resolve";
|
|
6
|
+
export { Tailer, parseLineEvents } from "./parser";
|
|
7
|
+
export { hasPendingNativePrompt, hasPendingQuestion, parseNativePermissionPrompt, } from "./inspect";
|
|
8
|
+
export { createTerminalHost, hasTmuxBinary, resolveTerminalBackend } from "../terminal";
|
|
9
|
+
export type { TerminalBackend, ResolvedTerminalBackend, TerminalHost, TerminalStartOptions, } from "../terminal";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface NativePermissionPrompt {
|
|
2
|
+
question: string;
|
|
3
|
+
options: {
|
|
4
|
+
number: string;
|
|
5
|
+
label: string;
|
|
6
|
+
}[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Scan a Claude Code session JSONL file for an unresolved AskUserQuestion.
|
|
10
|
+
* Returns true if the last AskUserQuestion tool_use has no matching tool_result.
|
|
11
|
+
*/
|
|
12
|
+
export declare function hasPendingQuestion(jsonlPath: string): Promise<boolean>;
|
|
13
|
+
export declare function parseNativePermissionPrompt(paneText: string): NativePermissionPrompt | null;
|
|
14
|
+
export declare function hasPendingNativePrompt(paneText: string): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Event } from "../wrap/event";
|
|
2
|
+
export declare function parseLineEvents(line: string): Event[];
|
|
3
|
+
export declare class Tailer {
|
|
4
|
+
private path;
|
|
5
|
+
private abortController;
|
|
6
|
+
private eventQueue;
|
|
7
|
+
private resolvers;
|
|
8
|
+
private done;
|
|
9
|
+
private startOffset;
|
|
10
|
+
constructor(path: string, startOffset?: number);
|
|
11
|
+
close(): void;
|
|
12
|
+
events(): AsyncGenerator<Event>;
|
|
13
|
+
private pushEvent;
|
|
14
|
+
private finish;
|
|
15
|
+
private emitCompleteLines;
|
|
16
|
+
private run;
|
|
17
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { hasPendingNativePrompt, hasPendingQuestion, parseClaudeArgs, resolveTerminalBackend, sessionPath, type TerminalBackend } from "./claude";
|
|
2
|
+
import { type ResolvedTerminalBackend } from "./terminal";
|
|
3
|
+
import type { Event as ClaudrabandEvent } from "./wrap/event";
|
|
4
|
+
import { EventKind } from "./wrap/event";
|
|
5
|
+
import type { Wrapper } from "./wrap/wrapper";
|
|
6
|
+
import { type SessionOwnerRecord } from "./session-registry";
|
|
7
|
+
export { EventKind };
|
|
8
|
+
export { hasPendingNativePrompt };
|
|
9
|
+
export { hasPendingQuestion };
|
|
10
|
+
export { parseClaudeArgs };
|
|
11
|
+
export { resolveTerminalBackend };
|
|
12
|
+
export { sessionPath };
|
|
13
|
+
export { awaitPaneIdle } from "./terminal/activity";
|
|
14
|
+
export type { PaneActivityOptions, ActivityResult } from "./terminal/activity";
|
|
15
|
+
export type { ClaudrabandEvent };
|
|
16
|
+
export type { TerminalBackend };
|
|
17
|
+
export type { ResolvedTerminalBackend };
|
|
18
|
+
export type { SessionOwnerRecord };
|
|
19
|
+
/** Check if a Claude Code session has a live tmux process. */
|
|
20
|
+
export declare function hasLiveProcess(sessionId: string): Promise<boolean>;
|
|
21
|
+
export declare function closeLiveProcess(sessionId: string): Promise<boolean>;
|
|
22
|
+
export type PermissionMode = "default" | "plan" | "auto" | "acceptEdits" | "dontAsk" | "bypassPermissions";
|
|
23
|
+
export type ToolKind = "read" | "edit" | "execute" | "search" | "fetch" | "think" | "other";
|
|
24
|
+
export interface ClaudrabandLogger {
|
|
25
|
+
info(msg: string, ...args: unknown[]): void;
|
|
26
|
+
debug(msg: string, ...args: unknown[]): void;
|
|
27
|
+
warn(msg: string, ...args: unknown[]): void;
|
|
28
|
+
error(msg: string, ...args: unknown[]): void;
|
|
29
|
+
}
|
|
30
|
+
export interface ClaudrabandContentBlock {
|
|
31
|
+
type: "text";
|
|
32
|
+
text: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ClaudrabandPermissionOption {
|
|
35
|
+
kind: "allow_once" | "reject_once";
|
|
36
|
+
optionId: string;
|
|
37
|
+
name: string;
|
|
38
|
+
textInput?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface ClaudrabandPermissionRequest {
|
|
41
|
+
source: "native_prompt" | "ask_user_question";
|
|
42
|
+
sessionId: string;
|
|
43
|
+
toolCallId: string;
|
|
44
|
+
title: string;
|
|
45
|
+
kind: ToolKind;
|
|
46
|
+
content: ClaudrabandContentBlock[];
|
|
47
|
+
options: ClaudrabandPermissionOption[];
|
|
48
|
+
}
|
|
49
|
+
export type ClaudrabandPermissionDecision = {
|
|
50
|
+
outcome: "selected";
|
|
51
|
+
optionId: string;
|
|
52
|
+
} | {
|
|
53
|
+
outcome: "text";
|
|
54
|
+
text: string;
|
|
55
|
+
} | {
|
|
56
|
+
outcome: "deferred";
|
|
57
|
+
} | {
|
|
58
|
+
outcome: "cancelled";
|
|
59
|
+
};
|
|
60
|
+
export interface ClaudrabandOptions {
|
|
61
|
+
cwd?: string;
|
|
62
|
+
claudeArgs?: string[];
|
|
63
|
+
claudeExecutable?: string;
|
|
64
|
+
model?: string;
|
|
65
|
+
permissionMode?: PermissionMode;
|
|
66
|
+
allowTextResponses?: boolean;
|
|
67
|
+
terminalBackend?: TerminalBackend;
|
|
68
|
+
paneWidth?: number;
|
|
69
|
+
paneHeight?: number;
|
|
70
|
+
logger?: ClaudrabandLogger;
|
|
71
|
+
onPermissionRequest?: (request: ClaudrabandPermissionRequest) => Promise<ClaudrabandPermissionDecision>;
|
|
72
|
+
sessionOwner?: SessionOwnerRecord;
|
|
73
|
+
}
|
|
74
|
+
export interface SessionSummary {
|
|
75
|
+
sessionId: string;
|
|
76
|
+
cwd: string;
|
|
77
|
+
title?: string;
|
|
78
|
+
createdAt: string;
|
|
79
|
+
updatedAt?: string;
|
|
80
|
+
backend: ResolvedTerminalBackend;
|
|
81
|
+
source: "live" | "history";
|
|
82
|
+
alive: boolean;
|
|
83
|
+
reattachable: boolean;
|
|
84
|
+
owner: SessionOwnerRecord;
|
|
85
|
+
}
|
|
86
|
+
export interface PromptResult {
|
|
87
|
+
stopReason: "end_turn" | "cancelled";
|
|
88
|
+
}
|
|
89
|
+
export interface ClaudrabandSession {
|
|
90
|
+
readonly sessionId: string;
|
|
91
|
+
readonly cwd: string;
|
|
92
|
+
readonly backend: ResolvedTerminalBackend;
|
|
93
|
+
readonly model: string;
|
|
94
|
+
readonly permissionMode: PermissionMode;
|
|
95
|
+
events(): AsyncIterable<ClaudrabandEvent>;
|
|
96
|
+
prompt(text: string): Promise<PromptResult>;
|
|
97
|
+
awaitTurn(): Promise<PromptResult>;
|
|
98
|
+
sendAndAwaitTurn(text: string): Promise<PromptResult>;
|
|
99
|
+
send(text: string): Promise<void>;
|
|
100
|
+
interrupt(): Promise<void>;
|
|
101
|
+
stop(): Promise<void>;
|
|
102
|
+
/** Disconnect without killing the process. */
|
|
103
|
+
detach(): Promise<void>;
|
|
104
|
+
isProcessAlive(): boolean;
|
|
105
|
+
capturePane(): Promise<string>;
|
|
106
|
+
hasPendingInput(): Promise<{
|
|
107
|
+
pending: boolean;
|
|
108
|
+
source: "none" | "terminal";
|
|
109
|
+
}>;
|
|
110
|
+
setModel(model: string): Promise<void>;
|
|
111
|
+
setPermissionMode(mode: PermissionMode): Promise<void>;
|
|
112
|
+
flushEvents(): Promise<void>;
|
|
113
|
+
}
|
|
114
|
+
export interface Claudraband {
|
|
115
|
+
startSession(options?: ClaudrabandOptions): Promise<ClaudrabandSession>;
|
|
116
|
+
resumeSession(sessionId: string, options?: ClaudrabandOptions): Promise<ClaudrabandSession>;
|
|
117
|
+
listSessions(cwd?: string): Promise<SessionSummary[]>;
|
|
118
|
+
inspectSession(sessionId: string, cwd?: string): Promise<SessionSummary | null>;
|
|
119
|
+
closeSession(sessionId: string): Promise<boolean>;
|
|
120
|
+
replaySession(sessionId: string, cwd: string): Promise<ClaudrabandEvent[]>;
|
|
121
|
+
}
|
|
122
|
+
export declare const MODEL_OPTIONS: readonly [{
|
|
123
|
+
readonly value: "haiku";
|
|
124
|
+
readonly name: "Haiku";
|
|
125
|
+
readonly description: "Fast and lightweight";
|
|
126
|
+
}, {
|
|
127
|
+
readonly value: "sonnet";
|
|
128
|
+
readonly name: "Sonnet";
|
|
129
|
+
readonly description: "Balanced speed and intelligence";
|
|
130
|
+
}, {
|
|
131
|
+
readonly value: "opus";
|
|
132
|
+
readonly name: "Opus";
|
|
133
|
+
readonly description: "Most capable";
|
|
134
|
+
}];
|
|
135
|
+
export declare const PERMISSION_MODES: readonly [{
|
|
136
|
+
readonly id: "default";
|
|
137
|
+
readonly name: "Default";
|
|
138
|
+
readonly description: "Ask before tool use";
|
|
139
|
+
}, {
|
|
140
|
+
readonly id: "plan";
|
|
141
|
+
readonly name: "Plan";
|
|
142
|
+
readonly description: "Plan-only mode, no edits";
|
|
143
|
+
}, {
|
|
144
|
+
readonly id: "auto";
|
|
145
|
+
readonly name: "Auto";
|
|
146
|
+
readonly description: "Bypass permission checks";
|
|
147
|
+
}, {
|
|
148
|
+
readonly id: "acceptEdits";
|
|
149
|
+
readonly name: "Accept Edits";
|
|
150
|
+
readonly description: "Auto-accept file edits";
|
|
151
|
+
}, {
|
|
152
|
+
readonly id: "dontAsk";
|
|
153
|
+
readonly name: "Don't Ask";
|
|
154
|
+
readonly description: "Skip all confirmations";
|
|
155
|
+
}, {
|
|
156
|
+
readonly id: "bypassPermissions";
|
|
157
|
+
readonly name: "Bypass Permissions";
|
|
158
|
+
readonly description: "Dangerously Skip Permissions";
|
|
159
|
+
}];
|
|
160
|
+
export declare const TERMINAL_BACKENDS: readonly [{
|
|
161
|
+
readonly id: "auto";
|
|
162
|
+
readonly name: "Auto";
|
|
163
|
+
readonly description: "Prefer tmux, then fall back to headless xterm";
|
|
164
|
+
}, {
|
|
165
|
+
readonly id: "tmux";
|
|
166
|
+
readonly name: "tmux";
|
|
167
|
+
readonly description: "Run Claude Code inside a tmux session";
|
|
168
|
+
}, {
|
|
169
|
+
readonly id: "xterm";
|
|
170
|
+
readonly name: "xterm";
|
|
171
|
+
readonly description: "Run Claude Code in a headless xterm-backed PTY";
|
|
172
|
+
}];
|
|
173
|
+
interface AskUserQuestionOption {
|
|
174
|
+
label: string;
|
|
175
|
+
description: string;
|
|
176
|
+
}
|
|
177
|
+
interface AskUserQuestionItem {
|
|
178
|
+
question: string;
|
|
179
|
+
header: string;
|
|
180
|
+
multiSelect: boolean;
|
|
181
|
+
options: AskUserQuestionOption[];
|
|
182
|
+
}
|
|
183
|
+
export declare function createClaudraband(defaults?: ClaudrabandOptions): Claudraband;
|
|
184
|
+
interface SessionWrapper extends Wrapper {
|
|
185
|
+
capturePane(): Promise<string>;
|
|
186
|
+
setModel(model: string): void;
|
|
187
|
+
setPermissionMode(mode: string): void;
|
|
188
|
+
restart(): Promise<void>;
|
|
189
|
+
detach(): Promise<void>;
|
|
190
|
+
isProcessAlive(): boolean;
|
|
191
|
+
processId(): Promise<number | undefined>;
|
|
192
|
+
}
|
|
193
|
+
export declare const __test: {
|
|
194
|
+
buildAskUserQuestionOptions: typeof buildAskUserQuestionOptions;
|
|
195
|
+
createSession(wrapper: SessionWrapper, options?: {
|
|
196
|
+
sessionId?: string;
|
|
197
|
+
cwd?: string;
|
|
198
|
+
backend?: ResolvedTerminalBackend;
|
|
199
|
+
model?: string;
|
|
200
|
+
permissionMode?: PermissionMode;
|
|
201
|
+
allowTextResponses?: boolean;
|
|
202
|
+
logger?: ClaudrabandLogger;
|
|
203
|
+
onPermissionRequest?: ClaudrabandOptions["onPermissionRequest"];
|
|
204
|
+
lifetime?: AbortController;
|
|
205
|
+
}): ClaudrabandSession;
|
|
206
|
+
};
|
|
207
|
+
declare function buildAskUserQuestionOptions(question: AskUserQuestionItem, allowTextResponses?: boolean): ClaudrabandPermissionOption[];
|