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,108 @@
1
+ export interface RetryOptions {
2
+ retries?: number; // default 3 total attempts
3
+ baseDelayMs?: number; // default 250
4
+ maxDelayMs?: number; // default 4000
5
+ isRetryable?: (err: unknown, attempt: number) => boolean;
6
+ sleep?: (ms: number) => Promise<void>; // injectable for tests (default real setTimeout)
7
+ random?: () => number; // injectable RNG for jitter (default Math.random); equal-jitter in [0.5x, 1x]
8
+ onRetry?: (attempt: number, err: unknown) => void;
9
+ }
10
+
11
+ // Default retryable predicate: true for transient network errors, transient/overload
12
+ // keywords, or a transient HTTP status (408/425/429/500/502/503/504/529) found either on a
13
+ // numeric `.status` field or embedded as "HTTP <code>" in the error message.
14
+ const RETRYABLE_STATUS = new Set([408, 425, 429, 500, 502, 503, 504, 529]);
15
+ export function defaultRetryable(err: unknown): boolean {
16
+ if (!err) {
17
+ return false;
18
+ }
19
+
20
+ let message = "";
21
+ if (err instanceof Error) {
22
+ message = err.message;
23
+ } else if (typeof err === "object" && "message" in err && typeof (err as any).message === "string") {
24
+ message = (err as any).message;
25
+ } else {
26
+ message = String(err);
27
+ }
28
+
29
+ const lowerMessage = message.toLowerCase();
30
+ if (
31
+ lowerMessage.includes("fetch") ||
32
+ lowerMessage.includes("network") ||
33
+ lowerMessage.includes("econn") ||
34
+ lowerMessage.includes("timeout") ||
35
+ lowerMessage.includes("overloaded") ||
36
+ lowerMessage.includes("rate limit") ||
37
+ lowerMessage.includes("rate_limit")
38
+ ) {
39
+ return true;
40
+ }
41
+
42
+ // Numeric `.status` field (structured provider errors, fetch responses).
43
+ if (typeof err === "object" && err !== null) {
44
+ const status = (err as any).status;
45
+ const numericStatus = typeof status === "number" ? status : (typeof status === "string" ? Number(status) : NaN);
46
+ if (!isNaN(numericStatus) && RETRYABLE_STATUS.has(numericStatus)) {
47
+ return true;
48
+ }
49
+ }
50
+
51
+ // Fallback: a status embedded in the message, e.g. "... (HTTP 503): overloaded".
52
+ const httpMatch = lowerMessage.match(/http[\s/]*?(\d{3})/);
53
+ if (httpMatch && RETRYABLE_STATUS.has(Number(httpMatch[1]))) {
54
+ return true;
55
+ }
56
+
57
+ return false;
58
+ }
59
+
60
+ // Server-directed `Retry-After` is honored but capped so a CLI never hangs on a hostile header.
61
+ const RETRY_AFTER_CAP_MS = 30_000;
62
+
63
+ // Run fn; on a retryable error, back off and retry up to `retries` attempts. Backoff is
64
+ // exponential (baseDelay * 2^(attempt-1), capped at maxDelay) with equal jitter (the wait lands in
65
+ // [0.5x, 1x] of that cap), unless the error carries a `retryAfterMs` (server `Retry-After`), which
66
+ // takes precedence (capped at RETRY_AFTER_CAP_MS). Re-throws the last error when exhausted.
67
+ export async function withRetry<T>(fn: () => Promise<T>, opts?: RetryOptions): Promise<T> {
68
+ const retries = opts?.retries ?? 3;
69
+ const baseDelayMs = opts?.baseDelayMs ?? 250;
70
+ const maxDelayMs = opts?.maxDelayMs ?? 4000;
71
+ const isRetryable = opts?.isRetryable ?? defaultRetryable;
72
+ const sleep = opts?.sleep ?? ((ms: number) => new Promise<void>(resolve => setTimeout(resolve, ms)));
73
+ const random = opts?.random ?? Math.random;
74
+ const onRetry = opts?.onRetry;
75
+
76
+ let attempt = 1;
77
+ while (true) {
78
+ try {
79
+ return await fn();
80
+ } catch (err) {
81
+ if (attempt >= retries || !isRetryable(err, attempt)) {
82
+ throw err;
83
+ }
84
+
85
+ const capped = Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
86
+ // Equal jitter: half fixed + half random → [0.5x, 1x] of the capped backoff.
87
+ const jittered = capped / 2 + random() * (capped / 2);
88
+ const serverDelay = retryAfterOf(err);
89
+ const delay = serverDelay !== undefined ? Math.min(serverDelay, RETRY_AFTER_CAP_MS) : jittered;
90
+
91
+ if (onRetry) {
92
+ onRetry(attempt, err);
93
+ }
94
+
95
+ await sleep(delay);
96
+ attempt++;
97
+ }
98
+ }
99
+ }
100
+
101
+ // Extract a non-negative `retryAfterMs` from an error, if it carries one (e.g. ProviderHttpError).
102
+ function retryAfterOf(err: unknown): number | undefined {
103
+ if (typeof err === "object" && err !== null) {
104
+ const v = (err as { retryAfterMs?: unknown }).retryAfterMs;
105
+ if (typeof v === "number" && Number.isFinite(v) && v >= 0) return v;
106
+ }
107
+ return undefined;
108
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["ESNext"],
4
+ "target": "ESNext",
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "moduleDetection": "force",
8
+ "allowImportingTsExtensions": true,
9
+ "verbatimModuleSyntax": true,
10
+ "noEmit": true,
11
+ "strict": true,
12
+ "skipLibCheck": true,
13
+ "resolveJsonModule": true,
14
+ "esModuleInterop": true,
15
+ "types": ["bun"]
16
+ },
17
+ "include": ["src/**/*.ts"]
18
+ }