From ab12dfecca834fbf98d8a2f805d2cfc858f8de2e Mon Sep 17 00:00:00 2001 From: Risto Jamul Date: Wed, 8 Apr 2026 12:59:30 -0600 Subject: [PATCH] fix: sync skills with TypeScript CLI rewrite and update tool counts Replace all 9 skills with the updated versions from elnora-cli that match the TypeScript CLI architecture (Commander.js, Zod schemas, elnora__ MCP tool naming convention). Update elnora/README.md tool counts from 71 to 93 commands across 14 groups. Bump plugin version to 1.3.0. Co-Authored-By: Claude Opus 4.6 (1M context) --- elnora/.claude-plugin/plugin.json | 2 +- elnora/README.md | 21 +- elnora/skills/elnora-admin/SKILL.md | 341 ++++++++++++++++------ elnora/skills/elnora-agent/SKILL.md | 53 ++-- elnora/skills/elnora-files/SKILL.md | 379 ++++++++++--------------- elnora/skills/elnora-folders/SKILL.md | 98 ++++--- elnora/skills/elnora-orgs/SKILL.md | 255 ++++++++++++----- elnora/skills/elnora-platform/SKILL.md | 171 +++++++---- elnora/skills/elnora-projects/SKILL.md | 246 +++++----------- elnora/skills/elnora-search/SKILL.md | 174 ++++-------- elnora/skills/elnora-tasks/SKILL.md | 258 ++++++++--------- 11 files changed, 1056 insertions(+), 942 deletions(-) diff --git a/elnora/.claude-plugin/plugin.json b/elnora/.claude-plugin/plugin.json index e73f96c..2648ae0 100644 --- a/elnora/.claude-plugin/plugin.json +++ b/elnora/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "elnora", - "version": "1.2.0", + "version": "1.3.0", "description": "AI-powered bioprotocol generation and lab workflow management. Connect to the Elnora AI Platform to generate, optimize, and manage bioprotocols for wet-lab experiments.", "author": { "name": "Elnora AI", diff --git a/elnora/README.md b/elnora/README.md index a3e4a42..3f2b379 100644 --- a/elnora/README.md +++ b/elnora/README.md @@ -17,17 +17,22 @@ Elnora is an AI-powered platform that helps researchers generate, optimize, and ## Capabilities -71 tools across 7 categories. All tools are discoverable through your MCP client's tool listing. +93 commands across 14 groups. All tools are discoverable through your MCP client's tool listing or via the `elnora` CLI. -| Category | Tools | What you can do | -|----------|------:|-----------------| -| Tasks & Protocols | 8 | Create conversation threads, send messages, generate bioprotocols | -| Files | 15 | Upload, download, version, fork, and manage protocol files | -| Projects | 10 | Create projects and manage team membership | +| Category | Commands | What you can do | +|----------|--------:|-----------------| +| Tasks | 8 | Create conversation threads, send messages, stream agent responses | +| Files | 16 | Upload, download, version, fork, and manage protocol files | +| Projects | 11 | Create projects and manage team membership | | Organizations | 16 | Org settings, billing, member invitations, shared library | | Folders | 5 | Organize files into nested folder structures | -| Search | 3 | Full-text search across tasks, files, and all resources | -| Admin | 14 | API keys, audit logs, account, health checks, feature flags | +| Search | 4 | Full-text search across tasks, files, and all resources | +| Admin | 6 | API keys, audit logs, feature flags | +| Account | 8 | User management, legal docs, agreements | +| Auth | 5 | Authentication, profiles, API key validation | +| Library | 5 | Organization library management | +| Feedback | 1 | Submit feedback | +| Other | 8 | Health, doctor, whoami, open, completion, update, MCP serve | See the individual [skill files](skills/) for full tool reference with parameters and workflow recipes. diff --git a/elnora/skills/elnora-admin/SKILL.md b/elnora/skills/elnora-admin/SKILL.md index 5166f80..1a02e3e 100644 --- a/elnora/skills/elnora-admin/SKILL.md +++ b/elnora/skills/elnora-admin/SKILL.md @@ -1,130 +1,301 @@ --- name: elnora-admin description: > - Use this skill when the user asks about "Elnora account", "API keys", - "audit log", "feature flags", "health check", "terms of service", - "platform status", "feedback", "invitation", or any Elnora platform - administration task. + This skill should be used when the user asks to "log in", "check auth", "create API key", + "revoke API key", "check health", "submit feedback", "view audit log", + "shell completions", "account details", "accept terms", "validate token", "elnora setup", + "api key policy", "delete account", "list users", "feature flags", "legal documents", + "set feature flag", "manage legal docs", "list profiles", "show profiles", "whoami", + "run diagnostics", "open platform", + or any task involving Elnora Platform authentication, administration, or diagnostics. --- -# Elnora Admin +# Elnora Admin & Diagnostics -Platform administration tools for account management, API keys, audit logs, -feature flags, agreements, invitations, and system health. +Authentication, API key management, account settings, health checks, audit logs, feedback, and shell completions. -## Auth +## Invocation -The Elnora MCP server handles authentication automatically via OAuth 2.1 -(browser popup) or API key bearer tokens in the MCP connection headers. -There is no manual login/logout step — auth "just works" when the MCP -server is configured. +```bash +CLI="elnora" +``` -## Core Concepts +## Authentication -- **Health check** requires no authentication — use it to verify the platform is up. -- **API keys** are shown in full **only once** at creation time. Store them securely immediately. -- **Audit logs** track actions across the org. Filterable by org, action type, and user. -- **Feature flags** are read-only. Use them to check what capabilities are enabled. -- **Agreements** (terms of service) must be accepted before using certain features. -- **Invitations** can be inspected and accepted to join an org. +### Login -## Tools Reference +```bash +$CLI --compact auth login --api-key +$CLI --compact auth login --api-key --profile university +``` -### System Health +`--api-key` is required — there is no interactive prompt. Keys must start with `elnora_live_` and be 20+ characters. Saves to `~/.elnora/profiles.toml`. -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_health_check` | Check platform status | — (no auth required) | +Response: `{"profile":"default","verified":true,"configPath":"/Users//.elnora/profiles.toml"}` -### Account +### Check Auth Status -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_get_account` | Get current user's account info | — | -| `elnora_update_account` | Update account details | fields to update | +```bash +$CLI --compact auth status +# -> {"profile":"default","authenticated":true,"projectCount":N} +``` -### API Keys +### Logout -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_list_api_keys` | List existing API keys | — | -| `elnora_create_api_key` | Create a new API key | `name` | -| `elnora_revoke_api_key` | Revoke an API key | `key_id` | +```bash +$CLI --compact auth logout +$CLI --compact auth logout --all +``` -**Critical**: `elnora_create_api_key` returns the full key **only once**. The key is never -shown again. Always present it to the user immediately and remind them to store it securely. +Without `--all`, removes the current profile. With `--all`, removes all saved profiles from `profiles.toml`. -### Agreements +### List Profiles -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_list_agreements` | List terms/agreements | — | -| `elnora_accept_terms` | Accept terms of service | `agreement_id` | +```bash +$CLI --compact auth profiles +# -> {"profiles":[{"name":"default","apiKey":"elnora_live_...abcd"}]} +``` -### Feedback +Shows all configured profiles with masked API keys. -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_submit_feedback` | Submit platform feedback | `message`, optional `type` | +### Validate Token -### Audit Log +```bash +$CLI --compact auth validate +$CLI --compact auth validate --token +``` -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_list_audit_log` | Query audit events | `org_id`, optional filters | +Validates the current API key (or a specific token). -Filters may include action type, user, and date range. Always scope to a specific -`org_id` to get relevant results. +### Who Am I -### Feature Flags +```bash +$CLI whoami +$CLI --json whoami +``` -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_list_flags` | List all feature flags | — | -| `elnora_get_flag` | Get a specific flag's value | `flag_name` | +Shows current profile, masked API key, and organization name. -Feature flags are **read-only**. Use them to check whether a feature is enabled -before attempting to use it. +## API Key Management -### Invitations +### Create API Key -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_get_invitation_info` | Inspect an invitation | `invitation_id` | -| `elnora_accept_invitation` | Accept an org invitation | `invitation_id` | +```bash +$CLI --compact api-keys create --name "CI Pipeline" +$CLI --compact api-keys create --name "Agent Key" --scopes "read,write" +``` -## Common Workflows +**IMPORTANT:** The key value is only shown once in the response. Store it securely. -### Check platform health +### List API Keys -1. `elnora_health_check` — no auth needed, confirms the API is reachable +```bash +$CLI --compact api-keys list +``` -### Create and store an API key +### Revoke API Key -1. `elnora_create_api_key` with a descriptive `name` -2. **Immediately** present the returned key to the user -3. Remind them this is the only time the full key is shown +```bash +$CLI --compact api-keys revoke +# -> {"revoked":true,"keyId":"..."} +``` -### Review audit activity +Destructive — confirm with user first. -1. `elnora_list_audit_log` with `org_id` and any desired filters -2. Paginate if needed — check response for pagination fields +### Get API Key Policy -### Check feature availability +```bash +$CLI --compact api-keys get-policy +# -> {"policy":"all_members"} +``` -1. `elnora_list_flags` to see all flags, or `elnora_get_flag` for a specific one -2. Use the flag value to decide whether to proceed with a feature +### Set API Key Policy -### Accept an invitation +```bash +$CLI --compact api-keys set-policy --policy admins_only +$CLI --compact api-keys set-policy --policy all_members +``` -1. `elnora_get_invitation_info` with `invitation_id` to review details -2. `elnora_accept_invitation` to join the org +Org admin/owner only. Values: `all_members` or `admins_only`. -### View and accept terms +## Account Management -1. `elnora_list_agreements` to see pending agreements -2. `elnora_accept_terms` with the `agreement_id` to accept +### Get Account -## ID Format +```bash +$CLI --compact account get +``` -All IDs are UUIDs (e.g., `bfdc6fbd-40ed-4042-9ea7-c79a5ec90085`). +`` is positional. Get user IDs from `account users`. + +### Update Account + +```bash +$CLI --compact account update --first-name Jane --last-name Doe +``` + +Must provide at least one of `--first-name` or `--last-name`. + +### List Agreements + +```bash +$CLI --compact account agreements +``` + +### Accept Terms + +```bash +$CLI --compact account accept-terms +``` + +`` is positional. + +### Delete Account + +```bash +$CLI --compact account delete +$CLI --compact account delete --yes +``` + +**DANGEROUS: Permanently deletes the user's account. Irreversible.** +Requires typing "DELETE" to confirm. Use `--yes` to skip (non-interactive/CI only). + +### List Users (SystemAdmin) + +```bash +$CLI --compact account users +$CLI --compact account users --state Active +$CLI --compact account users --state Deleted --ref-code ABC123 +``` + +Optional filters: `--state` (Active, Pending, Deleted), `--ref-code`. + +### Add Legal Document Version (SystemAdmin) + +```bash +$CLI --compact account add-legal-doc --document-type TermsOfService --version "2.0" --content "Terms text..." --effective-date 2026-04-01 +``` + +| Flag | Required | Notes | +|------|----------|-------| +| `--document-type` | Yes | e.g. TermsOfService, PrivacyPolicy | +| `--version` | Yes | Version string | +| `--content` | Yes | Document content | +| `--effective-date` | No | ISO 8601 date | + +### Update Legal Document Version (SystemAdmin) + +```bash +$CLI --compact account update-legal-doc --content "Updated terms..." +$CLI --compact account update-legal-doc --effective-date 2026-05-01 +``` + +`` is positional. Must provide at least one of `--content` or `--effective-date`. + +### Delete Legal Document Version (SystemAdmin) + +```bash +$CLI --compact account delete-legal-doc --yes +``` + +`` is positional. Requires confirmation unless `--yes`. + +## Feature Flags (SystemAdmin) + +### List Feature Flags + +```bash +$CLI --compact flags list +``` + +### Get Feature Flag + +```bash +$CLI --compact flags get --key enable-new-editor +``` + +`--key` is a required flag (not positional). + +### Set Feature Flag + +```bash +$CLI --compact flags set --key enable-new-editor --value true --yes +``` + +| Flag | Required | Notes | +|------|----------|-------| +| `--key` | Yes | Flag key name | +| `--value` | Yes | `true` or `false` | +| `--yes` | No | Skip confirmation prompt | + +**WARNING: Affects ALL users on the platform.** Always use `--yes` in agent context. + +## Health & Diagnostics + +### Health Check + +```bash +$CLI health +``` + +No auth required. Returns `{"status":"ok","timestamp":"..."}` on success. Exits 1 if unreachable (network error). + +### Doctor + +```bash +$CLI doctor +``` + +Runs diagnostic checks: API reachability, authentication, version currency, config permissions, AI server reachability. + +### Open Platform + +```bash +elnora open # Opens platform (default) +elnora open docs # Opens documentation +elnora open keys # Opens API keys page +elnora open billing # Opens billing page +elnora open github # Opens GitHub repo +``` + +## Audit Log + +```bash +$CLI --compact audit list --org +$CLI --compact audit list --org --action "project.created" --user-id +$CLI --compact audit list --org --page 2 --page-size 50 +``` + +`--org` is a required flag. Optional filters: `--action`, `--user-id`. + +## Feedback + +```bash +$CLI --compact feedback submit --title "Feature request" --description "Add batch export" +``` + +Both `--title` and `--description` are required. + +## Shell Completions + +```bash +elnora completion bash >> ~/.bashrc +elnora completion zsh >> ~/.zshrc +elnora completion fish > ~/.config/fish/completions/elnora.fish +``` + +## Agent Recipes + +**Verify setup:** + +```bash +$CLI health && $CLI --compact auth status +``` + +**Rotate an API key:** + +```bash +$CLI --compact api-keys create --name "Replacement Key" +# Update .env with the new key, then: +$CLI --compact api-keys revoke +``` diff --git a/elnora/skills/elnora-agent/SKILL.md b/elnora/skills/elnora-agent/SKILL.md index 270a6d3..bbe3b70 100644 --- a/elnora/skills/elnora-agent/SKILL.md +++ b/elnora/skills/elnora-agent/SKILL.md @@ -12,16 +12,22 @@ description: > # Elnora Agent Capabilities -The Elnora Agent is a sandboxed Python environment with ~78 core tools + 2,100 ToolUniverse scientific tools. Interact via `elnora_create_task` / `elnora_send_message` — describe what you need in plain language, don't reference internal tool names. +The Elnora Agent is a sandboxed Python environment with ~78 core tools + 2,100 ToolUniverse scientific tools. Interact via `tasks create` and `tasks send` — describe what you need in plain language. -## MCP Tools for Agent Interaction +## Quick Start -| Tool | Purpose | -|------|---------| -| `elnora_create_task` | Create a task with optional `initial_message` to start generation | -| `elnora_send_message` | Send follow-up message. 30-120s for complex requests. | -| `elnora_get_task_messages` | Read agent responses | -| `elnora_generate_protocol` | Convenience: create task + send message in one call | +```bash +CLI="elnora" + +# Create a task and wait for the response +$CLI --compact tasks create --project --title "My task" --message "Your request" + +# Send follow-up and wait for response +$CLI --compact tasks send --message "Follow-up request" --wait + +# Or stream the response in real-time +$CLI --compact tasks send --message "Follow-up request" --stream +``` ## What the Agent Can Do @@ -35,25 +41,24 @@ The Elnora Agent is a sandboxed Python environment with ~78 core tools + 2,100 T | **Memory** (9 tools) | Remember facts across tasks, share findings between agents, recall prior context | | **Code execution** | Persistent Python REPL with pandas, numpy, biopython. Variables survive across executions. 30s timeout, 1MB output max | -## Good Prompts - -**Web research:** -> "Search for recent CRISPR delivery methods and summarize the top findings" +## Example Prompts -**Literature review:** -> "Search PubMed for BRCA1 DNA repair papers from 2024, find the most cited ones" +```bash +# Web research +$CLI --compact tasks send "$TASK" --message "Search for recent CRISPR delivery methods and summarize" --wait -**Drug target research:** -> "Search for compounds targeting EGFR, cross-reference with active clinical trials" +# Literature review +$CLI --compact tasks send "$TASK" --message "Search PubMed for BRCA1 DNA repair papers from 2024" --wait -**Scientific computation:** -> "Use ToolUniverse to run AlphaFold on this sequence: MVLSPADKTNVKAAWGKVGA" +# Drug target research +$CLI --compact tasks send "$TASK" --message "Search for compounds targeting EGFR, cross-reference with active clinical trials" --wait -**Memory:** -> "Remember that our lab uses Q5 polymerase for all high-fidelity PCR at 62C" +# Scientific computation +$CLI --compact tasks send "$TASK" --message "Use ToolUniverse to run AlphaFold on this sequence: MVLSPADKTNVKAAWGKVGA" --stream -**File search:** -> "Search all project files for mentions of 'annealing temperature' and summarize" +# Memory +$CLI --compact tasks send "$TASK" --message "Remember that our lab uses Q5 polymerase for all high-fidelity PCR at 62C" --wait -**Reference existing files:** -Use `file_ids` in `elnora_send_message` or `context_file_ids` in `elnora_create_task` to give the agent context about existing protocols. +# Reference existing files +$CLI --compact tasks send "$TASK" --message "Read the attached template and generate a new version" --file-refs "" --wait +``` diff --git a/elnora/skills/elnora-files/SKILL.md b/elnora/skills/elnora-files/SKILL.md index 6d38a82..1555f8b 100644 --- a/elnora/skills/elnora-files/SKILL.md +++ b/elnora/skills/elnora-files/SKILL.md @@ -3,298 +3,231 @@ name: elnora-files description: > This skill should be used when the user asks to "list files", "read a file", "get file content", "view protocol output", "file versions", "version history", - "download protocol", "upload a file", "fork a file", "working copy", - or any task involving Elnora Platform file management. + "download protocol", "upload file", "upload batch", "bulk upload", "create file", + "archive file", "fork file", "promote file", "working copy", "restore version", + "search file content", or any task involving Elnora Platform file management. --- # Elnora Files -Manage files on the Elnora AI Platform. Files are protocol outputs, templates, datasets, and other artifacts attached to projects. The platform tracks version history for every file, supports working copies for edit-in-place workflows, and allows forking files across projects. - -## Organization Context - -All list, create, and upload tools accept an optional `org_id` parameter (UUID). -When provided, the operation targets that organization instead of the user's -active org. The user must be a member of the target org. - -## Concepts - -- **File**: A document stored in a project. Has metadata (name, type, size) and content. -- **Version**: An immutable snapshot of file content. Every change creates a new version. -- **Working copy**: A mutable draft of a file for editing. Commit to save changes as a new version. -- **Fork**: Copy a file to another project, preserving content but creating an independent copy. -- **Promote**: Change a file's visibility level (e.g., to organization library). -- **All IDs are UUIDs** (e.g., `bfdc6fbd-40ed-4042-9ea7-c79a5ec90085`). - -## MCP Tools - -### elnora_list_files - -List files in a project or workspace. - -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `project_id` | uuid | No | - | Filter by project UUID | -| `page` | integer | No | 1 | Page number (min: 1) | -| `page_size` | integer | No | 25 | Results per page (min: 1, max: 100) | - -Returns paginated results: - -```json -{ - "items": [ - { - "id": "", - "name": "pcr-protocol.md", - "mimeType": "text/markdown", - "size": 2048, - "createdAt": "...", - "updatedAt": "..." - } - ], - "page": 1, - "totalCount": 5, - "hasNextPage": false -} -``` - -### elnora_get_file - -Get file metadata (name, type, size, timestamps) without content. - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | - -Use this to inspect a file before reading its content. - -### elnora_get_file_content - -Retrieve the full content of a file. - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | - -Returns the raw file content. Use this to read protocol outputs, templates, or any file stored on the platform. - -### elnora_create_file - -Create a new empty file in a project. +Browse, read, create, upload, version, and manage files on the Elnora AI Platform. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | -| `name` | string | Yes | Filename (min: 1, max: 255 chars) | -| `file_type` | string | No | File type / MIME type | -| `folder_id` | uuid | No | Folder UUID to place the file in | +## Invocation -Returns the created file object with its `id`. The file is created empty; use `elnora_create_version` to add content. - -### elnora_upload_file - -Upload a text file with content in a single call. - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `name` | string | Yes | Filename (min: 1, max: 255 chars) | -| `content` | string | Yes | File content (min: 1, max: 100,000 chars) | -| `file_type` | string | No | MIME type (default: text/markdown) | - -Use this for quick uploads when you have the content ready. For structured project placement, use `elnora_create_file` + `elnora_create_version` instead. - -### elnora_update_file - -Update file metadata (rename or move to a different folder). - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | -| `name` | string | No | New filename (min: 1, max: 255 chars) | -| `folder_id` | uuid | No | New folder UUID | - -Must provide at least one of `name` or `folder_id`. - -### elnora_archive_file +```bash +CLI="elnora" +``` -Archive (permanently delete) a file. **Destructive -- confirm with user first.** +## Commands -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | +### List Files -### elnora_download_file +```bash +$CLI --compact files list --project +$CLI --compact files list --project --page 2 --page-size 50 +$CLI --compact --fields "id,name" files list --project +``` -Download a file (returns a download URL or content). +`--project` is required. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | +### Get File Metadata -## Version Management +```bash +$CLI --compact files get +``` -### elnora_get_file_versions +Returns metadata (name, type, size, timestamps) without actual content. -Get version history for a file. Use this to track how a protocol evolved across iterations. +### Get File Content -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `file_id` | uuid | Yes | - | File UUID | -| `page` | integer | No | 1 | Page number (min: 1) | -| `page_size` | integer | No | 25 | Results per page (min: 1, max: 100) | +```bash +$CLI files content +``` -Returns paginated list of versions with timestamps and metadata. +Returns raw file content to stdout. Pipe to save: -### elnora_get_version_content +```bash +$CLI files content > protocol.md +``` -Get the content of a specific historical file version. Essential for comparing versions or reviewing past protocol iterations. +Note: `--compact` or `--fields` wraps output in JSON. Omit both for raw text. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | -| `version_id` | uuid | Yes | Version UUID | +### Download File -Get version IDs from `elnora_get_file_versions` first. +```bash +$CLI files download +``` -### elnora_create_version +Downloads file content via the `/download` endpoint (may differ from `content` in backend handling). -Create a new version of a file with updated content. +### Get Version History -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | -| `content` | string | No | Version content (max: 100,000 chars) | +```bash +$CLI --compact files versions +$CLI --compact files versions --page-size 10 +``` -Each call creates a new immutable version. The file's current content becomes this version. +### Get Version Content -### elnora_restore_version +```bash +$CLI files version-content +``` -Restore a file to a specific previous version. +Both `` and `` are positional. Returns raw content. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | -| `version_id` | uuid | Yes | Version UUID to restore | +### Create Version -Get version IDs from `elnora_get_file_versions` first. +```bash +$CLI --compact files create-version +$CLI --compact files create-version --content "Updated protocol text" +``` -## Working Copies +### Restore Version -Working copies let you edit a file in place before committing changes. +```bash +$CLI --compact files restore +``` -### elnora_create_working_copy +Both positional. Destructive — confirm with user first. -Create a mutable working copy of a file for editing. +### Create File -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | -| `task_id` | uuid | No | Associated task UUID | +```bash +$CLI --compact files create --project --name "protocol.md" --type Document +$CLI --compact files create --project --name "data.csv" --type Dataset --folder +``` -### elnora_commit_working_copy +| Flag | Required | Notes | +|------|----------|-------| +| `--project` | Yes | Project UUID | +| `--name` | Yes | File name | +| `--type` | Yes | File type (e.g. Document, Protocol, Dataset) | +| `--folder` | No | Folder UUID | -Commit the working copy back to the file, saving changes as a new version. +### Upload File -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | +```bash +$CLI --compact files upload --project --file-path /path/to/file.md +$CLI --compact files upload --project --file-path /path/to/data.csv --file-name "renamed.csv" --content-type "text/csv" +``` -## Cross-Project Operations +Three-step process (handled automatically): presigned URL, upload, confirm. -### elnora_fork_file +| Flag | Required | Notes | +|------|----------|-------| +| `--project` | Yes | Project UUID | +| `--file-path` | Yes | Local file path | +| `--file-name` | No | Override filename | +| `--content-type` | No | MIME type (defaults to application/octet-stream) | -Fork (copy) a file to another project. Creates an independent copy in the target project. +### Upload Batch -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | Source file UUID | -| `target_project_id` | uuid | Yes | Target project UUID | +```bash +$CLI --compact files upload-batch --project --file-paths "a.pdf,b.docx,c.txt" +$CLI --compact files upload-batch --project --file-paths "file1.md,file2.md" --folder +``` -### elnora_promote_file +Uploads up to 50 files. Returns per-file success/failure results. -Change a file's visibility level (e.g., promote to organization library). +| Flag | Required | Notes | +|------|----------|-------| +| `--project` | Yes | Project UUID | +| `--file-paths` | Yes | Comma-separated local file paths | +| `--folder` | No | Folder UUID (applies to all files) | -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID | -| `visibility` | string | Yes | Target visibility level | +### Confirm Upload -## Agent Workflow Recipes +```bash +$CLI --compact files confirm-upload +``` -### Read a protocol from a project +Only needed if `upload` was interrupted after the PUT step. -1. Call `elnora_list_files` with `project_id` to browse files -2. Call `elnora_get_file_content` with the target file's `id` +### Update File -### Upload a protocol template +```bash +$CLI --compact files update --name "new-name.md" +$CLI --compact files update --folder +``` -1. Call `elnora_upload_file` with `name` and `content` -2. Use the returned file `id` in `elnora_send_message` via `file_ids` to reference it in a task +Must provide at least one of `--name` or `--folder`. -### Track protocol evolution +### Archive File -1. Call `elnora_get_file_versions` to see all versions -2. Call `elnora_get_file_content` to read current content -3. Use `elnora_restore_version` if you need to revert +```bash +$CLI --compact files archive +# -> {"archived":true,"fileId":""} +``` -### Edit a file with working copies +Destructive — confirm with user before running. -1. Call `elnora_create_working_copy` with the file ID -2. Make edits (the working copy is mutable) -3. Call `elnora_commit_working_copy` to save changes as a new version +### Promote File -### Copy a file to another project +```bash +$CLI --compact files promote --visibility +``` -1. Get the source file ID from `elnora_list_files` or `elnora_search_files` -2. Get the target project ID from `elnora_list_projects` -3. Call `elnora_fork_file` with both IDs +`--visibility` is required. -### Reference a file in a task conversation +### Fork File -Use file IDs from `elnora_list_files` as `file_ids` in `elnora_send_message` or `context_file_ids` in `elnora_create_task` to give the AI context about existing protocols or datasets. +```bash +$CLI --compact files fork --target-project +``` -## Presigned URL Upload (Large/Binary Files) +`` is positional (`fileId`). `--target-project` is a flag (`targetProject` doesn't end in "Id"). -For files too large for inline upload (>100KB) or binary files, use the two-step presigned URL flow: +### Working Copy -### elnora_initiate_upload +```bash +$CLI --compact files working-copy +$CLI --compact files working-copy --task +``` -Start a multi-step file upload. Returns a presigned URL for uploading content directly to storage. +### Commit Working Copy -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | -| `file_name` | string | Yes | Filename (min: 1, max: 255 chars) | -| `content_type` | string | No | MIME type (default: application/octet-stream) | -| `file_size_bytes` | integer | Yes | File size in bytes | +```bash +$CLI --compact files commit +``` -Returns a presigned URL and file ID. PUT the file content to the URL, then confirm. +### Search File Content -### elnora_confirm_upload +```bash +$CLI --compact files search-content --query "annealing temperature" +$CLI --compact files search-content --query "BRCA1" --project +$CLI --compact files search-content --query "gel electrophoresis" --page-size 10 +``` -Confirm that a file upload to the presigned URL has completed. +Full-text search inside file contents. Also available as `search file-content`. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `file_id` | uuid | Yes | File UUID from `elnora_initiate_upload` | +| Flag | Required | Notes | +|------|----------|-------| +| `--query` | Yes | Search query string (no `-q` shorthand) | +| `--project` | No | Project UUID to filter | +| `--page` | No | Page number (default 1) | +| `--page-size` | No | Results per page (default 25, max 100) | -## Search Inside Files +## Agent Recipes -### elnora_search_file_content +**Read a protocol from a project:** -Full-text search inside file bodies. Finds content within protocols and documents, not just metadata. +```bash +$CLI --compact --fields "id,name" files list --project +$CLI files content +``` -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `query` | string | Yes | - | Search query (min: 1, max: 1,000 chars) | -| `page` | integer | No | 1 | Page number | -| `page_size` | integer | No | 25 | Results per page (max: 100) | +**Upload a file and reference it in a task:** -## Token Efficiency +```bash +$CLI --compact files upload --project --file-path /path/to/protocol.md +# Use the returned file ID: +$CLI --compact tasks send --message "Optimize this protocol" --file-refs "" --wait +``` -All file tools support optional `compact` and `fields` parameters: +**Edit-in-place (working copy):** -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `compact` | boolean | false | Strip null/empty values (~30-40% token savings) | -| `fields` | string | all | Comma-separated field names (e.g., "id,name") | +```bash +WC=$($CLI --compact files working-copy | jq -r '.id') +# ... make edits externally ... +$CLI --compact files commit "$WC" +``` diff --git a/elnora/skills/elnora-folders/SKILL.md b/elnora/skills/elnora-folders/SKILL.md index 012558a..553b472 100644 --- a/elnora/skills/elnora-folders/SKILL.md +++ b/elnora/skills/elnora-folders/SKILL.md @@ -1,72 +1,82 @@ --- name: elnora-folders description: > - Use this skill when the user asks about "Elnora folders", "project folders", - "organize files", "move folder", "create folder", "rename folder", - "delete folder", or any task involving folder management within Elnora projects. + This skill should be used when the user asks to "create folder", "list folders", + "rename folder", "move folder", "delete folder", "organize files into folders", + or any task involving Elnora Platform project folder management. --- # Elnora Folders -Manage folders within Elnora projects via MCP tools. Folders organize files -hierarchically inside a project. +Manage the folder tree within Elnora projects. -## Organization Context +## Invocation -All folder tools accept an optional `org_id` parameter (UUID). When provided, -the operation targets that organization instead of the user's active org. The -user must be a member of the target org. +```bash +CLI="elnora" +``` -## Core Concepts +## Commands -- **Folders** exist within a project and organize files into a hierarchy. -- Folders can be nested — a folder can have a **parent folder**. -- Moving a folder to root means setting no parent. -- **Deleting a folder is destructive** — always confirm with the user before proceeding. +### List Folders -## Tools Reference +```bash +$CLI --compact folders list +``` -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_list_folders` | List folders in a project | `project_id` | -| `elnora_create_folder` | Create a new folder | `project_id`, `name`, optional `parent_id` | -| `elnora_rename_folder` | Rename a folder | `project_id`, `folder_id`, `name` | -| `elnora_move_folder` | Move a folder to a new parent | `project_id`, `folder_id`, optional `parent_id` | -| `elnora_delete_folder` | Delete a folder | `project_id`, `folder_id` | +`` is positional (`projectId`). Returns the folder tree for the project. -### Parameter Details +### Create Folder -- **`project_id`** (required): The UUID of the project containing the folders. -- **`folder_id`** (required for rename/move/delete): The UUID of the target folder. -- **`parent_id`** (optional): The UUID of the parent folder. Omit to place at root level. -- **`name`** (required for create/rename): The folder name. +```bash +$CLI --compact folders create --name "Experiments" +$CLI --compact folders create --name "Sub Folder" --parent-id +``` -## Common Workflows +| Flag/Arg | Required | Notes | +|----------|----------|-------| +| `` | Yes | Positional — project UUID | +| `--name` | Yes | Folder name | +| `--parent-id` | No | Parent folder UUID for nesting (optional, so it's a flag) | -### Browse project folder structure +### Rename Folder -1. `elnora_list_folders` with `project_id` to see all folders and their hierarchy +```bash +$CLI --compact folders rename --name "New Name" +``` -### Create a nested folder +### Move Folder -1. `elnora_list_folders` to find the parent folder's ID -2. `elnora_create_folder` with `project_id`, `name`, and `parent_id` +```bash +$CLI --compact folders move +$CLI --compact folders move root +``` -### Move a folder to root +Both `` and `` are positional (`folderId` and `parentId`). Use `root` to move to the project root level. -1. `elnora_move_folder` with `project_id` and `folder_id`, omitting `parent_id` +### Delete Folder -### Reorganize folders +```bash +$CLI --compact folders delete +# -> {"deleted":true,"folderId":""} +``` -1. `elnora_list_folders` to see current structure -2. `elnora_move_folder` to relocate folders as needed -3. `elnora_rename_folder` to update names if required +Destructive — confirm with user before running. -### Delete a folder +## Agent Recipes -1. **Confirm with the user first** — deletion is destructive -2. `elnora_delete_folder` with `project_id` and `folder_id` +**Set up folder structure for a new project:** -## ID Format +```bash +PROJECT="" +$CLI --compact folders create "$PROJECT" --name "Protocols" +$CLI --compact folders create "$PROJECT" --name "Data" +$CLI --compact folders create "$PROJECT" --name "Reports" +``` -All IDs are UUIDs (e.g., `bfdc6fbd-40ed-4042-9ea7-c79a5ec90085`). +**Move a file into a folder:** + +```bash +$CLI --compact folders list +$CLI --compact files update --folder +``` diff --git a/elnora/skills/elnora-orgs/SKILL.md b/elnora/skills/elnora-orgs/SKILL.md index fd9ef43..2076e9f 100644 --- a/elnora/skills/elnora-orgs/SKILL.md +++ b/elnora/skills/elnora-orgs/SKILL.md @@ -1,103 +1,222 @@ --- name: elnora-orgs description: > - Use this skill when the user asks about "Elnora organizations", "org members", - "org billing", "org invitations", "shared library", "library folders", - "org settings", or any task involving Elnora organization management. - Covers org CRUD, membership, invitations, billing, and the shared library. + This skill should be used when the user asks to "list organizations", "create org", + "org members", "billing", "invite member", "manage invitations", "organization library", + "shared library", "library files", "library folders", "set default org", "delete org", + "list all orgs", "set stripe", + or any task involving Elnora Platform organization management and shared library resources. --- -# Elnora Organizations +# Elnora Organizations & Library -Manage organizations, members, invitations, billing, and the shared org library -via Elnora MCP tools. +Manage organizations, members, billing, invitations, and the shared organization library. -## Core Concepts +## Invocation -- **Organizations** are the top-level container. They hold projects, members, and a shared library. -- **Members** have roles (owner, admin, member). Use the **membership ID** (not user ID) for role updates and removals. -- **Invitations** are sent by email with a role. They can be cancelled before acceptance. -- **Billing** is per-org. Query it to check plan, usage, and limits. -- **Shared Library** stores org-wide files and folders accessible to all members. +```bash +CLI="elnora" +``` -## Tools Reference +## Organization Commands -### Organization CRUD +### List Organizations -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_list_orgs` | List all orgs the user belongs to | — | -| `elnora_get_org` | Get org details | `org_id` | -| `elnora_create_org` | Create a new org | `name` | -| `elnora_update_org` | Update org settings | `org_id`, fields to update | +```bash +$CLI --compact orgs list +``` -### Membership +### Get Organization -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_list_org_members` | List members of an org | `org_id` | -| `elnora_update_org_member_role` | Change a member's role | `org_id`, `membership_id`, `role` | -| `elnora_remove_org_member` | Remove a member from org | `org_id`, `membership_id` | +```bash +$CLI --compact orgs get +``` -**Important**: `elnora_update_org_member_role` and `elnora_remove_org_member` require the -**membership ID**, not the user ID. Get it from `elnora_list_org_members` first. +### Create Organization -### Invitations +```bash +$CLI --compact orgs create --name "Elnora Bio Lab" +$CLI --compact orgs create --name "Elnora Bio Lab" --description "Main research org" +``` -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_invite_org_member` | Invite someone by email | `org_id`, `email`, `role` | -| `elnora_list_org_invitations` | List pending invitations | `org_id` | -| `elnora_cancel_org_invitation` | Cancel a pending invitation | `org_id`, `invitation_id` | +### Update Organization -### Billing +```bash +$CLI --compact orgs update --name "New Name" +$CLI --compact orgs update --description "Updated description" +``` -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_get_org_billing` | Get billing/plan info | `org_id` | +Must provide at least one of `--name` or `--description`. -### Shared Library +### List Members -The shared library provides org-wide file and folder storage. +```bash +$CLI --compact orgs members +``` -| Tool | Purpose | Key Parameters | -|------|---------|----------------| -| `elnora_list_library_files` | List files in the shared library | `org_id`, optional `folder_id` | -| `elnora_list_library_folders` | List library folders | `org_id` | -| `elnora_create_library_folder` | Create a library folder | `org_id`, `name` | -| `elnora_rename_library_folder` | Rename a library folder | `org_id`, `folder_id`, `name` | -| `elnora_delete_library_folder` | Delete a library folder | `org_id`, `folder_id` | +### Update Member Role -**Warning**: `elnora_delete_library_folder` is destructive. Confirm with the user before deleting. +```bash +$CLI --compact orgs update-role --role Admin +``` -## Common Workflows +Both positional. `--role` is required. Uses the **membership ID** (not user ID) — get it from `orgs members`. -### List orgs and inspect one +### Remove Member -1. `elnora_list_orgs` to get all orgs -2. `elnora_get_org` with the chosen `org_id` for details +```bash +$CLI --compact orgs remove-member +# -> {"removed":true} +``` -### Invite a new member +Both positional. Destructive — confirm with user first. -1. `elnora_invite_org_member` with `org_id`, `email`, and `role` -2. `elnora_list_org_invitations` to confirm the invitation was sent +### Get Billing -### Change a member's role +```bash +$CLI --compact orgs billing +``` -1. `elnora_list_org_members` with `org_id` to find the `membership_id` -2. `elnora_update_org_member_role` with `org_id`, `membership_id`, and new `role` +### List Org Files (Admin Compliance View) -### Manage the shared library +```bash +$CLI --compact orgs files +$CLI --compact orgs files --page 2 --page-size 50 +``` -1. `elnora_list_library_folders` to see existing folders -2. `elnora_create_library_folder` to add a new folder -3. `elnora_list_library_files` with optional `folder_id` to browse contents +`` is positional (`orgId`). Lists all files across all projects in the organization. -### Check billing +### Set Default Organization -1. `elnora_list_orgs` to get the `org_id` -2. `elnora_get_org_billing` to view plan, usage, and limits +```bash +$CLI --compact orgs set-default +``` -## ID Format +### Set Stripe Customer ID (SystemAdmin) -All IDs are UUIDs (e.g., `bfdc6fbd-40ed-4042-9ea7-c79a5ec90085`). +```bash +$CLI --compact orgs set-stripe +``` + +Both positional. Example: `elnora --compact orgs set-stripe cus_xxx` + +### List All Organizations (SystemAdmin) + +```bash +$CLI --compact orgs list-all +``` + +### Delete Organization + +```bash +$CLI --compact orgs delete +$CLI --compact orgs delete --yes +# -> {"deleted":true,"orgId":""} +``` + +**DANGEROUS.** Requires y/N confirmation. Use `--yes` to skip (non-interactive/CI only). + +## Invitation Commands + +### Send Invitation + +```bash +$CLI --compact orgs invite --email user@example.com +$CLI --compact orgs invite --email user@example.com --role Admin +``` + +### List Pending Invitations + +```bash +$CLI --compact orgs invitations +``` + +### Cancel Invitation + +```bash +$CLI --compact orgs cancel-invite +# -> {"cancelled":true,"invitationId":"..."} +``` + +Both positional. + +### Get Invitation Info (by token) + +```bash +$CLI --compact orgs invitation-info --token +``` + +`--token` is a flag (not positional — `token` doesn't end in "Id"). + +### Accept Invitation + +```bash +$CLI --compact orgs accept-invite --token +``` + +`--token` is a flag. + +## Organization Library Commands + +The organization library holds shared files and folders accessible to all org members. + +### List Library Files + +```bash +$CLI --compact library files --org +$CLI --compact library files --org --page 2 --page-size 50 +``` + +`--org` is a flag (`org` doesn't end in "Id"). + +### List Library Folders + +```bash +$CLI --compact library folders --org +``` + +### Create Library Folder + +```bash +$CLI --compact library create-folder --org --name "Shared Protocols" +$CLI --compact library create-folder --org --name "Sub Folder" --parent +``` + +### Rename Library Folder + +```bash +$CLI --compact library rename-folder --org --name "New Name" +``` + +`` is positional (`folderId`). `--org` and `--name` are flags. + +### Delete Library Folder + +```bash +$CLI --compact library delete-folder --org +# -> {"deleted":true,"folderId":"..."} +``` + +Destructive — confirm with user first. + +## Agent Recipes + +**Get org ID, then check billing:** + +```bash +ORG=$($CLI --compact orgs list | jq -r 'if type == "array" then .[0].id else .items[0].id end') +$CLI --compact orgs billing "$ORG" +``` + +**Invite a team member:** + +```bash +$CLI --compact orgs invite --email new.researcher@lab.com --role Member +``` + +**Browse shared library:** + +```bash +$CLI --compact library folders --org +$CLI --compact library files --org +``` diff --git a/elnora/skills/elnora-platform/SKILL.md b/elnora/skills/elnora-platform/SKILL.md index d11adae..e276845 100644 --- a/elnora/skills/elnora-platform/SKILL.md +++ b/elnora/skills/elnora-platform/SKILL.md @@ -1,98 +1,167 @@ --- name: elnora-platform description: > - Use when the user asks about Elnora platform, Elnora AI, bioprotocol generation, - platform API, elnora projects, elnora tasks, elnora files, protocol generation, - platform search, elnora orgs, elnora folders, elnora admin, API keys, - elnora health, elnora auth, or any task involving the Elnora AI Platform. + Use when the user asks about "Elnora platform", "elnora CLI", + "platform API", "elnora projects", "elnora tasks", "elnora files", "protocol generation", + "platform search", "elnora orgs", "elnora folders", "elnora admin", "API keys", + "elnora health", "elnora auth", or any task involving the Elnora AI Platform. Routes to domain-specific sub-skills for token-efficient guidance. --- -# Elnora Platform +# Elnora Platform CLI Route Elnora Platform queries to the correct sub-skill. Load only what is needed. -## What is Elnora? +## Invocation -Elnora is an AI-powered platform that helps researchers generate, optimize, and manage bioprotocols for wet-lab experiments. This plugin connects your agent to the Elnora Platform via MCP. +```bash +CLI="elnora" +``` + +Global flags go BEFORE the subcommand: -## Authentication +```bash +$CLI --compact projects list # correct +$CLI projects list --compact # WRONG -- fails +``` -Auth is handled automatically by the MCP connection: +## Global Flags -- **OAuth 2.1** (recommended): Browser popup on first use, tokens refresh automatically -- **API Key**: Set as Bearer token in MCP headers (create at platform.elnora.ai > Settings > API Keys) +| Flag | Effect | +|------|--------| +| `--compact` | Minified JSON — always use for agent workflows | +| `--output ` | Output format (default: json) | +| `--fields "id,name"` | Return only these fields | +| `--profile ` | Named profile (default: `default`). Set with `auth login --api-key --profile ` | +| `--json` | Force JSON output | -No manual login required. +## Auth -## Token Efficiency +Requires `ELNORA_API_KEY` environment variable (prefix: `elnora_live_`), `ELNORA_MCP_API_KEY`, or a saved profile in `~/.elnora/profiles.toml`. -All MCP tools support two optional params for reducing token usage: +```bash +$CLI --compact auth status +# -> {"profile":"default","authenticated":true,"projectCount":N} +``` -| Param | Effect | -|-------|--------| -| `compact: true` | Strip null/empty values (~30-40% savings). Always use in agent workflows. | -| `fields: "id,name"` | Return only specified fields. Applied to each item in paginated results. | +Get keys: platform.elnora.ai > Settings > API Keys ## Routing Table | Need | Sub-skill | Trigger keywords | |------|-----------|------------------| -| List/get/create/update/archive projects, manage members | `elnora-projects` | project, workspace, create project, members | -| Create/manage/message tasks, protocol generation | `elnora-tasks` | task, protocol, send message, generate | -| Browse/read/upload/create/version/fork files | `elnora-files` | file, content, version history, upload, download, fork | -| Find tasks, files, or content by keyword | `elnora-search` | search, find, query, search file content | +| List/get/create/update/archive projects, manage members | `elnora-projects` | project, workspace, create project, members, add member | +| Create/manage/message tasks, protocol generation | `elnora-tasks` | task, protocol, send message, conversation, generate | +| Browse/read/upload/create/version/fork files | `elnora-files` | file, content, version history, upload, download, fork, working copy | +| Find tasks or files by keyword | `elnora-search` | search, find, query | | Manage project folder trees | `elnora-folders` | folder, create folder, move folder | | Org management, members, billing, invitations, shared library | `elnora-orgs` | organization, org, billing, invite, library | -| Auth, API keys, account, health, diagnostics | `elnora-admin` | api key, health, account, feedback, audit, flags | +| Auth, API keys, account, health, diagnostics | `elnora-admin` | login, logout, profiles, api key, health, account, feedback, audit, completion | +| Feature flags (SystemAdmin) | `elnora-admin` | feature flag, flags, set flag, list flags | | What can the Elnora Agent do? (tools, search, memory) | `elnora-agent` | agent capabilities, agent tools, what can agent do | -## Organization Context +## Positional Argument Convention + +Required string fields ending in `Id` (e.g. `taskId`, `projectId`, `fileId`) become positional arguments. Everything else becomes a flag. -Most org-scoped tools (projects, tasks, files, folders, search) accept an -optional `org_id` parameter (UUID). When provided, the operation targets that -organization instead of the user's active org. The user must be a member of the -target org. +```bash +elnora tasks get # taskId -> positional +elnora tasks list --project # project -> flag (doesn't end in "Id") +elnora files fork --target-project # fileId -> positional, targetProject -> flag +``` -**Workflow for org switching:** -1. Call `elnora_list_orgs` first to discover available org IDs and names -2. Pass the target `org_id` to any org-scoped tool (e.g., `elnora_list_projects`, `elnora_create_task`) -3. By-ID tools (get, update, archive, delete) do NOT need `org_id` — they resolve via ownership +**Rule:** positional if and only if the field is: required + not boolean + no enum choices + key ends in "Id". ## ID Format -All IDs are UUIDs (e.g., `bfdc6fbd-40ed-4042-9ea7-c79a5ec90085`). +All IDs are UUIDs: `bfdc6fbd-40ed-4042-9ea7-c79a5ec90085`. Invalid format exits 1 with a suggestion showing the correct list command. + +Exception: `account get` and `account update` use `userId` which accepts any string (typically an integer like `42`). ## Pagination -List endpoints return paginated results: +List endpoints return: ```json -{"items": [...], "page": 1, "pageSize": 25, "totalCount": N, "totalPages": N, "hasNextPage": true} +{"items":[...],"page":1,"pageSize":25,"totalCount":N,"totalPages":N,"hasNextPage":true} ``` -Use `page` and `pageSize` parameters (max 100). Check `hasNextPage` to paginate. +Use `--page N --page-size N` (max 100). Check `hasNextPage` to paginate. -Message endpoints use cursor-based pagination: check `hasMore` and pass `cursor` from `nextCursor`. +Message endpoints use cursor-based pagination: check `hasMore` and pass `--cursor `. -## Common Workflow +## Error Contract -Projects contain tasks and files. Typical flow: +Errors -> stderr, exit code > 0: + +```json +{"error":"message","code":"AUTH_FAILED","suggestion":"how to fix"} +``` + +| Code | Exit | Action | +|------|------|--------| +| `AUTH_FAILED` | 3 | Check ELNORA_API_KEY env var or profile | +| `NOT_FOUND` | 4 | Verify the UUID | +| `VALIDATION_ERROR` | 2 | Check parameters | +| `RATE_LIMITED` | 5 | Wait and retry (see Rate Limits below) | +| `SERVER_ERROR` | 6 | Retry later | +| `ELNORA_ERROR` | 1 | Unexpected — report bug | + +## Rate Limits -1. `elnora_list_projects` — get project ID -2. `elnora_create_task` — start a conversation with Elnora AI -3. `elnora_send_message` — describe the protocol you need -4. `elnora_get_task_messages` — read the AI response -5. `elnora_list_files` — browse generated outputs -6. `elnora_get_file_content` — read a protocol file +HTTP 429 on limit. Check the `Retry-After` header for seconds to wait. -## Quick Protocol Generation +| Context | Limit | Window | +|---------|-------|--------| +| API key (CLI/agent default) | 200 req | 1 min | +| Agent processing endpoints | 100 req per task | 1 min | +| AI processing (tasks send, protocol generate) | 20 req | 1 min | +| Auth endpoints (login, register) | 5 req | 1 min | +| Global fallback (per IP) | 1000 req | 1 min | -For one-shot protocol generation, use `elnora_generate_protocol`: +**Agent strategy:** On exit code 5, read `Retry-After` from stderr if available, otherwise wait 60 seconds before retrying. Do not retry in a tight loop. -- `description`: What protocol you need (e.g., "HEK 293 cell maintenance protocol") -- Returns the complete generated protocol +## File Upload Limits -## Tool Discovery +| Constraint | Value | +|-----------|-------| +| Max file size | 100 MB | +| Max filename length | 255 characters | +| Max files per batch upload | 50 | +| Accepted MIME types | Unrestricted (any type) | +| Upload presigned URL expiry | 15 minutes | +| Download presigned URL expiry | 5 minutes | -Each sub-skill lists its own MCP tools with full parameter docs and workflow recipes. Load the relevant sub-skill from the routing table above to see available tools. +## Common Workflow + +Projects contain tasks and files. Typical flow: + +1. `projects list` -> get project ID +2. `tasks create --project --message "..."` -> create task with initial prompt +3. `tasks send --message "..." --wait` -> send message and wait for response +4. `files list --project ` -> browse generated outputs +5. `files content ` -> read a protocol file + +## All Command Groups + +``` +elnora account Manage user account, agreements, and legal docs +elnora api-keys Manage API keys and creation policy +elnora audit View audit logs +elnora auth Manage authentication +elnora completion Generate shell completion script +elnora doctor Run diagnostics (API, auth, version, config checks) +elnora feedback Submit feedback +elnora files Manage project files (incl. batch upload) +elnora flags Manage global feature flags (SystemAdmin) +elnora folders Manage project folders +elnora health Check platform reachability +elnora library Manage organization library +elnora mcp Run as MCP server (--http or --stdio) +elnora open Open platform pages in browser +elnora orgs Manage organizations (incl. set-default, delete, list-all) +elnora projects Manage projects +elnora search Search tasks, files, and file content +elnora tasks Manage tasks +elnora whoami Show current profile and org +``` diff --git a/elnora/skills/elnora-projects/SKILL.md b/elnora/skills/elnora-projects/SKILL.md index 1311fed..b671fab 100644 --- a/elnora/skills/elnora-projects/SKILL.md +++ b/elnora/skills/elnora-projects/SKILL.md @@ -3,222 +3,124 @@ name: elnora-projects description: > This skill should be used when the user asks to "list projects", "create a project", "get project details", "show my Elnora projects", "new project", "project members", - "add member", "remove member", "change role", "archive project", + "update project", "archive project", "add member", "remove member", "leave project", or any task involving Elnora Platform project management. --- # Elnora Projects -Manage projects on the Elnora AI Platform. Projects are the top-level containers for tasks (conversations) and files (protocol outputs). Each project has members with roles that control access. +Manage projects on the Elnora AI Platform. Projects are containers for tasks, files, and folders. -## Organization Context +## Invocation -All list and create tools accept an optional `org_id` parameter (UUID). When -provided, the operation targets that organization instead of the user's active -org. The user must be a member of the target org. - -## Concepts - -- **Project**: A workspace containing tasks and files. Has a name, description, icon, and member list. -- **Member roles**: `owner` (full control, cannot be removed), `admin` (manage members and settings), `member` (create tasks and files). -- **Archive**: Soft-deletes a project. **This hides all tasks and files in the project.** Always confirm with the user first. -- **All IDs are UUIDs** (e.g., `bfdc6fbd-40ed-4042-9ea7-c79a5ec90085`). - -## MCP Tools - -### elnora_list_projects - -List all projects you have access to. - -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `page` | integer | No | 1 | Page number (min: 1) | -| `page_size` | integer | No | 25 | Results per page (min: 1, max: 100) | - -Returns paginated results: - -```json -{ - "items": [ - { - "id": "", - "name": "Protocol Lab", - "description": "PCR and cloning protocols", - "icon": "...", - "isDefault": false, - "isArchived": false, - "memberCount": 3, - "myRole": "owner", - "createdAt": "...", - "updatedAt": "..." - } - ], - "page": 1, - "pageSize": 25, - "totalCount": 4, - "totalPages": 1, - "hasNextPage": false -} +```bash +CLI="elnora" ``` -Key fields: `id` (needed for all other operations), `name`, `myRole`, `memberCount`. +## Commands -### elnora_get_project +### List Projects -Get full details for a single project, including its member list. - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | +```bash +$CLI --compact projects list +$CLI --compact projects list --page 2 --page-size 50 +$CLI --compact --fields "id,name" projects list +``` -Returns project detail with `members` array: +Response: ```json -{ - "id": "", - "name": "Protocol Lab", - "description": "...", - "icon": "...", - "memberCount": 2, - "myRole": "owner", - "members": [ - { - "id": "", - "userId": 42, - "email": "user@example.com", - "displayName": "Jane Doe", - "role": "owner", - "createdAt": "..." - } - ] -} +{"items":[{"id":"","name":"...","description":"...","isDefault":false,"isArchived":false,"memberCount":1,"myRole":"owner","createdAt":"..."}],"page":1,"totalCount":N,"hasNextPage":false} ``` -Use this to check membership and roles before performing operations. - -### elnora_create_project - -Create a new project. - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `name` | string | Yes | Project name (min: 1, max: 200 chars) | -| `description` | string | No | Project description (max: 2,000 chars) | -| `icon` | string | No | Project icon/emoji (max: 50 chars) | - -Returns the created project with its new `id`. The creating user becomes the owner. - -### elnora_update_project - -Update project metadata. - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | -| `name` | string | No | New name (min: 1, max: 200 chars) | -| `description` | string | No | New description (max: 2,000 chars) | -| `icon` | string | No | New icon (max: 50 chars) | +### Get Project -Must provide at least one of `name`, `description`, or `icon`. - -### elnora_archive_project - -Archive (soft-delete) a project. **This hides all tasks and files in the project. Confirm with the user before calling.** - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | - -## Member Management - -### elnora_list_project_members +```bash +$CLI --compact projects get +``` -List all members of a project. +Returns project detail with `members` array. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | +### Create Project -Returns an array of members with `userId`, `email`, `displayName`, and `role`. +```bash +$CLI --compact projects create --name "Protocol Lab" --description "PCR protocols" --icon "lab" +``` -### elnora_add_project_member +| Flag | Required | Notes | +|------|----------|-------| +| `--name` | Yes | Project name | +| `--description` | No | Project description | +| `--icon` | No | Project icon | -Add a user to a project. +### Update Project -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | -| `user_id` | string | Yes | User ID to add (max: 255 chars) | -| `role` | string | No | Role to assign (default: "Member", max: 100 chars) | +```bash +$CLI --compact projects update --name "New Name" +$CLI --compact projects update --description "Updated description" +``` -### elnora_remove_project_member +Must provide at least one of `--name`, `--description`, or `--icon`. -Remove a user from a project. +### Archive Project -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | -| `user_id` | string | Yes | User ID to remove (max: 255 chars) | +```bash +$CLI --compact projects archive +# -> {"archived":true,"projectId":""} +``` -Cannot remove the project owner. +Destructive — confirm with user before running. -### elnora_update_project_member_role +### List Members -Change a project member's role. +```bash +$CLI --compact projects members +``` -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | -| `user_id` | string | Yes | User ID (max: 255 chars) | -| `role` | string | Yes | New role (max: 100 chars) | +### Add Member -### elnora_leave_project +```bash +$CLI --compact projects add-member --role Member +``` -Leave a project you are a member of. +Both `` and `` are positional (`projectId` and `userId`). `--role` defaults to "Member". -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | Yes | Project UUID | +### Update Member Role -Owners cannot leave their own project without transferring ownership first. +```bash +$CLI --compact projects update-role --role Admin +``` -## Pagination +Both positional. `--role` is required. -List endpoints return page-based pagination: +### Remove Member -```json -{ - "items": [...], - "page": 1, - "pageSize": 25, - "totalCount": 50, - "totalPages": 2, - "hasNextPage": true -} +```bash +$CLI --compact projects remove-member +# -> {"removed":true} ``` -If `hasNextPage` is true, increment `page` and call again. +Both positional. Destructive — confirm with user before running. -## Agent Workflow Recipes +### Leave Project -### Find a project by name - -1. Call `elnora_list_projects` to get all projects -2. Scan the `items` array for a matching `name` -3. Use the `id` for subsequent operations +```bash +$CLI --compact projects leave +``` -### Create a project and start generating protocols +Removes the current user from the project. -1. Call `elnora_create_project` with a `name` and `description` -2. Call `elnora_create_task` with the new project's `id` and an `initial_message` -3. Read the response with `elnora_get_task_messages` +## Agent Recipes -### Check project membership before adding someone +**Get the default project ID:** -1. Call `elnora_get_project` to see current members -2. If the user is not already a member, call `elnora_add_project_member` +```bash +$CLI --compact --fields "id,name" projects list --page-size 5 +``` -### Transfer effective ownership +**Full project setup with members:** -1. Call `elnora_update_project_member_role` to promote another member to owner/admin -2. The original owner remains but the new member now has elevated access +```bash +PROJECT=$($CLI --compact projects create --name "New Lab" | jq -r '.id') +$CLI --compact projects add-member "$PROJECT" --role Member +``` diff --git a/elnora/skills/elnora-search/SKILL.md b/elnora/skills/elnora-search/SKILL.md index d10a001..9e3b950 100644 --- a/elnora/skills/elnora-search/SKILL.md +++ b/elnora/skills/elnora-search/SKILL.md @@ -3,158 +3,84 @@ name: elnora-search description: > This skill should be used when the user asks to "search tasks", "find a protocol", "search files", "search file content", "search inside files", "find tasks about", - "look up", "query Elnora", "search Elnora", "full text search", - or any task involving searching the Elnora Platform for tasks or files by keyword. + "query Elnora", "search Elnora platform", "full text search", + or any task involving searching the Elnora Platform for tasks, files, or all resources + by keyword. NOT for web search — use elnora-agent for that. --- # Elnora Search -Full-text search across tasks and files on the Elnora AI Platform. Search by keyword to find protocols, conversations, and documents across all projects you have access to. +Search tasks, files, or all resources across projects by keyword. -## Organization Context +## Invocation -All search tools accept an optional `org_id` parameter (UUID). When provided, -the search targets that organization instead of the user's active org. The user -must be a member of the target org. - -## Concepts - -- **Search results** include a `snippet` with HTML-bold highlighted matches and a `rank` score for relevance sorting. -- **Search is read-only.** Use search to find resources, then use domain-specific tools (`elnora_get_task`, `elnora_get_file_content`, etc.) to act on them. -- Results span all projects you have access to. There is no project filter on search -- use `elnora_list_tasks` or `elnora_list_files` with `project_id` to browse within a single project. - -## MCP Tools +```bash +CLI="elnora" +``` -### elnora_search_all +## Commands -Full-text search across all resource types (tasks, files, etc.) in a single call. +### Search Tasks -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `query` | string | Yes | - | Search query (min: 1, max: 1,000 chars) | -| `page` | integer | No | 1 | Page number (min: 1) | -| `page_size` | integer | No | 25 | Results per page (min: 1, max: 100) | +```bash +$CLI --compact search tasks --query "PCR protocol" +$CLI --compact search tasks --query "BRCA1" --page-size 10 +``` -Returns paginated results: +Results include `snippet` with HTML-bold match highlights and `rank` for relevance: ```json -{ - "items": [ - { - "type": "task", - "id": "", - "title": "PCR Protocol for BRCA1", - "snippet": "...amplify BRCA1 exon 11 using standard PCR...", - "projectId": "", - "createdAt": "...", - "rank": 0.85 - }, - { - "type": "file", - "id": "", - "title": "brca1-protocol-v2.md", - "snippet": "...PCR amplification protocol for...", - "projectId": "", - "createdAt": "...", - "rank": 0.72 - } - ], - "page": 1, - "totalCount": 8, - "hasNextPage": false -} +{"items":[{"type":"task","id":"","title":"...","snippet":"...with highlighted matches...","projectId":"","rank":0.06}],"page":1,"totalCount":N,"hasNextPage":false} ``` -Use the `type` field to distinguish between tasks and files in results. - -### elnora_search_tasks - -Full-text search scoped to tasks only. - -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `query` | string | Yes | - | Search query (min: 1, max: 1,000 chars) | -| `page` | integer | No | 1 | Page number (min: 1) | -| `page_size` | integer | No | 25 | Results per page (min: 1, max: 100) | - -Same response shape as `elnora_search_all` but only returns task results. Use this when you know you are looking for a conversation thread. - -### elnora_search_files - -Full-text search scoped to files only. +### Search Files -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `query` | string | Yes | - | Search query (min: 1, max: 1,000 chars) | -| `page` | integer | No | 1 | Page number (min: 1) | -| `page_size` | integer | No | 25 | Results per page (min: 1, max: 100) | +```bash +$CLI --compact search files --query "gel electrophoresis" +$CLI --compact search files --query "template" --page 2 +``` -Same response shape as `elnora_search_all` but only returns file results. Use this when you know you are looking for a document or protocol output. +### Search File Content -### elnora_search_file_content +```bash +$CLI --compact search file-content --query "annealing temperature" +$CLI --compact search file-content --query "BRCA1" --project-id +``` -Full-text search inside file bodies (protocols, documents). Unlike `elnora_search_files` which searches metadata, this searches the actual content of files. +Full-text search inside file contents. Also available as `files search-content` (which uses `--project` instead of `--project-id`). -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `query` | string | Yes | - | Search query (min: 1, max: 1,000 chars) | -| `page` | integer | No | 1 | Page number (min: 1) | -| `page_size` | integer | No | 25 | Results per page (min: 1, max: 100) | +Note: `search file-content` uses `--project-id` (field name: `projectId`, optional so it's a flag). `files search-content` uses `--project` (field name: `project`). -Same response shape as other search tools. Use this to find specific protocol steps, reagent mentions, or methods within generated protocols. +### Search All -## Token Efficiency +```bash +$CLI --compact search all --query "BRCA1" +$CLI --compact search all --query "transfection" --page-size 50 +``` -All search tools support optional `compact` and `fields` parameters: +Searches both tasks and files. Results include a `type` field ("task" or "file"). -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `compact` | boolean | false | Strip null/empty values (~30-40% token savings) | -| `fields` | string | all | Comma-separated field names (e.g., "id,name,snippet") | +## Shared Options -## Choosing the Right Search Tool +All four commands share: -| Goal | Tool | -|------|------| -| Find anything matching a keyword | `elnora_search_all` | -| Find a conversation about a topic | `elnora_search_tasks` | -| Find a protocol document by name | `elnora_search_files` | -| Find content INSIDE file bodies | `elnora_search_file_content` | -| Browse all files in a specific project | `elnora_list_files` (not search) | -| Browse all tasks in a specific project | `elnora_list_tasks` (not search) | +| Flag | Default | Notes | +|------|---------|-------| +| `--query` | Required | Search query string | +| `--page` | 1 | Page number | +| `--page-size` | 25 | Results per page (max 100) | -## Pagination +## Agent Recipes -Search results use page-based pagination: +**Find a task, then read it:** -```json -{ - "items": [...], - "page": 1, - "totalCount": 50, - "hasNextPage": true -} +```bash +TASK_ID=$($CLI --compact search tasks --query "BRCA1" | jq -r '.items[0].id') +$CLI --compact tasks messages "$TASK_ID" ``` -If `hasNextPage` is true, increment `page` and call again. - -## Agent Workflow Recipes - -### Find a task by topic, then read the conversation +**Broad search:** -1. Call `elnora_search_tasks` with a keyword query (e.g., "BRCA1") -2. Pick the best match by `rank` -3. Call `elnora_get_task_messages` with the task's `id` to read the full conversation - -### Find a protocol file and read its content - -1. Call `elnora_search_files` with a keyword query (e.g., "gel electrophoresis") -2. Pick the best match by `rank` -3. Call `elnora_get_file_content` with the file's `id` to read the protocol - -### Search across everything, then route by type - -1. Call `elnora_search_all` with a broad query -2. For each result, check the `type` field: - - `"task"` -- use `elnora_get_task` or `elnora_get_task_messages` - - `"file"` -- use `elnora_get_file` or `elnora_get_file_content` +```bash +$CLI --compact search all --query "HEK 293" +``` diff --git a/elnora/skills/elnora-tasks/SKILL.md b/elnora/skills/elnora-tasks/SKILL.md index b327510..8996c2d 100644 --- a/elnora/skills/elnora-tasks/SKILL.md +++ b/elnora/skills/elnora-tasks/SKILL.md @@ -9,195 +9,169 @@ description: > # Elnora Tasks -Tasks are conversation threads with the Elnora AI Platform. Each task is a chat where you send messages and receive AI-generated protocol responses. Use tasks to generate, iterate on, and refine bioprotocols. +Tasks are conversations with the Elnora AI Agent. Send messages to generate protocols, iterate on outputs, and reference uploaded files. -## Organization Context +## Response Retrieval -All list and create tools accept an optional `org_id` parameter (UUID). When -provided, the operation targets that organization instead of the user's active -org. The user must be a member of the target org. +The Elnora backend processes agent responses asynchronously. When you send a message, the POST returns immediately with the user message echo — the AI response arrives separately. -## Concepts +The CLI provides three modes for retrieving agent responses: -- **Task**: A conversation thread tied to a project. Has a title, status, and message history. -- **Message**: A single turn in the conversation. Each has a `role` (user or assistant), `sequence` number, optional `attachments`, and `content`. -- **Protocol generation**: Create a task, send a message describing what you need, and the assistant responds with a generated protocol. Iterate by sending follow-up messages. -- **All IDs are UUIDs** (e.g., `bfdc6fbd-40ed-4042-9ea7-c79a5ec90085`). +| Mode | Flag | Behavior | Timeout | +|------|------|----------|---------| +| Fire-and-forget | _(default)_ | Returns immediately, no response | — | +| Polling | `--wait` | Auto-polls every 2s until assistant message appears | 120s | +| Streaming | `--stream` | Real-time SSE token-by-token output | 300s | -## MCP Tools +**MCP mode** (`elnora_tasks_send`): Always collects the full response automatically via streaming, with polling as fallback. The caller receives `{ sent, taskId, response }` with the complete assistant content. -### elnora_list_tasks +**Recommended:** Use `--wait` for simple interactions, `--stream` for long responses where you want real-time output. -List tasks, optionally filtered by project or status. +## Invocation -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `project_id` | uuid | No | - | Filter by project UUID | -| `status` | string | No | - | Filter by status (e.g., "active", "completed") | -| `page` | integer | No | 1 | Page number (min: 1) | -| `page_size` | integer | No | 25 | Results per page (min: 1, max: 100) | +```bash +CLI="elnora" +``` -Returns paginated results: +## Commands -```json -{ - "items": [ - { - "id": "", - "projectId": "", - "title": "...", - "status": "active", - "messageCount": 4, - "lastMessageAt": "...", - "createdAt": "..." - } - ], - "page": 1, - "pageSize": 25, - "totalCount": 12, - "totalPages": 1, - "hasNextPage": false -} +### List Tasks + +```bash +$CLI --compact tasks list +$CLI --compact tasks list --project +$CLI --compact tasks list --project --page 2 --page-size 50 ``` -### elnora_get_task +Pagination: `--page` (default 1), `--page-size` (default 25, max 100). -Get full details for a single task. +Response: -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `task_id` | uuid | Yes | Task UUID | +```json +{"items":[{"id":"","projectId":"","title":"...","status":"active","messageCount":4,"lastMessageAt":"...","createdAt":"..."}],"page":1,"totalCount":N,"hasNextPage":false} +``` -Returns task detail including metadata, status, and associated project. Use this to inspect a task before reading its messages. +### Get Task -### elnora_create_task +```bash +$CLI --compact tasks get +``` -Create a new task (conversation thread). +Returns full task detail. Use this to inspect a task before interacting. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | uuid | No | Project UUID to create the task in | -| `title` | string | No | Task title (max 200 chars; auto-generated if omitted) | -| `initial_message` | string | No | Initial message to start the conversation (max 50,000 chars) | -| `context_file_ids` | uuid[] | No | File UUIDs to attach as context | +### Create Task -Returns the created task object with its `id`. Use this ID for all subsequent operations (send messages, get messages, update, archive). +```bash +$CLI --compact tasks create --project --title "PCR protocol for BRCA1" --message "Generate a simple PCR protocol for BRCA1 exon 11" +``` -To start protocol generation immediately, provide `initial_message`. To create an empty task for later use, omit it. +| Flag | Required | Notes | +|------|----------|-------| +| `--project` | Yes | Project UUID | +| `--title` | No | Task title (auto-generated if omitted) | +| `--message` | No | Initial message to start the conversation | -### elnora_send_message +Returns the created task with its `id`. If `--message` is provided, the agent will process it asynchronously — use `tasks send --wait` or `tasks messages` to retrieve the response. -Send a message to a task and receive the AI response. **May take 30-120 seconds** for complex protocol generation requests. +### Send Message -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `task_id` | uuid | Yes | Task UUID | -| `message` | string | Yes | Message content, markdown supported (min: 1, max: 50,000 chars) | -| `file_ids` | uuid[] | No | File UUIDs to attach as context | +```bash +# Fire-and-forget (returns immediately) +$CLI --compact tasks send --message "Use Taq polymerase and set annealing to 58C" -Returns the AI response. Use `file_ids` to reference uploaded files (templates, datasets) that should inform the protocol generation. +# Wait for agent response (polls until complete, 120s timeout) +$CLI --compact tasks send --message "Use Taq polymerase" --wait -### elnora_get_task_messages +# Stream response in real-time via SSE +$CLI --compact tasks send --message "Use Taq polymerase" --stream -Get message history for a task. Uses cursor-based pagination. +# Reference uploaded files +$CLI --compact tasks send --message "Optimize based on this template" --file-refs "," +``` -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `task_id` | uuid | Yes | - | Task UUID | -| `limit` | integer | No | 50 | Max messages to return (min: 1, max: 100) | -| `cursor` | string | No | - | Cursor from previous response for pagination | +| Flag | Required | Notes | +|------|----------|-------| +| `--message` | Yes | Message content | +| `--file-refs` | No | Comma-separated file UUIDs to attach as context | +| `--wait` | No | Poll for agent response (120s timeout) | +| `--stream` | No | Stream agent response in real-time via SSE | -Returns: +**Streaming details:** Status events (thinking, tool use) go to stderr, content tokens go to stdout. This makes streaming pipeable: `elnora tasks send ... --stream > response.txt`. -```json -{ - "items": [ - { - "id": "", - "role": "user", - "content": "Generate a PCR protocol for BRCA1 exon 11", - "sequence": 1, - "createdAt": "...", - "attachments": [] - }, - { - "id": "", - "role": "assistant", - "content": "# PCR Protocol for BRCA1 Exon 11\n...", - "metadata": "{\"status\":\"completed\"}", - "sequence": 2, - "createdAt": "...", - "attachments": [] - } - ], - "nextCursor": null, - "hasMore": false -} -``` +SSE event types: `think`, `tool_start`, `tool_end`, `progress`, `token`, `completed`, `error`, `timeout`. -Messages are ordered by `sequence`. If `hasMore` is true, pass `nextCursor` as `cursor` in the next call. +### Get Messages -### elnora_update_task +```bash +$CLI --compact tasks messages +$CLI --compact tasks messages --limit 10 +$CLI --compact tasks messages --cursor +``` -Update a task's title or status. +Response — messages ordered by `sequence`, with `role` (user/assistant): -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `task_id` | uuid | Yes | Task UUID | -| `title` | string | No | New title (max 200 chars) | -| `status` | string | No | New status | +```json +{"items":[{"id":"","role":"user","content":"...","sequence":1,"createdAt":"..."},{"id":"","role":"assistant","content":"...","metadata":"{\"status\":\"completed\"}","sequence":2,"createdAt":"..."}],"nextCursor":null,"hasMore":false} +``` -Must provide at least one of `title` or `status`. +Cursor-based pagination: if `hasMore` is true, pass `nextCursor` as `--cursor`. Default limit is 50 (max 100). -### elnora_archive_task +### Update Task -Archive (permanently delete) a task. **This is destructive and cannot be undone.** Always confirm with the user before calling. +```bash +$CLI --compact tasks update --title "Updated title" +$CLI --compact tasks update --status completed +``` -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `task_id` | uuid | Yes | Task UUID | +Must provide at least one of `--title` or `--status`. -## Agent Workflow Recipes +### Archive Task -### Generate a protocol (full flow) +```bash +$CLI --compact tasks archive +# -> {"archived":true,"taskId":""} +``` -1. Find or create a project: - - Call `elnora_list_projects` to get a project ID - - Or call `elnora_create_project` if needed -2. Create a task with an initial prompt: - - Call `elnora_create_task` with `project_id`, `title`, and `initial_message` - - Save the returned task `id` -3. Read the AI response: - - Call `elnora_get_task_messages` with the task ID - - Look for the message with `role: "assistant"` -4. Iterate on the output: - - Call `elnora_send_message` with refinement instructions - - Read updated messages to see the new response +Destructive — confirm with user before running. -### Quick protocol generation (shortcut) +## MCP Tool Names -For simple one-shot generation, use `elnora_generate_protocol` instead: +All commands are auto-registered as MCP tools with the `elnora_` prefix: -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `description` | string | Yes | Protocol description (min: 10, max: 5,000 chars) | -| `title` | string | No | Task title (max 200 chars) | +| CLI command | MCP tool name | +|-------------|---------------| +| `tasks list` | `elnora_tasks_list` | +| `tasks get` | `elnora_tasks_get` | +| `tasks create` | `elnora_tasks_create` | +| `tasks send` | `elnora_tasks_send` | +| `tasks messages` | `elnora_tasks_messages` | +| `tasks update` | `elnora_tasks_update` | +| `tasks archive` | `elnora_tasks_archive` | -This creates a task, sends the description, waits for the response, and returns the result in one call. Takes 30-120 seconds. Use the full flow above when you need to iterate. +MCP tools accept the same parameters as CLI flags (camelCase). `elnora_tasks_send` always waits for the full agent response. -### Check the latest assistant response +## Agent Recipes -1. Call `elnora_get_task_messages` with `limit: 2` -2. Find the message where `role` is `"assistant"` -- this is the most recent AI output +**Full protocol generation with --wait:** -### Iterate on a protocol with file context +```bash +PROJECT=$($CLI --compact --fields "id" projects list | jq -r '.items[0].id') +TASK=$($CLI --compact tasks create --project "$PROJECT" --title "PCR BRCA1" --message "Generate PCR protocol for BRCA1 exon 11" | jq -r '.id') +$CLI --compact tasks send "$TASK" --message "Add gel electrophoresis step" --wait +``` + +**Read latest assistant response:** -1. Get the file ID from `elnora_list_files` or `elnora_search_files` -2. Call `elnora_send_message` with the task ID, your refinement message, and `file_ids` containing the reference file -3. The AI will use the file content to inform its response +```bash +$CLI --compact tasks messages | jq '.items[-1] | select(.role == "assistant") | .content' +``` -### Pagination for long conversations +**Manual polling (custom timeout/retry):** -1. Call `elnora_get_task_messages` with `limit: 50` -2. If `hasMore` is `true`, call again with `cursor` set to `nextCursor` -3. Repeat until `hasMore` is `false` +```bash +# Poll until the last message is from the assistant +LAST=$($CLI --compact tasks messages | jq '.items[-1]') +echo "$LAST" | jq '{role: .role, status: (.metadata | fromjson? // {} | .status)}' +# -> {"role":"assistant","status":"completed"} <- ready +# -> {"role":"user","status":null} <- still processing +```