NanoPM Viewer

June 16, 2026 · View on GitHub

Throwaway macOS prototype for the .nanopm/ artifacts that nanopm generates — pick a project (Claude-Code-style recents), browse artifacts grouped by phase (Define / Discover / Planning / Build), read them as rendered Markdown. No Claude Code window needed, no API: all file access goes through background shell commands.

Two layers, two trust levels. The browser is strictly read-only — it never writes to .nanopm/. The run features below are not: launching a skill spawns the claude CLI, which writes artifacts and runs tools on your machine. See Safety and Requirements before using them or distributing a build.

Each phase (Define, Discover, Planning, Build) has an Overview page: every runnable skill for that phase with its status (generated / running / waiting / missing) and a Run button — Define (/pm-vision-mission, /pm-business-model, /pm-org, /pm-product, /pm-personas), Discover (/pm-user-feedback, /pm-data, /pm-discovery, /pm-competitors-intel), Planning (/pm-objectives, /pm-strategy, /pm-roadmap), Build (/pm-prd, /pm-breakdown), plus a Day to Day section (/pm-challenge-me, /pm-standup, /pm-weekly-update) — executed through claude -p in a background process. The future artifact shows up in the sidebar with a running indicator while you keep browsing. Runs are interactive: when the model needs input it emits a structured question block; the app notifies you, renders the questions natively (choices + free text) alongside the model's messages, and resumes the same session (claude --resume) with your answers until the document is written. A macOS notification fires when it's ready.

The Define overview additionally leads with the Context Brief.nanopm/CONTEXT-SUMMARY.md rendered inline — the consolidated company + product context a subagent regenerates after each Define skill and every skill reloads at startup. (It's shown only on the Define page, not as a sidebar document.)

The Planning overview mirrors this with a Plan Brief.nanopm/PLAN-SUMMARY.md rendered inline — the consolidated objectives, strategy

  • roadmap a subagent regenerates after each Plan skill and every skill reloads at startup, right after the context brief. (Same treatment: shown only on the Planning page, not as a sidebar document.)

Runs stream live via claude --output-format stream-json: an Activity Monitor window (toolbar, badged with the in-flight count) lists every run across the session and shows a live console for the selected one — session start, each tool call and its result, assistant messages, and the final cost/duration. Built to follow several parallel runs at once.

Brainstorm is an always-on entry at the top of the Day-to-Day section: a free-form chat with Nano, the expert CPO. It opens on a new conversation, streams replies on the same claude run engine, and a History menu lists past jams — auto-titled by Claude's own ai-title and resumable with full prior context via claude --resume. Brainstorm runs are read-only: Bash/Edit/Write are denied via --disallowedTools, so a free chat over untrusted project content can't mutate the repo.

Once intel exists, an expandable Competitors entry appears inside the Discover section: clicking it lands on the latest report (with a History menu for past reports, newest first); expanding it lists each monitored competitor — links to its monitored pages and its captured snapshots (changelog / API docs / pricing / site) as tabs, all read from competitors.json and intel/.

In the Build section, PRDs are grouped in an expandable PRDs folder: clicking it shows a recap of every product spec and its status (parsed from each file's header); expanding lists the individual PRDs.

When a newer nanopm skill pack is available, a dismissible update banner appears at the top of the window ("nanopm vX available — you have vY") with a one-click Update now button — the GUI mirror of the CLI's update check. Detection delegates to nanopm_update_check (same semver + 24h cache as the terminal); the update re-runs setup from main. On a local clone the update is refused with a maintainer warning (it reads the ~/.nanopm/install-source marker setup writes) so you never overwrite your working copy.

This is the proof instrument for the form-factor bet in the nanopm Q3 strategy (see PRD.md). It is deliberately minimal and explicitly throwaway — no editing, no connector management, no cross-skill orchestration (single-skill runs only). Do not grow it before the prototype cohort AND the terminal-comfortable control both read positive (see the cross-read matrix in the strategy).

Build & run

./build-app.sh
open "build/NanoPM Viewer.app"

Smoke test (headless)

swift build
.build/debug/NanoPMViewer --smoke /path/to/a/project

Prints the phase-mapped artifact list the UI would show, then exits.

.build/debug/NanoPMViewer --parse-update-check

Runs the update-banner version parser against a fixed table of cases (clean line, buried in shell output, malformed) and exits non-zero on any mismatch.

Requirements

  • Browsing artifacts: nothing beyond the app itself.
  • Running skills: the Claude Code claude CLI installed, on your PATH, and authenticated. The app resolves it through a login shell. If it's missing, runs fail with a clear message and browsing still works. Note that the prototype's target user (non-terminal-native) typically won't have the CLI — the run features are exercisable mainly by terminal-comfortable users, which is worth keeping in mind when reading the form-factor experiment's results.

Safety

The viewer launches skills by spawning claude -p as a background process. That process is not sandboxed by the app, so its file/tool access is bounded only by the permission flags we pass:

  • We run with --permission-mode default and an explicit --allowedTools allow-list (Read/Edit/Write/Glob/Grep/Bash/WebFetch/…) — never bypassPermissions. Tools off the list are denied.
  • Skills still need Bash, and they read untrusted input (artifact text, fetched competitor pages). So a hostile project or a poisoned web page could still influence what a run does. Only open projects you trust.
  • The app itself cannot adopt the macOS App Sandbox — sandboxing forbids spawning the claude subprocess it depends on. For that reason, ad-hoc builds (what build-app.sh produces) are dev-only. Before handing a build to external testers, sign with a Developer ID + hardened runtime, notarize, and add an explicit in-app consent step the first time a user launches a run.

Stack

Swift / SwiftUI (macOS 14+), Swift Package Manager, MarkdownUI for rendering.