ente-cli (0.4.48)

Published 2026-09-26 12:34:22 +00:00 by ivo.zilkenat

Installation

registry=https://gitea.i.ivo-zilkenat.de/api/packages/ivo.zilkenat/npm/
npm install ente-cli@0.4.48
"ente-cli": "0.4.48"

About this package

CLI for ente — relationship manager and knowledge graph (Convex backend).

ente CLI

Command-line interface for ente — a relationship manager and knowledge graph (people, orgs, projects, topics and the notes/calls/tasks/conversations logged against them).

TypeScript, built on clipanion, bundled with esbuild into a single self-contained file, published to the Gitea npm registry. It talks to ente's external REST API (/api/external/*) with a static Bearer API key.

Install

npm i -g ente-cli --registry https://gitea.i.ivo-zilkenat.de/api/packages/ivo.zilkenat/npm
# or set the registry once:
npm config set @ivo:registry https://gitea.i.ivo-zilkenat.de/api/packages/ivo.zilkenat/npm

Setup

Connect a normal CLI profile with browser approval. Replace the site URL and email with your Ente deployment and account:

ente auth pair --url https://your-deployment.convex.site --email you@example.com

The CLI prints a review link and six-digit code. Open the link, sign in, inspect the requested profile, enter the code, and approve it. The CLI generates its key locally and sends its hash and short prefix to Ente. The full key stays local and never appears in the browser or terminal output. Keep the CLI running until it verifies the new profile.

To connect an operator to one agent, use that agent's ID from ente agent list and name the local profile:

ente auth pair --url https://your-deployment.convex.site --email you@example.com \
  --profile mail-operator --agent <agent-id> --access write

For up to ten operators, put the exact agent IDs and local profile names in a JSON file outside a repository:

[
  { "profile": "operator-a", "agentId": "<agent-id-a>", "access": "write" },
  { "profile": "operator-b", "agentId": "<agent-id-b>", "access": "read" }
]
ente auth pair --url https://your-deployment.convex.site --email you@example.com \
  --manifest /private/path/operators.json

One Ente approval page lists all profiles and scopes. Existing local profiles are never overwritten unless --replace is supplied. A stopped or expired CLI run must be started again. Pending requests expire after ten minutes. Both agent access modes can read and change Ente data and manage spaces. With read, the key can inspect the bound agent and inbox, mark inbox threads read/unread, and change their workflow state. write also permits agent changes and sending email. The CLI saves approved profiles before activating their keys, so a failed local save cannot leave active keys behind.

For headless integrations or a legacy key, generate an API key in the web app and enter it directly in the terminal:

ente auth login --url https://your-deployment.convex.site --key-stdin

Credentials are stored at ~/.config/ente/config.toml (~/Library/Application Support/ente/config.toml on macOS), 0600. ENTE_API_URL and ENTE_API_KEY override the file only when both are set.

An agent operator profile is bound to that agent's configuration, threads, scheduled runs, and inbox when enabled:

ENTE_PROFILE=mail-operator ente agent config show
ENTE_PROFILE=mail-operator ente agent mail threads --unread

Operator keys use the CLI's scoped REST commands. They cannot be exchanged for the legacy full-account CLI session token, so the bound-agent restriction cannot be bypassed through direct Convex commands. Use a normal account key for legacy administrative CLI commands that require that session token.

Named profiles are optional. Use one only when a person or process deliberately switches between several credentials. --profile overrides ENTE_PROFILE. Profiles do not activate from the current directory and are not a security boundary. Use a separate OS account or container when operators on the same machine must not read each other's keys. Never commit a key or put it in a project .env file.

Usage

ente search "Alice"
ente entity list --type person
ente entity rename "Lorey Georg" "Georg Lorey"
ente task list --due today
ente activity create --type note --title "Meeting notes" --entity "Alice" --space "Personal"
ente activity get <activityId> --json # includes the body, nested agenda, messages/replies, entities, and attachments
ente agenda create-point --meeting <meetingActivityId> --title "Decisions" --content="- Ship the smaller scope"
ente agenda link-task --point <agendaPointId> --task "#12"
ente activity message add <activityId> --content "Decision: ship the smaller scope first."
ente activity content read <activityId> --json
ente activity content edit <activityId> --expected-version 42 --operations-file edits.json --json
ente canvas boards <entityId>
ente canvas html create <boardId> --title "Prototype" --file ./prototype.html --operation-id prototype-v1
ente notification send --subject "Weekly brief" --text "Your brief is ready." --html-file ./brief.html --attachment ./brief.pdf --inline-image chart=./chart.png
ente agent config show
ente agent threads
ente agent mail threads --unread
ente agent mail send --to person@example.net --subject "Update" --text "Plain fallback" --attachment ./handoff.md --html "<p><strong>Update</strong></p>" --idempotency-key agent-update-2026-09-01
ente tasks
ente guide              # concepts; `ente guide <topic>`: entities, tasks, activities, search, patterns, limits

Every command supports --json. Run ente --help or ente <group> --help.

Command groups

Group Commands
auth pair, login, status, logout, profiles
entity list, create, get, update (--name, --tag, --description), rename, archive, restore (--share-parents plus the returned grant fingerprint), pin (--role, optional confirmed parent grants), unpin, add-to-space, remove-from-space (--remove-from-activities optional)
activity list, create, search, get, update, delete, restore, message add, attachment upload
agenda create-point, link-task
task list, get, create, update, done, assign, unassign, set-assignees, clear-assignees
pins list
space members
recording list, show, inspect, rerun (admin only)
canvas boards, html list, html get, html create, html update, html delete
notification send (emails only your own Ente account address; optional HTML, file attachments, and CID inline images)
agent list, threads, show, new, send, config show, config set-prompt, schedules configure
agent mail address, threads, show, send, reply, mark
top-level search, ask, query, tasks, guide

Agent operators and inboxes

An agent operator key can read and change Ente data, manage spaces, and access one bound agent. Agent read includes Ente configuration such as the prompt, Ente thread history, scheduled-run configuration, inbox reads, and thread status updates when an inbox is active. Agent write additionally allows prompt changes, full scheduled-run replacement, and inbox send/reply. New write-capable keys also receive agent:communicate, which lets the bound external agent start, claim, and reply to external threads without calling an Ente-hosted model. Ente prompt and scheduled runs configure the Ente agent counterpart; they are not instructions or schedules for the external operator. The caller cannot select another agent, mailbox, or sender. The corresponding scopes are agent:read, agent:write, mail:read, and mail:send, and agent:communicate.

The inbox owner must add each exact correspondent in Ente. Unlisted inbound mail stays owner-only and never appears in operator REST, MCP, WebMCP, or CLI reads. New sends and replies are rejected before persistence unless the final recipient is allowed. An administrator-granted unlimited-mail account may enable send-to-anyone or receive-from-anyone separately for each mailbox.

ente agent config show
ente agent threads --include-archived --limit 20
ente agent show <ente-thread-id>
ente agent new "Can I publish this?" --title "Release note" --request text --idempotency-key release-question-1
ente agent threads --attention agent
ente agent send <ente-thread-id> "Published." --request ack --request-prompt "Release note published" --idempotency-key release-answer-1
ente agent config set-prompt --text "Review finance updates."
ente agent config set-prompt --file ./ente-agent-prompt.md
ente agent schedules configure --file ./schedules.json
ente agent mail address
ente agent mail threads --unread --limit 20
ente agent mail show <thread-id>
ente agent mail send --to person@example.net --subject "Update" --text "Plain fallback" --html "<p>Rich update</p>" --attachment ./reference.pdf --idempotency-key update-2026-09-01
ente agent mail reply <thread-id> --message <message-id> --text-file ./reply.txt --html-file ./reply.html --attachment ./handoff.docx --idempotency-key reply-2026-09-01
ente agent mail mark <thread-id> --state-version 4 --handled

schedules.json is the complete replacement list. Omitted schedules are deleted:

[
  {
    "enabled": true,
    "prompt": "Review new finance mail and prepare follow-ups.",
    "timeMinutes": 480,
    "timezone": "Europe/Berlin"
  }
]

Send and reply support repeatable --inline-image CONTENT_ID=PATH alongside --attachment PATH. Supply HTML containing <img src="cid:readiness"> and --inline-image readiness=./readiness.png. The CLI embeds local file bytes in the email; use CID images for private charts, never remote URLs or data URIs. Inline images must be PNG, JPEG, GIF, or WebP (verified by file signature). Content-IDs must be unique, case-sensitive, at most 128 characters, start with a letter or number, and contain only letters, numbers, ., _, @, or -. Every inline image must have a matching HTML CID reference, and every CID reference must have an image. Keep the complete report in the required plain-text fallback; HTML and images do not replace it.

The combined limit is four files across ordinary attachments and inline images, 750,000 bytes per file (3,000,000 decoded bytes total). Four Health charts fit only when no ordinary attachment is also sent. Five SaaS Spending charts exceed this limit and are rejected; inline images do not bypass it. For example:

ente agent mail send --to owner@example.net --subject "Readiness" --text-file ./report.txt --html-file ./report.html --inline-image readiness=./readiness.png --idempotency-key readiness-report-v1
ente agent mail reply <thread-id> --message <message-id> --text-file ./report.txt --html-file ./report.html --inline-image readiness=./readiness.png --attachment ./notes.txt --idempotency-key readiness-reply-v1

Retries must keep filenames, MIME types, Content-IDs, file order, and exact file bytes unchanged, along with the recipient, text, HTML, and reply target. A changed image or CID with the same key is rejected. Reported sent means transport accepted the message; delivery feedback may later report delivered, delayed, bounced, or complained. An unknown delivery outcome must never be retried with a new key.

--text and --html accept inline strings. Their --text-file and --html-file counterparts read UTF-8 files. After an ambiguous timeout, retry the exact same operation with the same --idempotency-key; changing the body, recipient, thread, or message requires a new key.

Operational recipes (playbooks)

Copy-pasteable, task-oriented recipes live in playbooks/ — log a meeting, rename/merge an entity, work around cross-space linking, etc. Start there for "how do I do X".

Develop in-repo / build

pnpm setup:cli                     # from the repository root; once per checkout
cd cli
pnpm dev entity list                # run from source via tsx
pnpm typecheck                      # the build-from-truth gate (tsc --noEmit)
pnpm build                          # → dist/cli.mjs (+ dist/SKILL.md)

The CLI is not a workspace member. pnpm setup:cli installs its locked dependencies separately. The repository's pnpm check typechecks and tests the CLI without installing dependencies.

Publishing is automatic: a push to main touching cli/** (or the relevant backend surface) bumps the patch version and publishes to Gitea npm — see .github/workflows/publish-cli.yml.

Architecture

core/    brand-neutral: transport (REST/fetch), config, output, errors, update, command base.
ente/    branded: the /api/external client, types, resolve, deadline, formatters, commands/*.
cli.ts   clipanion bootstrap: registers every command group.

The dependency direction is one-way — ente/ imports core/, never the reverse. See CLAUDE.md for the layering rules and conventions.

Public installation and recovery guide

This is the Ente private knowledge-graph / relationship-manager CLI at ente.fast, not Ente Photos. Follow https://ente.fast/cli.md for new installations, upgrades, PATH conflicts, configuration reuse, legacy API keys, and stale authentication. Keep working credentials. ente auth status --json reports local configuration without key material; verify server access with ente entity list --limit 1 --json. Use auth login --key-stdin for hidden local key entry as shown in the guide. Never put secrets in chat, repositories, project .env files, or logs.

Dependencies

Development Dependencies

ID Version
@types/node ^22.10.0
clipanion 4.0.0-rc.4
convex ^1.37.0
esbuild 0.27.0
smol-toml ^1.3.1
tsx ^4.21.0
typescript ^6.0.3
Details
npm
2026-09-26 12:34:22 +00:00
3
399 KiB
Assets (1)
Versions (78) View all
0.4.77 2026-10-24
0.4.76 2026-10-23
0.4.75 2026-10-23
0.4.74 2026-10-23
0.4.73 2026-10-22