feat: add resend tools, MCP collection endpoint, and UI refinements

- Add @tpmjs/tools-resend with email API tools and blocks.yml entries
- Add MCP route for collection skill discovery
- Add InstallationSection component for collections
- Refactor collection pages to use shared components and simplify layouts
- Update skills questions API, rate limiting, and API key handling
- Add tpmjs-tool-creator skill for Claude
- Update video feature scenes and fix lint issues
- Update .gitignore with IDE and temp file exclusions
This commit is contained in:
Ajax Davis 2026-02-07 00:49:40 +10:00
parent f3a46045ba
commit a52d32c367
40 changed files with 3310 additions and 1694 deletions

View file

@ -0,0 +1,290 @@
---
name: tpmjs-tool-creator
description: Guide for creating official TPMJS tools using the blocks CLI. Use when a user wants to create a new tool for the TPMJS registry, add a tool to packages/tools/official/, implement an AI SDK v6 tool, define a block in blocks.yml, validate a tool with `pnpm blocks run`, or publish a tool to npm with the tpmjs keyword.
---
# TPMJS Tool Creator
Create production-ready tools for the TPMJS registry using the blocks CLI. Tools are npm packages following the AI SDK v6 pattern, validated by blocks, and automatically synced to tpmjs.com.
## Workflow
1. Define the tool block in `packages/tools/official/blocks.yml`
2. Create the tool package directory
3. Implement the tool using AI SDK v6 `tool()` + `jsonSchema()`
4. Validate with `pnpm blocks run <tool-name>`
5. Build and publish to npm
## Step 1: Define in blocks.yml
Add to the `blocks:` section of `packages/tools/official/blocks.yml`:
```yaml
blocks:
category.toolName:
type: utility
description: "LLM-friendly description of what the tool does"
path: "tool-directory-name"
domain_rules:
- id: rule_name
description: "What this implementation must do"
inputs:
- name: inputName
type: string
description: "Description for LLMs"
- name: optionalInput
type: number
optional: true
description: "Optional parameter"
outputs:
- name: result
type: ResultType
description: "What the tool returns"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance]
```
**Category prefix** (before the dot): `research`, `web`, `data`, `documentation`, `engineering`, `security`, `statistics`, `ops`, `agent`, `sandbox`, `utilities`, `html`, `compliance`.
For domain entities and quality measures, see [references/domain.md](references/domain.md).
## Step 2: Create Package Directory
Create `packages/tools/official/<tool-name>/`:
```
<tool-name>/
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── README.md
└── src/
└── index.ts
```
**package.json:**
```json
{
"name": "@tpmjs/official-<tool-name>",
"version": "0.1.0",
"description": "Short description",
"type": "module",
"keywords": ["tpmjs", "<category>", "ai"],
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"files": ["dist"],
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"type-check": "tsc --noEmit",
"clean": "rm -rf dist .turbo"
},
"devDependencies": {
"@tpmjs/tsconfig": "workspace:*",
"tsup": "^8.5.1",
"typescript": "^5.9.3"
},
"dependencies": {
"ai": "6.0.49"
},
"publishConfig": { "access": "public" },
"repository": {
"type": "git",
"url": "https://github.com/tpmjs/tpmjs.git",
"directory": "packages/tools/official/<tool-name>"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "<category>",
"frameworks": ["vercel-ai"],
"tools": [
{
"name": "toolName",
"description": "Clear description (20+ chars)."
}
]
}
}
```
**tsconfig.json:**
```json
{
"extends": "@tpmjs/tsconfig/react-library.json",
"compilerOptions": { "outDir": "dist", "rootDir": "src" },
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
```
**tsup.config.ts:**
```typescript
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
sourcemap: true,
target: 'es2022',
});
```
## Step 3: Implement the Tool
Every tool follows this AI SDK v6 pattern in `src/index.ts`:
```typescript
import { jsonSchema, tool } from 'ai';
interface MyToolInput {
param1: string;
param2?: number;
}
export interface MyToolResult {
data: string;
metadata: { processedAt: string };
}
export const myTool = tool({
description: 'Clear LLM-friendly description of what this tool does.',
parameters: jsonSchema<MyToolInput>({
type: 'object',
properties: {
param1: {
type: 'string',
description: 'What param1 is for',
},
param2: {
type: 'number',
description: 'Optional: what param2 is for',
},
},
required: ['param1'],
additionalProperties: false,
}),
execute: async (input): Promise<MyToolResult> => {
if (!input.param1) {
throw new Error('param1 is required and must be non-empty');
}
try {
const result = await processData(input.param1);
return {
data: result,
metadata: { processedAt: new Date().toISOString() },
};
} catch (error) {
throw new Error(
`Failed to process: ${error instanceof Error ? error.message : String(error)}`
);
}
},
});
export default myTool;
```
**Hard rules:**
- No stubs, TODOs, or placeholders — every tool must be fully working
- Single-shot: one call in, one structured result out
- Validate inputs before processing
- Try-catch with descriptive errors including context
- `additionalProperties: false` on jsonSchema
- Description on every schema property
- Export as both named and default export
- Output interface must be exported
### Multi-Tool Packages
For packages with multiple tools, add root-level files:
**block.ts:**
```typescript
import { toolA, toolB } from './src/index.js';
export const block = { name: 'package-name', tools: { toolA, toolB } };
export default block;
```
**index.ts (root):**
```typescript
export * from './src/index.js';
export { default } from './src/index.js';
```
Each tool gets its own entry in blocks.yml (same `path`) and in `tpmjs.tools` array.
## Step 4: Validate
```bash
cd packages/tools/official
pnpm blocks run <tool-name> # Validate (schema → shape → domain)
pnpm blocks run <tool-name> --force # Force full validation (skip cache)
pnpm blocks run <tool-name> --json # JSON output for debugging
pnpm blocks run --all # Validate all tools
```
**Common errors:**
- `Tool "X" not found in exports` → Export name must match blocks.yml
- `Required file not found` → Check package root has all required files
- `invalid tpmjs field` → Category must be valid, tools array required
## Step 5: Build and Publish
```bash
pnpm --filter=@tpmjs/official-<tool-name> build
cd packages/tools/official/<tool-name> && npm publish --access public
```
The tool syncs to tpmjs.com automatically via the changes feed (every 2 min) and keyword search (every 15 min). To trigger immediately:
```bash
source apps/web/.env.local
curl -X POST https://tpmjs.com/api/sync/keyword \
-H "Authorization: Bearer $CRON_SECRET"
```
## README Template
Every tool needs a README:
```markdown
# @tpmjs/official-<tool-name>
Short description.
## Installation
npm install @tpmjs/official-<tool-name>
## Usage
\`\`\`typescript
import { myTool } from '@tpmjs/official-<tool-name>';
const result = await myTool.execute({ param1: 'example' });
\`\`\`
## Parameters
| Name | Type | Required | Description |
|--------|--------|----------|--------------------|
| param1 | string | Yes | What param1 is for |
## Output
| Field | Type | Description |
|-------|--------|----------------------|
| data | string | The processed result |
## License
MIT
```

View file

@ -0,0 +1,58 @@
# Domain Reference
## Entities
Reusable output types defined in blocks.yml. Reference these in your tool's output `type` field.
| Entity | Fields |
|--------|--------|
| url | href, domain, protocol, path, query, fragment |
| webpage | url, title, html, text, metadata |
| text_content | raw, sentences, paragraphs, wordCount |
| claim | statement, confidence, needsCitation, category |
| timeline | events, dateRange, gaps, eventCount |
| evidence | source, type, strength, relevance |
| summary | text, keyPoints, length, compressionRatio |
| sentiment | score, label, confidence, aspects |
| entity | name, type, mentions, context |
| relationship | source, target, type, strength |
| pattern | name, frequency, examples, significance |
| anomaly | description, severity, context, recommendation |
| metric | name, value, unit, trend |
| comparison | items, criteria, rankings, analysis |
| recommendation | action, priority, rationale, impact |
| risk | description, likelihood, impact, mitigation |
| code_snippet | language, code, explanation, complexity |
| api_endpoint | method, path, parameters, response |
| data_schema | fields, types, constraints, relationships |
| workflow_step | action, input, output, conditions |
## Quality Measures
Reference these in your output's `measures` array.
| Measure | Severity | What it checks |
|---------|----------|---------------|
| working_implementation | error | No TODOs, stubs, or placeholders. Returns actual computed values. |
| valid_output_structure | error | Returns object matching declared interface. All required fields present. Arrays never undefined. |
| proper_error_handling | error | Throws descriptive Error with context. Validates inputs. Catches external API errors. |
| ai_sdk_compliance | error | Uses `tool()` + `jsonSchema()` from 'ai'. Clear description. Every property has description. |
| npm_publishable | error | Valid package.json with tpmjs field. Named + default exports. Proper types. Semver version. |
| readme_documentation | error | README exists. Describes tool. Usage example. Documents inputs/outputs. |
| deterministic_output | warning | Same input produces same output (where applicable). |
| minimal_dependencies | warning | Uses stable, well-maintained packages. Avoids unnecessary deps. |
## Domain Rules
Common domain rule categories for the `domain_rules` field in blocks.yml:
- **Core implementation**: working code, proper types, error handling
- **Web & fetch**: URL validation, content extraction, timeout handling
- **Document generation**: format compliance, template rendering
- **Data transformation**: schema validation, type coercion, encoding
- **Engineering/code analysis**: AST parsing, complexity metrics
- **Security & compliance**: input sanitization, safe execution
- **Statistical rigor**: numerical accuracy, proper rounding
- **Workflow/recipe**: step sequencing, state management
Define custom rules specific to your tool's requirements. Each rule needs an `id` and `description`.