@herdctl/core 5.6.0 → 5.7.1
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/config/__tests__/merge.test.js +1 -1
- package/dist/config/__tests__/merge.test.js.map +1 -1
- package/dist/config/schema.d.ts +10 -2
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +6 -2
- package/dist/config/schema.js.map +1 -1
- package/dist/scheduler/schedule-runner.d.ts.map +1 -1
- package/dist/scheduler/schedule-runner.js +6 -5
- package/dist/scheduler/schedule-runner.js.map +1 -1
- package/dist/state/__tests__/jsonl-parser.test.d.ts +5 -0
- package/dist/state/__tests__/jsonl-parser.test.d.ts.map +1 -0
- package/dist/state/__tests__/jsonl-parser.test.js +332 -0
- package/dist/state/__tests__/jsonl-parser.test.js.map +1 -0
- package/dist/state/__tests__/session-attribution.test.d.ts +2 -0
- package/dist/state/__tests__/session-attribution.test.d.ts.map +1 -0
- package/dist/state/__tests__/session-attribution.test.js +567 -0
- package/dist/state/__tests__/session-attribution.test.js.map +1 -0
- package/dist/state/__tests__/session-discovery.test.d.ts +2 -0
- package/dist/state/__tests__/session-discovery.test.d.ts.map +1 -0
- package/dist/state/__tests__/session-discovery.test.js +953 -0
- package/dist/state/__tests__/session-discovery.test.js.map +1 -0
- package/dist/state/__tests__/session-metadata.test.d.ts +2 -0
- package/dist/state/__tests__/session-metadata.test.d.ts.map +1 -0
- package/dist/state/__tests__/session-metadata.test.js +474 -0
- package/dist/state/__tests__/session-metadata.test.js.map +1 -0
- package/dist/state/__tests__/tool-parsing.test.d.ts +5 -0
- package/dist/state/__tests__/tool-parsing.test.d.ts.map +1 -0
- package/dist/state/__tests__/tool-parsing.test.js +315 -0
- package/dist/state/__tests__/tool-parsing.test.js.map +1 -0
- package/dist/state/index.d.ts +5 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +10 -0
- package/dist/state/index.js.map +1 -1
- package/dist/state/jsonl-parser.d.ts +126 -0
- package/dist/state/jsonl-parser.d.ts.map +1 -0
- package/dist/state/jsonl-parser.js +482 -0
- package/dist/state/jsonl-parser.js.map +1 -0
- package/dist/state/session-attribution.d.ts +35 -0
- package/dist/state/session-attribution.d.ts.map +1 -0
- package/dist/state/session-attribution.js +179 -0
- package/dist/state/session-attribution.js.map +1 -0
- package/dist/state/session-discovery.d.ts +198 -0
- package/dist/state/session-discovery.d.ts.map +1 -0
- package/dist/state/session-discovery.js +555 -0
- package/dist/state/session-discovery.js.map +1 -0
- package/dist/state/session-metadata.d.ts +240 -0
- package/dist/state/session-metadata.d.ts.map +1 -0
- package/dist/state/session-metadata.js +377 -0
- package/dist/state/session-metadata.js.map +1 -0
- package/dist/state/tool-parsing.d.ts +88 -0
- package/dist/state/tool-parsing.d.ts.map +1 -0
- package/dist/state/tool-parsing.js +199 -0
- package/dist/state/tool-parsing.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Metadata Store
|
|
3
|
+
*
|
|
4
|
+
* Manages user-customizable metadata for Claude Code sessions.
|
|
5
|
+
* Metadata is stored sparsely in .herdctl/session-metadata/{agent-qualified-name}.json
|
|
6
|
+
* Files are only created when the first custom name is set for an agent.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
/**
|
|
10
|
+
* Schema for a single session's metadata entry
|
|
11
|
+
*/
|
|
12
|
+
export declare const SessionMetadataEntrySchema: z.ZodObject<{
|
|
13
|
+
customName: z.ZodOptional<z.ZodString>;
|
|
14
|
+
/** Auto-generated session name (extracted from JSONL summary) */
|
|
15
|
+
autoName: z.ZodOptional<z.ZodString>;
|
|
16
|
+
/** ISO 8601 timestamp of when autoName was extracted (for cache invalidation) */
|
|
17
|
+
autoNameMtime: z.ZodOptional<z.ZodString>;
|
|
18
|
+
/** First user message preview (truncated to 100 chars) */
|
|
19
|
+
preview: z.ZodOptional<z.ZodString>;
|
|
20
|
+
/** ISO 8601 timestamp of when preview was extracted (for cache invalidation) */
|
|
21
|
+
previewMtime: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, "strip", z.ZodTypeAny, {
|
|
23
|
+
customName?: string | undefined;
|
|
24
|
+
autoName?: string | undefined;
|
|
25
|
+
autoNameMtime?: string | undefined;
|
|
26
|
+
preview?: string | undefined;
|
|
27
|
+
previewMtime?: string | undefined;
|
|
28
|
+
}, {
|
|
29
|
+
customName?: string | undefined;
|
|
30
|
+
autoName?: string | undefined;
|
|
31
|
+
autoNameMtime?: string | undefined;
|
|
32
|
+
preview?: string | undefined;
|
|
33
|
+
previewMtime?: string | undefined;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Schema for the entire metadata file for an agent
|
|
37
|
+
*/
|
|
38
|
+
export declare const SessionMetadataFileSchema: z.ZodObject<{
|
|
39
|
+
version: z.ZodLiteral<1>;
|
|
40
|
+
agentName: z.ZodString;
|
|
41
|
+
sessions: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
42
|
+
customName: z.ZodOptional<z.ZodString>;
|
|
43
|
+
/** Auto-generated session name (extracted from JSONL summary) */
|
|
44
|
+
autoName: z.ZodOptional<z.ZodString>;
|
|
45
|
+
/** ISO 8601 timestamp of when autoName was extracted (for cache invalidation) */
|
|
46
|
+
autoNameMtime: z.ZodOptional<z.ZodString>;
|
|
47
|
+
/** First user message preview (truncated to 100 chars) */
|
|
48
|
+
preview: z.ZodOptional<z.ZodString>;
|
|
49
|
+
/** ISO 8601 timestamp of when preview was extracted (for cache invalidation) */
|
|
50
|
+
previewMtime: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, "strip", z.ZodTypeAny, {
|
|
52
|
+
customName?: string | undefined;
|
|
53
|
+
autoName?: string | undefined;
|
|
54
|
+
autoNameMtime?: string | undefined;
|
|
55
|
+
preview?: string | undefined;
|
|
56
|
+
previewMtime?: string | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
customName?: string | undefined;
|
|
59
|
+
autoName?: string | undefined;
|
|
60
|
+
autoNameMtime?: string | undefined;
|
|
61
|
+
preview?: string | undefined;
|
|
62
|
+
previewMtime?: string | undefined;
|
|
63
|
+
}>>;
|
|
64
|
+
}, "strip", z.ZodTypeAny, {
|
|
65
|
+
version: 1;
|
|
66
|
+
sessions: Record<string, {
|
|
67
|
+
customName?: string | undefined;
|
|
68
|
+
autoName?: string | undefined;
|
|
69
|
+
autoNameMtime?: string | undefined;
|
|
70
|
+
preview?: string | undefined;
|
|
71
|
+
previewMtime?: string | undefined;
|
|
72
|
+
}>;
|
|
73
|
+
agentName: string;
|
|
74
|
+
}, {
|
|
75
|
+
version: 1;
|
|
76
|
+
sessions: Record<string, {
|
|
77
|
+
customName?: string | undefined;
|
|
78
|
+
autoName?: string | undefined;
|
|
79
|
+
autoNameMtime?: string | undefined;
|
|
80
|
+
preview?: string | undefined;
|
|
81
|
+
previewMtime?: string | undefined;
|
|
82
|
+
}>;
|
|
83
|
+
agentName: string;
|
|
84
|
+
}>;
|
|
85
|
+
export type SessionMetadataEntry = z.infer<typeof SessionMetadataEntrySchema>;
|
|
86
|
+
export type SessionMetadataFile = z.infer<typeof SessionMetadataFileSchema>;
|
|
87
|
+
/**
|
|
88
|
+
* Store for managing user-customizable session metadata.
|
|
89
|
+
*
|
|
90
|
+
* Provides operations for getting/setting custom names for sessions.
|
|
91
|
+
* Data is sparse - files are only created when metadata is first set.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* const store = new SessionMetadataStore('/path/to/.herdctl');
|
|
96
|
+
*
|
|
97
|
+
* // Set a custom name for a session
|
|
98
|
+
* await store.setCustomName('my-agent', 'session-123', 'Feature Work');
|
|
99
|
+
*
|
|
100
|
+
* // Get the custom name
|
|
101
|
+
* const name = await store.getCustomName('my-agent', 'session-123');
|
|
102
|
+
* // Returns: 'Feature Work'
|
|
103
|
+
*
|
|
104
|
+
* // Remove custom name
|
|
105
|
+
* await store.removeCustomName('my-agent', 'session-123');
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare class SessionMetadataStore {
|
|
109
|
+
private readonly metadataDir;
|
|
110
|
+
private readonly cache;
|
|
111
|
+
/**
|
|
112
|
+
* Create a new SessionMetadataStore
|
|
113
|
+
*
|
|
114
|
+
* @param stateDir - Path to the .herdctl state directory
|
|
115
|
+
*/
|
|
116
|
+
constructor(stateDir: string);
|
|
117
|
+
/**
|
|
118
|
+
* Get the file path for an agent's metadata
|
|
119
|
+
*/
|
|
120
|
+
private getFilePath;
|
|
121
|
+
/**
|
|
122
|
+
* Load metadata for an agent from disk (or cache)
|
|
123
|
+
*/
|
|
124
|
+
private loadMetadata;
|
|
125
|
+
/**
|
|
126
|
+
* Save metadata for an agent to disk
|
|
127
|
+
*/
|
|
128
|
+
private saveMetadata;
|
|
129
|
+
/**
|
|
130
|
+
* Create a new empty metadata file structure
|
|
131
|
+
*/
|
|
132
|
+
private createEmptyMetadata;
|
|
133
|
+
/**
|
|
134
|
+
* Get custom name for a session
|
|
135
|
+
*
|
|
136
|
+
* @param agentName - The agent's qualified name
|
|
137
|
+
* @param sessionId - The session ID
|
|
138
|
+
* @returns The custom name if set, undefined otherwise
|
|
139
|
+
*/
|
|
140
|
+
getCustomName(agentName: string, sessionId: string): Promise<string | undefined>;
|
|
141
|
+
/**
|
|
142
|
+
* Set custom name for a session
|
|
143
|
+
*
|
|
144
|
+
* Creates the metadata file if it doesn't exist.
|
|
145
|
+
*
|
|
146
|
+
* @param agentName - The agent's qualified name
|
|
147
|
+
* @param sessionId - The session ID
|
|
148
|
+
* @param name - The custom name to set
|
|
149
|
+
*/
|
|
150
|
+
setCustomName(agentName: string, sessionId: string, name: string): Promise<void>;
|
|
151
|
+
/**
|
|
152
|
+
* Remove custom name for a session
|
|
153
|
+
*
|
|
154
|
+
* If this was the only metadata for the session, the session entry is removed.
|
|
155
|
+
* If this was the only session with metadata, the file is kept but empty
|
|
156
|
+
* (to avoid repeatedly creating/deleting files).
|
|
157
|
+
*
|
|
158
|
+
* @param agentName - The agent's qualified name
|
|
159
|
+
* @param sessionId - The session ID
|
|
160
|
+
*/
|
|
161
|
+
removeCustomName(agentName: string, sessionId: string): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* Get all metadata for an agent's sessions
|
|
164
|
+
*
|
|
165
|
+
* Useful for batch operations or displaying metadata for all sessions.
|
|
166
|
+
*
|
|
167
|
+
* @param agentName - The agent's qualified name
|
|
168
|
+
* @returns The full metadata file, or null if no metadata exists
|
|
169
|
+
*/
|
|
170
|
+
getAgentMetadata(agentName: string): Promise<SessionMetadataFile | null>;
|
|
171
|
+
/**
|
|
172
|
+
* Get auto-generated name and its mtime for a session
|
|
173
|
+
*
|
|
174
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
175
|
+
* @param sessionId - The session ID
|
|
176
|
+
* @returns Object with autoName and autoNameMtime, or undefined if not cached
|
|
177
|
+
*/
|
|
178
|
+
getAutoName(agentName: string, sessionId: string): Promise<{
|
|
179
|
+
autoName?: string;
|
|
180
|
+
autoNameMtime?: string;
|
|
181
|
+
} | undefined>;
|
|
182
|
+
/**
|
|
183
|
+
* Set auto-generated name for a session
|
|
184
|
+
*
|
|
185
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
186
|
+
* @param sessionId - The session ID
|
|
187
|
+
* @param autoName - The auto-generated name to set
|
|
188
|
+
* @param mtime - ISO 8601 timestamp of the session file when the name was extracted
|
|
189
|
+
*/
|
|
190
|
+
setAutoName(agentName: string, sessionId: string, autoName: string, mtime: string): Promise<void>;
|
|
191
|
+
/**
|
|
192
|
+
* Batch set auto-generated names for multiple sessions
|
|
193
|
+
*
|
|
194
|
+
* More efficient than calling setAutoName repeatedly since it performs
|
|
195
|
+
* a single file write for all updates.
|
|
196
|
+
*
|
|
197
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
198
|
+
* @param entries - Array of { sessionId, autoName, mtime } objects
|
|
199
|
+
*/
|
|
200
|
+
batchSetAutoNames(agentName: string, entries: Array<{
|
|
201
|
+
sessionId: string;
|
|
202
|
+
autoName: string;
|
|
203
|
+
mtime: string;
|
|
204
|
+
}>): Promise<void>;
|
|
205
|
+
/**
|
|
206
|
+
* Get cached preview and its mtime for a session
|
|
207
|
+
*
|
|
208
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
209
|
+
* @param sessionId - The session ID
|
|
210
|
+
* @returns Object with preview and previewMtime, or undefined if not cached
|
|
211
|
+
*/
|
|
212
|
+
getPreview(agentName: string, sessionId: string): Promise<{
|
|
213
|
+
preview?: string;
|
|
214
|
+
previewMtime?: string;
|
|
215
|
+
} | undefined>;
|
|
216
|
+
/**
|
|
217
|
+
* Set preview for a session
|
|
218
|
+
*
|
|
219
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
220
|
+
* @param sessionId - The session ID
|
|
221
|
+
* @param preview - The first user message preview text
|
|
222
|
+
* @param mtime - ISO 8601 timestamp of the session file when the preview was extracted
|
|
223
|
+
*/
|
|
224
|
+
setPreview(agentName: string, sessionId: string, preview: string, mtime: string): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Batch set previews for multiple sessions
|
|
227
|
+
*
|
|
228
|
+
* More efficient than calling setPreview repeatedly since it performs
|
|
229
|
+
* a single file write for all updates.
|
|
230
|
+
*
|
|
231
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
232
|
+
* @param entries - Array of { sessionId, preview, mtime } objects
|
|
233
|
+
*/
|
|
234
|
+
batchSetPreviews(agentName: string, entries: Array<{
|
|
235
|
+
sessionId: string;
|
|
236
|
+
preview: string;
|
|
237
|
+
mtime: string;
|
|
238
|
+
}>): Promise<void>;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=session-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-metadata.d.ts","sourceRoot":"","sources":["../../src/state/session-metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Metadata Store
|
|
3
|
+
*
|
|
4
|
+
* Manages user-customizable metadata for Claude Code sessions.
|
|
5
|
+
* Metadata is stored sparsely in .herdctl/session-metadata/{agent-qualified-name}.json
|
|
6
|
+
* Files are only created when the first custom name is set for an agent.
|
|
7
|
+
*/
|
|
8
|
+
import { mkdir } from "node:fs/promises";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { createLogger } from "../utils/logger.js";
|
|
12
|
+
import { atomicWriteJson } from "./utils/atomic.js";
|
|
13
|
+
import { safeReadJson } from "./utils/reads.js";
|
|
14
|
+
const logger = createLogger("SessionMetadataStore");
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Schemas
|
|
17
|
+
// =============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Schema for a single session's metadata entry
|
|
20
|
+
*/
|
|
21
|
+
export const SessionMetadataEntrySchema = z.object({
|
|
22
|
+
customName: z.string().optional(),
|
|
23
|
+
/** Auto-generated session name (extracted from JSONL summary) */
|
|
24
|
+
autoName: z.string().optional(),
|
|
25
|
+
/** ISO 8601 timestamp of when autoName was extracted (for cache invalidation) */
|
|
26
|
+
autoNameMtime: z.string().optional(),
|
|
27
|
+
/** First user message preview (truncated to 100 chars) */
|
|
28
|
+
preview: z.string().optional(),
|
|
29
|
+
/** ISO 8601 timestamp of when preview was extracted (for cache invalidation) */
|
|
30
|
+
previewMtime: z.string().optional(),
|
|
31
|
+
// Future: pinned, archived, tags
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* Schema for the entire metadata file for an agent
|
|
35
|
+
*/
|
|
36
|
+
export const SessionMetadataFileSchema = z.object({
|
|
37
|
+
version: z.literal(1),
|
|
38
|
+
agentName: z.string(),
|
|
39
|
+
sessions: z.record(z.string(), SessionMetadataEntrySchema),
|
|
40
|
+
});
|
|
41
|
+
// =============================================================================
|
|
42
|
+
// SessionMetadataStore
|
|
43
|
+
// =============================================================================
|
|
44
|
+
/**
|
|
45
|
+
* Store for managing user-customizable session metadata.
|
|
46
|
+
*
|
|
47
|
+
* Provides operations for getting/setting custom names for sessions.
|
|
48
|
+
* Data is sparse - files are only created when metadata is first set.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const store = new SessionMetadataStore('/path/to/.herdctl');
|
|
53
|
+
*
|
|
54
|
+
* // Set a custom name for a session
|
|
55
|
+
* await store.setCustomName('my-agent', 'session-123', 'Feature Work');
|
|
56
|
+
*
|
|
57
|
+
* // Get the custom name
|
|
58
|
+
* const name = await store.getCustomName('my-agent', 'session-123');
|
|
59
|
+
* // Returns: 'Feature Work'
|
|
60
|
+
*
|
|
61
|
+
* // Remove custom name
|
|
62
|
+
* await store.removeCustomName('my-agent', 'session-123');
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export class SessionMetadataStore {
|
|
66
|
+
metadataDir;
|
|
67
|
+
cache;
|
|
68
|
+
/**
|
|
69
|
+
* Create a new SessionMetadataStore
|
|
70
|
+
*
|
|
71
|
+
* @param stateDir - Path to the .herdctl state directory
|
|
72
|
+
*/
|
|
73
|
+
constructor(stateDir) {
|
|
74
|
+
this.metadataDir = join(stateDir, "session-metadata");
|
|
75
|
+
this.cache = new Map();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get the file path for an agent's metadata
|
|
79
|
+
*/
|
|
80
|
+
getFilePath(agentName) {
|
|
81
|
+
return join(this.metadataDir, `${agentName}.json`);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Load metadata for an agent from disk (or cache)
|
|
85
|
+
*/
|
|
86
|
+
async loadMetadata(agentName) {
|
|
87
|
+
// Check cache first
|
|
88
|
+
const cached = this.cache.get(agentName);
|
|
89
|
+
if (cached !== undefined) {
|
|
90
|
+
return cached;
|
|
91
|
+
}
|
|
92
|
+
const filePath = this.getFilePath(agentName);
|
|
93
|
+
const result = await safeReadJson(filePath);
|
|
94
|
+
if (!result.success) {
|
|
95
|
+
// File not found is expected for sparse storage
|
|
96
|
+
if (result.error.code === "ENOENT") {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
logger.warn(`Failed to read metadata file for ${agentName}: ${result.error.message}`);
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
// Validate the file structure
|
|
103
|
+
const parseResult = SessionMetadataFileSchema.safeParse(result.data);
|
|
104
|
+
if (!parseResult.success) {
|
|
105
|
+
logger.warn(`Corrupted metadata file for ${agentName}: ${parseResult.error.message}. Returning null.`);
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
// Cache and return
|
|
109
|
+
this.cache.set(agentName, parseResult.data);
|
|
110
|
+
return parseResult.data;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Save metadata for an agent to disk
|
|
114
|
+
*/
|
|
115
|
+
async saveMetadata(agentName, metadata) {
|
|
116
|
+
// Ensure directory exists
|
|
117
|
+
await mkdir(this.metadataDir, { recursive: true });
|
|
118
|
+
const filePath = this.getFilePath(agentName);
|
|
119
|
+
await atomicWriteJson(filePath, metadata);
|
|
120
|
+
// Update cache
|
|
121
|
+
this.cache.set(agentName, metadata);
|
|
122
|
+
logger.debug(`Saved metadata for agent ${agentName}`, {
|
|
123
|
+
sessionCount: Object.keys(metadata.sessions).length,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Create a new empty metadata file structure
|
|
128
|
+
*/
|
|
129
|
+
createEmptyMetadata(agentName) {
|
|
130
|
+
return {
|
|
131
|
+
version: 1,
|
|
132
|
+
agentName,
|
|
133
|
+
sessions: {},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get custom name for a session
|
|
138
|
+
*
|
|
139
|
+
* @param agentName - The agent's qualified name
|
|
140
|
+
* @param sessionId - The session ID
|
|
141
|
+
* @returns The custom name if set, undefined otherwise
|
|
142
|
+
*/
|
|
143
|
+
async getCustomName(agentName, sessionId) {
|
|
144
|
+
const metadata = await this.loadMetadata(agentName);
|
|
145
|
+
if (!metadata) {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
return metadata.sessions[sessionId]?.customName;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Set custom name for a session
|
|
152
|
+
*
|
|
153
|
+
* Creates the metadata file if it doesn't exist.
|
|
154
|
+
*
|
|
155
|
+
* @param agentName - The agent's qualified name
|
|
156
|
+
* @param sessionId - The session ID
|
|
157
|
+
* @param name - The custom name to set
|
|
158
|
+
*/
|
|
159
|
+
async setCustomName(agentName, sessionId, name) {
|
|
160
|
+
let metadata = await this.loadMetadata(agentName);
|
|
161
|
+
if (!metadata) {
|
|
162
|
+
metadata = this.createEmptyMetadata(agentName);
|
|
163
|
+
}
|
|
164
|
+
// Get or create the session entry
|
|
165
|
+
const sessionEntry = metadata.sessions[sessionId] ?? {};
|
|
166
|
+
// Update the custom name
|
|
167
|
+
metadata.sessions[sessionId] = {
|
|
168
|
+
...sessionEntry,
|
|
169
|
+
customName: name,
|
|
170
|
+
};
|
|
171
|
+
await this.saveMetadata(agentName, metadata);
|
|
172
|
+
logger.debug(`Set custom name for session ${sessionId}`, {
|
|
173
|
+
agentName,
|
|
174
|
+
customName: name,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Remove custom name for a session
|
|
179
|
+
*
|
|
180
|
+
* If this was the only metadata for the session, the session entry is removed.
|
|
181
|
+
* If this was the only session with metadata, the file is kept but empty
|
|
182
|
+
* (to avoid repeatedly creating/deleting files).
|
|
183
|
+
*
|
|
184
|
+
* @param agentName - The agent's qualified name
|
|
185
|
+
* @param sessionId - The session ID
|
|
186
|
+
*/
|
|
187
|
+
async removeCustomName(agentName, sessionId) {
|
|
188
|
+
const metadata = await this.loadMetadata(agentName);
|
|
189
|
+
if (!metadata) {
|
|
190
|
+
// No metadata file exists, nothing to remove
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const sessionEntry = metadata.sessions[sessionId];
|
|
194
|
+
if (!sessionEntry) {
|
|
195
|
+
// No entry for this session, nothing to remove
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// Remove the customName
|
|
199
|
+
delete sessionEntry.customName;
|
|
200
|
+
// If the session entry is now empty, remove it entirely
|
|
201
|
+
if (Object.keys(sessionEntry).length === 0) {
|
|
202
|
+
delete metadata.sessions[sessionId];
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
metadata.sessions[sessionId] = sessionEntry;
|
|
206
|
+
}
|
|
207
|
+
await this.saveMetadata(agentName, metadata);
|
|
208
|
+
logger.debug(`Removed custom name for session ${sessionId}`, { agentName });
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get all metadata for an agent's sessions
|
|
212
|
+
*
|
|
213
|
+
* Useful for batch operations or displaying metadata for all sessions.
|
|
214
|
+
*
|
|
215
|
+
* @param agentName - The agent's qualified name
|
|
216
|
+
* @returns The full metadata file, or null if no metadata exists
|
|
217
|
+
*/
|
|
218
|
+
async getAgentMetadata(agentName) {
|
|
219
|
+
return this.loadMetadata(agentName);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Get auto-generated name and its mtime for a session
|
|
223
|
+
*
|
|
224
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
225
|
+
* @param sessionId - The session ID
|
|
226
|
+
* @returns Object with autoName and autoNameMtime, or undefined if not cached
|
|
227
|
+
*/
|
|
228
|
+
async getAutoName(agentName, sessionId) {
|
|
229
|
+
const metadata = await this.loadMetadata(agentName);
|
|
230
|
+
if (!metadata) {
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
const entry = metadata.sessions[sessionId];
|
|
234
|
+
if (!entry) {
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
autoName: entry.autoName,
|
|
239
|
+
autoNameMtime: entry.autoNameMtime,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Set auto-generated name for a session
|
|
244
|
+
*
|
|
245
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
246
|
+
* @param sessionId - The session ID
|
|
247
|
+
* @param autoName - The auto-generated name to set
|
|
248
|
+
* @param mtime - ISO 8601 timestamp of the session file when the name was extracted
|
|
249
|
+
*/
|
|
250
|
+
async setAutoName(agentName, sessionId, autoName, mtime) {
|
|
251
|
+
let metadata = await this.loadMetadata(agentName);
|
|
252
|
+
if (!metadata) {
|
|
253
|
+
metadata = this.createEmptyMetadata(agentName);
|
|
254
|
+
}
|
|
255
|
+
// Get or create the session entry
|
|
256
|
+
const sessionEntry = metadata.sessions[sessionId] ?? {};
|
|
257
|
+
// Update the auto name fields
|
|
258
|
+
metadata.sessions[sessionId] = {
|
|
259
|
+
...sessionEntry,
|
|
260
|
+
autoName,
|
|
261
|
+
autoNameMtime: mtime,
|
|
262
|
+
};
|
|
263
|
+
await this.saveMetadata(agentName, metadata);
|
|
264
|
+
logger.debug(`Set auto name for session ${sessionId}`, {
|
|
265
|
+
agentName,
|
|
266
|
+
autoName,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Batch set auto-generated names for multiple sessions
|
|
271
|
+
*
|
|
272
|
+
* More efficient than calling setAutoName repeatedly since it performs
|
|
273
|
+
* a single file write for all updates.
|
|
274
|
+
*
|
|
275
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
276
|
+
* @param entries - Array of { sessionId, autoName, mtime } objects
|
|
277
|
+
*/
|
|
278
|
+
async batchSetAutoNames(agentName, entries) {
|
|
279
|
+
if (entries.length === 0) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
let metadata = await this.loadMetadata(agentName);
|
|
283
|
+
if (!metadata) {
|
|
284
|
+
metadata = this.createEmptyMetadata(agentName);
|
|
285
|
+
}
|
|
286
|
+
// Apply all updates
|
|
287
|
+
for (const { sessionId, autoName, mtime } of entries) {
|
|
288
|
+
const sessionEntry = metadata.sessions[sessionId] ?? {};
|
|
289
|
+
metadata.sessions[sessionId] = {
|
|
290
|
+
...sessionEntry,
|
|
291
|
+
autoName,
|
|
292
|
+
autoNameMtime: mtime,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
await this.saveMetadata(agentName, metadata);
|
|
296
|
+
logger.debug(`Batch set auto names for ${entries.length} sessions`, {
|
|
297
|
+
agentName,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Get cached preview and its mtime for a session
|
|
302
|
+
*
|
|
303
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
304
|
+
* @param sessionId - The session ID
|
|
305
|
+
* @returns Object with preview and previewMtime, or undefined if not cached
|
|
306
|
+
*/
|
|
307
|
+
async getPreview(agentName, sessionId) {
|
|
308
|
+
const metadata = await this.loadMetadata(agentName);
|
|
309
|
+
if (!metadata) {
|
|
310
|
+
return undefined;
|
|
311
|
+
}
|
|
312
|
+
const entry = metadata.sessions[sessionId];
|
|
313
|
+
if (!entry) {
|
|
314
|
+
return undefined;
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
preview: entry.preview,
|
|
318
|
+
previewMtime: entry.previewMtime,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Set preview for a session
|
|
323
|
+
*
|
|
324
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
325
|
+
* @param sessionId - The session ID
|
|
326
|
+
* @param preview - The first user message preview text
|
|
327
|
+
* @param mtime - ISO 8601 timestamp of the session file when the preview was extracted
|
|
328
|
+
*/
|
|
329
|
+
async setPreview(agentName, sessionId, preview, mtime) {
|
|
330
|
+
let metadata = await this.loadMetadata(agentName);
|
|
331
|
+
if (!metadata) {
|
|
332
|
+
metadata = this.createEmptyMetadata(agentName);
|
|
333
|
+
}
|
|
334
|
+
const sessionEntry = metadata.sessions[sessionId] ?? {};
|
|
335
|
+
metadata.sessions[sessionId] = {
|
|
336
|
+
...sessionEntry,
|
|
337
|
+
preview,
|
|
338
|
+
previewMtime: mtime,
|
|
339
|
+
};
|
|
340
|
+
await this.saveMetadata(agentName, metadata);
|
|
341
|
+
logger.debug(`Set preview for session ${sessionId}`, {
|
|
342
|
+
agentName,
|
|
343
|
+
preview,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Batch set previews for multiple sessions
|
|
348
|
+
*
|
|
349
|
+
* More efficient than calling setPreview repeatedly since it performs
|
|
350
|
+
* a single file write for all updates.
|
|
351
|
+
*
|
|
352
|
+
* @param agentName - The agent's qualified name (use "adhoc" for unattributed sessions)
|
|
353
|
+
* @param entries - Array of { sessionId, preview, mtime } objects
|
|
354
|
+
*/
|
|
355
|
+
async batchSetPreviews(agentName, entries) {
|
|
356
|
+
if (entries.length === 0) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
let metadata = await this.loadMetadata(agentName);
|
|
360
|
+
if (!metadata) {
|
|
361
|
+
metadata = this.createEmptyMetadata(agentName);
|
|
362
|
+
}
|
|
363
|
+
for (const { sessionId, preview, mtime } of entries) {
|
|
364
|
+
const sessionEntry = metadata.sessions[sessionId] ?? {};
|
|
365
|
+
metadata.sessions[sessionId] = {
|
|
366
|
+
...sessionEntry,
|
|
367
|
+
preview,
|
|
368
|
+
previewMtime: mtime,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
await this.saveMetadata(agentName, metadata);
|
|
372
|
+
logger.debug(`Batch set previews for ${entries.length} sessions`, {
|
|
373
|
+
agentName,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=session-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-metadata.js","sourceRoot":"","sources":["../../src/state/session-metadata.ts"],"names":[],"mappings":"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"}
|