-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(kap-server): add workspace add-dir endpoint #3451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| import { | ||
| IBootstrapService, | ||
| IHostFileSystem, | ||
| IWorkspaceInstanceManager, | ||
| IWorkspaceService, | ||
|
|
@@ -7,7 +8,7 @@ import { | |
| type Scope, | ||
| type Workspace, | ||
| } from '@moonshot-ai/agent-core-v2'; | ||
| import { isAbsolute } from 'node:path'; | ||
| import { isAbsolute, join, normalize, resolve } from 'node:path'; | ||
|
|
||
| import { z } from 'zod'; | ||
|
|
||
|
|
@@ -16,6 +17,8 @@ import { requestLog } from '../lib/requestLog'; | |
| import { defineRoute } from '../middleware/defineRoute'; | ||
| import { ErrorCode } from '../protocol/error-codes'; | ||
| import { | ||
| addDirRequestSchema, | ||
| addDirResponseSchema, | ||
| createWorkspaceRequestSchema, | ||
| createWorkspaceResponseSchema, | ||
| deleteWorkspaceResponseSchema, | ||
|
|
@@ -269,6 +272,84 @@ export function registerWorkspacesRoutes(app: WorkspaceRouteHost, core: Scope): | |
| 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 }); | ||
|
Comment on lines
+316
to
+318
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If a concurrent Useful? React with 👍 / 👎. |
||
| 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 }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit adds and publicly documents a user-perceivable REST capability shipped with the CLI, but it contains no
.changesetentry, so the release process will not record the feature in the CLI changelog or version bump. Add a confirmed changeset for@moonshot-ai/kimi-codealongside the endpoint.AGENTS.md reference: AGENTS.md:L85-L85
Useful? React with 👍 / 👎.