Transfer and export Files
Stream bytes, build an inventory and export retained work.
Stream bytes through the SDK
For a seekable source, prepareFileUploadFromSource computes the immutable request
with bounded reads. Persist that request, then call uploadFileFromSource with the
same bytes. Every reread part is checked before dispatch. Reopening a source does
not allow changing the saved operation, content or deadline. The caller closes its
source on success, failure or cancellation. CLI files put uses bounded reads too.
Before uploading parts, the SDK now inspects the existing operation and sends
only absent parts. A lost response after an accepted part therefore does not
require sending that part again. It still checks the entire local source against
the frozen request, and the API verifies the completed object before publication.
Use files finalize UPLOAD_ID when all bytes are already uploaded and you no
longer have the source. Admission replay preserves the original expiry and returns
an expired result once that deadline passes.
For explicit inspection, use agent-workplace files parts UPLOAD_ID --json, SDK
getFileUploadedParts(auth, { workplaceId, uploadId }), or authenticated
GET /v1/files/uploads/{uploadId}/parts?workplaceId=WORKPLACE_ID. The response
contains upload (the current operation status) and presentPartNumbers.
For an open upload, this is a complete list of present manifest positions, at most
239; [] means none are present. null means inspection does not apply to the
current state, such as creation, completion or a terminal result. Inspect upload
to decide whether to wait, finalize, or handle its terminal outcome.
This is presence and size evidence, not checksum verification. Part numbers do not
prove content integrity, and the response never includes provider identifiers,
ETags or grants. Current authority is checked before and after storage inspection.
Incomplete, duplicate, malformed or unavailable listings fail; clients must not
interpret an error or null as an empty list and retransmit. Grants and finalization
remain separate authorized operations. This observation is not a lock against
another process or an already-issued write grant; serialize retries of one operation.
downloadFileTo writes to an asynchronous sink with backpressure and returns file
metadata only after full SHA-256 verification. It pins the revision and renews
short-lived grants for bounded Range reads, rechecking current access. It never
switches to a newer revision when pinned content expires or becomes unavailable.
To retain progress, save the revision reference, byte length and SHA-256 before
starting. Supply resume with those values and the durable offset, and give the
sink a read(offset, length) function for its existing prefix. The SDK rehashes
that prefix; a saved digest or offset alone does not prove integrity. A sink's
checkpoint(offset) must flush bytes durably before saving that offset. Keep all
partial output untrusted and unpublished until the download succeeds. The sink
owner closes resources and handles interrupted writes and local file ownership.
The bounded source/sink methods support decimal 2 GB (2,000,000,000 bytes).
uploadFile and downloadFile remain whole-buffer methods capped at 64 MiB.
The latter rejects larger declared content before fetching object bytes.
Build an inventory with the SDK
Use walkFilesTree for the active current contents of a folder. Omit parentId
for the workplace root. Each file event includes pinned revision metadata:
for await (const item of client.walkFilesTree(auth, {
workplaceId,
parentId,
})) {
if (item.kind === "file") {
// Select a safe destination yourself; item.path contains untrusted names.
console.log(item.path, item.file.revisionReference);
}
}
Use walkRetainedFiles for all retained workplace work, including previous
revisions and trash. Entry events preserve folder relationships, names and trash
metadata; revision events include expiry and restoration metadata:
for await (const item of client.walkRetainedFiles(auth, { workplaceId })) {
if (item.kind === "revision") {
console.log(item.file.revisionReference, item.file.isCurrent);
}
}
Both methods stream metadata through ordinary authorized API reads. They do not
fetch bytes or grant access to content that has expired or been purged. Use
downloadFileTo with each pinned revision to copy its bytes. Retention and
permissions can still change before that read.
An inventory is not a snapshot. The start event carries a change checkpoint.
An issue event reports content that disappeared or a tree entry encountered
again during concurrent moves. A file event's changedSinceListing flag reports
a version change between listing and metadata resolution. The final complete
event means enumeration ended, not that every file was downloaded: inspect its
issue count. workplaceChanges reports observed, none_observed, or unknown
for the enumeration interval. unknown means change-history coverage is
incomplete. Changes may concern other folders. Authorization and transport errors
stop iteration and propagate to the caller. If copying bytes afterward, check
changes again from the start checkpoint to cover that additional interval.
Names and path segments are untrusted. A filesystem consumer must handle unsafe names, case collisions, symbolic links and existing destinations without silently overwriting local work. These methods do not provide archive restoration or extend any retention period.
The tree walker retains one page per traversal depth and a visited-ID index.
By default that index grows with the number of entries. Large consumers can pass
{ visits } as the third argument, implementing FilesTreeVisitStore.addIfNew(id)
with a fresh store for each traversal. Return true exactly once per ID and
propagate storage failures. The CLI uses a disk-backed index. Retained inventory
uses ordered pages without a global visited-ID index.
Download a folder or export retained work
Use the default saved CLI credential. Create a private directory for the operation records before either command:
mkdir -p private-files
chmod 700 private-files
Download the active current contents beneath a folder, or use root for all
active current Files:
agent-workplace files get-folder root \
--output ./current-files --operation private-files/current-export.json --json
Export all retained workplace Files, including previous revisions and trash:
agent-workplace files export \
--output ./retained-files --operation private-files/retained-export.json --json
Both commands require a new destination directory whose parent exists and a
private operation path outside that destination. Recovery currently requires a
POSIX filesystem. Keep the operation file and its adjacent private .awp-export-*
directory until you finish recovery. These contain the inventory, directory and
per-file receipts; their disk usage grows with the exported metadata and attempts.
They contain no saved API keys or temporary grants.
Folder downloads use the observed names and create empty folders. Retained
exports store bytes under files/FILE_UUID/REVISION_UUID; manifest.ndjson
preserves names, parent relationships, empty-folder metadata, trash, revision
expiry and restoration metadata. Folder-download manifests live in the private
operation directory to avoid colliding with remote names. The result reports
both manifest and inventory paths. This is a Files export, not a Mail export or
an archive-import/restore interface.
The CLI finishes and saves its inventory before copying content, then downloads pinned revisions with byte-length and SHA-256 verification. It streams file bytes and inventory records, rather than loading all content or entries into memory. Unsafe names, local collisions, missing content and authorization failures are reported instead of silently overwriting or skipping work. Retention still applies: export does not reserve content or extend its lifetime.
Repeat the exact command to resume its saved inventory and interrupted file checkpoints. Completed files are verified again using current authorization. A frozen inventory is not refreshed on retry: choose a new operation and new destination to discover later changes or resolve inventory omissions. Unknown files, replaced directories and unrecorded ownership after a crash are preserved; when safe recovery cannot be established, the command refuses to overwrite them.
The result is explicitly non_snapshot. workplaceChanges covers inventory and
content copying, and can reflect changes outside a selected folder. observed
means changes occurred; none_observed is not a snapshot guarantee. An expired
change window reports unknown and a partial result. Concurrent changes can
leave an export that completed its recorded inventory without representing one
instant in time.
With --json, stdout contains the result, including plannedFiles, copied,
failed, unattempted, stopped, and manifest paths. failed counts issues,
including folder failures, not just failed payloads. A partial result also exits
nonzero and emits a safe diagnostic on stderr. On lost authority the CLI stops
further downloads and reports unattempted content. Each manifest attempt contains
observed inventory records, successful downloads, failures and a final result if
that attempt reaches completion; a killed attempt may have no final result.
Inspect the latest result and its manifest before treating an export as complete.