jeo-code 0.12.0 → 0.12.1

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.
package/CHANGELOG.md CHANGED
@@ -9,6 +9,33 @@ The README mirrors the latest 5 entries — regenerate with `bun run changelog:s
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.12.1] - 2026-10-16
13
+ _Logged-in OpenAI subscription models were invisible on proxy-configured machines._
14
+
15
+ ### Fixed
16
+ - **OpenAI OAuth catalog discarded when a custom base URL is set** (`src/ai/model-discovery.ts`) — with `OPENAI_BASE_URL`/config `openaiBaseUrl` configured, discovery dropped the stored OAuth credential, probed the proxy keyless (`auth rejected`), and the Codex second pass never fired (it only covered `api_key` primaries). OpenAI has no static fallback by design, so the picker showed zero models despite a valid login. New `codexCatalog` option queries the ChatGPT subscription catalog ignoring any custom base URL; `discoverModels` now appends it whenever the primary pass did not already return the OAuth catalog. The post-login report (`jeo auth login openai`) uses it too.
17
+
18
+ ### Verified
19
+ - Live on a proxy-configured machine: `openai` rows went from 1 failed keyless row to keyless-fail + 7-model OAuth catalog; `providerPickEntries` returns 7 rows. `bun run typecheck` clean; discovery suites green including 2 new regression tests.
20
+
21
+ ## [0.12.1] - 2026-10-16
22
+ _Explicitly select the official agy full agent with its own live model catalog and session, separate from jeo's Cloud Code Assist backend._
23
+
24
+ ### Added
25
+ - **Opt-in official agy discovery and execution** — `agy/<official-cli-slug>` selects the installed, externally authenticated official CLI as a full agent, not a raw-model adapter or CCA alias. `/model provider agy` reads the live `agy models` list, preserves exact slugs, and reports empty lists and failures without static fallback. CLI catalogs stay process-local; no identity or credential parity with jeo OAuth is assumed.
26
+ - **Session-owned resume and process lifecycle** — saved jeo sessions retain their own CLI conversation ID rather than resuming the CLI's unrelated latest conversation. Turns support cancellation and bounded timeouts. The requested model and upstream quota/auth/permission errors remain visible, with no fallback to CCA, another model, or another account.
27
+ - **Explicit execution boundary** — the CLI owns its tools, sandbox, permissions, and conversation; jeo approvals do not mediate its inner tool calls. The bridge is text-only, excluded from automatic raw-model/subagent routing, and rejects images and jeo-only tool/system/step/thinking controls it cannot enforce.
28
+
29
+ ### Changed
30
+ - **CCA account model discovery** — combine `agentModelSorts`, `tieredModelIds`, and `defaultAgentModelId` instead of treating one metadata list as the whole chat catalog. Existing `antigravity/<CCA-id>` discovery remains scoped to the selected jeo OAuth account, without claiming direct CCA Argon support.
31
+
32
+ ### Fixed
33
+ - **Malformed normalized CCA IDs** — reject invalid discovery responses instead of replacing an account's known-good cache with malformed IDs. Authoritative empty lists remain empty, failed discovery remains a failure, and existing account-cache isolation is preserved.
34
+
35
+ ### Verification and release status
36
+ - A real, isolated source-jeo invocation of `jeo launch --model agy/gemini-4-argon-low --plan --no-tui --no-session --no-skills "Explain this repository"` exited **0**, reporting **30.5k input / 11 output tokens**. This verifies that CLI bridge invocation, not direct CCA Argon access or availability for every account.
37
+ - Three independent code, TypeScript, and security reviewers identified six failure-path issues; test-first fixes and regression coverage are in progress. Final release gates and public publication are not yet claimed.
38
+
12
39
  ## [0.12.0] - 2026-10-16
13
40
  _Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router._
14
41
 
package/README.ja.md CHANGED
@@ -395,10 +395,10 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
395
395
 
396
396
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
397
397
  - **[Unreleased]**
398
+ - **[0.12.1]** (2026-10-16) — Logged-in OpenAI subscription models were invisible on proxy-configured machines.
399
+ - **[0.12.1]** (2026-10-16) — Explicitly select the official agy full agent with its own live model catalog and session, separate from jeo's Cloud Code Assist backend.
398
400
  - **[0.12.0]** (2026-10-16) — Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router.
399
401
  - **[0.11.6]** (2026-10-16) — Live Antigravity account model discovery now serves the actual account's available models instead of assuming static availability.
400
- - **[0.11.5]** (2026-10-04) — Anthropic login now runs Opus 5.5 and Sonnet 5.5 as the selected models: the OAuth client version gate and incompatible fast-mode temperature are fixed, with real request and streaming responses verified.
401
- - **[0.11.4]** (2026-10-01) — The release pipeline could not actually release: 13 tests failed on Linux CI only, and the stored npm token no longer authenticated. Both are fixed at the root — the suite is order-independent, and publishing no longer depends on a secret that can expire.
402
402
 
403
403
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
404
404
  <!-- CHANGELOG:END -->
package/README.ko.md CHANGED
@@ -397,10 +397,10 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
397
397
 
398
398
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
399
399
  - **[Unreleased]**
400
+ - **[0.12.1]** (2026-10-16) — Logged-in OpenAI subscription models were invisible on proxy-configured machines.
401
+ - **[0.12.1]** (2026-10-16) — Explicitly select the official agy full agent with its own live model catalog and session, separate from jeo's Cloud Code Assist backend.
400
402
  - **[0.12.0]** (2026-10-16) — Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router.
401
403
  - **[0.11.6]** (2026-10-16) — Live Antigravity account model discovery now serves the actual account's available models instead of assuming static availability.
402
- - **[0.11.5]** (2026-10-04) — Anthropic login now runs Opus 5.5 and Sonnet 5.5 as the selected models: the OAuth client version gate and incompatible fast-mode temperature are fixed, with real request and streaming responses verified.
403
- - **[0.11.4]** (2026-10-01) — The release pipeline could not actually release: 13 tests failed on Linux CI only, and the stored npm token no longer authenticated. Both are fixed at the root — the suite is order-independent, and publishing no longer depends on a secret that can expire.
404
404
 
405
405
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
406
406
  <!-- CHANGELOG:END -->
package/README.md CHANGED
@@ -389,10 +389,10 @@ Huge thanks to [gajae-code](https://github.com/Yeachan-Heo/gajae-code) for the i
389
389
 
390
390
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
391
391
  - **[Unreleased]**
392
+ - **[0.12.1]** (2026-10-16) — Logged-in OpenAI subscription models were invisible on proxy-configured machines.
393
+ - **[0.12.1]** (2026-10-16) — Explicitly select the official agy full agent with its own live model catalog and session, separate from jeo's Cloud Code Assist backend.
392
394
  - **[0.12.0]** (2026-10-16) — Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router.
393
395
  - **[0.11.6]** (2026-10-16) — Live Antigravity account model discovery now serves the actual account's available models instead of assuming static availability.
394
- - **[0.11.5]** (2026-10-04) — Anthropic login now runs Opus 5.5 and Sonnet 5.5 as the selected models: the OAuth client version gate and incompatible fast-mode temperature are fixed, with real request and streaming responses verified.
395
- - **[0.11.4]** (2026-10-01) — The release pipeline could not actually release: 13 tests failed on Linux CI only, and the stored npm token no longer authenticated. Both are fixed at the root — the suite is order-independent, and publishing no longer depends on a secret that can expire.
396
396
 
397
397
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
398
398
  <!-- CHANGELOG:END -->
package/README.zh.md CHANGED
@@ -393,10 +393,10 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
393
393
 
394
394
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
395
395
  - **[Unreleased]**
396
+ - **[0.12.1]** (2026-10-16) — Logged-in OpenAI subscription models were invisible on proxy-configured machines.
397
+ - **[0.12.1]** (2026-10-16) — Explicitly select the official agy full agent with its own live model catalog and session, separate from jeo's Cloud Code Assist backend.
396
398
  - **[0.12.0]** (2026-10-16) — Karpathy behavioral guardrails become always-on discipline, and skill routing gains an ECC single-harness inventory plus a Jev-style advisory router.
397
399
  - **[0.11.6]** (2026-10-16) — Live Antigravity account model discovery now serves the actual account's available models instead of assuming static availability.
398
- - **[0.11.5]** (2026-10-04) — Anthropic login now runs Opus 5.5 and Sonnet 5.5 as the selected models: the OAuth client version gate and incompatible fast-mode temperature are fixed, with real request and streaming responses verified.
399
- - **[0.11.4]** (2026-10-01) — The release pipeline could not actually release: 13 tests failed on Linux CI only, and the stored npm token no longer authenticated. Both are fixed at the root — the suite is order-independent, and publishing no longer depends on a secret that can expire.
400
400
 
401
401
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
402
402
  <!-- CHANGELOG:END -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jeo-code",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Clean, highly optimized AI coding agent using spec-first loop",
5
5
  "type": "module",
6
6
  "main": "src/cli.ts",
@@ -63,6 +63,17 @@ export interface DiscoveryOptions {
63
63
  * queries both OpenAI catalogs when both credentials are configured.
64
64
  */
65
65
  preferOAuth?: boolean;
66
+ /**
67
+ * Query the ChatGPT Codex OAuth catalog even when a custom OpenAI base URL
68
+ * (config `openaiBaseUrl` or `OPENAI_BASE_URL`) is configured. A stored
69
+ * subscription is an independent catalog that lives at ChatGPT, never at
70
+ * the proxy — without this, a proxy-configured machine silently drops the
71
+ * OAuth credential, probes the proxy keyless, and surfaces zero models
72
+ * despite a valid login. Implies `preferOAuth` for OpenAI. Used by
73
+ * `discoverModels`' second pass and the post-login report; has no effect
74
+ * on other providers.
75
+ */
76
+ codexCatalog?: boolean;
66
77
  }
67
78
 
68
79
  const DEFAULT_TIMEOUT = 5000;
@@ -106,6 +117,7 @@ export function discoveryRequest(
106
117
  cred: Credential | undefined,
107
118
  baseUrl?: string,
108
119
  oauthAccountId?: string,
120
+ opts?: { forceCodexCatalog?: boolean },
109
121
  ): { url: string; headers: Record<string, string>; method?: "GET" | "POST"; body?: string } {
110
122
  // Catalog-driven compat providers: OpenAI `${base}/models` (Bearer) or Anthropic
111
123
  // `${base}/v1/models` (x-api-key). Both return { data: [{ id }] }.
@@ -123,7 +135,7 @@ export function discoveryRequest(
123
135
  return { url: "https://api.anthropic.com/v1/models", headers: anthropicHeaders(cred!) };
124
136
  case "openai": {
125
137
  const token = cred?.kind === "oauth" || cred?.kind === "api_key" ? cred.token : "";
126
- if (cred?.kind === "oauth" && !baseUrl && !process.env.OPENAI_BASE_URL) {
138
+ if (cred?.kind === "oauth" && (opts?.forceCodexCatalog || (!baseUrl && !process.env.OPENAI_BASE_URL))) {
127
139
  const accountId = extractChatgptAccountId(token) || oauthAccountId;
128
140
  const headers: Record<string, string> = {
129
141
  Authorization: `Bearer ${token}`,
@@ -348,6 +360,11 @@ export async function listProviderModels(
348
360
  const fetchImpl = opts.fetchImpl ?? fetch;
349
361
  const limit = opts.limit ?? (provider === "openai" || provider === "antigravity" ? Number.POSITIVE_INFINITY : DEFAULT_LIMIT);
350
362
  let baseUrl = opts.baseUrl;
363
+ // An explicit Codex-catalog request (discoverModels' second pass, the
364
+ // post-login report) ignores every custom base URL: the subscription
365
+ // catalog lives at ChatGPT, never at the proxy. Function-scoped (not
366
+ // block-scoped) so the request builder below can see it.
367
+ const forceCodexCatalog = provider === "openai" && !!opts.codexCatalog;
351
368
 
352
369
  let cred: Credential | undefined;
353
370
  let oauthAccountId: string | undefined;
@@ -365,7 +382,7 @@ export async function listProviderModels(
365
382
  cred = raw;
366
383
  source = cred.kind === "oauth" ? "oauth" : cred.kind === "api_key" ? "api_key" : "none";
367
384
  const config = opts.config ?? (await readGlobalConfig());
368
- if (provider === "openai") baseUrl = (baseUrl ?? config.openaiBaseUrl ?? process.env.OPENAI_BASE_URL)?.replace(/\/+$/, "");
385
+ if (provider === "openai" && !forceCodexCatalog) baseUrl = (baseUrl ?? config.openaiBaseUrl ?? process.env.OPENAI_BASE_URL)?.replace(/\/+$/, "");
369
386
 
370
387
  if (provider === "antigravity") {
371
388
  // Antigravity lists models from the LIVE Cloud Code Assist endpoint
@@ -390,12 +407,13 @@ export async function listProviderModels(
390
407
  // no api-key header), so never swap its credential to an api_key.
391
408
  // `preferOAuth` (post-login report only) skips this swap so the report
392
409
  // reflects the freshly stored OAuth credential, not an unrelated key.
393
- if (provider !== "antigravity" && cred.kind === "oauth" && config.providers?.[prov] && !opts.preferOAuth) {
410
+ // `codexCatalog` implies the same (plus base-URL immunity above).
411
+ if (provider !== "antigravity" && cred.kind === "oauth" && config.providers?.[prov] && !opts.preferOAuth && !forceCodexCatalog) {
394
412
  // An API key is the broader, documented path — prefer it for live discovery.
395
413
  cred = { kind: "api_key", provider: prov, token: config.providers[prov]! };
396
414
  source = "api_key";
397
415
  }
398
- if (provider === "openai" && baseUrl && cred.kind === "oauth") {
416
+ if (provider === "openai" && baseUrl && cred.kind === "oauth" && !forceCodexCatalog) {
399
417
  // Subscription credentials belong to ChatGPT, not a configured proxy.
400
418
  const key = config.providers?.openai;
401
419
  cred = key ? { kind: "api_key", provider: "openai", token: key } : { kind: "none", provider: "openai" };
@@ -456,7 +474,7 @@ export async function listProviderModels(
456
474
  }
457
475
  setAntigravityAccountScope(scope.accountId);
458
476
  }
459
- const { url, headers, method, body: requestBody } = discoveryRequest(provider, cred, baseUrl, oauthAccountId);
477
+ const { url, headers, method, body: requestBody } = discoveryRequest(provider, cred, baseUrl, oauthAccountId, forceCodexCatalog ? { forceCodexCatalog: true } : undefined);
460
478
  const res = await fetchImpl(url, { method: method ?? "GET", headers, body: requestBody, signal });
461
479
  if (!res.ok) {
462
480
  const reason = res.status === 401 || res.status === 403 ? "auth rejected" : `HTTP ${res.status}`;
@@ -584,12 +602,17 @@ export async function discoverModels(
584
602
  baseUrl: p === "ollama" ? (cfg.ollamaBaseUrl ?? opts.baseUrl) : p === "lmstudio" ? (cfg.lmstudioBaseUrl ?? opts.baseUrl) : p === "openai" ? (cfg.openaiBaseUrl ?? opts.baseUrl) : opts.baseUrl,
585
603
  };
586
604
  const primary = await listProviderModels(p, discoveryOpts);
587
- // Both credentials can coexist. API discovery alone omits subscription-only
588
- // models and never teaches the Codex call gate what this account can serve.
589
- if (p === "openai" && primary.source === "api_key" && !discoveryOpts.baseUrl && !process.env.OPENAI_BASE_URL) {
605
+ // A stored ChatGPT subscription is a second, independent catalog: the
606
+ // primary pass may have covered an API key or a custom proxy (or failed
607
+ // keyless against one) without ever asking the Codex endpoint. Whenever
608
+ // the primary pass did NOT already return the OAuth catalog, query it as
609
+ // an additional result so logged-in subscription models stay visible —
610
+ // otherwise a proxy-configured machine shows zero OpenAI models despite
611
+ // a valid login. The Codex pass ignores any custom base URL by construction.
612
+ if (p === "openai" && primary.source !== "oauth") {
590
613
  const credential = await resolveCredential("openai");
591
614
  if (credential.kind === "oauth") {
592
- return [primary, await listProviderModels(p, { ...discoveryOpts, preferOAuth: true })];
615
+ return [primary, await listProviderModels(p, { ...discoveryOpts, baseUrl: undefined, preferOAuth: true, codexCatalog: true })];
593
616
  }
594
617
  }
595
618
  return [primary];
@@ -156,7 +156,13 @@ const LIVE_MODEL_REPORT_PROVIDERS = new Set<AuthProvider>(["openai", "anthropic"
156
156
 
157
157
  async function reportLiveModels(provider: AuthProvider): Promise<void> {
158
158
  try {
159
- const result = await listProviderModels(provider, { preferOAuth: true });
159
+ // The OpenAI subscription catalog lives at ChatGPT, never at a custom
160
+ // proxy — request it explicitly so the report works on proxy-configured
161
+ // machines too (otherwise the OAuth credential is discarded for the
162
+ // proxy and the report shows nothing despite a fresh login).
163
+ const result = await listProviderModels(provider, provider === "openai"
164
+ ? { preferOAuth: true, codexCatalog: true }
165
+ : { preferOAuth: true });
160
166
  if (result.ok) {
161
167
  // Persist immediately: the very next `jeo` launch then knows this account's
162
168
  // real model set (including ids newer than the maintained static snapshot)