docs/design/session-artifacts-directory-expansion.md
Models often register a generated folder as one workspace artifact
(kind: file, workspacePath pointing at the directory). Clients then
open or download it through GET /file or GET /file/bytes, which
require a regular file and return HTTP 400.
Office outputs (Word / Excel / PowerPoint) were also second-class: they were not treated as artifact-like files, and the preview path tried to read them as text.
Directories are never artifacts. If a registration points at a directory, the store expands it to one artifact per recordable file inside that directory. The original directory path is not stored.
Office documents are first-class file artifacts (kind: document) and
are opened as downloadable binaries, not text previews.
The chat turn-output list shows at most 3 artifact cards, with the same expand/collapse control already used for edited files.
record_artifact, hooks, client POST) behaves the same.~$*),
symlinks, and well-known junk directories. Cap is 100 files and 4
directory levels; either limit is disclosed to the model and store
warnings instead of silently dropping files.record_artifact call (or artifacts with no
tool call id). Later files written under the same folder stay on their
own turn.available.kind: document. The client shows a type label and a download action
instead of a CodeMirror text preview.write_file / shell output without
record_artifact.Upstream analysis (QwenLM/qwen-code@main) confirmed the original
decision. Keep store-side expansion, kind: document, and the 3-card
collapse. Fine-tune the landing, do not change the product rule.
#9142 (fix/artifact-workspace-path-contract) stats the locator in
record_artifact and rejects directories (TARGET_IS_DIRECTORY).
That stops the 400, but it is not this issue: the user still does not
get one card per generated file.
Keep #9142's path canonicalization (workspace-root-relative
workspacePath, worktree prefix, no invented w/agent/ prefixes).
Replace its directory rejection with expansion:
Recorded artifact
for the folder itself..xlsx in #9142's write_file whitelist must be document, not
file. .csv stays file (text-previewable).
Upstream Web Shell already has Download (canDownloadArtifact,
readWorkspaceFileAsBlob) and GET /stat. Reuse those. Do not add a
second download stack.
kind: document and other non-text kinds (pdf, image, video,
audio) never fall through to the 'source' / CodeMirror preview.GET /stat returns type: directory (legacy dirty records),
disable Open and do not call /file or /file/bytes.document to ARTIFACT_FORMAT_ICONS and kind labels.On current main the whitelist is ARTIFACT_KIND_BY_EXTENSION, not a
plain extension set. Office/OpenDocument entries belong there as
document. Do not call record_artifact again for a path
write_file already recorded.