Menu da documentação

Documentação

Store overview

Terminal apps, agent skills, plugins, pipelines and per-project services.

Nesta página

One window, five catalogs

The Store is where you add things to TDE without leaving it. Press F2 (or Alt+S, or pick Store from the launcher and the command palette) and you get a single window with five tabs, each backed by a different kind of catalog:

TabWhat it installsCatalog
TUITerminal applications — lazygit, btop, k9s, and 600-odd moreBundled, optionally replaced live from the network
SkillsAgent skills from skills.shRemote only
PluginsThe two shell proxies TDE integrates with, rtk and ctxHard-coded, two entries
PipelinesMy Loop pipeline presetsLocal, from the built-in preset list
ServicesPer-project databases in containersBundled only — four manifests, never fetched

Installed is not a tab. It is a row in the left rail of the Skills, Plugins and Pipelines tabs. The TUI tab uses that rail for ★ Trending at the top and ⟳ Updates at the bottom, which is also the app updater's view.

Navigation is the same everywhere: / move between tabs, / select, Tab moves between rail and grid, Enter opens a card, Esc goes back. On a detail card Enter installs or opens, Delete (or r) removes and v votes.

The TUI catalog

638 TOML manifests are compiled into the binary. That is the catalog you get with no network, on a fresh machine, in an air-gapped VM. They cover 18 categories — Developer, Utilities, DevOps, Files, System, Git, Security, Monitor, Network, AI Agents, Database, Internet, Editor, Office, Games, Music, Connectors and Audio.

When the Store window opens, TDE also asks the network for a fresher list:

Store catalog fetch
GET  https://www.tde.sh/api/apps            # override with TDE_STORE_API
GET  https://www.tde.sh/api/store/trending?kind=tui&limit=50

Both calls have a 4-second timeout. A success replaces the in-memory catalog for that session; a failure changes nothing — you keep browsing the bundled list. The only visible difference is the header, and only if you set TDE_STORE_API yourself: it then reads offline: built-in TUIs, so a misconfigured endpoint is never silent. A failing trending call keeps the last ranking and adds trending offline.

The Store also hides apps your host cannot install. An entry whose package depends on a package manager you do not have is dropped from the grid rather than offered and then failing.

Searching

/ focuses the search field. Plain text matches name, category and description. Pressing ? in the field shows the filter cheatsheet:

Store search filters
name:lazygit         category:Git       cat:DevOps
tier:core            desc:kubernetes    description:docker
source:bundled       src:remote         installed:yes
inst:no              start-only:yes

A search always applies to the tab you are on.

What a manifest contains

Each catalog entry is one TOML file. This is the schema the parser actually defines:

crates/tde-apps/catalog/lazygit.toml
[app]
name        = "lazygit"        # required
category    = "Git"            # required
description = "Terminal UI for git commands"   # required
exec        = "lazygit"        # required — what the launcher runs
about       = "Longer prose for the detail card"
tier        = "option"         # "core" or "option" (default)
workdir     = "home"           # "home" (default) or "git"
start_only  = false            # true hides it from the Store

[install]
method   = "binary_download"   # "system" | "binary_download" (default) | "git"
github   = "jesseduffield/lazygit"
version  = "v0.44.1"           # pins a release tag
asset    = ["linux_x86_64"]    # asset-matching hints
amd64    = "https://..."       # explicit per-arch URLs
arm64    = "https://..."
package  = "lazygit"           # system package name
command  = "..."               # shell fallback
requires = ["git"]

[uninstall]
command    = "..."
data_dirs  = ["~/.config/lazygit"]
extra_bins = []

[[launch.options]]
label = "Log view"
exec  = "lazygit log"
hint  = "Opens straight on the commit graph"

[sync]
config_paths = ["~/.config/lazygit/config.yml"]

Two fields are worth explaining because their names mislead:

  • tier is core or option, and it is about provisioning, not pricing. The 26 core apps are installed at first boot; the other 612 download on demand. It has nothing to do with what you pay for.
  • start_only = true means "show in the Start menu, hide from the Store". It marks the 31 entries that are TDE's own native apps plus a few things TDE installs for you, like stripe-cli and sentry-cli.

[sync].config_paths lists small text files under $HOME that Sync replicates so an app feels the same on every machine. When it is empty, [uninstall].data_dirs is used instead.

eget does the downloading

519 of the 638 manifests install from a GitHub release, and TDE shells out to eget to do it: it resolves the release, picks the asset matching your platform — helped by the install.asset hints — and drops the binary into TDE's managed bin directory, /opt/tde/bin when that is writable and ~/.local/share/tde/bin otherwise.

If eget is not present, the generated install script bootstraps it first, then runs the real command in a visible terminal window so you can watch it. The same mechanism powers the ⟳ Updates rail: TDE asks the GitHub Releases API for each installed app's latest tag, compares it against a one-second --version probe of the managed binary, and re-runs eget with no tag to update.

Agent CLIs are checked against the npm registry instead, because claude, codex and opencode publish there. ctx is skipped because it self-updates, and rtk uses a pinned installer script of its own.

Skills

The Skills tab is a live proxy onto skills.sh. Its rail is ★ Trending, All, Hot, then eight curated topics — Frontend & React, Next.js, Design & UI, Mobile, Agent workflows, Databases, Testing, Marketing — then Installed. A search forces the all-time view and overrides the rail.

Installing a skill is not a file copy. TDE:

  1. fetches the repository's files and picks the shallowest SKILL.md;
  2. parses its frontmatter for a description and tags;
  3. derives the slug from the last segment of the skills.sh id, so anthropics/skills/pdf becomes pdf;
  4. writes it into the skill SSOT at ~/.tde/skills/, recording the source as repo:<owner/repo/slug> so a later re-install knows it owns that slug;
  5. writes any support files alongside it, rejecting path traversal;
  6. enables the skill for all four agent CLIs and syncs each one.

Support files stay in the SSOT — only the SKILL.md is materialized into an agent's own configuration. See Skills, prompts and deliverables for what each agent receives.

Services

The Services tab installs project-scoped local infrastructure: a real container running a real database, owned by one project on one machine. Four services ship, and there is no remote catalog — the manifests are bundled, pinned and validated inside the binary.

ServiceImageVariable it exports
PostgreSQLpostgres:16.3-bookwormDATABASE_URL
MySQLmysql:8.4.0-oraclelinux8MYSQL_URL
MongoDBmongo:7.0.11-jammyMONGODB_URI
Redisredis:7.2.5-bookwormREDIS_URL

The rail lists All projects first, then one row per project. Services install into a project, so the aggregate card's action reads Install in a project… and refuses if you have no projects yet.

What installing does

TDE talks to Docker through the Bollard library, never the docker CLI. A deployment is identified by the tuple (project, service, machine), hashed into a deployment id, and every resource it creates carries that identity — the container, the network and the named volumes all get a tde-<project>-<service>-<machine> base name plus the digest. Two projects on one machine therefore get two completely separate PostgreSQL instances.

Then, in order:

  1. Validate. The manifest schema rejects the latest tag, host path mounts, the Docker socket, privileged mode, host networking, undeclared ports, capabilities outside a five-item allowlist, a writable root filesystem, and any plaintext default for a secret.
  2. Claim. Under Sync, a (license, project, service) row is claimed atomically before any local Docker work happens. One machine owns a deployment; the others render it as remote, with the owner's name.
  3. Generate secrets. 32 random bytes per credential, written into the secret vault under the project's scope with put-if-absent semantics. The services database stores only references.
  4. Pin the image. The tag is pulled, its repository digest read back, and the container created from repository@sha256:…. Retries reuse the resolved digest, so an upstream re-tag cannot silently change what you are running.
  5. Publish on loopback only. Docker assigns an ephemeral host port and it is bound to 127.0.0.1. A container whose inspection reports any other host IP is rejected rather than used.
  6. Wait for health, then persist runtime state and render the connection URL.

The connection URL is never written to a file

This is the part worth internalizing. The exported variable — DATABASE_URL, MYSQL_URL, MONGODB_URI or REDIS_URL — is rendered in memory and merged into the environment of tasks, agent runs and sandbox profiles for that project. TDE does not create a .env, does not copy one into a worktree, and does not write the credential into the project at all. A value you set in the session overrides the service's, and a variable you explicitly removed stays removed.

PostgreSQL and MySQL additionally get a managed MCP profile, so agents can query the service by name. The agent's configuration file contains only database-mcp --profile-id <n>; the DSN is resolved from the vault at runtime, inside the server process. See MCP and Data apps.

Install, uninstall and vote events are posted to /api/v1/store/event on the same host as the catalog, with your license key as a bearer token and a body carrying the kind, the name and the event. kind is tui, skill, plugin or pipeline. That is what feeds the ★ Trending rail and the ↓ N installs · ▲ N votes line on a card.

Two properties are enforced in code rather than promised:

  • An unlicensed device never sends anything. The request is not built at all when there is no license key, so browsing and installing on an unactivated machine is silent. Voting reports Sign in to vote (license required).
  • Services never emit events. The Services tab has no remote kind, so nothing about your infrastructure — not even the fact that you installed PostgreSQL — leaves the machine.

Votes are optimistic: the chip flips immediately and rolls back if the post fails. Installs and uninstalls are fire-and-forget.