Encode intention. Decode software.
A Bun-based AI coding-agent CLI — interviews, reviewed plans, gated execution, honest verification.
` | Retry last request · side question without touching history | | `/usage` · `/context` · `/compact` | Token usage, context breakdown, manual compaction | | `/theme` · `/config` · `/help` | Theme, runtime config, help | | `jeo autopilot status` | Ratchet status field with score direction, keep/revert counts, and next action | ## Spec-first workflow Requirements → plan → approval → execution → verification, carried through `.jeo/state/` with **real, blocking gates** at every handoff: ```bash jeo deep-interview "Describe what you want to build" jeo ralplan jeo approvejeo team jeo ultragoal ``` ``` ┌──────────────────────┐ │ deep-interview │ Socratic ambiguity gate · seed frozen when concrete └──────────┬───────────┘ │ .jeo/state/ .json ▼ ┌──────────────────────┐ │ ralplan │ Draft + repo-grounded critic → [OKAY] persisted └──────────┬───────────┘ │ requires [OKAY] verdict ▼ ┌──────────────────────┐ │ approve │ Schema + roles + [OKAY] — unlocks execution └──────────┬───────────┘ │ ▼ ┌──────────────────────┐ │ team │ Serial executor · run lock · mutation audit └──────────┬───────────┘ │ all tasks done ▼ ┌──────────────────────┐ │ ultragoal │ Honest verification — suite once, no fabrication └──────────────────────┘ ``` - **deep-interview** — Socratic loop with ambiguity scoring; freezes a seed only when criteria are concrete (vague-only criteria are refused) and the seed round-trips its own parser. A new idea never silently reuses a completed interview. - **ralplan** — drafting passes plus a **repo-grounded critic subagent gate**: the critic reads the actual repository, must return `[OKAY]`/`[ITERATE]`/`[REJECT]`, and the verdict is persisted. Invalid plans (schema, unknown roles) are never marked complete. - **approve** — validates the exact contract `team` executes (schema + roles) *and* requires the persisted `[OKAY]` consensus verdict. - **team** — serial plan executor with a cross-process run lock, stale-plan reset, per-task subagent contracts, a parent-side mutation audit (a "completed" task with zero observed writes is flagged), and failed-task markers that warn about partial edits on resume. - **ultragoal** — honest verification: the suite runs once as a global signal; criteria are recorded, never fabricated as individually passed. ## Verification hooks (self-correction) Enable hooks once globally (`"hooks": { "enabled": true }` in `~/.jeo/config.json`), then add a post-edit check per project; the agent sees failures and fixes them before it may call `done`: ```jsonc // .jeo/hooks.json { "enabled": true, "hooks": [ { "event": "post-turn", "match": { "tool": "edit|write" }, "run": "bun x tsc --noEmit" } ] } ``` Non-zero hook output is appended to the tool result the model reads (deduped per batch); a still-red hook triggers a `done` pushback naming the hook. ## Memory flow `jeo` keeps a **local-first, distilled project memory** under `.jeo/memory/` (no remote backend, zero native deps). Past sessions are distilled into an [OKF](docs/okf_mem/) concept bundle, and the next session injects only the relevant, budget-bounded slice back into the system prompt — hardened as DATA, never as instructions. Disable everything with `JEO_NO_MEMORY=1`. **Migration (`jeo memory-migrate`, one-shot · idempotent).** A legacy single-doc `MEMORY.md` is converted losslessly into the bundle: `## heading → type`, each bullet → a typed concept, indented lines → body; `index.md`/`log.md` are rebuilt and the original is renamed to `MEMORY.md.bak`. Re-running is a no-op once the bundle has concepts. **Rollback:** `JEO_MEMORY_LEGACY=1` ignores the bundle and reads `MEMORY.md`/`.bak` through the same injection-hardening (`JEO_NO_MEMORY=1` still wins over everything). ## Works beside your existing agent or bot | Tool or bot | Recommended jeo command | Boundary | | ----------- | ----------------------- | -------- | | Codex CLI | `jeo --tmux --worktree ` or `jeo` | `--worktree` names a jeo-managed sibling git worktree (basename → new branch); for an existing path, `cd` there first. | | Claude Code | `jeo --tmux` or `jeo --tmux --worktree ` | jeo does not become a Claude Code extension. | | OpenCode | `jeo` or `jeo --tmux` | External-runner workflow only. | | Claw Code | `jeo --tmux --worktree ` | jeo does not install into or replace Claw Code. | | External controller / bot | `jeo mcp serve` (MCP stdio server) | External controllers drive jeo over the MCP tool contract, not scrollback scraping. | `--worktree ` runs jeo in an isolated sibling git worktree (reused if the path exists, else created on a branch named after the basename) so risky or reviewable work never touches your main checkout. `jeo mcp serve` exposes jeo's tools to any MCP-capable controller over stdio (`jeo mcp tools` lists them). Add `-q`/`--quiet` (or `JEO_QUIET=1`) to suppress startup banners, the welcome animation, release notes, and resume hints so jeo runs cleanly beside another agent or is driven by a bot — `-p`/`--print` implies quiet. ## Local models ```bash ollama pull qwen2.5:0.5b export JEO_DEFAULT_MODEL=ollama/qwen2.5:0.5b jeo doctor && jeo ``` ## Configuration - Global config: `~/.jeo/config.json` (model picks are MRU-persisted) - Project state/sessions: ` /.jeo/` ```bash ANTHROPIC_API_KEY=... OPENAI_API_KEY=... GEMINI_API_KEY=... JEO_DEFAULT_MODEL=... # e.g. ollama/qwen2.5:0.5b OLLAMA_HOST=http://localhost:11434 JEO_TUI_THEME=cosmic # cosmic/matrix/solar/red-claw/blue-crab/mono/aurora/synthwave/sakura JEO_TUI_ALT_SCREEN=1 # legacy alt-screen turn (default: inline scrollback) JEO_STEP_BASE=24 # dynamic step budget: rolling base JEO_STEP_HARD_CAP=600 # absolute termination guarantee JEO_STREAM_MAX_MS=300000 # opt-in overall stream deadline (default off; bounds slow-drip streams) JEO_STREAM_IDLE_MS=300000 # per-chunk idle cap (default 300s); raise for slow/local backends silent before first token JEO_TOOL_OUTPUT_MAX=4000 # model-visible tool output cap (full output spills to artifacts) ``` Retry behavior is tunable via `retry` in `~/.jeo/config.json` (`requestMaxRetries`, `streamMaxRetries`, `rateLimitRetries`, `failFastStatuses`, …). The step budget is dynamic by default — it extends while recent tool calls show novel progress and consolidates with a wrap-up when stalled; `--max-steps N` restores a bounded flow. ## Skill migration and bundled skill inspection When moving a workflow into jeo, inspect the bundled defaults before installing or overwriting anything: ```bash jeo skills list # bundled + user + project skills, with discovery dirs jeo skills read ralplan # print one skill's full SKILL.md jeo skills sync --check # report drift vs ~/.jeo/skills (non-zero exit on drift) ``` `jeo skills sync` installs the bundled workflow skills (deep-interview, deep-dive, ralplan, team, ultragoal) into `~/.jeo/skills` and **preserves existing local files by default** — a differing local copy is reported as `preserved`, never clobbered. If `--check` flags a missing or different file, compare it with `jeo skills read ` first; use `jeo skills sync --force` only when you intentionally want to replace local default workflow skill files. Target a different dir with a trailing path argument (or `JEO_CONFIG_DIR`), and add `--json` for the structured `SkillSyncResult`. ## Development jeo is pure TypeScript on Bun with **zero native dependencies**, so the global `jeo` command can run this checkout's source directly — no build step, hot to every edit. ```bash bun install bun run dev:link # symlink `jeo` -> /src/cli.ts into ~/.local/bin bun run dev:doctor # report whether global `jeo` runs this source (linked/drift/missing) ``` `dev:link` refuses to proceed if another `jeo` shadows the managed link earlier on `PATH` (override the destination with `JEO_DEV_LINK_DIR`) and runs a `--version` smoke test. `dev:doctor` exits non-zero when the resolved `jeo` is a compiled binary or an installed copy rather than this source. Run from source without linking via `bun src/cli.ts --help`. Bundled workflow skills live in source at `src/prompts/skills/ /SKILL.md`; verify with `bun run typecheck` and `bun test`. ## Publishing CI publishes via `.github/workflows/npm-publish.yml` — triggered by a published GitHub release, or manually with `workflow_dispatch` (optional dry-run). The workflow typechecks, tests, verifies the token (`npm whoami`), then runs `npm publish --provenance`. Required npm token permissions (repository secret `NPM_TOKEN`): - A **Granular Access Token** with Read/Write access to the `jeo-code` package, or a classic **Automation** token - "**bypass 2FA** for publishing" must be allowed — Automation tokens always bypass; granular tokens need the option enabled ## Acknowledgements Huge thanks to [gajae-code](https://github.com/Yeachan-Heo/gajae-code) for the inspiration. ## Changelog - **[0.7.21]** (2026-06-26) — Global llm-wiki vault integration, Gemini/Antigravity thinking indicators, generous file-reading windows, and autopilot flag validation. Adds a shared global wiki root configuration with a /wiki slash command, fires reasoning start signals up front for Gemini/Antigravity models, adjusts the large-file reading discipline to use generous windows, and validates autopilot goal and integer flags. - **[0.7.20]** (2026-06-26) — OKF concept-memory retrieval gains a hybrid reranker ported from memsearch. Injection priority no longer rides one raw keyword score — it fuses two complementary ranked channels by Reciprocal Rank Fusion (RRF): IDF-weighted lexical relevance (the sparse/BM25 channel, so rare discriminating terms steer recall) and concept-graph proximity (the local dense/semantic-neighbour channel, so a hub linked from multiple query hits surfaces even with no keyword of its own). All embedding-free and deterministic, layered atop the existing failure-first tier and pinned-invariant reserved budget. - **[0.7.19]** (2026-06-26) — The live model picker gains gajae-code's `/model` provider tabs, and skill invocation is consolidated onto a single `$` entrypoint. The picker now shows an `ALL` tab plus one tab per provider that `tab`/`shift+tab` cycles, and skills (including their declared aliases) are invoked only via `$` — the slash palette stays builtins-only. - **[0.7.18]** (2026-06-26) — Slash-command discovery and the `/model` flow reach gajae-code parity. The slash palette/autocomplete now fuzzy-matches command names (with a description fallback for intent-style queries), resolved skills can contribute their own `/aliases` as real dispatchable commands, and `/model` runs gjc's two-menu target → reasoning flow so a picked model can be assigned to the default or any subagent role with its own thinking budget. - **[0.7.17]** (2026-06-25) — Developer workflow parity (gjc `dev:link`/`dev:doctor`, adapted for jeo's zero-native-dep Bun runtime): the global `jeo` command can be linked to run this checkout's source hot to every edit, with a drift doctor that flags when `jeo` resolves to a compiled binary or an installed copy instead. README gains "Skill migration and bundled skill inspection" + "Development" sections. Also ships OKF concept-memory search/scoring with budget-aware injection and a round of workflow-prompt hardening (anti-punt, todo-first planning, verdict discipline) that keeps every loop escape hatch intact. See [CHANGELOG.md](CHANGELOG.md) for the full history.