How to Use Pinodock: The Complete Guide


Pinodock replaces your new tab with a command center: live data widgets, a keyboard-first launcher, snippets, automations, user scripts, and a local AI assistant — all running on your device with no cloud required. This guide covers every feature from first launch to advanced custom code.

Contributor build order: Build the free browser experience first (new tab, palette, widgets, snippets, plugins), then shared packages, then desktop, then billing and enterprise. That ordering keeps the architecture clean and prevents cloud or identity work leaking into Phase 1.

1. First launch and initial setup

After installing from the Chrome Web Store, open a new tab. The first-run overlay asks for three things: your name (shown in the greeting), your home city for the weather widget, and whether you want analytics. All three are optional and all three can be changed later in Settings.

Settings are in the gear icon on the top-right of the new tab. Everything persists in chrome.storage.sync — your settings follow you across Chrome profiles automatically.

Privacy note: Every setting, snippet, script, and AI profile is stored locally in your browser. Nothing is uploaded to PencilCard servers. The only data that leaves your device is your email address and subscription status, used for authentication.

2. Appearance — themes, widget styles, and typography

Open Settings → Appearance to personalise how Pinodock looks. All options apply instantly — no refresh needed.

Theme presets

Eight named colour themes replace the old dark / light toggle. Pick one from the visual grid; each shows a swatch and name.

PresetCharacterBest for
Warm DarkCharcoal background, terracotta accentDefault — comfortable for long sessions
LightOff-white background, same terracotta accentBright offices, print-friendly screenshots
MidnightNear-black, GitHub-blue accentDevelopers, dark-room environments
ForestDark green, fresh-green accentNature lovers, low-fatigue reading
OceanDeep teal, sky-blue accentWriters, calm focus environments
RoseDark burgundy, pink accentCreative work, evening sessions
SlateCool grey light, indigo accentPresentations, light-mode alternative
SandWarm beige light, bronze accentWarm light-mode, analog feel

The accent colour picker below the theme grid lets you override the preset accent with any hex value. The first dot in the accent picker resets the accent to the preset default.

Widget style

Four widget surface styles control how plugin widgets look on your dashboard:

StyleAppearanceUse it when
CardSurface background, subtle border, soft shadowDefault — works with all themes
FlatTransparent — no border or shadowClean, minimal look; works well on solid colour backgrounds
BorderedSemi-transparent fill with a 1 px border, no shadowStructured look that still shows the background through
GlassFrosted-glass blur, translucent fill, soft borderPhoto or gradient backgrounds; high-contrast photos work best

Font family

Choose the typeface used across the entire dashboard. The setting writes a --font-family CSS variable that all components inherit.

OptionWhat loads
SystemOS default — San Francisco on Mac, Segoe UI on Windows. Zero load time.
InterInter variable — the most legible screen font for dense data dashboards.
MonoJetBrains Mono (or Fira Code / Cascadia Code as fallbacks). Best for Dev dashboards.
SerifGeorgia. Warmer and more editorial — pairs well with the Sand or Light theme.

4. Widget builder — build your own widget

The widget builder is a three-step wizard that lets you turn any JSON API, relay function, or open browser tab into a live dashboard widget — no code required.

Open it from Dashboard → Customize → Build widget.

Step 1: Choose a widget type

Pick the visual layout that matches your data. Twelve types are available:

TypeBest for
Metric cardA single number — revenue, error rate, build time. Colour-codes at warn/danger thresholds.
Status cardA coloured badge showing an operational state (OK / Warn / Error).
ListAn ordered list of items from an API array — HN stories, open PRs, recent deploys.
TableTwo-column label / value pairs — ideal for weather, system stats, or key-value configs.
SparklineMini line chart from a numeric array — price history, request counts, memory usage.
Progress ringCircular progress from a current / max ratio — storage used, sprint completion, quota.
CountdownTime remaining until a date you set — launch day, sprint deadline, subscription renewal.
AgendaTimeline of upcoming events from an API array — calendar events, release milestones.
Image cardStatic image with title and caption — team photo, architecture diagram, marketing asset.
QuoteStatic or API-sourced text block — team motto, rotating tip, daily affirmation.
Calendar strip7-day rolling mini calendar with optional event dots from Google Calendar.
Text blockFree-form text note stored locally — pinned reminder, on-call notes.

Step 2: Name, icon, and data source

Give the widget a name, emoji icon, and accent colour. Then choose where data comes from:

  • Static — no fetch; you type the content directly (used for Quote, Text block, Countdown, Image).
  • API fetch — GET any CORS-enabled JSON endpoint from your browser.
  • Relay — POST to your own serverless function; credentials stay server-side.
  • Scrape tab — read text from an open browser tab via a CSS selector (internal tools, Retool, legacy dashboards).
Countdown, Image, Quote, and Text block skip directly to step 2 with the "Static" source pre-selected — no field mapping needed.

Step 3: Map fields

For API fetch and relay modes, map JSON response fields to the widget's display slots. Each field needs a label, a dot-notation path (e.g. bitcoin.usd or [0].title), and an optional transform:

TransformEffect
numberFormats with locale thousands separators
currencyPrepends $ and 2 decimal places
percentAppends % and 1 decimal place
dateConverts ISO/Unix timestamp to locale date string
truncateClips text to 60 characters
uppercase / lowercaseCase transforms

For metric cards, you can also set warn and danger thresholds per field — the value text colour turns amber or red when crossed.

5. Widget Store — community and official widgets

The Widget Store is a curated registry of ready-made widgets you can install in one click. Open it from Dashboard → Customize → Widget Store.

Official widgets from PencilCard are bundled in the extension and available offline. The live registry at pencilcard.com/pinodock-widgets.json is fetched in the background; if you're offline the bundled set is used automatically.

Official starter widgets

WidgetTypeData source
Bitcoin PriceMetric cardCoinGecko API (free, no key)
Hacker News Top 5ListHN Firebase API (free, no key)
GitHub Open PRsMetric cardGitHub REST API (needs token)
PagerDuty IncidentsStatus cardYour relay function (credentials server-side)
Stripe MRRMetric cardYour relay function (credentials server-side)
OpenWeatherMapTableOpenWeatherMap API (free key)
Launch CountdownCountdownStatic — edit the target date after installing

Clicking Install saves the widget definition locally and adds it to the current dashboard. If the widget requires a URL, API key, or relay endpoint, the widget card will prompt you to fill those in after install.

Publishing a widget

Any widget you build in the widget builder can be exported as a JSON definition. Submit it to pencilcard.com/pinodock-widgets and — after review — it will appear in the store for everyone to install. No code review required; the format is the same JSON Pinodock already uses internally.

6. Dashboards — your multiple workspaces

A dashboard is a named configuration of widgets and plugins. You can have as many as you want. Each one stores independently: which plugins are on, which widgets are visible, and which layout template is active.

Pinodock ships with four preset dashboards to get you started:

DashboardDefault pluginsLayout
Work 💼Google Calendar, Gmail, GitHub, TodoistTwo-col
Creator 🎬YouTube Studio, Spotify, RedditMasonry-left
Dev ⌨️GitHub, Hacker News, AWS, CryptoThree-col
Personal 🌿Spotify, Crypto, RedditHero-top

To create a custom dashboard: open the Dashboard panel (bottom of the settings sidebar), click + New Dashboard, give it a name and an emoji. You'll get a blank canvas. Add plugins from the Plugins tab, choose a layout, and toggle which widgets appear on that dashboard.

Layout templates

Eight layout options control how plugins are distributed across the grid:

  • Single — one full-width column
  • Two-col — equal side-by-side columns
  • Three-col — three equal columns
  • Hero-top — first plugin spans full width, rest split below
  • Wide-left / Wide-right — 2:1 split favouring one side
  • Tall-left / Tall-right — one plugin spans two rows on the dominant side

7. Built-in widgets

Widgets are the static components that appear alongside your plugin data. Each widget can be shown or hidden per-dashboard, and the order is fully draggable in Settings → Widgets.

WidgetWhat it doesConfig
ClockAlways visible in the header12h/24h, seconds on/off, digital/analog style
QuoteDaily motivational quoteShow/hide
Quick LinksPinned URLs as clickable chipsAdd/remove/reorder links
Scratch PadEphemeral text note, persists in storageShow/hide
Pomodoro25/5 focus timerWork and break durations, session log
Ambient SoundBackground audio while workingOff / Rain / Focus
WeatherCurrent conditions for your cityCity name, show/hide

8. Backgrounds — nine source types

Open Settings → Appearance → Background to choose your source. All nine modes are free:

ModeHow it worksConfig needed
CuratedPinodock's built-in photo library. Click the refresh button on the new tab to cycle to the next one.None
DailyA new random photo each day. Same image across all tabs until midnight.None
UnsplashRandom photo from Unsplash by topic, refreshed on each new tab open.Your Unsplash API key + topic
GiphyAnimated GIF background matched to a tag.Your Giphy API key + tag
GradientCSS gradient between two colors at a custom angle.Start color, end color, angle
Solid colorFlat background color.Hex color
Custom URLAny HTTPS image URL.The URL
Local fileUpload an image from your device, stored locally in the extension.File upload
FolderRotate through a set of local images. Click refresh to advance to the next one.Multiple file uploads

9. The command palette (⌘K)

Press ⌘K (Mac) or Ctrl K (Windows/Linux) anywhere on your new tab to open the command palette. It searches across:

  • Open browser tabs (purple badge)
  • Bookmarks (blue badge)
  • Recent history (grey badge)
  • Your snippets (teal badge)
  • Your URL aliases (orange badge)
  • Script commands triggered with ! prefix (yellow badge)
  • Built-in actions: new tab, close tab, go back, go forward, zoom controls

The palette also runs on active tabs. Press ⌘⇧K on any page to open the Quick Palette overlay — you get the full command set without navigating back to your new tab.

Search tip: The palette uses fuzzy matching. Typing ghp will surface a bookmark titled "GitHub Pull Requests". You don't need to type the full title.

7. Snippets and URL aliases

Text snippets FREE

Go to Settings → Snippets → Add Snippet. Each snippet has a title (what you search for) and content (what gets copied to your clipboard when you pick it). Selecting a snippet in the palette instantly copies the content — press ⌘V to paste it wherever you need it.

Practical snippet setups:

// Snippet: "meet-zoom" → content:
https://zoom.us/j/YOUR_MEETING_ID?pwd=YOUR_PASSWORD

// Snippet: "sig-email" → content:
Best regards,
Sarah Chen
Senior Engineer · Acme Corp
sarah@acme.com · +1 (555) 000-1234

// Snippet: "pr-template" → content:
## What this PR does


## Test plan
- [ ] Unit tests pass
- [ ] Tested on staging
- [ ] No breaking changes to public API

## Related issues
Closes #

// Snippet: "sql-explain" → content:
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM 

URL aliases FREE

Go to Settings → Aliases → Add Alias. Set a short prefix and the full URL. Type the prefix in ⌘K and press Enter to navigate directly.

// Developer shortcuts
gh      https://github.com/YOUR_ORG
prs     https://github.com/YOUR_ORG/YOUR_REPO/pulls
li      https://linear.app/YOUR_WORKSPACE
fig     https://www.figma.com/files/YOUR_TEAM

// Environments
prd     https://app.yourproduct.com
stg     https://staging.yourproduct.com
log     https://us-east1.console.cloud.google.com/logs

// Daily tools
cal     https://calendar.google.com
mail    https://mail.google.com
doc     https://www.notion.so/YOUR_WORKSPACE

8. Built-in plugins FREE

Enable plugins per-dashboard from the Plugins tab in Settings. Built-in plugins fall into two categories: public (no auth needed) and connected (reads data from an open browser tab).

PluginTypeWhat it shows
Hacker NewsPublicTop 5 stories from the HN front page
Crypto PricesPublicBTC, ETH, SOL price + 7-day sparkline
Reddit FeedPublicTop posts from any subreddit (configurable)
GitHubConnected (github.com tab)Open notification count + username
GmailConnected (mail.google.com tab)Unread count + latest 5 subjects
Google CalendarConnected (calendar.google.com tab)Today's upcoming events
SpotifyConnected (open.spotify.com tab)Now playing track, artist, play state
YouTube StudioConnected (studio.youtube.com tab)Recent video views and subscriber count
AWS ConsoleConnected (console.aws.amazon.com tab)Current month cost + active region
TodoistConnected (app.todoist.com tab)Today's task list

Connected plugins require the target site to be open in a tab. When Pinodock finds it, it injects a small read-only script to extract the data. No credentials are stored — Pinodock reads from the session your browser already has.

9. Custom plugins PRO

Go to Settings → Plugins → Custom → Add Plugin. Three fetch modes cover virtually any data source.

Fetch mode — public JSON APIs

Makes a direct GET request from your browser. Works with any API that supports CORS. Here are three complete plugin configs you can enter directly into the settings form:

// ── Plugin: GitHub open PRs ───────────────────────────────
Name:     Open PRs
Icon:     🐙   Color:  #24292e
Mode:     fetch
URL:      https://api.github.com/repos/YOUR_ORG/YOUR_REPO/pulls?state=open&per_page=100
Headers:  {"Authorization": "Bearer ghp_YOUR_TOKEN", "X-GitHub-Api-Version": "2022-11-28"}
Template: stat
Fields:
   Label: "Open PRs"  Path: "length"  Transform: number
    Threshold: warnAbove=5  dangerAbove=10

// ── Plugin: Bitcoin price ─────────────────────────────────
Name:     Bitcoin
Icon:         Color:  #f7931a
Mode:     fetch
URL:      https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd&include_24hr_change=true
Template: stat
Fields:
   Label: "Price"       Path: "bitcoin.usd"          Transform: currency
   Label: "24h change"  Path: "bitcoin.usd_24h_change"  Transform: percent

// ── Plugin: OpenWeatherMap temperature ───────────────────
Name:     Weather — Sydney
Icon:     🌤   Color:  #0ea5e9
Mode:     fetch
URL:      https://api.openweathermap.org/data/2.5/weather?q=Sydney&appid=YOUR_KEY&units=metric
Template: table
Fields:
   Label: "Temp"       Path: "main.temp"          Transform: number
   Label: "Feels like" Path: "main.feels_like"   Transform: number
   Label: "Humidity"   Path: "main.humidity"      Transform: percent
   Label: "Wind km/h"  Path: "wind.speed"        Transform: number

Relay mode — private APIs where credentials stay server-side

Some APIs block CORS or shouldn't have their keys in browser storage. Relay mode POSTs to a small function you control; the function calls the real API and returns just the data you need.

Here's a complete relay function for Vercel (also works as a Cloudflare Worker or AWS Lambda):

// vercel/functions/pinodock-relay.js
export default async function handler(req, res) {
  const { key, params } = req.body

  // Optional: verify the shared secret from Pinodock settings
  const secret = process.env.PINODOCK_RELAY_SECRET
  if (secret && req.headers['x-pinodock-secret'] !== secret) {
    return res.status(401).json({ error: 'Unauthorized' })
  }

  switch (key) {
    case 'stripe-mrr': {
      const stripe = await fetch(
        'https://api.stripe.com/v1/charges?limit=100&created[gte]=' +
        Math.floor(Date.now() / 1000) - 2592000,
        { headers: { Authorization: `Bearer ${process.env.STRIPE_SECRET_KEY}` } }
      ).then(r => r.json())
      const mrr = stripe.data.reduce((s, c) => s + c.amount, 0) / 100
      return res.json({ mrr, currency: 'usd' })
    }

    case 'pagerduty-incidents': {
      const pd = await fetch(
        'https://api.pagerduty.com/incidents?statuses[]=triggered&statuses[]=acknowledged',
        { headers: {
          Authorization: `Token token=${process.env.PAGERDUTY_TOKEN}`,
          Accept: 'application/vnd.pagerduty+json;version=2'
        }}
      ).then(r => r.json())
      return res.json({ count: pd.total, incidents: pd.incidents.slice(0, 5) })
    }

    default:
      return res.status(400).json({ error: 'Unknown plugin key' })
  }
}

In Pinodock settings, configure the relay plugin:

// ── Plugin: Stripe MRR (relay) ─────────────────────────
Name:      MRR
Icon:      💳   Color: #635bff
Mode:      relay
URL:       https://your-vercel-app.vercel.app/api/pinodock-relay
Relay key: stripe-mrr
Secret:    YOUR_SHARED_SECRET
Refresh:   60 (minutes)
Template:  stat
Fields:
   Label: "Monthly Revenue"  Path: "mrr"  Transform: currency

Scrape mode — data from any open tab

Point at a URL and a CSS selector. Pinodock reads the matching element's text from your open tab. No API needed — ideal for internal dashboards, Retool apps, and legacy tools.

// ── Plugin: Retool metric ─────────────────────────────
Name:      Active Users
Icon:      📊   Color: #f59e0b
Mode:      scrape
URL:       https://your-company.retool.com/apps/your-dashboard
Selector:  [data-testid="active-user-count"] .value
Template:  stat

10. Automations PRO

Automations are trigger → action rules that run in the background. Go to Settings → Automations → Add Automation.

Trigger typeFormatExample
TimeHH:MM — fires daily at that time09:00
QueryTyped prefix in the palettestandup
Action typeWhat it does
open_urlOpens a URL in a new tab
open_aliasNavigates to one of your saved URL aliases
copyCopies a text string to your clipboard

Automation examples:

// ── Automation 1: Open your standup tools at 9 AM ────────
Name:     Morning Standup
Trigger:  time09:00
Action:   open_urlhttps://meet.google.com/your-standup-link

// ── Automation 2: "deploy" in palette → open your CI run ─
Name:     Open Latest Deploy
Trigger:  querydeploy
Action:   open_urlhttps://github.com/YOUR_ORG/YOUR_REPO/actions

// ── Automation 3: "eod" → copy end-of-day template ──────
Name:     EOD Template
Trigger:  queryeod
Action:   copyDone today:
-
-

Tomorrow:
-

Blockers: none

Enable Auto-run automations in settings to have time-based automations fire automatically without any user action. Leave it off to keep them as manual triggers only.

11. Script commands PRO

Script commands are JavaScript functions triggered by typing !trigger in the command palette. Go to Settings → Scripts → Add Script Command.

Each command receives the rest of your typed input as input: string and can do anything JavaScript can do in a Chrome extension background context — fetch requests, clipboard writes, tab operations, and more.

// ── Script: "!ip" — fetch and copy your public IP ────────
Name:     Get Public IP
Trigger:  ip
Code:
const res = await fetch('https://api.ipify.org?format=json')
const data = await res.json()
await navigator.clipboard.writeText(data.ip)
return `Copied: ${data.ip}`


// ── Script: "!time London" — world clock ─────────────────
Name:     World Clock
Trigger:  time
// input = the timezone name (e.g. "London", "Tokyo", "New_York")
Code:
const zone = input.trim() || 'UTC'
const fmt = new Intl.DateTimeFormat('en-GB', {
  timeZone: zone, hour: '2-digit', minute: '2-digit', second: '2-digit'
})
const result = `${zone}: ${fmt.format(new Date())}`
await navigator.clipboard.writeText(result)
return result


// ── Script: "!uuid" — generate and copy a UUID ───────────
Name:     New UUID
Trigger:  uuid
Code:
const id = crypto.randomUUID()
await navigator.clipboard.writeText(id)
return id


// ── Script: "!b64 Hello world" — base64 encode ───────────
Name:     Base64 Encode
Trigger:  b64
Code:
const encoded = btoa(unescape(encodeURIComponent(input)))
await navigator.clipboard.writeText(encoded)
return encoded


// ── Script: "!tab github" — switch to a matching tab ─────
Name:     Jump to Tab
Trigger:  tab
Code:
const tabs = await chrome.tabs.query({})
const match = tabs.find(t =>
  t.url?.toLowerCase().includes(input.toLowerCase()) ||
  t.title?.toLowerCase().includes(input.toLowerCase())
)
if (match) {
  chrome.tabs.update(match.id, { active: true })
  chrome.windows.update(match.windowId, { focused: true })
  return `Switched to: ${match.title}`
}
return 'No matching tab found'

12. User scripts PRO

User scripts are JavaScript that runs automatically when you visit a URL matching a pattern you define. They use Chrome's userScripts API and require Developer Mode to be enabled in chrome://extensions.

Go to Settings → User Scripts → Add Script. Each script has URL match patterns, a JS code body, a world context (USER_SCRIPT for isolation or MAIN for full page access), and a run-at timing.

Three recipe scripts are built-in and available free:

  • GitHub TODO Highlighter — wraps TODO, FIXME, HACK comments in yellow
  • Cookie Banner Remover — hides OneTrust, Cookiebot, and similar on any site
  • Linear Focus Mode — collapses the sidebar on Linear

With Pro you can write your own. Here are four complete examples:

// ── Script 1: Auto-dark-mode on any page ─────────────────
Name:    Force Dark Mode
Matches: ["https://*/*"]
World:   USER_SCRIPT
RunAt:   document_start
Code:
const style = document.createElement('style')
style.textContent = `
  html { filter: invert(1) hue-rotate(180deg) !important; }
  img, video, canvas, svg, iframe { filter: invert(1) hue-rotate(180deg) !important; }
`
document.documentElement.appendChild(style)


// ── Script 2: GitHub — show PR age in the PR list ────────
Name:    GitHub PR Age
Matches: ["https://github.com/*/pulls*"]
World:   MAIN
RunAt:   document_idle
Code:
document.querySelectorAll('[aria-label*="opened"] relative-time').forEach(el => {
  const opened = new Date(el.getAttribute('datetime'))
  const days = Math.floor((Date.now() - opened) / 86400000)
  const badge = document.createElement('span')
  badge.textContent = `${days}d`
  badge.style.cssText = `
    background: ${days > 7 ? '#dc2626' : days > 3 ? '#d97706' : '#16a34a'};
    color: white; font-size: 10px; font-weight: 700; border-radius: 4px;
    padding: 1px 5px; margin-left: 6px; vertical-align: middle;
  `
  el.parentNode?.appendChild(badge)
})


// ── Script 3: Notion — hide the left sidebar ─────────────
Name:    Notion Focus Mode
Matches: ["https://www.notion.so/*"]
World:   USER_SCRIPT
RunAt:   document_idle
Code:
const hide = () => {
  const sidebar = document.querySelector('.notion-sidebar-container, [class*="sidebar"]')
  if (sidebar) sidebar.style.display = 'none'
}
hide()
new MutationObserver(hide).observe(document.body, { childList: true, subtree: true })


// ── Script 4: Any page — floating word count for writers ──
Name:    Word Count HUD
Matches: ["https://docs.google.com/document/*", "https://www.notion.so/*"]
World:   MAIN
RunAt:   document_idle
Code:
const hud = document.createElement('div')
hud.style.cssText = `
  position: fixed; bottom: 16px; right: 16px; z-index: 99999;
  background: rgba(15,23,42,0.85); color: #e2e8f0;
  font: 600 11px/1 monospace; padding: 6px 10px; border-radius: 6px;
  pointer-events: none; backdrop-filter: blur(4px);
`
document.body.appendChild(hud)

function update() {
  const text = document.body.innerText || ''
  const words = text.trim().split(/\s+/).filter(Boolean).length
  hud.textContent = `${words.toLocaleString()} words`
}
update()
new MutationObserver(update).observe(document.body, { subtree: true, characterData: true })

To export all your scripts as a JSON backup, open Settings → User Scripts → Export. To share or import a set of scripts, use the Import button and paste a JSON array in the same format.

13. AI profiles and BYOK setup PRO

Pinodock supports multiple AI profiles. Each profile points to a different provider or model. Go to Settings → AI → Add Profile.

ProviderKey prefixDefault model
OpenAI (ChatGPT)sk-…gpt-4o-mini
Anthropic (Claude)sk-ant-…claude-haiku-4-5
Google GeminiAIza…gemini-2.0-flash
DeepSeeksk-…deepseek-chat
Perplexitypplx-…llama-3.1-sonar-small-128k-online
Local (OpenAI-compatible)OptionalAny Ollama model (e.g. gemma3, llama3.2)

For Local mode, set the base URL to your Ollama or LM Studio endpoint (default: http://127.0.0.1:11434/v1). Pinodock will call /models to verify the connection and list available models. Everything stays on your device — no API key required.

// Local Ollama profile setup
Provider:   Local (OpenAI API)
Base URL:   http://127.0.0.1:11434/v1
Model:      gemma3:4b          ← or llama3.2, phi4-mini, etc.
Max tokens: 512
API key:    (leave blank)

// LM Studio profile setup
Provider:   Local (OpenAI API)
Base URL:   http://127.0.0.1:1234/v1
Model:      lmstudio-community/gemma-3-4b-it-GGUF
API key:    lm-studio          ← LM Studio requires any non-empty string

Switch between profiles at any time from the AI panel. The active profile is used for all AI actions: the command palette AI query, document summarisation, and in-page context answers.

14. Workspace presets FREE

A workspace preset is a named group of URLs. Activating a preset opens all URLs as new tabs in one click. Create them in Settings → Workspaces → Add Preset.

// Preset: Morning routine
Name:  Morning  Icon: ☀️
URLs:
  https://mail.google.com
  https://calendar.google.com
  https://linear.app/YOUR_WORKSPACE/my-issues
  https://github.com/notifications

// Preset: Deep work (no distractions)
Name:  Deep Work  Icon: 🎯
URLs:
  https://www.notion.so/YOUR_WORKSPACE
  https://docs.google.com

// Preset: Code review
Name:  Review PRs  Icon: 🔍
URLs:
  https://github.com/YOUR_ORG/YOUR_REPO/pulls?q=is:open+review-requested:@me
  https://github.com/YOUR_ORG/YOUR_REPO/actions

// Preset: Weekly planning
Name:  Weekly Plan  Icon: 📅
URLs:
  https://calendar.google.com
  https://linear.app/YOUR_WORKSPACE/projects
  https://docs.google.com/spreadsheets/d/YOUR_OKR_SHEET

15. Todos, habits, and focus mode FREE

Todos are accessible from the command palette (⌘K → "todo" → press enter on "Open Todos") or from the Todo widget on your dashboard. Each task has a title, status (Todo / In Progress / Done), priority (Low / Medium / High), and an optional due date.

Recurring todos — tasks that reset daily, weekly, or monthly — are created from the recurring toggle inside any todo item. They re-open automatically on their cadence without any action from you.

Habits live on the Habits panel. Each habit shows a streak counter and a weekly completion heatmap. The number of days shown in the heatmap is configurable. A habit reminder notification can be scheduled from Settings → Reminders.

Focus mode is a toggle in Settings or accessible via the command palette. When on, it hides all non-essential dashboard elements and dims background content, leaving only your active timer and current task visible. Toggle off anytime.

Tip: Set your habit reminder to fire at the same time as your morning standup automation. Open the new tab, see the standup URL open automatically, see your habits at a glance, check your todo list — the whole morning ritual in under 10 seconds.

18. Dock — favicon icons, preset packs, and overflow stacks

The dock at the bottom of the new tab now shows two sections separated by a thin divider: your built-in navigation shortcuts on the left, and your custom site icons on the right. Every site you add appears as a real favicon — not an emoji.

Click the + button at the right end of the dock to open the dock customizer. Six preset packs let you add an entire category of sites at once:

PackSites
🎬 StreamingNetflix, YouTube, Spotify, Twitch, Disney+, Prime Video, Apple TV+, Max
🌐 SocialX/Twitter, Instagram, Facebook, TikTok, Reddit, LinkedIn, Pinterest
💬 MessagingWhatsApp Web, Telegram, Discord, Slack, Messenger, Gmail, Outlook
💻 DevGitHub, Stack Overflow, MDN, npm, CodePen, Vercel
⚡ ProductivityNotion, Figma, Linear, Calendar, Drive, Trello
📰 NewsHacker News, BBC, The Guardian, Reuters

The dock has a visible limit per size setting (small: 7, medium: 9, large: 6). Any sites beyond the limit collapse into an overflow stack button — a 2×2 favicon grid. Click it to open a popover showing all overflow sites.

Moving your cursor over the dock activates macOS-style magnification — icons scale continuously based on cursor proximity, growing in the direction away from the dock edge (upward for a bottom dock).

Dock settings (Settings → Dashboard): position (bottom/left/right), size (small/medium/large), and auto-hide (slides off-screen, reappears when the cursor nears the edge).

Full guide: customizing the Pinodock dock

19. Projects and Tags — organise your research

Every piece of content in Pinodock — highlights, reading list items, snippets, and todos — can now be assigned to a Project. A Project is a named container with an emoji and a color. It groups items across content types so you can see everything related to a client, subject, or side project in one view.

Open the Projects tab (📁 in the sidebar) to create and manage projects. The overview shows a card grid; click any card to open the project's detail view: all four content types together, filtered to that project.

To assign an item to a project, open the Highlights, Snippets, Reading, or Todos panel, find the item, and click ▼ tag / project to expand its assignment controls. Select a project from the picker dropdown.

Tags are secondary free-form labels added to individual items. Type in the tag input and press Enter. Tags appear as colored pills and can be filtered within the project detail view. Use tags for sub-context within a project: status (urgent, done), category (frontend, citation), or person (alice).

Full guide: Projects and Tags in Pinodock

20. Smart palette — context bubbles and recently used

When you open the new tab launcher (⌘K) without typing anything, two things appear below the input:

Context bubbles — five one-click navigation shortcuts: Todos, Reading, Snippets, Highlights, Clipboard. Click any to jump to that panel instantly.

Recently used — the last five commands or items you activated, sorted by recency. Click to re-run. Useful for commands with arguments you want to repeat with a slight variation.

Search results are ranked by a three-factor formula: fuzzy match quality (55%), usage frequency (30%), and recency (15%). Items you use often float to the top of results automatically — no configuration needed.

Full guide: the smart context-aware palette

21. Page actions — highlight, screenshot, reader mode

The on-page command palette (⌘Shift+P on any website) now includes two new actions in its quick-action grid:

🖊 Highlight — if text is selected on the page when you open the palette, clicking Highlight saves that text as a Pinodock highlight: the selected text, surrounding context, page URL, title, and timestamp. It appears immediately in your Highlights panel and can be assigned to a project.

📸 Screenshot — captures the visible tab as a PNG using Chrome's captureVisibleTab API and opens the result in a new tab for saving or copying.

These join the existing page actions: Copy URL, Copy Markdown, Reader Mode, QR Code, UTM Builder, Pick Color, and Encode URL. All nine actions are available by keyboard number (1–9) when the palette is open and the input is empty.

22. Pro sync — highlights and todos across devices

Pinodock Pro users can enable cross-device sync via Firestore (Settings → Account → Enable sync). The following data syncs when you're signed in on multiple Chrome profiles:

SyncedNot synced (privacy)
Highlights (text, color, URL, tags, project)Clipboard history
Reading List (title, URL, tags, project)AI chat sessions
Snippets (title, content, tags, project)Command frequency data
Todos (text, status, priority, tags, project)Browser history
QuickLinks / Dock sites
Project definitions

Settings sync automatically via chrome.storage.sync (Chrome handles this natively without sign-in). The Pro Firestore sync layer handles content, not settings.