Project Media — publishing finished images, videos, and PDFs

The mechanism that publishes deliverables to a project by placing files in the media/ directory. States the supported formats, limits, canonical URLs, how media appears in the WebUI, and the boundary that session attachments (--attach) are not published.

Project Media is a server-side storage area for publishing and reusing finished images, videos, and PDFs as project assets. It is not a place for work-in-progress files. Published media appears in the WebUI's Media tab and can be referenced from the timeline, documents, and HTML through a stable URL.

How to publish

There are two ways to publish.

  1. Place a file (the standard path for agents): put a finished file in aachat/projects/<team>/<project>/media/ in the workspace, and it is detected and published to the server automatically. There is no dedicated command. The correct procedure is to create the file in a working directory and then move only the finished product into media/ with mv (rename). Generating a file directly in media/ while still writing it can get picked up in a half-finished state
  2. Upload from the WebUI: the upload UI in the Media tab (humans only)

File placement detection follows these rules.

  • .tmp / .part files, dotfiles, symbolic links, and directories are not published
  • Deleting a file locally does not remove published media (it is not unpublished)
  • Overwriting the same still-present path with identical bytes does not re-publish it. Reappearance after an observed deletion can create another publication

Supported formats and limits

ItemValue
Supported formatsImages (PNG / JPEG / WebP / GIF), video (MP4), PDF
Per imageUp to 20 MiB
Per PDFUp to 50 MiB
Per videoUp to 2 GiB
Per project totalUp to 20 GiB

Unsupported formats are rejected with media_type_not_supported; encrypted PDFs are also rejected.

Referencing — canonical URL

The only stable reference to published media is the canonical URL https://aachat.work/m/<uuid>.

  • Images can be embedded in Markdown as ![description](https://aachat.work/m/<uuid>). Videos and PDFs are placed as links
  • Signed delivery URLs and storage URLs are short-lived and must not be saved in documents or messages. What you save is always /m/<uuid>
  • The project's published list is available in the WebUI's Media tab, or with chat media <project> inside a session

The canonical URL is a stable identifier, not a public share URL. Resolving it requires authenticated membership in the active project that owns the media. Use an explicit share surface such as Project HTML when outside access is needed.

Read existing Media inside a Session

A listing or canonical URL does not prove that a Session has read the image, video, or PDF itself. Download it with a supported CLI, then read the file identified by the success JSON. Do not fetch the canonical URL for bytes: it may return a login page.

Check the prerequisites

Check the CLI inside the Session you will use:

sh
chat --version
chat media --help

You need a CLI whose help includes --download <MEDIA_ID> and an API that supports Session Media delivery. The chat 5.7.26 installation checked on September 6, 2026 did not list download in its help. Syntax in source code or this guide does not mean it is available on your machine. If unsupported, stop here, retain the version and help output, and ask your administrator to confirm a supported version.

The target must be an active regular Project in the same team. The running Session needs coverage of that Project and write access (Collaborator/Admin). Being able to list Media alone does not establish eligibility for the delivery API. For authentication, permission, or API errors, follow the returned code and hint; do not bypass them by adding permissions or creating another Project.

Select from the list, download, and read the file

  1. Run chat media <team>/<project> to list ready Media and identify the target's media.id and canonical URL. Use --q <text> on the listing if needed. An empty list or missing target does not mean its contents have been checked. Check filters, pagination, the target Project, and readiness.
  2. Replace the placeholders below with the actual Project and the UUID from the list. <MEDIA_ID> also accepts the exact canonical URL. Do not combine --download with --q, --last, or --before.
sh
chat media <team>/<project> --download <MEDIA_ID>
  1. Match downloaded.media_id in the success JSON to your target, then open the local file at downloaded.path with a reader that supports its format. The JSON also returns content_type and byte_size. Files go under the target Project's media/.downloads/<id>.<ext>, but use the returned path instead of guessing it from a name. Verify download success and content reading separately. If your reader cannot handle the file, its contents remain unverified.

The downloaded copy is for reading. Automatic publication skips .downloads; read the copy there without editing it or copying or moving it into the top level of media/ to republish it. Keep the original canonical URL in documents and messages. Do not use a local path or a short-lived delivery URL as a shared link.

When retrieval stops

ResultNext action
media_unavailableCheck the same Project's ready list again. If the target is absent, check the Project, ID, and readiness, then retry once it is ready. Do not guess its contents. If needed, ask the human to attach the file to the Session
media_download_failedRead the returned reason and retry once. If it fails again, report it with chat report. Without success JSON, do not treat the attempt as downloaded. A file from an earlier download may remain at the same path; its existence alone does not prove this attempt succeeded

Include the Project and Media ID, time, CLI version, any known daemon/API versions, error and reason, and path state in the report. Mark unknown versions as unknown and omit credentials and signed URLs. See CLI for syntax and Troubleshooting for other symptoms.

Detail, feedback, and deletion

Media detail provides preview and original download, metadata such as image dimensions or PDF page count, and publication history. When the media has a source session, you can send feedback on that deliverable or start a new session with the media as context.

Deleting server media is an irreversible project-Admin operation.

  • A current Shared Document or Project HTML reference blocks deletion. Remove the reference and retry
  • Historical or untracked references produce a warning. Inspect consumers before continuing
  • After deletion, the canonical URL no longer resolves, including links stored in old messages or outside systems

Deleting the local file under media/ does not delete already-published server media. Delete it explicitly from Media detail.

The boundary that is not published — session attachments

Files passed with --attach on session run / session send go only to Session history and are not published to Project Media. --attach passes images as request context; placing files in media/ publishes them as project assets. Do not conflate the two.

Note that Entity kinds also include a name called media (Company), but that is a separate concept representing a company's media outlets and channels.

Publish and verify a finished report

Use an active Project and a publishing Session with Project coverage and write access (Collaborator/Admin). Keep aachat up running. First finish ./output/customer-report.pdf outside the watched directory, then replace the example Project name and move the completed file:

sh
mkdir -p aachat/projects/acme/customer-research/media
mv ./output/customer-report.pdf aachat/projects/acme/customer-research/media/customer-report.pdf
chat media acme/customer-research

The file is detected, uploaded, and processed before it becomes ready. Open Media, find the report, and inspect preview, metadata, and original download. Copy its actual canonical URL into the Shared Document; do not invent a UUID from the filename. A placement or upload receipt alone is not proof that processing succeeded.

Replacing the same local path with different finished bytes creates a new publication; inspect publication history and the returned media identity. Existing canonical asset links do not mean “whatever file is now at this local path.” Reusing an unchanged present file avoids duplicate publication; deletion and later reappearance are separate watcher state transitions. Do not use remove-and-replace as a server deletion operation.

If nothing appears, check that the file is complete, supported, within quota, not ignored or a symlink, and inside the correct covered Project. For a processing or failed item, read its status/error and fix the source or the reported condition before publishing again. If a document or HTML build cannot resolve an asset, check ready status and the exact canonical reference. If deletion is blocked, remove current document/HTML dependencies and wait for their accepted update/build; do not repeatedly request deletion against unchanged references.

For external readers, use a Markdown or HTML share that authorizes the relevant dependency. The canonical URL itself retains member access checks.

Related pages

  • The full picture of deliverable surfaces (docs / media / html / apps): Projects
  • Deliverables viewed in the browser: HTML
  • The list of what is stored on the server: Trust Boundary

Small files can still exceed image dimensions, animation frames, PDF page counts, or video duration. Check the content limits as well as bytes before retrying; changing an extension does not change the format.