ascendant
v0.3.0
Published
A CLI operating system for agent-driven software development. Persistent state, replaceable intelligence.
Maintainers
Readme
Ascendant
A CLI operating system for agent-driven software development.
Persistent State. Replaceable Intelligence.
Ascendant has no intelligence. It does not think, reason, or write code. It presents as one native chat agent while routing each turn to a real coding-agent product — Claude Code, Codex, Cursor, Gemini, whatever comes next — with the same persistent project context.
The project, not the conversation, is the source of truth.
Developer ⇄ Ascendant chat → (Claude · Codex · Cursor) → .ascendant/ → RepositoryWithout an attached agent, Ascendant does nothing. Without Ascendant, every agent starts from scratch. Together they form an agent-driven development environment.
Install
npm install -g ascendantRequires Node ≥ 18. Then run ascendant --help.
From source (local dev)
npm install && npm run build && npm linkQuick start
ascendant init # create .ascendant/ in the current repo
ascendant status # see the objective, state, and active tasks
ascendant # open native chat; ask it to do work
# or use status/tasks/handoff directly
ascendant handoff --completed "What I did" --next "What to do next"
ascendant resume # next agent: read the latest handoff + state, continueGoal: a brand-new agent continues development in under 30 seconds.
The .ascendant/ workspace
Everything lives alongside your repository, in plain Markdown/JSON/YAML — inspectable, editable, and version-controlled. No hidden memory, no proprietary storage.
.ascendant/
docs/
00-mission.md # why the project exists
10-project.md # features, stack, roadmap
20-architecture.md # technical architecture
30-conventions.md # engineering conventions
50-decisions.md # architecture decision record
state/
current.json # objective, branch, milestone, focus, blockers, session
tasks.json # task list with status / priority / dependencies
history/
handoffs/ # one timestamped handoff per session
config.yml # project name, version, agent settingsCommands
| Command | What it does |
| --- | --- |
| ascendant | Open the native Ascendant chat in an interactive terminal. |
| ascendant chat / ascendant repl | Explicit aliases for the native chat. |
| ascendant init [--force] | Scaffold .ascendant/. Seeds the active branch from git. --force overwrites an existing workspace. |
| ascendant status [--json] | Print the current objective, project state, and active (non-done) tasks. |
| ascendant start | Open a new session and print the onboarding bundle (doc pointers + state + tasks). |
| ascendant resume | Same bundle, led by the latest handoff — continue where the last agent stopped. |
| ascendant tasks <list\|add\|set\|rm> | Manage the task list from the CLI instead of hand-editing tasks.json. |
| ascendant handoff [flags] | Write a timestamped handoff for the next agent and close the session. |
ascendant handoff flags
The handoff auto-fills facts from your project: Modified Files (local git status),
Remaining Work (open tasks), and Known Issues (blockers). The narrative is supplied
by you — Ascendant never invents prose.
| Flag | Effect |
| --- | --- |
| --completed <text> | Summary of completed work. If omitted, reads piped stdin. |
| --next <text> | Recommended next action. |
| --remaining <text> | Note appended to the auto-derived remaining work. |
| --issues <text> | Note appended to the auto-derived known issues. |
| --author <name> | Handoff author (defaults to agent.defaultHandoffAuthor in config). |
| --no-git | Skip git inspection of modified files. |
| --edit | Open the generated handoff in $EDITOR. |
# Pipe completed-work prose in, set the next action explicitly:
echo "Implemented login form + validation" | ascendant handoff --next "Wire up the API"ascendant tasks
Edit the task list without touching tasks.json by hand. Ids are auto-assigned (T-001, …).
| Command | Effect |
| --- | --- |
| tasks list [-a/--all] [--json] | List open tasks (or all with --all). Default subcommand. |
| tasks add <title> [-p <level>] [--deps <ids>] | Add a task (status todo). --deps is comma-separated. |
| tasks set <id> [-s <status>] [-p <level>] [-t <title>] [--add-deps <ids>] [--rm-deps <ids>] | Update a task. |
| tasks rm <id> | Remove a task. |
status ∈ todo | in_progress | blocked | done; priority ∈ low | medium | high.
ascendant tasks add "Wire up the API" --priority high --deps T-001
ascendant tasks set T-002 --status in_progress
ascendant tasks listNative Chat (v0.3)
Ascendant can be the CLI you actually work in. Run ascendant to open a polished line-based
chat that looks like Ascendant, not like a wrapper around another tool. Under the hood,
each turn is routed to a coding-agent product — Claude Code, Codex, or Cursor — driven
headlessly in structured-output mode. Ascendant parses that stream, renders it in one
consistent style, keeps provider session ids for conversation continuity, and captures the
result back into .ascendant/.
Ascendant itself stays intelligence-free: it is the native interface and shared memory layer;
the backing provider does the reasoning. The active provider is shown only as subtle
attribution (via claude, via codex, etc.).
$ ascendant
ascendant · ready
via Claude Code
Type a message, or /help.
❯ add a CONTRIBUTING.md describing the dev setup
● Ascendant via claude
…streamed response rendered in Ascendant's style…
1 file(s) changed: CONTRIBUTING.md
❯ /provider codex # same project context now goes to a different vendor
now via Codex
❯ /status
❯ /exitChat commands: /providers, /provider [name], /model [name], /status, /handoff,
/help, /exit. Each turn is logged to .ascendant/history/sessions/<id>.jsonl.
Provider configuration (optional)
Add a providers block to .ascendant/config.yml (entirely optional — omit it and Ascendant
uses the first installed agent in conservative mode):
providers:
default: claude # which agent to start with
autoApprove: false # true = bypass approvals/sandbox (use only in trusted/sandboxed envs)
claude: { model: claude-opus-4-8 }
codex: { extraArgs: ["--add-dir", "../shared"] }Safety: by default each agent runs in its most conservative working mode (edits allowed,
full bypass off). autoApprove: true grants full bypass — only use it in sandboxed/trusted
environments.
Agent lifecycle
Every coding agent follows the same loop — no prior conversation required:
- Start a fresh session
ascendant resume(orstart) — read project state + latest handoff- Do the development work
- Update
.ascendant/state (objective, tasks, blockers) ascendant handoff— record what happened and what's next- Exit
Design principles
- Stateless agents. Every session is disposable; none rely on prior conversations.
- Persistent project state. All knowledge lives in
.ascendant/, in the repo. - Human-readable first. Plain text you can read, edit, diff, and review.
- Replaceable intelligence. Swap the agent anytime; the operating system remains.
Development
npm run typecheck # tsc --noEmit
npm test # vitest
npm run build # tsup → dist/cli.jsScope
v0.3 adds a native chat interface and provider session continuity, but Ascendant stays intelligence-free — it does not decompose or sequence work itself. Still out of scope: a meta/orchestration layer, autonomous planning, GitHub/Linear/Notion integration, scheduling, semantic search, vector databases, and automatic PR generation. (Reading local git branch/status is not GitHub integration — there are no network calls.)
License
MIT
