style: 完成所有文件的lint

This commit is contained in:
claude-code-best
2026-05-01 21:39:30 +08:00
parent d136872cc9
commit 6182015005
1333 changed files with 68255 additions and 77882 deletions

View File

@@ -1,27 +1,30 @@
import { Hono } from "hono";
import { storeBindSession } from "../../store";
import { resolveExistingWebSessionId, toWebSessionId } from "../../services/session";
import { Hono } from 'hono'
import { storeBindSession } from '../../store'
import {
resolveExistingWebSessionId,
toWebSessionId,
} from '../../services/session'
const app = new Hono();
const app = new Hono()
/** POST /web/bind — Bind a session to a UUID (no-login auth) */
app.post("/bind", async (c) => {
const body = await c.req.json();
const sessionId = body.sessionId;
app.post('/bind', async c => {
const body = await c.req.json()
const sessionId = body.sessionId
// UUID can come from query param (api.js sends it in URL) or body
const uuid = c.req.query("uuid") || body.uuid;
const uuid = c.req.query('uuid') || body.uuid
if (!sessionId || !uuid) {
return c.json({ error: "sessionId and uuid are required" }, 400);
return c.json({ error: 'sessionId and uuid are required' }, 400)
}
const resolvedSessionId = resolveExistingWebSessionId(sessionId);
const resolvedSessionId = resolveExistingWebSessionId(sessionId)
if (!resolvedSessionId) {
return c.json({ error: "Session not found" }, 404);
return c.json({ error: 'Session not found' }, 404)
}
storeBindSession(resolvedSessionId, uuid);
return c.json({ ok: true, sessionId: toWebSessionId(resolvedSessionId) });
});
storeBindSession(resolvedSessionId, uuid)
return c.json({ ok: true, sessionId: toWebSessionId(resolvedSessionId) })
})
export default app;
export default app

View File

@@ -1,86 +1,130 @@
import { log, error as logError } from "../../logger";
import { Hono } from "hono";
import { uuidAuth } from "../../auth/middleware";
import { getSession, isSessionClosedStatus, resolveOwnedWebSessionId, updateSessionStatus } from "../../services/session";
import { publishSessionEvent } from "../../services/transport";
import { getEventBus } from "../../transport/event-bus";
import { log, error as logError } from '../../logger'
import { Hono } from 'hono'
import { uuidAuth } from '../../auth/middleware'
import {
getSession,
isSessionClosedStatus,
resolveOwnedWebSessionId,
updateSessionStatus,
} from '../../services/session'
import { publishSessionEvent } from '../../services/transport'
import { getEventBus } from '../../transport/event-bus'
const app = new Hono();
const app = new Hono()
type OwnershipCheckResult =
| { error: true }
| { error: true; reason: string }
| { error: false; session: NonNullable<ReturnType<typeof getSession>>; sessionId: string };
| {
error: false
session: NonNullable<ReturnType<typeof getSession>>
sessionId: string
}
function checkOwnership(c: { get: (key: string) => string | undefined }, sessionId: string): OwnershipCheckResult {
const uuid = c.get("uuid")!;
const resolvedSessionId = resolveOwnedWebSessionId(sessionId, uuid);
function checkOwnership(
c: { get: (key: string) => string | undefined },
sessionId: string,
): OwnershipCheckResult {
const uuid = c.get('uuid')!
const resolvedSessionId = resolveOwnedWebSessionId(sessionId, uuid)
if (!resolvedSessionId) {
return { error: true };
return { error: true }
}
const session = getSession(resolvedSessionId);
const session = getSession(resolvedSessionId)
if (!session) {
return { error: true };
return { error: true }
}
if (isSessionClosedStatus(session.status)) {
return { error: true, reason: `Session is ${session.status}` };
return { error: true, reason: `Session is ${session.status}` }
}
return { error: false, session, sessionId: resolvedSessionId };
return { error: false, session, sessionId: resolvedSessionId }
}
function closedSessionResponse(message: string) {
return { error: { type: "session_closed", message } };
return { error: { type: 'session_closed', message } }
}
/** POST /web/sessions/:id/events — Send user message to session */
app.post("/sessions/:id/events", uuidAuth, async (c) => {
const requestedSessionId = c.req.param("id")!;
const ownership = checkOwnership(c, requestedSessionId);
app.post('/sessions/:id/events', uuidAuth, async c => {
const requestedSessionId = c.req.param('id')!
const ownership = checkOwnership(c, requestedSessionId)
if (ownership.error) {
const message = "reason" in ownership ? ownership.reason : "Not your session";
const status = "reason" in ownership ? 409 : 403;
return c.json("reason" in ownership ? closedSessionResponse(message) : { error: { type: "forbidden", message } }, status);
const message =
'reason' in ownership ? ownership.reason : 'Not your session'
const status = 'reason' in ownership ? 409 : 403
return c.json(
'reason' in ownership
? closedSessionResponse(message)
: { error: { type: 'forbidden', message } },
status,
)
}
const { sessionId } = ownership;
const { sessionId } = ownership
const body = await c.req.json();
const eventType = body.type || "user";
log(`[RC-DEBUG] web -> server: POST /web/sessions/${sessionId}/events type=${eventType} content=${JSON.stringify(body).slice(0, 200)}`);
const event = publishSessionEvent(sessionId, eventType, body, "outbound");
log(`[RC-DEBUG] web -> server: published outbound event id=${event.id} type=${event.type} direction=${event.direction} subscribers=${getEventBus(sessionId).subscriberCount()}`);
return c.json({ status: "ok", event }, 200);
});
const body = await c.req.json()
const eventType = body.type || 'user'
log(
`[RC-DEBUG] web -> server: POST /web/sessions/${sessionId}/events type=${eventType} content=${JSON.stringify(body).slice(0, 200)}`,
)
const event = publishSessionEvent(sessionId, eventType, body, 'outbound')
log(
`[RC-DEBUG] web -> server: published outbound event id=${event.id} type=${event.type} direction=${event.direction} subscribers=${getEventBus(sessionId).subscriberCount()}`,
)
return c.json({ status: 'ok', event }, 200)
})
/** POST /web/sessions/:id/control — Send control request (permission approval etc) */
app.post("/sessions/:id/control", uuidAuth, async (c) => {
const requestedSessionId = c.req.param("id")!;
const ownership = checkOwnership(c, requestedSessionId);
app.post('/sessions/:id/control', uuidAuth, async c => {
const requestedSessionId = c.req.param('id')!
const ownership = checkOwnership(c, requestedSessionId)
if (ownership.error) {
const message = "reason" in ownership ? ownership.reason : "Not your session";
const status = "reason" in ownership ? 409 : 403;
return c.json("reason" in ownership ? closedSessionResponse(message) : { error: { type: "forbidden", message } }, status);
const message =
'reason' in ownership ? ownership.reason : 'Not your session'
const status = 'reason' in ownership ? 409 : 403
return c.json(
'reason' in ownership
? closedSessionResponse(message)
: { error: { type: 'forbidden', message } },
status,
)
}
const { sessionId } = ownership;
const { sessionId } = ownership
const body = await c.req.json();
const event = publishSessionEvent(sessionId, body.type || "control_request", body, "outbound");
return c.json({ status: "ok", event }, 200);
});
const body = await c.req.json()
const event = publishSessionEvent(
sessionId,
body.type || 'control_request',
body,
'outbound',
)
return c.json({ status: 'ok', event }, 200)
})
/** POST /web/sessions/:id/interrupt — Interrupt session */
app.post("/sessions/:id/interrupt", uuidAuth, async (c) => {
const requestedSessionId = c.req.param("id")!;
const ownership = checkOwnership(c, requestedSessionId);
app.post('/sessions/:id/interrupt', uuidAuth, async c => {
const requestedSessionId = c.req.param('id')!
const ownership = checkOwnership(c, requestedSessionId)
if (ownership.error) {
const message = "reason" in ownership ? ownership.reason : "Not your session";
const status = "reason" in ownership ? 409 : 403;
return c.json("reason" in ownership ? closedSessionResponse(message) : { error: { type: "forbidden", message } }, status);
const message =
'reason' in ownership ? ownership.reason : 'Not your session'
const status = 'reason' in ownership ? 409 : 403
return c.json(
'reason' in ownership
? closedSessionResponse(message)
: { error: { type: 'forbidden', message } },
status,
)
}
const { sessionId } = ownership;
const { sessionId } = ownership
publishSessionEvent(sessionId, "interrupt", { action: "interrupt" }, "outbound");
updateSessionStatus(sessionId, "idle");
return c.json({ status: "ok" }, 200);
});
publishSessionEvent(
sessionId,
'interrupt',
{ action: 'interrupt' },
'outbound',
)
updateSessionStatus(sessionId, 'idle')
return c.json({ status: 'ok' }, 200)
})
export default app;
export default app

View File

@@ -1,14 +1,14 @@
import { Hono } from "hono";
import { uuidAuth } from "../../auth/middleware";
import { listActiveEnvironmentsResponse } from "../../services/environment";
import { Hono } from 'hono'
import { uuidAuth } from '../../auth/middleware'
import { listActiveEnvironmentsResponse } from '../../services/environment'
const app = new Hono();
const app = new Hono()
/** GET /web/environments — List active environments (UUID-based, no user filtering) */
app.get("/environments", uuidAuth, async (c) => {
app.get('/environments', uuidAuth, async c => {
// Environments are shared across all UUIDs for now
const envs = listActiveEnvironmentsResponse();
return c.json(envs, 200);
});
const envs = listActiveEnvironmentsResponse()
return c.json(envs, 200)
})
export default app;
export default app

View File

@@ -1,7 +1,7 @@
import { log, error as logError } from "../../logger";
import { Hono } from "hono";
import { uuidAuth } from "../../auth/middleware";
import { getAutomationStateSnapshot } from "../../services/automationState";
import { log, error as logError } from '../../logger'
import { Hono } from 'hono'
import { uuidAuth } from '../../auth/middleware'
import { getAutomationStateSnapshot } from '../../services/automationState'
import {
createSession,
getSession,
@@ -10,109 +10,137 @@ import {
listWebSessionsByOwnerUuid,
resolveOwnedWebSessionId,
toWebSessionResponse,
} from "../../services/session";
import { storeBindSession, storeGetSessionWorker } from "../../store";
import { createWorkItem } from "../../services/work-dispatch";
import { createSSEStream } from "../../transport/sse-writer";
import { getEventBus } from "../../transport/event-bus";
} from '../../services/session'
import { storeBindSession, storeGetSessionWorker } from '../../store'
import { createWorkItem } from '../../services/work-dispatch'
import { createSSEStream } from '../../transport/sse-writer'
import { getEventBus } from '../../transport/event-bus'
const app = new Hono();
const app = new Hono()
/** POST /web/sessions — Create a session from web UI */
app.post("/sessions", uuidAuth, async (c) => {
const uuid = c.get("uuid")!;
const body = await c.req.json();
app.post('/sessions', uuidAuth, async c => {
const uuid = c.get('uuid')!
const body = await c.req.json()
const session = createSession({
environment_id: body.environment_id || null,
title: body.title || "New Session",
source: "web",
permission_mode: body.permission_mode || "default",
});
title: body.title || 'New Session',
source: 'web',
permission_mode: body.permission_mode || 'default',
})
// Auto-bind to creator's UUID
storeBindSession(session.id, uuid);
storeBindSession(session.id, uuid)
// Dispatch work to environment if specified
if (body.environment_id) {
try {
await createWorkItem(body.environment_id, session.id);
await createWorkItem(body.environment_id, session.id)
} catch (err) {
logError(`[RCS] Failed to create work item: ${(err as Error).message}`);
logError(`[RCS] Failed to create work item: ${(err as Error).message}`)
}
}
return c.json(session, 200);
});
return c.json(session, 200)
})
/** GET /web/sessions — List sessions owned by the requesting UUID */
app.get("/sessions", uuidAuth, async (c) => {
const uuid = c.get("uuid")!;
const sessions = listWebSessionsByOwnerUuid(uuid);
return c.json(sessions, 200);
});
app.get('/sessions', uuidAuth, async c => {
const uuid = c.get('uuid')!
const sessions = listWebSessionsByOwnerUuid(uuid)
return c.json(sessions, 200)
})
/** GET /web/sessions/all — List sessions owned by the requesting UUID (unowned sessions excluded) */
app.get("/sessions/all", uuidAuth, async (c) => {
const uuid = c.get("uuid")!;
const sessions = listWebSessionSummariesByOwnerUuid(uuid);
return c.json(sessions, 200);
});
app.get('/sessions/all', uuidAuth, async c => {
const uuid = c.get('uuid')!
const sessions = listWebSessionSummariesByOwnerUuid(uuid)
return c.json(sessions, 200)
})
/** GET /web/sessions/:id — Session detail */
app.get("/sessions/:id", uuidAuth, async (c) => {
const uuid = c.get("uuid")!;
const sessionId = resolveOwnedWebSessionId(c.req.param("id")!, uuid);
app.get('/sessions/:id', uuidAuth, async c => {
const uuid = c.get('uuid')!
const sessionId = resolveOwnedWebSessionId(c.req.param('id')!, uuid)
if (!sessionId) {
return c.json({ error: { type: "forbidden", message: "Not your session" } }, 403);
return c.json(
{ error: { type: 'forbidden', message: 'Not your session' } },
403,
)
}
const session = getSession(sessionId);
const session = getSession(sessionId)
if (!session) {
return c.json({ error: { type: "not_found", message: "Session not found" } }, 404);
return c.json(
{ error: { type: 'not_found', message: 'Session not found' } },
404,
)
}
const worker = storeGetSessionWorker(sessionId);
const automationState = getAutomationStateSnapshot(worker?.externalMetadata);
const response = toWebSessionResponse(session);
const worker = storeGetSessionWorker(sessionId)
const automationState = getAutomationStateSnapshot(worker?.externalMetadata)
const response = toWebSessionResponse(session)
return c.json(
automationState === undefined ? response : { ...response, automation_state: automationState },
automationState === undefined
? response
: { ...response, automation_state: automationState },
200,
);
});
)
})
/** GET /web/sessions/:id/history — Historical events for session */
app.get("/sessions/:id/history", uuidAuth, async (c) => {
const uuid = c.get("uuid")!;
const sessionId = resolveOwnedWebSessionId(c.req.param("id")!, uuid);
app.get('/sessions/:id/history', uuidAuth, async c => {
const uuid = c.get('uuid')!
const sessionId = resolveOwnedWebSessionId(c.req.param('id')!, uuid)
if (!sessionId) {
return c.json({ error: { type: "forbidden", message: "Not your session" } }, 403);
return c.json(
{ error: { type: 'forbidden', message: 'Not your session' } },
403,
)
}
const session = getSession(sessionId);
const session = getSession(sessionId)
if (!session) {
return c.json({ error: { type: "not_found", message: "Session not found" } }, 404);
return c.json(
{ error: { type: 'not_found', message: 'Session not found' } },
404,
)
}
const bus = getEventBus(sessionId);
const events = bus.getEventsSince(0);
return c.json({ events }, 200);
});
const bus = getEventBus(sessionId)
const events = bus.getEventsSince(0)
return c.json({ events }, 200)
})
/** SSE /web/sessions/:id/events — Real-time event stream */
app.get("/sessions/:id/events", uuidAuth, async (c) => {
const uuid = c.get("uuid")!;
const sessionId = resolveOwnedWebSessionId(c.req.param("id")!, uuid);
app.get('/sessions/:id/events', uuidAuth, async c => {
const uuid = c.get('uuid')!
const sessionId = resolveOwnedWebSessionId(c.req.param('id')!, uuid)
if (!sessionId) {
return c.json({ error: { type: "forbidden", message: "Not your session" } }, 403);
return c.json(
{ error: { type: 'forbidden', message: 'Not your session' } },
403,
)
}
const session = getSession(sessionId);
const session = getSession(sessionId)
if (!session) {
return c.json({ error: { type: "not_found", message: "Session not found" } }, 404);
return c.json(
{ error: { type: 'not_found', message: 'Session not found' } },
404,
)
}
if (isSessionClosedStatus(session.status)) {
return c.json({ error: { type: "session_closed", message: `Session is ${session.status}` } }, 409);
return c.json(
{
error: {
type: 'session_closed',
message: `Session is ${session.status}`,
},
},
409,
)
}
const lastEventId = c.req.header("Last-Event-ID");
const fromSeqNum = lastEventId ? parseInt(lastEventId) : 0;
return createSSEStream(c, sessionId, fromSeqNum);
});
const lastEventId = c.req.header('Last-Event-ID')
const fromSeqNum = lastEventId ? parseInt(lastEventId, 10) : 0
return createSSEStream(c, sessionId, fromSeqNum)
})
export default app;
export default app