@danypops/pi-packed 0.10.0 → 0.12.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 +3 -3
- package/extension/src/tui.ts +161 -82
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,13 +10,13 @@ The extension connects to Packed's authenticated user daemon and starts the pack
|
|
|
10
10
|
|
|
11
11
|
## Commands
|
|
12
12
|
|
|
13
|
-
- `/packed` --
|
|
14
|
-
- `u` / `U` -- update the selected package / update every outdated package, one combined confirmation and one reload.
|
|
13
|
+
- `/packed` -- a floating overlay panel: every installed Pi package, with update availability. Mnemonics follow lazy.nvim's own convention (uppercase acts on every row, lowercase on the one under the cursor):
|
|
14
|
+
- `u` / `U` -- update the selected package / update every outdated package, one combined confirmation and one reload. `U`'s progress bar appears inline next to the package currently updating -- the list stays visible throughout, nothing swaps to a separate screen.
|
|
15
15
|
- `x` -- remove the selected package.
|
|
16
16
|
- `d` -- disable (or re-enable) the selected package's own extensions.
|
|
17
17
|
- `c` -- jump to resource config for the selected package (skills, prompts, themes).
|
|
18
18
|
- `f` -- find: search the npm registry for new Pi packages and install one.
|
|
19
|
-
- `s` -- settings. `Enter` opens a floating action menu with all of the above. `r` refreshes, `/` filters, `Tab` cycles view modes.
|
|
19
|
+
- `s` -- settings. `Enter` opens a smaller floating action menu with all of the above. `r` refreshes, `/` filters, `Tab` cycles view modes.
|
|
20
20
|
- `/packed config` -- enable or disable individual extensions, skills, prompt templates, and themes declared by installed packages, per package, at global or project scope.
|
|
21
21
|
- `/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.
|
|
22
22
|
- `/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/tui.ts
CHANGED
|
@@ -6,15 +6,19 @@
|
|
|
6
6
|
* only (x remove -- there is no safe "remove every installed package"
|
|
7
7
|
* bulk analog, so no X is bound). Adds d disable/enable this package's
|
|
8
8
|
* extensions, c jump to full resource config, f find/install new
|
|
9
|
-
* packages, s settings.
|
|
10
|
-
* overlay
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* packages, s settings. The panel itself is a real bordered (rounded)
|
|
10
|
+
* floating overlay (`ctx.ui.custom` with overlay:true, Malevich's
|
|
11
|
+
* Envelope for the box), anchored to the top so its header stays put and
|
|
12
|
+
* only the footer moves as content height changes. Enter opens a second,
|
|
13
|
+
* smaller overlay action menu on top of it. U's batch update stays on
|
|
14
|
+
* this same package list -- progress renders inline next to the row
|
|
15
|
+
* currently being updated, not as a separate screen. All data flows
|
|
16
|
+
* through the packed CLI (thin seam).
|
|
13
17
|
*/
|
|
14
18
|
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
15
19
|
import { DynamicBorder, rawKeyHint } from "@earendil-works/pi-coding-agent";
|
|
16
|
-
import { Container, Input, Spacer, truncateToWidth
|
|
17
|
-
import { Menu, ProgressBar, type MenuItem } from "malevich-tui-components";
|
|
20
|
+
import { Container, Input, Spacer, truncateToWidth } from "@earendil-works/pi-tui";
|
|
21
|
+
import { Envelope, Menu, ProgressBar, type MenuItem } from "malevich-tui-components";
|
|
18
22
|
import { filterRows, mergeRows, nextMode, visibleRows } from "./model.js";
|
|
19
23
|
import type { Row, ViewMode } from "./model.js";
|
|
20
24
|
import type { Natives, PackageResources } from "./packed.js";
|
|
@@ -25,7 +29,7 @@ import { showDiscoverPanel } from "./discover.js";
|
|
|
25
29
|
import { menuTheme } from "./menu-theme.js";
|
|
26
30
|
|
|
27
31
|
interface PanelAction {
|
|
28
|
-
type: "update" | "
|
|
32
|
+
type: "update" | "remove" | "disable" | "config" | "find" | "refresh" | "settings";
|
|
29
33
|
row?: Row;
|
|
30
34
|
}
|
|
31
35
|
|
|
@@ -88,11 +92,73 @@ export async function applyPackageChoice(
|
|
|
88
92
|
|
|
89
93
|
interface UpdateAllResult { changed: number; failedNames: string[]; }
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
*
|
|
95
|
-
*
|
|
95
|
+
interface UpdateProgressEvent { row: Row; index: number; total: number; phase: "start" | "done"; }
|
|
96
|
+
|
|
97
|
+
/** The core sequential-update loop, with no UI of its own -- reports each
|
|
98
|
+
* step via onProgress so any host surface (a floating overlay, or the
|
|
99
|
+
* packages panel's own body) can render it however fits. */
|
|
100
|
+
async function performUpdateAll(
|
|
101
|
+
outdated: Row[],
|
|
102
|
+
natives: Natives,
|
|
103
|
+
approved: boolean | undefined,
|
|
104
|
+
onProgress?: (event: UpdateProgressEvent) => void,
|
|
105
|
+
): Promise<UpdateAllResult> {
|
|
106
|
+
let changed = 0;
|
|
107
|
+
const failedNames: string[] = [];
|
|
108
|
+
for (let i = 0; i < outdated.length; i++) {
|
|
109
|
+
const row = outdated[i]!;
|
|
110
|
+
onProgress?.({ row, index: i, total: outdated.length, phase: "start" });
|
|
111
|
+
try {
|
|
112
|
+
const outcome = await natives.update(`npm:${row.name}`, approved);
|
|
113
|
+
if (outcome.reloadRequired) changed += 1;
|
|
114
|
+
} catch (e) {
|
|
115
|
+
failedNames.push(`${row.name}: ${e instanceof Error ? e.message : e}`);
|
|
116
|
+
}
|
|
117
|
+
onProgress?.({ row, index: i, total: outdated.length, phase: "done" });
|
|
118
|
+
}
|
|
119
|
+
return { changed, failedNames };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Approves once for the whole batch, runs it via whatever runBatch does
|
|
123
|
+
* (a floating overlay for applyUpdateAll's own public API, or renderPanel's
|
|
124
|
+
* embedded progress bar), then reports the combined result -- shared so
|
|
125
|
+
* both surfaces stay behaviorally identical. */
|
|
126
|
+
async function approveAndRunUpdateAll(
|
|
127
|
+
outdated: Row[],
|
|
128
|
+
natives: Natives,
|
|
129
|
+
ctx: ExtensionCommandContext,
|
|
130
|
+
runBatch: (outdated: Row[], approved: boolean | undefined) => Promise<UpdateAllResult>,
|
|
131
|
+
): Promise<PackageChoiceOutcome> {
|
|
132
|
+
if (outdated.length === 0) {
|
|
133
|
+
ctx.ui.notify("Nothing to update.", "info");
|
|
134
|
+
return "unchanged";
|
|
135
|
+
}
|
|
136
|
+
const approval = await approvePackageOperation(
|
|
137
|
+
"update",
|
|
138
|
+
`pi update --extension ${outdated.map((row) => `npm:${row.name}`).join(" ")}`,
|
|
139
|
+
natives,
|
|
140
|
+
ctx,
|
|
141
|
+
);
|
|
142
|
+
if (!approval.allowed) {
|
|
143
|
+
ctx.ui.notify(approval.message ?? "update denied", "warning");
|
|
144
|
+
return "cancelled";
|
|
145
|
+
}
|
|
146
|
+
const { changed, failedNames } = await runBatch(outdated, approval.approved);
|
|
147
|
+
for (const failure of failedNames) ctx.ui.notify(`update failed: ${failure}`, "error");
|
|
148
|
+
if (changed === 0) {
|
|
149
|
+
ctx.ui.notify(failedNames.length > 0 ? `No packages updated; ${failedNames.length} failed.` : "All packages already up to date.", failedNames.length > 0 ? "warning" : "info");
|
|
150
|
+
return failedNames.length > 0 ? "cancelled" : "unchanged";
|
|
151
|
+
}
|
|
152
|
+
ctx.ui.notify(`Updated ${changed} package(s)${failedNames.length > 0 ? `, ${failedNames.length} failed` : ""}; reloading Pi resources.`, "info");
|
|
153
|
+
await ctx.reload();
|
|
154
|
+
return "changed";
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Floats its own progress-bar overlay over the still-open panel -- kept
|
|
158
|
+
* for applyUpdateAll's own public API (and anything calling it directly,
|
|
159
|
+
* outside the packages panel). renderPanel's own U key does not use this;
|
|
160
|
+
* it renders the same progress bar inline on its own already-open overlay
|
|
161
|
+
* instead of stacking a second one. */
|
|
96
162
|
async function runUpdatesWithProgress(
|
|
97
163
|
outdated: Row[],
|
|
98
164
|
natives: Natives,
|
|
@@ -112,24 +178,11 @@ async function runUpdatesWithProgress(
|
|
|
112
178
|
container.addChild(new Spacer(1));
|
|
113
179
|
container.addChild(border());
|
|
114
180
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
bar.setLabel(`${row.name} (${i + 1}/${outdated.length})`);
|
|
121
|
-
tui.requestRender();
|
|
122
|
-
try {
|
|
123
|
-
const outcome = await natives.update(`npm:${row.name}`, approved);
|
|
124
|
-
if (outcome.reloadRequired) changed += 1;
|
|
125
|
-
} catch (e) {
|
|
126
|
-
failedNames.push(`${row.name}: ${e instanceof Error ? e.message : e}`);
|
|
127
|
-
}
|
|
128
|
-
bar.setValue(i + 1);
|
|
129
|
-
tui.requestRender();
|
|
130
|
-
}
|
|
131
|
-
done({ changed, failedNames });
|
|
132
|
-
})();
|
|
181
|
+
performUpdateAll(outdated, natives, approved, (event) => {
|
|
182
|
+
bar.setLabel(`${event.row.name} (${event.index + 1}/${event.total})`);
|
|
183
|
+
if (event.phase === "done") bar.setValue(event.index + 1);
|
|
184
|
+
tui.requestRender();
|
|
185
|
+
}).then(done);
|
|
133
186
|
|
|
134
187
|
return { render: (width: number) => container.render(width), invalidate: () => container.invalidate(), handleInput() {} };
|
|
135
188
|
},
|
|
@@ -139,32 +192,12 @@ async function runUpdatesWithProgress(
|
|
|
139
192
|
|
|
140
193
|
/** U -- update every outdated row with one combined approval and one
|
|
141
194
|
* reload, instead of applyPackageChoice's own per-call reload (which
|
|
142
|
-
* would end the session after the first successful update).
|
|
195
|
+
* would end the session after the first successful update). Public API:
|
|
196
|
+
* opens its own progress overlay. renderPanel's own U key instead renders
|
|
197
|
+
* progress inline via approveAndRunUpdateAll + performUpdateAll directly. */
|
|
143
198
|
export async function applyUpdateAll(rows: Row[], natives: Natives, ctx: ExtensionCommandContext): Promise<PackageChoiceOutcome> {
|
|
144
199
|
const outdated = rows.filter((row) => row.hasUpdate);
|
|
145
|
-
|
|
146
|
-
ctx.ui.notify("Nothing to update.", "info");
|
|
147
|
-
return "unchanged";
|
|
148
|
-
}
|
|
149
|
-
const approval = await approvePackageOperation(
|
|
150
|
-
"update",
|
|
151
|
-
`pi update --extension ${outdated.map((row) => `npm:${row.name}`).join(" ")}`,
|
|
152
|
-
natives,
|
|
153
|
-
ctx,
|
|
154
|
-
);
|
|
155
|
-
if (!approval.allowed) {
|
|
156
|
-
ctx.ui.notify(approval.message ?? "update denied", "warning");
|
|
157
|
-
return "cancelled";
|
|
158
|
-
}
|
|
159
|
-
const { changed, failedNames } = await runUpdatesWithProgress(outdated, natives, approval.approved, ctx);
|
|
160
|
-
for (const failure of failedNames) ctx.ui.notify(`update failed: ${failure}`, "error");
|
|
161
|
-
if (changed === 0) {
|
|
162
|
-
ctx.ui.notify(failedNames.length > 0 ? `No packages updated; ${failedNames.length} failed.` : "All packages already up to date.", failedNames.length > 0 ? "warning" : "info");
|
|
163
|
-
return failedNames.length > 0 ? "cancelled" : "unchanged";
|
|
164
|
-
}
|
|
165
|
-
ctx.ui.notify(`Updated ${changed} package(s)${failedNames.length > 0 ? `, ${failedNames.length} failed` : ""}; reloading Pi resources.`, "info");
|
|
166
|
-
await ctx.reload();
|
|
167
|
-
return "changed";
|
|
200
|
+
return approveAndRunUpdateAll(outdated, natives, ctx, (batch, approved) => runUpdatesWithProgress(batch, natives, approved, ctx));
|
|
168
201
|
}
|
|
169
202
|
|
|
170
203
|
/** d -- toggles every declared extension of this package on or off in one
|
|
@@ -248,8 +281,10 @@ export async function showPackedPanel(ctx: ExtensionCommandContext, natives: Nat
|
|
|
248
281
|
}
|
|
249
282
|
|
|
250
283
|
// Panel loop: actions resolve the component, run outside it, then reopen.
|
|
284
|
+
// U/updateAll is handled entirely inside renderPanel itself (progress
|
|
285
|
+
// rendered on the same already-open overlay) and never reaches here.
|
|
251
286
|
for (;;) {
|
|
252
|
-
const action = await renderPanel(ctx, rows);
|
|
287
|
+
const action = await renderPanel(ctx, natives, rows);
|
|
253
288
|
if (!action) return; // closed
|
|
254
289
|
|
|
255
290
|
if (action.type === "refresh") {
|
|
@@ -268,12 +303,6 @@ export async function showPackedPanel(ctx: ExtensionCommandContext, natives: Nat
|
|
|
268
303
|
continue; // a successful install already reloaded; a no-op returns here
|
|
269
304
|
}
|
|
270
305
|
|
|
271
|
-
if (action.type === "updateAll") {
|
|
272
|
-
const outcome = await applyUpdateAll(rows, natives, ctx);
|
|
273
|
-
if (outcome === "changed") return; // ctx.reload() already replaced the session
|
|
274
|
-
continue;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
306
|
if (action.type === "config") {
|
|
278
307
|
await showResourceConfig(ctx, natives, action.row?.name);
|
|
279
308
|
continue; // showResourceConfig already handles its own reload prompt
|
|
@@ -293,13 +322,19 @@ export async function showPackedPanel(ctx: ExtensionCommandContext, natives: Nat
|
|
|
293
322
|
}
|
|
294
323
|
}
|
|
295
324
|
|
|
296
|
-
function renderPanel(ctx: ExtensionCommandContext,
|
|
325
|
+
function renderPanel(ctx: ExtensionCommandContext, natives: Natives, initialRows: Row[]): Promise<PanelAction | undefined> {
|
|
297
326
|
return ctx.ui.custom<PanelAction | undefined>((tui, theme, _kb, done) => {
|
|
327
|
+
let rows = initialRows;
|
|
298
328
|
let mode: ViewMode = "all";
|
|
299
329
|
const searchInput = new Input();
|
|
300
330
|
let searchActive = false;
|
|
301
331
|
let filtered = visibleRows(rows, mode);
|
|
302
332
|
let selectedIndex = 0;
|
|
333
|
+
// Set only while U's batch update is running. The list stays fully
|
|
334
|
+
// visible throughout -- this just names which row the shared bar
|
|
335
|
+
// (below) is currently sitting next to.
|
|
336
|
+
let updatingRowName: string | undefined;
|
|
337
|
+
const updatingBar = new ProgressBar({ value: 0, max: 1, width: 10, style: (s) => theme.fg("accent", s) });
|
|
303
338
|
|
|
304
339
|
const maxVisible = 20;
|
|
305
340
|
|
|
@@ -308,12 +343,44 @@ function renderPanel(ctx: ExtensionCommandContext, rows: Row[]): Promise<PanelAc
|
|
|
308
343
|
selectedIndex = 0;
|
|
309
344
|
}
|
|
310
345
|
|
|
346
|
+
/** U -- runs the whole approve+update+notify+reload flow without ever
|
|
347
|
+
* closing this panel or replacing the list: each step's progress
|
|
348
|
+
* appears inline next to the row currently being updated, via
|
|
349
|
+
* updatingRowName/updatingBar, which list's own render checks. Rows
|
|
350
|
+
* refresh in place afterward unless a reload already ended the
|
|
351
|
+
* session. */
|
|
352
|
+
async function runUpdateAllInline(): Promise<void> {
|
|
353
|
+
const outdated = rows.filter((row) => row.hasUpdate);
|
|
354
|
+
const outcome = await approveAndRunUpdateAll(outdated, natives, ctx, (batch, approved) => {
|
|
355
|
+
updatingBar.setValue(0);
|
|
356
|
+
updatingBar.setMax(batch.length);
|
|
357
|
+
return performUpdateAll(batch, natives, approved, (event) => {
|
|
358
|
+
updatingRowName = event.row.name;
|
|
359
|
+
if (event.phase === "done") updatingBar.setValue(event.index + 1);
|
|
360
|
+
tui.requestRender();
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
updatingRowName = undefined;
|
|
364
|
+
if (outcome === "changed") {
|
|
365
|
+
done(undefined); // ctx.reload() already replaced the session
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const reloaded = await loadRows(natives);
|
|
369
|
+
if (reloaded.error) ctx.ui.notify(`refresh failed: ${reloaded.error}`, "error");
|
|
370
|
+
else rows = reloaded.rows;
|
|
371
|
+
applyFilter();
|
|
372
|
+
tui.requestRender();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function panelTitle(): string {
|
|
376
|
+
if (updatingRowName) return "Packages · updating…";
|
|
377
|
+
const outdated = rows.filter((r) => r.hasUpdate).length;
|
|
378
|
+
return outdated > 0 ? `Packages · ${outdated} update(s)` : "Packages";
|
|
379
|
+
}
|
|
380
|
+
|
|
311
381
|
const header = {
|
|
312
382
|
invalidate() {},
|
|
313
383
|
render(width: number): string[] {
|
|
314
|
-
const title = theme.bold("Packages");
|
|
315
|
-
const outdated = rows.filter((r) => r.hasUpdate).length;
|
|
316
|
-
const badge = outdated > 0 ? theme.fg("warning", ` ${outdated} update(s)`) : "";
|
|
317
384
|
const hint = searchActive
|
|
318
385
|
? rawKeyHint("esc", "clear")
|
|
319
386
|
: rawKeyHint("enter", "menu") +
|
|
@@ -331,8 +398,7 @@ function renderPanel(ctx: ExtensionCommandContext, rows: Row[]): Promise<PanelAc
|
|
|
331
398
|
rawKeyHint("s", "settings") +
|
|
332
399
|
theme.fg("muted", " · ") +
|
|
333
400
|
rawKeyHint("esc", "close");
|
|
334
|
-
const
|
|
335
|
-
const line1 = truncateToWidth(`${title}${badge}${" ".repeat(spacing)}${hint}`, width, "");
|
|
401
|
+
const line1 = truncateToWidth(hint, width, "");
|
|
336
402
|
const dot = "·";
|
|
337
403
|
const line2 = truncateToWidth(
|
|
338
404
|
theme.fg("muted", `view: ${mode} ${dot} / filter ${dot} tab view ${dot} r refresh ${dot} ${rows.length} installed`),
|
|
@@ -361,7 +427,10 @@ function renderPanel(ctx: ExtensionCommandContext, rows: Row[]): Promise<PanelAc
|
|
|
361
427
|
const cursor = selected ? theme.fg("accent", "❯") : " ";
|
|
362
428
|
const name = selected ? theme.bold(row.name) : row.name;
|
|
363
429
|
const ver = theme.fg("dim", `@${row.version}`);
|
|
364
|
-
const
|
|
430
|
+
const isUpdating = updatingRowName === row.name;
|
|
431
|
+
const upd = isUpdating
|
|
432
|
+
? theme.fg("accent", ` ${updatingBar.format(10)} updating…`)
|
|
433
|
+
: row.hasUpdate ? theme.fg("warning", ` ↑${row.latest}`) : "";
|
|
365
434
|
lines.push(truncateToWidth(`${cursor} ${name}${ver}${upd}`, width, ""));
|
|
366
435
|
}
|
|
367
436
|
const hasScroll = start > 0 || end < filtered.length;
|
|
@@ -370,21 +439,31 @@ function renderPanel(ctx: ExtensionCommandContext, rows: Row[]): Promise<PanelAc
|
|
|
370
439
|
},
|
|
371
440
|
};
|
|
372
441
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
442
|
+
// Real bordered box (rounded corners), not just a horizontal rule --
|
|
443
|
+
// title carries the live update badge/status instead of a header line.
|
|
444
|
+
const envelope = new Envelope({
|
|
445
|
+
title: panelTitle(),
|
|
446
|
+
borderStyle: "rounded",
|
|
447
|
+
style: (s) => theme.fg("border", s),
|
|
448
|
+
titleStyle: (s) => theme.bold(theme.fg("accent", s)),
|
|
449
|
+
});
|
|
450
|
+
const body = {
|
|
451
|
+
invalidate() { header.invalidate(); list.invalidate(); },
|
|
452
|
+
render(width: number): string[] {
|
|
453
|
+
return [...header.render(width), "", ...list.render(width)];
|
|
454
|
+
},
|
|
455
|
+
};
|
|
456
|
+
envelope.setContent(body);
|
|
383
457
|
|
|
384
458
|
return {
|
|
385
|
-
render
|
|
386
|
-
|
|
459
|
+
render(width: number): string[] {
|
|
460
|
+
envelope.setTitle(panelTitle());
|
|
461
|
+
return envelope.render(width);
|
|
462
|
+
},
|
|
463
|
+
invalidate: () => envelope.invalidate(),
|
|
387
464
|
handleInput(data: string) {
|
|
465
|
+
if (updatingRowName) return; // the installer owns input until it finishes
|
|
466
|
+
|
|
388
467
|
if (searchActive) {
|
|
389
468
|
if (data === "\x1b") {
|
|
390
469
|
searchActive = false;
|
|
@@ -424,7 +503,7 @@ function renderPanel(ctx: ExtensionCommandContext, rows: Row[]): Promise<PanelAc
|
|
|
424
503
|
done({ type: "find" });
|
|
425
504
|
return;
|
|
426
505
|
case "U":
|
|
427
|
-
|
|
506
|
+
void runUpdateAllInline();
|
|
428
507
|
return;
|
|
429
508
|
case "u": {
|
|
430
509
|
const row = filtered[selectedIndex];
|
|
@@ -467,5 +546,5 @@ function renderPanel(ctx: ExtensionCommandContext, rows: Row[]): Promise<PanelAc
|
|
|
467
546
|
tui.requestRender();
|
|
468
547
|
},
|
|
469
548
|
};
|
|
470
|
-
});
|
|
549
|
+
}, { overlay: true, overlayOptions: { width: "70%", maxHeight: "70%", anchor: "top-center", offsetY: 1 } });
|
|
471
550
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danypops/pi-packed",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Pi package tools, commands, profiles, and TUI for the Packed daemon",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": ["pi-package"],
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"@danypops/packed": "^0.2.0",
|
|
16
16
|
"@danypops/vehicle-client": "^0.1.1",
|
|
17
17
|
"@danypops/vehicle-client-pi": "^0.1.5",
|
|
18
|
-
"malevich-tui-components": "^0.
|
|
18
|
+
"malevich-tui-components": "^0.8.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"@earendil-works/pi-coding-agent": "*",
|