osborn 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +13 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -300,41 +300,31 @@ function startApiServer(workingDir, port) {
|
|
|
300
300
|
// GET /sessions/export — stream a gzipped tar of ~/.claude/projects/ to the client
|
|
301
301
|
// Optional ?workDir= query param: if present, export only that project's slug folder.
|
|
302
302
|
if (req.method === 'GET' && url.pathname === '/sessions/export') {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (!existsSync(slugDir)) {
|
|
309
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
310
|
-
res.end(JSON.stringify({ error: 'Project not found', slug }));
|
|
303
|
+
if (syncToken) {
|
|
304
|
+
const authHeader = req.headers['authorization'] ?? '';
|
|
305
|
+
if (authHeader !== `Bearer ${syncToken}`) {
|
|
306
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
307
|
+
res.end(JSON.stringify({ error: 'Unauthorized' }));
|
|
311
308
|
return;
|
|
312
309
|
}
|
|
313
|
-
res.writeHead(200, {
|
|
314
|
-
'Content-Type': 'application/gzip',
|
|
315
|
-
'Content-Disposition': `attachment; filename="claude-sessions-${slug}.tar.gz"`,
|
|
316
|
-
'Access-Control-Allow-Origin': '*',
|
|
317
|
-
});
|
|
318
|
-
// Use '--' to prevent tar from interpreting the leading-hyphen slug as flags
|
|
319
|
-
const tar = spawn('tar', ['-czf', '-', '-C', projectsDir, '--', slug]);
|
|
320
|
-
tar.stdout.pipe(res);
|
|
321
|
-
tar.stderr.on('data', (d) => console.error('[export]', d.toString()));
|
|
322
|
-
tar.on('close', (code) => { if (code !== 0)
|
|
323
|
-
res.destroy(); });
|
|
324
|
-
return;
|
|
325
310
|
}
|
|
311
|
+
const claudeDir = join(homedir(), '.claude');
|
|
312
|
+
const projectsDir = join(claudeDir, 'projects');
|
|
313
|
+
const workDir = url.searchParams.get('workDir');
|
|
326
314
|
if (!existsSync(projectsDir)) {
|
|
327
315
|
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
328
316
|
res.end(JSON.stringify({ error: 'No sessions found' }));
|
|
329
317
|
return;
|
|
330
318
|
}
|
|
319
|
+
const tarArgs = ['-czf', '-', '-C', claudeDir, 'projects'];
|
|
320
|
+
void workDir; // workDir param accepted but full projects/ export is returned
|
|
331
321
|
res.writeHead(200, {
|
|
332
322
|
'Content-Type': 'application/gzip',
|
|
333
323
|
'Content-Disposition': 'attachment; filename="claude-sessions.tar.gz"',
|
|
334
324
|
'Access-Control-Allow-Origin': '*',
|
|
335
325
|
});
|
|
336
326
|
// Stream tar output directly to response
|
|
337
|
-
const tar = spawn('tar',
|
|
327
|
+
const tar = spawn('tar', tarArgs);
|
|
338
328
|
tar.stdout.pipe(res);
|
|
339
329
|
tar.stderr.on('data', (d) => console.error('[export]', d.toString()));
|
|
340
330
|
tar.on('close', (code) => { if (code !== 0)
|
|
@@ -370,7 +360,8 @@ function startApiServer(workingDir, port) {
|
|
|
370
360
|
return;
|
|
371
361
|
}
|
|
372
362
|
try {
|
|
373
|
-
const
|
|
363
|
+
const claudeDir = join(homedir(), '.claude');
|
|
364
|
+
const projectsDir = join(claudeDir, 'projects');
|
|
374
365
|
mkdirSync(projectsDir, { recursive: true });
|
|
375
366
|
// The archive should contain a 'projects' subdirectory
|
|
376
367
|
const extractedProjects = join(tmpDir, 'projects');
|