@pi-unipi/unipi 2.14.0 → 2.14.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/CHANGELOG.md +11 -0
- package/package.json +23 -23
- package/packages/ask-user/package.json +3 -3
- package/packages/autocomplete/package.json +1 -1
- package/packages/autocomplete/src/constants.ts +2 -0
- package/packages/background-tasks/package.json +3 -3
- package/packages/btw/package.json +3 -3
- package/packages/compactor/package.json +4 -4
- package/packages/core/constants.ts +1 -0
- package/packages/core/package.json +1 -1
- package/packages/footer/package.json +4 -4
- package/packages/image/package.json +2 -2
- package/packages/info-screen/index.ts +49 -10
- package/packages/info-screen/package.json +3 -3
- package/packages/info-screen/tui/info-overlay.ts +54 -22
- package/packages/input-shortcuts/package.json +3 -3
- package/packages/kanboard/package.json +3 -3
- package/packages/mcp/package.json +3 -3
- package/packages/memory/package.json +3 -3
- package/packages/milestone/package.json +3 -3
- package/packages/notify/package.json +3 -3
- package/packages/ralph/package.json +3 -3
- package/packages/subagents/package.json +3 -3
- package/packages/trajectory/package.json +1 -1
- package/packages/unipi/bundled.js +886 -687
- package/packages/updater/package.json +3 -3
- package/packages/utility/README.md +20 -0
- package/packages/utility/package.json +3 -3
- package/packages/utility/src/commands.ts +54 -0
- package/packages/utility/src/index.ts +15 -0
- package/packages/utility/src/skill-discovery.ts +178 -0
- package/packages/web-api/package.json +2 -2
- package/packages/workflow/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.14.1] — 2026-08-28
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `utility`: **skill startup discovery toggle** (`/unipi:skills-settings`, default on) — controls whether Unipi's built-in skills are cataloged in the agent's system prompt at startup. When off (`unipi.skills.discovery: false` in pi settings.json), Unipi's bundled skills are removed from the `<available_skills>` section every turn while user-owned skills (global, project, settings-mounted, third-party packages) stay cataloged; `/skill:name` invocation keeps working since pi expands those commands by reading SKILL.md directly from disk. Filtering is anchor-based (agentskills.io tags) and applied consistently per turn, preserving provider prefix cache.
|
|
14
|
+
- `autocomplete`: registered `/unipi:skills-settings` in COMMAND_REGISTRY + COMMAND_DESCRIPTIONS so the command autosuggests.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- `info-screen`: **boot splash no longer eats keystrokes or strands the session** — the auto-close boot dashboard was a capturing overlay during its 2s window: typing during boot was swallowed (worse, its vim-style keys interpreted command text as tab switches), the first-keypress-cancels-auto-close rule left it on screen forever as an unclosable input-eating zombie, and prompts appeared to never send (the agent actually responded behind the overlay). The splash is now non-capturing (typing always reaches the editor) and dismisses itself via a stack-safe `handle.hide()` that only fires while it is the topmost visible overlay entry — if the user opens any dialog during the splash window (e.g. `/unipi:skills-settings`), dismissal defers until it closes, so the overlay can no longer be orphaned with a pending interaction (previously the covered overlay vanished while its `ctx.ui.select` promise hung forever). Interactive (`bootMode: "on"`) dashboards are unchanged; splash footer now reads "auto-dismissing…" instead of keyboard hints that could never reach it.
|
|
19
|
+
|
|
9
20
|
## [2.14.0] — 2026-08-29
|
|
10
21
|
|
|
11
22
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/unipi",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.1",
|
|
4
4
|
"description": "All-in-one extension suite for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -82,28 +82,28 @@
|
|
|
82
82
|
"typebox": "^1.1.38"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
|
-
"@pi-unipi/ask-user": "2.14.
|
|
86
|
-
"@pi-unipi/background-tasks": "2.14.
|
|
87
|
-
"@pi-unipi/btw": "2.14.
|
|
88
|
-
"@pi-unipi/command-enchantment": "2.14.
|
|
89
|
-
"@pi-unipi/compactor": "2.14.
|
|
90
|
-
"@pi-unipi/core": "2.14.
|
|
91
|
-
"@pi-unipi/footer": "2.14.
|
|
92
|
-
"@pi-unipi/image": "2.14.
|
|
93
|
-
"@pi-unipi/info-screen": "2.14.
|
|
94
|
-
"@pi-unipi/input-shortcuts": "2.14.
|
|
95
|
-
"@pi-unipi/kanboard": "2.14.
|
|
96
|
-
"@pi-unipi/mcp": "2.14.
|
|
97
|
-
"@pi-unipi/memory": "2.14.
|
|
98
|
-
"@pi-unipi/milestone": "2.14.
|
|
99
|
-
"@pi-unipi/notify": "2.14.
|
|
100
|
-
"@pi-unipi/ralph": "2.14.
|
|
101
|
-
"@pi-unipi/subagents": "2.14.
|
|
102
|
-
"@pi-unipi/trajectory": "2.14.
|
|
103
|
-
"@pi-unipi/updater": "2.14.
|
|
104
|
-
"@pi-unipi/utility": "2.14.
|
|
105
|
-
"@pi-unipi/web-api": "2.14.
|
|
106
|
-
"@pi-unipi/workflow": "2.14.
|
|
85
|
+
"@pi-unipi/ask-user": "2.14.1",
|
|
86
|
+
"@pi-unipi/background-tasks": "2.14.1",
|
|
87
|
+
"@pi-unipi/btw": "2.14.1",
|
|
88
|
+
"@pi-unipi/command-enchantment": "2.14.1",
|
|
89
|
+
"@pi-unipi/compactor": "2.14.1",
|
|
90
|
+
"@pi-unipi/core": "2.14.1",
|
|
91
|
+
"@pi-unipi/footer": "2.14.1",
|
|
92
|
+
"@pi-unipi/image": "2.14.1",
|
|
93
|
+
"@pi-unipi/info-screen": "2.14.1",
|
|
94
|
+
"@pi-unipi/input-shortcuts": "2.14.1",
|
|
95
|
+
"@pi-unipi/kanboard": "2.14.1",
|
|
96
|
+
"@pi-unipi/mcp": "2.14.1",
|
|
97
|
+
"@pi-unipi/memory": "2.14.1",
|
|
98
|
+
"@pi-unipi/milestone": "2.14.1",
|
|
99
|
+
"@pi-unipi/notify": "2.14.1",
|
|
100
|
+
"@pi-unipi/ralph": "2.14.1",
|
|
101
|
+
"@pi-unipi/subagents": "2.14.1",
|
|
102
|
+
"@pi-unipi/trajectory": "2.14.1",
|
|
103
|
+
"@pi-unipi/updater": "2.14.1",
|
|
104
|
+
"@pi-unipi/utility": "2.14.1",
|
|
105
|
+
"@pi-unipi/web-api": "2.14.1",
|
|
106
|
+
"@pi-unipi/workflow": "2.14.1"
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
109
|
"@earendil-works/pi-agent-core": "^0.84.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/ask-user",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Structured user input tool for Pi coding agent
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Structured user input tool for Pi coding agent \u2014 single-select, multi-select, freeform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@pi-unipi/core": "2.14.
|
|
43
|
+
"@pi-unipi/core": "2.14.1"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
@@ -131,6 +131,7 @@ export const COMMAND_REGISTRY: Record<string, string> = {
|
|
|
131
131
|
"unipi:badge-toggle": "utility",
|
|
132
132
|
"unipi:badge-settings": "utility",
|
|
133
133
|
"unipi:util-settings": "utility",
|
|
134
|
+
"unipi:skills-settings": "utility",
|
|
134
135
|
|
|
135
136
|
// ask-user (1 command)
|
|
136
137
|
"unipi:ask-user-settings": "ask-user",
|
|
@@ -270,6 +271,7 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
270
271
|
"unipi:badge-toggle": "Configure badge settings (autoGen, badgeEnabled, agentTool)",
|
|
271
272
|
"unipi:badge-settings": "Configure badge settings via TUI overlay",
|
|
272
273
|
"unipi:util-settings": "Unified settings — badge + diff rendering config",
|
|
274
|
+
"unipi:skills-settings": "Toggle skill startup discovery (skills catalog in system prompt)",
|
|
273
275
|
"unipi:kanboard": "Start the kanboard visualization server",
|
|
274
276
|
"unipi:kanboard-doctor": "Diagnose and fix kanboard parser issues",
|
|
275
277
|
"unipi:trajectory": "Open/reuse trajectory; add stop/off or toggle to close it",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/background-tasks",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Background tasks for UniPi
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Background tasks for UniPi \u2014 durable shell jobs, delegated agents, attested Pi runs, and fixed-purpose Fusion workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"types": "src/index.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@earendil-works/pi-ai": "^0.84.0",
|
|
13
|
-
"@pi-unipi/core": "2.14.
|
|
13
|
+
"@pi-unipi/core": "2.14.1",
|
|
14
14
|
"turndown": "^7.2.4"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/btw",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "A pi extension for parallel side conversations with /unipi:btw
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "A pi extension for parallel side conversations with /unipi:btw \u2014 part of the Unipi suite",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "extensions/btw.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@earendil-works/pi-tui": "^0.84.0"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@pi-unipi/core": "2.14.
|
|
40
|
+
"@pi-unipi/core": "2.14.1"
|
|
41
41
|
},
|
|
42
42
|
"pi": {
|
|
43
43
|
"extensions": [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/compactor",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Context engine for Pi
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Context engine for Pi \u2014 zero-LLM compaction, session continuity, sandbox execution, and tool display optimization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@pi-unipi/core": "2.14.
|
|
38
|
-
"@pi-unipi/info-screen": "2.14.
|
|
37
|
+
"@pi-unipi/core": "2.14.1",
|
|
38
|
+
"@pi-unipi/info-screen": "2.14.1",
|
|
39
39
|
"@earendil-works/pi-agent-core": "^0.84.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/footer",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Persistent status bar for Unipi
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Persistent status bar for Unipi \u2014 subscribes to UNIPI_EVENTS and renders key stats from all unipi packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@pi-unipi/core": "2.14.
|
|
36
|
-
"@pi-unipi/background-tasks": "2.14.
|
|
35
|
+
"@pi-unipi/core": "2.14.1",
|
|
36
|
+
"@pi-unipi/background-tasks": "2.14.1"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/image",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.1",
|
|
4
4
|
"description": "Image generation and image recognition tools for the Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@pi-unipi/core": "2.14.
|
|
37
|
+
"@pi-unipi/core": "2.14.1"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@earendil-works/pi-ai": "^0.84.0",
|
|
@@ -113,10 +113,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
113
113
|
*/
|
|
114
114
|
function showOverlay(ctx: ExtensionContext, autoCloseMs?: number): void {
|
|
115
115
|
let overlay: InfoOverlay;
|
|
116
|
+
// Splash mode (auto-close): the overlay must NEVER take keyboard focus —
|
|
117
|
+
// it lives exactly during the window where the user starts typing their
|
|
118
|
+
// first prompt. A capturing overlay here eats those keystrokes (worse: its
|
|
119
|
+
// vim-style keys "work", so command text vanishes into tab switches), and
|
|
120
|
+
// its first-keypress-cancels-auto-close rule strands it on screen forever
|
|
121
|
+
// as an unclosable, input-eating zombie. Non-capturing + stack-safe
|
|
122
|
+
// self-dismiss (see startBootTimer) makes it pure eye-candy.
|
|
123
|
+
const splashMode = autoCloseMs !== undefined && autoCloseMs > 0;
|
|
116
124
|
ctx.ui.custom<void>(
|
|
117
125
|
(tui, theme, _keybindings, done) => {
|
|
118
126
|
overlay = new InfoOverlay();
|
|
119
127
|
overlay.setTheme(theme);
|
|
128
|
+
overlay.interactive = !splashMode;
|
|
120
129
|
overlayVisible = true;
|
|
121
130
|
overlay.onClose = () => {
|
|
122
131
|
overlayVisible = false;
|
|
@@ -127,14 +136,37 @@ export default function (pi: ExtensionAPI) {
|
|
|
127
136
|
const component = {
|
|
128
137
|
render: (w: number) => overlay.render(w),
|
|
129
138
|
invalidate: () => overlay.invalidate(),
|
|
139
|
+
// In splash mode the overlay is non-capturing and never receives
|
|
140
|
+
// input; keep handleInput wired for interactive ("on") mode.
|
|
130
141
|
handleInput: (data: string) => {
|
|
131
142
|
overlay.handleInput(data);
|
|
132
143
|
tui.requestRender();
|
|
133
144
|
},
|
|
134
145
|
};
|
|
135
|
-
//
|
|
146
|
+
// Splash self-dismiss may only run while this overlay is the topmost
|
|
147
|
+
// VISIBLE entry of the TUI overlay stack. If the user opens anything
|
|
148
|
+
// during the splash window (a /unipi:… settings dialog, the updater's
|
|
149
|
+
// update prompt, …), dismissal must wait — removing a covered entry
|
|
150
|
+
// breaks the covering overlay (pi retargets focus and orphans its
|
|
151
|
+
// pending interaction, e.g. a hung ctx.ui.select promise). Re-check
|
|
152
|
+
// on every timer tick; once the stack clears we dismiss as usual.
|
|
153
|
+
const isTopmostVisible = (): boolean => {
|
|
154
|
+
try {
|
|
155
|
+
const stack = (tui as unknown as { overlayStack?: Array<{ component?: unknown; hidden?: boolean }> }).overlayStack;
|
|
156
|
+
if (!stack || stack.length === 0) return true;
|
|
157
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
158
|
+
const entry = stack[i];
|
|
159
|
+
if (entry?.hidden) continue;
|
|
160
|
+
return entry?.component === component;
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
} catch {
|
|
164
|
+
return true; // Stack unreadable — assume topmost (legacy behavior).
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
// Boot dashboard dismisses itself (splash mode).
|
|
136
168
|
if (autoCloseMs && autoCloseMs > 0) {
|
|
137
|
-
overlay.startBootTimer(autoCloseMs);
|
|
169
|
+
overlay.startBootTimer(autoCloseMs, isTopmostVisible);
|
|
138
170
|
}
|
|
139
171
|
return component;
|
|
140
172
|
},
|
|
@@ -145,17 +177,24 @@ export default function (pi: ExtensionAPI) {
|
|
|
145
177
|
minWidth: 60,
|
|
146
178
|
anchor: "center" as const,
|
|
147
179
|
margin: 2,
|
|
180
|
+
nonCapturing: splashMode,
|
|
148
181
|
},
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
// until we are the focused (topmost) entry; the user can still press
|
|
156
|
-
// q/Esc to close once the covering overlay is gone.
|
|
182
|
+
// In splash mode the timer uses `selfHide` (handle.hide() splices this
|
|
183
|
+
// entry out by identity) guarded by the topmost-visible check above —
|
|
184
|
+
// never `done()`, which pops whatever is TOPMOST. `isTopmostOverlay`
|
|
185
|
+
// remains as the focused-done() fallback for interactive ("on") mode,
|
|
186
|
+
// where the user drives the dashboard directly: it is topmost while
|
|
187
|
+
// being driven, so the q/Esc → done() path is correct there.
|
|
157
188
|
onHandle: (handle) => {
|
|
158
189
|
overlay.isTopmostOverlay = () => handle.isFocused();
|
|
190
|
+
overlay.selfHide = () => {
|
|
191
|
+
overlayVisible = false;
|
|
192
|
+
if (typeof handle.hide === "function") {
|
|
193
|
+
handle.hide();
|
|
194
|
+
} else if (typeof (handle as { setHidden?: (v: boolean) => void }).setHidden === "function") {
|
|
195
|
+
(handle as { setHidden: (v: boolean) => void }).setHidden(true);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
159
198
|
},
|
|
160
199
|
}
|
|
161
200
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/info-screen",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Dashboard and module registry for Unipi
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Dashboard and module registry for Unipi \u2014 configurable info overlay with tabbed groups",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pi-unipi/core": "2.14.
|
|
36
|
+
"@pi-unipi/core": "2.14.1"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
@@ -69,6 +69,21 @@ export class InfoOverlay implements Component {
|
|
|
69
69
|
* `startBootTimer` for why.
|
|
70
70
|
*/
|
|
71
71
|
isTopmostOverlay?: () => boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Stack-safe self-removal via the overlay handle (`handle.hide()` splices
|
|
74
|
+
* this entry out of the TUI stack by identity, unlike `done()` which pops
|
|
75
|
+
* whatever is TOPMOST). Set from `onHandle` in index.ts. When available,
|
|
76
|
+
* the boot auto-close timer prefers this over `done()` so a splash that
|
|
77
|
+
* lingers while another overlay opens can never dismiss that overlay
|
|
78
|
+
* instead of itself.
|
|
79
|
+
*/
|
|
80
|
+
selfHide?: () => void;
|
|
81
|
+
/**
|
|
82
|
+
* False when running as a non-capturing boot splash (auto-close): the
|
|
83
|
+
* overlay never receives keyboard input, so interactive hints like
|
|
84
|
+
* "q/Esc close" would be misleading and are replaced accordingly.
|
|
85
|
+
*/
|
|
86
|
+
interactive = true;
|
|
72
87
|
|
|
73
88
|
private overlay = new OverlayTheme();
|
|
74
89
|
|
|
@@ -232,31 +247,46 @@ export class InfoOverlay implements Component {
|
|
|
232
247
|
}
|
|
233
248
|
|
|
234
249
|
/**
|
|
235
|
-
* Auto-close the overlay after `ms
|
|
250
|
+
* Auto-close the overlay after `ms`.
|
|
236
251
|
*
|
|
237
|
-
* Used when the overlay is shown
|
|
238
|
-
* it should get out of the way on its own rather than
|
|
252
|
+
* Used when the overlay is shown as a boot splash: the dashboard is
|
|
253
|
+
* informational, so it should get out of the way on its own rather than
|
|
254
|
+
* requiring a keypress.
|
|
239
255
|
*
|
|
240
|
-
*
|
|
241
|
-
* TUI stack
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
256
|
+
* Dismissal uses `selfHide` (handle.hide() — removes THIS entry from the
|
|
257
|
+
* TUI overlay stack by identity) and only fires while `isTopmostVisible`
|
|
258
|
+
* confirms nothing is stacked above: dismissing a covered overlay breaks
|
|
259
|
+
* the covering one (pi retargets focus and orphans its pending
|
|
260
|
+
* interaction, e.g. a ctx.ui.select promise that never resolves while its
|
|
261
|
+
* overlay vanishes). If covered, the timer re-arms and retries.
|
|
262
|
+
*
|
|
263
|
+
* If `selfHide` is unavailable (older host), falls back to the guarded
|
|
264
|
+
* `onClose` (`done()`) path, which requires focus (topmost) for the same
|
|
265
|
+
* reason.
|
|
248
266
|
*/
|
|
249
|
-
startBootTimer(ms: number): void {
|
|
267
|
+
startBootTimer(ms: number, isTopmostVisible?: () => boolean): void {
|
|
250
268
|
this.cancelBootTimer();
|
|
251
269
|
if (!Number.isFinite(ms) || ms <= 0) return;
|
|
252
270
|
const arm = (): void => {
|
|
253
271
|
this.bootTimer = setTimeout(() => {
|
|
254
272
|
this.bootTimer = null;
|
|
255
273
|
if (this._destroyed) return;
|
|
274
|
+
if (this.selfHide) {
|
|
275
|
+
if (isTopmostVisible && !isTopmostVisible()) {
|
|
276
|
+
// Something is stacked on top of us — dismissing now would break
|
|
277
|
+
// it (orphaned select promise, focus retarget). Retry shortly;
|
|
278
|
+
// once the stack clears we dismiss as usual.
|
|
279
|
+
arm();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
this.selfHide();
|
|
283
|
+
this.destroy();
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
256
286
|
if (this.isTopmostOverlay && !this.isTopmostOverlay()) {
|
|
257
|
-
//
|
|
258
|
-
// instead of this dashboard. Retry shortly; once
|
|
259
|
-
//
|
|
287
|
+
// Fallback (no selfHide available): closing now would pop the
|
|
288
|
+
// covering overlay instead of this dashboard. Retry shortly; once
|
|
289
|
+
// we are topmost the close is safe.
|
|
260
290
|
arm();
|
|
261
291
|
return;
|
|
262
292
|
}
|
|
@@ -346,7 +376,7 @@ export class InfoOverlay implements Component {
|
|
|
346
376
|
lines.push(this.overlay.frameLine(this.overlay.fg("dim", "Modules will register groups on startup."), innerWidth));
|
|
347
377
|
for (let i = 0; i < 4; i++) lines.push(this.overlay.frameLine("", innerWidth));
|
|
348
378
|
lines.push(this.overlay.ruleLine(innerWidth));
|
|
349
|
-
lines.push(this.overlay.frameLine(this.overlay.fg("dim", "q/Esc close · r refresh"), innerWidth));
|
|
379
|
+
lines.push(this.overlay.frameLine(this.overlay.fg("dim", this.interactive ? "q/Esc close · r refresh" : "auto-dismissing…"), innerWidth));
|
|
350
380
|
lines.push(this.overlay.borderLine(innerWidth, "bottom"));
|
|
351
381
|
return lines;
|
|
352
382
|
}
|
|
@@ -529,12 +559,14 @@ export class InfoOverlay implements Component {
|
|
|
529
559
|
const lastUp = infoRegistry.getLastUpdated(group?.id ?? "");
|
|
530
560
|
const age = lastUp > 0 ? humanizeAge(Date.now() - lastUp) : "loading…";
|
|
531
561
|
|
|
532
|
-
const hints =
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
562
|
+
const hints = this.interactive
|
|
563
|
+
? [
|
|
564
|
+
`${this.overlay.fg("accent", "←/→")} tabs`,
|
|
565
|
+
`${this.overlay.fg("success", "↑/↓")} scroll`,
|
|
566
|
+
`${this.overlay.fg("warning", "r")} refresh`,
|
|
567
|
+
`${this.overlay.fg("error", "q/Esc")} close`,
|
|
568
|
+
]
|
|
569
|
+
: [`${this.overlay.fg("dim", "auto-dismissing…")}`];
|
|
538
570
|
|
|
539
571
|
const hintStr = hints.join(` ${this.overlay.fg("borderMuted", "•")} `);
|
|
540
572
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/input-shortcuts",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Keyboard shortcuts for stash/restore, undo/redo, clipboard, and thinking toggle
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Keyboard shortcuts for stash/restore, undo/redo, clipboard, and thinking toggle \u2014 chord-based overlay system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pi-unipi/core": "2.14.
|
|
36
|
+
"@pi-unipi/core": "2.14.1"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/kanboard",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Visualization layer for unipi workflow
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Visualization layer for unipi workflow \u2014 HTTP server with htmx/Alpine.js UI, modular parsers, TUI overlay, and kanban board",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@pi-unipi/core": "2.14.
|
|
42
|
+
"@pi-unipi/core": "2.14.1"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/mcp",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "MCP server management extension for Pi coding agent
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "MCP server management extension for Pi coding agent \u2014 browse, add, configure, and use MCP servers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"test": "npx tsx --test tests/**/*.test.ts"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@pi-unipi/core": "2.14.
|
|
33
|
+
"@pi-unipi/core": "2.14.1"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/memory",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.1",
|
|
4
4
|
"description": "Persistent cross-session memory with MemPalace backend (auto-installed) and SQLite fallback for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"README.md"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@pi-unipi/core": "2.14.
|
|
43
|
-
"@pi-unipi/info-screen": "2.14.
|
|
42
|
+
"@pi-unipi/core": "2.14.1",
|
|
43
|
+
"@pi-unipi/info-screen": "2.14.1",
|
|
44
44
|
"js-yaml": "^4.1.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/milestone",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Lifecycle layer for project-level goals
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Lifecycle layer for project-level goals \u2014 MILESTONES.md tracking, session hooks, auto-sync",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@pi-unipi/core": "2.14.
|
|
35
|
+
"@pi-unipi/core": "2.14.1"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/notify",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Cross-platform notification extension for Pi
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Cross-platform notification extension for Pi \u2014 native OS, Gotify, and Telegram notifications for agent lifecycle events",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@pi-unipi/core": "2.14.
|
|
37
|
+
"@pi-unipi/core": "2.14.1",
|
|
38
38
|
"node-notifier": "^10.0.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/ralph",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.1",
|
|
4
4
|
"description": "Long-running iterative development loops for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"test": "npx tsx --test reminder.test.ts"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@pi-unipi/core": "2.14.
|
|
35
|
-
"@pi-unipi/info-screen": "2.14.
|
|
34
|
+
"@pi-unipi/core": "2.14.1",
|
|
35
|
+
"@pi-unipi/info-screen": "2.14.1"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@earendil-works/pi-ai": "^0.84.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/subagents",
|
|
3
|
-
"version": "2.14.
|
|
4
|
-
"description": "Subagents for UniPi
|
|
3
|
+
"version": "2.14.1",
|
|
4
|
+
"description": "Subagents for UniPi \u2014 parallel execution, file locking, workflow integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"types": "src/index.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"test": "npx tsx --test src/__tests__/*.test.ts"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@pi-unipi/core": "2.14.
|
|
12
|
+
"@pi-unipi/core": "2.14.1",
|
|
13
13
|
"@earendil-works/pi-agent-core": "^0.84.0",
|
|
14
14
|
"acorn": "8.18.0"
|
|
15
15
|
},
|