jeo-code 0.5.5 → 0.5.6

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/README.ja.md CHANGED
@@ -150,11 +150,11 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
150
150
  ## 変更履歴 (Changelog)
151
151
 
152
152
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
153
+ - **[0.5.6]** (2026-06-15) — `/model` sets only the default thinking; per-role reasoning moved to `/agents`.
153
154
  - **[0.5.5]** (2026-06-15) — Full multi-line visibility — the input box scrolls to the caret and the submitted card shows every line.
154
155
  - **[0.5.4]** (2026-06-15) — Reliable multi-line input is ON by default — a paste fills the box and submits as one message.
155
156
  - **[0.5.3]** (2026-06-15) — `$` chains multiple skills in one line (all run, in order), plus multi-line prompt input — paste-merge and gated Shift+Enter.
156
157
  - **[0.5.2]** (2026-06-14) — `$skill` prompt invocation with prefix/fuzzy suggestions, and a per-session input-box hue (amber in cmd-mode).
157
- - **[0.5.1]** (2026-06-14) — cmd-mode `!<command>` shell escape — run a shell command without engaging the agent.
158
158
 
159
159
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
160
160
  <!-- CHANGELOG:END -->
package/README.ko.md CHANGED
@@ -150,11 +150,11 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
150
150
  ## 변경 이력 (Changelog)
151
151
 
152
152
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
153
+ - **[0.5.6]** (2026-06-15) — `/model` sets only the default thinking; per-role reasoning moved to `/agents`.
153
154
  - **[0.5.5]** (2026-06-15) — Full multi-line visibility — the input box scrolls to the caret and the submitted card shows every line.
154
155
  - **[0.5.4]** (2026-06-15) — Reliable multi-line input is ON by default — a paste fills the box and submits as one message.
155
156
  - **[0.5.3]** (2026-06-15) — `$` chains multiple skills in one line (all run, in order), plus multi-line prompt input — paste-merge and gated Shift+Enter.
156
157
  - **[0.5.2]** (2026-06-14) — `$skill` prompt invocation with prefix/fuzzy suggestions, and a per-session input-box hue (amber in cmd-mode).
157
- - **[0.5.1]** (2026-06-14) — cmd-mode `!<command>` shell escape — run a shell command without engaging the agent.
158
158
 
159
159
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
160
160
  <!-- CHANGELOG:END -->
package/README.md CHANGED
@@ -150,11 +150,11 @@ Required npm token permissions (repository secret `NPM_TOKEN`):
150
150
  ## Changelog
151
151
 
152
152
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
153
+ - **[0.5.6]** (2026-06-15) — `/model` sets only the default thinking; per-role reasoning moved to `/agents`.
153
154
  - **[0.5.5]** (2026-06-15) — Full multi-line visibility — the input box scrolls to the caret and the submitted card shows every line.
154
155
  - **[0.5.4]** (2026-06-15) — Reliable multi-line input is ON by default — a paste fills the box and submits as one message.
155
156
  - **[0.5.3]** (2026-06-15) — `$` chains multiple skills in one line (all run, in order), plus multi-line prompt input — paste-merge and gated Shift+Enter.
156
157
  - **[0.5.2]** (2026-06-14) — `$skill` prompt invocation with prefix/fuzzy suggestions, and a per-session input-box hue (amber in cmd-mode).
157
- - **[0.5.1]** (2026-06-14) — cmd-mode `!<command>` shell escape — run a shell command without engaging the agent.
158
158
 
159
159
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
160
160
  <!-- CHANGELOG:END -->
package/README.zh.md CHANGED
@@ -150,11 +150,11 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
150
150
  ## 更新日志 (Changelog)
151
151
 
152
152
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
153
+ - **[0.5.6]** (2026-06-15) — `/model` sets only the default thinking; per-role reasoning moved to `/agents`.
153
154
  - **[0.5.5]** (2026-06-15) — Full multi-line visibility — the input box scrolls to the caret and the submitted card shows every line.
154
155
  - **[0.5.4]** (2026-06-15) — Reliable multi-line input is ON by default — a paste fills the box and submits as one message.
155
156
  - **[0.5.3]** (2026-06-15) — `$` chains multiple skills in one line (all run, in order), plus multi-line prompt input — paste-merge and gated Shift+Enter.
156
157
  - **[0.5.2]** (2026-06-14) — `$skill` prompt invocation with prefix/fuzzy suggestions, and a per-session input-box hue (amber in cmd-mode).
157
- - **[0.5.1]** (2026-06-14) — cmd-mode `!<command>` shell escape — run a shell command without engaging the agent.
158
158
 
159
159
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
160
160
  <!-- CHANGELOG:END -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jeo-code",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "Clean, highly optimized AI coding agent using spec-first loop",
5
5
  "type": "module",
6
6
  "main": "src/cli.ts",
@@ -2753,17 +2753,7 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
2753
2753
  disabled: true,
2754
2754
  });
2755
2755
  appendChildren([
2756
- { value: `${role.id}:keep`, label: "Set model only", hint: `keep thinking ${roleThinking}` },
2757
- {
2758
- value: `${role.id}:inherit`,
2759
- label: "thinking inherit",
2760
- hint: `follow default (${config.thinkingLevel ?? "medium"})`,
2761
- },
2762
- ...levels.map(level => ({
2763
- value: `${role.id}:${level}`,
2764
- label: `thinking ${level}`,
2765
- hint: roleThinking === level ? "current" : `~${Math.round(thinkingMaxTokens(level) / 1000)}k tokens`,
2766
- })),
2756
+ { value: `${role.id}:keep`, label: "Set model only", hint: `keep thinking ${roleThinking} · set via /agents edit` },
2767
2757
  ]);
2768
2758
  }
2769
2759
 
@@ -3276,28 +3266,58 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
3276
3266
  continue;
3277
3267
  }
3278
3268
  if (input === "/resume" || input.startsWith("/resume ")) {
3279
- const id = input.substring(7).trim();
3280
- if (!id) {
3281
- const sessions = await listSessions(cwd);
3282
- if (sessions.length === 0) {
3283
- console.log("(no saved sessions)");
3284
- continue;
3285
- }
3286
- console.log("Saved sessions — resume with /resume <id>:");
3287
- for (const s of sessions.slice(0, 15)) {
3288
- const marker = s.id === sessionId ? "*" : " ";
3289
- console.log(` ${marker}${s.id} (${s.messageCount} msgs) ${s.title ? `[${s.title}] ` : ""}${s.preview}`);
3269
+ const arg = input.substring(7).trim();
3270
+ // Load a session into history and print its transcript so the resume is visible.
3271
+ const applyResume = async (rid: string): Promise<void> => {
3272
+ try {
3273
+ const { messages } = await loadSession(rid, cwd);
3274
+ history.length = 1;
3275
+ for (const m of messages) history.push(m);
3276
+ sessionId = rid;
3277
+ // Seed /retry + reply marker from the last user/assistant turn.
3278
+ lastUserInput = ""; lastReply = "";
3279
+ for (let k = history.length - 1; k >= 1; k--) {
3280
+ if (history[k]!.role === "user" && !lastUserInput) lastUserInput = String(history[k]!.content ?? "");
3281
+ if (history[k]!.role === "assistant" && !lastReply) lastReply = String(history[k]!.content ?? "");
3282
+ if (lastUserInput && lastReply) break;
3283
+ }
3284
+ const sep = "─".repeat(Math.min(48, Math.max(20, (process.stdout.columns ?? 80) - 1)));
3285
+ logLines([
3286
+ sep,
3287
+ `resumed session ${rid} · ${messages.length} message(s) (/history all for the full transcript)`,
3288
+ sep,
3289
+ ...formatTranscript(history, { maxTurns: 6, color: true, unicode: true }),
3290
+ sep,
3291
+ ]);
3292
+ } catch (err) {
3293
+ console.log(`! ${(err as Error).message}`);
3290
3294
  }
3295
+ };
3296
+ if (arg) { await applyResume(arg); continue; }
3297
+ // No id → only sessions with a real conversation are resumable (every launch
3298
+ // creates an empty session; those are noise).
3299
+ const sessions = (await listSessions(cwd)).filter(s => s.messageCount > 0);
3300
+ if (sessions.length === 0) {
3301
+ console.log("(no saved sessions with history)");
3291
3302
  continue;
3292
3303
  }
3293
- try {
3294
- const { messages } = await loadSession(id, cwd);
3295
- history.length = 1;
3296
- for (const m of messages) history.push(m);
3297
- sessionId = id;
3298
- console.log(`Resumed session ${id} (${messages.length} messages).`);
3299
- } catch (err) {
3300
- console.log(`! ${(err as Error).message}`);
3304
+ // Interactive arrow-key picker on a TTY: ↑↓ to move, Enter to resume, Esc cancels.
3305
+ if (process.stdin.isTTY && process.stdout.isTTY) {
3306
+ const items: SelectItem<string>[] = sessions.slice(0, 50).map(s => ({
3307
+ value: s.id,
3308
+ label: `${s.title ? `[${s.title}] ` : ""}${(s.preview || s.id).replace(/\s+/g, " ")}`.slice(0, 76) || s.id,
3309
+ hint: `${s.messageCount} msgs${s.id === sessionId ? " · current" : ""}`,
3310
+ }));
3311
+ const picked = await pickFromOptions("Resume a session ↑↓ move · Enter resume · Esc cancel", items);
3312
+ if (picked) await applyResume(picked);
3313
+ else console.log("(resume cancelled)");
3314
+ continue;
3315
+ }
3316
+ // Non-TTY fallback: static list (resume with /resume <id>).
3317
+ console.log("Saved sessions — resume with /resume <id>:");
3318
+ for (const s of sessions.slice(0, 15)) {
3319
+ const marker = s.id === sessionId ? "*" : " ";
3320
+ console.log(` ${marker}${s.id} (${s.messageCount} msgs) ${s.title ? `[${s.title}] ` : ""}${s.preview}`);
3301
3321
  }
3302
3322
  continue;
3303
3323
  }
@@ -3992,10 +4012,10 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
3992
4012
  let roleModelArg = (roleMatch[3] ?? "").trim();
3993
4013
  const roleThinking = /^(?:thinking|think)(?:\s+(\S+))?$/i.exec(roleModelArg);
3994
4014
  if (roleThinking) {
3995
- await setRoleThinking(role.id, roleThinking[1]);
4015
+ console.log(`Subagent thinking is set via /agents — try: /agents ${role.id} thinking ${roleThinking[1] ?? "<level|inherit>"} (or /agents edit). /model only sets the default thinking.`);
3996
4016
  continue;
3997
4017
  }
3998
- let roleModelPickedFromSelector = false;
4018
+
3999
4019
  if (!roleModelArg && process.stdin.isTTY && process.stdout.isTTY) {
4000
4020
  const live = await getLiveModels();
4001
4021
  lastPickIndex = flattenModels(live);
@@ -4007,7 +4027,7 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
4007
4027
  continue;
4008
4028
  }
4009
4029
  roleModelArg = qualifyModelId(picked.model, picked.provider);
4010
- roleModelPickedFromSelector = true;
4030
+
4011
4031
  }
4012
4032
  }
4013
4033
  if (roleModelArg && lastPickIndex.length) {
@@ -4019,7 +4039,7 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
4019
4039
  continue;
4020
4040
  }
4021
4041
  roleModelArg = qualifyModelId(sel.entry.model, sel.entry.provider);
4022
- roleModelPickedFromSelector = true;
4042
+
4023
4043
  } else if (sel.kind === "ambiguous") {
4024
4044
  console.log(`'${roleModelArg}' matches ${sel.matches.length} models — be more specific:`);
4025
4045
  for (const e of sel.matches.slice(0, 12)) console.log(` #${e.index} ${e.model} (${e.provider})`);
@@ -4033,20 +4053,9 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
4033
4053
  continue;
4034
4054
  }
4035
4055
  if (roleModelArg) {
4036
- let thinkPatch: { thinking?: ThinkLevel } = {};
4037
- if (roleModelPickedFromSelector && process.stdin.isTTY && process.stdout.isTTY) {
4038
- const cfgForRole = await readGlobalConfig();
4039
- const lvl = await pickThinkingLevel(
4040
- `Reasoning for ${role.title}: ${roleModelArg}`,
4041
- cfgForRole.subagents?.[role.id]?.thinking,
4042
- `inherit — follow default (${cfgForRole.thinkingLevel ?? "medium"})`,
4043
- );
4044
- thinkPatch = lvl === "inherit" ? { thinking: undefined } : lvl ? { thinking: lvl } : {};
4045
- }
4046
- await saveConfigPatch(raw => ({ subagents: withSubagentSetting(raw, role.id, { model: roleModelArg, ...thinkPatch }) }));
4056
+ await saveConfigPatch(raw => ({ subagents: withSubagentSetting(raw, role.id, { model: roleModelArg }) }));
4047
4057
  const { provider } = await describeModel(roleModelArg);
4048
- const thinkNote = thinkPatch.thinking ? ` · thinking ${thinkPatch.thinking}` : "";
4049
- console.log(`${role.title} model set to ${roleModelArg} (${provider})${thinkNote} — saved to ~/.jeo/config.json`);
4058
+ console.log(`${role.title} model set to ${roleModelArg} (${provider}) — saved to ~/.jeo/config.json. Set its thinking via /agents ${role.id} thinking <level> (or /agents edit).`);
4050
4059
  } else {
4051
4060
  const current = resolveSubagentModel(role.id, await readGlobalConfig());
4052
4061
  const { resolved, provider } = await describeModel(current);