@danypops/pi-packed 0.16.0 → 0.16.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.
@@ -33,7 +33,12 @@
33
33
  * genuinely different overlay stacked on top -- confirmed live as a real
34
34
  * user complaint). Declining a reload defers it: the mutation itself
35
35
  * already happened, and the panel stays open with refreshed rows instead
36
- * of ending the session. All data flows through the packed CLI (thin seam).
36
+ * of ending the session. Every non-"changed" settle point (already up to
37
+ * date, pinned, deferred, a genuine failure) shows its own real reason on
38
+ * that row too via the same settled map U's batch path uses, not only as
39
+ * a scrollback toast -- confirmed live as a real bug: a single-row update
40
+ * that turned out to be a no-op gave zero acknowledgment on the panel
41
+ * itself. All data flows through the packed CLI (thin seam).
37
42
  */
38
43
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
39
44
  import { DynamicBorder, rawKeyHint } from "@earendil-works/pi-coding-agent";
@@ -63,11 +68,19 @@ interface PanelAction {
63
68
  * "unchanged"/"cancelled" mean the panel keeps running as-is. */
64
69
  export type PackageChoiceOutcome = "changed" | "unchanged" | "cancelled" | "deferred";
65
70
 
71
+ /** A non-"changed" settle point's own detail -- the exact reason nothing
72
+ * (or only a partial thing) happened, so a caller with somewhere to show
73
+ * it inline (a row's own status cell) isn't limited to the scrollback
74
+ * toast every outcome already gets via ctx.ui.notify. "changed" never
75
+ * calls this: ctx.reload() already replaces the session by then. */
76
+ export interface PackageChoiceSettled { ok: boolean; message: string; }
77
+
66
78
  export async function applyPackageChoice(
67
79
  choice: string | undefined,
68
80
  row: Row,
69
81
  natives: Natives,
70
82
  ctx: ExtensionCommandContext,
83
+ onSettled?: (settled: PackageChoiceSettled) => void,
71
84
  ): Promise<PackageChoiceOutcome> {
72
85
  if (choice?.startsWith("Update")) {
73
86
  try {
@@ -84,18 +97,22 @@ export async function applyPackageChoice(
84
97
  ? `pinned to ${version ?? "an exact version"} -- pi update intentionally leaves pinned packages unchanged`
85
98
  : `already up to date${version ? ` at ${version}` : ""}`;
86
99
  ctx.ui.notify(`${row.name} is ${reason}.`, "info");
100
+ onSettled?.({ ok: true, message: reason });
87
101
  return "unchanged";
88
102
  }
89
103
  const transition = outcome.previousVersion && outcome.currentVersion ? ` (${outcome.previousVersion} → ${outcome.currentVersion})` : "";
90
104
  if (!(await confirmReload(ctx))) {
91
105
  ctx.ui.notify(`Updated ${row.name}${transition}; reload pending -- run /reload when ready.`, "warning");
106
+ onSettled?.({ ok: true, message: `updated${transition}; reload pending` });
92
107
  return "deferred";
93
108
  }
94
109
  ctx.ui.notify(`Updated ${row.name}${transition}; reloading Pi resources.`, "info");
95
110
  await ctx.reload();
96
111
  return "changed";
97
112
  } catch (e) {
98
- ctx.ui.notify(`update failed: ${e instanceof Error ? e.message : e}`, "error");
113
+ const message = e instanceof Error ? e.message : String(e);
114
+ ctx.ui.notify(`update failed: ${message}`, "error");
115
+ onSettled?.({ ok: false, message });
99
116
  return "cancelled";
100
117
  }
101
118
  }
@@ -109,13 +126,16 @@ export async function applyPackageChoice(
109
126
  await natives.remove(row.name, approval.approved);
110
127
  if (!(await confirmReload(ctx))) {
111
128
  ctx.ui.notify(`Removed ${row.name}; reload pending -- run /reload when ready.`, "warning");
129
+ onSettled?.({ ok: true, message: "removed; reload pending" });
112
130
  return "deferred";
113
131
  }
114
132
  ctx.ui.notify(`Removed ${row.name}; reloading Pi resources.`, "info");
115
133
  await ctx.reload();
116
134
  return "changed";
117
135
  } catch (e) {
118
- ctx.ui.notify(`remove failed: ${e instanceof Error ? e.message : e}`, "error");
136
+ const message = e instanceof Error ? e.message : String(e);
137
+ ctx.ui.notify(`remove failed: ${message}`, "error");
138
+ onSettled?.({ ok: false, message });
119
139
  return "cancelled";
120
140
  }
121
141
  }
@@ -463,9 +483,15 @@ function renderPanel(ctx: ExtensionCommandContext, natives: Natives, initialRows
463
483
  async function runRowActionInline(action: { type: "update" | "remove" | "disable"; row: Row }): Promise<void> {
464
484
  updatingRowName = action.row.name;
465
485
  tui.requestRender();
486
+ // A non-"changed" settle point (already up to date, pinned, deferred,
487
+ // a genuine failure) shows its own real reason on this row, the same
488
+ // settled map U's batch path already renders -- not just a scrollback
489
+ // toast, which was the whole bug: nothing on the panel itself ever
490
+ // acknowledged that a single-row action had even run.
491
+ const onSettled = (result: PackageChoiceSettled) => settled.set(action.row.name, { ok: result.ok, tail: result.message });
466
492
  const outcome = action.type === "disable"
467
493
  ? await applyDisableExtensions(action.row, natives, inlineCtx)
468
- : await applyPackageChoice(action.type === "update" ? `Update to ${action.row.latest}` : "Remove", action.row, natives, inlineCtx);
494
+ : await applyPackageChoice(action.type === "update" ? `Update to ${action.row.latest}` : "Remove", action.row, natives, inlineCtx, onSettled);
469
495
  updatingRowName = undefined;
470
496
  if (outcome === "changed") {
471
497
  done(undefined); // ctx.reload() already replaced the session
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danypops/pi-packed",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "Pi package tools, commands, profiles, and TUI for the Packed daemon",
5
5
  "type": "module",
6
6
  "keywords": ["pi-package"],