Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
058dc14
feat(jira): adds Jira Cloud integration
wgordon17 Apr 24, 2026
eeb2c0d
fix(jira): addresses review findings from Phase 4 + 4.5
wgordon17 Apr 24, 2026
48c0156
docs(jira): adds Jira integration setup and usage documentation
wgordon17 Apr 24, 2026
a28d834
fix(jira): resolves all remaining review findings and test gaps
wgordon17 Apr 24, 2026
9e3c6f7
test(jira): adds missing Jira tracked item and tab filter tests
wgordon17 Apr 24, 2026
a2e7b93
test(jira): adds TrackedTab Jira component tests and docs
wgordon17 Apr 24, 2026
da6fe94
fix(jira): address 23 PR review findings
wgordon17 Apr 24, 2026
dc599e0
fix(jira): harden expires_in guard in callback against undefined/NaN
wgordon17 Apr 24, 2026
d5ab50f
fix(jira): adds Zod validation for token exchange
wgordon17 Apr 24, 2026
d568576
fix(jira): address PR review findings from code review cycle
wgordon17 Apr 24, 2026
a01e813
fix(jira): local dev fixes and error observability
wgordon17 Apr 25, 2026
38478f8
fix(jira): stabilize tab data and add sort/density/collapse
wgordon17 Apr 25, 2026
d9abcb4
fix(jira): address quality gate review findings
wgordon17 Apr 25, 2026
6e35e9b
fix(jira): address Layer 2 adversarial review findings
wgordon17 Apr 25, 2026
3a3b007
fix(jira): moves fetch guard to module scope
wgordon17 Apr 25, 2026
dbe3c24
fix(jira): adds siteUrl guard to JiraBadge, auto-expands groups
wgordon17 Apr 25, 2026
e65d6b2
fix(jira): adds tests for new features, hardens sort lookup
wgordon17 Apr 25, 2026
a9c5365
fix(jira): uses group-aware pagination, natural key sort, test reset
wgordon17 Apr 25, 2026
f03be25
fix(jira): backfills siteUrl from auth, normalizes priority names
wgordon17 Apr 25, 2026
2cd83d8
fix(jira): removes redundant assignee, inlines compact title
wgordon17 Apr 25, 2026
0389b3a
feat(jira): renders issue type icons with hover tooltips
wgordon17 Apr 25, 2026
25d4647
fix(jira): uses Tooltip component for issue type hover
wgordon17 Apr 25, 2026
815d402
fix(jira): adds text fallback when issue type icon is missing
wgordon17 Apr 25, 2026
4bfd869
chore(jira): adds dev-only diagnostic for missing issuetype
wgordon17 Apr 25, 2026
3ae7a6b
fix(jira): falls back to text badge when icon blocked by client
wgordon17 Apr 25, 2026
650ed81
feat(jira): adds inline SVG fallback icons for common issue types
wgordon17 Apr 25, 2026
77ee660
chore(jira): adds dev-only key detection diagnostic
wgordon17 Apr 25, 2026
0e889db
chore(jira): adds guard-level diagnostic for key detection
wgordon17 Apr 25, 2026
f155581
fix(jira): removes defer from key detection effect
wgordon17 Apr 25, 2026
ac50430
feat(jira): adds source tooltip to JiraBadge (title vs branch)
wgordon17 Apr 25, 2026
2ec2746
fix(jira): improves JiraBadge tooltip with summary and source prefix
wgordon17 Apr 25, 2026
26a5e45
fix(jira): refines JiraBadge tooltip content
wgordon17 Apr 25, 2026
8380f2e
fix(jira): adds priority sort type with correct labels
wgordon17 Apr 25, 2026
96dc61e
feat(jira): improves sort options and moves badges right
wgordon17 Apr 26, 2026
bcbc0f3
feat(jira): adds SDLC sub-ordering for indeterminate statuses
wgordon17 Apr 26, 2026
6c95276
fix(jira): changes default sort to Status (To Do → Done)
wgordon17 Apr 26, 2026
a7d236f
test(jira): temporarily switches JQL to reporter for UAT
wgordon17 Apr 26, 2026
3b843b3
feat(jira): adds scope dropdown for assigned/created/watching
wgordon17 Apr 26, 2026
a82f4dd
fix(jira): pins filter toolbar with sticky positioning
wgordon17 Apr 26, 2026
f9908a7
revert(jira): removes broken sticky toolbar positioning
wgordon17 Apr 26, 2026
f1b26bc
fix(jira): address PR review findings — security, correctness, tests
wgordon17 Apr 26, 2026
5320a0f
fix(jira): adds auth guard test, explicit array join
wgordon17 Apr 26, 2026
2d55e6e
chore: merges upstream/main into jira branch
wgordon17 Apr 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .dev.vars.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
GITHUB_CLIENT_ID=your_client_id_here
GITHUB_CLIENT_SECRET=your_client_secret_here
# Note: ALLOWED_ORIGIN must match the registered OAuth callback origin.
# For Jira local dev, this must be http://localhost:5173 — the Worker constructs
# redirect_uri as ${ALLOWED_ORIGIN}/jira/callback, which Atlassian validates against
# the registered callback URLs in your Atlassian Developer Console app settings.
ALLOWED_ORIGIN=http://localhost:5173
SESSION_KEY=your-base64-encoded-32-byte-key
SEAL_KEY=your-base64-encoded-32-byte-key
TURNSTILE_SECRET_KEY=your-turnstile-secret-from-cf-dashboard
# Optional: only needed if Sentry "Allowed Domains" is configured in your Sentry project settings
# SENTRY_SECURITY_TOKEN=your-sentry-security-token

# ── Jira Cloud Integration (optional) ─────────────────────────────────────────
# Get these from the Atlassian Developer Console: https://developer.atlassian.com/console/myapps/
# Create an OAuth 2.0 (3LO) app, add read:jira-work scope, set callback to ${ALLOWED_ORIGIN}/jira/callback
# JIRA_CLIENT_ID=your-jira-oauth-client-id
# JIRA_CLIENT_SECRET=your-jira-oauth-client-secret
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ GITHUB_TOKEN=your_github_token_here
# Default: 9876
# MCP_WS_PORT=9876

# ── Jira Cloud Integration (optional) ─────────────────────────────────────────
# Public Jira OAuth client ID — embedded into client-side bundle at build time by Vite.
# This is public information (visible in the OAuth authorize URL).
# VITE_JIRA_CLIENT_ID=your-jira-oauth-client-id

# ── Turnstile (Cloudflare) ─────────────────────────────────────────────────────
# Public site key — embedded into client-side bundle at build time by Vite.
# This is public information (visible in the Turnstile widget script).
Expand Down
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ pnpm run dev

The dev server starts at `http://localhost:5173`. You'll need a GitHub OAuth app client ID in `.env` (copy `.env.example` and fill in your value).

**Jira integration (optional):** The Jira Cloud integration is opt-in. Tests run without Jira credentials. To develop or test the Jira features locally:

1. Add `VITE_JIRA_CLIENT_ID=<your-atlassian-oauth-client-id>` to `.env` — this gates visibility of the Jira section in Settings
2. Add `JIRA_CLIENT_ID` and `JIRA_CLIENT_SECRET` to `.dev.vars` (copy from `.dev.vars.example`) — these are used by the Cloudflare Worker for OAuth token exchange

In production, provision `JIRA_CLIENT_ID` and `JIRA_CLIENT_SECRET` as Worker secrets via `wrangler secret put`. Never commit them to `.env` or `.dev.vars`.

The repo uses a pnpm workspace: the root package is the SolidJS SPA; `mcp/` is a separate package (`github-tracker-mcp`) built with tsup. Running `pnpm install` at the root installs both.

To run the MCP server in standalone mode, set `GITHUB_TOKEN` before starting:
Expand Down
3 changes: 1 addition & 2 deletions DEPLOY.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,12 @@ Cloudflare Worker secrets are set. In CI, the deploy workflow runs

### Scopes

The login flow requests `scope=repo read:org notifications`:
The login flow requests `scope=repo read:org`:

| Scope | Used for |
|-------|----------|
| `repo` | Read issues, PRs, check runs, workflow runs (includes private repos) |
| `read:org` | `GET /user/orgs` — list user's organizations for the org selector |
| `notifications` | `GET /notifications` — polling optimization gate (304 = skip full fetch) |

**Note:** The `repo` scope grants write access to repositories, but this app never performs write operations (POST/PUT/PATCH/DELETE on repo endpoints). It is read-only by design.

Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ A second, faster poll loop (default 30s, configurable 10–120s) targets only in

### Desktop Notifications

Browser notifications for new issues, PRs, and failed runs. Per-type toggles in settings. Notification permission requested on first enable. Uses the GitHub Notifications API as a change-detection gate when the `notifications` scope is available.
Browser notifications for new issues, PRs, and failed runs. Per-type toggles in settings. Notification permission requested on first enable. New items are detected via the Events API polling loop and full refresh cycles.

### Repo Pinning and Reordering

Expand All @@ -77,6 +77,10 @@ Star counts appear in repo group headers, fetched as part of the standard data r

Create named filtered views over the existing Issues, PRs, and Actions data. Each custom tab has a name, a base type (Issues, PRs, or Actions), an optional org/repo scope, and optional filter presets. An "exclusive" toggle hides matching items from the standard tabs so they only appear in the custom tab. Up to 10 custom tabs can be created. Manage them via the "+" button in the tab bar or in **Settings > Custom Tabs**.

### Jira Cloud Integration

Opt-in Jira Cloud integration: auto-detect Jira issue keys in GitHub issue and PR titles and display inline status badges, view your assigned Jira issues in a dedicated tab with status/priority filters, and bookmark Jira issues to the Tracked tab alongside GitHub items. Supports OAuth 2.0 (3LO) and API token authentication.

### Themes

9 themes: auto (follows system), corporate, cupcake, light, nord, dim, dracula, dark, forest. Theme is applied immediately on selection with no page reload.
Expand All @@ -87,7 +91,7 @@ Hide specific items with a persistent ignore list. An "N ignored" badge on the r

### ETag Caching and Auto-Refresh

Conditional requests using `If-None-Match` headers — GitHub doesn't count 304 responses against the rate limit. Background polling keeps data fresh even when the tab is hidden (when the notifications scope is available for efficient change detection).
Conditional requests using `If-None-Match` headers — GitHub doesn't count 304 responses against the rate limit. A 60-second events poll uses ETag requests to detect changes and trigger targeted per-repo refreshes, keeping data fresh even in background tabs at zero rate-limit cost.

## Tech Stack

Expand Down
Loading