jeo-code 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +342 -0
  2. package/package.json +57 -0
  3. package/scripts/install.sh +322 -0
  4. package/scripts/uninstall.sh +30 -0
  5. package/src/agent/compaction.ts +75 -0
  6. package/src/agent/config-schema.ts +87 -0
  7. package/src/agent/context-files.ts +51 -0
  8. package/src/agent/engine.ts +208 -0
  9. package/src/agent/json.ts +87 -0
  10. package/src/agent/loop.ts +22 -0
  11. package/src/agent/session.ts +198 -0
  12. package/src/agent/state.ts +199 -0
  13. package/src/agent/subagents.ts +149 -0
  14. package/src/agent/tools.ts +355 -0
  15. package/src/ai/index.ts +11 -0
  16. package/src/ai/model-catalog-compat.ts +119 -0
  17. package/src/ai/model-catalog.ts +97 -0
  18. package/src/ai/model-discovery.ts +148 -0
  19. package/src/ai/model-enrich.ts +75 -0
  20. package/src/ai/model-manager.ts +178 -0
  21. package/src/ai/model-picker.ts +73 -0
  22. package/src/ai/model-registry.ts +83 -0
  23. package/src/ai/provider-status.ts +77 -0
  24. package/src/ai/providers/anthropic.ts +87 -0
  25. package/src/ai/providers/errors.ts +47 -0
  26. package/src/ai/providers/gemini.ts +77 -0
  27. package/src/ai/providers/ollama.ts +54 -0
  28. package/src/ai/providers/openai.ts +67 -0
  29. package/src/ai/sse.ts +46 -0
  30. package/src/ai/types.ts +37 -0
  31. package/src/auth/callback-server.ts +195 -0
  32. package/src/auth/flows/anthropic.ts +114 -0
  33. package/src/auth/flows/google.ts +120 -0
  34. package/src/auth/flows/index.ts +50 -0
  35. package/src/auth/flows/openai.ts +130 -0
  36. package/src/auth/index.ts +23 -0
  37. package/src/auth/oauth.ts +80 -0
  38. package/src/auth/pkce.ts +24 -0
  39. package/src/auth/refresh.ts +60 -0
  40. package/src/auth/storage.ts +113 -0
  41. package/src/auth/types.ts +26 -0
  42. package/src/cli/index.ts +1 -0
  43. package/src/cli/runner.ts +245 -0
  44. package/src/cli.ts +17 -0
  45. package/src/commands/approve.ts +63 -0
  46. package/src/commands/auth.ts +144 -0
  47. package/src/commands/chat.ts +37 -0
  48. package/src/commands/deep-interview.ts +239 -0
  49. package/src/commands/doctor.ts +250 -0
  50. package/src/commands/evolve.ts +191 -0
  51. package/src/commands/launch.ts +745 -0
  52. package/src/commands/mcp.ts +18 -0
  53. package/src/commands/models.ts +104 -0
  54. package/src/commands/ralplan.ts +86 -0
  55. package/src/commands/resume.ts +6 -0
  56. package/src/commands/setup-helpers.ts +93 -0
  57. package/src/commands/setup.ts +190 -0
  58. package/src/commands/skills.ts +38 -0
  59. package/src/commands/team.ts +337 -0
  60. package/src/commands/ultragoal.ts +102 -0
  61. package/src/index.ts +31 -0
  62. package/src/mcp/index.ts +3 -0
  63. package/src/mcp/protocol.ts +45 -0
  64. package/src/mcp/server.ts +97 -0
  65. package/src/mcp/tools.ts +156 -0
  66. package/src/skills/catalog.ts +61 -0
  67. package/src/tui/app.ts +297 -0
  68. package/src/tui/components/ascii-art.ts +340 -0
  69. package/src/tui/components/autocomplete.ts +165 -0
  70. package/src/tui/components/capability.ts +29 -0
  71. package/src/tui/components/code-view.ts +146 -0
  72. package/src/tui/components/color.ts +172 -0
  73. package/src/tui/components/config-panel.ts +193 -0
  74. package/src/tui/components/evolution.ts +305 -0
  75. package/src/tui/components/footer.ts +95 -0
  76. package/src/tui/components/forge.ts +167 -0
  77. package/src/tui/components/index.ts +7 -0
  78. package/src/tui/components/layout.ts +105 -0
  79. package/src/tui/components/meter.ts +61 -0
  80. package/src/tui/components/model-picker.ts +82 -0
  81. package/src/tui/components/provider-picker.ts +42 -0
  82. package/src/tui/components/select-list.ts +199 -0
  83. package/src/tui/components/slash.ts +34 -0
  84. package/src/tui/components/spinner.ts +49 -0
  85. package/src/tui/components/status.ts +45 -0
  86. package/src/tui/components/stream.ts +36 -0
  87. package/src/tui/components/themes.ts +86 -0
  88. package/src/tui/components/tool-list.ts +67 -0
  89. package/src/tui/index.ts +2 -0
  90. package/src/tui/renderer.ts +70 -0
  91. package/src/tui/terminal.ts +78 -0
  92. package/src/util/retry.ts +108 -0
  93. package/tsconfig.json +18 -0
package/README.md ADDED
@@ -0,0 +1,342 @@
1
+ # jeo-code (`joc`)
2
+
3
+ [![Bun Version](https://img.shields.io/badge/Bun-%3E%3D%201.3.14-blue?logo=bun)](https://bun.sh)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Build Status](https://img.shields.io/badge/Build-Passing-brightgreen)]()
6
+ [![Tests Status](https://img.shields.io/badge/Tests-348%20Passed-brightgreen)]()
7
+
8
+ > An interactive AI coding agent **and** a disciplined spec-first pipeline — one
9
+ > lean, pure-TypeScript CLI on Bun.
10
+ `jeo-code` is a single-package coding agent (binary `joc`) that you can use two ways:
11
+
12
+ - **Interactive agent** — run bare `joc` to chat with an agent that reads, writes,
13
+ edits, and runs commands in a loop until your request is done (with a live TUI).
14
+ - **Spec-first pipeline** — `deep-interview → ralplan → team → ultragoal`: crystallize
15
+ requirements before any code changes, plan, execute, then verify against acceptance criteria.
16
+
17
+ It re-implements the [`gajae-code`](https://github.com/Yeachan-Heo/gajae-code) (`gjc`)
18
+ workflow contract and adopts [`pi-mono`](https://github.com/badlogic/pi-mono) runtime
19
+ ergonomics (minimal tool loop, persistent sessions, compaction, project context) — with
20
+ **no native deps**: just Bun + TypeScript.
21
+
22
+ ```text
23
+ joc → interactive coding agent (TUI: live tools + status footer)
24
+
25
+ joc deep-interview → joc ralplan → joc approve → joc team → joc ultragoal
26
+ (Socratic clarify) (blueprint) (gate) (execute) (verify)
27
+
28
+ [Mutation Lock] — file edits blocked until ambiguity ≤ 20%
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Quick start
34
+
35
+ Install `joc` the same way you install `gjc` — a single Bun global install — then
36
+ launch it from whatever repository you want it to operate on:
37
+
38
+ ```bash
39
+ # 1. Install (gjc parity: one bun global install)
40
+ bun install -g jeo-code # npm registry (once published)
41
+ bun install -g github:akillness/jeo-code # GitHub shorthand
42
+ bun install -g git+https://github.com/akillness/jeo-code.git # explicit Git URL
43
+ # …or bootstrap Bun + install from the Git URL in one shot:
44
+ curl -fsSL https://raw.githubusercontent.com/akillness/jeo-code/main/scripts/install.sh | sh
45
+
46
+ # 2. Configure a provider + default model (interactive)
47
+ joc setup
48
+ # …or go fully local with Ollama, no key:
49
+ ollama pull qwen2.5:0.5b
50
+ export JOC_DEFAULT_MODEL=ollama/qwen2.5:0.5b
51
+
52
+ # 3. Verify the setup is reachable
53
+ joc doctor
54
+
55
+ # 4. Launch from the target repo (gjc-style entrypoints)
56
+ joc # interactive agent in the current checkout
57
+ joc --tmux # create/attach a joc-managed tmux session
58
+ joc --tmux --worktree ../joc-feature # isolate work in a dedicated git worktree
59
+ joc "add a /health route to server.ts and run the tests" # one-shot request
60
+ ```
61
+
62
+ **Requirements:** Bun `v1.3.14+` (the installer auto-installs it if missing; the CLI re-checks at startup).
63
+
64
+ ---
65
+
66
+ ## Installation
67
+
68
+ `joc` installs exactly like `gjc`: a single Bun global install that registers the
69
+ `joc` binary in `~/.bun/bin`. The installer also drops a compatibility symlink at
70
+ `~/.local/bin/joc` and auto-installs Bun (enforcing the `1.3.14` floor) when it is missing.
71
+
72
+ ```bash
73
+ bun install -g jeo-code # npm registry (gjc parity, once published)
74
+ bun install -g github:akillness/jeo-code # GitHub shorthand
75
+ bun install -g git+https://github.com/akillness/jeo-code.git # explicit Git URL
76
+ sh scripts/install.sh --repo https://github.com/akillness/jeo-code.git
77
+ sh scripts/install.sh --ref v0.1.0 # global install of a specific tag
78
+ sh scripts/install.sh --binary # compile a standalone binary (no bun at runtime)
79
+ sh scripts/uninstall.sh [--purge] # remove the bin + bun registry entry (--purge also wipes ~/.joc/)
80
+ ```
81
+
82
+ ### Registry-aware installs
83
+
84
+ `joc` does **not** mutate your npm registry by default. Use `--registry` for a one-shot
85
+ Bun install, and add `--persist-registry` only when you intentionally want the installer
86
+ to run `npm config set ...`.
87
+
88
+ ```bash
89
+ # One-shot registry for this install only
90
+ sh scripts/install.sh --npm --registry https://registry.npmjs.org/
91
+ sh scripts/install.sh --npm --registry https://npmjs.co.kr
92
+ sh scripts/install.sh --npm --registry https://your-company-registry.com
93
+
94
+ # Persist globally via npm config (official registry restore / mirror / private)
95
+ sh scripts/install.sh --npm --registry https://registry.npmjs.org/ --persist-registry
96
+ sh scripts/install.sh --npm --registry https://npmjs.co.kr --persist-registry
97
+ sh scripts/install.sh --npm --registry https://your-company-registry.com --persist-registry
98
+
99
+ # Scope-only registry (writes @my-org:registry, not the global registry)
100
+ sh scripts/install.sh --npm --scope @my-org --registry https://your-company-registry.com --persist-registry
101
+
102
+ # Project-pinned .npmrc instead of global npm config
103
+ sh scripts/install.sh --npm --registry https://registry.npmjs.org/ --project-npmrc
104
+
105
+ # Inspect / reset npm registry config
106
+ sh scripts/install.sh --print-registry
107
+ sh scripts/install.sh --delete-registry
108
+ ```
109
+
110
+ ### Publishing `jeo-code` to npm
111
+
112
+ `bun install -g jeo-code` resolves through the npm registry, so the package must be
113
+ published there. The package is configured for public npm publication
114
+ (`publishConfig.registry=https://registry.npmjs.org/`, `publishConfig.access=public`)
115
+ and keeps the executable bin as `joc -> src/cli.ts` with a Bun shebang.
116
+
117
+ ```bash
118
+ npm login --registry https://registry.npmjs.org/
119
+ bun run publish:npm
120
+ npm view jeo-code version bin --registry https://registry.npmjs.org/
121
+ bun install -g jeo-code
122
+ joc --version
123
+ ```
124
+
125
+ For CI/release publishing, add an npm token as the repository secret `NPM_TOKEN`,
126
+ then run the `Publish npm package` GitHub Action (dry-run or publish) or publish a
127
+ GitHub release. The workflow runs `bun install --frozen-lockfile`, `bun run typecheck`,
128
+ `bun test`, `npm pack --dry-run`, then `npm publish --provenance`.
129
+
130
+ Required npm token permissions:
131
+
132
+ 1. npmjs.com → account settings → **Access Tokens** → create an **Automation** token, or
133
+ a **Granular Access Token** with package publish/read-write permission.
134
+ 2. If the npm account has 2FA enabled, the token must be allowed to **bypass 2FA for
135
+ publishing**. A read-only token or granular token without 2FA bypass fails with:
136
+ `Two-factor authentication or granular access token with bypass 2fa enabled is required`.
137
+ 3. GitHub repo → Settings → Secrets and variables → Actions → set `NPM_TOKEN` to that token.
138
+ 4. Re-run the `Publish npm package` workflow. After it succeeds, verify:
139
+
140
+ ```bash
141
+ npm view jeo-code version bin --registry https://registry.npmjs.org/
142
+ bun install -g jeo-code
143
+ joc --version
144
+ ```
145
+
146
+ From a clone, `./install.sh` performs the dev install (`bun link`) so source edits
147
+ take effect immediately; `scripts/install.sh --help` lists every mode.
148
+
149
+ ```bash
150
+ ./install.sh # dev install from this clone (= scripts/install.sh --local)
151
+ ```
152
+
153
+ Local dev without installing (from the repo root):
154
+
155
+ ```bash
156
+ bun run start --help # = bun src/cli.ts --help
157
+ bun run typecheck # tsc -p tsconfig.json --noEmit
158
+ bun test # unit tests (61 files, 372 tests)
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Commands
164
+
165
+ | Command | What it does |
166
+ | --- | --- |
167
+ | `joc` / `joc launch ["request"]` | Interactive coding agent (TUI REPL, one-shot, or piped). `--tmux` (create/attach a joc tmux session), `--worktree <path>` (run in a dedicated git worktree), `--resume [id]`, `--list`, `--no-tui`, `--no-session`. |
168
+ | `joc setup` | Interactive provider/model picker (API key / browser OAuth / local), with live model probing. |
169
+ | `joc auth [login\|logout\|refresh\|status] [provider] [--token <bearer>]` | Real OAuth (PKCE) login + token storage with auto-refresh. |
170
+ | `joc doctor [--strict] [--json]` | Probe provider connectivity, credentials, and OAuth expiry; report if the default model is reachable. Colorized status on a TTY. `--strict` exits non-zero when it isn't; `--json` emits a machine-readable report for CI. |
171
+ | `joc deep-interview "<idea>" [--auto]` | Socratic requirements interview; freezes a spec when ambiguity ≤ 20%. `--auto` runs non-interactively (CI/pipes). |
172
+ | `joc ralplan` | Planner/Architect/Critic blueprint from the frozen seed. |
173
+ | `joc approve <plan-path>` | Approve the active plan blueprint; gates execution (`team` refuses to run until approved). Idempotent. |
174
+ | `joc team` | Per-task executor loop (shared tool engine) against the plan. |
175
+ | `joc ultragoal` | Verify acceptance criteria and write a report. |
176
+ | `joc models [name] [--catalog] [--caps] [--check]` | Live model list from logged-in (OAuth/API) accounts + aliases & provider credentials. `--catalog` shows the capability catalog (context/out/thinking/images), `--caps` merges live models with capabilities (`--thinking=<lvl>`/`--images`/`--long` filters), `--check` is a per-provider auth/reachability probe. |
177
+ | `joc skills [name]` | List bundled workflow skills; `joc skills <name>` prints details. |
178
+ | `joc resume [id]` | Resume the latest interactive session (or a specific id). |
179
+ | `joc chat "<msg>"` | Single-shot streaming chat (no tools) — renders the reply token-by-token. |
180
+ | `joc mcp [serve\|tools]` | Run `joc` as an MCP stdio server (set `JOC_MCP_PIPELINE=1` to also expose the pipeline tools). |
181
+ | `joc evolve [--step N] [--max M] [--animate] [--loop N] [--theme cosmic\|matrix\|solar\|mono] [--gradient] [--ascii] [--fit] [--width W] [--list] [--list-themes] [--json] [--no-color]` | Preview the **evolution TUI** identity — five ASCII-art stages with track + stage meter. `--gradient` truecolor (256/16/plain downgrade), `--theme` palettes, `--ascii` legacy-terminal fallback, `--fit`/`--width` terminal sizing, `--list`/`--list-themes`/`--json` for tooling. |
182
+
183
+ ---
184
+
185
+ ## Interactive agent
186
+
187
+ Run bare `joc` (or `joc launch`) for a conversational coding agent built on a shared,
188
+ hardened tool-call engine (`src/agent/engine.ts`). It calls `read` / `write` / `edit` /
189
+ `bash` / `find` / `search` in a loop until it signals done.
190
+
191
+ - **TUI** — on a TTY it renders a differential UI (live tool-call list, `joc thinking`
192
+ progress status, `joc forge` tool stats, and boxed previews for `bash` / `write` /
193
+ `read` / `edit` calls); `--no-tui`, piped input, and non-TTY fall back to a
194
+ plain `stream:complete` / `stream:error` event stream.
195
+ - **Evolution TUI** — the live view evolves with the agent's progress through five stages
196
+ (**Primordial Cell → Double Helix → Tool User → AI Coding Agent → Singularity**). The ASCII
197
+ art, spinner, progress meter, and footer track all advance in lockstep from one canonical
198
+ stage model (`src/tui/components/evolution.ts`); `finish()` records `Evolved to: <stage>`.
199
+ Preview it any time with `joc evolve` (try `--theme matrix --gradient --fit`). On a TTY the
200
+ live frame **fills the terminal** — art centered to the width, footer pinned to the bottom row —
201
+ and downgrades gracefully (truecolor→256→16→plain, unicode→ASCII) per terminal capability.
202
+ - **Model & provider control (live)** — `<Tab>` autocompletes slash commands and their
203
+ arguments: model ids, providers, and subagent roles. `/model` and `/models` pull the
204
+ **real model list from your logged-in (OAuth / API-key) accounts** via live discovery —
205
+ pick by id or `#N`, set the session model or save it as default. `/provider` switches
206
+ providers (and lists that provider's live models), and `/agents <role> [model]` pins a per-role
207
+ model for the `executor` / `planner` / `architect` / `critic` subagents. `/roles [tier model]`
208
+ sets the `smol`/`slow`/`plan` model tiers; `/thinking` spans `minimal`→`xhigh`; `/view` / `/diff`
209
+ / `/find` / `/search` give an in-TUI code view.
210
+ - **Sessions** — every turn is appended to `.joc/sessions/<id>.jsonl`; `joc launch --list`
211
+ and `joc launch --resume [id]` resume past conversations.
212
+ - **tmux orchestration (gjc parity)** — `joc --tmux` creates/attaches a leader session named
213
+ `joc-<branch>`; add `--worktree <path>` to run inside a dedicated git worktree (auto-created
214
+ on a branch named after the path) so edits and evidence stay isolated from your main checkout.
215
+ - **Project context** — the prompt auto-loads the first of `JEO.md` / `AGENTS.md` /
216
+ `.joc/context.md` / `CLAUDE.md`.
217
+ - **Compaction** — long conversations are summarized automatically to stay within the context window.
218
+ - **Progress guards** — if a (weak/local) model repeats the same tool call 3× or racks up 5
219
+ consecutive tool failures without signalling done, the loop stops with a clear message instead of burning steps.
220
+ - **Token usage** — each turn prints a `(N in / M out tokens)` footer; all four provider
221
+ adapters report usage in both blocking `call` and streaming modes.
222
+
223
+ ```bash
224
+ joc # REPL — slash: /model /models /provider /agents /roles /thinking /config /view /diff /find /search (Tab to autocomplete)
225
+ joc launch "fix the failing test" # one-shot
226
+ echo "summarize src/agent" | joc # piped / non-TTY (plain output)
227
+ joc launch --resume # resume the latest session (or --resume <uuid>)
228
+ joc --tmux # create/attach a joc-managed tmux session (named joc-<branch>)
229
+ joc --tmux --worktree ../joc-feature # isolate edits/evidence in a dedicated git worktree
230
+ ```
231
+
232
+ ---
233
+
234
+ ## Spec-first pipeline
235
+
236
+ Crystallize requirements before touching code. While a `deep-interview` is active, the
237
+ **MutationGuard** blocks code-mutating tools — `write`/`edit` outside `.joc/`, and `bash`
238
+ entirely — releasing once ambiguity ≤ 20%.
239
+
240
+ 1. **`joc deep-interview "<idea>"`** — Socratic loop scoring ambiguity across Goal clarity,
241
+ Constraint completeness, and Success/Acceptance criteria. Freezes a seed to
242
+ `.joc/seeds/seed-<slug>.yaml`.
243
+ 2. **`joc ralplan`** — multi-role (Planner/Architect/Critic) blueprint → `.joc/plans/plan-<slug>.yaml`.
244
+ 3. **`joc approve <plan-path>`** — approval gate: marks the plan approved so `team` will execute it.
245
+ 4. **`joc team`** — executes plan tasks via the shared tool engine; checkpoints to `.joc/state/team-state.json`.
246
+ 5. **`joc ultragoal`** — runs acceptance checks and writes `.joc/state/ultragoal-report.md`.
247
+
248
+ ---
249
+
250
+ ## Providers, OAuth & local models
251
+
252
+ Routing is inferred from the model id; credentials resolve from `~/.joc/config.json` (or env).
253
+
254
+ | Provider | Model id example | Credential |
255
+ | --- | --- | --- |
256
+ | Anthropic | `claude-3-5-sonnet` | `ANTHROPIC_API_KEY` or OAuth (`ANTHROPIC_OAUTH_TOKEN` / `CLAUDE_CODE_OAUTH_TOKEN`) |
257
+ | OpenAI | `gpt-4o` / `openai/<model>` | `OPENAI_API_KEY` or `OPENAI_OAUTH_TOKEN` |
258
+ | Gemini | `gemini-2.5-flash` | `GEMINI_API_KEY` or `GEMINI_OAUTH_TOKEN` |
259
+ | Ollama (local) | `ollama/qwen2.5:0.5b` | none — offline via `OLLAMA_HOST` (default `http://localhost:11434`) |
260
+ | OpenAI-compatible (LM Studio / vLLM / llama.cpp) | `openai/<model>` | optional key; set `openaiBaseUrl` / `OPENAI_BASE_URL` |
261
+
262
+ - **Real OAuth (PKCE):** `joc auth login <anthropic|openai|gemini>` opens the provider's
263
+ authorize URL, runs a local callback server (Anthropic `:54545`, OpenAI `:1455`,
264
+ Google `:8085`), exchanges the code, and stores `access` + `refresh` + `expires`. Tokens
265
+ **auto-refresh** on expiry (single-flight); `joc auth refresh <provider>` forces it. On
266
+ headless boxes, paste the redirect URL/code when prompted, or use
267
+ `joc auth login <provider> --token <bearer>` for a manual (non-refreshing) token.
268
+ - **Compatibility:** OAuth beats API keys for the same provider, **except** the bundled
269
+ adapters fall back to the API key when the OAuth flow isn't end-to-end compatible.
270
+ Anthropic OAuth is verified e2e with the Messages adapter; OpenAI/Google OAuth tokens
271
+ target the Codex / Cloud-Code-Assist backends, so the bundled chat / generativelanguage
272
+ adapters prefer an API key (the CLI warns you up front).
273
+ - **Local/offline:** set `JOC_DEFAULT_MODEL=ollama/<model>` after `ollama pull <model>` — no
274
+ key required. Any OpenAI-compatible endpoint works via `openaiBaseUrl`.
275
+
276
+ ---
277
+
278
+ ## Configuration
279
+
280
+ | What | Where |
281
+ | --- | --- |
282
+ | Global config | `~/.joc/config.json` (dir `0700`, file `0600`); override dir with `JOC_CONFIG_DIR` |
283
+ | Per-project runtime | `<cwd>/.joc/` → `seeds/`, `plans/`, `state/`, `sessions/` |
284
+
285
+ `config.json` fields: `providers`, `oauth`, `defaultModel`, `ollamaBaseUrl`, `openaiBaseUrl`,
286
+ `thinkingLevel` (`minimal`/`low`/`medium`/`high`/`xhigh`), `modelAliases`, `roles` (`smol`/`slow`/`plan`
287
+ model tiers), `subagents` (per-role model/maxSteps), `retry`. Env vars (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`,
288
+ `GEMINI_API_KEY`, the `*_OAUTH_TOKEN` bearers, `OLLAMA_HOST`, `OPENAI_BASE_URL`,
289
+ `JOC_DEFAULT_MODEL`) fill gaps but never override on-disk values. Verify everything with `joc doctor`.
290
+
291
+ **Provider retry budgets (gjc parity).** `retry.requestMaxRetries` sets how many times a failed
292
+ provider request is retried (the initial request is not counted); `retry.maxDelayMs` caps the
293
+ exponential backoff. `retry.streamMaxRetries` / `retry.maxRetries` are accepted for gjc-config
294
+ compatibility. Retries apply only to transient failures (network errors, `408/425/429/5xx/529`),
295
+ honoring a server `Retry-After`; auth, bad-model, and malformed-request errors stay fail-fast.
296
+
297
+ ```json
298
+ { "defaultModel": "claude-3-5-sonnet", "retry": { "requestMaxRetries": 4, "maxDelayMs": 300000 } }
299
+ ```
300
+
301
+ ---
302
+
303
+ ## Project structure
304
+
305
+ ```text
306
+ jeo-code/
307
+ ├── package.json # name: jeo-code, bin: { joc: src/cli.ts }, bun scripts
308
+ ├── tsconfig.json # strict typecheck config
309
+ ├── install.sh # top-level shim → scripts/install.sh --local
310
+ ├── src/
311
+ │ ├── cli.ts # entry: Bun version guard + dispatch
312
+ │ ├── cli/runner.ts # lazy command registry (bare joc → launch)
313
+ │ ├── commands/ # launch, setup, auth, deep-interview, ralplan, approve, team, ultragoal, doctor, mcp, models, skills, resume, chat
314
+ │ ├── agent/ # engine (tool loop), loop, json, tools (+MutationGuard), session, compaction, context-files, state
315
+ │ ├── ai/ # provider adapters (anthropic/openai/gemini/ollama) + model-manager
316
+ │ ├── auth/ # storage (+auto-refresh), pkce, callback-server, refresh, flows/{anthropic,openai,google}
317
+ │ ├── mcp/ # MCP protocol + tools + stdio server
318
+ │ └── tui/ # differential renderer + components + LaunchTui
319
+ ├── scripts/ # install.sh / uninstall.sh (bun install + bun link)
320
+ ├── test/ # 61 suites (372 tests): oauth, engine, tools-fs, retry, config-schema, cli-runner, mutation-guard, approve, team-schema, session, compaction, streaming, evolution, ascii-art, footer, evolve, meter, install, model-discovery/picker/catalog/enrich/roles, provider-status, config-panel, code-view, tui-*
321
+ ├── docs/improvements.md # architectural analysis & changelog (ralph passes)
322
+ ├── plan/ # long-horizon work plans (TUI, features, install, model, provider)
323
+ └── README.md
324
+ ```
325
+
326
+ ---
327
+
328
+ ## Development
329
+
330
+ ```bash
331
+ bun install # deps: zod (config validation), chalk (doctor colors)
332
+ bun run typecheck # tsc -p tsconfig.json --noEmit
333
+ bun test # full suite
334
+ GEMINI_OAUTH_CLIENT_SECRET=<x> bun test # Google OAuth flow tests need this env var
335
+ ```
336
+
337
+ Design lineage and the milestone roadmap (TUI, features, install, model config, provider)
338
+ live in [`plan/`](./plan/README.md); the running changelog is [`docs/improvements.md`](./docs/improvements.md).
339
+
340
+ ## License
341
+
342
+ MIT.
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "jeo-code",
3
+ "version": "0.1.0",
4
+ "description": "Clean, highly optimized AI coding agent using spec-first loop",
5
+ "type": "module",
6
+ "main": "src/cli.ts",
7
+ "bin": {
8
+ "joc": "src/cli.ts"
9
+ },
10
+ "files": [
11
+ "src",
12
+ "scripts/install.sh",
13
+ "scripts/uninstall.sh",
14
+ "tsconfig.json",
15
+ "README.md"
16
+ ],
17
+ "engines": {
18
+ "bun": ">=1.3.14"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/akillness/jeo-code.git"
23
+ },
24
+ "homepage": "https://github.com/akillness/jeo-code#readme",
25
+ "bugs": {
26
+ "url": "https://github.com/akillness/jeo-code/issues"
27
+ },
28
+ "keywords": [
29
+ "ai",
30
+ "coding-agent",
31
+ "bun",
32
+ "cli",
33
+ "spec-first",
34
+ "gjc"
35
+ ],
36
+ "publishConfig": {
37
+ "access": "public",
38
+ "registry": "https://registry.npmjs.org/"
39
+ },
40
+ "license": "MIT",
41
+ "scripts": {
42
+ "start": "bun src/cli.ts",
43
+ "typecheck": "tsc -p tsconfig.json --noEmit",
44
+ "build": "bun build src/cli.ts --compile --outfile dist/joc",
45
+ "pack:check": "npm pack --dry-run",
46
+ "publish:npm": "npm publish --access public --registry https://registry.npmjs.org/",
47
+ "test": "bun test"
48
+ },
49
+ "dependencies": {
50
+ "zod": "^3.24.1",
51
+ "chalk": "^5.3.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/bun": "^1.1.14",
55
+ "typescript": "^5.6.3"
56
+ }
57
+ }