@oh-my-pi/pi-tui 18.10.2 → 18.10.3

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
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.10.3] - 2026-10-12
6
+
7
+ ### Changed
8
+
9
+ - Updated model picker to offer manual effort selection for unverified models instead of automatic mode
10
+
11
+ ### Fixed
12
+
13
+ - Fixed the `snapcompact.shape` settings preview labelling variants `5x8-sent` and repeating the first variant's sample when the frame edge differs from the variant table (Claude and GPT on Cursor; `auto` on high-resolution Claude) ([#15448](https://github.com/can1357/oh-my-pi/pull/15448) by [@will-bogusz](https://github.com/will-bogusz))
14
+
5
15
  ## [18.10.2] - 2026-10-12
6
16
 
7
17
  ### Added
@@ -37,6 +37,11 @@ export declare function shouldDisableReasoning(level: ThinkingLevel | undefined)
37
37
  * Resolves a selector against the current model while preserving explicit "off".
38
38
  */
39
39
  export declare function resolveThinkingLevelForModel(model: Model | undefined, level: ThinkingLevel | undefined): ResolvedThinkingLevel | undefined;
40
+ /**
41
+ * Level applied to `model` when the user has not picked one for it (carried,
42
+ * global default, auto). Unverified thinking stays unset until the user picks.
43
+ */
44
+ export declare function automaticThinkingLevel<T>(model: Model | undefined, fallback: T): T | undefined;
40
45
  /**
41
46
  * Sentinel selector for the coding-agent "auto" thinking mode. Kept entirely
42
47
  * inside the coding-agent layer: it is never an {@link Effort} or
@@ -18,6 +18,8 @@ export interface BashToolDetails {
18
18
  requestedTimeoutSeconds?: number;
19
19
  timeoutDisabled?: boolean;
20
20
  wallTimeMs?: number;
21
+ /** False when no wall-time footer was emitted; absent on older results. */
22
+ wallTimeNoticeEmitted?: boolean;
21
23
  /** Exit code of a command that ran to completion but failed (non-zero). */
22
24
  exitCode?: number;
23
25
  /** True when the command was killed by its timeout deadline (not a failure). */
@@ -38,6 +40,8 @@ export interface BashToolDetails {
38
40
  type: "bash";
39
41
  };
40
42
  }
43
+ /** Minimum duration for a model-facing wall-time notice; shorter runs keep timing only in details. */
44
+ export declare const WALL_TIME_NOTICE_MIN_MS = 1000;
41
45
  /** Formats the model-facing command duration notice. */
42
46
  export declare function formatWallTimeNotice(wallTimeMs: number): string;
43
47
  /** Formats the model-facing command exit status notice. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-tui",
4
- "version": "18.10.2",
4
+ "version": "18.10.3",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": {
@@ -41,14 +41,14 @@
41
41
  "gen:glyphs": "bun scripts/gen-glyphs.ts"
42
42
  },
43
43
  "dependencies": {
44
- "@oh-my-pi/omptype": "18.10.2",
45
- "@oh-my-pi/pi-agent-core": "18.10.2",
46
- "@oh-my-pi/pi-ai": "18.10.2",
47
- "@oh-my-pi/pi-catalog": "18.10.2",
48
- "@oh-my-pi/pi-natives": "18.10.2",
49
- "@oh-my-pi/pi-utils": "18.10.2",
50
- "@oh-my-pi/pi-wire": "18.10.2",
51
- "@oh-my-pi/snapcompact": "18.10.2"
44
+ "@oh-my-pi/omptype": "18.10.3",
45
+ "@oh-my-pi/pi-agent-core": "18.10.3",
46
+ "@oh-my-pi/pi-ai": "18.10.3",
47
+ "@oh-my-pi/pi-catalog": "18.10.3",
48
+ "@oh-my-pi/pi-natives": "18.10.3",
49
+ "@oh-my-pi/pi-utils": "18.10.3",
50
+ "@oh-my-pi/pi-wire": "18.10.3",
51
+ "@oh-my-pi/snapcompact": "18.10.3"
52
52
  },
53
53
  "devDependencies": {
54
54
  "kitty-vt-wasm": "^0.2.0"
@@ -1328,6 +1328,7 @@ export class ModelHubComponent implements Component {
1328
1328
  */
1329
1329
  #thinkingOptionsFor(model: Model): ConfiguredThinkingLevel[] {
1330
1330
  if (!model.reasoning) return [];
1331
+ if (model.thinking?.unverified) return [ThinkingLevel.Inherit, ThinkingLevel.Off, ...getSupportedEfforts(model)];
1331
1332
  return [ThinkingLevel.Inherit, ThinkingLevel.Off, AUTO_THINKING, ...getSupportedEfforts(model)];
1332
1333
  }
1333
1334
 
@@ -24,6 +24,7 @@ import {
24
24
  SHAPE_VARIANT_NAMES,
25
25
  SHAPE_VARIANTS,
26
26
  type Shape,
27
+ type ShapeGeometry,
27
28
  type ShapeTarget,
28
29
  type ShapeVariantName,
29
30
  } from "@oh-my-pi/snapcompact";
@@ -90,7 +91,7 @@ export class SnapcompactShapePreview implements Component {
90
91
 
91
92
  describe(cx: DescribeContext): NativeNode {
92
93
  const shape = resolveShape(this.#model, this.#variant);
93
- const name = resolvedVariantName(shape);
94
+ const name = this.#variant === "auto" ? resolvedVariantName(shape) : this.#variant;
94
95
  const entry = cx.supports("image") ? this.#ensureEntry(name, shape) : undefined;
95
96
  const memo = this.#native;
96
97
  if (memo !== undefined && memo.variant === this.#variant && memo.entry === entry) return memo.node;
@@ -128,7 +129,7 @@ export class SnapcompactShapePreview implements Component {
128
129
 
129
130
  render(width: number): readonly string[] {
130
131
  const shape = resolveShape(this.#model, this.#variant);
131
- const name = resolvedVariantName(shape);
132
+ const name = this.#variant === "auto" ? resolvedVariantName(shape) : this.#variant;
132
133
  const { label, stats } = this.#caption(shape, name);
133
134
  const lines: string[] = [theme.fg("muted", ` Sample (zoomed) · ${label} · ${stats}`), ""];
134
135
 
@@ -215,17 +216,23 @@ export class SnapcompactShapePreview implements Component {
215
216
  }
216
217
  }
217
218
 
218
- /** Research name of the concrete geometry `resolveShape` picked (for `auto`). */
219
+ /**
220
+ * Research name of the geometry `resolveShape` picked for `auto`. The frame
221
+ * edge is not compared: `auto` widens it per model line and hosts cap it
222
+ * (catalog `image-max-edge`), and the sample renders a fixed mini-page anyway.
223
+ */
219
224
  function resolvedVariantName(shape: Shape): ShapeVariantName {
220
225
  for (const name of SHAPE_VARIANT_NAMES) {
221
- const candidate = SHAPE_VARIANTS[name];
226
+ const candidate: ShapeGeometry = SHAPE_VARIANTS[name];
222
227
  if (
223
228
  candidate.font === shape.font &&
224
229
  candidate.cellWidth === shape.cellWidth &&
225
230
  candidate.cellHeight === shape.cellHeight &&
231
+ candidate.stretch === shape.stretch &&
226
232
  candidate.variant === shape.variant &&
227
- candidate.lineRepeat === shape.lineRepeat &&
228
- candidate.frameSize === shape.frameSize
233
+ candidate.stopwordDim === shape.stopwordDim &&
234
+ candidate.columns === shape.columns &&
235
+ candidate.lineRepeat === shape.lineRepeat
229
236
  ) {
230
237
  return name;
231
238
  }
package/src/thinking.ts CHANGED
@@ -132,6 +132,14 @@ export function resolveThinkingLevelForModel(
132
132
  return clampThinkingLevelForModel(model, level);
133
133
  }
134
134
 
135
+ /**
136
+ * Level applied to `model` when the user has not picked one for it (carried,
137
+ * global default, auto). Unverified thinking stays unset until the user picks.
138
+ */
139
+ export function automaticThinkingLevel<T>(model: Model | undefined, fallback: T): T | undefined {
140
+ return model?.thinking?.unverified ? undefined : fallback;
141
+ }
142
+
135
143
  /**
136
144
  * Sentinel selector for the coding-agent "auto" thinking mode. Kept entirely
137
145
  * inside the coding-agent layer: it is never an {@link Effort} or
@@ -374,7 +382,7 @@ export function modelSupportsEffortCeiling(model: Model, ceiling: Effort): boole
374
382
  * models.
375
383
  */
376
384
  export function resolveProvisionalAutoLevel(model: Model | undefined): Effort | undefined {
377
- if (!model?.reasoning) return undefined;
385
+ if (!model?.reasoning || model.thinking?.unverified) return undefined;
378
386
  const preferred = model.thinking?.defaultLevel ?? Effort.High;
379
387
  return clampAutoThinkingEffort(model, preferred === Effort.Max ? Effort.XHigh : preferred, Effort.XHigh);
380
388
  }
package/src/tools/bash.ts CHANGED
@@ -62,6 +62,8 @@ export interface BashToolDetails {
62
62
  requestedTimeoutSeconds?: number;
63
63
  timeoutDisabled?: boolean;
64
64
  wallTimeMs?: number;
65
+ /** False when no wall-time footer was emitted; absent on older results. */
66
+ wallTimeNoticeEmitted?: boolean;
65
67
  /** Exit code of a command that ran to completion but failed (non-zero). */
66
68
  exitCode?: number;
67
69
  /** True when the command was killed by its timeout deadline (not a failure). */
@@ -209,6 +211,9 @@ function formatWallTimeSeconds(wallTimeMs: number): string {
209
211
  return (wallTimeMs / 1000).toFixed(2);
210
212
  }
211
213
 
214
+ /** Minimum duration for a model-facing wall-time notice; shorter runs keep timing only in details. */
215
+ export const WALL_TIME_NOTICE_MIN_MS = 1000;
216
+
212
217
  /** Formats the model-facing command duration notice. */
213
218
  export function formatWallTimeNotice(wallTimeMs: number): string {
214
219
  return `Wall time: ${formatWallTimeSeconds(wallTimeMs)} seconds`;
@@ -319,7 +324,7 @@ function stripBashNotices(
319
324
  ? strippedOutput
320
325
  : stripTrailingNotice(strippedOutput, formatExitCodeNotice(details.exitCode));
321
326
  const withoutWall =
322
- details?.wallTimeMs === undefined
327
+ details?.wallTimeMs === undefined || details.wallTimeNoticeEmitted === false
323
328
  ? withoutExit
324
329
  : stripTrailingNotice(withoutExit, formatWallTimeNotice(details.wallTimeMs));
325
330
  return stripRawOutputArtifactNotice(withoutWall);