Repository navigation
Releases: lukaszgard/den
Release list
v1.2.0
What you type for an agent is no longer lost. The request of the Runbooks pane's n and
the change E asks for lived only in their pop-up: esc, a quit or a crash lost it, and a
restarted agent tab started without it. den now keeps them on disk as drafts until you send
them, and keeps the request a runbook was made with, so an agent that failed can get it again.
📜 Runbooks
- The
nandEforms save what you type as a draft a second after you stop typing, and when
den quits, soctrl+c,qor a crash loses at most that second.escon a form with
something in it asks Keep as a draft?:ykeeps it,ndeletes it,escgoes back to the
form. An empty form closes as before. - A kept draft is a row at the top of the Runbooks list, TYPE
draft, with its request's first
line as the description, so/finds it.enteropens its form where you left it andD
deletes it after asking; the run keys say it is a draft instead of running it. nfirst offers your drafts of new runbooks, newest first, beside a new one; with none it
opens the form at once, as before.Eon a runbook with a draft of a change opens that draft.enterin either form keeps the request with the runbook. Restarting a failed agent's tab
now asks first:y(orenter) sends the request again,nstarts the agent empty,esc
restarts nothing. After den itself restarted,Eon the runbook opens filled with that
request, ready to send again or to change. A runbook that cannot be created keeps what was
typed as a draft.- Drafts and saved requests are files in den's state directory readable only by you, since a
request may hold a password;den mcpand--jsonnever show them.den pathslists the
folder, and deleting a runbook deletes its requests.
🔧 Configuration and checks
runbooks.drafts.keep_requestsays how long a request outlives the runbook it created:
until-deleted(the default) until the runbook is deleted,until-exituntil its agent exits
cleanly by itself,neveronce the agent has started. An agent that fails, or whose tab den
closed, keeps it.runbooks.drafts.days(default 30) is how long an untouched draft is kept;0keeps drafts
until you delete them.
v1.1.1
The den.yaml schema and the configuration reference describe every key. Each key is
documented where den defines it, but the schema generator looked those notes up under the wrong
package name, found none and reported nothing. The schema shipped without a single key
description, and every Description cell of the configuration reference was empty.
🔧 Configuration and checks
den schemanow carries a description for every key, so an editor with the YAML language
server shows what a key does when you hover it. If you saved the schema to a file
(den schema > ~/.config/den/den.schema.json), run that again after updating.- The configuration reference on the documentation site fills its Description column from the
same text. - The reference's Required column says yes or no for every key, where it left optional keys
blank. A key needed only in some setups says when in its description:aws_region_codeand
ec2_instance_id(in the service's section or from itsenv), the transport'shost,
endpoint_idandresource, Redshift'scluster_identifierandworkgroup_name, the VPN's
config_fileand KeePassXC'skey_file. - A key with a fixed set of values lists them in its Type (
string, one of ssm, ssh, …), in
place of an Allowed values column that stood empty on all but 11 rows. - The schema marks
rds_host,db_user(RDS),documentdb_host,redshift_host,
opensearch_host,neptune_hostand a runbook parameter'snameas required, as den itself
always did, so an editor flags them when they are missing.
v1.1.0
Six more agent CLIs can write and change your runbooks. den runbook new --agent, the
Runbooks pane's n and E started only Claude Code and Codex. They now also start OpenCode,
Copilot CLI, Qwen Code, Droid, Pi and Kimi Code, each with den's runbook guide, and without
touching that agent's own configuration.
📜 Runbooks
kindinrunbooks.agents,runbooks.agent, a runbook'sagent:and--agenttake
opencode,copilot,qwen,droid,piandkimibesideclaudeandcodex. The kind
is read from the command (opencode --model …,/opt/bin/copilot) and from
ollama launch <kind>, whereollama launch copilot-climeans Copilot CLI.autotakes the
first one installed, in that order after Claude Code and Codex.- OpenCode and Copilot CLI get den's MCP server for the session, as Claude Code and Codex do:
OpenCode through a config den writes and names inOPENCODE_CONFIG, which it merges with
yours; Copilot CLI through--additional-mcp-config, with anAGENTS.mdden adds to
COPILOT_CUSTOM_INSTRUCTIONS_DIRSahead of your own folders. - Qwen Code, Droid, Pi and Kimi Code cannot take an MCP server for one session, so they check
their work with the newden runbook validatefrom their shell. Kimi Code takes no first
prompt: den puts the request in its instructions and tells you to typegoin its tab. den runbook validate [folder] [--json]checks a runbook folder the way den loads it and
reports what thevalidate_runbookMCP tool does, exiting 1 while the folder does not load.- The setting files den writes for these agents live in
agents/under den's state directory,
one folder per start, readable only by you; folders unused for 30 days are removed.
🔧 Configuration and checks
den doctor --for opencode(andcopilot,qwen,droid,pi,kimi) shows how to
install each agent CLI on your OS.
v1.0.4
An old SSO login left in the cache no longer hides a fresh one. ~/.aws/sso/cache keeps a
file per session name and per start URL, and the files of a renamed session stay behind. den took
the first match in file name order, so an expired leftover that sorted before today's login made a
logged-in session show as expired.
🔧 Configuration and checks
- A session counts as logged in when any of its cached logins is still valid. Secrets no longer
say "SSO login expired — log in from the AWS pane" for a session you have just logged in to,
and the AWS pane andden doctorread the login that runs out last.
v1.0.3
aws.config_path and aws.credentials_path now reach the aws CLI and the AWS SDK. den read
the files named there to find your SSO sessions, but the aws commands it runs looked in
~/.aws/config, so an SSO login from a custom config file ended in exit status 255.
🔧 Configuration and checks
- den exports
AWS_CONFIG_FILEandAWS_SHARED_CREDENTIALS_FILEfromaws.config_pathand
aws.credentials_pathfor everything it starts: SSO logins, RDS tokens, SSM tunnels, credential
exports and the SDK. A keyden.yamlleaves out does not override a variable you exported
yourself, and a config reload that drops a key puts back the value den started with.
🔌 Data stores and tunnels
- A failed SSO login says why. The row shows the last line of the
awsCLI's output after
exit status N, instead of the exit status alone.
v1.0.2
🔄 Updates
- A failed update check with
GITHUB_TOKENset no longer ends in a bare "HTTP 404". GitHub
answers 404 for a repository a valid token cannot read, so the message now says so and what
the token needs: for a fine-grained token, the repository selected under its owner and
Contents: read; for a classic one, thereposcope, authorized for SSO when the organization
enforces it. A rejected token (HTTP 401) is reported as invalid, expired or revoked.
v1.0.1
Checking for updates no longer depends on GitHub's API rate limit. den checks on every
start, and without a token GitHub's API allows 60 requests an hour per IP, so an office, a VPN
exit or a CI fleet behind one address got HTTP 403 in the Updates pane.
🔄 Updates
- The check reads the release feed on github.com (
latest.jsonof the latest release) and the
download uses the release's files by their URLs: the routeinstall.shandinstall.ps1
already take, with no API call and no rate limit. A public repository needs nothing
configured: no token, noupdates:block. den needs HTTPS access togithub.comand to
release-assets.githubusercontent.com; behind a proxy it honoursHTTPS_PROXY. GITHUB_TOKENstill selects the releases API, which a private repository needs. A release
withoutlatest.jsonfalls back to the API, and a fork whosegithub_apiis on
api.github.comreads the feed of its own repository. GitHub Enterprise and the S3 mirror
work as before.- A failed check says what to do: that den could not reach github.com (set
HTTPS_PROXY), that
the repository is private (setGITHUB_TOKEN), or that GitHub's rate limit was reached. - The Updates pane's help (
h) shows where releases are read from and what you need, and the
Updates documentation and Help topic list the same requirements.
v1.0.0
den 1.0: reach the private data stores of your AWS accounts from one terminal. den opens the
tunnel, mints and refreshes the IAM credential the store accepts, and wraps the chores around
them: AWS SSO logins, a VPN, secrets and your own scripts as runbooks. It also serves itself to AI
agents without ever showing them a credential.
🔌 Data stores and tunnels
- One tunnel model for every store: RDS and Aurora (PostgreSQL, MySQL, MariaDB), ElastiCache
(Redis OSS, Valkey), MemoryDB, DocumentDB, Redshift (provisioned and Serverless), OpenSearch
(domains and Serverless), Neptune and Docker Compose. The tunnel opens, waits until the port
accepts connections, mints the credential, refreshes it before it expires and reconnects when it
drops. Kafka (Amazon MSK) is planned: akafkaservice loads and says so when connected. - Environments are written once under
environments:and shared by services and runbooks with
env:. Region and environment are labels you choose;production: true(or an environment
calledprodorproduction) makes an AI agent ask before it connects. den has no built-in
knowledge of any account, andden connect NAMEopens the dashboard with a configured service
connecting. credential_profileis the profile the credential is minted as; it defaults toaws_profile,
so an account with one role needs a single key. An empty profile or region is left off the AWS
CLI calls, soAWS_PROFILEand the default chain work.- Transports: SSM (the default), an SSH bastion, an EC2 Instance
Connect Endpoint orkubectl port-forward. - SSH and SOCKS tunnels with a real data-path health check, and
openfortivpnwith SAML and an
optional privilege helper so connecting never asks for your admin password.
🖥 The dashboard
- A split-pane TUI: Connect, Tunnel, Runbooks, AWS, VPN, Secrets, Create Env, Config, Help, Updates
and Logs. Terminal tabs run the store's client (psql,mysql,redis-cli,mongosh) next to
the logs, already logged in. A shortcuts pop-up (hor?) lists the keys of every panel. - AWS SSO sessions are discovered from your AWS config and can be curated and renamed in
den.yaml. - Secrets from SOPS, AWS Secrets Manager, KeePassXC and HashiCorp Vault: masked until revealed,
never written to disk or the log. - A Help panel with one topic per feature, searchable with
/.
📜 Runbooks
- Your scripts, one folder each with a
runbook.yaml, run with den's context (AWS profile,
region, live tunnel ports asDEN_PORT_*,DEN_CREDENTIAL_PROFILE). Each opens like a service,
with its logs, run history and a terminal in its folder. - Runbook sources: your team's runbooks from a git repository, pinned in
den.lock, updated only
when you ask, and asking again when a runbook changes. - Runbooks can be written by an agent:
den runbook new --agent claude, the Runbooks pane, or
den mcp.
🔧 Configuration and checks
den.yamlis found with-c, in the current directory or in the config directory;den paths
lists every file den uses. A JSON Schema (den schema) gives editors completion and validation.den config --checklists every problem with its line and a hint; the Config panel shows the
same list. Editing the file from the Config panel applies it when the editor closes, keeping the
connections of services that did not change.den init --profile Pwrites a starterden.yamlfrom what an AWS profile can see.den doctorchecks the tools, profiles, logins and ports a config needs and prints the install
command for your OS.
🤖 AI agents
den mcplets Claude Code, Cursor or another MCP client list services, open tunnels and run
runbooks. Credentials never leave den, production services need your confirmation, and what an
agent may reach is limited bymcp:inden.yaml.
📦 Install and updates
- Install with one command from the project's GitHub Releases (
install.sh,install.ps1), with
go install github.com/lukaszgard/den/cmd/den@latest, or from a release archive; every download is
checked against the release'schecksums.txt. - The Updates panel checks GitHub Releases and installs a new version in place.
updates.github_api
points it at a fork or a GitHub Enterprise server, andupdates.s3_bucketat a mirror you host.