@claude-sessions/core 0.4.4-beta.1 → 0.4.4-beta.2

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 CHANGED
@@ -123,6 +123,147 @@ declare const parseJsonlLines: <T = Record<string, unknown>>(lines: string[], fi
123
123
  * Combines file reading and JSONL parsing with proper error messages
124
124
  */
125
125
  declare const readJsonlFile: <T = Record<string, unknown>>(filePath: string) => Effect.Effect<T[], effect_Cause.UnknownException, never>;
126
+ /**
127
+ * Format timestamp as relative time (e.g., "2h ago", "3d ago")
128
+ * Used by both VSCode Extension tree view and Web UI
129
+ *
130
+ * @param timestamp - Unix timestamp (ms) or ISO date string
131
+ * @returns Relative time string
132
+ */
133
+ declare const formatRelativeTime: (timestamp: number | string) => string;
134
+ /**
135
+ * Calculate total todo count from session todos
136
+ * Includes both session-level and agent-level todos
137
+ */
138
+ declare const getTotalTodoCount: (todos: SessionTodos) => number;
139
+ /**
140
+ * Check if session has sub-items (summaries, agents, or todos)
141
+ * Used to determine if tree item should be expandable
142
+ */
143
+ declare const sessionHasSubItems: (data: {
144
+ summaries: {
145
+ length: number;
146
+ };
147
+ agents: {
148
+ length: number;
149
+ };
150
+ todos: SessionTodos;
151
+ }) => boolean;
152
+ /**
153
+ * Get session tooltip text based on what's displayed as title
154
+ * Shows complementary information to the displayed title + session ID
155
+ *
156
+ * Logic:
157
+ * - If customTitle is displayed → show currentSummary
158
+ * - If currentSummary is displayed → show original title
159
+ * - If title is displayed → show currentSummary
160
+ * - Always append session ID at the end
161
+ */
162
+ declare const getSessionTooltip: (session: {
163
+ id: string;
164
+ title?: string;
165
+ customTitle?: string;
166
+ currentSummary?: string;
167
+ createdAt?: string;
168
+ updatedAt?: string;
169
+ }) => string;
170
+ /**
171
+ * Check if session can be moved to target project
172
+ * Returns false if source and target are the same project
173
+ */
174
+ declare const canMoveSession: (sourceProject: string, targetProject: string) => boolean;
175
+
176
+ /**
177
+ * Shared constants and utilities for tree view rendering
178
+ * Used by both VSCode Extension and Web UI
179
+ */
180
+ /**
181
+ * Tree item type discriminator
182
+ * Used for identifying node types in both VSCode TreeView and Web UI
183
+ */
184
+ type TreeItemType = 'project' | 'session' | 'summaries-group' | 'todos-group' | 'agents-group' | 'summary' | 'todo' | 'agent';
185
+ /**
186
+ * Icon definition with both VSCode codicon and emoji variants
187
+ */
188
+ interface IconDef {
189
+ /** VSCode codicon name (without 'codicon-' prefix) */
190
+ codicon: string;
191
+ /** Emoji for web/terminal display */
192
+ emoji: string;
193
+ }
194
+ /**
195
+ * Todo status icon with optional color
196
+ */
197
+ interface TodoIconDef extends IconDef {
198
+ /** Optional color for VSCode ThemeColor */
199
+ color?: 'green' | 'yellow';
200
+ }
201
+ /**
202
+ * Icon mappings for all tree item types
203
+ * - Use `.codicon` for VSCode Extension (ThemeIcon)
204
+ * - Use `.emoji` for Web UI and terminal
205
+ */
206
+ declare const TREE_ICONS: {
207
+ readonly project: {
208
+ readonly codicon: "folder";
209
+ readonly emoji: "📁";
210
+ };
211
+ readonly session: {
212
+ readonly codicon: "comment-discussion";
213
+ readonly emoji: "💬";
214
+ };
215
+ readonly 'summaries-group': {
216
+ readonly codicon: "history";
217
+ readonly emoji: "📝";
218
+ };
219
+ readonly 'todos-group': {
220
+ readonly codicon: "checklist";
221
+ readonly emoji: "📋";
222
+ };
223
+ readonly 'agents-group': {
224
+ readonly codicon: "hubot";
225
+ readonly emoji: "🤖";
226
+ };
227
+ readonly summary: {
228
+ readonly codicon: "note";
229
+ readonly emoji: "📝";
230
+ };
231
+ readonly agent: {
232
+ readonly codicon: "hubot";
233
+ readonly emoji: "🤖";
234
+ };
235
+ readonly todo: {
236
+ readonly completed: TodoIconDef;
237
+ readonly in_progress: TodoIconDef;
238
+ readonly pending: TodoIconDef;
239
+ };
240
+ };
241
+ /**
242
+ * Get todo icon based on status
243
+ */
244
+ declare const getTodoIcon: (status: "pending" | "in_progress" | "completed") => TodoIconDef;
245
+ /**
246
+ * Generate unique tree node ID for drag & drop and state management
247
+ * Format: `{type}:{projectName}:{sessionId}[:agentId][:itemIndex]`
248
+ *
249
+ * @example
250
+ * generateTreeNodeId('session', 'my-project', 'abc123')
251
+ * // => 'session:my-project:abc123'
252
+ *
253
+ * generateTreeNodeId('todo', 'my-project', 'abc123', 'agent-1', 0)
254
+ * // => 'todo:my-project:abc123:agent-1:0'
255
+ */
256
+ declare const generateTreeNodeId: (type: TreeItemType, projectName: string, sessionId: string, agentId?: string, itemIndex?: number) => string;
257
+ /**
258
+ * Parse tree node ID back to components
259
+ */
260
+ declare const parseTreeNodeId: (id: string) => {
261
+ type: TreeItemType;
262
+ projectName: string;
263
+ sessionId: string;
264
+ agentId?: string;
265
+ itemIndex?: number;
266
+ } | null;
126
267
 
127
268
  declare const findLinkedAgents: (projectName: string, sessionId: string) => Effect.Effect<string[], effect_Cause.UnknownException, never>;
128
269
  declare const findOrphanAgents: (projectName: string) => Effect.Effect<{
@@ -527,4 +668,4 @@ declare const getLogger: () => Logger;
527
668
  */
528
669
  declare const createLogger: (namespace: string) => Logger;
529
670
 
530
- export { AgentInfo, type ChainError, CompressSessionOptions, ConversationLine, FileChange, type GenericMessage, type Logger, Message, MessagePayload$1 as MessagePayload, MoveSessionResult, type ProgressError, Project, ProjectTreeData, SearchResult, SessionIndexEntry, SessionSortOptions, SessionTodos, SessionsIndex, SummarizeSessionOptions, SummaryInfo, type ToolUseResultError, type ValidationResult, analyzeSession, autoRepairChain, clearSessions, compressSession, createLogger, deleteLinkedTodos, deleteMessage, deleteMessageWithChainRepair, deleteOrphanAgents, deleteOrphanTodos, deleteSession, displayPathToFolderName, extractProjectKnowledge, extractTextContent, extractTitle, findLinkedAgents, findLinkedTodos, findOrphanAgents, findOrphanTodos, findProjectByWorkspacePath, folderNameToDisplayPath, folderNameToPath, getDisplayTitle, getIndexEntryDisplayTitle, getLogger, getRealPathFromSession, getSessionFiles, getSessionSortTimestamp, getSessionsDir, getTodosDir, hasSessionsIndex, isContinuationSummary, isInvalidApiKeyMessage, listProjects, listSessions, loadAgentMessages, loadProjectTreeData, loadSessionTreeData, loadSessionsIndex, maskHomePath, moveSession, parseCommandMessage, parseJsonlLines, pathToFolderName, previewCleanup, readJsonlFile, readSession, renameSession, repairChain, repairParentUuidChain, restoreMessage, searchSessions, sessionHasTodos, setLogger, sortIndexEntriesByModified, sortProjects, splitSession, summarizeSession, tryParseJsonLine, updateSessionSummary, validateChain, validateProgressMessages, validateToolUseResult };
671
+ export { AgentInfo, type ChainError, CompressSessionOptions, ConversationLine, FileChange, type GenericMessage, type Logger, Message, MessagePayload$1 as MessagePayload, MoveSessionResult, type ProgressError, Project, ProjectTreeData, SearchResult, SessionIndexEntry, SessionSortOptions, SessionTodos, SessionsIndex, SummarizeSessionOptions, SummaryInfo, TREE_ICONS, type ToolUseResultError, type TreeItemType, type ValidationResult, analyzeSession, autoRepairChain, canMoveSession, clearSessions, compressSession, createLogger, deleteLinkedTodos, deleteMessage, deleteMessageWithChainRepair, deleteOrphanAgents, deleteOrphanTodos, deleteSession, displayPathToFolderName, extractProjectKnowledge, extractTextContent, extractTitle, findLinkedAgents, findLinkedTodos, findOrphanAgents, findOrphanTodos, findProjectByWorkspacePath, folderNameToDisplayPath, folderNameToPath, formatRelativeTime, generateTreeNodeId, getDisplayTitle, getIndexEntryDisplayTitle, getLogger, getRealPathFromSession, getSessionFiles, getSessionSortTimestamp, getSessionTooltip, getSessionsDir, getTodoIcon, getTodosDir, getTotalTodoCount, hasSessionsIndex, isContinuationSummary, isInvalidApiKeyMessage, listProjects, listSessions, loadAgentMessages, loadProjectTreeData, loadSessionTreeData, loadSessionsIndex, maskHomePath, moveSession, parseCommandMessage, parseJsonlLines, parseTreeNodeId, pathToFolderName, previewCleanup, readJsonlFile, readSession, renameSession, repairChain, repairParentUuidChain, restoreMessage, searchSessions, sessionHasSubItems, sessionHasTodos, setLogger, sortIndexEntriesByModified, sortProjects, splitSession, summarizeSession, tryParseJsonLine, updateSessionSummary, validateChain, validateProgressMessages, validateToolUseResult };
package/dist/index.js CHANGED
@@ -72,9 +72,6 @@ var extractTitle = (input) => {
72
72
  if (cleaned.includes("\n\n")) {
73
73
  cleaned = cleaned.split("\n\n")[0];
74
74
  }
75
- if (cleaned.length > 100) {
76
- return cleaned.slice(0, 100) + "...";
77
- }
78
75
  return cleaned || "Untitled";
79
76
  };
80
77
  var isInvalidApiKeyMessage = (msg) => {
@@ -174,6 +171,51 @@ var readJsonlFile = (filePath) => Effect.gen(function* () {
174
171
  const lines = content.trim().split("\n").filter(Boolean);
175
172
  return parseJsonlLines(lines, filePath);
176
173
  });
174
+ var formatRelativeTime = (timestamp) => {
175
+ const date = typeof timestamp === "string" ? new Date(timestamp) : new Date(timestamp);
176
+ const now = /* @__PURE__ */ new Date();
177
+ const diff = now.getTime() - date.getTime();
178
+ const minutes = Math.floor(diff / 6e4);
179
+ const hours = Math.floor(diff / 36e5);
180
+ const days = Math.floor(diff / 864e5);
181
+ if (minutes < 1) return "just now";
182
+ if (minutes < 60) return `${minutes}m ago`;
183
+ if (hours < 24) return `${hours}h ago`;
184
+ if (days < 7) return `${days}d ago`;
185
+ return date.toLocaleDateString();
186
+ };
187
+ var getTotalTodoCount = (todos) => {
188
+ return todos.sessionTodos.length + todos.agentTodos.reduce((sum, a) => sum + a.todos.length, 0);
189
+ };
190
+ var sessionHasSubItems = (data) => {
191
+ const todoCount = getTotalTodoCount(data.todos);
192
+ return data.summaries.length > 0 || data.agents.length > 0 || todoCount > 0;
193
+ };
194
+ var getSessionTooltip = (session) => {
195
+ const { id, title, customTitle, currentSummary, createdAt, updatedAt } = session;
196
+ let text;
197
+ if (customTitle && currentSummary) {
198
+ text = currentSummary;
199
+ } else if (currentSummary && title && title !== "Untitled") {
200
+ text = title;
201
+ } else if (currentSummary) {
202
+ text = currentSummary;
203
+ } else {
204
+ text = title ?? "No title";
205
+ }
206
+ const lines = [`ID: ${id}`];
207
+ if (createdAt) {
208
+ lines.push(`Created: ${new Date(createdAt).toLocaleString()}`);
209
+ }
210
+ if (updatedAt) {
211
+ lines.push(`Updated: ${new Date(updatedAt).toLocaleString()}`);
212
+ }
213
+ text += "\n\n" + lines.join("\n");
214
+ return text;
215
+ };
216
+ var canMoveSession = (sourceProject, targetProject) => {
217
+ return sourceProject !== targetProject;
218
+ };
177
219
 
178
220
  // src/paths.ts
179
221
  var log = createLogger("paths");
@@ -324,6 +366,50 @@ var sortProjects = (projects, options = {}) => {
324
366
  });
325
367
  };
326
368
 
369
+ // src/tree-constants.ts
370
+ var TREE_ICONS = {
371
+ project: { codicon: "folder", emoji: "\u{1F4C1}" },
372
+ session: { codicon: "comment-discussion", emoji: "\u{1F4AC}" },
373
+ "summaries-group": { codicon: "history", emoji: "\u{1F4DD}" },
374
+ "todos-group": { codicon: "checklist", emoji: "\u{1F4CB}" },
375
+ "agents-group": { codicon: "hubot", emoji: "\u{1F916}" },
376
+ summary: { codicon: "note", emoji: "\u{1F4DD}" },
377
+ agent: { codicon: "hubot", emoji: "\u{1F916}" },
378
+ todo: {
379
+ completed: { codicon: "pass-filled", emoji: "\u2705", color: "green" },
380
+ in_progress: { codicon: "sync~spin", emoji: "\u{1F504}", color: "yellow" },
381
+ pending: { codicon: "circle-outline", emoji: "\u2B55" }
382
+ }
383
+ };
384
+ var getTodoIcon = (status) => {
385
+ return TREE_ICONS.todo[status];
386
+ };
387
+ var generateTreeNodeId = (type, projectName, sessionId, agentId, itemIndex) => {
388
+ let id = `${type}:${projectName}:${sessionId}`;
389
+ if (agentId) id += `:${agentId}`;
390
+ if (itemIndex !== void 0) id += `:${itemIndex}`;
391
+ return id;
392
+ };
393
+ var parseTreeNodeId = (id) => {
394
+ const parts = id.split(":");
395
+ if (parts.length < 3) return null;
396
+ const result = {
397
+ type: parts[0],
398
+ projectName: parts[1],
399
+ sessionId: parts[2]
400
+ };
401
+ if (parts.length >= 4 && parts[3]) {
402
+ result.agentId = parts[3];
403
+ }
404
+ if (parts.length >= 5 && parts[4]) {
405
+ const idx = parseInt(parts[4], 10);
406
+ if (!isNaN(idx)) {
407
+ result.itemIndex = idx;
408
+ }
409
+ }
410
+ return result;
411
+ };
412
+
327
413
  // src/agents.ts
328
414
  import { Effect as Effect2 } from "effect";
329
415
  import * as fs3 from "fs/promises";
@@ -2276,8 +2362,10 @@ var hasSessionsIndex = (projectName) => Effect11.gen(function* () {
2276
2362
  }
2277
2363
  });
2278
2364
  export {
2365
+ TREE_ICONS,
2279
2366
  analyzeSession,
2280
2367
  autoRepairChain,
2368
+ canMoveSession,
2281
2369
  clearSessions,
2282
2370
  compressSession,
2283
2371
  createLogger,
@@ -2298,14 +2386,19 @@ export {
2298
2386
  findProjectByWorkspacePath,
2299
2387
  folderNameToDisplayPath,
2300
2388
  folderNameToPath,
2389
+ formatRelativeTime,
2390
+ generateTreeNodeId,
2301
2391
  getDisplayTitle,
2302
2392
  getIndexEntryDisplayTitle,
2303
2393
  getLogger,
2304
2394
  getRealPathFromSession,
2305
2395
  getSessionFiles,
2306
2396
  getSessionSortTimestamp,
2397
+ getSessionTooltip,
2307
2398
  getSessionsDir,
2399
+ getTodoIcon,
2308
2400
  getTodosDir,
2401
+ getTotalTodoCount,
2309
2402
  hasSessionsIndex,
2310
2403
  isContinuationSummary,
2311
2404
  isInvalidApiKeyMessage,
@@ -2319,6 +2412,7 @@ export {
2319
2412
  moveSession,
2320
2413
  parseCommandMessage,
2321
2414
  parseJsonlLines,
2415
+ parseTreeNodeId,
2322
2416
  pathToFolderName,
2323
2417
  previewCleanup,
2324
2418
  readJsonlFile,
@@ -2328,6 +2422,7 @@ export {
2328
2422
  repairParentUuidChain,
2329
2423
  restoreMessage,
2330
2424
  searchSessions,
2425
+ sessionHasSubItems,
2331
2426
  sessionHasTodos,
2332
2427
  setLogger,
2333
2428
  sortIndexEntriesByModified,