Skip to content

Add to-do-s extension#27453

Open
Matias-Sandoval wants to merge 5 commits intoraycast:mainfrom
Matias-Sandoval:ext/to-do-s
Open

Add to-do-s extension#27453
Matias-Sandoval wants to merge 5 commits intoraycast:mainfrom
Matias-Sandoval:ext/to-do-s

Conversation

@Matias-Sandoval
Copy link
Copy Markdown

@Matias-Sandoval Matias-Sandoval commented Apr 26, 2026

Description

This is a new extension called Todos that allows users to quickly manage their daily tasks directly from Raycast.

Key Features:

  • Create custom categories to organize todos logically.
  • Pick a custom color for each category, which automatically styles the UI and icons.
  • Add, edit, delete, and mark todos as completed.
  • Completed tasks are automatically sorted by completion date (most recent first).
  • Built entirely with native Raycast UI components for a seamless, fast, and familiar macOS experience.

Screencast

1 2

Checklist

- Update extension icon
- Initial commit: Todos extension
@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.

- Rename extension title to Todos
- Update extension and command titles to match Raycast guidelines
@Matias-Sandoval Matias-Sandoval marked this pull request as ready for review April 27, 2026 03:29
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 27, 2026

Greptile Summary

This PR introduces a new To-do's Raycast extension that lets users manage daily tasks grouped into color-coded categories, with full CRUD support and automatic sorting of completed items. The implementation is clean and makes good use of native Raycast components.

  • Missing metadata/ folder: The extension has a view-mode command but no metadata/ folder with Raycast-styled screenshots, which is required for Raycast Store submission.
  • Unused dependency: @raycast/utils is listed in package.json but never imported anywhere in src/.

Confidence Score: 3/5

Not ready to merge — missing required metadata screenshots for store submission.

A P1 finding (missing metadata folder, which blocks store publishing) caps the score at 4, and the combination with several P2s brings it down to 3.

A metadata/ folder with Raycast-styled screenshots must be added before this extension can be published to the store.

Important Files Changed

Filename Overview
extensions/to-do-s/package.json @raycast/utils is declared as a dependency but never imported in any source file; also missing required metadata folder for store screenshots.
extensions/to-do-s/src/storage.ts LocalStorage-backed CRUD layer for categories and todos; uses Date.now() for IDs which risks collision on rapid creation.
extensions/to-do-s/src/categories.tsx Main categories list view with create/edit/delete flows; well-structured with correct use of Raycast API.
extensions/to-do-s/src/category-todos.tsx Per-category todo list with toggle, edit, and delete; onUpdate() is called on every loadTodos including initial mount, causing unnecessary parent reloads.
extensions/to-do-s/src/types.ts Clean type definitions for Todo, Category, and AppData; no issues.
extensions/to-do-s/src/new-todo.tsx Entry-point that simply re-exports CategoriesView; no issues.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/to-do-s/package.json
Line: 17-23

Comment:
**Missing `metadata/` folder with store screenshots**

The extension declares a `view`-mode command but no `metadata/` folder with Raycast-styled screenshots is present in the PR. This folder is required for publishing to the Raycast Store — the submission will be rejected without it.

See the [store preparation docs](https://developers.raycast.com/basics/prepare-an-extension-for-store#screenshots) for the expected format and naming convention.

**Rule Used:** What: Extensions with view-type commands must incl... ([source](https://app.greptile.com/review/custom-context?memory=87059ac1-c601-487f-9f1c-bce8a3cb6209))

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/to-do-s/package.json
Line: 27

Comment:
**Unused dependency: `@raycast/utils`**

`@raycast/utils` is declared as a dependency but is never imported in any source file under `src/`. Unused dependencies bloat the bundle and slow installations without providing any benefit.

**Rule Used:** What: Every dependency listed in package.json must... ([source](https://app.greptile.com/review/custom-context?memory=bffc60eb-f9f2-4219-b804-76e29e267d43))

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/to-do-s/src/storage.ts
Line: 31

Comment:
**`Date.now()` IDs risk collision**

Both `createCategory` (line 31) and `createTodo` (line 66) use `Date.now().toString()` as a unique ID. If two items are created in the same millisecond (e.g. programmatic creation or rapid key presses), they will receive the same ID, causing silent data corruption when one item overwrites the other in the storage record. Consider using a simple UUID or a monotonic counter instead.

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/to-do-s/src/category-todos.tsx
Line: 115-121

Comment:
**`onUpdate()` fires on every load, including initial mount**

`loadTodos` calls `onUpdate()` (the parent's `loadData`) unconditionally on every invocation, including the initial `useEffect` mount. This means navigating into any category always triggers a full reload of all categories and their todo counts in the parent, even though the data was just fetched. Consider calling `onUpdate()` only after a mutation (toggle, delete, create) rather than after every read.

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

Reviews (1): Last reviewed commit: "Update to-do-s extension" | Re-trigger Greptile

Comment on lines +17 to +23
{
"name": "new-todo",
"title": "Todos",
"description": "View and manage todos organized by categories",
"icon": "extension-icon.png",
"mode": "view"
}
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 Missing metadata/ folder with store screenshots

The extension declares a view-mode command but no metadata/ folder with Raycast-styled screenshots is present in the PR. This folder is required for publishing to the Raycast Store — the submission will be rejected without it.

See the store preparation docs for the expected format and naming convention.

Rule Used: What: Extensions with view-type commands must incl... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/to-do-s/package.json
Line: 17-23

Comment:
**Missing `metadata/` folder with store screenshots**

The extension declares a `view`-mode command but no `metadata/` folder with Raycast-styled screenshots is present in the PR. This folder is required for publishing to the Raycast Store — the submission will be rejected without it.

See the [store preparation docs](https://developers.raycast.com/basics/prepare-an-extension-for-store#screenshots) for the expected format and naming convention.

**Rule Used:** What: Extensions with view-type commands must incl... ([source](https://app.greptile.com/review/custom-context?memory=87059ac1-c601-487f-9f1c-bce8a3cb6209))

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

],
"dependencies": {
"@raycast/api": "^1.104.13",
"@raycast/utils": "^1.17.0"
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 Unused dependency: @raycast/utils

@raycast/utils is declared as a dependency but is never imported in any source file under src/. Unused dependencies bloat the bundle and slow installations without providing any benefit.

Rule Used: What: Every dependency listed in package.json must... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/to-do-s/package.json
Line: 27

Comment:
**Unused dependency: `@raycast/utils`**

`@raycast/utils` is declared as a dependency but is never imported in any source file under `src/`. Unused dependencies bloat the bundle and slow installations without providing any benefit.

**Rule Used:** What: Every dependency listed in package.json must... ([source](https://app.greptile.com/review/custom-context?memory=bffc60eb-f9f2-4219-b804-76e29e267d43))

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

export async function createCategory(name: string, color: string): Promise<Category> {
const data = await loadData();
const category: Category = {
id: Date.now().toString(),
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 Date.now() IDs risk collision

Both createCategory (line 31) and createTodo (line 66) use Date.now().toString() as a unique ID. If two items are created in the same millisecond (e.g. programmatic creation or rapid key presses), they will receive the same ID, causing silent data corruption when one item overwrites the other in the storage record. Consider using a simple UUID or a monotonic counter instead.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/to-do-s/src/storage.ts
Line: 31

Comment:
**`Date.now()` IDs risk collision**

Both `createCategory` (line 31) and `createTodo` (line 66) use `Date.now().toString()` as a unique ID. If two items are created in the same millisecond (e.g. programmatic creation or rapid key presses), they will receive the same ID, causing silent data corruption when one item overwrites the other in the storage record. Consider using a simple UUID or a monotonic counter instead.

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

Comment on lines +115 to +121
async function loadTodos() {
setIsLoading(true);
const data = await getTodos(category.id);
setTodos(data);
setIsLoading(false);
onUpdate();
}
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 onUpdate() fires on every load, including initial mount

loadTodos calls onUpdate() (the parent's loadData) unconditionally on every invocation, including the initial useEffect mount. This means navigating into any category always triggers a full reload of all categories and their todo counts in the parent, even though the data was just fetched. Consider calling onUpdate() only after a mutation (toggle, delete, create) rather than after every read.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/to-do-s/src/category-todos.tsx
Line: 115-121

Comment:
**`onUpdate()` fires on every load, including initial mount**

`loadTodos` calls `onUpdate()` (the parent's `loadData`) unconditionally on every invocation, including the initial `useEffect` mount. This means navigating into any category always triggers a full reload of all categories and their todo counts in the parent, even though the data was just fetched. Consider calling `onUpdate()` only after a mutation (toggle, delete, create) rather than after every read.

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

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