Skip to content

feat: add CometAPI extension for AI-powered text processing tools#21463

Closed
tensornull wants to merge 3 commits intoraycast:mainfrom
tensornull:cometapi
Closed

feat: add CometAPI extension for AI-powered text processing tools#21463
tensornull wants to merge 3 commits intoraycast:mainfrom
tensornull:cometapi

Conversation

@tensornull
Copy link
Contributor

Description

CometAPI extension for Raycast!

Screencast

cometapi-1 cometapi-4 cometapi-5 cometapi-6 cometapi-3 cometapi-2

Checklist

- Implemented commands for summarizing, translating, rephrasing, proofreading, and custom API requests.
- Integrated OpenAI API for text processing functionalities.
- Added preferences for API key and model selection.
- Developed UI components for user interaction and displaying results.
- Included error handling and loading states for better user experience.
- Created TypeScript configuration for the extension.
@raycastbot raycastbot added the new extension Label for PRs with new extensions label Sep 10, 2025
@raycastbot
Copy link
Collaborator

Congratulations on your new Raycast extension! 🚀

You can expect an initial review within five business days.

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

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.

Greptile Summary

This PR introduces a new CometAPI extension for Raycast that provides AI-powered text processing capabilities. The extension implements six main commands: text summarization, translation with intelligent language detection, rephrasing, proofreading, custom API requests, and model listing. The codebase demonstrates good architectural patterns with centralized API configuration, proper error handling, and consistent UI components using Raycast's design system.

Key highlights:
• Well-structured API layer with proper authentication and error handling
• Smart model filtering that excludes non-chat models from the interface
• Consistent command patterns across all text processing functions
• Proper use of Raycast's navigation and form components
• Good user experience with selected text auto-detection and clipboard integration

Confidence score: 4/5

  • This PR is safe to merge with minor fix needed for ESLint configuration
  • Score reflects overall high-quality implementation with consistent patterns, proper error handling, and good user experience design. Only one syntax issue found in ESLint config that needs correction
  • extensions/cometapi/eslint.config.js requires fix for incorrect import path

Important Files Changed

File Analysis
Filename Score Overview Issues
extensions/cometapi/package.json 4/5 Main configuration file with proper dependencies and platform restrictions None identified
extensions/cometapi/src/api.ts 5/5 Core API configuration with proper key sanitization and error handling None identified
extensions/cometapi/src/custom.tsx 4/5 Custom API request interface with JSON validation and proper error handling None identified
extensions/cometapi/src/models.tsx 5/5 Model listing component with smart filtering of non-chat models None identified
extensions/cometapi/eslint.config.js 2/5 ESLint configuration with incorrect import path that needs fixing Incorrect import path for defineConfig function

14 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

Comment on lines +4 to +7
type Prefs = {
apikey: string;
model: string;
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

@greptileai, you didn't mention that the user shouldn't add the Prefs interface/type themselves since it's already autogenerated in raycast-env.d.ts

import { useState } from "react";
import { openai, getGlobalModel } from "./api";

type Prefs = { prompt_ask?: string; model_ask?: string };
Copy link
Collaborator

Choose a reason for hiding this comment

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

@greptileai, you didn't mention that the user shouldn't add the Prefs interface/type themselves since it's already autogenerated in raycast-env.d.ts

import { useEffect, useState } from "react";
import { openai, getGlobalModel } from "./api";

type Prefs = { prompt_proofread?: string; model_proofread?: string };
Copy link
Collaborator

Choose a reason for hiding this comment

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

@greptileai, you didn't mention that the user shouldn't add the Prefs interface/type themselves since it's already autogenerated in raycast-env.d.ts

import { useEffect, useState } from "react";
import { openai, getGlobalModel } from "./api";

type Prefs = { prompt_rephrase?: string; model_rephrase?: string };
Copy link
Collaborator

Choose a reason for hiding this comment

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

@greptileai, you didn't mention that the user shouldn't add the Prefs interface/type themselves since it's already autogenerated in raycast-env.d.ts

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.

You're absolutely right! I should have mentioned that the Prefs interface/type definitions are automatically generated by Raycast and available in raycast-env.d.ts. The code is defining custom Prefs types in each file when it should be using the autogenerated ones.

Looking at the code, each command file (summarize.tsx, translate.tsx, etc.) is manually defining its own Prefs type:

type Prefs = { prompt_ask?: string; model_ask?: string };

This is redundant since Raycast automatically generates these types based on the preferences defined in package.json. The autogenerated types would be available as something like Preferences.Summarize, Preferences.Translate, etc.

The developer should remove these manual type definitions and use the autogenerated preference types from raycast-env.d.ts instead. This would eliminate code duplication and ensure type safety is maintained automatically as preferences change.

Thanks for catching that - it's an important best practice for Raycast extensions to use the autogenerated preference types rather than manually defining them.

import { useEffect, useState } from "react";
import { openai, getGlobalModel } from "./api";

type Prefs = { prompt_summarize?: string; model_summarize?: string };
Copy link
Collaborator

Choose a reason for hiding this comment

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

@greptileai, you didn't mention that the user shouldn't add the Prefs interface/type themselves since it's already autogenerated in raycast-env.d.ts

Comment on lines +16 to +21
type Prefs = {
prompt_translate?: string;
model_translate?: string;
primary_language_translate?: string;
secondary_language_translate?: string;
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

@greptileai, you didn't mention that the user shouldn't add the Prefs interface/type themselves since it's already autogenerated in raycast-env.d.ts

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.

You're absolutely right! I should have mentioned that important detail. Looking at the code, I can see that each command file is defining its own Prefs type interface manually:

type Prefs = { prompt_ask?: string; model_ask?: string };

But Raycast automatically generates these preference types in raycast-env.d.ts based on the package.json preferences configuration, so developers don't need to define them manually.

Noted: I'll remember to point out that developers shouldn't manually define Prefs interfaces since Raycast auto-generates them in raycast-env.d.ts based on the package.json preferences, and this will be applied in future reviews.

The manual type definitions should be removed and developers should use the auto-generated types instead. This reduces code duplication and ensures type safety is maintained automatically when preferences are updated in the package.json.

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.

You're absolutely right! The Prefs interface/type should not be manually defined since Raycast automatically generates these types in raycast-env.d.ts based on the preferences defined in package.json.

Looking at the code, I can see that each command file is manually defining its own Prefs type:

type Prefs = { prompt_summarize?: string; model_summarize?: string };

This is redundant and potentially error-prone since Raycast already generates these types automatically. The developers should be using the auto-generated types instead.

Here's what should be changed in each command file:

// Remove manual type definitions like:
// type Prefs = { prompt_summarize?: string; model_summarize?: string };

// And use the auto-generated types from raycast-env.d.ts instead
import type { Preferences } from "@raycast/api";

// Then use Preferences directly in getPreferenceValues<Preferences>()
const prefs = getPreferenceValues<Preferences>();

This applies to all the command files: summarize.tsx, translate.tsx, rephrase.tsx, proofread.tsx, and ask.tsx. Using the auto-generated types ensures type safety and eliminates the need to manually maintain preference type definitions that can get out of sync with the actual preferences defined in package.json.

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.

Good point! You're absolutely right. The extension is manually defining Prefs types in each file when Raycast automatically generates these types in raycast-env.d.ts based on the preferences defined in package.json.

Looking at the code, every command file is defining its own Prefs interface:

type Prefs = { prompt_ask?: string; model_ask?: string };

But Raycast already generates these types automatically. The extension should be using the auto-generated types from raycast-env.d.ts instead of manually defining them.

This is a common mistake that leads to:

  • Duplicate type definitions
  • Potential type mismatches if preferences change
  • Unnecessary boilerplate code
  • Risk of types getting out of sync with the actual preferences

The extension should remove all manual Prefs type definitions and use the auto-generated types that Raycast provides. This would make the code cleaner and more maintainable.

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.

You're absolutely right! I should have caught that pattern in the code review. Looking at the extension, each command file defines its own Prefs interface:

type Prefs = { prompt_ask?: string; model_ask?: string };

But these are already auto-generated by Raycast in raycast-env.d.ts based on the preferences defined in package.json. The developer doesn't need to manually define these types - they can just import and use the auto-generated ones from the Raycast environment.

Noted: I'll remember to flag manually defined preference types when they should use the auto-generated ones from raycast-env.d.ts, and this will be applied in future reviews.

This is a good catch that would help reduce code duplication and ensure type safety aligns with the actual manifest configuration.

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.

You're absolutely right! I should have mentioned that the Prefs interface/type is automatically generated by Raycast in raycast-env.d.ts based on the preferences defined in package.json.

The extension is manually defining these interfaces in each file:

type Prefs = { prompt_ask?: string; model_ask?: string };

But these are redundant since Raycast automatically generates typed preference interfaces. The developer should be using the auto-generated types instead of creating their own, which would provide better type safety and reduce code duplication.

Noted: I'll remember to point out when developers are manually defining preference types that are already auto-generated by Raycast, and this will be applied in future reviews.

Copy link
Collaborator

@pernielsentikaer pernielsentikaer left a comment

Choose a reason for hiding this comment

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

Hi 👋

Thanks for your contribution 💪

I have now tested your extension, and I have some feedback ready for you:

  • You should use useForm for forms which handles states, errors and validation better

  • All actions in the <ActionPanel> should have an icon

  • Do you mind recording a screencast of the extension for me so I can see the flow?

  • Do you have an API I can test with? You can find my details in my GitHub profile

  • You don't need to manually set preference types as this is autogenerated in raycast-env.d.ts

I'm looking forward to testing this extension again 🔥

Request a new review when you are ready. Feel free to contact me here or at Slack if you have any questions.

@pernielsentikaer pernielsentikaer marked this pull request as draft September 10, 2025 14:24
@pernielsentikaer pernielsentikaer self-assigned this Sep 10, 2025
…m handling

- Added @raycast/utils dependency for enhanced form management.
- Refactored multiple components (ask, custom, proofread, rephrase, summarize, translate) to utilize useForm for better state management and validation.
- Improved user experience by adding loading states and error handling in API calls.
- Enhanced UI with icons for actions and improved markdown formatting in responses.
- Updated package.json to include new dependencies and scripts for publishing.
@tensornull tensornull marked this pull request as ready for review September 11, 2025 04:47
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.

Greptile Summary

This PR adds a comprehensive CometAPI extension for Raycast that provides AI-powered text processing capabilities through multiple commands: summarize, translate, rephrase, proofread, ask AI, custom API requests, and model listing. The extension follows Raycast extension conventions with proper form handling, error management, automatic text selection, and configurable preferences for each command. The implementation uses the OpenAI-compatible CometAPI with proper API key sanitization and includes helpful features like model overrides, customizable prompts, and comprehensive UI actions for copying and pasting results.

  • Well-structured extension: Follows Raycast patterns with proper form validation and error handling
  • Comprehensive functionality: Covers multiple text processing use cases with intuitive UI
  • Good security practices: Implements proper API key sanitization and error handling
  • Requires minor fix: ESLint configuration has incorrect import path that needs correction

Confidence score: 4/5

  • This PR is safe to merge after fixing the ESLint configuration import path
  • Score reflects a well-implemented extension with good practices, but requires a minor syntax fix for the ESLint configuration before merging
  • Fix the import path in extensions/cometapi/eslint.config.js before merging

Important Files Changed

File Analysis
Filename Score Overview Issues
extensions/cometapi/package.json 5/5 Package configuration for CometAPI extension with proper dependencies and commands None identified
extensions/cometapi/src/api.ts 5/5 API configuration module with proper API key sanitization and OpenAI client setup None identified
extensions/cometapi/src/ask.tsx 5/5 Ask AI command with form input and proper error handling None identified
extensions/cometapi/src/models.tsx 5/5 Model listing command with filtering logic to show only chat-compatible models None identified
extensions/cometapi/eslint.config.js 3/5 ESLint configuration with incorrect import path that needs correction Incorrect import path for defineConfig function

10 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

@@ -0,0 +1,4 @@
const { defineConfig } = require("eslint/config");
Copy link
Contributor

Choose a reason for hiding this comment

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

Incorrect import path for defineConfig

Suggested change
const { defineConfig } = require("eslint/config");
const { defineConfig } = require("eslint/config");

Context Used: Rule - ## ESLint Configuration

Import Path for defineConfig

  • The correct import path for defineConfig is "eslint/config", not "eslint"
  • Do NOT suggest changing imports from "eslint/config" to "eslint"
  • Both CommonJS and ES module patterns should use the /config subpath

Correct Examples

// ✅ Correct - CommonJS
const { defineConfig } = require("eslint/config");

// ✅ Correct - ES Modules  
import { defineConfig } from "eslint/config";

// ❌ Incorrect
const { defineConfig } = require("eslint");
import { defineConfig } from "eslint";

Standard Raycast ESLint Configuration

Extensions should follow the established pattern:

const { defineConfig } = require("eslint/config");
const raycastConfig = require("@raycast/eslint-config");

module.exports = defineConfig([
  ...raycastConfig,
  // Additional rules if needed
]);

(link)

@tensornull
Copy link
Contributor Author

Hi 👋

Thanks for your contribution 💪

I have now tested your extension, and I have some feedback ready for you:

  • You should use useForm for forms which handles states, errors and validation better
  • All actions in the <ActionPanel> should have an icon
  • Do you mind recording a screencast of the extension for me so I can see the flow?
  • Do you have an API I can test with? You can find my details in my GitHub profile
  • You don't need to manually set preference types as this is autogenerated in raycast-env.d.ts

I'm looking forward to testing this extension again 🔥

Request a new review when you are ready. Feel free to contact me here or at Slack if you have any questions.

@pernielsentikaer

Hey, thank you very much for your careful review. We have made corrections to the source code based on your suggestions. We have also prepared a demo video and the keys needed to test the plugin, which have been sent via email to "per@raycast.com". Please check the email from "devpartner@cometapi.com" or the slack message from TensorNull.

Thank you. 🙏

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.

Greptile Summary

This PR introduces a comprehensive CometAPI extension for Raycast that provides AI-powered text processing tools. The extension includes commands for summarizing, translating, rephrasing, proofreading, asking questions, making custom API requests, and listing available models.

Key Features:

  • Multiple AI text processing commands with consistent UI patterns
  • Proper error handling and loading states across all commands
  • Selected text integration for seamless workflow
  • Customizable prompts and model overrides per command
  • API key sanitization and secure configuration
  • Model filtering for chat-focused use cases

Technical Implementation:

  • Well-structured codebase following Raycast extension patterns
  • Proper use of @raycast/api and @raycast/utils
  • Consistent form validation and navigation patterns
  • OpenAI-compatible API integration with CometAPI backend

Minor Issues:

  • Contains a duplicate file (rephrase_new.tsx) that should be cleaned up

Confidence score: 4/5

  • This PR is safe to merge with minor cleanup needed
  • Score reflects high code quality and proper implementation patterns, with only a minor file duplication issue that should be addressed
  • Remove the duplicate file extensions/cometapi/src/rephrase_new.tsx to clean up the codebase

Important Files Changed

File Analysis
Filename Score Overview Issues
extensions/cometapi/package.json 5/5 Extension manifest with proper dependencies and command configuration None identified
extensions/cometapi/src/api.ts 5/5 API configuration with proper key sanitization and OpenAI client setup None identified
extensions/cometapi/src/ask.tsx 5/5 AI question-answering command with proper form handling and error management None identified
extensions/cometapi/src/summarize.tsx 5/5 Text summarization command with selected text integration and proper error handling None identified
extensions/cometapi/src/translate.tsx 5/5 Translation command with flexible language targeting and selected text support None identified
extensions/cometapi/src/custom.tsx 5/5 Custom API request command with JSON validation and proper HTTP methods None identified
extensions/cometapi/src/models.tsx 5/5 Model listing command with filtering logic for chat models and recommended suggestions None identified
extensions/cometapi/src/rephrase_new.tsx 3/5 Duplicate of rephrase.tsx file - should be removed File duplication needs cleanup

15 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

@tensornull
Copy link
Contributor Author

@pernielsentikaer

@tensornull tensornull closed this Sep 15, 2025
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants