pi-goal 0.1.1 → 0.1.2

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.
@@ -21,6 +21,7 @@ type GoalState = {
21
21
  type GoalEventKind = "active" | "continuation" | "paused" | "resumed" | "cleared" | "budget_limited" | "complete";
22
22
 
23
23
  let goal: GoalState | null = null;
24
+ let statusBarEnabled = true;
24
25
  let activeTurnStartedAt: number | null = null;
25
26
  let continuationQueued = false;
26
27
  let pendingControlPrompt: string | null = null;
@@ -118,22 +119,33 @@ function emitGoalEvent(
118
119
  );
119
120
  }
120
121
 
121
- function latestGoalFromSession(ctx: ExtensionContext): GoalState | null {
122
+ function latestStateFromSession(ctx: ExtensionContext): { goal: GoalState | null; statusBarEnabled: boolean } {
122
123
  const entries = ctx.sessionManager.getBranch?.() ?? ctx.sessionManager.getEntries();
123
124
  for (let i = entries.length - 1; i >= 0; i--) {
124
125
  const entry = entries[i] as any;
125
126
  if (entry.type === "custom" && entry.customType === CUSTOM_TYPE) {
126
- return entry.data?.goal ?? null;
127
+ return {
128
+ goal: entry.data?.goal ?? null,
129
+ statusBarEnabled: entry.data?.statusBarEnabled ?? true,
130
+ };
127
131
  }
128
132
  }
129
- return null;
133
+ return { goal: null, statusBarEnabled: true };
134
+ }
135
+
136
+ function updateStatusBar(ctx: ExtensionContext) {
137
+ ctx.ui.setStatus(CUSTOM_TYPE, statusBarEnabled ? statusLine(goal) ?? "" : "");
130
138
  }
131
139
 
132
140
  function persist(pi: ExtensionAPI, ctx: ExtensionContext, next: GoalState | null) {
133
141
  goal = next;
134
- pi.appendEntry(CUSTOM_TYPE, { goal: next });
135
- const line = statusLine(next);
136
- ctx.ui.setStatus(CUSTOM_TYPE, line ?? "");
142
+ pi.appendEntry(CUSTOM_TYPE, { goal: next, statusBarEnabled });
143
+ updateStatusBar(ctx);
144
+ }
145
+
146
+ function persistSettings(pi: ExtensionAPI, ctx: ExtensionContext) {
147
+ pi.appendEntry(CUSTOM_TYPE, { goal, statusBarEnabled });
148
+ updateStatusBar(ctx);
137
149
  }
138
150
 
139
151
  function continuationPrompt(state: GoalState): string {
@@ -286,9 +298,9 @@ export default function piGoal(pi: ExtensionAPI) {
286
298
  });
287
299
 
288
300
  pi.registerCommand("goal", {
289
- description: "Set, view, pause, resume, or clear a long-running goal",
301
+ description: "Set, view, pause, resume, clear, or configure a long-running goal",
290
302
  getArgumentCompletions: (prefix) => {
291
- const values = ["pause", "resume", "clear", "status"];
303
+ const values = ["pause", "resume", "clear", "status", "statusbar", "statusbar on", "statusbar off"];
292
304
  const filtered = values.filter((value) => value.startsWith(prefix));
293
305
  return filtered.length ? filtered.map((value) => ({ value, label: value })) : null;
294
306
  },
@@ -298,7 +310,15 @@ export default function piGoal(pi: ExtensionAPI) {
298
310
 
299
311
  if (!trimmed || trimmed === "status") {
300
312
  if (!goal) ctx.ui.notify("Usage: /goal [--tokens 50k] <objective>", "info");
301
- else ctx.ui.notify(`${statusLine(goal)}\nObjective: ${goal.objective}`, "info");
313
+ else ctx.ui.notify(`${statusLine(goal)}\nObjective: ${goal.objective}\nStatus bar: ${statusBarEnabled ? "on" : "off"}`, "info");
314
+ return;
315
+ }
316
+
317
+ if (trimmed === "statusbar" || trimmed === "statusbar toggle" || trimmed === "statusbar on" || trimmed === "statusbar off") {
318
+ const [, value] = trimmed.split(/\s+/, 2);
319
+ statusBarEnabled = value === "on" ? true : value === "off" ? false : !statusBarEnabled;
320
+ persistSettings(pi, ctx);
321
+ ctx.ui.notify(`Goal status bar ${statusBarEnabled ? "enabled" : "disabled"}.`, "info");
302
322
  return;
303
323
  }
304
324
 
@@ -357,7 +377,9 @@ export default function piGoal(pi: ExtensionAPI) {
357
377
  });
358
378
 
359
379
  pi.on("session_start", (event, ctx) => {
360
- goal = latestGoalFromSession(ctx);
380
+ const restored = latestStateFromSession(ctx);
381
+ goal = restored.goal;
382
+ statusBarEnabled = restored.statusBarEnabled;
361
383
  pendingControlPrompt = null;
362
384
  continuationQueued = false;
363
385
  activeTurnStartedAt = null;
@@ -372,7 +394,7 @@ export default function piGoal(pi: ExtensionAPI) {
372
394
  );
373
395
  return;
374
396
  }
375
- ctx.ui.setStatus(CUSTOM_TYPE, statusLine(goal) ?? "");
397
+ updateStatusBar(ctx);
376
398
  if (goal?.status === "active") {
377
399
  emitGoalEvent(
378
400
  pi,
package/README.md CHANGED
@@ -25,6 +25,7 @@ pi install git:github.com/Michaelliv/pi-goal
25
25
  /goal pause
26
26
  /goal resume
27
27
  /goal clear
28
+ /goal statusbar off
28
29
  ```
29
30
 
30
31
  When a goal is active, the extension shows compact visible lifecycle markers like `Goal active` and `Goal continuing`; expand them with `ctrl+o` to inspect the objective and usage. The actual continuation instructions are injected into the next turn's system prompt, so the full prompt does not clutter the transcript.
@@ -38,6 +39,7 @@ The same Pi agent keeps running normal turns in the same session context until i
38
39
  - `/goal pause`: stop autonomous continuation without deleting the goal
39
40
  - `/goal resume`: reactivate a paused goal
40
41
  - `/goal clear`: remove the goal
42
+ - `/goal statusbar on|off`: show or hide the footer status line
41
43
  - `get_goal` tool: read current goal state
42
44
  - `update_goal` tool: model can only mark the goal `complete`
43
45
  - footer status: `Pursuing goal`, `Goal paused`, `Goal achieved`, or `Goal unmet`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Persistent autonomous goals for pi — /goal loops until complete, paused, or budget-limited",
5
5
  "type": "commonjs",
6
6
  "keywords": [