@infinite-room-labs/claudesync-cli 0.1.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.
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const exportCommand: Command;
3
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,aAAa,SA6EtB,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { Command } from "commander";
2
+ import { resolve } from "node:path";
3
+ import { writeFileSync } from "node:fs";
4
+ import { ClaudeSyncClient, buildGitBundle, exportToGit, } from "@infinite-room-labs/claudesync-core";
5
+ import { createClient, resolveOrgId } from "../utils.js";
6
+ export const exportCommand = new Command("export")
7
+ .description("Export a conversation to a git repository")
8
+ .argument("<conversation-id>", "Conversation UUID to export")
9
+ .option("--org <orgId>", "Organization ID (auto-detected if omitted)")
10
+ .option("--output <path>", "Output directory (default: ./<conversation-name>)")
11
+ .option("--format <format>", "Output format: git or json", "git")
12
+ .option("--author-name <name>", "Git author name", "Claude")
13
+ .option("--author-email <email>", "Git author email", "claude@anthropic.com")
14
+ .action(async (conversationId, options) => {
15
+ const { auth, client } = createClient();
16
+ const orgId = await resolveOrgId(auth, options.org);
17
+ // 1. Fetch conversation
18
+ console.log(`Fetching conversation ${conversationId}...`);
19
+ const conversation = await client.getConversation(orgId, conversationId);
20
+ console.log(` Name: ${conversation.name}`);
21
+ console.log(` Messages: ${conversation.chat_messages.length}`);
22
+ // 2. Fetch artifacts
23
+ console.log("Fetching artifacts...");
24
+ const artifacts = await client.listArtifacts(orgId, conversationId);
25
+ console.log(` Found ${artifacts.files_metadata.length} artifact(s).`);
26
+ // 3. Download artifact contents
27
+ const artifactContents = new Map();
28
+ for (const meta of artifacts.files_metadata) {
29
+ const filename = ClaudeSyncClient.safeFilename(meta.path);
30
+ console.log(` Downloading: ${filename}`);
31
+ const content = await client.downloadArtifact(orgId, conversationId, meta.path);
32
+ artifactContents.set(meta.path, content);
33
+ }
34
+ // 4. Build GitBundle
35
+ console.log("Building export bundle...");
36
+ const bundle = buildGitBundle(conversation, artifacts, artifactContents, {
37
+ authorName: options.authorName,
38
+ authorEmail: options.authorEmail,
39
+ });
40
+ // 5. Output
41
+ if (options.format === "json") {
42
+ const outputPath = options.output;
43
+ if (outputPath) {
44
+ const fullPath = resolve(outputPath);
45
+ writeFileSync(fullPath, JSON.stringify(bundle, null, 2), "utf-8");
46
+ console.log(`\nBundle written to ${fullPath}`);
47
+ }
48
+ else {
49
+ console.log(JSON.stringify(bundle, null, 2));
50
+ }
51
+ }
52
+ else {
53
+ // git format
54
+ const slug = conversation.name
55
+ .toLowerCase()
56
+ .replace(/[^a-z0-9]+/g, "-")
57
+ .replace(/^-|-$/g, "")
58
+ .slice(0, 60);
59
+ const outputPath = resolve(options.output ?? `./${slug}`);
60
+ console.log(`Exporting to git repository: ${outputPath}`);
61
+ await exportToGit(bundle, outputPath);
62
+ console.log(`\nExport complete!`);
63
+ console.log(` Repository: ${outputPath}`);
64
+ console.log(` Commits: ${bundle.commits.length}`);
65
+ }
66
+ });
67
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const lsCommand: Command;
3
+ //# sourceMappingURL=ls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../src/commands/ls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,SAAS,SA0DlB,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { Command } from "commander";
2
+ import { createClient, resolveOrgId, truncate, outputJson } from "../utils.js";
3
+ export const lsCommand = new Command("ls")
4
+ .description("List conversations")
5
+ .option("--org <orgId>", "Organization ID (auto-detected if omitted)")
6
+ .option("--limit <n>", "Max conversations to show", "20")
7
+ .option("--starred", "Show only starred conversations")
8
+ .option("--json", "Output as JSON instead of table")
9
+ .option("--query <expression>", "JMESPath query to filter JSON output (implies --json)")
10
+ .action(async (options) => {
11
+ const { auth, client } = createClient();
12
+ const orgId = await resolveOrgId(auth, options.org);
13
+ const limit = parseInt(options.limit, 10);
14
+ let conversations = [];
15
+ for await (const conv of client.listConversations(orgId)) {
16
+ if (options.starred && !conv.is_starred) {
17
+ continue;
18
+ }
19
+ conversations.push(conv);
20
+ if (conversations.length >= limit) {
21
+ break;
22
+ }
23
+ }
24
+ if (options.json || options.query) {
25
+ outputJson(conversations, options.query);
26
+ return;
27
+ }
28
+ if (conversations.length === 0) {
29
+ console.log("No conversations found.");
30
+ return;
31
+ }
32
+ // Table output
33
+ const uuidWidth = 36;
34
+ const modelWidth = 20;
35
+ console.log(` ${"UUID".padEnd(uuidWidth)} ${"Model".padEnd(modelWidth)} Name`);
36
+ for (const conv of conversations) {
37
+ const uuid = conv.uuid;
38
+ const model = truncate(conv.model ?? "unknown", modelWidth);
39
+ const name = truncate(conv.name, 60);
40
+ console.log(` ${uuid.padEnd(uuidWidth)} ${model.padEnd(modelWidth)} ${name}`);
41
+ }
42
+ console.log(`\n ${conversations.length} conversation(s) shown.`);
43
+ console.log(` Export a conversation: claudesync export <UUID>`);
44
+ });
45
+ //# sourceMappingURL=ls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ls.js","sourceRoot":"","sources":["../../src/commands/ls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/E,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;KACvC,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,eAAe,EAAE,4CAA4C,CAAC;KACrE,MAAM,CAAC,aAAa,EAAE,2BAA2B,EAAE,IAAI,CAAC;KACxD,MAAM,CAAC,WAAW,EAAE,iCAAiC,CAAC;KACtD,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;KACnD,MAAM,CAAC,sBAAsB,EAAE,uDAAuD,CAAC;KACvF,MAAM,CAAC,KAAK,EAAE,OAMd,EAAE,EAAE;IACH,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAE1C,IAAI,aAAa,GAA0B,EAAE,CAAC;IAC9C,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,SAAS;QACX,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,aAAa,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;YAClC,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClC,UAAU,CAAC,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,eAAe;IACf,MAAM,SAAS,GAAG,EAAE,CAAC;IACrB,MAAM,UAAU,GAAG,EAAE,CAAC;IAEtB,OAAO,CAAC,GAAG,CACT,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CACrE,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,EAAE,UAAU,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CACT,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE,CACpE,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,OAAO,aAAa,CAAC,MAAM,yBAAyB,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const projectsCommand: Command;
3
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,eAAe,SACc,CAAC"}
@@ -0,0 +1,204 @@
1
+ import { Command } from "commander";
2
+ import { resolve } from "node:path";
3
+ import { writeFileSync, mkdirSync } from "node:fs";
4
+ import { ClaudeSyncClient, buildGitBundle, exportToGit, } from "@infinite-room-labs/claudesync-core";
5
+ import { createClient, resolveOrgId, truncate, outputJson } from "../utils.js";
6
+ export const projectsCommand = new Command("projects")
7
+ .description("List and export projects");
8
+ // --- projects list (default) ---
9
+ projectsCommand
10
+ .command("list", { isDefault: true })
11
+ .description("List projects")
12
+ .option("--org <orgId>", "Organization ID (auto-detected if omitted)")
13
+ .option("--json", "Output as JSON instead of table")
14
+ .option("--query <expression>", "JMESPath query to filter JSON output (implies --json)")
15
+ .action(async (options) => {
16
+ const { auth, client } = createClient();
17
+ const orgId = await resolveOrgId(auth, options.org);
18
+ const projects = await client.listProjects(orgId);
19
+ if (options.json || options.query) {
20
+ outputJson(projects, options.query);
21
+ return;
22
+ }
23
+ if (projects.length === 0) {
24
+ console.log("No projects found.");
25
+ return;
26
+ }
27
+ console.log(` ${"UUID".padEnd(38)} ${"Name".padEnd(30)} Docs`);
28
+ for (const project of projects) {
29
+ const name = truncate(project.name, 30);
30
+ const docs = project.docs_count ?? 0;
31
+ console.log(` ${project.uuid.padEnd(38)} ${name.padEnd(30)} ${docs}`);
32
+ }
33
+ console.log(`\n ${projects.length} project(s) found.`);
34
+ console.log(` Export a project: claudesync projects export <UUID>`);
35
+ });
36
+ // --- projects export ---
37
+ projectsCommand
38
+ .command("export")
39
+ .description("Export an entire project (knowledge docs + all conversations + artifacts)")
40
+ .argument("<project-id>", "Project UUID to export")
41
+ .option("--org <orgId>", "Organization ID (auto-detected if omitted)")
42
+ .option("--output <path>", "Output directory (default: ./<project-name>)")
43
+ .option("--format <format>", "Output format: git or json", "git")
44
+ .option("--author-name <name>", "Git author name", "Claude")
45
+ .option("--author-email <email>", "Git author email", "claude@anthropic.com")
46
+ .option("--skip-artifacts", "Skip downloading artifacts (faster)")
47
+ .action(async (projectId, options) => {
48
+ const { auth, client } = createClient();
49
+ const orgId = await resolveOrgId(auth, options.org);
50
+ const author = { name: options.authorName, email: options.authorEmail };
51
+ // 1. Fetch project metadata
52
+ console.log(`Fetching project ${projectId}...`);
53
+ const projects = await client.listProjects(orgId);
54
+ const project = projects.find((p) => p.uuid === projectId);
55
+ if (!project) {
56
+ console.error(`Project ${projectId} not found.`);
57
+ process.exit(1);
58
+ }
59
+ console.log(` Name: ${project.name}`);
60
+ console.log(` Description: ${project.description ?? "(none)"}`);
61
+ // 2. Fetch knowledge docs
62
+ console.log("Fetching knowledge docs...");
63
+ const docs = await client.getProjectDocs(orgId, projectId);
64
+ console.log(` Found ${docs.length} knowledge doc(s).`);
65
+ // 3. Fetch project conversations
66
+ console.log("Fetching project conversations...");
67
+ const conversations = await client.getProjectConversations(orgId, projectId);
68
+ console.log(` Found ${conversations.length} conversation(s).`);
69
+ // 4. Build commits
70
+ const commits = [];
71
+ const now = new Date().toISOString();
72
+ // Commit 1: Project README + knowledge docs
73
+ const projectFiles = {};
74
+ projectFiles["README.md"] = buildProjectReadme(project, docs.length, conversations.length);
75
+ for (const doc of docs) {
76
+ const safeName = doc.file_name.replace(/[/\\]/g, "_");
77
+ projectFiles[`knowledge/${safeName}`] = doc.content;
78
+ console.log(` Knowledge: ${safeName} (${doc.content.length} chars)`);
79
+ }
80
+ commits.push({
81
+ message: `Export project: ${project.name}`,
82
+ timestamp: project.created_at,
83
+ author,
84
+ files: projectFiles,
85
+ });
86
+ // 5. For each conversation: fetch full content + artifacts
87
+ for (let i = 0; i < conversations.length; i++) {
88
+ const convSummary = conversations[i];
89
+ const progress = `[${i + 1}/${conversations.length}]`;
90
+ console.log(`${progress} ${convSummary.name}...`);
91
+ const conversation = await client.getConversation(orgId, convSummary.uuid);
92
+ const slug = convSummary.name
93
+ .toLowerCase()
94
+ .replace(/[^a-z0-9]+/g, "-")
95
+ .replace(/^-|-$/g, "")
96
+ .slice(0, 50);
97
+ const convDir = `conversations/${slug}`;
98
+ // Build conversation bundle and extract files
99
+ let artifacts = { success: true, files: [], files_metadata: [] };
100
+ const artifactContents = new Map();
101
+ if (!options.skipArtifacts) {
102
+ try {
103
+ artifacts = await client.listArtifacts(orgId, convSummary.uuid);
104
+ for (const meta of artifacts.files_metadata) {
105
+ try {
106
+ const content = await client.downloadArtifact(orgId, convSummary.uuid, meta.path);
107
+ artifactContents.set(meta.path, content);
108
+ }
109
+ catch {
110
+ // Skip failed downloads
111
+ }
112
+ }
113
+ if (artifacts.files_metadata.length > 0) {
114
+ console.log(` ${progress} ${artifacts.files_metadata.length} artifact(s)`);
115
+ }
116
+ }
117
+ catch {
118
+ // Some conversations may not support artifacts
119
+ }
120
+ }
121
+ const bundle = buildGitBundle(conversation, artifacts, artifactContents, {
122
+ authorName: options.authorName,
123
+ authorEmail: options.authorEmail,
124
+ });
125
+ // Remap file paths into conversation subdirectory
126
+ for (const commit of bundle.commits) {
127
+ const remappedFiles = {};
128
+ for (const [path, content] of Object.entries(commit.files)) {
129
+ remappedFiles[`${convDir}/${path}`] = content;
130
+ }
131
+ commits.push({
132
+ message: `${progress} ${commit.message}`,
133
+ timestamp: commit.timestamp,
134
+ author: commit.author,
135
+ files: remappedFiles,
136
+ });
137
+ }
138
+ }
139
+ // 6. Output
140
+ const projectSlug = project.name
141
+ .toLowerCase()
142
+ .replace(/[^a-z0-9]+/g, "-")
143
+ .replace(/^-|-$/g, "")
144
+ .slice(0, 60);
145
+ const fullBundle = {
146
+ metadata: {
147
+ conversationId: projectId,
148
+ conversationName: project.name,
149
+ model: null,
150
+ createdAt: project.created_at,
151
+ exportedAt: now,
152
+ },
153
+ commits,
154
+ };
155
+ if (options.format === "json") {
156
+ const outputPath = options.output;
157
+ if (outputPath) {
158
+ const fullPath = resolve(outputPath);
159
+ writeFileSync(fullPath, JSON.stringify(fullBundle, null, 2), "utf-8");
160
+ console.log(`\nBundle written to ${fullPath}`);
161
+ }
162
+ else {
163
+ console.log(JSON.stringify(fullBundle, null, 2));
164
+ }
165
+ }
166
+ else {
167
+ const outputPath = resolve(options.output ?? `./${projectSlug}`);
168
+ console.log(`\nExporting to git repository: ${outputPath}`);
169
+ await exportToGit(fullBundle, outputPath);
170
+ console.log(`\nExport complete!`);
171
+ console.log(` Repository: ${outputPath}`);
172
+ console.log(` Commits: ${commits.length}`);
173
+ console.log(` Knowledge docs: ${docs.length}`);
174
+ console.log(` Conversations: ${conversations.length}`);
175
+ }
176
+ });
177
+ function buildProjectReadme(project, docCount, convCount) {
178
+ const lines = [];
179
+ lines.push(`# ${project.name}`);
180
+ lines.push("");
181
+ if (project.description) {
182
+ lines.push(project.description);
183
+ lines.push("");
184
+ }
185
+ lines.push(`- **Project ID:** ${project.uuid}`);
186
+ lines.push(`- **Created:** ${project.created_at}`);
187
+ lines.push(`- **Updated:** ${project.updated_at}`);
188
+ lines.push(`- **Knowledge docs:** ${docCount}`);
189
+ lines.push(`- **Conversations:** ${convCount}`);
190
+ lines.push("");
191
+ lines.push("## Structure");
192
+ lines.push("");
193
+ lines.push("```");
194
+ lines.push("knowledge/ # Project knowledge documents");
195
+ lines.push("conversations/ # Exported conversations with artifacts");
196
+ lines.push("```");
197
+ lines.push("");
198
+ lines.push("---");
199
+ lines.push("");
200
+ lines.push("Exported by [ClaudeSync](https://github.com/infiniteroomlabs/claudesync)");
201
+ lines.push("");
202
+ return lines.join("\n");
203
+ }
204
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const searchCommand: Command;
3
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,SA6CtB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { Command } from "commander";
2
+ import { createClient, resolveOrgId, truncate, outputJson } from "../utils.js";
3
+ export const searchCommand = new Command("search")
4
+ .description("Search conversations")
5
+ .argument("<query>", "Search query")
6
+ .option("--org <orgId>", "Organization ID (auto-detected if omitted)")
7
+ .option("--limit <n>", "Max results to show", "10")
8
+ .option("--json", "Output as JSON instead of table")
9
+ .option("--query <expression>", "JMESPath query to filter JSON output (implies --json)")
10
+ .action(async (query, options) => {
11
+ const { auth, client } = createClient();
12
+ const orgId = await resolveOrgId(auth, options.org);
13
+ const limit = parseInt(options.limit, 10);
14
+ const results = await client.searchConversations(orgId, query, limit);
15
+ if (options.json || options.query) {
16
+ outputJson(results, options.query);
17
+ return;
18
+ }
19
+ if (results.chunks.length === 0) {
20
+ console.log(`No results found for "${query}".`);
21
+ return;
22
+ }
23
+ console.log(`Found ${results.chunks.length} result(s) for "${query}":\n`);
24
+ for (const chunk of results.chunks) {
25
+ const title = chunk.extras.conversation_title ?? chunk.name;
26
+ const preview = truncate(chunk.text.replace(/\n/g, " ").trim(), 100);
27
+ console.log(` ${title}`);
28
+ console.log(` Conversation: ${chunk.extras.conversation_uuid}`);
29
+ console.log(` ${preview}`);
30
+ console.log();
31
+ }
32
+ });
33
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/E,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,sBAAsB,CAAC;KACnC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;KACnC,MAAM,CAAC,eAAe,EAAE,4CAA4C,CAAC;KACrE,MAAM,CAAC,aAAa,EAAE,qBAAqB,EAAE,IAAI,CAAC;KAClD,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;KACnD,MAAM,CAAC,sBAAsB,EAAE,uDAAuD,CAAC;KACvF,MAAM,CAAC,KAAK,EACX,KAAa,EACb,OAKC,EACD,EAAE;IACF,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAE1C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAEtE,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACnC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,IAAI,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,MAAM,mBAAmB,KAAK,MAAM,CAAC,CAAC;IAE1E,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,kBAAkB,IAAI,KAAK,CAAC,IAAI,CAAC;QAC5D,MAAM,OAAO,GAAG,QAAQ,CACtB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EACrC,GAAG,CACJ,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { AuthError, ClaudeSyncError, RateLimitError } from "@infinite-room-labs/claudesync-core";
4
+ import { lsCommand } from "./commands/ls.js";
5
+ import { exportCommand } from "./commands/export.js";
6
+ import { projectsCommand } from "./commands/projects.js";
7
+ import { searchCommand } from "./commands/search.js";
8
+ const program = new Command();
9
+ program
10
+ .name("claudesync")
11
+ .description("ClaudeSync -- Export claude.ai conversations as git repositories")
12
+ .version("0.1.0");
13
+ program.addCommand(lsCommand);
14
+ program.addCommand(exportCommand);
15
+ program.addCommand(projectsCommand);
16
+ program.addCommand(searchCommand);
17
+ // Global error handling
18
+ program.hook("preAction", () => {
19
+ // Set up unhandled rejection handler before each command
20
+ process.on("unhandledRejection", handleError);
21
+ });
22
+ function handleError(error) {
23
+ if (error instanceof AuthError) {
24
+ console.error(`Auth error: ${error.message}`);
25
+ process.exit(1);
26
+ }
27
+ if (error instanceof RateLimitError) {
28
+ console.error(`Rate limited. Try again in ${error.sleepSeconds} seconds.`);
29
+ process.exit(1);
30
+ }
31
+ if (error instanceof ClaudeSyncError) {
32
+ console.error(`API error: ${error.message}`);
33
+ process.exit(1);
34
+ }
35
+ if (error instanceof Error) {
36
+ console.error(`Error: ${error.message}`);
37
+ process.exit(1);
38
+ }
39
+ console.error("An unexpected error occurred.");
40
+ process.exit(1);
41
+ }
42
+ program.parseAsync(process.argv).catch(handleError);
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACjG,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,kEAAkE,CAAC;KAC/E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC9B,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,wBAAwB;AACxB,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;IAC7B,yDAAyD;IACzD,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,CACX,8BAA8B,KAAK,CAAC,YAAY,WAAW,CAC5D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { EnvAuth, ClaudeSyncClient } from "@infinite-room-labs/claudesync-core";
2
+ /**
3
+ * Creates an authenticated ClaudeSyncClient from environment variables.
4
+ * Exits with a user-friendly message if CLAUDE_AI_COOKIE is not set.
5
+ */
6
+ export declare function createClient(): {
7
+ auth: EnvAuth;
8
+ client: ClaudeSyncClient;
9
+ };
10
+ /**
11
+ * Resolves the organization ID from the provided option or auto-detects it
12
+ * from the authenticated session.
13
+ */
14
+ export declare function resolveOrgId(auth: EnvAuth, orgIdOption?: string): Promise<string>;
15
+ export declare function outputJson(data: unknown, query?: string): void;
16
+ /**
17
+ * Truncates a string to the given max length, appending an ellipsis if needed.
18
+ */
19
+ export declare function truncate(str: string, maxLen: number): string;
20
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,gBAAgB,EAEjB,MAAM,qCAAqC,CAAC;AAI7C;;;GAGG;AACH,wBAAgB,YAAY,IAAI;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAY1E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,OAAO,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAcjB;AAmBD,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAe9D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAK5D"}
package/dist/utils.js ADDED
@@ -0,0 +1,82 @@
1
+ import { EnvAuth, ClaudeSyncClient, AuthError, } from "@infinite-room-labs/claudesync-core";
2
+ import { search } from "@metrichor/jmespath";
3
+ /**
4
+ * Creates an authenticated ClaudeSyncClient from environment variables.
5
+ * Exits with a user-friendly message if CLAUDE_AI_COOKIE is not set.
6
+ */
7
+ export function createClient() {
8
+ try {
9
+ const auth = new EnvAuth();
10
+ const client = new ClaudeSyncClient(auth);
11
+ return { auth, client };
12
+ }
13
+ catch (error) {
14
+ if (error instanceof AuthError) {
15
+ console.error(`Auth error: ${error.message}`);
16
+ process.exit(1);
17
+ }
18
+ throw error;
19
+ }
20
+ }
21
+ /**
22
+ * Resolves the organization ID from the provided option or auto-detects it
23
+ * from the authenticated session.
24
+ */
25
+ export async function resolveOrgId(auth, orgIdOption) {
26
+ if (orgIdOption) {
27
+ return orgIdOption;
28
+ }
29
+ try {
30
+ return await auth.getOrganizationId();
31
+ }
32
+ catch (error) {
33
+ if (error instanceof AuthError) {
34
+ console.error(`Failed to auto-detect organization: ${error.message}`);
35
+ console.error("Specify --org <orgId> manually.");
36
+ process.exit(1);
37
+ }
38
+ throw error;
39
+ }
40
+ }
41
+ /**
42
+ * Outputs JSON data, optionally filtered by a JMESPath query.
43
+ * Used by all commands that support --json and --query flags.
44
+ *
45
+ * Usage in commands:
46
+ * .option("--json", "Output as JSON")
47
+ * .option("--query <expression>", "JMESPath query to filter JSON output (implies --json)")
48
+ *
49
+ * When --query is provided without --json, it implies --json automatically.
50
+ */
51
+ // Zod's passthrough() creates objectOutputType<...> which doesn't structurally
52
+ // match JSONValue, even though the data is always JSON-serializable (it came
53
+ // from JSON.parse via the API client). This cast bridges that gap.
54
+ function asJsonValue(data) {
55
+ return data;
56
+ }
57
+ export function outputJson(data, query) {
58
+ if (query) {
59
+ try {
60
+ const result = search(asJsonValue(data), query);
61
+ console.log(JSON.stringify(result, null, 2));
62
+ }
63
+ catch (err) {
64
+ console.error(`Invalid JMESPath query: ${err instanceof Error ? err.message : String(err)}`);
65
+ console.error(" See https://jmespath.org/tutorial.html for syntax help.");
66
+ process.exit(1);
67
+ }
68
+ }
69
+ else {
70
+ console.log(JSON.stringify(data, null, 2));
71
+ }
72
+ }
73
+ /**
74
+ * Truncates a string to the given max length, appending an ellipsis if needed.
75
+ */
76
+ export function truncate(str, maxLen) {
77
+ if (str.length <= maxLen) {
78
+ return str;
79
+ }
80
+ return str.slice(0, maxLen - 3) + "...";
81
+ }
82
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,gBAAgB,EAChB,SAAS,GACV,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAa,EACb,WAAoB;IAEpB,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,uCAAuC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACtE,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,+EAA+E;AAC/E,6EAA6E;AAC7E,mEAAmE;AACnE,SAAS,WAAW,CAAC,IAAa;IAChC,OAAO,IAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAa,EAAE,KAAc;IACtD,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC9E,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,MAAc;IAClD,IAAI,GAAG,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;AAC1C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@infinite-room-labs/claudesync-cli",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "claudesync": "./dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "dependencies": {
12
+ "@metrichor/jmespath": "^0.3.1",
13
+ "commander": "^14.0.3",
14
+ "@infinite-room-labs/claudesync-core": "0.1.0"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^25.5.0",
18
+ "typescript": "^5.9.3"
19
+ },
20
+ "scripts": {
21
+ "build": "tsc -p tsconfig.json",
22
+ "typecheck": "tsc --noEmit"
23
+ }
24
+ }