andrewlb notes

PM Toolkit

PM Toolkit

Tools

Claude CodeNext.jsReactTypeScriptTailwind CSSshadcn/uiReact FlowdagreZodgray-matterCommander.jsPuppeteerVitestpnpm

What worked

70 days of sustained execution: 18 shipped milestones + v3.4 in progress, 354+ completed plans, 2,122 total commits. Claude Code handled 23 content types with a Zod SCHEMA_REGISTRY for exhaustive type checking, built the strategy graph (React Flow + dagre), the PostHog-style horizontal changelog timeline, the Now-Next-Later kanban, the Opportunity Solution Tree, and bidirectional sync with Jira + Workboard + GitHub + Miro. The export quality is the key differentiator — screenshots and PDFs are stakeholder-ready without post-processing. Line-level write-back with `expectedRawLine` guards handled conflict detection cleanly.

What broke

External validation is still not executed — v3.3 shipped demo mode + feedback DB + validation session UI, but no external PMs have used it yet. The March 23 recommendation to 'find 2-3 PMs and watch them try it' is still outstanding one month later; velocity continues without user feedback. Tag parsing collisions between the task parser and signal extractor are a known risk. Weekly dashboard is O(N) scanning all daily notes synchronously (mitigated with ISR). Sync state partial failures leave inconsistency. Schema registry breaks on new content types until you update all four consumers.

Roles

I set the strategic bet — markdown + YAML frontmatter over a database, because PMs should own their data and git is a better substrate than a SaaS lock-in. I wrote the dear-new-pm.md AI collaboration patterns document. Claude Code built the web app, the monorepo packages (obsidian-plugin, chrome-extension, jira-client, workboard-client, github-client, miro-client), and the CLI. The v3.4 insight that Key Results should be first-class file-backed entities (not inline OKR sub-objects) was mine — surfaced by 70 days of dogfooding — and Claude executed the cascading refactor.

PM Toolkit

Overview

PM Toolkit is a personal product management intelligence system that transforms an Obsidian vault (markdown files with YAML frontmatter) into a polished, web-based strategic planning dashboard. It provides complete strategy-to-execution traceability for individual PMs who want to own their data, maintain full strategic visibility, and generate stakeholder-ready artifacts without a database or SaaS platform.

Core value proposition: Screenshots and exports look professional enough to share directly with stakeholders — no additional formatting needed.

Target users: Individual product managers using Obsidian + Jira/Workboard, who want a unified view from customer signals through strategy to shipped outcomes.

Key Features

  • Strategy graph visualization (React Flow, dagre layout) with interactive node/edge manipulation
  • Changelog with PostHog-style horizontal timeline
  • Customer signals pipeline with vectors, KANO grid, and Cost-of-Delay matrix
  • Now-Next-Later kanban planning
  • Opportunity Solution Tree (5-level hierarchy)
  • Outcome measurement with impact tracking
  • Bidirectional sync with Jira, Workboard, GitHub, and Miro
  • Daily task management with Obsidian integration and write-back
  • Cross-team strategy mapping
  • Data analytics with computed metrics and auto-updating KPIs
  • Newsletter builder with auto-rendering
  • Multiple export formats (PDF, PNG, Markdown)
  • Obsidian plugin with validation, linting, quick capture
  • Chrome extension for Jira/Confluence capture
  • CLI for sync, reporting, and changelog generation

Architecture

Tech Stack

LayerTechnology
FrameworkNext.js 16.1.6 (App Router)
UIReact 19.2.3 + Tailwind CSS v4 + shadcn/ui
VisualizationReact Flow 12.10 + dagre 2.0 + d3-* libraries + Mermaid 11.12
ValidationZod 4.3.6
Contentgray-matter (YAML frontmatter), js-yaml
CLICommander.js
ExportPuppeteer 24.36 + html-to-image + Handlebars
TestingVitest 4.0 + @testing-library/react
Monorepopnpm 10.29 workspaces
Buildesbuild (plugins), tsup (CLI/packages)

Monorepo Structure

pmtoolkit/
├── src/                    # Next.js web app (App Router)
│   ├── app/                # Route pages (changelog/, signals/, vectors/, strategy/, etc.)
│   ├── components/         # React components (dashboard, strategy graph, charts)
│   ├── lib/
│   │   ├── content/        # Vault reading, config, markdown parsing
│   │   ├── tasks/          # Daily note scanning, task parsing, task actions
│   │   ├── dashboard/      # Aggregators (task, discovery, okr, activity)
│   │   ├── miro/           # MiroClient, mapping, types
│   │   └── jira/           # Jira sync state, manifest builders
│   ├── actions/            # Server actions (write-back)
│   └── types/              # TypeScript interfaces
├── packages/
│   ├── shared-schemas/     # Zod schemas for all 23 content types
│   ├── cli/                # pmt CLI binary
│   ├── obsidian-plugin/    # Obsidian plugin (esbuild)
│   ├── chrome-extension/   # Chrome extension (MV3)
│   ├── jira-client/        # Jira Cloud API client
│   ├── workboard-client/   # Workboard API client
│   ├── github-client/      # GitHub API client
│   └── miro-client/        # Miro API client
├── demo-content/           # Bundled Obsidian vault for demo mode
├── templates/              # Obsidian Templater templates
└── .planning/              # Planning docs, milestones, requirements

Key Design Patterns

  1. Markdown Source of Truth — All content is YAML-frontmatter markdown in Obsidian vault. Web app reads files, never modifies vault directly during normal operation.
  2. Server-Side Aggregation + Client Components — Dashboard computation in server components; clients receive pre-computed props.
  3. Sync State Files.pmtoolkit/sync-state/ tracks bidirectional sync with external tools, prevents re-processing.
  4. Schema Registry — Zod SCHEMA_REGISTRY maps 23 content types to their schemas for exhaustive type checking.
  5. Line-Level Write-Back — Task mutations use string surgery with expectedRawLine guard for conflict detection.
  6. Config Unification — Single Zod schema in shared-schemas consumed by web, CLI, and Obsidian plugin with per-platform secret storage.

Data Flow

Reading: Obsidian Vault → readVaultContent() → Schema validation (Zod) → Dashboard aggregators (server-side) → React components (client-side)

Writing: User interaction → Server action → Line-level string surgery with expectedRawLine guard → Sync state update → revalidatePath() → Next.js cache invalidation

Integration: Web/CLI reads config → API client (OAuth/token auth) → Sync state comparison for conflict detection → Frontmatter update or rejection → Obsidian reads fresh files

Development History

Timeline: 70 days (Feb 3 - Apr 13, 2026), 18 shipped milestones + v3.4 (7/10 phases complete), 354+ completed plans, 2,122 total commits.

VersionDateFocus
v1.0Feb 3Foundation, Changelog, PRDs, Stakeholder Mapping, Export
v1.1Feb 4Strategy content types, React Flow visualization
v1.2Feb 6Universal edit mode, KR parsing, dashboard
v1.3Feb 7Signals/Vectors/Customers, KANO grid, Cost of Delay
v1.4Feb 8Strategy detail pages, Now-Next-Later kanban
v1.5Feb 9Monorepo, Obsidian plugin, Chrome extension
v1.6Feb 11Daily note task parsing, time-bucket kanban, write-back
v1.7Feb 14Workboard bidirectional sync
v1.8Feb 19Jira Cloud sync, sprint reporting
v1.9Feb 21OST, outcome measurement, GitHub integration
v2.0Feb 22Clustering board, newsletter builder, Miro export
v2.1Feb 27Strategy canvas, experiment management
v2.2Feb 28Teams, cross-team strategy map
v3.0Mar 1Dataset loading, metric computation, KR auto-update
v3.1Mar 1Jira UX overhaul, traceability chains, KPI health cascade
v3.2Mar 13Daily signal extraction, weekly dashboard, Miro CLI
v3.3Apr 10Sustainability & self-awareness — SQLite usage analytics + heatmap, nav consolidation (30 → 20 items), TypeScript cleanup (110+ errors), demo mode infrastructure with feedback DB and 5 validation UI components, demo vault pruned 143 → 77 files
v3.4In progressTeam GitHub activity analysis — multi-repo config, team discovery, commit/tag wiring, contributor stats, cycle time, Copilot detection, Jira cross-referencing, multi-repo changelog. 7 of 10 phases complete (117-123); Phase 124 (OKR/KR restructuring) in progress

Structural Shift: Key Results as First-Class Entities (Phase 124, April)

The most significant architectural change post-profile is a data model correction: Key Results were promoted from inline OKR sub-objects to first-class file-backed entities under strategy/key-results/. OKR files now hold a keyResults: [slug] array only. The canonical strategy-theory.md (edited April 12) reframes OKRs as grouping, not structural — KRs become the team-level execution citizens, with edges to initiatives and KPIs.

Cascading refactor: schemas, canvas, Workboard sync, migration CLI, templates, web components. This is not feature creep — it's a conceptual correction surfaced after 70 days of dogfooding. "The data model was inverted" is a legitimate v3.4 insight and the kind of thing that only emerges from sustained real use.

Architectural Decisions

DecisionRationale
Markdown over databaseUser data ownership, portability, version control
YAML frontmatter over JSONSingle file per entity, self-contained, Obsidian native
Server actions for write-backAvoids API layer, leverages Next.js, direct file access
Monorepo over separate reposShared types, consistent CLI patterns, monolithic release
Custom API clients (not SDKs)Fine-grained control, rate limiting, retry logic, ~300-400 LOC each
Line-level write-backFine-grained mutations preserve manual edits
Puppeteer for exportProven PDF quality, singleton browser pool

Strengths

  • Complete strategy-to-execution traceability — North Stars through OKRs to measured outcomes; unique vs. commercial PM tools
  • Signal-to-vector discovery pipeline — Evidence-driven prioritization with KANO/Cost-of-Delay scoring
  • File-based portability — Zero lock-in, git-friendly, user controls backup
  • Bidirectional sync — Content-hash conflict detection, echo prevention, explicit merge strategy per field
  • Export quality — Stakeholder-ready PDFs, PNGs, and Markdown without post-processing
  • Comprehensive testing — 43+ test files, 47 tests for task parser alone

Weaknesses & Risks

  • Tag parsing collision risk — Task parser and signal extractor both scan daily notes for #tags
  • Config unification can break credentials — Three config systems with incompatible assumptions need careful migration
  • Weekly dashboard O(N) scanning — Aggregators read all daily notes synchronously; mitigated with date filtering and ISR
  • TODO write-back race conditions — Two rapid toggles on same task could read stale line content
  • Sync state complexity — Partial failure leaves inconsistent state; needs atomic writes
  • Schema registry breaks on new content types — Adding types requires updates to enum, registry, Obsidian detector, switch cases
  • External validation still not executed — v3.3 shipped demo mode, feedback DB, and validation session UI, but no external PMs have used the tool yet. The March 23 recommendation to "find 2-3 PMs and watch them try it" is still outstanding one month later. The velocity continues without user validation

Prompting Patterns

The project documents clear AI collaboration patterns in dear-new-pm.md:

  1. Signal Synthesis — Copy 10-15 signals, ask Claude to group into vectors, compare AI vs. human groupings
  2. Strategy Stress-Testing — Export strategy graph, ask for assumption identification and gap analysis
  3. PRD Drafting — Provide vector + connected signals + target OKR, ask for problem section draft
  4. Sprint Narrative — Provide sprint summary data, ask for executive summary
  5. Prioritization Challenge — Copy scored vectors + OKRs, ask if prioritization aligns

Anti-patterns explicitly warned against: AI cannot replace customer relationships, AI confidently generates plausible-but-wrong strategy, AI hallucinates connections, velocity trap (producing more artifacts faster while real bottleneck is judgment).