Skip to main content

openmates-add-app-skill

Scaffold a new skill in an existing app (BaseSkill, schemas, app.yml, i18n)

インストールへ移動

ソース情報

リポジトリ
glowingkitty/OpenMates
ソースの最終更新活動
2026年9月1日 15:39
検出された SKILL.md の言語
英語
スター
46
フォーク
3

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
openmates:add-app-skill
description
Scaffold a new skill in an existing app (BaseSkill, schemas, app.yml, i18n)
user-invocable
true
argument-hint
<appId> <skillId> <SkillClassName>
## Arguments Parse `$ARGUMENTS` into three parts: - `appId` — app directory name (e.g., `web`, `news`, `travel`) - `skillId` — kebab-case skill identifier (e.g., `deep-research`) - `SkillClassName` — PascalCase class name (e.g., `DeepResearchSkill`) If any are missing, ask the user before proceeding. ## Instructions You are adding a new skill to an existing app microservice. This touches backend Python code, YAML config, and i18n. ### Step 1: Understand the Target App Read these files to understand the app's patterns: 1. `backend/apps/{appId}/app.yml` — existing skills, embed types, categories 2. `backend/apps/base_skill.py` (lines 1-145) — BaseSkill interface 3. An existing skill in `backend/apps/{appId}/skills/` — use as template 4. `backend/shared/python_schemas/app_metadata_schemas.py` — AppYAML schema (for valid field names) ### Step 1b: Create Skill Behavior Spec Before scaffolding a new app skill, run `create-plan` or create an inline Plan using `docs/contributing/guides/spec-driven-development.md`. New app skills usually require a full spec because they define user-facing AI behavior, tool contracts, provider behavior, and often embed behavior. The spec must include: - Sample user prompts - Expected tool input parameters - Expected skill output shape - No-results behavior - Provider-error behavior - Permission, privacy, and API-key behavior - Embed preview/fullscreen behavior if the skill produces embeds - App-store examples that double as executable examples The spec or inline contract must also define the phase gate for this skill: 1. Implement and test the skill through OpenMates CLI against the dev server first, using real prompts or CLI contract tests that exercise the backend skill without browser state. This proof must use real CLI commands against the real dev API/WebSocket path; mocked OpenMates API calls, mocked SDK clients, stubbed servers, direct function calls, and fixture replay do not satisfy the gate. 2. Implement and test npm SDK and pip SDK parity locally against the dev server for the same callable behavior when the skill is exposed programmatically. After local CLI and SDK evidence is green, reproduce or wire the same coverage into GitHub Actions for CI/daily tests. 3. Implement web app surfaces, embeds, and app-store examples only after CLI and SDK parity are green. 4. Run deployed Playwright visual smoke for larger web/UI surfaces in both laptop and mobile viewports, fixing and redeploying any objective rendering, error, loading, or responsiveness issue, then ask the user to confirm the deployed dev web behavior works and looks correct before starting any Apple parity work. Use Firecrawl only as a recorded fallback when Playwright is impractical or blocked. Playwright specs alone are not enough. 5. Start Apple parity only after CLI, SDK, web, and user-confirmation evidence are complete, or after the spec records an explicit waiver/blocker. ### Step 2: Create the Skill File Create `backend/apps/{appId}/skills/{skill_file}.py` where `skill_file` is `skillId` with hyphens replaced by underscores. Follow this structure exactly: ```python """ {SkillClassName} — {brief description}. Architecture: docs/architecture/app_skills.md """ import logging from typing import Dict, Any, Optional from pydantic import BaseModel, Field from backend.apps.base_skill import BaseSkill logger = logging.getLogger(__name__) class {SkillName}Request(BaseModel): """{description}.""" # Define input fields from tool_schema class {SkillName}Response(BaseModel): """{description}.""" success: bool = Field(default=False) # Define output fields class {SkillClassName}(BaseSkill): """ {Description of what this skill does}. """ async def execute( self, # Skill-specific params (must match tool_schema properties) secrets_manager=None, cache_service=None, encryption_service=None, directus_service=None, user_id: Optional[str] = None, chat_id: Optional[str] = None, **kwargs ) -> {SkillName}Response: """Execute the skill.""" try: # Implementation here return {SkillName}Response(success=True) except Exception as e: logger.error(f"{SkillClassName} error: {e}", exc_info=True) return {SkillName}Response(success=False, error=str(e)) ``` ### Step 3: Register in app.yml Add to the `skills:` list in `backend/apps/{appId}/app.yml`: ```yaml - id: {skillId} name_translation_key: {appId}.{skill_id_underscored} description_translation_key: {appId}.{skill_id_underscored}.description icon_image: {icon}.svg preprocessor_hint: > Natural language description for AI model routing providers: - name: OpenMates no_api_key: true class_path: backend.apps.{appId}.skills.{skill_file}.{SkillClassName} tool_schema: type: object properties: # Define input parameters required: # List required params ``` If the skill produces embeds, also add an `embed_types:` entry. ### Step 4: Add i18n Entries Add skill name and description to `frontend/packages/ui/src/i18n/sources/skills.yml` (all 20 locales). Then rebuild: ```bash cd frontend/packages/ui && npm run build:translations ``` ### Step 5: Add App-Store Examples Every new app skill must include app-store examples so the skill details page can show realistic preview cards. If the skill produces embeds: 1. Run or script at least two real CLI skill requests that cover the main provider/result shapes. 2. Create `frontend/packages/ui/src/components/embeds/{appId}/{SkillName}EmbedPreview.examples.ts` next to the preview component. 3. Export an array of flat preview props matching the preview component, with `query_translation_key` values under `settings.app_store_examples.{appId}.{skill_id_underscored}.<n>`. 4. Add those query labels to `frontend/packages/ui/src/i18n/sources/settings/app_store_examples.yml`. If the skill does not produce embeds, add equivalent user-facing examples in `backend/apps/{appId}/app.yml` using the existing `example_entries` or `example_translation_keys` pattern for that app. ### Step 6: Create Test Script (Optional) If `scripts/test_skills/` exists, create `test_{skill_id_underscored}.py` following the pattern of other test scripts in that directory. ### Step 7: Check for Embed Need Ask the user: "Does this skill produce embeds that need a frontend component?" If yes, suggest running `/add-embed-type {appId} {skillId} {SkillName}` next. ## Rules - Skills must NOT import from other skills — shared logic goes to `BaseSkill` or `backend/shared/` - All `execute()` params must match `tool_schema.properties` names exactly - Use `logger = logging.getLogger(__name__)` — never `print()` - Type hints on all function parameters and return values - Pydantic models use `PascalCase` — end request models with `Request`, response with `Response` - Do not add `stage`; implemented skills are enabled by default unless `default_enabled: false` is explicitly needed - App-store examples are required for every new skill; do not ship a skill with an empty examples section
GitHubで見る