@stage-labs/metro 0.1.0-beta.43 → 0.1.0-beta.45

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stage-labs/metro",
3
- "version": "0.1.0-beta.43",
3
+ "version": "0.1.0-beta.45",
4
4
  "description": "The metro command line. Sign in once per machine, then hand your MCP connector list to Claude Code without the credentials touching disk, argv or shell history.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -4,6 +4,7 @@ import { apiFailure, apiSession, cors, sendJson } from './api-http.js';
4
4
  import { ApiError } from './api-error.js';
5
5
  import {
6
6
  claudeDir,
7
+ deleteClaudeSession,
7
8
  listClaudeProjects,
8
9
  listClaudeSessions,
9
10
  listMemory,
@@ -48,9 +49,14 @@ const ITEMS: Record<string, Handler> = {
48
49
  memory: (query, dir, name) => ({ name, content: readMemoryFile(projectOf(query), name, dir) }),
49
50
  };
50
51
 
51
- function answer(path: string, query: URLSearchParams, dir: string): unknown {
52
+ function answer(method: string, path: string, query: URLSearchParams, dir: string): unknown {
52
53
  const rest = path.slice(PREFIX.length + 1).split('/').filter(Boolean);
53
54
  const [head = '', item] = rest;
55
+ if (method === 'DELETE') {
56
+ if (rest.length !== 2 || head !== 'sessions') throw new ApiError('method not allowed', 405);
57
+ deleteClaudeSession(projectOf(query), item ?? '', dir);
58
+ return { deleted: item };
59
+ }
54
60
  const handler = rest.length === 1 ? COLLECTIONS[head] : rest.length === 2 ? ITEMS[head] : undefined;
55
61
  if (handler === undefined) throw new ApiError('no such route', 404);
56
62
  return handler(query, dir, item ?? '');
@@ -67,7 +73,7 @@ export function handleClaudeRequest(
67
73
  res.writeHead(204, cors(req)).end();
68
74
  return true;
69
75
  }
70
- if (req.method !== 'GET') {
76
+ if (req.method !== 'GET' && req.method !== 'DELETE') {
71
77
  sendJson(req, res, 405, { error: 'method not allowed' });
72
78
  return true;
73
79
  }
@@ -79,7 +85,7 @@ export function handleClaudeRequest(
79
85
  Promise.resolve()
80
86
  .then(() => {
81
87
  deps.authorize(session.subject);
82
- return answer(path, new URLSearchParams(search), (deps.dir ?? claudeDir)());
88
+ return answer(req.method ?? 'GET', path, new URLSearchParams(search), (deps.dir ?? claudeDir)());
83
89
  })
84
90
  .then((body) => {
85
91
  sendJson(req, res, 200, body);
@@ -5,6 +5,7 @@ import {
5
5
  openSync,
6
6
  readdirSync,
7
7
  readSync,
8
+ rmSync,
8
9
  statSync,
9
10
  } from 'node:fs';
10
11
  import { homedir } from 'node:os';
@@ -273,6 +274,15 @@ export async function readTranscript(
273
274
  return { entries, total, next: offset + limit < total ? offset + limit : null };
274
275
  }
275
276
 
277
+ export function deleteClaudeSession(project: string, session: string, dir = claudeDir()): void {
278
+ const root = projectDir(project, dir);
279
+ const id = safeName(session, SESSION_RE, 'session id');
280
+ const file = join(root, `${id}.jsonl`);
281
+ if (!existsSync(file)) throw new ApiError('no such session', 404);
282
+ rmSync(file);
283
+ rmSync(join(root, id), { recursive: true, force: true });
284
+ }
285
+
276
286
  export interface MemoryFile {
277
287
  name: string;
278
288
  bytes: number;
@@ -2,8 +2,13 @@ import { hostname } from 'node:os';
2
2
 
3
3
  const uiBase = (): string => process.env.METRO_UI_URL ?? 'https://metro.box';
4
4
 
5
- export const connectLink = (base: string): string =>
6
- `${uiBase()}/#/connect/${encodeURIComponent(base)}`;
5
+ export const connectLink = (base: string): string => {
6
+ try {
7
+ return `${uiBase()}/#/${new URL(base).host}`;
8
+ } catch {
9
+ return `${uiBase()}/#/connect/${encodeURIComponent(base)}`;
10
+ }
11
+ };
7
12
 
8
13
  export function localConnectHint(port: number): string {
9
14
  const here = `http://127.0.0.1:${String(port)}`;
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.1.0-beta.43"
2
+ "version": "0.1.0-beta.45"
3
3
  }