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
@@ -0,0 +1,191 @@
1
+ import {
2
+ getStageByIndex,
3
+ renderAsciiArt,
4
+ stageHeight,
5
+ stageWidth,
6
+ stageCaption,
7
+ animateAsciiArt,
8
+ animateFrames,
9
+ } from "../tui/components/ascii-art";
10
+ import {
11
+ EVOLUTION_STAGE_COUNT,
12
+ EVOLUTION_STAGE_NAMES,
13
+ EVOLUTION_STAGE_TIPS,
14
+ evolutionTrack,
15
+ stageIndexForStep,
16
+ stageProgressRatio,
17
+ transitionMessage,
18
+ } from "../tui/components/evolution";
19
+ import { meter } from "../tui/components/meter";
20
+ import { centerBlock, padLineTo } from "../tui/components/layout";
21
+ import { detectColorLevel, ColorLevel } from "../tui/components/color";
22
+ import { supportsUnicode } from "../tui/components/capability";
23
+ import { getTheme, listThemes, themeGradient } from "../tui/components/themes";
24
+ import { size, isTTY } from "../tui/terminal";
25
+
26
+ export interface EvolveOptions {
27
+ write?: (s: string) => void;
28
+ sleep?: (ms: number) => Promise<void>;
29
+ }
30
+
31
+ interface EvolveFlags {
32
+ color: boolean;
33
+ animate: boolean;
34
+ step?: number;
35
+ max: number;
36
+ ascii: boolean;
37
+ gradient: boolean;
38
+ theme: string;
39
+ listThemes: boolean;
40
+ list: boolean;
41
+ json: boolean;
42
+ loop: number;
43
+ width?: number;
44
+ fit: boolean;
45
+ }
46
+
47
+ function parseFlags(args: string[]): EvolveFlags {
48
+ const flags: EvolveFlags = {
49
+ color: true,
50
+ animate: false,
51
+ max: 25,
52
+ ascii: false,
53
+ gradient: false,
54
+ theme: "cosmic",
55
+ listThemes: false,
56
+ list: false,
57
+ json: false,
58
+ loop: 0,
59
+ fit: false,
60
+ };
61
+ const intArg = (inline: string | undefined, next: string | undefined): { v: number; consumed: boolean } => {
62
+ if (inline !== undefined) return { v: parseInt(inline, 10), consumed: false };
63
+ return { v: parseInt(next ?? "", 10), consumed: true };
64
+ };
65
+ for (let i = 0; i < args.length; i++) {
66
+ const a = args[i]!;
67
+ if (a === "--no-color") flags.color = false;
68
+ else if (a === "--animate") flags.animate = true;
69
+ else if (a === "--ascii") flags.ascii = true;
70
+ else if (a === "--gradient") flags.gradient = true;
71
+ else if (a === "--fit") flags.fit = true;
72
+ else if (a === "--list-themes") flags.listThemes = true;
73
+ else if (a === "--list") flags.list = true;
74
+ else if (a === "--json") flags.json = true;
75
+ else if (a === "--theme") flags.theme = args[++i] ?? flags.theme;
76
+ else if (a.startsWith("--theme=")) flags.theme = a.slice(8);
77
+ else if (a === "--step" || a.startsWith("--step=")) {
78
+ const { v, consumed } = intArg(a.startsWith("--step=") ? a.slice(7) : undefined, args[i + 1]);
79
+ if (Number.isFinite(v)) flags.step = v;
80
+ if (consumed) i++;
81
+ } else if (a === "--max" || a.startsWith("--max=")) {
82
+ const { v, consumed } = intArg(a.startsWith("--max=") ? a.slice(6) : undefined, args[i + 1]);
83
+ if (Number.isFinite(v) && v > 0) flags.max = v;
84
+ if (consumed) i++;
85
+ } else if (a === "--width" || a.startsWith("--width=")) {
86
+ const { v, consumed } = intArg(a.startsWith("--width=") ? a.slice(8) : undefined, args[i + 1]);
87
+ if (Number.isFinite(v) && v > 0) flags.width = v;
88
+ if (consumed) i++;
89
+ } else if (a === "--loop" || a.startsWith("--loop=")) {
90
+ const { v, consumed } = intArg(a.startsWith("--loop=") ? a.slice(7) : undefined, args[i + 1]);
91
+ flags.loop = Number.isFinite(v) && v > 0 ? v : 3;
92
+ // `--loop` with no following integer keeps the default and does not consume.
93
+ if (consumed && !Number.isFinite(v)) {
94
+ /* no numeric arg followed */
95
+ } else if (consumed) i++;
96
+ }
97
+ }
98
+ return flags;
99
+ }
100
+
101
+ /** The canonical stage model as a plain object (for `--json` tooling). */
102
+ function stageModelJson() {
103
+ return {
104
+ stageCount: EVOLUTION_STAGE_COUNT,
105
+ stages: Array.from({ length: EVOLUTION_STAGE_COUNT }, (_, i) => ({
106
+ index: i,
107
+ name: EVOLUTION_STAGE_NAMES[i],
108
+ caption: stageCaption(getStageByIndex(i)),
109
+ tip: EVOLUTION_STAGE_TIPS[i],
110
+ transition: transitionMessage(i),
111
+ })),
112
+ themes: listThemes(),
113
+ };
114
+ }
115
+
116
+ /**
117
+ * Preview the joc "evolution" TUI identity: render the five stages (or one stage
118
+ * for a given step) with art, evolution track, and a stage meter. Supports
119
+ * theming, truecolor gradients, ASCII-only fallback, terminal-width fitting,
120
+ * frame-loop animation, and machine-readable `--json` / `--list` output.
121
+ */
122
+ export async function runEvolveCommand(args: string[], opts: EvolveOptions = {}): Promise<void> {
123
+ const write = opts.write ?? ((s: string) => process.stdout.write(s));
124
+ const flags = parseFlags(args);
125
+ const line = (s = "") => write(s + "\n");
126
+
127
+ if (flags.json) {
128
+ line(JSON.stringify(stageModelJson(), null, 2));
129
+ return;
130
+ }
131
+
132
+ if (flags.listThemes) {
133
+ line("Evolution TUI themes:");
134
+ for (const t of listThemes()) line(` ${t.name.padEnd(8)} ${t.description}`);
135
+ return;
136
+ }
137
+
138
+ const unicode = !flags.ascii && supportsUnicode();
139
+ const theme = getTheme(flags.theme);
140
+ const useColor = flags.color && theme.color;
141
+
142
+ if (flags.list) {
143
+ for (let i = 0; i < EVOLUTION_STAGE_COUNT; i++) {
144
+ const track = evolutionTrack(i, { color: useColor, unicode });
145
+ line(`${track} — ${EVOLUTION_STAGE_TIPS[i]}`);
146
+ }
147
+ return;
148
+ }
149
+
150
+ const cols = size().cols;
151
+ const fitWidth = flags.fit || isTTY();
152
+ const colorLevel = useColor ? detectColorLevel(process.env, isTTY()) : ColorLevel.None;
153
+ const gradientOn = flags.gradient && useColor && colorLevel !== ColorLevel.None;
154
+ const artWidth = flags.width ?? stageWidth();
155
+
156
+ const renderOne = async (index: number, ratio?: number) => {
157
+ const stage = getStageByIndex(index);
158
+ const header = `── Stage ${index + 1}/${EVOLUTION_STAGE_COUNT}: ${stage.name} ──`;
159
+ line(fitWidth ? padLineTo(header, cols, "center") : header);
160
+
161
+ const renderOpts = {
162
+ color: useColor,
163
+ width: artWidth,
164
+ height: stageHeight(),
165
+ ...(gradientOn ? { gradient: themeGradient(theme, index), colorLevel } : {}),
166
+ };
167
+
168
+ if (flags.loop > 0) {
169
+ await animateFrames(stage, { ...renderOpts, frames: flags.loop, write, sleep: opts.sleep, frameDelayMs: opts.sleep ? 0 : 120 });
170
+ } else if (flags.animate) {
171
+ await animateAsciiArt(stage, { ...renderOpts, write, sleep: opts.sleep, delayMs: opts.sleep ? 0 : 60 });
172
+ } else {
173
+ const art = renderAsciiArt(stage, renderOpts);
174
+ for (const l of fitWidth ? centerBlock(art, cols) : art) line(l);
175
+ }
176
+
177
+ const track = evolutionTrack(index, { color: useColor, unicode, ratio });
178
+ line(fitWidth ? padLineTo(track, cols, "center") : track);
179
+ const meterRatio = EVOLUTION_STAGE_COUNT > 1 ? index / (EVOLUTION_STAGE_COUNT - 1) : 1;
180
+ const bar = meter(meterRatio, 1, 20, { unicode });
181
+ line(fitWidth ? padLineTo(bar, cols, "center") : bar);
182
+ line();
183
+ };
184
+
185
+ if (flags.step !== undefined) {
186
+ const idx = stageIndexForStep(flags.step, flags.max);
187
+ await renderOne(idx, stageProgressRatio(flags.step, flags.max));
188
+ return;
189
+ }
190
+ for (let i = 0; i < EVOLUTION_STAGE_COUNT; i++) await renderOne(i);
191
+ }