Visualize your Linear issues as interactive hill charts. Track progress from "figuring things out" to "making it happen" with an intuitive drag-and-drop interface.
Here's what this app assumes:
- A pitch in Shape Up maps to a Linear Project.
- An issue with a label (e.g. Slice) maps to a slice in Shape Up.
- Connect your Linear account with OAuth
- Create a "New Hillchart" and choose your Linear project to create it for
- Choose what label you'd like to use as slices to sync
- Issues that are started are put on the hill chart
- Drag 'n drop and relish in your progress!
- OAuth 2.0 Authentication - Secure integration with Linear's official OAuth flow
- Auto-sync with Linear issues based on labels
- Drag-and-drop positioning to track progress
- Multiple projects - organize different hill charts
- Browser storage - positions persist locally
- Real-time updates - syncs with Linear every 5 minutes
- Token refresh - automatic token renewal for uninterrupted access
Note that this currently only works for single player mode as positions are stored on localStorage.
-
Left side (0-50%): "Figuring it out"
- High uncertainty
- Exploration and discovery
- Understanding the problem
-
Peak (50%): Maximum uncertainty
- Transition point
- Key decisions being made
-
Right side (50-100%): "Making it happen"
- Decreasing uncertainty
- Execution mode
- Shipping and finishing
- Drag horizontally - Move issues along the hill to update their progress
- Color indicators - Priority levels shown by colored dots
- Red: Urgent
- Orange: High
- Blue: Medium
- Gray: Low
- Sync button - Manually refresh issues from Linear
- Auto-sync - Issues automatically refresh every 5 minutes
- Node.js 20.3.0 or higher
- A Linear account with workspace admin access
- Linear OAuth application credentials
-
Create a Linear OAuth Application:
- Go to Linear Settings > API > Applications
- Click "New OAuth application"
- Fill in the application details:
- Name: Linear Hill Charts
- Description: Visualize Linear issues as interactive hill charts
- Redirect URLs: Add your callback URLs:
- Development:
http://localhost:3000/api/auth/callback - Production:
https://yourdomain.com/api/auth/callback
- Development:
- Scopes: Select
readandwrite
-
Copy your OAuth credentials:
- Client ID
- Client Secret (keep this secure!)
-
Clone or download this repository
-
Install dependencies:
npm install
-
Configure environment variables:
cp .env.local.example .env.local
Edit
.env.localand add your OAuth credentials:LINEAR_OAUTH_CLIENT_ID=your_client_id_here LINEAR_OAUTH_CLIENT_SECRET=your_client_secret_here LINEAR_OAUTH_REDIRECT_URI=http://localhost:3000/api/auth/callback SESSION_SECRET=your_random_session_secret_here NEXTAUTH_URL=http://localhost:3000
Generate a secure session secret:
openssl rand -base64 32
-
Run the development server:
npm run dev
-
Open your browser to http://localhost:3000
- Click "Connect with Linear" on the setup page
- Authorize the application in Linear
- Create your first project:
- Choose a name for your hill chart
- Select a Linear team
- Enter a label filter (e.g., "hill-chart")
- Add the label to issues in Linear that you want to track
- Start dragging issues along the hill to track their progress!
Hill charts are inspired by Basecamp's hill charts and provide a visual way to track project progress:
├── app/ # Next.js app directory
│ ├── api/
│ │ └── auth/ # OAuth API routes
│ │ ├── login/ # Initiate OAuth flow
│ │ ├── callback/ # OAuth callback handler
│ │ ├── token/ # Token endpoint with auto-refresh
│ │ ├── logout/ # Logout and token revocation
│ │ └── session/ # Session status check
│ ├── setup/ # OAuth login page
│ ├── projects/ # Projects list and individual views
│ ├── layout.tsx # Root layout with providers
│ └── page.tsx # Home page (redirects)
├── components/
│ ├── hill-chart/ # Hill chart visualization
│ ├── projects/ # Project management UI
│ ├── layout/ # Layout components
│ └── ui/ # Reusable UI components
├── lib/
│ ├── auth/ # OAuth and session management
│ │ ├── oauth.ts # OAuth utilities
│ │ └── session.ts # Encrypted session management
│ ├── linear/ # Linear API integration
│ ├── storage/ # localStorage management
│ ├── store/ # Zustand state management
│ ├── hooks/ # React hooks
│ └── utils/ # Utility functions
└── types/ # TypeScript type definitions
- Next.js 15 - React framework with App Router
- TypeScript - Type safety
- Tailwind CSS - Styling
- Zustand - State management
- React Query - Server state
- Linear SDK - Linear API client
- Zod - Runtime validation
- OAuth 2.0 - Industry-standard authorization protocol
- PKCE - Proof Key for Code Exchange for enhanced security
- Encrypted Sessions - Server-side encrypted cookie sessions
- Automatic Token Refresh - Tokens refresh automatically before expiration
- Secure Storage - OAuth tokens never stored in browser localStorage
- CSRF Protection - State parameter validation
- OAuth Tokens: Encrypted server-side session cookies
- Projects: Browser localStorage
- Issue Positions: Browser localStorage
- Issue Metadata: Fetched from Linear (not stored)
npm run dev- Start development servernpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run type-check- Run TypeScript type checking
MIT