pi-ultracode 0.3.0 → 0.3.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-ultracode",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Claude-Code-style \"ultracode\" for Pi: an effort mode that defaults to deterministic multi-agent workflow orchestration, with worktree isolation, per-agent model overrides, custom agent types, nested workflows, resumable runs, and a /workflows manager.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
"acorn": "^8.11.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@earendil-works/pi-agent-core": "^0.
|
|
57
|
-
"@earendil-works/pi-ai": "^0.
|
|
58
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
59
|
-
"@earendil-works/pi-tui": "^0.
|
|
56
|
+
"@earendil-works/pi-agent-core": "^0.84.0",
|
|
57
|
+
"@earendil-works/pi-ai": "^0.84.0",
|
|
58
|
+
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
59
|
+
"@earendil-works/pi-tui": "^0.84.0",
|
|
60
60
|
"@types/node": "^24.12.4",
|
|
61
61
|
"typebox": "1.3.7",
|
|
62
62
|
"typescript": "^5.9.3"
|
|
@@ -619,9 +619,27 @@ export function resolveSessionThinkingLevel(
|
|
|
619
619
|
|
|
620
620
|
function matchExactModelIn(models: ModelLike[] | undefined, pattern: string): ModelLike | undefined {
|
|
621
621
|
if (!models || !pattern.trim()) return undefined;
|
|
622
|
-
const
|
|
623
|
-
|
|
624
|
-
|
|
622
|
+
const trimmed = pattern.trim();
|
|
623
|
+
const lower = trimmed.toLowerCase();
|
|
624
|
+
const canonicalMatches = models.filter((model) =>
|
|
625
|
+
`${model.provider}/${model.id}`.toLowerCase() === lower
|
|
626
|
+
);
|
|
627
|
+
if (canonicalMatches.length === 1) return canonicalMatches[0];
|
|
628
|
+
if (canonicalMatches.length > 1) throw ambiguousModelReferenceError(trimmed, canonicalMatches);
|
|
629
|
+
|
|
630
|
+
const idMatches = models.filter((model) => model.id.toLowerCase() === lower);
|
|
631
|
+
if (idMatches.length === 1) return idMatches[0];
|
|
632
|
+
if (idMatches.length > 1) throw ambiguousModelReferenceError(trimmed, idMatches);
|
|
633
|
+
return undefined;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
function ambiguousModelReferenceError(pattern: string, matches: ModelLike[]): Error {
|
|
637
|
+
const references = [...new Set(matches.map((model) => `${model.provider}/${model.id}`))]
|
|
638
|
+
.sort((left, right) => left.localeCompare(right))
|
|
639
|
+
.join(", ");
|
|
640
|
+
return new Error(
|
|
641
|
+
`Model "${safeDisplayText(pattern, 80)}" is ambiguous across providers: ${safeDisplayText(references, 400)}. Use provider/model.`,
|
|
642
|
+
);
|
|
625
643
|
}
|
|
626
644
|
|
|
627
645
|
/** Match a model pattern against a registry list: exact provider/id, then exact id, then substring. */
|
|
@@ -24,6 +24,12 @@ const MIN_SPLIT_WIDTH = 100;
|
|
|
24
24
|
const MAX_RENDER_FPS_INTERVAL_MS = 100;
|
|
25
25
|
let overlayOpen = false;
|
|
26
26
|
|
|
27
|
+
type OverlayNavigationKey = "pageUp" | "pageDown" | "end";
|
|
28
|
+
|
|
29
|
+
function matchesOverlayNavigationKey(data: string, key: OverlayNavigationKey): boolean {
|
|
30
|
+
return matchesKey(data, key) || matchesKey(data, `ctrl+${key}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
27
33
|
interface TaskViewport {
|
|
28
34
|
offset: number;
|
|
29
35
|
follow: boolean;
|
|
@@ -318,8 +324,8 @@ export class WorkflowOverlayComponent implements Component {
|
|
|
318
324
|
if (currentIndex >= 0) this.selectedTaskIndex = currentIndex;
|
|
319
325
|
if (matchesKey(data, "up")) this.selectedTaskIndex = Math.max(0, this.selectedTaskIndex - 1);
|
|
320
326
|
else if (matchesKey(data, "down")) this.selectedTaskIndex = Math.min(tasks.length - 1, this.selectedTaskIndex + 1);
|
|
321
|
-
else if (
|
|
322
|
-
else if (
|
|
327
|
+
else if (matchesOverlayNavigationKey(data, "pageUp")) this.selectedTaskIndex = Math.max(0, this.selectedTaskIndex - 10);
|
|
328
|
+
else if (matchesOverlayNavigationKey(data, "pageDown")) this.selectedTaskIndex = Math.min(tasks.length - 1, this.selectedTaskIndex + 10);
|
|
323
329
|
else if (matchesKey(data, "enter") || matchesKey(data, "return")) {
|
|
324
330
|
if (split) this.focus = "detail";
|
|
325
331
|
else {
|
|
@@ -341,13 +347,13 @@ export class WorkflowOverlayComponent implements Component {
|
|
|
341
347
|
} else if (matchesKey(data, "down")) {
|
|
342
348
|
viewport.offset++;
|
|
343
349
|
viewport.follow = false;
|
|
344
|
-
} else if (
|
|
350
|
+
} else if (matchesOverlayNavigationKey(data, "pageUp")) {
|
|
345
351
|
viewport.offset = Math.max(0, viewport.offset - page);
|
|
346
352
|
viewport.follow = false;
|
|
347
|
-
} else if (
|
|
353
|
+
} else if (matchesOverlayNavigationKey(data, "pageDown")) {
|
|
348
354
|
viewport.offset += page;
|
|
349
355
|
viewport.follow = false;
|
|
350
|
-
} else if (
|
|
356
|
+
} else if (matchesOverlayNavigationKey(data, "end")) {
|
|
351
357
|
viewport.follow = true;
|
|
352
358
|
viewport.newLines = 0;
|
|
353
359
|
}
|
|
@@ -456,9 +462,13 @@ export class WorkflowOverlayComponent implements Component {
|
|
|
456
462
|
viewport.offset = Math.max(0, Math.min(viewport.offset, maxOffset));
|
|
457
463
|
}
|
|
458
464
|
const visible = body.slice(viewport.offset, viewport.offset + bodyHeight);
|
|
465
|
+
// Fullscreen owns unmodified paging keys before focused overlays receive input.
|
|
466
|
+
// Ctrl variants remain routed to the overlay under Pi 0.84's default bindings.
|
|
467
|
+
const pageKeys = this.tui.mode === "fullscreen" ? "Ctrl+PgUp/Dn" : "PgUp/Dn";
|
|
468
|
+
const endKey = this.tui.mode === "fullscreen" ? "Ctrl+End" : "End";
|
|
459
469
|
const footer = viewport.follow
|
|
460
|
-
?
|
|
461
|
-
: `↓ ${viewport.newLines} new lines ·
|
|
470
|
+
? `↑↓/${pageKeys} scroll · ${endKey} follow · p prompt · Tab tasks · Esc back`
|
|
471
|
+
: `↓ ${viewport.newLines} new lines · ${endKey} to follow`;
|
|
462
472
|
return fitHeight([...fixed, "", ...visible, this.theme.fg("dim", footer)], height);
|
|
463
473
|
}
|
|
464
474
|
|