Skip to content

feat(kap-server): add GET /api/v1/fs:content endpoint for host files - #2012

Merged
sailist merged 3 commits into
MoonshotAI:mainfrom
sailist:feat/fs-content-endpoint
Jul 21, 2026
Merged

feat(kap-server): add GET /api/v1/fs:content endpoint for host files#2012
sailist merged 3 commits into
MoonshotAI:mainfrom
sailist:feat/fs-content-endpoint

Conversation

@sailist

@sailist sailist commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is explained below.

Problem

Frontends served by kap-server (web UI, inspector, future file pickers) currently have no way to read a file outside a session workspace. The session fs routes (/api/v1/sessions/{id}/fs:*) are strictly confined to the workspace root by design, and the only global fs endpoint (/api/v1/fs:browse) lists directories but cannot return file content. Reading an arbitrary host file is only possible through the debug RPC surface (/api/v1/debug/hostFileSystem/*), which is loopback-only and gated behind --debug-endpoints, so it is not usable by regular clients.

What changed

  • Add GET /api/v1/fs:content?path=<absolute-path> to kap-server, serving any host file as a raw byte stream: best-effort Content-Type (extension-based, with a leading-bytes sample to distinguish text/plain from application/octet-stream for unknown extensions), ETag/If-None-Match (304), and single-range Range requests (206). Responses are streamed, so there is no size cap and browsers can render previews directly. Errors keep the envelope form: relative path 40001, not found 40409, permission denied 40411, directory 40906.
  • All file handling lives in the kap-server transport layer on top of the os IHostFileSystem primitives — deliberately no new "unconfined read" domain Service in agent-core-v2. The endpoint's only access gate is the existing global bearer auth, same as the rest of /api/v1.
  • Extract the file-content metadata helpers (binary detection, line counting, etag, mime/language guessing) from sessionFs into agent-core-v2/_base/utils/fileMeta so both read surfaces classify content identically; extract pickHeader/parseRangeHeader into kap-server lib/httpRange shared by the session download route and the new route.
  • Tests: 10 new route tests covering text/binary/image mime, etag 304, range 206, and each error code; API surface snapshot updated.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

- serve any host file by absolute path as raw content with Content-Type, ETag caching, and single-range support
- extract shared file metadata helpers (binary detection, line counting, etag, mime/language guessing) into agent-core-v2 _base/utils/fileMeta
- extract pickHeader/parseRangeHeader into kap-server lib/httpRange for reuse across download/content routes
@changeset-bot

changeset-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e662260

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 21, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@e662260
npx https://pkg.pr.new/@moonshot-ai/kimi-code@e662260

commit: e662260

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3298e5de0f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

return;
}

if (st.isDirectory) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject non-regular host paths before streaming

When an authenticated client requests a non-regular absolute path such as /dev/zero, a FIFO, or a socket, stat reports neither directory nor file, so this check falls through to sampling/streaming with content-length derived from st.size (often 0). That can hang the request, stream unbounded device data, or send a malformed response; please require st.isFile before reading or return a wire error for non-file nodes.

Useful? React with 👍 / 👎.

@@ -0,0 +1,108 @@
/**

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use the agent-core-v2 header convention

packages/agent-core-v2/AGENTS.md requires package comments to be header-only and to start with <domain> domain (Ln) — .... This new helper's top block starts with a generic description instead, so it violates the documented convention for touched agent-core-v2 files; please rewrite it to the required domain identity header and avoid additional symbol-level comments below.

Useful? React with 👍 / 👎.

sailist added 2 commits July 21, 2026 18:37
Return the reply.send(stream) result through the handler promise instead of
using return-await, matching the session fs download route pattern.
Device nodes, FIFOs, sockets, and zero-size virtual files (/proc, /sys)
would otherwise hang the request or stream unbounded data. Addresses
review feedback; also folds fileMeta symbol comments into the header
block per the agent-core-v2 header-only comment convention.
@sailist
sailist merged commit d67a200 into MoonshotAI:main Jul 21, 2026
14 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant