@claude-sessions/core 0.3.2 → 0.3.4
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 +31 -226
- package/dist/index.js +88 -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/index.d.ts
CHANGED
|
@@ -1,231 +1,8 @@
|
|
|
1
|
+
import { M as MessagePayload, a as Message, P as Project, T as TodoItem, F as FileChange, b as MoveSessionResult, S as SearchResult, c as SummaryInfo, A as AgentInfo } from './types-C2fzbmg9.js';
|
|
2
|
+
export { i as CleanupPreview, h as ClearSessionsResult, C as ContentItem, D as DeleteSessionResult, k as ProjectTreeData, R as RenameSessionResult, l as ResumeSessionOptions, m as ResumeSessionResult, f as SessionFilesSummary, d as SessionMeta, e as SessionTodos, j as SessionTreeData, g as SplitSessionResult } from './types-C2fzbmg9.js';
|
|
1
3
|
import * as effect_Cause from 'effect/Cause';
|
|
2
4
|
import { Effect } from 'effect';
|
|
3
5
|
|
|
4
|
-
/**
|
|
5
|
-
* Core types for Claude Code session management
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Base interface for objects with a type discriminator.
|
|
9
|
-
* Used as a foundation for message and content types.
|
|
10
|
-
*/
|
|
11
|
-
interface TypedObject {
|
|
12
|
-
type: string;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Text content block in a message.
|
|
16
|
-
* @see https://docs.anthropic.com/en/api/messages
|
|
17
|
-
*/
|
|
18
|
-
interface TextContent {
|
|
19
|
-
type: 'text';
|
|
20
|
-
text: string;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Tool result content returned after tool execution.
|
|
24
|
-
* Contains the output from a tool_use request.
|
|
25
|
-
*/
|
|
26
|
-
interface ToolResultContent {
|
|
27
|
-
type: 'tool_result';
|
|
28
|
-
tool_use_id: string;
|
|
29
|
-
content: string;
|
|
30
|
-
is_error?: boolean;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Tool use request from the assistant.
|
|
34
|
-
* Represents a function call with input parameters.
|
|
35
|
-
*/
|
|
36
|
-
interface ToolUseContent {
|
|
37
|
-
type: 'tool_use';
|
|
38
|
-
id: string;
|
|
39
|
-
name: string;
|
|
40
|
-
input: unknown;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Union type for all message content blocks.
|
|
44
|
-
* Includes known types and a fallback for unknown content types.
|
|
45
|
-
*/
|
|
46
|
-
type ContentItem = TextContent | ToolResultContent | ToolUseContent | {
|
|
47
|
-
type: string;
|
|
48
|
-
text?: string;
|
|
49
|
-
name?: string;
|
|
50
|
-
input?: unknown;
|
|
51
|
-
content?: string;
|
|
52
|
-
};
|
|
53
|
-
/**
|
|
54
|
-
* Message payload containing role and content.
|
|
55
|
-
* Matches Anthropic API message structure.
|
|
56
|
-
*/
|
|
57
|
-
interface MessagePayload {
|
|
58
|
-
role?: string;
|
|
59
|
-
content?: ContentItem[] | string;
|
|
60
|
-
model?: string;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* A single message in a Claude Code session.
|
|
64
|
-
* Stored as a line in a JSONL session file.
|
|
65
|
-
*/
|
|
66
|
-
interface Message extends TypedObject {
|
|
67
|
-
/** Unique identifier for this message */
|
|
68
|
-
uuid: string;
|
|
69
|
-
/** Parent message UUID for conversation threading */
|
|
70
|
-
parentUuid?: string | null;
|
|
71
|
-
/** Session ID this message belongs to */
|
|
72
|
-
sessionId?: string;
|
|
73
|
-
/** Timestamp in ISO format */
|
|
74
|
-
timestamp?: string;
|
|
75
|
-
/** Message content (nested payload structure) */
|
|
76
|
-
message?: MessagePayload;
|
|
77
|
-
/** Direct content (alternative to message.content) */
|
|
78
|
-
content?: ContentItem[] | string;
|
|
79
|
-
/** User-defined custom title for this message */
|
|
80
|
-
customTitle?: string;
|
|
81
|
-
/** Summary text for summary-type messages */
|
|
82
|
-
summary?: string;
|
|
83
|
-
/** Flag indicating this is a context continuation summary */
|
|
84
|
-
isCompactSummary?: boolean;
|
|
85
|
-
/** Tool use result text (for tool_result messages) */
|
|
86
|
-
toolUseResult?: string;
|
|
87
|
-
}
|
|
88
|
-
/** Basic metadata for a session, used in listings and summaries */
|
|
89
|
-
interface SessionMeta {
|
|
90
|
-
id: string;
|
|
91
|
-
projectName: string;
|
|
92
|
-
title?: string;
|
|
93
|
-
messageCount: number;
|
|
94
|
-
createdAt?: string;
|
|
95
|
-
updatedAt?: string;
|
|
96
|
-
}
|
|
97
|
-
/** Project directory information */
|
|
98
|
-
interface Project {
|
|
99
|
-
name: string;
|
|
100
|
-
displayName: string;
|
|
101
|
-
path: string;
|
|
102
|
-
sessionCount: number;
|
|
103
|
-
}
|
|
104
|
-
/** A single todo item from TodoWrite tool */
|
|
105
|
-
interface TodoItem {
|
|
106
|
-
content: string;
|
|
107
|
-
status: 'pending' | 'in_progress' | 'completed';
|
|
108
|
-
/** Active form text shown during execution */
|
|
109
|
-
activeForm?: string;
|
|
110
|
-
}
|
|
111
|
-
/** Aggregated todos for a session including agent todos */
|
|
112
|
-
interface SessionTodos {
|
|
113
|
-
sessionId: string;
|
|
114
|
-
sessionTodos: TodoItem[];
|
|
115
|
-
agentTodos: {
|
|
116
|
-
agentId: string;
|
|
117
|
-
todos: TodoItem[];
|
|
118
|
-
}[];
|
|
119
|
-
hasTodos: boolean;
|
|
120
|
-
}
|
|
121
|
-
/** A file modification recorded during a session */
|
|
122
|
-
interface FileChange {
|
|
123
|
-
path: string;
|
|
124
|
-
action: 'created' | 'modified' | 'deleted';
|
|
125
|
-
timestamp?: string;
|
|
126
|
-
messageUuid?: string;
|
|
127
|
-
}
|
|
128
|
-
/** Summary of all file changes in a session */
|
|
129
|
-
interface SessionFilesSummary {
|
|
130
|
-
sessionId: string;
|
|
131
|
-
projectName: string;
|
|
132
|
-
files: FileChange[];
|
|
133
|
-
totalChanges: number;
|
|
134
|
-
}
|
|
135
|
-
/** Result of deleting a session */
|
|
136
|
-
interface DeleteSessionResult {
|
|
137
|
-
success: boolean;
|
|
138
|
-
backupPath?: string;
|
|
139
|
-
deletedAgents: number;
|
|
140
|
-
deletedTodos?: number;
|
|
141
|
-
}
|
|
142
|
-
/** Result of renaming a session */
|
|
143
|
-
interface RenameSessionResult {
|
|
144
|
-
success: boolean;
|
|
145
|
-
error?: string;
|
|
146
|
-
}
|
|
147
|
-
/** Result of splitting a session at a message */
|
|
148
|
-
interface SplitSessionResult {
|
|
149
|
-
success: boolean;
|
|
150
|
-
newSessionId?: string;
|
|
151
|
-
newSessionPath?: string;
|
|
152
|
-
movedMessageCount?: number;
|
|
153
|
-
duplicatedSummary?: boolean;
|
|
154
|
-
error?: string;
|
|
155
|
-
}
|
|
156
|
-
/** Result of moving a session to another project */
|
|
157
|
-
interface MoveSessionResult {
|
|
158
|
-
success: boolean;
|
|
159
|
-
error?: string;
|
|
160
|
-
}
|
|
161
|
-
/** Result of clearing empty/invalid sessions */
|
|
162
|
-
interface ClearSessionsResult {
|
|
163
|
-
success: boolean;
|
|
164
|
-
deletedCount: number;
|
|
165
|
-
removedMessageCount?: number;
|
|
166
|
-
deletedOrphanAgentCount?: number;
|
|
167
|
-
deletedOrphanTodoCount?: number;
|
|
168
|
-
}
|
|
169
|
-
/** Preview of sessions that would be cleaned up */
|
|
170
|
-
interface CleanupPreview {
|
|
171
|
-
project: string;
|
|
172
|
-
emptySessions: SessionMeta[];
|
|
173
|
-
invalidSessions: SessionMeta[];
|
|
174
|
-
emptyWithTodosCount?: number;
|
|
175
|
-
orphanAgentCount?: number;
|
|
176
|
-
orphanTodoCount?: number;
|
|
177
|
-
}
|
|
178
|
-
/** A search result matching a session or message */
|
|
179
|
-
interface SearchResult {
|
|
180
|
-
sessionId: string;
|
|
181
|
-
projectName: string;
|
|
182
|
-
title: string;
|
|
183
|
-
matchType: 'title' | 'content';
|
|
184
|
-
snippet?: string;
|
|
185
|
-
messageUuid?: string;
|
|
186
|
-
timestamp?: string;
|
|
187
|
-
}
|
|
188
|
-
/** Summary extracted from a session for display */
|
|
189
|
-
interface SummaryInfo {
|
|
190
|
-
summary: string;
|
|
191
|
-
leafUuid?: string;
|
|
192
|
-
timestamp?: string;
|
|
193
|
-
}
|
|
194
|
-
/** Agent information for tree display */
|
|
195
|
-
interface AgentInfo {
|
|
196
|
-
id: string;
|
|
197
|
-
name?: string;
|
|
198
|
-
messageCount: number;
|
|
199
|
-
}
|
|
200
|
-
/** Full session data for tree view rendering */
|
|
201
|
-
interface SessionTreeData {
|
|
202
|
-
id: string;
|
|
203
|
-
projectName: string;
|
|
204
|
-
/** First user message title */
|
|
205
|
-
title: string;
|
|
206
|
-
/** User-set custom title */
|
|
207
|
-
customTitle?: string;
|
|
208
|
-
/** Current (first) summary text for display/tooltip */
|
|
209
|
-
currentSummary?: string;
|
|
210
|
-
messageCount: number;
|
|
211
|
-
createdAt?: string;
|
|
212
|
-
updatedAt?: string;
|
|
213
|
-
/** All summaries in reverse order (newest first) */
|
|
214
|
-
summaries: SummaryInfo[];
|
|
215
|
-
agents: AgentInfo[];
|
|
216
|
-
todos: SessionTodos;
|
|
217
|
-
/** UUID of last compact_boundary message */
|
|
218
|
-
lastCompactBoundaryUuid?: string;
|
|
219
|
-
}
|
|
220
|
-
/** Project with all sessions for tree view */
|
|
221
|
-
interface ProjectTreeData {
|
|
222
|
-
name: string;
|
|
223
|
-
displayName: string;
|
|
224
|
-
path: string;
|
|
225
|
-
sessionCount: number;
|
|
226
|
-
sessions: SessionTreeData[];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
6
|
interface Logger$1 {
|
|
230
7
|
debug: (msg: string) => void;
|
|
231
8
|
warn: (msg: string) => void;
|
|
@@ -266,6 +43,18 @@ declare const getRealPathFromSession: (folderName: string, sessionsDir?: string,
|
|
|
266
43
|
* If path is under home directory, show relative (~/...)
|
|
267
44
|
*/
|
|
268
45
|
declare const folderNameToPath: (folderName: string) => string;
|
|
46
|
+
/**
|
|
47
|
+
* Find project folder name that matches the given workspace path
|
|
48
|
+
* Searches through all projects and checks if any session's cwd matches
|
|
49
|
+
*
|
|
50
|
+
* @param workspacePath - Absolute path of current workspace
|
|
51
|
+
* @param projectNames - List of project folder names to search
|
|
52
|
+
* @param sessionsDir - Optional sessions directory for testing
|
|
53
|
+
* @param fileSystem - Optional FileSystem for testing
|
|
54
|
+
* @param logger - Optional Logger for testing
|
|
55
|
+
* @returns Matching project folder name or null
|
|
56
|
+
*/
|
|
57
|
+
declare const findProjectByWorkspacePath: (workspacePath: string, projectNames: string[], sessionsDir?: string, fileSystem?: FileSystem, logger?: Logger$1) => string | null;
|
|
269
58
|
|
|
270
59
|
/**
|
|
271
60
|
* Utility functions for message processing
|
|
@@ -280,6 +69,22 @@ declare const isContinuationSummary: (msg: Message) => boolean;
|
|
|
280
69
|
* Priority: customTitle > currentSummary (truncated) > title > fallback
|
|
281
70
|
*/
|
|
282
71
|
declare const getDisplayTitle: (customTitle: string | undefined, currentSummary: string | undefined, title: string | undefined, maxLength?: number, fallback?: string) => string;
|
|
72
|
+
/**
|
|
73
|
+
* Mask home directory path with ~
|
|
74
|
+
* Only masks the specified homeDir, not other users' paths
|
|
75
|
+
*/
|
|
76
|
+
declare const maskHomePath: (text: string, homeDir: string) => string;
|
|
77
|
+
/**
|
|
78
|
+
* Sort projects with priority:
|
|
79
|
+
* 1. Current project (if specified)
|
|
80
|
+
* 2. Current user's home directory subpaths
|
|
81
|
+
* 3. Others (alphabetically by displayName)
|
|
82
|
+
*/
|
|
83
|
+
declare const sortProjects: (projects: Project[], options?: {
|
|
84
|
+
currentProjectName?: string | null;
|
|
85
|
+
homeDir?: string;
|
|
86
|
+
filterEmpty?: boolean;
|
|
87
|
+
}) => Project[];
|
|
283
88
|
|
|
284
89
|
declare const findLinkedAgents: (projectName: string, sessionId: string) => Effect.Effect<string[], effect_Cause.UnknownException, never>;
|
|
285
90
|
declare const findOrphanAgents: (projectName: string) => Effect.Effect<{
|
|
@@ -507,4 +312,4 @@ declare const getLogger: () => Logger;
|
|
|
507
312
|
*/
|
|
508
313
|
declare const createLogger: (namespace: string) => Logger;
|
|
509
314
|
|
|
510
|
-
export {
|
|
315
|
+
export { AgentInfo, FileChange, type Logger, Message, MessagePayload, MoveSessionResult, Project, SearchResult, SummaryInfo, TodoItem, clearSessions, createLogger, deleteLinkedTodos, deleteMessage, deleteOrphanAgents, deleteOrphanTodos, deleteSession, displayPathToFolderName, extractTextContent, extractTitle, findLinkedAgents, findLinkedTodos, findOrphanAgents, findOrphanTodos, findProjectByWorkspacePath, folderNameToDisplayPath, folderNameToPath, getDisplayTitle, getLogger, getRealPathFromSession, getSessionFiles, getSessionsDir, getTodosDir, isContinuationSummary, isInvalidApiKeyMessage, listProjects, listSessions, loadAgentMessages, loadProjectTreeData, loadSessionTreeData, maskHomePath, moveSession, pathToFolderName, previewCleanup, readSession, renameSession, restoreMessage, searchSessions, sessionHasTodos, setLogger, sortProjects, splitSession, updateSessionSummary };
|
package/dist/index.js
CHANGED
|
@@ -135,6 +135,30 @@ var folderNameToPath = (folderName) => {
|
|
|
135
135
|
const absolutePath = folderNameToDisplayPath(folderName);
|
|
136
136
|
return toRelativePath(absolutePath, homeDir);
|
|
137
137
|
};
|
|
138
|
+
var findProjectByWorkspacePath = (workspacePath, projectNames, sessionsDir = getSessionsDir(), fileSystem = fs, logger2 = log) => {
|
|
139
|
+
const directMatch = pathToFolderName(workspacePath);
|
|
140
|
+
if (projectNames.includes(directMatch)) {
|
|
141
|
+
return directMatch;
|
|
142
|
+
}
|
|
143
|
+
for (const projectName of projectNames) {
|
|
144
|
+
const projectDir = path.join(sessionsDir, projectName);
|
|
145
|
+
try {
|
|
146
|
+
const files = fileSystem.readdirSync(projectDir).filter(isSessionFile);
|
|
147
|
+
for (const f of files) {
|
|
148
|
+
const cwd = tryGetCwdFromFile(path.join(projectDir, f), fileSystem, logger2);
|
|
149
|
+
if (cwd === workspacePath) {
|
|
150
|
+
logger2.debug(
|
|
151
|
+
`findProjectByWorkspacePath: ${workspacePath} -> found in ${projectName} (moved session)`
|
|
152
|
+
);
|
|
153
|
+
return projectName;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
logger2.debug(`findProjectByWorkspacePath: ${workspacePath} -> no matching project found`);
|
|
160
|
+
return null;
|
|
161
|
+
};
|
|
138
162
|
|
|
139
163
|
// src/utils.ts
|
|
140
164
|
var logger = createLogger("utils");
|
|
@@ -186,22 +210,56 @@ var getDisplayTitle = (customTitle, currentSummary, title, maxLength = 60, fallb
|
|
|
186
210
|
if (title && title !== "Untitled") return title;
|
|
187
211
|
return fallback;
|
|
188
212
|
};
|
|
213
|
+
var replaceMessageContent = (msg, text) => ({
|
|
214
|
+
...msg,
|
|
215
|
+
message: {
|
|
216
|
+
...msg.message,
|
|
217
|
+
content: [{ type: "text", text }]
|
|
218
|
+
},
|
|
219
|
+
toolUseResult: void 0
|
|
220
|
+
});
|
|
189
221
|
var cleanupSplitFirstMessage = (msg) => {
|
|
190
222
|
const toolUseResult = msg.toolUseResult;
|
|
191
223
|
if (!toolUseResult) return msg;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
224
|
+
if (typeof toolUseResult === "object" && "answers" in toolUseResult) {
|
|
225
|
+
const answers = toolUseResult.answers;
|
|
226
|
+
const qaText = Object.entries(answers).map(([q, a]) => `Q: ${q}
|
|
227
|
+
A: ${a}`).join("\n\n");
|
|
228
|
+
return replaceMessageContent(msg, qaText);
|
|
229
|
+
}
|
|
230
|
+
if (typeof toolUseResult === "string") {
|
|
231
|
+
const rejectionMarker = "The user provided the following reason for the rejection:";
|
|
232
|
+
const rejectionIndex = toolUseResult.indexOf(rejectionMarker);
|
|
233
|
+
if (rejectionIndex === -1) return msg;
|
|
234
|
+
const text = toolUseResult.slice(rejectionIndex + rejectionMarker.length).trim();
|
|
235
|
+
if (!text) return msg;
|
|
236
|
+
return replaceMessageContent(msg, text);
|
|
237
|
+
}
|
|
238
|
+
return msg;
|
|
239
|
+
};
|
|
240
|
+
var maskHomePath = (text, homeDir) => {
|
|
241
|
+
if (!homeDir) return text;
|
|
242
|
+
const escapedHome = homeDir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
243
|
+
const regex = new RegExp(`${escapedHome}(?=[/\\\\]|$)`, "g");
|
|
244
|
+
return text.replace(regex, "~");
|
|
245
|
+
};
|
|
246
|
+
var sortProjects = (projects, options = {}) => {
|
|
247
|
+
const { currentProjectName, homeDir, filterEmpty = true } = options;
|
|
248
|
+
const filtered = filterEmpty ? projects.filter((p) => p.sessionCount > 0) : projects;
|
|
249
|
+
const homeDirPrefix = homeDir ? pathToFolderName(homeDir) : null;
|
|
250
|
+
return filtered.sort((a, b) => {
|
|
251
|
+
if (currentProjectName) {
|
|
252
|
+
if (a.name === currentProjectName) return -1;
|
|
253
|
+
if (b.name === currentProjectName) return 1;
|
|
254
|
+
}
|
|
255
|
+
if (homeDirPrefix) {
|
|
256
|
+
const aIsUserHome = a.name.startsWith(homeDirPrefix);
|
|
257
|
+
const bIsUserHome = b.name.startsWith(homeDirPrefix);
|
|
258
|
+
if (aIsUserHome && !bIsUserHome) return -1;
|
|
259
|
+
if (!aIsUserHome && bIsUserHome) return 1;
|
|
260
|
+
}
|
|
261
|
+
return a.displayName.localeCompare(b.displayName);
|
|
262
|
+
});
|
|
205
263
|
};
|
|
206
264
|
|
|
207
265
|
// src/agents.ts
|
|
@@ -847,36 +905,40 @@ var splitSession = (projectName, sessionId, splitAtMessageUuid) => Effect3.gen(f
|
|
|
847
905
|
const summaryMessage = summaryMessages.length > 0 ? summaryMessages[summaryMessages.length - 1] : null;
|
|
848
906
|
const splitMessage = allMessages[splitIndex];
|
|
849
907
|
const shouldDuplicate = isContinuationSummary(splitMessage);
|
|
850
|
-
let
|
|
851
|
-
|
|
908
|
+
let keptMessages = allMessages.slice(splitIndex);
|
|
909
|
+
let movedMessages;
|
|
852
910
|
if (shouldDuplicate) {
|
|
853
911
|
const duplicatedMessage = {
|
|
854
912
|
...splitMessage,
|
|
855
913
|
uuid: crypto.randomUUID(),
|
|
856
|
-
sessionId
|
|
857
|
-
// Keep original session ID
|
|
914
|
+
sessionId: newSessionId
|
|
858
915
|
};
|
|
859
|
-
|
|
916
|
+
movedMessages = [...allMessages.slice(0, splitIndex), duplicatedMessage];
|
|
860
917
|
} else {
|
|
861
|
-
|
|
918
|
+
movedMessages = allMessages.slice(0, splitIndex);
|
|
862
919
|
}
|
|
863
|
-
|
|
864
|
-
let updated = { ...msg
|
|
920
|
+
keptMessages = keptMessages.map((msg, index) => {
|
|
921
|
+
let updated = { ...msg };
|
|
865
922
|
if (index === 0) {
|
|
866
923
|
updated.parentUuid = null;
|
|
867
924
|
updated = cleanupSplitFirstMessage(updated);
|
|
868
925
|
}
|
|
869
926
|
return updated;
|
|
870
927
|
});
|
|
928
|
+
const updatedMovedMessages = movedMessages.map((msg) => ({
|
|
929
|
+
...msg,
|
|
930
|
+
sessionId: newSessionId
|
|
931
|
+
}));
|
|
871
932
|
if (summaryMessage) {
|
|
872
933
|
const clonedSummary = {
|
|
873
934
|
...summaryMessage,
|
|
935
|
+
sessionId: newSessionId,
|
|
874
936
|
leafUuid: updatedMovedMessages[0]?.uuid ?? null
|
|
875
937
|
};
|
|
876
938
|
updatedMovedMessages.unshift(clonedSummary);
|
|
877
939
|
}
|
|
878
|
-
const
|
|
879
|
-
yield* Effect3.tryPromise(() => fs4.writeFile(filePath,
|
|
940
|
+
const keptContent = keptMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
941
|
+
yield* Effect3.tryPromise(() => fs4.writeFile(filePath, keptContent, "utf-8"));
|
|
880
942
|
const newFilePath = path4.join(projectPath, `${newSessionId}.jsonl`);
|
|
881
943
|
const newContent = updatedMovedMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
882
944
|
yield* Effect3.tryPromise(() => fs4.writeFile(newFilePath, newContent, "utf-8"));
|
|
@@ -1367,6 +1429,7 @@ export {
|
|
|
1367
1429
|
findLinkedTodos,
|
|
1368
1430
|
findOrphanAgents,
|
|
1369
1431
|
findOrphanTodos,
|
|
1432
|
+
findProjectByWorkspacePath,
|
|
1370
1433
|
folderNameToDisplayPath,
|
|
1371
1434
|
folderNameToPath,
|
|
1372
1435
|
getDisplayTitle,
|
|
@@ -1382,6 +1445,7 @@ export {
|
|
|
1382
1445
|
loadAgentMessages,
|
|
1383
1446
|
loadProjectTreeData,
|
|
1384
1447
|
loadSessionTreeData,
|
|
1448
|
+
maskHomePath,
|
|
1385
1449
|
moveSession,
|
|
1386
1450
|
pathToFolderName,
|
|
1387
1451
|
previewCleanup,
|
|
@@ -1391,6 +1455,7 @@ export {
|
|
|
1391
1455
|
searchSessions,
|
|
1392
1456
|
sessionHasTodos,
|
|
1393
1457
|
setLogger,
|
|
1458
|
+
sortProjects,
|
|
1394
1459
|
splitSession,
|
|
1395
1460
|
updateSessionSummary
|
|
1396
1461
|
};
|