aboutsummaryrefslogtreecommitdiff
path: root/src/state.ts
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmal.com>2026-04-29 00:40:36 +0530
committeramankumarsingh77 <amankumarsingh7702@gmal.com>2026-04-29 00:40:36 +0530
commit8fff91522918a8309dea2e9fa725e15f6ed1c3ea (patch)
treea2f5fb863fd6ac260a3f37e4ed308d0c6df0a9ed /src/state.ts
Initial release: pi-browser-harness
Browser control extension for pi — 20 browser_* tools for navigating, clicking, typing, screenshotting, and extracting data from real Chrome via CDP. Includes self-extending harness (register_tool/remove_tool), guided /browser-setup, session persistence, and custom TUI renderers.
Diffstat (limited to 'src/state.ts')
-rw-r--r--src/state.ts77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/state.ts b/src/state.ts
new file mode 100644
index 0000000..9423309
--- /dev/null
+++ b/src/state.ts
@@ -0,0 +1,77 @@
+/**
+ * Session persistence for pi-browser-harness.
+ *
+ * Persists daemon namespace, tab history, and preferences across
+ * session reloads and branch navigation.
+ */
+
+import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
+
+// ── Types ────────────────────────────────────────────────────────────────────
+
+export interface BrowserState {
+ /** Daemon namespace (BU_NAME) for this session */
+ namespace: string;
+ /** Recently active tab target IDs */
+ tabHistory: string[];
+ /** Cloud browser ID (for remote sessions) */
+ remoteBrowserId?: string;
+ /** Screenshot output directory */
+ screenshotDir: string;
+ /** Whether debug click overlay is enabled */
+ debugClicks: boolean;
+}
+
+// ── Defaults ─────────────────────────────────────────────────────────────────
+
+export function defaultState(namespace = "default"): BrowserState {
+ return {
+ namespace,
+ tabHistory: [],
+ screenshotDir: "",
+ debugClicks: false,
+ };
+}
+
+// ── Persist ──────────────────────────────────────────────────────────────────
+
+export function persistState(pi: ExtensionAPI, state: BrowserState): void {
+ pi.appendEntry<BrowserState>("browser-harness-state", state);
+}
+
+// ── Restore ──────────────────────────────────────────────────────────────────
+
+/**
+ * Find the last browser-harness-state entry in the current branch
+ * and return the restored state, merged with defaults.
+ */
+export function restoreState(ctx: ExtensionContext, currentNamespace?: string): BrowserState {
+ const branchEntries = ctx.sessionManager.getBranch();
+ const defaults = defaultState(currentNamespace);
+
+ // Walk branch from newest to oldest to find last persisted state
+ for (let i = branchEntries.length - 1; i >= 0; i--) {
+ const entry = branchEntries[i];
+ if (entry.type === "custom" && entry.customType === "browser-harness-state") {
+ const data = entry.data as Partial<BrowserState> | undefined;
+ if (data) {
+ // Merge persisted data onto defaults, but always keep the current
+ // namespace (which comes from the --browser-namespace flag or auto-gen).
+ return { ...defaults, ...data, namespace: currentNamespace || data.namespace || defaults.namespace };
+ }
+ }
+ }
+
+ return defaults;
+}
+
+// ── Merge helpers ────────────────────────────────────────────────────────────
+
+export function addToTabHistory(state: BrowserState, targetId: string): BrowserState {
+ const filtered = state.tabHistory.filter((id) => id !== targetId);
+ return { ...state, tabHistory: [targetId, ...filtered].slice(0, 20) };
+}
+
+export function setRemoteBrowser(state: BrowserState, browserId: string): BrowserState {
+ return { ...state, remoteBrowserId: browserId };
+}