jeo-code 0.1.0 → 0.4.5

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 (177) hide show
  1. package/README.ja.md +160 -0
  2. package/README.ko.md +160 -0
  3. package/README.md +115 -297
  4. package/README.zh.md +160 -0
  5. package/package.json +11 -6
  6. package/scripts/install.sh +28 -28
  7. package/scripts/uninstall.sh +17 -15
  8. package/src/AGENTS.md +50 -0
  9. package/src/agent/AGENTS.md +49 -0
  10. package/src/agent/bash-fixups.ts +103 -0
  11. package/src/agent/compaction.ts +410 -19
  12. package/src/agent/config-schema.ts +119 -5
  13. package/src/agent/context-files.ts +314 -17
  14. package/src/agent/dev/AGENTS.md +36 -0
  15. package/src/agent/dev/advanced-analyzer.ts +12 -0
  16. package/src/agent/dev/evolution-bridge.ts +82 -0
  17. package/src/agent/dev/evolution-logger.ts +41 -0
  18. package/src/agent/dev/self-analysis.ts +64 -0
  19. package/src/agent/dev/self-improve.ts +24 -0
  20. package/src/agent/dev/spec-automation.ts +49 -0
  21. package/src/agent/engine.ts +808 -54
  22. package/src/agent/hooks.ts +273 -0
  23. package/src/agent/loop.ts +21 -1
  24. package/src/agent/memory.ts +201 -0
  25. package/src/agent/model-recency.ts +32 -0
  26. package/src/agent/output-minimizer.ts +108 -0
  27. package/src/agent/output-util.ts +64 -0
  28. package/src/agent/plan.ts +187 -0
  29. package/src/agent/seed.ts +52 -0
  30. package/src/agent/session.ts +235 -21
  31. package/src/agent/state.ts +286 -39
  32. package/src/agent/step-budget.ts +232 -0
  33. package/src/agent/subagents.ts +223 -26
  34. package/src/agent/task-tool.ts +272 -0
  35. package/src/agent/todo-tool.ts +87 -0
  36. package/src/agent/tokenizer.ts +117 -0
  37. package/src/agent/tool-registry.ts +54 -0
  38. package/src/agent/tools.ts +624 -103
  39. package/src/agent/web-search.ts +538 -0
  40. package/src/ai/AGENTS.md +44 -0
  41. package/src/ai/index.ts +1 -0
  42. package/src/ai/model-catalog-compat.ts +3 -1
  43. package/src/ai/model-catalog.ts +74 -9
  44. package/src/ai/model-discovery.ts +215 -17
  45. package/src/ai/model-manager.ts +346 -32
  46. package/src/ai/model-picker.ts +1 -1
  47. package/src/ai/model-registry.ts +4 -2
  48. package/src/ai/pricing.ts +84 -0
  49. package/src/ai/provider-registry.ts +23 -0
  50. package/src/ai/provider-status.ts +60 -16
  51. package/src/ai/providers/AGENTS.md +42 -0
  52. package/src/ai/providers/anthropic.ts +250 -31
  53. package/src/ai/providers/antigravity.ts +219 -0
  54. package/src/ai/providers/errors.ts +15 -1
  55. package/src/ai/providers/gemini.ts +196 -13
  56. package/src/ai/providers/ollama.ts +37 -7
  57. package/src/ai/providers/openai-responses.ts +173 -0
  58. package/src/ai/providers/openai.ts +64 -12
  59. package/src/ai/sse.ts +4 -1
  60. package/src/ai/types.ts +18 -1
  61. package/src/auth/AGENTS.md +41 -0
  62. package/src/auth/callback-server.ts +6 -1
  63. package/src/auth/flows/AGENTS.md +32 -0
  64. package/src/auth/flows/antigravity.ts +151 -0
  65. package/src/auth/flows/google-project.ts +190 -0
  66. package/src/auth/flows/google.ts +39 -18
  67. package/src/auth/flows/index.ts +15 -5
  68. package/src/auth/flows/openai.ts +2 -2
  69. package/src/auth/oauth.ts +8 -0
  70. package/src/auth/refresh.ts +44 -27
  71. package/src/auth/storage.ts +149 -26
  72. package/src/auth/types.ts +1 -1
  73. package/src/autopilot.ts +362 -0
  74. package/src/bun-imports.d.ts +4 -0
  75. package/src/cli/AGENTS.md +39 -0
  76. package/src/cli/runner.ts +148 -14
  77. package/src/cli.ts +13 -4
  78. package/src/commands/AGENTS.md +40 -0
  79. package/src/commands/approve.ts +62 -3
  80. package/src/commands/auth.ts +167 -25
  81. package/src/commands/chat.ts +37 -8
  82. package/src/commands/deep-interview.ts +633 -175
  83. package/src/commands/doctor.ts +84 -37
  84. package/src/commands/evolve-core.ts +18 -0
  85. package/src/commands/evolve.ts +2 -1
  86. package/src/commands/export.ts +176 -0
  87. package/src/commands/gjc.ts +52 -0
  88. package/src/commands/launch.ts +3549 -240
  89. package/src/commands/mcp.ts +3 -3
  90. package/src/commands/ooo-seed.ts +19 -0
  91. package/src/commands/ralplan.ts +253 -35
  92. package/src/commands/resume.ts +1 -1
  93. package/src/commands/session.ts +183 -0
  94. package/src/commands/setup-helpers.ts +10 -3
  95. package/src/commands/setup.ts +57 -16
  96. package/src/commands/skills.ts +78 -18
  97. package/src/commands/state.ts +198 -0
  98. package/src/commands/status.ts +84 -0
  99. package/src/commands/team.ts +340 -212
  100. package/src/commands/ultragoal.ts +122 -61
  101. package/src/commands/update.ts +244 -0
  102. package/src/ledger.ts +270 -0
  103. package/src/mcp/AGENTS.md +38 -0
  104. package/src/mcp/server.ts +115 -14
  105. package/src/mcp/tools.ts +42 -22
  106. package/src/md-modules.d.ts +4 -0
  107. package/src/prompts/AGENTS.md +41 -0
  108. package/src/prompts/agents/AGENTS.md +35 -0
  109. package/src/prompts/agents/architect.md +35 -0
  110. package/src/prompts/agents/critic.md +37 -0
  111. package/src/prompts/agents/executor.md +36 -0
  112. package/src/prompts/agents/planner.md +37 -0
  113. package/src/prompts/skills/AGENTS.md +36 -0
  114. package/src/prompts/skills/deep-dive/AGENTS.md +31 -0
  115. package/src/prompts/skills/deep-dive/SKILL.md +13 -0
  116. package/src/prompts/skills/deep-interview/AGENTS.md +31 -0
  117. package/src/prompts/skills/deep-interview/SKILL.md +12 -0
  118. package/src/prompts/skills/gjc/AGENTS.md +31 -0
  119. package/src/prompts/skills/gjc/SKILL.md +15 -0
  120. package/src/prompts/skills/ralplan/AGENTS.md +31 -0
  121. package/src/prompts/skills/ralplan/SKILL.md +11 -0
  122. package/src/prompts/skills/team/AGENTS.md +31 -0
  123. package/src/prompts/skills/team/SKILL.md +11 -0
  124. package/src/prompts/skills/ultragoal/AGENTS.md +31 -0
  125. package/src/prompts/skills/ultragoal/SKILL.md +11 -0
  126. package/src/skills/AGENTS.md +38 -0
  127. package/src/skills/catalog.ts +565 -31
  128. package/src/tui/AGENTS.md +43 -0
  129. package/src/tui/app.ts +1181 -92
  130. package/src/tui/components/AGENTS.md +42 -0
  131. package/src/tui/components/ascii-art.ts +257 -15
  132. package/src/tui/components/autocomplete.ts +98 -16
  133. package/src/tui/components/autopilot-status.ts +65 -0
  134. package/src/tui/components/category-index.ts +49 -0
  135. package/src/tui/components/code-view.ts +54 -11
  136. package/src/tui/components/color.ts +171 -2
  137. package/src/tui/components/config-panel.ts +82 -15
  138. package/src/tui/components/duration.ts +38 -0
  139. package/src/tui/components/evolution.ts +3 -3
  140. package/src/tui/components/footer.ts +91 -42
  141. package/src/tui/components/forge.ts +426 -31
  142. package/src/tui/components/hints.ts +54 -0
  143. package/src/tui/components/hud.ts +73 -0
  144. package/src/tui/components/index.ts +4 -0
  145. package/src/tui/components/input-box.ts +150 -0
  146. package/src/tui/components/layout.ts +11 -3
  147. package/src/tui/components/live-model-picker.ts +108 -0
  148. package/src/tui/components/markdown-table.ts +140 -0
  149. package/src/tui/components/markdown-text.ts +97 -0
  150. package/src/tui/components/meter.ts +4 -1
  151. package/src/tui/components/model-picker.ts +3 -2
  152. package/src/tui/components/provider-picker.ts +3 -2
  153. package/src/tui/components/section.ts +70 -0
  154. package/src/tui/components/select-list.ts +40 -10
  155. package/src/tui/components/skill-picker.ts +25 -0
  156. package/src/tui/components/slash.ts +244 -21
  157. package/src/tui/components/status.ts +272 -11
  158. package/src/tui/components/step-timeline.ts +218 -0
  159. package/src/tui/components/stream.ts +26 -9
  160. package/src/tui/components/themes.ts +212 -6
  161. package/src/tui/components/todo-card.ts +47 -0
  162. package/src/tui/components/tool-list.ts +58 -12
  163. package/src/tui/components/transcript.ts +120 -0
  164. package/src/tui/components/update-box.ts +31 -0
  165. package/src/tui/components/welcome.ts +162 -0
  166. package/src/tui/components/width.ts +163 -0
  167. package/src/tui/monitoring/AGENTS.md +31 -0
  168. package/src/tui/monitoring/hud-view.ts +55 -0
  169. package/src/tui/renderer.ts +112 -3
  170. package/src/tui/terminal.ts +40 -33
  171. package/src/util/AGENTS.md +39 -0
  172. package/src/util/clipboard-image.ts +118 -0
  173. package/src/util/env.ts +12 -0
  174. package/src/util/provider-error.ts +78 -0
  175. package/src/util/retry.ts +91 -6
  176. package/src/util/update-check.ts +64 -0
  177. package/src/commands/models.ts +0 -104
package/package.json CHANGED
@@ -1,18 +1,21 @@
1
1
  {
2
2
  "name": "jeo-code",
3
- "version": "0.1.0",
3
+ "version": "0.4.5",
4
4
  "description": "Clean, highly optimized AI coding agent using spec-first loop",
5
5
  "type": "module",
6
6
  "main": "src/cli.ts",
7
7
  "bin": {
8
- "joc": "src/cli.ts"
8
+ "jeo": "src/cli.ts"
9
9
  },
10
10
  "files": [
11
11
  "src",
12
12
  "scripts/install.sh",
13
13
  "scripts/uninstall.sh",
14
14
  "tsconfig.json",
15
- "README.md"
15
+ "README.md",
16
+ "README.ko.md",
17
+ "README.ja.md",
18
+ "README.zh.md"
16
19
  ],
17
20
  "engines": {
18
21
  "bun": ">=1.3.14"
@@ -31,7 +34,7 @@
31
34
  "bun",
32
35
  "cli",
33
36
  "spec-first",
34
- "gjc"
37
+ "jeo"
35
38
  ],
36
39
  "publishConfig": {
37
40
  "access": "public",
@@ -41,14 +44,16 @@
41
44
  "scripts": {
42
45
  "start": "bun src/cli.ts",
43
46
  "typecheck": "tsc -p tsconfig.json --noEmit",
44
- "build": "bun build src/cli.ts --compile --outfile dist/joc",
47
+ "build": "bun build src/cli.ts --compile --outfile dist/jeo",
45
48
  "pack:check": "npm pack --dry-run",
46
49
  "publish:npm": "npm publish --access public --registry https://registry.npmjs.org/",
50
+ "changelog:sync": "bun scripts/sync-changelog.ts",
47
51
  "test": "bun test"
48
52
  },
49
53
  "dependencies": {
50
54
  "zod": "^3.24.1",
51
- "chalk": "^5.3.0"
55
+ "chalk": "^5.3.0",
56
+ "js-tiktoken": "^1.0.21"
52
57
  },
53
58
  "devDependencies": {
54
59
  "@types/bun": "^1.1.14",
@@ -1,5 +1,5 @@
1
1
  #!/bin/sh
2
- # joc (jeo-code) installer — gjc-style bun global install.
2
+ # jeo (jeo-code) installer — gjc-style bun global install.
3
3
  #
4
4
  # The gjc parity path is a single Bun global install. The published-package form
5
5
  # (once jeo-code is on npm) is identical to gajae-code's:
@@ -25,25 +25,25 @@
25
25
  set -e
26
26
 
27
27
  DEFAULT_REPO="https://github.com/akillness/jeo-code.git"
28
- REPO="${JOC_REPO:-${JOC_REPO_URL:-$DEFAULT_REPO}}"
29
- PKG="${JOC_PKG:-jeo-code}"
30
- INSTALL_DIR="${JOC_INSTALL_DIR:-$HOME/.local/bin}"
28
+ REPO="${JEO_REPO:-${JEO_REPO:-${JEO_REPO_URL:-${JEO_REPO_URL:-$DEFAULT_REPO}}}}"
29
+ PKG="${JEO_PKG:-${JEO_PKG:-jeo-code}}"
30
+ INSTALL_DIR="${JEO_INSTALL_DIR:-${JEO_INSTALL_DIR:-$HOME/.local/bin}}"
31
31
  MIN_BUN_VERSION="1.3.14"
32
32
 
33
33
  MODE="global"
34
34
  REF=""
35
35
  SRC_DIR=""
36
36
  LINKED=""
37
- REGISTRY="${JOC_REGISTRY:-}"
38
- SCOPE="${JOC_REGISTRY_SCOPE:-}"
37
+ REGISTRY="${JEO_REGISTRY:-${JEO_REGISTRY:-}}"
38
+ SCOPE="${JEO_REGISTRY_SCOPE:-${JEO_REGISTRY_SCOPE:-}}"
39
39
  PERSIST_REGISTRY=0
40
40
  PROJECT_NPMRC=0
41
41
  DRY_RUN=0
42
42
 
43
43
  usage() {
44
44
  cat <<EOF
45
- joc installer (gjc-style Bun global install)
46
- (default) bun global install from $REPO → exposes 'joc'
45
+ jeo installer (gjc-style Bun global install)
46
+ (default) bun global install from $REPO → exposes 'jeo'
47
47
  --repo <url|owner/repo> git source (default $DEFAULT_REPO)
48
48
  --npm bun install -g $PKG (npm registry; gjc parity once published)
49
49
  --package <name> npm package name for --npm (default $PKG)
@@ -58,11 +58,11 @@ joc installer (gjc-style Bun global install)
58
58
  --ref <ref> install a specific tag/branch/commit
59
59
  --dry-run print the bun/npm commands without installing
60
60
  Environment:
61
- JOC_INSTALL_DIR (default \$HOME/.local/bin — compatibility symlink)
62
- JOC_REPO/JOC_REPO_URL(default $DEFAULT_REPO)
63
- JOC_PKG (default $PKG)
64
- JOC_REGISTRY one-shot or persisted registry URL
65
- JOC_REGISTRY_SCOPE optional scope such as @my-org
61
+ JEO_INSTALL_DIR (default \$HOME/.local/bin — compatibility symlink; legacy JEO_* names still honored)
62
+ JEO_REPO/JEO_REPO_URL(default $DEFAULT_REPO)
63
+ JEO_PKG (default $PKG)
64
+ JEO_REGISTRY one-shot or persisted registry URL
65
+ JEO_REGISTRY_SCOPE optional scope such as @my-org
66
66
  EOF
67
67
  }
68
68
 
@@ -225,8 +225,8 @@ run_bun_global_add() {
225
225
  fi
226
226
  }
227
227
 
228
- # Bun global install (the gjc-idiomatic path). Exposes the package's `joc` bin
229
- # in Bun's global bin dir (~/.bun/bin/joc).
228
+ # Bun global install (the gjc-idiomatic path). Exposes the package's `jeo` bin
229
+ # in Bun's global bin dir (~/.bun/bin/jeo).
230
230
  install_global() {
231
231
  spec=$(normalize_repo_spec "$REPO")
232
232
  echo "Installing $PKG globally via Bun ($spec)..."
@@ -267,26 +267,26 @@ install_binary() {
267
267
  fi
268
268
  if [ "$DRY_RUN" = "1" ]; then
269
269
  echo "+ ( cd $SRC_DIR && bun install --silent )"
270
- echo "+ bun build src/cli.ts --compile --outfile $INSTALL_DIR/joc"
270
+ echo "+ bun build src/cli.ts --compile --outfile $INSTALL_DIR/jeo"
271
271
  else
272
272
  ( cd "$SRC_DIR" && bun install --silent >/dev/null )
273
273
  mkdir -p "$INSTALL_DIR"
274
- echo "Compiling standalone binary → $INSTALL_DIR/joc ..."
275
- ( cd "$SRC_DIR" && bun build src/cli.ts --compile --outfile "$INSTALL_DIR/joc" >/dev/null )
276
- chmod +x "$INSTALL_DIR/joc" 2>/dev/null || true
274
+ echo "Compiling standalone binary → $INSTALL_DIR/jeo ..."
275
+ ( cd "$SRC_DIR" && bun build src/cli.ts --compile --outfile "$INSTALL_DIR/jeo" >/dev/null )
276
+ chmod +x "$INSTALL_DIR/jeo" 2>/dev/null || true
277
277
  fi
278
278
  }
279
279
 
280
- # Add a compatibility symlink in INSTALL_DIR so the documented location keeps
281
- # working even when Bun's global bin dir is not on PATH.
280
+ # Add a symlink in INSTALL_DIR so the documented location works even when
281
+ # Bun's global bin dir is not on PATH.
282
282
  link_compat() {
283
283
  [ "$DRY_RUN" = "1" ] && return 0
284
284
  BUN_BIN="$(bun_bin_dir)"
285
- [ -e "$BUN_BIN/joc" ] && LINKED="$BUN_BIN/joc"
285
+ [ -e "$BUN_BIN/jeo" ] && LINKED="$BUN_BIN/jeo"
286
286
  mkdir -p "$INSTALL_DIR"
287
287
  if [ -n "$LINKED" ]; then
288
- ln -sf "$LINKED" "$INSTALL_DIR/joc"
289
- chmod +x "$INSTALL_DIR/joc" 2>/dev/null || true
288
+ ln -sf "$LINKED" "$INSTALL_DIR/jeo"
289
+ chmod +x "$INSTALL_DIR/jeo" 2>/dev/null || true
290
290
  fi
291
291
  }
292
292
 
@@ -297,11 +297,11 @@ print_done() {
297
297
  echo "Dry run complete; no install changes were made."
298
298
  return 0
299
299
  fi
300
- [ -n "$LINKED" ] && echo "Linked joc via Bun → $LINKED"
301
- [ -e "$INSTALL_DIR/joc" ] && echo "Compatibility symlink → $INSTALL_DIR/joc"
300
+ [ -n "$LINKED" ] && echo "Linked jeo via Bun → $LINKED"
301
+ [ -e "$INSTALL_DIR/jeo" ] && echo "Compatibility symlink → $INSTALL_DIR/jeo"
302
302
  case ":$PATH:" in
303
- *":$BUN_BIN:"*|*":$INSTALL_DIR:"*) echo "Run: joc --help" ;;
304
- *) echo "Add $BUN_BIN (or $INSTALL_DIR) to PATH, then run: joc --help" ;;
303
+ *":$BUN_BIN:"*|*":$INSTALL_DIR:"*) echo "Run: jeo --help" ;;
304
+ *) echo "Add $BUN_BIN (or $INSTALL_DIR) to PATH, then run: jeo --help" ;;
305
305
  esac
306
306
  }
307
307
 
@@ -1,30 +1,32 @@
1
1
  #!/bin/sh
2
- # joc uninstaller — removes binary symlink and optionally global config.
2
+ # jeo uninstaller — removes binary symlink and optionally global config.
3
3
  # Usage:
4
4
  # sh scripts/uninstall.sh # remove binary only
5
- # sh scripts/uninstall.sh --purge # also remove ~/.joc/
5
+ # sh scripts/uninstall.sh --purge # also remove ~/.jeo/
6
6
  set -e
7
- INSTALL_DIR="${JOC_INSTALL_DIR:-$HOME/.local/bin}"
7
+ INSTALL_DIR="${JEO_INSTALL_DIR:-$HOME/.local/bin}"
8
8
  PURGE=0
9
9
  [ "$1" = "--purge" ] && PURGE=1
10
10
 
11
- if [ -L "$INSTALL_DIR/joc" ] || [ -f "$INSTALL_DIR/joc" ]; then
12
- rm -f "$INSTALL_DIR/joc"
13
- echo "Removed $INSTALL_DIR/joc"
14
- else
15
- echo "No joc binary at $INSTALL_DIR/joc"
16
- fi
11
+ for BIN_NAME in jeo; do
12
+ if [ -L "$INSTALL_DIR/$BIN_NAME" ] || [ -f "$INSTALL_DIR/$BIN_NAME" ]; then
13
+ rm -f "$INSTALL_DIR/$BIN_NAME"
14
+ echo "Removed $INSTALL_DIR/$BIN_NAME"
15
+ fi
16
+ done
17
17
 
18
18
  # Remove the bun-native link (bin + global registry entry).
19
19
  BUN_BIN="${BUN_INSTALL:-$HOME/.bun}/bin"
20
- if [ -L "$BUN_BIN/joc" ] || [ -f "$BUN_BIN/joc" ]; then
21
- rm -f "$BUN_BIN/joc"
22
- echo "Removed $BUN_BIN/joc (bun link)"
23
- fi
20
+ for BIN_NAME in jeo; do
21
+ if [ -L "$BUN_BIN/$BIN_NAME" ] || [ -f "$BUN_BIN/$BIN_NAME" ]; then
22
+ rm -f "$BUN_BIN/$BIN_NAME"
23
+ echo "Removed $BUN_BIN/$BIN_NAME (bun link)"
24
+ fi
25
+ done
24
26
  GLOBAL_PKG="${BUN_INSTALL:-$HOME/.bun}/install/global/node_modules/jeo-code"
25
27
  [ -e "$GLOBAL_PKG" ] && rm -rf "$GLOBAL_PKG" && echo "Unregistered jeo-code from bun global"
26
28
 
27
29
  if [ "$PURGE" = "1" ]; then
28
- rm -rf "$HOME/.joc"
29
- echo "Removed ~/.joc/"
30
+ rm -rf "$HOME/.jeo"
31
+ echo "Removed ~/.jeo/"
30
32
  fi
package/src/AGENTS.md ADDED
@@ -0,0 +1,50 @@
1
+ <!-- Parent: ../AGENTS.md -->
2
+ <!-- Generated: 2026-06-11 | Updated: 2026-06-11 -->
3
+
4
+ # src
5
+
6
+ ## Purpose
7
+ Core application source code for the `jeo-code` CLI and agent runtime. It orchestrates user commands, TUI rendering, agent intelligence, tool execution, and workspace integrations.
8
+
9
+ ## Key Files
10
+ | File | Description |
11
+ |------|-------------|
12
+ | `cli.ts` | The main binary entrypoint |
13
+ | `index.ts` | Library exports |
14
+ | `bun-imports.d.ts` / `md-modules.d.ts` | TypeScript declarations for Bun built-ins and raw module imports |
15
+
16
+ ## Subdirectories
17
+ | Directory | Purpose |
18
+ |-----------|---------|
19
+ | `agent/` | Agent execution loop, tool registry, session state, and subagent management (see `agent/AGENTS.md`) |
20
+ | `ai/` | LLM client interactions, provider abstractions, and token management (see `ai/AGENTS.md`) |
21
+ | `auth/` | OAuth flows and credential management (see `auth/AGENTS.md`) |
22
+ | `cli/` | Command-line interface definitions and arg parsing (see `cli/AGENTS.md`) |
23
+ | `commands/` | Implementations for all `jeo` subcommands (launch, setup, team, etc.) (see `commands/AGENTS.md`) |
24
+ | `mcp/` | Model Context Protocol integration (see `mcp/AGENTS.md`) |
25
+ | `prompts/` | Bundled system prompts and skills (see `prompts/AGENTS.md`) |
26
+ | `skills/` | Skill execution framework and discovery (see `skills/AGENTS.md`) |
27
+ | `tui/` | Terminal User Interface, layout, and rendering (see `tui/AGENTS.md`) |
28
+ | `util/` | General utilities, retry logic, and update checking (see `util/AGENTS.md`) |
29
+
30
+ ## For AI Agents
31
+
32
+ ### Working In This Directory
33
+ - Entrypoints reside here, but domain logic should be pushed into appropriate subdirectories.
34
+ - Adhere strictly to the Bun execution environment (no Node.js-specific modules unless polyfilled by Bun).
35
+
36
+ ### Testing Requirements
37
+ - Code touched here is highly central; verify with `bun test` and `bun run typecheck`.
38
+
39
+ ### Common Patterns
40
+ - Fast startup: limit top-level imports that execute expensive initialization.
41
+
42
+ ## Dependencies
43
+
44
+ ### Internal
45
+ - Depends heavily on all subdirectories (`agent`, `tui`, `ai`, etc.).
46
+
47
+ ### External
48
+ - Bun runtime APIs.
49
+
50
+ <!-- MANUAL: -->
@@ -0,0 +1,49 @@
1
+ <!-- Parent: ../AGENTS.md -->
2
+ <!-- Generated: 2026-06-11 | Updated: 2026-06-11 -->
3
+
4
+ # agent
5
+
6
+ ## Purpose
7
+ The core runtime loop, tool registry, session management, and state persistence for the `jeo-code` agent.
8
+
9
+ ## Key Files
10
+ | File | Description |
11
+ |------|-------------|
12
+ | `loop.ts` | The primary execution loop orchestrating model calls and tool execution |
13
+ | `tools.ts` | Built-in tool definitions (bash, read, write, edit, etc.) |
14
+ | `state.ts` | File-backed state and session persistence (`.jeo/state/`) |
15
+ | `session.ts` | Session context building, compaction, and history management |
16
+ | `plan.ts` | Subagent planning structures and validation |
17
+ | `step-budget.ts` | gjc-style flexible step budgeting: progress-scored extensions, hard cap, fail-fast |
18
+ | `subagents.ts` / `task-tool.ts` | Delegation mechanisms and background execution of task subagents |
19
+
20
+ ## Subdirectories
21
+ | Directory | Purpose |
22
+ |-----------|---------|
23
+ | `dev/` | Developer-specific agent tooling and spec automation (see `dev/AGENTS.md`) |
24
+
25
+ ## For AI Agents
26
+
27
+ ### Working In This Directory
28
+ - Modifications here affect the fundamental capabilities of the agent. Proceed with extreme caution.
29
+ - Ensure state writes are atomic and safe for concurrent execution.
30
+ - Tool schemas must remain strict and well-documented.
31
+
32
+ ### Testing Requirements
33
+ - Extensive unit testing required. Use mock tools to test the loop logic without side effects.
34
+ - Verify session compaction does not lose critical context.
35
+
36
+ ### Common Patterns
37
+ - Tool results are fenced properly to prevent prompt injection.
38
+ - The loop is decoupled from the UI (events are emitted to be consumed by the TUI).
39
+
40
+ ## Dependencies
41
+
42
+ ### Internal
43
+ - `src/ai/` for model inference.
44
+ - `src/tui/` consumes events emitted by the loop.
45
+
46
+ ### External
47
+ - System APIs (fs, child_process) via Bun.
48
+
49
+ <!-- MANUAL: -->
@@ -0,0 +1,103 @@
1
+ /**
2
+ * GJC Bash Command Fixups — conservative, INTENT-PRESERVING, off-by-default rewrites
3
+ * for common CLI mistakes. Every rule is a no-op unless it matches exactly, and no rule
4
+ * may change what the command observably does (only its form). Gated behind
5
+ * `JEO_BASH_FIXUPS=1` by the caller (bashTool); never altered by default.
6
+ *
7
+ * Rules that would CHANGE behavior (e.g. merging stderr into a pipe with `2>&1`, which
8
+ * adds new data to the matched stream) are intentionally NOT included — that is
9
+ * intent-inferring, not intent-preserving.
10
+ */
11
+
12
+ /** Tokenize respecting single/double quotes (quotes kept in the token). */
13
+ function tokenize(cmd: string): string[] {
14
+ const tokens: string[] = [];
15
+ let current = "";
16
+ let inDoubleQuote = false;
17
+ let inSingleQuote = false;
18
+ for (let i = 0; i < cmd.length; i++) {
19
+ const char = cmd[i];
20
+ if (char === '"' && !inSingleQuote) {
21
+ inDoubleQuote = !inDoubleQuote;
22
+ current += char;
23
+ } else if (char === "'" && !inDoubleQuote) {
24
+ inSingleQuote = !inSingleQuote;
25
+ current += char;
26
+ } else if (char === " " && !inDoubleQuote && !inSingleQuote) {
27
+ if (current) { tokens.push(current); current = ""; }
28
+ } else {
29
+ current += char;
30
+ }
31
+ }
32
+ if (current) tokens.push(current);
33
+ return tokens;
34
+ }
35
+
36
+ /** Apply intent-preserving, conservative fixups. Returns the (possibly) rewritten
37
+ * command and the list of rule names applied (empty when nothing matched). */
38
+ export function applyBashFixups(command: string): { command: string; applied: string[] } {
39
+ let currentCommand = command;
40
+ const applied: string[] = [];
41
+
42
+ // Rule 1: strip-trailing — `ls -la; ` → `ls -la` (drop one trailing `;` + surrounding ws).
43
+ {
44
+ let newCmd = currentCommand.trim();
45
+ if (newCmd.endsWith(";")) newCmd = newCmd.slice(0, -1).trim();
46
+ if (newCmd !== command) {
47
+ currentCommand = newCmd;
48
+ applied.push("strip-trailing");
49
+ }
50
+ }
51
+
52
+ // Rule 2: useless-cat — `cat file | grep PAT` → `grep PAT file`.
53
+ // SINGLE-STAGE ONLY: bail if the grep args carry a downstream pipe/compound operator
54
+ // (`| && || ;`), since appending the file after them would corrupt the pipeline
55
+ // (`cat f | grep x | head` must NOT become `grep x | head f`).
56
+ const uselessCatRegex = /^\s*cat\s+((?:'[^']*'|"[^"]*"|[^\s|]+))\s*\|\s*(grep|egrep|fgrep)\s+(.+)$/;
57
+ const catMatch = currentCommand.match(uselessCatRegex);
58
+ if (catMatch && !/[|&;]/.test(catMatch[3]!)) {
59
+ currentCommand = `${catMatch[2]} ${catMatch[3]} ${catMatch[1]}`;
60
+ applied.push("useless-cat");
61
+ }
62
+
63
+ // Rule 3: dev-null-merge — both streams discarded two ways → the canonical form.
64
+ // `cmd >/dev/null 2>/dev/null` / `cmd 2>/dev/null 1>/dev/null` → `cmd >/dev/null 2>&1`
65
+ // (behavior-identical: stdout AND stderr both go to /dev/null either way).
66
+ const devNull = /(?:^|\s)(?:1?>\s*\/dev\/null\s+2>\s*\/dev\/null|2>\s*\/dev\/null\s+1?>\s*\/dev\/null)\s*$/;
67
+ if (devNull.test(currentCommand)) {
68
+ currentCommand = currentCommand.replace(devNull, " >/dev/null 2>&1");
69
+ applied.push("dev-null-merge");
70
+ }
71
+
72
+ // Rule 4: collapse-dot-slash — `././bin/run` → `./bin/run`.
73
+ const dotSlashRegex = /^\s*(?:\.\/){2,}(.*)$/;
74
+ const dotSlashMatch = currentCommand.match(dotSlashRegex);
75
+ if (dotSlashMatch) {
76
+ const leadingSpaces = currentCommand.match(/^\s*/)?.[0] || "";
77
+ currentCommand = `${leadingSpaces}./${dotSlashMatch[1]}`;
78
+ applied.push("collapse-dot-slash");
79
+ }
80
+
81
+ // Rule 5: grep-r-default-path — recursive grep with no path → append ` .`.
82
+ // Matches both short `-r`/`-R` (in a bundled flag) and `--recursive`.
83
+ const tokens = tokenize(currentCommand);
84
+ if (tokens.length > 1 && tokens[0] === "grep") {
85
+ let hasRecursiveFlag = false;
86
+ const posArgs: string[] = [];
87
+ for (let i = 1; i < tokens.length; i++) {
88
+ const token = tokens[i]!;
89
+ if (token.startsWith("-")) {
90
+ if (token === "--recursive") hasRecursiveFlag = true;
91
+ else if (!token.startsWith("--") && /[rR]/.test(token)) hasRecursiveFlag = true;
92
+ } else {
93
+ posArgs.push(token);
94
+ }
95
+ }
96
+ if (hasRecursiveFlag && posArgs.length === 1) {
97
+ currentCommand = `${currentCommand} .`;
98
+ applied.push("grep-r-default-path");
99
+ }
100
+ }
101
+
102
+ return { command: currentCommand, applied };
103
+ }