jeo-code 0.6.24 → 0.6.27
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 +25 -0
- package/README.ja.md +3 -3
- package/README.ko.md +3 -3
- package/README.md +3 -3
- package/README.zh.md +3 -3
- package/package.json +1 -1
- package/src/ai/model-manager.ts +6 -6
- package/src/ai/providers/anthropic.ts +4 -2
- package/src/ai/providers/antigravity.ts +5 -1
- package/src/ai/providers/gemini.ts +4 -3
- package/src/commands/launch/flags.ts +5 -2
- package/src/commands/launch.ts +31 -5
- package/src/tui/components/ascii-art.ts +41 -43
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
The README mirrors the latest 5 entries — regenerate with `bun run changelog:sync`.
|
|
8
8
|
|
|
9
|
+
## [0.6.27] - 2026-06-19
|
|
10
|
+
_Ponytail pass on the reasoning-tier mapper, plus a real-tmux verification of `jeo --tmux`._
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **`thinkingToReasoningEffort` collapsed to its essential mapping (ponytail/YAGNI pass).** The four redundant pass-through branches (`minimal`/`low`/`medium`/`high` each returning themselves) are now a single `level === "xhigh" ? "high" : level` — behavior-identical (every level still maps to a genuine reasoning effort; only an unset level stays off), 8 fewer lines, fully covered by the existing `model-manager`/`round-b` contract tests. Reasoning continues to activate at EVERY thinking level (gajae parity).
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **`/agents <role> provider <name>` now accepts every registered provider and always shows a model list (jeo team role config).** Three compounding bugs surfaced via a real `jeo --tmux` session pinning a role to `groq`: (1) `isProviderName` was an unsound type guard hardcoding only 5 names (`anthropic|openai|gemini|antigravity|ollama`), so `/agents <role> provider groq` (and every other OpenAI-compat provider — deepseek, openrouter, mistral, …) was rejected as invalid usage; it now validates against the canonical `PROVIDER_NAMES` registry. (2) Live discovery only returns ids for a logged-in, reachable provider, and the catalog backfill applied only to OAuth-source providers — so an unconfigured API-key provider showed an EMPTY model list and silently pinned a bare default. (3) The 24 OpenAI-compat providers carry no capability-catalog rows, so even the catalog fallback was empty for them. The new `providerPickEntries` helper now climbs live ids → static catalog → the provider's known default model, so the list is never empty, and the source is labeled (`Live`/`Catalog … log in to list live models`). Verified end-to-end in a real tmux session (`#1 groq/llama-3.3-70b-versatile` listed and pinned). Covered by `test/provider-pick-entries.test.ts` and a new `isProviderName` regression test in `test/launch-flags.test.ts`.
|
|
17
|
+
|
|
18
|
+
### Verified
|
|
19
|
+
- **`jeo --tmux` session profile confirmed against the real `tmux` binary.** The gjc-parity profile (`mouse on`, `@jeo-profile`/`@jeo-branch`/`@jeo-project` markers, `set-clipboard on`, copy-mode `mode-style`) was exercised on an isolated `-L` socket using the exact `=name:` target syntax the launch code emits — every option set and read back correctly. `test/tmux.test.ts` passes 12/0 alongside the full 1645/0 suite.
|
|
20
|
+
|
|
21
|
+
## [0.6.26] - 2026-06-19
|
|
22
|
+
_The forge emblem is redrawn again as the mascot crayfish, foregrounding its signature pincer claws (집게)._
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- **Forge emblem redrawn as the mascot crayfish with raised pincer claws (집게).** The compact and grand forge marks (`FORGE_MARK_ART` / `_GRAND`) now read as the neon crayfish (가재) from `assets/character.png`, foregrounding its defining feature — two raised pincer claws on angled arms (`◣◣ ◢◢` jaws over `◆══╲ ╱══◆` arms) above the glowing eye/terminal cluster (`◉◉◉`) and a rounded carapace/tail. Purely pictographic and wordless (no embedded lettering), width-1 glyphs only so the TUI's padding/centering math stays exact; the blink frames snap the claws shut so the crayfish "clicks". Cross-checked against gajae-code's image-based crab/crayfish brand and the shared blue→violet→pink neon palette. The grand variant stays wide enough (30 cols) to keep the narrow-box compact fallback reachable.
|
|
26
|
+
|
|
27
|
+
## [0.6.25] - 2026-06-19
|
|
28
|
+
_Reasoning works at every thinking level (gajae parity), and the forge emblem is redrawn as the neon-lens coding wizard._
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
- **Reasoning now activates at EVERY thinking level — no level restriction (gajae parity).** Previously the lowest tier disabled reasoning entirely: `thinkingToReasoningEffort` collapsed `minimal`→`low`, and the provider budgets treated `minimal`/unset effort as OFF, so picking the lowest level (or `/fast`) silently turned thinking off. `minimal` is now a genuine lightest reasoning effort threaded end to end — Anthropic (`minimal → 2000` budget_tokens), Gemini (`minimal → 2000`, clamped under the output cap), and Antigravity-Claude (`minimal → 2000`) all enable scaling-depth thinking for `minimal`/`low`/`medium`/`high`, matching gajae-code's `[Minimal, Low, Medium, High]` effort set. Only a fully UNSET effort stays non-thinking (the explicit off path). `xhigh` still maps to the deepest `high` tier the provider APIs accept.
|
|
32
|
+
- **Forge emblem redrawn as the mascot neon-lens coding wizard.** The compact and grand forge marks (`FORGE_MARK_ART` / `_GRAND`) now read as the character from `assets/character.png` — a pointed wizard hat with a twinkling star tip, the glowing asymmetric ◆/◇ neon lens eyes on a nose-bridge, and the violet gown shoulders cradling the glowing terminal screen the wizard holds (`◉◉◉`). Purely pictographic and wordless (no embedded lettering), width-1 glyphs only so the TUI's padding/centering math stays exact; the blink frames twinkle the star and wink the lenses.
|
|
33
|
+
|
|
9
34
|
## [0.6.24] - 2026-06-19
|
|
10
35
|
_`/provider` opens an interactive onboarding selector (OAuth vs API-compatible), and OpenAI-compatible backends gain per-vendor native-reasoning formats._
|
|
11
36
|
|
package/README.ja.md
CHANGED
|
@@ -204,11 +204,11 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
|
|
|
204
204
|
## 変更履歴 (Changelog)
|
|
205
205
|
|
|
206
206
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
207
|
+
- **[0.6.27]** (2026-06-19) — Ponytail pass on the reasoning-tier mapper, plus a real-tmux verification of `jeo --tmux`.
|
|
208
|
+
- **[0.6.26]** (2026-06-19) — The forge emblem is redrawn again as the mascot crayfish, foregrounding its signature pincer claws (집게).
|
|
209
|
+
- **[0.6.25]** (2026-06-19) — Reasoning works at every thinking level (gajae parity), and the forge emblem is redrawn as the neon-lens coding wizard.
|
|
207
210
|
- **[0.6.24]** (2026-06-19) — `/provider` opens an interactive onboarding selector (OAuth vs API-compatible), and OpenAI-compatible backends gain per-vendor native-reasoning formats.
|
|
208
211
|
- **[0.6.23]** (2026-06-19) — Live reasoning/thinking streams in the TUI across every provider, three new OpenAI-compatible backends (LM Studio, xAI, Kimi) join the auth/discovery/catalog surface, and Gemini gains native function-calling.
|
|
209
|
-
- **[0.6.22]** (2026-06-18) — Extended-thinking activation is now consistent across providers: a `low` session thinking level enables reasoning everywhere.
|
|
210
|
-
- **[0.6.21]** (2026-06-18) — Session thinking level now reaches the provider's actual reasoning depth, not just the token ceiling.
|
|
211
|
-
- **[0.6.20]** (2026-06-18) — Launch REPL internals decomposed into testable modules: `@mention` path completion, slash-command view renderers, and slash-command handlers extracted from the monolithic `launch.ts` into dedicated files with full unit-test coverage.
|
|
212
212
|
|
|
213
213
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
214
214
|
<!-- CHANGELOG:END -->
|
package/README.ko.md
CHANGED
|
@@ -204,11 +204,11 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
|
|
|
204
204
|
## 변경 이력 (Changelog)
|
|
205
205
|
|
|
206
206
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
207
|
+
- **[0.6.27]** (2026-06-19) — Ponytail pass on the reasoning-tier mapper, plus a real-tmux verification of `jeo --tmux`.
|
|
208
|
+
- **[0.6.26]** (2026-06-19) — The forge emblem is redrawn again as the mascot crayfish, foregrounding its signature pincer claws (집게).
|
|
209
|
+
- **[0.6.25]** (2026-06-19) — Reasoning works at every thinking level (gajae parity), and the forge emblem is redrawn as the neon-lens coding wizard.
|
|
207
210
|
- **[0.6.24]** (2026-06-19) — `/provider` opens an interactive onboarding selector (OAuth vs API-compatible), and OpenAI-compatible backends gain per-vendor native-reasoning formats.
|
|
208
211
|
- **[0.6.23]** (2026-06-19) — Live reasoning/thinking streams in the TUI across every provider, three new OpenAI-compatible backends (LM Studio, xAI, Kimi) join the auth/discovery/catalog surface, and Gemini gains native function-calling.
|
|
209
|
-
- **[0.6.22]** (2026-06-18) — Extended-thinking activation is now consistent across providers: a `low` session thinking level enables reasoning everywhere.
|
|
210
|
-
- **[0.6.21]** (2026-06-18) — Session thinking level now reaches the provider's actual reasoning depth, not just the token ceiling.
|
|
211
|
-
- **[0.6.20]** (2026-06-18) — Launch REPL internals decomposed into testable modules: `@mention` path completion, slash-command view renderers, and slash-command handlers extracted from the monolithic `launch.ts` into dedicated files with full unit-test coverage.
|
|
212
212
|
|
|
213
213
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
214
214
|
<!-- CHANGELOG:END -->
|
package/README.md
CHANGED
|
@@ -204,11 +204,11 @@ Required npm token permissions (repository secret `NPM_TOKEN`):
|
|
|
204
204
|
## Changelog
|
|
205
205
|
|
|
206
206
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
207
|
+
- **[0.6.27]** (2026-06-19) — Ponytail pass on the reasoning-tier mapper, plus a real-tmux verification of `jeo --tmux`.
|
|
208
|
+
- **[0.6.26]** (2026-06-19) — The forge emblem is redrawn again as the mascot crayfish, foregrounding its signature pincer claws (집게).
|
|
209
|
+
- **[0.6.25]** (2026-06-19) — Reasoning works at every thinking level (gajae parity), and the forge emblem is redrawn as the neon-lens coding wizard.
|
|
207
210
|
- **[0.6.24]** (2026-06-19) — `/provider` opens an interactive onboarding selector (OAuth vs API-compatible), and OpenAI-compatible backends gain per-vendor native-reasoning formats.
|
|
208
211
|
- **[0.6.23]** (2026-06-19) — Live reasoning/thinking streams in the TUI across every provider, three new OpenAI-compatible backends (LM Studio, xAI, Kimi) join the auth/discovery/catalog surface, and Gemini gains native function-calling.
|
|
209
|
-
- **[0.6.22]** (2026-06-18) — Extended-thinking activation is now consistent across providers: a `low` session thinking level enables reasoning everywhere.
|
|
210
|
-
- **[0.6.21]** (2026-06-18) — Session thinking level now reaches the provider's actual reasoning depth, not just the token ceiling.
|
|
211
|
-
- **[0.6.20]** (2026-06-18) — Launch REPL internals decomposed into testable modules: `@mention` path completion, slash-command view renderers, and slash-command handlers extracted from the monolithic `launch.ts` into dedicated files with full unit-test coverage.
|
|
212
212
|
|
|
213
213
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
214
214
|
<!-- CHANGELOG:END -->
|
package/README.zh.md
CHANGED
|
@@ -204,11 +204,11 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
|
|
|
204
204
|
## 更新日志 (Changelog)
|
|
205
205
|
|
|
206
206
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
207
|
+
- **[0.6.27]** (2026-06-19) — Ponytail pass on the reasoning-tier mapper, plus a real-tmux verification of `jeo --tmux`.
|
|
208
|
+
- **[0.6.26]** (2026-06-19) — The forge emblem is redrawn again as the mascot crayfish, foregrounding its signature pincer claws (집게).
|
|
209
|
+
- **[0.6.25]** (2026-06-19) — Reasoning works at every thinking level (gajae parity), and the forge emblem is redrawn as the neon-lens coding wizard.
|
|
207
210
|
- **[0.6.24]** (2026-06-19) — `/provider` opens an interactive onboarding selector (OAuth vs API-compatible), and OpenAI-compatible backends gain per-vendor native-reasoning formats.
|
|
208
211
|
- **[0.6.23]** (2026-06-19) — Live reasoning/thinking streams in the TUI across every provider, three new OpenAI-compatible backends (LM Studio, xAI, Kimi) join the auth/discovery/catalog surface, and Gemini gains native function-calling.
|
|
209
|
-
- **[0.6.22]** (2026-06-18) — Extended-thinking activation is now consistent across providers: a `low` session thinking level enables reasoning everywhere.
|
|
210
|
-
- **[0.6.21]** (2026-06-18) — Session thinking level now reaches the provider's actual reasoning depth, not just the token ceiling.
|
|
211
|
-
- **[0.6.20]** (2026-06-18) — Launch REPL internals decomposed into testable modules: `@mention` path completion, slash-command view renderers, and slash-command handlers extracted from the monolithic `launch.ts` into dedicated files with full unit-test coverage.
|
|
212
212
|
|
|
213
213
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
214
214
|
<!-- CHANGELOG:END -->
|
package/package.json
CHANGED
package/src/ai/model-manager.ts
CHANGED
|
@@ -100,15 +100,15 @@ export function thinkingMaxTokens(level?: "minimal" | "low" | "medium" | "high"
|
|
|
100
100
|
return 16000;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
/** Map the thinking level to an OpenAI reasoning-effort tier.
|
|
104
|
-
*
|
|
103
|
+
/** Map the thinking level to an OpenAI reasoning-effort tier. minimal/low/medium/high pass
|
|
104
|
+
* through unchanged and xhigh folds to high (the deepest tier the provider APIs accept), so
|
|
105
|
+
* reasoning works at EVERY thinking level (gajae parity: minimal is a real effort). Only an
|
|
106
|
+
* unset level returns undefined (reasoning off — the explicit /fast path). */
|
|
105
107
|
export function thinkingToReasoningEffort(
|
|
106
108
|
level?: "minimal" | "low" | "medium" | "high" | "xhigh",
|
|
107
|
-
): "low" | "medium" | "high" | undefined {
|
|
109
|
+
): "minimal" | "low" | "medium" | "high" | undefined {
|
|
108
110
|
if (!level) return undefined;
|
|
109
|
-
|
|
110
|
-
if (level === "high" || level === "xhigh") return "high";
|
|
111
|
-
return "medium";
|
|
111
|
+
return level === "xhigh" ? "high" : level;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/** Describe a model id: alias expansion + the provider it routes to. For `/model` + diagnostics.
|
|
@@ -73,11 +73,13 @@ function anthropicSystemBlocks(
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
/** Anthropic extended-thinking budget by reasoning effort (kept under max_tokens). Cross-provider
|
|
76
|
-
* parity (matches Gemini's tiers): low/medium/high
|
|
77
|
-
*
|
|
76
|
+
* parity (matches Gemini's tiers): minimal/low/medium/high ALL enable thinking with scaling
|
|
77
|
+
* depth — reasoning works at every thinking level (gajae parity: Minimal is a real effort).
|
|
78
|
+
* Only an UNSET effort stays non-thinking (the explicit /fast off path). */
|
|
78
79
|
function anthropicThinkingBudget(effort: CallOptions["reasoningEffort"], maxTokens: number): number | undefined {
|
|
79
80
|
let budget: number;
|
|
80
81
|
switch (effort) {
|
|
82
|
+
case "minimal": budget = 2000; break;
|
|
81
83
|
case "low": budget = 4000; break;
|
|
82
84
|
case "medium": budget = 10000; break;
|
|
83
85
|
case "high": budget = 24000; break;
|
|
@@ -9,11 +9,15 @@ import { geminiThinkingBudget } from "./gemini";
|
|
|
9
9
|
const ANTIGRAVITY_DAILY_ENDPOINT = "https://daily-cloudcode-pa.googleapis.com";
|
|
10
10
|
const ANTIGRAVITY_SANDBOX_ENDPOINT = "https://daily-cloudcode-pa.sandbox.googleapis.com";
|
|
11
11
|
|
|
12
|
+
|
|
12
13
|
/** Anthropic-style thinking budget for Claude served via CCA. gemini's budget fn
|
|
13
14
|
* returns undefined for claude ids, which left antigravity Claude with NO thinking
|
|
14
|
-
* requested (the opus "no reasoning" gap). Mirrors anthropic's effort→budget tiers
|
|
15
|
+
* requested (the opus "no reasoning" gap). Mirrors anthropic's effort→budget tiers —
|
|
16
|
+
* minimal/low/medium/high ALL think (gajae parity: reasoning at every level); only an
|
|
17
|
+
* UNSET effort stays non-thinking. */
|
|
15
18
|
function antigravityClaudeThinkingBudget(effort: CallOptions["reasoningEffort"]): number | undefined {
|
|
16
19
|
switch (effort) {
|
|
20
|
+
case "minimal": return 2000;
|
|
17
21
|
case "low": return 4000;
|
|
18
22
|
case "medium": return 10000;
|
|
19
23
|
case "high": return 24000;
|
|
@@ -24,14 +24,15 @@ export function geminiThinkingBudget(model: string, effort?: CallOptions["reason
|
|
|
24
24
|
const floor = m.includes("pro") ? 128 : 0; // pro-class cannot fully disable thinking
|
|
25
25
|
let budget: number;
|
|
26
26
|
switch (effort) {
|
|
27
|
+
// minimal/low/medium/high ALL enable thinking with scaling depth — reasoning works at
|
|
28
|
+
// every thinking level (gajae parity: Minimal is a real effort). Only an UNSET effort
|
|
29
|
+
// falls through to the floor (off for flash-class, the API minimum for pro-class).
|
|
30
|
+
case "minimal": budget = Math.max(floor, 2000); break;
|
|
27
31
|
case "low": budget = 4000; break;
|
|
28
32
|
case "medium": budget = 10000; break;
|
|
29
33
|
case "high": budget = 24000; break;
|
|
30
|
-
case "minimal":
|
|
31
34
|
default: budget = floor;
|
|
32
35
|
}
|
|
33
|
-
// Thought tokens bill against maxOutputTokens: keep at least ~1K of the output
|
|
34
|
-
// budget for visible text, or thinking starves the reply to an empty MAX_TOKENS.
|
|
35
36
|
if (typeof maxTokens === "number") budget = Math.min(budget, Math.max(floor, maxTokens - 1024));
|
|
36
37
|
return budget;
|
|
37
38
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { type ProviderName, type ModelRole, type ThinkLevel, catalogMetadata } from "../../ai";
|
|
3
|
+
import { type ProviderName, type ModelRole, type ThinkLevel, catalogMetadata, PROVIDER_NAMES } from "../../ai";
|
|
4
4
|
|
|
5
5
|
export interface LaunchFlags {
|
|
6
6
|
list: boolean;
|
|
@@ -39,7 +39,10 @@ function takeValue(args: string[], index: number, inlinePrefix: string): { value
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export function isProviderName(input: string | undefined): input is ProviderName {
|
|
42
|
-
|
|
42
|
+
// Validate against the canonical registry, not a hand-maintained subset — the
|
|
43
|
+
// old 5-name list silently rejected every OpenAI-compat provider (groq,
|
|
44
|
+
// deepseek, openrouter, …) at `/agents <role> provider <name>`.
|
|
45
|
+
return input !== undefined && (PROVIDER_NAMES as readonly string[]).includes(input);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
export function isThinkingLevel(input: string | undefined): input is ThinkLevel {
|
package/src/commands/launch.ts
CHANGED
|
@@ -36,7 +36,7 @@ import { callLlm, type Message } from "../agent/loop";
|
|
|
36
36
|
import { friendlyProviderError } from "../util/provider-error";
|
|
37
37
|
import { readGlobalConfig, saveConfigPatch } from "../agent/state";
|
|
38
38
|
import { rememberModelPatch, recentModelsForDisplay } from "../agent/model-recency";
|
|
39
|
-
import { describeModel, describeAllProviders, thinkingMaxTokens, thinkingToReasoningEffort, discoverModels, flattenModels, resolveSelection, catalogMetadata, resolveRoleModel, CODEX_MODELS, qualifyModelId } from "../ai";
|
|
39
|
+
import { describeModel, describeAllProviders, thinkingMaxTokens, thinkingToReasoningEffort, discoverModels, flattenModels, resolveSelection, catalogMetadata, catalogByProvider, resolveRoleModel, CODEX_MODELS, qualifyModelId } from "../ai";
|
|
40
40
|
import type { ProviderModelsResult, PickEntry, ProviderName, ModelRole, ThinkLevel } from "../ai";
|
|
41
41
|
import { readGoalState, writeGoalState, clearGoalState, verifyGoal } from "../agent/goal-verifier";
|
|
42
42
|
|
|
@@ -232,6 +232,29 @@ function providerDefaultModel(p: ProviderName): string {
|
|
|
232
232
|
return openaiCompatDef(p)?.defaultModel ?? STATIC_PROVIDER_DEFAULT[p] ?? "";
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Pick-list entries for ONE provider, with static fallbacks so the list is never
|
|
237
|
+
* empty.
|
|
238
|
+
*
|
|
239
|
+
* Live discovery yields ids only for a logged-in, reachable provider, and
|
|
240
|
+
* `catalogOr` backfills the static catalog ONLY for OAuth sources — so an
|
|
241
|
+
* API-key/keyless provider that isn't configured yet had an empty list and was
|
|
242
|
+
* silently pinned to a bare default. Prefer live ids; else the provider's
|
|
243
|
+
* capability catalog; else its single known default model (all 24 OpenAI-compat
|
|
244
|
+
* providers carry one) so the user always sees at least one pickable id.
|
|
245
|
+
*/
|
|
246
|
+
export function providerPickEntries(live: ProviderModelsResult[], want: ProviderName): PickEntry[] {
|
|
247
|
+
const fromLive = flattenModels(live.filter(r => r.provider === want));
|
|
248
|
+
if (fromLive.length) return fromLive;
|
|
249
|
+
const catalog = catalogByProvider(want);
|
|
250
|
+
if (catalog.length) {
|
|
251
|
+
return catalog.map((m, i) => ({ index: i + 1, provider: want, model: qualifyModelId(m.providerModel, want) }));
|
|
252
|
+
}
|
|
253
|
+
const fallback = providerDefaultModel(want);
|
|
254
|
+
return fallback ? [{ index: 1, provider: want, model: qualifyModelId(fallback, want) }] : [];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
|
|
235
258
|
|
|
236
259
|
export function formatResumeHint(sessionId: string): string {
|
|
237
260
|
return `Resume with: jeo launch --resume ${sessionId}`;
|
|
@@ -3462,7 +3485,7 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
3462
3485
|
if (modelArg?.toLowerCase() === "provider") {
|
|
3463
3486
|
const want = (tokens[2] ?? "").toLowerCase();
|
|
3464
3487
|
if (!isProviderName(want)) {
|
|
3465
|
-
console.log(`Usage: /agents ${role.id} provider <
|
|
3488
|
+
console.log(`Usage: /agents ${role.id} provider <name> [model|#N] — e.g. anthropic, openai, gemini, groq, deepseek, openrouter (any configured provider)`);
|
|
3466
3489
|
continue;
|
|
3467
3490
|
}
|
|
3468
3491
|
const st = (await describeAllProviders()).find(s => s.name === want);
|
|
@@ -3475,7 +3498,8 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
3475
3498
|
}
|
|
3476
3499
|
}
|
|
3477
3500
|
const live = await getLiveModels();
|
|
3478
|
-
const forProvider =
|
|
3501
|
+
const forProvider = providerPickEntries(live, want);
|
|
3502
|
+
const liveForProvider = live.some(r => r.ok && r.provider === want && r.models.length > 0);
|
|
3479
3503
|
const explicit = tokens[3];
|
|
3480
3504
|
let chosenModel: string;
|
|
3481
3505
|
if (explicit && forProvider.length) {
|
|
@@ -3494,7 +3518,7 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
3494
3518
|
} else if (explicit) {
|
|
3495
3519
|
chosenModel = qualifyModelId(explicit, want);
|
|
3496
3520
|
} else if (forProvider.length) {
|
|
3497
|
-
// No model given → the provider's first
|
|
3521
|
+
// No model given → the provider's first known model, provider-qualified.
|
|
3498
3522
|
chosenModel = qualifyModelId(forProvider[0]!.model, want);
|
|
3499
3523
|
} else {
|
|
3500
3524
|
chosenModel = providerDefaultModel(want);
|
|
@@ -3503,7 +3527,9 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
3503
3527
|
console.log(`${role.title} pinned to ${want} via model ${chosenModel} — saved to ~/.jeo/config.json`);
|
|
3504
3528
|
if (forProvider.length) {
|
|
3505
3529
|
lastPickIndex = forProvider;
|
|
3506
|
-
|
|
3530
|
+
const sourceNote = liveForProvider ? "Live" : "Catalog";
|
|
3531
|
+
const tail = liveForProvider ? "" : " (log in to list live models)";
|
|
3532
|
+
console.log(`${sourceNote} ${want} models — refine with /agents ${role.id} #N:${tail}`);
|
|
3507
3533
|
for (const line of formatPickListWithCapabilities(lastPickIndex, { current: chosenModel, cap: 12 })) console.log(line);
|
|
3508
3534
|
}
|
|
3509
3535
|
continue;
|
|
@@ -412,50 +412,48 @@ export async function animateFrames(stage: AsciiStage, opts: AnimateFramesOption
|
|
|
412
412
|
}
|
|
413
413
|
return total;
|
|
414
414
|
}
|
|
415
|
-
/** The compact jeo forge mark: a
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
* (
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
415
|
+
/** The compact jeo forge mark: a horizontal lobster/crayfish (가재) emblem composed
|
|
416
|
+
* of SIMPLE, DISCONNECTED shapes (no connecting strokes) that together read as the
|
|
417
|
+
* mascot lying on its side, left→right: the raised pincer CLAWS (집게) as the splayed
|
|
418
|
+
* corner wedges (◤◣ left, ◥◢ right), the body carrying the JEO wordmark (J E O), and
|
|
419
|
+
* a DNA double-helix woven above and below as a row of crossing nodes (╳ = base-pair
|
|
420
|
+
* crossings). gjc-forge aesthetic: clean negative space, geometric symmetry, the
|
|
421
|
+
* blue→violet→pink flow gradient applied by renderForgeMark doing the neon glow. The
|
|
422
|
+
* lobster identity is carried by the disconnected silhouette; the JEO typography is
|
|
423
|
+
* the deliberate lettermark at the core. Width-1 glyphs only (box drawing + geometrics)
|
|
422
424
|
* so padding/centering math stays exact. Frame 0 is the static symbol. */
|
|
423
425
|
export const FORGE_MARK_ART: string[] = [
|
|
424
|
-
"
|
|
425
|
-
"
|
|
426
|
-
"
|
|
427
|
-
" ◀▮▶ "
|
|
426
|
+
"◤ ╳ ╳ ╳ ╳ ◥",
|
|
427
|
+
"❮ J E O ▮",
|
|
428
|
+
"◣ ╳ ╳ ╳ ╳ ◢"
|
|
428
429
|
];
|
|
429
430
|
|
|
430
431
|
export const FORGE_MARK_ART_ASCII: string[] = [
|
|
431
|
-
"
|
|
432
|
-
"
|
|
433
|
-
"
|
|
434
|
-
" <#> "
|
|
432
|
+
"/ x x x x \\",
|
|
433
|
+
"< J E O |",
|
|
434
|
+
"\\ x x x x /"
|
|
435
435
|
];
|
|
436
436
|
|
|
437
|
-
/**
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
* Frame 0 === FORGE_MARK_ART, so a frameless render is byte-identical to the
|
|
441
|
-
*
|
|
437
|
+
/** Claw-snap blink frames for the compact lobster forge mark: the helix nodes, the
|
|
438
|
+
* JEO body and the inner claw/tail glyphs stay fixed while the four splayed pincer
|
|
439
|
+
* CORNERS snap (◤◣ / ◥◢ open → ◢◥ / ◣◤ closed), so the lobster "clicks" its claws.
|
|
440
|
+
* Frame 0 === FORGE_MARK_ART, so a frameless render is byte-identical to the static
|
|
441
|
+
* symbol. All lines share the same width and width-1 glyphs. */
|
|
442
442
|
export const FORGE_MARK_FRAMES: string[][] = [
|
|
443
443
|
FORGE_MARK_ART,
|
|
444
444
|
[
|
|
445
|
-
"
|
|
446
|
-
"
|
|
447
|
-
"
|
|
448
|
-
" ◀▯▶ "
|
|
445
|
+
"◢ ╳ ╳ ╳ ╳ ◣",
|
|
446
|
+
"❮ J E O ▮",
|
|
447
|
+
"◥ ╳ ╳ ╳ ╳ ◤"
|
|
449
448
|
]
|
|
450
449
|
];
|
|
451
450
|
|
|
452
451
|
export const FORGE_MARK_FRAMES_ASCII: string[][] = [
|
|
453
452
|
FORGE_MARK_ART_ASCII,
|
|
454
453
|
[
|
|
455
|
-
"
|
|
456
|
-
"
|
|
457
|
-
"
|
|
458
|
-
" <_> "
|
|
454
|
+
"\\ x x x x /",
|
|
455
|
+
"< J E O |",
|
|
456
|
+
"/ x x x x \\"
|
|
459
457
|
]
|
|
460
458
|
];
|
|
461
459
|
|
|
@@ -464,25 +462,25 @@ export function forgeMarkFrameCount(): number {
|
|
|
464
462
|
return FORGE_MARK_FRAMES.length;
|
|
465
463
|
}
|
|
466
464
|
|
|
467
|
-
/** Grand hero variant for the welcome forge box (gjc-style spacious banner): the
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
465
|
+
/** Grand hero variant for the welcome forge box (gjc-style spacious banner): the same
|
|
466
|
+
* horizontal lobster emblem rendered large — the splayed pincer claws as corner wedges
|
|
467
|
+
* (◤◣ left, ◥◢ right), the JEO wordmark spaced across the body (J E O), and the DNA
|
|
468
|
+
* double-helix woven above and below as a wider row of crossing nodes (╳). gjc-forge
|
|
469
|
+
* aesthetic: generous negative space + geometric symmetry, with renderForgeMark's
|
|
470
|
+
* blue→violet→pink flow gradient supplying the neon glow. The JEO typography is the
|
|
471
|
+
* deliberate lettermark; the lobster reads from the disconnected silhouette. Width 29
|
|
472
|
+
* (matches the welcome compact↔grand threshold) and width-1 glyphs only so
|
|
473
|
+
* padding/centering math stays exact. */
|
|
474
474
|
export const FORGE_MARK_ART_GRAND: string[] = [
|
|
475
|
-
"
|
|
476
|
-
"
|
|
477
|
-
"
|
|
478
|
-
" ◀──▮──▶ "
|
|
475
|
+
"◤ ╳ ╳ ╳ ╳ ╳ ╳ ◥",
|
|
476
|
+
"❮ J E O ▮",
|
|
477
|
+
"◣ ╳ ╳ ╳ ╳ ╳ ╳ ◢"
|
|
479
478
|
];
|
|
480
479
|
|
|
481
480
|
export const FORGE_MARK_ART_GRAND_ASCII: string[] = [
|
|
482
|
-
"
|
|
483
|
-
"
|
|
484
|
-
"
|
|
485
|
-
" <--#--> "
|
|
481
|
+
"/ x x x x x x \\",
|
|
482
|
+
"< J E O |",
|
|
483
|
+
"\\ x x x x x x /"
|
|
486
484
|
];
|
|
487
485
|
|
|
488
486
|
|