@pi-unipi/unipi 3.0.0-alpha.27 → 3.0.0-alpha.29
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 +10 -0
- package/README.md +9 -1
- package/package.json +21 -21
- package/packages/ask-user/package.json +2 -2
- package/packages/autocomplete/package.json +1 -1
- package/packages/autocomplete/src/constants.ts +1 -1
- package/packages/background-tasks/package.json +2 -2
- package/packages/btw/package.json +2 -2
- package/packages/compactor/package.json +3 -3
- package/packages/core/package.json +1 -1
- package/packages/footer/package.json +3 -3
- package/packages/fusion/package.json +4 -4
- package/packages/info-screen/package.json +2 -2
- package/packages/input-shortcuts/package.json +2 -2
- package/packages/kanboard/package.json +7 -7
- package/packages/long-horizon/package.json +2 -2
- package/packages/mcp/package.json +2 -2
- package/packages/memory/package.json +3 -3
- package/packages/notify/README.md +4 -0
- package/packages/notify/activity.ts +4 -2
- package/packages/notify/events.ts +116 -11
- package/packages/notify/input-needed-message.ts +27 -0
- package/packages/notify/package.json +2 -2
- package/packages/notify/settings.ts +2 -0
- package/packages/notify/skills/configure-notify/SKILL.md +4 -2
- package/packages/skill-registry/package.json +2 -2
- package/packages/subagents/package.json +3 -3
- package/packages/unipi/bundled.js +87 -23
- package/packages/updater/package.json +2 -2
- package/packages/utility/README.md +3 -2
- package/packages/utility/package.json +2 -2
- package/packages/utility/skills/summarize/SKILL.md +9 -2
- package/packages/utility/skills/utility/SKILL.md +1 -1
- package/packages/utility/src/summarize/index.ts +7 -9
- package/packages/watchdog/package.json +3 -3
- package/packages/web-api/package.json +2 -2
- package/packages/workflow/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [3.0.0-alpha.29] — 2026-10-04
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- `notify`: prompts that send no event of their own (third-party `ask_user` tools, the permission prompt, the plan review) can notify through the new **Input Needed** event (`input_needed`, off by default); closing any prompt now stops its reminders. (GitHub #38)
|
|
13
|
+
|
|
14
|
+
## [3.0.0-alpha.28] — 2026-10-04
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- `utility`: **`/unipi:summarize` re-summarizes the last reply**, with the session as context. The command sends only `/skill:summarize`, plus any text you add, which reaches the skill as your question ("what would it change?" now asks about the last reply). It no longer wraps your text in a "summarize this session" prompt.
|
|
18
|
+
|
|
9
19
|
## [3.0.0-alpha.27] — 2026-10-04
|
|
10
20
|
|
|
11
21
|
### Added
|
package/README.md
CHANGED
|
@@ -27,9 +27,16 @@
|
|
|
27
27
|
## Install
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
pi install npm:@pi-unipi/unipi
|
|
30
|
+
pi install npm:@pi-unipi/unipi@alpha
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
> [!NOTE]
|
|
34
|
+
> **UniPi 3 is in alpha.** This README describes v3, published under the npm
|
|
35
|
+
> `alpha` tag. Plain `pi install npm:@pi-unipi/unipi` still installs the stable
|
|
36
|
+
> 2.x line ([2.x README](https://github.com/Neuron-Mr-White/unipi/tree/main#readme)).
|
|
37
|
+
> To update an alpha install: `pi update npm:@pi-unipi/unipi@alpha`. To go back
|
|
38
|
+
> to stable: `pi install npm:@pi-unipi/unipi@latest`.
|
|
39
|
+
|
|
33
40
|
UniPi needs [Pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent)
|
|
34
41
|
`0.87.1` or later. This command installs 21 extension packages. Each package
|
|
35
42
|
also works alone.
|
|
@@ -242,6 +249,7 @@ The recent releases, in short. The [changelog](CHANGELOG.md) has the details.
|
|
|
242
249
|
|
|
243
250
|
| Release | What changed for you |
|
|
244
251
|
|---|---|
|
|
252
|
+
| alpha.29 | Plan mode plans with you: it asks before it submits, blocks only edits outside the plan, and the review shows a summary beside the steps. Notify can alert on any prompt the agent waits on (Input Needed). |
|
|
245
253
|
| alpha.27 | The footer shows tokens in and out and the session cost under the input. It fits narrow and short windows. Each part of the stats line, the frame badges and the rainbow can be turned off in `/unipi:settings` → Footer. The classic footer is gone. |
|
|
246
254
|
| alpha.25 | The Unicrab splash at startup. A new `/unipi:info`: this session, the context bucket, compaction savings and `s`/`p`/`g` scope tags. Prompts that UniPi sends for you (goal, summarize, answer) show as a UniPi panel, not as your own message. |
|
|
247
255
|
| alpha.24 | The `summarize` skill and `/unipi:summarize [focus]`. Long work ends with a short recap: the answer first, then findings, open items and questions. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/unipi",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "All-in-one extension suite for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -83,26 +83,26 @@
|
|
|
83
83
|
"typebox": "^1.1.38"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@pi-unipi/ask-user": "3.0.0-alpha.
|
|
87
|
-
"@pi-unipi/background-tasks": "3.0.0-alpha.
|
|
88
|
-
"@pi-unipi/btw": "3.0.0-alpha.
|
|
89
|
-
"@pi-unipi/command-enchantment": "3.0.0-alpha.
|
|
90
|
-
"@pi-unipi/compactor": "3.0.0-alpha.
|
|
91
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
92
|
-
"@pi-unipi/footer": "3.0.0-alpha.
|
|
93
|
-
"@pi-unipi/fusion": "3.0.0-alpha.
|
|
94
|
-
"@pi-unipi/info-screen": "3.0.0-alpha.
|
|
95
|
-
"@pi-unipi/input-shortcuts": "3.0.0-alpha.
|
|
96
|
-
"@pi-unipi/kanboard": "3.0.0-alpha.
|
|
97
|
-
"@pi-unipi/mcp": "3.0.0-alpha.
|
|
98
|
-
"@pi-unipi/memory": "3.0.0-alpha.
|
|
99
|
-
"@pi-unipi/notify": "3.0.0-alpha.
|
|
100
|
-
"@pi-unipi/skill-registry": "3.0.0-alpha.
|
|
101
|
-
"@pi-unipi/subagents": "3.0.0-alpha.
|
|
102
|
-
"@pi-unipi/updater": "3.0.0-alpha.
|
|
103
|
-
"@pi-unipi/utility": "3.0.0-alpha.
|
|
104
|
-
"@pi-unipi/web-api": "3.0.0-alpha.
|
|
105
|
-
"@pi-unipi/workflow": "3.0.0-alpha.
|
|
86
|
+
"@pi-unipi/ask-user": "3.0.0-alpha.29",
|
|
87
|
+
"@pi-unipi/background-tasks": "3.0.0-alpha.29",
|
|
88
|
+
"@pi-unipi/btw": "3.0.0-alpha.29",
|
|
89
|
+
"@pi-unipi/command-enchantment": "3.0.0-alpha.29",
|
|
90
|
+
"@pi-unipi/compactor": "3.0.0-alpha.29",
|
|
91
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
92
|
+
"@pi-unipi/footer": "3.0.0-alpha.29",
|
|
93
|
+
"@pi-unipi/fusion": "3.0.0-alpha.29",
|
|
94
|
+
"@pi-unipi/info-screen": "3.0.0-alpha.29",
|
|
95
|
+
"@pi-unipi/input-shortcuts": "3.0.0-alpha.29",
|
|
96
|
+
"@pi-unipi/kanboard": "3.0.0-alpha.29",
|
|
97
|
+
"@pi-unipi/mcp": "3.0.0-alpha.29",
|
|
98
|
+
"@pi-unipi/memory": "3.0.0-alpha.29",
|
|
99
|
+
"@pi-unipi/notify": "3.0.0-alpha.29",
|
|
100
|
+
"@pi-unipi/skill-registry": "3.0.0-alpha.29",
|
|
101
|
+
"@pi-unipi/subagents": "3.0.0-alpha.29",
|
|
102
|
+
"@pi-unipi/updater": "3.0.0-alpha.29",
|
|
103
|
+
"@pi-unipi/utility": "3.0.0-alpha.29",
|
|
104
|
+
"@pi-unipi/web-api": "3.0.0-alpha.29",
|
|
105
|
+
"@pi-unipi/workflow": "3.0.0-alpha.29"
|
|
106
106
|
},
|
|
107
107
|
"devDependencies": {
|
|
108
108
|
"@earendil-works/pi-agent-core": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/ask-user",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Structured user input tool for Pi coding agent — single-select, multi-select, freeform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
43
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -160,7 +160,7 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
160
160
|
"unipi:cleanup": "Remove stale UniPi temp files and leftovers (preview first)",
|
|
161
161
|
"unipi:doctor": "Check UniPi's runtime: config, model cache, Decision Model, skills",
|
|
162
162
|
"unipi:answer": "Answer the last reply — fixed input under the scrollable reply, per question, or web form",
|
|
163
|
-
"unipi:summarize": "Summarize
|
|
163
|
+
"unipi:summarize": "Summarize your last reply again (answer first, then findings, open items, questions). Add text to ask about it",
|
|
164
164
|
"unipi:skills": "Manage skills — on/off per project, listed or not, the skill vault",
|
|
165
165
|
|
|
166
166
|
"unipi:kanboard": "Kanboard — capture tasks, run them, open the board",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/background-tasks",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Background tasks for UniPi — durable shell jobs and delegated background agents with a footer dock",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@earendil-works/pi-ai": "^0.87.1",
|
|
13
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
13
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
14
14
|
"turndown": "^7.2.4"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/btw",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "A pi extension for parallel side conversations with /unipi:btw — part of the Unipi suite",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "extensions/btw.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@earendil-works/pi-tui": "^0.87.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
40
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
41
41
|
},
|
|
42
42
|
"pi": {
|
|
43
43
|
"extensions": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/compactor",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Compaction for Pi — lossless zero-LLM or model summaries, rebuilt from full history, with session recall",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
37
|
-
"@pi-unipi/info-screen": "3.0.0-alpha.
|
|
36
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
37
|
+
"@pi-unipi/info-screen": "3.0.0-alpha.29",
|
|
38
38
|
"@earendil-works/pi-agent-core": "^0.87.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/footer",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Persistent status bar for Unipi — subscribes to UNIPI_EVENTS and renders key stats from all unipi packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
36
|
-
"@pi-unipi/background-tasks": "3.0.0-alpha.
|
|
35
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
36
|
+
"@pi-unipi/background-tasks": "3.0.0-alpha.29"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/fusion",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Devin-style model picker, fusion presets (lead + sidekick), and Local Fusion runtime for UniPi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
36
|
-
"@pi-unipi/subagents": "3.0.0-alpha.
|
|
37
|
-
"@pi-unipi/utility": "3.0.0-alpha.
|
|
35
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
36
|
+
"@pi-unipi/subagents": "3.0.0-alpha.29",
|
|
37
|
+
"@pi-unipi/utility": "3.0.0-alpha.29"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@earendil-works/pi-ai": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/info-screen",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Unicrab startup splash and the /unipi:info dashboard — this session, context, usage, compaction savings",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
36
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/input-shortcuts",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Keyboard shortcuts for stash/restore, undo/redo, clipboard, and thinking toggle — chord-based overlay system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
36
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/kanboard",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Kanboard v3 — deferred-work board: CLI/daemon bridge, task runner and skill",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
34
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"themes": []
|
|
49
49
|
},
|
|
50
50
|
"optionalDependencies": {
|
|
51
|
-
"@pi-unipi/kanboard-linux-x64": "3.0.0-alpha.
|
|
52
|
-
"@pi-unipi/kanboard-linux-arm64": "3.0.0-alpha.
|
|
53
|
-
"@pi-unipi/kanboard-darwin-x64": "3.0.0-alpha.
|
|
54
|
-
"@pi-unipi/kanboard-darwin-arm64": "3.0.0-alpha.
|
|
55
|
-
"@pi-unipi/kanboard-win32-x64": "3.0.0-alpha.
|
|
51
|
+
"@pi-unipi/kanboard-linux-x64": "3.0.0-alpha.29",
|
|
52
|
+
"@pi-unipi/kanboard-linux-arm64": "3.0.0-alpha.29",
|
|
53
|
+
"@pi-unipi/kanboard-darwin-x64": "3.0.0-alpha.29",
|
|
54
|
+
"@pi-unipi/kanboard-darwin-arm64": "3.0.0-alpha.29",
|
|
55
|
+
"@pi-unipi/kanboard-win32-x64": "3.0.0-alpha.29"
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/long-horizon",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Long-horizon execution for Pi — mode-gated /goal /ralph /swarm /graph orchestration with a TypeSafe prompt judge",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
40
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/mcp",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "MCP server management extension for Pi coding agent — browse, add, configure, and use MCP servers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"test": "npx tsx --test tests/**/*.test.ts"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
33
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/memory",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Persistent cross-session memory on MemPalace (auto-installed): daemon-routed writes, shared palace with other agents, for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"README.md"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
46
|
-
"@pi-unipi/info-screen": "3.0.0-alpha.
|
|
45
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
46
|
+
"@pi-unipi/info-screen": "3.0.0-alpha.29",
|
|
47
47
|
"js-yaml": "^4.1.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
@@ -71,9 +71,12 @@ notify_user({ title: "Build failed", message: "tsc found 12 errors.", priority:
|
|
|
71
71
|
| `session_shutdown` | off | The session ends. |
|
|
72
72
|
| `ask_user_prompt` | off | The agent asks you a question and waits. |
|
|
73
73
|
| `permission_request` | off | A permission prompt opens. This needs [`@gotgenes/pi-permission-system`](https://www.npmjs.com/package/@gotgenes/pi-permission-system). |
|
|
74
|
+
| `input_needed` | off | The agent waits on any prompt while it runs. Covers prompts that send no event of their own — third-party `ask_user` tools, the permission prompt, the plan review. |
|
|
74
75
|
|
|
75
76
|
`ask_user_prompt` and `permission_request` are blocking events. The agent stops until you answer.
|
|
76
77
|
|
|
78
|
+
`input_needed` is the catch-all for the same situation: Pi fires it around every blocking prompt, including ones that emit no event of their own. It only fires while the agent is running — prompts you open yourself while the agent is idle (for example `/unipi:settings`) stay quiet — and a prompt already announced as `ask_user_prompt` or `permission_request` is not announced twice. Closing any prompt stops its reminders.
|
|
79
|
+
|
|
77
80
|
## Settings
|
|
78
81
|
|
|
79
82
|
Open `/unipi:settings` → **Notify**. The file is `~/.unipi/config/notify/config.json`. A project file at `.unipi/config/notify/config.json` overrides it.
|
|
@@ -104,6 +107,7 @@ A reminder has the text `(still waiting)` in its title and `high` priority. Remi
|
|
|
104
107
|
- You press a key.
|
|
105
108
|
- herdr reports that the agent is not blocked.
|
|
106
109
|
- The agent starts a new turn.
|
|
110
|
+
- The prompt closes.
|
|
107
111
|
- The session ends.
|
|
108
112
|
|
|
109
113
|
Only one reminder runs at a time. Silence after input does not apply to blocking events.
|
|
@@ -26,6 +26,7 @@ const VALID_PLATFORMS: ReadonlySet<NotifyPlatform> = new Set([
|
|
|
26
26
|
const BLOCKING_EVENTS: ReadonlySet<string> = new Set([
|
|
27
27
|
"ask_user_prompt",
|
|
28
28
|
"permission_request",
|
|
29
|
+
"input_needed",
|
|
29
30
|
]);
|
|
30
31
|
|
|
31
32
|
/** Whether an event type is a human-blocking prompt. */
|
|
@@ -51,8 +52,9 @@ export function resetInputActivity(): void {
|
|
|
51
52
|
* Empty `platforms` (while enabled) silences all incoming channels, matching
|
|
52
53
|
* `events.*.platforms: []` → all enabled.
|
|
53
54
|
*
|
|
54
|
-
* Human-blocking events (`ask_user_prompt`, `permission_request
|
|
55
|
-
* filter entirely — the keypress that triggered
|
|
55
|
+
* Human-blocking events (`ask_user_prompt`, `permission_request`,
|
|
56
|
+
* `input_needed`) bypass the filter entirely — the keypress that triggered
|
|
57
|
+
* them must not mute them.
|
|
56
58
|
*/
|
|
57
59
|
export function filterPlatformsAfterInput(
|
|
58
60
|
platforms: NotifyPlatform[],
|
|
@@ -15,6 +15,7 @@ import { sendTelegramNotification } from "./platforms/telegram.js";
|
|
|
15
15
|
import { sendNtfyNotification } from "./platforms/ntfy.js";
|
|
16
16
|
import { buildAskUserPromptMessage } from "./ask-user-prompt-message.js";
|
|
17
17
|
import { buildPermissionPromptMessage } from "./permission-prompt-message.js";
|
|
18
|
+
import { buildInputNeededMessage } from "./input-needed-message.js";
|
|
18
19
|
import { summarizeLastMessage } from "./summarize.js";
|
|
19
20
|
import { filterPlatformsAfterInput, isBlockingEvent } from "./activity.js";
|
|
20
21
|
|
|
@@ -75,6 +76,22 @@ const unsubs: Array<() => void> = [];
|
|
|
75
76
|
/** Pending re-notify interval for an unanswered blocking prompt. */
|
|
76
77
|
let renotifyTimer: ReturnType<typeof setInterval> | undefined;
|
|
77
78
|
|
|
79
|
+
/**
|
|
80
|
+
* A `ui_prompt_start` within this window of an ask_user/permission alert is
|
|
81
|
+
* the same prompt — pi emits the bus event and the lifecycle event back to
|
|
82
|
+
* back. Exported for tests.
|
|
83
|
+
*/
|
|
84
|
+
export const PROMPT_DEDUP_MS = 2000;
|
|
85
|
+
|
|
86
|
+
/** Whether an agent run is in progress — `input_needed` fires only while it is. */
|
|
87
|
+
let agentRunning = false;
|
|
88
|
+
|
|
89
|
+
/** Open blocking UI prompts (`ui_prompt_start`/`ui_prompt_end` pairing). */
|
|
90
|
+
let openPrompts = 0;
|
|
91
|
+
|
|
92
|
+
/** When the last ask_user/permission alert went out, for ui_prompt de-dup. */
|
|
93
|
+
let lastBlockingAlertAt = 0;
|
|
94
|
+
|
|
78
95
|
/** Cancel any pending re-notify timer. Safe to call at any time. */
|
|
79
96
|
export function disarmRenotify(): void {
|
|
80
97
|
const timer = renotifyTimer;
|
|
@@ -128,9 +145,33 @@ function armRenotify(
|
|
|
128
145
|
renotifyTimer = timer;
|
|
129
146
|
}
|
|
130
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Dispatch a human-blocking prompt alert: high priority plus the reminder
|
|
150
|
+
* loop. Non-`input_needed` alerts also stamp `lastBlockingAlertAt` so the
|
|
151
|
+
* back-to-back `ui_prompt_start` for the same prompt is seen as announced.
|
|
152
|
+
*/
|
|
153
|
+
function notifyBlocking(
|
|
154
|
+
pi: ExtensionAPI,
|
|
155
|
+
eventKey: string,
|
|
156
|
+
title: string,
|
|
157
|
+
message: string,
|
|
158
|
+
platforms: NotifyPlatform[],
|
|
159
|
+
config: NotifyConfig,
|
|
160
|
+
cwd: string,
|
|
161
|
+
dispatch: DispatchNotification,
|
|
162
|
+
): void {
|
|
163
|
+
if (eventKey !== "input_needed") lastBlockingAlertAt = Date.now();
|
|
164
|
+
dispatch(pi, title, message, platforms, eventKey, config, cwd, "high").catch(() => {
|
|
165
|
+
// Silently ignore — background notification failure is non-blocking.
|
|
166
|
+
});
|
|
167
|
+
armRenotify(pi, title, message, platforms, eventKey, config, cwd, dispatch);
|
|
168
|
+
}
|
|
169
|
+
|
|
131
170
|
/** Unregister all previously registered pi.events.on() listeners. */
|
|
132
171
|
function unregisterAll(): void {
|
|
133
172
|
disarmRenotify();
|
|
173
|
+
agentRunning = false;
|
|
174
|
+
openPrompts = 0;
|
|
134
175
|
for (const unsub of unsubs) {
|
|
135
176
|
try { unsub(); } catch { /* ignore */ }
|
|
136
177
|
}
|
|
@@ -161,6 +202,7 @@ export const BUILTIN_EVENTS: Record<
|
|
|
161
202
|
session_shutdown: { hook: "session_shutdown", label: "Session End" },
|
|
162
203
|
ask_user_prompt: { hook: UNIPI_EVENTS.ASK_USER_PROMPT, label: "Question Asked" },
|
|
163
204
|
permission_request: { hook: PERMISSION_UI_PROMPT_EVENT, label: "Permission Request" },
|
|
205
|
+
input_needed: { hook: "ui_prompt_start", label: "Input Needed" },
|
|
164
206
|
};
|
|
165
207
|
|
|
166
208
|
/**
|
|
@@ -184,7 +226,9 @@ export function registerEventListeners(
|
|
|
184
226
|
unregisterAll();
|
|
185
227
|
// Register built-in events (except agent lifecycle notifications which have custom logic)
|
|
186
228
|
for (const [eventKey, def] of Object.entries(BUILTIN_EVENTS)) {
|
|
187
|
-
|
|
229
|
+
// Agent notifications have custom logic; input_needed has its own
|
|
230
|
+
// ui_prompt_start registration below (with agent-running + de-dup guards).
|
|
231
|
+
if (isAgentNotificationEvent(eventKey) || eventKey === "input_needed") continue;
|
|
188
232
|
|
|
189
233
|
const eventConfig = config.events[eventKey];
|
|
190
234
|
if (!eventConfig?.enabled) continue;
|
|
@@ -192,6 +236,12 @@ export function registerEventListeners(
|
|
|
192
236
|
const handler = (payload: unknown) => {
|
|
193
237
|
const title = `Pi — ${def.label}`;
|
|
194
238
|
const message = buildEventMessage(eventKey, payload);
|
|
239
|
+
// Human-blocking prompts: high priority, reminder loop, and a stamp
|
|
240
|
+
// that keeps the follow-up ui_prompt_start from double-firing.
|
|
241
|
+
if (isBlockingEvent(eventKey)) {
|
|
242
|
+
notifyBlocking(pi, eventKey, title, message, eventConfig.platforms, config, cwd, dispatch);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
195
245
|
// Fire-and-forget: don't block the event emitter
|
|
196
246
|
dispatch(
|
|
197
247
|
pi,
|
|
@@ -205,9 +255,6 @@ export function registerEventListeners(
|
|
|
205
255
|
).catch(() => {
|
|
206
256
|
// Silently ignore — background notification failure is non-blocking.
|
|
207
257
|
});
|
|
208
|
-
if (isBlockingEvent(eventKey)) {
|
|
209
|
-
armRenotify(pi, title, message, eventConfig.platforms, eventKey, config, cwd, dispatch);
|
|
210
|
-
}
|
|
211
258
|
};
|
|
212
259
|
|
|
213
260
|
// Pi lifecycle events are dispatched via ExtensionRunner — must use
|
|
@@ -225,14 +272,16 @@ export function registerEventListeners(
|
|
|
225
272
|
const askUserConfig = config.events["ask_user_prompt"];
|
|
226
273
|
if (askUserConfig?.enabled) {
|
|
227
274
|
unsubs.push(pi.events.on(ASK_USER_PROMPT_EVENT, (payload: unknown) => {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
275
|
+
notifyBlocking(
|
|
276
|
+
pi,
|
|
277
|
+
"ask_user_prompt",
|
|
278
|
+
`Pi — ${BUILTIN_EVENTS.ask_user_prompt.label}`,
|
|
279
|
+
buildAskUserPromptMessage(payload),
|
|
280
|
+
askUserConfig.platforms,
|
|
281
|
+
config,
|
|
282
|
+
cwd,
|
|
283
|
+
dispatch,
|
|
234
284
|
);
|
|
235
|
-
armRenotify(pi, title, message, askUserConfig.platforms, "ask_user_prompt", config, cwd, dispatch);
|
|
236
285
|
}));
|
|
237
286
|
}
|
|
238
287
|
|
|
@@ -242,11 +291,67 @@ export function registerEventListeners(
|
|
|
242
291
|
if ((payload as { active?: unknown } | null)?.active === false) disarmRenotify();
|
|
243
292
|
}));
|
|
244
293
|
(pi as any).on("agent_start", () => {
|
|
294
|
+
agentRunning = true;
|
|
245
295
|
disarmRenotify();
|
|
246
296
|
});
|
|
247
297
|
|
|
248
298
|
registerAgentNotification(pi, "agent_end", config, cwd, dispatch);
|
|
249
299
|
registerAgentNotification(pi, "agent_settled", config, cwd, dispatch);
|
|
300
|
+
|
|
301
|
+
// Keep the agent-running flag in sync. Registered after the agent
|
|
302
|
+
// notification handlers above so the first agent_end handler stays the
|
|
303
|
+
// notification path (pi.on handlers fire in registration order).
|
|
304
|
+
(pi as any).on("agent_end", () => {
|
|
305
|
+
agentRunning = false;
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
registerInputNeeded(pi, config, cwd, dispatch);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* pi ≥0.84.4 fires `ui_prompt_start`/`ui_prompt_end` around every blocking
|
|
313
|
+
* user-facing prompt — including ones that emit no bus event of their own
|
|
314
|
+
* (third-party ask_user tools, the permission prompt, the plan review).
|
|
315
|
+
*
|
|
316
|
+
* The start/end pair is registered whenever we are not a subagent child,
|
|
317
|
+
* independent of the `input_needed` flag: the open-prompt counter must stay
|
|
318
|
+
* paired so a prompt closing also disarms ask_user/permission reminders.
|
|
319
|
+
* Only the notification itself respects the flag, and it fires only while
|
|
320
|
+
* the agent is running — a `ui_prompt_start` while idle is the user's own
|
|
321
|
+
* overlay (e.g. /unipi:settings).
|
|
322
|
+
*/
|
|
323
|
+
function registerInputNeeded(
|
|
324
|
+
pi: ExtensionAPI,
|
|
325
|
+
config: NotifyConfig,
|
|
326
|
+
cwd: string,
|
|
327
|
+
dispatch: DispatchNotification,
|
|
328
|
+
): void {
|
|
329
|
+
// Subagent children never own a user-facing prompt.
|
|
330
|
+
if (process.env.UNIPI_SUBAGENT_CHILD === "1") return;
|
|
331
|
+
|
|
332
|
+
(pi as any).on("ui_prompt_start", (payload: unknown) => {
|
|
333
|
+
openPrompts += 1;
|
|
334
|
+
const eventConfig = config.events["input_needed"];
|
|
335
|
+
if (!eventConfig?.enabled) return;
|
|
336
|
+
if (!agentRunning) return;
|
|
337
|
+
// Same prompt already announced as ask_user/permission_request.
|
|
338
|
+
if (Date.now() - lastBlockingAlertAt < PROMPT_DEDUP_MS) return;
|
|
339
|
+
notifyBlocking(
|
|
340
|
+
pi,
|
|
341
|
+
"input_needed",
|
|
342
|
+
`Pi — ${BUILTIN_EVENTS.input_needed.label}`,
|
|
343
|
+
buildInputNeededMessage(payload),
|
|
344
|
+
eventConfig.platforms,
|
|
345
|
+
config,
|
|
346
|
+
cwd,
|
|
347
|
+
dispatch,
|
|
348
|
+
);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
(pi as any).on("ui_prompt_end", () => {
|
|
352
|
+
openPrompts = Math.max(0, openPrompts - 1);
|
|
353
|
+
if (openPrompts === 0) disarmRenotify();
|
|
354
|
+
});
|
|
250
355
|
}
|
|
251
356
|
|
|
252
357
|
/** Get all platforms that are currently enabled in config */
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pi-unipi/notify — Internal helper: build notification message from pi's
|
|
3
|
+
* `ui_prompt_start` lifecycle payload.
|
|
4
|
+
*
|
|
5
|
+
* @internal — not part of the public API. Shared by the event listener and tests.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Longest prompt title kept verbatim before an ellipsis is appended. */
|
|
9
|
+
export const INPUT_TITLE_MAX_CHARS = 120;
|
|
10
|
+
|
|
11
|
+
function cleanKind(value: unknown): string {
|
|
12
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : "prompt";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Truncate by code points (Array.from) so surrogate pairs are never split. */
|
|
16
|
+
function truncate(text: string, max: number): string {
|
|
17
|
+
const chars = Array.from(text);
|
|
18
|
+
return chars.length <= max ? text : `${chars.slice(0, max).join("")}…`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Build a human-readable notification message from a ui_prompt_start payload. */
|
|
22
|
+
export function buildInputNeededMessage(payload: unknown): string {
|
|
23
|
+
const p = (payload ?? {}) as { title?: unknown; kind?: unknown };
|
|
24
|
+
const title = typeof p.title === "string" ? p.title.replace(/\s+/g, " ").trim() : "";
|
|
25
|
+
if (title.length === 0) return `Waiting for your input (${cleanKind(p.kind)})`;
|
|
26
|
+
return `Waiting for your input: ${truncate(title, INPUT_TITLE_MAX_CHARS)}`;
|
|
27
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/notify",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Cross-platform notification extension for Pi — native OS, Gotify, and Telegram notifications for agent lifecycle events",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
37
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
38
38
|
"node-notifier": "^10.0.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
@@ -30,6 +30,7 @@ export const DEFAULT_CONFIG: NotifyConfig = {
|
|
|
30
30
|
session_shutdown: { enabled: false, platforms: [] },
|
|
31
31
|
ask_user_prompt: { enabled: false, platforms: [] },
|
|
32
32
|
permission_request: { enabled: false, platforms: [] },
|
|
33
|
+
input_needed: { enabled: false, platforms: [] },
|
|
33
34
|
},
|
|
34
35
|
native: {
|
|
35
36
|
enabled: true,
|
|
@@ -79,6 +80,7 @@ const EVENT_PHRASES: Record<string, string> = {
|
|
|
79
80
|
session_shutdown: "the session shuts down.",
|
|
80
81
|
ask_user_prompt: "the agent asks you a question.",
|
|
81
82
|
permission_request: "a permission prompt opens.",
|
|
83
|
+
input_needed: "the agent is waiting on any prompt (covers tools that send no event of their own).",
|
|
82
84
|
};
|
|
83
85
|
|
|
84
86
|
/** One section per known event: enable + platform routing. */
|
|
@@ -38,7 +38,8 @@ Help users configure the `@pi-unipi/notify` notification system.
|
|
|
38
38
|
"memory_consolidated": { "enabled": false, "platforms": [] },
|
|
39
39
|
"session_shutdown": { "enabled": false, "platforms": [] },
|
|
40
40
|
"ask_user_prompt": { "enabled": false, "platforms": [] },
|
|
41
|
-
"permission_request": { "enabled": false, "platforms": [] }
|
|
41
|
+
"permission_request": { "enabled": false, "platforms": [] },
|
|
42
|
+
"input_needed": { "enabled": false, "platforms": [] }
|
|
42
43
|
},
|
|
43
44
|
"native": {
|
|
44
45
|
"enabled": true,
|
|
@@ -207,10 +208,11 @@ ntfy uses dedicated `ntfy.json` files at both global and project scope, with ful
|
|
|
207
208
|
| `session_shutdown` | Off | Session ends |
|
|
208
209
|
| `ask_user_prompt` | Off | Agent asked a question and is waiting for an answer |
|
|
209
210
|
| `permission_request` | Off | A permission prompt is about to be shown |
|
|
211
|
+
| `input_needed` | Off | The agent waits on any prompt while it runs (covers tools that send no event of their own) |
|
|
210
212
|
|
|
211
213
|
Each event can override `platforms` — empty array means use `defaultPlatforms`.
|
|
212
214
|
|
|
213
|
-
`ask_user_prompt` and `
|
|
215
|
+
`ask_user_prompt`, `permission_request` and `input_needed` are **blocking** events: while one is unanswered the agent is parked, so notify re-sends it periodically (see the Re-notify unanswered prompts section under Platforms).
|
|
214
216
|
|
|
215
217
|
### `permission_request`
|
|
216
218
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/skill-registry",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Skill registry for pi — per-project skill on/off, a skill vault, and jev-judged skill exposure",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"main": "index.ts",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
36
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/subagents",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Subagents for UniPi — Devin-model independent child agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"test": "npx tsx --test src/__tests__/*.test.ts"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
13
|
-
"@pi-unipi/utility": "3.0.0-alpha.
|
|
12
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
13
|
+
"@pi-unipi/utility": "3.0.0-alpha.29",
|
|
14
14
|
"@earendil-works/pi-agent-core": "^0.87.1",
|
|
15
15
|
"acorn": "8.18.0"
|
|
16
16
|
},
|
|
@@ -10735,8 +10735,7 @@ init_core();
|
|
|
10735
10735
|
var SUMMARIZE_SKILL = "summarize";
|
|
10736
10736
|
function summarizePrompt(focus) {
|
|
10737
10737
|
const f = focus.trim();
|
|
10738
|
-
|
|
10739
|
-
return `/skill:${SUMMARIZE_SKILL} ${scope} Use only what happened in this session. Do not call tools.`;
|
|
10738
|
+
return f ? `/skill:${SUMMARIZE_SKILL} ${f}` : `/skill:${SUMMARIZE_SKILL}`;
|
|
10740
10739
|
}
|
|
10741
10740
|
function hasSummarizeSkill(pi) {
|
|
10742
10741
|
try {
|
|
@@ -10761,7 +10760,7 @@ function registerSummarizeCommand(pi) {
|
|
|
10761
10760
|
sendHarnessUserMessage(
|
|
10762
10761
|
pi,
|
|
10763
10762
|
summarizePrompt(focus),
|
|
10764
|
-
{ source: "Utility", title: "Summarize", synopsis: focus ? `
|
|
10763
|
+
{ source: "Utility", title: "Summarize", synopsis: focus ? `ask: ${focus}` : "last reply" },
|
|
10765
10764
|
{ expandPromptTemplates: true }
|
|
10766
10765
|
);
|
|
10767
10766
|
await new Promise((r) => setTimeout(r, 0));
|
|
@@ -25337,10 +25336,10 @@ import { dirname as dirname20, join as join37 } from "node:path";
|
|
|
25337
25336
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
25338
25337
|
function primaryArg(name, args) {
|
|
25339
25338
|
if (!args) return "";
|
|
25340
|
-
const
|
|
25339
|
+
const truncate3 = (v, max) => v.length > max ? `${v.slice(0, Math.max(0, max - 1))}\u2026` : v;
|
|
25341
25340
|
const firstLine3 = (v) => v.split("\n", 1)[0] ?? "";
|
|
25342
25341
|
const value = name === "bash" ? args.command : name === "read" || name === "edit" || name === "write" ? args.path ?? args.file_path ?? args.filePath : Object.values(args).find((entry) => typeof entry === "string");
|
|
25343
|
-
return typeof value === "string" ?
|
|
25342
|
+
return typeof value === "string" ? truncate3(firstLine3(value), 100) : "";
|
|
25344
25343
|
}
|
|
25345
25344
|
var DENY_WITH_NOTE = "Deny with note\u2026";
|
|
25346
25345
|
var BACKGROUND_DENY_NOTE = "Permission denied for this tool: this agent is running in the background, where tools that would require approval are automatically denied. Do not retry variants of this call; finish what you can without it and say in your report what needs approval.";
|
|
@@ -36578,8 +36577,8 @@ function renderMcpSettingsOverlay(params) {
|
|
|
36578
36577
|
const selected = i === state2.selectedIndex;
|
|
36579
36578
|
const statusIcon = server.status === "running" ? "\u25CF" : server.status === "error" ? "\u2717" : server.enabled ? "\u25CB" : "\u25CB";
|
|
36580
36579
|
const label = `${statusIcon} ${server.enabled ? "" : "disabled \xB7 "}${server.name}`;
|
|
36581
|
-
const tools = server.status === "running" && server.toolCount > 0 ? `${server.toolCount} tools` : server.status === "error" && server.error ?
|
|
36582
|
-
const value = `${
|
|
36580
|
+
const tools = server.status === "running" && server.toolCount > 0 ? `${server.toolCount} tools` : server.status === "error" && server.error ? truncate3(server.error, 20) : "stopped";
|
|
36581
|
+
const value = `${truncate3(server.command, 24)} \xB7 ${tools} \xB7 [${server.source}]`;
|
|
36583
36582
|
body.push(hubExactRow(hubRowColumns({
|
|
36584
36583
|
inner,
|
|
36585
36584
|
selected,
|
|
@@ -36601,7 +36600,7 @@ function renderMcpSettingsOverlay(params) {
|
|
|
36601
36600
|
title: hubBoldText(hubFrameTitle("mcp", [], `\u2014 ${state2.viewScope}`)),
|
|
36602
36601
|
borderFg: (t) => hubTheme.fg("borderMuted", t)
|
|
36603
36602
|
});
|
|
36604
|
-
function
|
|
36603
|
+
function truncate3(text, n) {
|
|
36605
36604
|
return text.length > n ? text.slice(0, n - 1) + "\u2026" : text;
|
|
36606
36605
|
}
|
|
36607
36606
|
}
|
|
@@ -36880,7 +36879,8 @@ var VALID_PLATFORMS = /* @__PURE__ */ new Set([
|
|
|
36880
36879
|
]);
|
|
36881
36880
|
var BLOCKING_EVENTS = /* @__PURE__ */ new Set([
|
|
36882
36881
|
"ask_user_prompt",
|
|
36883
|
-
"permission_request"
|
|
36882
|
+
"permission_request",
|
|
36883
|
+
"input_needed"
|
|
36884
36884
|
]);
|
|
36885
36885
|
function isBlockingEvent(eventType) {
|
|
36886
36886
|
return eventType !== void 0 && BLOCKING_EVENTS.has(eventType);
|
|
@@ -36949,7 +36949,8 @@ var DEFAULT_CONFIG5 = {
|
|
|
36949
36949
|
memory_consolidated: { enabled: false, platforms: [] },
|
|
36950
36950
|
session_shutdown: { enabled: false, platforms: [] },
|
|
36951
36951
|
ask_user_prompt: { enabled: false, platforms: [] },
|
|
36952
|
-
permission_request: { enabled: false, platforms: [] }
|
|
36952
|
+
permission_request: { enabled: false, platforms: [] },
|
|
36953
|
+
input_needed: { enabled: false, platforms: [] }
|
|
36953
36954
|
},
|
|
36954
36955
|
native: {
|
|
36955
36956
|
enabled: true,
|
|
@@ -36993,7 +36994,8 @@ var EVENT_PHRASES = {
|
|
|
36993
36994
|
memory_consolidated: "a memory consolidation completes.",
|
|
36994
36995
|
session_shutdown: "the session shuts down.",
|
|
36995
36996
|
ask_user_prompt: "the agent asks you a question.",
|
|
36996
|
-
permission_request: "a permission prompt opens."
|
|
36997
|
+
permission_request: "a permission prompt opens.",
|
|
36998
|
+
input_needed: "the agent is waiting on any prompt (covers tools that send no event of their own)."
|
|
36997
36999
|
};
|
|
36998
37000
|
var EVENT_SECTIONS = Object.keys(DEFAULT_CONFIG5.events).map((event) => ({
|
|
36999
37001
|
title: event,
|
|
@@ -37559,6 +37561,22 @@ function buildPermissionPromptMessage(payload) {
|
|
|
37559
37561
|
return parts.join(" ");
|
|
37560
37562
|
}
|
|
37561
37563
|
|
|
37564
|
+
// packages/notify/input-needed-message.ts
|
|
37565
|
+
var INPUT_TITLE_MAX_CHARS = 120;
|
|
37566
|
+
function cleanKind(value) {
|
|
37567
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : "prompt";
|
|
37568
|
+
}
|
|
37569
|
+
function truncate2(text, max) {
|
|
37570
|
+
const chars = Array.from(text);
|
|
37571
|
+
return chars.length <= max ? text : `${chars.slice(0, max).join("")}\u2026`;
|
|
37572
|
+
}
|
|
37573
|
+
function buildInputNeededMessage(payload) {
|
|
37574
|
+
const p = payload ?? {};
|
|
37575
|
+
const title = typeof p.title === "string" ? p.title.replace(/\s+/g, " ").trim() : "";
|
|
37576
|
+
if (title.length === 0) return `Waiting for your input (${cleanKind(p.kind)})`;
|
|
37577
|
+
return `Waiting for your input: ${truncate2(title, INPUT_TITLE_MAX_CHARS)}`;
|
|
37578
|
+
}
|
|
37579
|
+
|
|
37562
37580
|
// packages/notify/summarize.ts
|
|
37563
37581
|
var SYSTEM_PROMPT2 = "Summarize this in one concise sentence for a push notification. Reply with ONLY the summary.";
|
|
37564
37582
|
var MAX_INPUT_CHARS = 2e3;
|
|
@@ -37676,6 +37694,10 @@ function defaultEventPriority(eventKey) {
|
|
|
37676
37694
|
var sessionCtx = null;
|
|
37677
37695
|
var unsubs = [];
|
|
37678
37696
|
var renotifyTimer;
|
|
37697
|
+
var PROMPT_DEDUP_MS = 2e3;
|
|
37698
|
+
var agentRunning = false;
|
|
37699
|
+
var openPrompts = 0;
|
|
37700
|
+
var lastBlockingAlertAt = 0;
|
|
37679
37701
|
function disarmRenotify() {
|
|
37680
37702
|
const timer = renotifyTimer;
|
|
37681
37703
|
renotifyTimer = void 0;
|
|
@@ -37708,8 +37730,16 @@ function armRenotify(pi, title, message, platforms, eventType, config, cwd, disp
|
|
|
37708
37730
|
timer.unref?.();
|
|
37709
37731
|
renotifyTimer = timer;
|
|
37710
37732
|
}
|
|
37733
|
+
function notifyBlocking(pi, eventKey, title, message, platforms, config, cwd, dispatch) {
|
|
37734
|
+
if (eventKey !== "input_needed") lastBlockingAlertAt = Date.now();
|
|
37735
|
+
dispatch(pi, title, message, platforms, eventKey, config, cwd, "high").catch(() => {
|
|
37736
|
+
});
|
|
37737
|
+
armRenotify(pi, title, message, platforms, eventKey, config, cwd, dispatch);
|
|
37738
|
+
}
|
|
37711
37739
|
function unregisterAll() {
|
|
37712
37740
|
disarmRenotify();
|
|
37741
|
+
agentRunning = false;
|
|
37742
|
+
openPrompts = 0;
|
|
37713
37743
|
for (const unsub of unsubs) {
|
|
37714
37744
|
try {
|
|
37715
37745
|
unsub();
|
|
@@ -37733,18 +37763,23 @@ var BUILTIN_EVENTS = {
|
|
|
37733
37763
|
memory_consolidated: { hook: UNIPI_EVENTS.MEMORY_CONSOLIDATED, label: "Memory Saved" },
|
|
37734
37764
|
session_shutdown: { hook: "session_shutdown", label: "Session End" },
|
|
37735
37765
|
ask_user_prompt: { hook: UNIPI_EVENTS.ASK_USER_PROMPT, label: "Question Asked" },
|
|
37736
|
-
permission_request: { hook: PERMISSION_UI_PROMPT_EVENT, label: "Permission Request" }
|
|
37766
|
+
permission_request: { hook: PERMISSION_UI_PROMPT_EVENT, label: "Permission Request" },
|
|
37767
|
+
input_needed: { hook: "ui_prompt_start", label: "Input Needed" }
|
|
37737
37768
|
};
|
|
37738
37769
|
var LIFECYCLE_EVENTS = /* @__PURE__ */ new Set(["agent_end", "agent_settled", "session_shutdown"]);
|
|
37739
37770
|
function registerEventListeners(pi, config, cwd, dispatch = dispatchNotification) {
|
|
37740
37771
|
unregisterAll();
|
|
37741
37772
|
for (const [eventKey, def] of Object.entries(BUILTIN_EVENTS)) {
|
|
37742
|
-
if (isAgentNotificationEvent(eventKey)) continue;
|
|
37773
|
+
if (isAgentNotificationEvent(eventKey) || eventKey === "input_needed") continue;
|
|
37743
37774
|
const eventConfig = config.events[eventKey];
|
|
37744
37775
|
if (!eventConfig?.enabled) continue;
|
|
37745
37776
|
const handler = (payload) => {
|
|
37746
37777
|
const title = `Pi \u2014 ${def.label}`;
|
|
37747
37778
|
const message = buildEventMessage(eventKey, payload);
|
|
37779
|
+
if (isBlockingEvent(eventKey)) {
|
|
37780
|
+
notifyBlocking(pi, eventKey, title, message, eventConfig.platforms, config, cwd, dispatch);
|
|
37781
|
+
return;
|
|
37782
|
+
}
|
|
37748
37783
|
dispatch(
|
|
37749
37784
|
pi,
|
|
37750
37785
|
title,
|
|
@@ -37756,9 +37791,6 @@ function registerEventListeners(pi, config, cwd, dispatch = dispatchNotification
|
|
|
37756
37791
|
defaultEventPriority(eventKey)
|
|
37757
37792
|
).catch(() => {
|
|
37758
37793
|
});
|
|
37759
|
-
if (isBlockingEvent(eventKey)) {
|
|
37760
|
-
armRenotify(pi, title, message, eventConfig.platforms, eventKey, config, cwd, dispatch);
|
|
37761
|
-
}
|
|
37762
37794
|
};
|
|
37763
37795
|
if (LIFECYCLE_EVENTS.has(eventKey)) {
|
|
37764
37796
|
pi.on(def.hook, handler);
|
|
@@ -37769,23 +37801,55 @@ function registerEventListeners(pi, config, cwd, dispatch = dispatchNotification
|
|
|
37769
37801
|
const askUserConfig = config.events["ask_user_prompt"];
|
|
37770
37802
|
if (askUserConfig?.enabled) {
|
|
37771
37803
|
unsubs.push(pi.events.on(ASK_USER_PROMPT_EVENT, (payload) => {
|
|
37772
|
-
|
|
37773
|
-
|
|
37774
|
-
|
|
37775
|
-
|
|
37776
|
-
|
|
37804
|
+
notifyBlocking(
|
|
37805
|
+
pi,
|
|
37806
|
+
"ask_user_prompt",
|
|
37807
|
+
`Pi \u2014 ${BUILTIN_EVENTS.ask_user_prompt.label}`,
|
|
37808
|
+
buildAskUserPromptMessage(payload),
|
|
37809
|
+
askUserConfig.platforms,
|
|
37810
|
+
config,
|
|
37811
|
+
cwd,
|
|
37812
|
+
dispatch
|
|
37777
37813
|
);
|
|
37778
|
-
armRenotify(pi, title, message, askUserConfig.platforms, "ask_user_prompt", config, cwd, dispatch);
|
|
37779
37814
|
}));
|
|
37780
37815
|
}
|
|
37781
37816
|
unsubs.push(pi.events.on("herdr:blocked", (payload) => {
|
|
37782
37817
|
if (payload?.active === false) disarmRenotify();
|
|
37783
37818
|
}));
|
|
37784
37819
|
pi.on("agent_start", () => {
|
|
37820
|
+
agentRunning = true;
|
|
37785
37821
|
disarmRenotify();
|
|
37786
37822
|
});
|
|
37787
37823
|
registerAgentNotification(pi, "agent_end", config, cwd, dispatch);
|
|
37788
37824
|
registerAgentNotification(pi, "agent_settled", config, cwd, dispatch);
|
|
37825
|
+
pi.on("agent_end", () => {
|
|
37826
|
+
agentRunning = false;
|
|
37827
|
+
});
|
|
37828
|
+
registerInputNeeded(pi, config, cwd, dispatch);
|
|
37829
|
+
}
|
|
37830
|
+
function registerInputNeeded(pi, config, cwd, dispatch) {
|
|
37831
|
+
if (process.env.UNIPI_SUBAGENT_CHILD === "1") return;
|
|
37832
|
+
pi.on("ui_prompt_start", (payload) => {
|
|
37833
|
+
openPrompts += 1;
|
|
37834
|
+
const eventConfig = config.events["input_needed"];
|
|
37835
|
+
if (!eventConfig?.enabled) return;
|
|
37836
|
+
if (!agentRunning) return;
|
|
37837
|
+
if (Date.now() - lastBlockingAlertAt < PROMPT_DEDUP_MS) return;
|
|
37838
|
+
notifyBlocking(
|
|
37839
|
+
pi,
|
|
37840
|
+
"input_needed",
|
|
37841
|
+
`Pi \u2014 ${BUILTIN_EVENTS.input_needed.label}`,
|
|
37842
|
+
buildInputNeededMessage(payload),
|
|
37843
|
+
eventConfig.platforms,
|
|
37844
|
+
config,
|
|
37845
|
+
cwd,
|
|
37846
|
+
dispatch
|
|
37847
|
+
);
|
|
37848
|
+
});
|
|
37849
|
+
pi.on("ui_prompt_end", () => {
|
|
37850
|
+
openPrompts = Math.max(0, openPrompts - 1);
|
|
37851
|
+
if (openPrompts === 0) disarmRenotify();
|
|
37852
|
+
});
|
|
37789
37853
|
}
|
|
37790
37854
|
function getEnabledPlatforms(config, ntfyEnabled) {
|
|
37791
37855
|
const enabled = [];
|
|
@@ -42174,7 +42238,7 @@ var COMMAND_DESCRIPTIONS = {
|
|
|
42174
42238
|
"unipi:cleanup": "Remove stale UniPi temp files and leftovers (preview first)",
|
|
42175
42239
|
"unipi:doctor": "Check UniPi's runtime: config, model cache, Decision Model, skills",
|
|
42176
42240
|
"unipi:answer": "Answer the last reply \u2014 fixed input under the scrollable reply, per question, or web form",
|
|
42177
|
-
"unipi:summarize": "Summarize
|
|
42241
|
+
"unipi:summarize": "Summarize your last reply again (answer first, then findings, open items, questions). Add text to ask about it",
|
|
42178
42242
|
"unipi:skills": "Manage skills \u2014 on/off per project, listed or not, the skill vault",
|
|
42179
42243
|
"unipi:kanboard": "Kanboard \u2014 capture tasks, run them, open the board",
|
|
42180
42244
|
"unipi:kanboard-add": "Kanboard \u2014 capture a task into Backlog",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/updater",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Auto-updater, changelog browser, and readme browser for Unipi — checks npm registry, renders CHANGELOG.md and README.md files in TUI overlays",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
37
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -35,7 +35,7 @@ pi install npm:@pi-unipi/utility
|
|
|
35
35
|
| `/unipi:cleanup` | Lists stale UniPi files, then asks before it removes them. `--dry-run` only lists. `--yes` does not ask. |
|
|
36
36
|
| `/unipi:doctor` | Checks folders, config files, Node, the model cache, the Decision Model and skill exposure. |
|
|
37
37
|
| `/unipi:answer [reply\|questions\|web]` | Opens a screen to answer the last agent reply. |
|
|
38
|
-
| `/unipi:summarize [focus]` |
|
|
38
|
+
| `/unipi:summarize [focus]` | Re-summarizes the last reply (the `summarize` skill). Any text is passed to the skill as your question. |
|
|
39
39
|
|
|
40
40
|
The skill manager is in [Skill Registry](../skill-registry/README.md) (`/unipi:skills`).
|
|
41
41
|
|
|
@@ -51,7 +51,8 @@ final reply after work:
|
|
|
51
51
|
5. Questions for you. Each question has a type: pick one, pick any or your answer.
|
|
52
52
|
|
|
53
53
|
The agent uses the skill for every final reply, unless you ask for full detail
|
|
54
|
-
or raw output. `/unipi:summarize`
|
|
54
|
+
or raw output. `/unipi:summarize` runs this summary again on the last reply.
|
|
55
|
+
Any text you add goes to the skill as your question.
|
|
55
56
|
|
|
56
57
|
The skill is "must show" by default, so exposure judging does not hide it. To
|
|
57
58
|
turn this off, open `/unipi:skills` and clear **M** on `summarize`. Clear **E**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/utility",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Utility commands and tools for Pi coding agent — lifecycle, diagnostics, cache, analytics, display, batch execution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
39
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {},
|
|
42
42
|
"peerDependencies": {
|
|
@@ -11,8 +11,15 @@ description: |
|
|
|
11
11
|
|
|
12
12
|
Use this skill for the final reply after work (a task, an investigation, a
|
|
13
13
|
fix), and when the user runs /unipi:summarize. "The work" below means the
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
latest piece of work: the user's last request, the tool calls and results
|
|
15
|
+
that answered it, and your last reply. Use the rest of the session only as
|
|
16
|
+
context to explain it.
|
|
17
|
+
|
|
18
|
+
When the user runs /unipi:summarize, summarize your last reply again in
|
|
19
|
+
this shape. Do not call tools. If text follows this skill, it is the
|
|
20
|
+
user's question or focus. Answer it about your last reply. Words like "it"
|
|
21
|
+
or "this" refer to what your last reply covered. Use earlier parts of the
|
|
22
|
+
session only when the user's text asks about them.
|
|
16
23
|
|
|
17
24
|
## When not to use it
|
|
18
25
|
|
|
@@ -17,7 +17,7 @@ description: |
|
|
|
17
17
|
| `/unipi:continue` / `/unipi:retry` | Take another turn without new text |
|
|
18
18
|
| `/unipi:cleanup` | Remove stale UniPi temp files (previews and asks first; `--dry-run`, `--yes`) |
|
|
19
19
|
| `/unipi:doctor` | Check config, model cache, Decision Model key, skill exposure |
|
|
20
|
-
| `/unipi:summarize [focus]` |
|
|
20
|
+
| `/unipi:summarize [focus]` | Summarize the last reply again (runs the `summarize` skill); any text is passed to the skill as the user's question |
|
|
21
21
|
|
|
22
22
|
## Notes for the agent
|
|
23
23
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @pi-unipi/utility — /unipi:summarize [focus]
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Runs the bundled `summarize` skill again on the last reply. The command
|
|
5
|
+
* sends `/skill:summarize` (plus the user's own text, if any), so pi inlines
|
|
6
|
+
* the skill file into the turn, the agent cannot skip it, and the command
|
|
7
|
+
* adds no wording of its own.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
@@ -11,13 +12,10 @@ import { sendHarnessUserMessage, UNIPI_PREFIX, UTILITY_COMMANDS } from "@pi-unip
|
|
|
11
12
|
|
|
12
13
|
export const SUMMARIZE_SKILL = "summarize";
|
|
13
14
|
|
|
14
|
-
/** The
|
|
15
|
+
/** The text the command sends: the skill, plus the user's own text (if any) as-is. */
|
|
15
16
|
export function summarizePrompt(focus: string): string {
|
|
16
17
|
const f = focus.trim();
|
|
17
|
-
|
|
18
|
-
? `Summarize this session for me, with the focus on: ${f}`
|
|
19
|
-
: "Summarize this session for me: what we did, why, and where it stands now.";
|
|
20
|
-
return `/skill:${SUMMARIZE_SKILL} ${scope} Use only what happened in this session. Do not call tools.`;
|
|
18
|
+
return f ? `/skill:${SUMMARIZE_SKILL} ${f}` : `/skill:${SUMMARIZE_SKILL}`;
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
/** True when pi can expand `/skill:summarize` (the skill is loaded and on). */
|
|
@@ -45,7 +43,7 @@ export function registerSummarizeCommand(pi: ExtensionAPI): void {
|
|
|
45
43
|
sendHarnessUserMessage(
|
|
46
44
|
pi,
|
|
47
45
|
summarizePrompt(focus),
|
|
48
|
-
{ source: "Utility", title: "Summarize", synopsis: focus ? `
|
|
46
|
+
{ source: "Utility", title: "Summarize", synopsis: focus ? `ask: ${focus}` : "last reply" },
|
|
49
47
|
{ expandPromptTemplates: true },
|
|
50
48
|
);
|
|
51
49
|
// sendUserMessage does not wait. Print mode (-p) exits when the handler
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/watchdog",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Jev watchdog for long-running tool calls and background tasks — judges stuck work via TypeSafe System One and kills or warns",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@pi-unipi/background-tasks": "3.0.0-alpha.
|
|
36
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
35
|
+
"@pi-unipi/background-tasks": "3.0.0-alpha.29",
|
|
36
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/web-api",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Web search, read, and summarize tools with provider-based backend selection for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"README.md"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
34
|
+
"@pi-unipi/core": "3.0.0-alpha.29",
|
|
35
35
|
"defuddle": "^0.18.1",
|
|
36
36
|
"linkedom": "^0.18.12",
|
|
37
37
|
"wreq-js": "^2.3.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/workflow",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.29",
|
|
4
4
|
"description": "Plan mode and permission modes for the Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
30
|
+
"@pi-unipi/core": "3.0.0-alpha.29"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@earendil-works/pi-ai": "^0.87.1",
|