@pi-unipi/unipi 2.2.4 → 2.2.5
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 +5 -5
- package/packages/compactor/package.json +2 -2
- package/packages/compactor/src/tui/settings-overlay.ts +2 -2
- package/packages/footer/package.json +1 -1
- package/packages/footer/src/tui/settings-tui.ts +2 -2
- package/packages/image/package.json +1 -1
- package/packages/image/src/tui/model-selector.ts +47 -35
- package/packages/info-screen/package.json +1 -1
- package/packages/info-screen/tui/info-overlay.ts +2 -2
- package/packages/memory/package.json +1 -1
- package/packages/notify/package.json +1 -1
- package/packages/notify/tui/gotify-setup.ts +6 -6
- package/packages/notify/tui/ntfy-setup.ts +7 -7
- package/packages/notify/tui/recap-model-selector.ts +2 -2
- package/packages/notify/tui/telegram-setup.ts +5 -5
- package/packages/ralph/package.json +1 -1
- package/packages/subagents/package.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/unipi",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"description": "All-in-one extension suite for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -68,11 +68,11 @@
|
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@pi-unipi/ask-user": "2.2.0",
|
|
70
70
|
"@pi-unipi/btw": "2.2.0",
|
|
71
|
-
"@pi-unipi/compactor": "2.2.
|
|
72
|
-
"@pi-unipi/notify": "2.2.
|
|
71
|
+
"@pi-unipi/compactor": "2.2.1",
|
|
72
|
+
"@pi-unipi/notify": "2.2.2",
|
|
73
73
|
"@pi-unipi/command-enchantment": "2.2.0",
|
|
74
74
|
"@pi-unipi/core": "2.2.0",
|
|
75
|
-
"@pi-unipi/info-screen": "2.2.
|
|
75
|
+
"@pi-unipi/info-screen": "2.2.1",
|
|
76
76
|
"@pi-unipi/mcp": "2.2.0",
|
|
77
77
|
"@pi-unipi/memory": "2.2.0",
|
|
78
78
|
"@pi-unipi/ralph": "2.2.0",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"@pi-unipi/kanboard": "2.2.0",
|
|
83
83
|
"@pi-unipi/web-api": "2.2.0",
|
|
84
84
|
"@pi-unipi/workflow": "2.2.0",
|
|
85
|
-
"@pi-unipi/footer": "2.2.
|
|
85
|
+
"@pi-unipi/footer": "2.2.1",
|
|
86
86
|
"@pi-unipi/updater": "2.2.0",
|
|
87
87
|
"@pi-unipi/input-shortcuts": "2.2.0",
|
|
88
88
|
"@pi-unipi/cocoindex": "2.2.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/compactor",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Context engine for Pi — zero-LLM compaction, session continuity, sandbox execution, and tool display optimization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@pi-unipi/core": "2.2.0",
|
|
38
|
-
"@pi-unipi/info-screen": "2.2.
|
|
38
|
+
"@pi-unipi/info-screen": "2.2.1",
|
|
39
39
|
"@earendil-works/pi-agent-core": "^0.80.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { Component, TUI } from "@earendil-works/pi-tui";
|
|
11
|
-
import { truncateToWidth, visibleWidth, SettingsList, type SettingItem, type SettingsListTheme } from "@earendil-works/pi-tui";
|
|
11
|
+
import { matchesKey, truncateToWidth, visibleWidth, SettingsList, type SettingItem, type SettingsListTheme } from "@earendil-works/pi-tui";
|
|
12
12
|
import type { Theme, KeybindingsManager } from "@earendil-works/pi-coding-agent";
|
|
13
13
|
import { loadConfig, saveConfig, projectConfigPath } from "../config/manager.js";
|
|
14
14
|
import { applyPreset, detectPreset } from "../config/presets.js";
|
|
@@ -566,7 +566,7 @@ export class CompactorSettingsOverlay implements Component {
|
|
|
566
566
|
}
|
|
567
567
|
|
|
568
568
|
// Escape cancels (but SettingsList also handles it, calling onCancel)
|
|
569
|
-
if (data
|
|
569
|
+
if (matchesKey(data, "escape")) {
|
|
570
570
|
this.onClose?.();
|
|
571
571
|
return;
|
|
572
572
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
13
|
-
import { SettingsList, type SettingItem, type SettingsListTheme } from "@earendil-works/pi-tui";
|
|
13
|
+
import { matchesKey, SettingsList, type SettingItem, type SettingsListTheme } from "@earendil-works/pi-tui";
|
|
14
14
|
import { loadFooterSettings, saveFooterSettings } from "../config.js";
|
|
15
15
|
import { PRESET_NAMES } from "../presets.js";
|
|
16
16
|
import { setIconStyle } from "../rendering/icons.js";
|
|
@@ -151,7 +151,7 @@ class FooterSettingsOverlay {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// Escape — back from drill-down, or close at root
|
|
154
|
-
if (data
|
|
154
|
+
if (matchesKey(data, "escape")) {
|
|
155
155
|
if (this.section === "segments" && this.selectedGroupId) {
|
|
156
156
|
this.backToGroups();
|
|
157
157
|
} else {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Component } from "@earendil-works/pi-tui";
|
|
9
|
-
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
9
|
+
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
10
10
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
11
11
|
import { boxInnerWidth, safeRepeat } from "@pi-unipi/core";
|
|
12
12
|
|
|
@@ -61,7 +61,7 @@ export class ImageModelSelectorOverlay implements Component {
|
|
|
61
61
|
handleInput(data: string): void {
|
|
62
62
|
// Ctrl+C must always escape, even mid-filter. Without this the overlay traps
|
|
63
63
|
// the user with no way out.
|
|
64
|
-
if (data
|
|
64
|
+
if (matchesKey(data, "ctrl+c")) {
|
|
65
65
|
this.onClose?.();
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
@@ -76,49 +76,61 @@ export class ImageModelSelectorOverlay implements Component {
|
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
79
|
+
// Escape is checked via matchesKey, not `data === "\x1b"`: under the kitty
|
|
80
|
+
// keyboard protocol it arrives as "\x1b[27u" (and as "\x1b[27;1;27~" with
|
|
81
|
+
// modifyOtherKeys), so a bare comparison silently fails to close.
|
|
82
|
+
if (matchesKey(data, "escape")) {
|
|
83
|
+
this.onClose?.();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (matchesKey(data, "up") || data === "k") {
|
|
87
|
+
this.selectedIndex = Math.max(0, this.selectedIndex - 1);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (matchesKey(data, "down") || data === "j") {
|
|
91
|
+
this.selectedIndex = Math.min(this.filtered.length - 1, this.selectedIndex + 1);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (matchesKey(data, "enter")) {
|
|
95
|
+
this.commit();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (data === "/") {
|
|
99
|
+
this.filterMode = true;
|
|
100
|
+
this.filter = "";
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (data === "c" || data === "C") {
|
|
104
|
+
// Escape hatch: generator detection is heuristic, so a provider may
|
|
105
|
+
// expose a model the catalog cannot recognise. Let the user name it.
|
|
106
|
+
this.customMode = true;
|
|
107
|
+
this.custom = "";
|
|
108
|
+
this.error = null;
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
private handleFilterInput(data: string): void {
|
|
110
|
-
if (data
|
|
113
|
+
if (matchesKey(data, "enter")) {
|
|
111
114
|
this.filterMode = false;
|
|
112
115
|
return;
|
|
113
116
|
}
|
|
114
|
-
if (data
|
|
117
|
+
if (matchesKey(data, "escape")) {
|
|
115
118
|
this.filter = "";
|
|
116
119
|
this.filterMode = false;
|
|
117
120
|
this.applyFilter();
|
|
118
121
|
this.selectedIndex = 0;
|
|
119
122
|
return;
|
|
120
123
|
}
|
|
121
|
-
|
|
124
|
+
// Let the list be navigated without leaving the filter.
|
|
125
|
+
if (matchesKey(data, "up")) {
|
|
126
|
+
this.selectedIndex = Math.max(0, this.selectedIndex - 1);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (matchesKey(data, "down")) {
|
|
130
|
+
this.selectedIndex = Math.min(this.filtered.length - 1, this.selectedIndex + 1);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (matchesKey(data, "backspace") || data === "\x7f" || data === "\b") {
|
|
122
134
|
this.filter = this.filter.slice(0, -1);
|
|
123
135
|
this.applyFilter();
|
|
124
136
|
this.clampSelection();
|
|
@@ -133,17 +145,17 @@ export class ImageModelSelectorOverlay implements Component {
|
|
|
133
145
|
|
|
134
146
|
/** Free-text "provider/model-id" entry. */
|
|
135
147
|
private handleCustomInput(data: string): void {
|
|
136
|
-
if (data
|
|
148
|
+
if (matchesKey(data, "enter")) {
|
|
137
149
|
this.commitCustom();
|
|
138
150
|
return;
|
|
139
151
|
}
|
|
140
|
-
if (data
|
|
152
|
+
if (matchesKey(data, "escape")) {
|
|
141
153
|
this.customMode = false;
|
|
142
154
|
this.custom = "";
|
|
143
155
|
this.error = null;
|
|
144
156
|
return;
|
|
145
157
|
}
|
|
146
|
-
if (data === "\x7f" || data === "\b") {
|
|
158
|
+
if (matchesKey(data, "backspace") || data === "\x7f" || data === "\b") {
|
|
147
159
|
this.custom = this.custom.slice(0, -1);
|
|
148
160
|
this.error = null;
|
|
149
161
|
return;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { Component } from "@earendil-works/pi-tui";
|
|
11
|
-
import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
|
|
11
|
+
import { matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
|
|
12
12
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
13
13
|
import { infoRegistry } from "../registry.js";
|
|
14
14
|
import { getInfoSettings } from "../config.js";
|
|
@@ -200,7 +200,7 @@ export class InfoOverlay implements Component {
|
|
|
200
200
|
} else if (data === "R") {
|
|
201
201
|
// Refresh all
|
|
202
202
|
this.refreshAll();
|
|
203
|
-
} else if (data === "q" || data
|
|
203
|
+
} else if (data === "q" || matchesKey(data, "escape")) {
|
|
204
204
|
this.destroy();
|
|
205
205
|
this.onClose?.();
|
|
206
206
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { Component } from "@earendil-works/pi-tui";
|
|
10
|
-
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
10
|
+
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
11
11
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
12
12
|
import { sendGotifyNotification } from "../platforms/gotify.js";
|
|
13
13
|
import { updateConfig, loadConfig } from "../settings.js";
|
|
@@ -59,7 +59,7 @@ export class GotifySetupOverlay implements Component {
|
|
|
59
59
|
case "instructions":
|
|
60
60
|
if (data === "\r" || data === " ") {
|
|
61
61
|
this.phase = this.serverUrl ? "app-token" : "server-url";
|
|
62
|
-
} else if (data
|
|
62
|
+
} else if (matchesKey(data, "escape")) {
|
|
63
63
|
this.onClose?.();
|
|
64
64
|
}
|
|
65
65
|
break;
|
|
@@ -79,7 +79,7 @@ export class GotifySetupOverlay implements Component {
|
|
|
79
79
|
case "priority":
|
|
80
80
|
if (data === "\r" && this.isValidPriority()) {
|
|
81
81
|
this.testConnection();
|
|
82
|
-
} else if (data
|
|
82
|
+
} else if (matchesKey(data, "escape")) {
|
|
83
83
|
this.onClose?.();
|
|
84
84
|
} else if (data === "\x7f" || data === "\b") {
|
|
85
85
|
this.priority = this.priority.slice(0, -1);
|
|
@@ -92,7 +92,7 @@ export class GotifySetupOverlay implements Component {
|
|
|
92
92
|
break;
|
|
93
93
|
|
|
94
94
|
case "testing":
|
|
95
|
-
if (data
|
|
95
|
+
if (matchesKey(data, "escape")) {
|
|
96
96
|
this.onClose?.();
|
|
97
97
|
}
|
|
98
98
|
break;
|
|
@@ -100,7 +100,7 @@ export class GotifySetupOverlay implements Component {
|
|
|
100
100
|
case "success":
|
|
101
101
|
case "error":
|
|
102
102
|
case "test-failed":
|
|
103
|
-
if (data === "\r" || data === " " || data
|
|
103
|
+
if (data === "\r" || data === " " || matchesKey(data, "escape")) {
|
|
104
104
|
this.onClose?.();
|
|
105
105
|
}
|
|
106
106
|
break;
|
|
@@ -137,7 +137,7 @@ export class GotifySetupOverlay implements Component {
|
|
|
137
137
|
}
|
|
138
138
|
if (data === "\r") {
|
|
139
139
|
onEnter();
|
|
140
|
-
} else if (data
|
|
140
|
+
} else if (matchesKey(data, "escape")) {
|
|
141
141
|
this.onClose?.();
|
|
142
142
|
} else if (data === "\x7f" || data === "\b") {
|
|
143
143
|
if (target === "server-url") {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { Component } from "@earendil-works/pi-tui";
|
|
10
|
-
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
10
|
+
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
11
11
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
12
12
|
import { sendNtfyNotification } from "../platforms/ntfy.js";
|
|
13
13
|
import { loadNtfyConfig, saveNtfyConfig, getNtfyConfigScope } from "../ntfy-config.js";
|
|
@@ -70,7 +70,7 @@ export class NtfySetupOverlay implements Component {
|
|
|
70
70
|
case "instructions":
|
|
71
71
|
if (data === "\r" || data === " ") {
|
|
72
72
|
this.phase = "scope";
|
|
73
|
-
} else if (data
|
|
73
|
+
} else if (matchesKey(data, "escape")) {
|
|
74
74
|
this.onClose?.();
|
|
75
75
|
}
|
|
76
76
|
break;
|
|
@@ -85,7 +85,7 @@ export class NtfySetupOverlay implements Component {
|
|
|
85
85
|
} else if (data === "\r" || data === " ") {
|
|
86
86
|
this.scope = this.scopeIndex === 1 ? "project" : "global";
|
|
87
87
|
this.phase = this.serverUrl ? "topic" : "server-url";
|
|
88
|
-
} else if (data
|
|
88
|
+
} else if (matchesKey(data, "escape")) {
|
|
89
89
|
this.onClose?.();
|
|
90
90
|
}
|
|
91
91
|
break;
|
|
@@ -114,7 +114,7 @@ export class NtfySetupOverlay implements Component {
|
|
|
114
114
|
case "priority":
|
|
115
115
|
if (data === "\r" && this.isValidPriority()) {
|
|
116
116
|
this.testConnection();
|
|
117
|
-
} else if (data
|
|
117
|
+
} else if (matchesKey(data, "escape")) {
|
|
118
118
|
this.onClose?.();
|
|
119
119
|
} else if (data === "\x7f" || data === "\b") {
|
|
120
120
|
this.priority = this.priority.slice(0, -1);
|
|
@@ -127,7 +127,7 @@ export class NtfySetupOverlay implements Component {
|
|
|
127
127
|
break;
|
|
128
128
|
|
|
129
129
|
case "testing":
|
|
130
|
-
if (data
|
|
130
|
+
if (matchesKey(data, "escape")) {
|
|
131
131
|
this.onClose?.();
|
|
132
132
|
}
|
|
133
133
|
break;
|
|
@@ -135,7 +135,7 @@ export class NtfySetupOverlay implements Component {
|
|
|
135
135
|
case "success":
|
|
136
136
|
case "error":
|
|
137
137
|
case "test-failed":
|
|
138
|
-
if (data === "\r" || data === " " || data
|
|
138
|
+
if (data === "\r" || data === " " || matchesKey(data, "escape")) {
|
|
139
139
|
this.onClose?.();
|
|
140
140
|
}
|
|
141
141
|
break;
|
|
@@ -173,7 +173,7 @@ export class NtfySetupOverlay implements Component {
|
|
|
173
173
|
}
|
|
174
174
|
if (data === "\r") {
|
|
175
175
|
onEnter();
|
|
176
|
-
} else if (data
|
|
176
|
+
} else if (matchesKey(data, "escape")) {
|
|
177
177
|
// Escape during token phase — skip token (optional field)
|
|
178
178
|
if (target === "token") {
|
|
179
179
|
this.phase = "priority";
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Component } from "@earendil-works/pi-tui";
|
|
9
|
-
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
9
|
+
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
10
10
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
11
11
|
import { readModelCache, type CachedModel, boxInnerWidth } from "@pi-unipi/core";
|
|
12
12
|
import { loadConfig, saveConfig } from "../settings.js";
|
|
@@ -56,7 +56,7 @@ export class RecapModelSelectorOverlay implements Component {
|
|
|
56
56
|
this.filterMode = false;
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
|
-
if (data
|
|
59
|
+
if (matchesKey(data, "escape")) {
|
|
60
60
|
// Escape — clear filter and exit filter mode
|
|
61
61
|
this.filter = "";
|
|
62
62
|
this.filterMode = false;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Component } from "@earendil-works/pi-tui";
|
|
9
|
-
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
9
|
+
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
10
10
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
11
11
|
import { pollForChatId } from "../platforms/telegram.js";
|
|
12
12
|
import { updateConfig } from "../settings.js";
|
|
@@ -48,7 +48,7 @@ export class TelegramSetupOverlay implements Component {
|
|
|
48
48
|
case "instructions":
|
|
49
49
|
if (data === "\r" || data === " ") {
|
|
50
50
|
this.phase = "token";
|
|
51
|
-
} else if (data
|
|
51
|
+
} else if (matchesKey(data, "escape")) {
|
|
52
52
|
this.cleanup();
|
|
53
53
|
this.onClose?.();
|
|
54
54
|
}
|
|
@@ -75,7 +75,7 @@ export class TelegramSetupOverlay implements Component {
|
|
|
75
75
|
}
|
|
76
76
|
if (data === "\r" && this.botToken.length > 0) {
|
|
77
77
|
this.startPolling();
|
|
78
|
-
} else if (data
|
|
78
|
+
} else if (matchesKey(data, "escape")) {
|
|
79
79
|
this.cleanup();
|
|
80
80
|
this.onClose?.();
|
|
81
81
|
} else if (data === "\x7f" || data === "\b") {
|
|
@@ -85,7 +85,7 @@ export class TelegramSetupOverlay implements Component {
|
|
|
85
85
|
}
|
|
86
86
|
break;
|
|
87
87
|
case "polling":
|
|
88
|
-
if (data
|
|
88
|
+
if (matchesKey(data, "escape")) {
|
|
89
89
|
this.cleanup();
|
|
90
90
|
this.onClose?.();
|
|
91
91
|
}
|
|
@@ -93,7 +93,7 @@ export class TelegramSetupOverlay implements Component {
|
|
|
93
93
|
case "success":
|
|
94
94
|
case "error":
|
|
95
95
|
case "timeout":
|
|
96
|
-
if (data === "\r" || data === " " || data
|
|
96
|
+
if (data === "\r" || data === " " || matchesKey(data, "escape")) {
|
|
97
97
|
this.cleanup();
|
|
98
98
|
this.onClose?.();
|
|
99
99
|
}
|