thread-mcp 1.0.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.
Files changed (63) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +497 -0
  3. package/dist/formatters/index.d.ts +5 -0
  4. package/dist/formatters/index.d.ts.map +1 -0
  5. package/dist/formatters/index.js +12 -0
  6. package/dist/formatters/index.js.map +1 -0
  7. package/dist/formatters/json.d.ts +3 -0
  8. package/dist/formatters/json.d.ts.map +1 -0
  9. package/dist/formatters/json.js +25 -0
  10. package/dist/formatters/json.js.map +1 -0
  11. package/dist/formatters/markdown.d.ts +3 -0
  12. package/dist/formatters/markdown.d.ts.map +1 -0
  13. package/dist/formatters/markdown.js +134 -0
  14. package/dist/formatters/markdown.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/server.d.ts +4 -0
  20. package/dist/server.d.ts.map +1 -0
  21. package/dist/server.js +175 -0
  22. package/dist/server.js.map +1 -0
  23. package/dist/storage/index.d.ts +3 -0
  24. package/dist/storage/index.d.ts.map +1 -0
  25. package/dist/storage/index.js +3 -0
  26. package/dist/storage/index.js.map +1 -0
  27. package/dist/storage/local.d.ts +23 -0
  28. package/dist/storage/local.d.ts.map +1 -0
  29. package/dist/storage/local.js +126 -0
  30. package/dist/storage/local.js.map +1 -0
  31. package/dist/storage/remote.d.ts +15 -0
  32. package/dist/storage/remote.d.ts.map +1 -0
  33. package/dist/storage/remote.js +91 -0
  34. package/dist/storage/remote.js.map +1 -0
  35. package/dist/tools/delete-thread.d.ts +71 -0
  36. package/dist/tools/delete-thread.d.ts.map +1 -0
  37. package/dist/tools/delete-thread.js +74 -0
  38. package/dist/tools/delete-thread.js.map +1 -0
  39. package/dist/tools/find-threads.d.ts +175 -0
  40. package/dist/tools/find-threads.d.ts.map +1 -0
  41. package/dist/tools/find-threads.js +265 -0
  42. package/dist/tools/find-threads.js.map +1 -0
  43. package/dist/tools/index.d.ts +270 -0
  44. package/dist/tools/index.d.ts.map +1 -0
  45. package/dist/tools/index.js +18 -0
  46. package/dist/tools/index.js.map +1 -0
  47. package/dist/tools/resume-thread.d.ts +138 -0
  48. package/dist/tools/resume-thread.d.ts.map +1 -0
  49. package/dist/tools/resume-thread.js +191 -0
  50. package/dist/tools/resume-thread.js.map +1 -0
  51. package/dist/tools/save-thread.d.ts +155 -0
  52. package/dist/tools/save-thread.d.ts.map +1 -0
  53. package/dist/tools/save-thread.js +116 -0
  54. package/dist/tools/save-thread.js.map +1 -0
  55. package/dist/tools/update-thread.d.ts +180 -0
  56. package/dist/tools/update-thread.d.ts.map +1 -0
  57. package/dist/tools/update-thread.js +159 -0
  58. package/dist/tools/update-thread.js.map +1 -0
  59. package/dist/types.d.ts +177 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +41 -0
  62. package/dist/types.js.map +1 -0
  63. package/package.json +67 -0
@@ -0,0 +1,155 @@
1
+ import { z } from "zod";
2
+ export declare const SaveThreadInputSchema: z.ZodObject<{
3
+ title: z.ZodString;
4
+ messages: z.ZodArray<z.ZodObject<{
5
+ role: z.ZodEnum<["user", "assistant", "system"]>;
6
+ content: z.ZodString;
7
+ timestamp: z.ZodOptional<z.ZodString>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ role: "user" | "assistant" | "system";
10
+ content: string;
11
+ timestamp?: string | undefined;
12
+ }, {
13
+ role: "user" | "assistant" | "system";
14
+ content: string;
15
+ timestamp?: string | undefined;
16
+ }>, "many">;
17
+ destination: z.ZodDefault<z.ZodEnum<["local", "remote"]>>;
18
+ format: z.ZodDefault<z.ZodEnum<["markdown", "json"]>>;
19
+ sourceApp: z.ZodOptional<z.ZodString>;
20
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21
+ summary: z.ZodOptional<z.ZodString>;
22
+ outputDir: z.ZodOptional<z.ZodString>;
23
+ remoteUrl: z.ZodOptional<z.ZodString>;
24
+ apiKey: z.ZodOptional<z.ZodString>;
25
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
26
+ includeMetadata: z.ZodDefault<z.ZodBoolean>;
27
+ includeTimestamps: z.ZodDefault<z.ZodBoolean>;
28
+ }, "strip", z.ZodTypeAny, {
29
+ title: string;
30
+ messages: {
31
+ role: "user" | "assistant" | "system";
32
+ content: string;
33
+ timestamp?: string | undefined;
34
+ }[];
35
+ format: "markdown" | "json";
36
+ includeMetadata: boolean;
37
+ includeTimestamps: boolean;
38
+ destination: "local" | "remote";
39
+ sourceApp?: string | undefined;
40
+ tags?: string[] | undefined;
41
+ summary?: string | undefined;
42
+ apiKey?: string | undefined;
43
+ headers?: Record<string, string> | undefined;
44
+ remoteUrl?: string | undefined;
45
+ outputDir?: string | undefined;
46
+ }, {
47
+ title: string;
48
+ messages: {
49
+ role: "user" | "assistant" | "system";
50
+ content: string;
51
+ timestamp?: string | undefined;
52
+ }[];
53
+ sourceApp?: string | undefined;
54
+ tags?: string[] | undefined;
55
+ summary?: string | undefined;
56
+ format?: "markdown" | "json" | undefined;
57
+ includeMetadata?: boolean | undefined;
58
+ includeTimestamps?: boolean | undefined;
59
+ apiKey?: string | undefined;
60
+ headers?: Record<string, string> | undefined;
61
+ remoteUrl?: string | undefined;
62
+ destination?: "local" | "remote" | undefined;
63
+ outputDir?: string | undefined;
64
+ }>;
65
+ export type SaveThreadInput = z.infer<typeof SaveThreadInputSchema>;
66
+ export declare function saveThread(input: SaveThreadInput): Promise<{
67
+ success: boolean;
68
+ id: string;
69
+ title: string;
70
+ destination: string;
71
+ remoteUrl: string | undefined;
72
+ format: "markdown" | "json";
73
+ savedAt: string;
74
+ messageCount: number;
75
+ filePath?: undefined;
76
+ } | {
77
+ success: boolean;
78
+ id: string;
79
+ title: string;
80
+ destination: string;
81
+ filePath: string | undefined;
82
+ format: "markdown" | "json";
83
+ savedAt: string;
84
+ messageCount: number;
85
+ remoteUrl?: undefined;
86
+ }>;
87
+ export declare const saveThreadTool: {
88
+ name: string;
89
+ description: string;
90
+ inputSchema: z.ZodObject<{
91
+ title: z.ZodString;
92
+ messages: z.ZodArray<z.ZodObject<{
93
+ role: z.ZodEnum<["user", "assistant", "system"]>;
94
+ content: z.ZodString;
95
+ timestamp: z.ZodOptional<z.ZodString>;
96
+ }, "strip", z.ZodTypeAny, {
97
+ role: "user" | "assistant" | "system";
98
+ content: string;
99
+ timestamp?: string | undefined;
100
+ }, {
101
+ role: "user" | "assistant" | "system";
102
+ content: string;
103
+ timestamp?: string | undefined;
104
+ }>, "many">;
105
+ destination: z.ZodDefault<z.ZodEnum<["local", "remote"]>>;
106
+ format: z.ZodDefault<z.ZodEnum<["markdown", "json"]>>;
107
+ sourceApp: z.ZodOptional<z.ZodString>;
108
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
109
+ summary: z.ZodOptional<z.ZodString>;
110
+ outputDir: z.ZodOptional<z.ZodString>;
111
+ remoteUrl: z.ZodOptional<z.ZodString>;
112
+ apiKey: z.ZodOptional<z.ZodString>;
113
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
114
+ includeMetadata: z.ZodDefault<z.ZodBoolean>;
115
+ includeTimestamps: z.ZodDefault<z.ZodBoolean>;
116
+ }, "strip", z.ZodTypeAny, {
117
+ title: string;
118
+ messages: {
119
+ role: "user" | "assistant" | "system";
120
+ content: string;
121
+ timestamp?: string | undefined;
122
+ }[];
123
+ format: "markdown" | "json";
124
+ includeMetadata: boolean;
125
+ includeTimestamps: boolean;
126
+ destination: "local" | "remote";
127
+ sourceApp?: string | undefined;
128
+ tags?: string[] | undefined;
129
+ summary?: string | undefined;
130
+ apiKey?: string | undefined;
131
+ headers?: Record<string, string> | undefined;
132
+ remoteUrl?: string | undefined;
133
+ outputDir?: string | undefined;
134
+ }, {
135
+ title: string;
136
+ messages: {
137
+ role: "user" | "assistant" | "system";
138
+ content: string;
139
+ timestamp?: string | undefined;
140
+ }[];
141
+ sourceApp?: string | undefined;
142
+ tags?: string[] | undefined;
143
+ summary?: string | undefined;
144
+ format?: "markdown" | "json" | undefined;
145
+ includeMetadata?: boolean | undefined;
146
+ includeTimestamps?: boolean | undefined;
147
+ apiKey?: string | undefined;
148
+ headers?: Record<string, string> | undefined;
149
+ remoteUrl?: string | undefined;
150
+ destination?: "local" | "remote" | undefined;
151
+ outputDir?: string | undefined;
152
+ }>;
153
+ handler: typeof saveThread;
154
+ };
155
+ //# sourceMappingURL=save-thread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-thread.d.ts","sourceRoot":"","sources":["../../src/tools/save-thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoDhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,wBAAsB,UAAU,CAAC,KAAK,EAAE,eAAe;;;;;;;;;;;;;;;;;;;;GAiEtD;AAED,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAO1B,CAAC"}
@@ -0,0 +1,116 @@
1
+ import { z } from "zod";
2
+ import { OutputFormatSchema } from "../types.js";
3
+ import { getDefaultLocalStorage, createLocalStorage } from "../storage/local.js";
4
+ import { createRemoteStorage } from "../storage/remote.js";
5
+ export const SaveThreadInputSchema = z.object({
6
+ title: z.string().describe("Title for the thread"),
7
+ messages: z
8
+ .array(z.object({
9
+ role: z.enum(["user", "assistant", "system"]),
10
+ content: z.string(),
11
+ timestamp: z.string().optional(),
12
+ }))
13
+ .describe("Array of messages in the thread"),
14
+ destination: z
15
+ .enum(["local", "remote"])
16
+ .default("local")
17
+ .describe("Where to save: 'local' for filesystem, 'remote' for server"),
18
+ format: OutputFormatSchema.default("markdown").describe("Output format: 'markdown' or 'json'"),
19
+ sourceApp: z
20
+ .string()
21
+ .optional()
22
+ .describe("Name of the AI application (e.g., 'Claude', 'ChatGPT')"),
23
+ tags: z.array(z.string()).optional().describe("Tags for categorization"),
24
+ summary: z.string().optional().describe("Summary of the thread"),
25
+ // Local options
26
+ outputDir: z
27
+ .string()
28
+ .optional()
29
+ .describe("Custom output directory for local storage (defaults to ~/.thread-mcp)"),
30
+ // Remote options
31
+ remoteUrl: z
32
+ .string()
33
+ .url()
34
+ .optional()
35
+ .describe("Base URL of the remote server (required if destination is 'remote')"),
36
+ apiKey: z.string().optional().describe("API key for remote authentication"),
37
+ headers: z
38
+ .record(z.string())
39
+ .optional()
40
+ .describe("Additional headers for remote requests"),
41
+ // Output options
42
+ includeMetadata: z
43
+ .boolean()
44
+ .default(true)
45
+ .describe("Whether to include metadata in the output"),
46
+ includeTimestamps: z
47
+ .boolean()
48
+ .default(true)
49
+ .describe("Whether to include timestamps for each message"),
50
+ });
51
+ export async function saveThread(input) {
52
+ const conversation = {
53
+ id: crypto.randomUUID(),
54
+ metadata: {
55
+ title: input.title,
56
+ sourceApp: input.sourceApp,
57
+ createdAt: new Date().toISOString(),
58
+ tags: input.tags,
59
+ summary: input.summary,
60
+ },
61
+ messages: input.messages.map((msg) => ({
62
+ role: msg.role,
63
+ content: msg.content,
64
+ timestamp: msg.timestamp,
65
+ })),
66
+ };
67
+ const options = {
68
+ format: input.format,
69
+ includeMetadata: input.includeMetadata,
70
+ includeTimestamps: input.includeTimestamps,
71
+ };
72
+ if (input.destination === "remote") {
73
+ if (!input.remoteUrl) {
74
+ throw new Error("remoteUrl is required when destination is 'remote'");
75
+ }
76
+ const storage = createRemoteStorage({
77
+ url: input.remoteUrl,
78
+ apiKey: input.apiKey,
79
+ headers: input.headers,
80
+ });
81
+ const result = await storage.save(conversation, options);
82
+ return {
83
+ success: true,
84
+ id: result.id,
85
+ title: result.title,
86
+ destination: "remote",
87
+ remoteUrl: result.remoteUrl,
88
+ format: result.format,
89
+ savedAt: result.savedAt,
90
+ messageCount: conversation.messages.length,
91
+ };
92
+ }
93
+ // Local storage
94
+ const storage = input.outputDir
95
+ ? createLocalStorage(input.outputDir)
96
+ : getDefaultLocalStorage();
97
+ const result = await storage.save(conversation, options);
98
+ return {
99
+ success: true,
100
+ id: result.id,
101
+ title: result.title,
102
+ destination: "local",
103
+ filePath: result.filePath,
104
+ format: result.format,
105
+ savedAt: result.savedAt,
106
+ messageCount: conversation.messages.length,
107
+ };
108
+ }
109
+ export const saveThreadTool = {
110
+ name: "save_thread",
111
+ description: "Save a conversation thread to local storage or a remote server. " +
112
+ "Supports Markdown and JSON formats with rich metadata including tags, summary, and timestamps.",
113
+ inputSchema: SaveThreadInputSchema,
114
+ handler: saveThread,
115
+ };
116
+ //# sourceMappingURL=save-thread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-thread.js","sourceRoot":"","sources":["../../src/tools/save-thread.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ import { z } from "zod";
2
+ export declare const UpdateThreadInputSchema: z.ZodObject<{
3
+ id: z.ZodOptional<z.ZodString>;
4
+ title: z.ZodOptional<z.ZodString>;
5
+ messages: z.ZodArray<z.ZodObject<{
6
+ role: z.ZodEnum<["user", "assistant", "system"]>;
7
+ content: z.ZodString;
8
+ timestamp: z.ZodOptional<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ role: "user" | "assistant" | "system";
11
+ content: string;
12
+ timestamp?: string | undefined;
13
+ }, {
14
+ role: "user" | "assistant" | "system";
15
+ content: string;
16
+ timestamp?: string | undefined;
17
+ }>, "many">;
18
+ mode: z.ZodDefault<z.ZodEnum<["append", "replace"]>>;
19
+ deduplicate: z.ZodDefault<z.ZodBoolean>;
20
+ newTitle: z.ZodOptional<z.ZodString>;
21
+ newTags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
22
+ newSummary: z.ZodOptional<z.ZodString>;
23
+ source: z.ZodDefault<z.ZodEnum<["local", "remote"]>>;
24
+ outputDir: z.ZodOptional<z.ZodString>;
25
+ remoteUrl: z.ZodOptional<z.ZodString>;
26
+ apiKey: z.ZodOptional<z.ZodString>;
27
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
28
+ format: z.ZodOptional<z.ZodEnum<["markdown", "json"]>>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ messages: {
31
+ role: "user" | "assistant" | "system";
32
+ content: string;
33
+ timestamp?: string | undefined;
34
+ }[];
35
+ source: "local" | "remote";
36
+ mode: "replace" | "append";
37
+ deduplicate: boolean;
38
+ title?: string | undefined;
39
+ id?: string | undefined;
40
+ format?: "markdown" | "json" | undefined;
41
+ apiKey?: string | undefined;
42
+ headers?: Record<string, string> | undefined;
43
+ remoteUrl?: string | undefined;
44
+ outputDir?: string | undefined;
45
+ newTitle?: string | undefined;
46
+ newTags?: string[] | undefined;
47
+ newSummary?: string | undefined;
48
+ }, {
49
+ messages: {
50
+ role: "user" | "assistant" | "system";
51
+ content: string;
52
+ timestamp?: string | undefined;
53
+ }[];
54
+ title?: string | undefined;
55
+ id?: string | undefined;
56
+ format?: "markdown" | "json" | undefined;
57
+ apiKey?: string | undefined;
58
+ headers?: Record<string, string> | undefined;
59
+ remoteUrl?: string | undefined;
60
+ outputDir?: string | undefined;
61
+ source?: "local" | "remote" | undefined;
62
+ mode?: "replace" | "append" | undefined;
63
+ deduplicate?: boolean | undefined;
64
+ newTitle?: string | undefined;
65
+ newTags?: string[] | undefined;
66
+ newSummary?: string | undefined;
67
+ }>;
68
+ export type UpdateThreadInput = z.infer<typeof UpdateThreadInputSchema>;
69
+ export declare function updateThread(input: UpdateThreadInput): Promise<{
70
+ success: boolean;
71
+ error: string;
72
+ source: "local" | "remote";
73
+ id?: undefined;
74
+ title?: undefined;
75
+ filePath?: undefined;
76
+ remoteUrl?: undefined;
77
+ format?: undefined;
78
+ savedAt?: undefined;
79
+ messageCount?: undefined;
80
+ messagesAdded?: undefined;
81
+ mode?: undefined;
82
+ } | {
83
+ success: boolean;
84
+ error: string;
85
+ id: string | undefined;
86
+ source: "local" | "remote";
87
+ title?: undefined;
88
+ filePath?: undefined;
89
+ remoteUrl?: undefined;
90
+ format?: undefined;
91
+ savedAt?: undefined;
92
+ messageCount?: undefined;
93
+ messagesAdded?: undefined;
94
+ mode?: undefined;
95
+ } | {
96
+ success: boolean;
97
+ id: string;
98
+ title: string;
99
+ source: "local" | "remote";
100
+ filePath: string | undefined;
101
+ remoteUrl: string | undefined;
102
+ format: "markdown" | "json";
103
+ savedAt: string;
104
+ messageCount: number;
105
+ messagesAdded: number;
106
+ mode: "replace" | "append";
107
+ error?: undefined;
108
+ }>;
109
+ export declare const updateThreadTool: {
110
+ name: string;
111
+ description: string;
112
+ inputSchema: z.ZodObject<{
113
+ id: z.ZodOptional<z.ZodString>;
114
+ title: z.ZodOptional<z.ZodString>;
115
+ messages: z.ZodArray<z.ZodObject<{
116
+ role: z.ZodEnum<["user", "assistant", "system"]>;
117
+ content: z.ZodString;
118
+ timestamp: z.ZodOptional<z.ZodString>;
119
+ }, "strip", z.ZodTypeAny, {
120
+ role: "user" | "assistant" | "system";
121
+ content: string;
122
+ timestamp?: string | undefined;
123
+ }, {
124
+ role: "user" | "assistant" | "system";
125
+ content: string;
126
+ timestamp?: string | undefined;
127
+ }>, "many">;
128
+ mode: z.ZodDefault<z.ZodEnum<["append", "replace"]>>;
129
+ deduplicate: z.ZodDefault<z.ZodBoolean>;
130
+ newTitle: z.ZodOptional<z.ZodString>;
131
+ newTags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
132
+ newSummary: z.ZodOptional<z.ZodString>;
133
+ source: z.ZodDefault<z.ZodEnum<["local", "remote"]>>;
134
+ outputDir: z.ZodOptional<z.ZodString>;
135
+ remoteUrl: z.ZodOptional<z.ZodString>;
136
+ apiKey: z.ZodOptional<z.ZodString>;
137
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
138
+ format: z.ZodOptional<z.ZodEnum<["markdown", "json"]>>;
139
+ }, "strip", z.ZodTypeAny, {
140
+ messages: {
141
+ role: "user" | "assistant" | "system";
142
+ content: string;
143
+ timestamp?: string | undefined;
144
+ }[];
145
+ source: "local" | "remote";
146
+ mode: "replace" | "append";
147
+ deduplicate: boolean;
148
+ title?: string | undefined;
149
+ id?: string | undefined;
150
+ format?: "markdown" | "json" | undefined;
151
+ apiKey?: string | undefined;
152
+ headers?: Record<string, string> | undefined;
153
+ remoteUrl?: string | undefined;
154
+ outputDir?: string | undefined;
155
+ newTitle?: string | undefined;
156
+ newTags?: string[] | undefined;
157
+ newSummary?: string | undefined;
158
+ }, {
159
+ messages: {
160
+ role: "user" | "assistant" | "system";
161
+ content: string;
162
+ timestamp?: string | undefined;
163
+ }[];
164
+ title?: string | undefined;
165
+ id?: string | undefined;
166
+ format?: "markdown" | "json" | undefined;
167
+ apiKey?: string | undefined;
168
+ headers?: Record<string, string> | undefined;
169
+ remoteUrl?: string | undefined;
170
+ outputDir?: string | undefined;
171
+ source?: "local" | "remote" | undefined;
172
+ mode?: "replace" | "append" | undefined;
173
+ deduplicate?: boolean | undefined;
174
+ newTitle?: string | undefined;
175
+ newTags?: string[] | undefined;
176
+ newSummary?: string | undefined;
177
+ }>;
178
+ handler: typeof updateThread;
179
+ };
180
+ //# sourceMappingURL=update-thread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-thread.d.ts","sourceRoot":"","sources":["../../src/tools/update-thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0ClC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAmBxE,wBAAsB,YAAY,CAAC,KAAK,EAAE,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8G1D;AAED,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQ5B,CAAC"}
@@ -0,0 +1,159 @@
1
+ import { z } from "zod";
2
+ import { OutputFormatSchema } from "../types.js";
3
+ import { getDefaultLocalStorage, createLocalStorage } from "../storage/local.js";
4
+ import { createRemoteStorage } from "../storage/remote.js";
5
+ export const UpdateThreadInputSchema = z.object({
6
+ // Lookup (use one)
7
+ id: z.string().optional().describe("ID of the thread to update"),
8
+ title: z.string().optional().describe("Find thread by exact title match"),
9
+ // Messages to add/replace
10
+ messages: z
11
+ .array(z.object({
12
+ role: z.enum(["user", "assistant", "system"]),
13
+ content: z.string(),
14
+ timestamp: z.string().optional(),
15
+ }))
16
+ .describe("Messages to append or replace with"),
17
+ mode: z
18
+ .enum(["append", "replace"])
19
+ .default("append")
20
+ .describe("'append' adds to existing messages, 'replace' overwrites all"),
21
+ deduplicate: z
22
+ .boolean()
23
+ .default(true)
24
+ .describe("When appending, skip messages that already exist (by role+content)"),
25
+ // Metadata updates (optional)
26
+ newTitle: z.string().optional().describe("New title for the thread"),
27
+ newTags: z.array(z.string()).optional().describe("New tags (replaces existing)"),
28
+ newSummary: z.string().optional().describe("New summary"),
29
+ // Source
30
+ source: z
31
+ .enum(["local", "remote"])
32
+ .default("local")
33
+ .describe("Source where thread is stored"),
34
+ outputDir: z.string().optional().describe("Custom directory for local storage"),
35
+ remoteUrl: z.string().url().optional().describe("Remote server URL"),
36
+ apiKey: z.string().optional().describe("API key for remote"),
37
+ headers: z.record(z.string()).optional().describe("Additional headers for remote"),
38
+ format: OutputFormatSchema.optional().describe("Output format (keeps existing if not set)"),
39
+ });
40
+ function messagesEqual(a, b) {
41
+ return a.role === b.role && a.content === b.content;
42
+ }
43
+ function deduplicateMessages(existing, incoming) {
44
+ const newMessages = [];
45
+ for (const msg of incoming) {
46
+ const isDuplicate = existing.some((e) => messagesEqual(e, msg));
47
+ if (!isDuplicate) {
48
+ newMessages.push(msg);
49
+ }
50
+ }
51
+ return newMessages;
52
+ }
53
+ export async function updateThread(input) {
54
+ if (!input.id && !input.title) {
55
+ throw new Error("Either 'id' or 'title' must be provided to identify the thread");
56
+ }
57
+ if (input.source === "remote" && !input.remoteUrl) {
58
+ throw new Error("remoteUrl is required when source is 'remote'");
59
+ }
60
+ const storage = input.source === "remote"
61
+ ? createRemoteStorage({
62
+ url: input.remoteUrl,
63
+ apiKey: input.apiKey,
64
+ headers: input.headers,
65
+ })
66
+ : input.outputDir
67
+ ? createLocalStorage(input.outputDir)
68
+ : getDefaultLocalStorage();
69
+ // Find the thread
70
+ let threadId = input.id;
71
+ let existingInfo;
72
+ if (!threadId && input.title) {
73
+ const allInfos = await storage.list();
74
+ for (const info of allInfos) {
75
+ const conv = await storage.get(info.id);
76
+ if (conv && conv.metadata.title === input.title) {
77
+ threadId = info.id;
78
+ existingInfo = info;
79
+ break;
80
+ }
81
+ }
82
+ if (!threadId) {
83
+ return {
84
+ success: false,
85
+ error: `Thread with title '${input.title}' not found`,
86
+ source: input.source,
87
+ };
88
+ }
89
+ }
90
+ const existing = await storage.get(threadId);
91
+ if (!existing) {
92
+ return {
93
+ success: false,
94
+ error: `Thread with ID '${threadId}' not found`,
95
+ id: threadId,
96
+ source: input.source,
97
+ };
98
+ }
99
+ // Get format from existing info if not provided
100
+ if (!existingInfo) {
101
+ const allInfos = await storage.list();
102
+ existingInfo = allInfos.find((i) => i.id === threadId);
103
+ }
104
+ const originalFormat = existingInfo?.format || "markdown";
105
+ // Build updated messages
106
+ let updatedMessages;
107
+ if (input.mode === "replace") {
108
+ updatedMessages = input.messages;
109
+ }
110
+ else {
111
+ const messagesToAdd = input.deduplicate
112
+ ? deduplicateMessages(existing.messages, input.messages)
113
+ : input.messages;
114
+ updatedMessages = [...existing.messages, ...messagesToAdd];
115
+ }
116
+ // Build updated conversation
117
+ const updated = {
118
+ id: existing.id,
119
+ metadata: {
120
+ ...existing.metadata,
121
+ title: input.newTitle ?? existing.metadata.title,
122
+ tags: input.newTags ?? existing.metadata.tags,
123
+ summary: input.newSummary ?? existing.metadata.summary,
124
+ updatedAt: new Date().toISOString(),
125
+ },
126
+ messages: updatedMessages,
127
+ };
128
+ const options = {
129
+ format: input.format ?? originalFormat,
130
+ includeMetadata: true,
131
+ includeTimestamps: true,
132
+ };
133
+ // Delete old and save updated
134
+ await storage.delete(existing.id);
135
+ const result = await storage.save(updated, options);
136
+ const messagesAdded = input.mode === "append" ? updatedMessages.length - existing.messages.length : updatedMessages.length;
137
+ return {
138
+ success: true,
139
+ id: result.id,
140
+ title: updated.metadata.title,
141
+ source: input.source,
142
+ filePath: result.filePath,
143
+ remoteUrl: result.remoteUrl,
144
+ format: result.format,
145
+ savedAt: result.savedAt,
146
+ messageCount: updatedMessages.length,
147
+ messagesAdded,
148
+ mode: input.mode,
149
+ };
150
+ }
151
+ export const updateThreadTool = {
152
+ name: "update_thread",
153
+ description: "Update an existing conversation thread. Can find by ID or title. " +
154
+ "Use 'append' mode to add new messages (with automatic deduplication). " +
155
+ "Use 'replace' mode to overwrite all messages. Can also update title, tags, and summary.",
156
+ inputSchema: UpdateThreadInputSchema,
157
+ handler: updateThread,
158
+ };
159
+ //# sourceMappingURL=update-thread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-thread.js","sourceRoot":"","sources":["../../src/tools/update-thread.ts"],"names":[],"mappings":"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"}