Skip to content

Add timely extension#25085

Merged
raycastbot merged 6 commits intoraycast:mainfrom
jakedohm:ext/timely
Mar 7, 2026
Merged

Add timely extension#25085
raycastbot merged 6 commits intoraycast:mainfrom
jakedohm:ext/timely

Conversation

@jakedohm
Copy link
Contributor

@jakedohm jakedohm commented Feb 2, 2026

Description

Screencast

Checklist

@jakedohm jakedohm marked this pull request as ready for review February 2, 2026 20:33
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 2, 2026

Greptile Summary

This PR introduces a new Timely extension that lets users search and create Timely projects directly from Raycast, using a manual PKCE OAuth flow (since Timely doesn't natively support PKCE challenge parameters).

  • Bug: providerIcon in oauth.ts references "extension-icon.png", which does not exist — the actual asset is "timely-icon.png". This breaks the icon display in the OAuth connection dialog.
  • Inconsistency: getClients correctly filters to active-only records (?show=active), but getProjects fetches all projects including archived/inactive ones.
  • Config (.prettierrc, eslint.config.js, CHANGELOG.md) follows the required Raycast standards, metadata screenshots are present, and the Preferences type is correctly auto-generated rather than manually defined.

Confidence Score: 3/5

  • The extension has one clear bug (missing icon asset reference) that should be fixed before merging.
  • The overall structure and logic are sound, but the broken providerIcon reference in the OAuth client is a concrete bug that affects the user-facing connection dialog. Everything else — auth flow, project/client fetching, form handling, and config — is well-implemented.
  • extensions/timely/src/lib/oauth.ts (providerIcon mismatch), extensions/timely/src/lib/timely-api.ts (inactive project filtering)

Important Files Changed

Filename Overview
extensions/timely/src/lib/oauth.ts Implements PKCE OAuth flow with manual token exchange (Timely doesn't support PKCE params). Has a broken providerIcon reference ("extension-icon.png" instead of "timely-icon.png"). Token refresh logic is otherwise correct.
extensions/timely/src/lib/timely-api.ts Clean API wrapper with typed responses. getClients filters by active status but getProjects does not, causing archived projects to appear in search results.
extensions/timely/src/timely.tsx Search Projects command with proper loading/error states, cancel-on-unmount pattern, and project list rendering. No issues found.
extensions/timely/src/create-project.tsx Create Project form with client dropdown, submit validation, and post-creation browser open. No issues found.
extensions/timely/src/hooks/useTimely.ts Custom hook that handles auth + account resolution with proper cancellation on unmount. Always uses the first Timely account.
extensions/timely/package.json Extension manifest with valid category (Productivity), macOS + Windows platforms, and two correctly-configured preferences for OAuth credentials.
extensions/timely/eslint.config.js ESLint config correctly uses defineConfig from "eslint/config" with @raycast/eslint-config.

Last reviewed commit: ec595ef

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +16 to +28
"commands": [
{
"name": "timely",
"title": "Search Projects",
"description": "Search Timely projects and open or copy them",
"mode": "view"
},
{
"name": "create-project",
"title": "Create Project",
"description": "Create a new Timely project",
"mode": "view"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing metadata/ folder with screenshots - extensions with view-type commands require Raycast-styled screenshots

Create a metadata/ folder with screenshots showing the extension in action. See: https://developers.raycast.com/basics/prepare-an-extension-for-store#screenshots

Context Used: Rule from dashboard - What: Extensions with view-type commands must include a metadata/ folder containing Raycast-styled... (source)

jakedohm and others added 2 commits February 2, 2026 15:51
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
- Merge branch \'contributions/merge-1770087012374\'
- Pull contributions
- Adding metadata with command screenshots
@raycastbot
Copy link
Collaborator

Congratulations on your new Raycast extension! 🚀

We're currently experiencing a high volume of incoming requests. As a result, the initial review may take up to 10-15 business days.

Once the PR is approved and merged, the extension will be available on our Store.

@jakedohm
Copy link
Contributor Author

jakedohm commented Feb 3, 2026

Not sure why the check pull_request step is failing, everything compiles & runs when I run npm run build locally.

If you can point me in the right direction, I'm more than happy to fix!

@0xdhrv 0xdhrv self-assigned this Feb 16, 2026
@0xdhrv
Copy link
Contributor

0xdhrv commented Feb 16, 2026

@greptileai, could you please do a fresh review of this PR?

@0xdhrv
Copy link
Contributor

0xdhrv commented Feb 16, 2026

Not sure why the check pull_request step is failing, everything compiles & runs when I run npm run build locally.

If you can point me in the right direction, I'm more than happy to fix!

https://github.com/raycast/extensions/actions/runs/21614928250/job/62291472893?pr=25085#step:7:439

The type check is failing

@0xdhrv 0xdhrv marked this pull request as draft February 16, 2026 11:43
@raycastbot
Copy link
Collaborator

This pull request has been automatically marked as stale because it did not have any recent activity.

It will be closed if no further activity occurs in the next 7 days to keep our backlog clean 😊

@raycastbot raycastbot added the status: stalled Stalled due inactivity label Mar 2, 2026
@raycastbot raycastbot removed the status: stalled Stalled due inactivity label Mar 6, 2026
@jakedohm
Copy link
Contributor Author

jakedohm commented Mar 6, 2026

Was able to resolve the TypeScript errors! Let's get this thing merged 😉

@0xdhrv 0xdhrv marked this pull request as ready for review March 7, 2026 04:29
Copy link
Contributor

@0xdhrv 0xdhrv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, approved ✅

@raycastbot raycastbot merged commit c2c1e0d into raycast:main Mar 7, 2026
2 checks passed
@github-actions
Copy link
Contributor

github-actions bot commented Mar 7, 2026

Published to the Raycast Store:
https://raycast.com/Dohm/timely

@raycastbot
Copy link
Collaborator

🎉 🎉 🎉

Such a great contribution deserves a reward, but unfortunately we couldn't find your Raycast account based on your GitHub username (@jakedohm).

Please link your GitHub account to your Raycast account to receive your credits and soon be able to exchange them for some swag.

const oauthClient = new OAuth.PKCEClient({
redirectMethod: OAuth.RedirectMethod.Web,
providerName: "Timely",
providerIcon: "extension-icon.png",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect providerIcon filename

"extension-icon.png" does not exist in the assets/ folder — the actual icon is "timely-icon.png" (matching the "icon" field in package.json). This will cause a broken/missing icon in the Timely OAuth connection dialog.

Suggested change
providerIcon: "extension-icon.png",
providerIcon: "timely-icon.png",

Comment on lines +60 to +67
export async function getProjects(accessToken: string, accountId: number): Promise<TimelyProject[]> {
const res = await timelyFetch(accessToken, `/${accountId}/projects`);
if (!res.ok) {
const text = await res.text();
throw new Error(`Timely API: ${res.status} ${res.statusText}${text ? ` - ${text}` : ""}`);
}
return (await res.json()) as TimelyProject[];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Archived projects are not filtered out

getClients correctly passes ?show=active to exclude inactive clients, but getProjects fetches all projects regardless of their active status. This means archived/inactive projects will appear alongside active ones in the Search Projects list.

Consider adding a filter to exclude inactive projects:

Suggested change
export async function getProjects(accessToken: string, accountId: number): Promise<TimelyProject[]> {
const res = await timelyFetch(accessToken, `/${accountId}/projects`);
if (!res.ok) {
const text = await res.text();
throw new Error(`Timely API: ${res.status} ${res.statusText}${text ? ` - ${text}` : ""}`);
}
return (await res.json()) as TimelyProject[];
}
export async function getProjects(accessToken: string, accountId: number): Promise<TimelyProject[]> {
const res = await timelyFetch(accessToken, `/${accountId}/projects?filter=active`);
if (!res.ok) {
const text = await res.text();
throw new Error(`Timely API: ${res.status} ${res.statusText}${text ? ` - ${text}` : ""}`);
}
return (await res.json()) as TimelyProject[];
}

(Verify the exact query parameter for filtering active projects against the Timely API docs, as the parameter name may differ from the clients endpoint.)

LlaziG added a commit to LlaziG/raycast-extensions that referenced this pull request Mar 7, 2026
- chore(hugeicons-ui):Update hugeicons-ui: bump @hugeicons/core-free-icons and @hugeicons/react
- [Skills] Display Metadata from SKILL.md frontmatter (raycast#26101)
- Update CODEOWNERs (c2c1e0d)
- Add timely extension (raycast#25085)
- Fix: copy prompt/answer for selected message (raycast#25438)
- Update CODEOWNERs (46ecffc)
- Update todoist extension (raycast#26087)
- Dia: update @raycast/utils to 2.2.3 (raycast#26091)
- Update CODEOWNERs (3503a64)
- Add typewhisper extension (raycast#25733)
- Update CODEOWNERs (5ea5ef7)
- Add number-research extension (raycast#26060)
- Update trustmrr extension (raycast#26085)
- Update CODEOWNERs (40aabef)
- Add desktoprenamer extension (raycast#24610)
- Update tailwindcss extension (raycast#26067)
- Update CODEOWNERs (7a13ffd)
- Update time-awareness extension (raycast#25765)
- Update CODEOWNERs (6c50032)
- Update github-status extension (raycast#26063)
- Update anna-s-archive extension (raycast#26076)
- Update CODEOWNERs (46b879a)
- Update shopify-developer-changelog extension (raycast#25711)
- Update CODEOWNERs (22aa04d)
- Update weather extension (raycast#26074)
- Update kagi-news extension (raycast#25679)
- Update (raycast#26073)
- Update teak-raycast extension (raycast#25995)
- otp-inbox: Add Windows support (raycast#25441)
- Update CODEOWNERs (36e7a5f)
- Add trustmrr extension (raycast#26069)
- Update CODEOWNERs (d7c540c)
- Add doubao-tts extension (raycast#25705)
- GitHub: Improve auto-merge support (raycast#25256)
- Update CODEOWNERs (9f556d5)
- Update microsoft-edge extension add new feat to search and launch workspaces (raycast#25335)
- Add RouteMesh MCP server to model-context-protocol-registry (raycast#25960)
- feat: Add Advanced Batch Rename command with rule-based engine (raycast#25501)
- Update media-converter extension (raycast#25836)
- Update scheduler extension (raycast#26059)
- Docs: Update the utils docs
- [pipe-commands] Add data formatting utilities (raycast#25824)
- Update CODEOWNERs (5b660b2)
- Add hdri-library extension (raycast#25701)
- Update CODEOWNERs (2ea8b9c)
- Update ente-auth extension (raycast#25773)
- Update CODEOWNERs (b9b9e2b)
- Add grpcui extension (raycast#25697)
- Update CODEOWNERs (1730346)
- Update openrouter model search extension (raycast#26045)
- System Monitor: Fix stale temperature readings in menubar (raycast#26025)
- Update CODEOWNERs (4e3ff41)
- Fix truncated row values in pass extension (raycast#25843)
- Update CODEOWNERs (489aede)
- Add quickreferences-raycast extension (raycast#23629)
- Update CODEOWNERs (84a0a58)
- Update cleanshotx extension (raycast#25985)
- [ccusage] Hide "Usage Limits" details when using non-OAuth authentication (raycast#26009)
- Browser Bookmarks: Add support for Perplexity Comet browser (raycast#25874)
- Add Windows support (raycast#25882)
- Update bmrks extension (raycast#25952)
- Update CODEOWNERs (2faa166)
- Update radarr extension (raycast#25953)
- Update CODEOWNERs (d8b0e95)
- Update google-chrome extension (raycast#25939)
- Add PrusaConnect links to Prusa extension (raycast#25955)
- Update CODEOWNERs (9f8c615)
- Claude Code Launcher: Fix Ghostty PATH by using interactive shell (raycast#25976)
- Update aave-search extension (raycast#26016)
- uuid-generator: add Pack Type Id command (raycast#25800)
- Update CODEOWNERs (39fe5d1)
- [ccusage] Fix npx path resolution for fnm installs using XDG directories (raycast#26008)
- fix(arc): prevent duplicate windows when Arc is not running (raycast#25806)
- System Monitor: Add pin-to-display for menubar stats (raycast#25821)
- Update CODEOWNERs (ec57b0b)
- Add unified Wispr Flow extension (raycast#25218)
- Update shadcn ui extension (raycast#26011)
- Update CODEOWNERs (b354d33)
- feat(gumroad): add price filter and copy actions (raycast#25703)
- Update CODEOWNERs (134d6f9)
- Add raycast-ai-custom-providers extension (raycast#25180)
- Update CODEOWNERs (4accbb2)
- Add zo-raycast extension (raycast#25464)
- Update CODEOWNERs (227732f)
- Add job-dojo extension (raycast#25677)
- Update CODEOWNERs (eace185)
- Add wallhaven extension (raycast#25656)
- Update existing somafm extension: launch flow, refresh toasts, menu fallback (raycast#25187)
- Update CODEOWNERs (d0f014f)
- Add email-finder extension (raycast#24847)
- Update cut-out extension (raycast#25990)
- Update CODEOWNERs (1ef7a10)
- Add cut-out extension (raycast#25663)
- [Pokedex] Added support for Scarlet & Violet–style sprite artwork (raycast#25986)
- Discogs extension new functions (raycast#25686)
- Update nhk-program-search extension (raycast#25967)
- Update kimi extension (raycast#25962)
- Update CODEOWNERs (de246c1)
- Update shiori-sh extension (raycast#25944)
- fix(browser-bookmarks): fix slow initial load and open-in-browser reliability (raycast#25979)
- Update CODEOWNERs (0ad09cd)
- Add spacer extension (raycast#25652)
- [zotero] Fix Zotero 7+ / Better BibTeX compatibility (raycast#25634)
- Docs: update for the new API release
- added ARM64 sdk support (raycast#25966)
- Update CODEOWNERs (3051c01)
- Add Bird extension (raycast#25481)
- Update CODEOWNERs (7c4f8af)
- Add Lock Time extension (raycast#25255)
- Update CODEOWNERs (cdc0ceb)
- Add paste-safely extension (raycast#25951)
- Update CODEOWNERs (bd032c8)
- Add polars-documentation-search extension (raycast#25589)
- Update CODEOWNERs (564b0f2)
- Add DevContainer Features extension (raycast#25603)
- Update CODEOWNERs (2cdb8f6)
- Update gift-stardew-valley extension (raycast#25552)
- Update CODEOWNERs (f728891)
- Update Inkdrop extension (raycast#25529)
- Sourcegraph: Setup improvements (raycast#25950)
- [Skills] Add support for updating skills (raycast#25887)
- Update CODEOWNERs (cb956f6)
- Add search repositories feature for Github for Enterprise (raycast#25661)
- Fix/trakt manager user agent v2 (raycast#25825)
- Update `CricketCast` extension - add menu bar for scores (raycast#25942)
- Add Windows platform support to Goodreads extension (raycast#25936)
- idonthavespotify: Add Qobuz, Bandcamp, Pandora support & fix crash on unknown adapters (raycast#25937)
- Update singularityapp extension (raycast#25943)
- Update raycast-surge extension (raycast#25883)
- Update awork extension (raycast#25844)
- Update extend-display extension (raycast#25894)
- Update git-worktrees extension (raycast#25898)
- [Image Modification] Fix QSpace / QSpace Pro selection detection (raycast#25923)
- Update zeabur extension (raycast#25924)
- Update vietnamese-calendar extension (raycast#25917)
- [AzTU LMS] Fix Color & Add New Image (raycast#25912)
- Update CODEOWNERs (c2aba2b)
- Add Hop extension (raycast#25162)
- [Music Assistant Controls]:  Big update with many features (raycast#25860)
- [MXroute] set mail hosting status + open webmail link (raycast#25895)
- Update kitty extension (raycast#25856)
- Update CODEOWNERs (b73dbee)
- Addeed SDK implementation (raycast#25820)
- Update CODEOWNERs (66857dc)
- Add notilight-controller extension (raycast#25424)
- Update raycast-store-updates extension (raycast#25865)
- Update reader-mode extension (raycast#25872)
- Update CODEOWNERs (f8eeb0d)
- Update battery-optimizer extension (raycast#25509)
- fix: show window icons on first load in window-walker extension (raycast#25871)
- Update CODEOWNERs (7e705b7)
- Update t3 chat extension (raycast#25803)
- Update CODEOWNERs (19f337b)
- Update modify-hash extension (raycast#25816)
- Update CODEOWNERs (64e21d0)
- Add `ZeroSSL` extension - list certificates, view + validate csr (raycast#25861)
- [Cron Manager] Fix tasks disappearing from UI & permission handling (raycast#25845)
- Update CODEOWNERs (abe1d59)
- Add markdown-converter extension (raycast#24129)
- Update betaseries extension (raycast#25842)
- [Skills] Inline detail Panel (raycast#25658)
- Update CODEOWNERs (f1bac6d)
- Removed two extensions (raycast#25851)
- Update CODEOWNERs (53db7b3)
- Add shiori-sh extension (raycast#25757)
- Docs: update for the new API release
- feat(everything-search): allow custom cli arguments (raycast#24607)
- Update CODEOWNERs (93ff0be)
- Delete extensions/proton-pass-client directory (raycast#25841)
- update (raycast#25840)
- Update CODEOWNERs (d85419c)
- Add kaneo-for-raycast extension (raycast#25461)
- [Apple Reminders] Prevent accidental recurring reminders from AI (raycast#25746)
- [Apple Notes] Fix AI tool note ID mismatch, timeout, and search filtering (raycast#25720)
- fix: show window icons on first load in window-walker extension (raycast#25818)
- [Namecheap] fix error when no domain dns hosts (raycast#25827)
- Update youversion-suggest extension (raycast#25797)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants