CLI Reference¶
aikito web¶
Start the local Web Console on 127.0.0.1:8765:
The Console browses canonical resources and governance status. It does not modify canonical resource files or expose MCP secret values.
Choose collection permissions on the linked Gateway's /account page, grouped
by global resources and project. All collections default to no access; each can
be read-only or read/write, with an authorization lifetime of up to 30 days.
Skills include all attachments and scripts. Account management also lists active
collection grants and connected AI clients, with explicit revocation controls.
The Remote and Gateway must share the same public HTTPS origin for this flow.
Store ownership and recipient trust must already be established using the CLI.
Open aikito web on a device holding the workspace keys. The Console queries the
Gateway for pending requests and active collection grants. Review the account,
recipient, Store, collections, permissions and expiration, then confirm or reject once.
Polling does not release collection keys. The cloud does not connect to the device,
and the device needs no public inbound listener.
Use Resource authorizations & access to open this view directly.
The confirmation button shows progress and retains the completion result in the view. An uncertain result stays visible with an instruction to check the online account page; polling never repeats the submission.
Account cookies remain at the Gateway origin. Store credentials and device keys remain in the local process; confirmation submits only the selected collections' sealed subkeys using the pinned recipient. Local endpoints require the exact loopback origin and a per-console token. Consumer OAuth consent remains separate.
A failed or uncertain submission stops the remaining collections. Completed Grants remain active; multi-collection approval is not atomic. Check the online account page, cancel any remaining request and create a fresh request if needed. A host-local confirmation journal prevents automatic replay after a Console restart. Authorization credentials and revocation controls are managed via your online account page; the Console displays confirmed active grants and provides direct links to revoke access on Cloud.

Command Overview¶
Aikito uses an operation-first command structure. Run
aikito <command> --help for the complete options supported by the installed
version.
| Command | Purpose |
|---|---|
aikito init workspace [path] |
Initialize a new workspace or connect an existing one, detect installed Agents, and remember an explicit path |
aikito path workspace |
Print the resolved active workspace path |
aikito migrate workspace-resources [--dry-run] |
Preview or apply the required one-time migration to per-resource Agent and subagent files |
aikito import workspace <source> [--dry-run] [--verbose] |
Preview or import canonical resources from another workspace into the active workspace |
aikito git [args...] |
Run git commands directly in the active Aikito workspace |
aikito init project [name] [path] [--description <text>] |
Register a code project and synchronize its .agents/ runtime |
aikito add skill [name] [--from <path>] [--force] [--project <projects>] [--global] [--sync] |
Create or import a canonical skill; defaults to current project when inside one, or workspace global if outside or with --global |
aikito add subagent [name] [--from <path>] [--description <desc>] [--agents <list>] [--sync] [--force] |
Create a canonical subagent skeleton or import from external markdown source; use --force with --from to replace |
aikito add mcp [name] [--from <source>] [--transport {stdio,remote}] [--command <cmd>] [--url <url>] [--agents <list>] [--sync] [--force] |
Create a canonical MCP server configuration or import from an external file (.json, .toml) or remote URL |
aikito adopt [path] [--dry-run] [--verbose] [--skip <resource>] |
Preflight existing local configuration, then import it only when the complete plan is safe |
aikito status |
Show the synchronization dashboard |
aikito diff [project|mcp|subagent] [--all] |
Show drift index or drill-down unified diffs for drifted resources |
aikito sync [--dry-run] [--verbose] |
Preflight all host-compatible resources together, then synchronize only when the complete plan is safe |
aikito sync global [--dry-run] |
Synchronize or preview global instructions and skills |
aikito sync project [name] [path] [--dry-run] [--force] |
Synchronize or preview a project's .agents/ directory (detected from cwd if omitted) |
aikito sync mcp |
Synchronize MCP entries |
aikito sync subagents |
Render and synchronize subagents |
aikito auth mcp <agent> <server> |
Authenticate a configured MCP server |
aikito show mcp [server] [--agent agent] [--live] |
Inspect MCP configuration or compare a server's live tool discovery across Agents |
aikito show subagents [target] [--agent agent] |
Inspect the subagent matrix, drill into platform options per agent, or print the canonical Markdown file |
aikito show project [name|.] |
List registered projects, or inspect one project (detected from cwd if omitted or .) |
aikito show instructions [global|project|.] |
List or print global and project instructions |
aikito show inbox [target] |
Print raw markdown content of an inbox note, or list all inbox notes if target is omitted |
aikito edit inbox <target> |
Open an inbox note in $VISUAL or $EDITOR |
aikito rm inbox <target> |
Remove an inbox note file |
aikito show memory [target] [--project <name> | --all] |
Print a memory note, or list memory notes (defaults to current project + global if inside one; use --all for all projects) |
aikito show skill [target] |
Print a skill's SKILL.md file, or list all skills if target is omitted |
aikito rename memory <target> <new-name> |
Rename a memory note and refactor inbound wikilinks |
aikito rm memory <target> |
Remove a memory note and scan for inbound wikilinks |
aikito rm skill <name> [--project <projects>] [--force] [--sync] |
Remove a skill globally or unregister it from specific project(s) |
aikito rm subagent <name> [--sync] |
Remove a subagent and unregister it from workspace |
aikito rm mcp <name> [--sync] [--force] |
Remove a canonical MCP server configuration from workspace |
aikito edit memory <target> |
Open a memory note in the configured editor |
aikito maintain memory [global\|<project>\|.] [--agent <name>] |
Launch an Agent to review one complete memory scope and propose maintenance before making changes |
aikito edit instructions [global|<project>|.] |
Open canonical instructions in $VISUAL or $EDITOR (detected from cwd or defaults to global) |
aikito edit skill <target> |
Open a skill's SKILL.md in $VISUAL or $EDITOR |
aikito edit subagent <target> |
Open a subagent's instruction markdown in $VISUAL or $EDITOR |
aikito doctor [--fix] |
Run deep workspace diagnostics and repair supported configuration issues |
aikito remote bind [url] [--rebind] [--recovery-fd <FD>] [--recovery-output-fd <FD>] [--no-initialize] [--workspace <PATH>] |
Connect through browser approval (automatically initializes encryption or recovers the key) |
aikito remote unbind [--force] [--workspace <PATH>] |
Unbind workspace from external remote store and stop background synchronization |
aikito remote sync [--dry-run \| --apply] [--verbose] [--workspace <PATH>] |
Synchronize workspace resources with bound remote store (defaults to apply) |
aikito remote watch [--poll-interval <SEC>] [--debounce-ms <MS>] [--once] [--verbose] [--workspace <PATH>] |
Continuously synchronize local workspace changes and remote updates |
aikito remote start [--workspace <PATH>] [--mode {auto,system,process}] |
Start background automatic synchronization service |
aikito remote stop [--workspace <PATH>] [--mode {auto,system,process}] |
Stop background automatic synchronization service |
aikito remote status [--workspace <PATH>] [--json] [--mode {auto,system,process}] |
Show status of remote binding and background synchronization |
aikito remote credential {set,list,path} |
Manage credentials in secure user configuration storage |
aikito completion zsh\|bash\|fish\|powershell |
Print a shell completion script |
aikito completion candidates projects\|skills\|subagents\|mcps\|memories\|memory-completions\|inbox\|inbox-completions\|paths [prefix] |
List dynamic completion candidates |
aikito version [-c\|--check] [--force] [--json] |
Print the CLI version and check for available updates |
Remote Store Synchronization¶
For a step-by-step account connection and recovery walkthrough, see Aikito Cloud.
Aikito allows synchronizing workspace resources with an external remote store. To configure synchronization, first connect through your service URL:
The browser asks you to sign in, compare the connection code and approve your device. Your account synchronization space and device credentials are configured automatically.
When connecting to a new empty space, aikito remote bind automatically initializes end-to-end encryption in interactive terminals and saves the recovery code to the private configuration file ~/.config/aikito/encrypted-remote/recovery.txt. An explicit copy can also be sent to --recovery-output-fd <FD>. To bind without initializing immediately, pass --no-initialize.
When connecting to an already initialized encrypted Store (e.g. connecting a second device), aikito remote bind automatically detects the existing encryption header and prompts for the Store recovery code, storing the unlocked Device Key in the local keystore and the verified recovery code in the same local recovery file. Non-interactive environments can supply --recovery-fd <FD>. Existing bindings can be updated with --rebind.
To disconnect the workspace from the remote store and halt background sync:
The binding persists the endpoint and pinned sync_id locally in .local/state/aikito/workspace-reconcile/binding.json.
Credentials are never written to the workspace; Aikito references the environment variable name (default: AIKITO_REMOTE_TOKEN) or resolves from secure user credential storage.
Secure Credentials (aikito remote credential)¶
Background services running outside an interactive shell can securely resolve tokens from user configuration storage (~/.config/aikito/credentials with 0600 permissions) or OS keychains:
# Store a bearer token securely in credentials file (prompts interactively with hidden input)
aikito remote credential set AIKITO_REMOTE_TOKEN
# Or pass token non-interactively via standard input
echo "secret-token-value" | aikito remote credential set AIKITO_REMOTE_TOKEN --stdin
# Or store directly into the operating system keychain / keyring (macOS / Linux)
aikito remote credential set AIKITO_REMOTE_TOKEN --keychain
# Native OS keychain tools can also be populated manually:
# macOS: security add-generic-password -U -s aikito -a AIKITO_REMOTE_TOKEN -w "secret-token-value"
# Linux: echo "secret-token-value" | secret-tool store --label="aikito" service aikito key AIKITO_REMOTE_TOKEN
# (Note: Windows is not currently supported for --keychain; use the secure credentials file instead.
# On macOS, `security -w <value>` passes the token as a CLI argument during execution; for maximum confidentiality,
# use the credentials file with 0600 permissions or standard environment variables.)
# List configured credential names (values are masked)
aikito remote credential list
# Display path to the secure credentials file
aikito remote credential path
Previewing Changes (--dry-run)¶
Synchronizing Changes (aikito remote sync)¶
By default, aikito remote sync applies synchronization changes directly:
Reconciliation transfers mutations transactionally between the local workspace and remote store. Unresolved conflicts and blocked resources remain untouched while safe resources are applied. The --apply flag is also accepted for backwards compatibility.
Previewing Changes (--dry-run)¶
To preview planned changes without modifying local files or the remote store:
Dry-run mode inspects local and remote snapshots and reports planned creations, updates, deletions, conflicts, and blocked resources.
Continuous Synchronization (aikito remote watch)¶
Run the foreground auto-sync worker to continuously synchronize changes between the local workspace and the remote store (useful for debugging):
aikito remote watch
aikito remote watch --poll-interval 5.0 --debounce-ms 500
aikito remote watch --once
Background Service (aikito remote start / stop / status)¶
Run automatic synchronization as an operating system background service:
# Start background service (auto-detects macOS launchd, Linux systemd --user, or Windows Task Scheduler)
aikito remote start
# Inspect service liveness, PID, revision, conflicts, and pending commits
aikito remote status
aikito remote status --json
# Gracefully stop background service and disable autostart
aikito remote stop
aikito remote disable
The background service:
- Registers native OS background definitions (macOS LaunchAgent in ~/Library/LaunchAgents/, Linux systemd unit in ~/.config/systemd/user/, Windows Scheduled Task via schtasks).
- Reuses the worker lifecycle lock to ensure idempotency and prevent duplicate workers.
- Gracefully handles termination via stop requests with a 35-second termination window (covering the 30-second HTTP timeout), ensuring in-flight rounds and pending journals finish safely before stopping.
- Disables and removes autostart registrations on stop/disable so services do not respawn on subsequent logins.
- Never logs sensitive tokens or file bodies.
Workspace Import¶
To move resources from an existing workspace to the active workspace, first
review the plan, then run the same command without --dry-run:
aikito import workspace /path/to/source-workspace --dry-run
aikito import workspace /path/to/source-workspace
The importer creates missing projects from their canonical workspace files;
their code directories may be cloned and synchronized later. Non-conflicting
resources are applied in one transaction; unresolved conflicts keep the target
unchanged and the command exits with status 2. Actual partial application is
reported as [PARTIAL]. A dry run with unresolved conflicts also exits with
status 2 but writes nothing. Path safety problems and snapshot findings still
block the entire import with status 1 and no resource writes. Status 0 means
there are no unresolved conflicts or blockers. Status 2 reports unresolved
conflicts, including a dry run or an import with no accepted changes; it does
not by itself guarantee that files were written. The source workspace is read only. The default output lists
one CREATE or UPDATE line per changed file and blockers with a summary;
--verbose adds the affected resource IDs and lists unchanged and skipped
source items. Resolve individual conflicts by resource ID, repeating the
options for multiple resources:
aikito import workspace /path/to/source-workspace --dry-run \
--keep-target memory:notes/local-policy.md \
--take-source skill:reviewer
aikito import workspace /path/to/source-workspace \
--keep-target memory:notes/local-policy.md \
--take-source skill:reviewer
--keep-target skips importing the resource, whether it would be created,
updated, or conflicted. An existing target stays unchanged; an absent target
stays absent. --take-source resolves conflicts only and does not override a
customized target when the source is still at its template. IDs must belong to
the source's supported resources, and an ID cannot have opposite choices. Choices are scoped to that
invocation, so retaining a differing target requires the same choice on a later
import or manually making the resources agree. Selecting the source cannot
bypass reference or safety checks. Changes with missing references are reported
as conflicts and skipped along with their dependent changes. Shared TOML writes
include only accepted fields and collection members.
After importing, preview runtime synchronization with
aikito sync --dry-run, bind any offline project with
aikito sync project <name> <path>, and review the workspace with aikito git.
Discovery¶
Write Boundaries¶
Commands differ in their effect:
status,diff,show,completion, andadopt --dry-runare read-only;gitforwards arbitrary Git commands and arguments directly to the active workspace;init workspacecreates or updates a recognized workspace;migrate workspace-resources --dry-runpreviews all changes and blockers without writing; the command without--dry-runapplies the migration transaction;import workspace <source> --dry-runpreviews each resource action without writing; the command without--dry-runapplies the reference-safe subset, preserving unresolved conflicts; global safety findings still prevent all writes;init projectcreates an idempotent canonical project skeleton and its runtime links;addcreates a canonical resource skeleton and performs required registration;adoptpreflights all detected resources, then writes imported resources into the workspace after backup only when the complete plan is safe;syncpreflights every workspace scope, then writes managed Agent or project runtime configuration only when the complete plan is safe;editdelegates a canonical memory, skill, instruction, or subagent file to an external editor.maintain memorylaunches an interactive Agent whose prompt requires confirmation before writes.
Bare aikito sync --dry-run prints a concise read-only plan; add --verbose for
every item and path. Targeted project, MCP, and subagent sync commands also
support --dry-run. Consult the Safety model before applying
changes to an existing setup.
doctor compares registered Agents with the current bundled registry schema.
Missing fields are warnings; doctor --fix adds bundled defaults without
replacing existing values. Installed supported Agents missing from the registry
are also reported and can be added by doctor --fix.
Registered bundled Agents that are no longer detected are reported as offline
and preserved safely in agents/<name>.toml for multi-host roaming.
It also reports each project's native instruction, skill, and memory runtime
issues. Missing resources point to sync project; conflicts remain read-only
and point to show project for review. Findings are aggregated per project;
when missing resources and conflicts coexist, the conflict action wins.
The Adoption section uses the same structured findings as adopt, including
the affected resource, source, reason, and exact review or skip command.
Adoption findings are warnings: doctor and doctor --fix never import or skip
resources.
The LocalState section checks host-local project skill copy records under
~/.local/state/aikito/project-skills/. Records for temporary workspaces and
checkouts that both no longer exist include the cleanup command
aikito doctor --fix. Cleanup rechecks bindings under the writer lock and is
deferred while transaction journals are present. Unavailable non-temporary
paths, malformed records, and symlinks are reported and preserved. Ordinary
doctor, including JSON output, never removes or rewrites these records.
When one detected resource is intentionally out of scope, repeat
--skip instructions, --skip mcp/<name>, or --skip subagent/<name> as
needed. Skips apply only to that invocation and are printed in the plan. Unknown
resource names fail instead of being ignored; unreadable or malformed source
configuration remains a plan-level error and cannot be skipped.
adopt also accepts --skip agent/<name> for a planned built-in Agent
registration. Skip its dependent new MCP or subagent resources too; otherwise
preflight blocks the entire import.
status is the compact dashboard: its Memory Status column combines the
presence of canonical note directories and runtime connection health, and the
legend explains any warning symbols. Use
show project <name> to inspect the exact runtime resource paths and link
issues for one project.
Python API¶
See the Python API Reference for Project.load(),
Project.prepare(), Project.add_path(), PreparedProject, and the full
exception hierarchy.
Project.prepare() has no CLI wrapper. Operators use
aikito sync project [name] for manual project synchronisation and path
registration (detected from cwd if omitted).
aikito maintain memory defaults to the project whose locally present path
contains the current directory and launches the codex runner configured in
agents/<name>.toml. A named project uses the candidate that contains the current
directory; if you are not inside one, a project with a single local path still
uses that path, while multiple local paths require running the command from one
of them. Use global or a registered project name to select another scope, and
--agent to choose codex, claude-code, agy, opencode, or
github-copilot.
Custom Agents can define [agents.<name>.runner] with a command array.
Supported placeholders are {prompt}, {workdir}, {scope}, and
{memory_dir}. Optional [agents.<name>.runner.env] string values override
the inherited process environment and support the same placeholders:
Runner environment values belong to the user workspace and must not be added to the source repository. Keep only safe commented examples in source-controlled templates, and never rely on repository publication as a secrets store.
Drift Diff¶
After aikito status or aikito doctor reports drift, inspect drifted managed resources:
# High-level drift index across the workspace
aikito diff
# Drill-down into a specific project (defaults to cwd if omitted inside a project)
aikito diff project [project]
aikito diff project <project> <skill>
aikito diff project <project> <skill> <file>
# Specific MCP server or subagent
aikito diff mcp <agent> <server>
aikito diff subagent <agent> <name>
# Full unified diff dump across all drifted resources
aikito diff --all
The bare aikito diff command outputs a high-level drift index showing which MCPs, subagents, and projects have drifted, without dumping raw unified diffs. To inspect full diffs, drill down by project/skill/file or use --all to print all unified diffs at once. MCP credentials and sensitive headers are redacted. Binary project skill files are reported without printing their contents. Missing resources and unmanaged conflicts remain status findings and are not rendered as drift diffs.
Targeted commands inspect only their resource kind, so unrelated MCP configuration errors do not block project or subagent diffs. Project indices group changes by checkout path, and full diffs identify the checkout in each resource label. File targets accept / or \ separators and equivalent relative paths such as ./scripts/check.py.
Instructions¶
Aikito calls this resource “instructions” and stores its canonical content in
AGENTS.md for ecosystem compatibility.
Without a target, show how each Agent is connected to global instructions,
followed by a compact Projects section. A project with missing or empty
canonical instructions is shown as -; otherwise its runtime link is shown
as linked, missing, or conflict. Provide global, a project name, or .
to print raw Markdown content:
aikito show instructions
aikito show instructions global
aikito show instructions example
aikito show instructions .
aikito edit instructions
aikito edit instructions example
aikito edit instructions .
. resolves the registered project containing the current directory and notes
that global instructions are also active. If target is omitted for aikito edit instructions,
it resolves the project containing the current working directory, falling back to global
when run outside any project.
Inbox¶
inbox/ acts as a staging directory for raw notes captured from browser AI conversations before they are curated into durable memory.
List inbox notes sorted by modification time (Name and Modified):
Print the raw Markdown content of an inbox note by exact name or unique prefix:
Open an inbox note in the configured editor:
Remove an inbox note after reviewing or curating it:
The inbox directory defaults to <workspace>/inbox and can be customized in config.toml:
Workspace Configuration¶
Global workspace behavior is governed by <workspace>/config.toml:
# <workspace>/config.toml
[memory]
# Days after which an untouched durable memory note is flagged as stale (default: 30)
stale_days = 30
[inbox]
# Staging directory for incoming distilled notes (default: "inbox")
path = "inbox"
[update]
# Enable or disable automatic background update checks and CLI notifications (default: true)
check = true
Update Notifications and Checks¶
Aikito performs lightweight, non-blocking version checks against PyPI and GitHub releases using a 24-hour local cache.
To disable automatic upgrade notifications:
- In <workspace>/config.toml: set [update] check = false
- In the shell environment: set export AIKITO_NO_UPDATE_NOTIFIER=1 or NO_UPDATE_NOTIFIER=1
To inspect version and update status manually:
# Print current version (plus cached update notice on stderr if available)
aikito version
# Check for updates against remote source (reuses cache if checked within 24h)
aikito version --check
# Bypass cache and force an immediate remote check
aikito version --check --force
# Machine-readable output in JSON format
aikito version --json
Projects¶
List each registered project's path, synchronization mode, instructions, selected skill count, project memory note count, context footprint estimate, and aggregate sync status:
Inspect one project's canonical and project directories, configuration, and sync issues when present:
When inside a registered project directory, aikito show project defaults to the
current project. An explicit . also resolves the current project. Outside any
registered project, omitting the argument lists all projects (equivalent to
aikito show projects).
Initialization¶
Initialize a new workspace or connect an existing one:
# Brand new workspace:
aikito init workspace ~/aikito
# Existing workspace:
aikito init workspace <workspace-path>
aikito sync
Register a code project from its directory. The directory name becomes the project name by default:
Both values can be explicit:
Project initialization creates agent.toml, AGENTS.md, and the project
memory skeleton under <workspace>/projects/<name>/, then synchronizes the target
project's .agents/ runtime and each workspace-registered Agent's native project
instruction path. Targets shared by multiple agents are linked once.
Existing unmanaged files are reported as conflicts and are never replaced. The
initial AGENTS.md is empty until project-specific instructions are added.
The optional description is display-only metadata stored in agent.toml.
Initialization is idempotent. A
project name already bound to another path, or unmanaged resources at a target
runtime path, is reported as a conflict rather than overwritten.
Shell Completion¶
Aikito ships its own completion scripts so you do not need third-party packages.
Zsh — add one line to ~/.zshrc:
Bash — add one line to ~/.bashrc or ~/.bash_profile:
Fish — install the completion file once:
PowerShell — add one line to your $PROFILE:
Completion covers all commands, subcommands, and options statically. When tab-completing a memory note, skill name, or project name, Aikito calls a lightweight internal interface that reads only the local workspace files with no network requests or expensive diagnostics:
aikito completion candidates projects
aikito completion candidates skills
aikito completion candidates subagents
aikito completion candidates mcps
aikito completion candidates memories
aikito completion candidates inbox-completions
aikito completion candidates paths agent
Path arguments combine normal local filesystem completion with basename-prefix matches from the Aikito workspace and registered project roots. Hidden and generated dependency directories are skipped, and ambiguous matches remain visible for explicit selection.
Installation via brew install lsaint/tap/aikito automatically installs
Zsh, Bash, and Fish completions without modifying ~/.zshrc.
Store Ownership Proof¶
With a bound HTTPS Store, submit a short-lived ownership challenge to the same service. Select the account independently of the challenge file:
aikito remote claim --workspace ~/aikito --challenge ownership-challenge.json \
--account account-123
This uses the existing Store credential reference. It does not log into an
account, export content keys, enable synchronization or grant access to Memory.
The service must support the claim endpoint and issue the challenge from an
authenticated account session. A challenge file alone does not authenticate its
account label; verify the account ID in your authenticated session before passing
--account. The service checks the expected account before changing ownership.
The file contains version 1, challenge_id, account_id, store_id, sync_id
and UTC Unix expires_at. Unknown fields, wrong identity/account, expired or
more than five-minute challenges are rejected before resolving credentials.
The destination is derived exclusively from the existing HTTPS binding; the
file cannot choose a URL. Requests never follow redirects, and response loss is
reported as claim_outcome_unknown without retries. Check the account's Store
status before attempting another claim. Workspace content, Base, binding and
pending state stay unchanged.
Local Encrypted Recovery¶
These commands manage a local device key. Local header recovery does not enable sync by itself. Ordinary sync uses end-to-end encryption with no plaintext fallback.
python -m pip install 'aikito[encrypted]'
aikito remote key path --workspace ~/aikito
aikito remote key recover --header recovery-header.json --sync-id STORE_SYNC_ID --workspace ~/aikito
The recovery command prompts without echo. Automation must provide an explicit
--recovery-fd; the code must not appear in arguments or environment variables.
The header is public metadata, while the recovery code is secret. Device keys are
saved outside workspace and Git; home backups may include them. See the
Remote Store Boundary
for storage and recovery limits.
Optional Native Device Key Storage¶
Files remain the default. On a bound, unlocked encrypted Store, explicitly select OS protection or return to a file:
aikito remote key storage --workspace ~/aikito --backend native
aikito remote key storage --workspace ~/aikito --backend file
macOS uses an unlocked default Keychain; Windows uses current-user DPAPI; Linux
requires secret-tool, gdbus, a session D-Bus and an unlocked default Secret
Service collection. Missing tools, a locked store or access denial stop with
key_storage_unavailable. There is no automatic fallback or unlock prompt.
The operation authenticates the remote header, reads back the protected key and
atomically switches the local record. It does not change remote content or Base.
Native items are retained when switching to files because other workspaces may
use them. Older clients cannot read native records; explicitly switch to files
before downgrading.
If the native backend is unavailable, use the recovery code to explicitly restore file storage. A verified header and matching Vault key are required:
aikito remote key recover --workspace ~/aikito --header recovery-header.json \
--sync-id STORE_SYNC_ID --file-storage
File storage uses owner-only permissions. Home backups include the raw key file
or its protected native reference/blob. DPAPI blobs depend on the user's Windows
profile; a copied keychain reference alone cannot unlock another machine. Keep
the recovery code separately. Homebrew installs the encrypted runtime by default;
other Python installations opt in with aikito[encrypted].
Bounded Encrypted Discovery¶
For an initialized workspace with an existing remote binding and a recovered device key, inspect one read-only discovery round:
Repeat until the output says complete. Each invocation authenticates the format
header and verifies at most 32 business resources within the shared fetch byte
budget. Private resources bootstrap project identities before project Memory is
discovered. Output includes counts and revision, without content or logical names.
The authenticated local map allows separate CLI processes to resume; unchanged
verified descriptors are not downloaded again.
This command does not change remote data, business files, bindings, pending or
Replica Base. An incomplete view cannot authorize deletions or writes. Ordinary remote sync uses the same authenticated discovery. Unsupported formats are refused.
Encrypted Synchronization and Empty Store Initialization¶
Use the explicit encrypted commands with an existing binding to initialize an empty Store. Initialization refuses any Store containing plaintext resources. The recovery code is generated independently, saved in the private local recovery file, and optionally delivered to a secure terminal or explicit output descriptor, and never persisted in the workspace or Git.
aikito remote key initialize --workspace ~/aikito
aikito remote sync --dry-run --workspace ~/aikito
aikito remote sync --apply --workspace ~/aikito
Automation must provide --recovery-output-fd to initialization; keep that channel
private. On a fresh device, use the Store Token environment variable and enter the
recovery code securely to recover and bind directly:
aikito remote key recover --endpoint https://remote.example/v1/stores/STORE/remote --workspace ~/aikito
An optional --sync-id checks the expected Store identity. The default token source
is AIKITO_REMOTE_TOKEN, changeable with --token-env. Recovery codes only enter
through the secure prompt or explicit --recovery-fd; --header local recovery
continues to require --sync-id and does not create a binding.
Encrypted sync discovers unknown descriptors in bounded rounds before planning business changes. Preview does not write discovery, Base, pending or remote data. Apply encrypts uploads before persisting a request. Delivery uncertainty retains that exact request; rerun the command to resolve its receipt or resend identical bytes. Captured uploads advance logical Base without overwriting newer local edits. Later applied local edits win and replaced remote versions are archived locally. Initialization also retains its public header request across response loss. A CAS loser must recover the winning Vault; retrying cannot replace it.
remote sync, remote watch and the background service all use end-to-end encryption.
There is no plaintext synchronization, migration or rollback command. Existing plaintext
Stores must be discarded administratively and devices connected to a new empty Store.
Local workspace files remain readable and are preserved.
HTTPS Recipient Discovery and Trust¶
Fetch a recipient public key from an explicit HTTPS origin before creating a scoped export. This command works without the optional encrypted dependency:
aikito remote key fetch --workspace ~/aikito \
--origin https://recipient.example.com --output recipient.json
The origin must have no path, query, userinfo or fragment. The fixed request is
GET /v1/keys/recipient; TLS certificates are verified, redirects are rejected,
and no Store token or browser cookie is sent. The response is a bounded canonical
recipient JSON document matching the format below.
First use automatically pins the key ID and public key under the local config
base's aikito/remote-recipients/, outside the selected workspace. Repeating with
the same identity succeeds. Any change to either field stops without creating an
output or changing the pin. After independently establishing that the change is
expected, explicitly accept it with a fresh output path:
aikito remote key fetch --workspace ~/aikito \
--origin https://recipient.example.com --output recipient-new.json \
--accept-key-change
There is no manual fingerprint comparison requirement. First use trusts the chosen origin and its TLS identity; losing or deleting local pins loses that continuity. Corrupt, linked or unsafe pin records fail closed even with the acceptance flag. Pins are owner-only and serialized against other local writers. The command never overwrites an output file, changes a Remote binding or grants content access. A failed output write can follow a successfully saved pin; retry using a fresh output path. The resulting document can be passed to key export.
Scoped Read Key Export¶
Export one explicitly selected existing project Memory collection to a trusted
recipient's X25519 public key. This requires aikito[encrypted] with
cryptography>=47, an existing binding and the external device key:
aikito remote key export --workspace ~/aikito \
--collection project/demo/memory \
--recipient recipient.json --authorization request.json \
--output scoped-read.json
The command verifies the Store header, parent Project and one Memory sample,
then seals only the explicitly selected collection keys. The default permission
is read, exporting only its content key. It refuses private, global Memory,
other resource types, empty collections and migrations.
There is no implicit project, wildcard or plaintext-key output. The output is a
new owner-only encrypted file; existing files and links are never overwritten.
Remote data, discovery checkpoints, pending and Replica Base are unchanged.
Both inputs use canonical JSON (sorted keys, compact UTF-8, no trailing newline).
The recipient document contains exactly version:1,
algorithm:"hpke-x25519-hkdf-sha256-a256gcm", key_id and public_key (standard
Base64 raw 32-byte key). Obtain this document from a trusted source; this local
export command does not discover or pin a remote recipient; use remote key fetch
for HTTPS discovery with local trust continuity.
The authorization request contains exactly version:1, account_id, store_id,
sync_id, vault_id, collection_id, recipient_key_id, permissions:["read"],
grant_id, nonce (Base64 32 bytes) and expires_at (future UTC Unix seconds).
Store, grant and recipient key identifiers use 1–128 ASCII letters,
digits, dots, underscores or hyphens. Account identifiers also allow colons. Select the collection explicitly and match
its name and recipient key ID to the request. The encrypted package binds every
request field, Vault/Store identity, collection Tag, recipient public key hash and
fixed parent opaque ID. Project names and the content key remain inside HPKE.
Export creates a local package; it does not activate a grant, prove account ownership or consume a one-time nonce. Receivers must separately authenticate the sender and trusted request, verify Store ownership, reject replay, test resource decryption and enforce expiry/revocation. HPKE Base mode does not authenticate senders. A recipient holding the content key can read the entire selected collection, including future content until key rotation; expiry cannot erase copied keys. Private resources and other projects have independent keys.
For independent write delegation, obtain a separate authorization whose permissions
are exactly ["read","write"] and explicitly select write on both commands:
aikito remote key export --workspace ~/aikito --collection project/demo/memory \
--permission write --recipient recipient.json --authorization write-request.json \
--output scoped-write.json
aikito remote key submit --workspace ~/aikito --origin https://recipient.example.com \
--permission write --package scoped-write.json --authorization write-request.json \
--account account-123 --collection project/demo/memory
A write request is rejected by the default read command before loading keys or
resolving a Store credential; selecting write against a read request is also rejected.
Write material contains only this collection's content, resource-ID and fingerprint
subkeys, bound to the independent aikito.scoped-write-export HPKE info domain.
It does not contain the Vault root, collection master, tag key or private keys.
The fixed parent opaque ID comes from the authenticated local parent Project.
Receivers must verify all three keys against a real sample and persist/revoke the
write grant independently. This export does not write any Memory or imply that
consumer write tools are available.
Scoped Package Submission¶
Submit an existing sealed package to an explicit HTTPS recipient origin:
aikito remote key submit --workspace ~/aikito \
--origin https://recipient.example.com --package scoped-read.json \
--authorization request.json --account account-123 \
--collection project/demo/memory
This command works without the encrypted extra. First obtain and inspect the
recipient's authorization request, then use remote key fetch and remote key
export as above. Choose the account and collection independently; submission
checks both against the request before resolving the bound Store credential.
It also checks the binding's Store/sync identity, all package context fields,
and a freshly fetched public key against the existing origin pin. Missing or
changed pins stop submission; accepting a key change requires a separate fetch.
The command sends one authenticated POST to /v1/stores/{store}/grants on the
explicit origin, using the existing Store Token. It verifies TLS, sends no
browser Cookie, refuses redirects, and never retries a submission. Keep this
origin distinct from the Remote endpoint when the recipient uses separate
listeners. Request/package files must be canonical JSON. No workspace, Remote,
pending or Replica Base data is written.
A successful HTTP 202 receipt must report active: the receiver saved the
scoped grant with the exact requested permissions. Verification-only receipts
are rejected; the CLI reports activation only after validating the complete receipt. An active grant lasts until its stated expiry
or explicit receiver-side revocation, independently of the submitting device.
Content endpoints and authorization for individual consumers are separate
receiver capabilities.
A rejected request may already be consumed; a lost or malformed response reports
export_outcome_unknown. Check the receiver's grant list before requesting a
fresh authorization. Submission never retries or follows redirects. Receivers
must enforce revocation and must not restore revoked keys from backups.