Help us shape the future of Go! Take the 2026 Go Developer Survey

codemeld

module
v0.4.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: MIT

README

codemeld

An agentic code editor for the terminal — without vendor lock-in, permission re-prompt fatigue, or telemetry.

codemeld is a coding assistant you run in your own projects, from your own terminal. You choose the model provider and the version-control system, you decide what leaves your machine, and you approve a command once instead of every time it's written slightly differently.

Status: v0.4.6 is the latest release; v0.4.5 was the first public release. See the roadmap for what's planned.


Before you try it

  • It is alpha software and under heavy development.
  • AI was used in its development.

Why try it

  • Your choice of provider: ChatGPT subscription, OpenRouter, or Venice.
  • Tuned OpenRouter routing: pick providers by speed or best value, and cap the price per model so you get speed without the most expensive providers.
  • Your choice of version control: Git, Jujutsu, and Mercurial work out of the box. Other systems are added with YAML templates.
  • Permission modes from read-only to auto-approved edits inside your project. See below.
  • No phone-home: no telemetry, analytics, crash reporter, or auto-updater.
  • Open formats: config and permissions are YAML, and each session is a JSON-lines log you can query with jq.

Permission modes

A mode sets how much the agent may do before it stops to ask. It never replaces the permission system.

Mode What the agent may do Changes
Plan Read, search, and plan. Denied. Write tools aren't offered to the model, and mutating requests to codemeld's own tools are refused without a prompt. On a host with confined shell commands (below), Plan's shell commands run inside the boundary, where writes fail.
Build (default) Normal work. Prompted, unless an existing grant covers the request.
Auto edits Continuous work with fewer interruptions. Auto-approved inside your project: creating, editing, making folders, and moving files. Creating, editing, and making folders are also auto-approved inside a declared writable_folders entry (see below). Deletes, version-control changes, and any other change outside the project still prompt.
  • Switch with /mode <plan|build|auto-edits>, or press shift+tab to cycle through them.
  • Auto edits covers only those four operations, and only when the target, after symlinks are resolved, is inside the project, or, for creating, editing, and making folders, inside a folder declared in writable_folders while shell commands are confined (below) and no settings file is broken. A move needs both ends inside the project; a declared folder never auto-approves a delete or a move.
  • Auto-edit approvals are per call. Nothing is stored, so switching back to Build applies from the next tool call.
  • Shell commands follow their own rules. On a supported Linux host they run inside a boundary (below). Elsewhere they prompt, and Plan refuses mutating ones.

Full rules: docs/permissions.md.

Confined shell commands (Linux)

On Linux amd64 and arm64 hosts with Landlock ABI 3 or newer (kernel 6.2+) that pass codemeld's startup self-test, Plan and Auto edits shell commands run inside a fixed boundary built from Landlock, seccomp, and resource limits. No setting turns it off.

  • Plan: no filesystem writes (except /dev/null) and no network. A blocked write or network call simply fails.
  • Auto edits: writes are limited to the project's top-level files and folders (not .codemeld, and not symlinks that leave the project), plus a private temp folder for the session and each folder declared in writable_folders. Commands get that private folder as TMPDIR; codemeld adds no other temp grant, so /tmp and the launch $TMPDIR are writable only when an effective declared writable_folders entry covers where they resolve, or when they resolve inside a granted project top-level entry (never the project root itself, .codemeld, or an entry resolving outside the project), and blocked and protected paths stay carved out. Approving network access for one command opens sockets for that command only.
  • Every confined command can read the filesystem except ~/.codemeld and your blocked paths, and cannot write ~/.codemeld or <project>/.codemeld.
  • Build shell commands always run outside the boundary, with ordinary prompts.

The status bar shows sandbox: on, sandbox: off, or sandbox: unavailable. unavailable has two meanings. If the self-test failed or the host is unsupported, the boundary is off, so Plan and Auto edits use ordinary permission behavior: prompts, and Plan's usual refusals. If the self-test passed but a settings file's blocked-path list is broken, commands stay confined, and every shell command asks until the file is fixed, except one you already denied this turn (see the broken-settings case for version-control tool calls). /status shows the reason. What the boundary does not cover is in SECURITY.md; fallback cases are in docs/architecture.md.


Runs where developers work

  • Linux is the tested target. macOS and FreeBSD build but are untested. Windows is not supported.
  • One binary with no runtime, npm install, Python virtualenv, or Docker. Built with mise run build, it is static.
  • Release binaries are Linux-only. Linux amd64 and arm64 binaries are attached to each GitHub release. Elsewhere, install with go install or build from source.
  • Confined shell commands are Linux amd64/arm64 only. Elsewhere the status bar shows sandbox: unavailable.
  • The structured move tool is Linux-only. Elsewhere it refuses to move anything rather than risk overwriting a destination.

Install

From Binaries

See Releases

With the Go toolchain

Needs the Go version on the go line of go.mod (currently 1.26.9).

go install codemeld.dev/codemeld/cmd/codemeld@latest

The binary lands in $(go env GOBIN), or $(go env GOPATH)/bin when GOBIN is unset. Put that folder on your $PATH.

From source

Requires mise, which manages the Go version.

git clone https://github.com/commonforge-dev/codemeld
cd codemeld
mise install        # installs the Go version declared in mise.toml
mise run build      # produces ./codemeld

Then follow the steps below, using ./codemeld in place of codemeld.


First run

  1. Run codemeld once. It writes ~/.codemeld/global/settings.yaml, with comments explaining each key, and exits.

  2. Run it in a project: cd ~/code/myproject && codemeld

  3. Connect a provider.

    • API key (OpenAI Platform, OpenRouter, or Venice): type /connect, pick the provider, and paste its key. The key is hidden as you type, checked by loading the provider's models, and saved to the global settings file only if that check succeeds. /connect openrouter skips the picker.
    • ChatGPT subscription (no API key): run codemeld auth login openai-chatgpt in your shell. This opens a browser sign-in, with a device-code fallback.

    A ChatGPT subscription and the OpenAI Platform are separate, separately billed options.

    Without the app (for CI or servers): set OPENAI_API_KEY, which takes precedence over a saved key, or add api_key under provider.openai, provider.openrouter, or provider.venice in the settings file.

    Check your setup with codemeld auth status. It prints no secrets; add --json for machine-readable output.

  4. Resume a session in the same folder: codemeld --resume lists resumable sessions, and codemeld --resume <id> opens one.

Keep the global settings file private. It is written with mode 0600, but it holds plaintext provider API keys and your ChatGPT session token (there is no OS keychain support). Don't commit it, paste it into bug reports, or sync it to untrusted places.


Configuration

File Purpose
~/.codemeld/global/settings.yaml Provider keys, ChatGPT login, defaults, global permissions
<project>/.codemeld/settings.yaml Project overrides. Folder approvals are saved beside it in settings.local.yaml.
~/.codemeld/global/vcs/ and <project>/.codemeld/vcs/ VCS templates for git, hg, jj, or your own
AGENTS.md Project guidance for the agent
~/.codemeld/sessions/ Per-session transcripts and event logs

By default, codemeld reads only the .codemeld/settings.yaml in the folder you launch from. To let it search upward for the nearest one, set discovery.boundary: project-root in the global settings file; project files reject that key.


Learn more

Bug reports and design feedback are welcome. See CONTRIBUTING.md.

Repository: github.com/commonforge-dev/codemeld · Website: codemeld.dev (in development)

License: MIT. See LICENSE.

Directories

Path Synopsis
cmd
codemeld command
Entry point for the codemeld CLI binary; delegates argument parsing and dispatch to internal/cli.
Entry point for the codemeld CLI binary; delegates argument parsing and dispatch to internal/cli.
internal
agent
Parallel agent work scheduling: runs a single assistant turn's independent work units up to agent.max_concurrency at a time, while serializing on declared dependencies and conflicting write targets.
Parallel agent work scheduling: runs a single assistant turn's independent work units up to agent.max_concurrency at a time, while serializing on declared dependencies and conflicting write targets.
agentinstr
Assembles the single synthetic system message sent on every provider request: the active mode's product-authored base prompt, the environment block, and the loaded AGENTS.md instructions, in that fixed order.
Assembles the single synthetic system message sent on every provider request: the active mode's product-authored base prompt, the environment block, and the loaded AGENTS.md instructions, in that fixed order.
authstate
Parse, classify, and persist the OpenAI ChatGPT session stored as plaintext under auth.openai-chatgpt in the global settings file.
Parse, classify, and persist the OpenAI ChatGPT session stored as plaintext under auth.openai-chatgpt in the global settings file.
authstatus
Offline OpenAI auth-status report backing `codemeld auth status`: classifies the OpenAI Platform (API-key) and OpenAI ChatGPT (subscription) providers from OPENAI_API_KEY and the global settings file only, without printing secrets, composing project-local settings, constructing a provider client, or making any network call.
Offline OpenAI auth-status report backing `codemeld auth status`: classifies the OpenAI Platform (API-key) and OpenAI ChatGPT (subscription) providers from OPENAI_API_KEY and the global settings file only, without printing secrets, composing project-local settings, constructing a provider client, or making any network call.
bootstrap
Production permission-authorizer assembly: binds the landed permission seams — the in-memory grant table, the turn-scoped approval cache, the gated prompt, persistence-with-degradation, and the event emitters — into one dispatch.Authorizer that drives permissions.Authorize for every production tool/shell permission check.
Production permission-authorizer assembly: binds the landed permission seams — the in-memory grant table, the turn-scoped approval cache, the gated prompt, persistence-with-degradation, and the event emitters — into one dispatch.Authorizer that drives permissions.Authorize for every production tool/shell permission check.
cli
`codemeld auth login` wiring: starts the OpenAI ChatGPT browser/device login flow and persists the resulting session under auth.openai-chatgpt only after upstream login succeeds, while refusing a ChatGPT login for the API-key-only `openai` provider.
`codemeld auth login` wiring: starts the OpenAI ChatGPT browser/device login flow and persists the resulting session under auth.openai-chatgpt only after upstream login succeeds, while refusing a ChatGPT login for the API-key-only `openai` provider.
config
Session-lifetime composed-config cache: the single read source for one run.
Session-lifetime composed-config cache: the single read source for one run.
dispatch
Raw shell dispatch: normalize a whole command, resolve one request/execution path scope, authorize each stage or the literal subject, then run direct pipelines or the literal form through the shared runner —.
Raw shell dispatch: normalize a whole command, resolve one request/execution path scope, authorize each stage or the literal subject, then run direct pipelines or the literal form through the shared runner —.
enforce
Package enforce reports the session-level execution capability.
Package enforce reports the session-level execution capability.
events
Event append API: validates a payload, coerces invalid UTF-8 to U+FFFD, mints a UUIDv7 record id, stamps the canonical timestamp, and appends the event record to the active session store.
Event append API: validates a payload, coerces invalid UTF-8 to U+FFFD, mints a UUIDv7 record id, stamps the canonical timestamp, and appends the event record to the active session store.
filetools
codemeld-owned ignore filtering: a single-format `codemeldignore` matcher plugged into the walker's traversal seam, honored by glob/grep/list/tree by default in place of native .gitignore/.hgignore parsing.
codemeld-owned ignore filtering: a single-format `codemeldignore` matcher plugged into the walker's traversal seam, honored by glob/grep/list/tree by default in place of native .gitignore/.hgignore parsing.
fserrors
Package fserrors maps filesystem errnos to codemeld's canonical error-category vocabulary.
Package fserrors maps filesystem errnos to codemeld's canonical error-category vocabulary.
fsutil
Atomic file write via a sibling temp file plus rename, fsyncing the temp file and parent directory.
Atomic file write via a sibling temp file plus rename, fsyncing the temp file and parent directory.
ids
Package ids mints and validates the UUIDv7 identifiers used for sessions and records.
Package ids mints and validates the UUIDv7 identifiers used for sessions and records.
locks
Package locks wraps gofrs/flock with typed-reason acquire helpers for the kernel-managed advisory locks required by and 440b, plus a non-blocking single-attempt try (TryAcquire) for the retention pruner.
Package locks wraps gofrs/flock with typed-reason acquire helpers for the kernel-managed advisory locks required by and 440b, plus a non-blocking single-attempt try (TryAcquire) for the retention pruner.
mode
Run-scoped holder for the active interaction mode and the Source the next interaction_mode event must record, mirroring model.ActiveState.
Run-scoped holder for the active interaction mode and the Source the next interaction_mode event must record, mirroring model.ActiveState.
model
Run-scoped holder for the active model Selection and the Source the next model_turn must record, with a distinct "no model selected yet" state.
Run-scoped holder for the active model Selection and the Source the next model_turn must record, with a distinct "no model selected yet" state.
openaiauth
OpenAI Codex OAuth device-authorization-grant primitives (RFC 8628) for the explicit interactive fallback when browser/loopback login cannot be used.
OpenAI Codex OAuth device-authorization-grant primitives (RFC 8628) for the explicit interactive fallback when browser/loopback login cannot be used.
paths
Package paths resolves the user's home directory and expands ~-prefixed paths against it.
Package paths resolves the user's home directory and expands ~-prefixed paths against it.
permissionpersist
Package permissionpersist persists permission grants.
Package permissionpersist persists permission grants.
permissions
Capability tool-subjects: reserved grant subjects that fold a family of concrete file-tool subjects so one approval authorizes every member.
Capability tool-subjects: reserved grant subjects that fold a family of concrete file-tool subjects so one approval authorizes every member.
provider
OpenAI-compatible API-key GET /models discovery: a redirect-refusing, credential-safe request returning sanitized model ids plus whitelisted reasoning-effort capability metadata.
OpenAI-compatible API-key GET /models discovery: a redirect-refusing, credential-safe request returning sanitized model ids plus whitelisted reasoning-effort capability metadata.
runner
Package runner is the single internal command runner every tool invocation routes through.
Package runner is the single internal command runner every tool invocation routes through.
securitystate
Classification of the run's protected settings files and blocked paths, and the typed refusal a covered structured-tool call produces before it is authorized.
Classification of the run's protected settings files and blocked paths, and the typed refusal a covered structured-tool call produces before it is authorized.
sessionfailures
Session write-failure protocol: the per-turn handler that records a failed atomic session write and the clean-shutdown final-flush retry.
Session write-failure protocol: the per-turn handler that records a failed atomic session write and the clean-shutdown final-flush retry.
sessions
Explicit session deletion plus the shared lock-and-unlink core the retention pruner reuses.
Explicit session deletion plus the shared lock-and-unlink core the retention pruner reuses.
sessionturn
Package sessionturn owns the pre-turn boundary that makes user input durable on disk before a model-provider request is issued.
Package sessionturn owns the pre-turn boundary that makes user input durable on disk before a model-provider request is issued.
subagent
Package subagent runs one bounded child agent conversation in a private, memory-only session and reports its outcome as a bounded Result.
Package subagent runs one bounded child agent conversation in a private, memory-only session and reports its outcome as a bounded Result.
subagenttool
Package subagenttool registers the delegate tool, the production caller that hands one bounded piece of work to a child agent confined to caller-declared write, delete, move, and directory scopes.
Package subagenttool registers the delegate tool, the production caller that hands one bounded piece of work to a child agent confined to caller-declared write, delete, move, and directory scopes.
testsupport
Package testsupport holds small helpers shared across package test suites.
Package testsupport holds small helpers shared across package test suites.
toolactivity
Package toolactivity formats tool-activity display lines.
Package toolactivity formats tool-activity display lines.
tools
Package tools defines the structured-tool registry, the Tool interface, and the shared tool-dispatch Result type.
Package tools defines the structured-tool registry, the Tool interface, and the shared tool-dispatch Result type.
trust
Package trust records which project roots the user approved to contribute their own settings layer to a run.
Package trust records which project roots the user approved to contribute their own settings layer to a run.
tui
Package tui implements the terminal user interface shell: the tview application, the transcript pane, and the input area.
Package tui implements the terminal user interface shell: the tview application, the transcript pane, and the input area.
turn
Builds the streaming provider.Request from the active model selection and the session's text conversation history.
Builds the streaming provider.Request from the active model selection and the session's text conversation history.
vcs
Boundary-aware upward VCS auto-detection: innermost-match selection across built-in and user detectors.
Boundary-aware upward VCS auto-detection: innermost-match selection across built-in and user detectors.
vcs/builtin
Package builtin embeds codemeld's built-in VCS templates (git, hg, jj) as copy-and-modify reference bytes.
Package builtin embeds codemeld's built-in VCS templates (git, hg, jj) as copy-and-modify reference bytes.
Package schemas owns the embedded JSON Schema documents used both at runtime for settings validation and by editors that discover the on-disk files.
Package schemas owns the embedded JSON Schema documents used both at runtime for settings validation and by editors that discover the on-disk files.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL