pi-chrome 0.15.5 → 0.15.7

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 CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable user-facing changes to `pi-chrome`.
4
4
 
5
+ ## 0.15.7 — 2026-05-14
6
+
7
+ - **Grouped `/chrome` menu.** Bare `/chrome` now opens a status dashboard with grouped actions: authorize, lock, status, doctor, background/watch mode, and onboard. Authorize/background open submenus instead of showing one flat command list.
8
+
9
+ ## 0.15.6 — 2026-05-14
10
+
11
+ - **Bare `/chrome` is now a command menu.** Running `/chrome` shows interactive options for every `/chrome ...` command, including authorize/revoke/status/doctor/onboard/background variants.
12
+
5
13
  ## 0.15.5 — 2026-05-14
6
14
 
7
15
  - **Chrome control authorization.** `chrome_*` tools are locked until the user runs `/chrome authorize` in the current Pi session. Grants can be one command, 15 minutes, 1 hour, or the session; `/chrome revoke` locks control again and `/chrome status` shows auth state.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Pi Chrome Connector",
4
- "version": "0.15.5",
4
+ "version": "0.15.7",
5
5
  "description": "Lets Pi control tabs in Chrome via a local connector at 127.0.0.1.",
6
6
  "permissions": [
7
7
  "tabs",
@@ -1,6 +1,4 @@
1
1
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
3
- import { Container, type SettingItem, SettingsList, Text } from "@earendil-works/pi-tui";
4
2
  import { Type } from "typebox";
5
3
  import { existsSync, readFileSync, statSync } from "node:fs";
6
4
  import { mkdir, writeFile } from "node:fs/promises";
@@ -702,47 +700,58 @@ Usage rules:
702
700
  ctx.ui.notify(await statusSummary(), "info");
703
701
  };
704
702
 
705
- // Interactive dialog: each row is a setting whose value cycles with Space/Enter. Enter on
706
- // the last value also saves; Esc / 'q' closes. The description below changes with the
707
- // current value so users always see what the active setting means.
708
- const openSettingsDialog = async (ctx: ExtensionContext): Promise<void> => {
709
- const backgroundItem: SettingItem = {
710
- id: "background",
711
- label: "Run in background",
712
- currentValue: backgroundDefault ? "on" : "off",
713
- values: ["on", "off"],
714
- description: BACKGROUND_DESC[backgroundDefault ? "on" : "off"] ?? "",
715
- };
716
- const items: SettingItem[] = [backgroundItem];
717
-
718
- await ctx.ui.custom<void>((_tui, theme, _kb, done) => {
719
- const container = new Container();
720
- container.addChild(new Text(theme.fg("accent", theme.bold("pi-chrome settings")), 1, 1));
721
- container.addChild(new Text(theme.fg("muted", "\u2191\u2193 navigate · space/enter cycle · esc close"), 1, 0));
722
-
723
- let list: SettingsList;
724
- list = new SettingsList(
725
- items,
726
- Math.min(items.length + 2, 8),
727
- getSettingsListTheme(),
728
- (id, newValue) => {
729
- if (id === "background") {
730
- backgroundDefault = newValue === "on";
731
- backgroundItem.currentValue = newValue;
732
- backgroundItem.description = BACKGROUND_DESC[newValue] ?? "";
733
- list.invalidate();
734
- }
735
- },
736
- () => done(undefined),
737
- );
738
- container.addChild(list);
703
+ const openAuthorizeMenu = async (ctx: ExtensionContext): Promise<void> => {
704
+ const choice = await ctx.ui.select("Authorize Chrome control", [
705
+ "This Pi session",
706
+ "15 minutes",
707
+ "1 hour",
708
+ "One Chrome command",
709
+ "Auth status",
710
+ ]);
711
+ if (!choice) return;
712
+ switch (choice) {
713
+ case "This Pi session": return authorizeHandler(ctx, "session");
714
+ case "15 minutes": return authorizeHandler(ctx, "15m");
715
+ case "1 hour": return authorizeHandler(ctx, "1h");
716
+ case "One Chrome command": return authorizeHandler(ctx, "once");
717
+ case "Auth status": return authorizeHandler(ctx, "status");
718
+ }
719
+ };
739
720
 
740
- return {
741
- render: (w) => container.render(w),
742
- invalidate: () => container.invalidate(),
743
- handleInput: (data: string) => list.handleInput(data),
744
- };
745
- });
721
+ const openBackgroundMenu = async (ctx: ExtensionContext): Promise<void> => {
722
+ const choice = await ctx.ui.select("Background / watch mode", [
723
+ "Toggle background mode",
724
+ "Run in background",
725
+ "Bring Chrome forward",
726
+ "Background status",
727
+ ]);
728
+ if (!choice) return;
729
+ switch (choice) {
730
+ case "Toggle background mode": return backgroundHandler(ctx, "toggle");
731
+ case "Run in background": return backgroundHandler(ctx, "on");
732
+ case "Bring Chrome forward": return backgroundHandler(ctx, "off");
733
+ case "Background status": return backgroundHandler(ctx, "status");
734
+ }
735
+ };
736
+
737
+ const openCommandMenu = async (ctx: ExtensionContext): Promise<void> => {
738
+ const choice = await ctx.ui.select(`pi-chrome\n${await statusSummary()}`, [
739
+ "Authorize Chrome control…",
740
+ "Lock Chrome control",
741
+ "Connection status",
742
+ "Doctor / troubleshoot",
743
+ "Background / watch mode…",
744
+ "Install / onboard extension",
745
+ ]);
746
+ if (!choice) return;
747
+ switch (choice) {
748
+ case "Authorize Chrome control…": return openAuthorizeMenu(ctx);
749
+ case "Lock Chrome control": return revokeHandler(ctx);
750
+ case "Connection status": return statusHandler(ctx);
751
+ case "Doctor / troubleshoot": return doctorHandler(ctx);
752
+ case "Background / watch mode…": return openBackgroundMenu(ctx);
753
+ case "Install / onboard extension": return onboardHandler(ctx);
754
+ }
746
755
  };
747
756
 
748
757
  pi.registerCommand("chrome", {
@@ -795,7 +804,7 @@ Usage rules:
795
804
  handler: async (args, ctx) => {
796
805
  const tokens = (args || "").trim().split(/\s+/).filter(Boolean);
797
806
  if (tokens.length === 0) {
798
- await openSettingsDialog(ctx);
807
+ await openCommandMenu(ctx);
799
808
  return;
800
809
  }
801
810
  const [head, ...rest] = tokens;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-chrome",
3
- "version": "0.15.5",
3
+ "version": "0.15.7",
4
4
  "scripts": {
5
5
  "version": "node scripts/sync-manifest-version.js",
6
6
  "prepublishOnly": "node scripts/sync-manifest-version.js"