Write Workflows & Dry-runs
Relevant source files
The following files were used as context for generating this wiki page:
Write workflows in the putio-cli represent operations that mutate state on the put.io platform, such as creating directories, renaming files, moving resources, or deleting content. To ensure safety and predictability, especially for automated agents, the CLI implements a robust validation layer and a "Dry-run" capability. Dry-runs allow users to preview the exact request payload and command intent without executing a network call to the API.
Sources: src/internal/agent-dx.ts:40-45, src/internal/command.ts:479-491
Mutation Architecture
Mutating commands (categorized as kind: "write") follow a structured execution path that includes input resolution, hardening/validation, and conditional execution based on the presence of the --dry-run flag. The system prioritizes machine-readability and safety, offering both standard CLI flags and raw JSON input for complex operations.
Sources: src/internal/metadata.test.ts:98-110, src/internal/agent-dx.ts:54-65
Input Resolution Flow
The CLI supports two primary ways to provide data for write operations:
- Standard Flags: Individual command-line arguments (e.g.,
--id,--name). - Raw JSON Payload: A structured JSON string provided via the
--jsonflag, which bypasses flag-based parsing in favor of direct schema decoding.
The following diagram illustrates how the CLI resolves these inputs before proceeding to execution or dry-run reporting.
Dry-run Execution
The dry-run mechanism is a safety rail that prevents accidental mutations. When the --dry-run flag is active, the CLI generates a "Dry-run Plan" instead of invoking the SDK. This plan includes the command name, a confirmation that no API call was made, and the final resolved request object that would have been sent.
Components of a Dry-run Plan
| Field | Type | Description |
|---|---|---|
command | string | The full name of the command being simulated. |
dryRun | boolean | Constant true identifying the output as a simulation. |
request | object | The fully resolved and validated payload intended for the API. |
Sources: src/internal/command.ts:748-765
export const writeDryRunPlan = <A>(command: string, request: A, output: RequestedOutputMode) =>
writeOutput(
{
command,
dryRun: true as const,
request,
},
output,
renderDryRunPlanTerminal,
);
Sources: src/internal/command.ts:758-765
Input Hardening and Safety
To prevent malicious or accidental command injection (particularly from untrusted API text used as input for follow-up commands), the CLI implements strict validation rules for write workflows.
Validation Rules
- Control Characters: Inputs like file names or resource identifiers are rejected if they contain control characters (ASCII <= 0x1f or 0x7f).
- Path Traversal: Commands involving file names (e.g.,
mkdir,rename) explicitly reject segments like../or%2eto prevent directory traversal. - Query/Fragment Protection: Identifiers are checked for
?or#to ensure they do not unintentionally alter API request structures. - Non-Blank Strings: Mutating inputs like folder names must contain at least one non-whitespace character.
Sources: src/internal/command.ts:160-200, src/commands/files.ts:76-81, src/cli.test.ts:327-353
Mutating Command Examples
| Command | Primary Input(s) | Hardening Rules |
|---|---|---|
files mkdir | --name, --parent-id | No traversal, no control chars, non-blank name. |
files rename | --id, --name | No traversal, no control chars, non-blank name. |
files move | --id (repeated), --parent-id | IDs must be integers. |
files delete | --id (repeated), --skip-trash | Non-empty ID list required. |
Sources: src/commands/files.ts:425-500, src/internal/command.ts:210-220
Summary
Write workflows in putio-cli are designed with a "safety-first" philosophy. By utilizing the resolveMutationInput helper, the CLI ensures that whether a user provides flags or a raw --json payload, the data is decoded against an Effect Schema and subjected to standard hardening rules. The integration of --dry-run across all mutating commands provides a deterministic way for both humans and agents to verify automation logic before committing changes to the put.io cloud environment.
Sources: src/internal/agent-dx.ts:98-105, src/internal/command.ts:420-435