Configuration & Environment
Relevant source files
The following files were used as context for generating this wiki page:
The putio-cli configuration system is designed for deterministic automation and flexible user management. It employs an "Agent-first" philosophy, prioritizing stable machine-readable contracts and environmental overrides while maintaining a convenient multi-profile system for human operators. The system is built using the Effect library, leveraging its Config and Layer modules to provide a robust, type-safe configuration layer.
The configuration architecture is split into two primary domains: Runtime Configuration, which handles environment-level overrides and service endpoints, and Persisted State, which manages local file storage, authentication tokens, and named user profiles.
Runtime Configuration
Runtime configuration is resolved dynamically at the start of a command execution. It aggregates settings from environment variables and system paths to establish the operating context for the CLI.
Configuration Resolution Logic
The CliConfig service manages the resolution of runtime settings. It identifies the API base URL, the location of the configuration file, and any active profile or token overrides.
The diagram shows the hierarchical resolution of configuration settings from environment variables to local files. Sources: src/internal/config.ts:88-115, src/internal/state.ts:474-490
Config Path Hierarchy
The CLI determines the path to its config.json file based on the following precedence:
- Explicit Path: Defined via the
PUTIO_CLI_CONFIG_PATHenvironment variable. - XDG Home: Defined via
XDG_CONFIG_HOME/putio/config.json. - Default Home: Defaults to
~/.config/putio/config.json.
Sources: src/internal/config.ts:46-56, src/internal/state.test.ts:46-68
Persisted State & Profiles
The CLI maintains a JSON file to persist state across sessions. This file contains authentication tokens and profile-specific settings.
Configuration Schema
The persisted configuration follows a strict schema defined via Schema.Struct. It supports a legacy single-token setup and a modern multi-profile system.
| Field | Type | Description |
|---|---|---|
api_base_url | string | The default API endpoint (usually https://api.put.io). |
auth_token | string (Optional) | Legacy global authentication token. |
default_profile | string (Optional) | The name of the profile to use if none is specified. |
profiles | Record<string, Profile> | A dictionary of named configurations. |
Sources: src/internal/state.ts:18-28
Profile Structure
Each profile within the profiles record can override the global API base URL and maintains its own authentication token.
The relationship between the root configuration and specific user profiles. Sources: src/internal/state.ts:18-28
Environment Variables
The CLI exposes several environment variables to facilitate headless automation and testing isolation.
| Variable | Description | Precedence |
|---|---|---|
PUTIO_CLI_TOKEN | Headless authentication token. | Highest (overrides all persisted tokens). |
PUTIO_CLI_PROFILE | Selects a specific named profile from the config. | Overrides default_profile in config. |
PUTIO_CLI_CONFIG_PATH | Overrides the default config.json location. | Overrides system defaults. |
PUTIO_CLI_API_BASE_URL | Overrides the API endpoint. | Used if no profile or legacy URL is set. |
Sources: src/internal/config.ts:18-26, src/internal/metadata.ts:62-85, README.md:126-135
Authentication State Resolution
The resolution of authentication state is critical for command execution. The resolveAuthState function determines which token and API URL to use based on the environment and persisted profiles.
The sequence of checks performed to determine the active authentication credentials. Sources: src/internal/state.ts:474-548
Security & Persistence
When saving state, the CLI ensures that the configuration file is created with restrictive permissions (0o600) to protect sensitive tokens.
// src/internal/state.ts:183-199
yield* fs
.makeDirectory(runtime.dirname(effectiveConfigPath), { recursive: true })
.pipe(Effect.mapError((error) => mapFileSystemError(error, message)));
yield* fs
.writeFileString(effectiveConfigPath, `${JSON.stringify(state, null, 2)}\n`, {
mode: CONFIG_FILE_MODE, // 0o600
})
.pipe(Effect.mapError((error) => mapFileSystemError(error, message)));
Sources: src/internal/state.ts:183-199, src/internal/state.test.ts:70-93
Summary
The "Configuration & Environment" system provides a robust foundation for both manual and automated usage of the putio-cli. By prioritizing environment variables, developers can easily integrate the CLI into CI/CD pipelines using PUTIO_CLI_TOKEN, while the multi-profile system allows human users to switch between accounts seamlessly using putio auth profiles use. The use of strict schemas and file permissions ensures that configuration management remains safe and predictable.