@danypops/pi-packed 0.6.2 → 0.7.0
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/README.md +9 -1
- package/extension/src/index.ts +5 -13
- package/extension/src/model.ts +1 -1
- package/extension/src/reload.ts +1 -1
- package/extension/src/tui.ts +21 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
# pi-packed
|
|
2
2
|
|
|
3
|
-
Pi integration for `@danypops/packed`: package tools, `/
|
|
3
|
+
Pi integration for `@danypops/packed`: package tools, `/packed`, setup apply/reload, and named profiles.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
pi install npm:@danypops/pi-packed
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
The extension connects to Packed's authenticated user daemon and starts the package-local `packed serve` process when no healthy daemon is available. It contains no SQLite, registry, package execution, or daemon implementation code.
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
- `/packed` -- opens on the packages panel: every installed Pi package, with update availability. Select one to update or remove it; `r` refreshes, `/` filters, `Tab` cycles view modes, `s` opens settings.
|
|
14
|
+
- `/packed` settings (`s` from the panel) -- package mutation-approval settings: require confirmation before install/update/remove/security changes (the default), or turn it off.
|
|
15
|
+
- `/packed config` -- enable or disable individual extensions, skills, prompt templates, and themes declared by installed packages, per package, at global or project scope.
|
|
16
|
+
- `/packed setup plan [path] [--prune]` / `/packed setup apply [path] [--prune]` -- preview or apply a reproducible-environment manifest (`pi-setup.json`) against installed packages and profiles.
|
|
17
|
+
- `/profile [name]` -- switch to a named Pi profile (provider, model, tools, instructions, theme), reading `~/.pi/agent/profiles.json` and a trusted project's own `.pi/profiles.json`. `pi --profile <name>` activates one at startup; `Ctrl+Shift+U` cycles through them.
|
package/extension/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* pi-packed — Pi extension seam.
|
|
3
3
|
*
|
|
4
4
|
* Thin by design: registers agent tools (pkg_search/pkg_info/pkg_install/pkg_update/pkg_remove),
|
|
5
|
-
* the /
|
|
5
|
+
* the /packed command, and a session_start update notification. ALL logic
|
|
6
6
|
* lives in the Bun service (src/): registry access, caching, watcher,
|
|
7
7
|
* catalog sync, install execution.
|
|
8
8
|
*
|
|
@@ -10,10 +10,9 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
12
12
|
import { registerTools } from "./tools.js";
|
|
13
|
-
import {
|
|
13
|
+
import { showPackedPanel } from "./tui.js";
|
|
14
14
|
import { createNatives } from "./packed.js";
|
|
15
15
|
import { formatUpdateNotice } from "./model.js";
|
|
16
|
-
import { showPackedSettings } from "./security-tui.js";
|
|
17
16
|
import { registerProfiles } from "./profile.js";
|
|
18
17
|
import { handleSetupCommand } from "./setup-command.js";
|
|
19
18
|
import { handleResourceConfigCommand } from "./resource-config.js";
|
|
@@ -26,18 +25,11 @@ export default async function (pi: ExtensionAPI) {
|
|
|
26
25
|
registerTools(pi, natives);
|
|
27
26
|
|
|
28
27
|
pi.registerCommand("packed", {
|
|
29
|
-
description: "
|
|
28
|
+
description: "Browse and manage installed Pi packages; press s for settings, or run setup plan/apply or config directly",
|
|
30
29
|
handler: async (args, ctx) => {
|
|
31
30
|
if (await handleSetupCommand(args, ctx, natives)) return;
|
|
32
31
|
if (await handleResourceConfigCommand(args, ctx, natives)) return;
|
|
33
|
-
await
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
pi.registerCommand("packages", {
|
|
38
|
-
description: "Browse and manage installed Pi packages (pi-packed)",
|
|
39
|
-
handler: async (_args, ctx) => {
|
|
40
|
-
await showPackages(ctx, natives);
|
|
32
|
+
await showPackedPanel(ctx, natives);
|
|
41
33
|
},
|
|
42
34
|
});
|
|
43
35
|
|
|
@@ -47,7 +39,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
47
39
|
try {
|
|
48
40
|
const updates = await natives.updates();
|
|
49
41
|
if (updates.length) {
|
|
50
|
-
ctx.ui.notify(`${formatUpdateNotice(updates)} — /
|
|
42
|
+
ctx.ui.notify(`${formatUpdateNotice(updates)} — /packed to review`, "info");
|
|
51
43
|
}
|
|
52
44
|
} catch {
|
|
53
45
|
// mirror missing or unreadable — stay silent, never block startup.
|
package/extension/src/model.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* model.ts — pure row logic for the /
|
|
2
|
+
* model.ts — pure row logic for the /packed panel. No I/O: vitest drives
|
|
3
3
|
* this directly (the TUI component is a thin shell over these functions).
|
|
4
4
|
*/
|
|
5
5
|
import type { InstalledPkg, UpdateEntry } from "./packed.js";
|
package/extension/src/reload.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* reload.ts — one shared decision for whether a Pi package mutation needs a
|
|
3
3
|
* reload to take effect, and the exact wording every mutation surface
|
|
4
|
-
* (native tools, the /
|
|
4
|
+
* (native tools, the /packed panel, and the resource overlay) uses to
|
|
5
5
|
* warn about it. Keeps three independent implementations from drifting
|
|
6
6
|
* apart on when and how they say a reload is coming.
|
|
7
7
|
*/
|
package/extension/src/tui.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* tui.ts — /
|
|
3
|
-
*
|
|
4
|
-
* type-to-filter (/), Tab view modes, Enter → actions, r refresh,
|
|
5
|
-
*
|
|
2
|
+
* tui.ts — /packed's default panel. Follows the pi-extension-manager idiom:
|
|
3
|
+
* ctx.ui.custom with Container/DynamicBorder layout, header hints,
|
|
4
|
+
* type-to-filter (/), Tab view modes, Enter → actions, r refresh, s
|
|
5
|
+
* settings, esc close. Packages is the landing page; s opens settings
|
|
6
|
+
* (mutation approval) as a sub-flow and returns to the same panel
|
|
7
|
+
* afterward, rather than a second rendered page. All data flows through
|
|
8
|
+
* the packed CLI (thin seam).
|
|
6
9
|
*/
|
|
7
10
|
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
8
11
|
import { DynamicBorder, rawKeyHint } from "@earendil-works/pi-coding-agent";
|
|
@@ -11,9 +14,10 @@ import { filterRows, mergeRows, nextMode, visibleRows } from "./model.js";
|
|
|
11
14
|
import type { Row, ViewMode } from "./model.js";
|
|
12
15
|
import type { Natives } from "./packed.js";
|
|
13
16
|
import { approvePackageOperation } from "./tools.js";
|
|
17
|
+
import { showPackedSettings } from "./security-tui.js";
|
|
14
18
|
|
|
15
19
|
interface PanelAction {
|
|
16
|
-
type: "menu" | "refresh";
|
|
20
|
+
type: "menu" | "refresh" | "settings";
|
|
17
21
|
row?: Row;
|
|
18
22
|
}
|
|
19
23
|
|
|
@@ -86,9 +90,9 @@ async function loadRows(natives: Natives): Promise<{ rows: Row[]; error?: string
|
|
|
86
90
|
}
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
export async function
|
|
93
|
+
export async function showPackedPanel(ctx: ExtensionCommandContext, natives: Natives): Promise<void> {
|
|
90
94
|
if (!ctx.hasUI) {
|
|
91
|
-
ctx.ui.notify("/
|
|
95
|
+
ctx.ui.notify("/packed requires interactive mode", "warning");
|
|
92
96
|
return;
|
|
93
97
|
}
|
|
94
98
|
|
|
@@ -109,6 +113,11 @@ export async function showPackages(ctx: ExtensionCommandContext, natives: Native
|
|
|
109
113
|
continue;
|
|
110
114
|
}
|
|
111
115
|
|
|
116
|
+
if (action.type === "settings") {
|
|
117
|
+
await showPackedSettings(ctx, natives);
|
|
118
|
+
continue; // settings never changes package rows -- reopen as-is
|
|
119
|
+
}
|
|
120
|
+
|
|
112
121
|
const row = action.row;
|
|
113
122
|
if (!row) continue;
|
|
114
123
|
|
|
@@ -155,6 +164,8 @@ function renderPanel(ctx: ExtensionCommandContext, rows: Row[]): Promise<PanelAc
|
|
|
155
164
|
theme.fg("muted", " · ") +
|
|
156
165
|
rawKeyHint("tab", "view") +
|
|
157
166
|
theme.fg("muted", " · ") +
|
|
167
|
+
rawKeyHint("s", "settings") +
|
|
168
|
+
theme.fg("muted", " · ") +
|
|
158
169
|
rawKeyHint("esc", "close");
|
|
159
170
|
const spacing = Math.max(1, width - visibleWidth(title) - visibleWidth(badge) - visibleWidth(hint));
|
|
160
171
|
const line1 = truncateToWidth(`${title}${badge}${" ".repeat(spacing)}${hint}`, width, "");
|
|
@@ -241,6 +252,9 @@ function renderPanel(ctx: ExtensionCommandContext, rows: Row[]): Promise<PanelAc
|
|
|
241
252
|
case "r":
|
|
242
253
|
done({ type: "refresh" });
|
|
243
254
|
return;
|
|
255
|
+
case "s":
|
|
256
|
+
done({ type: "settings" });
|
|
257
|
+
return;
|
|
244
258
|
case "\r": {
|
|
245
259
|
const row = filtered[selectedIndex];
|
|
246
260
|
if (row) done({ type: "menu", row });
|