Download packages/kap-server/src/routes/workspaces.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 12.8 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/kap-server/src/routes/workspaces.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/kap-server/src/routes/workspaces.ts
-
curl -L -o workspaces.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/kap-server/src/routes/workspaces.ts
12.8 kB
| import { | |
| IBootstrapService, | |
| IHostFileSystem, | |
| IWorkspaceInstanceManager, | |
| IWorkspaceService, | |
| IWorkspaceSessions, | |
| IWorkspaceTrust, | |
| type Scope, | |
| type Workspace, | |
| } from '@moonshot-ai/agent-core-v2'; | |
| import { isAbsolute, join, normalize, resolve } from 'node:path'; | |
| import { z } from 'zod'; | |
| import { errEnvelope, okEnvelope } from '../envelope'; | |
| import { requestLog } from '../lib/requestLog'; | |
| import { defineRoute } from '../middleware/defineRoute'; | |
| import { ErrorCode } from '../protocol/error-codes'; | |
| import { | |
| addDirRequestSchema, | |
| addDirResponseSchema, | |
| createWorkspaceRequestSchema, | |
| createWorkspaceResponseSchema, | |
| deleteWorkspaceResponseSchema, | |
| listWorkspacesResponseSchema, | |
| updateWorkspaceRequestSchema, | |
| updateWorkspaceResponseSchema, | |
| workspaceIdParamSchema, | |
| workspaceTrustResponseSchema, | |
| } from '../protocol/rest-workspace'; | |
| import type { Workspace as WorkspaceWire } from '../protocol/workspace'; | |
| interface WorkspaceRouteHost { | |
| get( | |
| path: string, | |
| options: { preHandler: unknown[]; schema?: Record<string, unknown> } | undefined, | |
| handler: ( | |
| req: { id: string }, | |
| reply: { send(payload: unknown): unknown }, | |
| ) => Promise<void> | void, | |
| ): unknown; | |
| post( | |
| path: string, | |
| options: { preHandler: unknown[]; schema?: Record<string, unknown> }, | |
| handler: ( | |
| req: { id: string; body: unknown; params: unknown }, | |
| reply: { send(payload: unknown): unknown }, | |
| ) => Promise<void> | void, | |
| ): unknown; | |
| patch( | |
| path: string, | |
| options: { preHandler: unknown[]; schema?: Record<string, unknown> }, | |
| handler: ( | |
| req: { id: string; body: unknown; params: unknown }, | |
| reply: { send(payload: unknown): unknown }, | |
| ) => Promise<void> | void, | |
| ): unknown; | |
| delete( | |
| path: string, | |
| options: { preHandler: unknown[]; schema?: Record<string, unknown> } | undefined, | |
| handler: ( | |
| req: { id: string; params: unknown }, | |
| reply: { send(payload: unknown): unknown }, | |
| ) => Promise<void> | void, | |
| ): unknown; | |
| } | |
| const detailsSchema = z.array(z.object({ path: z.string(), message: z.string() })); | |
| export function registerWorkspacesRoutes(app: WorkspaceRouteHost, core: Scope): void { | |
| const listRoute = defineRoute( | |
| { | |
| method: 'GET', | |
| path: '/workspaces', | |
| success: { data: listWorkspacesResponseSchema }, | |
| description: 'List registered workspaces', | |
| tags: ['workspaces'], | |
| }, | |
| async (req, reply) => { | |
| const items = await core.accessor.get(IWorkspaceService).list(); | |
| const projected = await Promise.all(items.map((ws) => toWireWorkspace(core, ws))); | |
| reply.send(okEnvelope({ items: projected }, req.id)); | |
| }, | |
| ); | |
| app.get(listRoute.path, listRoute.options, listRoute.handler as Parameters<WorkspaceRouteHost['get']>[2]); | |
| const createRoute = defineRoute( | |
| { | |
| method: 'POST', | |
| path: '/workspaces', | |
| body: createWorkspaceRequestSchema, | |
| success: { data: createWorkspaceResponseSchema }, | |
| errors: { | |
| [ErrorCode.VALIDATION_FAILED]: { detailsSchema }, | |
| [ErrorCode.FS_PATH_NOT_FOUND]: {}, | |
| }, | |
| description: 'Register a workspace (idempotent on root)', | |
| tags: ['workspaces'], | |
| }, | |
| async (req, reply) => { | |
| const root = req.body.root; | |
| if (!isAbsolute(root)) { | |
| reply.send( | |
| buildValidationEnvelope( | |
| [{ path: 'root', message: 'root must be an absolute path' }], | |
| req.id, | |
| ), | |
| ); | |
| return; | |
| } | |
| const hostFs = core.accessor.get(IHostFileSystem); | |
| try { | |
| const stat = await hostFs.stat(root); | |
| if (!stat.isDirectory) { | |
| reply.send( | |
| errEnvelope(ErrorCode.FS_PATH_NOT_FOUND, `root ${root} is not a directory`, req.id), | |
| ); | |
| return; | |
| } | |
| } catch { | |
| reply.send(errEnvelope(ErrorCode.FS_PATH_NOT_FOUND, `root ${root} does not exist`, req.id)); | |
| return; | |
| } | |
| const ws = await core.accessor.get(IWorkspaceService).createOrTouch(root, req.body.name); | |
| reply.send(okEnvelope(await toWireWorkspace(core, ws), req.id)); | |
| }, | |
| ); | |
| app.post( | |
| createRoute.path, | |
| createRoute.options, | |
| createRoute.handler as Parameters<WorkspaceRouteHost['post']>[2], | |
| ); | |
| const updateRoute = defineRoute( | |
| { | |
| method: 'PATCH', | |
| path: '/workspaces/{workspace_id}', | |
| params: workspaceIdParamSchema, | |
| body: updateWorkspaceRequestSchema, | |
| success: { data: updateWorkspaceResponseSchema }, | |
| errors: { | |
| [ErrorCode.VALIDATION_FAILED]: { detailsSchema }, | |
| [ErrorCode.WORKSPACE_NOT_FOUND]: {}, | |
| }, | |
| description: 'Rename a workspace (display name only)', | |
| tags: ['workspaces'], | |
| }, | |
| async (req, reply) => { | |
| const { workspace_id } = req.params; | |
| const ws = await core.accessor | |
| .get(IWorkspaceService) | |
| .update(workspace_id, { name: req.body.name }); | |
| if (ws === undefined) { | |
| reply.send( | |
| errEnvelope(ErrorCode.WORKSPACE_NOT_FOUND, `workspace ${workspace_id} does not exist`, req.id), | |
| ); | |
| return; | |
| } | |
| reply.send(okEnvelope(await toWireWorkspace(core, ws), req.id)); | |
| }, | |
| ); | |
| app.patch( | |
| updateRoute.path, | |
| updateRoute.options, | |
| updateRoute.handler as Parameters<WorkspaceRouteHost['patch']>[2], | |
| ); | |
| const deleteRoute = defineRoute( | |
| { | |
| method: 'DELETE', | |
| path: '/workspaces/{workspace_id}', | |
| params: workspaceIdParamSchema, | |
| success: { data: deleteWorkspaceResponseSchema }, | |
| errors: { | |
| [ErrorCode.VALIDATION_FAILED]: { detailsSchema }, | |
| [ErrorCode.WORKSPACE_NOT_FOUND]: {}, | |
| }, | |
| description: 'Unregister a workspace (does not remove on-disk content)', | |
| tags: ['workspaces'], | |
| }, | |
| async (req, reply) => { | |
| const { workspace_id } = req.params; | |
| const registry = core.accessor.get(IWorkspaceService); | |
| const existing = await registry.get(workspace_id); | |
| if (existing === undefined) { | |
| reply.send( | |
| errEnvelope(ErrorCode.WORKSPACE_NOT_FOUND, `workspace ${workspace_id} does not exist`, req.id), | |
| ); | |
| return; | |
| } | |
| await registry.delete(workspace_id); | |
| requestLog(req)?.info({ workspace_id }, 'workspace deleted'); | |
| reply.send(okEnvelope({ deleted: true as const }, req.id)); | |
| }, | |
| ); | |
| app.delete( | |
| deleteRoute.path, | |
| deleteRoute.options, | |
| deleteRoute.handler as Parameters<WorkspaceRouteHost['delete']>[2], | |
| ); | |
| const getTrustRoute = defineRoute( | |
| { | |
| method: 'GET', | |
| path: '/workspaces/{workspace_id}/trust', | |
| params: workspaceIdParamSchema, | |
| success: { data: workspaceTrustResponseSchema }, | |
| errors: { | |
| [ErrorCode.WORKSPACE_NOT_FOUND]: {}, | |
| }, | |
| description: 'Read the workspace trust state', | |
| tags: ['workspaces'], | |
| }, | |
| async (req, reply) => { | |
| const trust = await resolveTrust(core, req.params.workspace_id, req.id, reply); | |
| if (trust === undefined) return; | |
| reply.send(okEnvelope({ trusted: await trust.get() }, req.id)); | |
| }, | |
| ); | |
| app.get( | |
| getTrustRoute.path, | |
| getTrustRoute.options, | |
| getTrustRoute.handler as Parameters<WorkspaceRouteHost['get']>[2], | |
| ); | |
| const trustRoute = defineRoute( | |
| { | |
| method: 'POST', | |
| path: '/workspaces/{workspace_id}/trust', | |
| params: workspaceIdParamSchema, | |
| success: { data: workspaceTrustResponseSchema }, | |
| errors: { | |
| [ErrorCode.WORKSPACE_NOT_FOUND]: {}, | |
| }, | |
| description: 'Mark the workspace trusted (project-level MCP config loads)', | |
| tags: ['workspaces'], | |
| }, | |
| async (req, reply) => { | |
| const trust = await resolveTrust(core, req.params.workspace_id, req.id, reply); | |
| if (trust === undefined) return; | |
| await trust.trust(); | |
| reply.send(okEnvelope({ trusted: true }, req.id)); | |
| }, | |
| ); | |
| app.post( | |
| trustRoute.path, | |
| trustRoute.options, | |
| trustRoute.handler as Parameters<WorkspaceRouteHost['post']>[2], | |
| ); | |
| const untrustRoute = defineRoute( | |
| { | |
| method: 'POST', | |
| path: '/workspaces/{workspace_id}/untrust', | |
| params: workspaceIdParamSchema, | |
| success: { data: workspaceTrustResponseSchema }, | |
| errors: { | |
| [ErrorCode.WORKSPACE_NOT_FOUND]: {}, | |
| }, | |
| description: 'Revoke workspace trust (project-level MCP config unloads)', | |
| tags: ['workspaces'], | |
| }, | |
| async (req, reply) => { | |
| const trust = await resolveTrust(core, req.params.workspace_id, req.id, reply); | |
| if (trust === undefined) return; | |
| await trust.untrust(); | |
| reply.send(okEnvelope({ trusted: false }, req.id)); | |
| }, | |
| ); | |
| app.post( | |
| untrustRoute.path, | |
| untrustRoute.options, | |
| untrustRoute.handler as Parameters<WorkspaceRouteHost['post']>[2], | |
| ); | |
| const addDirRoute = defineRoute( | |
| { | |
| method: 'POST', | |
| path: '/workspaces/{workspace_id}/add-dir', | |
| params: workspaceIdParamSchema, | |
| body: addDirRequestSchema, | |
| success: { data: addDirResponseSchema }, | |
| errors: { | |
| [ErrorCode.VALIDATION_FAILED]: { detailsSchema }, | |
| [ErrorCode.FS_PATH_NOT_FOUND]: {}, | |
| [ErrorCode.WORKSPACE_NOT_FOUND]: {}, | |
| }, | |
| description: 'Add an additional directory to the workspace', | |
| tags: ['workspaces'], | |
| }, | |
| async (req, reply) => { | |
| const { workspace_id } = req.params; | |
| const ws = await core.accessor.get(IWorkspaceService).get(workspace_id); | |
| if (ws === undefined) { | |
| reply.send( | |
| errEnvelope(ErrorCode.WORKSPACE_NOT_FOUND, `workspace ${workspace_id} does not exist`, req.id), | |
| ); | |
| return; | |
| } | |
| const resolved = resolveAdditionalDirPath(core, ws.root, req.body.path); | |
| const hostFs = core.accessor.get(IHostFileSystem); | |
| try { | |
| const stat = await hostFs.stat(resolved); | |
| if (!stat.isDirectory) { | |
| reply.send( | |
| errEnvelope(ErrorCode.FS_PATH_NOT_FOUND, `path ${req.body.path} is not a directory`, req.id), | |
| ); | |
| return; | |
| } | |
| } catch { | |
| reply.send( | |
| errEnvelope(ErrorCode.FS_PATH_NOT_FOUND, `path ${req.body.path} does not exist`, req.id), | |
| ); | |
| return; | |
| } | |
| const workspace = await core | |
| .accessor.get(IWorkspaceInstanceManager) | |
| .getOrCreate({ workspaceId: workspace_id, root: ws.root }); | |
| const result = await workspace.program.dirs.addDir({ | |
| path: req.body.path, | |
| persist: req.body.persist, | |
| }); | |
| reply.send( | |
| okEnvelope( | |
| { | |
| project_root: result.projectRoot, | |
| config_path: result.configPath, | |
| additional_dirs: [...result.additionalDirs], | |
| persisted: result.persisted, | |
| }, | |
| req.id, | |
| ), | |
| ); | |
| }, | |
| ); | |
| app.post( | |
| addDirRoute.path, | |
| addDirRoute.options, | |
| addDirRoute.handler as Parameters<WorkspaceRouteHost['post']>[2], | |
| ); | |
| } | |
| function resolveAdditionalDirPath(core: Scope, root: string, input: string): string { | |
| const trimmed = input.trim(); | |
| const osHomeDir = core.accessor.get(IBootstrapService).osHomeDir; | |
| const expanded = | |
| trimmed === '~' | |
| ? osHomeDir | |
| : trimmed.startsWith('~/') | |
| ? join(osHomeDir, trimmed.slice(2)) | |
| : trimmed; | |
| return isAbsolute(expanded) ? normalize(expanded) : resolve(root, expanded); | |
| } | |
| type TrustReply = { send(payload: unknown): unknown }; | |
| async function resolveTrust( | |
| core: Scope, | |
| workspaceId: string, | |
| requestId: string, | |
| reply: TrustReply, | |
| ): Promise<IWorkspaceTrust | undefined> { | |
| const ws = await core.accessor.get(IWorkspaceService).get(workspaceId); | |
| if (ws === undefined) { | |
| reply.send( | |
| errEnvelope(ErrorCode.WORKSPACE_NOT_FOUND, `workspace ${workspaceId} does not exist`, requestId), | |
| ); | |
| return undefined; | |
| } | |
| const workspace = await core | |
| .accessor.get(IWorkspaceInstanceManager) | |
| .getOrCreate({ workspaceId, root: ws.root }); | |
| return workspace.program.trust; | |
| } | |
| export async function toWireWorkspace(core: Scope, ws: Workspace): Promise<WorkspaceWire> { | |
| const sessionCount = await core.accessor.get(IWorkspaceSessions).count(ws.id); | |
| return { | |
| id: ws.id, | |
| root: ws.root, | |
| name: ws.name, | |
| created_at: new Date(ws.createdAt).toISOString(), | |
| last_opened_at: new Date(ws.lastOpenedAt).toISOString(), | |
| session_count: sessionCount, | |
| }; | |
| } | |
| function buildValidationEnvelope( | |
| details: { path: string; message: string }[], | |
| requestId: string, | |
| ): { | |
| code: number; | |
| msg: string; | |
| data: null; | |
| request_id: string; | |
| details: { path: string; message: string }[]; | |
| } { | |
| const first = details[0]; | |
| const msg = first === undefined ? 'validation failed' : `${first.path}: ${first.message}`; | |
| return { | |
| code: ErrorCode.VALIDATION_FAILED, | |
| msg, | |
| data: null, | |
| request_id: requestId, | |
| details, | |
| }; | |
| } | |