Skip to content

Add Simple Timer extension#26567

Draft
dejwv wants to merge 3 commits intoraycast:mainfrom
dejwv:add-simple-timer
Draft

Add Simple Timer extension#26567
dejwv wants to merge 3 commits intoraycast:mainfrom
dejwv:add-simple-timer

Conversation

@dejwv
Copy link
Copy Markdown

@dejwv dejwv commented Mar 23, 2026

Description

A keyboard-first timer extension for Raycast on Windows. Supports timers, stopwatch, and Pomodoro sessions with background operation via .NET worker.

Screencast

Screenshots are included in the metadata/ folder.

Checklist

@raycastbot raycastbot added new extension Label for PRs with new extensions platform: Windows labels Mar 23, 2026
@raycastbot
Copy link
Copy Markdown
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.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 23, 2026

Greptile Summary

This PR adds a new Simple Timer extension for Raycast on Windows, providing a keyboard-first timer with stopwatch and Pomodoro modes backed by a native .NET worker process for background operation. The overall architecture is well thought-out, but there are two TypeScript compilation errors that will prevent the extension from building, plus a platform misconfiguration and a potentially disruptive system-level side effect.

Key issues found:

  • package.json declares platforms: ["windows"] (lowercase), which must be "Windows" to pass schema validation and load correctly on Windows.
  • src/utils.ts declares the PomodoroInput interface twice (lines 215 and 223), causing a TypeScript duplicate-identifier error that breaks the build.
  • src/pomodoro-running.tsx declares toggleNotifications twice (lines 59 and 67), also a TypeScript compilation error; additionally setNotificationsState(...) is called redundantly on consecutive lines 34–35.
  • src/sound.ts: stopAllAlertSounds() issues taskkill /IM powershell.exe /F, which kills every PowerShell process running on the user's system — not just the extension's own sound processes — and could disrupt unrelated user workflows.
  • CHANGELOG.md: Both entries use the hardcoded date 2026-03-23 instead of the required {PR_MERGE_DATE} placeholder.

Confidence Score: 2/5

  • Not safe to merge — two TypeScript compilation errors prevent the extension from building, and a platform misconfiguration would prevent it from loading.
  • The duplicate PomodoroInput interface and duplicate toggleNotifications function are hard compilation blockers; the incorrect "windows" platform casing is a schema validation failure. All three must be resolved before the extension can be built and published. The system-wide taskkill is an additional behavioral concern worth addressing before release.
  • src/utils.ts (duplicate interface), src/pomodoro-running.tsx (duplicate function + duplicate state call), package.json (platform casing), and src/sound.ts (system-wide process kill).

Important Files Changed

Filename Overview
extensions/simple-timer/package.json Platform entry uses lowercase "windows" instead of the required "Windows" — this will fail Raycast schema validation.
extensions/simple-timer/src/pomodoro-running.tsx Two blocking issues: toggleNotifications is declared twice (TypeScript compilation error) and setNotificationsState is called redundantly twice inside refresh().
extensions/simple-timer/src/utils.ts PomodoroInput interface is declared twice (lines 215 and 223), causing a TypeScript duplicate identifier error that prevents the build.
extensions/simple-timer/src/sound.ts stopAllAlertSounds() uses taskkill /IM powershell.exe /F which terminates all PowerShell processes on the system, not just extension-owned ones.
extensions/simple-timer/src/timer-state.ts Core state management using a JSON file with a native .NET worker daemon. Logic is sound; dynamic require() inside functions is a minor style concern.
extensions/simple-timer/src/index.tsx Main view with input parsing, suggestions, and nested navigation; require() used dynamically inside component functions instead of top-level ES module imports.
extensions/simple-timer/CHANGELOG.md Both entries use a hardcoded date 2026-03-23 instead of the required {PR_MERGE_DATE} placeholder.
extensions/simple-timer/src/active-timers.tsx Clean list view for active/paused timers; polls every 500 ms and auto-pops when empty.
extensions/simple-timer/src/finished-timers.tsx Finished timer list with dismiss/cancel actions; state is refreshed via polling and screen auto-closes when queue empties.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/simple-timer/package.json
Line: 87

Comment:
**Invalid platform capitalization**

The `platforms` value `"windows"` uses incorrect casing. Per the Raycast schema, the correct value is `"Windows"` (Title Case). Using lowercase may cause the extension to fail validation or not load correctly.

```suggestion
    "Windows"
```

**Rule Used:** What: Ensure `platforms` only contains macOS and/o... ([source](https://app.greptile.com/review/custom-context?memory=b3b94d4e-bae6-49ea-b437-ed0f62a1456c))

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/simple-timer/src/utils.ts
Line: 223-230

Comment:
**Duplicate interface declaration causes a TypeScript error**

`PomodoroInput` is declared twice — once at line 215 and again at line 223. TypeScript does not allow duplicate interface identifiers in the same module scope, so this will cause a compilation error and the extension will fail to build. The second declaration is an exact copy and should be removed.

```suggestion

```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/simple-timer/src/pomodoro-running.tsx
Line: 67-72

Comment:
**Duplicate function declaration causes a TypeScript error**

`toggleNotifications` is already declared at line 59. Declaring it a second time here is a copy-paste artifact that will produce a "Duplicate identifier 'toggleNotifications'" TypeScript error, preventing the extension from building. The second declaration should be removed.

```suggestion

```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/simple-timer/src/pomodoro-running.tsx
Line: 34-35

Comment:
**Duplicate `setNotificationsState` call**

`setNotificationsState(state.notificationsEnabled ?? true)` is called twice in a row. While harmless in practice (both calls set the same value), the second call is redundant and is likely an unintentional copy-paste error. Remove one of them.

```suggestion
    setNotificationsState(state.notificationsEnabled ?? true);
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/simple-timer/src/sound.ts
Line: 99-101

Comment:
**Kills all `powershell.exe` processes system-wide**

`taskkill /IM powershell.exe /F` terminates every running PowerShell process on the machine, not just the ones spawned by this extension. If the user has unrelated scripts or automation running in PowerShell at that moment, they will be forcibly killed with no warning. The comment says "covers both Raycast and worker sound processes," but the individual PID-based approach above already handles the in-memory sound processes. Consider only killing the tracked PIDs instead of broadcasting a process-wide kill.

```suggestion
  // All per-timer pids are already killed above; skip the broadcast kill.
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/simple-timer/CHANGELOG.md
Line: 3

Comment:
**Hardcoded dates should use `{PR_MERGE_DATE}` placeholder**

Both changelog entries (lines 3 and 11) use a hardcoded date `2026-03-23` instead of the standard `{PR_MERGE_DATE}` template variable. Since neither version has been released yet, both should use the placeholder so the merge date is automatically substituted during release.

```suggestion
## [1.0.1] - {PR_MERGE_DATE}
```

**Rule Used:** What: Changelog entries must use `{PR_MERGE_DATE}`... ([source](https://app.greptile.com/review/custom-context?memory=c2214c11-df56-490a-b1c0-09a385df481a))

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Add Simple Timer extension" | Re-trigger Greptile

Comment thread extensions/simple-timer/package.json Outdated
"publish": "npx @raycast/api@latest publish"
},
"platforms": [
"windows"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P0 Invalid platform capitalization

The platforms value "windows" uses incorrect casing. Per the Raycast schema, the correct value is "Windows" (Title Case). Using lowercase may cause the extension to fail validation or not load correctly.

Suggested change
"windows"
"Windows"

Rule Used: What: Ensure platforms only contains macOS and/o... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/simple-timer/package.json
Line: 87

Comment:
**Invalid platform capitalization**

The `platforms` value `"windows"` uses incorrect casing. Per the Raycast schema, the correct value is `"Windows"` (Title Case). Using lowercase may cause the extension to fail validation or not load correctly.

```suggestion
    "Windows"
```

**Rule Used:** What: Ensure `platforms` only contains macOS and/o... ([source](https://app.greptile.com/review/custom-context?memory=b3b94d4e-bae6-49ea-b437-ed0f62a1456c))

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +223 to +230
export interface PomodoroInput {
workSeconds: number;
breakSeconds: number;
note: string;
maxCycles: number; // 0 = infinite
}

// Parse time string like: 25m, 5m30s, 1h30m, 45s, 2h, 33m40s
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P0 Duplicate interface declaration causes a TypeScript error

PomodoroInput is declared twice — once at line 215 and again at line 223. TypeScript does not allow duplicate interface identifiers in the same module scope, so this will cause a compilation error and the extension will fail to build. The second declaration is an exact copy and should be removed.

Suggested change
export interface PomodoroInput {
workSeconds: number;
breakSeconds: number;
note: string;
maxCycles: number; // 0 = infinite
}
// Parse time string like: 25m, 5m30s, 1h30m, 45s, 2h, 33m40s
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/simple-timer/src/utils.ts
Line: 223-230

Comment:
**Duplicate interface declaration causes a TypeScript error**

`PomodoroInput` is declared twice — once at line 215 and again at line 223. TypeScript does not allow duplicate interface identifiers in the same module scope, so this will cause a compilation error and the extension will fail to build. The second declaration is an exact copy and should be removed.

```suggestion

```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +67 to +72
function toggleNotifications() {
const next = !notificationsEnabled;
setNotificationsState(next);
setNotificationsInState(next);
showHUD(next ? "🔔 Notifications on" : "🔕 Notifications off");
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P0 Duplicate function declaration causes a TypeScript error

toggleNotifications is already declared at line 59. Declaring it a second time here is a copy-paste artifact that will produce a "Duplicate identifier 'toggleNotifications'" TypeScript error, preventing the extension from building. The second declaration should be removed.

Suggested change
function toggleNotifications() {
const next = !notificationsEnabled;
setNotificationsState(next);
setNotificationsInState(next);
showHUD(next ? "🔔 Notifications on" : "🔕 Notifications off");
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/simple-timer/src/pomodoro-running.tsx
Line: 67-72

Comment:
**Duplicate function declaration causes a TypeScript error**

`toggleNotifications` is already declared at line 59. Declaring it a second time here is a copy-paste artifact that will produce a "Duplicate identifier 'toggleNotifications'" TypeScript error, preventing the extension from building. The second declaration should be removed.

```suggestion

```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +34 to +35
setNotificationsState(state.notificationsEnabled ?? true);
setNotificationsState(state.notificationsEnabled ?? true);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Duplicate setNotificationsState call

setNotificationsState(state.notificationsEnabled ?? true) is called twice in a row. While harmless in practice (both calls set the same value), the second call is redundant and is likely an unintentional copy-paste error. Remove one of them.

Suggested change
setNotificationsState(state.notificationsEnabled ?? true);
setNotificationsState(state.notificationsEnabled ?? true);
setNotificationsState(state.notificationsEnabled ?? true);
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/simple-timer/src/pomodoro-running.tsx
Line: 34-35

Comment:
**Duplicate `setNotificationsState` call**

`setNotificationsState(state.notificationsEnabled ?? true)` is called twice in a row. While harmless in practice (both calls set the same value), the second call is redundant and is likely an unintentional copy-paste error. Remove one of them.

```suggestion
    setNotificationsState(state.notificationsEnabled ?? true);
```

How can I resolve this? If you propose a fix, please make it concise.

Comment thread extensions/simple-timer/src/sound.ts Outdated
Comment on lines +99 to +101
// Kill all powershell (covers both Raycast and worker sound processes)
try {
execSync(`taskkill /IM powershell.exe /F`, { stdio: "ignore" });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Kills all powershell.exe processes system-wide

taskkill /IM powershell.exe /F terminates every running PowerShell process on the machine, not just the ones spawned by this extension. If the user has unrelated scripts or automation running in PowerShell at that moment, they will be forcibly killed with no warning. The comment says "covers both Raycast and worker sound processes," but the individual PID-based approach above already handles the in-memory sound processes. Consider only killing the tracked PIDs instead of broadcasting a process-wide kill.

Suggested change
// Kill all powershell (covers both Raycast and worker sound processes)
try {
execSync(`taskkill /IM powershell.exe /F`, { stdio: "ignore" });
// All per-timer pids are already killed above; skip the broadcast kill.
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/simple-timer/src/sound.ts
Line: 99-101

Comment:
**Kills all `powershell.exe` processes system-wide**

`taskkill /IM powershell.exe /F` terminates every running PowerShell process on the machine, not just the ones spawned by this extension. If the user has unrelated scripts or automation running in PowerShell at that moment, they will be forcibly killed with no warning. The comment says "covers both Raycast and worker sound processes," but the individual PID-based approach above already handles the in-memory sound processes. Consider only killing the tracked PIDs instead of broadcasting a process-wide kill.

```suggestion
  // All per-timer pids are already killed above; skip the broadcast kill.
```

How can I resolve this? If you propose a fix, please make it concise.

Comment thread extensions/simple-timer/CHANGELOG.md Outdated
@@ -0,0 +1,53 @@
# Changelog

## [1.0.1] - 2026-03-23
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Hardcoded dates should use {PR_MERGE_DATE} placeholder

Both changelog entries (lines 3 and 11) use a hardcoded date 2026-03-23 instead of the standard {PR_MERGE_DATE} template variable. Since neither version has been released yet, both should use the placeholder so the merge date is automatically substituted during release.

Suggested change
## [1.0.1] - 2026-03-23
## [1.0.1] - {PR_MERGE_DATE}

Rule Used: What: Changelog entries must use {PR_MERGE_DATE}... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/simple-timer/CHANGELOG.md
Line: 3

Comment:
**Hardcoded dates should use `{PR_MERGE_DATE}` placeholder**

Both changelog entries (lines 3 and 11) use a hardcoded date `2026-03-23` instead of the standard `{PR_MERGE_DATE}` template variable. Since neither version has been released yet, both should use the placeholder so the merge date is automatically substituted during release.

```suggestion
## [1.0.1] - {PR_MERGE_DATE}
```

**Rule Used:** What: Changelog entries must use `{PR_MERGE_DATE}`... ([source](https://app.greptile.com/review/custom-context?memory=c2214c11-df56-490a-b1c0-09a385df481a))

How can I resolve this? If you propose a fix, please make it concise.

@raycastbot
Copy link
Copy Markdown
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 Apr 6, 2026
@0xdhrv 0xdhrv self-assigned this Apr 10, 2026
@raycastbot raycastbot removed the status: stalled Stalled due inactivity label Apr 10, 2026
Copy link
Copy Markdown
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.

Hey @dejwv 👋

Thank you for your contribution!

Can we try to extend the existing timer extension to add windows support, instead of creating a new one?

@0xdhrv 0xdhrv marked this pull request as draft April 10, 2026 09:34
@dejwv
Copy link
Copy Markdown
Author

dejwv commented Apr 10, 2026

Hey @dejwv 👋

Thank you for your contribution!

Can we try to extend the existing timer extension to add windows support, instead of creating a new one?

Hey, yes, that would be good as I vibe-coded this just because of missing windows timer. No need for 2 timers :)

@raycastbot
Copy link
Copy Markdown
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 Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new extension Label for PRs with new extensions platform: Windows status: stalled Stalled due inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants