@claude-sessions/core 0.3.1 → 0.3.3
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/index.d.ts +19 -226
- package/dist/index.js +63 -23
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +10 -0
- package/dist/server.js +66 -0
- package/dist/server.js.map +1 -0
- package/dist/types-C2fzbmg9.d.ts +264 -0
- package/package.json +5 -1
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { l as ResumeSessionOptions, m as ResumeSessionResult } from './types-C2fzbmg9.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resume a session using claude CLI
|
|
5
|
+
* On macOS: opens Terminal.app with claude --resume command
|
|
6
|
+
* On other platforms: spawns a detached process with appropriate terminal
|
|
7
|
+
*/
|
|
8
|
+
declare const resumeSession: (options: ResumeSessionOptions) => ResumeSessionResult;
|
|
9
|
+
|
|
10
|
+
export { ResumeSessionOptions, ResumeSessionResult, resumeSession };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// src/resume.ts
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
var resumeSession = (options) => {
|
|
4
|
+
const { sessionId, cwd, fork = false, args = [] } = options;
|
|
5
|
+
try {
|
|
6
|
+
const claudeArgs = ["--resume", sessionId];
|
|
7
|
+
if (fork) {
|
|
8
|
+
claudeArgs.push("--fork-session");
|
|
9
|
+
}
|
|
10
|
+
claudeArgs.push(...args);
|
|
11
|
+
const claudeCommand = `claude ${claudeArgs.join(" ")}`;
|
|
12
|
+
const workingDir = cwd ?? process.cwd();
|
|
13
|
+
if (process.platform === "darwin") {
|
|
14
|
+
const escapedDir = workingDir.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
15
|
+
const escapedCmd = claudeCommand.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
16
|
+
const script = `
|
|
17
|
+
tell application "Terminal"
|
|
18
|
+
activate
|
|
19
|
+
set newWindow to do script "cd \\"${escapedDir}\\" && ${escapedCmd}"
|
|
20
|
+
set frontmost of newWindow to true
|
|
21
|
+
end tell
|
|
22
|
+
tell application "System Events"
|
|
23
|
+
set frontmost of process "Terminal" to true
|
|
24
|
+
end tell
|
|
25
|
+
`;
|
|
26
|
+
const child = spawn("osascript", ["-e", script], {
|
|
27
|
+
detached: true,
|
|
28
|
+
stdio: "ignore"
|
|
29
|
+
});
|
|
30
|
+
child.unref();
|
|
31
|
+
return { success: true, pid: child.pid };
|
|
32
|
+
}
|
|
33
|
+
if (process.platform === "win32") {
|
|
34
|
+
const child = spawn("cmd", ["/c", "start", "cmd", "/k", claudeCommand], {
|
|
35
|
+
cwd: workingDir,
|
|
36
|
+
detached: true,
|
|
37
|
+
stdio: "ignore"
|
|
38
|
+
});
|
|
39
|
+
child.unref();
|
|
40
|
+
return { success: true, pid: child.pid };
|
|
41
|
+
}
|
|
42
|
+
const terminals = ["gnome-terminal", "konsole", "xterm"];
|
|
43
|
+
for (const term of terminals) {
|
|
44
|
+
try {
|
|
45
|
+
const child = spawn(term, ["--", "bash", "-c", `cd "${workingDir}" && ${claudeCommand}`], {
|
|
46
|
+
detached: true,
|
|
47
|
+
stdio: "ignore"
|
|
48
|
+
});
|
|
49
|
+
child.unref();
|
|
50
|
+
return { success: true, pid: child.pid };
|
|
51
|
+
} catch {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { success: false, error: "No supported terminal emulator found" };
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: error instanceof Error ? error.message : String(error)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
export {
|
|
64
|
+
resumeSession
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/resume.ts"],"sourcesContent":["/**\n * Resume session functionality - Server-side only\n * This module uses child_process and should NOT be imported in browser environments\n */\nimport { spawn } from 'node:child_process'\nimport type { ResumeSessionOptions, ResumeSessionResult } from './types.js'\n\n/**\n * Resume a session using claude CLI\n * On macOS: opens Terminal.app with claude --resume command\n * On other platforms: spawns a detached process with appropriate terminal\n */\nexport const resumeSession = (options: ResumeSessionOptions): ResumeSessionResult => {\n const { sessionId, cwd, fork = false, args = [] } = options\n\n try {\n const claudeArgs = ['--resume', sessionId]\n if (fork) {\n claudeArgs.push('--fork-session')\n }\n claudeArgs.push(...args)\n\n const claudeCommand = `claude ${claudeArgs.join(' ')}`\n const workingDir = cwd ?? process.cwd()\n\n // macOS: use osascript to open Terminal.app and run command\n if (process.platform === 'darwin') {\n // AppleScript to open new Terminal window, cd to directory, and run command\n const escapedDir = workingDir.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n const escapedCmd = claudeCommand.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n const script = `\ntell application \"Terminal\"\n activate\n set newWindow to do script \"cd \\\\\"${escapedDir}\\\\\" && ${escapedCmd}\"\n set frontmost of newWindow to true\nend tell\ntell application \"System Events\"\n set frontmost of process \"Terminal\" to true\nend tell\n`\n const child = spawn('osascript', ['-e', script], {\n detached: true,\n stdio: 'ignore',\n })\n child.unref()\n\n return { success: true, pid: child.pid }\n }\n\n // Windows: use start cmd\n if (process.platform === 'win32') {\n const child = spawn('cmd', ['/c', 'start', 'cmd', '/k', claudeCommand], {\n cwd: workingDir,\n detached: true,\n stdio: 'ignore',\n })\n child.unref()\n\n return { success: true, pid: child.pid }\n }\n\n // Linux: try common terminal emulators\n const terminals = ['gnome-terminal', 'konsole', 'xterm']\n for (const term of terminals) {\n try {\n const child = spawn(term, ['--', 'bash', '-c', `cd \"${workingDir}\" && ${claudeCommand}`], {\n detached: true,\n stdio: 'ignore',\n })\n child.unref()\n return { success: true, pid: child.pid }\n } catch {\n continue\n }\n }\n\n return { success: false, error: 'No supported terminal emulator found' }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n"],"mappings":";AAIA,SAAS,aAAa;AAQf,IAAM,gBAAgB,CAAC,YAAuD;AACnF,QAAM,EAAE,WAAW,KAAK,OAAO,OAAO,OAAO,CAAC,EAAE,IAAI;AAEpD,MAAI;AACF,UAAM,aAAa,CAAC,YAAY,SAAS;AACzC,QAAI,MAAM;AACR,iBAAW,KAAK,gBAAgB;AAAA,IAClC;AACA,eAAW,KAAK,GAAG,IAAI;AAEvB,UAAM,gBAAgB,UAAU,WAAW,KAAK,GAAG,CAAC;AACpD,UAAM,aAAa,OAAO,QAAQ,IAAI;AAGtC,QAAI,QAAQ,aAAa,UAAU;AAEjC,YAAM,aAAa,WAAW,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK;AACxE,YAAM,aAAa,cAAc,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK;AAC3E,YAAM,SAAS;AAAA;AAAA;AAAA,sCAGiB,UAAU,UAAU,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO9D,YAAM,QAAQ,MAAM,aAAa,CAAC,MAAM,MAAM,GAAG;AAAA,QAC/C,UAAU;AAAA,QACV,OAAO;AAAA,MACT,CAAC;AACD,YAAM,MAAM;AAEZ,aAAO,EAAE,SAAS,MAAM,KAAK,MAAM,IAAI;AAAA,IACzC;AAGA,QAAI,QAAQ,aAAa,SAAS;AAChC,YAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,SAAS,OAAO,MAAM,aAAa,GAAG;AAAA,QACtE,KAAK;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,MACT,CAAC;AACD,YAAM,MAAM;AAEZ,aAAO,EAAE,SAAS,MAAM,KAAK,MAAM,IAAI;AAAA,IACzC;AAGA,UAAM,YAAY,CAAC,kBAAkB,WAAW,OAAO;AACvD,eAAW,QAAQ,WAAW;AAC5B,UAAI;AACF,cAAM,QAAQ,MAAM,MAAM,CAAC,MAAM,QAAQ,MAAM,OAAO,UAAU,QAAQ,aAAa,EAAE,GAAG;AAAA,UACxF,UAAU;AAAA,UACV,OAAO;AAAA,QACT,CAAC;AACD,cAAM,MAAM;AACZ,eAAO,EAAE,SAAS,MAAM,KAAK,MAAM,IAAI;AAAA,MACzC,QAAQ;AACN;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,OAAO,OAAO,uCAAuC;AAAA,EACzE,SAAS,OAAO;AACd,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for Claude Code session management
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Base interface for objects with a type discriminator.
|
|
6
|
+
* Used as a foundation for message and content types.
|
|
7
|
+
*/
|
|
8
|
+
interface TypedObject {
|
|
9
|
+
type: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Text content block in a message.
|
|
13
|
+
* @see https://docs.anthropic.com/en/api/messages
|
|
14
|
+
*/
|
|
15
|
+
interface TextContent {
|
|
16
|
+
type: 'text';
|
|
17
|
+
text: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Tool result content returned after tool execution.
|
|
21
|
+
* Contains the output from a tool_use request.
|
|
22
|
+
*/
|
|
23
|
+
interface ToolResultContent {
|
|
24
|
+
type: 'tool_result';
|
|
25
|
+
tool_use_id: string;
|
|
26
|
+
content: string;
|
|
27
|
+
is_error?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Tool use request from the assistant.
|
|
31
|
+
* Represents a function call with input parameters.
|
|
32
|
+
*/
|
|
33
|
+
interface ToolUseContent {
|
|
34
|
+
type: 'tool_use';
|
|
35
|
+
id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
input: unknown;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Union type for all message content blocks.
|
|
41
|
+
* Includes known types and a fallback for unknown content types.
|
|
42
|
+
*/
|
|
43
|
+
type ContentItem = TextContent | ToolResultContent | ToolUseContent | {
|
|
44
|
+
type: string;
|
|
45
|
+
text?: string;
|
|
46
|
+
name?: string;
|
|
47
|
+
input?: unknown;
|
|
48
|
+
content?: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Message payload containing role and content.
|
|
52
|
+
* Matches Anthropic API message structure.
|
|
53
|
+
*/
|
|
54
|
+
interface MessagePayload {
|
|
55
|
+
role?: string;
|
|
56
|
+
content?: ContentItem[] | string;
|
|
57
|
+
model?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* AskUserQuestion tool response with questions and user answers.
|
|
61
|
+
*/
|
|
62
|
+
interface AskUserQuestionResult {
|
|
63
|
+
questions: Array<{
|
|
64
|
+
question: string;
|
|
65
|
+
header: string;
|
|
66
|
+
options: Array<{
|
|
67
|
+
label: string;
|
|
68
|
+
description: string;
|
|
69
|
+
}>;
|
|
70
|
+
multiSelect: boolean;
|
|
71
|
+
}>;
|
|
72
|
+
answers: Record<string, string>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Tool use result - either a string (rejection reason) or AskUserQuestion response.
|
|
76
|
+
*/
|
|
77
|
+
type ToolUseResult = string | AskUserQuestionResult;
|
|
78
|
+
/**
|
|
79
|
+
* A single message in a Claude Code session.
|
|
80
|
+
* Stored as a line in a JSONL session file.
|
|
81
|
+
*/
|
|
82
|
+
interface Message extends TypedObject {
|
|
83
|
+
/** Unique identifier for this message */
|
|
84
|
+
uuid: string;
|
|
85
|
+
/** Parent message UUID for conversation threading */
|
|
86
|
+
parentUuid?: string | null;
|
|
87
|
+
/** Session ID this message belongs to */
|
|
88
|
+
sessionId?: string;
|
|
89
|
+
/** Timestamp in ISO format */
|
|
90
|
+
timestamp?: string;
|
|
91
|
+
/** Message content (nested payload structure) */
|
|
92
|
+
message?: MessagePayload;
|
|
93
|
+
/** Direct content (alternative to message.content) */
|
|
94
|
+
content?: ContentItem[] | string;
|
|
95
|
+
/** User-defined custom title for this message */
|
|
96
|
+
customTitle?: string;
|
|
97
|
+
/** Summary text for summary-type messages */
|
|
98
|
+
summary?: string;
|
|
99
|
+
/** Flag indicating this is a context continuation summary */
|
|
100
|
+
isCompactSummary?: boolean;
|
|
101
|
+
/** Tool use result (string for rejections, AskUserQuestionResult for Q&A) */
|
|
102
|
+
toolUseResult?: ToolUseResult;
|
|
103
|
+
}
|
|
104
|
+
/** Basic metadata for a session, used in listings and summaries */
|
|
105
|
+
interface SessionMeta {
|
|
106
|
+
id: string;
|
|
107
|
+
projectName: string;
|
|
108
|
+
title?: string;
|
|
109
|
+
messageCount: number;
|
|
110
|
+
createdAt?: string;
|
|
111
|
+
updatedAt?: string;
|
|
112
|
+
}
|
|
113
|
+
/** Project directory information */
|
|
114
|
+
interface Project {
|
|
115
|
+
name: string;
|
|
116
|
+
displayName: string;
|
|
117
|
+
path: string;
|
|
118
|
+
sessionCount: number;
|
|
119
|
+
}
|
|
120
|
+
/** A single todo item from TodoWrite tool */
|
|
121
|
+
interface TodoItem {
|
|
122
|
+
content: string;
|
|
123
|
+
status: 'pending' | 'in_progress' | 'completed';
|
|
124
|
+
/** Active form text shown during execution */
|
|
125
|
+
activeForm?: string;
|
|
126
|
+
}
|
|
127
|
+
/** Aggregated todos for a session including agent todos */
|
|
128
|
+
interface SessionTodos {
|
|
129
|
+
sessionId: string;
|
|
130
|
+
sessionTodos: TodoItem[];
|
|
131
|
+
agentTodos: {
|
|
132
|
+
agentId: string;
|
|
133
|
+
todos: TodoItem[];
|
|
134
|
+
}[];
|
|
135
|
+
hasTodos: boolean;
|
|
136
|
+
}
|
|
137
|
+
/** A file modification recorded during a session */
|
|
138
|
+
interface FileChange {
|
|
139
|
+
path: string;
|
|
140
|
+
action: 'created' | 'modified' | 'deleted';
|
|
141
|
+
timestamp?: string;
|
|
142
|
+
messageUuid?: string;
|
|
143
|
+
}
|
|
144
|
+
/** Summary of all file changes in a session */
|
|
145
|
+
interface SessionFilesSummary {
|
|
146
|
+
sessionId: string;
|
|
147
|
+
projectName: string;
|
|
148
|
+
files: FileChange[];
|
|
149
|
+
totalChanges: number;
|
|
150
|
+
}
|
|
151
|
+
/** Result of deleting a session */
|
|
152
|
+
interface DeleteSessionResult {
|
|
153
|
+
success: boolean;
|
|
154
|
+
backupPath?: string;
|
|
155
|
+
deletedAgents: number;
|
|
156
|
+
deletedTodos?: number;
|
|
157
|
+
}
|
|
158
|
+
/** Result of renaming a session */
|
|
159
|
+
interface RenameSessionResult {
|
|
160
|
+
success: boolean;
|
|
161
|
+
error?: string;
|
|
162
|
+
}
|
|
163
|
+
/** Result of splitting a session at a message */
|
|
164
|
+
interface SplitSessionResult {
|
|
165
|
+
success: boolean;
|
|
166
|
+
newSessionId?: string;
|
|
167
|
+
newSessionPath?: string;
|
|
168
|
+
movedMessageCount?: number;
|
|
169
|
+
duplicatedSummary?: boolean;
|
|
170
|
+
error?: string;
|
|
171
|
+
}
|
|
172
|
+
/** Result of moving a session to another project */
|
|
173
|
+
interface MoveSessionResult {
|
|
174
|
+
success: boolean;
|
|
175
|
+
error?: string;
|
|
176
|
+
}
|
|
177
|
+
/** Result of clearing empty/invalid sessions */
|
|
178
|
+
interface ClearSessionsResult {
|
|
179
|
+
success: boolean;
|
|
180
|
+
deletedCount: number;
|
|
181
|
+
removedMessageCount?: number;
|
|
182
|
+
deletedOrphanAgentCount?: number;
|
|
183
|
+
deletedOrphanTodoCount?: number;
|
|
184
|
+
}
|
|
185
|
+
/** Preview of sessions that would be cleaned up */
|
|
186
|
+
interface CleanupPreview {
|
|
187
|
+
project: string;
|
|
188
|
+
emptySessions: SessionMeta[];
|
|
189
|
+
invalidSessions: SessionMeta[];
|
|
190
|
+
emptyWithTodosCount?: number;
|
|
191
|
+
orphanAgentCount?: number;
|
|
192
|
+
orphanTodoCount?: number;
|
|
193
|
+
}
|
|
194
|
+
/** A search result matching a session or message */
|
|
195
|
+
interface SearchResult {
|
|
196
|
+
sessionId: string;
|
|
197
|
+
projectName: string;
|
|
198
|
+
title: string;
|
|
199
|
+
matchType: 'title' | 'content';
|
|
200
|
+
snippet?: string;
|
|
201
|
+
messageUuid?: string;
|
|
202
|
+
timestamp?: string;
|
|
203
|
+
}
|
|
204
|
+
/** Summary extracted from a session for display */
|
|
205
|
+
interface SummaryInfo {
|
|
206
|
+
summary: string;
|
|
207
|
+
leafUuid?: string;
|
|
208
|
+
timestamp?: string;
|
|
209
|
+
}
|
|
210
|
+
/** Agent information for tree display */
|
|
211
|
+
interface AgentInfo {
|
|
212
|
+
id: string;
|
|
213
|
+
name?: string;
|
|
214
|
+
messageCount: number;
|
|
215
|
+
}
|
|
216
|
+
/** Full session data for tree view rendering */
|
|
217
|
+
interface SessionTreeData {
|
|
218
|
+
id: string;
|
|
219
|
+
projectName: string;
|
|
220
|
+
/** First user message title */
|
|
221
|
+
title: string;
|
|
222
|
+
/** User-set custom title */
|
|
223
|
+
customTitle?: string;
|
|
224
|
+
/** Current (first) summary text for display/tooltip */
|
|
225
|
+
currentSummary?: string;
|
|
226
|
+
messageCount: number;
|
|
227
|
+
createdAt?: string;
|
|
228
|
+
updatedAt?: string;
|
|
229
|
+
/** All summaries in reverse order (newest first) */
|
|
230
|
+
summaries: SummaryInfo[];
|
|
231
|
+
agents: AgentInfo[];
|
|
232
|
+
todos: SessionTodos;
|
|
233
|
+
/** UUID of last compact_boundary message */
|
|
234
|
+
lastCompactBoundaryUuid?: string;
|
|
235
|
+
}
|
|
236
|
+
/** Project with all sessions for tree view */
|
|
237
|
+
interface ProjectTreeData {
|
|
238
|
+
name: string;
|
|
239
|
+
displayName: string;
|
|
240
|
+
path: string;
|
|
241
|
+
sessionCount: number;
|
|
242
|
+
sessions: SessionTreeData[];
|
|
243
|
+
}
|
|
244
|
+
/** Options for resuming a session */
|
|
245
|
+
interface ResumeSessionOptions {
|
|
246
|
+
/** Session ID to resume */
|
|
247
|
+
sessionId: string;
|
|
248
|
+
/** Working directory for the claude process */
|
|
249
|
+
cwd?: string;
|
|
250
|
+
/** Whether to fork the session instead of continuing */
|
|
251
|
+
fork?: boolean;
|
|
252
|
+
/** Additional arguments to pass to claude */
|
|
253
|
+
args?: string[];
|
|
254
|
+
}
|
|
255
|
+
/** Result of spawning a resume session process */
|
|
256
|
+
interface ResumeSessionResult {
|
|
257
|
+
success: boolean;
|
|
258
|
+
/** Process ID if spawned successfully */
|
|
259
|
+
pid?: number;
|
|
260
|
+
/** Error message if failed */
|
|
261
|
+
error?: string;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export type { AgentInfo as A, ContentItem as C, DeleteSessionResult as D, FileChange as F, MessagePayload as M, Project as P, RenameSessionResult as R, SearchResult as S, TodoItem as T, Message as a, MoveSessionResult as b, SummaryInfo as c, SessionMeta as d, SessionTodos as e, SessionFilesSummary as f, SplitSessionResult as g, ClearSessionsResult as h, CleanupPreview as i, SessionTreeData as j, ProjectTreeData as k, ResumeSessionOptions as l, ResumeSessionResult as m };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-sessions/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Core library for Claude Code session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
".": {
|
|
15
15
|
"import": "./dist/index.js",
|
|
16
16
|
"types": "./dist/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./server": {
|
|
19
|
+
"import": "./dist/server.js",
|
|
20
|
+
"types": "./dist/server.d.ts"
|
|
17
21
|
}
|
|
18
22
|
},
|
|
19
23
|
"files": [
|