Skip to content

Files & Mirrors

Files in Portuni live in two places at once: the remote (the source of truth for the team) and the local mirror on each device. The metadata row in files binds a node to a remote location; the path on the current device is derived from the per-device mirror root, the file’s remote_path, and the node’s sync_key. There is no persisted local_path column on files — it would go stale across devices and renames.

Create a local folder for a node on this device and register it.

ParameterTypeRequiredDescription
node_idstringyesNode ID
targetsstring[]yesMirror targets (only "local" supported in Phase 1)
custom_pathstringnoOverride default path

Default path: {PORTUNI_WORKSPACE_ROOT}/{org-slug}/{type-plural}/{node-sync-key}/

Creates subdirectories: outputs/, wip/, resources/. Organization mirrors additionally contain projects/, processes/, areas/, principles/ for child nodes.

Mirror registrations are per device. Each machine keeps its own copy of the registry in ~/.portuni/sync.db; the shared Turso DB does NOT store per-device paths.

Copy a file into the node’s local mirror, upload it via the routed remote, and persist a files row + file_state cache.

ParameterTypeRequiredDescription
node_idstringyesNode ID
local_pathstringyesAbsolute path of the source file on this device
descriptionstringnoFile description
statusenumnowip (default) or output
subpathstringnoOptional subfolder within the section

The file is copied to {mirror}/wip/... or {mirror}/outputs/... based on status (or detected from the source path if it already lives inside the mirror), then uploaded to the remote at {org-sync-key}/{type-plural}/{node-sync-key}/{section}/{subpath}/{filename}.

The remote is resolved through remote_routing (priority-ordered). The sync_key-anchored path means renaming a node does NOT change the remote location, so existing references stay valid.

Returns: { file_id, remote_name, remote_path, local_path, hash }

Two modes:

  • file_id — download the remote version into the mirror, refresh the local hash cache. Used to restore a deleted local copy or pull a teammate’s update.
  • node_id — preview only. Classifies each file as unchanged | updated | conflict | orphan | native without modifying anything. Use this before pulling to see what would change.
ParameterTypeRequiredDescription
file_idstringone ofFile ID (download mode)
node_idstringone ofNode ID (preview mode)
forcebooleannoDownload mode only. Overwrite the local file even when it has unpushed local changes. Default false

List files across all nodes with optional filtering. Each row includes a derived local_path (from the current mirror + remote_path + sync_key); it is null when the node has no mirror on this device.

ParameterTypeRequiredDescription
node_idstringnoFilter by node
statusenumnoFilter by status (wip or output)
limitnumbernoMax rows, newest first (default 500, max 2000)

Returns: Array of files, each with: id, node_id, node_name, filename, status, description, remote_name, remote_path, current_remote_hash, last_pushed_at, is_native_format, the derived local_path, and updated_at.

Scan tracked files and (optionally) discover new local / new remote files. Call this at session end when files were touched, before major migrations, or whenever the user asks about sync state.

ParameterTypeRequiredDescription
node_idstringnoRestrict to one node
remote_namestringnoRestrict to one remote
include_discoverybooleannoWalk the mirror + list the remote for new files (default: true)

Returns: classified buckets (clean, push_candidates, pull_candidates, conflicts, orphan, native, new_local, new_remote, deleted_local, moved).

portuni_list_remotes / portuni_setup_remote / portuni_set_routing_policy

Section titled “portuni_list_remotes / portuni_setup_remote / portuni_set_routing_policy”

Manage the pluggable remote backends and the priority-ordered routing rules that pick a remote for each (node_type, org_slug) combination. See concepts/mirrors for the per-device mirror model.